Skip to content

Commit ef8b4b7

Browse files
committed
KVM: ensure APICv is considered inactive if there is no APIC
kvm_vcpu_apicv_active() returns false if a virtual machine has no in-kernel local APIC, however kvm_apicv_activated might still be true if there are no reasons to disable APICv; in fact it is quite likely that there is none because APICv is inhibited by specific configurations of the local APIC and those configurations cannot be programmed. This triggers a WARN: WARN_ON_ONCE(kvm_apicv_activated(vcpu->kvm) != kvm_vcpu_apicv_active(vcpu)); To avoid this, introduce another cause for APICv inhibition, namely the absence of an in-kernel local APIC. This cause is enabled by default, and is dropped by either KVM_CREATE_IRQCHIP or the enabling of KVM_CAP_IRQCHIP_SPLIT. Reported-by: Ignat Korchagin <[email protected]> Fixes: ee49a89 ("KVM: x86: Move SVM's APICv sanity check to common x86", 2021-10-22) Reviewed-by: Maxim Levitsky <[email protected]> Reviewed-by: Sean Christopherson <[email protected]> Tested-by: Ignat Korchagin <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent cb1d220 commit ef8b4b7

File tree

4 files changed

+8
-4
lines changed

4 files changed

+8
-4
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,7 @@ struct kvm_x86_msr_filter {
10361036
#define APICV_INHIBIT_REASON_PIT_REINJ 4
10371037
#define APICV_INHIBIT_REASON_X2APIC 5
10381038
#define APICV_INHIBIT_REASON_BLOCKIRQ 6
1039+
#define APICV_INHIBIT_REASON_ABSENT 7
10391040

10401041
struct kvm_arch {
10411042
unsigned long n_used_mmu_pages;

arch/x86/kvm/svm/avic.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,7 @@ int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
900900
bool svm_check_apicv_inhibit_reasons(ulong bit)
901901
{
902902
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
903+
BIT(APICV_INHIBIT_REASON_ABSENT) |
903904
BIT(APICV_INHIBIT_REASON_HYPERV) |
904905
BIT(APICV_INHIBIT_REASON_NESTED) |
905906
BIT(APICV_INHIBIT_REASON_IRQWIN) |

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7525,6 +7525,7 @@ static void hardware_unsetup(void)
75257525
static bool vmx_check_apicv_inhibit_reasons(ulong bit)
75267526
{
75277527
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
7528+
BIT(APICV_INHIBIT_REASON_ABSENT) |
75287529
BIT(APICV_INHIBIT_REASON_HYPERV) |
75297530
BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
75307531

arch/x86/kvm/x86.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5740,6 +5740,7 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
57405740
smp_wmb();
57415741
kvm->arch.irqchip_mode = KVM_IRQCHIP_SPLIT;
57425742
kvm->arch.nr_reserved_ioapic_pins = cap->args[0];
5743+
kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT);
57435744
r = 0;
57445745
split_irqchip_unlock:
57455746
mutex_unlock(&kvm->lock);
@@ -6120,6 +6121,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
61206121
/* Write kvm->irq_routing before enabling irqchip_in_kernel. */
61216122
smp_wmb();
61226123
kvm->arch.irqchip_mode = KVM_IRQCHIP_KERNEL;
6124+
kvm_request_apicv_update(kvm, true, APICV_INHIBIT_REASON_ABSENT);
61236125
create_irqchip_unlock:
61246126
mutex_unlock(&kvm->lock);
61256127
break;
@@ -8818,10 +8820,9 @@ static void kvm_apicv_init(struct kvm *kvm)
88188820
{
88198821
init_rwsem(&kvm->arch.apicv_update_lock);
88208822

8821-
if (enable_apicv)
8822-
clear_bit(APICV_INHIBIT_REASON_DISABLE,
8823-
&kvm->arch.apicv_inhibit_reasons);
8824-
else
8823+
set_bit(APICV_INHIBIT_REASON_ABSENT,
8824+
&kvm->arch.apicv_inhibit_reasons);
8825+
if (!enable_apicv)
88258826
set_bit(APICV_INHIBIT_REASON_DISABLE,
88268827
&kvm->arch.apicv_inhibit_reasons);
88278828
}

0 commit comments

Comments
 (0)