Skip to content

Commit 8264e85

Browse files
Ackerley Tngsean-jc
authored andcommitted
KVM: selftests: Adjust VM's initial stack address to align with SysV ABI spec
Align the guest stack to match calling sequence requirements in section "The Stack Frame" of the System V ABI AMD64 Architecture Processor Supplement, which requires the value (%rsp + 8), NOT %rsp, to be a multiple of 16 when control is transferred to the function entry point. I.e. in a normal function call, %rsp needs to be 16-byte aligned _before_ CALL, not after. This fixes unexpected #GPs in guest code when the compiler uses SSE instructions, e.g. to initialize memory, as many SSE instructions require memory operands (including those on the stack) to be 16-byte-aligned. Signed-off-by: Ackerley Tng <ackerleytng@google.com> Link: https://lore.kernel.org/r/20230227180601.104318-1-ackerleytng@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 5b1abc2 commit 8264e85

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

tools/testing/selftests/kvm/lib/x86_64/processor.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright (C) 2018, Google LLC.
66
*/
77

8+
#include "linux/bitmap.h"
89
#include "test_util.h"
910
#include "kvm_util.h"
1011
#include "processor.h"
@@ -573,14 +574,29 @@ struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,
573574
DEFAULT_GUEST_STACK_VADDR_MIN,
574575
MEM_REGION_DATA);
575576

577+
stack_vaddr += DEFAULT_STACK_PGS * getpagesize();
578+
579+
/*
580+
* Align stack to match calling sequence requirements in section "The
581+
* Stack Frame" of the System V ABI AMD64 Architecture Processor
582+
* Supplement, which requires the value (%rsp + 8) to be a multiple of
583+
* 16 when control is transferred to the function entry point.
584+
*
585+
* If this code is ever used to launch a vCPU with 32-bit entry point it
586+
* may need to subtract 4 bytes instead of 8 bytes.
587+
*/
588+
TEST_ASSERT(IS_ALIGNED(stack_vaddr, PAGE_SIZE),
589+
"__vm_vaddr_alloc() did not provide a page-aligned address");
590+
stack_vaddr -= 8;
591+
576592
vcpu = __vm_vcpu_add(vm, vcpu_id);
577593
vcpu_init_cpuid(vcpu, kvm_get_supported_cpuid());
578594
vcpu_setup(vm, vcpu);
579595

580596
/* Setup guest general purpose registers */
581597
vcpu_regs_get(vcpu, &regs);
582598
regs.rflags = regs.rflags | 0x2;
583-
regs.rsp = stack_vaddr + (DEFAULT_STACK_PGS * getpagesize());
599+
regs.rsp = stack_vaddr;
584600
regs.rip = (unsigned long) guest_code;
585601
vcpu_regs_set(vcpu, &regs);
586602

0 commit comments

Comments
 (0)