From owner-svn-src-projects@FreeBSD.ORG  Wed Dec 19 12:09:03 2012
Return-Path: <owner-svn-src-projects@FreeBSD.ORG>
Delivered-To: svn-src-projects@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
 by hub.freebsd.org (Postfix) with ESMTP id 69FB9B19;
 Wed, 19 Dec 2012 12:09:03 +0000 (UTC)
 (envelope-from cherry@FreeBSD.org)
Received: from svn.freebsd.org (svn.freebsd.org
 [IPv6:2001:1900:2254:2068::e6a:0])
 by mx1.freebsd.org (Postfix) with ESMTP id 4FC6A8FC12;
 Wed, 19 Dec 2012 12:09:03 +0000 (UTC)
Received: from svn.freebsd.org (localhost [127.0.0.1])
 by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qBJC93EH089070;
 Wed, 19 Dec 2012 12:09:03 GMT (envelope-from cherry@svn.freebsd.org)
Received: (from cherry@localhost)
 by svn.freebsd.org (8.14.5/8.14.5/Submit) id qBJC93T4089069;
 Wed, 19 Dec 2012 12:09:03 GMT (envelope-from cherry@svn.freebsd.org)
Message-Id: <201212191209.qBJC93T4089069@svn.freebsd.org>
From: "Cherry G. Mathew" <cherry@FreeBSD.org>
Date: Wed, 19 Dec 2012 12:09:03 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject: svn commit: r244425 - projects/amd64_xen_pv/sys/amd64/xen
X-SVN-Group: projects
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-projects@freebsd.org
X-Mailman-Version: 2.1.14
Precedence: list
List-Id: "SVN commit messages for the src &quot; projects&quot;
 tree" <svn-src-projects.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-projects>, 
 <mailto:svn-src-projects-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-projects>
List-Post: <mailto:svn-src-projects@freebsd.org>
List-Help: <mailto:svn-src-projects-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-projects>, 
 <mailto:svn-src-projects-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Wed, 19 Dec 2012 12:09:03 -0000

Author: cherry
Date: Wed Dec 19 12:09:02 2012
New Revision: 244425
URL: http://svnweb.freebsd.org/changeset/base/244425

Log:
   - Add a dummy userland pagetable pointer to keep xen happy. This allows us to hypervisor_iret() into xen to resume from exceptions. (Xen checks for a valid userland pagetable irrespective of the domain "mode" (ie; user/kernel)) being returned to.
   - Enhance xen_vm_vtop() to lookup early (boottime) kernel mappings.
   - A few more sanity checks ie; KASSERTS()

Modified:
  projects/amd64_xen_pv/sys/amd64/xen/pmap.c

Modified: projects/amd64_xen_pv/sys/amd64/xen/pmap.c
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/xen/pmap.c	Wed Dec 19 12:00:09 2012	(r244424)
+++ projects/amd64_xen_pv/sys/amd64/xen/pmap.c	Wed Dec 19 12:09:02 2012	(r244425)
@@ -429,7 +429,7 @@ pmap_xen_bootpages(vm_paddr_t *firstaddr
 	uintptr_t va;
 	vm_paddr_t ma;
 
-	/* Share info */
+	/* i) Share info */
 	ma = xen_start_info->shared_info;
 
 	/* This is a bit of a hack right now - we waste a physical
@@ -452,6 +452,27 @@ pmap_xen_bootpages(vm_paddr_t *firstaddr
 	PT_SET_MA(va, ma | PG_RW | PG_V | PG_U);
 
 	HYPERVISOR_shared_info = (void *) va;
+
+
+	/* ii) Userland page table base */
+	va = vallocpages(firstaddr, 1);
+	bzero((void *)va, PAGE_SIZE);
+
+	/* 
+	 * x86_64 has 2 privilege rings and Xen keeps separate pml4
+	 * pointers for each, which are sanity checked on every
+	 * exit via hypervisor_iret. We therefore set up a zeroed out
+	 * user page table pml4 to satisfy/fool xen.
+	 */
+	
+	/* Mark the page r/o before pinning */
+	pmap_xen_setpages_ro(va, 1);
+
+	/* Pin the table */
+	xen_pgdir_pin(phystomach(VTOP(va)));
+
+	/* Register user page table with Xen */
+	xen_pt_user_switch(VTOP(va));
 }
 
 /* Boot time ptov - xen guarantees bootpages to be offset */
@@ -906,7 +927,12 @@ pmap_extract_and_hold(pmap_t pmap, vm_of
 vm_paddr_t
 pmap_kextract(vm_offset_t va)
 {
-	return xpmap_mtop(pmap_kextract_ma(va));
+	vm_paddr_t ma;
+	ma = pmap_kextract_ma(va);
+
+	KASSERT(ma != 0, ("%s: Unmapped va: 0x%lx \n", __func__, va));
+
+	return xpmap_mtop(ma);
 }
 
 vm_paddr_t
@@ -1301,8 +1327,12 @@ xen_vm_vtop(uintptr_t va)
 {
 	int result;
 
-	/* The kernel expects to have full access to its address space */
-	const vm_prot_t accesstype = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
+	/* 
+	 * The kernel expects to have at least read access to its
+	 * address space. On Xen we don't have full access, since
+	 * page-table pages, for eg: are read-only.
+	 */
+	const vm_prot_t accesstype = VM_PROT_READ;
 
 	vm_page_t m;
 	vm_object_t object; /* Backing object for this va */
@@ -1315,12 +1345,20 @@ xen_vm_vtop(uintptr_t va)
 		 va <= VM_MAX_KERNEL_ADDRESS),
 		("Invalid kernel virtual address"));
 
+	if (va >= KERNBASE && va <= virtual_avail) { /* 
+						      * Boot time page
+						      */
+		return VTOP(va);
+	}
+
 	/* Get the specific object and pindex where the va may be mapped */
 	result = vm_map_lookup(&kernel_map, va, accesstype, &entry,
 			       &object, &pindex, &tmp_prot, &wired);
 
-	KASSERT(result == KERN_SUCCESS, ("Couldn't find va in the  kernel map. \n"));
-	KASSERT(accesstype == tmp_prot, ("Kernel access permissions disparity\n"));
+	KASSERT(result == KERN_SUCCESS, ("Couldn't find va = 0x%lx in the  kernel map. \n", va));
+
+	KASSERT(accesstype | tmp_prot, ("Kernel access permissions disparity for va = 0x%lx: %s\n", va, ((tmp_prot & VM_PROT_READ) ? "VM_PROT_READ" : (
+																     (tmp_prot & VM_PROT_WRITE) ? "| VM_PROT_WRITE" : ((tmp_prot & VM_PROT_EXECUTE) ? "| VM_PROT_EXECUTE" : "")))));
 
 	VM_OBJECT_LOCK(object);