WARNING in kvm_vcpu_ioctl

Status: closed as dup on 2026/10/29 17:26
Subsystems: kvm
Labels: prio:low
[Documentation on labels]
Reported-by: syzbot+da2a2f350196c7a0a389@syzkaller.appspotmail.com
First crash: 2d03h, last: 2d03h
✨ AI-generated root cause summary:

When a VM is terminated or marked dead (e.g., via kvm_vm_dead() due to an error in enter_smm() or migration), the KVM_REQ_VM_DEAD request is raised on its vCPUs. If userspace subsequently issues the KVM_PRE_FAULT_MEMORY ioctl, kvm_tdp_page_prefault() bails out upon observing KVM_REQ_VM_DEAD and returns -EIO. However, kvm_vcpu_pre_fault_memory() in virt/kvm/kvm_main.c considers -EIO an unexpected internal condition and triggers WARN_ON_ONCE(r == 0 || r == -EIO). In a production kernel without panic_on_warn, execution breaks out of the loop and cleanly returns -EIO to userspace without crashing or corrupting memory.

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit c339f4010dea:

Root Cause Analysis

1. Functions, Structs, and Files Involved

  • virt/kvm/kvm_main.c: kvm_vcpu_pre_fault_memory() handles the generic KVM_PRE_FAULT_MEMORY vCPU ioctl.
  • arch/x86/kvm/mmu/mmu.c:
    • kvm_arch_vcpu_pre_fault_memory(): x86 architecture backend for prefaulting GPA ranges.
    • kvm_tdp_page_prefault(): Performs TDP prefaulting for a given GPA and checks vCPU requests.
  • include/linux/kvm_host.h & arch/x86/kvm/smm.c (and other caller sites): kvm_vm_dead() marks a VM as dead and raises KVM_REQ_VM_DEAD on all vCPUs.

2. Mechanism and Trigger

  1. When a fatal condition occurs in a VM that does not bug the host kernel data structuresβ€”for example, failure to enter SMM via enter_smm() in arch/x86/kvm/smm.c:370 (goto error -> kvm_vm_dead(vcpu->kvm)), or after context migration in sev_vm_move_enc_context_from()β€”KVM marks the VM dead by calling kvm_vm_dead(kvm).
  2. kvm_vm_dead() sets kvm->vm_dead = true and raises KVM_REQ_VM_DEAD on each vCPU via kvm_make_all_cpus_request(kvm, KVM_REQ_VM_DEAD).
  3. If userspace subsequently invokes ioctl(vcpu_fd, KVM_PRE_FAULT_MEMORY, ...) on the vCPU:
    • kvm_vcpu_ioctl() calls kvm_vcpu_pre_fault_memory().
    • kvm_vcpu_pre_fault_memory() invokes the arch hook kvm_arch_vcpu_pre_fault_memory(), which calls kvm_tdp_page_prefault().
    • In kvm_tdp_page_prefault() (arch/x86/kvm/mmu/mmu.c:5119):
      if (kvm_test_request(KVM_REQ_VM_DEAD, vcpu))
          return -EIO;
      
      kvm_tdp_page_prefault() checks for KVM_REQ_VM_DEAD to avoid getting stuck in a prefault retry loop and explicitly returns -EIO.
    • This -EIO is propagated back to kvm_vcpu_pre_fault_memory() in virt/kvm/kvm_main.c:4464-4465:
      r = kvm_arch_vcpu_pre_fault_memory(vcpu, range);
      if (WARN_ON_ONCE(r == 0 || r == -EIO))
          break;
      
    • Because r == -EIO (-5, matching register R12 = 0xfffffffffffffffb), WARN_ON_ONCE(r == 0 || r == -EIO) triggers.

The defect is an API contract mismatch between the generic KVM pre-fault memory loop in virt/kvm/kvm_main.c (which assumes -EIO is a bug that should never occur and asserts on it) and the architecture-specific TDP page fault handler (which legitimately returns -EIO when KVM_REQ_VM_DEAD is set).

3. Runtime Consequences in a Production Kernel

  • Memory Corruption: False. No invalid memory access, out-of-bounds write/read, or use-after-free occurs.
  • Info Leak: "none". No kernel memory or pointer values are disclosed to userspace.
  • Denial of Service: False. WARN_ON_ONCE does not halt execution in a production kernel without panic_on_warn. When the warning fires, execution immediately executes break;, drops the SRCU lock (srcu_read_unlock(&vcpu->kvm->srcu, idx)), releases the vCPU (vcpu_put(vcpu)), and safely returns -EIO to userspace. All kernel state remains consistent and no deadlock or leak ensues.
▶ ▼ ✨ AI Jobs (1)
ID Workflow Result Correct Bug Created Started Finished Revision
61400d8b assessment-security DenialOfService: ❌ Exploitable: ❌ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ❌ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ❌ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ WARNING in kvm_vcpu_ioctl 2026/10/29 10:31 2026/10/29 10:32 2026/10/29 11:36 b1d00f76
▶ ▼ Duplicate of
Title Rank πŸ›ˆ Repro Cause bisect Fix bisect Count Last Reported
WARNING in kvm_vcpu_pre_fault_memory prio:low kvm -1 syz, C error 2 2d02h 26d
▶ ▼ Discussions (1)
Title Replies (including bot) Last reply
[syzbot] [kvm?] WARNING in kvm_vcpu_ioctl 1 (2) 2026/10/29 17:26

Sample crash report:
------------[ cut here ]------------
r == 0 || r == -EIO
WARNING: arch/x86/kvm/../../../virt/kvm/kvm_main.c:4465 at kvm_vcpu_pre_fault_memory virt/kvm/kvm_main.c:4465 [inline], CPU#1: syz.0.17/6063
WARNING: arch/x86/kvm/../../../virt/kvm/kvm_main.c:4465 at kvm_vcpu_ioctl+0x156a/0x17b0 virt/kvm/kvm_main.c:4744, CPU#1: syz.0.17/6063
Modules linked in:
CPU: 1 UID: 0 PID: 6063 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:kvm_vcpu_pre_fault_memory virt/kvm/kvm_main.c:4465 [inline]
RIP: 0010:kvm_vcpu_ioctl+0x156a/0x17b0 virt/kvm/kvm_main.c:4744
Code: 9c 35 8b 00 be 01 00 00 00 4c 89 f7 e8 4f b1 b5 03 e9 c3 f8 ff ff e8 85 35 8b 00 90 0f 0b 90 e9 2c f2 ff ff e8 77 35 8b 00 90 <0f> 0b 90 e9 38 fd ff ff e8 69 35 8b 00 65 48 8b 3d 99 02 36 14 31
RSP: 0018:ffffc90003957c98 EFLAGS: 00010293
RAX: 0000000000000000 RBX: 1ffff9200072af98 RCX: 0000000000000000
RDX: ffff8880355fcb00 RSI: ffffffff81831d69 RDI: 0000000000000007
RBP: ffff8880459f8048 R08: fffffffffffffffb R09: fffffffffffffffb
R10: ffff8880459f803f R11: 0000000000000001 R12: fffffffffffffffb
R13: ffffed1006abf960 R14: ffff8880459f8000 R15: ffffc90003957d70
FS:  00007f7bf8c946c0(0000) GS:ffff8880d458e000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f0b9aa1ee9c CR3: 0000000037636000 CR4: 0000000000352ef0
Call Trace:
 <TASK>
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:597 [inline]
 __se_sys_ioctl fs/ioctl.c:583 [inline]
 __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f7bf7d9f559
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f7bf8c94028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f7bf8026090 RCX: 00007f7bf7d9f559
RDX: 0000200000000800 RSI: 00000000c040aed5 RDI: 0000000000000005
RBP: 00007f7bf7e36b20 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f7bf8026128 R14: 00007f7bf8026090 R15: 00007ffcdd24ea18
 </TASK>

Crashes (3):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/10/29 11:14 upstream c339f4010dea 4902417d .config console log report syz / log [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream WARNING in kvm_vcpu_ioctl
2026/10/29 10:51 upstream c339f4010dea 4902417d .config console log report syz / log [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream WARNING in kvm_vcpu_ioctl
2026/10/29 10:31 upstream c339f4010dea 4902417d .config console log report info [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream WARNING in kvm_vcpu_ioctl
* Struck through repros no longer work on HEAD.