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.
Unified · Split
| @@ -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 | /******************************************************/ |
| @@ -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 | ||
| 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 | |||
| 2042 | static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) | 2055 | static 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 | else | 2065 | 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 | ||
| 2343 | void kvm_apic_update_apicv(struct kvm_vcpu *vcpu) | 2360 | void 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; |
| @@ -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 | } |
| @@ -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 | } |