Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Mar 2007 15:23:08 GMT
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 116925 for review
Message-ID:  <200703301523.l2UFN8CO006204@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=116925

Change 116925 by gonzo@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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703301523.l2UFN8CO006204>