diff options
author | Nadav Amit <namit@cs.technion.ac.il> | 2014-05-07 08:32:50 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-05-07 11:25:22 -0400 |
commit | 5f7dde7bbb3c628766676cbd63c0a1834035d6fa (patch) | |
tree | 39fde3ae31697b7e1ef19af9f1d3d626d0f7e909 /arch/x86/kvm | |
parent | a4ab9d0cf1ef0bf521bb69099aa464f38c71393c (diff) |
KVM: x86: Mark bit 7 in long-mode PDPTE according to 1GB pages support
In long-mode, bit 7 in the PDPTE is not reserved only if 1GB pages are
supported by the CPU. Currently the bit is considered by KVM as always
reserved.
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/cpuid.h | 7 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 8 |
2 files changed, 13 insertions, 2 deletions
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index eeecbed26ac7..f9087315e0cd 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h | |||
@@ -88,4 +88,11 @@ 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_has_gbpages(struct kvm_vcpu *vcpu) | ||
92 | { | ||
93 | struct kvm_cpuid_entry2 *best; | ||
94 | |||
95 | best = kvm_find_cpuid_entry(vcpu, 0x80000001, 0); | ||
96 | return best && (best->edx & bit(X86_FEATURE_GBPAGES)); | ||
97 | } | ||
91 | #endif | 98 | #endif |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 65f2400b8268..931467881da7 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "mmu.h" | 22 | #include "mmu.h" |
23 | #include "x86.h" | 23 | #include "x86.h" |
24 | #include "kvm_cache_regs.h" | 24 | #include "kvm_cache_regs.h" |
25 | #include "cpuid.h" | ||
25 | 26 | ||
26 | #include <linux/kvm_host.h> | 27 | #include <linux/kvm_host.h> |
27 | #include <linux/types.h> | 28 | #include <linux/types.h> |
@@ -3516,11 +3517,14 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, | |||
3516 | { | 3517 | { |
3517 | int maxphyaddr = cpuid_maxphyaddr(vcpu); | 3518 | int maxphyaddr = cpuid_maxphyaddr(vcpu); |
3518 | u64 exb_bit_rsvd = 0; | 3519 | u64 exb_bit_rsvd = 0; |
3520 | u64 gbpages_bit_rsvd = 0; | ||
3519 | 3521 | ||
3520 | context->bad_mt_xwr = 0; | 3522 | context->bad_mt_xwr = 0; |
3521 | 3523 | ||
3522 | if (!context->nx) | 3524 | if (!context->nx) |
3523 | exb_bit_rsvd = rsvd_bits(63, 63); | 3525 | exb_bit_rsvd = rsvd_bits(63, 63); |
3526 | if (!guest_cpuid_has_gbpages(vcpu)) | ||
3527 | gbpages_bit_rsvd = rsvd_bits(7, 7); | ||
3524 | switch (context->root_level) { | 3528 | switch (context->root_level) { |
3525 | case PT32_ROOT_LEVEL: | 3529 | case PT32_ROOT_LEVEL: |
3526 | /* no rsvd bits for 2 level 4K page table entries */ | 3530 | /* no rsvd bits for 2 level 4K page table entries */ |
@@ -3557,14 +3561,14 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, | |||
3557 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | | 3561 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | |
3558 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(7, 7); | 3562 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(7, 7); |
3559 | context->rsvd_bits_mask[0][2] = exb_bit_rsvd | | 3563 | context->rsvd_bits_mask[0][2] = exb_bit_rsvd | |
3560 | rsvd_bits(maxphyaddr, 51) | rsvd_bits(7, 7); | 3564 | gbpages_bit_rsvd | rsvd_bits(maxphyaddr, 51); |
3561 | context->rsvd_bits_mask[0][1] = exb_bit_rsvd | | 3565 | context->rsvd_bits_mask[0][1] = exb_bit_rsvd | |
3562 | rsvd_bits(maxphyaddr, 51); | 3566 | rsvd_bits(maxphyaddr, 51); |
3563 | context->rsvd_bits_mask[0][0] = exb_bit_rsvd | | 3567 | context->rsvd_bits_mask[0][0] = exb_bit_rsvd | |
3564 | rsvd_bits(maxphyaddr, 51); | 3568 | rsvd_bits(maxphyaddr, 51); |
3565 | context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3]; | 3569 | context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3]; |
3566 | context->rsvd_bits_mask[1][2] = exb_bit_rsvd | | 3570 | context->rsvd_bits_mask[1][2] = exb_bit_rsvd | |
3567 | rsvd_bits(maxphyaddr, 51) | | 3571 | gbpages_bit_rsvd | rsvd_bits(maxphyaddr, 51) | |
3568 | rsvd_bits(13, 29); | 3572 | rsvd_bits(13, 29); |
3569 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | | 3573 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | |
3570 | rsvd_bits(maxphyaddr, 51) | | 3574 | rsvd_bits(maxphyaddr, 51) | |