root/tools/testing/selftests/kvm/lib/x86_64/vmx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vcpu_enable_evmcs
  2. vcpu_alloc_vmx
  3. prepare_for_vmx_operation
  4. load_vmcs
  5. init_vmcs_control_fields
  6. init_vmcs_host_state
  7. init_vmcs_guest_state
  8. prepare_vmcs
  9. nested_vmx_check_supported
  10. nested_pg_map
  11. nested_map
  12. nested_map_memslot
  13. prepare_eptp

   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 
  18 bool enable_evmcs;
  19 
  20 struct hv_enlightened_vmcs *current_evmcs;
  21 struct hv_vp_assist_page *current_vp_assist;
  22 
  23 struct 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 
  38 struct 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 };
  46 int 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  */
  77 struct vmx_pages *
  78 vcpu_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 
 133 bool 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 = FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
 164         required |= FEATURE_CONTROL_LOCKED;
 165         feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL);
 166         if ((feature_control & required) != required)
 167                 wrmsr(MSR_IA32_FEATURE_CONTROL, 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 
 177 bool 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 = vmcs_revision();
 198         }
 199 
 200         return true;
 201 }
 202 
 203 /*
 204  * Initialize the control fields to the most basic settings possible.
 205  */
 206 static 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  */
 266 static 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_base() + get_tr())));
 295         vmwrite(HOST_GDTR_BASE, get_gdt_base());
 296         vmwrite(HOST_IDTR_BASE, get_idt_base());
 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  */
 306 static 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 
 375 void 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 
 382 void nested_vmx_check_supported(void)
 383 {
 384         struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1);
 385 
 386         if (!(entry->ecx & CPUID_VMX)) {
 387                 fprintf(stderr, "nested VMX not enabled, skipping test\n");
 388                 exit(KSFT_SKIP);
 389         }
 390 }
 391 
 392 void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
 393                    uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot)
 394 {
 395         uint16_t index[4];
 396         struct eptPageTableEntry *pml4e;
 397 
 398         TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use "
 399                     "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
 400 
 401         TEST_ASSERT((nested_paddr % vm->page_size) == 0,
 402                     "Nested physical address not on page boundary,\n"
 403                     "  nested_paddr: 0x%lx vm->page_size: 0x%x",
 404                     nested_paddr, vm->page_size);
 405         TEST_ASSERT((nested_paddr >> vm->page_shift) <= vm->max_gfn,
 406                     "Physical address beyond beyond maximum supported,\n"
 407                     "  nested_paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
 408                     paddr, vm->max_gfn, vm->page_size);
 409         TEST_ASSERT((paddr % vm->page_size) == 0,
 410                     "Physical address not on page boundary,\n"
 411                     "  paddr: 0x%lx vm->page_size: 0x%x",
 412                     paddr, vm->page_size);
 413         TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn,
 414                     "Physical address beyond beyond maximum supported,\n"
 415                     "  paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
 416                     paddr, vm->max_gfn, vm->page_size);
 417 
 418         index[0] = (nested_paddr >> 12) & 0x1ffu;
 419         index[1] = (nested_paddr >> 21) & 0x1ffu;
 420         index[2] = (nested_paddr >> 30) & 0x1ffu;
 421         index[3] = (nested_paddr >> 39) & 0x1ffu;
 422 
 423         /* Allocate page directory pointer table if not present. */
 424         pml4e = vmx->eptp_hva;
 425         if (!pml4e[index[3]].readable) {
 426                 pml4e[index[3]].address = vm_phy_page_alloc(vm,
 427                           KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
 428                         >> vm->page_shift;
 429                 pml4e[index[3]].writable = true;
 430                 pml4e[index[3]].readable = true;
 431                 pml4e[index[3]].executable = true;
 432         }
 433 
 434         /* Allocate page directory table if not present. */
 435         struct eptPageTableEntry *pdpe;
 436         pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size);
 437         if (!pdpe[index[2]].readable) {
 438                 pdpe[index[2]].address = vm_phy_page_alloc(vm,
 439                           KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
 440                         >> vm->page_shift;
 441                 pdpe[index[2]].writable = true;
 442                 pdpe[index[2]].readable = true;
 443                 pdpe[index[2]].executable = true;
 444         }
 445 
 446         /* Allocate page table if not present. */
 447         struct eptPageTableEntry *pde;
 448         pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size);
 449         if (!pde[index[1]].readable) {
 450                 pde[index[1]].address = vm_phy_page_alloc(vm,
 451                           KVM_EPT_PAGE_TABLE_MIN_PADDR, eptp_memslot)
 452                         >> vm->page_shift;
 453                 pde[index[1]].writable = true;
 454                 pde[index[1]].readable = true;
 455                 pde[index[1]].executable = true;
 456         }
 457 
 458         /* Fill in page table entry. */
 459         struct eptPageTableEntry *pte;
 460         pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size);
 461         pte[index[0]].address = paddr >> vm->page_shift;
 462         pte[index[0]].writable = true;
 463         pte[index[0]].readable = true;
 464         pte[index[0]].executable = true;
 465 
 466         /*
 467          * For now mark these as accessed and dirty because the only
 468          * testcase we have needs that.  Can be reconsidered later.
 469          */
 470         pte[index[0]].accessed = true;
 471         pte[index[0]].dirty = true;
 472 }
 473 
 474 /*
 475  * Map a range of EPT guest physical addresses to the VM's physical address
 476  *
 477  * Input Args:
 478  *   vm - Virtual Machine
 479  *   nested_paddr - Nested guest physical address to map
 480  *   paddr - VM Physical Address
 481  *   size - The size of the range to map
 482  *   eptp_memslot - Memory region slot for new virtual translation tables
 483  *
 484  * Output Args: None
 485  *
 486  * Return: None
 487  *
 488  * Within the VM given by vm, creates a nested guest translation for the
 489  * page range starting at nested_paddr to the page range starting at paddr.
 490  */
 491 void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm,
 492                 uint64_t nested_paddr, uint64_t paddr, uint64_t size,
 493                 uint32_t eptp_memslot)
 494 {
 495         size_t page_size = vm->page_size;
 496         size_t npages = size / page_size;
 497 
 498         TEST_ASSERT(nested_paddr + size > nested_paddr, "Vaddr overflow");
 499         TEST_ASSERT(paddr + size > paddr, "Paddr overflow");
 500 
 501         while (npages--) {
 502                 nested_pg_map(vmx, vm, nested_paddr, paddr, eptp_memslot);
 503                 nested_paddr += page_size;
 504                 paddr += page_size;
 505         }
 506 }
 507 
 508 /* Prepare an identity extended page table that maps all the
 509  * physical pages in VM.
 510  */
 511 void nested_map_memslot(struct vmx_pages *vmx, struct kvm_vm *vm,
 512                         uint32_t memslot, uint32_t eptp_memslot)
 513 {
 514         sparsebit_idx_t i, last;
 515         struct userspace_mem_region *region =
 516                 memslot2region(vm, memslot);
 517 
 518         i = (region->region.guest_phys_addr >> vm->page_shift) - 1;
 519         last = i + (region->region.memory_size >> vm->page_shift);
 520         for (;;) {
 521                 i = sparsebit_next_clear(region->unused_phy_pages, i);
 522                 if (i > last)
 523                         break;
 524 
 525                 nested_map(vmx, vm,
 526                            (uint64_t)i << vm->page_shift,
 527                            (uint64_t)i << vm->page_shift,
 528                            1 << vm->page_shift,
 529                            eptp_memslot);
 530         }
 531 }
 532 
 533 void prepare_eptp(struct vmx_pages *vmx, struct kvm_vm *vm,
 534                   uint32_t eptp_memslot)
 535 {
 536         vmx->eptp = (void *)vm_vaddr_alloc(vm, getpagesize(), 0x10000, 0, 0);
 537         vmx->eptp_hva = addr_gva2hva(vm, (uintptr_t)vmx->eptp);
 538         vmx->eptp_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->eptp);
 539 }

/* [<][>][^][v][top][bottom][index][help] */