aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_kvm_amd64_syzos.h
Commit message (Collapse)AuthorAgeFilesLines
* executor: sys/linux: SYZOS: add AMD VMLOAD and VMSAVE primitivesAlexander Potapenko2026-01-201-0/+32
| | | | | | | | | | | | This patch introduces SYZOS_API_NESTED_AMD_VMLOAD and SYZOS_API_NESTED_AMD_VMSAVE. These primitives allow the L1 guest to execute the VMLOAD and VMSAVE instructions, which load/store additional guest state (FS, GS, TR, LDTR, etc.) to/from the VMCB specified by the 'vm_id' argument. This stresses the KVM L0 instruction emulator, which must validate the L1-provided physical address in RAX and perform the state transfer.
* executor: sys/linux: SYZOS: add AMD SET_INTERCEPT primitiveAlexander Potapenko2026-01-191-0/+33
| | | | | | | | | | | | | | | This patch introduces SYZOS_API_NESTED_AMD_SET_INTERCEPT to SYZOS. This primitive enables the fuzzer to surgically modify intercept vectors in the AMD VMCB (Virtual Machine Control Block) Control Area. It implements a read-modify-write operation on 32-bit VMCB offsets, allowing the L1 hypervisor (SYZOS) to deterministically set or clear specific intercept bits (e.g., for RDTSC, HLT, or exceptions) for the L2 guest. This capability allows syzkaller to systematically explore KVM's nested SVM emulation logic by toggling intercepts on and off, rather than relying on static defaults or random memory corruption.
* executor: sys/linux: SYZOS: add support for AMD Nested Event InjectionAlexander Potapenko2026-01-151-0/+33
| | | | | | | | | | | | | Implement SYZOS_API_NESTED_AMD_INJECT_EVENT to allow the L1 guest to inject events (Interrupts, NMIs, Exceptions) into L2 via the VMCB EVENTINJ field. This primitive abstracts the VMCB bit-packing logic (Vector, Type, Valid, Error Code) into a high-level API, enabling the fuzzer to semantically mutate event injection parameters. This targets KVM's nested event merging logic, specifically where L0 must reconcile L1-injected events with Host-pending events.
* executor: sys/linux: SYZOS: add support for AMD STGI and CLGI instructionsAlexander Potapenko2026-01-151-0/+26
| | | | | | | | | Implement the SYZOS_API_NESTED_AMD_STGI and SYZOS_API_NESTED_AMD_CLGI primitives to toggle the Global Interrupt Flag (GIF). These commands execute the stgi and clgi instructions respectively and require no arguments. Also add a test checking that CLGI correctly masks NMI injection from L0.
* executor: sys/linux: SYZOS: add support for AMD INVLPGA instructionAlexander Potapenko2026-01-141-0/+18
| | | | | | | | | | Implement the SYZOS_API_NESTED_AMD_INVLPGA primitive to execute the INVLPGA instruction in the L1 guest. This allows the fuzzer to target KVM's Shadow MMU and Nested Paging (NPT) logic by invalidating TLB entries for specific ASIDs. Also add a simple syzlang seed/regression test.
* executor: apply optnone to guest_handle_nested_vmentry_intel()Alexander Potapenko2025-11-281-1/+4
| | | | | | | | | | | | | Florent Revest reported ThinLTO builds failing with the following error: <inline asm>:2:1: error: symbol 'after_vmentry_label' is already defined after_vmentry_label: ^ error: cannot compile inline asm , which turned out to be caused by the compiler not respecting `noinline`. Adding __attribute__((optnone)) (or optimize("O0") on GCC) fixes the issue.
* executor: sys/linux: implement SYZOS_API_NESTED_AMD_VMCB_WRITE_MASKAlexander Potapenko2025-11-211-0/+23
| | | | | | | | | | | The new command allows mutation of AMD VMCB block with plain 64-bit writes. In addition to VM ID and VMCB offset, @nested_amd_vmcb_write_mask takes three 64-bit numbers: the set mask, the unset mask, and the flip mask. This allows to make bitwise modifications to VMCB without disturbing the execution too much. Also add sys/linux/test/amd64-syz_kvm_nested_amd_vmcb_write_mask to test the new command behavior.
* executor: sys/linux: implement SYZOS_API_NESTED_INTEL_VMWRITE_MASKAlexander Potapenko2025-11-211-0/+28
| | | | | | | | | | | | The new command allows mutation of Intel VMCS fields with the help of vmwrite instruction. In addition to VM ID and field ID, @nested_intel_vmwrite_mask takes three 64-bit numbers: the set mask, the unset mask, and the flip mask. This allows to make bitwise modifications to VMCS without disturbing the execution too much. Also add sys/linux/test/amd64-syz_kvm_nested_vmwrite_mask to test the new command behavior.
* executor: sys/linux/test: handle RDTSCP in L2Alexander Potapenko2025-11-211-3/+18
| | | | | | | Enable basic RDTSCP handling. Ensure that Intel hosts exit on RDTSCP in L2, and that both Intel and AMD can handle RDTSCP exits. Add amd64-syz_kvm_nested_vmresume-rdtscp to test that.
* executor: x86: factor out common code in rdmsr()/wrmsr()Alexander Potapenko2025-11-211-37/+21
| | | | | | | | | | While at it, fix a bug in rdmsr() that apparently lost the top 32 bits. Also fix a bug in Intel's Secondary Processor-based Controls: we were incorrectly using the top 32 bits of X86_MSR_IA32_VMX_PROCBASED_CTLS2 to enable all the available controls without additional setup. This only worked because rdmsr() zeroed out those top bits.
* executor: sys/linux/test: handle RDTSC in L2Alexander Potapenko2025-11-211-3/+15
| | | | | | | Enable basic RDTSC handling. Ensure that Intel hosts exit on RDTSC in L2, and that both Intel and AMD can handle RDTSC exits. Add amd64-syz_kvm_nested_vmresume-rdtsc to test that.
* executor: sys/linux/test: basic CPUID handling in L2Alexander Potapenko2025-11-211-9/+20
| | | | | Ensure L2 correctly exits to L1 on CPUID and resumes properly. Add a test.
* executor: sys/linux: implement SYZOS_API_NESTED_VMRESUMEAlexander Potapenko2025-11-201-18/+59
| | | | | | | | | | | | | | | Provide the SYZOS API command to resume L2 execution after a VM exit, using VMRESUME on Intel and VMRUN on AMD. For testing purpose, implement basic handling of the INVD instruction: - enable INVD interception on AMD (set all bits in VMCB 00Ch); - map EXIT_REASON_INVD and VMEXIT_INVD into SYZOS_NESTED_EXIT_REASON_INVD; - advance L2 RIP to skip to the next instruction. While at it, perform minor refactorings of L2 exit reason handling. sys/linux/test/amd64-syz_kvm_nested_vmresume tests the new command by executing two instructions, INVD and HLT, in the nested VM.
* executor: x86: retire UEXIT_STOP_L2Alexander Potapenko2025-11-201-6/+3
| | | | | | | It was useful initially for vendor-agnostic tests, but given that we have guest_uexit_l2() right before it, we can save an extra L2-L1 exit. Perhaps this should increase the probability of executing more complex payloads (fewer KVM_RUN calls to reach the same point in L2 code).
* executor: sys/linux: implement SYZOS_API_NESTED_VMLAUNCHAlexander Potapenko2025-11-191-1/+200
| | | | | | | | | | | | Provide a SYZOS API command to launch the L2 VM using the VMLAUNCH (Intel) or VMRUN (AMD) instruction. For testing purposes, each L2->L1 exit is followed by a guest_uexit_l2() returning the exit code to L0. Common exit reasons (like HLT) will be mapped into a common exit code space (0xe2e20000 | reason), so that a single test can be used for both Intel and AMD. Vendor-specific exit codes will be returned using the 0xe2110000 mask for Intel and 0xe2aa0000 for AMD.
* executor: sys/linux: implement SYZOS_API_NESTED_LOAD_CODEAlexander Potapenko2025-11-191-0/+41
| | | | The new command loads an instruction blob into the specified L2 VM.
* executor: sys/linux: renumber SYZOS API IDsAlexander Potapenko2025-11-191-13/+13
| | | | | | | | Now that we are using volatiles in guest_main(), there is no particular need to base the numbers on primes (this didn't work well with Clang anyway). Instead, group the commands logically and leave some space between the groups for future updates.
* executor: x86: implement SYZOS_API_NESTED_CREATE_VMAlexander Potapenko2025-11-191-0/+412
| | | | | | Provide basic setup for registers, page tables, and segments to create Intel/AMD-based nested virtual machines. Note that the machines do not get started yet.
* executor: x86: implement SYZOS_API_ENABLE_NESTEDAlexander Potapenko2025-11-191-0/+118
| | | | | | Add vendor-specific code to turn on nested virtualization on Intel and AMD. Also provide get_cpu_vendor() to pick the correct implementation.
* executor: add include guards to KVM headersAlexander Potapenko2025-10-271-0/+5
| | | | | Not having these results in three copies of every KVM-related #define in each reproducer.
* executor: introduce __addrspace_guestAlexander Potapenko2025-10-171-13/+12
| | | | | | | | | | | | Apply __addrspace_guest to every guest function and use a C++ template to statically validate that host functions are not passed to executor_fn_guest_addr(). This only works in Clang builds of syz-executor, because GCC does not support address spaces, and C reproducers cannot use templates. The static check allows us to drop the dynamic checks in DEFINE_GUEST_FN_TO_GPA_FN(). While at it, replace DEFINE_GUEST_FN_TO_GPA_FN() with explicit declarations of host_fn_guest_addr() and guest_fn_guest_addr().
* executor: amd64: remove the switch from guest_main()Alexander Potapenko2025-10-171-31/+35
| | | | Somehow Clang still manages to emit a jump table for it.
* executor: sys/linux: implement SYZOS_API_SET_IRQ_HANDLERAlexander Potapenko2025-10-171-1/+70
| | | | | | | | | | The new API call allows to initialize the handler with one of the three possible values: - NULL (should cause a page fault) - dummy_null_handler (should call iret) - uexit_irq_handler (should perform guest_uexit(UEXIT_IRQ)) Also add a test for uexit_irq_handler()
* executor: rework GDT setup for SYZOSAlexander Potapenko2025-10-171-0/+7
| | | | | Untangle SYZOS GDT setup from the legacy one. Drop LDT and TSS for now.
* executor: rename SYZOS-related address definitionsAlexander Potapenko2025-10-171-2/+2
| | | | | | | To distinguish SYZOS addresses from other x86 definitions, change them to start with X86_SYZOS_ADDR_ No functional change.
* sys/linux: executor: add IN_DX and OUT_DX to SYZOS x86 APIAlexander Potapenko2025-09-191-0/+67
| | | | | | | | Add SYZOS calls that correspond to the IN and OUT x86 instructions that perform port I/O. These instructions have different variants, for now we just implement the one that takes the port number from DX instead of encoding it in the opcode.
* sys/linux: executor: implement SYZOS_API_WR_DRN on x86Alexander Potapenko2025-09-191-0/+45
| | | | | Add a SYZOS call to write to one of the debug registers (DR0-DR7).
* executor: introduce __no_stack_protector and use it for guest codeAlexander Potapenko2025-09-111-11/+1
| | | | | | | | | | | When compiling the executor in syz-env-old, -fstack-protector may kick in and introduce global accesses that tools/check-syzos.sh reports. To prevent this, introduce the __no_stack_protector macro attribute that disable stack protection for the function in question, and use it for guest code. While at it, factor out some common definitions into common_kvm_syzos.h
* executor: x86: fix check-syzos errorAlexander Potapenko2025-09-111-14/+16
| | | | | Replace the switch statement in guest_handle_wr_crn() with a series of if statements.
* sys/linux: executor: implement SYZOS_API_WR_CRN on x86Alexander Potapenko2025-07-241-0/+37
| | | | | Add a SYZOS call to write to one of the system registers (CR0, CR2, CR3, CR4, CR8).
* executor/common_kvm_amd64_syzos.h: add _handle_ to function namesAlexander Potapenko2025-07-241-9/+9
| | | | | | Let's try to stick to the convention of naming every SYZOS API handler syzos_handle_something(). No functional change.
* executor: sys/linux/dev_kvm_amd64.txt: implement rdmsr/wrmsrAlexander Potapenko2025-07-241-0/+54
| | | | Let SYZOS execute RDMSR and WRMSR on x86.
* executor/common_kvm_amd64_syzos.h: add a missing breakAlexander Potapenko2025-07-241-0/+1
|
* executor: sys/linux: use sparse IDs for SYZOS APIAlexander Potapenko2025-07-241-3/+7
| | | | | | Like we already do on ARM, use prime numbers multiplied by 10 for SYZOS API IDs to prevent the compiler from emitting a jump table in guest_main().
* executor/kvm: add SYZOS support for CPUIDMarios Pomonis2025-05-191-0/+21
| | | | | This commit adds support for CPUID instructions on AMD64. It also adds a relevant test.
* executor/kvm: add x86-64 SYZOS fuzzerMarios Pomonis2025-04-231-0/+96
This commit adds the actual SyzOS fuzzer for x86-64 and a small test. It also updates some necessary parts of the ARM version and adds some glue for i386.