[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.