+ assert(p->pm_eptp != 0);
+
+ return TRUE;
+}
+
+void hv_ept_pmap_create(void **ept_pmap, void **eptp);
+
+#if NCOPY_WINDOWS > 0
+#define PMAP_PDPT_FIRST_WINDOW 0
+#define PMAP_PDPT_NWINDOWS 4
+#define PMAP_PDE_FIRST_WINDOW (PMAP_PDPT_NWINDOWS)
+#define PMAP_PDE_NWINDOWS 4
+#define PMAP_PTE_FIRST_WINDOW (PMAP_PDE_FIRST_WINDOW + PMAP_PDE_NWINDOWS)
+#define PMAP_PTE_NWINDOWS 4
+
+#define PMAP_NWINDOWS_FIRSTFREE (PMAP_PTE_FIRST_WINDOW + PMAP_PTE_NWINDOWS)
+#define PMAP_WINDOW_SIZE 8
+#define PMAP_NWINDOWS (PMAP_NWINDOWS_FIRSTFREE + PMAP_WINDOW_SIZE)
+
+typedef struct {
+ pt_entry_t *prv_CMAP;
+ caddr_t prv_CADDR;
+} mapwindow_t;
+
+typedef struct cpu_pmap {
+ int pdpt_window_index;
+ int pde_window_index;
+ int pte_window_index;
+ mapwindow_t mapwindow[PMAP_NWINDOWS];
+} cpu_pmap_t;
+
+
+extern mapwindow_t *pmap_get_mapwindow(pt_entry_t pentry);
+extern void pmap_put_mapwindow(mapwindow_t *map);
+#endif
+
+typedef struct pmap_memory_regions {
+ ppnum_t base; /* first page of this region */
+ ppnum_t alloc_up; /* pages below this one have been "stolen" */
+ ppnum_t alloc_down; /* pages above this one have been "stolen" */
+ ppnum_t end; /* last page of this region */
+ uint32_t type;
+ uint64_t attribute;
+} pmap_memory_region_t;
+
+extern unsigned pmap_memory_region_count;
+extern unsigned pmap_memory_region_current;
+
+#define PMAP_MEMORY_REGIONS_SIZE 128
+
+extern pmap_memory_region_t pmap_memory_regions[];
+#include <i386/pmap_pcid.h>
+
+static inline void
+set_dirbase(pmap_t tpmap, thread_t thread, int my_cpu) {
+ int ccpu = my_cpu;
+ uint64_t pcr3 = tpmap->pm_cr3, ucr3 = tpmap->pm_ucr3;
+ cpu_datap(ccpu)->cpu_task_cr3 = pcr3;
+ cpu_shadowp(ccpu)->cpu_task_cr3 = pcr3;
+
+ cpu_datap(ccpu)->cpu_ucr3 = ucr3;
+ cpu_shadowp(ccpu)->cpu_ucr3 = ucr3;
+
+ cpu_datap(ccpu)->cpu_task_map = tpmap->pm_task_map;
+
+ assert((get_preemption_level() > 0) || (ml_get_interrupts_enabled() == FALSE));
+ assert(ccpu == cpu_number());
+ /*
+ * Switch cr3 if necessary
+ * - unless running with no_shared_cr3 debugging mode
+ * and we're not on the kernel's cr3 (after pre-empted copyio)
+ */
+ boolean_t nopagezero = tpmap->pagezero_accessible;
+ boolean_t priorpagezero = cpu_datap(ccpu)->cpu_pagezero_mapped;
+ cpu_datap(ccpu)->cpu_pagezero_mapped = nopagezero;
+
+ if (__probable(!no_shared_cr3)) {
+ if (__improbable(nopagezero)) {
+ boolean_t copyio_active = ((thread->machine.specFlags & CopyIOActive) != 0);
+ if (pmap_pcid_ncpus) {
+ pmap_pcid_activate(tpmap, ccpu, TRUE, copyio_active);
+ } else {
+ if (copyio_active) {
+ if (get_cr3_base() != tpmap->pm_cr3) {
+ set_cr3_raw(tpmap->pm_cr3);
+ }
+ } else if (get_cr3_base() != cpu_datap(ccpu)->cpu_kernel_cr3) {
+ set_cr3_raw(cpu_datap(ccpu)->cpu_kernel_cr3);
+ }
+ }
+ } else if ((get_cr3_base() != tpmap->pm_cr3) || priorpagezero) {
+ if (pmap_pcid_ncpus) {
+ pmap_pcid_activate(tpmap, ccpu, FALSE, FALSE);
+ } else {
+ set_cr3_raw(tpmap->pm_cr3);
+ }
+ }
+ } else {
+ if (get_cr3_base() != cpu_datap(ccpu)->cpu_kernel_cr3)
+ set_cr3_raw(cpu_datap(ccpu)->cpu_kernel_cr3);
+ }
+}