summaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/cpuid.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2020-03-03 15:54:39 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2020-03-16 17:58:21 +0100
commitfb7d4377d513145303c1d0a192cb4b33d72be2d9 (patch)
tree343eb8702600f30a278dda6141402b453ec90890 /arch/x86/kvm/cpuid.c
parentdbd068040c64162fbbfa278eb63ef64704190612 (diff)
KVM: x86: handle GBPAGE CPUID adjustment for EPT with generic code
The clearing of the GBPAGE CPUID bit for VMX is wrong; support for 1GB pages in EPT has no relationship to whether 1GB pages should be marked as supported in CPUID. This has no ill effect because we're only clearing the bit, but we're not marking 1GB pages as available when EPT is disabled (even though they are actually supported thanks to shadowing). Instead, forcibly enable 1GB pages in the shadow paging case. This also eliminates an instance of the undesirable "unsigned f_* = *_supported ? F(*) : 0" pattern in the common CPUID handling code, and paves the way toward eliminating ->get_lpage_level(). Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/cpuid.c')
-rw-r--r--arch/x86/kvm/cpuid.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 26955c724571..aeab6573fe0f 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -408,8 +408,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
int r, i, max_idx;
unsigned f_nx = is_efer_nx() ? F(NX) : 0;
#ifdef CONFIG_X86_64
- unsigned f_gbpages = (kvm_x86_ops->get_lpage_level() == PT_PDPE_LEVEL)
- ? F(GBPAGES) : 0;
+ unsigned f_gbpages = F(GBPAGES);
unsigned f_lm = F(LM);
#else
unsigned f_gbpages = 0;
@@ -683,6 +682,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
case 0x80000001:
entry->edx &= kvm_cpuid_8000_0001_edx_x86_features;
cpuid_entry_mask(entry, CPUID_8000_0001_EDX);
+ if (!tdp_enabled)
+ cpuid_entry_set(entry, X86_FEATURE_GBPAGES);
entry->ecx &= kvm_cpuid_8000_0001_ecx_x86_features;
cpuid_entry_mask(entry, CPUID_8000_0001_ECX);
break;