PERFORCE change 116925 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Fri Mar 30 15:23:09 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=116925
Change 116925 by gonzo at gonzo_jeeves on 2007/03/30 15:22:20
o ASID generation logic reworked.
o PTE for kernel virtual address space should have global
bit set. With EntryHi set in pmap_active some undesirable
effects appeared, i.e.: "splitting" KVA among processes.
Affected files ...
.. //depot/projects/mips2/src/sys/mips/mips/pmap.c#25 edit
Differences ...
==== //depot/projects/mips2/src/sys/mips/mips/pmap.c#25 (text+ko) ====
@@ -169,7 +169,7 @@
/*
* Active segtab.
*/
-struct segtab * segtab_active;
+struct segtab * segtab_active = 0;
/*
* Data for the ASID allocator
@@ -207,6 +207,7 @@
static int
pte_prot(pmap_t pmap, vm_prot_t prot)
{
+
if(prot & VM_PROT_WRITE)
return PG_D;
@@ -342,7 +343,7 @@
kernel_pmap->pm_private.pm_direct_map = kptmap;
kernel_pmap->pm_active = ~0;
kernel_pmap->pm_asid = PMAP_ASID_RESERVED;
- kernel_pmap->pm_asid_generation = 1;
+ kernel_pmap->pm_asid_generation = 0;
PMAP_LOCK_INIT(kernel_pmap);
TAILQ_INIT(&kernel_pmap->pm_pvlist);
@@ -509,8 +510,10 @@
* Invalidate all per-process mappings and I-cache
*/
PCPU_SET(next_asid, 1);
- PCPU_SET(current_asid_generation, (PCPU_GET(current_asid_generation) + 1) &
- ASIDGEN_MASK);
+
+ /* It's OK to turn to 0 */
+ PCPU_SET(current_asid_generation,
+ (PCPU_GET(current_asid_generation) + 1));
if (PCPU_GET(current_asid_generation) == 0) {
/*
@@ -679,7 +682,7 @@
pmap_kenter(vm_offset_t va, vm_offset_t pa)
{
- tlb_enter(kernel_pmap, va, pa, PG_V | PG_W | PG_D);
+ tlb_enter(kernel_pmap, va, pa, PG_V | PG_W | PG_D | PG_G);
}
/*
@@ -730,12 +733,13 @@
pmap->pm_active = 0;
pmap->pm_asid = PMAP_ASID_RESERVED;
- pmap->pm_asid_generation = 1;
+ pmap->pm_asid_generation = 0;
TAILQ_INIT(&pmap->pm_pvlist);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
mtx_init(&allpmaps_lock, "allpmaps", NULL, MTX_SPIN | MTX_QUIET);
LIST_INSERT_HEAD(&allpmaps, pmap, pm_list);
+ PCPU_SET(current_asid_generation, 1);
}
/*
@@ -771,9 +775,8 @@
pmap->pm_ptphint = NULL;
pmap->pm_active = 0;
- /* XXXMIPS: put proper asid generation here */
- pmap->pm_asid = 1;
- pmap->pm_asid_generation = 1;
+ pmap->pm_asid = PMAP_ASID_RESERVED;
+ pmap->pm_asid_generation = 0;
PMAP_LOCK_INIT(pmap);
TAILQ_INIT(&pmap->pm_pvlist);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
@@ -974,7 +977,9 @@
int retval;
oldpte = *ptq;
- *ptq = 0;
+ /* Preserve global bit */
+ *ptq &= PG_G;
+
if (oldpte & PG_W)
pmap->pm_stats.wired_count -= 1;
@@ -1029,6 +1034,7 @@
{
pmap_remove_pte(pmap, pte, va);
tlb_remove(pmap, va);
+
}
va += PAGE_SIZE;
}
@@ -1185,7 +1191,7 @@
pt_entry_t *pte;
vm_offset_t opa;
vm_page_t mpte, mem;
- int p, has_mapping = 0;
+ int p, has_mapping = 0, global;
if (pmap == NULL)
return;
@@ -1298,8 +1304,9 @@
pmap->pm_stats.wired_count++;
wired = wired ? PG_W : 0;
+ global = pmap == kernel_pmap ? PG_G : 0;
p = pte_prot(pmap, prot);
- tlb_enter(pmap, va, pa, PG_V | wired | p);
+ tlb_enter(pmap, va, pa, PG_V | wired | global | p);
}
/*
@@ -1843,30 +1850,34 @@
pmap = vmspace_pmap(td->td_proc->p_vmspace);
critical_enter();
- if (pmap_active && pmap != pmap_active) {
- atomic_clear_int(&pmap_active->pm_active,
- PCPU_GET(cpumask));
- pmap_active = 0;
- segtab_active = 0;
- }
- if (pmap->pm_asid_generation != PCPU_GET(current_asid_generation))
+ /*
+ * Kernel pmap has ASID equal zero and generation zero as well
+ * Just don't mess with it's ASID on generation turnover.
+ */
+ if ((pmap != kernel_pmap) &&
+ (pmap->pm_asid_generation != PCPU_GET(current_asid_generation)))
pmap_get_asid(pmap);
- mips_wr_entryhi(pmap->pm_asid);
+ if (td == curthread)
+ {
+ if (pmap_active && pmap != pmap_active)
+ {
+ atomic_clear_int(&pmap_active->pm_active,
+ PCPU_GET(cpumask));
+ pmap_active = 0;
+ segtab_active = 0;
+ }
+
+ mips_wr_entryhi(pmap->pm_asid);
- pmap_active = pmap;
- segtab_active = pmap->pm_private.pm_segtab;
- atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask));
+ pmap_active = pmap;
+ segtab_active = pmap->pm_private.pm_segtab;
+ atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask));
+ mips_dcache_wbinv_all();
+ }
critical_exit();
-
- if (td == curthread) {
- /* XXX swap context?
- alpha_pal_swpctx((u_long)td->td_md.md_pcbpaddr);
- */
- }
- mips_dcache_wbinv_all();
}
void
More information about the p4-projects
mailing list