aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2026-02-05 13:59:18 +0100
committerAlexander Potapenko <glider@google.com>2026-02-09 09:43:36 +0000
commit168b436f204a8cae6542d42542e18cc1197ac5b2 (patch)
tree6692e6d1adf4770d717b4551f19a22b9be4ec0ff /executor
parent91d686647eca17c731c837e1f1b817e8a61ddb6a (diff)
executor: enable X86_EFER_SVME for AMD
When setting up L1 guest, execute CPUID and enable X86_EFER_SVME for AMD CPUs.
Diffstat (limited to 'executor')
-rw-r--r--executor/common_kvm_amd64.h23
1 files changed, 21 insertions, 2 deletions
diff --git a/executor/common_kvm_amd64.h b/executor/common_kvm_amd64.h
index d090afaa0..474bc875b 100644
--- a/executor/common_kvm_amd64.h
+++ b/executor/common_kvm_amd64.h
@@ -436,9 +436,17 @@ static void setup_gdt_64(struct gdt_entry* gdt)
// We'll keep the base 0 for simplicity, so the second entry (index 4) can remain 0.
}
+static void get_cpuid(uint32 eax, uint32 ecx, uint32* a, uint32* b, uint32* c, uint32* d)
+{
+ *a = *b = *c = *d = 0;
+ asm volatile("cpuid"
+ : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d)
+ : "a"(eax), "c"(ecx));
+}
+
// This only sets up a 64-bit VCPU.
// TODO: Should add support for other modes.
-static void setup_gdt_ldt_pg(struct kvm_syz_vm* vm, int cpufd)
+static void setup_gdt_ldt_pg(struct kvm_syz_vm* vm, int cpufd, int cpu_id)
{
struct kvm_sregs sregs;
ioctl(cpufd, KVM_GET_SREGS, &sregs);
@@ -507,6 +515,17 @@ static void setup_gdt_ldt_pg(struct kvm_syz_vm* vm, int cpufd)
sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG;
sregs.cr4 |= X86_CR4_PAE | X86_CR4_OSFXSR;
sregs.efer |= (X86_EFER_LME | X86_EFER_LMA | X86_EFER_NXE);
+
+ uint32 eax = 0, ebx = 0, ecx = 0, edx = 0;
+ get_cpuid(0, 0, &eax, &ebx, &ecx, &edx);
+ if (ebx == 0x68747541 && edx == 0x69746e65 && ecx == 0x444d4163) { // "AuthenticAMD"
+ sregs.efer |= X86_EFER_SVME;
+
+ // Zero out the HSAVE area for AMD.
+ void* hsave_host = (void*)((uint64)vm->host_mem + X86_SYZOS_ADDR_VM_ARCH_SPECIFIC(cpu_id));
+ memset(hsave_host, 0, KVM_PAGE_SIZE);
+ }
+
sregs.cr3 = X86_ADDR_PML4;
ioctl(cpufd, KVM_SET_SREGS, &sregs);
@@ -1105,7 +1124,7 @@ static void install_user_code(struct kvm_syz_vm* vm, int cpufd, int cpu_id, cons
text_size = KVM_PAGE_SIZE;
void* target = (void*)((uint64)vm->user_text + (KVM_PAGE_SIZE * cpu_id));
memcpy(target, text, text_size);
- setup_gdt_ldt_pg(vm, cpufd);
+ setup_gdt_ldt_pg(vm, cpufd, cpu_id);
setup_cpuid(cpufd);
reset_cpu_regs(cpufd, cpu_id, text_size);
}