mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
KVM: x86/mmu: Move kvm_mmu_do_page_fault() from mmu_internal.h => mmu.c
Move kvm_mmu_do_page_fault() into mmu.c, as there are no users outside of mmu.c, and the function typically isn't inlined by the compiler anyways. This will allow moving the EMULTYPE_xxx definitions into x86.h without having to include x86.h in mmu_internal.h, i.e. will help preserve the goal of making x86.h KVM x86's "top-level" include. No functional change intended. Reviewed-by: Yosry Ahmed <yosry@kernel.org> Reviewed-by: Kai Huang <kai.huang@intel.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com> Message-ID: <20260613000329.732085-30-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
31a2cf735c
commit
20fe925246
|
|
@ -4929,7 +4929,7 @@ static int kvm_tdp_mmu_page_fault(struct kvm_vcpu *vcpu,
|
|||
}
|
||||
#endif
|
||||
|
||||
int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
||||
static int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
if (tdp_mmu_enabled)
|
||||
|
|
@ -4939,6 +4939,71 @@ int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
|||
return direct_page_fault(vcpu, fault);
|
||||
}
|
||||
|
||||
static int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
||||
u64 err, bool prefetch, int *emulation_type,
|
||||
u8 *level)
|
||||
{
|
||||
struct kvm_page_fault fault = {
|
||||
.addr = cr2_or_gpa,
|
||||
.error_code = err,
|
||||
.exec = err & PFERR_FETCH_MASK,
|
||||
.write = err & PFERR_WRITE_MASK,
|
||||
.present = err & PFERR_PRESENT_MASK,
|
||||
.rsvd = err & PFERR_RSVD_MASK,
|
||||
.user = err & PFERR_USER_MASK,
|
||||
.prefetch = prefetch,
|
||||
.is_tdp = likely(vcpu->arch.mmu->page_fault == kvm_tdp_page_fault),
|
||||
.nx_huge_page_workaround_enabled =
|
||||
is_nx_huge_page_enabled(vcpu->kvm),
|
||||
|
||||
.max_level = KVM_MAX_HUGEPAGE_LEVEL,
|
||||
.req_level = PG_LEVEL_4K,
|
||||
.goal_level = PG_LEVEL_4K,
|
||||
.is_private = err & PFERR_PRIVATE_ACCESS,
|
||||
|
||||
.pfn = KVM_PFN_ERR_FAULT,
|
||||
};
|
||||
int r;
|
||||
|
||||
if (vcpu->arch.mmu->root_role.direct) {
|
||||
/*
|
||||
* Things like memslots don't understand the concept of a shared
|
||||
* bit. Strip it so that the GFN can be used like normal, and the
|
||||
* fault.addr can be used when the shared bit is needed.
|
||||
*/
|
||||
fault.gfn = gpa_to_gfn(fault.addr) & ~kvm_gfn_direct_bits(vcpu->kvm);
|
||||
fault.slot = kvm_vcpu_gfn_to_memslot(vcpu, fault.gfn);
|
||||
}
|
||||
|
||||
/*
|
||||
* With retpoline being active an indirect call is rather expensive,
|
||||
* so do a direct call in the most common case.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) && fault.is_tdp)
|
||||
r = kvm_tdp_page_fault(vcpu, &fault);
|
||||
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;
|
||||
if (level)
|
||||
*level = fault.goal_level;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int kvm_tdp_page_prefault(struct kvm_vcpu *vcpu, gpa_t gpa,
|
||||
u64 error_code, u8 *level)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -290,8 +290,6 @@ struct kvm_page_fault {
|
|||
bool write_fault_to_shadow_pgtable;
|
||||
};
|
||||
|
||||
int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault);
|
||||
|
||||
/*
|
||||
* Return values of handle_mmio_page_fault(), mmu.page_fault(), fast_page_fault(),
|
||||
* and of course kvm_mmu_do_page_fault().
|
||||
|
|
@ -337,70 +335,6 @@ static inline void kvm_mmu_prepare_memory_fault_exit(struct kvm_vcpu *vcpu,
|
|||
fault->is_private);
|
||||
}
|
||||
|
||||
static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
|
||||
u64 err, bool prefetch,
|
||||
int *emulation_type, u8 *level)
|
||||
{
|
||||
struct kvm_page_fault fault = {
|
||||
.addr = cr2_or_gpa,
|
||||
.error_code = err,
|
||||
.exec = err & PFERR_FETCH_MASK,
|
||||
.write = err & PFERR_WRITE_MASK,
|
||||
.present = err & PFERR_PRESENT_MASK,
|
||||
.rsvd = err & PFERR_RSVD_MASK,
|
||||
.user = err & PFERR_USER_MASK,
|
||||
.prefetch = prefetch,
|
||||
.is_tdp = likely(vcpu->arch.mmu->page_fault == kvm_tdp_page_fault),
|
||||
.nx_huge_page_workaround_enabled =
|
||||
is_nx_huge_page_enabled(vcpu->kvm),
|
||||
|
||||
.max_level = KVM_MAX_HUGEPAGE_LEVEL,
|
||||
.req_level = PG_LEVEL_4K,
|
||||
.goal_level = PG_LEVEL_4K,
|
||||
.is_private = err & PFERR_PRIVATE_ACCESS,
|
||||
|
||||
.pfn = KVM_PFN_ERR_FAULT,
|
||||
};
|
||||
int r;
|
||||
|
||||
if (vcpu->arch.mmu->root_role.direct) {
|
||||
/*
|
||||
* Things like memslots don't understand the concept of a shared
|
||||
* bit. Strip it so that the GFN can be used like normal, and the
|
||||
* fault.addr can be used when the shared bit is needed.
|
||||
*/
|
||||
fault.gfn = gpa_to_gfn(fault.addr) & ~kvm_gfn_direct_bits(vcpu->kvm);
|
||||
fault.slot = kvm_vcpu_gfn_to_memslot(vcpu, fault.gfn);
|
||||
}
|
||||
|
||||
/*
|
||||
* With retpoline being active an indirect call is rather expensive,
|
||||
* so do a direct call in the most common case.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) && fault.is_tdp)
|
||||
r = kvm_tdp_page_fault(vcpu, &fault);
|
||||
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;
|
||||
if (level)
|
||||
*level = fault.goal_level;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int kvm_mmu_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault,
|
||||
const struct kvm_memory_slot *slot, gfn_t gfn);
|
||||
void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user