From d36c2ba14701aaa8b613b9babb65720a9b510bf9 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Tue, 27 Jan 2026 17:20:16 +0100 Subject: 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. --- executor/kvm.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'executor/kvm.h') diff --git a/executor/kvm.h b/executor/kvm.h index 024f70351..1e0ceae06 100644 --- a/executor/kvm.h +++ b/executor/kvm.h @@ -64,7 +64,7 @@ #define X86_SYZOS_ADDR_STACK0 0x60f80 // Base address for all per-L1-VCPU regions. -#define X86_SYZOS_PER_VCPU_REGIONS_BASE 0x70000 +#define X86_SYZOS_PER_VCPU_REGIONS_BASE 0x400000 // Size of the entire memory block allocated for a single L1 VCPU to manage its L2 VMs. // We need space for 1 VMXON page + 4 L2 VMs. Let's allocate 256KB per L1 VCPU for ample space. #define X86_SYZOS_L1_VCPU_REGION_SIZE 0x40000 @@ -98,7 +98,7 @@ #define X86_SYZOS_L2_VM_OFFSET_MSR_BITMAP 0x7000 // Subsequent addresses are shifted to accommodate all L1 VCPU regions. -#define X86_SYZOS_ADDR_UNUSED 0x200000 +#define X86_SYZOS_ADDR_UNUSED 0x1000000 #define X86_SYZOS_ADDR_IOAPIC 0xfec00000 #define X86_SYZOS_ADDR_VMCS_VMCB(cpu, vm) \ @@ -344,6 +344,7 @@ // VMCS Guest State Fields. #define VMCS_GUEST_INTR_STATUS 0x00000810 #define VMCS_GUEST_PML_INDEX 0x00000812 +#define VMCS_GUEST_PHYSICAL_ADDRESS 0x00002400 #define VMCS_GUEST_IA32_DEBUGCTL 0x00002802 #define VMCS_GUEST_IA32_PAT 0x00002804 #define VMCS_GUEST_IA32_EFER 0x00002806 @@ -410,6 +411,7 @@ #define VMCB_CTRL_ASID 0x058 #define VMCB_EXIT_CODE 0x070 +#define VMCB_EXITINFO2 0x080 // NP_ENABLE is actually 1 byte, but the 7 following bytes are reserved, so it's okay #define VMCB_CTRL_NP_ENABLE 0x090 @@ -471,6 +473,7 @@ #define VMCB_GUEST_RSP 0x5d8 #define VMCB_GUEST_PAT 0x668 #define VMCB_GUEST_DEBUGCTL 0x670 +#define VMCB_RAX 0x5f8 // SVM Segment Attribute Defines #define SVM_ATTR_G (1 << 15) @@ -498,6 +501,7 @@ #endif // x86-specific definitions. #define KVM_MAX_VCPU 4 +#define KVM_MAX_L2_VMS 4 #define KVM_PAGE_SIZE (1 << 12) #define KVM_GUEST_PAGES 1024 #define KVM_GUEST_MEM_SIZE (KVM_GUEST_PAGES * KVM_PAGE_SIZE) -- cgit mrf-deployment