virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: Thomas Gleixner <tglx@linutronix.de>, mst@redhat.com
Cc: "Paul E. McKenney" <paulmck@kernel.org>,
	david.kaplan@amd.com, konrad.wilk@oracle.com,
	Peter Zijlstra <peterz@infradead.org>,
	Boqun Feng <boqun.feng@gmail.com>,
	f.hetzelt@tu-berlin.de, linux-kernel@vger.kernel.org,
	virtualization@lists.linux-foundation.org,
	Will Deacon <will@kernel.org>
Subject: Re: [PATCH 7/9] virtio-pci: harden INTX interrupts
Date: Tue, 14 Sep 2021 10:50:06 +0800	[thread overview]
Message-ID: <dae944d8-a658-cb52-2c4b-076c6a41c458@redhat.com> (raw)
In-Reply-To: <875yv4f99j.ffs@tglx>


在 2021/9/14 上午5:36, Thomas Gleixner 写道:
> Jason,
>
> On Mon, Sep 13 2021 at 13:53, Jason Wang wrote:
>> This patch tries to make sure the virtio interrupt handler for INTX
>> won't be called after a reset and before virtio_device_ready(). We
>> can't use IRQF_NO_AUTOEN since we're using shared interrupt
>> (IRQF_SHARED). So this patch tracks the INTX enabling status in a new
>> intx_soft_enabled variable and toggle it during in
>> vp_disable/enable_vectors(). The INTX interrupt handler will check
>> intx_soft_enabled before processing the actual interrupt.
> Ah, there it is :)
>
> Cc'ed our memory ordering wizards as I might be wrong as usual.
>
>> -	if (vp_dev->intx_enabled)
>> +	if (vp_dev->intx_enabled) {
>> +		vp_dev->intx_soft_enabled = false;
>> +		/* ensure the vp_interrupt see this intx_soft_enabled value */
>> +		smp_wmb();
>>   		synchronize_irq(vp_dev->pci_dev->irq);
> As you are synchronizing the interrupt here anyway, what is the value of
> the barrier?
>
>   		vp_dev->intx_soft_enabled = false;
>    		synchronize_irq(vp_dev->pci_dev->irq);
>
> is sufficient because of:
>
> synchronize_irq()
>     do {
>     	raw_spin_lock(desc->lock);
>          in_progress = check_inprogress(desc);
>     	raw_spin_unlock(desc->lock);
>     } while (in_progress);
>
> raw_spin_lock() has ACQUIRE semantics so the store to intx_soft_enabled
> can complete after lock has been acquired which is uninteresting.
>
> raw_spin_unlock() has RELEASE semantics so the store to intx_soft_enabled
> has to be completed before the unlock completes.
>
> So if the interrupt is on the flight then it might or might not see
> intx_soft_enabled == false. But that's true for your barrier construct
> as well.
>
> The important part is that any interrupt for this line arriving after
> synchronize_irq() has completed is guaranteed to see intx_soft_enabled
> == false.
>
> That is what you want to achieve, right?


Right.


>
>>   	for (i = 0; i < vp_dev->msix_vectors; ++i)
>>   		disable_irq(pci_irq_vector(vp_dev->pci_dev, i));
>> @@ -43,8 +47,12 @@ void vp_enable_vectors(struct virtio_device *vdev)
>>   	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
>>   	int i;
>>   
>> -	if (vp_dev->intx_enabled)
>> +	if (vp_dev->intx_enabled) {
>> +		vp_dev->intx_soft_enabled = true;
>> +		/* ensure the vp_interrupt see this intx_soft_enabled value */
>> +		smp_wmb();
> For the enable case the barrier is pointless vs. intx_soft_enabled
>
> CPU 0                                           CPU 1
>
> interrupt                                       vp_enable_vectors()
>    vp_interrupt()
>      if (!vp_dev->intx_soft_enabled)
>         return IRQ_NONE;
>                                                    vp_dev->intx_soft_enabled = true;
>
> IOW, the concurrent interrupt might or might not see the store. That's
> not a problem for legacy PCI interrupts. If it did not see the store and
> the interrupt originated from that device then it will account it as one
> spurious interrupt which will get raised again because those interrupts
> are level triggered and nothing acknowledged it at the device level.


I see.


>
> Now, what's more interesting is that is has to be guaranteed that the
> interrupt which observes
>
>          vp_dev->intx_soft_enabled == true
>
> also observes all preceeding stores, i.e. those which make the interrupt
> handler capable of handling the interrupt.
>
> That's the real problem and for that your barrier is at the wrong place
> because you want to make sure that those stores are visible before the
> store to intx_soft_enabled becomes visible, i.e. this should be:
>
>
>          /* Ensure that all preceeding stores are visible before intx_soft_enabled */
> 	smp_wmb();
> 	vp_dev->intx_soft_enabled = true;


Yes, I see.


>
> Now Micheal is not really enthusiatic about the barrier in the interrupt
> handler hotpath, which is understandable.
>
> As the device startup is not really happening often it's sensible to do
> the following
>
>          disable_irq();
>          vp_dev->intx_soft_enabled = true;
>          enable_irq();
>
> because:
>
>          disable_irq()
>            synchronize_irq()
>
> acts as a barrier for the preceeding stores:
>
>          disable_irq()
>     	  raw_spin_lock(desc->lock);
>            __disable_irq(desc);
>     	  raw_spin_unlock(desc->lock);
>
>            synchronize_irq()
>              do {
>     	      raw_spin_lock(desc->lock);
>                in_progress = check_inprogress(desc);
>     	      raw_spin_unlock(desc->lock);
>              } while (in_progress);
>
>          intx_soft_enabled = true;
>
>          enable_irq();
>
> In this case synchronize_irq() prevents the subsequent store to
> intx_soft_enabled to leak into the __disable_irq(desc) section which in
> turn makes it impossible for an interrupt handler to observe
> intx_soft_enabled == true before the prerequisites which preceed the
> call to disable_irq() are visible.
>
> Of course the memory ordering wizards might disagree, but if they do,
> then we have a massive chase of ordering problems vs. similar constructs
> all over the tree ahead of us.
>
>  From the interrupt perspective the sequence:
>
>          disable_irq();
>          vp_dev->intx_soft_enabled = true;
>          enable_irq();
>
> is perfectly fine as well. Any interrupt arriving during the disabled
> section will be reraised on enable_irq() in hardware because it's a
> level interrupt. Any resulting failure is either a hardware or a
> hypervisor bug.


Thanks a lot for the detail clarifications. Will switch to use 
disable_irq()/enable_irq() if no objection from memory ordering wizards.


>
> Thanks,
>
>          tglx
>

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

  parent reply	other threads:[~2021-09-14  2:50 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-13  5:53 [PATCH 0/9] More virtio hardening Jason Wang
2021-09-13  5:53 ` [PATCH 1/9] virtio-blk: validate num_queues during probe Jason Wang
2021-09-13  7:48   ` Stefano Garzarella
2021-09-14  2:29     ` Jason Wang
2021-09-13 12:05   ` Stefan Hajnoczi
2021-09-13  5:53 ` [PATCH 2/9] virtio: add doc for validate() method Jason Wang
2021-09-13  5:53 ` [PATCH 3/9] virtio-console: switch to use .validate() Jason Wang
2021-09-13  5:53 ` [PATCH 4/9] virtio_console: validate max_nr_ports before trying to use it Jason Wang
2021-09-13  5:53 ` [PATCH 5/9] virtio_config: introduce a new ready method Jason Wang
2021-09-13  5:53 ` [PATCH 6/9] virtio_pci: harden MSI-X interrupts Jason Wang
2021-09-13  6:03   ` Michael S. Tsirkin
2021-09-13  6:08     ` Jason Wang
2021-09-13  6:28       ` Michael S. Tsirkin
2021-09-13  6:34         ` Jason Wang
2021-09-13  6:37           ` Michael S. Tsirkin
2021-09-13  6:43             ` Jason Wang
2021-09-13  7:01               ` Michael S. Tsirkin
2021-09-13  7:15                 ` Jason Wang
2021-09-13  6:50             ` Michael S. Tsirkin
2021-09-13  7:07               ` Jason Wang
2021-09-13 19:38                 ` Thomas Gleixner
2021-09-13 20:54                   ` Michael S. Tsirkin
2021-09-13 22:31                     ` Thomas Gleixner
2021-09-14  2:20                       ` Jason Wang
2021-09-14  8:29                     ` Thomas Gleixner
2021-09-13  5:53 ` [PATCH 7/9] virtio-pci: harden INTX interrupts Jason Wang
2021-09-13  6:33   ` Michael S. Tsirkin
2021-09-13  6:36     ` Jason Wang
2021-09-13  6:41       ` Michael S. Tsirkin
2021-09-13  6:45         ` Jason Wang
2021-09-13  7:02           ` Michael S. Tsirkin
2021-09-13  7:17             ` Jason Wang
2021-09-13 21:36   ` Thomas Gleixner
2021-09-13 22:01     ` Michael S. Tsirkin
2021-09-13 22:20       ` Thomas Gleixner
2021-09-14  2:50     ` Jason Wang [this message]
2021-09-14  9:34     ` Boqun Feng
2021-09-14 11:03     ` Peter Zijlstra
2021-09-14 11:09       ` Thomas Gleixner
2021-09-13  5:53 ` [PATCH 8/9] virtio_ring: fix typos in vring_desc_extra Jason Wang
2021-09-13  5:53 ` [PATCH 9/9] virtio_ring: validate used buffer length Jason Wang
2021-09-13  6:36   ` Michael S. Tsirkin
2021-09-13  6:40     ` Jason Wang
2021-09-13  6:57       ` Michael S. Tsirkin
2021-09-13  7:13         ` Jason Wang
2021-10-05  7:42 ` [PATCH 0/9] More virtio hardening Michael S. Tsirkin
2021-10-11  7:36   ` Jason Wang
2021-10-11 12:36     ` Michael S. Tsirkin
2021-10-12  2:43       ` Jason Wang
2021-10-12  5:44         ` Michael S. Tsirkin
2021-10-12  6:11           ` Jason Wang
2021-10-12  6:35             ` Michael S. Tsirkin
2021-10-12  6:43               ` Jason Wang
2021-10-12  7:03                 ` Michael S. Tsirkin
2021-10-12  8:46                   ` Jason Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dae944d8-a658-cb52-2c4b-076c6a41c458@redhat.com \
    --to=jasowang@redhat.com \
    --cc=boqun.feng@gmail.com \
    --cc=david.kaplan@amd.com \
    --cc=f.hetzelt@tu-berlin.de \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).