Skip to content

Commit 27de925

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86/mmu: Let guest use GBPAGES if supported in hardware and TDP is on
Let the guest use 1g hugepages if TDP is enabled and the host supports GBPAGES, KVM can't actively prevent the guest from using 1g pages in this case since they can't be disabled in the hardware page walker. While injecting a page fault if a bogus 1g page is encountered during a software page walk is perfectly reasonable since KVM is simply honoring userspace's vCPU model, doing so arguably doesn't provide any meaningful value, and at worst will be horribly confusing as the guest will see inconsistent behavior and seemingly spurious page faults. Signed-off-by: Sean Christopherson <seanjc@google.com> Message-Id: <20210622175739.3610207-55-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 9a65d0b commit 27de925

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

arch/x86/kvm/mmu/mmu.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4174,13 +4174,28 @@ __reset_rsvds_bits_mask(struct rsvd_bits_validate *rsvd_check,
41744174
}
41754175
}
41764176

4177+
static bool guest_can_use_gbpages(struct kvm_vcpu *vcpu)
4178+
{
4179+
/*
4180+
* If TDP is enabled, let the guest use GBPAGES if they're supported in
4181+
* hardware. The hardware page walker doesn't let KVM disable GBPAGES,
4182+
* i.e. won't treat them as reserved, and KVM doesn't redo the GVA->GPA
4183+
* walk for performance and complexity reasons. Not to mention KVM
4184+
* _can't_ solve the problem because GVA->GPA walks aren't visible to
4185+
* KVM once a TDP translation is installed. Mimic hardware behavior so
4186+
* that KVM's is at least consistent, i.e. doesn't randomly inject #PF.
4187+
*/
4188+
return tdp_enabled ? boot_cpu_has(X86_FEATURE_GBPAGES) :
4189+
guest_cpuid_has(vcpu, X86_FEATURE_GBPAGES);
4190+
}
4191+
41774192
static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu,
41784193
struct kvm_mmu *context)
41794194
{
41804195
__reset_rsvds_bits_mask(&context->guest_rsvd_check,
41814196
vcpu->arch.reserved_gpa_bits,
41824197
context->root_level, is_efer_nx(context),
4183-
guest_cpuid_has(vcpu, X86_FEATURE_GBPAGES),
4198+
guest_can_use_gbpages(vcpu),
41844199
is_cr4_pse(context),
41854200
guest_cpuid_is_amd_or_hygon(vcpu));
41864201
}
@@ -4259,8 +4274,7 @@ static void reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu,
42594274
shadow_zero_check = &context->shadow_zero_check;
42604275
__reset_rsvds_bits_mask(shadow_zero_check, reserved_hpa_bits(),
42614276
context->shadow_root_level, uses_nx,
4262-
guest_cpuid_has(vcpu, X86_FEATURE_GBPAGES),
4263-
is_pse, is_amd);
4277+
guest_can_use_gbpages(vcpu), is_pse, is_amd);
42644278

42654279
if (!shadow_me_mask)
42664280
return;

0 commit comments

Comments
 (0)