Skip to content

Commit ccf31d6

Browse files
committed
KVM: x86/mmu: Use KVM-governed feature framework to track "GBPAGES enabled"
Use the governed feature framework to track whether or not the guest can use 1GiB pages, and drop the one-off helper that wraps the surprisingly non-trivial logic surrounding 1GiB page usage in the guest. No functional change intended. Reviewed-by: Yuan Yao <yuan.yao@intel.com> Link: https://lore.kernel.org/r/20230815203653.519297-3-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 4276441 commit ccf31d6

File tree

3 files changed

+22
-17
lines changed

3 files changed

+22
-17
lines changed

arch/x86/kvm/cpuid.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,28 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
312312
{
313313
struct kvm_lapic *apic = vcpu->arch.apic;
314314
struct kvm_cpuid_entry2 *best;
315+
bool allow_gbpages;
315316

316317
BUILD_BUG_ON(KVM_NR_GOVERNED_FEATURES > KVM_MAX_NR_GOVERNED_FEATURES);
317318
bitmap_zero(vcpu->arch.governed_features.enabled,
318319
KVM_MAX_NR_GOVERNED_FEATURES);
319320

321+
/*
322+
* If TDP is enabled, let the guest use GBPAGES if they're supported in
323+
* hardware. The hardware page walker doesn't let KVM disable GBPAGES,
324+
* i.e. won't treat them as reserved, and KVM doesn't redo the GVA->GPA
325+
* walk for performance and complexity reasons. Not to mention KVM
326+
* _can't_ solve the problem because GVA->GPA walks aren't visible to
327+
* KVM once a TDP translation is installed. Mimic hardware behavior so
328+
* that KVM's is at least consistent, i.e. doesn't randomly inject #PF.
329+
* If TDP is disabled, honor *only* guest CPUID as KVM has full control
330+
* and can install smaller shadow pages if the host lacks 1GiB support.
331+
*/
332+
allow_gbpages = tdp_enabled ? boot_cpu_has(X86_FEATURE_GBPAGES) :
333+
guest_cpuid_has(vcpu, X86_FEATURE_GBPAGES);
334+
if (allow_gbpages)
335+
kvm_governed_feature_set(vcpu, X86_FEATURE_GBPAGES);
336+
320337
best = kvm_find_cpuid_entry(vcpu, 1);
321338
if (best && apic) {
322339
if (cpuid_entry_has(best, X86_FEATURE_TSC_DEADLINE_TIMER))

arch/x86/kvm/governed_features.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ BUILD_BUG()
55

66
#define KVM_GOVERNED_X86_FEATURE(x) KVM_GOVERNED_FEATURE(X86_FEATURE_##x)
77

8+
KVM_GOVERNED_X86_FEATURE(GBPAGES)
9+
810
#undef KVM_GOVERNED_X86_FEATURE
911
#undef KVM_GOVERNED_FEATURE

arch/x86/kvm/mmu/mmu.c

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4808,28 +4808,13 @@ static void __reset_rsvds_bits_mask(struct rsvd_bits_validate *rsvd_check,
48084808
}
48094809
}
48104810

4811-
static bool guest_can_use_gbpages(struct kvm_vcpu *vcpu)
4812-
{
4813-
/*
4814-
* If TDP is enabled, let the guest use GBPAGES if they're supported in
4815-
* hardware. The hardware page walker doesn't let KVM disable GBPAGES,
4816-
* i.e. won't treat them as reserved, and KVM doesn't redo the GVA->GPA
4817-
* walk for performance and complexity reasons. Not to mention KVM
4818-
* _can't_ solve the problem because GVA->GPA walks aren't visible to
4819-
* KVM once a TDP translation is installed. Mimic hardware behavior so
4820-
* that KVM's is at least consistent, i.e. doesn't randomly inject #PF.
4821-
*/
4822-
return tdp_enabled ? boot_cpu_has(X86_FEATURE_GBPAGES) :
4823-
guest_cpuid_has(vcpu, X86_FEATURE_GBPAGES);
4824-
}
4825-
48264811
static void reset_guest_rsvds_bits_mask(struct kvm_vcpu *vcpu,
48274812
struct kvm_mmu *context)
48284813
{
48294814
__reset_rsvds_bits_mask(&context->guest_rsvd_check,
48304815
vcpu->arch.reserved_gpa_bits,
48314816
context->cpu_role.base.level, is_efer_nx(context),
4832-
guest_can_use_gbpages(vcpu),
4817+
guest_can_use(vcpu, X86_FEATURE_GBPAGES),
48334818
is_cr4_pse(context),
48344819
guest_cpuid_is_amd_or_hygon(vcpu));
48354820
}
@@ -4906,7 +4891,8 @@ static void reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu,
49064891
__reset_rsvds_bits_mask(shadow_zero_check, reserved_hpa_bits(),
49074892
context->root_role.level,
49084893
context->root_role.efer_nx,
4909-
guest_can_use_gbpages(vcpu), is_pse, is_amd);
4894+
guest_can_use(vcpu, X86_FEATURE_GBPAGES),
4895+
is_pse, is_amd);
49104896

49114897
if (!shadow_me_mask)
49124898
return;

0 commit comments

Comments
 (0)