1366f6083SPeter Grehan /*- 2366f6083SPeter Grehan * Copyright (c) 2011 NetApp, Inc. 3366f6083SPeter Grehan * All rights reserved. 4366f6083SPeter Grehan * 5366f6083SPeter Grehan * Redistribution and use in source and binary forms, with or without 6366f6083SPeter Grehan * modification, are permitted provided that the following conditions 7366f6083SPeter Grehan * are met: 8366f6083SPeter Grehan * 1. Redistributions of source code must retain the above copyright 9366f6083SPeter Grehan * notice, this list of conditions and the following disclaimer. 10366f6083SPeter Grehan * 2. Redistributions in binary form must reproduce the above copyright 11366f6083SPeter Grehan * notice, this list of conditions and the following disclaimer in the 12366f6083SPeter Grehan * documentation and/or other materials provided with the distribution. 13366f6083SPeter Grehan * 14366f6083SPeter Grehan * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15366f6083SPeter Grehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16366f6083SPeter Grehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17366f6083SPeter Grehan * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18366f6083SPeter Grehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19366f6083SPeter Grehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20366f6083SPeter Grehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21366f6083SPeter Grehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22366f6083SPeter Grehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23366f6083SPeter Grehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24366f6083SPeter Grehan * SUCH DAMAGE. 25366f6083SPeter Grehan * 26366f6083SPeter Grehan * $FreeBSD$ 27366f6083SPeter Grehan */ 28366f6083SPeter Grehan 29366f6083SPeter Grehan #include <sys/cdefs.h> 30366f6083SPeter Grehan __FBSDID("$FreeBSD$"); 31366f6083SPeter Grehan 32366f6083SPeter Grehan #include <sys/types.h> 33366f6083SPeter Grehan #include <sys/errno.h> 34366f6083SPeter Grehan #include <sys/systm.h> 35366f6083SPeter Grehan #include <sys/malloc.h> 36366f6083SPeter Grehan #include <sys/smp.h> 37366f6083SPeter Grehan 38366f6083SPeter Grehan #include <vm/vm.h> 39366f6083SPeter Grehan #include <vm/pmap.h> 40366f6083SPeter Grehan 41366f6083SPeter Grehan #include <machine/param.h> 42366f6083SPeter Grehan #include <machine/cpufunc.h> 43366f6083SPeter Grehan #include <machine/pmap.h> 44366f6083SPeter Grehan #include <machine/vmparam.h> 45366f6083SPeter Grehan 46366f6083SPeter Grehan #include <machine/vmm.h> 47366f6083SPeter Grehan #include "vmx_cpufunc.h" 48366f6083SPeter Grehan #include "vmx_msr.h" 49366f6083SPeter Grehan #include "vmx.h" 50366f6083SPeter Grehan #include "ept.h" 51366f6083SPeter Grehan 52366f6083SPeter Grehan #define EPT_PWL4(cap) ((cap) & (1UL << 6)) 53366f6083SPeter Grehan #define EPT_MEMORY_TYPE_WB(cap) ((cap) & (1UL << 14)) 54366f6083SPeter Grehan #define EPT_PDE_SUPERPAGE(cap) ((cap) & (1UL << 16)) /* 2MB pages */ 55366f6083SPeter Grehan #define EPT_PDPTE_SUPERPAGE(cap) ((cap) & (1UL << 17)) /* 1GB pages */ 56366f6083SPeter Grehan #define INVVPID_SUPPORTED(cap) ((cap) & (1UL << 32)) 57366f6083SPeter Grehan #define INVEPT_SUPPORTED(cap) ((cap) & (1UL << 20)) 58366f6083SPeter Grehan 59366f6083SPeter Grehan #define INVVPID_ALL_TYPES_MASK 0xF0000000000UL 60366f6083SPeter Grehan #define INVVPID_ALL_TYPES_SUPPORTED(cap) \ 61366f6083SPeter Grehan (((cap) & INVVPID_ALL_TYPES_MASK) == INVVPID_ALL_TYPES_MASK) 62366f6083SPeter Grehan 63366f6083SPeter Grehan #define INVEPT_ALL_TYPES_MASK 0x6000000UL 64366f6083SPeter Grehan #define INVEPT_ALL_TYPES_SUPPORTED(cap) \ 65366f6083SPeter Grehan (((cap) & INVEPT_ALL_TYPES_MASK) == INVEPT_ALL_TYPES_MASK) 66366f6083SPeter Grehan 67366f6083SPeter Grehan #define EPT_PG_RD (1 << 0) 68366f6083SPeter Grehan #define EPT_PG_WR (1 << 1) 69366f6083SPeter Grehan #define EPT_PG_EX (1 << 2) 70366f6083SPeter Grehan #define EPT_PG_MEMORY_TYPE(x) ((x) << 3) 71366f6083SPeter Grehan #define EPT_PG_IGNORE_PAT (1 << 6) 72366f6083SPeter Grehan #define EPT_PG_SUPERPAGE (1 << 7) 73366f6083SPeter Grehan 74366f6083SPeter Grehan #define EPT_ADDR_MASK ((uint64_t)-1 << 12) 75366f6083SPeter Grehan 76366f6083SPeter Grehan MALLOC_DECLARE(M_VMX); 77366f6083SPeter Grehan 78366f6083SPeter Grehan static uint64_t page_sizes_mask; 79366f6083SPeter Grehan 80366f6083SPeter Grehan int 81366f6083SPeter Grehan ept_init(void) 82366f6083SPeter Grehan { 83366f6083SPeter Grehan int page_shift; 84366f6083SPeter Grehan uint64_t cap; 85366f6083SPeter Grehan 86366f6083SPeter Grehan cap = rdmsr(MSR_VMX_EPT_VPID_CAP); 87366f6083SPeter Grehan 88366f6083SPeter Grehan /* 89366f6083SPeter Grehan * Verify that: 90366f6083SPeter Grehan * - page walk length is 4 steps 91366f6083SPeter Grehan * - extended page tables can be laid out in write-back memory 92366f6083SPeter Grehan * - invvpid instruction with all possible types is supported 93366f6083SPeter Grehan * - invept instruction with all possible types is supported 94366f6083SPeter Grehan */ 95366f6083SPeter Grehan if (!EPT_PWL4(cap) || 96366f6083SPeter Grehan !EPT_MEMORY_TYPE_WB(cap) || 97366f6083SPeter Grehan !INVVPID_SUPPORTED(cap) || 98366f6083SPeter Grehan !INVVPID_ALL_TYPES_SUPPORTED(cap) || 99366f6083SPeter Grehan !INVEPT_SUPPORTED(cap) || 100366f6083SPeter Grehan !INVEPT_ALL_TYPES_SUPPORTED(cap)) 101366f6083SPeter Grehan return (EINVAL); 102366f6083SPeter Grehan 103366f6083SPeter Grehan /* Set bits in 'page_sizes_mask' for each valid page size */ 104366f6083SPeter Grehan page_shift = PAGE_SHIFT; 105366f6083SPeter Grehan page_sizes_mask = 1UL << page_shift; /* 4KB page */ 106366f6083SPeter Grehan 107366f6083SPeter Grehan page_shift += 9; 108366f6083SPeter Grehan if (EPT_PDE_SUPERPAGE(cap)) 109366f6083SPeter Grehan page_sizes_mask |= 1UL << page_shift; /* 2MB superpage */ 110366f6083SPeter Grehan 111366f6083SPeter Grehan page_shift += 9; 112366f6083SPeter Grehan if (EPT_PDPTE_SUPERPAGE(cap)) 113366f6083SPeter Grehan page_sizes_mask |= 1UL << page_shift; /* 1GB superpage */ 114366f6083SPeter Grehan 115366f6083SPeter Grehan return (0); 116366f6083SPeter Grehan } 117366f6083SPeter Grehan 118*bda273f2SNeel Natu #if 0 119*bda273f2SNeel Natu static void 120*bda273f2SNeel Natu ept_dump(uint64_t *ptp, int nlevels) 121*bda273f2SNeel Natu { 122*bda273f2SNeel Natu int i, t, tabs; 123*bda273f2SNeel Natu uint64_t *ptpnext, ptpval; 124*bda273f2SNeel Natu 125*bda273f2SNeel Natu if (--nlevels < 0) 126*bda273f2SNeel Natu return; 127*bda273f2SNeel Natu 128*bda273f2SNeel Natu tabs = 3 - nlevels; 129*bda273f2SNeel Natu for (t = 0; t < tabs; t++) 130*bda273f2SNeel Natu printf("\t"); 131*bda273f2SNeel Natu printf("PTP = %p\n", ptp); 132*bda273f2SNeel Natu 133*bda273f2SNeel Natu for (i = 0; i < 512; i++) { 134*bda273f2SNeel Natu ptpval = ptp[i]; 135*bda273f2SNeel Natu 136*bda273f2SNeel Natu if (ptpval == 0) 137*bda273f2SNeel Natu continue; 138*bda273f2SNeel Natu 139*bda273f2SNeel Natu for (t = 0; t < tabs; t++) 140*bda273f2SNeel Natu printf("\t"); 141*bda273f2SNeel Natu printf("%3d 0x%016lx\n", i, ptpval); 142*bda273f2SNeel Natu 143*bda273f2SNeel Natu if (nlevels != 0 && (ptpval & EPT_PG_SUPERPAGE) == 0) { 144*bda273f2SNeel Natu ptpnext = (uint64_t *) 145*bda273f2SNeel Natu PHYS_TO_DMAP(ptpval & EPT_ADDR_MASK); 146*bda273f2SNeel Natu ept_dump(ptpnext, nlevels); 147*bda273f2SNeel Natu } 148*bda273f2SNeel Natu } 149*bda273f2SNeel Natu } 150*bda273f2SNeel Natu #endif 151*bda273f2SNeel Natu 152366f6083SPeter Grehan static size_t 153366f6083SPeter Grehan ept_create_mapping(uint64_t *ptp, vm_paddr_t gpa, vm_paddr_t hpa, size_t length, 154366f6083SPeter Grehan vm_memattr_t attr, vm_prot_t prot, boolean_t spok) 155366f6083SPeter Grehan { 156366f6083SPeter Grehan int spshift, ptpshift, ptpindex, nlevels; 157366f6083SPeter Grehan 158366f6083SPeter Grehan /* 159366f6083SPeter Grehan * Compute the size of the mapping that we can accomodate. 160366f6083SPeter Grehan * 161366f6083SPeter Grehan * This is based on three factors: 162366f6083SPeter Grehan * - super page sizes supported by the processor 163366f6083SPeter Grehan * - alignment of the region starting at 'gpa' and 'hpa' 164366f6083SPeter Grehan * - length of the region 'len' 165366f6083SPeter Grehan */ 166366f6083SPeter Grehan spshift = PAGE_SHIFT; 167366f6083SPeter Grehan if (spok) 168366f6083SPeter Grehan spshift += (EPT_PWLEVELS - 1) * 9; 169366f6083SPeter Grehan while (spshift >= PAGE_SHIFT) { 170366f6083SPeter Grehan uint64_t spsize = 1UL << spshift; 171366f6083SPeter Grehan if ((page_sizes_mask & spsize) != 0 && 172366f6083SPeter Grehan (gpa & (spsize - 1)) == 0 && 173366f6083SPeter Grehan (hpa & (spsize - 1)) == 0 && 174366f6083SPeter Grehan length >= spsize) { 175366f6083SPeter Grehan break; 176366f6083SPeter Grehan } 177366f6083SPeter Grehan spshift -= 9; 178366f6083SPeter Grehan } 179366f6083SPeter Grehan 180366f6083SPeter Grehan if (spshift < PAGE_SHIFT) { 181366f6083SPeter Grehan panic("Invalid spshift for gpa 0x%016lx, hpa 0x%016lx, " 182366f6083SPeter Grehan "length 0x%016lx, page_sizes_mask 0x%016lx", 183366f6083SPeter Grehan gpa, hpa, length, page_sizes_mask); 184366f6083SPeter Grehan } 185366f6083SPeter Grehan 186366f6083SPeter Grehan nlevels = EPT_PWLEVELS; 187366f6083SPeter Grehan while (--nlevels >= 0) { 188366f6083SPeter Grehan ptpshift = PAGE_SHIFT + nlevels * 9; 189366f6083SPeter Grehan ptpindex = (gpa >> ptpshift) & 0x1FF; 190366f6083SPeter Grehan 191366f6083SPeter Grehan /* We have reached the leaf mapping */ 192366f6083SPeter Grehan if (spshift >= ptpshift) 193366f6083SPeter Grehan break; 194366f6083SPeter Grehan 195366f6083SPeter Grehan /* 196366f6083SPeter Grehan * We are working on a non-leaf page table page. 197366f6083SPeter Grehan * 198366f6083SPeter Grehan * Create the next level page table page if necessary and point 199366f6083SPeter Grehan * to it from the current page table. 200366f6083SPeter Grehan */ 201366f6083SPeter Grehan if (ptp[ptpindex] == 0) { 202366f6083SPeter Grehan void *nlp = malloc(PAGE_SIZE, M_VMX, M_WAITOK | M_ZERO); 203366f6083SPeter Grehan ptp[ptpindex] = vtophys(nlp); 204366f6083SPeter Grehan ptp[ptpindex] |= EPT_PG_RD | EPT_PG_WR | EPT_PG_EX; 205366f6083SPeter Grehan } 206366f6083SPeter Grehan 207366f6083SPeter Grehan /* Work our way down to the next level page table page */ 208366f6083SPeter Grehan ptp = (uint64_t *)PHYS_TO_DMAP(ptp[ptpindex] & EPT_ADDR_MASK); 209366f6083SPeter Grehan } 210366f6083SPeter Grehan 211366f6083SPeter Grehan if ((gpa & ((1UL << ptpshift) - 1)) != 0) { 212366f6083SPeter Grehan panic("ept_create_mapping: gpa 0x%016lx and ptpshift %d " 213366f6083SPeter Grehan "mismatch\n", gpa, ptpshift); 214366f6083SPeter Grehan } 215366f6083SPeter Grehan 216*bda273f2SNeel Natu if (prot != VM_PROT_NONE) { 217366f6083SPeter Grehan /* Do the mapping */ 218366f6083SPeter Grehan ptp[ptpindex] = hpa; 219366f6083SPeter Grehan 220366f6083SPeter Grehan /* Apply the access controls */ 221366f6083SPeter Grehan if (prot & VM_PROT_READ) 222366f6083SPeter Grehan ptp[ptpindex] |= EPT_PG_RD; 223366f6083SPeter Grehan if (prot & VM_PROT_WRITE) 224366f6083SPeter Grehan ptp[ptpindex] |= EPT_PG_WR; 225366f6083SPeter Grehan if (prot & VM_PROT_EXECUTE) 226366f6083SPeter Grehan ptp[ptpindex] |= EPT_PG_EX; 227366f6083SPeter Grehan 228366f6083SPeter Grehan /* 229*bda273f2SNeel Natu * XXX should we enforce this memory type by setting the 230*bda273f2SNeel Natu * ignore PAT bit to 1. 231366f6083SPeter Grehan */ 232366f6083SPeter Grehan ptp[ptpindex] |= EPT_PG_MEMORY_TYPE(attr); 233366f6083SPeter Grehan 234366f6083SPeter Grehan if (nlevels > 0) 235366f6083SPeter Grehan ptp[ptpindex] |= EPT_PG_SUPERPAGE; 236*bda273f2SNeel Natu } else { 237*bda273f2SNeel Natu /* Remove the mapping */ 238*bda273f2SNeel Natu ptp[ptpindex] = 0; 239*bda273f2SNeel Natu } 240366f6083SPeter Grehan 241366f6083SPeter Grehan return (1UL << ptpshift); 242366f6083SPeter Grehan } 243366f6083SPeter Grehan 244*bda273f2SNeel Natu static vm_paddr_t 245*bda273f2SNeel Natu ept_lookup_mapping(uint64_t *ptp, vm_paddr_t gpa) 246*bda273f2SNeel Natu { 247*bda273f2SNeel Natu int nlevels, ptpshift, ptpindex; 248*bda273f2SNeel Natu uint64_t ptpval, hpabase, pgmask; 249*bda273f2SNeel Natu 250*bda273f2SNeel Natu nlevels = EPT_PWLEVELS; 251*bda273f2SNeel Natu while (--nlevels >= 0) { 252*bda273f2SNeel Natu ptpshift = PAGE_SHIFT + nlevels * 9; 253*bda273f2SNeel Natu ptpindex = (gpa >> ptpshift) & 0x1FF; 254*bda273f2SNeel Natu 255*bda273f2SNeel Natu ptpval = ptp[ptpindex]; 256*bda273f2SNeel Natu 257*bda273f2SNeel Natu /* Cannot make progress beyond this point */ 258*bda273f2SNeel Natu if ((ptpval & (EPT_PG_RD | EPT_PG_WR | EPT_PG_EX)) == 0) 259*bda273f2SNeel Natu break; 260*bda273f2SNeel Natu 261*bda273f2SNeel Natu if (nlevels == 0 || (ptpval & EPT_PG_SUPERPAGE)) { 262*bda273f2SNeel Natu pgmask = (1UL << ptpshift) - 1; 263*bda273f2SNeel Natu hpabase = ptpval & ~pgmask; 264*bda273f2SNeel Natu return (hpabase | (gpa & pgmask)); 265*bda273f2SNeel Natu } 266*bda273f2SNeel Natu 267*bda273f2SNeel Natu /* Work our way down to the next level page table page */ 268*bda273f2SNeel Natu ptp = (uint64_t *)PHYS_TO_DMAP(ptpval & EPT_ADDR_MASK); 269*bda273f2SNeel Natu } 270*bda273f2SNeel Natu 271*bda273f2SNeel Natu return ((vm_paddr_t)-1); 272*bda273f2SNeel Natu } 273*bda273f2SNeel Natu 274366f6083SPeter Grehan static void 275366f6083SPeter Grehan ept_free_pt_entry(pt_entry_t pte) 276366f6083SPeter Grehan { 277366f6083SPeter Grehan if (pte == 0) 278366f6083SPeter Grehan return; 279366f6083SPeter Grehan 280366f6083SPeter Grehan /* sanity check */ 281366f6083SPeter Grehan if ((pte & EPT_PG_SUPERPAGE) != 0) 282366f6083SPeter Grehan panic("ept_free_pt_entry: pte cannot have superpage bit"); 283366f6083SPeter Grehan 284366f6083SPeter Grehan return; 285366f6083SPeter Grehan } 286366f6083SPeter Grehan 287366f6083SPeter Grehan static void 288366f6083SPeter Grehan ept_free_pd_entry(pd_entry_t pde) 289366f6083SPeter Grehan { 290366f6083SPeter Grehan pt_entry_t *pt; 291366f6083SPeter Grehan int i; 292366f6083SPeter Grehan 293366f6083SPeter Grehan if (pde == 0) 294366f6083SPeter Grehan return; 295366f6083SPeter Grehan 296366f6083SPeter Grehan if ((pde & EPT_PG_SUPERPAGE) == 0) { 297366f6083SPeter Grehan pt = (pt_entry_t *)PHYS_TO_DMAP(pde & EPT_ADDR_MASK); 298366f6083SPeter Grehan for (i = 0; i < NPTEPG; i++) 299366f6083SPeter Grehan ept_free_pt_entry(pt[i]); 300366f6083SPeter Grehan free(pt, M_VMX); /* free the page table page */ 301366f6083SPeter Grehan } 302366f6083SPeter Grehan } 303366f6083SPeter Grehan 304366f6083SPeter Grehan static void 305366f6083SPeter Grehan ept_free_pdp_entry(pdp_entry_t pdpe) 306366f6083SPeter Grehan { 307366f6083SPeter Grehan pd_entry_t *pd; 308366f6083SPeter Grehan int i; 309366f6083SPeter Grehan 310366f6083SPeter Grehan if (pdpe == 0) 311366f6083SPeter Grehan return; 312366f6083SPeter Grehan 313366f6083SPeter Grehan if ((pdpe & EPT_PG_SUPERPAGE) == 0) { 314366f6083SPeter Grehan pd = (pd_entry_t *)PHYS_TO_DMAP(pdpe & EPT_ADDR_MASK); 315366f6083SPeter Grehan for (i = 0; i < NPDEPG; i++) 316366f6083SPeter Grehan ept_free_pd_entry(pd[i]); 317366f6083SPeter Grehan free(pd, M_VMX); /* free the page directory page */ 318366f6083SPeter Grehan } 319366f6083SPeter Grehan } 320366f6083SPeter Grehan 321366f6083SPeter Grehan static void 322366f6083SPeter Grehan ept_free_pml4_entry(pml4_entry_t pml4e) 323366f6083SPeter Grehan { 324366f6083SPeter Grehan pdp_entry_t *pdp; 325366f6083SPeter Grehan int i; 326366f6083SPeter Grehan 327366f6083SPeter Grehan if (pml4e == 0) 328366f6083SPeter Grehan return; 329366f6083SPeter Grehan 330366f6083SPeter Grehan if ((pml4e & EPT_PG_SUPERPAGE) == 0) { 331366f6083SPeter Grehan pdp = (pdp_entry_t *)PHYS_TO_DMAP(pml4e & EPT_ADDR_MASK); 332366f6083SPeter Grehan for (i = 0; i < NPDPEPG; i++) 333366f6083SPeter Grehan ept_free_pdp_entry(pdp[i]); 334366f6083SPeter Grehan free(pdp, M_VMX); /* free the page directory ptr page */ 335366f6083SPeter Grehan } 336366f6083SPeter Grehan } 337366f6083SPeter Grehan 338366f6083SPeter Grehan void 339366f6083SPeter Grehan ept_vmcleanup(struct vmx *vmx) 340366f6083SPeter Grehan { 341366f6083SPeter Grehan int i; 342366f6083SPeter Grehan 343366f6083SPeter Grehan for (i = 0; i < NPML4EPG; i++) 344366f6083SPeter Grehan ept_free_pml4_entry(vmx->pml4ept[i]); 345366f6083SPeter Grehan } 346366f6083SPeter Grehan 347366f6083SPeter Grehan int 348*bda273f2SNeel Natu ept_vmmmap_set(void *arg, vm_paddr_t gpa, vm_paddr_t hpa, size_t len, 349366f6083SPeter Grehan vm_memattr_t attr, int prot, boolean_t spok) 350366f6083SPeter Grehan { 351366f6083SPeter Grehan size_t n; 352366f6083SPeter Grehan struct vmx *vmx = arg; 353366f6083SPeter Grehan 354366f6083SPeter Grehan while (len > 0) { 355366f6083SPeter Grehan n = ept_create_mapping(vmx->pml4ept, gpa, hpa, len, attr, 356366f6083SPeter Grehan prot, spok); 357366f6083SPeter Grehan len -= n; 358366f6083SPeter Grehan gpa += n; 359366f6083SPeter Grehan hpa += n; 360366f6083SPeter Grehan } 361366f6083SPeter Grehan 362366f6083SPeter Grehan return (0); 363366f6083SPeter Grehan } 364366f6083SPeter Grehan 365*bda273f2SNeel Natu vm_paddr_t 366*bda273f2SNeel Natu ept_vmmmap_get(void *arg, vm_paddr_t gpa) 367*bda273f2SNeel Natu { 368*bda273f2SNeel Natu vm_paddr_t hpa; 369*bda273f2SNeel Natu struct vmx *vmx; 370*bda273f2SNeel Natu 371*bda273f2SNeel Natu vmx = arg; 372*bda273f2SNeel Natu hpa = ept_lookup_mapping(vmx->pml4ept, gpa); 373*bda273f2SNeel Natu return (hpa); 374*bda273f2SNeel Natu } 375*bda273f2SNeel Natu 376366f6083SPeter Grehan static void 377366f6083SPeter Grehan invept_single_context(void *arg) 378366f6083SPeter Grehan { 379366f6083SPeter Grehan struct invept_desc desc = *(struct invept_desc *)arg; 380366f6083SPeter Grehan 381366f6083SPeter Grehan invept(INVEPT_TYPE_SINGLE_CONTEXT, desc); 382366f6083SPeter Grehan } 383366f6083SPeter Grehan 384366f6083SPeter Grehan void 385366f6083SPeter Grehan ept_invalidate_mappings(u_long pml4ept) 386366f6083SPeter Grehan { 387366f6083SPeter Grehan struct invept_desc invept_desc = { 0 }; 388366f6083SPeter Grehan 389366f6083SPeter Grehan invept_desc.eptp = EPTP(pml4ept); 390366f6083SPeter Grehan 391366f6083SPeter Grehan smp_rendezvous(NULL, invept_single_context, NULL, &invept_desc); 392366f6083SPeter Grehan } 393