Commit 6e0918ae authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini

KVM: x86/mmu: Check PDPTRs before allocating PAE roots

Check the validity of the PDPTRs before allocating any of the PAE roots,
otherwise a bad PDPTR will cause KVM to leak any previously allocated
roots.
Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Message-Id: <20210305011101.3597423-8-seanjc@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 6e6ec584
...@@ -3275,7 +3275,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) ...@@ -3275,7 +3275,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu) static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
{ {
struct kvm_mmu *mmu = vcpu->arch.mmu; struct kvm_mmu *mmu = vcpu->arch.mmu;
u64 pdptr, pm_mask; u64 pdptrs[4], pm_mask;
gfn_t root_gfn, root_pgd; gfn_t root_gfn, root_pgd;
hpa_t root; hpa_t root;
int i; int i;
...@@ -3286,6 +3286,17 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu) ...@@ -3286,6 +3286,17 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
if (mmu_check_root(vcpu, root_gfn)) if (mmu_check_root(vcpu, root_gfn))
return 1; return 1;
if (mmu->root_level == PT32E_ROOT_LEVEL) {
for (i = 0; i < 4; ++i) {
pdptrs[i] = mmu->get_pdptr(vcpu, i);
if (!(pdptrs[i] & PT_PRESENT_MASK))
continue;
if (mmu_check_root(vcpu, pdptrs[i] >> PAGE_SHIFT))
return 1;
}
}
/* /*
* Do we shadow a long mode page table? If so we need to * Do we shadow a long mode page table? If so we need to
* write-protect the guests page table root. * write-protect the guests page table root.
...@@ -3315,14 +3326,11 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu) ...@@ -3315,14 +3326,11 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
MMU_WARN_ON(VALID_PAGE(mmu->pae_root[i])); MMU_WARN_ON(VALID_PAGE(mmu->pae_root[i]));
if (mmu->root_level == PT32E_ROOT_LEVEL) { if (mmu->root_level == PT32E_ROOT_LEVEL) {
pdptr = mmu->get_pdptr(vcpu, i); if (!(pdptrs[i] & PT_PRESENT_MASK)) {
if (!(pdptr & PT_PRESENT_MASK)) {
mmu->pae_root[i] = 0; mmu->pae_root[i] = 0;
continue; continue;
} }
root_gfn = pdptr >> PAGE_SHIFT; root_gfn = pdptrs[i] >> PAGE_SHIFT;
if (mmu_check_root(vcpu, root_gfn))
return 1;
} }
root = mmu_alloc_root(vcpu, root_gfn, i << 30, root = mmu_alloc_root(vcpu, root_gfn, i << 30,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment