Skip to content

Commit 3743c2f

Browse files
Maxim Levitskybonzini
authored andcommitted
KVM: x86: inhibit APICv/AVIC on changes to APIC ID or APIC base
Neither of these settings should be changed by the guest and it is a burden to support it in the acceleration code, so just inhibit this code instead. Signed-off-by: Maxim Levitsky <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent a9603ae commit 3743c2f

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,14 @@ enum kvm_apicv_inhibit {
10761076
*/
10771077
APICV_INHIBIT_REASON_BLOCKIRQ,
10781078

1079+
/*
1080+
* For simplicity, the APIC acceleration is inhibited
1081+
* first time either APIC ID or APIC base are changed by the guest
1082+
* from their reset values.
1083+
*/
1084+
APICV_INHIBIT_REASON_APIC_ID_MODIFIED,
1085+
APICV_INHIBIT_REASON_APIC_BASE_MODIFIED,
1086+
10791087
/******************************************************/
10801088
/* INHIBITs that are relevant only to the AMD's AVIC. */
10811089
/******************************************************/

arch/x86/kvm/lapic.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,19 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
20392039
}
20402040
}
20412041

2042+
static void kvm_lapic_xapic_id_updated(struct kvm_lapic *apic)
2043+
{
2044+
struct kvm *kvm = apic->vcpu->kvm;
2045+
2046+
if (KVM_BUG_ON(apic_x2apic_mode(apic), kvm))
2047+
return;
2048+
2049+
if (kvm_xapic_id(apic) == apic->vcpu->vcpu_id)
2050+
return;
2051+
2052+
kvm_set_apicv_inhibit(apic->vcpu->kvm, APICV_INHIBIT_REASON_APIC_ID_MODIFIED);
2053+
}
2054+
20422055
static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
20432056
{
20442057
int ret = 0;
@@ -2047,10 +2060,12 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
20472060

20482061
switch (reg) {
20492062
case APIC_ID: /* Local APIC ID */
2050-
if (!apic_x2apic_mode(apic))
2063+
if (!apic_x2apic_mode(apic)) {
20512064
kvm_apic_set_xapic_id(apic, val >> 24);
2052-
else
2065+
kvm_lapic_xapic_id_updated(apic);
2066+
} else {
20532067
ret = 1;
2068+
}
20542069
break;
20552070

20562071
case APIC_TASKPRI:
@@ -2336,8 +2351,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
23362351
MSR_IA32_APICBASE_BASE;
23372352

23382353
if ((value & MSR_IA32_APICBASE_ENABLE) &&
2339-
apic->base_address != APIC_DEFAULT_PHYS_BASE)
2340-
pr_warn_once("APIC base relocation is unsupported by KVM");
2354+
apic->base_address != APIC_DEFAULT_PHYS_BASE) {
2355+
kvm_set_apicv_inhibit(apic->vcpu->kvm,
2356+
APICV_INHIBIT_REASON_APIC_BASE_MODIFIED);
2357+
}
23412358
}
23422359

23432360
void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
@@ -2648,6 +2665,8 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
26482665
icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
26492666
__kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
26502667
}
2668+
} else {
2669+
kvm_lapic_xapic_id_updated(vcpu->arch.apic);
26512670
}
26522671

26532672
return 0;

arch/x86/kvm/svm/avic.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,9 @@ bool avic_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason)
910910
BIT(APICV_INHIBIT_REASON_PIT_REINJ) |
911911
BIT(APICV_INHIBIT_REASON_X2APIC) |
912912
BIT(APICV_INHIBIT_REASON_BLOCKIRQ) |
913-
BIT(APICV_INHIBIT_REASON_SEV);
913+
BIT(APICV_INHIBIT_REASON_SEV |
914+
BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) |
915+
BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED));
914916

915917
return supported & BIT(reason);
916918
}

arch/x86/kvm/vmx/vmx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7709,7 +7709,9 @@ static bool vmx_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason)
77097709
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
77107710
BIT(APICV_INHIBIT_REASON_ABSENT) |
77117711
BIT(APICV_INHIBIT_REASON_HYPERV) |
7712-
BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
7712+
BIT(APICV_INHIBIT_REASON_BLOCKIRQ) |
7713+
BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) |
7714+
BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED);
77137715

77147716
return supported & BIT(reason);
77157717
}

0 commit comments

Comments
 (0)