KVM: x86/mmu: Exit to userspace with -EFAULT if private fault hits emulation
Exit to userspace with -EFAULT / KVM_EXIT_MEMORY_FAULT if a private fault triggers emulation of any kind, as KVM doesn't currently support emulating access to guest private memory. Practically speaking, private faults and emulation are already mutually exclusive, but there are many flow that can result in KVM returning RET_PF_EMULATE, and adding one last check to harden against weird, unexpected combinations and/or KVM bugs is inexpensive. Suggested-by: Yan Zhao <yan.y.zhao@intel.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20240228024147.41573-2-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
a96cb3bf39
commit
d0bf8e6e44
@ -4256,14 +4256,6 @@ static inline u8 kvm_max_level_for_order(int order)
|
||||
return PG_LEVEL_4K;
|
||||
}
|
||||
|
||||
static void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
|
||||
struct kvm_page_fault *fault)
|
||||
{
|
||||
kvm_prepare_memory_fault_exit(vcpu, fault->gfn << PAGE_SHIFT,
|
||||
PAGE_SIZE, fault->write, fault->exec,
|
||||
fault->is_private);
|
||||
}
|
||||
|
||||
static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
|
||||
struct kvm_page_fault *fault)
|
||||
{
|
||||
|
@ -279,6 +279,14 @@ enum {
|
||||
RET_PF_SPURIOUS,
|
||||
};
|
||||
|
||||
static inline void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
|
||||
struct kvm_page_fault *fault)
|
||||
{
|
||||
kvm_prepare_memory_fault_exit(vcpu, fault->gfn << PAGE_SHIFT,
|
||||
PAGE_SIZE, fault->write, fault->exec,
|
||||
fault->is_private);
|
||||
}
|
||||
|
||||
static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
||||
u32 err, bool prefetch, int *emulation_type)
|
||||
{
|
||||
@ -320,6 +328,17 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
||||
else
|
||||
r = vcpu->arch.mmu->page_fault(vcpu, &fault);
|
||||
|
||||
/*
|
||||
* Not sure what's happening, but punt to userspace and hope that
|
||||
* they can fix it by changing memory to shared, or they can
|
||||
* provide a better error.
|
||||
*/
|
||||
if (r == RET_PF_EMULATE && fault.is_private) {
|
||||
pr_warn_ratelimited("kvm: unexpected emulation request on private memory\n");
|
||||
kvm_mmu_prepare_memory_fault_exit(vcpu, &fault);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (fault.write_fault_to_shadow_pgtable && emulation_type)
|
||||
*emulation_type |= EMULTYPE_WRITE_PF_TO_SP;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user