Re: [PATCH 1/3] KVM: x86: VMX: __kvm_apic_update_irr must update the IRR atomically

From: Paolo Bonzini
Date: Tue Jul 18 2023 - 07:42:43 EST


On 7/18/23 11:13, Maxim Levitsky wrote:
+ irr_val = READ_ONCE(*((u32 *)(regs + APIC_IRR + i * 0x10)));

Let's separate out the complicated arithmetic, as it recurs below too:

u32 *p_irr = (u32 *)(regs + APIC_IRR + i * 0x10);

+ while (!try_cmpxchg(((u32 *)(regs + APIC_IRR + i * 0x10)),
+ &irr_val, irr_val | pir_val));
+
prev_irr_val = irr_val;
- irr_val |= xchg(&pir[i], 0);
- *((u32 *)(regs + APIC_IRR + i * 0x10)) = irr_val;
- if (prev_irr_val != irr_val) {
- max_updated_irr =
- __fls(irr_val ^ prev_irr_val) + vec;
- }
+ irr_val |= pir_val;
+
+ if (prev_irr_val != irr_val)
+ max_updated_irr = __fls(irr_val ^ prev_irr_val) + vec;

We can write this a bit more cleanly too, and avoid unnecessary
try_cmpxchg too:

prev_irr_val = irr_val;
do
irr_val = prev_irr_val | pir_val;
while (prev_irr_val != irr_val &&
!try_cmpxchg(p_irr, &prev_irr_val, irr_val));

if (prev_irr_val != irr_val)
max_updated_irr = __fls(irr_val ^ prev_irr_val) + vec;

If this looks okay to you, I'll queue the patches for -rc3 and also Cc them for inclusion in stable kernels.

Paolo