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: 10h55m, last: 10h12m
✨ 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`): ```c 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`: ```c 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 9h27m 24d
▶ ▼ 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.