On Wed, 2026-09-30 at 10:12 -0300, Daniel Henrique Barboza wrote:
> Hello,
> 
> 
> Seems like we have a mem leak down there:
> 
> On 9/27/2026 5:13 PM, Kuan-Wei Chiu wrote:
> > Add the dw8250 uart support. This hardware is a widely used 16550A
> > derivative that includes additional registers.
> > 
> > Without this specific device support, the Linux 8250_dw driver
> > fails to
> > probe the extended registers (UCV, CPR, etc.), which are essential
> > for
> > correct feature detection.
> > 
> > Signed-off-by: Kuan-Wei Chiu <[email protected]>
> > Reviewed-by: Chao Liu <[email protected]>
> > Reviewed-by: Alistair Francis <[email protected]>
> > ---
> >   MAINTAINERS              |   6 ++
> >   hw/char/Kconfig          |   4 ++
> >   hw/char/dw8250.c         | 131
> > +++++++++++++++++++++++++++++++++++++++
> >   hw/char/meson.build      |   1 +
> >   include/hw/char/dw8250.h |  27 ++++++++
> >   5 files changed, 169 insertions(+)
> >   create mode 100644 hw/char/dw8250.c
> >   create mode 100644 include/hw/char/dw8250.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 6be9c5725b..d4e9cf61ea 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2848,6 +2848,12 @@ S: Maintained
> >   F: hw/i2c/designware_i2c.c
> >   F: include/hw/i2c/designware_i2c.h
> >   
> > +DesignWare 8250 UART
> > +M: Kuan-Wei Chiu <[email protected]>
> > +S: Maintained
> > +F: hw/char/dw8250.c
> > +F: include/hw/char/dw8250.h
> > +
> >   Generic Loader
> >   M: Alistair Francis <[email protected]>
> >   S: Maintained
> > diff --git a/hw/char/Kconfig b/hw/char/Kconfig
> > index 020c0a84bb..418d99b757 100644
> > --- a/hw/char/Kconfig
> > +++ b/hw/char/Kconfig
> > @@ -95,3 +95,7 @@ config IP_OCTAL_232
> >       bool
> >       default y
> >       depends on IPACK
> > +
> > +config DW8250
> > +    bool
> > +    select SERIAL
> > diff --git a/hw/char/dw8250.c b/hw/char/dw8250.c
> > new file mode 100644
> > index 0000000000..ccf05dd9ad
> > --- /dev/null
> > +++ b/hw/char/dw8250.c
> > @@ -0,0 +1,131 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Synopsys DesignWare APB UART (DW 8250)
> > + *
> > + * Copyright (c) 2026 Kuan-Wei Chiu <[email protected]>
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/log.h"
> > +#include "qapi/error.h"
> > +#include "hw/char/dw8250.h"
> > +#include "hw/core/qdev-properties.h"
> > +#include "hw/core/qdev-properties-system.h"
> > +
> > +#define DW_UART_REGION_SIZE 0x100
> > +
> > +#define DW_UART_RE_EN (0xB4 >> 2) /* Receiver Output Enable
> > Register */
> > +#define DW_UART_DLF   (0xC0 >> 2) /* Divisor Latch Fraction
> > Register */
> > +#define DW_UART_CPR   (0xF4 >> 2) /* Component Parameter Register
> > */
> > +#define DW_UART_UCV   (0xF8 >> 2) /* UART Component Version */
> > +#define DW_UART_CTR   (0xFC >> 2) /* Component Type Register */
> > +
> > +#define DW_UART_UCV_VALUE 0x3332332A /* "323*" -> v3.23a */
> > +#define DW_UART_CTR_VALUE 0x44570110 /* "DW" */
> > +
> > +static uint64_t dw8250_ext_read(void *opaque, hwaddr addr,
> > unsigned int size)
> > +{
> > +    DW8250State *s = opaque;
> > +
> > +    switch (addr >> s->regshift) {
> > +    case DW_UART_UCV:
> > +        return DW_UART_UCV_VALUE;
> > +    case DW_UART_CPR:
> > +        return 0x00000000; /* No advanced features (DMA, extra
> > FIFOs) */
> > +    case DW_UART_CTR:
> > +        return DW_UART_CTR_VALUE;
> > +
> > +    case DW_UART_RE_EN:
> > +    case DW_UART_DLF:
> > +        /*
> > +         * Return 0 to indicate these optional features
> > +         * (RS485 and Fractional Divisor) are not implemented.
> > +         */
> > +        return 0x00000000;
> > +
> > +    default:
> > +        return 0;
> > +    }
> > +}
> > +
> > +static void dw8250_ext_write(void *opaque, hwaddr addr, uint64_t
> > val, unsigned int size)
> > +{
> > +    qemu_log_mask(LOG_UNIMP, "%s: Unimplemented write to address
> > 0x%" HWADDR_PRIx "\n",
> > +                  __func__, addr);
> > +}
> > +
> > +static const MemoryRegionOps dw8250_ext_ops = {
> > +    .read = dw8250_ext_read,
> > +    .write = dw8250_ext_write,
> > +    .endianness = DEVICE_LITTLE_ENDIAN,
> > +    .impl = {
> > +        .min_access_size = 4,
> > +        .max_access_size = 4,
> > +    },
> > +    .valid = {
> > +        .min_access_size = 1,
> > +        .max_access_size = 4,
> > +    },
> > +};
> > +
> > +static void dw8250_instance_init(Object *obj)
> > +{
> > +    DW8250State *s = DW8250(obj);
> > +
> > +    s->serial_mm = qdev_new("serial-mm");
> > +    object_property_add_child(obj, "serial-mm", OBJECT(s-
> > >serial_mm));
> 
> ^ here. s->serial_mm is being alloc in qdev_new() and then during
> object_property_add_child().
> 
> This is being fixed by Portia in another patch:
> 
> [PATCH 1/5] hw/char/dw8250: Fix leak when creating child device
> https://lore.kernel.org/qemu-devel/[email protected]/
> 
> 
> Given that this isn't merged yet I suggest fixing the leak in this
> patch instead.

I've pulled in Portia's patch and squashed it. It's a pretty simple fix
and as it's already in my tree it's an easy fix

Alistair

Reply via email to