diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-02 07:24:12 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-03 04:04:11 -0400 |
commit | a0c0feb57992c5caed170feab8a68c51306eb7c3 (patch) | |
tree | 03865eccb27cbc1a2604d6e83ae3f8ecff9b355c | |
parent | d143148383d0395539073dd6c2f25ddf6656bdcc (diff) |
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>
-rw-r--r-- | arch/x86/kvm/cpuid.h | 8 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 13 |
2 files changed, 19 insertions, 2 deletions
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index a5380590ab0e..43b33e301e68 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h | |||
@@ -88,6 +88,14 @@ static inline bool guest_cpuid_has_x2apic(struct kvm_vcpu *vcpu) | |||
88 | return best && (best->ecx & bit(X86_FEATURE_X2APIC)); | 88 | return best && (best->ecx & bit(X86_FEATURE_X2APIC)); |
89 | } | 89 | } |
90 | 90 | ||
91 | static inline bool guest_cpuid_is_amd(struct kvm_vcpu *vcpu) | ||
92 | { | ||
93 | struct kvm_cpuid_entry2 *best; | ||
94 | |||
95 | best = kvm_find_cpuid_entry(vcpu, 0, 0); | ||
96 | return best && best->ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx; | ||
97 | } | ||
98 | |||
91 | static inline bool guest_cpuid_has_gbpages(struct kvm_vcpu *vcpu) | 99 | static inline bool guest_cpuid_has_gbpages(struct kvm_vcpu *vcpu) |
92 | { | 100 | { |
93 | struct kvm_cpuid_entry2 *best; | 101 | struct kvm_cpuid_entry2 *best; |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 6b6df0c5be3d..5b93a597e0c8 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -3512,6 +3512,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, | |||
3512 | int maxphyaddr = cpuid_maxphyaddr(vcpu); | 3512 | int maxphyaddr = cpuid_maxphyaddr(vcpu); |
3513 | u64 exb_bit_rsvd = 0; | 3513 | u64 exb_bit_rsvd = 0; |
3514 | u64 gbpages_bit_rsvd = 0; | 3514 | u64 gbpages_bit_rsvd = 0; |
3515 | u64 nonleaf_bit8_rsvd = 0; | ||
3515 | 3516 | ||
3516 | context->bad_mt_xwr = 0; | 3517 | context->bad_mt_xwr = 0; |
3517 | 3518 | ||
@@ -3519,6 +3520,14 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, | |||
3519 | exb_bit_rsvd = rsvd_bits(63, 63); | 3520 | exb_bit_rsvd = rsvd_bits(63, 63); |
3520 | if (!guest_cpuid_has_gbpages(vcpu)) | 3521 | if (!guest_cpuid_has_gbpages(vcpu)) |
3521 | gbpages_bit_rsvd = rsvd_bits(7, 7); | 3522 | gbpages_bit_rsvd = rsvd_bits(7, 7); |
3523 | |||
3524 | /* | ||
3525 | * Non-leaf PML4Es and PDPEs reserve bit 8 (which would be the G bit for | ||
3526 | * leaf entries) on AMD CPUs only. | ||
3527 | */ | ||
3528 | if (guest_cpuid_is_amd(vcpu)) | ||
3529 | nonleaf_bit8_rsvd = rsvd_bits(8, 8); | ||
3530 | |||
3522 | switch (context->root_level) { | 3531 | switch (context->root_level) { |
3523 | case PT32_ROOT_LEVEL: | 3532 | case PT32_ROOT_LEVEL: |
3524 | /* no rsvd bits for 2 level 4K page table entries */ | 3533 | /* no rsvd bits for 2 level 4K page table entries */ |
@@ -3553,9 +3562,9 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, | |||
3553 | break; | 3562 | break; |
3554 | case PT64_ROOT_LEVEL: | 3563 | case PT64_ROOT_LEVEL: |
3555 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | | 3564 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | |
3556 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(7, 7); | 3565 | nonleaf_bit8_rsvd | rsvd_bits(7, 7) | rsvd_bits(maxphyaddr, 51); |
3557 | context->rsvd_bits_mask[0][2] = exb_bit_rsvd | | 3566 | context->rsvd_bits_mask[0][2] = exb_bit_rsvd | |
3558 | gbpages_bit_rsvd | rsvd_bits(maxphyaddr, 51); | 3567 | nonleaf_bit8_rsvd | gbpages_bit_rsvd | rsvd_bits(maxphyaddr, 51); |
3559 | context->rsvd_bits_mask[0][1] = exb_bit_rsvd | | 3568 | context->rsvd_bits_mask[0][1] = exb_bit_rsvd | |
3560 | rsvd_bits(maxphyaddr, 51); | 3569 | rsvd_bits(maxphyaddr, 51); |
3561 | context->rsvd_bits_mask[0][0] = exb_bit_rsvd | | 3570 | context->rsvd_bits_mask[0][0] = exb_bit_rsvd | |