KVM: x86/mmu: hard code more bits in kvm_init_shadow_npt_mmu

The host CR0 does not really reflect onto the NPT format because
hCR0.PG=1 must be set and hCR0.WP is ignored.  Carve that in stone
by removing the cr0 argument from kvm_init_shadow_npt_mmu.

Pass in WP=1 as well; it does not matter for GMET disabled because
PFERR_USER_MASK is always set, but a cleared W bit in the nested page
tables cannot be overridden in supervisor mode when GMET is enabled,
either.  In fact, since CR0.WP=0 is the weird "extra accesses allowed"
mode, it is acutally easier think about it being always set.

Likewise, clear X86_CR4_SMAP to avoid that KVM erroneously faults on
supervisor accesses to an U=1 page.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2026-04-27 11:30:56 -04:00
parent 7658b9343a
commit ec65797ce3
3 changed files with 7 additions and 7 deletions

View File

@ -96,8 +96,8 @@ void kvm_mmu_set_me_spte_mask(u64 me_value, u64 me_mask);
void kvm_mmu_set_ept_masks(bool has_ad_bits);
void kvm_init_mmu(struct kvm_vcpu *vcpu);
void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0,
unsigned long cr4, u64 efer, gpa_t nested_cr3);
void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr4,
u64 efer, gpa_t nested_cr3);
void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly,
int huge_page_level, bool accessed_dirty,
bool mbec, gpa_t new_eptp);

View File

@ -5939,13 +5939,13 @@ static void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu,
shadow_mmu_init_context(vcpu, context, cpu_role, root_role);
}
void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0,
unsigned long cr4, u64 efer, gpa_t nested_cr3)
void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr4,
u64 efer, gpa_t nested_cr3)
{
struct kvm_mmu *context = &vcpu->arch.guest_mmu;
struct kvm_mmu_role_regs regs = {
.cr0 = cr0,
.cr4 = cr4 & ~X86_CR4_PKE,
.cr0 = X86_CR0_PG | X86_CR0_WP,
.cr4 = cr4 & ~(X86_CR4_PKE | X86_CR4_SMAP),
.efer = efer,
};
union kvm_cpu_role cpu_role = kvm_calc_cpu_role(vcpu, &regs);

View File

@ -93,7 +93,7 @@ static void nested_svm_init_mmu_context(struct kvm_vcpu *vcpu)
* when called via KVM_SET_NESTED_STATE, that state may _not_ match current
* vCPU state. CR0.WP is explicitly ignored, while CR0.PG is required.
*/
kvm_init_shadow_npt_mmu(vcpu, X86_CR0_PG, svm->vmcb01.ptr->save.cr4,
kvm_init_shadow_npt_mmu(vcpu, svm->vmcb01.ptr->save.cr4,
svm->vmcb01.ptr->save.efer,
svm->nested.ctl.nested_cr3);
vcpu->arch.mmu->get_guest_pgd = nested_svm_get_tdp_cr3;