hw/char/sifive_uart: Free fifo on unrealize

We previously allocate the fifo on reset and never free it, which means
we are leaking memory.

Instead let's allocate on realize and free on unrealize.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Tested-by: Clément Chigot <chigot@adacore.com>
Message-ID: <20250303023120.157221-1-alistair.francis@wdc.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
Alistair Francis 2025-03-03 12:31:20 +10:00 committed by Philippe Mathieu-Daudé
parent 543671d990
commit 7fc96bc4fc

View File

@ -251,6 +251,23 @@ static int sifive_uart_be_change(void *opaque)
return 0; return 0;
} }
static void sifive_uart_reset_enter(Object *obj, ResetType type)
{
SiFiveUARTState *s = SIFIVE_UART(obj);
s->txfifo = 0;
s->ie = 0;
s->ip = 0;
s->txctrl = 0;
s->rxctrl = 0;
s->div = 0;
s->rx_fifo_len = 0;
memset(s->rx_fifo, 0, SIFIVE_UART_RX_FIFO_SIZE);
fifo8_reset(&s->tx_fifo);
}
static const Property sifive_uart_properties[] = { static const Property sifive_uart_properties[] = {
DEFINE_PROP_CHR("chardev", SiFiveUARTState, chr), DEFINE_PROP_CHR("chardev", SiFiveUARTState, chr),
}; };
@ -270,30 +287,24 @@ static void sifive_uart_realize(DeviceState *dev, Error **errp)
{ {
SiFiveUARTState *s = SIFIVE_UART(dev); SiFiveUARTState *s = SIFIVE_UART(dev);
fifo8_create(&s->tx_fifo, SIFIVE_UART_TX_FIFO_SIZE);
s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL, s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
fifo_trigger_update, s); fifo_trigger_update, s);
qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx, if (qemu_chr_fe_backend_connected(&s->chr)) {
sifive_uart_event, sifive_uart_be_change, s, qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
NULL, true); sifive_uart_event, sifive_uart_be_change, s,
NULL, true);
}
} }
static void sifive_uart_reset_enter(Object *obj, ResetType type) static void sifive_uart_unrealize(DeviceState *dev)
{ {
SiFiveUARTState *s = SIFIVE_UART(obj); SiFiveUARTState *s = SIFIVE_UART(dev);
s->txfifo = 0; fifo8_destroy(&s->tx_fifo);
s->ie = 0;
s->ip = 0;
s->txctrl = 0;
s->rxctrl = 0;
s->div = 0;
s->rx_fifo_len = 0;
memset(s->rx_fifo, 0, SIFIVE_UART_RX_FIFO_SIZE);
fifo8_create(&s->tx_fifo, SIFIVE_UART_TX_FIFO_SIZE);
} }
static void sifive_uart_reset_hold(Object *obj, ResetType type) static void sifive_uart_reset_hold(Object *obj, ResetType type)
@ -329,6 +340,7 @@ static void sifive_uart_class_init(ObjectClass *oc, void *data)
ResettableClass *rc = RESETTABLE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(oc);
dc->realize = sifive_uart_realize; dc->realize = sifive_uart_realize;
dc->unrealize = sifive_uart_unrealize;
dc->vmsd = &vmstate_sifive_uart; dc->vmsd = &vmstate_sifive_uart;
rc->phases.enter = sifive_uart_reset_enter; rc->phases.enter = sifive_uart_reset_enter;
rc->phases.hold = sifive_uart_reset_hold; rc->phases.hold = sifive_uart_reset_hold;