History

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.

Maxim Levitsky committed 4 years ago

Commit 3743c2f1 parent a9603ae4 files · +37 −6Browse files

Unified · Split

4 files
  1. arch/x86/include/asm/kvm_host.h +8 −0
  2. arch/x86/kvm/lapic.c +23 −4
  3. arch/x86/kvm/svm/avic.c +3 −1
  4. arch/x86/kvm/vmx/vmx.c +3 −1
arch/x86/include/asm/kvm_host.h+8−0
@@ -1076,6 +1076,14 @@ enum kvm_apicv_inhibit { · 1075 unmodified lines
1076 */1076 */
1077 APICV_INHIBIT_REASON_BLOCKIRQ,1077 APICV_INHIBIT_REASON_BLOCKIRQ,
1078 1078
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
1079 /******************************************************/1087 /******************************************************/
1080 /* INHIBITs that are relevant only to the AMD's AVIC. */1088 /* INHIBITs that are relevant only to the AMD's AVIC. */
1081 /******************************************************/1089 /******************************************************/
arch/x86/kvm/lapic.c+23−4
@@ -2039,6 +2039,19 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) · 2038 unmodified lines
2039 }2039 }
2040}2040}
2041 2041
2042static 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
2042static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)2055static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
2043{2056{
2044 int ret = 0;2057 int ret = 0;
@@ -2047,10 +2060,12 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) · 2 unmodified lines
2047 2060
2048 switch (reg) {2061 switch (reg) {
2049 case APIC_ID: /* Local APIC ID */2062 case APIC_ID: /* Local APIC ID */
2050 if (!apic_x2apic_mode(apic))2063 if (!apic_x2apic_mode(apic)) {
2051 kvm_apic_set_xapic_id(apic, val >> 24);2064 kvm_apic_set_xapic_id(apic, val >> 24);
2052 else2065 kvm_lapic_xapic_id_updated(apic);
2066 } else {
2053 ret = 1;2067 ret = 1;
2068 }
2054 break;2069 break;
2055 2070
2056 case APIC_TASKPRI:2071 case APIC_TASKPRI:
@@ -2336,8 +2351,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) · 279 unmodified lines
2336 MSR_IA32_APICBASE_BASE;2351 MSR_IA32_APICBASE_BASE;
2337 2352
2338 if ((value & MSR_IA32_APICBASE_ENABLE) &&2353 if ((value & MSR_IA32_APICBASE_ENABLE) &&
2339 apic->base_address != APIC_DEFAULT_PHYS_BASE)2354 apic->base_address != APIC_DEFAULT_PHYS_BASE) {
2340 pr_warn_once("APIC base relocation is unsupported by KVM");2355 kvm_set_apicv_inhibit(apic->vcpu->kvm,
2356 APICV_INHIBIT_REASON_APIC_BASE_MODIFIED);
2357 }
2341}2358}
2342 2359
2343void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)2360void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
@@ -2648,6 +2665,8 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu, · 304 unmodified lines
2648 icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);2665 icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
2649 __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);2666 __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
2650 }2667 }
2668 } else {
2669 kvm_lapic_xapic_id_updated(vcpu->arch.apic);
2651 }2670 }
2652 2671
2653 return 0;2672 return 0;
arch/x86/kvm/svm/avic.c+3−1
@@ -910,7 +910,9 @@ bool avic_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason) · 909 unmodified lines
910 BIT(APICV_INHIBIT_REASON_PIT_REINJ) |910 BIT(APICV_INHIBIT_REASON_PIT_REINJ) |
911 BIT(APICV_INHIBIT_REASON_X2APIC) |911 BIT(APICV_INHIBIT_REASON_X2APIC) |
912 BIT(APICV_INHIBIT_REASON_BLOCKIRQ) |912 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));
914 916
915 return supported & BIT(reason);917 return supported & BIT(reason);
916}918}
arch/x86/kvm/vmx/vmx.c+3−1
@@ -7709,7 +7709,9 @@ static bool vmx_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason) · 7708 unmodified lines
7709 ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |7709 ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
7710 BIT(APICV_INHIBIT_REASON_ABSENT) |7710 BIT(APICV_INHIBIT_REASON_ABSENT) |
7711 BIT(APICV_INHIBIT_REASON_HYPERV) |7711 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);
7713 7715
7714 return supported & BIT(reason);7716 return supported & BIT(reason);
7715}7717}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t