mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
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 <mlevitsk@redhat.com> Message-Id: <20220606180829.102503-3-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
a9603ae0e4
commit
3743c2f025
@ -1076,6 +1076,14 @@ enum kvm_apicv_inhibit {
|
||||
*/
|
||||
APICV_INHIBIT_REASON_BLOCKIRQ,
|
||||
|
||||
/*
|
||||
* For simplicity, the APIC acceleration is inhibited
|
||||
* first time either APIC ID or APIC base are changed by the guest
|
||||
* from their reset values.
|
||||
*/
|
||||
APICV_INHIBIT_REASON_APIC_ID_MODIFIED,
|
||||
APICV_INHIBIT_REASON_APIC_BASE_MODIFIED,
|
||||
|
||||
/******************************************************/
|
||||
/* INHIBITs that are relevant only to the AMD's AVIC. */
|
||||
/******************************************************/
|
||||
|
@ -2039,6 +2039,19 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_lapic_xapic_id_updated(struct kvm_lapic *apic)
|
||||
{
|
||||
struct kvm *kvm = apic->vcpu->kvm;
|
||||
|
||||
if (KVM_BUG_ON(apic_x2apic_mode(apic), kvm))
|
||||
return;
|
||||
|
||||
if (kvm_xapic_id(apic) == apic->vcpu->vcpu_id)
|
||||
return;
|
||||
|
||||
kvm_set_apicv_inhibit(apic->vcpu->kvm, APICV_INHIBIT_REASON_APIC_ID_MODIFIED);
|
||||
}
|
||||
|
||||
static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -2047,10 +2060,12 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
|
||||
|
||||
switch (reg) {
|
||||
case APIC_ID: /* Local APIC ID */
|
||||
if (!apic_x2apic_mode(apic))
|
||||
if (!apic_x2apic_mode(apic)) {
|
||||
kvm_apic_set_xapic_id(apic, val >> 24);
|
||||
else
|
||||
kvm_lapic_xapic_id_updated(apic);
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case APIC_TASKPRI:
|
||||
@ -2336,8 +2351,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
|
||||
MSR_IA32_APICBASE_BASE;
|
||||
|
||||
if ((value & MSR_IA32_APICBASE_ENABLE) &&
|
||||
apic->base_address != APIC_DEFAULT_PHYS_BASE)
|
||||
pr_warn_once("APIC base relocation is unsupported by KVM");
|
||||
apic->base_address != APIC_DEFAULT_PHYS_BASE) {
|
||||
kvm_set_apicv_inhibit(apic->vcpu->kvm,
|
||||
APICV_INHIBIT_REASON_APIC_BASE_MODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
|
||||
@ -2648,6 +2665,8 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
|
||||
icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
|
||||
__kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
|
||||
}
|
||||
} else {
|
||||
kvm_lapic_xapic_id_updated(vcpu->arch.apic);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -910,7 +910,9 @@ bool avic_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason)
|
||||
BIT(APICV_INHIBIT_REASON_PIT_REINJ) |
|
||||
BIT(APICV_INHIBIT_REASON_X2APIC) |
|
||||
BIT(APICV_INHIBIT_REASON_BLOCKIRQ) |
|
||||
BIT(APICV_INHIBIT_REASON_SEV);
|
||||
BIT(APICV_INHIBIT_REASON_SEV |
|
||||
BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) |
|
||||
BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED));
|
||||
|
||||
return supported & BIT(reason);
|
||||
}
|
||||
|
@ -7709,7 +7709,9 @@ static bool vmx_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason)
|
||||
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
|
||||
BIT(APICV_INHIBIT_REASON_ABSENT) |
|
||||
BIT(APICV_INHIBIT_REASON_HYPERV) |
|
||||
BIT(APICV_INHIBIT_REASON_BLOCKIRQ);
|
||||
BIT(APICV_INHIBIT_REASON_BLOCKIRQ) |
|
||||
BIT(APICV_INHIBIT_REASON_APIC_ID_MODIFIED) |
|
||||
BIT(APICV_INHIBIT_REASON_APIC_BASE_MODIFIED);
|
||||
|
||||
return supported & BIT(reason);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user