diff mbox series

chardev: Convert IOReadHandler to read an unsigned number of bytes

Message ID 20181011131413.22208-1-philmd@redhat.com (mailing list archive)
State New, archived
Headers show
Series chardev: Convert IOReadHandler to read an unsigned number of bytes | expand

Commit Message

Philippe Mathieu-Daudé Oct. 11, 2018, 1:14 p.m. UTC
The number of bytes can not be negative nor zero.

Fixed 2 format string:
- hw/char/spapr_vty.c
- hw/usb/ccid-card-passthru.c

Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
See: https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg02212.html

 backends/rng-egd.c          | 4 ++--
 chardev/char-fd.c           | 2 +-
 chardev/char-mux.c          | 4 ++--
 chardev/char-pty.c          | 2 +-
 chardev/char-socket.c       | 4 ++--
 chardev/char-udp.c          | 2 +-
 gdbstub.c                   | 4 ++--
 hw/arm/pxa2xx.c             | 4 ++--
 hw/arm/strongarm.c          | 5 +++--
 hw/char/bcm2835_aux.c       | 4 ++--
 hw/char/cadence_uart.c      | 4 ++--
 hw/char/cmsdk-apb-uart.c    | 4 ++--
 hw/char/digic-uart.c        | 4 ++--
 hw/char/escc.c              | 6 +++---
 hw/char/etraxfs_ser.c       | 4 ++--
 hw/char/exynos4210_uart.c   | 5 +++--
 hw/char/grlib_apbuart.c     | 4 ++--
 hw/char/imx_serial.c        | 4 ++--
 hw/char/ipoctal232.c        | 4 ++--
 hw/char/lm32_juart.c        | 4 ++--
 hw/char/lm32_uart.c         | 4 ++--
 hw/char/mcf_uart.c          | 4 ++--
 hw/char/milkymist-uart.c    | 4 ++--
 hw/char/parallel.c          | 2 +-
 hw/char/pl011.c             | 4 ++--
 hw/char/sclpconsole-lm.c    | 4 ++--
 hw/char/sclpconsole.c       | 4 ++--
 hw/char/serial.c            | 6 +++---
 hw/char/sh_serial.c         | 6 +++---
 hw/char/spapr_vty.c         | 6 +++---
 hw/char/stm32f2xx_usart.c   | 5 +++--
 hw/char/terminal3270.c      | 4 ++--
 hw/char/virtio-console.c    | 4 ++--
 hw/char/xen_console.c       | 4 ++--
 hw/char/xilinx_uartlite.c   | 4 ++--
 hw/ipmi/ipmi_bmc_extern.c   | 8 ++++----
 hw/misc/ivshmem.c           | 6 +++---
 hw/riscv/riscv_htif.c       | 4 ++--
 hw/riscv/sifive_uart.c      | 4 ++--
 hw/usb/ccid-card-passthru.c | 6 +++---
 hw/usb/dev-serial.c         | 4 ++--
 hw/usb/redirect.c           | 4 ++--
 include/qemu/main-loop.h    | 4 ++--
 monitor.c                   | 6 +++---
 net/colo-compare.c          | 6 +++---
 net/filter-mirror.c         | 4 ++--
 net/slirp.c                 | 4 ++--
 qtest.c                     | 4 ++--
 target/xtensa/xtensa-semi.c | 4 ++--
 49 files changed, 107 insertions(+), 104 deletions(-)

Comments

Alberto Garcia Oct. 11, 2018, 2:08 p.m. UTC | #1
On Thu 11 Oct 2018 03:14:13 PM CEST, Philippe Mathieu-Daudé wrote:
> diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
> index 5e09caf851..ba3f3408a2 100644
> --- a/hw/char/ipoctal232.c
> +++ b/hw/char/ipoctal232.c
> @@ -461,14 +461,14 @@ static void mem_write8(IPackDevice *ip, uint32_t addr, uint8_t val)
>      }
>  }
>  
> -static int hostdev_can_receive(void *opaque)
> +static size_t hostdev_can_receive(void *opaque)
>  {
>      SCC2698Channel *ch = opaque;
>      int available_bytes = RX_FIFO_SIZE - ch->rx_pending;
>      return ch->rx_enabled ? available_bytes : 0;
>  }
>  
> -static void hostdev_receive(void *opaque, const uint8_t *buf, int size)
> +static void hostdev_receive(void *opaque, const uint8_t *buf, size_t size)
>  {
>      SCC2698Channel *ch = opaque;
>      IPOctalState *dev = ch->ipoctal;

Acked-by: Alberto Garcia <berto@igalia.com>

Berto
Paolo Bonzini Oct. 11, 2018, 3:14 p.m. UTC | #2
On 11/10/2018 15:14, Philippe Mathieu-Daudé wrote:
> The number of bytes can not be negative nor zero.
> 
> Fixed 2 format string:
> - hw/char/spapr_vty.c
> - hw/usb/ccid-card-passthru.c
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
> See: https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg02212.html

Not that easy; you need to adjust qemu_chr_be_can_write,
qemu_chr_be_write_impl, qemu_chr_be_write (which is where the callbacks
are invoked).

On the other hand, fd_chr_read_poll is not an IOCanReadHandler, and this
patch therefore probably doesn't compile?

Paolo
Philippe Mathieu-Daudé Oct. 11, 2018, 3:24 p.m. UTC | #3
On 11/10/2018 17:14, Paolo Bonzini wrote:
> On 11/10/2018 15:14, Philippe Mathieu-Daudé wrote:
>> The number of bytes can not be negative nor zero.
>>
>> Fixed 2 format string:
>> - hw/char/spapr_vty.c
>> - hw/usb/ccid-card-passthru.c
>>
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
>> ---
>> See: https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg02212.html
> 
> Not that easy; you need to adjust qemu_chr_be_can_write,
> qemu_chr_be_write_impl, qemu_chr_be_write (which is where the callbacks
> are invoked).

OK.

> On the other hand, fd_chr_read_poll is not an IOCanReadHandler, and this
> patch therefore probably doesn't compile?

It does compile.

fd_chr_update_read_handler() uses fd_chr_read_poll with io_add_watch_poll():

GSource *io_add_watch_poll(Chardev *chr,
                        QIOChannel *ioc,
                        IOCanReadHandler *fd_can_read,
                        QIOChannelFunc fd_read,
                        gpointer user_data,
                        GMainContext *context);
Paolo Bonzini Oct. 11, 2018, 3:34 p.m. UTC | #4
On 11/10/2018 17:24, Philippe Mathieu-Daudé wrote:
>> On the other hand, fd_chr_read_poll is not an IOCanReadHandler, and this
>> patch therefore probably doesn't compile?
> It does compile.
> 
> fd_chr_update_read_handler() uses fd_chr_read_poll with io_add_watch_poll():
> 
> GSource *io_add_watch_poll(Chardev *chr,
>                         QIOChannel *ioc,
>                         IOCanReadHandler *fd_can_read,
>                         QIOChannelFunc fd_read,
>                         gpointer user_data,
>                         GMainContext *context);

Oh, that's somewhat weird.  It could just as well return a bool.

However, this made me notice that you need to change e.g. s->max_size's
declaration (in include/chardev/char-fd.h) from int to size_t, and
likewise for: 1) all users of s->max_size, such as len in fd_chr_read;
2) all the similar variables in other char backends.

So it's probably best to structure the series as follows:

1) change fd_can_read from IOCanReadHandler to a GSourceFunc (which
returns a boolean value), changing all "return s->foo" to "return s->foo
> 0;".  Then you can remove the > 0 from

    bool now_active = iwp->fd_can_read(iwp->opaque) > 0;

(Having the > 0 repeated in all backends is now a bit ugly, but there
are future cleanup opportunities here to move the qemu_chr_be_can_write
call to qemu_chr_be_can_write; this way most chardev backends can skip
defining a read_poll function.  But I digress).

2) assert in qemu_chr_be_can_write that the returned value is >= 0

3) for each backend, change the assigned variable from int to size_t

4) now the rest of your patch, touching all front-ends.  The assertion
from (2) now does not make sense anymore, since ->can_read returns an
unsigned value, but perhaps you can keep a "fail-safe" assertion that
(ssize_t)returned_value >= 0 to catch undesired overflows.

Paolo
Philippe Mathieu-Daudé Oct. 11, 2018, 3:53 p.m. UTC | #5
On 11/10/2018 17:34, Paolo Bonzini wrote:
> On 11/10/2018 17:24, Philippe Mathieu-Daudé wrote:
>>> On the other hand, fd_chr_read_poll is not an IOCanReadHandler, and this
>>> patch therefore probably doesn't compile?
>> It does compile.
>>
>> fd_chr_update_read_handler() uses fd_chr_read_poll with io_add_watch_poll():
>>
>> GSource *io_add_watch_poll(Chardev *chr,
>>                         QIOChannel *ioc,
>>                         IOCanReadHandler *fd_can_read,
>>                         QIOChannelFunc fd_read,
>>                         gpointer user_data,
>>                         GMainContext *context);
> 
> Oh, that's somewhat weird.  It could just as well return a bool.
> 
> However, this made me notice that you need to change e.g. s->max_size's
> declaration (in include/chardev/char-fd.h) from int to size_t, and
> likewise for: 1) all users of s->max_size, such as len in fd_chr_read;
> 2) all the similar variables in other char backends.
> 
> So it's probably best to structure the series as follows:
> 
> 1) change fd_can_read from IOCanReadHandler to a GSourceFunc (which
> returns a boolean value), changing all "return s->foo" to "return s->foo
>> 0;".  Then you can remove the > 0 from
> 
>     bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
> 
> (Having the > 0 repeated in all backends is now a bit ugly, but there
> are future cleanup opportunities here to move the qemu_chr_be_can_write
> call to qemu_chr_be_can_write; this way most chardev backends can skip
> defining a read_poll function.  But I digress).
> 
> 2) assert in qemu_chr_be_can_write that the returned value is >= 0
> 
> 3) for each backend, change the assigned variable from int to size_t
> 
> 4) now the rest of your patch, touching all front-ends.  The assertion
> from (2) now does not make sense anymore, since ->can_read returns an
> unsigned value, but perhaps you can keep a "fail-safe" assertion that
> (ssize_t)returned_value >= 0 to catch undesired overflows.

OK! thanks for sorting this :)
diff mbox series

Patch

diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index d2b9ce6cbf..d9d044ef98 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -48,7 +48,7 @@  static void rng_egd_request_entropy(RngBackend *b, RngRequest *req)
     }
 }
 
-static int rng_egd_chr_can_read(void *opaque)
+static size_t rng_egd_chr_can_read(void *opaque)
 {
     RngEgd *s = RNG_EGD(opaque);
     RngRequest *req;
@@ -61,7 +61,7 @@  static int rng_egd_chr_can_read(void *opaque)
     return size;
 }
 
-static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
+static void rng_egd_chr_read(void *opaque, const uint8_t *buf, size_t size)
 {
     RngEgd *s = RNG_EGD(opaque);
     size_t buf_offset = 0;
diff --git a/chardev/char-fd.c b/chardev/char-fd.c
index 2c9b2ce567..622adf92c5 100644
--- a/chardev/char-fd.c
+++ b/chardev/char-fd.c
@@ -69,7 +69,7 @@  static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
     return TRUE;
 }
 
-static int fd_chr_read_poll(void *opaque)
+static size_t fd_chr_read_poll(void *opaque)
 {
     Chardev *chr = CHARDEV(opaque);
     FDChardev *s = FD_CHARDEV(opaque);
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index 6055e76293..50bb398494 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -192,7 +192,7 @@  static void mux_chr_accept_input(Chardev *chr)
     }
 }
 
-static int mux_chr_can_read(void *opaque)
+static size_t mux_chr_can_read(void *opaque)
 {
     MuxChardev *d = MUX_CHARDEV(opaque);
     int m = d->focus;
@@ -209,7 +209,7 @@  static int mux_chr_can_read(void *opaque)
     return 0;
 }
 
-static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
+static void mux_chr_read(void *opaque, const uint8_t *buf, size_t size)
 {
     Chardev *chr = CHARDEV(opaque);
     MuxChardev *d = MUX_CHARDEV(opaque);
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index e8d9a53476..32e39bba3f 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -148,7 +148,7 @@  static GSource *pty_chr_add_watch(Chardev *chr, GIOCondition cond)
     return qio_channel_create_watch(s->ioc, cond);
 }
 
-static int pty_chr_read_poll(void *opaque)
+static size_t pty_chr_read_poll(void *opaque)
 {
     Chardev *chr = CHARDEV(opaque);
     PtyChardev *s = PTY_CHARDEV(opaque);
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index a75b46d9fe..6e88135190 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -120,7 +120,7 @@  static void tcp_chr_accept(QIONetListener *listener,
                            QIOChannelSocket *cioc,
                            void *opaque);
 
-static int tcp_chr_read_poll(void *opaque);
+static size_t tcp_chr_read_poll(void *opaque);
 static void tcp_chr_disconnect(Chardev *chr);
 
 /* Called with chr_write_lock held.  */
@@ -157,7 +157,7 @@  static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
     }
 }
 
-static int tcp_chr_read_poll(void *opaque)
+static size_t tcp_chr_read_poll(void *opaque)
 {
     Chardev *chr = CHARDEV(opaque);
     SocketChardev *s = SOCKET_CHARDEV(opaque);
diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index 097a2f0f42..d388bf21f0 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -65,7 +65,7 @@  static void udp_chr_flush_buffer(UdpChardev *s)
     }
 }
 
-static int udp_chr_read_poll(void *opaque)
+static size_t udp_chr_read_poll(void *opaque)
 {
     Chardev *chr = CHARDEV(opaque);
     UdpChardev *s = UDP_CHARDEV(opaque);
diff --git a/gdbstub.c b/gdbstub.c
index c8478de8f5..0e134eef85 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1916,14 +1916,14 @@  void gdbserver_fork(CPUState *cpu)
     cpu_watchpoint_remove_all(cpu, BP_GDB);
 }
 #else
-static int gdb_chr_can_receive(void *opaque)
+static size_t gdb_chr_can_receive(void *opaque)
 {
   /* We can handle an arbitrarily large amount of data.
    Pick the maximum packet size, which is as good as anything.  */
   return MAX_PACKET_LENGTH;
 }
 
-static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
+static void gdb_chr_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     int i;
 
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index f598a1c053..a72d9bd4fe 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1923,13 +1923,13 @@  static const MemoryRegionOps pxa2xx_fir_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static int pxa2xx_fir_is_empty(void *opaque)
+static size_t pxa2xx_fir_is_empty(void *opaque)
 {
     PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
     return (s->rx_len < 64);
 }
 
-static void pxa2xx_fir_rx(void *opaque, const uint8_t *buf, int size)
+static void pxa2xx_fir_rx(void *opaque, const uint8_t *buf, size_t size)
 {
     PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
     if (!(s->control[0] & (1 << 4)))			/* RXE */
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index ec2627374d..6fdd4da3d0 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1058,7 +1058,7 @@  static void strongarm_uart_rx_push(StrongARMUARTState *s, uint16_t c)
         s->rx_fifo[(s->rx_start + 11) % 12] |= RX_FIFO_ROR;
 }
 
-static int strongarm_uart_can_receive(void *opaque)
+static size_t strongarm_uart_can_receive(void *opaque)
 {
     StrongARMUARTState *s = opaque;
 
@@ -1072,7 +1072,8 @@  static int strongarm_uart_can_receive(void *opaque)
     return 1;
 }
 
-static void strongarm_uart_receive(void *opaque, const uint8_t *buf, int size)
+static void strongarm_uart_receive(void *opaque, const uint8_t *buf,
+                                   size_t size)
 {
     StrongARMUARTState *s = opaque;
     int i;
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index 0364596c55..5dd1b652c0 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -211,7 +211,7 @@  static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
     bcm2835_aux_update(s);
 }
 
-static int bcm2835_aux_can_receive(void *opaque)
+static size_t bcm2835_aux_can_receive(void *opaque)
 {
     BCM2835AuxState *s = opaque;
 
@@ -235,7 +235,7 @@  static void bcm2835_aux_put_fifo(void *opaque, uint8_t value)
     bcm2835_aux_update(s);
 }
 
-static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, int size)
+static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     bcm2835_aux_put_fifo(opaque, *buf);
 }
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index fbdbd463bb..5425abd807 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -216,7 +216,7 @@  static void uart_parameters_setup(CadenceUARTState *s)
     qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 }
 
-static int uart_can_receive(void *opaque)
+static size_t uart_can_receive(void *opaque)
 {
     CadenceUARTState *s = opaque;
     int ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE);
@@ -332,7 +332,7 @@  static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf,
     cadence_uart_xmit(NULL, G_IO_OUT, s);
 }
 
-static void uart_receive(void *opaque, const uint8_t *buf, int size)
+static void uart_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     CadenceUARTState *s = opaque;
     uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
index ddfbb25c24..c1437674a5 100644
--- a/hw/char/cmsdk-apb-uart.c
+++ b/hw/char/cmsdk-apb-uart.c
@@ -108,7 +108,7 @@  static void cmsdk_apb_uart_update(CMSDKAPBUART *s)
     qemu_set_irq(s->uartint, !!(s->intstatus));
 }
 
-static int uart_can_receive(void *opaque)
+static size_t uart_can_receive(void *opaque)
 {
     CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
 
@@ -119,7 +119,7 @@  static int uart_can_receive(void *opaque)
     return 0;
 }
 
-static void uart_receive(void *opaque, const uint8_t *buf, int size)
+static void uart_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     CMSDKAPBUART *s = CMSDK_APB_UART(opaque);
 
diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c
index ccc75eaa4d..f805ee5766 100644
--- a/hw/char/digic-uart.c
+++ b/hw/char/digic-uart.c
@@ -112,14 +112,14 @@  static const MemoryRegionOps uart_mmio_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static int uart_can_rx(void *opaque)
+static size_t uart_can_rx(void *opaque)
 {
     DigicUartState *s = opaque;
 
     return !(s->reg_st & ST_RX_RDY);
 }
 
-static void uart_rx(void *opaque, const uint8_t *buf, int size)
+static void uart_rx(void *opaque, const uint8_t *buf, size_t size)
 {
     DigicUartState *s = opaque;
 
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 628f5f81f7..503541ca5c 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -166,7 +166,7 @@ 
 #define R_EXTINT 15
 
 static void handle_kbd_command(ESCCChannelState *s, int val);
-static int serial_can_receive(void *opaque);
+static size_t serial_can_receive(void *opaque);
 static void serial_receive_byte(ESCCChannelState *s, int ch);
 
 static void clear_queue(void *opaque)
@@ -573,7 +573,7 @@  static const MemoryRegionOps escc_mem_ops = {
     },
 };
 
-static int serial_can_receive(void *opaque)
+static size_t serial_can_receive(void *opaque)
 {
     ESCCChannelState *s = opaque;
     int ret;
@@ -601,7 +601,7 @@  static void serial_receive_break(ESCCChannelState *s)
     escc_update_irq(s);
 }
 
-static void serial_receive1(void *opaque, const uint8_t *buf, int size)
+static void serial_receive1(void *opaque, const uint8_t *buf, size_t size)
 {
     ESCCChannelState *s = opaque;
     serial_receive_byte(s, buf[0]);
diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index a184026410..970f6a6e90 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -166,7 +166,7 @@  static Property etraxfs_ser_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void serial_receive(void *opaque, const uint8_t *buf, int size)
+static void serial_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     ETRAXSerial *s = opaque;
     int i;
@@ -187,7 +187,7 @@  static void serial_receive(void *opaque, const uint8_t *buf, int size)
     ser_update_irq(s);
 }
 
-static int serial_can_receive(void *opaque)
+static size_t serial_can_receive(void *opaque)
 {
     ETRAXSerial *s = opaque;
 
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index a5a285655f..b93edec08a 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -487,7 +487,7 @@  static const MemoryRegionOps exynos4210_uart_ops = {
     },
 };
 
-static int exynos4210_uart_can_receive(void *opaque)
+static size_t exynos4210_uart_can_receive(void *opaque)
 {
     Exynos4210UartState *s = (Exynos4210UartState *)opaque;
 
@@ -495,7 +495,8 @@  static int exynos4210_uart_can_receive(void *opaque)
 }
 
 
-static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size)
+static void exynos4210_uart_receive(void *opaque, const uint8_t *buf,
+                                    size_t size)
 {
     Exynos4210UartState *s = (Exynos4210UartState *)opaque;
     int i;
diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c
index bac11bec58..7b57dce7fb 100644
--- a/hw/char/grlib_apbuart.c
+++ b/hw/char/grlib_apbuart.c
@@ -130,14 +130,14 @@  static void uart_add_to_fifo(UART          *uart,
     uart->len += length;
 }
 
-static int grlib_apbuart_can_receive(void *opaque)
+static size_t grlib_apbuart_can_receive(void *opaque)
 {
     UART *uart = opaque;
 
     return FIFO_LENGTH - uart->len;
 }
 
-static void grlib_apbuart_receive(void *opaque, const uint8_t *buf, int size)
+static void grlib_apbuart_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     UART *uart = opaque;
 
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 1e363190e3..abbe68571d 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -293,7 +293,7 @@  static void imx_serial_write(void *opaque, hwaddr offset,
     }
 }
 
-static int imx_can_receive(void *opaque)
+static size_t imx_can_receive(void *opaque)
 {
     IMXSerialState *s = (IMXSerialState *)opaque;
     return !(s->usr1 & USR1_RRDY);
@@ -315,7 +315,7 @@  static void imx_put_data(void *opaque, uint32_t value)
     imx_update(s);
 }
 
-static void imx_receive(void *opaque, const uint8_t *buf, int size)
+static void imx_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     imx_put_data(opaque, *buf);
 }
diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
index 5e09caf851..ba3f3408a2 100644
--- a/hw/char/ipoctal232.c
+++ b/hw/char/ipoctal232.c
@@ -461,14 +461,14 @@  static void mem_write8(IPackDevice *ip, uint32_t addr, uint8_t val)
     }
 }
 
-static int hostdev_can_receive(void *opaque)
+static size_t hostdev_can_receive(void *opaque)
 {
     SCC2698Channel *ch = opaque;
     int available_bytes = RX_FIFO_SIZE - ch->rx_pending;
     return ch->rx_enabled ? available_bytes : 0;
 }
 
-static void hostdev_receive(void *opaque, const uint8_t *buf, int size)
+static void hostdev_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     SCC2698Channel *ch = opaque;
     IPOctalState *dev = ch->ipoctal;
diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c
index d75c835ad2..51e598c570 100644
--- a/hw/char/lm32_juart.c
+++ b/hw/char/lm32_juart.c
@@ -88,14 +88,14 @@  void lm32_juart_set_jrx(DeviceState *d, uint32_t jtx)
     s->jrx &= ~JRX_FULL;
 }
 
-static void juart_rx(void *opaque, const uint8_t *buf, int size)
+static void juart_rx(void *opaque, const uint8_t *buf, size_t size)
 {
     LM32JuartState *s = opaque;
 
     s->jrx = *buf | JRX_FULL;
 }
 
-static int juart_can_rx(void *opaque)
+static size_t juart_can_rx(void *opaque)
 {
     LM32JuartState *s = opaque;
 
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index c4a3b9b275..2593434f8f 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -211,7 +211,7 @@  static const MemoryRegionOps uart_ops = {
     },
 };
 
-static void uart_rx(void *opaque, const uint8_t *buf, int size)
+static void uart_rx(void *opaque, const uint8_t *buf, size_t size)
 {
     LM32UartState *s = opaque;
 
@@ -225,7 +225,7 @@  static void uart_rx(void *opaque, const uint8_t *buf, int size)
     uart_update_irq(s);
 }
 
-static int uart_can_rx(void *opaque)
+static size_t uart_can_rx(void *opaque)
 {
     LM32UartState *s = opaque;
 
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index 787f985db6..cd9c499a51 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -267,14 +267,14 @@  static void mcf_uart_event(void *opaque, int event)
     }
 }
 
-static int mcf_uart_can_receive(void *opaque)
+static size_t mcf_uart_can_receive(void *opaque)
 {
     mcf_uart_state *s = (mcf_uart_state *)opaque;
 
     return s->rx_enabled && (s->sr & MCF_UART_FFULL) == 0;
 }
 
-static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
+static void mcf_uart_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     mcf_uart_state *s = (mcf_uart_state *)opaque;
 
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index 548ee27bca..0efcd829ce 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -158,7 +158,7 @@  static const MemoryRegionOps uart_mmio_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void uart_rx(void *opaque, const uint8_t *buf, int size)
+static void uart_rx(void *opaque, const uint8_t *buf, size_t size)
 {
     MilkymistUartState *s = opaque;
 
@@ -170,7 +170,7 @@  static void uart_rx(void *opaque, const uint8_t *buf, int size)
     uart_update_irq(s);
 }
 
-static int uart_can_rx(void *opaque)
+static size_t uart_can_rx(void *opaque)
 {
     MilkymistUartState *s = opaque;
 
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index a80da47ecf..fe0e5c8756 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -513,7 +513,7 @@  static const VMStateDescription vmstate_parallel_isa = {
     }
 };
 
-static int parallel_can_receive(void *opaque)
+static size_t parallel_can_receive(void *opaque)
 {
      return 1;
 }
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 2aa277fc4f..8af7dd8269 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -224,7 +224,7 @@  static void pl011_write(void *opaque, hwaddr offset,
     }
 }
 
-static int pl011_can_receive(void *opaque)
+static size_t pl011_can_receive(void *opaque)
 {
     PL011State *s = (PL011State *)opaque;
     int r;
@@ -260,7 +260,7 @@  static void pl011_put_fifo(void *opaque, uint32_t value)
     }
 }
 
-static void pl011_receive(void *opaque, const uint8_t *buf, int size)
+static void pl011_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     pl011_put_fifo(opaque, *buf);
 }
diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
index dbc91a1e5b..ad5f791227 100644
--- a/hw/char/sclpconsole-lm.c
+++ b/hw/char/sclpconsole-lm.c
@@ -61,7 +61,7 @@  typedef struct SCLPConsoleLM {
  * truncated to the guest in case it doesn't fit into the SCCB.
  */
 
-static int chr_can_read(void *opaque)
+static size_t chr_can_read(void *opaque)
 {
     SCLPConsoleLM *scon = opaque;
 
@@ -71,7 +71,7 @@  static int chr_can_read(void *opaque)
     return 1;
 }
 
-static void chr_read(void *opaque, const uint8_t *buf, int size)
+static void chr_read(void *opaque, const uint8_t *buf, size_t size)
 {
     SCLPConsoleLM *scon = opaque;
 
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index 1fa16e9055..8ccdff50d1 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -47,7 +47,7 @@  typedef struct SCLPConsole {
 /* character layer call-back functions */
 
 /* Return number of bytes that fit into iov buffer */
-static int chr_can_read(void *opaque)
+static size_t chr_can_read(void *opaque)
 {
     SCLPConsole *scon = opaque;
     int avail = SIZE_BUFFER_VT220 - scon->iov_data_len;
@@ -59,7 +59,7 @@  static int chr_can_read(void *opaque)
 }
 
 /* Send data from a char device over to the guest */
-static void chr_read(void *opaque, const uint8_t *buf, int size)
+static void chr_read(void *opaque, const uint8_t *buf, size_t size)
 {
     SCLPConsole *scon = opaque;
 
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 02463e3388..1763e63c3f 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -105,7 +105,7 @@  do { fprintf(stderr, "serial: " fmt , ## __VA_ARGS__); } while (0)
 do {} while (0)
 #endif
 
-static void serial_receive1(void *opaque, const uint8_t *buf, int size);
+static void serial_receive1(void *opaque, const uint8_t *buf, size_t size);
 static void serial_xmit(SerialState *s);
 
 static inline void recv_fifo_put(SerialState *s, uint8_t chr)
@@ -600,13 +600,13 @@  static void fifo_timeout_int (void *opaque) {
     }
 }
 
-static int serial_can_receive1(void *opaque)
+static size_t serial_can_receive1(void *opaque)
 {
     SerialState *s = opaque;
     return serial_can_receive(s);
 }
 
-static void serial_receive1(void *opaque, const uint8_t *buf, int size)
+static void serial_receive1(void *opaque, const uint8_t *buf, size_t size)
 {
     SerialState *s = opaque;
 
diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
index 12831561a6..f5402d3b5c 100644
--- a/hw/char/sh_serial.c
+++ b/hw/char/sh_serial.c
@@ -300,7 +300,7 @@  static uint64_t sh_serial_read(void *opaque, hwaddr offs,
     return ret;
 }
 
-static int sh_serial_can_receive(sh_serial_state *s)
+static size_t sh_serial_can_receive(sh_serial_state *s)
 {
     return s->scr & (1 << 4);
 }
@@ -311,7 +311,7 @@  static void sh_serial_receive_break(sh_serial_state *s)
         s->sr |= (1 << 4);
 }
 
-static int sh_serial_can_receive1(void *opaque)
+static size_t sh_serial_can_receive1(void *opaque)
 {
     sh_serial_state *s = opaque;
     return sh_serial_can_receive(s);
@@ -327,7 +327,7 @@  static void sh_serial_timeout_int(void *opaque)
     }
 }
 
-static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size)
+static void sh_serial_receive1(void *opaque, const uint8_t *buf, size_t size)
 {
     sh_serial_state *s = opaque;
 
diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 6748334ded..0ac9dc8448 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -21,14 +21,14 @@  typedef struct VIOsPAPRVTYDevice {
 #define VIO_SPAPR_VTY_DEVICE(obj) \
      OBJECT_CHECK(VIOsPAPRVTYDevice, (obj), TYPE_VIO_SPAPR_VTY_DEVICE)
 
-static int vty_can_receive(void *opaque)
+static size_t vty_can_receive(void *opaque)
 {
     VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(opaque);
 
     return VTERM_BUFSIZE - (dev->in - dev->out);
 }
 
-static void vty_receive(void *opaque, const uint8_t *buf, int size)
+static void vty_receive(void *opaque, const uint8_t *buf, size_t size)
 {
     VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(opaque);
     int i;
@@ -42,7 +42,7 @@  static void vty_receive(void *opaque, const uint8_t *buf, int size)
             static bool reported;
             if (!reported) {
                 error_report("VTY input buffer exhausted - characters dropped."
-                             " (input size = %i)", size);
+                             " (input size = %zu)", size);
                 reported = true;
             }
             break;
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 032b5fda13..63256da77b 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -38,7 +38,7 @@ 
 
 #define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
 
-static int stm32f2xx_usart_can_receive(void *opaque)
+static size_t stm32f2xx_usart_can_receive(void *opaque)
 {
     STM32F2XXUsartState *s = opaque;
 
@@ -49,7 +49,8 @@  static int stm32f2xx_usart_can_receive(void *opaque)
     return 0;
 }
 
-static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
+static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf,
+                                    size_t size)
 {
     STM32F2XXUsartState *s = opaque;
 
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index e9c45e55b1..a9db0a3401 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -38,7 +38,7 @@  typedef struct Terminal3270 {
 #define TERMINAL_3270(obj) \
         OBJECT_CHECK(Terminal3270, (obj), TYPE_TERMINAL_3270)
 
-static int terminal_can_read(void *opaque)
+static size_t terminal_can_read(void *opaque)
 {
     Terminal3270 *t = opaque;
 
@@ -90,7 +90,7 @@  static gboolean send_timing_mark_cb(gpointer opaque)
  * As of now, for such case, we simply terminate the connection,
  * and we should come back here later with a better solution.
  */
-static void terminal_read(void *opaque, const uint8_t *buf, int size)
+static void terminal_read(void *opaque, const uint8_t *buf, size_t size)
 {
     Terminal3270 *t = opaque;
     CcwDevice *ccw_dev = CCW_DEVICE(t);
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 2cbe1d4ed5..b942159d82 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -126,7 +126,7 @@  static void guest_writable(VirtIOSerialPort *port)
 }
 
 /* Readiness of the guest to accept data on a port */
-static int chr_can_read(void *opaque)
+static size_t chr_can_read(void *opaque)
 {
     VirtConsole *vcon = opaque;
 
@@ -134,7 +134,7 @@  static int chr_can_read(void *opaque)
 }
 
 /* Send data from a char device over to the guest */
-static void chr_read(void *opaque, const uint8_t *buf, int size)
+static void chr_read(void *opaque, const uint8_t *buf, size_t size)
 {
     VirtConsole *vcon = opaque;
     VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 44f7236382..0a1cbaeafa 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -116,13 +116,13 @@  static int ring_free_bytes(struct XenConsole *con)
     return (sizeof(intf->in) - space);
 }
 
-static int xencons_can_receive(void *opaque)
+static size_t xencons_can_receive(void *opaque)
 {
     struct XenConsole *con = opaque;
     return ring_free_bytes(con);
 }
 
-static void xencons_receive(void *opaque, const uint8_t *buf, int len)
+static void xencons_receive(void *opaque, const uint8_t *buf, size_t len)
 {
     struct XenConsole *con = opaque;
     struct xencons_interface *intf = con->sring;
diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c
index 2a8bc1e497..2473cb0ad7 100644
--- a/hw/char/xilinx_uartlite.c
+++ b/hw/char/xilinx_uartlite.c
@@ -177,7 +177,7 @@  static Property xilinx_uartlite_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static void uart_rx(void *opaque, const uint8_t *buf, int size)
+static void uart_rx(void *opaque, const uint8_t *buf, size_t size)
 {
     XilinxUARTLite *s = opaque;
 
@@ -195,7 +195,7 @@  static void uart_rx(void *opaque, const uint8_t *buf, int size)
     uart_update_irq(s);
 }
 
-static int uart_can_rx(void *opaque)
+static size_t uart_can_rx(void *opaque)
 {
     XilinxUARTLite *s = opaque;
 
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index bf0b7ee0f5..e45fdb3ce6 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -85,8 +85,8 @@  typedef struct IPMIBmcExtern {
     bool send_reset;
 } IPMIBmcExtern;
 
-static int can_receive(void *opaque);
-static void receive(void *opaque, const uint8_t *buf, int size);
+static size_t can_receive(void *opaque);
+static void receive(void *opaque, const uint8_t *buf, size_t size);
 static void chr_event(void *opaque, int event);
 
 static unsigned char
@@ -311,12 +311,12 @@  static void handle_msg(IPMIBmcExtern *ibe)
     k->handle_rsp(ibe->parent.intf, ibe->inbuf[0], ibe->inbuf + 1, ibe->inpos - 1);
 }
 
-static int can_receive(void *opaque)
+static size_t can_receive(void *opaque)
 {
     return 1;
 }
 
-static void receive(void *opaque, const uint8_t *buf, int size)
+static void receive(void *opaque, const uint8_t *buf, size_t size)
 {
     IPMIBmcExtern *ibe = opaque;
     int i;
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 6febbabcaa..aa7f5a1ef4 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -620,7 +620,7 @@  static void process_msg(IVShmemState *s, int64_t msg, int fd, Error **errp)
     }
 }
 
-static int ivshmem_can_receive(void *opaque)
+static size_t ivshmem_can_receive(void *opaque)
 {
     IVShmemState *s = opaque;
 
@@ -628,14 +628,14 @@  static int ivshmem_can_receive(void *opaque)
     return sizeof(s->msg_buf) - s->msg_buffered_bytes;
 }
 
-static void ivshmem_read(void *opaque, const uint8_t *buf, int size)
+static void ivshmem_read(void *opaque, const uint8_t *buf, size_t size)
 {
     IVShmemState *s = opaque;
     Error *err = NULL;
     int fd;
     int64_t msg;
 
-    assert(size >= 0 && s->msg_buffered_bytes + size <= sizeof(s->msg_buf));
+    assert(s->msg_buffered_bytes + size <= sizeof(s->msg_buf));
     memcpy((unsigned char *)&s->msg_buf + s->msg_buffered_bytes, buf, size);
     s->msg_buffered_bytes += size;
     if (s->msg_buffered_bytes < sizeof(s->msg_buf)) {
diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index 4f7b11dc37..565120df7d 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -65,7 +65,7 @@  void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
 /*
  * Called by the char dev to see if HTIF is ready to accept input.
  */
-static int htif_can_recv(void *opaque)
+static size_t htif_can_recv(void *opaque)
 {
     return 1;
 }
@@ -74,7 +74,7 @@  static int htif_can_recv(void *opaque)
  * Called by the char dev to supply input to HTIF console.
  * We assume that we will receive one character at a time.
  */
-static void htif_recv(void *opaque, const uint8_t *buf, int size)
+static void htif_recv(void *opaque, const uint8_t *buf, size_t size)
 {
     HTIFState *htifstate = opaque;
 
diff --git a/hw/riscv/sifive_uart.c b/hw/riscv/sifive_uart.c
index b0c3798cf2..c6a8f5fbc4 100644
--- a/hw/riscv/sifive_uart.c
+++ b/hw/riscv/sifive_uart.c
@@ -123,7 +123,7 @@  static const MemoryRegionOps uart_ops = {
     }
 };
 
-static void uart_rx(void *opaque, const uint8_t *buf, int size)
+static void uart_rx(void *opaque, const uint8_t *buf, size_t size)
 {
     SiFiveUARTState *s = opaque;
 
@@ -137,7 +137,7 @@  static void uart_rx(void *opaque, const uint8_t *buf, int size)
     update_irq(s);
 }
 
-static int uart_can_rx(void *opaque)
+static size_t uart_can_rx(void *opaque)
 {
     SiFiveUARTState *s = opaque;
 
diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c
index 0a6c657228..5dc10ef850 100644
--- a/hw/usb/ccid-card-passthru.c
+++ b/hw/usb/ccid-card-passthru.c
@@ -112,7 +112,7 @@  static void ccid_card_vscard_send_init(PassthruState *s)
                          (uint8_t *)&msg, sizeof(msg));
 }
 
-static int ccid_card_vscard_can_read(void *opaque)
+static size_t ccid_card_vscard_can_read(void *opaque)
 {
     PassthruState *card = opaque;
 
@@ -270,13 +270,13 @@  static void ccid_card_vscard_drop_connection(PassthruState *card)
     card->vscard_in_pos = card->vscard_in_hdr = 0;
 }
 
-static void ccid_card_vscard_read(void *opaque, const uint8_t *buf, int size)
+static void ccid_card_vscard_read(void *opaque, const uint8_t *buf, size_t size)
 {
     PassthruState *card = opaque;
     VSCMsgHeader *hdr;
 
     if (card->vscard_in_pos + size > VSCARD_IN_SIZE) {
-        error_report("no room for data: pos %u +  size %d > %" PRId64 "."
+        error_report("no room for data: pos %u +  size %zu > %" PRId64 "."
                      " dropping connection.",
                      card->vscard_in_pos, size, VSCARD_IN_SIZE);
         ccid_card_vscard_drop_connection(card);
diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 98d1ca3c91..e9735d4b5d 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -421,7 +421,7 @@  static void usb_serial_handle_data(USBDevice *dev, USBPacket *p)
     }
 }
 
-static int usb_serial_can_read(void *opaque)
+static size_t usb_serial_can_read(void *opaque)
 {
     USBSerialState *s = opaque;
 
@@ -431,7 +431,7 @@  static int usb_serial_can_read(void *opaque)
     return RECV_BUF - s->recv_used;
 }
 
-static void usb_serial_read(void *opaque, const uint8_t *buf, int size)
+static void usb_serial_read(void *opaque, const uint8_t *buf, size_t size)
 {
     USBSerialState *s = opaque;
     int first_size, start;
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 99094a721e..f025c91d28 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1284,7 +1284,7 @@  static void usbredir_do_attach(void *opaque)
  * chardev callbacks
  */
 
-static int usbredir_chardev_can_read(void *opaque)
+static size_t usbredir_chardev_can_read(void *opaque)
 {
     USBRedirDevice *dev = opaque;
 
@@ -1302,7 +1302,7 @@  static int usbredir_chardev_can_read(void *opaque)
     return 1 * MiB;
 }
 
-static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
+static void usbredir_chardev_read(void *opaque, const uint8_t *buf, size_t size)
 {
     USBRedirDevice *dev = opaque;
 
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index e59f9ae1e9..b51f9a5267 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -167,7 +167,7 @@  void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque);
 
 /* async I/O support */
 
-typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
+typedef void IOReadHandler(void *opaque, const uint8_t *buf, size_t size);
 
 /**
  * IOCanReadHandler: Return the number of bytes that #IOReadHandler can accept
@@ -182,7 +182,7 @@  typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
  * is called again.  aio_notify() or qemu_notify_event() can be used to kick
  * the event loop.
  */
-typedef int IOCanReadHandler(void *opaque);
+typedef size_t IOCanReadHandler(void *opaque);
 
 /**
  * qemu_set_fd_handler: Register a file descriptor with the main loop
diff --git a/monitor.c b/monitor.c
index b9258a7438..3417c5f044 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4038,7 +4038,7 @@  cleanup:
     free_cmdline_args(args, nb_args);
 }
 
-static int monitor_can_read(void *opaque)
+static size_t monitor_can_read(void *opaque)
 {
     Monitor *mon = opaque;
 
@@ -4240,14 +4240,14 @@  static void handle_qmp_command(void *opaque, QObject *req, Error *err)
     qemu_bh_schedule(qmp_dispatcher_bh);
 }
 
-static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
+static void monitor_qmp_read(void *opaque, const uint8_t *buf, size_t size)
 {
     Monitor *mon = opaque;
 
     json_message_parser_feed(&mon->qmp.parser, (const char *) buf, size);
 }
 
-static void monitor_read(void *opaque, const uint8_t *buf, int size)
+static void monitor_read(void *opaque, const uint8_t *buf, size_t size)
 {
     Monitor *old_mon = cur_mon;
     int i;
diff --git a/net/colo-compare.c b/net/colo-compare.c
index dd745a491b..9321d81a98 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -683,7 +683,7 @@  err:
     return ret < 0 ? ret : -EIO;
 }
 
-static int compare_chr_can_read(void *opaque)
+static size_t compare_chr_can_read(void *opaque)
 {
     return COMPARE_READ_LEN_MAX;
 }
@@ -692,7 +692,7 @@  static int compare_chr_can_read(void *opaque)
  * Called from the main thread on the primary for packets
  * arriving over the socket from the primary.
  */
-static void compare_pri_chr_in(void *opaque, const uint8_t *buf, int size)
+static void compare_pri_chr_in(void *opaque, const uint8_t *buf, size_t size)
 {
     CompareState *s = COLO_COMPARE(opaque);
     int ret;
@@ -709,7 +709,7 @@  static void compare_pri_chr_in(void *opaque, const uint8_t *buf, int size)
  * Called from the main thread on the primary for packets
  * arriving over the socket from the secondary.
  */
-static void compare_sec_chr_in(void *opaque, const uint8_t *buf, int size)
+static void compare_sec_chr_in(void *opaque, const uint8_t *buf, size_t size)
 {
     CompareState *s = COLO_COMPARE(opaque);
     int ret;
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index 3a61cf21e8..8e16535fad 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -114,12 +114,12 @@  static void redirector_to_filter(NetFilterState *nf,
      }
 }
 
-static int redirector_chr_can_read(void *opaque)
+static size_t redirector_chr_can_read(void *opaque)
 {
     return REDIRECTOR_MAX_LEN;
 }
 
-static void redirector_chr_read(void *opaque, const uint8_t *buf, int size)
+static void redirector_chr_read(void *opaque, const uint8_t *buf, size_t size)
 {
     NetFilterState *nf = opaque;
     MirrorState *s = FILTER_REDIRECTOR(nf);
diff --git a/net/slirp.c b/net/slirp.c
index 99884de204..9dbcaffb07 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -712,13 +712,13 @@  struct GuestFwd {
     Slirp *slirp;
 };
 
-static int guestfwd_can_read(void *opaque)
+static size_t guestfwd_can_read(void *opaque)
 {
     struct GuestFwd *fwd = opaque;
     return slirp_socket_can_recv(fwd->slirp, fwd->server, fwd->port);
 }
 
-static void guestfwd_read(void *opaque, const uint8_t *buf, int size)
+static void guestfwd_read(void *opaque, const uint8_t *buf, size_t size)
 {
     struct GuestFwd *fwd = opaque;
     slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
diff --git a/qtest.c b/qtest.c
index 69b9e9962b..bc685700cd 100644
--- a/qtest.c
+++ b/qtest.c
@@ -657,7 +657,7 @@  static void qtest_process_inbuf(CharBackend *chr, GString *inbuf)
     }
 }
 
-static void qtest_read(void *opaque, const uint8_t *buf, int size)
+static void qtest_read(void *opaque, const uint8_t *buf, size_t size)
 {
     CharBackend *chr = opaque;
 
@@ -665,7 +665,7 @@  static void qtest_read(void *opaque, const uint8_t *buf, int size)
     qtest_process_inbuf(chr, inbuf);
 }
 
-static int qtest_can_read(void *opaque)
+static size_t qtest_can_read(void *opaque)
 {
     return 1024;
 }
diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c
index 2f76216276..bd787cabc9 100644
--- a/target/xtensa/xtensa-semi.c
+++ b/target/xtensa/xtensa-semi.c
@@ -162,7 +162,7 @@  typedef struct XtensaSimConsole {
 static XtensaSimConsole *sim_console;
 
 static IOCanReadHandler sim_console_can_read;
-static int sim_console_can_read(void *opaque)
+static size_t sim_console_can_read(void *opaque)
 {
     XtensaSimConsole *p = opaque;
 
@@ -170,7 +170,7 @@  static int sim_console_can_read(void *opaque)
 }
 
 static IOReadHandler sim_console_read;
-static void sim_console_read(void *opaque, const uint8_t *buf, int size)
+static void sim_console_read(void *opaque, const uint8_t *buf, size_t size)
 {
     XtensaSimConsole *p = opaque;
     size_t copy = sizeof(p->input.buffer) - p->input.offset;