Re: [PATCH 1/1] KVM: x86/mmu: Emulate, don't kill the VM, on access to a disabled passthrough BAR
From: Sean Christopherson
Date: Mon Jun 22 2026 - 19:23:56 EST
On Sun, Jun 21, 2026, mike.malyshev@xxxxxxxxx wrote:
> ---
> arch/x86/kvm/mmu/mmu.c | 16 +++++++++++++++-
> include/linux/kvm_host.h | 8 ++++++++
> virt/kvm/kvm_main.c | 9 ++++++++-
> 3 files changed, 31 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 91843e9224d04..115e2c4db5fa0 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -4759,8 +4759,22 @@ static int kvm_mmu_faultin_pfn(struct kvm_vcpu *vcpu,
> if (ret != RET_PF_CONTINUE)
> return ret;
>
> - if (unlikely(is_error_pfn(fault->pfn)))
> + if (unlikely(is_error_pfn(fault->pfn))) {
> + /*
> + * A passed-through PCI BAR is backed by a VM_IO/VM_PFNMAP
> + * mapping whose fault handler refuses to install a PTE while the
> + * device's memory space is disabled (e.g. the guest cleared
> + * PCI_COMMAND.MEM). The fault then fails even though the memslot
> + * is still valid. Treat such an access as MMIO and emulate it so
> + * the guest observes Unsupported Request semantics, matching
> + * bare metal, instead of killing the VM with -EFAULT. Genuine,
> + * non-pfnmap errors still take the fatal path.
> + */
> + if (fault->pfn == KVM_PFN_ERR_PFNMAP)
> + return kvm_handle_noslot_fault(vcpu, fault, access);
I really don't like this. It's an ABI change that affects years of precedent,
and the ABI it creates is very haphazard. E.g. why should PFNMAP memory get
emulate MMIO semantics for this case? And a PROT_NONE VMA really shouldn't get
MMIO semantics either.
I would rather have KVM exit to userspace with KVM_EXIT_MEMORY_FAULT and fill
run->memory_fault, i.e.
diff --git arch/x86/kvm/mmu/mmu.c arch/x86/kvm/mmu/mmu.c
index 26ed97efda91..aff6b82b0fdd 100644
--- arch/x86/kvm/mmu/mmu.c
+++ arch/x86/kvm/mmu/mmu.c
@@ -3534,6 +3534,7 @@ static int kvm_handle_error_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fa
return RET_PF_RETRY;
}
+ kvm_mmu_prepare_memory_fault_exit(vcpu, fault);
return -EFAULT;
}
Huh, knew I had a feeling of deja vu. I even proposed this as a fix a while
back. I don't know why it didn't go anywhere. Maybe simply because no one cared
at the time?
https://lore.kernel.org/all/Zr-8M9rYplgN6IS3@xxxxxxxxxx