提交 3cffc89d 编写于 作者: P Paolo Bonzini

KVM: x86/mmu: load new PGD after the shadow MMU is initialized

Now that __kvm_mmu_new_pgd does not look at the MMU's root_level and
shadow_root_level anymore, pull the PGD load after the initialization of
the shadow MMUs.

Besides being more intuitive, this enables future simplifications
and optimizations because it's not necessary anymore to compute the
role outside kvm_init_mmu.  In particular, kvm_mmu_reset_context was not
attempting to use a cached PGD to avoid having to figure out the new role.
With this change, it could follow what nested_{vmx,svm}_load_cr3 are doing,
and avoid unloading all the cached roots.
Reviewed-by: NSean Christopherson <seanjc@google.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 5499ea73
...@@ -4881,9 +4881,8 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0, ...@@ -4881,9 +4881,8 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0,
new_role = kvm_calc_shadow_npt_root_page_role(vcpu, &regs); new_role = kvm_calc_shadow_npt_root_page_role(vcpu, &regs);
__kvm_mmu_new_pgd(vcpu, nested_cr3, new_role.base);
shadow_mmu_init_context(vcpu, context, &regs, new_role); shadow_mmu_init_context(vcpu, context, &regs, new_role);
__kvm_mmu_new_pgd(vcpu, nested_cr3, new_role.base);
} }
EXPORT_SYMBOL_GPL(kvm_init_shadow_npt_mmu); EXPORT_SYMBOL_GPL(kvm_init_shadow_npt_mmu);
...@@ -4921,27 +4920,25 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly, ...@@ -4921,27 +4920,25 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly,
kvm_calc_shadow_ept_root_page_role(vcpu, accessed_dirty, kvm_calc_shadow_ept_root_page_role(vcpu, accessed_dirty,
execonly, level); execonly, level);
__kvm_mmu_new_pgd(vcpu, new_eptp, new_role.base); if (new_role.as_u64 != context->mmu_role.as_u64) {
context->mmu_role.as_u64 = new_role.as_u64;
if (new_role.as_u64 == context->mmu_role.as_u64)
return; context->shadow_root_level = level;
context->mmu_role.as_u64 = new_role.as_u64; context->ept_ad = accessed_dirty;
context->page_fault = ept_page_fault;
context->shadow_root_level = level; context->gva_to_gpa = ept_gva_to_gpa;
context->sync_page = ept_sync_page;
context->ept_ad = accessed_dirty; context->invlpg = ept_invlpg;
context->page_fault = ept_page_fault; context->root_level = level;
context->gva_to_gpa = ept_gva_to_gpa; context->direct_map = false;
context->sync_page = ept_sync_page; update_permission_bitmask(context, true);
context->invlpg = ept_invlpg; context->pkru_mask = 0;
context->root_level = level; reset_rsvds_bits_mask_ept(vcpu, context, execonly, huge_page_level);
context->direct_map = false; reset_ept_shadow_zero_bits_mask(context, execonly);
}
update_permission_bitmask(context, true); __kvm_mmu_new_pgd(vcpu, new_eptp, new_role.base);
context->pkru_mask = 0;
reset_rsvds_bits_mask_ept(vcpu, context, execonly, huge_page_level);
reset_ept_shadow_zero_bits_mask(context, execonly);
} }
EXPORT_SYMBOL_GPL(kvm_init_shadow_ept_mmu); EXPORT_SYMBOL_GPL(kvm_init_shadow_ept_mmu);
......
...@@ -492,14 +492,14 @@ static int nested_svm_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, ...@@ -492,14 +492,14 @@ static int nested_svm_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,
CC(!load_pdptrs(vcpu, cr3))) CC(!load_pdptrs(vcpu, cr3)))
return -EINVAL; return -EINVAL;
if (!nested_npt)
kvm_mmu_new_pgd(vcpu, cr3);
vcpu->arch.cr3 = cr3; vcpu->arch.cr3 = cr3;
/* Re-initialize the MMU, e.g. to pick up CR4 MMU role changes. */ /* Re-initialize the MMU, e.g. to pick up CR4 MMU role changes. */
kvm_init_mmu(vcpu); kvm_init_mmu(vcpu);
if (!nested_npt)
kvm_mmu_new_pgd(vcpu, cr3);
return 0; return 0;
} }
......
...@@ -1126,15 +1126,15 @@ static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, ...@@ -1126,15 +1126,15 @@ static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,
return -EINVAL; return -EINVAL;
} }
if (!nested_ept)
kvm_mmu_new_pgd(vcpu, cr3);
vcpu->arch.cr3 = cr3; vcpu->arch.cr3 = cr3;
kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3); kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
/* Re-initialize the MMU, e.g. to pick up CR4 MMU role changes. */ /* Re-initialize the MMU, e.g. to pick up CR4 MMU role changes. */
kvm_init_mmu(vcpu); kvm_init_mmu(vcpu);
if (!nested_ept)
kvm_mmu_new_pgd(vcpu, cr3);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册