Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Jan 2008 05:13:16 GMT
From:      Scott Long <scottl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 134353 for review
Message-ID:  <200801290513.m0T5DG12096428@repoman.freebsd.org>

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

Change 134353 by scottl@scottl-deimos on 2008/01/29 05:12:42

	Integrate from xen31

Affected files ...

.. //depot/projects/xen31-xenbus/sys/conf/files.i386#2 integrate
.. //depot/projects/xen31-xenbus/sys/i386/i386/trap.c#3 integrate
.. //depot/projects/xen31-xenbus/sys/i386/include/xen/xenpmap.h#3 integrate
.. //depot/projects/xen31-xenbus/sys/i386/xen/pmap.c#6 integrate
.. //depot/projects/xen31-xenbus/sys/vm/pmap.h#2 integrate
.. //depot/projects/xen31-xenbus/sys/vm/vm_fault.c#2 integrate

Differences ...

==== //depot/projects/xen31-xenbus/sys/conf/files.i386#2 (text+ko) ====

@@ -317,7 +317,7 @@
 i386/i386/nexus.c		standard
 i386/i386/perfmon.c		optional perfmon
 i386/i386/pmap.c		optional native
-i386/xen/pmap.c			optional xen nowerror
+i386/xen/pmap.c			optional xen 
 i386/i386/ptrace_machdep.c	standard
 i386/i386/stack_machdep.c	optional ddb | stack
 i386/i386/support.s		standard

==== //depot/projects/xen31-xenbus/sys/i386/i386/trap.c#3 (text+ko) ====

@@ -69,6 +69,7 @@
 #include <sys/syscall.h>
 #include <sys/sysctl.h>
 #include <sys/sysent.h>
+#include <sys/syslog.h>
 #include <sys/uio.h>
 #include <sys/vmmeter.h>
 #ifdef KTRACE
@@ -834,7 +835,7 @@
 	}
 #ifdef XEN
 	if (rv == KERN_PROTECTION_FAILURE)
-		printf("SIGBUS: p=%s va=0x%x ftype=0x%x eip=0x%x\n", p->p_comm, va, ftype, frame->tf_eip);
+		log(LOG_ERR, "SIGBUS: p=%s va=0x%x ftype=0x%x eip=0x%x\n", p->p_comm, va, ftype, frame->tf_eip);
 #endif
 	    
 	return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);

==== //depot/projects/xen31-xenbus/sys/i386/include/xen/xenpmap.h#3 (text+ko) ====

@@ -202,13 +202,17 @@
 static __inline vm_paddr_t
 xpmap_mtop(vm_paddr_t mpa)
 {
-    return machtophys(mpa) | (mpa & PAGE_MASK);
+	vm_paddr_t tmp = (mpa & PG_FRAME);
+	
+	return machtophys(tmp) | (mpa & ~PG_FRAME);
 }
 
 static __inline vm_paddr_t
 xpmap_ptom(vm_paddr_t ppa)
 {
-    return phystomach(ppa) | (ppa & PAGE_MASK);
+	vm_paddr_t tmp = (ppa & PG_FRAME);
+
+	return phystomach(tmp) | (ppa & ~PG_FRAME);
 }
 
 static __inline void

==== //depot/projects/xen31-xenbus/sys/i386/xen/pmap.c#6 (text+ko) ====

@@ -213,8 +213,10 @@
 
 #ifdef PAE
 pt_entry_t pg_nx;
+#if !defined(XEN) 
 static uma_zone_t pdptzone;
 #endif
+#endif
 
 /*
  * Data for the pv entry allocation mechanism
@@ -270,7 +272,7 @@
 static void	free_pv_entry(pmap_t pmap, pv_entry_t pv);
 static pv_entry_t get_pv_entry(pmap_t locked_pmap, int try);
 
-static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va,
+static vm_page_t pmap_enter_quick_locked(multicall_entry_t **mcl, int *count, pmap_t pmap, vm_offset_t va,
     vm_page_t m, vm_prot_t prot, vm_page_t mpte);
 static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva,
     vm_page_t *free);
@@ -290,7 +292,9 @@
 static void pmap_pte_release(pt_entry_t *pte);
 static int pmap_unuse_pt(pmap_t, vm_offset_t, vm_page_t *);
 static vm_offset_t pmap_kmem_choose(vm_offset_t addr);
-#ifdef PAE
+static boolean_t pmap_is_prefaultable_locked(pmap_t pmap, vm_offset_t addr);
+
+#if defined(PAE) && !defined(XEN)
 static void *pmap_pdpt_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait);
 #endif
 
@@ -583,7 +587,7 @@
 	TAILQ_INIT(&m->md.pv_list);
 }
 
-#ifdef PAE
+#if defined(PAE) && !defined(XEN)
 
 static MALLOC_DEFINE(M_PMAPPDPT, "pmap", "pmap pdpt");
 
@@ -677,7 +681,7 @@
 	if (pv_chunkbase == NULL)
 		panic("pmap_init: not enough kvm for pv chunks");
 	pmap_ptelist_init(&pv_vafree, pv_chunkbase, pv_maxchunks);
-#ifdef PAE
+#if defined(PAE) && !defined(XEN)
 	pdptzone = uma_zcreate("PDPT", NPGPTD * sizeof(pdpt_entry_t), NULL,
 	    NULL, NULL, NULL, (NPGPTD * sizeof(pdpt_entry_t)) - 1,
 	    UMA_ZONE_VM | UMA_ZONE_NOFREE);
@@ -1217,24 +1221,49 @@
 void
 pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
 {
-	pt_entry_t *endpte, oldpte, *pte;
-
-	oldpte = 0;
+	pt_entry_t *endpte, *pte;
+	vm_paddr_t pa;
+	vm_offset_t va = sva;
+	int mclcount = 0;
+	multicall_entry_t mcl[16];
+	multicall_entry_t *mclp = mcl;
+	int error;
+	
 	pte = vtopte(sva);
 	endpte = pte + count;
 	while (pte < endpte) {
-		oldpte |= *pte;
-		PT_SET_VA(pte, VM_PAGE_TO_PHYS(*ma) | pgeflag | PG_RW | PG_V, FALSE);
+		pa = xpmap_ptom(VM_PAGE_TO_PHYS(*ma)) | pgeflag | PG_RW | PG_V | PG_M | PG_A;
+
+		mclp->op = __HYPERVISOR_update_va_mapping;
+		mclp->args[0] = va;
+		mclp->args[1] = (uint32_t)(pa & 0xffffffff);
+		mclp->args[2] = (uint32_t)(pa >> 32);
+		mclp->args[3] = (*pte & PG_V) ? UVMF_INVLPG|UVMF_ALL : 0;
+	
+		va += PAGE_SIZE;
 		pte++;
 		ma++;
+		mclp++;
+		mclcount++;
+		if (mclcount == 16) {
+			error = HYPERVISOR_multicall(mcl, mclcount);
+			mclp = mcl;
+			mclcount = 0;
+			KASSERT(error == 0, ("bad multicall %d", error));
+		}		
+	}
+	if (mclcount) {
+		error = HYPERVISOR_multicall(mcl, mclcount);
+		KASSERT(error == 0, ("bad multicall %d", error));
 	}
-	if ((oldpte & PG_V) != 0)
-		pmap_invalidate_range(kernel_pmap, sva, sva + count *
-		    PAGE_SIZE);
-	else
-		PT_UPDATES_FLUSH();
+	
+#ifdef INVARIANTS
+	for (pte = vtopte(sva), mclcount = 0; mclcount < count; mclcount++, pte++)
+		KASSERT(*pte, ("pte not set for va=0x%x\n", sva + mclcount*PAGE_SIZE));
+#endif	
 }
 
+
 /*
  * This routine tears out page mappings from the
  * kernel -- it is meant only for temporary mappings.
@@ -1692,37 +1721,40 @@
 void
 pmap_release(pmap_t pmap)
 {
-	vm_page_t m, ptdpg[NPGPTD+1];
+	vm_page_t m, ptdpg[2*NPGPTD+1];
 	vm_paddr_t ma;
 	int i;
+#ifdef XEN
 #ifdef PAE	
 	int npgptd = 2*NPGPTD + 1;
 #else
 	int npgptd = 2*NPGPTD;
 #endif
-
+#else 
+	int npgptd = NPGPTD;
+#endif	
 	KASSERT(pmap->pm_stats.resident_count == 0,
 	    ("pmap_release: pmap resident count %ld != 0",
 	    pmap->pm_stats.resident_count));
+	PT_UPDATES_FLUSH();
 
 	pmap_lazyfix(pmap);
 	mtx_lock_spin(&allpmaps_lock);
 	LIST_REMOVE(pmap, pm_list);
 	mtx_unlock_spin(&allpmaps_lock);
 
+#ifdef XEN	
 	for (i = 0; i < NPGPTD; i++)
 		ptdpg[i] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdir_shadow + (i*NPDEPG)) & PG_FRAME);
+	pmap_qremove((vm_offset_t)pmap->pm_pdir_shadow, NPGPTD);	
+#endif
 	for (i = 0; i < NPGPTD; i++)
 		ptdpg[NPGPTD + i] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdir + (i*NPDEPG)) & PG_FRAME);
-
-#ifdef PAE
+	pmap_qremove((vm_offset_t)pmap->pm_pdir, NPGPTD);
+#if defined(PAE) && defined(XEN)
 	ptdpg[2*NPGPTD] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdpt));
 #endif	
 
-	PT_UPDATES_FLUSH();
-	pmap_qremove((vm_offset_t)pmap->pm_pdir, NPGPTD);
-	pmap_qremove((vm_offset_t)pmap->pm_pdir_shadow, NPGPTD);	
-
 	for (i = 0; i < npgptd; i++) {
 		m = ptdpg[i];
 		ma = xpmap_ptom(VM_PAGE_TO_PHYS(m));
@@ -2695,6 +2727,7 @@
 		*PMAP1 = 0;
 	sched_unpin();
 	vm_page_unlock_queues();
+	KASSERT(*vtopte(va), ("pte not set for va=0x%x\n", va));
 	PMAP_UNLOCK(pmap);
 }
 
@@ -2716,18 +2749,33 @@
 {
 	vm_page_t m, mpte;
 	vm_pindex_t diff, psize;
-
+	multicall_entry_t mcl[16];
+	multicall_entry_t *mclp = mcl;
+	int error, count = 0;
+	
 	VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED);
 	psize = atop(end - start);
+	    
 	mpte = NULL;
 	m = m_start;
 	PMAP_LOCK(pmap);
 	while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
-		mpte = pmap_enter_quick_locked(pmap, start + ptoa(diff), m,
+		mpte = pmap_enter_quick_locked(&mclp, &count, pmap, start + ptoa(diff), m,
 		    prot, mpte);
 		m = TAILQ_NEXT(m, listq);
+		if (count == 16) {
+			error = HYPERVISOR_multicall(mcl, count);
+			KASSERT(error == 0, ("bad multicall %d", error));
+			mclp = mcl;
+			count = 0;
+		}
+	}
+	if (count) {
+		error = HYPERVISOR_multicall(mcl, count);
+		KASSERT(error == 0, ("bad multicall %d", error));
 	}
- 	PMAP_UNLOCK(pmap);
+	
+	PMAP_UNLOCK(pmap);
 }
 
 /*
@@ -2742,20 +2790,54 @@
 void
 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
 {
+	multicall_entry_t mcl, *mclp;
+	int count = 0;
+	mclp = &mcl;
+	
+	PMAP_LOCK(pmap);
+	(void) pmap_enter_quick_locked(&mclp, &count, pmap, va, m, prot, NULL);
+	if (count)
+		HYPERVISOR_multicall(&mcl, count);
+	PMAP_UNLOCK(pmap);
+}
 
+void
+pmap_enter_quick_range(pmap_t pmap, vm_offset_t *addrs, vm_page_t *pages, vm_prot_t *prots, int count)
+{
+	int i, error, index = 0;
+	multicall_entry_t mcl[16];
+	multicall_entry_t *mclp = mcl;
+		
 	PMAP_LOCK(pmap);
-	(void) pmap_enter_quick_locked(pmap, va, m, prot, NULL);
+	for (i = 0; i < count; i++, addrs++, pages++, prots++) {
+		if (!pmap_is_prefaultable_locked(pmap, *addrs))
+			continue;
+
+		(void) pmap_enter_quick_locked(&mclp, &index, pmap, *addrs, *pages, *prots, NULL);
+		if (index == 16) {
+			error = HYPERVISOR_multicall(mcl, index);
+			mclp = mcl;
+			index = 0;
+			KASSERT(error == 0, ("bad multicall %d", error));
+		}
+	}
+	if (index) {
+		error = HYPERVISOR_multicall(mcl, index);
+		KASSERT(error == 0, ("bad multicall %d", error));
+	}
+	
 	PMAP_UNLOCK(pmap);
 }
 
 static vm_page_t
-pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
+pmap_enter_quick_locked(multicall_entry_t **mclpp, int *count, pmap_t pmap, vm_offset_t va, vm_page_t m,
     vm_prot_t prot, vm_page_t mpte)
 {
 	pt_entry_t *pte;
 	vm_paddr_t pa;
 	vm_page_t free;
-
+	multicall_entry_t *mcl = *mclpp;
+	
 	KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva ||
 	    (m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0,
 	    ("pmap_enter_quick_locked: managed mapping within the clean submap"));
@@ -2845,6 +2927,7 @@
 		pa |= pg_nx;
 #endif
 
+#if 0
 	/*
 	 * Now validate mapping with RO protection
 	 */
@@ -2852,6 +2935,23 @@
 		pte_store(pte, pa | PG_V | PG_U);
 	else
 		pte_store(pte, pa | PG_V | PG_U | PG_MANAGED);
+#else
+	/*
+	 * Now validate mapping with RO protection
+	 */
+	if (m->flags & (PG_FICTITIOUS|PG_UNMANAGED))
+		pa = 	xpmap_ptom(pa | PG_V | PG_U);
+	else
+		pa = xpmap_ptom(pa | PG_V | PG_U | PG_MANAGED);
+
+	mcl->op = __HYPERVISOR_update_va_mapping;
+	mcl->args[0] = va;
+	mcl->args[1] = (uint32_t)(pa & 0xffffffff);
+	mcl->args[2] = (uint32_t)(pa >> 32);
+	mcl->args[3] = 0;
+	*mclpp = mcl + 1;
+	*count = *count + 1;
+#endif	
 	return mpte;
 }
 
@@ -3058,7 +3158,11 @@
 					 * accessed (referenced) bits
 					 * during the copy.
 					 */
+#if 0					
 					PT_SET_VA_MA(dst_pte, ptetemp & ~(PG_W | PG_M | PG_A), FALSE);
+#else					
+					*dst_pte = ptetemp & ~(PG_W | PG_M | PG_A);
+#endif					
 					dst_pmap->pm_stats.resident_count++;
 	 			} else {
 					free = NULL;
@@ -3407,22 +3511,32 @@
  *	Return whether or not the specified virtual address is elgible
  *	for prefault.
  */
-boolean_t
-pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
+static boolean_t
+pmap_is_prefaultable_locked(pmap_t pmap, vm_offset_t addr)
 {
 	pt_entry_t *pte;
 	boolean_t rv = FALSE;
 
-	PMAP_LOCK(pmap);
+	return (rv);
+	
 	if (*pmap_pde(pmap, addr)) {
 		pte = vtopte(addr);
-		rv = *pte == 0;
+		rv = ((*pte & PG_V) == 0);
 	}
+	return (rv);
+}
+
+boolean_t
+pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
+{
+	boolean_t rv;
+	
+	PMAP_LOCK(pmap);
+	rv = pmap_is_prefaultable_locked(pmap, addr);
 	PMAP_UNLOCK(pmap);
 	return (rv);
 }
 
-
 void
 pmap_map_readonly(pmap_t pmap, vm_offset_t va, int len)
 {

==== //depot/projects/xen31-xenbus/sys/vm/pmap.h#2 (text+ko) ====

@@ -99,6 +99,8 @@
 		    vm_prot_t, boolean_t);
 void		 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m,
 		    vm_prot_t prot);
+void		 pmap_enter_quick_range(pmap_t pmap, vm_offset_t *addrs, vm_page_t *m,
+                    vm_prot_t *prot, int count);
 void		 pmap_enter_object(pmap_t pmap, vm_offset_t start,
 		    vm_offset_t end, vm_page_t m_start, vm_prot_t prot);
 vm_paddr_t	 pmap_extract(pmap_t pmap, vm_offset_t va);

==== //depot/projects/xen31-xenbus/sys/vm/vm_fault.c#2 (text+ko) ====

@@ -932,12 +932,15 @@
 static void
 vm_fault_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
 {
-	int i;
+	int i, count;
 	vm_offset_t addr, starta;
 	vm_pindex_t pindex;
 	vm_page_t m;
-	vm_object_t object;
-
+	vm_object_t object, lobject;
+	vm_prot_t prots[PAGEORDER_SIZE];
+	vm_page_t pages[PAGEORDER_SIZE];
+	vm_offset_t addrs[PAGEORDER_SIZE];
+	
 	if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace))
 		return;
 
@@ -949,10 +952,16 @@
 	} else if (starta > addra) {
 		starta = 0;
 	}
-
+       
+	for (i = 0; i < PAGEORDER_SIZE; i++) 
+		pages[i] = NULL;
+	count = 0;
+	lobject = object;
+	VM_OBJECT_LOCK(lobject);
 	for (i = 0; i < PAGEORDER_SIZE; i++) {
-		vm_object_t backing_object, lobject;
+		vm_object_t backing_object;
 
+		    
 		addr = addra + prefault_pageorder[i];
 		if (addr > addra + (PFFOR * PAGE_SIZE))
 			addr = 0;
@@ -964,35 +973,45 @@
 			continue;
 
 		pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
-		lobject = object;
-		VM_OBJECT_LOCK(lobject);
 		while ((m = vm_page_lookup(lobject, pindex)) == NULL &&
 		    lobject->type == OBJT_DEFAULT &&
 		    (backing_object = lobject->backing_object) != NULL) {
 			if (lobject->backing_object_offset & PAGE_MASK)
 				break;
 			pindex += lobject->backing_object_offset >> PAGE_SHIFT;
+
+			if (count) {
+				vm_page_lock_queues();
+				pmap_enter_quick_range(pmap, addrs, pages, prots, count);
+				vm_page_unlock_queues();
+			}
+			count = 0;
 			VM_OBJECT_LOCK(backing_object);
 			VM_OBJECT_UNLOCK(lobject);
 			lobject = backing_object;
+			
 		}
 		/*
 		 * give-up when a page is not in memory
 		 */
-		if (m == NULL) {
-			VM_OBJECT_UNLOCK(lobject);
+		if (m == NULL) 
 			break;
-		}
+
 		if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
 			(m->busy == 0) &&
 		    (m->flags & PG_FICTITIOUS) == 0) {
-
-			vm_page_lock_queues();
-			pmap_enter_quick(pmap, addr, m, entry->protection);
-			vm_page_unlock_queues();
+			pages[count] = m;
+			prots[count] = entry->protection;
+			addrs[count] = addr;
+			count++;
 		}
-		VM_OBJECT_UNLOCK(lobject);
+	}
+	if (count) {	
+		vm_page_lock_queues();
+		pmap_enter_quick_range(pmap, addrs, pages, prots, count);
+		vm_page_unlock_queues();
 	}
+	VM_OBJECT_UNLOCK(lobject);
 }
 
 /*



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