[PATCH v3 06/11] KVM: x86: lapic: don't allow to change APIC ID when apic acceleration is enabled

From: Maxim Levitsky
Date: Tue Mar 01 2022 - 13:28:17 EST


No normal guest has any reason to change physical APIC IDs, and
allowing this introduces bugs into APIC acceleration code.

Signed-off-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx>
---
arch/x86/kvm/lapic.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 80a2020c4db40..ffb5fc6449bc5 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -2042,10 +2042,20 @@ 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))
- kvm_apic_set_xapic_id(apic, val >> 24);
- else
+ if (apic_x2apic_mode(apic)) {
ret = 1;
+ break;
+ }
+ /*
+ * Don't allow setting APIC ID with any APIC acceleration
+ * enabled to avoid unexpected issues
+ */
+ if (enable_apicv && ((val >> 24) != apic->vcpu->vcpu_id)) {
+ kvm_vm_bugged(apic->vcpu->kvm);
+ break;
+ }
+
+ kvm_apic_set_xapic_id(apic, val >> 24);
break;

case APIC_TASKPRI:
@@ -2613,8 +2623,16 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s, bool set)
{
- if (apic_x2apic_mode(vcpu->arch.apic)) {
- u32 *id = (u32 *)(s->regs + APIC_ID);
+ u32 *id = (u32 *)(s->regs + APIC_ID);
+
+ if (!apic_x2apic_mode(vcpu->arch.apic)) {
+ /* Don't allow setting APIC ID with any APIC acceleration
+ * enabled to avoid unexpected issues
+ */
+ if (enable_apicv && (*id >> 24) != vcpu->vcpu_id)
+ return -EINVAL;
+ } else {
+
u32 *ldr = (u32 *)(s->regs + APIC_LDR);
u64 icr;

--
2.26.3