[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] hvc/xen: prevent concurrent accesses to the shared ring


  • To: Stefano Stabellini <sstabellini@xxxxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Wed, 30 Nov 2022 10:26:07 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=2TzLxx3p+XBF6obhIGVlm//r/ntLl/f7S09/Az1T3TE=; b=C8ArNvCUME4TFpdm1A/YLoQigcFu3maxdghz98L3OmfkVx9K3BT7dAxQZTT+giL3DOKQrRPMj09wKgDBtI/Co0HOugYHtfPu58CssyjokS438oxJ8zcg+WwvPxsv2ML80vGnmmm3cuSIxtDc5A9TivyIhp0AeuDkM6m0HUMA2twCPRymrWvPbeASoKN2E0ml7n1B0w8GJGQsplhG1l4+cTQaIfdx82bIRY2CZyfhPi6U5rdpo1G1G+6CMnvAgbf96bPRt3yDj2WQifZJWjrvs7Dt6RiZCtvLeMrFoQSOClD3OReouQsUR+p9L6joAXh/mvp9xw/nBdaOU4WegaqHug==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Mem0jsJxVYcRnfsmc+k/2LMZTuFHuUdkWiyD1lPHwlvAPUU3cLbfwVRy0UPUm7G5IA/j9dxAHBHui+TcBCEYoGWCMx8Lqqm3sLY5qOWNHQjAvWo66r4jywrXnBo7FUGTegelcFyjDgrR30KIsZ10u0B0XlhRGHwNtKyhdplR47ewU8jXXf+NEstGJIzIIbOr8T/zrCRUaU+sk+jCqRZ5P5gggV/ssUI+5y0FI0U2gZau/r83C2R6YNd2J0eOxfcWcEFJ6/z3jXXc2TGNciWWgrvQdPbYR2MqxqtVtmKg+AnBuCt+Fsz5XBsu91f0EtDWWkUikeHBc7f7Ec4CEeL7eg==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: linux-kernel@xxxxxxxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxxx, Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>, Jiri Slaby <jirislaby@xxxxxxxxxx>, Juergen Gross <jgross@xxxxxxxx>, Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Olof Johansson <olof@xxxxxxxxx>, Ingo Molnar <mingo@xxxxxxx>, Jeremy Fitzhardinge <jeremy@xxxxxxxxxxxxx>, Chris Wright <chrisw@xxxxxxxxxxxx>, linuxppc-dev@xxxxxxxxxxxxxxxx
  • Delivery-date: Wed, 30 Nov 2022 09:26:51 +0000
  • Ironport-data: A9a23:VB20q60by8+5IVB2c/bD5ahxkn2cJEfYwER7XKvMYLTBsI5bpzwFy 2BKD2zTaPmMZWOhLtAnbom0oxsDsJLcz9ZnSlM6pC1hF35El5HIVI+TRqvS04F+DeWYFR46s J9OAjXkBJppJpMJjk71atANlVEliefTAOK5ULSfUsxIbVcMYD87jh5+kPIOjIdtgNyoayuAo tq3qMDEULOf82cc3lk8tuTS9nuDgNyo4GlC5wVlPagS1LPjvyJ94Kw3dPnZw0TQGuG4LsbiL 87fwbew+H/u/htFIrtJRZ6iLyXm6paLVeS/oiI+t5qK23CulQRrukoPD9IOaF8/ttm8t4sZJ OOhF3CHYVxB0qXkwIzxWvTDes10FfUuFLTveRBTvSEPpqFvnrSFL/hGVSkL0YMkFulfHGV// t48IRc2awmbieW86rP4UvNAr5F2RCXrFNt3VnBI6xj8VK9ja7aTBqLA6JlfwSs6gd1IEbDGf c0FZDFzbRPGJRpSJlMQD5F4l+Ct7pX9W2QA9BTJ+uxqsy6Kkl0ZPLvFabI5fvSQQspYhACAr 3/u9GXlGBAKcteYzFJp91r827+Tx3qjAer+EpXkqdR0q0LJ91YwGS0tDVGf/NWCpm6xDoc3x 0s8v3BGQbIJ3FewUtD3Uhm8oXiFlh0RQdxdF6s98g7l4q7V5RuJQ2sJVDhMbPQ4u8IsAz8nz FmEm5XuHzMHmK2YTzeR+6mZqRu2ODMJNikSaCkcVwwH7tL/5oYpgXrnQcxuH621ptn0Hyzgz TeXqiQ3m7QUi4gMzarT1VLGmTO3opHDXyY26x/RU2bj6Rl2DKanaJav8kPz9utbIcCSSVzpl HIDgcmFqucVEYuKijeOUc0KBrii4/vDOzrZ6XZtFZQ88zWm+1a4YJtdpjp5IS9BNcIDdxftY V/UvEVX6YM7FH6ra6BwS4+1F8lszbWIPd/lTPHPcfJVZYVqMRSA+Gdpf0H492TsllU8ibk0f JuWb+6oDG0GEuJg3j6/Tfxb1qUkrh3S3kvWTJH/ih6hgbyXYSfMTa9faQXfKOck8KmDvQPZt c5FMNeHwAleV+u4ZTTL9YkULhYBKn1T6Y3KlvG7v9WremJOcFzNwdeIqV/9U+SJR5hoq9o=
  • Ironport-hdrordr: A9a23:KmIqBqyGuaRbmbOWOHBeKrPxTOgkLtp133Aq2lEZdPULSKGlfp GV9sjziyWetN9wYh4dcB67Scy9qFfnhOZICO4qTMyftWjdyRKVxeRZgbcKrAeBJ8STzJ8/6U 4kSdkFNDSSNykEsS+Z2njeLz9I+rDunsGVbKXlvhFQpGlRGt1dBmxCe2Km+yNNNWt77c1TLu vg2iMLnUvXRV0nKuCAQlUVVenKoNPG0LrgfB49HhYirCWekD+y77b+Mh6AmjMTSSlGz7sO+X XM11WR3NToj9iLjjvnk0PD5ZVfn9XsjvNFGcy3k8AQbhn8lwqyY4xlerua+BQ4uvum5loGmM TF5z0gI8NwwXXMeXzdm2qn5yDQlBIVr1Pyw16RhnXu5eT/WTIBEsJEwaZUaAHQ5UYMtMx1lP sj5RPQi7NnSTf72Ajt7dnBUB9n0mKyvHoZiOYWy1hSS5EXZrN9pZEWuGlVDJADNiTn751PKp gmMOjsoNJtNX+KZXHQuWdihPSqQ3QIBx+DBnMPv8SEugIm6UxR/g89/ogyj30A/JUyR91v/O LfKJllk7lIU4s/cb99LP1pe7r4NkX9BTb3dE6CK1XuE68Kf1jXrYTs3bkz7Oa2PLQV0ZoJno jbWl8wjx98R6vXM7zP4HR3yGGPfI3kNg6diP22pqIJ9oEUfYCbcBFqEzsV4o6dS/Z2OLyoZx /8AuMTPxbZFxqfJW945XyBZ3BsEwhubCQ0gKdOZ7vcmLO9FqTa8srmTd30GJ3BVR4ZZ0KXOA pxYNG0HrQM0nyW
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Tue, Nov 29, 2022 at 02:12:10PM -0800, Stefano Stabellini wrote:
> On Tue, 29 Nov 2022, Roger Pau Monne wrote:
> > The hvc machinery registers both a console and a tty device based on
> > the hv ops provided by the specific implementation.  Those two
> > interfaces however have different locks, and there's no single locks
> > that's shared between the tty and the console implementations, hence
> > the driver needs to protect itself against concurrent accesses.
> > Otherwise concurrent calls using the split interfaces are likely to
> > corrupt the ring indexes, leaving the console unusable.
> >
> > Introduce a lock to xencons_info to serialize accesses to the shared
> > ring.  This is only required when using the shared memory console,
> > concurrent accesses to the hypercall based console implementation are
> > not an issue.
> > 
> > Note the conditional logic in domU_read_console() is slightly modified
> > so the notify_daemon() call can be done outside of the locked region:
> > it's an hypercall and there's no need for it to be done with the lock
> > held.
> > 
> > Fixes: b536b4b96230 ('xen: use the hvc console infrastructure for Xen 
> > console')
> > Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
> > ---
> > While the write handler (domU_write_console()) is used by both the
> > console and the tty ops, that's not the case for the read side
> > (domU_read_console()).  It's not obvious to me whether we could get
> > concurrent poll calls from the poll_get_char tty hook, hence stay on
> > the safe side also serialize read accesses in domU_read_console().
> 
> I think domU_read_console doesn't need it. struct hv_ops and struct
> console are both already locked although independently locked.
> 
> I think we shouldn't add an unrequired lock there.

Not all accesses are done using the tty lock.  There's a path using
tty_find_polling_driver() in kgdboc.c that directly calls into the
->poll_get_char() hook without any locks apparently taken.

> 
> > ---
> >  drivers/tty/hvc/hvc_xen.c | 16 ++++++++++++++--
> >  1 file changed, 14 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
> > index 7c23112dc923..d65741983837 100644
> > --- a/drivers/tty/hvc/hvc_xen.c
> > +++ b/drivers/tty/hvc/hvc_xen.c
> > @@ -43,6 +43,7 @@ struct xencons_info {
> >     int irq;
> >     int vtermno;
> >     grant_ref_t gntref;
> > +   spinlock_t ring_lock;
> >  };
> >  
> >  static LIST_HEAD(xenconsoles);
> > @@ -84,12 +85,15 @@ static int __write_console(struct xencons_info *xencons,
> >     XENCONS_RING_IDX cons, prod;
> >     struct xencons_interface *intf = xencons->intf;
> >     int sent = 0;
> > +   unsigned long flags;
> >  
> > +   spin_lock_irqsave(&xencons->ring_lock, flags);
> >     cons = intf->out_cons;
> >     prod = intf->out_prod;
> >     mb();                   /* update queue values before going on */
> >  
> >     if ((prod - cons) > sizeof(intf->out)) {
> > +           spin_unlock_irqrestore(&xencons->ring_lock, flags);
> >             pr_err_once("xencons: Illegal ring page indices");
> >             return -EINVAL;
> >     }
> > @@ -99,6 +103,7 @@ static int __write_console(struct xencons_info *xencons,
> >  
> >     wmb();                  /* write ring before updating pointer */
> >     intf->out_prod = prod;
> > +   spin_unlock_irqrestore(&xencons->ring_lock, flags);
> >  
> >     if (sent)
> >             notify_daemon(xencons);
> > @@ -141,16 +146,19 @@ static int domU_read_console(uint32_t vtermno, char 
> > *buf, int len)
> >     int recv = 0;
> >     struct xencons_info *xencons = vtermno_to_xencons(vtermno);
> >     unsigned int eoiflag = 0;
> > +   unsigned long flags;
> >  
> >     if (xencons == NULL)
> >             return -EINVAL;
> >     intf = xencons->intf;
> >  
> > +   spin_lock_irqsave(&xencons->ring_lock, flags);
> >     cons = intf->in_cons;
> >     prod = intf->in_prod;
> >     mb();                   /* get pointers before reading ring */
> >  
> >     if ((prod - cons) > sizeof(intf->in)) {
> > +           spin_unlock_irqrestore(&xencons->ring_lock, flags);
> >             pr_err_once("xencons: Illegal ring page indices");
> >             return -EINVAL;
> >     }
> > @@ -174,10 +182,13 @@ static int domU_read_console(uint32_t vtermno, char 
> > *buf, int len)
> >             xencons->out_cons = intf->out_cons;
> >             xencons->out_cons_same = 0;
> >     }
> > +   if (!recv && xencons->out_cons_same++ > 1) {
> > +           eoiflag = XEN_EOI_FLAG_SPURIOUS;
> > +   }
> > +   spin_unlock_irqrestore(&xencons->ring_lock, flags);
> > +
> >     if (recv) {
> >             notify_daemon(xencons);
> > -   } else if (xencons->out_cons_same++ > 1) {
> > -           eoiflag = XEN_EOI_FLAG_SPURIOUS;
> >     }
> >  
> >     xen_irq_lateeoi(xencons->irq, eoiflag);
> > @@ -576,6 +587,7 @@ static int __init xen_hvc_init(void)
> >  
> >             info = vtermno_to_xencons(HVC_COOKIE);
> >             info->irq = bind_evtchn_to_irq_lateeoi(info->evtchn);
> > +           spin_lock_init(&info->ring_lock);
> 
> Don't we also need a call to spin_lock_init in xencons_connect_backend
> and xen_cons_init and xenboot_console_setup ?

Not in xencons_connect_backend(), as that's called on resume.  Will
fix the missing lock init, didn't realize the console init paths are
so convoluted.

Early PV console on the shared ring worked fine,  I wonder why that
didn't explode.

Thanks, Roger.



 


Rackspace

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