mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 10:02:02 +02:00
KVM: selftests: Allocate a dedicated guest page for x86 L2 guest stack
Instead of relying on the L1-provided stack for L2, which is usually an
array on L1's own stack, allocate a dedicated page of VM memory for the
L2 stack in vcpu_alloc_{vmx/svm}() and use that as L2's RSP in the
VMCS/VMCB instead of the L1-provided value.
Most L1 guest code does not do anything with the L2 stack other than
stuff it in RSP, so this change is transparent and the L1-provided stack
is silently ignored. The only exception is memstress nested L1 code
which puts the vCPU index on L2's stack, so update this code to use the
newly allocated stack.
L1-provided stacks will be dropped and cleaned up separately.
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Yosry Ahmed <yosry@kernel.org>
Link: https://patch.msgid.link/20260610003030.2957261-3-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
3280efa75c
commit
54adab32d3
|
|
@ -1226,6 +1226,8 @@ struct idt_entry {
|
|||
void vm_install_exception_handler(struct kvm_vm *vm, int vector,
|
||||
void (*handler)(struct ex_regs *));
|
||||
|
||||
gva_t vm_alloc_stack(struct kvm_vm *vm, int nr_pages);
|
||||
|
||||
/*
|
||||
* Exception fixup morphs #DE to an arbitrary magic vector so that '0' can be
|
||||
* used to signal "no expcetion".
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ struct svm_test_data {
|
|||
void *msr_hva;
|
||||
u64 msr_gpa;
|
||||
|
||||
/* Stack */
|
||||
void *stack; /* gva */
|
||||
|
||||
/* NPT */
|
||||
u64 ncr3_gpa;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -524,6 +524,8 @@ struct vmx_pages {
|
|||
u64 apic_access_gpa;
|
||||
void *apic_access;
|
||||
|
||||
void *stack;
|
||||
|
||||
u64 eptp_gpa;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static void l1_vmx_code(struct vmx_pages *vmx, u64 vcpu_id)
|
|||
GUEST_ASSERT(ept_1g_pages_supported());
|
||||
|
||||
rsp = &l2_guest_stack[L2_GUEST_STACK_SIZE - 1];
|
||||
*rsp = vcpu_id;
|
||||
*(u64 *)vmx->stack = vcpu_id;
|
||||
prepare_vmcs(vmx, memstress_l2_guest_entry, rsp);
|
||||
|
||||
GUEST_ASSERT(!vmlaunch());
|
||||
|
|
@ -56,9 +56,8 @@ static void l1_svm_code(struct svm_test_data *svm, u64 vcpu_id)
|
|||
unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
|
||||
unsigned long *rsp;
|
||||
|
||||
|
||||
rsp = &l2_guest_stack[L2_GUEST_STACK_SIZE - 1];
|
||||
*rsp = vcpu_id;
|
||||
*(u64 *)svm->stack = vcpu_id;
|
||||
generic_svm_setup(svm, memstress_l2_guest_entry, rsp);
|
||||
|
||||
run_guest(svm->vmcb, svm->vmcb_gpa);
|
||||
|
|
|
|||
|
|
@ -778,7 +778,7 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
|
|||
REPORT_GUEST_ASSERT(uc);
|
||||
}
|
||||
|
||||
static gva_t vm_alloc_stack(struct kvm_vm *vm, int nr_pages)
|
||||
gva_t vm_alloc_stack(struct kvm_vm *vm, int nr_pages)
|
||||
{
|
||||
int size = nr_pages * getpagesize();
|
||||
gva_t stack_gva;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ vcpu_alloc_svm(struct kvm_vm *vm, gva_t *p_svm_gva)
|
|||
svm->msr_gpa = addr_gva2gpa(vm, (uintptr_t)svm->msr);
|
||||
memset(svm->msr_hva, 0, getpagesize());
|
||||
|
||||
svm->stack = (void *)vm_alloc_stack(vm, 1);
|
||||
|
||||
if (vm->stage2_mmu.pgd_created)
|
||||
svm->ncr3_gpa = vm->stage2_mmu.pgd;
|
||||
|
||||
|
|
@ -122,7 +124,7 @@ void generic_svm_setup(struct svm_test_data *svm, void *guest_rip, void *guest_r
|
|||
ctrl->msrpm_base_pa = svm->msr_gpa;
|
||||
|
||||
vmcb->save.rip = (u64)guest_rip;
|
||||
vmcb->save.rsp = (u64)guest_rsp;
|
||||
vmcb->save.rsp = (u64)svm->stack;
|
||||
guest_regs.rdi = (u64)svm;
|
||||
|
||||
if (svm->ncr3_gpa) {
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ vcpu_alloc_vmx(struct kvm_vm *vm, gva_t *p_vmx_gva)
|
|||
vmx->vmwrite_gpa = addr_gva2gpa(vm, (uintptr_t)vmx->vmwrite);
|
||||
memset(vmx->vmwrite_hva, 0, getpagesize());
|
||||
|
||||
vmx->stack = (void *)vm_alloc_stack(vm, 1);
|
||||
|
||||
if (vm->stage2_mmu.pgd_created)
|
||||
vmx->eptp_gpa = vm->stage2_mmu.pgd;
|
||||
|
||||
|
|
@ -370,7 +372,7 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp)
|
|||
{
|
||||
init_vmcs_control_fields(vmx);
|
||||
init_vmcs_host_state();
|
||||
init_vmcs_guest_state(guest_rip, guest_rsp);
|
||||
init_vmcs_guest_state(guest_rip, vmx->stack);
|
||||
}
|
||||
|
||||
bool kvm_cpu_has_ept(void)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user