Commit 513d44f
KVM: x86/mmu: emulate (not -EFAULT) guest access to a disabled passthrough BAR
A passed-through PCI device's BAR is mapped into the guest via a VM_IO/
VM_PFNMAP VMA whose fault handler (e.g. vfio_pci_mmap_fault) declines to
install a PTE while the device's memory space is disabled, such as right
after the guest clears PCI_COMMAND.MEM. If another vCPU accesses that BAR
during the window, the gup in the page-fault path fails with an error pfn
even though the memslot is still valid, and KVM_RUN returns -EFAULT to
userspace, crashing the VM. A guest can trigger this at will, so it is a
guest-triggerable host-side VM kill.
On real hardware an access to a BAR with memory decoding disabled completes
as an Unsupported Request (reads return all-ones, writes are dropped). KVM
can present the same behaviour by treating the access as MMIO and emulating
it, which is exactly what the noslot path already does.
Distinguish the VM_IO/VM_PFNMAP fault-handler failure from other error pfns
with a new KVM_PFN_ERR_PFNMAP value (in-range, so existing error-pfn range
checks are unaffected) and route it to kvm_handle_noslot_fault() in the x86
TDP fault path. Genuine, non-pfnmap faults (e.g. a vanished anonymous
backing) still take the fatal -EFAULT path, so real errors are not masked.
The MMIO mapping self-heals when the device memory is re-enabled and the
memslot is updated, bumping the MMIO generation.
Fixes: abafbc5 ("vfio-pci: Invalidate mmaps and block MMIO access on disabled memory")
Signed-off-by: Mikhail Malyshev <mike.malyshev@gmail.com>1 parent d5cf6db commit 513d44f
3 files changed
Lines changed: 29 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4521 | 4521 | | |
4522 | 4522 | | |
4523 | 4523 | | |
4524 | | - | |
| 4524 | + | |
| 4525 | + | |
| 4526 | + | |
| 4527 | + | |
| 4528 | + | |
| 4529 | + | |
| 4530 | + | |
| 4531 | + | |
| 4532 | + | |
| 4533 | + | |
| 4534 | + | |
| 4535 | + | |
| 4536 | + | |
| 4537 | + | |
4525 | 4538 | | |
| 4539 | + | |
4526 | 4540 | | |
4527 | 4541 | | |
4528 | 4542 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
97 | 97 | | |
98 | 98 | | |
99 | 99 | | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
100 | 107 | | |
101 | 108 | | |
102 | 109 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2991 | 2991 | | |
2992 | 2992 | | |
2993 | 2993 | | |
2994 | | - | |
| 2994 | + | |
| 2995 | + | |
| 2996 | + | |
| 2997 | + | |
| 2998 | + | |
| 2999 | + | |
| 3000 | + | |
2995 | 3001 | | |
2996 | 3002 | | |
2997 | 3003 | | |
| |||
0 commit comments