lkml.org 
[lkml]   [2024]   [Feb]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 24/25] KVM: selftests: Add a new VM guest mode to run user level code
    Date
    Add a new VM guest mode VM_MODE_PXXV48_4K_USER to set the user bit of
    guest page table entries, thus allow user level code to run in guests.

    Suggested-by: Sean Christopherson <seanjc@google.com>
    Signed-off-by: Xin Li <xin3.li@intel.com>
    ---
    .../testing/selftests/kvm/include/kvm_util_base.h | 1 +
    tools/testing/selftests/kvm/lib/kvm_util.c | 5 ++++-
    .../testing/selftests/kvm/lib/x86_64/processor.c | 15 ++++++++++-----
    tools/testing/selftests/kvm/lib/x86_64/vmx.c | 4 ++--
    4 files changed, 17 insertions(+), 8 deletions(-)

    diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h
    index 9e5afc472c14..ea1a585ef6f4 100644
    --- a/tools/testing/selftests/kvm/include/kvm_util_base.h
    +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h
    @@ -187,6 +187,7 @@ enum vm_guest_mode {
    VM_MODE_P36V48_16K,
    VM_MODE_P36V48_64K,
    VM_MODE_P36V47_16K,
    + VM_MODE_PXXV48_4K_USER, /* For 48bits VA but ANY bits PA with USER bit set */
    NUM_VM_MODES,
    };

    diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c
    index e066d584c656..8b4761836b3e 100644
    --- a/tools/testing/selftests/kvm/lib/kvm_util.c
    +++ b/tools/testing/selftests/kvm/lib/kvm_util.c
    @@ -163,6 +163,7 @@ const char *vm_guest_mode_string(uint32_t i)
    [VM_MODE_P36V48_16K] = "PA-bits:36, VA-bits:48, 16K pages",
    [VM_MODE_P36V48_64K] = "PA-bits:36, VA-bits:48, 64K pages",
    [VM_MODE_P36V47_16K] = "PA-bits:36, VA-bits:47, 16K pages",
    + [VM_MODE_PXXV48_4K_USER] = "PA-bits:ANY, VA-bits:48, 4K user pages",
    };
    _Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
    "Missing new mode strings?");
    @@ -189,6 +190,7 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
    [VM_MODE_P36V48_16K] = { 36, 48, 0x4000, 14 },
    [VM_MODE_P36V48_64K] = { 36, 48, 0x10000, 16 },
    [VM_MODE_P36V47_16K] = { 36, 47, 0x4000, 14 },
    + [VM_MODE_PXXV48_4K_USER] = { 0, 0, 0x1000, 12 },
    };
    _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
    "Missing new mode params?");
    @@ -263,6 +265,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
    vm->pgtable_levels = 3;
    break;
    case VM_MODE_PXXV48_4K:
    + case VM_MODE_PXXV48_4K_USER:
    #ifdef __x86_64__
    kvm_get_cpu_address_width(&vm->pa_bits, &vm->va_bits);
    /*
    @@ -278,7 +281,7 @@ struct kvm_vm *____vm_create(struct vm_shape shape)
    vm->pgtable_levels = 4;
    vm->va_bits = 48;
    #else
    - TEST_FAIL("VM_MODE_PXXV48_4K not supported on non-x86 platforms");
    + TEST_FAIL("VM_MODE_PXXV48_4K(_USER) not supported on non-x86 platforms");
    #endif
    break;
    case VM_MODE_P47V64_4K:
    diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c
    index d8288374078e..a8e60641df53 100644
    --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c
    +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c
    @@ -124,8 +124,8 @@ bool kvm_is_tdp_enabled(void)

    void virt_arch_pgd_alloc(struct kvm_vm *vm)
    {
    - TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use "
    - "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
    + TEST_ASSERT((vm->mode == VM_MODE_PXXV48_4K) || (vm->mode == VM_MODE_PXXV48_4K_USER),
    + "Attempt to use unknown or unsupported guest mode, mode: 0x%x", vm->mode);

    /* If needed, create page map l4 table. */
    if (!vm->pgd_created) {
    @@ -159,6 +159,8 @@ static uint64_t *virt_create_upper_pte(struct kvm_vm *vm,

    if (!(*pte & PTE_PRESENT_MASK)) {
    *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK;
    + if (vm->mode == VM_MODE_PXXV48_4K_USER)
    + *pte |= PTE_USER_MASK;
    if (current_level == target_level)
    *pte |= PTE_LARGE_MASK | (paddr & PHYSICAL_PAGE_MASK);
    else
    @@ -185,7 +187,7 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
    uint64_t *pml4e, *pdpe, *pde;
    uint64_t *pte;

    - TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K,
    + TEST_ASSERT((vm->mode == VM_MODE_PXXV48_4K) || (vm->mode == VM_MODE_PXXV48_4K_USER),
    "Unknown or unsupported guest mode, mode: 0x%x", vm->mode);

    TEST_ASSERT((vaddr % pg_size) == 0,
    @@ -222,6 +224,8 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
    TEST_ASSERT(!(*pte & PTE_PRESENT_MASK),
    "PTE already present for 4k page at vaddr: 0x%lx\n", vaddr);
    *pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK);
    + if (vm->mode == VM_MODE_PXXV48_4K_USER)
    + *pte |= PTE_USER_MASK;
    }

    void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr)
    @@ -268,8 +272,8 @@ uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr,
    TEST_ASSERT(*level >= PG_LEVEL_NONE && *level < PG_LEVEL_NUM,
    "Invalid PG_LEVEL_* '%d'", *level);

    - TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use "
    - "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
    + TEST_ASSERT((vm->mode == VM_MODE_PXXV48_4K) || (vm->mode == VM_MODE_PXXV48_4K_USER),
    + "Attempt to use unknown or unsupported guest mode, mode: 0x%x", vm->mode);
    TEST_ASSERT(sparsebit_is_set(vm->vpages_valid,
    (vaddr >> vm->page_shift)),
    "Invalid virtual address, vaddr: 0x%lx",
    @@ -536,6 +540,7 @@ static void vcpu_setup(struct kvm_vm *vm, struct kvm_vcpu *vcpu)

    switch (vm->mode) {
    case VM_MODE_PXXV48_4K:
    + case VM_MODE_PXXV48_4K_USER:
    sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG;
    sregs.cr4 |= X86_CR4_PAE | X86_CR4_OSFXSR;
    sregs.efer |= (EFER_LME | EFER_LMA | EFER_NX);
    diff --git a/tools/testing/selftests/kvm/lib/x86_64/vmx.c b/tools/testing/selftests/kvm/lib/x86_64/vmx.c
    index 59d97531c9b1..65147de6f9c0 100644
    --- a/tools/testing/selftests/kvm/lib/x86_64/vmx.c
    +++ b/tools/testing/selftests/kvm/lib/x86_64/vmx.c
    @@ -403,8 +403,8 @@ void __nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm,
    struct eptPageTableEntry *pt = vmx->eptp_hva, *pte;
    uint16_t index;

    - TEST_ASSERT(vm->mode == VM_MODE_PXXV48_4K, "Attempt to use "
    - "unknown or unsupported guest mode, mode: 0x%x", vm->mode);
    + TEST_ASSERT((vm->mode == VM_MODE_PXXV48_4K) || (vm->mode == VM_MODE_PXXV48_4K_USER),
    + "Attempt to use unknown or unsupported guest mode, mode: 0x%x", vm->mode);

    TEST_ASSERT((nested_paddr >> 48) == 0,
    "Nested physical address 0x%lx requires 5-level paging",
    --
    2.43.0

    \
     
     \ /
      Last update: 2024-05-27 14:53    [W:4.811 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site