mirror of
https://github.com/raspberrypi/linux.git
synced 2026-01-03 00:03:44 +00:00
KVM: selftests: Create a vendor independent helper to allocate Hyper-V specific test pages
There's no need to pollute VMX and SVM code with Hyper-V specific stuff and allocate Hyper-V specific test pages for all test as only few really need them. Create a dedicated struct and an allocation helper. Reviewed-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20221101145426.251680-43-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
committed by
Paolo Bonzini
parent
cd8f11bd6b
commit
2dc458b862
@@ -256,9 +256,9 @@ static inline int evmcs_vmptrld(uint64_t vmcs_pa, void *vmcs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool load_evmcs(uint64_t enlightened_vmcs_gpa, void *enlightened_vmcs)
|
||||
static inline bool load_evmcs(struct hyperv_test_pages *hv)
|
||||
{
|
||||
if (evmcs_vmptrld(enlightened_vmcs_gpa, enlightened_vmcs))
|
||||
if (evmcs_vmptrld(hv->enlightened_vmcs_gpa, hv->enlightened_vmcs))
|
||||
return false;
|
||||
|
||||
current_evmcs->revision_id = EVMCS_VERSION;
|
||||
|
||||
@@ -268,4 +268,19 @@ extern struct hv_vp_assist_page *current_vp_assist;
|
||||
|
||||
int enable_vp_assist(uint64_t vp_assist_pa, void *vp_assist);
|
||||
|
||||
struct hyperv_test_pages {
|
||||
/* VP assist page */
|
||||
void *vp_assist_hva;
|
||||
uint64_t vp_assist_gpa;
|
||||
void *vp_assist;
|
||||
|
||||
/* Enlightened VMCS */
|
||||
void *enlightened_vmcs_hva;
|
||||
uint64_t enlightened_vmcs_gpa;
|
||||
void *enlightened_vmcs;
|
||||
};
|
||||
|
||||
struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm,
|
||||
vm_vaddr_t *p_hv_pages_gva);
|
||||
|
||||
#endif /* !SELFTEST_KVM_HYPERV_H */
|
||||
|
||||
@@ -517,14 +517,6 @@ struct vmx_pages {
|
||||
uint64_t vmwrite_gpa;
|
||||
void *vmwrite;
|
||||
|
||||
void *vp_assist_hva;
|
||||
uint64_t vp_assist_gpa;
|
||||
void *vp_assist;
|
||||
|
||||
void *enlightened_vmcs_hva;
|
||||
uint64_t enlightened_vmcs_gpa;
|
||||
void *enlightened_vmcs;
|
||||
|
||||
void *eptp_hva;
|
||||
uint64_t eptp_gpa;
|
||||
void *eptp;
|
||||
|
||||
@@ -8,6 +8,26 @@
|
||||
#include "processor.h"
|
||||
#include "hyperv.h"
|
||||
|
||||
struct hyperv_test_pages *vcpu_alloc_hyperv_test_pages(struct kvm_vm *vm,
|
||||
vm_vaddr_t *p_hv_pages_gva)
|
||||
{
|
||||
vm_vaddr_t hv_pages_gva = vm_vaddr_alloc_page(vm);
|
||||
struct hyperv_test_pages *hv = addr_gva2hva(vm, hv_pages_gva);
|
||||
|
||||
/* Setup of a region of guest memory for the VP Assist page. */
|
||||
hv->vp_assist = (void *)vm_vaddr_alloc_page(vm);
|
||||
hv->vp_assist_hva = addr_gva2hva(vm, (uintptr_t)hv->vp_assist);
|
||||
hv->vp_assist_gpa = addr_gva2gpa(vm, (uintptr_t)hv->vp_assist);
|
||||
|
||||
/* Setup of a region of guest memory for the enlightened VMCS. */
|
||||
hv->enlightened_vmcs = (void *)vm_vaddr_alloc_page(vm);
|
||||
hv->enlightened_vmcs_hva = addr_gva2hva(vm, (uintptr_t)hv->enlightened_vmcs);
|
||||
hv->enlightened_vmcs_gpa = addr_gva2gpa(vm, (uintptr_t)hv->enlightened_vmcs);
|
||||
|
||||
*p_hv_pages_gva = hv_pages_gva;
|
||||
return hv;
|
||||
}
|
||||
|
||||
int enable_vp_assist(uint64_t vp_assist_pa, void *vp_assist)
|
||||
{
|
||||
uint64_t val = (vp_assist_pa & HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_MASK) |
|
||||
|
||||
@@ -109,18 +109,6 @@ vcpu_alloc_vmx(struct kvm_vm *vm, vm_vaddr_t *p_vmx_gva)
|
||||
vmx->vmwrite_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->vmwrite);
|
||||
memset(vmx->vmwrite_hva, 0, getpagesize());
|
||||
|
||||
/* Setup of a region of guest memory for the VP Assist page. */
|
||||
vmx->vp_assist = (void *)vm_vaddr_alloc_page(vm);
|
||||
vmx->vp_assist_hva = addr_gva2hva(vm, (uintptr_t)vmx->vp_assist);
|
||||
vmx->vp_assist_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->vp_assist);
|
||||
|
||||
/* Setup of a region of guest memory for the enlightened VMCS. */
|
||||
vmx->enlightened_vmcs = (void *)vm_vaddr_alloc_page(vm);
|
||||
vmx->enlightened_vmcs_hva =
|
||||
addr_gva2hva(vm, (uintptr_t)vmx->enlightened_vmcs);
|
||||
vmx->enlightened_vmcs_gpa =
|
||||
addr_gva2gpa(vm, (uintptr_t)vmx->enlightened_vmcs);
|
||||
|
||||
*p_vmx_gva = vmx_gva;
|
||||
return vmx;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ void l2_guest_code(void)
|
||||
vmcall();
|
||||
}
|
||||
|
||||
void guest_code(struct vmx_pages *vmx_pages)
|
||||
void guest_code(struct vmx_pages *vmx_pages, struct hyperv_test_pages *hv_pages)
|
||||
{
|
||||
#define L2_GUEST_STACK_SIZE 64
|
||||
unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
|
||||
@@ -78,23 +78,22 @@ void guest_code(struct vmx_pages *vmx_pages)
|
||||
GUEST_SYNC(1);
|
||||
GUEST_SYNC(2);
|
||||
|
||||
enable_vp_assist(vmx_pages->vp_assist_gpa, vmx_pages->vp_assist);
|
||||
enable_vp_assist(hv_pages->vp_assist_gpa, hv_pages->vp_assist);
|
||||
evmcs_enable();
|
||||
|
||||
GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
|
||||
GUEST_SYNC(3);
|
||||
GUEST_ASSERT(load_evmcs(vmx_pages->enlightened_vmcs_gpa,
|
||||
vmx_pages->enlightened_vmcs));
|
||||
GUEST_ASSERT(vmptrstz() == vmx_pages->enlightened_vmcs_gpa);
|
||||
GUEST_ASSERT(load_evmcs(hv_pages));
|
||||
GUEST_ASSERT(vmptrstz() == hv_pages->enlightened_vmcs_gpa);
|
||||
|
||||
GUEST_SYNC(4);
|
||||
GUEST_ASSERT(vmptrstz() == vmx_pages->enlightened_vmcs_gpa);
|
||||
GUEST_ASSERT(vmptrstz() == hv_pages->enlightened_vmcs_gpa);
|
||||
|
||||
prepare_vmcs(vmx_pages, l2_guest_code,
|
||||
&l2_guest_stack[L2_GUEST_STACK_SIZE]);
|
||||
|
||||
GUEST_SYNC(5);
|
||||
GUEST_ASSERT(vmptrstz() == vmx_pages->enlightened_vmcs_gpa);
|
||||
GUEST_ASSERT(vmptrstz() == hv_pages->enlightened_vmcs_gpa);
|
||||
current_evmcs->revision_id = -1u;
|
||||
GUEST_ASSERT(vmlaunch());
|
||||
current_evmcs->revision_id = EVMCS_VERSION;
|
||||
@@ -104,7 +103,7 @@ void guest_code(struct vmx_pages *vmx_pages)
|
||||
PIN_BASED_NMI_EXITING);
|
||||
|
||||
GUEST_ASSERT(!vmlaunch());
|
||||
GUEST_ASSERT(vmptrstz() == vmx_pages->enlightened_vmcs_gpa);
|
||||
GUEST_ASSERT(vmptrstz() == hv_pages->enlightened_vmcs_gpa);
|
||||
|
||||
/*
|
||||
* NMI forces L2->L1 exit, resuming L2 and hope that EVMCS is
|
||||
@@ -152,7 +151,7 @@ void guest_code(struct vmx_pages *vmx_pages)
|
||||
GUEST_SYNC(11);
|
||||
|
||||
/* Try enlightened vmptrld with an incorrect GPA */
|
||||
evmcs_vmptrld(0xdeadbeef, vmx_pages->enlightened_vmcs);
|
||||
evmcs_vmptrld(0xdeadbeef, hv_pages->enlightened_vmcs);
|
||||
GUEST_ASSERT(vmlaunch());
|
||||
GUEST_ASSERT(ud_count == 1);
|
||||
GUEST_DONE();
|
||||
@@ -199,7 +198,7 @@ static struct kvm_vcpu *save_restore_vm(struct kvm_vm *vm,
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
vm_vaddr_t vmx_pages_gva = 0;
|
||||
vm_vaddr_t vmx_pages_gva = 0, hv_pages_gva = 0;
|
||||
|
||||
struct kvm_vcpu *vcpu;
|
||||
struct kvm_vm *vm;
|
||||
@@ -217,7 +216,8 @@ int main(int argc, char *argv[])
|
||||
vcpu_enable_evmcs(vcpu);
|
||||
|
||||
vcpu_alloc_vmx(vm, &vmx_pages_gva);
|
||||
vcpu_args_set(vcpu, 1, vmx_pages_gva);
|
||||
vcpu_alloc_hyperv_test_pages(vm, &hv_pages_gva);
|
||||
vcpu_args_set(vcpu, 2, vmx_pages_gva, hv_pages_gva);
|
||||
|
||||
vm_init_descriptor_tables(vm);
|
||||
vcpu_init_descriptor_tables(vcpu);
|
||||
|
||||
Reference in New Issue
Block a user