KVM: x86: reserve bit 8 of non-leaf PDPEs and PML4Es in 64-bit mode on AMD
Bit 8 would be the "global" bit, which does not quite make sense for non-leaf page table entries. Intel ignores it; AMD ignores it in PDEs, but reserves it in PDPEs and PML4Es. The SVM test is relying on this behavior, so enforce it. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
d143148383
commit
a0c0feb579
2 changed files with 19 additions and 2 deletions
|
@ -88,6 +88,14 @@ static inline bool guest_cpuid_has_x2apic(struct kvm_vcpu *vcpu)
|
|||
return best && (best->ecx & bit(X86_FEATURE_X2APIC));
|
||||
}
|
||||
|
||||
static inline bool guest_cpuid_is_amd(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpuid_entry2 *best;
|
||||
|
||||
best = kvm_find_cpuid_entry(vcpu, 0, 0);
|
||||
return best && best->ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx;
|
||||
}
|
||||
|
||||
static inline bool guest_cpuid_has_gbpages(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_cpuid_entry2 *best;
|
||||
|
|
|
@ -3512,6 +3512,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu,
|
|||
int maxphyaddr = cpuid_maxphyaddr(vcpu);
|
||||
u64 exb_bit_rsvd = 0;
|
||||
u64 gbpages_bit_rsvd = 0;
|
||||
u64 nonleaf_bit8_rsvd = 0;
|
||||
|
||||
context->bad_mt_xwr = 0;
|
||||
|
||||
|
@ -3519,6 +3520,14 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu,
|
|||
exb_bit_rsvd = rsvd_bits(63, 63);
|
||||
if (!guest_cpuid_has_gbpages(vcpu))
|
||||
gbpages_bit_rsvd = rsvd_bits(7, 7);
|
||||
|
||||
/*
|
||||
* Non-leaf PML4Es and PDPEs reserve bit 8 (which would be the G bit for
|
||||
* leaf entries) on AMD CPUs only.
|
||||
*/
|
||||
if (guest_cpuid_is_amd(vcpu))
|
||||
nonleaf_bit8_rsvd = rsvd_bits(8, 8);
|
||||
|
||||
switch (context->root_level) {
|
||||
case PT32_ROOT_LEVEL:
|
||||
/* no rsvd bits for 2 level 4K page table entries */
|
||||
|
@ -3553,9 +3562,9 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu,
|
|||
break;
|
||||
case PT64_ROOT_LEVEL:
|
||||
context->rsvd_bits_mask[0][3] = exb_bit_rsvd |
|
||||
rsvd_bits(maxphyaddr, 51) | rsvd_bits(7, 7);
|
||||
nonleaf_bit8_rsvd | rsvd_bits(7, 7) | rsvd_bits(maxphyaddr, 51);
|
||||
context->rsvd_bits_mask[0][2] = exb_bit_rsvd |
|
||||
gbpages_bit_rsvd | rsvd_bits(maxphyaddr, 51);
|
||||
nonleaf_bit8_rsvd | gbpages_bit_rsvd | rsvd_bits(maxphyaddr, 51);
|
||||
context->rsvd_bits_mask[0][1] = exb_bit_rsvd |
|
||||
rsvd_bits(maxphyaddr, 51);
|
||||
context->rsvd_bits_mask[0][0] = exb_bit_rsvd |
|
||||
|
|
Loading…
Reference in a new issue