@@ -2046,10 +2046,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:
@@ -2617,8 +2627,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;
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@redhat.com> --- arch/x86/kvm/lapic.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)