Skip to content

Commit 90a2db6

Browse files
committed
KVM: nVMX: INVPCID support
Expose the "Enable INVPCID" secondary execution control to the guest and properly reflect the exit reason. In addition, before this patch the guest was always running with INVPCID enabled, causing pcid.flat's "Test on INVPCID when disabled" test to fail. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 72c139b commit 90a2db6

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

arch/x86/kvm/vmx.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8219,6 +8219,10 @@ static bool nested_vmx_exit_reflected(struct kvm_vcpu *vcpu, u32 exit_reason)
82198219
* table is L0's fault.
82208220
*/
82218221
return false;
8222+
case EXIT_REASON_INVPCID:
8223+
return
8224+
nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_INVPCID) &&
8225+
nested_cpu_has(vmcs12, CPU_BASED_INVLPG_EXITING);
82228226
case EXIT_REASON_WBINVD:
82238227
return nested_cpu_has2(vmcs12, SECONDARY_EXEC_WBINVD_EXITING);
82248228
case EXIT_REASON_XSETBV:
@@ -9469,7 +9473,6 @@ static void nested_vmx_cr_fixed1_bits_update(struct kvm_vcpu *vcpu)
94699473

94709474
static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
94719475
{
9472-
struct kvm_cpuid_entry2 *best;
94739476
struct vcpu_vmx *vmx = to_vmx(vcpu);
94749477
u32 secondary_exec_ctl = vmx_secondary_exec_control(vmx);
94759478

@@ -9488,15 +9491,27 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
94889491
}
94899492
}
94909493

9491-
/* Exposing INVPCID only when PCID is exposed */
9492-
best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
9493-
if (vmx_invpcid_supported() &&
9494-
(!best || !(best->ebx & bit(X86_FEATURE_INVPCID)) ||
9495-
!guest_cpuid_has_pcid(vcpu))) {
9496-
secondary_exec_ctl &= ~SECONDARY_EXEC_ENABLE_INVPCID;
9494+
if (vmx_invpcid_supported()) {
9495+
/* Exposing INVPCID only when PCID is exposed */
9496+
struct kvm_cpuid_entry2 *best = kvm_find_cpuid_entry(vcpu, 0x7, 0);
9497+
bool invpcid_enabled =
9498+
best && best->ebx & bit(X86_FEATURE_INVPCID) &&
9499+
guest_cpuid_has_pcid(vcpu);
94979500

9498-
if (best)
9499-
best->ebx &= ~bit(X86_FEATURE_INVPCID);
9501+
if (!invpcid_enabled) {
9502+
secondary_exec_ctl &= ~SECONDARY_EXEC_ENABLE_INVPCID;
9503+
if (best)
9504+
best->ebx &= ~bit(X86_FEATURE_INVPCID);
9505+
}
9506+
9507+
if (nested) {
9508+
if (invpcid_enabled)
9509+
vmx->nested.nested_vmx_secondary_ctls_high |=
9510+
SECONDARY_EXEC_ENABLE_INVPCID;
9511+
else
9512+
vmx->nested.nested_vmx_secondary_ctls_high &=
9513+
~SECONDARY_EXEC_ENABLE_INVPCID;
9514+
}
95009515
}
95019516

95029517
if (cpu_has_secondary_exec_ctrls())
@@ -10198,6 +10213,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
1019810213

1019910214
/* Take the following fields only from vmcs12 */
1020010215
exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
10216+
SECONDARY_EXEC_ENABLE_INVPCID |
1020110217
SECONDARY_EXEC_RDTSCP |
1020210218
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
1020310219
SECONDARY_EXEC_APIC_REGISTER_VIRT);

0 commit comments

Comments
 (0)