Skip to content

Commit a444326

Browse files
vittyvkbonzini
authored andcommitted
KVM: nVMX: clear PIN_BASED_POSTED_INTR from nested pinbased_ctls only when apicv is globally disabled
When apicv is disabled on a vCPU (e.g. by enabling KVM_CAP_HYPERV_SYNIC*), nothing happens to VMX MSRs on the already existing vCPUs, however, all new ones are created with PIN_BASED_POSTED_INTR filtered out. This is very confusing and results in the following picture inside the guest: $ rdmsr -ax 0x48d ff00000016 7f00000016 7f00000016 7f00000016 This is observed with QEMU and 4-vCPU guest: QEMU creates vCPU0, does KVM_CAP_HYPERV_SYNIC2 and then creates the remaining three. L1 hypervisor may only check CPU0's controls to find out what features are available and it will be very confused later. Switch to setting PIN_BASED_POSTED_INTR control based on global 'enable_apicv' setting. Signed-off-by: Vitaly Kuznetsov <[email protected]> Cc: [email protected] Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 91a5f41 commit a444326

File tree

4 files changed

+8
-11
lines changed

4 files changed

+8
-11
lines changed

arch/x86/kvm/vmx/capabilities.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ extern bool __read_mostly enable_ept;
1212
extern bool __read_mostly enable_unrestricted_guest;
1313
extern bool __read_mostly enable_ept_ad_bits;
1414
extern bool __read_mostly enable_pml;
15+
extern bool __read_mostly enable_apicv;
1516
extern int __read_mostly pt_mode;
1617

1718
#define PT_MODE_SYSTEM 0

arch/x86/kvm/vmx/nested.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5949,8 +5949,7 @@ void nested_vmx_set_vmcs_shadowing_bitmap(void)
59495949
* bit in the high half is on if the corresponding bit in the control field
59505950
* may be on. See also vmx_control_verify().
59515951
*/
5952-
void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps,
5953-
bool apicv)
5952+
void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
59545953
{
59555954
/*
59565955
* Note that as a general rule, the high half of the MSRs (bits in
@@ -5977,7 +5976,7 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps,
59775976
PIN_BASED_EXT_INTR_MASK |
59785977
PIN_BASED_NMI_EXITING |
59795978
PIN_BASED_VIRTUAL_NMIS |
5980-
(apicv ? PIN_BASED_POSTED_INTR : 0);
5979+
(enable_apicv ? PIN_BASED_POSTED_INTR : 0);
59815980
msrs->pinbased_ctls_high |=
59825981
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
59835982
PIN_BASED_VMX_PREEMPTION_TIMER;

arch/x86/kvm/vmx/nested.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ enum nvmx_vmentry_status {
1717
};
1818

1919
void vmx_leave_nested(struct kvm_vcpu *vcpu);
20-
void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps,
21-
bool apicv);
20+
void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps);
2221
void nested_vmx_hardware_unsetup(void);
2322
__init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *));
2423
void nested_vmx_set_vmcs_shadowing_bitmap(void);

arch/x86/kvm/vmx/vmx.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO);
9595
static bool __read_mostly fasteoi = 1;
9696
module_param(fasteoi, bool, S_IRUGO);
9797

98-
static bool __read_mostly enable_apicv = 1;
98+
bool __read_mostly enable_apicv = 1;
9999
module_param(enable_apicv, bool, S_IRUGO);
100100

101101
/*
@@ -6769,8 +6769,7 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
67696769

67706770
if (nested)
67716771
nested_vmx_setup_ctls_msrs(&vmx->nested.msrs,
6772-
vmx_capability.ept,
6773-
kvm_vcpu_apicv_active(vcpu));
6772+
vmx_capability.ept);
67746773
else
67756774
memset(&vmx->nested.msrs, 0, sizeof(vmx->nested.msrs));
67766775

@@ -6851,8 +6850,7 @@ static int __init vmx_check_processor_compat(void)
68516850
if (setup_vmcs_config(&vmcs_conf, &vmx_cap) < 0)
68526851
return -EIO;
68536852
if (nested)
6854-
nested_vmx_setup_ctls_msrs(&vmcs_conf.nested, vmx_cap.ept,
6855-
enable_apicv);
6853+
nested_vmx_setup_ctls_msrs(&vmcs_conf.nested, vmx_cap.ept);
68566854
if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) {
68576855
printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n",
68586856
smp_processor_id());
@@ -7714,7 +7712,7 @@ static __init int hardware_setup(void)
77147712

77157713
if (nested) {
77167714
nested_vmx_setup_ctls_msrs(&vmcs_config.nested,
7717-
vmx_capability.ept, enable_apicv);
7715+
vmx_capability.ept);
77187716

77197717
r = nested_vmx_hardware_setup(kvm_vmx_exit_handlers);
77207718
if (r)

0 commit comments

Comments
 (0)