From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paolo Bonzini Subject: Re: [PATCH 2/2] KVM: x86: fix edge EOI and IOAPIC reconfig race Date: Wed, 7 Oct 2015 11:31:07 +0200 Message-ID: <5614E65B.1080801@redhat.com> References: <1439473570-13763-1-git-send-email-rkrcmar@redhat.com> <1439473570-13763-3-git-send-email-rkrcmar@redhat.com> <55CCAF5D.8050204@redhat.com> <20150814083857.GA2492@potion.redhat.com> <55CE812E.7080008@redhat.com> <20151006203338.GB4508@potion.brq.redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Steve Rutherford , stable@vger.kernel.org To: =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= Return-path: In-Reply-To: <20151006203338.GB4508@potion.brq.redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-Id: kvm.vger.kernel.org On 06/10/2015 22:33, Radim Kr=C4=8Dm=C3=A1=C5=99 wrote: > 2015-08-15 02:00+0200, Paolo Bonzini: >> On 14/08/2015 10:38, Radim Kr=C4=8Dm=C3=A1=C5=99 wrote: >>>> How do you reproduce the bug? >>> I run rhel4 (2.6.9) kernel on 2 VCPUs and frequently alternate >>> smp_affinity of "timer". The bug is hit within seconds. >> >> Nice, I'll try to make a unit test for it on the plane. :) >=20 > (Time on planes is best spent by sleeping ;]) That's what I ended up doing. :) > What do you think about the series? I had just a few small comments. I had all but forgotten it, sorry. The unit test makes the bug clear, thanks. What's the issue with handle_irq? Paolo > I made a prototype kvm-unit-test ... > (Reproduces with APICv or split irqchip builds.) > ---8<--- > x86: test IO-APIC dest_id modification before >=20 > Regression test for kvm commit $TODO. > Run with '-smp 2'. >=20 > I had problems with handle_irq so this version uses asm workaround; > will fix that in final version. Initialization also presumes that > everything will work as it did on my machines :) > --- > x86/ioapic.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 45 insertions(+), 2 deletions(-) >=20 > diff --git a/x86/ioapic.c b/x86/ioapic.c > index 1fe1ccc9eadd..55f8eea03496 100644 > --- a/x86/ioapic.c > +++ b/x86/ioapic.c > @@ -4,21 +4,27 @@ > #include "smp.h" > #include "desc.h" > #include "isr.h" > +#include "io.h" > =20 > #define EDGE_TRIGGERED 0 > #define LEVEL_TRIGGERED 1 > =20 > -static void set_ioapic_redir(unsigned line, unsigned vec, unsigned t= rig_mode) > +static void __set_ioapic_redir(unsigned line, u8 vec, bool trig_mode= , u8 dest_id) > { > ioapic_redir_entry_t e =3D { > .vector =3D vec, > - .delivery_mode =3D 0, > .trig_mode =3D trig_mode, > + .dest_id =3D dest_id, > }; > =20 > ioapic_write_redir(line, e); > } > =20 > +static void set_ioapic_redir(unsigned line, unsigned vec, unsigned t= rig_mode) > +{ > + __set_ioapic_redir(line, vec, trig_mode, 0); > +} > + > static void set_irq_line(unsigned line, int val) > { > asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line= ))); > @@ -298,6 +304,41 @@ static void test_ioapic_level_retrigger_mask(voi= d) > set_mask(0x0e, false); > } > =20 > +static volatile int pit_working =3D -1; > + > +static void __attribute__((used)) pit_isr_fn(void) > +{ > + if (!pit_working++); > + __set_ioapic_redir(0x2, 0x84, EDGE_TRIGGERED, 1); > + eoi(); > +} > + > +void pit_isr(void); > +asm ( > + "pit_isr: \n" > + " call pit_isr_fn \n" > +#ifndef __x86_64__ > + " iret" > +#else > + " iretq" > +#endif > + ); > + > +static void test_ioapic_eoi_bug(void) > +{ > + if (cpu_count() < 2) > + return; > + > + set_idt_entry(0x84, pit_isr, 0); > + __set_ioapic_redir(0x2, 0x84, EDGE_TRIGGERED, 0); > + > + outb(0x34, 0x43); > + > + for (unsigned loops =3D 100000000; loops && pit_working < 1; loops-= -) > + asm volatile ("nop"); > + > + report("dest_id reconfiguration before EOI", pit_working >=3D 1); > +} > =20 > int main(void) > { > @@ -325,5 +366,7 @@ int main(void) > test_ioapic_level_mask(); > test_ioapic_level_retrigger_mask(); > =20 > + test_ioapic_eoi_bug(); > + > return report_summary(); > } >=20