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));
|
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)
|
static inline bool guest_cpuid_has_gbpages(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct kvm_cpuid_entry2 *best;
|
struct kvm_cpuid_entry2 *best;
|
||||||
|
|
|
@ -3512,6 +3512,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu,
|
||||||
int maxphyaddr = cpuid_maxphyaddr(vcpu);
|
int maxphyaddr = cpuid_maxphyaddr(vcpu);
|
||||||
u64 exb_bit_rsvd = 0;
|
u64 exb_bit_rsvd = 0;
|
||||||
u64 gbpages_bit_rsvd = 0;
|
u64 gbpages_bit_rsvd = 0;
|
||||||
|
u64 nonleaf_bit8_rsvd = 0;
|
||||||
|
|
||||||
context->bad_mt_xwr = 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);
|
exb_bit_rsvd = rsvd_bits(63, 63);
|
||||||
if (!guest_cpuid_has_gbpages(vcpu))
|
if (!guest_cpuid_has_gbpages(vcpu))
|
||||||
gbpages_bit_rsvd = rsvd_bits(7, 7);
|
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) {
|
switch (context->root_level) {
|
||||||
case PT32_ROOT_LEVEL:
|
case PT32_ROOT_LEVEL:
|
||||||
/* no rsvd bits for 2 level 4K page table entries */
|
/* 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;
|
break;
|
||||||
case PT64_ROOT_LEVEL:
|
case PT64_ROOT_LEVEL:
|
||||||
context->rsvd_bits_mask[0][3] = exb_bit_rsvd |
|
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 |
|
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 |
|
context->rsvd_bits_mask[0][1] = exb_bit_rsvd |
|
||||||
rsvd_bits(maxphyaddr, 51);
|
rsvd_bits(maxphyaddr, 51);
|
||||||
context->rsvd_bits_mask[0][0] = exb_bit_rsvd |
|
context->rsvd_bits_mask[0][0] = exb_bit_rsvd |
|
||||||
|
|
Loading…
Reference in a new issue