diff options
| author | Alexander Potapenko <glider@google.com> | 2026-01-13 15:21:18 +0100 |
|---|---|---|
| committer | Alexander Potapenko <glider@google.com> | 2026-01-14 07:29:47 +0000 |
| commit | 90f60a482c87f6baf11d087b0fbf141df123bc0c (patch) | |
| tree | 13166e8c371c13e4cce8eee5cbc55d95fdfa4dc8 /sys | |
| parent | ff8156b958fbf280f429d32adec18ecc3863cde0 (diff) | |
executor: sys/linux: SYZOS: add support for AMD INVLPGA instruction
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.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/linux/dev_kvm_amd64.txt | 6 | ||||
| -rw-r--r-- | sys/linux/test/amd64-syz_kvm_nested_amd_invlpga | 35 |
2 files changed, 41 insertions, 0 deletions
diff --git a/sys/linux/dev_kvm_amd64.txt b/sys/linux/dev_kvm_amd64.txt index c68528e34..abdde5644 100644 --- a/sys/linux/dev_kvm_amd64.txt +++ b/sys/linux/dev_kvm_amd64.txt @@ -147,6 +147,11 @@ syzos_api_nested_amd_vmcb_write_mask { flip_mask int64 } +syzos_api_nested_amd_invlpga { + addr flags[kvm_guest_addrs, int64] + asid int64[0:65535] +} + # IDs here must match those in executor/common_kvm_amd64_syzos.h. syzos_api_call$x86 [ uexit syzos_api$x86[0, intptr] @@ -166,6 +171,7 @@ syzos_api_call$x86 [ nested_vmresume syzos_api$x86[304, syzos_api_vm_id] 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] ] [varlen] kvm_text_x86 [ diff --git a/sys/linux/test/amd64-syz_kvm_nested_amd_invlpga b/sys/linux/test/amd64-syz_kvm_nested_amd_invlpga new file mode 100644 index 000000000..e7a8b1f67 --- /dev/null +++ b/sys/linux/test/amd64-syz_kvm_nested_amd_invlpga @@ -0,0 +1,35 @@ +# +# 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 L0 emulation of the AMD SVM INVLPGA instruction. +# +# 1. Setup nested environment (L1). +# 2. L1 executes INVLPGA with specific ASID and Linear Address. +# - This triggers a VMEXIT to L0. +# - L0 must emulate the invalidation in its Shadow MMU / NPT. +# - L0 resumes L1. +# 3. L1 executes UEXIT(0xface) to signal survival. +# +# Arguments for INVLPGA: +# Arg 0: Linear Address (e.g., 0x400000) +# Arg 1: ASID (e.g., 1) +# +r3 = syz_kvm_add_vcpu$x86(r2, &AUTO={0x0, &AUTO=[@enable_nested={AUTO, AUTO, 0x0}, @nested_create_vm={AUTO, AUTO, 0x0}, @nested_amd_invlpga={AUTO, AUTO, {0x400000, 0x1}}, @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 the VCPU. +# We expect the guest to execute INVLPGA (handled transparently by L0) +# and then immediately yield with UEXIT code 0xface. +# +ioctl$KVM_RUN(r3, AUTO, 0x0) +syz_kvm_assert_syzos_uexit$x86(r5, 0xface) + +# guest_main should finish with guest_uexit(-1). +# +ioctl$KVM_RUN(r3, AUTO, 0x0) +syz_kvm_assert_syzos_uexit$x86(r5, 0xffffffff) |
