VMM: handle EPT page faults

Pretty damn simple - just use the real page fault handler, and the EPT
is filled in under the hood by all the epte_ ops.
diff --git a/kern/arch/x86/vmm/intel/vmx.c b/kern/arch/x86/vmm/intel/vmx.c
index ef0bb45..61d37c9 100644
--- a/kern/arch/x86/vmm/intel/vmx.c
+++ b/kern/arch/x86/vmm/intel/vmx.c
@@ -1140,27 +1140,17 @@
 	exit_qual = vmcs_read32(EXIT_QUALIFICATION);
 	gva = vmcs_readl(GUEST_LINEAR_ADDRESS);
 	gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
-	printk("ept: gva %016lx, gpa %016lx\n", gva, gpa);
 
 	vmx_put_cpu(vcpu);
 
-	// this is a total hack, for testing things.
-	// note that we only care about the gpa, and the
-	// gpa is our process virtual address. 
-	// Confused yet?
-	page = page_lookup(current->env_pgdir, (void *)gpa, NULL);
-	printk("Lookup %p returns %p\n", gpa, page);
-	if (page) {
-		uint64_t hpa = page2pa(page);
-		printk("hpa for %p is %p\n", gpa, hpa);
-		ret = -1;
-		printk("vmx_do_ept_fault returns %d\n", ret);
-	}
+	int prot = 0;
+	prot |= exit_qual & VMX_EPT_FAULT_READ ? PROT_READ : 0;
+	prot |= exit_qual & VMX_EPT_FAULT_WRITE ? PROT_WRITE : 0;
+	prot |= exit_qual & VMX_EPT_FAULT_INS ? PROT_EXEC : 0;
+	ret = handle_page_fault(current, gpa, prot);
 
 	if (ret) {
-		printk("page fault failure "
-		       "GPA: 0x%lx, GVA: 0x%lx\n",
-		       gpa, gva);
+		printk("EPT page fault failure GPA: %p, GVA: %p\n", gpa, gva);
 		vmx_dump_cpu(vcpu);
 	}
 
@@ -1294,7 +1284,7 @@
 		} else if (ret == EXIT_REASON_EXTERNAL_INTERRUPT) {
 			printk("External interrupt\n");
 		} else {
-			printk("unhandled exit: reason %x, exit qualification %x\n",
+			printk("unhandled exit: reason 0x%x, exit qualification 0x%x\n",
 			       ret, vmcs_read32(EXIT_QUALIFICATION));
 			vmx_dump_cpu(vcpu);
 			vcpu->shutdown = SHUTDOWN_UNHANDLED_EXIT_REASON;
diff --git a/tests/vmmcp.c b/tests/vmmcp.c
index 886c06a..753a60d 100644
--- a/tests/vmmcp.c
+++ b/tests/vmmcp.c
@@ -10,7 +10,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ros/syscall.h>
+#include <sys/mman.h>
 
+int *mmap_blob;
 unsigned long long stack[1024];
 volatile int shared = 0;
 int mcp = 1;
@@ -19,6 +21,7 @@
 static void *fail(void*arg)
 {
 
+	*mmap_blob = 1337;
 	if (mcp)
 	while (V(&shared, int) < 31) {
 		if (! (V(&shared, int) & 1))
@@ -43,7 +46,7 @@
 		}
 		cpu_relax();
 	}
-	printf("All done\n");
+	printf("All done, read %d\n", *mmap_blob);
 	return NULL;
 }
 
@@ -65,6 +68,15 @@
 		perror("Guest pcore setup failed");
 		exit(1);
 	}
+	/* blob that is faulted in from the EPT first.  we need this to be in low
+	 * memory (not above the normal mmap_break), so the EPT can look it up.
+	 * Note that we won't get 4096.  The min is 1MB now, and ld is there. */
+	mmap_blob = mmap((int*)4096, PGSIZE, PROT_READ | PROT_WRITE,
+	                 MAP_ANONYMOUS, -1, 0);
+	if (mmap_blob == MAP_FAILED) {
+		perror("Unable to mmap");
+		exit(1);
+	}
 
 	mcp = 1; //argc - 1;
 	if (mcp) {
@@ -127,7 +139,7 @@
 	if (ret != strlen(cmd)) {
 		perror(cmd);
 	}
-	printf("shared is %d\n", shared);
+	printf("shared is %d, blob is %d\n", shared, *mmap_blob);
 
 	return 0;
 }