mirror of
https://github.com/torvalds/linux.git
synced 2026-10-03 17:59:02 +02:00
KVM: x86/mmu: change walk_mmu to struct kvm_pagewalk
Now that walk_mmu is only accessed for its "w" member, store directly the pointer to it. Since it is only used to convert guest GVAs or nGVAs, call it gva_walk. Note that there is still one container_of() going from (possibly) walk_mmu.w to its containing struct kvm_mmu, but for now all instances of struct kvm_pagewalk do live within a kvm_mmu. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9262ed5a03
commit
d42e93ee58
|
|
@ -923,7 +923,7 @@ struct kvm_vcpu_arch {
|
|||
* Pointer to the mmu context currently used for
|
||||
* gva_to_gpa translations.
|
||||
*/
|
||||
struct kvm_mmu *walk_mmu;
|
||||
struct kvm_pagewalk *gva_walk;
|
||||
|
||||
u64 pdptrs[4]; /* pae */
|
||||
|
||||
|
|
|
|||
|
|
@ -2046,7 +2046,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
|
|||
* read with kvm_read_guest().
|
||||
*/
|
||||
if (!hc->fast) {
|
||||
hc->ingpa = kvm_translate_gpa(vcpu, &vcpu->arch.walk_mmu->w, hc->ingpa,
|
||||
hc->ingpa = kvm_translate_gpa(vcpu, vcpu->arch.gva_walk, hc->ingpa,
|
||||
PFERR_GUEST_FINAL_MASK, NULL, 0);
|
||||
if (unlikely(hc->ingpa == INVALID_GPA))
|
||||
return HV_STATUS_INVALID_HYPERCALL_INPUT;
|
||||
|
|
|
|||
|
|
@ -6730,7 +6730,7 @@ void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva)
|
|||
* be synced when switching to that new cr3, so nothing needs to be
|
||||
* done here for them.
|
||||
*/
|
||||
kvm_mmu_invalidate_addr(vcpu, &vcpu->arch.walk_mmu->w, gva, KVM_MMU_ROOTS_ALL);
|
||||
kvm_mmu_invalidate_addr(vcpu, vcpu->arch.gva_walk, gva, KVM_MMU_ROOTS_ALL);
|
||||
++vcpu->stat.invlpg;
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_mmu_invlpg);
|
||||
|
|
@ -6867,7 +6867,7 @@ int kvm_mmu_create(struct kvm_vcpu *vcpu)
|
|||
vcpu->arch.mmu_shadow_page_cache.gfp_zero = __GFP_ZERO;
|
||||
|
||||
vcpu->arch.mmu = &vcpu->arch.root_mmu;
|
||||
vcpu->arch.walk_mmu = &vcpu->arch.root_mmu;
|
||||
vcpu->arch.gva_walk = &vcpu->arch.root_mmu.w;
|
||||
|
||||
ret = __kvm_mmu_create(vcpu, &vcpu->arch.guest_mmu);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -548,7 +548,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
|
|||
}
|
||||
#endif
|
||||
walker->fault.address = addr;
|
||||
walker->fault.nested_page_fault = w != &vcpu->arch.walk_mmu->w;
|
||||
walker->fault.nested_page_fault = w != vcpu->arch.gva_walk;
|
||||
walker->fault.async_page_fault = false;
|
||||
|
||||
#if PTTYPE != PTTYPE_EPT
|
||||
|
|
@ -906,7 +906,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, struct kvm_pagewalk *w,
|
|||
|
||||
#ifndef CONFIG_X86_64
|
||||
/* A 64-bit GVA should be impossible on 32-bit KVM. */
|
||||
WARN_ON_ONCE((addr >> 32) && w == &vcpu->arch.walk_mmu->w);
|
||||
WARN_ON_ONCE((addr >> 32) && w == vcpu->arch.gva_walk);
|
||||
#endif
|
||||
|
||||
r = FNAME(walk_addr_generic)(&walker, vcpu, w, addr, access);
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ static inline u64 pdptr_rsvd_bits(struct kvm_vcpu *vcpu)
|
|||
*/
|
||||
int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
|
||||
{
|
||||
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
|
||||
struct kvm_pagewalk *w = vcpu->arch.gva_walk;
|
||||
gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
|
||||
gpa_t real_gpa;
|
||||
int i;
|
||||
|
|
@ -165,7 +165,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
|
|||
* If the MMU is nested, CR3 holds an L2 GPA and needs to be translated
|
||||
* to an L1 GPA.
|
||||
*/
|
||||
real_gpa = kvm_translate_gpa(vcpu, &mmu->w, gfn_to_gpa(pdpt_gfn),
|
||||
real_gpa = kvm_translate_gpa(vcpu, w, gfn_to_gpa(pdpt_gfn),
|
||||
PFERR_USER_MASK | PFERR_WRITE_MASK |
|
||||
PFERR_GUEST_PAGE_MASK, NULL, 0);
|
||||
if (real_gpa == INVALID_GPA)
|
||||
|
|
@ -189,7 +189,8 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
|
|||
* Shadow page roots need to be reconstructed instead.
|
||||
*/
|
||||
if (!tdp_enabled && memcmp(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs)))
|
||||
kvm_mmu_free_roots(vcpu->kvm, mmu, KVM_MMU_ROOT_CURRENT);
|
||||
kvm_mmu_free_roots(vcpu->kvm, &vcpu->arch.root_mmu,
|
||||
KVM_MMU_ROOT_CURRENT);
|
||||
|
||||
memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
|
||||
kvm_register_mark_dirty(vcpu, VCPU_REG_PDPTR);
|
||||
|
|
|
|||
|
|
@ -118,13 +118,13 @@ static void nested_svm_init_mmu_context(struct kvm_vcpu *vcpu)
|
|||
vcpu->arch.mmu->w.get_pdptr = nested_svm_get_tdp_pdptr;
|
||||
|
||||
vcpu->arch.mmu->w.inject_page_fault = nested_svm_inject_npf_exit;
|
||||
vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu;
|
||||
vcpu->arch.gva_walk = &vcpu->arch.nested_mmu.w;
|
||||
}
|
||||
|
||||
static void nested_svm_uninit_mmu_context(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
vcpu->arch.mmu = &vcpu->arch.root_mmu;
|
||||
vcpu->arch.walk_mmu = &vcpu->arch.root_mmu;
|
||||
vcpu->arch.gva_walk = &vcpu->arch.root_mmu.w;
|
||||
}
|
||||
|
||||
static bool nested_vmcb_needs_vls_intercept(struct vcpu_svm *svm)
|
||||
|
|
|
|||
|
|
@ -517,13 +517,13 @@ static void nested_ept_init_mmu_context(struct kvm_vcpu *vcpu)
|
|||
|
||||
vcpu->arch.mmu->w.inject_page_fault = nested_ept_inject_page_fault;
|
||||
|
||||
vcpu->arch.walk_mmu = &vcpu->arch.nested_mmu;
|
||||
vcpu->arch.gva_walk = &vcpu->arch.nested_mmu.w;
|
||||
}
|
||||
|
||||
static void nested_ept_uninit_mmu_context(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
vcpu->arch.mmu = &vcpu->arch.root_mmu;
|
||||
vcpu->arch.walk_mmu = &vcpu->arch.root_mmu;
|
||||
vcpu->arch.gva_walk = &vcpu->arch.root_mmu.w;
|
||||
}
|
||||
|
||||
static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
|
||||
|
|
|
|||
|
|
@ -582,11 +582,12 @@ void __kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu,
|
|||
struct x86_exception *fault,
|
||||
bool from_hardware)
|
||||
{
|
||||
struct kvm_mmu *fault_mmu;
|
||||
struct kvm_pagewalk *fault_walk;
|
||||
|
||||
WARN_ON_ONCE(fault->vector != PF_VECTOR);
|
||||
|
||||
fault_mmu = fault->nested_page_fault ? vcpu->arch.mmu :
|
||||
vcpu->arch.walk_mmu;
|
||||
fault_walk = fault->nested_page_fault ? &vcpu->arch.mmu->w :
|
||||
vcpu->arch.gva_walk;
|
||||
|
||||
/*
|
||||
* Invalidate the TLB entry for the faulting address, if it exists,
|
||||
|
|
@ -594,10 +595,10 @@ void __kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu,
|
|||
*/
|
||||
if ((fault->error_code & PFERR_PRESENT_MASK) &&
|
||||
!(fault->error_code & PFERR_RSVD_MASK))
|
||||
kvm_mmu_invalidate_addr(vcpu, &fault_mmu->w, fault->address,
|
||||
kvm_mmu_invalidate_addr(vcpu, fault_walk, fault->address,
|
||||
KVM_MMU_ROOT_CURRENT);
|
||||
|
||||
fault_mmu->w.inject_page_fault(vcpu, fault, from_hardware);
|
||||
fault_walk->inject_page_fault(vcpu, fault, from_hardware);
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM_INTERNAL(__kvm_inject_emulated_page_fault);
|
||||
|
||||
|
|
@ -4768,7 +4769,7 @@ static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
|
|||
gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva,
|
||||
struct x86_exception *exception)
|
||||
{
|
||||
struct kvm_pagewalk *gva_walk = &vcpu->arch.walk_mmu->w;
|
||||
struct kvm_pagewalk *gva_walk = vcpu->arch.gva_walk;
|
||||
|
||||
u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
|
||||
return gva_walk->gva_to_gpa(vcpu, gva_walk, gva, access, exception);
|
||||
|
|
@ -4778,7 +4779,7 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_mmu_gva_to_gpa_read);
|
|||
gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva,
|
||||
struct x86_exception *exception)
|
||||
{
|
||||
struct kvm_pagewalk *gva_walk = &vcpu->arch.walk_mmu->w;
|
||||
struct kvm_pagewalk *gva_walk = vcpu->arch.gva_walk;
|
||||
|
||||
u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
|
||||
access |= PFERR_WRITE_MASK;
|
||||
|
|
@ -4790,7 +4791,7 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_mmu_gva_to_gpa_write);
|
|||
gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
|
||||
struct x86_exception *exception)
|
||||
{
|
||||
struct kvm_pagewalk *gva_walk = &vcpu->arch.walk_mmu->w;
|
||||
struct kvm_pagewalk *gva_walk = vcpu->arch.gva_walk;
|
||||
|
||||
return gva_walk->gva_to_gpa(vcpu, gva_walk, gva, 0, exception);
|
||||
}
|
||||
|
|
@ -4799,7 +4800,7 @@ static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
|
|||
struct kvm_vcpu *vcpu, u64 access,
|
||||
struct x86_exception *exception)
|
||||
{
|
||||
struct kvm_pagewalk *gva_walk = &vcpu->arch.walk_mmu->w;
|
||||
struct kvm_pagewalk *gva_walk = vcpu->arch.gva_walk;
|
||||
void *data = val;
|
||||
int r = X86EMUL_CONTINUE;
|
||||
|
||||
|
|
@ -4832,7 +4833,7 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt,
|
|||
struct x86_exception *exception)
|
||||
{
|
||||
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
|
||||
struct kvm_pagewalk *gva_walk = &vcpu->arch.walk_mmu->w;
|
||||
struct kvm_pagewalk *gva_walk = vcpu->arch.gva_walk;
|
||||
u64 access = (kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0;
|
||||
unsigned offset;
|
||||
int ret;
|
||||
|
|
@ -4891,7 +4892,7 @@ static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes
|
|||
struct kvm_vcpu *vcpu, u64 access,
|
||||
struct x86_exception *exception)
|
||||
{
|
||||
struct kvm_pagewalk *gva_walk = &vcpu->arch.walk_mmu->w;
|
||||
struct kvm_pagewalk *gva_walk = vcpu->arch.gva_walk;
|
||||
void *data = val;
|
||||
int r = X86EMUL_CONTINUE;
|
||||
|
||||
|
|
@ -4997,7 +4998,7 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
|
|||
gpa_t *gpa, struct x86_exception *exception,
|
||||
bool write)
|
||||
{
|
||||
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
|
||||
struct kvm_pagewalk *gva_walk = vcpu->arch.gva_walk;
|
||||
u64 access = ((kvm_x86_call(get_cpl)(vcpu) == 3) ? PFERR_USER_MASK : 0)
|
||||
| (write ? PFERR_WRITE_MASK : 0);
|
||||
|
||||
|
|
@ -5007,7 +5008,7 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
|
|||
* shadow page table for L2 guest.
|
||||
*/
|
||||
if (vcpu_match_mmio_gva(vcpu, gva) && (!is_paging(vcpu) ||
|
||||
!permission_fault(vcpu, &vcpu->arch.walk_mmu->w,
|
||||
!permission_fault(vcpu, gva_walk,
|
||||
vcpu->arch.mmio_access, 0, access))) {
|
||||
*gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT |
|
||||
(gva & (PAGE_SIZE - 1));
|
||||
|
|
@ -5015,7 +5016,7 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
|
|||
return 1;
|
||||
}
|
||||
|
||||
*gpa = mmu->w.gva_to_gpa(vcpu, &mmu->w, gva, access, exception);
|
||||
*gpa = gva_walk->gva_to_gpa(vcpu, gva_walk, gva, access, exception);
|
||||
|
||||
if (*gpa == INVALID_GPA)
|
||||
return -1;
|
||||
|
|
@ -10600,15 +10601,15 @@ void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end)
|
|||
|
||||
void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_code)
|
||||
{
|
||||
struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
|
||||
struct kvm_pagewalk *gva_walk = vcpu->arch.gva_walk;
|
||||
struct x86_exception fault;
|
||||
u64 access = error_code &
|
||||
(PFERR_WRITE_MASK | PFERR_FETCH_MASK | PFERR_USER_MASK);
|
||||
|
||||
if (!(error_code & PFERR_PRESENT_MASK) ||
|
||||
mmu->w.gva_to_gpa(vcpu, &mmu->w, gva, access, &fault) != INVALID_GPA) {
|
||||
gva_walk->gva_to_gpa(vcpu, gva_walk, gva, access, &fault) != INVALID_GPA) {
|
||||
/*
|
||||
* If vcpu->arch.walk_mmu->gva_to_gpa succeeded, the page
|
||||
* If gva_walk->gva_to_gpa succeeded, the page
|
||||
* tables probably do not match the TLB. Just proceed
|
||||
* with the error code that the processor gave.
|
||||
*/
|
||||
|
|
@ -10619,7 +10620,7 @@ void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_c
|
|||
fault.address = gva;
|
||||
fault.async_page_fault = false;
|
||||
}
|
||||
vcpu->arch.walk_mmu->w.inject_page_fault(vcpu, &fault, true);
|
||||
gva_walk->inject_page_fault(vcpu, &fault, true);
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_fixup_and_inject_pf_error);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user