[PATCH v2] hw/char/pl011: support backend hotswap

Alexander Mikhalitsyn posted 1 patch 1 month, 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260811081401.51771-1-alexander@mihalicyn.com
Maintainers: Peter Maydell <peter.maydell@linaro.org>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
There is a newer version of this series
hw/char/pl011.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
[PATCH v2] hw/char/pl011: support backend hotswap
Posted by Alexander Mikhalitsyn 1 month, 2 weeks ago
From: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>

Currently, when Incus issues "chardev-change" QMP command to change
chardev backend from ringbuf to socket it receives an error (with aarch64 VM):
"Chardev user does not support chardev hotswap" [1], [2]

Let's fix this by properly implementing BackendChangeHandler for pl011.

Please, note that we have to "replay" CHR_IOCTL_SERIAL_SET_BREAK, because
if BRK bit was set before backend change (i.e. (s->lcr & LCR_BRK) is true),
then after change we need to send break to a new backend too.

Link: https://discuss.linuxcontainers.org/t/unable-to-connect-to-vm-console-on-arm-architecture/23096/3 [1]
Link: https://github.com/lxc/distrobuilder/issues/892 [2]
Reported-by: Stéphane Graber <stgraber@stgraber.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
---
v2:
	- fixed a typo in commit author name
	  [ I did `git format-patch` and copied this patch from my Raspberry PI
	    dev/test machine and it turns out that I have a stupid typo in my
	    `git config get user.name` on that machine. ]
	- added RWB tag from Alex Bennée
	- adjusted a commit message
---
 hw/char/pl011.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index cb12c3e224f..3622248ec0c 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -660,12 +660,26 @@ static void pl011_init(Object *obj)
     s->id = pl011_id_arm;
 }
 
+static int pl011_be_change(void *opaque)
+{
+    PL011State *s = opaque;
+    int break_enable = s->lcr & LCR_BRK;
+
+    qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
+                             pl011_event, pl011_be_change, s, NULL, true);
+
+    qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
+                      &break_enable);
+
+    return 0;
+}
+
 static void pl011_realize(DeviceState *dev, Error **errp)
 {
     PL011State *s = PL011(dev);
 
     qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
-                             pl011_event, NULL, s, NULL, true);
+                             pl011_event, pl011_be_change, s, NULL, true);
 }
 
 static void pl011_reset(DeviceState *dev)
-- 
2.47.3


Re: [PATCH v2] hw/char/pl011: support backend hotswap
Posted by Philippe Mathieu-Daudé 1 month, 2 weeks ago
Hi Alexander,

On 11/8/26 10:14, Alexander Mikhalitsyn wrote:
> From: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
> 
> Currently, when Incus issues "chardev-change" QMP command to change
> chardev backend from ringbuf to socket it receives an error (with aarch64 VM):
> "Chardev user does not support chardev hotswap" [1], [2]
> 
> Let's fix this by properly implementing BackendChangeHandler for pl011.
> 
> Please, note that we have to "replay" CHR_IOCTL_SERIAL_SET_BREAK, because
> if BRK bit was set before backend change (i.e. (s->lcr & LCR_BRK) is true),
> then after change we need to send break to a new backend too.
> 
> Link: https://discuss.linuxcontainers.org/t/unable-to-connect-to-vm-console-on-arm-architecture/23096/3 [1]
> Link: https://github.com/lxc/distrobuilder/issues/892 [2]
> Reported-by: Stéphane Graber <stgraber@stgraber.org>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
> ---
> v2:
> 	- fixed a typo in commit author name
> 	  [ I did `git format-patch` and copied this patch from my Raspberry PI
> 	    dev/test machine and it turns out that I have a stupid typo in my
> 	    `git config get user.name` on that machine. ]
> 	- added RWB tag from Alex Bennée
> 	- adjusted a commit message
> ---
>   hw/char/pl011.c | 16 +++++++++++++++-
>   1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/char/pl011.c b/hw/char/pl011.c
> index cb12c3e224f..3622248ec0c 100644
> --- a/hw/char/pl011.c
> +++ b/hw/char/pl011.c
> @@ -660,12 +660,26 @@ static void pl011_init(Object *obj)
>       s->id = pl011_id_arm;
>   }
>   
> +static int pl011_be_change(void *opaque)
> +{
> +    PL011State *s = opaque;
> +    int break_enable = s->lcr & LCR_BRK;
> +
> +    qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
> +                             pl011_event, pl011_be_change, s, NULL, true);
> +
> +    qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
> +                      &break_enable);

Could we factor the common code used in pl011_write() in a common
helper?

> +
> +    return 0;
> +}
> +
>   static void pl011_realize(DeviceState *dev, Error **errp)
>   {
>       PL011State *s = PL011(dev);
>   
>       qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
> -                             pl011_event, NULL, s, NULL, true);
> +                             pl011_event, pl011_be_change, s, NULL, true);
>   }
>   
>   static void pl011_reset(DeviceState *dev)


Re: [PATCH v2] hw/char/pl011: support backend hotswap
Posted by Alexander Mikhalitsyn 1 month, 2 weeks ago
Am Di., 11. Aug. 2026 um 10:30 Uhr schrieb Philippe Mathieu-Daudé
<philmd@oss.qualcomm.com>:
>
> Hi Alexander,
>
> On 11/8/26 10:14, Alexander Mikhalitsyn wrote:
> > From: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
> >
> > Currently, when Incus issues "chardev-change" QMP command to change
> > chardev backend from ringbuf to socket it receives an error (with aarch64 VM):
> > "Chardev user does not support chardev hotswap" [1], [2]
> >
> > Let's fix this by properly implementing BackendChangeHandler for pl011.
> >
> > Please, note that we have to "replay" CHR_IOCTL_SERIAL_SET_BREAK, because
> > if BRK bit was set before backend change (i.e. (s->lcr & LCR_BRK) is true),
> > then after change we need to send break to a new backend too.
> >
> > Link: https://discuss.linuxcontainers.org/t/unable-to-connect-to-vm-console-on-arm-architecture/23096/3 [1]
> > Link: https://github.com/lxc/distrobuilder/issues/892 [2]
> > Reported-by: Stéphane Graber <stgraber@stgraber.org>
> > Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> > Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
> > ---
> > v2:
> >       - fixed a typo in commit author name
> >         [ I did `git format-patch` and copied this patch from my Raspberry PI
> >           dev/test machine and it turns out that I have a stupid typo in my
> >           `git config get user.name` on that machine. ]
> >       - added RWB tag from Alex Bennée
> >       - adjusted a commit message
> > ---
> >   hw/char/pl011.c | 16 +++++++++++++++-
> >   1 file changed, 15 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/char/pl011.c b/hw/char/pl011.c
> > index cb12c3e224f..3622248ec0c 100644
> > --- a/hw/char/pl011.c
> > +++ b/hw/char/pl011.c
> > @@ -660,12 +660,26 @@ static void pl011_init(Object *obj)
> >       s->id = pl011_id_arm;
> >   }
> >
> > +static int pl011_be_change(void *opaque)
> > +{
> > +    PL011State *s = opaque;
> > +    int break_enable = s->lcr & LCR_BRK;
> > +
> > +    qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
> > +                             pl011_event, pl011_be_change, s, NULL, true);
> > +
> > +    qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
> > +                      &break_enable);
>

Dear Philippe,

thank you for the review!

> Could we factor the common code used in pl011_write() in a common
> helper?

yep, I think we can factor out CHR_IOCTL_SERIAL_SET_BREAK call
together with break_enable variable.

Please, can you look into our thread with Alex Bennée:
https://lore.kernel.org/qemu-devel/87h5l22faq.fsf@draig.linaro.org/

It would be great to have your opinion there.

Kind regards,
Alex

>
> > +
> > +    return 0;
> > +}
> > +
> >   static void pl011_realize(DeviceState *dev, Error **errp)
> >   {
> >       PL011State *s = PL011(dev);
> >
> >       qemu_chr_fe_set_handlers(&s->chr, pl011_can_receive, pl011_receive,
> > -                             pl011_event, NULL, s, NULL, true);
> > +                             pl011_event, pl011_be_change, s, NULL, true);
> >   }
> >
> >   static void pl011_reset(DeviceState *dev)
>