Skip to content

Commit 7441865

Browse files
sean-jcpull[bot]
authored andcommitted
KVM: x86: Subsume nested GPA read helper into load_pdptrs()
Open code the call to mmu->translate_gpa() when loading nested PDPTRs and kill off the existing helper, kvm_read_guest_page_mmu(), to discourage incorrect use. Reading guest memory straight from an L2 GPA is extremely rare (as evidenced by the lack of users), as very few constructs in x86 specify physical addresses, even fewer are virtualized by KVM, and even fewer yet require emulation of L2 by L0 KVM. No functional change intended. Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20210831164224.1119728-3-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent dc8cfaf commit 7441865

File tree

2 files changed

+18
-41
lines changed

2 files changed

+18
-41
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,9 +1712,6 @@ void kvm_requeue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
17121712
void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
17131713
bool kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu,
17141714
struct x86_exception *fault);
1715-
int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
1716-
gfn_t gfn, void *data, int offset, int len,
1717-
u32 access);
17181715
bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
17191716
bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr);
17201717

arch/x86/kvm/x86.c

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -790,30 +790,6 @@ bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr)
790790
}
791791
EXPORT_SYMBOL_GPL(kvm_require_dr);
792792

793-
/*
794-
* This function will be used to read from the physical memory of the currently
795-
* running guest. The difference to kvm_vcpu_read_guest_page is that this function
796-
* can read from guest physical or from the guest's guest physical memory.
797-
*/
798-
int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
799-
gfn_t ngfn, void *data, int offset, int len,
800-
u32 access)
801-
{
802-
struct x86_exception exception;
803-
gfn_t real_gfn;
804-
gpa_t ngpa;
805-
806-
ngpa = gfn_to_gpa(ngfn);
807-
real_gfn = mmu->translate_gpa(vcpu, ngpa, access, &exception);
808-
if (real_gfn == UNMAPPED_GVA)
809-
return -EFAULT;
810-
811-
real_gfn = gpa_to_gfn(real_gfn);
812-
813-
return kvm_vcpu_read_guest_page(vcpu, real_gfn, data, offset, len);
814-
}
815-
EXPORT_SYMBOL_GPL(kvm_read_guest_page_mmu);
816-
817793
static inline u64 pdptr_rsvd_bits(struct kvm_vcpu *vcpu)
818794
{
819795
return vcpu->arch.reserved_gpa_bits | rsvd_bits(5, 8) | rsvd_bits(1, 2);
@@ -825,34 +801,38 @@ static inline u64 pdptr_rsvd_bits(struct kvm_vcpu *vcpu)
825801
int load_pdptrs(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, unsigned long cr3)
826802
{
827803
gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
828-
unsigned offset = ((cr3 & (PAGE_SIZE-1)) >> 5) << 2;
804+
unsigned offset = (((cr3 & (PAGE_SIZE-1)) >> 5) << 2) * sizeof(u64);
805+
gpa_t real_gpa;
829806
int i;
830807
int ret;
831808
u64 pdpte[ARRAY_SIZE(mmu->pdptrs)];
832809

833-
ret = kvm_read_guest_page_mmu(vcpu, mmu, pdpt_gfn, pdpte,
834-
offset * sizeof(u64), sizeof(pdpte),
835-
PFERR_USER_MASK|PFERR_WRITE_MASK);
836-
if (ret < 0) {
837-
ret = 0;
838-
goto out;
839-
}
810+
/*
811+
* If the MMU is nested, CR3 holds an L2 GPA and needs to be translated
812+
* to an L1 GPA.
813+
*/
814+
real_gpa = mmu->translate_gpa(vcpu, gfn_to_gpa(pdpt_gfn),
815+
PFERR_USER_MASK | PFERR_WRITE_MASK, NULL);
816+
if (real_gpa == UNMAPPED_GVA)
817+
return 0;
818+
819+
ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(real_gpa), pdpte,
820+
offset, sizeof(pdpte));
821+
if (ret < 0)
822+
return 0;
823+
840824
for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
841825
if ((pdpte[i] & PT_PRESENT_MASK) &&
842826
(pdpte[i] & pdptr_rsvd_bits(vcpu))) {
843-
ret = 0;
844-
goto out;
827+
return 0;
845828
}
846829
}
847-
ret = 1;
848830

849831
memcpy(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs));
850832
kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR);
851833
vcpu->arch.pdptrs_from_userspace = false;
852834

853-
out:
854-
855-
return ret;
835+
return 1;
856836
}
857837
EXPORT_SYMBOL_GPL(load_pdptrs);
858838

0 commit comments

Comments
 (0)