linux/tools/testing/selftests/kvm/lib/x86_64/vmx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * tools/testing/selftests/kvm/lib/x86_64/vmx.c
   4 *
   5 * Copyright (C) 2018, Google LLC.
   6 */
   7
   8#include "test_util.h"
   9#include "kvm_util.h"
  10#include "../kvm_util_internal.h"
  11#include "processor.h"
  12#include "vmx.h"
  13
  14#define PAGE_SHIFT_4K  12
  15
  16#define KVM_EPT_PAGE_TABLE_MIN_PADDR 0x1c0000
  17
  18bool enable_evmcs;
  19
  20struct hv_enlightened_vmcs *current_evmcs;
  21struct hv_vp_assist_page *current_vp_assist;
  22
  23struct eptPageTableEntry {
  24        uint64_t readable:1;
  25        uint64_t writable:1;
  26        uint64_t executable:1;
  27        uint64_t memory_type:3;
  28        uint64_t ignore_pat:1;
  29        uint64_t page_size:1;
  30        uint64_t accessed:1;
  31        uint64_t dirty:1;
  32        uint64_t ignored_11_10:2;
  33        uint64_t address:40;
  34        uint64_t ignored_62_52:11;
  35        uint64_t suppress_ve:1;
  36};
  37
  38struct eptPageTablePointer {
  39        uint64_t memory_type:3;
  40        uint64_t page_walk_length:3;
  41        uint64_t ad_enabled:1;
  42        uint64_t reserved_11_07:5;
  43        uint64_t address:40;
  44        uint64_t reserved_63_52:12;
  45};
  46int vcpu_enable_evmcs(struct kvm_vm *vm, int vcpu_id)
  47{
  48        uint16_t evmcs_ver;
  49
  50        struct kvm_enable_cap enable_evmcs_cap = {
  51                .cap = KVM_CAP_HYPERV_ENLIGHTENED_VMCS,
  52                 .args[0] = (unsigned long)&evmcs_ver
  53        };
  54
  55        vcpu_ioctl(vm, vcpu_id, KVM_ENABLE_CAP, &enable_evmcs_cap);
  56
  57        /* KVM should return supported EVMCS version range */
  58        TEST_ASSERT(((evmcs_ver >> 8) >= (evmcs_ver & 0xff)) &&
  59                    (evmcs_ver & 0xff) > 0,
  60                    "Incorrect EVMCS version range: %x:%x\n",
  61                    evmcs_ver & 0xff, evmcs_ver >> 8);
  62
  63        return evmcs_ver;
  64}
  65
  66/* Allocate memory regions for nested VMX tests.
  67 *
  68 * Input Args:
  69 *   vm - The VM to allocate guest-virtual addresses in.
  70 *
  71 * Output Args:
  72 *   p_vmx_gva - The guest virtual address for the struct vmx_pages.
  73 *
  74 * Return:
  75 *   Pointer to structure with the addresses of the VMX areas.
  76 */
  77struct vmx_pages *
  78vcpu_alloc_vmx(struct kvm_vm *vm, vm_vaddr_t *p_vmx_gva)
  79{
  80        vm_vaddr_t vmx_gva = vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
  81        struct vmx_pages *vmx = addr_gva2hva(vm, vmx_gva);
  82
  83        /* Setup of a region of guest memory for the vmxon region. */
  84        vmx->vmxon = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
  85        vmx->vmxon_hva = addr_gva2hva(vm, (uintptr_t)vmx->vmxon);
  86        vmx->vmxon_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->vmxon);
  87
  88        /* Setup of a region of guest memory for a vmcs. */
  89        vmx->vmcs = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
  90        vmx->vmcs_hva = addr_gva2hva(vm, (uintptr_t)vmx->vmcs);
  91        vmx->vmcs_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->vmcs);
  92
  93        /* Setup of a region of guest memory for the MSR bitmap. */
  94        vmx->msr = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
  95        vmx->msr_hva = addr_gva2hva(vm, (uintptr_t)vmx->msr);
  96        vmx->msr_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->msr);
  97        memset(vmx->msr_hva, 0, getpagesize());
  98
  99        /* Setup of a region of guest memory for the shadow VMCS. */
 100        vmx->shadow_vmcs = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
 101        vmx->shadow_vmcs_hva = addr_gva2hva(vm, (uintptr_t)vmx->shadow_vmcs);
 102        vmx->shadow_vmcs_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->shadow_vmcs);
 103
 104        /* Setup of a region of guest memory for the VMREAD and VMWRITE bitmaps. */
 105        vmx->vmread = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
 106        vmx->vmread_hva = addr_gva2hva(vm, (uintptr_t)vmx->vmread);
 107        vmx->vmread_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->vmread);
 108        memset(vmx->vmread_hva, 0, getpagesize());
 109
 110        vmx->vmwrite = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
 111        vmx->vmwrite_hva = addr_gva2hva(vm, (uintptr_t)vmx->vmwrite);
 112        vmx->vmwrite_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->vmwrite);
 113        memset(vmx->vmwrite_hva, 0, getpagesize());
 114
 115        /* Setup of a region of guest memory for the VP Assist page. */
 116        vmx->vp_assist = (void *)vm_vaddr_alloc(vm, getpagesize(),
 117                                                0x10000, 0, 0);
 118        vmx->vp_assist_hva = addr_gva2hva(vm, (uintptr_t)vmx->vp_assist);
 119        vmx->vp_assist_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->vp_assist);
 120
 121        /* Setup of a region of guest memory for the enlightened VMCS. */
 122        vmx->enlightened_vmcs = (void *)vm_vaddr_alloc(vm, getpagesize(),
 123                                                       0x10000, 0, 0);
 124        vmx->enlightened_vmcs_hva =
 125                addr_gva2hva(vm, (uintptr_t)vmx->enlightened_vmcs);
 126        vmx->enlightened_vmcs_gpa =
 127                addr_gva2gpa(vm, (uintptr_t)vmx->enlightened_vmcs);
 128
 129        *p_vmx_gva = vmx_gva;
 130        return vmx;
 131}
 132
 133bool prepare_for_vmx_operation(struct vmx_pages *vmx)
 134{
 135        uint64_t feature_control;
 136        uint64_t required;
 137        unsigned long cr0;
 138        unsigned long cr4;
 139
 140        /*
 141         * Ensure bits in CR0 and CR4 are valid in VMX operation:
 142         * - Bit X is 1 in _FIXED0: bit X is fixed to 1 in CRx.
 143         * - Bit X is 0 in _FIXED1: bit X is fixed to 0 in CRx.
 144         */
 145        __asm__ __volatile__("mov %%cr0, %0" : "=r"(cr0) : : "memory");
 146        cr0 &= rdmsr(MSR_IA32_VMX_CR0_FIXED1);
 147        cr0 |= rdmsr(MSR_IA32_VMX_CR0_FIXED0);
 148        __asm__ __volatile__("mov %0, %%cr0" : : "r"(cr0) : "memory");
 149
 150        __asm__ __volatile__("mov %%cr4, %0" : "=r"(cr4) : : "memory");
 151        cr4 &= rdmsr(MSR_IA32_VMX_CR4_FIXED1);
 152        cr4 |= rdmsr(MSR_IA32_VMX_CR4_FIXED0);
 153        /* Enable VMX operation */
 154        cr4 |= X86_CR4_VMXE;
 155        __asm__ __volatile__("mov %0, %%cr4" : : "r"(cr4) : "memory");
 156
 157        /*
 158         * Configure IA32_FEATURE_CONTROL MSR to allow VMXON:
 159         *  Bit 0: Lock bit. If clear, VMXON causes a #GP.
 160         *  Bit 2: Enables VMXON outside of SMX operation. If clear, VMXON
 161         *    outside of SMX causes a #GP.
 162         */
 163        required = FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
 164        required |= FEAT_CTL_LOCKED;
 165        feature_control = rdmsr(MSR_IA32_FEAT_CTL);
 166        if ((feature_control & required) != required)
 167                wrmsr(MSR_IA32_FEAT_CTL, feature_control | required);
 168
 169        /* Enter VMX root operation. */
 170        *(uint32_t *)(vmx->vmxon) = vmcs_revision();
 171        if (vmxon(vmx->vmxon_gpa))
 172                return false;
 173
 174        return true;
 175}
 176
 177bool load_vmcs(struct vmx_pages *vmx)
 178{
 179        if (!enable_evmcs) {
 180                /* Load a VMCS. */
 181                *(uint32_t *)(vmx->vmcs) = vmcs_revision();
 182                if (vmclear(vmx->vmcs_gpa))
 183                        return false;
 184
 185                if (vmptrld(vmx->vmcs_gpa))
 186                        return false;
 187
 188                /* Setup shadow VMCS, do not load it yet. */
 189                *(uint32_t *)(vmx->shadow_vmcs) =
 190                        vmcs_revision() | 0x80000000ul;
 191                if (vmclear(vmx->shadow_vmcs_gpa))
 192                        return false;
 193        } else {
 194                if (evmcs_vmptrld(vmx->enlightened_vmcs_gpa,
 195                                  vmx->enlightened_vmcs))
 196                        return false;
 197                current_evmcs->revision_id = EVMCS_VERSION;
 198        }
 199
 200        return true;
 201}
 202
 203/*
 204 * Initialize the control fields to the most basic settings possible.
 205 */
 206static inline void init_vmcs_control_fields(struct vmx_pages *vmx)
 207{
 208        uint32_t sec_exec_ctl = 0;
 209
 210        vmwrite(VIRTUAL_PROCESSOR_ID, 0);
 211        vmwrite(POSTED_INTR_NV, 0);
 212
 213        vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PINBASED_CTLS));
 214
 215        if (vmx->eptp_gpa) {
 216                uint64_t ept_paddr;
 217                struct eptPageTablePointer eptp = {
 218                        .memory_type = VMX_BASIC_MEM_TYPE_WB,
 219                        .page_walk_length = 3, /* + 1 */
 220                        .ad_enabled = !!(rdmsr(MSR_IA32_VMX_EPT_VPID_CAP) & VMX_EPT_VPID_CAP_AD_BITS),
 221                        .address = vmx->eptp_gpa >> PAGE_SHIFT_4K,
 222                };
 223
 224                memcpy(&ept_paddr, &eptp, sizeof(ept_paddr));
 225                vmwrite(EPT_POINTER, ept_paddr);
 226                sec_exec_ctl |= SECONDARY_EXEC_ENABLE_EPT;
 227        }
 228
 229        if (!vmwrite(SECONDARY_VM_EXEC_CONTROL, sec_exec_ctl))
 230                vmwrite(CPU_BASED_VM_EXEC_CONTROL,
 231                        rdmsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS) | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS);
 232        else {
 233                vmwrite(CPU_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_TRUE_PROCBASED_CTLS));
 234                GUEST_ASSERT(!sec_exec_ctl);
 235        }
 236
 237        vmwrite(EXCEPTION_BITMAP, 0);
 238        vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
 239        vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, -1); /* Never match */
 240        vmwrite(CR3_TARGET_COUNT, 0);
 241        vmwrite(VM_EXIT_CONTROLS, rdmsr(MSR_IA32_VMX_EXIT_CTLS) |
 242                VM_EXIT_HOST_ADDR_SPACE_SIZE);    /* 64-bit host */
 243        vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
 244        vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
 245        vmwrite(VM_ENTRY_CONTROLS, rdmsr(MSR_IA32_VMX_ENTRY_CTLS) |
 246                VM_ENTRY_IA32E_MODE);             /* 64-bit guest */
 247        vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
 248        vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
 249        vmwrite(TPR_THRESHOLD, 0);
 250
 251        vmwrite(CR0_GUEST_HOST_MASK, 0);
 252        vmwrite(CR4_GUEST_HOST_MASK, 0);
 253        vmwrite(CR0_READ_SHADOW, get_cr0());
 254        vmwrite(CR4_READ_SHADOW, get_cr4());
 255
 256        vmwrite(MSR_BITMAP, vmx->msr_gpa);
 257        vmwrite(VMREAD_BITMAP, vmx->vmread_gpa);
 258        vmwrite(VMWRITE_BITMAP, vmx->vmwrite_gpa);
 259}
 260
 261/*
 262 * Initialize the host state fields based on the current host state, with
 263 * the exception of HOST_RSP and HOST_RIP, which should be set by vmlaunch
 264 * or vmresume.
 265 */
 266static inline void init_vmcs_host_state(void)
 267{
 268        uint32_t exit_controls = vmreadz(VM_EXIT_CONTROLS);
 269
 270        vmwrite(HOST_ES_SELECTOR, get_es());
 271        vmwrite(HOST_CS_SELECTOR, get_cs());
 272        vmwrite(HOST_SS_SELECTOR, get_ss());
 273        vmwrite(HOST_DS_SELECTOR, get_ds());
 274        vmwrite(HOST_FS_SELECTOR, get_fs());
 275        vmwrite(HOST_GS_SELECTOR, get_gs());
 276        vmwrite(HOST_TR_SELECTOR, get_tr());
 277
 278        if (exit_controls & VM_EXIT_LOAD_IA32_PAT)
 279                vmwrite(HOST_IA32_PAT, rdmsr(MSR_IA32_CR_PAT));
 280        if (exit_controls & VM_EXIT_LOAD_IA32_EFER)
 281                vmwrite(HOST_IA32_EFER, rdmsr(MSR_EFER));
 282        if (exit_controls & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
 283                vmwrite(HOST_IA32_PERF_GLOBAL_CTRL,
 284                        rdmsr(MSR_CORE_PERF_GLOBAL_CTRL));
 285
 286        vmwrite(HOST_IA32_SYSENTER_CS, rdmsr(MSR_IA32_SYSENTER_CS));
 287
 288        vmwrite(HOST_CR0, get_cr0());
 289        vmwrite(HOST_CR3, get_cr3());
 290        vmwrite(HOST_CR4, get_cr4());
 291        vmwrite(HOST_FS_BASE, rdmsr(MSR_FS_BASE));
 292        vmwrite(HOST_GS_BASE, rdmsr(MSR_GS_BASE));
 293        vmwrite(HOST_TR_BASE,
 294                get_desc64_base((struct desc64 *)(get_gdt().address + get_tr())));
 295        vmwrite(HOST_GDTR_BASE, get_gdt().address);
 296        vmwrite(HOST_IDTR_BASE, get_idt().address);
 297        vmwrite(HOST_IA32_SYSENTER_ESP, rdmsr(MSR_IA32_SYSENTER_ESP));
 298        vmwrite(HOST_IA32_SYSENTER_EIP, rdmsr(MSR_IA32_SYSENTER_EIP));
 299}
 300
 301/*
 302 * Initialize the guest state fields essentially as a clone of
 303 * the host state fields. Some host state fields have fixed
 304 * values, and we set the corresponding guest state fields accordingly.
 305 */
 306static inline void init_vmcs_guest_state(void *rip, void *rsp)
 307{
 308        vmwrite(GUEST_ES_SELECTOR, vmreadz(HOST_ES_SELECTOR));
 309        vmwrite(GUEST_CS_SELECTOR, vmreadz(HOST_CS_SELECTOR));
 310        vmwrite(GUEST_SS_SELECTOR, vmreadz(HOST_SS_SELECTOR));
 311        vmwrite(GUEST_DS_SELECTOR, vmreadz(HOST_DS_SELECTOR));
 312        vmwrite(GUEST_FS_SELECTOR, vmreadz(HOST_FS_SELECTOR));
 313        vmwrite(GUEST_GS_SELECTOR, vmreadz(HOST_GS_SELECTOR));
 314        vmwrite(GUEST_LDTR_SELECTOR, 0);
 315        vmwrite(GUEST_TR_SELECTOR, vmreadz(HOST_TR_SELECTOR));
 316        vmwrite(GUEST_INTR_STATUS, 0);
 317        vmwrite(GUEST_PML_INDEX, 0);
 318
 319        vmwrite(VMCS_LINK_POINTER, -1ll);
 320        vmwrite(GUEST_IA32_DEBUGCTL, 0);
 321        vmwrite(GUEST_IA32_PAT, vmreadz(HOST_IA32_PAT));
 322        vmwrite(GUEST_IA32_EFER, vmreadz(HOST_IA32_EFER));
 323        vmwrite(GUEST_IA32_PERF_GLOBAL_CTRL,
 324                vmreadz(HOST_IA32_PERF_GLOBAL_CTRL));
 325
 326        vmwrite(GUEST_ES_LIMIT, -1);
 327        vmwrite(GUEST_CS_LIMIT, -1);
 328        vmwrite(GUEST_SS_LIMIT, -1);
 329        vmwrite(GUEST_DS_LIMIT, -1);
 330        vmwrite(GUEST_FS_LIMIT, -1);
 331        vmwrite(GUEST_GS_LIMIT, -1);
 332        vmwrite(GUEST_LDTR_LIMIT, -1);
 333        vmwrite(GUEST_TR_LIMIT, 0x67);
 334        vmwrite(GUEST_GDTR_LIMIT, 0xffff);
 335        vmwrite(GUEST_IDTR_LIMIT, 0xffff);
 336        vmwrite(GUEST_ES_AR_BYTES,
 337                vmreadz(GUEST_ES_SELECTOR) == 0 ? 0x10000 : 0xc093);
 338        vmwrite(GUEST_CS_AR_BYTES, 0xa09b);
 339        vmwrite(GUEST_SS_AR_BYTES, 0xc093);
 340        vmwrite(GUEST_DS_AR_BYTES,
 341                vmreadz(GUEST_DS_SELECTOR) == 0 ? 0x10000 : 0xc093);
 342        vmwrite(GUEST_FS_AR_BYTES,
 343                vmreadz(GUEST_FS_SELECTOR) == 0 ? 0x10000 : 0xc093);
 344        vmwrite(GUEST_GS_AR_BYTES,
 345                vmreadz(GUEST_GS_SELECTOR) == 0 ? 0x10000 : 0xc093);
 346        vmwrite(GUEST_LDTR_AR_BYTES, 0x10000);
 347        vmwrite(GUEST_TR_AR_BYTES, 0x8b);
 348        vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
 349        vmwrite(GUEST_ACTIVITY_STATE, 0);
 350        vmwrite(GUEST_SYSENTER_CS, vmreadz(HOST_IA32_SYSENTER_CS));
 351        vmwrite(VMX_PREEMPTION_TIMER_VALUE, 0);
 352
 353        vmwrite(GUEST_CR0, vmreadz(HOST_CR0));
 354        vmwrite(GUEST_CR3, vmreadz(HOST_CR3));
 355        vmwrite(GUEST_CR4, vmreadz(HOST_CR4));
 356        vmwrite(GUEST_ES_BASE, 0);
 357        vmwrite(GUEST_CS_BASE, 0);
 358        vmwrite(GUEST_SS_BASE, 0);
 359        vmwrite(GUEST_DS_BASE, 0);
 360        vmwrite(GUEST_FS_BASE, vmreadz(HOST_FS_BASE));
 361        vmwrite(GUEST_GS_BASE, vmreadz(HOST_GS_BASE));
 362        vmwrite(GUEST_LDTR_BASE, 0);
 363        vmwrite(GUEST_TR_BASE, vmreadz(HOST_TR_BASE));
 364        vmwrite(GUEST_GDTR_BASE, vmreadz(HOST_GDTR_BASE));
 365        vmwrite(GUEST_IDTR_BASE, vmreadz(HOST_IDTR_BASE));
 366        vmwrite(GUEST_DR7, 0x400);
 367        vmwrite(GUEST_RSP, (uint64_t)rsp);
 368        vmwrite(GUEST_RIP, (uint64_t)rip);
 369        vmwrite(GUEST_RFLAGS, 2);
 370        vmwrite(GUEST_PENDING_DBG_EXCEPTIONS, 0);
 371        vmwrite(GUEST_SYSENTER_ESP, vmreadz(HOST_IA32_SYSENTER_ESP));
 372        vmwrite(GUEST_SYSENTER_EIP, vmreadz(HOST_IA32_SYSENTER_EIP));
 373}
 374
 375void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp)
 376{
 377        init_vmcs_control_fields(vmx);
 378        init_vmcs_host_state();
 379        init_vmcs_guest_state(guest_rip, guest_rsp);
 380}
 381
 382bool nested_vmx_supported(void)
 383{
 384        struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1);
 385
 386        return entry->ecx & CPUID_VMX;
 387}
 388
 389void nested_vmx_check_supported(void)
 390{
 391        if (!nested_vmx_supported()) {
 392                print_skip("nested VMX not enabled");
 393                exit(KSFT_SKIP);
 394        }
 395}
 396
 397void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
 398                   uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot)
 399{
 400        uint16_t index[4];
 401        struct eptPageTableEntry *pml4e;
 402
 403        TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use "
 404                    "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
 405
 406        TEST_ASSERT((nested_paddr % vm->page_size) == 0,
 407                    "Nested physical address not on page boundary,\n"
 408                    "  nested_paddr: 0x%lx vm->page_size: 0x%x",
 409                    nested_paddr, vm->page_size);
 410        TEST_ASSERT((nested_paddr >> vm->page_shift) <= vm->max_gfn,
 411                    "Physical address beyond beyond maximum supported,\n"
 412                    "  nested_paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
 413                    paddr, vm->max_gfn, vm->page_size);
 414        TEST_ASSERT((paddr % vm->page_size) == 0,
 415                    "Physical address not on page boundary,\n"
 416                    "  paddr: 0x%lx vm->page_size: 0x%x",
 417                    paddr, vm->page_size);
 418        TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn,
 419                    "Physical address beyond beyond maximum supported,\n"
 420                    "  paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
 421                    paddr, vm->max_gfn, vm->page_size);
 422
 423        index[0] = (nested_paddr >> 12) & 0x1ffu;
 424        index[1] = (nested_paddr >> 21) & 0x1ffu;
 425        index[2] = (nested_paddr >> 30) & 0x1ffu;
 426        index[3] = (nested_paddr >> 39) & 0x1ffu;
 427
 428        /* Allocate page directory pointer table if not present. */
 429        pml4e = vmx->eptp_hva;
 430        if (!pml4e[index[3]].readable) {
 431                pml4e[index[3]].address = vm_phy_page_alloc(vm,
 432                          KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
 433                        >> vm->page_shift;
 434                pml4e[index[3]].writable = true;
 435                pml4e[index[3]].readable = true;
 436                pml4e[index[3]].executable = true;
 437        }
 438
 439        /* Allocate page directory table if not present. */
 440        struct eptPageTableEntry *pdpe;
 441        pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size);
 442        if (!pdpe[index[2]].readable) {
 443                pdpe[index[2]].address = vm_phy_page_alloc(vm,
 444                          KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
 445                        >> vm->page_shift;
 446                pdpe[index[2]].writable = true;
 447                pdpe[index[2]].readable = true;
 448                pdpe[index[2]].executable = true;
 449        }
 450
 451        /* Allocate page table if not present. */
 452        struct eptPageTableEntry *pde;
 453        pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size);
 454        if (!pde[index[1]].readable) {
 455                pde[index[1]].address = vm_phy_page_alloc(vm,
 456                          KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
 457                        >> vm->page_shift;
 458                pde[index[1]].writable = true;
 459                pde[index[1]].readable = true;
 460                pde[index[1]].executable = true;
 461        }
 462
 463        /* Fill in page table entry. */
 464        struct eptPageTableEntry *pte;
 465        pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size);
 466        pte[index[0]].address = paddr >> vm->page_shift;
 467        pte[index[0]].writable = true;
 468        pte[index[0]].readable = true;
 469        pte[index[0]].executable = true;
 470
 471        /*
 472         * For now mark these as accessed and dirty because the only
 473         * testcase we have needs that.  Can be reconsidered later.
 474         */
 475        pte[index[0]].accessed = true;
 476        pte[index[0]].dirty = true;
 477}
 478
 479/*
 480 * Map a range of EPT guest physical addresses to the VM's physical address
 481 *
 482 * Input Args:
 483 *   vm - Virtual Machine
 484 *   nested_paddr - Nested guest physical address to map
 485 *   paddr - VM Physical Address
 486 *   size - The size of the range to map
 487 *   eptp_memslot - Memory region slot for new virtual translation tables
 488 *
 489 * Output Args: None
 490 *
 491 * Return: None
 492 *
 493 * Within the VM given by vm, creates a nested guest translation for the
 494 * page range starting at nested_paddr to the page range starting at paddr.
 495 */
 496void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
 497                uint64_t nested_paddr, uint64_t paddr, uint64_t size,
 498                uint32_t eptp_memslot)
 499{
 500        size_t page_size = vm->page_size;
 501        size_t npages = size / page_size;
 502
 503        TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow");
 504        TEST_ASSERT(paddr + size > paddr, "Paddr overflow");
 505
 506        while (npages--) {
 507                nested_pg_map(vmx, vm, nested_paddr, paddr, eptp_memslot);
 508                nested_paddr += page_size;
 509                paddr += page_size;
 510        }
 511}
 512
 513/* Prepare an identity extended page table that maps all the
 514 * physical pages in VM.
 515 */
 516void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
 517                        uint32_t memslot, uint32_t eptp_memslot)
 518{
 519        sparsebit_idx_t i, last;
 520        struct userspace_mem_region *region =
 521                memslot2region(vm, memslot);
 522
 523        i = (region->region.guest_phys_addr >> vm->page_shift) - 1;
 524        last = i + (region->region.memory_size >> vm->page_shift);
 525        for (;;) {
 526                i = sparsebit_next_clear(region->unused_phy_pages, i);
 527                if (i > last)
 528                        break;
 529
 530                nested_map(vmx, vm,
 531                           (uint64_t)i << vm->page_shift,
 532                           (uint64_t)i << vm->page_shift,
 533                           1 << vm->page_shift,
 534                           eptp_memslot);
 535        }
 536}
 537
 538void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm,
 539                  uint32_t eptp_memslot)
 540{
 541        vmx->eptp = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
 542        vmx->eptp_hva = addr_gva2hva(vm, (uintptr_t)vmx->eptp);
 543        vmx->eptp_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->eptp);
 544}
 545
 546void prepare_virtualize_apic_accesses(struct vmx_pages *vmx, struct kvm_vm *vm,
 547                                      uint32_t eptp_memslot)
 548{
 549        vmx->apic_access = (void *)vm_vaddr_alloc(vm, getpagesize(),
 550                                                  0x10000, 0, 0);
 551        vmx->apic_access_hva = addr_gva2hva(vm, (uintptr_t)vmx->apic_access);
 552        vmx->apic_access_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->apic_access);
 553}
 554