diff options
| author | Alexander Potapenko <glider@google.com> | 2026-01-14 10:09:53 +0100 |
|---|---|---|
| committer | Alexander Potapenko <glider@google.com> | 2026-01-15 07:19:29 +0000 |
| commit | 0a1338c68f19bbea13b3ae7ce61a185b6a5f65ef (patch) | |
| tree | c3d8f5ed55ec4911b3fed2fcbd45900a5c618790 /sys/linux | |
| parent | 8d22bd8bfc28c79be87ab5da9975cbfe8c78beee (diff) | |
executor: sys/linux: SYZOS: add support for AMD STGI and CLGI instructions
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.
Diffstat (limited to 'sys/linux')
| -rw-r--r-- | sys/linux/dev_kvm_amd64.txt | 2 | ||||
| -rw-r--r-- | sys/linux/test/amd64-syz_kvm_nested_amd_stgi | 47 |
2 files changed, 49 insertions, 0 deletions
diff --git a/sys/linux/dev_kvm_amd64.txt b/sys/linux/dev_kvm_amd64.txt index abdde5644..ba5fa6e4c 100644 --- a/sys/linux/dev_kvm_amd64.txt +++ b/sys/linux/dev_kvm_amd64.txt @@ -172,6 +172,8 @@ syzos_api_call$x86 [ nested_intel_vmwrite_mask syzos_api$x86[340, syzos_api_nested_intel_vmwrite_mask] nested_amd_vmcb_write_mask syzos_api$x86[380, syzos_api_nested_amd_vmcb_write_mask] nested_amd_invlpga syzos_api$x86[381, syzos_api_nested_amd_invlpga] + nested_amd_stgi syzos_api$x86[382, void] + nested_amd_clgi syzos_api$x86[383, void] ] [varlen] kvm_text_x86 [ diff --git a/sys/linux/test/amd64-syz_kvm_nested_amd_stgi b/sys/linux/test/amd64-syz_kvm_nested_amd_stgi new file mode 100644 index 000000000..21f57e878 --- /dev/null +++ b/sys/linux/test/amd64-syz_kvm_nested_amd_stgi @@ -0,0 +1,47 @@ +# +# requires: arch=amd64 -threaded +# +r0 = openat$kvm(0, &AUTO='/dev/kvm\x00', 0x0, 0x0) +r1 = ioctl$KVM_CREATE_VM(r0, AUTO, 0x0) +r2 = syz_kvm_setup_syzos_vm$x86(r1, &(0x7f0000c00000/0x400000)=nil) + +# Test AMD SVM STGI/CLGI interaction with Host NMI Injection. +# +# 1. Guest executes CLGI (disabling interrupts). +# 2. Guest executes UEXIT (0x1337) to yield to Host. +# 3. Host injects an NMI via KVM_NMI. +# - Because GIF=0, this NMI must remain PENDING and NOT be delivered yet. +# 4. Guest resumes and executes STGI. +# - NMI should be delivered immediately after STGI. +# +r3 = syz_kvm_add_vcpu$x86(r2, &AUTO={0x0, &AUTO=[@enable_nested={AUTO, AUTO, 0x0}, @nested_create_vm={AUTO, AUTO, 0x0}, @nested_amd_clgi={AUTO, AUTO, ""}, @uexit={AUTO, AUTO, 0x1337}, @nested_amd_stgi={AUTO, AUTO, ""}, @uexit={AUTO, AUTO, 0xface}], AUTO}) +r4 = ioctl$KVM_GET_VCPU_MMAP_SIZE(r0, AUTO) +r5 = mmap$KVM_VCPU(&(0x7f0000009000/0x1000)=nil, r4, 0x3, 0x1, r3, 0x0) + +# Run 1: Execute CLGI -> UEXIT(0x1337) +# +ioctl$KVM_RUN(r3, AUTO, 0x0) +syz_kvm_assert_syzos_uexit$x86(r5, 0x1337) + +# Inject NMI into the vCPU. +# Since GIF=0 in the guest, this NMI should be queued by L0. +# +ioctl$KVM_NMI(r3, 0x0) + +# Run 2: Resume -> STGI -> NMI Delivery -> UEXIT(0xface) +# We verify that the guest survives the NMI delivery and reaches the final exit. +# (If KVM fails to queue the NMI and delivers it early, or corrupts state, this may crash). +# +ioctl$KVM_RUN(r3, AUTO, 0x0) + +# We check for successful completion. +# Note: If NMI is delivered, it might cause a standard KVM exit depending on interception settings. +# If the guest handles it transparently, we see 0xface. +# For this regression test, ensuring we don't crash L0 is the primary goal. +# +syz_kvm_assert_syzos_uexit$x86(r5, 0xface) + +# Cleanup. +# +ioctl$KVM_RUN(r3, AUTO, 0x0) +syz_kvm_assert_syzos_uexit$x86(r5, 0xffffffff) |
