[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH for-4.9 v2] hvm/vpt: fix inconsistent views of vIOAPIC in vmx_intr_assist()
On Fri, Apr 28, 2017 at 02:36:11AM -0600, Jan Beulich wrote: >>>> On 27.04.17 at 04:47, <chao.gao@xxxxxxxxx> wrote: >> When injecting periodic timer interrupt in vmx_intr_assist(), >> multi-read operations are done during one event delivery. For >> example, if a periodic timer interrupt is from PIT, when set the >> corresponding bit in vIRR, the corresponding RTE is accessed in >> pt_update_irq(). When this function returns, it accesses the RTE >> again to get the vector it sets in vIRR. Between the two >> accesses, the content of RTE may have been changed by another CPU >> for no protection method in use. This case can incur the >> assertion failure in vmx_intr_assist(). > >Btw., irrespective of this I'm not convinced this patch really is >4.9 material: While analyzing possible causes for the ASSERT() >to trigger, you've found a way no real OS would ever use. And >we'll need to do something about that ASSERT() anyway before >4.9 goes out. Fine to me. >> @@ -253,6 +263,7 @@ int pt_update_irq(struct vcpu *v) >> struct periodic_time *pt, *temp, *earliest_pt; >> uint64_t max_lag; >> int irq, is_lapic; >> + bool handle_by_pic = false; > >What do you need this variable for? You can simply clear is_lapic >instead. And if you needed it, please follow the naming of the >other one (i.e. would want to be is_pic). The interrupt source and interrupt controller is different here. for interrupt source we have RTSRC_isa and RTSRC_lapic. I think is_lapic is related to interrupt source. and 'handle_by_pic' means that vpic relay this interrupt, which is relevant to struct hvm_intsrc. Anyhow, it is not a big problem. > >> @@ -297,7 +308,15 @@ int pt_update_irq(struct vcpu *v) >> else >> { >> hvm_isa_irq_deassert(v->domain, irq); >> - hvm_isa_irq_assert(v->domain, irq); >> + spin_lock(&v->domain->arch.hvm_domain.irq_lock); >> + hvm_isa_irq_assert_locked(v->domain, irq); >> + if ( platform_legacy_irq(irq) && vlapic_accept_pic_intr(v) && >> + (&v->domain->arch.hvm_domain)->vpic[irq >> 3].int_output ) > >Please don't pointlessly complicate expressions: There's no need >to take the address of v->domain->arch.hvm_domain here. (I >notice that it has been this way originally, but as you're touching >it, you should also clean this up.) will do. > >> + { >> + handle_by_pic = true; >> + pt_set_latched_vector(earliest_pt, hvm_intsrc_lapic); > >I don't follow: If the interrupt is to be handled by the PIC, why >do you need to latch the vector in that case at all, and even >more so _only_ in that case? When delivered via PIC, the IO-APIC >RTE won't have a valid vector field anyway (it's supposed to be >in ExtINT mode; see __vlapic_accept_pic_intr()). Am I overlooking >anything here? Ok. I made a mistake here. Only need latching vector for the inverse case. > >> @@ -305,12 +324,7 @@ int pt_update_irq(struct vcpu *v) >> * IRR is returned and used to set eoi_exit_bitmap for virtual >> * interrupt delivery case. Otherwise return -1 to do nothing. >> */ >> - if ( !is_lapic && >> - platform_legacy_irq(irq) && vlapic_accept_pic_intr(v) && >> - (&v->domain->arch.hvm_domain)->vpic[irq >> 3].int_output ) >> - return -1; >> - else >> - return pt_irq_vector(earliest_pt, hvm_intsrc_lapic); >> + return handle_by_pic ? -1 : pt_irq_vector(earliest_pt, >> hvm_intsrc_lapic); > >Please either use unlikely() or invert the condition and swap the >other two operands. Agree. > >> --- a/xen/include/asm-x86/hvm/vpt.h >> +++ b/xen/include/asm-x86/hvm/vpt.h >> @@ -46,6 +46,12 @@ struct periodic_time { >> #define PTSRC_lapic 2 /* LAPIC time source */ >> u8 source; /* PTSRC_ */ >> u8 irq; >> + /* >> + * Vector set in vIRR in one interrupt delivery. Using this value can >> + * avoid reading the IOAPIC RTE again. Valid only when its source is >> + * 'PTSRC_isa' and handled by vlapic. >> + */ >> + int16_t latched_vector; > >Why is this PTSRC_isa specific? In the description you say >"for example, if a periodic timer interrupt is from PIT". PTSRC_lapic means the pt is lapic interrupt timer. We can read 'irq' field directly from structure periodic_timer. For other cases, namely PTSRC_isa, we should get vector from vioapic or vpic. For cases handle by vpic, the vector is generated in hvm_vcpu_ack_pending_irq(). I can latched here. So we have two restrictions. The first one is easy to remove. The latter I think needs some changes to hvm_vcpu_ack_pending_irq(). > >And then, if there is a requirement for this to be handled by the >LAPIC, you don't need a 16-bit field: You can easily use 0 to >indicate the field is not valid, as vectors below 0x10 are all invalid >in that case. will do. Thanks Chao _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |