aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_kvm_amd64.h
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2026-01-27 17:20:16 +0100
committerAlexander Potapenko <glider@google.com>2026-02-09 09:43:36 +0000
commitd36c2ba14701aaa8b613b9babb65720a9b510bf9 (patch)
tree356dfd2ea04462f093ba3598f2a6ead48d3ac2c4 /executor/common_kvm_amd64.h
parentdcd3f1a34151f50991c29aa21677ba6f09159da8 (diff)
executor: sys/linux: Implement nested SYZOS loading
This commit introduces the `SYZOS_API_NESTED_LOAD_SYZOS` command to enable running full SYZOS programs within a nested L2 guest, enhancing fuzzing capabilities for nested virtualization. Key changes include: - Nested SYZOS Execution: The new command loads a SYZOS program into an L2 VM, setting up its execution environment. - ABI Refinement: Program size is now passed via the shared `syzos_globals` memory region instead of registers, standardizing the ABI for L1 and L2. - L2 State Management: Improved saving and restoring of L2 guest GPRs across VM-exits using inline assembly wrappers for Intel and AMD. - Nested UEXIT Propagation: Intercepts EPT/NPT faults on the exit page to capture the L2 exit code from saved registers and forward it to L0 with an incremented nesting level. - L2 Memory Management: Updates to L2 page table setup, including skipping NO_HOST_MEM regions to force exits, and a new `l2_gpa_to_pa` helper.
Diffstat (limited to 'executor/common_kvm_amd64.h')
-rw-r--r--executor/common_kvm_amd64.h25
1 files changed, 17 insertions, 8 deletions
diff --git a/executor/common_kvm_amd64.h b/executor/common_kvm_amd64.h
index 474bc875b..c5d7c6983 100644
--- a/executor/common_kvm_amd64.h
+++ b/executor/common_kvm_amd64.h
@@ -206,6 +206,7 @@ static void setup_64bit_idt(struct kvm_sregs* sregs, char* host_mem, uintptr_t g
#endif
#if SYZ_EXECUTOR || __NR_syz_kvm_setup_syzos_vm || __NR_syz_kvm_add_vcpu
+
// SYZOS guest virtual memory layout (must be in sync with executor/kvm.h):
static const struct mem_region syzos_mem_regions[] = {
// AMD64 fixed data structures (5 pages: Zero, GDT, PML4, PDP, PD).
@@ -250,6 +251,7 @@ struct kvm_syz_vm {
void* user_text;
void* gpa0_mem;
void* pt_pool_mem;
+ void* globals_mem;
};
#endif
@@ -1100,19 +1102,16 @@ static volatile long syz_kvm_setup_cpu(volatile long a0, volatile long a1, volat
#define RFLAGS_1_BIT (1ULL << 1)
#define RFLAGS_IF_BIT (1ULL << 9)
-static void reset_cpu_regs(int cpufd, int cpu_id, size_t text_size)
+static void reset_cpu_regs(int cpufd, uint64 rip, uint64 cpu_id)
{
struct kvm_regs regs;
memset(&regs, 0, sizeof(regs));
// RFLAGS.1 must be 1, RFLAGS.IF enables interrupts.
regs.rflags |= RFLAGS_1_BIT | RFLAGS_IF_BIT;
- // PC points to the relative offset of guest_main() within the guest code.
- regs.rip = executor_fn_guest_addr(guest_main);
+ regs.rip = rip;
regs.rsp = X86_SYZOS_ADDR_STACK0;
- // Pass parameters to guest_main().
- regs.rdi = text_size;
- regs.rsi = cpu_id;
+ regs.rdi = cpu_id;
ioctl(cpufd, KVM_SET_REGS, &regs);
}
@@ -1126,7 +1125,15 @@ static void install_user_code(struct kvm_syz_vm* vm, int cpufd, int cpu_id, cons
memcpy(target, text, text_size);
setup_gdt_ldt_pg(vm, cpufd, cpu_id);
setup_cpuid(cpufd);
- reset_cpu_regs(cpufd, cpu_id, text_size);
+
+ uint64 entry_rip = executor_fn_guest_addr(guest_main);
+ reset_cpu_regs(cpufd, entry_rip, cpu_id);
+
+ // Pass the text size via the shared globals page.
+ if (vm->globals_mem) {
+ struct syzos_globals* globals = (struct syzos_globals*)vm->globals_mem;
+ globals->text_sizes[cpu_id] = text_size;
+ }
}
#endif
@@ -1196,6 +1203,8 @@ static void setup_vm(int vmfd, struct kvm_syz_vm* vm)
vm->gpa0_mem = next.addr;
if (r->gpa == X86_SYZOS_ADDR_PT_POOL)
vm->pt_pool_mem = next.addr;
+ if (r->gpa == X86_SYZOS_ADDR_GLOBALS)
+ vm->globals_mem = next.addr;
if (r->gpa == X86_SYZOS_ADDR_BOOT_ARGS) {
boot_args = (struct syzos_boot_args*)next.addr;
@@ -1326,4 +1335,4 @@ static long syz_kvm_assert_syzos_uexit(volatile long a0, volatile long a1, volat
}
#endif
-#endif // EXECUTOR_COMMON_KVM_AMD64_H \ No newline at end of file
+#endif // EXECUTOR_COMMON_KVM_AMD64_H