Re: [PATCH v3 2/4] util/qemu-sockets: Enable unix socket support on Windows

2022-08-01 Thread Marc-André Lureau
Hi

On Sat, Jul 30, 2022 at 6:52 PM Bin Meng  wrote:

> From: Bin Meng 
>
> Support for the unix socket has existed both in BSD and Linux for the
> longest time, but not on Windows. Since Windows 10 build 17063 [1],
> the native support for the unix socket has come to Windows. Starting
> this build, two Win32 processes can use the AF_UNIX address family
> over Winsock API to communicate with each other.
>
> [1] https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
>
> Signed-off-by: Xuzhou Cheng 
> Signed-off-by: Bin Meng 
> ---
>
> Changes in v3:
> - drop the run-time check afunix_available()
>
> Changes in v2:
> - move #include  to os-win32.h
> - define WIN_BUILD_AF_UNIX only when CONFIG_WIN32
>
>  meson.build   |  6 ++
>  include/sysemu/os-win32.h |  4 
>  util/qemu-sockets.c   | 14 +++---
>  3 files changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/meson.build b/meson.build
> index 294e9a8f32..3663b925d4 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -2327,6 +2327,12 @@ have_afalg = get_option('crypto_afalg') \
>'''), error_message: 'AF_ALG requested but could not be
> detected').allowed()
>  config_host_data.set('CONFIG_AF_ALG', have_afalg)
>
> +if targetos != 'windows'
> +  config_host_data.set('CONFIG_AF_UNIX', true)
>

Imho, we should simply define CONFIG_AFUNIX_H, regardless of the OS.


> +else
> +  config_host_data.set('CONFIG_AF_UNIX', cc.has_header('afunix.h'))
> +endif
>
+
>  config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
>'linux/vm_sockets.h', 'AF_VSOCK',
>prefix: '#include ',
> diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
> index edc3b38a57..cebf260694 100644
> --- a/include/sysemu/os-win32.h
> +++ b/include/sysemu/os-win32.h
> @@ -30,6 +30,10 @@
>  #include 
>  #include 
>
> +#ifdef CONFIG_AF_UNIX
> +# include 
> +#endif
>

we could also provide a fallback, the same I did for glib:
https://gitlab.gnome.org/GNOME/glib/-/commit/4339192b5391a37ecd55816c713537fb1990cd07

So all Windows build will have afunix code compiled.

+
>  #ifdef __cplusplus
>  extern "C" {
>  #endif
> diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
> index 0e2298278f..f9892506de 100644
> --- a/util/qemu-sockets.c
> +++ b/util/qemu-sockets.c
> @@ -880,7 +880,7 @@ static int vsock_parse(VsockSocketAddress *addr, const
> char *str,
>  }
>  #endif /* CONFIG_AF_VSOCK */
>
> -#ifndef _WIN32
> +#ifdef CONFIG_AF_UNIX
>
>  static bool saddr_is_abstract(UnixSocketAddress *saddr)
>  {
> @@ -1060,14 +1060,14 @@ static int unix_listen_saddr(UnixSocketAddress
> *saddr,
>   int num,
>   Error **errp)
>  {
> -error_setg(errp, "unix sockets are not available on windows");
> +error_setg(errp, "unix sockets are not available on your host");
>  errno = ENOTSUP;
>  return -1;
>  }
>
>  static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
>  {
> -error_setg(errp, "unix sockets are not available on windows");
> +error_setg(errp, "unix sockets are not available on your host");
>  errno = ENOTSUP;
>  return -1;
>  }
> @@ -1335,7 +1335,7 @@ socket_sockaddr_to_address_inet(struct
> sockaddr_storage *sa,
>  }
>
>
> -#ifndef WIN32
> +#ifdef CONFIG_AF_UNIX
>  static SocketAddress *
>  socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
>  socklen_t salen,
> @@ -1362,7 +1362,7 @@ socket_sockaddr_to_address_unix(struct
> sockaddr_storage *sa,
>  addr->u.q_unix.path = g_strndup(su->sun_path, salen);
>  return addr;
>  }
> -#endif /* WIN32 */
> +#endif /* CONFIG_AF_UNIX */
>
>  #ifdef CONFIG_AF_VSOCK
>  static SocketAddress *
> @@ -1394,10 +1394,10 @@ socket_sockaddr_to_address(struct sockaddr_storage
> *sa,
>  case AF_INET6:
>  return socket_sockaddr_to_address_inet(sa, salen, errp);
>
> -#ifndef WIN32
> +#ifdef CONFIG_AF_UNIX
>  case AF_UNIX:
>  return socket_sockaddr_to_address_unix(sa, salen, errp);
> -#endif /* WIN32 */
> +#endif
>
>  #ifdef CONFIG_AF_VSOCK
>  case AF_VSOCK:
> --
> 2.34.1
>
>
>

-- 
Marc-André Lureau


Re: [PATCH v4 6/7] vdpa: Add virtio-net mac address via CVQ at start

2022-08-01 Thread Eugenio Perez Martin
On Mon, Jul 25, 2022 at 11:32 AM Jason Wang  wrote:
>
>
> 在 2022/7/22 19:12, Eugenio Pérez 写道:
> > This is needed so the destination vdpa device see the same state a the
> > guest set in the source.
> >
> > Signed-off-by: Eugenio Pérez 
> > ---
> >   net/vhost-vdpa.c | 61 
> >   1 file changed, 61 insertions(+)
> >
> > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> > index 61516b1432..3e15a42c35 100644
> > --- a/net/vhost-vdpa.c
> > +++ b/net/vhost-vdpa.c
> > @@ -365,10 +365,71 @@ static virtio_net_ctrl_ack 
> > vhost_vdpa_net_cvq_add(VhostShadowVirtqueue *svq,
> >   return VIRTIO_NET_OK;
> >   }
> >
> > +static int vhost_vdpa_net_start(NetClientState *nc)
> > +{
> > +VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > +struct vhost_vdpa *v = &s->vhost_vdpa;
> > +VirtIONet *n;
> > +uint64_t features;
> > +VhostShadowVirtqueue *svq;
> > +
> > +assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> > +
> > +if (!v->shadow_vqs_enabled) {
> > +return 0;
> > +}
> > +
> > +if (v->dev->nvqs != 1 &&
> > +v->dev->vq_index + v->dev->nvqs != v->dev->vq_index_end) {
> > +/* Only interested in CVQ */
> > +return 0;
> > +}
>
>
> I'd have a dedicated NetClientInfo for cvq.
>

I'll try and come back to you.

>
> > +
> > +n = VIRTIO_NET(v->dev->vdev);
> > +features = v->dev->vdev->host_features;
> > +svq = g_ptr_array_index(v->shadow_vqs, 0);
> > +if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) {
> > +const struct virtio_net_ctrl_hdr ctrl = {
> > +.class = VIRTIO_NET_CTRL_MAC,
> > +.cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET,
> > +};
> > +uint8_t mac[6];
> > +const struct iovec out[] = {
> > +{
> > +.iov_base = (void *)&ctrl,
> > +.iov_len = sizeof(ctrl),
> > +},{
> > +.iov_base = mac,
> > +.iov_len = sizeof(mac),
> > +},
> > +};
> > +struct iovec dev_buffers[2] = {
> > +{ .iov_base = s->cvq_cmd_out_buffer },
> > +{ .iov_base = s->cvq_cmd_in_buffer },
> > +};
> > +bool ok;
> > +virtio_net_ctrl_ack state;
> > +
> > +ok = vhost_vdpa_net_cvq_map_sg(s, out, ARRAY_SIZE(out), 
> > dev_buffers);
>
>
> To speed up the state recovery, can we map those buffers during svq start?
>

Not sure if I follow you here. This is the callback that is called
during the device startup.

If you mean to make these buffers permanently mapped I think that can
be done for this series, but extra care will be needed when we
introduce ASID support to not make them visible from the guest. I'm ok
if you prefer to make it that way for this series.

Thanks!

> Thanks
>
>
> > +if (unlikely(!ok)) {
> > +return -1;
> > +}
> > +
> > +memcpy(mac, n->mac, sizeof(mac));
> > +state = vhost_vdpa_net_cvq_add(svq, dev_buffers);
> > +vhost_vdpa_cvq_unmap_buf(v, dev_buffers[0].iov_base);
> > +vhost_vdpa_cvq_unmap_buf(v, dev_buffers[1].iov_base);
> > +return state == VIRTIO_NET_OK ? 0 : 1;
> > +}
> > +
> > +return 0;
> > +}
> > +
> >   static NetClientInfo net_vhost_vdpa_info = {
> >   .type = NET_CLIENT_DRIVER_VHOST_VDPA,
> >   .size = sizeof(VhostVDPAState),
> >   .receive = vhost_vdpa_receive,
> > +.start = vhost_vdpa_net_start,
> >   .cleanup = vhost_vdpa_cleanup,
> >   .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
> >   .has_ufo = vhost_vdpa_has_ufo,
>




Re: [PATCH v2 4/7] vdpa: Add asid parameter to vhost_vdpa_dma_map/unmap

2022-08-01 Thread Eugenio Perez Martin
On Mon, Jul 25, 2022 at 11:36 AM Jason Wang  wrote:
>
>
> 在 2022/7/22 21:43, Eugenio Pérez 写道:
> > So the caller can choose which ASID is destined.
> >
> > No need to update the batch functions as they will always be called from
> > memory listener updates at the moment. Memory listener updates will
> > always update ASID 0, as it's the passthrough ASID.
> >
> > All vhost devices's ASID are 0 at this moment.
> >
> > Signed-off-by: Eugenio Pérez 
> > ---
> >   include/hw/virtio/vhost-vdpa.h |  8 +---
> >   hw/virtio/vhost-vdpa.c | 26 --
> >   net/vhost-vdpa.c   |  6 +++---
> >   hw/virtio/trace-events |  4 ++--
> >   4 files changed, 26 insertions(+), 18 deletions(-)
> >
> > diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
> > index d85643..6560bb9d78 100644
> > --- a/include/hw/virtio/vhost-vdpa.h
> > +++ b/include/hw/virtio/vhost-vdpa.h
> > @@ -29,6 +29,7 @@ typedef struct vhost_vdpa {
> >   int index;
> >   uint32_t msg_type;
> >   bool iotlb_batch_begin_sent;
> > +uint32_t address_space_id;
> >   MemoryListener listener;
> >   struct vhost_vdpa_iova_range iova_range;
> >   uint64_t acked_features;
> > @@ -42,8 +43,9 @@ typedef struct vhost_vdpa {
> >   VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
> >   } VhostVDPA;
> >
> > -int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
> > -   void *vaddr, bool readonly);
> > -int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size);
> > +int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
> > +   hwaddr size, void *vaddr, bool readonly);
> > +int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
> > + hwaddr size);
> >
> >   #endif
> > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> > index e1ed56b26d..79623badf2 100644
> > --- a/hw/virtio/vhost-vdpa.c
> > +++ b/hw/virtio/vhost-vdpa.c
> > @@ -72,22 +72,24 @@ static bool 
> > vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
> >   return false;
> >   }
> >
> > -int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
> > -   void *vaddr, bool readonly)
> > +int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
> > +   hwaddr size, void *vaddr, bool readonly)
> >   {
> >   struct vhost_msg_v2 msg = {};
> >   int fd = v->device_fd;
> >   int ret = 0;
> >
> >   msg.type = v->msg_type;
> > +msg.asid = asid;
> >   msg.iotlb.iova = iova;
> >   msg.iotlb.size = size;
> >   msg.iotlb.uaddr = (uint64_t)(uintptr_t)vaddr;
> >   msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW;
> >   msg.iotlb.type = VHOST_IOTLB_UPDATE;
> >
> > -   trace_vhost_vdpa_dma_map(v, fd, msg.type, msg.iotlb.iova, 
> > msg.iotlb.size,
> > -msg.iotlb.uaddr, msg.iotlb.perm, 
> > msg.iotlb.type);
> > +trace_vhost_vdpa_dma_map(v, fd, msg.type, msg.asid, msg.iotlb.iova,
> > + msg.iotlb.size, msg.iotlb.uaddr, 
> > msg.iotlb.perm,
> > + msg.iotlb.type);
> >
> >   if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> >   error_report("failed to write, fd=%d, errno=%d (%s)",
> > @@ -98,18 +100,20 @@ int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr 
> > iova, hwaddr size,
> >   return ret;
> >   }
> >
> > -int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size)
> > +int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
> > + hwaddr size)
> >   {
> >   struct vhost_msg_v2 msg = {};
> >   int fd = v->device_fd;
> >   int ret = 0;
> >
> >   msg.type = v->msg_type;
> > +msg.asid = asid;
> >   msg.iotlb.iova = iova;
> >   msg.iotlb.size = size;
> >   msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
> >
> > -trace_vhost_vdpa_dma_unmap(v, fd, msg.type, msg.iotlb.iova,
> > +trace_vhost_vdpa_dma_unmap(v, fd, msg.type, msg.asid, msg.iotlb.iova,
> >  msg.iotlb.size, msg.iotlb.type);
> >
> >   if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
> > @@ -228,7 +232,7 @@ static void 
> > vhost_vdpa_listener_region_add(MemoryListener *listener,
> >   }
> >
> >   vhost_vdpa_iotlb_batch_begin_once(v);
> > -ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
> > +ret = vhost_vdpa_dma_map(v, 0, iova, int128_get64(llsize),
> >vaddr, section->readonly);
> >   if (ret) {
> >   error_report("vhost vdpa map fail!");
> > @@ -293,7 +297,7 @@ static void 
> > vhost_vdpa_listener_region_del(MemoryListener *listener,
> >   vhost_iova_tree_remove(v->iova_tree, result);
> >   }
> >   vhost_vdpa_iotlb_batch_begin_once(v);
> > -ret = vhost_vdpa_dma_unmap(v, iova,

Re: [PATCH v3 3/4] chardev/char-socket: Update AF_UNIX for Windows

2022-08-01 Thread Marc-André Lureau
Hi

On Sat, Jul 30, 2022 at 6:54 PM Bin Meng  wrote:

> From: Bin Meng 
>
> Now that AF_UNIX has come to Windows, update the existing logic in
> qemu_chr_compute_filename() and qmp_chardev_open_socket() for Windows.
>
> Signed-off-by: Bin Meng 
> Reviewed-by: Marc-André Lureau 
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - drop #include  as it is now already included in osdep.h
>
>  chardev/char-socket.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/chardev/char-socket.c b/chardev/char-socket.c
> index dc4e218eeb..14a56b7b13 100644
> --- a/chardev/char-socket.c
> +++ b/chardev/char-socket.c
> @@ -557,7 +557,7 @@ static char *qemu_chr_compute_filename(SocketChardev
> *s)
>  const char *left = "", *right = "";
>
>  switch (ss->ss_family) {
> -#ifndef _WIN32
> +#ifdef CONFIG_AF_UNIX
>  case AF_UNIX:
>  return g_strdup_printf("unix:%s%s",
> ((struct sockaddr_un *)(ss))->sun_path,
> @@ -1372,10 +1372,12 @@ static void qmp_chardev_open_socket(Chardev *chr,
>  }
>
>  qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
> +#ifndef _WIN32
>  /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
>  if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
>  qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
>  }
> +#endif
>
>
With the fallback for afunix.h header on windows, we can enable various
code paths with AF_UNIX, without condition.



-- 
Marc-André Lureau


Re: [PATCH for-7.1?] linux-user/riscv: Align signal frame to 16 bytes

2022-08-01 Thread Alistair Francis
On Sat, Jul 30, 2022 at 6:19 AM Richard Henderson
 wrote:
>
> Follow the kernel's alignment, as we already noted.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1093
> Signed-off-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  linux-user/riscv/signal.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
> index 296e39fbf0..eaa168199a 100644
> --- a/linux-user/riscv/signal.c
> +++ b/linux-user/riscv/signal.c
> @@ -64,9 +64,7 @@ static abi_ulong get_sigframe(struct target_sigaction *ka,
>
>  /* This is the X/Open sanctioned signal stack switching.  */
>  sp = target_sigsp(sp, ka) - framesize;
> -
> -/* XXX: kernel aligns with 0xf ? */
> -sp &= ~3UL; /* align sp on 4-byte boundary */
> +sp &= ~0xf;
>
>  return sp;
>  }
> --
> 2.34.1
>
>



Re: [PATCH v3 4/4] tests/unit: Update test-io-channel-socket.c for Windows

2022-08-01 Thread Marc-André Lureau
Hi

On Sat, Jul 30, 2022 at 6:53 PM Bin Meng  wrote:

> From: Bin Meng 
>
> Enable the following 3 test cases for Windows when AF_UNIX is available:
>
>   * test_io_channel_unix_sync
>   * test_io_channel_unix_async
>   * test_io_channel_unix_listen_cleanup
>

The test should runtime-check the availability of AF_UNIX socket, and skip
those appropriately (not failing the test).
(for ex, in glib I wrote
https://gitlab.gnome.org/GNOME/glib/-/blob/main/gio/tests/gdbus-peer.c#L305)


> diff --git a/tests/unit/test-io-channel-socket.c
> b/tests/unit/test-io-channel-socket.c
> index 6713886d02..ec5df32489 100644
> --- a/tests/unit/test-io-channel-socket.c
> +++ b/tests/unit/test-io-channel-socket.c
> @@ -179,10 +179,12 @@ static void test_io_channel(bool async,
>  test_io_channel_setup_async(listen_addr, connect_addr,
>  &srv, &src, &dst);
>
> +#ifndef _WIN32
>  g_assert(!passFD ||
>   qio_channel_has_feature(src,
> QIO_CHANNEL_FEATURE_FD_PASS));
>  g_assert(!passFD ||
>   qio_channel_has_feature(dst,
> QIO_CHANNEL_FEATURE_FD_PASS));
> +#endif
>  g_assert(qio_channel_has_feature(src,
> QIO_CHANNEL_FEATURE_SHUTDOWN));
>  g_assert(qio_channel_has_feature(dst,
> QIO_CHANNEL_FEATURE_SHUTDOWN));
>
> @@ -206,10 +208,12 @@ static void test_io_channel(bool async,
>  test_io_channel_setup_async(listen_addr, connect_addr,
>  &srv, &src, &dst);
>
> +#ifndef _WIN32
>  g_assert(!passFD ||
>   qio_channel_has_feature(src,
> QIO_CHANNEL_FEATURE_FD_PASS));
>  g_assert(!passFD ||
>   qio_channel_has_feature(dst,
> QIO_CHANNEL_FEATURE_FD_PASS));
> +#endif
>  g_assert(qio_channel_has_feature(src,
> QIO_CHANNEL_FEATURE_SHUTDOWN));
>  g_assert(qio_channel_has_feature(dst,
> QIO_CHANNEL_FEATURE_SHUTDOWN));
>
> @@ -236,10 +240,12 @@ static void test_io_channel(bool async,
>  test_io_channel_setup_sync(listen_addr, connect_addr,
> &srv, &src, &dst);
>
> +#ifndef _WIN32
>  g_assert(!passFD ||
>   qio_channel_has_feature(src,
> QIO_CHANNEL_FEATURE_FD_PASS));
>  g_assert(!passFD ||
>   qio_channel_has_feature(dst,
> QIO_CHANNEL_FEATURE_FD_PASS));
> +#endif
>  g_assert(qio_channel_has_feature(src,
> QIO_CHANNEL_FEATURE_SHUTDOWN));
>  g_assert(qio_channel_has_feature(dst,
> QIO_CHANNEL_FEATURE_SHUTDOWN));
>
> @@ -263,10 +269,12 @@ static void test_io_channel(bool async,
>  test_io_channel_setup_sync(listen_addr, connect_addr,
> &srv, &src, &dst);
>
> +#ifndef _WIN32
>  g_assert(!passFD ||
>   qio_channel_has_feature(src,
> QIO_CHANNEL_FEATURE_FD_PASS));
>  g_assert(!passFD ||
>   qio_channel_has_feature(dst,
> QIO_CHANNEL_FEATURE_FD_PASS));
> +#endif
>  g_assert(qio_channel_has_feature(src,
> QIO_CHANNEL_FEATURE_SHUTDOWN));
>  g_assert(qio_channel_has_feature(dst,
> QIO_CHANNEL_FEATURE_SHUTDOWN));
>
> @@ -367,7 +375,7 @@ static void test_io_channel_ipv6_async(void)
>  }
>
>
> -#ifndef _WIN32
> +#ifdef CONFIG_AF_UNIX
>  static void test_io_channel_unix(bool async)
>  {
>  SocketAddress *listen_addr = g_new0(SocketAddress, 1);
> @@ -398,6 +406,7 @@ static void test_io_channel_unix_async(void)
>  return test_io_channel_unix(true);
>  }
>
> +#ifndef _WIN32
>  static void test_io_channel_unix_fd_pass(void)
>  {
>  SocketAddress *listen_addr = g_new0(SocketAddress, 1);
> @@ -491,6 +500,7 @@ static void test_io_channel_unix_fd_pass(void)
>  }
>  g_free(fdrecv);
>  }
> +#endif /* _WIN32 */
>
>  static void test_io_channel_unix_listen_cleanup(void)
>  {
> @@ -588,13 +598,15 @@ int main(int argc, char **argv)
>  test_io_channel_ipv6_async);
>  }
>
> -#ifndef _WIN32
> +#ifdef CONFIG_AF_UNIX
>  g_test_add_func("/io/channel/socket/unix-sync",
>  test_io_channel_unix_sync);
>  g_test_add_func("/io/channel/socket/unix-async",
>  test_io_channel_unix_async);
> +#ifndef _WIN32
>  g_test_add_func("/io/channel/socket/unix-fd-pass",
>  test_io_channel_unix_fd_pass);
> +#endif
>  g_test_add_func("/io/channel/socket/unix-listen-cleanup",
>  test_io_channel_unix_listen_cleanup);
>  #endif /* _WIN32 */
>

The comments needs to be updated


-- 
Marc-André Lureau


Re: [PATCH v4 2/7] vdpa: Extract vhost_vdpa_net_cvq_add from vhost_vdpa_net_handle_ctrl_avail

2022-08-01 Thread Eugenio Perez Martin
On Tue, Jul 26, 2022 at 4:50 AM Jason Wang  wrote:
>
>
> 在 2022/7/22 19:12, Eugenio Pérez 写道:
> > So we can reuse to inject state messages.
> >
> > Signed-off-by: Eugenio Pérez 
> > ---
> >   net/vhost-vdpa.c | 74 ++--
> >   1 file changed, 47 insertions(+), 27 deletions(-)
> >
> > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> > index 6abad276a6..1b82ac2e07 100644
> > --- a/net/vhost-vdpa.c
> > +++ b/net/vhost-vdpa.c
> > @@ -334,6 +334,46 @@ static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState 
> > *s,
> >   return true;
> >   }
> >
> > +static virtio_net_ctrl_ack vhost_vdpa_net_cvq_add(VhostShadowVirtqueue 
> > *svq,
> > +   const struct iovec 
> > *dev_buffers)
>
>
> Let's make this support any layout by accepting in/out sg.
>

I'll change for the next version.

>
> > +{
> > +/* in buffer used for device model */
> > +virtio_net_ctrl_ack status;
> > +size_t dev_written;
> > +int r;
> > +
> > +/*
> > + * Add a fake non-NULL VirtQueueElement since we'll remove before SVQ
> > + * event loop can get it.
> > + */
> > +r = vhost_svq_add(svq, &dev_buffers[0], 1, &dev_buffers[1], 1, (void 
> > *)1);
>
>
> I'd suggest to avoid the trick like (void *)1, which is usually a hint
> of the defect of the API.
>
> We can either:
>
> 1) make vhost_svq_get() check ndescs instead of elem
>
> or
>
> 2) simple pass sg
>

Option one sounds great actually, let me try it and I'll send a new version.

Thanks!


> Thanks
>
>
> > +if (unlikely(r != 0)) {
> > +if (unlikely(r == -ENOSPC)) {
> > +qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device 
> > queue\n",
> > +  __func__);
> > +}
> > +return VIRTIO_NET_ERR;
> > +}
> > +
> > +/*
> > + * We can poll here since we've had BQL from the time we sent the
> > + * descriptor. Also, we need to take the answer before SVQ pulls by 
> > itself,
> > + * when BQL is released
> > + */
> > +dev_written = vhost_svq_poll(svq);
> > +if (unlikely(dev_written < sizeof(status))) {
> > +error_report("Insufficient written data (%zu)", dev_written);
> > +return VIRTIO_NET_ERR;
> > +}
> > +
> > +memcpy(&status, dev_buffers[1].iov_base, sizeof(status));
> > +if (status != VIRTIO_NET_OK) {
> > +return VIRTIO_NET_ERR;
> > +}
> > +
> > +return VIRTIO_NET_OK;
> > +}
> > +
> >   /**
> >* Do not forward commands not supported by SVQ. Otherwise, the device 
> > could
> >* accept it and qemu would not know how to update the device model.
> > @@ -380,19 +420,18 @@ static int 
> > vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
> >   void *opaque)
> >   {
> >   VhostVDPAState *s = opaque;
> > -size_t in_len, dev_written;
> > +size_t in_len;
> >   virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
> >   /* out and in buffers sent to the device */
> >   struct iovec dev_buffers[2] = {
> >   { .iov_base = s->cvq_cmd_out_buffer },
> >   { .iov_base = s->cvq_cmd_in_buffer },
> >   };
> > -/* in buffer used for device model */
> > +/* in buffer seen by virtio-net device model */
> >   const struct iovec in = {
> >   .iov_base = &status,
> >   .iov_len = sizeof(status),
> >   };
> > -int r = -EINVAL;
> >   bool ok;
> >
> >   ok = vhost_vdpa_net_cvq_map_elem(s, elem, dev_buffers);
> > @@ -405,35 +444,16 @@ static int 
> > vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
> >   goto out;
> >   }
> >
> > -r = vhost_svq_add(svq, &dev_buffers[0], 1, &dev_buffers[1], 1, elem);
> > -if (unlikely(r != 0)) {
> > -if (unlikely(r == -ENOSPC)) {
> > -qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device 
> > queue\n",
> > -  __func__);
> > -}
> > -goto out;
> > -}
> > -
> > -/*
> > - * We can poll here since we've had BQL from the time we sent the
> > - * descriptor. Also, we need to take the answer before SVQ pulls by 
> > itself,
> > - * when BQL is released
> > - */
> > -dev_written = vhost_svq_poll(svq);
> > -if (unlikely(dev_written < sizeof(status))) {
> > -error_report("Insufficient written data (%zu)", dev_written);
> > -goto out;
> > -}
> > -
> > -memcpy(&status, dev_buffers[1].iov_base, sizeof(status));
> > +status = vhost_vdpa_net_cvq_add(svq, dev_buffers);
> >   if (status != VIRTIO_NET_OK) {
> >   goto out;
> >   }
> >
> >   status = VIRTIO_NET_ERR;
> > -virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, dev_buffers, 1);
> > -if (status != VIRTIO_NET_OK) {
> > +in_len = virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, dev_buffers, 1);
> > +if (in_len != sizeof(status) || status != VIRTIO_NET_OK) {
> >   error_report("Bad

Re: [PATCH v3 2/3] job: introduce dump guest memory job

2022-08-01 Thread Marc-André Lureau
Hi

On Sat, Jul 30, 2022 at 7:20 AM Hogan Wang via 
wrote:

> There's no way to cancel the current executing dump process, lead to the
> virtual machine manager daemon((e.g. libvirtd) cannot restore the dump
> job after daemon restart.
>
> Introduce dump guest memory job type, and add an optional 'job-id'
> argument for dump-guest-memory QMP to make use of jobs framework.
>
> Signed-off-by: Hogan Wang 
> ---
>  dump/dump-hmp-cmds.c | 12 ++--
>  dump/dump.c  |  1 +
>  qapi/dump.json   |  6 +-
>  qapi/job.json|  5 -
>  4 files changed, 20 insertions(+), 4 deletions(-)
>
> diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c
> index e5053b04cd..ba28a5e631 100644
> --- a/dump/dump-hmp-cmds.c
> +++ b/dump/dump-hmp-cmds.c
> @@ -24,9 +24,11 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict
> *qdict)
>  bool has_begin = qdict_haskey(qdict, "begin");
>  bool has_length = qdict_haskey(qdict, "length");
>  bool has_detach = qdict_haskey(qdict, "detach");
> +bool has_job_id = qdict_haskey(qdict, "job-id");
>  int64_t begin = 0;
>  int64_t length = 0;
>  bool detach = false;
> +const char *job_id = NULL;
>  enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
>  char *prot;
>
> @@ -62,10 +64,16 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict
> *qdict)
>  detach = qdict_get_bool(qdict, "detach");
>  }
>
> +if (has_job_id) {
> +job_id = qdict_get_str(qdict, "job-id");
> +}
> +
>  prot = g_strconcat("file:", file, NULL);
>
> -qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin,
> -  has_length, length, true, dump_format, &err);
> +qmp_dump_guest_memory(paging, prot, has_job_id, job_id,
> +  true, detach, has_begin, begin,
> +  has_length, length, true, dump_format,
> +  &err);
>  hmp_handle_error(mon, err);
>  g_free(prot);
>  }
> diff --git a/dump/dump.c b/dump/dump.c
> index a57c580b12..cec9be30b4 100644
> --- a/dump/dump.c
> +++ b/dump/dump.c
> @@ -1895,6 +1895,7 @@ DumpQueryResult *qmp_query_dump(Error **errp)
>  }
>
>  void qmp_dump_guest_memory(bool paging, const char *file,
> +   bool has_job_id, const char *job_id,
> bool has_detach, bool detach,
> bool has_begin, int64_t begin, bool has_length,
> int64_t length, bool has_format,
> diff --git a/qapi/dump.json b/qapi/dump.json
> index 90859c5483..5209d0b74f 100644
> --- a/qapi/dump.json
> +++ b/qapi/dump.json
> @@ -59,6 +59,9 @@
>  #2. fd: the protocol starts with "fd:", and the following
> string
>  #   is the fd's name.
>  #
> +# @job-id: identifier for the newly-created memory dump job. If
> +#  omitted, use 'memory-guest-dump' by default. (Since 7.2)
>

That's not what is done in the patch, probably the comment needs to be
adjusted

+#
>  # @detach: if true, QMP will return immediately rather than
>  #  waiting for the dump to finish. The user can track progress
>  #  using "query-dump". (since 2.6).
> @@ -88,7 +91,8 @@
>  #
>  ##
>  { 'command': 'dump-guest-memory',
> -  'data': { 'paging': 'bool', 'protocol': 'str', '*detach': 'bool',
> +  'data': { 'paging': 'bool', 'protocol': 'str',
> +'*job-id': 'str', '*detach': 'bool',
>  '*begin': 'int', '*length': 'int',
>  '*format': 'DumpGuestMemoryFormat'} }
>
> diff --git a/qapi/job.json b/qapi/job.json
> index d5f84e9615..e14d2290a5 100644
> --- a/qapi/job.json
> +++ b/qapi/job.json
> @@ -28,11 +28,14 @@
>  #
>  # @snapshot-delete: snapshot delete job type, see "snapshot-delete"
> (since 6.0)
>  #
> +# @dump-guest-memory: dump guest memory job type, see "dump-guest-memory"
> (since 7.2)
> +#
>  # Since: 1.7
>  ##
>  { 'enum': 'JobType',
>'data': ['commit', 'stream', 'mirror', 'backup', 'create', 'amend',
> -   'snapshot-load', 'snapshot-save', 'snapshot-delete'] }
> +   'snapshot-load', 'snapshot-save', 'snapshot-delete',
> +   'dump-guest-memory'] }
>
>  ##
>  # @JobStatus:
> --
> 2.33.0
>
>
>

-- 
Marc-André Lureau


Re: [PATCH v2 7/7] vdpa: Always start CVQ in SVQ mode

2022-08-01 Thread Eugenio Perez Martin
On Tue, Jul 26, 2022 at 5:04 AM Jason Wang  wrote:
>
>
> 在 2022/7/22 21:43, Eugenio Pérez 写道:
> > Isolate control virtqueue in its own group, allowing to intercept control
> > commands but letting dataplane run totally passthrough to the guest.
> >
> > Signed-off-by: Eugenio Pérez 
> > ---
> >   hw/virtio/vhost-vdpa.c |   3 +-
> >   net/vhost-vdpa.c   | 158 +++--
> >   2 files changed, 156 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> > index 79623badf2..fe1c85b086 100644
> > --- a/hw/virtio/vhost-vdpa.c
> > +++ b/hw/virtio/vhost-vdpa.c
> > @@ -668,7 +668,8 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev 
> > *dev)
> >   {
> >   uint64_t features;
> >   uint64_t f = 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2 |
> > -0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH;
> > +0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH |
> > +0x1ULL << VHOST_BACKEND_F_IOTLB_ASID;
> >   int r;
> >
> >   if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) {
> > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> > index 6c1c64f9b1..f5075ef487 100644
> > --- a/net/vhost-vdpa.c
> > +++ b/net/vhost-vdpa.c
> > @@ -37,6 +37,9 @@ typedef struct VhostVDPAState {
> >   /* Control commands shadow buffers */
> >   void *cvq_cmd_out_buffer, *cvq_cmd_in_buffer;
> >
> > +/* Number of address spaces supported by the device */
> > +unsigned address_space_num;
> > +
> >   /* The device always have SVQ enabled */
> >   bool always_svq;
> >   bool started;
> > @@ -100,6 +103,8 @@ static const uint64_t vdpa_svq_device_features =
> >   BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
> >   BIT_ULL(VIRTIO_NET_F_STANDBY);
> >
> > +#define VHOST_VDPA_NET_CVQ_ASID 1
> > +
> >   VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
> >   {
> >   VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > @@ -214,6 +219,109 @@ static ssize_t vhost_vdpa_receive(NetClientState *nc, 
> > const uint8_t *buf,
> >   return 0;
> >   }
> >
> > +static int vhost_vdpa_get_vring_group(int device_fd,
> > +  struct vhost_vring_state *state)
> > +{
> > +int r = ioctl(device_fd, VHOST_VDPA_GET_VRING_GROUP, state);
> > +return r < 0 ? -errno : 0;
> > +}
>
>
> It would be more convenient for the caller if we can simply return 0 here.
>

I don't follow this, how do we know if the call failed then?

>
> > +
> > +/**
> > + * Check if all the virtqueues of the virtio device are in a different vq 
> > than
> > + * the last vq. VQ group of last group passed in cvq_group.
> > + */
> > +static bool vhost_vdpa_cvq_group_is_independent(struct vhost_vdpa *v,
> > +struct vhost_vring_state 
> > cvq_group)
> > +{
> > +struct vhost_dev *dev = v->dev;
> > +int ret;
> > +
> > +for (int i = 0; i < (dev->vq_index_end - 1); ++i) {
> > +struct vhost_vring_state vq_group = {
> > +.index = i,
> > +};
> > +
> > +ret = vhost_vdpa_get_vring_group(v->device_fd, &vq_group);
> > +if (unlikely(ret)) {
> > +goto call_err;
> > +}
> > +if (unlikely(vq_group.num == cvq_group.num)) {
> > +error_report("CVQ %u group is the same as VQ %u one (%u)",
> > + cvq_group.index, vq_group.index, cvq_group.num);
>
>
> Any reason we need error_report() here?
>

We can move it to a migration blocker.

> Btw, I'd suggest to introduce new field in vhost_vdpa, then we can get
> and store the group_id there during init.
>
> This could be useful for the future e.g PASID virtualization.
>

Answering below.

>
> > +return false;
> > +}
> > +}
> > +
> > +return true;
> > +
> > +call_err:
> > +error_report("Can't read vq group, errno=%d (%s)", -ret, 
> > g_strerror(-ret));
> > +return false;
> > +}
> > +
> > +static int vhost_vdpa_set_address_space_id(struct vhost_vdpa *v,
> > +   unsigned vq_group,
> > +   unsigned asid_num)
> > +{
> > +struct vhost_vring_state asid = {
> > +.index = vq_group,
> > +.num = asid_num,
> > +};
> > +int ret;
> > +
> > +ret = ioctl(v->device_fd, VHOST_VDPA_SET_GROUP_ASID, &asid);
> > +if (unlikely(ret < 0)) {
> > +error_report("Can't set vq group %u asid %u, errno=%d (%s)",
> > +asid.index, asid.num, errno, g_strerror(errno));
> > +}
> > +return ret;
> > +}
> > +
> > +static void vhost_vdpa_net_prepare(NetClientState *nc)
> > +{
> > +VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > +struct vhost_vdpa *v = &s->vhost_vdpa;
> > +struct vhost_dev *dev = v->dev;
> > +struct vhost_vring_state cvq_group = {
> > +.index = v->dev->vq_index_end - 1,
> > +};
> > +int r;
> > +
> > +assert(nc->info->type == NET_CLIENT_DRIVER

Re: [PATCH v4 08/17] dump: Split write of section headers and data and add a prepare step

2022-08-01 Thread Janosch Frank

On 7/29/22 19:16, Janis Schoetterl-Glausch wrote:

On 7/26/22 11:22, Janosch Frank wrote:

By splitting the writing of the section headers and (future) section
data we prepare for the addition of a string table section and
architecture sections.

At the same time we move the writing of the section to the end of the
dump process. This allows the upcoming architecture section code to
add data after all of the common dump data has been written.

Signed-off-by: Janosch Frank 
---
  dump/dump.c   | 112 --
  include/sysemu/dump.h |   4 ++
  2 files changed, 90 insertions(+), 26 deletions(-)


[...]

+/* Write special section first */
+if (s->phdr_num == PN_XNUM) {


Should be >= right?


Yes, just fixed it.




+prepare_elf_section_hdr_zero(s);
+}
+}
+

[...]





Re: [PATCH v4 09/17] dump: Reorder struct DumpState

2022-08-01 Thread Janosch Frank

On 7/29/22 19:21, Janis Schoetterl-Glausch wrote:

On 7/26/22 11:22, Janosch Frank wrote:

Let's move ELF related members into one block and guest memory related
ones into another to improve readability.

Signed-off-by: Janosch Frank 
Reviewed-by: Richard Henderson 
Reviewed-by: Marc-André Lureau 
---
  include/sysemu/dump.h | 16 +---
  1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index 686555f908..3937afe0f9 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -154,15 +154,8 @@ typedef struct DumpState {
  GuestPhysBlockList guest_phys_blocks;
  ArchDumpInfo dump_info;
  MemoryMappingList list;
-uint32_t phdr_num;
-uint32_t shdr_num;
  bool resume;
  bool detached;
-ssize_t note_size;
-hwaddr shdr_offset;
-hwaddr phdr_offset;
-hwaddr section_offset;
-hwaddr note_offset;
  hwaddr memory_offset;
  int fd;
  
@@ -171,6 +164,15 @@ typedef struct DumpState {

  int64_t begin; /* Start address of the chunk we want to dump 
*/
  int64_t length;/* Length of the dump we want to dump */
  
+/* Elf dump related data */

+uint32_t phdr_num;
+uint32_t shdr_num;
+uint32_t sh_info;


Why is this ^ here?


Re-base damage




+ssize_t note_size;
+hwaddr shdr_offset;
+hwaddr phdr_offset;
+hwaddr note_offset;
+
  void *elf_header;
  void *elf_section_hdrs;
  uint64_t elf_section_data_size;






Re: [PATCH v4 4/7] vdpa: add NetClientState->start() callback

2022-08-01 Thread Eugenio Perez Martin
On Tue, Jul 26, 2022 at 4:53 AM Jason Wang  wrote:
>
>
> 在 2022/7/22 19:12, Eugenio Pérez 写道:
> > It allows per-net client operations right after device's successful
> > start.
> >
> > Vhost-vdpa net will use it to add the CVQ buffers to restore the device
> > status.
> >
> > Signed-off-by: Eugenio Pérez 
> > ---
> >   include/net/net.h  | 2 ++
> >   hw/net/vhost_net.c | 7 +++
> >   2 files changed, 9 insertions(+)
> >
> > diff --git a/include/net/net.h b/include/net/net.h
> > index 523136c7ac..ad9e80083a 100644
> > --- a/include/net/net.h
> > +++ b/include/net/net.h
> > @@ -44,6 +44,7 @@ typedef struct NICConf {
> >
> >   typedef void (NetPoll)(NetClientState *, bool enable);
> >   typedef bool (NetCanReceive)(NetClientState *);
> > +typedef int (NetStart)(NetClientState *);
> >   typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t);
> >   typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, 
> > int);
> >   typedef void (NetCleanup) (NetClientState *);
> > @@ -71,6 +72,7 @@ typedef struct NetClientInfo {
> >   NetReceive *receive_raw;
> >   NetReceiveIOV *receive_iov;
> >   NetCanReceive *can_receive;
> > +NetStart *start;
>
>
> I think we probably need a better name here. (start should go with
> DRIVER_OK or SET_VRING_ENABLE)
>
> How about load or other (not a native speaker).
>

At this moment, the plan is to call SET_VRING_ENABLE in this function
in the future. But I'm ok to call it load(), maybe it better reflects
the intention of the function.

Thanks!

> Thanks
>
>
> >   NetCleanup *cleanup;
> >   LinkStatusChanged *link_status_changed;
> >   QueryRxFilter *query_rx_filter;
> > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > index ccac5b7a64..ddd9ee0441 100644
> > --- a/hw/net/vhost_net.c
> > +++ b/hw/net/vhost_net.c
> > @@ -274,6 +274,13 @@ static int vhost_net_start_one(struct vhost_net *net,
> >   }
> >   }
> >   }
> > +
> > +if (net->nc->info->start) {
> > +r = net->nc->info->start(net->nc);
> > +if (r < 0) {
> > +goto fail;
> > +}
> > +}
> >   return 0;
> >   fail:
> >   file.fd = -1;
>




[PATCH v4 3/3] dump: use jobs framework for dump guest memory

2022-08-01 Thread Hogan Wang via
There's no way to cancel the current executing dump process, lead to the
virtual machine manager daemon((e.g. libvirtd) cannot restore the dump
job after daemon restart.

When caller pass the 'job-id' argument, create a job for dump process.
And then caller can use job-cancel QMP command to cancel the detached
dump process, use job-dismiss QMP command to release job object.

Examples:
Start dump job:
{"execute": "dump-guest-memory", "arguments": { "job-id": "dump-guest-memory",
"protocol": "file:/tmp/vm.dump",
"paging": false,
"format": "elf",
"detach": true
  }}

Cancel dump job:
{"execute": "job-cancel", "arguments": { "id": "dump-guest-memory" }}

Dismiss dump job:
{"execute": "job-dismiss", "arguments": { "id": "dump-guest-memory" }}

Signed-off-by: Hogan Wang 
---
 dump/dump.c | 76 +
 1 file changed, 76 insertions(+)

diff --git a/dump/dump.c b/dump/dump.c
index cec9be30b4..3f4ed8e7a7 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -98,6 +98,7 @@ static int dump_cleanup(DumpState *s)
 {
 guest_phys_blocks_free(&s->guest_phys_blocks);
 memory_mapping_list_free(&s->list);
+s->job = NULL;
 close(s->fd);
 g_free(s->guest_note);
 s->guest_note = NULL;
@@ -1542,6 +1543,14 @@ static void get_max_mapnr(DumpState *s)
 
 static DumpState dump_state_global = { .status = DUMP_STATUS_NONE };
 
+typedef struct DumpJob {
+Job common;
+DumpState *state;
+Coroutine *co;
+Error **errp;
+} DumpJob;
+
+
 static void dump_state_prepare(DumpState *s)
 {
 /* zero the struct, setting status to active */
@@ -1894,6 +1903,64 @@ DumpQueryResult *qmp_query_dump(Error **errp)
 return result;
 }
 
+static void *dump_job_thread(void *opaque)
+{
+DumpJob *job = (DumpJob *)opaque;
+job_progress_set_remaining(&job->common, 1);
+dump_process(job->state, job->errp);
+job_progress_update(&job->common, 1);
+aio_co_wake(job->co);
+return NULL;
+}
+
+static void dump_sync_job_bh(void *opaque)
+{
+dump_job_thread(opaque);
+}
+
+static int coroutine_fn dump_guest_memory_job_run(Job *job, Error **errp)
+{
+DumpJob *s = container_of(job, DumpJob, common);
+DumpState *state = &dump_state_global;
+
+s->errp = errp;
+s->co = qemu_coroutine_self();
+
+if (state->detached) {
+/* detached dump */
+qemu_thread_create(&s->state->dump_thread, "dump_thread",
+   dump_job_thread, job, QEMU_THREAD_DETACHED);
+} else {
+aio_bh_schedule_oneshot(qemu_get_aio_context(),
+dump_sync_job_bh, job);
+}
+qemu_coroutine_yield();
+return qatomic_read(&state->status) == DUMP_STATUS_COMPLETED ? 0 : -1;
+}
+
+static const JobDriver dump_guest_memory_job_driver = {
+.instance_size = sizeof(DumpJob),
+.job_type  = JOB_TYPE_DUMP_GUEST_MEMORY,
+.run   = dump_guest_memory_job_run,
+};
+
+static void dump_job_start(DumpState *state, const char *job_id,
+   bool detach, Error **errp)
+{
+DumpJob *job;
+
+job = job_create(job_id, &dump_guest_memory_job_driver, NULL,
+ qemu_get_aio_context(), JOB_MANUAL_DISMISS,
+ NULL, NULL, errp);
+if (!job) {
+return;
+}
+state->detached = detach;
+state->job = &job->common;
+job->state = state;
+job_start(&job->common);
+}
+
 void qmp_dump_guest_memory(bool paging, const char *file,
bool has_job_id, const char *job_id,
bool has_detach, bool detach,
@@ -2010,6 +2077,15 @@ void qmp_dump_guest_memory(bool paging, const char *file,
 return;
 }
 
+if (has_job_id) {
+dump_job_start(s, job_id, detach_p, errp);
+if (*errp) {
+qatomic_set(&s->status, DUMP_STATUS_FAILED);
+dump_cleanup(s);
+}
+return;
+}
+
 if (detach_p) {
 /* detached dump */
 s->detached = true;
-- 
2.33.0




[PATCH v4 1/3] dump: support cancel dump process

2022-08-01 Thread Hogan Wang via
Break saving pages or dump iterate when dump job in cancel state,
make sure dump process exits as soon as possible.

Signed-off-by: Hogan Wang 
---
 dump/dump.c   | 23 +++
 include/sysemu/dump.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/dump/dump.c b/dump/dump.c
index 4d9658ffa2..a57c580b12 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -54,6 +54,8 @@ static Error *dump_migration_blocker;
   DIV_ROUND_UP((name_size), 4) +\
   DIV_ROUND_UP((desc_size), 4)) * 4)
 
+static bool dump_cancelling(void);
+
 static inline bool dump_is_64bit(DumpState *s)
 {
 return s->dump_info.d_class == ELFCLASS64;
@@ -118,6 +120,10 @@ static int fd_write_vmcore(const void *buf, size_t size, 
void *opaque)
 DumpState *s = opaque;
 size_t written_size;
 
+if (dump_cancelling()) {
+return -ECANCELED;
+}
+
 written_size = qemu_write_full(s->fd, buf, size);
 if (written_size != size) {
 return -errno;
@@ -627,6 +633,10 @@ static void dump_iterate(DumpState *s, Error **errp)
 
 do {
 block = s->next_block;
+if (dump_cancelling()) {
+error_setg(errp, "dump: job cancelled");
+return;
+}
 
 size = block->target_end - block->target_start;
 if (s->has_filter) {
@@ -1321,6 +1331,10 @@ static void write_dump_pages(DumpState *s, Error **errp)
  * first page of page section
  */
 while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
+if (dump_cancelling()) {
+error_setg(errp, "dump: job cancelled");
+goto out;
+}
 /* check zero page */
 if (buffer_is_zero(buf, s->dump_info.page_size)) {
 ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
@@ -1540,6 +1554,15 @@ bool qemu_system_dump_in_progress(void)
 return (qatomic_read(&state->status) == DUMP_STATUS_ACTIVE);
 }
 
+static bool dump_cancelling(void)
+{
+DumpState *state = &dump_state_global;
+if (state->job && job_is_cancelled(state->job)) {
+return true;
+}
+return false;
+}
+
 /* calculate total size of memory to be dumped (taking filter into
  * acoount.) */
 static int64_t dump_calculate_size(DumpState *s)
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index ffc2ea1072..41bdbe595f 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -15,6 +15,7 @@
 #define DUMP_H
 
 #include "qapi/qapi-types-dump.h"
+#include "qemu/job.h"
 
 #define MAKEDUMPFILE_SIGNATURE  "makedumpfile"
 #define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header 
*/
@@ -154,6 +155,7 @@ typedef struct DumpState {
 GuestPhysBlockList guest_phys_blocks;
 ArchDumpInfo dump_info;
 MemoryMappingList list;
+Job *job;
 uint32_t phdr_num;
 uint32_t shdr_num;
 bool resume;
-- 
2.33.0




Re: [PATCH 2/2] docs: build-platforms: Clarify stance on minor releases and backports

2022-08-01 Thread Andrea Bolognani
On Tue, Jun 14, 2022 at 06:42:58AM -0700, Andrea Bolognani wrote:
> On Wed, May 04, 2022 at 09:23:28AM +0100, Daniel P. Berrangé wrote:
> > On Wed, May 04, 2022 at 01:01:03AM -0700, Andrea Bolognani wrote:
> > > On Wed, Apr 20, 2022 at 09:18:47AM -0700, Andrea Bolognani wrote:
> > > > On Wed, Apr 20, 2022 at 05:15:08PM +0100, Daniel P. Berrangé wrote:
> > > > > On Wed, Apr 20, 2022 at 06:03:11PM +0200, Andrea Bolognani wrote:
> > > > > > These changes match those made in the following libvirt commits:
> > > > > >
> > > > > >   2ac78307af docs: Clarify our stance on backported packages
> > > > > >   78cffd450a docs: Spell out our policy concerning minor releases
> > > > > >
> > > > > > Since QEMU's platform support policy is based on libvirt's, it
> > > > > > makes sense to mirror these recent changes made to the latter.
> > > > > >
> > > > > > The policy is not altered significantly - we're simply spelling
> > > > > > out some rules that were likely already being implicitly
> > > > > > enforced.
> > > > >
> > > > > Indeed, I think that's basically defacto the case already.
> > > > >
> > > > > Reviewed-by: Daniel P. Berrangé 
> > > >
> > > > Thanks! Are you going to bring these in through one of your trees, or
> > > > do I need to bug someone else so that they will pick them up? :)
> > >
> > > I see these haven't gone in yet. Anything I can/should do to make
> > > that happen?
> >
> > The tragedy of QEMU not having a central docs maintainer. I'll queue
> > this one for my next pull request.
>
> Still doesn't seem to have been merged. Not pressuring you or
> anything, just making sure it doesn't slip through the cracks :)

I'm still not seeing this in the tree. I figure with 7.1 coming up
you might be preparing a pull request at some point in the near
future so I though I'd ping again :)

-- 
Andrea Bolognani / Red Hat / Virtualization




Re: [PATCH for-7.1 0/2] scsi-disk: fixes for block size crashes found by fuzzer

2022-08-01 Thread Paolo Bonzini
Queued, thanks.

Paolo





[PATCH v4 2/3] job: introduce dump guest memory job

2022-08-01 Thread Hogan Wang via
There's no way to cancel the current executing dump process, lead to the
virtual machine manager daemon((e.g. libvirtd) cannot restore the dump
job after daemon restart.

Introduce dump guest memory job type, and add an optional 'job-id'
argument for dump-guest-memory QMP to make use of jobs framework.

Signed-off-by: Hogan Wang 
---
 dump/dump-hmp-cmds.c | 12 ++--
 dump/dump.c  |  1 +
 qapi/dump.json   |  6 +-
 qapi/job.json|  5 -
 4 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c
index e5053b04cd..ba28a5e631 100644
--- a/dump/dump-hmp-cmds.c
+++ b/dump/dump-hmp-cmds.c
@@ -24,9 +24,11 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
 bool has_begin = qdict_haskey(qdict, "begin");
 bool has_length = qdict_haskey(qdict, "length");
 bool has_detach = qdict_haskey(qdict, "detach");
+bool has_job_id = qdict_haskey(qdict, "job-id");
 int64_t begin = 0;
 int64_t length = 0;
 bool detach = false;
+const char *job_id = NULL;
 enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
 char *prot;
 
@@ -62,10 +64,16 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
 detach = qdict_get_bool(qdict, "detach");
 }
 
+if (has_job_id) {
+job_id = qdict_get_str(qdict, "job-id");
+}
+
 prot = g_strconcat("file:", file, NULL);
 
-qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin,
-  has_length, length, true, dump_format, &err);
+qmp_dump_guest_memory(paging, prot, has_job_id, job_id,
+  true, detach, has_begin, begin,
+  has_length, length, true, dump_format,
+  &err);
 hmp_handle_error(mon, err);
 g_free(prot);
 }
diff --git a/dump/dump.c b/dump/dump.c
index a57c580b12..cec9be30b4 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -1895,6 +1895,7 @@ DumpQueryResult *qmp_query_dump(Error **errp)
 }
 
 void qmp_dump_guest_memory(bool paging, const char *file,
+   bool has_job_id, const char *job_id,
bool has_detach, bool detach,
bool has_begin, int64_t begin, bool has_length,
int64_t length, bool has_format,
diff --git a/qapi/dump.json b/qapi/dump.json
index 90859c5483..d162a9f028 100644
--- a/qapi/dump.json
+++ b/qapi/dump.json
@@ -59,6 +59,9 @@
 #2. fd: the protocol starts with "fd:", and the following string
 #   is the fd's name.
 #
+# @job-id: identifier for the newly-created memory dump job. To be compatible
+#  with legacy dump process, @job-id should omitted. (Since 7.2)
+#
 # @detach: if true, QMP will return immediately rather than
 #  waiting for the dump to finish. The user can track progress
 #  using "query-dump". (since 2.6).
@@ -88,7 +91,8 @@
 #
 ##
 { 'command': 'dump-guest-memory',
-  'data': { 'paging': 'bool', 'protocol': 'str', '*detach': 'bool',
+  'data': { 'paging': 'bool', 'protocol': 'str',
+'*job-id': 'str', '*detach': 'bool',
 '*begin': 'int', '*length': 'int',
 '*format': 'DumpGuestMemoryFormat'} }
 
diff --git a/qapi/job.json b/qapi/job.json
index d5f84e9615..e14d2290a5 100644
--- a/qapi/job.json
+++ b/qapi/job.json
@@ -28,11 +28,14 @@
 #
 # @snapshot-delete: snapshot delete job type, see "snapshot-delete" (since 6.0)
 #
+# @dump-guest-memory: dump guest memory job type, see "dump-guest-memory" 
(since 7.2)
+#
 # Since: 1.7
 ##
 { 'enum': 'JobType',
   'data': ['commit', 'stream', 'mirror', 'backup', 'create', 'amend',
-   'snapshot-load', 'snapshot-save', 'snapshot-delete'] }
+   'snapshot-load', 'snapshot-save', 'snapshot-delete',
+   'dump-guest-memory'] }
 
 ##
 # @JobStatus:
-- 
2.33.0




Re: [PATCH v3 0/2] migration-test: Allow test to run without uffd

2022-08-01 Thread Thomas Huth

On 28/07/2022 15.35, Peter Xu wrote:

v2:
- Fix warning in patch 1 [Thomas]
- Collected R-b for Daniel

Compare to v1, this added a new patch as reported by Thomas to (hopefully)
allow auto-converge test to pass on some MacOS testbeds.

Please review, thanks.

Peter Xu (2):
   migration-test: Use migrate_ensure_converge() for auto-converge
   migration-test: Allow test to run without uffd

  tests/qtest/migration-test.c | 67 +++-
  1 file changed, 27 insertions(+), 40 deletions(-)


Thanks, I've queued this to my testing-next branch now:

 https://gitlab.com/thuth/qemu/-/commits/testing-next/

 Thomas





Re: [PATCH] ipmi:smbus: Add a check around a memcpy

2022-08-01 Thread Peter Maydell
On Mon, 1 Aug 2022 at 00:03,  wrote:
>
> From: Corey Minyard 
>
> In one case:
>
>   memcpy(sid->inmsg + sid->inlen, buf, len);
>
> if len == 0 then sid->inmsg + sig->inlen can point to one past the inmsg
> array if the array is full.  We have to allow len == 0 due to some
> vagueness in the spec, but we don't have to call memcpy.
>
> Found by Coverity.  This is not a problem in practice, but the results
> are technically (maybe) undefined.  So make Coverity happy.
>
> Reported-by: Peter Maydell 
> Signed-off-by: Corey Minyard 
> ---
>  hw/ipmi/smbus_ipmi.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> I think this should do it.
>
> diff --git a/hw/ipmi/smbus_ipmi.c b/hw/ipmi/smbus_ipmi.c
> index 9ef9112dd5..d0991ab7f9 100644
> --- a/hw/ipmi/smbus_ipmi.c
> +++ b/hw/ipmi/smbus_ipmi.c
> @@ -281,7 +281,9 @@ static int ipmi_write_data(SMBusDevice *dev, uint8_t 
> *buf, uint8_t len)
>   */
>  send = true;
>  }
> -memcpy(sid->inmsg + sid->inlen, buf, len);
> +if (len > 0) {
> +memcpy(sid->inmsg + sid->inlen, buf, len);
> +}
>  sid->inlen += len;
>  break;
>  }
> --
> 2.25.1
Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH] disas/nanomips: Convert nanoMIPS disassembler to C

2022-08-01 Thread Peter Maydell
On Mon, 1 Aug 2022 at 04:18, Vince Del Vecchio
 wrote:
>
> On Fri, 29 Jul 2022 at 10:18, Peter Maydell  wrote:
> > ...
> > Is it possible to break this down into smaller pieces so it isn't one 
> > single enormous 5000 line patch ?
> >
> > I guess partial conversion is likely to run into compilation difficulties 
> > mid-series; if so we could do "disable the disassembler; convert it; 
> > reenable it".
> >
> > The rationale here is code review -- reviewing a single huge patch is 
> > essentially impossible, so it needs to be broken down into coherent smaller 
> > pieces to be reviewable.

> Something like 90% of the patch is purely mechanical transformations of which 
> I've excerpted two examples below.  (There are 3-4 chunks of mechanical 
> transformations, of which I've shown the most complicated type that accounts 
> for ~60% of the changed lines.)  Did you intend to review this by having a 
> human inspect all of these?

If they're mechanical transformations then:
 * the commit message should say what the mechanical transformation is
   (ie quote the sed script or other mechanism used to create the commit)
 * where sensible, different transformations should be in different
   commits
 * the hand-implemented parts should be separate

And yes, review means human inspection. You need to make that
human inspection easy by separating out the stuff that is
"just change std::string to const char *" so that the human can
do a 30-second skim over that patch, and spend the time on
the patch containing the stuff that's more complicated.

-- PMM



Re: virtio: why no full reset on virtio_set_status 0 ?

2022-08-01 Thread Alex Bennée


Claudio Fontana  writes:

> On 7/29/22 16:00, Claudio Fontana wrote:
>> On 7/29/22 15:21, Alex Bennée wrote:
>>>
>>> Claudio Fontana  writes:
>>>
 On 7/29/22 12:13, Michael S. Tsirkin wrote:
> On Fri, Jul 29, 2022 at 11:46:05AM +0200, Claudio Fontana wrote:
 @@ -2025,7 +2031,6 @@ void virtio_reset(void *opaque)
  VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
  int i;
  
 -virtio_set_status(vdev, 0);
  if (current_cpu) {
  /* Guest initiated reset */
  vdev->device_endian = virtio_current_cpu_endian();
 -- 
 2.26.2
>>>
>>> As you say this is incomplete ... bout could you share a bit more
>>> of what issue does this address?
>>>
>>
>> Hi, the problem I am trying to address is a segfault in OVS/dpdk that 
>> looks like this:
>
> Sorry I was not clear. What I mean is, you don't yet know why does 
> removing
> virtio_set_status call here prevent the crash in ovs, do you?
>

 I have no idea. Trying to collect logs to figure things out, but as
 mentioned the logs easily hide the issue.
 Likely there is just more to study here.
>>>
>>> Given the OVS is going off on a NULL ptr deref could it just be it's not
>>> handling the disabling/reenabling of the virtqueues as you pause and
>>> restart properly? I could certainly imagine a backend jumping the gun to
>>> read a queue going very wrong if the current queue state is disabled.
>>>
>> 
>> In this case both the ovs buf_addr and buf_iova are NULL, which is a
>> nice case as they are more detectable,
>> however I also have segfaults where the addresses are just garbage.
>> 
>> I wonder whether it's possible that given the fact that the guest is
>> going away without notification (SIGKILL),
>> as the guest driver resets the device and communicates with QEMU,
>> QEMU adapts the state without notifying ovs,
>> so ovs happily tries to dequeue data from memory that isn't there. But I am 
>> just guessing.
>> 
>> I am still studying the qemu vhost user side and ovs/dpdk side to
>> try to understand how this whole thing works.
>> 
>> Thanks,
>> 
>> CLaudio
>> 
>
> I am pursuing this as a DPDK library issue.
>
> It would be cool to have ovs, dpdk and vhost-user with the default
> test-pmd application somehow hooked up in a basic test
> in one of these projects..

I agree although it's hard to marshal multiple projects into a known
working state that isn't too brittle for CI purposes. The existing
qos-test testing doesn't really exercise any more than the initial setup
and register reading of the VirtIO device.

For example we have a number of non network standalone vhost-user
backends in rust-vmm which would be nice to plumb in somehow.

>
> Thanks,
>
> Claudio


-- 
Alex Bennée



Re: [PATCH for-7.1] hw/mips/malta: turn off x86 specific features of PIIX4_PM

2022-08-01 Thread Dr. David Alan Gilbert
* Peter Maydell (peter.mayd...@linaro.org) wrote:
> On Fri, 29 Jul 2022 at 10:57, Igor Mammedov  wrote:
> >
> > On Thu, 28 Jul 2022 16:12:34 +0100
> > Peter Maydell  wrote:
> >
> > > On Thu, 28 Jul 2022 at 16:09, Dr. David Alan Gilbert
> > >  wrote:
> > > >
> > > > * Igor Mammedov (imamm...@redhat.com) wrote:
> > > > > On Thu, 28 Jul 2022 15:44:20 +0100
> > > > > "Dr. David Alan Gilbert"  wrote:
> > > > >
> > > > > > * Igor Mammedov (imamm...@redhat.com) wrote:
> > > > > > > QEMU crashes trying to save VMSTATE when only MIPS target are 
> > > > > > > compiled in
> > > > > > >   $ qemu-system-mips -monitor stdio
> > > > > > >   (qemu) migrate "exec:gzip -c > STATEFILE.gz"
> > > > > > >   Segmentation fault (core dumped)
> > > > > > >
> > > > > > > It happens due to PIIX4_PM trying to parse hotplug vmstate 
> > > > > > > structures
> > > > > > > which are valid only for x86 and not for MIPS (as it requires ACPI
> > > > > > > tables support which is not existent for ithe later)
> > > > > > >
> > > > > > > Issue was probably exposed by trying to cleanup/compile out unused
> > > > > > > ACPI bits from MIPS target (but forgetting about migration bits).
> > > > > > >
> > > > > > > Disable compiled out features using compat properties as the least
> > > > > > > risky way to deal with issue.
> > > > > >
> > > > > > Isn't the problem partially due to a 'stub' vmsd which isn't 
> > > > > > terminated?
> > > > >
> > > > > Not sure what "'stub' vmsd" is, can you explain?
> > > >
> > > > In hw/acpi/acpi-pci-hotplug-stub.c there is :
> > > > const VMStateDescription vmstate_acpi_pcihp_pci_status;
> > I think that one is there only for linking purposes and not meant
> > to be actually used.
> 
> Yes, exactly. The problem is that without this patch which
> sets various properties it *does* get used...
> 
> > > > this seg happens when the migration code walks into that - this should
> > > > always get populated with some of the minimal fields, in particular the
> > > > .name and .fields array terminated with VMSTATE_END_OF_LIST().
> > >
> > > Either:
> > >  (1) we should be sure the vmstate struct does not get used if the
> > >  compile-time config has ended up with the stub
> > > or
> >
> > >  (2) it needs to actually match the real vmstate struct, otherwise
> > >  migration between a QEMU built with a config that just got the
> > >  stub version and a QEMU built with a config that got the full
> > >  version will break
> > >
> > > This patch does the former. Segfaulting if we got something wrong
> > > and tried to use the vmstate when we weren't expecting to is
> > > arguably better than producing an incompatible migration stream.
> >
> > > (Better still would be if we caught this on machine startup rather
> > > than only when savevm was invoked.)
> > Theoretically possible with a bunch of mips and x86 stubs, but ...
> > we typically don't do this kind of checks for migration sake
> > as that complicates things a lot in general.
> > i.e. it's common to let migration fail in case of incompatible
> > migration stream. It's not exactly friendly to user but it's
> > graceful failure (assuming code is correct and not crashes QEMU)
> 
> The point here is that if we ever try to do a migrate with the
> stub vmstate struct then that's a bug in QEMU. We should prefer
> to catch those early and clearly.

I'd rather have something that was explicitly poisoned rather than just
walking off the end of an uninitialised array and having to break out
gdb.

Dave

> -- PMM
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH v4 11/17] dump/dump: Add section string table support

2022-08-01 Thread Janosch Frank

On 7/28/22 15:41, Marc-André Lureau wrote:

Hi

On Tue, Jul 26, 2022 at 6:26 PM Janosch Frank  wrote:


On 7/26/22 15:12, Marc-André Lureau wrote:

On Tue, Jul 26, 2022 at 4:55 PM Janosch Frank 

wrote:



On 7/26/22 13:25, Marc-André Lureau wrote:

Hi

On Tue, Jul 26, 2022 at 1:23 PM Janosch Frank 

wrote:


As sections don't have a type like the notes do we need another way to
determine their contents. The string table allows us to assign each
section an identification string which architectures can then use to
tag their sections with.

There will be no string table if the architecture doesn't add custom
sections which are introduced in a following patch.

Signed-off-by: Janosch Frank 

[...]

[..]

s->length = length;
+/* First index is 0, it's the special null name */
+s->string_table_buf = g_array_new(FALSE, TRUE, 1);
+/*
+ * Allocate the null name, due to the clearing option set to true
+ * it will be 0.
+ */
+g_array_set_size(s->string_table_buf, 1);


I wonder if GByteArray wouldn't be more appropriate, even if it
doesn't have the clearing option. If it's just for one byte, ...


I don't really care but I need a decision on it to change it :)



I haven't tried, but I think it would be a better fit.


Looking at this a second time there's an issue you should consider:

GByteArray uses guint8 while the GArray uses gchars which are apparently
compatible with normal C chars.

I.e. I need to cast all strings to (const guint8 *) when appending them
to the GByteArray.



Agh, boring.. well, we also have include/qemu/buffer.h that could be
considered perhaps



Why should I change it to something that's hardly being used, i.e. 
what's the problem here?


Re: [PATCH v3 2/4] util/qemu-sockets: Enable unix socket support on Windows

2022-08-01 Thread Daniel P . Berrangé
On Mon, Aug 01, 2022 at 11:09:24AM +0400, Marc-André Lureau wrote:
> Hi
> 
> On Sat, Jul 30, 2022 at 6:52 PM Bin Meng  wrote:
> 
> > From: Bin Meng 
> >
> > Support for the unix socket has existed both in BSD and Linux for the
> > longest time, but not on Windows. Since Windows 10 build 17063 [1],
> > the native support for the unix socket has come to Windows. Starting
> > this build, two Win32 processes can use the AF_UNIX address family
> > over Winsock API to communicate with each other.
> >
> > [1] https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
> >
> > Signed-off-by: Xuzhou Cheng 
> > Signed-off-by: Bin Meng 
> > ---
> >
> > Changes in v3:
> > - drop the run-time check afunix_available()
> >
> > Changes in v2:
> > - move #include  to os-win32.h
> > - define WIN_BUILD_AF_UNIX only when CONFIG_WIN32
> >
> >  meson.build   |  6 ++
> >  include/sysemu/os-win32.h |  4 
> >  util/qemu-sockets.c   | 14 +++---
> >  3 files changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/meson.build b/meson.build
> > index 294e9a8f32..3663b925d4 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -2327,6 +2327,12 @@ have_afalg = get_option('crypto_afalg') \
> >'''), error_message: 'AF_ALG requested but could not be
> > detected').allowed()
> >  config_host_data.set('CONFIG_AF_ALG', have_afalg)
> >
> > +if targetos != 'windows'
> > +  config_host_data.set('CONFIG_AF_UNIX', true)
> >
> 
> Imho, we should simply define CONFIG_AFUNIX_H, regardless of the OS.
> 
> 
> > +else
> > +  config_host_data.set('CONFIG_AF_UNIX', cc.has_header('afunix.h'))
> > +endif
> >
> +
> >  config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
> >'linux/vm_sockets.h', 'AF_VSOCK',
> >prefix: '#include ',
> > diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
> > index edc3b38a57..cebf260694 100644
> > --- a/include/sysemu/os-win32.h
> > +++ b/include/sysemu/os-win32.h
> > @@ -30,6 +30,10 @@
> >  #include 
> >  #include 
> >
> > +#ifdef CONFIG_AF_UNIX
> > +# include 
> > +#endif
> >
> 
> we could also provide a fallback, the same I did for glib:
> https://gitlab.gnome.org/GNOME/glib/-/commit/4339192b5391a37ecd55816c713537fb1990cd07
> 
> So all Windows build will have afunix code compiled.

That's much nicer. It lets us get rid of the conditionals around all
the UNIX socket handling code across the codebase, except for the
FD passing checks which have to remain.


With regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|




Re: [PATCH for-7.1] hw/mips/malta: turn off x86 specific features of PIIX4_PM

2022-08-01 Thread Peter Maydell
On Mon, 1 Aug 2022 at 10:17, Dr. David Alan Gilbert  wrote:
>
> * Peter Maydell (peter.mayd...@linaro.org) wrote:
> > On Fri, 29 Jul 2022 at 10:57, Igor Mammedov  wrote:
> > >
> > > On Thu, 28 Jul 2022 16:12:34 +0100
> > > Peter Maydell  wrote:
> > > > Either:
> > > >  (1) we should be sure the vmstate struct does not get used if the
> > > >  compile-time config has ended up with the stub
> > > > or
> > >
> > > >  (2) it needs to actually match the real vmstate struct, otherwise
> > > >  migration between a QEMU built with a config that just got the
> > > >  stub version and a QEMU built with a config that got the full
> > > >  version will break
> > > >
> > > > This patch does the former. Segfaulting if we got something wrong
> > > > and tried to use the vmstate when we weren't expecting to is
> > > > arguably better than producing an incompatible migration stream.
> > >
> > > > (Better still would be if we caught this on machine startup rather
> > > > than only when savevm was invoked.)
> > > Theoretically possible with a bunch of mips and x86 stubs, but ...
> > > we typically don't do this kind of checks for migration sake
> > > as that complicates things a lot in general.
> > > i.e. it's common to let migration fail in case of incompatible
> > > migration stream. It's not exactly friendly to user but it's
> > > graceful failure (assuming code is correct and not crashes QEMU)
> >
> > The point here is that if we ever try to do a migrate with the
> > stub vmstate struct then that's a bug in QEMU. We should prefer
> > to catch those early and clearly.
>
> I'd rather have something that was explicitly poisoned rather than just
> walking off the end of an uninitialised array and having to break out
> gdb.

It doesn't walk off the end of the array -- it segfaults because
it wants to dereference vmsd->name, which is NULL.

If we want to have a more obvious and concrete way to mark "this
vmsd is bad and should never be actively used" that's fine, but it
seems like a separate patch from this one, which is just fixing
the problem that we use a vmsd that we should not be using.

-- PMM



KVM call for 2022-08-09

2022-08-01 Thread Juan Quintela



Hi

Please, send any topic that you are interested in covering.

At the end of Monday I will send an email with the agenda or the
cancellation of the call, so hurry up.

After discussions on the QEMU Summit, we are going to have always open a
KVM call where you can add topics.

 Call details:

By popular demand, a google calendar public entry with it

  
https://www.google.com/calendar/embed?src=dG9iMXRqcXAzN3Y4ZXZwNzRoMHE4a3BqcXNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ

(Let me know if you have any problems with the calendar entry.  I just
gave up about getting right at the same time CEST, CET, EDT and DST).

If you need phone number details,  contact me privately

Thanks, Juan.




Re: VIRTIO_NET_F_MTU not negotiated

2022-08-01 Thread Eugenio Perez Martin
On Thu, Jul 28, 2022 at 7:51 AM Jason Wang  wrote:
>
> On Thu, Jul 28, 2022 at 1:39 PM Eli Cohen  wrote:
> >
> > > From: Jason Wang 
> > > Sent: Thursday, July 28, 2022 5:09 AM
> > > To: Eli Cohen 
> > > Cc: Eugenio Perez Martin ; qemu-devel@nongnu.org; 
> > > Michael S. Tsirkin ;
> > > virtualizat...@lists.linux-foundation.org
> > > Subject: Re: VIRTIO_NET_F_MTU not negotiated
> > >
> > > On Wed, Jul 27, 2022 at 2:52 PM Eli Cohen  wrote:
> > > >
> > > > I found out that the reason why I could not enforce the mtu stems from 
> > > > the fact that I did not configure max mtu for the net device
> > > (e.g. through libvirt ).
> > > > Libvirt does not allow this configuration for vdpa devices and probably 
> > > > for a reason. The vdpa backend driver has the freedom to do
> > > it using its copy of virtio_net_config.
> > > >
> > > > The code in qemu that is responsible to allow to consider the device 
> > > > MTU restriction is here:
> > > >
> > > > static void virtio_net_device_realize(DeviceState *dev, Error **errp)
> > > > {
> > > > VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> > > > VirtIONet *n = VIRTIO_NET(dev);
> > > > NetClientState *nc;
> > > > int i;
> > > >
> > > > if (n->net_conf.mtu) {
> > > > n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
> > > > }
> > > >
> > > > The above code can be interpreted as follows:
> > > > if the command line arguments of qemu indicates that mtu should be 
> > > > limited, then we would read this mtu limitation from the
> > > device (that actual value is ignored).
> > > >
> > > > I worked around this limitation by unconditionally setting 
> > > > VIRTIO_NET_F_MTU in the host features. As said, it only indicates that
> > > we should read the actual limitation for the device.
> > > >
> > > > If this makes sense I can send a patch to fix this.
> > >
> > > I wonder whether it's worth to bother:
> > >
> > > 1) mgmt (above libvirt) should have the knowledge to prepare the correct 
> > > XML
> > > 2) it's not specific to MTU, we had other features work like, for
> > > example, the multiqueue?
> > >
> >
> >
> > Currently libvirt does not recognize setting the mtu through XML for vdpa 
> > device. So you mean the fix should go to libvirt?
>
> Probably.
>
> > Furthermore, even if libvirt supports MTU configuration for a vdpa device, 
> > the actual value provided will be ignored and the limitation will be taken 
> > from what the vdpa device published in its virtio_net_config structure. 
> > That makes the XML configuration binary.
>
> Yes, we suffer from a similar issue for "queues=". I think we should
> fix qemu by failing the initialization if the value provided by cli
> doesn't match what is read from config space.
>
> E.g when mtu=9000 was set by cli but the actual mtu is 1500.
>

Maybe we can be less strict? Since config space mtu is the maximum
value accepted by the device.

So the case of setting mtu=9000 by cli while the device mtu is 1500
should fail, but not the reverse one. To set a cli mtu <= device mtu
should work in my opinion.

If libvirt has the knowledge to set max mtu properly, it can do so. If
not (or not using libvirt), it should be possible to pass the device's
one.

Other features may need to do the same.

Thanks!




[PULL for-7.1 1/3] hw/nvme: skip queue processing if notifier is cleared

2022-08-01 Thread Klaus Jensen
From: Klaus Jensen 

While it is safe to process the queues when they are empty, skip it if
the event notifier callback was invoked spuriously.

Reviewed-by: Keith Busch 
Reviewed-by: Jinhao Fan 
Signed-off-by: Klaus Jensen 
---
 hw/nvme/ctrl.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 533ad14e7a61..8aa73b048d51 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -4238,7 +4238,9 @@ static void nvme_cq_notifier(EventNotifier *e)
 NvmeCQueue *cq = container_of(e, NvmeCQueue, notifier);
 NvmeCtrl *n = cq->ctrl;
 
-event_notifier_test_and_clear(&cq->notifier);
+if (!event_notifier_test_and_clear(e)) {
+return;
+}
 
 nvme_update_cq_head(cq);
 
@@ -4275,7 +4277,9 @@ static void nvme_sq_notifier(EventNotifier *e)
 {
 NvmeSQueue *sq = container_of(e, NvmeSQueue, notifier);
 
-event_notifier_test_and_clear(&sq->notifier);
+if (!event_notifier_test_and_clear(e)) {
+return;
+}
 
 nvme_process_sq(sq);
 }
-- 
2.36.1




[PULL for-7.1 0/3] hw/nvme fixes

2022-08-01 Thread Klaus Jensen
From: Klaus Jensen 

Hi,

The following changes since commit 3916603e0c1d909e14e09d5ebcbdaa9c9e21adf3:

  Merge tag 'pull-la-20220729' of https://gitlab.com/rth7680/qemu into staging 
(2022-07-29 17:39:17 -0700)

are available in the Git repository at:

  git://git.infradead.org/qemu-nvme.git tags/nvme-next-pull-request

for you to fetch changes up to e2e137f64282a2ee2f359b6df4cd93c83a308e7b:

  hw/nvme: do not enable ioeventfd by default (2022-08-01 12:01:21 +0200)


hw/nvme fixes

Some fixes for hw/nvme ioeventfd support.



Klaus Jensen (3):
  hw/nvme: skip queue processing if notifier is cleared
  hw/nvme: unregister the event notifier handler on the main loop
  hw/nvme: do not enable ioeventfd by default

 hw/nvme/ctrl.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

-- 
2.36.1




[PULL for-7.1 3/3] hw/nvme: do not enable ioeventfd by default

2022-08-01 Thread Klaus Jensen
From: Klaus Jensen 

Do not enable ioeventfd by default. Let the feature mature a bit before
we consider enabling it by default.

Fixes: 2e53b0b45024 ("hw/nvme: Use ioeventfd to handle doorbell updates")
Reviewed-by: Keith Busch 
Reviewed-by: Jinhao Fan 
Signed-off-by: Klaus Jensen 
---
 hw/nvme/ctrl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 70b454eedbd8..87aeba056499 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -7670,7 +7670,7 @@ static Property nvme_props[] = {
 DEFINE_PROP_UINT8("vsl", NvmeCtrl, params.vsl, 7),
 DEFINE_PROP_BOOL("use-intel-id", NvmeCtrl, params.use_intel_id, false),
 DEFINE_PROP_BOOL("legacy-cmb", NvmeCtrl, params.legacy_cmb, false),
-DEFINE_PROP_BOOL("ioeventfd", NvmeCtrl, params.ioeventfd, true),
+DEFINE_PROP_BOOL("ioeventfd", NvmeCtrl, params.ioeventfd, false),
 DEFINE_PROP_UINT8("zoned.zasl", NvmeCtrl, params.zasl, 0),
 DEFINE_PROP_BOOL("zoned.auto_transition", NvmeCtrl,
  params.auto_transition_zones, true),
-- 
2.36.1




[PULL for-7.1 2/3] hw/nvme: unregister the event notifier handler on the main loop

2022-08-01 Thread Klaus Jensen
From: Klaus Jensen 

Make sure the notifier handler is unregistered in the main loop prior to
cleaning it up.

Fixes: 2e53b0b45024 ("hw/nvme: Use ioeventfd to handle doorbell updates")
Reviewed-by: Keith Busch 
Reviewed-by: Jinhao Fan 
Signed-off-by: Klaus Jensen 
---
 hw/nvme/ctrl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 8aa73b048d51..70b454eedbd8 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -4311,6 +4311,7 @@ static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n)
 if (sq->ioeventfd_enabled) {
 memory_region_del_eventfd(&n->iomem,
   0x1000 + offset, 4, false, 0, &sq->notifier);
+event_notifier_set_handler(&sq->notifier, NULL);
 event_notifier_cleanup(&sq->notifier);
 }
 g_free(sq->io_req);
@@ -4701,6 +4702,7 @@ static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n)
 if (cq->ioeventfd_enabled) {
 memory_region_del_eventfd(&n->iomem,
   0x1000 + offset, 4, false, 0, &cq->notifier);
+event_notifier_set_handler(&cq->notifier, NULL);
 event_notifier_cleanup(&cq->notifier);
 }
 if (msix_enabled(&n->parent_obj)) {
-- 
2.36.1




Re: [PATCH 0/2] migration: fix coverity nits

2022-08-01 Thread Peter Maydell
On Thu, 21 Jul 2022 at 12:52, Peter Maydell  wrote:
>
> This patchset fixes four Coverity nits in the migration code.
> The first patch is just adding an assert() to clue coverity in
> that an array index must be in-bounds. The second adds an ULL
> suffix to force a multiplication to be done at 64 bits.
>
> thanks
> -- PMM
>
> Peter Maydell (2):
>   migration: Assert that migrate_multifd_compression() returns an
> in-range value
>   migration: Define BLK_MIG_BLOCK_SIZE as unsigned long long

Ping? This series got reviewed but doesn't seem to have
made it into a migration pullreq yet.

thanks
-- PMM



migration test fails for aarch64 target (was: Re: [PULL 08/30] tests: Add dirty page rate limit test)

2022-08-01 Thread Thomas Huth

On 20/07/2022 13.19, Dr. David Alan Gilbert (git) wrote:

From: Hyman Huang(黄勇) 

Add dirty page rate limit test if kernel support dirty ring,

The following qmp commands are covered by this test case:
"calc-dirty-rate", "query-dirty-rate", "set-vcpu-dirty-limit",
"cancel-vcpu-dirty-limit" and "query-vcpu-dirty-limit".

Signed-off-by: Hyman Huang(黄勇) 
Acked-by: Peter Xu 
Message-Id: 

Signed-off-by: Dr. David Alan Gilbert 
---
  tests/qtest/migration-helpers.c |  22 +++
  tests/qtest/migration-helpers.h |   2 +
  tests/qtest/migration-test.c| 256 
  3 files changed, 280 insertions(+)

[...]

+static QTestState *dirtylimit_start_vm(void)
+{
+QTestState *vm = NULL;
+g_autofree gchar *cmd = NULL;
+const char *arch = qtest_get_arch();
+g_autofree char *bootpath = NULL;
+
+assert((strcmp(arch, "x86_64") == 0));


 Hi!

This assert triggers on my x86 laptop when I run "make check" there. More 
precisely, it triggers when qemu-system-aarch64 is getting tested:


$ QTEST_QEMU_BINARY=./qemu-system-aarch64 tests/qtest/migration-test
/aarch64/migration/bad_dest: OK
/aarch64/migration/fd_proto: OK
/aarch64/migration/validate_uuid: OK
/aarch64/migration/validate_uuid_error: OK
/aarch64/migration/validate_uuid_src_not_set: OK
/aarch64/migration/validate_uuid_dst_not_set: OK
/aarch64/migration/auto_converge: OK
/aarch64/migration/dirty_ring: OK
/aarch64/migration/vcpu_dirty_limit: migration-test: 
../../devel/qemu/tests/qtest/migration-test.c:2304: dirtylimit_start_vm: 
Assertion `(strcmp(arch, "x86_64") == 0)' failed.

Aborted (core dumped)


  static bool kvm_dirty_ring_supported(void)
  {
  #if defined(__linux__) && defined(HOST_X86_64)
@@ -2204,6 +2458,8 @@ int main(int argc, char **argv)
  if (kvm_dirty_ring_supported()) {
  qtest_add_func("/migration/dirty_ring",
 test_precopy_unix_dirty_ring);
+qtest_add_func("/migration/vcpu_dirty_limit",
+   test_vcpu_dirty_limit);
  }


kvm_dirty_ring_supported() returns "true" if the KVM of the *host* is x86 
and has the dirty ring support, but it does *not* check the target 
architecture that is currently tested, so you also get here "true" for 
qemu-system-aarch64 being tested on a x86 host... Thus I guess 
kvm_dirty_ring_supported() needs also a check for the right target architecture?


 Thomas




Re: [PATCH v2 0/3] target/arm: Fix kvm probe of ID_AA64ZFR0

2022-08-01 Thread Peter Maydell
On Tue, 26 Jul 2022 at 06:03, Richard Henderson
 wrote:
>
> Our probing of this SVE register was done within an incorrect
> vCPU environment, so that the id register was always RAZ.
>
> Changes for v2:
>   * Include the commit text I forgot.
>   * Fix svm thinko.
>
>
> r~



Applied to target-arm.next, thanks.

-- PMM



Re: migration test fails for aarch64 target (was: Re: [PULL 08/30] tests: Add dirty page rate limit test)

2022-08-01 Thread Peter Maydell
On Mon, 1 Aug 2022 at 11:41, Thomas Huth  wrote:
>
> On 20/07/2022 13.19, Dr. David Alan Gilbert (git) wrote:
> > From: Hyman Huang(黄勇) 
> >
> > Add dirty page rate limit test if kernel support dirty ring,
> >
> > The following qmp commands are covered by this test case:
> > "calc-dirty-rate", "query-dirty-rate", "set-vcpu-dirty-limit",
> > "cancel-vcpu-dirty-limit" and "query-vcpu-dirty-limit".

> This assert triggers on my x86 laptop when I run "make check" there. More
> precisely, it triggers when qemu-system-aarch64 is getting tested:
>
> $ QTEST_QEMU_BINARY=./qemu-system-aarch64 tests/qtest/migration-test
> /aarch64/migration/bad_dest: OK
> /aarch64/migration/fd_proto: OK
> /aarch64/migration/validate_uuid: OK
> /aarch64/migration/validate_uuid_error: OK
> /aarch64/migration/validate_uuid_src_not_set: OK
> /aarch64/migration/validate_uuid_dst_not_set: OK
> /aarch64/migration/auto_converge: OK
> /aarch64/migration/dirty_ring: OK
> /aarch64/migration/vcpu_dirty_limit: migration-test:
> ../../devel/qemu/tests/qtest/migration-test.c:2304: dirtylimit_start_vm:
> Assertion `(strcmp(arch, "x86_64") == 0)' failed.
> Aborted (core dumped)
>
> >   static bool kvm_dirty_ring_supported(void)
> >   {
> >   #if defined(__linux__) && defined(HOST_X86_64)
> > @@ -2204,6 +2458,8 @@ int main(int argc, char **argv)
> >   if (kvm_dirty_ring_supported()) {
> >   qtest_add_func("/migration/dirty_ring",
> >  test_precopy_unix_dirty_ring);
> > +qtest_add_func("/migration/vcpu_dirty_limit",
> > +   test_vcpu_dirty_limit);
> >   }
>
> kvm_dirty_ring_supported() returns "true" if the KVM of the *host* is x86
> and has the dirty ring support, but it does *not* check the target
> architecture that is currently tested, so you also get here "true" for
> qemu-system-aarch64 being tested on a x86 host... Thus I guess
> kvm_dirty_ring_supported() needs also a check for the right target 
> architecture?

Presumably it should be checking qtest_has_accel("kvm") -- even
if you're on an x86 host and with an x86 guest, if you're using
TCG you're not going to get KVM dirty ring support...

thanks
-- PMM



Re: [PATCH v3 3/5] hw/core: use qemu_fdt_setprop_strings()

2022-08-01 Thread Peter Maydell
On Wed, 27 Jul 2022 at 23:39, Ben Dooks  wrote:
>
> Change to using the qemu_fdt_setprop_strings() helper in
> hw/core code.
>
> Signed-off-by: Ben Dooks 
> ---

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH v3 4/5] hw/mips: use qemu_fdt_setprop_strings()

2022-08-01 Thread Peter Maydell
On Wed, 27 Jul 2022 at 23:40, Ben Dooks  wrote:
>
> Change to using qemu_fdt_setprop_strings() helper in hw/mips.
>
> Signed-off-by: Ben Dooks 
> ---
Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH v3 5/5] hw/arm: change to use qemu_fdt_setprop_strings()

2022-08-01 Thread Peter Maydell
On Wed, 27 Jul 2022 at 23:44, Ben Dooks  wrote:
>
> Change to using qemu_fdt_setprop_strings() instead of using
> \0 separated string arrays.
>
> Signed-off-by: Ben Dooks 
> ---
>  hw/arm/boot.c |  8 +++---
>  hw/arm/virt.c | 28 +
>  hw/arm/xlnx-versal-virt.c | 51 ---
>  3 files changed, 37 insertions(+), 50 deletions(-)
>
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index ada2717f76..bf29b7ae60 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -490,11 +490,11 @@ static void fdt_add_psci_node(void *fdt)
>  qemu_fdt_add_subnode(fdt, "/psci");
>  if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
>  if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
> -const char comp[] = "arm,psci-0.2\0arm,psci";
> -qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
> +qemu_fdt_setprop_strings(fdt, "/psci", "compatible",
> + "arm,psci-0.2", "arm,psci");

I think you may have some stray trailing whitespace here.
checkpatch should be able to tell you.

> @@ -858,8 +855,8 @@ static void create_uart(const VirtMachineState *vms, int 
> uart,
>  nodename = g_strdup_printf("/pl011@%" PRIx64, base);
>  qemu_fdt_add_subnode(ms->fdt, nodename);
>  /* Note that we can't use setprop_string because of the embedded NUL */

With this change, this comment becomes obsolete, and we should delete it too.

> -qemu_fdt_setprop(ms->fdt, nodename, "compatible",
> - compat, sizeof(compat));
> +qemu_fdt_setprop_strings(ms->fdt, nodename, "compatible",
> + "arm,pl011", "arm,primecell");
>  qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
>   2, base, 2, size);
>  qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",



> @@ -285,8 +280,6 @@ static void fdt_add_gem_nodes(VersalVirt *s)
>
>  static void fdt_add_zdma_nodes(VersalVirt *s)
>  {
> -const char clocknames[] = "clk_main\0clk_apb";
> -const char compat[] = "xlnx,zynqmp-dma-1.0";

This looks suspiciously like a pre-existing bug to me.
Alaistair, Edgar -- shouldn't this be a NUL-separated
'compatible' string, rather than a comma-separated one?

>  int i;
>
>  for (i = XLNX_VERSAL_NR_ADMAS - 1; i >= 0; i--) {
> @@ -298,22 +291,21 @@ static void fdt_add_zdma_nodes(VersalVirt *s)
>  qemu_fdt_setprop_cell(s->fdt, name, "xlnx,bus-width", 64);
>  qemu_fdt_setprop_cells(s->fdt, name, "clocks",
> s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
> -qemu_fdt_setprop(s->fdt, name, "clock-names",
> - clocknames, sizeof(clocknames));
> +qemu_fdt_setprop_strings(s->fdt, name, "clock-names",
> + "clk_main", "clk_apb");
>  qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> GIC_FDT_IRQ_TYPE_SPI, VERSAL_ADMA_IRQ_0 + i,
> GIC_FDT_IRQ_FLAGS_LEVEL_HI);
>  qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
>   2, addr, 2, 0x1000);
> -qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
> +qemu_fdt_setprop_string(s->fdt, name, "compatible",
> +"xlnx,zynqmp-dma-1.0");
>  g_free(name);
>  }
>  }
>
>  static void fdt_add_sd_nodes(VersalVirt *s)
>  {
> -const char clocknames[] = "clk_xin\0clk_ahb";
> -const char compat[] = "arasan,sdhci-8.9a";

Ditto here...

>  int i;
>
>  for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
> @@ -324,22 +316,21 @@ static void fdt_add_sd_nodes(VersalVirt *s)
>
>  qemu_fdt_setprop_cells(s->fdt, name, "clocks",
> s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
> -qemu_fdt_setprop(s->fdt, name, "clock-names",
> - clocknames, sizeof(clocknames));
> +qemu_fdt_setprop_strings(s->fdt, name, "clock-names",
> + "clk_xin", "clk_ahb");
>  qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 
> 2,
> GIC_FDT_IRQ_FLAGS_LEVEL_HI);
>  qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
>   2, addr, 2, MM_PMC_SD0_SIZE);
> -qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
> +qemu_fdt_setprop_string(s->fdt, name, "compatible",
> +"arasan,sdhci-8.9a");
>  g_free(name);
>  }
>  }
>
>  static void fdt_add_rtc_node(VersalVirt *s)
>  {
> -const char compat[] = "xlnx,zynqmp-rtc";

...and here.

> -const char interrupt_names[] = "alarm\0sec";
>  char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
>
>

Re: [PATCH] linux-user: Don't assume 0 is not a valid host timer_t value

2022-08-01 Thread Peter Maydell
On Mon, 25 Jul 2022 at 12:13, Daniel P. Berrangé  wrote:
>
> On Mon, Jul 25, 2022 at 12:00:35PM +0100, Peter Maydell wrote:
> > For handling guest POSIX timers, we currently use an array
> > g_posix_timers[], whose entries are a host timer_t value, or 0 for
> > "this slot is unused".  When the guest calls the timer_create syscall
> > we look through the array for a slot containing 0, and use that for
> > the new timer.
> >
> > This scheme assumes that host timer_t values can never be zero.  This
> > is unfortunately not a valid assumption -- for some host libc
> > versions, timer_t values are simply indexes starting at 0.  When
> > using this kind of host libc, the effect is that the first and second
> > timers end up sharing a slot, and so when the guest tries to operate
> > on the first timer it changes the second timer instead.
>
> For sake of historical record, could you mention here which specific
> libc impl / version highlights the problem.

How about:

"This can happen if you are using glibc's backwards-compatible
'timer_t is an integer' compat code for some reason. This happens
when a glibc newer than 2.3.3 is used for a program that was
linked to work with glibc 2.2 to 2.3.3."

Laurent, I'm going to assume you don't need a v2 sending just
for a commit message tweak, unless you'd like me to do that.

thanks
-- PMM



[PATCH] tests/qtest/migration-test: Run the dirty ring tests only with the x86 target

2022-08-01 Thread Thomas Huth
kvm_dirty_ring_supported() only checks whether the dirty ring support
is available on the x86 host, but it ignores whether the target QEMU
architecture is x86 or not. Thus the test_vcpu_dirty_limit() test
currently fails with the assert((strcmp(arch, "x86_64") == 0)) statement
in dirtylimit_start_vm() if the users run e.g. "make check-qtest-aarch64"
on their x86 host. Fix it by only executing the tests when we're running
with a x86_64 target QEMU binary with KVM.

Signed-off-by: Thomas Huth 
---
 tests/qtest/migration-test.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index 71595a74fd..f83360e0e0 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -2439,6 +2439,7 @@ int main(int argc, char **argv)
 {
 char template[] = "/tmp/migration-test-XX";
 const bool has_kvm = qtest_has_accel("kvm");
+const char *arch = qtest_get_arch();
 int ret;
 
 g_test_init(&argc, &argv, NULL);
@@ -2452,7 +2453,7 @@ int main(int argc, char **argv)
  * is touchy due to race conditions on dirty bits (especially on PPC for
  * some reason)
  */
-if (g_str_equal(qtest_get_arch(), "ppc64") &&
+if (g_str_equal(arch, "ppc64") &&
 (!has_kvm || access("/sys/module/kvm_hv", F_OK))) {
 g_test_message("Skipping test: kvm_hv not available");
 return g_test_run();
@@ -2462,7 +2463,7 @@ int main(int argc, char **argv)
  * Similar to ppc64, s390x seems to be touchy with TCG, so disable it
  * there until the problems are resolved
  */
-if (g_str_equal(qtest_get_arch(), "s390x") && !has_kvm) {
+if (g_str_equal(arch, "s390x") && !has_kvm) {
 g_test_message("Skipping test: s390x host with KVM is required");
 return g_test_run();
 }
@@ -2572,7 +2573,7 @@ int main(int argc, char **argv)
 #endif /* CONFIG_TASN1 */
 #endif /* CONFIG_GNUTLS */
 
-if (kvm_dirty_ring_supported()) {
+if (g_str_equal(arch, "x86_64") && has_kvm && kvm_dirty_ring_supported()) {
 qtest_add_func("/migration/dirty_ring",
test_precopy_unix_dirty_ring);
 qtest_add_func("/migration/vcpu_dirty_limit",
-- 
2.31.1




Re: [PATCH 3/3] dump: support cancel dump process

2022-08-01 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 28.07.2022 um 14:37 hat Marc-André Lureau geschrieben:
>> Hi
>> 
>> On Wed, Jul 27, 2022 at 6:02 PM Hogan Wang via 
>> wrote:
>> 
>> > Break saving pages or dump iterate when dump job in cancel state,
>> > make sure dump process exits as soon as possible.
>> >
>> > Signed-off-by: Hogan Wang 
>> >
>> 
>> Overall, the series looks good to me. Please send it with a top cover
>> letter, so it can be processed by patchew too.
>> 
>> I am not familiar with the job infrastructure, it would be nice if Kevin
>> could check the usage or give some advice.
>
> There is one big point I see with this series, which is that it could be
> considered an incompatible change to 'dump-guest-memory'. Clients are
> expected to manage the job now. Though in practice with the default
> settings, maybe it actually just results in clients receiving additional
> QMP events. (Technically, it is still incompatible because the command
> will now fail if you have another job called 'memory-guest-dump' - no
> good reason to have that, but it's a scenario that worked and breaks
> after this series.)
>
> Markus, do you have an opinion on whether job creation must be
> explicitly enabled with a new option or if we can just switch existing
> callers?

The conservative answer is to create a job only when new optional
argument @job-id is present, else maintain the traditional behavior.
This means we get to maintain two variations of the command: with and
without a job.

I can see the following alternatives:

(1) Keep both variations forever.  This could make sense if we believe
the additional complexity and maintenance burden is insignificant.

(2) Deprecate "without a job", and remove it after a suitable grace
period.  @job-id becomes mandatory then.

(3) Create a job even when the user doesn't ask for it (@job-id absent),
accept the change in behavior.  This could make sense if we're
confident the change is harmless in practice.  First step would be
documenting the change in behavior.  Second step would be the
argument why it's harmless.

We may want to deprecate absent @job-id then, so we can get rid of
the special case after a suitable grace period.

Does this answer your question, Kevin?

> The implementation of a very basic job looks mostly okay to me, though
> of course it doesn't support a few things like pausing the job and
> proper progress monitoring. But these things are optional, so it's not a
> blocker.

We can always improve on top.

> The one thing I would strongly recommend to include is an auto-dismiss
> option like every other job has. It is required so that management tools
> can query the final job status before it goes away. Most of the
> information is in QMP events, too, but events can be lost.

Concur.  Transmitting important information in QMP events only is an
interface design flaw.

>auto-finalize
> isn't required for this job because it doesn't actually do anything in
> the finalize phase.
>
> I'm not sure how safe the whole thing is when it runs in the background
> and you can send additional QMP commands while it's running, but that is
> preexisting with detach=true.
>
> Kevin




Re: [PATCH for-7.1? 0/2] Re-enable ppc32 as a linux-user host

2022-08-01 Thread Lucas Mateus Martins Araujo e Castro


On 29/07/2022 17:44, Daniel Henrique Barboza wrote:


On 7/29/22 14:21, Richard Henderson wrote:

This is, technically, a regression from 6.2, so it's not
implausible to apply before rc1.  Thoughts?



In gitlab #1097 the author comments that:

https://gitlab.com/qemu-project/qemu/-/issues/1097#note_1044810483

"there are several distributions still available on 32-bit powerpc, e.g.
Adélie Linux, for now still Void Linux, afaik Debian and OpenSUSE also
still build packages"

I checked these claims. Latest version OpenSuse LEAP doesn't support
ppc32 bits:

https://get.opensuse.org/leap/15.4/#download

The last Debian that supports ppc32 was Debian 8:

https://www.debian.org/ports/powerpc/#powerpc

"Debian on 32-bit PowerPC (powerpc)
It first became an official release architecture with Debian GNU/Linux 
2.2
(potato) and had retained that status until the publication of Debian 
9 (stretch).

The last supported release for 32-bit PowerPC is Debian 8 (jessie)"

And Void Linux doesn't seem to support any PowerPC flavor:

https://voidlinux.org/download/


The author is probably talking about Void Linux ppc as it seems it still 
support ppc


https://voidlinux-ppc.org/



Adélie Linux supports ppc32. I can also add that FreeBSD also supports 
ppc32.


Checking about/build-platforms.rst I can see that we would only somewhat
care for FreeBSD here, since Debian 8 is already out of our support
window.

All that said, I don't have strong feelings against re-enabling it, 
specially

because this build issue was deliberated caused by us.

However, after re-enabling it, I would only care about build bugs that 
are

reproduced on ppc32 FreeBSD.



Daniel




r~


Richard Henderson (2):
   common-user/host/ppc: Implement safe-syscall.inc.S
   linux-user: Implment host/ppc/host-signal.h

  linux-user/include/host/ppc/host-signal.h |  39 
  common-user/host/ppc/safe-syscall.inc.S   | 107 ++
  2 files changed, 146 insertions(+)
  create mode 100644 linux-user/include/host/ppc/host-signal.h
  create mode 100644 common-user/host/ppc/safe-syscall.inc.S




--
Lucas Mateus M. Araujo e Castro
Instituto de Pesquisas ELDORADO 


Departamento Computação Embarcada
Analista de Software Trainee
Aviso Legal - Disclaimer 


Re: [PATCH v4 2/3] job: introduce dump guest memory job

2022-08-01 Thread Markus Armbruster
Hogan Wang  writes:

> There's no way to cancel the current executing dump process, lead to the
> virtual machine manager daemon((e.g. libvirtd) cannot restore the dump
> job after daemon restart.
>
> Introduce dump guest memory job type, and add an optional 'job-id'
> argument for dump-guest-memory QMP to make use of jobs framework.
>
> Signed-off-by: Hogan Wang 
> ---
>  dump/dump-hmp-cmds.c | 12 ++--
>  dump/dump.c  |  1 +
>  qapi/dump.json   |  6 +-
>  qapi/job.json|  5 -
>  4 files changed, 20 insertions(+), 4 deletions(-)
>
> diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c
> index e5053b04cd..ba28a5e631 100644
> --- a/dump/dump-hmp-cmds.c
> +++ b/dump/dump-hmp-cmds.c
> @@ -24,9 +24,11 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict 
> *qdict)
>  bool has_begin = qdict_haskey(qdict, "begin");
>  bool has_length = qdict_haskey(qdict, "length");
>  bool has_detach = qdict_haskey(qdict, "detach");
> +bool has_job_id = qdict_haskey(qdict, "job-id");
>  int64_t begin = 0;
>  int64_t length = 0;
>  bool detach = false;
> +const char *job_id = NULL;
>  enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
>  char *prot;
>  
> @@ -62,10 +64,16 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict 
> *qdict)
>  detach = qdict_get_bool(qdict, "detach");
>  }
>  
> +if (has_job_id) {
> +job_id = qdict_get_str(qdict, "job-id");
> +}
> +

Simpler:

   const char *job_id = qdict_get_try_str(qdict, "job-id");

>  prot = g_strconcat("file:", file, NULL);
>  
> -qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin,
> -  has_length, length, true, dump_format, &err);
> +qmp_dump_guest_memory(paging, prot, has_job_id, job_id,

This becomes

   qmp_dump_guest_memory(paging, prot, !!job_id, job_id,

then.

> +  true, detach, has_begin, begin,
> +  has_length, length, true, dump_format,
> +  &err);
>  hmp_handle_error(mon, err);
>  g_free(prot);
>  }
> diff --git a/dump/dump.c b/dump/dump.c
> index a57c580b12..cec9be30b4 100644
> --- a/dump/dump.c
> +++ b/dump/dump.c
> @@ -1895,6 +1895,7 @@ DumpQueryResult *qmp_query_dump(Error **errp)
>  }
>  
>  void qmp_dump_guest_memory(bool paging, const char *file,
> +   bool has_job_id, const char *job_id,
> bool has_detach, bool detach,
> bool has_begin, int64_t begin, bool has_length,
> int64_t length, bool has_format,
> diff --git a/qapi/dump.json b/qapi/dump.json
> index 90859c5483..d162a9f028 100644
> --- a/qapi/dump.json
> +++ b/qapi/dump.json
> @@ -59,6 +59,9 @@
>  #2. fd: the protocol starts with "fd:", and the following string
>  #   is the fd's name.
>  #
> +# @job-id: identifier for the newly-created memory dump job. To be compatible
> +#  with legacy dump process, @job-id should omitted. (Since 7.2)
> +#

I think we need to describe things in more detail.

What are the behavioral differences between dumping with and without 
@job-id?

Why would you want to pass @job-id?  I figure it's to gain the ability
to monitor and control dump task with query-job, job-cancel, ...

>  # @detach: if true, QMP will return immediately rather than
>  #  waiting for the dump to finish. The user can track progress
>  #  using "query-dump". (since 2.6).

Hmm, does "detach": false make any sense when "job-id" is present?

Preexisting: @detach's default is undocumented.

> @@ -88,7 +91,8 @@
>  #
>  ##
>  { 'command': 'dump-guest-memory',
> -  'data': { 'paging': 'bool', 'protocol': 'str', '*detach': 'bool',
> +  'data': { 'paging': 'bool', 'protocol': 'str',
> +'*job-id': 'str', '*detach': 'bool',
>  '*begin': 'int', '*length': 'int',
>  '*format': 'DumpGuestMemoryFormat'} }
>  
> diff --git a/qapi/job.json b/qapi/job.json
> index d5f84e9615..e14d2290a5 100644
> --- a/qapi/job.json
> +++ b/qapi/job.json
> @@ -28,11 +28,14 @@
>  #
>  # @snapshot-delete: snapshot delete job type, see "snapshot-delete" (since 
> 6.0)
>  #
> +# @dump-guest-memory: dump guest memory job type, see "dump-guest-memory" 
> (since 7.2)
> +#
>  # Since: 1.7
>  ##
>  { 'enum': 'JobType',
>'data': ['commit', 'stream', 'mirror', 'backup', 'create', 'amend',
> -   'snapshot-load', 'snapshot-save', 'snapshot-delete'] }
> +   'snapshot-load', 'snapshot-save', 'snapshot-delete',
> +   'dump-guest-memory'] }
>  
>  ##
>  # @JobStatus:




Re: [PATCH] scsi-disk: support setting CD-ROM block size via device options.

2022-08-01 Thread John Millikin
Gentle ping -- this is my first time sending a patch for QEMU and it
hasn't shown up in the qemu-devel mailing list web UI yet, so I can't
tell whether the mail is being sent/received successfully.

On Tue, Jul 26, 2022 at 12:42:06PM +0900, John Millikin wrote:
> SunOS expects CD-ROM devices to have a block size of 512, and will
> fail to mount or install using QEMU's default block size of 2048.
> 
> When initializing the SCSI device, allow the `physical_block_device'
> block device option to override the default block size.
> 
> Signed-off-by: John Millikin 
> ---
>  hw/scsi/scsi-disk.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> index f5cdb9ad4b..acdf8dc05c 100644
> --- a/hw/scsi/scsi-disk.c
> +++ b/hw/scsi/scsi-disk.c
> @@ -2533,6 +2533,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error 
> **errp)
>  SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
>  AioContext *ctx;
>  int ret;
> +uint32_t blocksize = 2048;
>  
>  if (!dev->conf.blk) {
>  /* Anonymous BlockBackend for an empty drive. As we put it into
> @@ -2542,9 +2543,13 @@ static void scsi_cd_realize(SCSIDevice *dev, Error 
> **errp)
>  assert(ret == 0);
>  }
>  
> +if (dev->conf.physical_block_size != 0) {
> +blocksize = dev->conf.physical_block_size;
> +}
> +
>  ctx = blk_get_aio_context(dev->conf.blk);
>  aio_context_acquire(ctx);
> -s->qdev.blocksize = 2048;
> +s->qdev.blocksize = blocksize;
>  s->qdev.type = TYPE_ROM;
>  s->features |= 1 << SCSI_DISK_F_REMOVABLE;
>  if (!s->product) {
> -- 
> 2.25.1
> 



VGA hardware cursor query

2022-08-01 Thread Elliot Nunn
Dear all,

I want to give Mac OS 9 clients access to hardware cursor support, to improve
responsiveness in absolute-cursor mode.

Would it be acceptable to add a hardware cursor interface to the VGA device?
And if so, can anyone advise on an appropriate register layout?

This is an example of such a patch. Because it alters the Bochs VBE interface
it is ONLY an example, NOT fit for acceptance. I have omitted the changes to
the binary driver qemu_vga.ndrv.

Kind regards,

Elliot Nunn

---
 hw/display/vga.c   |  35 +
 include/hw/display/bochs-vbe.h |   7 +--
 pc-bios/qemu_vga.ndrv  | Bin 18752 -> 20944 bytes
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 5dca2d1528..9b562e24e2 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -744,6 +744,10 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, 
uint32_t val)
 {
 VGACommonState *s = opaque;
 
+static size_t cursorCounter;
+static uint8_t cursorData[16 * 16 * 4];
+QEMUCursor *cursor;
+
 if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
 trace_vga_vbe_write(s->vbe_index, val);
 switch(s->vbe_index) {
@@ -796,6 +800,37 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, 
uint32_t val)
 s->vbe_regs[s->vbe_index] = val;
 vga_update_memory_access(s);
 break;
+
+case VBE_DISPI_INDEX_CURSOR_IMG:
+cursorData[cursorCounter++] = val >> 8;
+cursorData[cursorCounter++] = val;
+cursorCounter &= sizeof(cursorData) - 1;
+break;
+
+case VBE_DISPI_INDEX_CURSOR_HOTSPOT:
+cursor = cursor_alloc(16, 16);
+
+if (val == 0x8080) { // blank cursor
+for (int i = 0; i < 16*16; i++) {
+cursor->data[i] = 0;
+}
+} else {
+for (int i = 0; i < 16*16; i++) {
+cursor->data[i] = 
+((uint32_t)cursorData[i*4] << 24) |
+((uint32_t)cursorData[i*4+1] << 16) |
+((uint32_t)cursorData[i*4+2] << 8) |
+(uint32_t)cursorData[i*4+3];
+}
+
+cursor->hot_x = (int8_t)(val >> 8);
+cursor->hot_y = (int8_t)val;
+}
+
+dpy_cursor_define(s->con, cursor);
+cursor_put(cursor); // dealloc
+break;
+
 default:
 break;
 }
diff --git a/include/hw/display/bochs-vbe.h b/include/hw/display/bochs-vbe.h
index bc2f046eee..7de409bae7 100644
--- a/include/hw/display/bochs-vbe.h
+++ b/include/hw/display/bochs-vbe.h
@@ -19,7 +19,10 @@
 #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
 #define VBE_DISPI_INDEX_X_OFFSET0x8
 #define VBE_DISPI_INDEX_Y_OFFSET0x9
-#define VBE_DISPI_INDEX_NB  0xa /* size of vbe_regs[] */
+#define VBE_DISPI_INDEX_CURSOR_IMG  0xb
+#define VBE_DISPI_INDEX_CURSOR_HOTSPOT  0xc
+#define VBE_DISPI_INDEX_CURSOR_ABS  0xd
+#define VBE_DISPI_INDEX_NB  0xe /* size of vbe_regs[] */
 #define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa /* read-only, not in vbe_regs */
 
 /* VBE_DISPI_INDEX_ID */
@@ -54,7 +57,7 @@
 
 /* bochs vbe register region */
 #define PCI_VGA_BOCHS_OFFSET  0x500
-#define PCI_VGA_BOCHS_SIZE(0x0b * 2)
+#define PCI_VGA_BOCHS_SIZE(VBE_DISPI_INDEX_NB * 2)
 
 /* qemu extension register region */
 #define PCI_VGA_QEXT_OFFSET   0x600

-- 
2.30.1 (Apple Git-130)




[PATCH 00/19] ppc: QOM'ify 405 board

2022-08-01 Thread Cédric Le Goater
Hello,

Here is large series QOM'ifying the PPC405 board. It introduces a new
generic machine and SoC models, converts the current device models to
QOM and populates the SoC. The process is quite mechanical without too
much issues to handle. The noisy part is the initial patch introducing
the SoC realize routine. 

What's left ?

* The DCR read/writre handler are attached in table to the CPU
  instance. We could probably rework the whole with a specific address
  space and memory regions handling the implemented registers. I don't
  think this is necessary.

* the SDRAM mappings are very baroque and certainly could be simplified.
  I think we should QOMify the ppc440 machines before addressing this
  part.

Thanks,

C.

Cédric Le Goater (19):
  ppc/ppc405: Remove taihu machine
  ppc/ppc405: Introduce a PPC405 generic machine
  ppc/ppc405: Move devices under the ref405ep machine
  ppc/ppc405: Introduce a PPC405 SoC
  ppc/ppc405: Start QOMification of the SoC
  ppc/ppc405: QOM'ify CPU
  ppc/ppc405: QOM'ify CPC
  ppc/ppc405: QOM'ify GPT
  ppc/ppc405: QOM'ify OCM
  ppc/ppc405: QOM'ify GPIO
  ppc/ppc405: QOM'ify DMA
  ppc/ppc405: QOM'ify EBC
  ppc/ppc405: QOM'ify OPBA
  ppc/ppc405: QOM'ify POB
  ppc/ppc405: QOM'ify PLB
  ppc/ppc405: QOM'ify MAL
  ppc/ppc405: QOM'ify FPGA
  ppc/ppc405: QOM'ify UIC
  ppc/ppc405: QOM'ify I2C

 docs/about/deprecated.rst|   9 -
 docs/system/ppc/embedded.rst |   1 -
 hw/ppc/ppc405.h  | 210 -
 include/hw/ppc/ppc4xx.h  |  28 ++
 hw/ppc/ppc405_boards.c   | 366 
 hw/ppc/ppc405_uc.c   | 802 +--
 hw/ppc/ppc4xx_devs.c | 120 --
 7 files changed, 887 insertions(+), 649 deletions(-)

-- 
2.37.1




[PATCH 01/19] ppc/ppc405: Remove taihu machine

2022-08-01 Thread Cédric Le Goater
It has been deprecated since 7.0.

Signed-off-by: Cédric Le Goater 
---
 docs/about/deprecated.rst|   9 --
 docs/system/ppc/embedded.rst |   1 -
 hw/ppc/ppc405_boards.c   | 232 ---
 3 files changed, 242 deletions(-)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 7ee26626d5cf..2f9b41aaea48 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -233,15 +233,6 @@ deprecated; use the new name ``dtb-randomness`` instead. 
The new name
 better reflects the way this property affects all random data within
 the device tree blob, not just the ``kaslr-seed`` node.
 
-PPC 405 ``taihu`` machine (since 7.0)
-'
-
-The PPC 405 CPU is a system-on-a-chip, so all 405 machines are very similar,
-except for some external periphery. However, the periphery of the ``taihu``
-machine is hardly emulated at all (e.g. neither the LCD nor the USB part had
-been implemented), so there is not much value added by this board. Use the
-``ref405ep`` machine instead.
-
 ``pc-i440fx-1.4`` up to ``pc-i440fx-1.7`` (since 7.0)
 '
 
diff --git a/docs/system/ppc/embedded.rst b/docs/system/ppc/embedded.rst
index cfffbda24da9..af3b3d9fa460 100644
--- a/docs/system/ppc/embedded.rst
+++ b/docs/system/ppc/embedded.rst
@@ -6,5 +6,4 @@ Embedded family boards
 - ``ppce500``  generic paravirt e500 platform
 - ``ref405ep`` ref405ep
 - ``sam460ex`` aCube Sam460ex
-- ``taihu``taihu
 - ``virtex-ml507`` Xilinx Virtex ML507 reference design
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index a66ad05e3ac3..1a4e7588c584 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -342,241 +342,9 @@ static const TypeInfo ref405ep_type = {
 .class_init = ref405ep_class_init,
 };
 
-/*/
-/* AMCC Taihu evaluation board */
-/* - PowerPC 405EP processor
- * - SDRAM   128 MB at 0x
- * - Boot flash  2 MB   at 0xFFE0
- * - Application flash   32 MB  at 0xFC00
- * - 2 serial ports
- * - 2 ethernet PHY
- * - 1 USB 1.1 device0x5000
- * - 1 LCD display   0x5010
- * - 1 CPLD  0x5010
- * - 1 I2C EEPROM
- * - 1 I2C thermal sensor
- * - a set of LEDs
- * - bit-bang SPI port using GPIOs
- * - 1 EBC interface connector 0 0x5020
- * - 1 cardbus controller + expansion slot.
- * - 1 PCI expansion slot.
- */
-typedef struct taihu_cpld_t taihu_cpld_t;
-struct taihu_cpld_t {
-uint8_t reg0;
-uint8_t reg1;
-};
-
-static uint64_t taihu_cpld_read(void *opaque, hwaddr addr, unsigned size)
-{
-taihu_cpld_t *cpld;
-uint32_t ret;
-
-cpld = opaque;
-switch (addr) {
-case 0x0:
-ret = cpld->reg0;
-break;
-case 0x1:
-ret = cpld->reg1;
-break;
-default:
-ret = 0;
-break;
-}
-
-return ret;
-}
-
-static void taihu_cpld_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
-taihu_cpld_t *cpld;
-
-cpld = opaque;
-switch (addr) {
-case 0x0:
-/* Read only */
-break;
-case 0x1:
-cpld->reg1 = value;
-break;
-default:
-break;
-}
-}
-
-static const MemoryRegionOps taihu_cpld_ops = {
-.read = taihu_cpld_read,
-.write = taihu_cpld_write,
-.impl = {
-.min_access_size = 1,
-.max_access_size = 1,
-},
-.endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void taihu_cpld_reset (void *opaque)
-{
-taihu_cpld_t *cpld;
-
-cpld = opaque;
-cpld->reg0 = 0x01;
-cpld->reg1 = 0x80;
-}
-
-static void taihu_cpld_init(MemoryRegion *sysmem, uint32_t base)
-{
-taihu_cpld_t *cpld;
-MemoryRegion *cpld_memory = g_new(MemoryRegion, 1);
-
-cpld = g_new0(taihu_cpld_t, 1);
-memory_region_init_io(cpld_memory, NULL, &taihu_cpld_ops, cpld, "cpld", 
0x100);
-memory_region_add_subregion(sysmem, base, cpld_memory);
-qemu_register_reset(&taihu_cpld_reset, cpld);
-}
-
-static void taihu_405ep_init(MachineState *machine)
-{
-MachineClass *mc = MACHINE_GET_CLASS(machine);
-const char *bios_name = machine->firmware ?: BIOS_FILENAME;
-const char *kernel_filename = machine->kernel_filename;
-const char *initrd_filename = machine->initrd_filename;
-char *filename;
-MemoryRegion *sysmem = get_system_memory();
-MemoryRegion *bios;
-MemoryRegion *ram_memories = g_new(MemoryRegion, 2);
-hwaddr ram_bases[2], ram_sizes[2];
-long bios_size;
-target_ulong kernel_base, initrd_base;
-long kernel_size, initrd_size;
-int linux_boot;
-int fl_idx;
-DriveInfo *dinfo;
-DeviceState *uicdev;
-
-if (machine->ram_size != mc->default_ram_size) {
-char *sz = size_to_str(mc->default_ram_size);
-error_report("Invalid RAM s

[PATCH 09/19] ppc/ppc405: QOM'ify OCM

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 18 
 hw/ppc/ppc405_uc.c | 73 --
 2 files changed, 63 insertions(+), 28 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index f7c0eb1d0008..e56363366cad 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,23 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* On Chip Memory */
+#define TYPE_PPC405_OCM "ppc405-ocm"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OcmState, PPC405_OCM);
+struct Ppc405OcmState {
+SysBusDevice parent_obj;
+
+PowerPCCPU *cpu;
+
+MemoryRegion ram;
+MemoryRegion isarc_ram;
+MemoryRegion dsarc_ram;
+uint32_t isarc;
+uint32_t isacntl;
+uint32_t dsarc;
+uint32_t dsacntl;
+};
+
 /* General purpose timers */
 #define TYPE_PPC405_GPT "ppc405-gpt"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GptState, PPC405_GPT);
@@ -141,6 +158,7 @@ struct Ppc405SoCState {
 DeviceState *uic;
 Ppc405CpcState cpc;
 Ppc405GptState gpt;
+Ppc405OcmState ocm;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 0f5e4ec15f14..59cade4c0680 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -773,20 +773,9 @@ enum {
 OCM0_DSACNTL = 0x01B,
 };
 
-typedef struct ppc405_ocm_t ppc405_ocm_t;
-struct ppc405_ocm_t {
-MemoryRegion ram;
-MemoryRegion isarc_ram;
-MemoryRegion dsarc_ram;
-uint32_t isarc;
-uint32_t isacntl;
-uint32_t dsarc;
-uint32_t dsacntl;
-};
-
-static void ocm_update_mappings (ppc405_ocm_t *ocm,
- uint32_t isarc, uint32_t isacntl,
- uint32_t dsarc, uint32_t dsacntl)
+static void ocm_update_mappings(Ppc405OcmState *ocm,
+uint32_t isarc, uint32_t isacntl,
+uint32_t dsarc, uint32_t dsacntl)
 {
 trace_ocm_update_mappings(isarc, isacntl, dsarc, dsacntl, ocm->isarc,
   ocm->isacntl, ocm->dsarc, ocm->dsacntl);
@@ -830,10 +819,9 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
 
 static uint32_t dcr_read_ocm (void *opaque, int dcrn)
 {
-ppc405_ocm_t *ocm;
+Ppc405OcmState *ocm = PPC405_OCM(opaque);
 uint32_t ret;
 
-ocm = opaque;
 switch (dcrn) {
 case OCM0_ISARC:
 ret = ocm->isarc;
@@ -857,10 +845,9 @@ static uint32_t dcr_read_ocm (void *opaque, int dcrn)
 
 static void dcr_write_ocm (void *opaque, int dcrn, uint32_t val)
 {
-ppc405_ocm_t *ocm;
+Ppc405OcmState *ocm = PPC405_OCM(opaque);
 uint32_t isarc, dsarc, isacntl, dsacntl;
 
-ocm = opaque;
 isarc = ocm->isarc;
 dsarc = ocm->dsarc;
 isacntl = ocm->isacntl;
@@ -886,12 +873,11 @@ static void dcr_write_ocm (void *opaque, int dcrn, 
uint32_t val)
 ocm->dsacntl = dsacntl;
 }
 
-static void ocm_reset (void *opaque)
+static void ppc405_ocm_reset(DeviceState *dev)
 {
-ppc405_ocm_t *ocm;
+Ppc405OcmState *ocm = PPC405_OCM(dev);
 uint32_t isarc, dsarc, isacntl, dsacntl;
 
-ocm = opaque;
 isarc = 0x;
 isacntl = 0x;
 dsarc = 0x;
@@ -903,17 +889,21 @@ static void ocm_reset (void *opaque)
 ocm->dsacntl = dsacntl;
 }
 
-static void ppc405_ocm_init(CPUPPCState *env)
+static void ppc405_ocm_realize(DeviceState *dev, Error **errp)
 {
-ppc405_ocm_t *ocm;
+Ppc405OcmState *ocm = PPC405_OCM(dev);
+CPUPPCState *env;
+
+assert(ocm->cpu);
+
+env = &ocm->cpu->env;
 
-ocm = g_new0(ppc405_ocm_t, 1);
 /* XXX: Size is 4096 or 0x0400 */
-memory_region_init_ram(&ocm->isarc_ram, NULL, "ppc405.ocm", 4 * KiB,
+memory_region_init_ram(&ocm->isarc_ram, OBJECT(ocm), "ppc405.ocm", 4 * KiB,
&error_fatal);
-memory_region_init_alias(&ocm->dsarc_ram, NULL, "ppc405.dsarc",
+memory_region_init_alias(&ocm->dsarc_ram, OBJECT(ocm), "ppc405.dsarc",
  &ocm->isarc_ram, 0, 4 * KiB);
-qemu_register_reset(&ocm_reset, ocm);
+
 ppc_dcr_register(env, OCM0_ISARC,
  ocm, &dcr_read_ocm, &dcr_write_ocm);
 ppc_dcr_register(env, OCM0_ISACNTL,
@@ -924,6 +914,22 @@ static void ppc405_ocm_init(CPUPPCState *env)
  ocm, &dcr_read_ocm, &dcr_write_ocm);
 }
 
+static Property ppc405_ocm_properties[] = {
+DEFINE_PROP_LINK("cpu", Ppc405OcmState, cpu, TYPE_POWERPC_CPU,
+ PowerPCCPU *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_ocm_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = ppc405_ocm_realize;
+dc->user_creatable = false;
+dc->reset = ppc405_ocm_reset;
+device_class_set_props(dc, ppc405_ocm_properties);
+}
+
 /*/
 /* General purpose timers */
 static int ppc4xx_gpt_compare(Ppc405GptState *gpt, int n)
@@ -1413,6 +1419,8 @@ static void ppc405_so

[PATCH 02/19] ppc/ppc405: Introduce a PPC405 generic machine

2022-08-01 Thread Cédric Le Goater
We will use this machine as a base to define the ref405ep and possibly
the PPC405 hotfoot board as found in the Linux kernel.

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405_boards.c | 31 ---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 1a4e7588c584..4c269b6526a5 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -50,6 +50,15 @@
 
 #define USE_FLASH_BIOS
 
+struct Ppc405MachineState {
+/* Private */
+MachineState parent_obj;
+/* Public */
+};
+
+#define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE);
+
 /*/
 /* PPC405EP reference board (IBM) */
 /* Standalone board with:
@@ -332,18 +341,34 @@ static void ref405ep_class_init(ObjectClass *oc, void 
*data)
 
 mc->desc = "ref405ep";
 mc->init = ref405ep_init;
-mc->default_ram_size = 0x0800;
-mc->default_ram_id = "ef405ep.ram";
 }
 
 static const TypeInfo ref405ep_type = {
 .name = MACHINE_TYPE_NAME("ref405ep"),
-.parent = TYPE_MACHINE,
+.parent = TYPE_PPC405_MACHINE,
 .class_init = ref405ep_class_init,
 };
 
+static void ppc405_machine_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+
+mc->desc = "PPC405 generic machine";
+mc->default_ram_size = 0x0800;
+mc->default_ram_id = "ppc405.ram";
+}
+
+static const TypeInfo ppc405_machine_type = {
+.name = TYPE_PPC405_MACHINE,
+.parent = TYPE_MACHINE,
+.instance_size = sizeof(Ppc405MachineState),
+.class_init = ppc405_machine_class_init,
+.abstract = true,
+};
+
 static void ppc405_machine_init(void)
 {
+type_register_static(&ppc405_machine_type);
 type_register_static(&ref405ep_type);
 }
 
-- 
2.37.1




[PATCH 03/19] ppc/ppc405: Move devices under the ref405ep machine

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405_boards.c | 31 +++
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 4c269b6526a5..24ec948d22a4 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -230,13 +230,11 @@ static void boot_from_kernel(MachineState *machine, 
PowerPCCPU *cpu)
 env->load_info = &boot_info;
 }
 
-static void ref405ep_init(MachineState *machine)
+static void ppc405_init(MachineState *machine)
 {
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 const char *kernel_filename = machine->kernel_filename;
 PowerPCCPU *cpu;
-DeviceState *dev;
-SysBusDevice *s;
 MemoryRegion *sram = g_new(MemoryRegion, 1);
 MemoryRegion *ram_memories = g_new(MemoryRegion, 2);
 hwaddr ram_bases[2], ram_sizes[2];
@@ -294,15 +292,6 @@ static void ref405ep_init(MachineState *machine)
 memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
 }
 
-/* Register FPGA */
-ref405ep_fpga_init(sysmem, PPC405EP_FPGA_BASE);
-/* Register NVRAM */
-dev = qdev_new("sysbus-m48t08");
-qdev_prop_set_int32(dev, "base-year", 1968);
-s = SYS_BUS_DEVICE(dev);
-sysbus_realize_and_unref(s, &error_fatal);
-sysbus_mmio_map(s, 0, PPC405EP_NVRAM_BASE);
-
 /* Load kernel and initrd using U-Boot images */
 if (kernel_filename && machine->firmware) {
 target_ulong kernel_base, initrd_base;
@@ -335,6 +324,23 @@ static void ref405ep_init(MachineState *machine)
 }
 }
 
+static void ref405ep_init(MachineState *machine)
+{
+DeviceState *dev;
+SysBusDevice *s;
+
+ppc405_init(machine);
+
+/* Register FPGA */
+ref405ep_fpga_init(get_system_memory(), PPC405EP_FPGA_BASE);
+/* Register NVRAM */
+dev = qdev_new("sysbus-m48t08");
+qdev_prop_set_int32(dev, "base-year", 1968);
+s = SYS_BUS_DEVICE(dev);
+sysbus_realize_and_unref(s, &error_fatal);
+sysbus_mmio_map(s, 0, PPC405EP_NVRAM_BASE);
+}
+
 static void ref405ep_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -354,6 +360,7 @@ static void ppc405_machine_class_init(ObjectClass *oc, void 
*data)
 MachineClass *mc = MACHINE_CLASS(oc);
 
 mc->desc = "PPC405 generic machine";
+mc->init = ppc405_init;
 mc->default_ram_size = 0x0800;
 mc->default_ram_id = "ppc405.ram";
 }
-- 
2.37.1




[PATCH 04/19] ppc/ppc405: Introduce a PPC405 SoC

2022-08-01 Thread Cédric Le Goater
It is an initial model to start QOMification of the PPC405 board.

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 17 ++
 hw/ppc/ppc405_boards.c | 29 ++-
 hw/ppc/ppc405_uc.c | 53 ++
 3 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 83f156f585c8..c8cddb71733a 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -25,6 +25,7 @@
 #ifndef PPC405_H
 #define PPC405_H
 
+#include "qom/object.h"
 #include "hw/ppc/ppc4xx.h"
 
 #define PPC405EP_SDRAM_BASE 0x
@@ -62,6 +63,22 @@ struct ppc4xx_bd_info_t {
 uint32_t bi_iic_fast[2];
 };
 
+#define TYPE_PPC405_SOC "ppc405-soc"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC);
+
+struct Ppc405SoCState {
+/* Private */
+DeviceState parent_obj;
+
+/* Public */
+MemoryRegion sram;
+MemoryRegion ram_memories[2];
+hwaddr ram_bases[2], ram_sizes[2];
+
+MemoryRegion *dram_mr;
+hwaddr ram_size;
+};
+
 /* PowerPC 405 core */
 ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size);
 
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 24ec948d22a4..96db52c5a309 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -54,6 +54,8 @@ struct Ppc405MachineState {
 /* Private */
 MachineState parent_obj;
 /* Public */
+
+Ppc405SoCState soc;
 };
 
 #define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
@@ -232,12 +234,10 @@ static void boot_from_kernel(MachineState *machine, 
PowerPCCPU *cpu)
 
 static void ppc405_init(MachineState *machine)
 {
+Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 const char *kernel_filename = machine->kernel_filename;
 PowerPCCPU *cpu;
-MemoryRegion *sram = g_new(MemoryRegion, 1);
-MemoryRegion *ram_memories = g_new(MemoryRegion, 2);
-hwaddr ram_bases[2], ram_sizes[2];
 MemoryRegion *sysmem = get_system_memory();
 DeviceState *uicdev;
 
@@ -248,23 +248,18 @@ static void ppc405_init(MachineState *machine)
 exit(EXIT_FAILURE);
 }
 
-/* XXX: fix this */
-memory_region_init_alias(&ram_memories[0], NULL, "ef405ep.ram.alias",
- machine->ram, 0, machine->ram_size);
-ram_bases[0] = 0;
-ram_sizes[0] = machine->ram_size;
-memory_region_init(&ram_memories[1], NULL, "ef405ep.ram1", 0);
-ram_bases[1] = 0x;
-ram_sizes[1] = 0x;
+object_initialize_child(OBJECT(machine), "soc", &ppc405->soc,
+TYPE_PPC405_SOC);
+object_property_set_uint(OBJECT(&ppc405->soc), "ram-size",
+ machine->ram_size, &error_fatal);
+object_property_set_link(OBJECT(&ppc405->soc), "dram",
+ OBJECT(machine->ram), &error_abort);
+qdev_realize(DEVICE(&ppc405->soc), NULL, &error_abort);
 
-cpu = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
+cpu = ppc405ep_init(sysmem, ppc405->soc.ram_memories, 
ppc405->soc.ram_bases,
+ppc405->soc.ram_sizes,
 , &uicdev, kernel_filename == NULL ? 0 : 1);
 
-/* allocate SRAM */
-memory_region_init_ram(sram, NULL, "ef405ep.sram", PPC405EP_SRAM_SIZE,
-   &error_fatal);
-memory_region_add_subregion(sysmem, PPC405EP_SRAM_BASE, sram);
-
 /* allocate and load BIOS */
 if (machine->firmware) {
 MemoryRegion *bios = g_new(MemoryRegion, 1);
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index d6420c88d3a6..156e839b8283 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -30,6 +30,7 @@
 #include "hw/ppc/ppc.h"
 #include "hw/i2c/ppc4xx_i2c.h"
 #include "hw/irq.h"
+#include "hw/qdev-properties.h"
 #include "ppc405.h"
 #include "hw/char/serial.h"
 #include "qemu/timer.h"
@@ -1530,3 +1531,55 @@ PowerPCCPU *ppc405ep_init(MemoryRegion 
*address_space_mem,
 
 return cpu;
 }
+
+static void ppc405_soc_realize(DeviceState *dev, Error **errp)
+{
+Ppc405SoCState *s = PPC405_SOC(dev);
+Error *err = NULL;
+
+/* XXX: fix this ? */
+memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
+ "ef405ep.ram.alias", s->dram_mr, 0, s->ram_size);
+s->ram_bases[0] = 0;
+s->ram_sizes[0] = s->ram_size;
+memory_region_init(&s->ram_memories[1], OBJECT(s), "ef405ep.ram1", 0);
+s->ram_bases[1] = 0x;
+s->ram_sizes[1] = 0x;
+
+/* allocate SRAM */
+memory_region_init_ram(&s->sram, OBJECT(s), "ef405ep.sram",
+   PPC405EP_SRAM_SIZE,  &err);
+if (err) {
+error_propagate(errp, err);
+return;
+}
+memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
+&s->sram);
+}
+
+static Property ppc405_soc_properties[] = {
+DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_R

[PATCH 14/19] ppc/ppc405: QOM'ify POB

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 14 +++
 hw/ppc/ppc405_uc.c | 58 +++---
 2 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ebff00bdad80..d39d65cc86e4 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,19 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* PLB to OPB bridge */
+#define TYPE_PPC405_POB "ppc405-pob"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
+struct Ppc405PobState {
+DeviceState parent_obj;
+
+PowerPCCPU *cpu;
+
+uint32_t bear;
+uint32_t besr0;
+uint32_t besr1;
+};
+
 /* OPB arbitrer */
 #define TYPE_PPC405_OPBA "ppc405-opba"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OpbaState, PPC405_OPBA);
@@ -231,6 +244,7 @@ struct Ppc405SoCState {
 Ppc405DmaState dma;
 Ppc405EbcState ebc;
 Ppc405OpbaState opba;
+Ppc405PobState pob;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index c5de00de7981..218d911bca3c 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -234,19 +234,11 @@ enum {
 POB0_BEAR  = 0x0A4,
 };
 
-typedef struct ppc4xx_pob_t ppc4xx_pob_t;
-struct ppc4xx_pob_t {
-uint32_t bear;
-uint32_t besr0;
-uint32_t besr1;
-};
-
 static uint32_t dcr_read_pob (void *opaque, int dcrn)
 {
-ppc4xx_pob_t *pob;
+Ppc405PobState *pob = PPC405_POB(opaque);
 uint32_t ret;
 
-pob = opaque;
 switch (dcrn) {
 case POB0_BEAR:
 ret = pob->bear;
@@ -268,9 +260,8 @@ static uint32_t dcr_read_pob (void *opaque, int dcrn)
 
 static void dcr_write_pob (void *opaque, int dcrn, uint32_t val)
 {
-ppc4xx_pob_t *pob;
+Ppc405PobState *pob = PPC405_POB(opaque);
 
-pob = opaque;
 switch (dcrn) {
 case POB0_BEAR:
 /* Read only */
@@ -286,26 +277,44 @@ static void dcr_write_pob (void *opaque, int dcrn, 
uint32_t val)
 }
 }
 
-static void ppc4xx_pob_reset (void *opaque)
+static void ppc405_pob_reset(DeviceState *dev)
 {
-ppc4xx_pob_t *pob;
+Ppc405PobState *pob = PPC405_POB(dev);
 
-pob = opaque;
 /* No error */
 pob->bear = 0x;
 pob->besr0 = 0x000;
 pob->besr1 = 0x000;
 }
 
-static void ppc4xx_pob_init(CPUPPCState *env)
+static void ppc405_pob_realize(DeviceState *dev, Error **errp)
 {
-ppc4xx_pob_t *pob;
+Ppc405PobState *pob = PPC405_POB(dev);
+CPUPPCState *env;
+
+assert(pob->cpu);
+
+env = &pob->cpu->env;
 
-pob = g_new0(ppc4xx_pob_t, 1);
 ppc_dcr_register(env, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob);
 ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob);
 ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob);
-qemu_register_reset(ppc4xx_pob_reset, pob);
+}
+
+static Property ppc405_pob_properties[] = {
+DEFINE_PROP_LINK("cpu", Ppc405PobState, cpu, TYPE_POWERPC_CPU,
+ PowerPCCPU *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_pob_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = ppc405_pob_realize;
+dc->user_creatable = false;
+dc->reset = ppc405_pob_reset;
+device_class_set_props(dc, ppc405_pob_properties);
 }
 
 /*/
@@ -1435,6 +1444,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
 
 object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
+
+object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1484,7 +1495,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 ppc4xx_plb_init(env);
 
 /* PLB to OPB bridge */
-ppc4xx_pob_init(env);
+object_property_set_link(OBJECT(&s->pob), "cpu", OBJECT(&s->cpu),
+ &error_abort);
+if (!qdev_realize(DEVICE(&s->pob), NULL, errp)) {
+return;
+}
 
 /* OBP arbitrer */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->opba), errp)) {
@@ -1602,6 +1617,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
 
 static const TypeInfo ppc405_types[] = {
 {
+.name   = TYPE_PPC405_POB,
+.parent = TYPE_DEVICE,
+.instance_size  = sizeof(Ppc405PobState),
+.class_init = ppc405_pob_class_init,
+}, {
 .name   = TYPE_PPC405_OPBA,
 .parent = TYPE_SYS_BUS_DEVICE,
 .instance_size  = sizeof(Ppc405OpbaState),
-- 
2.37.1




[PATCH 08/19] ppc/ppc405: QOM'ify GPT

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 22 
 hw/ppc/ppc405_uc.c | 90 +++---
 2 files changed, 67 insertions(+), 45 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index d51fb5094e95..f7c0eb1d0008 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,27 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* General purpose timers */
+#define TYPE_PPC405_GPT "ppc405-gpt"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GptState, PPC405_GPT);
+struct Ppc405GptState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+
+int64_t tb_offset;
+uint32_t tb_freq;
+QEMUTimer *timer;
+qemu_irq irqs[5];
+uint32_t oe;
+uint32_t ol;
+uint32_t im;
+uint32_t is;
+uint32_t ie;
+uint32_t comp[5];
+uint32_t mask[5];
+};
+
 #define TYPE_PPC405_CPC "ppc405-cpc"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405CpcState, PPC405_CPC);
 
@@ -119,6 +140,7 @@ struct Ppc405SoCState {
 PowerPCCPU cpu;
 DeviceState *uic;
 Ppc405CpcState cpc;
+Ppc405GptState gpt;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 20a3e5543423..0f5e4ec15f14 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -926,34 +926,18 @@ static void ppc405_ocm_init(CPUPPCState *env)
 
 /*/
 /* General purpose timers */
-typedef struct ppc4xx_gpt_t ppc4xx_gpt_t;
-struct ppc4xx_gpt_t {
-MemoryRegion iomem;
-int64_t tb_offset;
-uint32_t tb_freq;
-QEMUTimer *timer;
-qemu_irq irqs[5];
-uint32_t oe;
-uint32_t ol;
-uint32_t im;
-uint32_t is;
-uint32_t ie;
-uint32_t comp[5];
-uint32_t mask[5];
-};
-
-static int ppc4xx_gpt_compare (ppc4xx_gpt_t *gpt, int n)
+static int ppc4xx_gpt_compare(Ppc405GptState *gpt, int n)
 {
 /* XXX: TODO */
 return 0;
 }
 
-static void ppc4xx_gpt_set_output (ppc4xx_gpt_t *gpt, int n, int level)
+static void ppc4xx_gpt_set_output(Ppc405GptState *gpt, int n, int level)
 {
 /* XXX: TODO */
 }
 
-static void ppc4xx_gpt_set_outputs (ppc4xx_gpt_t *gpt)
+static void ppc4xx_gpt_set_outputs(Ppc405GptState *gpt)
 {
 uint32_t mask;
 int i;
@@ -974,7 +958,7 @@ static void ppc4xx_gpt_set_outputs (ppc4xx_gpt_t *gpt)
 }
 }
 
-static void ppc4xx_gpt_set_irqs (ppc4xx_gpt_t *gpt)
+static void ppc4xx_gpt_set_irqs(Ppc405GptState *gpt)
 {
 uint32_t mask;
 int i;
@@ -989,14 +973,14 @@ static void ppc4xx_gpt_set_irqs (ppc4xx_gpt_t *gpt)
 }
 }
 
-static void ppc4xx_gpt_compute_timer (ppc4xx_gpt_t *gpt)
+static void ppc4xx_gpt_compute_timer(Ppc405GptState *gpt)
 {
 /* XXX: TODO */
 }
 
 static uint64_t ppc4xx_gpt_read(void *opaque, hwaddr addr, unsigned size)
 {
-ppc4xx_gpt_t *gpt = opaque;
+Ppc405GptState *gpt = PPC405_GPT(opaque);
 uint32_t ret;
 int idx;
 
@@ -1050,7 +1034,7 @@ static uint64_t ppc4xx_gpt_read(void *opaque, hwaddr 
addr, unsigned size)
 static void ppc4xx_gpt_write(void *opaque, hwaddr addr, uint64_t value,
  unsigned size)
 {
-ppc4xx_gpt_t *gpt = opaque;
+Ppc405GptState *gpt = PPC405_GPT(opaque);
 int idx;
 
 trace_ppc4xx_gpt_write(addr, size, value);
@@ -1116,20 +1100,18 @@ static const MemoryRegionOps gpt_ops = {
 
 static void ppc4xx_gpt_cb (void *opaque)
 {
-ppc4xx_gpt_t *gpt;
+Ppc405GptState *gpt = PPC405_GPT(opaque);
 
-gpt = opaque;
 ppc4xx_gpt_set_irqs(gpt);
 ppc4xx_gpt_set_outputs(gpt);
 ppc4xx_gpt_compute_timer(gpt);
 }
 
-static void ppc4xx_gpt_reset (void *opaque)
+static void ppc405_gpt_reset(DeviceState *dev)
 {
-ppc4xx_gpt_t *gpt;
+Ppc405GptState *gpt = PPC405_GPT(dev);
 int i;
 
-gpt = opaque;
 timer_del(gpt->timer);
 gpt->oe = 0x;
 gpt->ol = 0x;
@@ -1142,21 +1124,28 @@ static void ppc4xx_gpt_reset (void *opaque)
 }
 }
 
-static void ppc4xx_gpt_init(hwaddr base, qemu_irq irqs[5])
+static void ppc405_gpt_realize(DeviceState *dev, Error **errp)
 {
-ppc4xx_gpt_t *gpt;
+Ppc405GptState *s = PPC405_GPT(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 int i;
 
-trace_ppc4xx_gpt_init(base);
+s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ppc4xx_gpt_cb, s);
+memory_region_init_io(&s->iomem, OBJECT(s), &gpt_ops, s, "gpt", 0x0d4);
+sysbus_init_mmio(sbd, &s->iomem);
 
-gpt = g_new0(ppc4xx_gpt_t, 1);
-for (i = 0; i < 5; i++) {
-gpt->irqs[i] = irqs[i];
+for (i = 0; i < ARRAY_SIZE(s->irqs); i++) {
+sysbus_init_irq(sbd, &s->irqs[i]);
 }
-gpt->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ppc4xx_gpt_cb, gpt);
-memory_region_init_io(&gpt->iomem, NULL, &gpt_ops, gpt, "gpt", 0x0d4);
-memory_region_add_subregion(get_system_memory(), base, &gpt->iomem);
-qemu_register_reset(ppc4xx_gpt_reset, gpt);
+}
+
+static void ppc405_gpt_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DE

[PATCH 10/19] ppc/ppc405: QOM'ify GPIO

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 21 +++
 hw/ppc/ppc405_uc.c | 50 +-
 2 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index e56363366cad..46366c3b8a19 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,26 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* GPIO */
+#define TYPE_PPC405_GPIO "ppc405-gpio"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GpioState, PPC405_GPIO);
+struct Ppc405GpioState {
+SysBusDevice parent_obj;
+
+MemoryRegion io;
+uint32_t or;
+uint32_t tcr;
+uint32_t osrh;
+uint32_t osrl;
+uint32_t tsrh;
+uint32_t tsrl;
+uint32_t odr;
+uint32_t ir;
+uint32_t rr1;
+uint32_t isr1h;
+uint32_t isr1l;
+};
+
 /* On Chip Memory */
 #define TYPE_PPC405_OCM "ppc405-ocm"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OcmState, PPC405_OCM);
@@ -159,6 +179,7 @@ struct Ppc405SoCState {
 Ppc405CpcState cpc;
 Ppc405GptState gpt;
 Ppc405OcmState ocm;
+Ppc405GpioState gpio;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 59cade4c0680..a6c4e6934ffc 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -713,23 +713,6 @@ static void ppc405_dma_init(CPUPPCState *env, qemu_irq 
irqs[4])
 }
 
 /*/
-/* GPIO */
-typedef struct ppc405_gpio_t ppc405_gpio_t;
-struct ppc405_gpio_t {
-MemoryRegion io;
-uint32_t or;
-uint32_t tcr;
-uint32_t osrh;
-uint32_t osrl;
-uint32_t tsrh;
-uint32_t tsrl;
-uint32_t odr;
-uint32_t ir;
-uint32_t rr1;
-uint32_t isr1h;
-uint32_t isr1l;
-};
-
 static uint64_t ppc405_gpio_read(void *opaque, hwaddr addr, unsigned size)
 {
 trace_ppc405_gpio_read(addr, size);
@@ -748,20 +731,22 @@ static const MemoryRegionOps ppc405_gpio_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void ppc405_gpio_reset (void *opaque)
+static void ppc405_gpio_realize(DeviceState *dev, Error **errp)
 {
+Ppc405GpioState *s = PPC405_GPIO(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+memory_region_init_io(&s->io, OBJECT(s), &ppc405_gpio_ops, s, "gpio",
+  0x038);
+sysbus_init_mmio(sbd, &s->io);
 }
 
-static void ppc405_gpio_init(hwaddr base)
+static void ppc405_gpio_class_init(ObjectClass *oc, void *data)
 {
-ppc405_gpio_t *gpio;
-
-trace_ppc405_gpio_init(base);
+DeviceClass *dc = DEVICE_CLASS(oc);
 
-gpio = g_new0(ppc405_gpio_t, 1);
-memory_region_init_io(&gpio->io, NULL, &ppc405_gpio_ops, gpio, "pgio", 
0x038);
-memory_region_add_subregion(get_system_memory(), base, &gpio->io);
-qemu_register_reset(&ppc405_gpio_reset, gpio);
+dc->realize = ppc405_gpio_realize;
+dc->user_creatable = false;
 }
 
 /*/
@@ -1421,6 +1406,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "gpt", &s->gpt, TYPE_PPC405_GPT);
 
 object_initialize_child(obj, "ocm", &s->ocm, TYPE_PPC405_OCM);
+
+object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1507,8 +1494,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 /* I2C controller */
 sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
  qdev_get_gpio_in(s->uic, 2));
+
 /* GPIO */
-ppc405_gpio_init(0xef600700);
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, 0xef600700);
 
 /* Serial ports */
 if (serial_hd(0) != NULL) {
@@ -1572,6 +1563,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
 
 static const TypeInfo ppc405_types[] = {
 {
+.name   = TYPE_PPC405_GPIO,
+.parent = TYPE_SYS_BUS_DEVICE,
+.instance_size  = sizeof(Ppc405GpioState),
+.class_init = ppc405_gpio_class_init,
+}, {
 .name   = TYPE_PPC405_OCM,
 .parent = TYPE_SYS_BUS_DEVICE,
 .instance_size  = sizeof(Ppc405OcmState),
-- 
2.37.1




[PATCH 15/19] ppc/ppc405: QOM'ify PLB

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 14 ++
 hw/ppc/ppc405_uc.c | 67 +-
 2 files changed, 62 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index d39d65cc86e4..4ff5cdcf5c65 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,19 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* Peripheral local bus arbitrer */
+#define TYPE_PPC405_PLB "ppc405-plb"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PlbState, PPC405_PLB);
+struct Ppc405PlbState {
+DeviceState parent_obj;
+
+PowerPCCPU *cpu;
+
+uint32_t acr;
+uint32_t bear;
+uint32_t besr;
+};
+
 /* PLB to OPB bridge */
 #define TYPE_PPC405_POB "ppc405-pob"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB);
@@ -245,6 +258,7 @@ struct Ppc405SoCState {
 Ppc405EbcState ebc;
 Ppc405OpbaState opba;
 Ppc405PobState pob;
+Ppc405PlbState plb;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 218d911bca3c..45bcf3a6dd8a 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -148,19 +148,11 @@ enum {
 PLB4A1_ACR = 0x089,
 };
 
-typedef struct ppc4xx_plb_t ppc4xx_plb_t;
-struct ppc4xx_plb_t {
-uint32_t acr;
-uint32_t bear;
-uint32_t besr;
-};
-
 static uint32_t dcr_read_plb (void *opaque, int dcrn)
 {
-ppc4xx_plb_t *plb;
+Ppc405PlbState *plb = PPC405_PLB(opaque);
 uint32_t ret;
 
-plb = opaque;
 switch (dcrn) {
 case PLB0_ACR:
 ret = plb->acr;
@@ -182,9 +174,8 @@ static uint32_t dcr_read_plb (void *opaque, int dcrn)
 
 static void dcr_write_plb (void *opaque, int dcrn, uint32_t val)
 {
-ppc4xx_plb_t *plb;
+Ppc405PlbState *plb = PPC405_PLB(opaque);
 
-plb = opaque;
 switch (dcrn) {
 case PLB0_ACR:
 /* We don't care about the actual parameters written as
@@ -202,28 +193,55 @@ static void dcr_write_plb (void *opaque, int dcrn, 
uint32_t val)
 }
 }
 
-static void ppc4xx_plb_reset (void *opaque)
+static void ppc405_plb_reset(DeviceState *dev)
 {
-ppc4xx_plb_t *plb;
+Ppc405PlbState *plb = PPC405_PLB(dev);
 
-plb = opaque;
 plb->acr = 0x;
 plb->bear = 0x;
 plb->besr = 0x;
 }
 
-void ppc4xx_plb_init(CPUPPCState *env)
+static void ppc405_plb_realize(DeviceState *dev, Error **errp)
 {
-ppc4xx_plb_t *plb;
+Ppc405PlbState *plb = PPC405_PLB(dev);
+CPUPPCState *env;
+
+assert(plb->cpu);
+
+env = &plb->cpu->env;
 
-plb = g_new0(ppc4xx_plb_t, 1);
 ppc_dcr_register(env, PLB3A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
 ppc_dcr_register(env, PLB4A0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
 ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
 ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
 ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
 ppc_dcr_register(env, PLB4A1_ACR, plb, &dcr_read_plb, &dcr_write_plb);
-qemu_register_reset(ppc4xx_plb_reset, plb);
+}
+
+static Property ppc405_plb_properties[] = {
+DEFINE_PROP_LINK("cpu", Ppc405PlbState, cpu, TYPE_POWERPC_CPU,
+ PowerPCCPU *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_plb_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = ppc405_plb_realize;
+dc->user_creatable = false;
+dc->reset = ppc405_plb_reset;
+device_class_set_props(dc, ppc405_plb_properties);
+}
+
+void ppc4xx_plb_init(CPUPPCState *env)
+{
+PowerPCCPU *cpu = env_archcpu(env);
+DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
+
+object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
+qdev_realize_and_unref(dev, NULL, &error_fatal);
 }
 
 /*/
@@ -1446,6 +1464,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
 
 object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB);
+
+object_initialize_child(obj, "plb", &s->plb, TYPE_PPC405_PLB);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1492,7 +1512,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 }
 
 /* PLB arbitrer */
-ppc4xx_plb_init(env);
+object_property_set_link(OBJECT(&s->plb), "cpu", OBJECT(&s->cpu),
+ &error_abort);
+if (!qdev_realize(DEVICE(&s->plb), NULL, errp)) {
+return;
+}
 
 /* PLB to OPB bridge */
 object_property_set_link(OBJECT(&s->pob), "cpu", OBJECT(&s->cpu),
@@ -1617,6 +1641,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
 
 static const TypeInfo ppc405_types[] = {
 {
+.name   = TYPE_PPC405_PLB,
+.parent = TYPE_DEVICE,
+.instance_size  = sizeof(Ppc405PlbState),
+.class_init = 

[PATCH 05/19] ppc/ppc405: Start QOMification of the SoC

2022-08-01 Thread Cédric Le Goater
This moves all the code previously done in the ppc405ep_init() routine
under ppc405_soc_realize().

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h|  12 ++--
 hw/ppc/ppc405_boards.c |  12 ++--
 hw/ppc/ppc405_uc.c | 151 -
 3 files changed, 84 insertions(+), 91 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index c8cddb71733a..5e4e96d86ceb 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -74,9 +74,14 @@ struct Ppc405SoCState {
 MemoryRegion sram;
 MemoryRegion ram_memories[2];
 hwaddr ram_bases[2], ram_sizes[2];
+bool do_dram_init;
 
 MemoryRegion *dram_mr;
 hwaddr ram_size;
+
+uint32_t sysclk;
+PowerPCCPU *cpu;
+DeviceState *uic;
 };
 
 /* PowerPC 405 core */
@@ -85,11 +90,4 @@ ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t 
ram_size);
 void ppc4xx_plb_init(CPUPPCState *env);
 void ppc405_ebc_init(CPUPPCState *env);
 
-PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
-MemoryRegion ram_memories[2],
-hwaddr ram_bases[2],
-hwaddr ram_sizes[2],
-uint32_t sysclk, DeviceState **uicdev,
-int do_init);
-
 #endif /* PPC405_H */
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 96db52c5a309..363cb0770506 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -237,9 +237,7 @@ static void ppc405_init(MachineState *machine)
 Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 const char *kernel_filename = machine->kernel_filename;
-PowerPCCPU *cpu;
 MemoryRegion *sysmem = get_system_memory();
-DeviceState *uicdev;
 
 if (machine->ram_size != mc->default_ram_size) {
 char *sz = size_to_str(mc->default_ram_size);
@@ -254,12 +252,12 @@ static void ppc405_init(MachineState *machine)
  machine->ram_size, &error_fatal);
 object_property_set_link(OBJECT(&ppc405->soc), "dram",
  OBJECT(machine->ram), &error_abort);
+object_property_set_bool(OBJECT(&ppc405->soc), "dram-init",
+ !(kernel_filename == NULL), &error_abort);
+object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", ,
+ &error_abort);
 qdev_realize(DEVICE(&ppc405->soc), NULL, &error_abort);
 
-cpu = ppc405ep_init(sysmem, ppc405->soc.ram_memories, 
ppc405->soc.ram_bases,
-ppc405->soc.ram_sizes,
-, &uicdev, kernel_filename == NULL ? 0 : 1);
-
 /* allocate and load BIOS */
 if (machine->firmware) {
 MemoryRegion *bios = g_new(MemoryRegion, 1);
@@ -315,7 +313,7 @@ static void ppc405_init(MachineState *machine)
 
 /* Load ELF kernel and rootfs.cpio */
 } else if (kernel_filename && !machine->firmware) {
-boot_from_kernel(machine, cpu);
+boot_from_kernel(machine, ppc405->soc.cpu);
 }
 }
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 156e839b8283..59612504bf3f 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1432,134 +1432,131 @@ static void ppc405ep_cpc_init (CPUPPCState *env, 
clk_setup_t clk_setup[8],
 #endif
 }
 
-PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem,
-MemoryRegion ram_memories[2],
-hwaddr ram_bases[2],
-hwaddr ram_sizes[2],
-uint32_t sysclk, DeviceState **uicdevp,
-int do_init)
+static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
+Ppc405SoCState *s = PPC405_SOC(dev);
 clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup;
 qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
-PowerPCCPU *cpu;
 CPUPPCState *env;
-DeviceState *uicdev;
-SysBusDevice *uicsbd;
+Error *err = NULL;
+
+/* XXX: fix this ? */
+memory_region_init_alias(&s->ram_memories[0], OBJECT(s),
+ "ef405ep.ram.alias", s->dram_mr, 0, s->ram_size);
+s->ram_bases[0] = 0;
+s->ram_sizes[0] = s->ram_size;
+memory_region_init(&s->ram_memories[1], OBJECT(s), "ef405ep.ram1", 0);
+s->ram_bases[1] = 0x;
+s->ram_sizes[1] = 0x;
+
+/* allocate SRAM */
+memory_region_init_ram(&s->sram, OBJECT(s), "ef405ep.sram",
+   PPC405EP_SRAM_SIZE, &err);
+if (err) {
+error_propagate(errp, err);
+return;
+}
+memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE,
+&s->sram);
 
 memset(clk_setup, 0, sizeof(clk_setup));
+
 /* init CPUs */
-cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
+s->cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
   &clk_setup[PPC405EP_CPU_CLK],
-  &tlb_clk_setup, sysclk);
- 

[PATCH 07/19] ppc/ppc405: QOM'ify CPC

2022-08-01 Thread Cédric Le Goater
Since all clock settings are now handled at the CPC level, this changes
the SoC "sys-clk" property to be an alias on the same property in the
CPC model.

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h|  39 +++-
 hw/ppc/ppc405_uc.c | 109 +++--
 2 files changed, 85 insertions(+), 63 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 4e99ab48be36..d51fb5094e95 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -63,6 +63,43 @@ struct ppc4xx_bd_info_t {
 uint32_t bi_iic_fast[2];
 };
 
+typedef struct Ppc405SoCState Ppc405SoCState;
+
+#define TYPE_PPC405_CPC "ppc405-cpc"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405CpcState, PPC405_CPC);
+
+enum {
+PPC405EP_CPU_CLK   = 0,
+PPC405EP_PLB_CLK   = 1,
+PPC405EP_OPB_CLK   = 2,
+PPC405EP_EBC_CLK   = 3,
+PPC405EP_MAL_CLK   = 4,
+PPC405EP_PCI_CLK   = 5,
+PPC405EP_UART0_CLK = 6,
+PPC405EP_UART1_CLK = 7,
+PPC405EP_CLK_NB= 8,
+};
+
+struct Ppc405CpcState {
+DeviceState parent_obj;
+
+PowerPCCPU *cpu;
+
+uint32_t sysclk;
+clk_setup_t clk_setup[PPC405EP_CLK_NB];
+uint32_t boot;
+uint32_t epctl;
+uint32_t pllmr[2];
+uint32_t ucr;
+uint32_t srr;
+uint32_t jtagid;
+uint32_t pci;
+/* Clock and power management */
+uint32_t er;
+uint32_t fr;
+uint32_t sr;
+};
+
 #define TYPE_PPC405_SOC "ppc405-soc"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC);
 
@@ -79,9 +116,9 @@ struct Ppc405SoCState {
 MemoryRegion *dram_mr;
 hwaddr ram_size;
 
-uint32_t sysclk;
 PowerPCCPU cpu;
 DeviceState *uic;
+Ppc405CpcState cpc;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index b84749b36114..20a3e5543423 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1178,36 +1178,7 @@ enum {
 #endif
 };
 
-enum {
-PPC405EP_CPU_CLK   = 0,
-PPC405EP_PLB_CLK   = 1,
-PPC405EP_OPB_CLK   = 2,
-PPC405EP_EBC_CLK   = 3,
-PPC405EP_MAL_CLK   = 4,
-PPC405EP_PCI_CLK   = 5,
-PPC405EP_UART0_CLK = 6,
-PPC405EP_UART1_CLK = 7,
-PPC405EP_CLK_NB= 8,
-};
-
-typedef struct ppc405ep_cpc_t ppc405ep_cpc_t;
-struct ppc405ep_cpc_t {
-uint32_t sysclk;
-clk_setup_t clk_setup[PPC405EP_CLK_NB];
-uint32_t boot;
-uint32_t epctl;
-uint32_t pllmr[2];
-uint32_t ucr;
-uint32_t srr;
-uint32_t jtagid;
-uint32_t pci;
-/* Clock and power management */
-uint32_t er;
-uint32_t fr;
-uint32_t sr;
-};
-
-static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
+static void ppc405ep_compute_clocks(Ppc405CpcState *cpc)
 {
 uint32_t CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk;
 uint32_t UART0_clk, UART1_clk;
@@ -1302,10 +1273,9 @@ static void ppc405ep_compute_clocks (ppc405ep_cpc_t *cpc)
 
 static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
 {
-ppc405ep_cpc_t *cpc;
+Ppc405CpcState *cpc = PPC405_CPC(opaque);
 uint32_t ret;
 
-cpc = opaque;
 switch (dcrn) {
 case PPC405EP_CPC0_BOOT:
 ret = cpc->boot;
@@ -1342,9 +1312,8 @@ static uint32_t dcr_read_epcpc (void *opaque, int dcrn)
 
 static void dcr_write_epcpc (void *opaque, int dcrn, uint32_t val)
 {
-ppc405ep_cpc_t *cpc;
+Ppc405CpcState *cpc = PPC405_CPC(opaque);
 
-cpc = opaque;
 switch (dcrn) {
 case PPC405EP_CPC0_BOOT:
 /* Read-only register */
@@ -1377,9 +1346,9 @@ static void dcr_write_epcpc (void *opaque, int dcrn, 
uint32_t val)
 }
 }
 
-static void ppc405ep_cpc_reset (void *opaque)
+static void ppc405_cpc_reset(DeviceState *dev)
 {
-ppc405ep_cpc_t *cpc = opaque;
+Ppc405CpcState *cpc = PPC405_CPC(dev);
 
 cpc->boot = 0x0010; /* Boot from PCI - IIC EEPROM disabled */
 cpc->epctl = 0x;
@@ -1391,21 +1360,24 @@ static void ppc405ep_cpc_reset (void *opaque)
 cpc->er = 0x;
 cpc->fr = 0x;
 cpc->sr = 0x;
+cpc->jtagid = 0x20267049;
 ppc405ep_compute_clocks(cpc);
 }
 
 /* XXX: sysclk should be between 25 and 100 MHz */
-static void ppc405ep_cpc_init (CPUPPCState *env, clk_setup_t clk_setup[8],
-   uint32_t sysclk)
+static void ppc405_cpc_realize(DeviceState *dev, Error **errp)
 {
-ppc405ep_cpc_t *cpc;
+Ppc405CpcState *cpc = PPC405_CPC(dev);
+CPUPPCState *env;
+
+assert(cpc->cpu);
+
+env = &cpc->cpu->env;
+
+cpc->clk_setup[PPC405EP_CPU_CLK].cb =
+ppc_40x_timers_init(env, cpc->sysclk, PPC_INTERRUPT_PIT);
+cpc->clk_setup[PPC405EP_CPU_CLK].opaque = env;
 
-cpc = g_new0(ppc405ep_cpc_t, 1);
-memcpy(cpc->clk_setup, clk_setup,
-   PPC405EP_CLK_NB * sizeof(clk_setup_t));
-cpc->jtagid = 0x20267049;
-cpc->sysclk = sysclk;
-qemu_register_reset(&ppc405ep_cpc_reset, cpc);
 ppc_dcr_register(env, PPC405EP_CPC0_BOOT, cpc,
  &dcr_read_epcpc, &dcr_write_epcpc);
 ppc_dcr_register(env, PPC405EP_CPC0_EPCTL, cpc,
@@ -1422

[PATCH 06/19] ppc/ppc405: QOM'ify CPU

2022-08-01 Thread Cédric Le Goater
Drop the use of ppc4xx_init() and duplicate a bit of code related to
clocks in the SoC realize routine. We will clean that up in the
following patches.

ppc_dcr_init simply allocates default DCR handlers for the CPU. Maybe
this could be done in model initializer of the CPU families needing it.

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h|  2 +-
 hw/ppc/ppc405_boards.c |  2 +-
 hw/ppc/ppc405_uc.c | 34 --
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 5e4e96d86ceb..4e99ab48be36 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -80,7 +80,7 @@ struct Ppc405SoCState {
 hwaddr ram_size;
 
 uint32_t sysclk;
-PowerPCCPU *cpu;
+PowerPCCPU cpu;
 DeviceState *uic;
 };
 
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 363cb0770506..82b51cc457fa 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -313,7 +313,7 @@ static void ppc405_init(MachineState *machine)
 
 /* Load ELF kernel and rootfs.cpio */
 } else if (kernel_filename && !machine->firmware) {
-boot_from_kernel(machine, ppc405->soc.cpu);
+boot_from_kernel(machine, &ppc405->soc.cpu);
 }
 }
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 59612504bf3f..b84749b36114 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1432,10 +1432,18 @@ static void ppc405ep_cpc_init (CPUPPCState *env, 
clk_setup_t clk_setup[8],
 #endif
 }
 
+static void ppc405_soc_instance_init(Object *obj)
+{
+Ppc405SoCState *s = PPC405_SOC(obj);
+
+object_initialize_child(obj, "cpu", &s->cpu,
+POWERPC_CPU_TYPE_NAME("405ep"));
+}
+
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
 Ppc405SoCState *s = PPC405_SOC(dev);
-clk_setup_t clk_setup[PPC405EP_CLK_NB], tlb_clk_setup;
+clk_setup_t clk_setup[PPC405EP_CLK_NB];
 qemu_irq dma_irqs[4], gpt_irqs[5], mal_irqs[4];
 CPUPPCState *env;
 Error *err = NULL;
@@ -1462,12 +1470,17 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 memset(clk_setup, 0, sizeof(clk_setup));
 
 /* init CPUs */
-s->cpu = ppc4xx_init(POWERPC_CPU_TYPE_NAME("405ep"),
-  &clk_setup[PPC405EP_CPU_CLK],
-  &tlb_clk_setup, s->sysclk);
-env = &s->cpu->env;
-clk_setup[PPC405EP_CPU_CLK].cb = tlb_clk_setup.cb;
-clk_setup[PPC405EP_CPU_CLK].opaque = tlb_clk_setup.opaque;
+if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
+return;
+}
+
+env = &s->cpu.env;
+
+clk_setup[PPC405EP_CPU_CLK].cb =
+ppc_40x_timers_init(env, s->sysclk, PPC_INTERRUPT_PIT);
+clk_setup[PPC405EP_CPU_CLK].opaque = env;
+
+ppc_dcr_init(env, NULL, NULL);
 
 /* CPU control */
 ppc405ep_cpc_init(env, clk_setup, s->sysclk);
@@ -1484,16 +1497,16 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 /* Universal interrupt controller */
 s->uic = qdev_new(TYPE_PPC_UIC);
 
-object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(s->cpu),
+object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(&s->cpu),
  &error_fatal);
 if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
 return;
 }
 
 sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
-   qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_INT));
+   qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_INT));
 sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
-   qdev_get_gpio_in(DEVICE(s->cpu), PPC40x_INPUT_CINT));
+   qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
 /* XXX 405EP has no ECC interrupt */
@@ -1575,6 +1588,7 @@ static const TypeInfo ppc405_types[] = {
 .name   = TYPE_PPC405_SOC,
 .parent = TYPE_DEVICE,
 .instance_size  = sizeof(Ppc405SoCState),
+.instance_init  = ppc405_soc_instance_init,
 .class_init = ppc405_soc_class_init,
 }
 };
-- 
2.37.1




[PATCH 13/19] ppc/ppc405: QOM'ify OPBA

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 12 
 hw/ppc/ppc405_uc.c | 47 +++---
 2 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index f1acb37185f5..ebff00bdad80 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,17 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* OPB arbitrer */
+#define TYPE_PPC405_OPBA "ppc405-opba"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OpbaState, PPC405_OPBA);
+struct Ppc405OpbaState {
+SysBusDevice parent_obj;
+
+MemoryRegion io;
+uint8_t cr;
+uint8_t pr;
+};
+
 /* Peripheral controller */
 #define TYPE_PPC405_EBC "ppc405-ebc"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
@@ -219,6 +230,7 @@ struct Ppc405SoCState {
 Ppc405GpioState gpio;
 Ppc405DmaState dma;
 Ppc405EbcState ebc;
+Ppc405OpbaState opba;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 8d73b8c2dff0..c5de00de7981 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -310,16 +310,10 @@ static void ppc4xx_pob_init(CPUPPCState *env)
 
 /*/
 /* OPB arbitrer */
-typedef struct ppc4xx_opba_t ppc4xx_opba_t;
-struct ppc4xx_opba_t {
-MemoryRegion io;
-uint8_t cr;
-uint8_t pr;
-};
 
 static uint64_t opba_readb(void *opaque, hwaddr addr, unsigned size)
 {
-ppc4xx_opba_t *opba = opaque;
+Ppc405OpbaState *opba = PPC405_OPBA(opaque);
 uint32_t ret;
 
 switch (addr) {
@@ -341,7 +335,7 @@ static uint64_t opba_readb(void *opaque, hwaddr addr, 
unsigned size)
 static void opba_writeb(void *opaque, hwaddr addr, uint64_t value,
 unsigned size)
 {
-ppc4xx_opba_t *opba = opaque;
+Ppc405OpbaState *opba = PPC405_OPBA(opaque);
 
 trace_opba_writeb(addr, value);
 
@@ -366,25 +360,30 @@ static const MemoryRegionOps opba_ops = {
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static void ppc4xx_opba_reset (void *opaque)
+static void ppc405_opba_reset(DeviceState *dev)
 {
-ppc4xx_opba_t *opba;
+Ppc405OpbaState *opba = PPC405_OPBA(dev);
 
-opba = opaque;
 opba->cr = 0x00; /* No dynamic priorities - park disabled */
 opba->pr = 0x11;
 }
 
-static void ppc4xx_opba_init(hwaddr base)
+static void ppc405_opba_realize(DeviceState *dev, Error **errp)
 {
-ppc4xx_opba_t *opba;
+Ppc405OpbaState *s = PPC405_OPBA(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
-trace_opba_init(base);
+memory_region_init_io(&s->io, OBJECT(s), &opba_ops, s, "opba", 0x002);
+sysbus_init_mmio(sbd, &s->io);
+}
+
+static void ppc405_opba_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
 
-opba = g_new0(ppc4xx_opba_t, 1);
-memory_region_init_io(&opba->io, NULL, &opba_ops, opba, "opba", 0x002);
-memory_region_add_subregion(get_system_memory(), base, &opba->io);
-qemu_register_reset(ppc4xx_opba_reset, opba);
+dc->realize = ppc405_opba_realize;
+dc->reset = ppc405_opba_reset;
+dc->user_creatable = false;
 }
 
 /*/
@@ -1434,6 +1433,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
 
 object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
+
+object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1486,7 +1487,10 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 ppc4xx_pob_init(env);
 
 /* OBP arbitrer */
-ppc4xx_opba_init(0xef600600);
+   if (!sysbus_realize(SYS_BUS_DEVICE(&s->opba), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->opba), 0, 0xef600600);
 
 /* Universal interrupt controller */
 s->uic = qdev_new(TYPE_PPC_UIC);
@@ -1598,6 +1602,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
 
 static const TypeInfo ppc405_types[] = {
 {
+.name   = TYPE_PPC405_OPBA,
+.parent = TYPE_SYS_BUS_DEVICE,
+.instance_size  = sizeof(Ppc405OpbaState),
+.class_init = ppc405_opba_class_init,
+}, {
 .name   = TYPE_PPC405_EBC,
 .parent = TYPE_DEVICE,
 .instance_size  = sizeof(Ppc405EbcState),
-- 
2.37.1




[PATCH 19/19] ppc/ppc405: QOM'ify I2C

2022-08-01 Thread Cédric Le Goater
Having an explicit I2C model object will help if one day we want to
add I2C devices on the bus.

Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h|  2 ++
 hw/ppc/ppc405_uc.c | 10 --
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index c2cfccb9d106..0b1e15c18fe0 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -28,6 +28,7 @@
 #include "qom/object.h"
 #include "hw/ppc/ppc4xx.h"
 #include "hw/intc/ppc-uic.h"
+#include "hw/i2c/ppc4xx_i2c.h"
 
 #define PPC405EP_SDRAM_BASE 0x
 #define PPC405EP_NVRAM_BASE 0xF000
@@ -256,6 +257,7 @@ struct Ppc405SoCState {
 Ppc405OcmState ocm;
 Ppc405GpioState gpio;
 Ppc405DmaState dma;
+PPC4xxI2CState i2c;
 Ppc405EbcState ebc;
 Ppc405OpbaState opba;
 Ppc405PobState pob;
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 0336d1e08689..5372c308c227 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1461,6 +1461,8 @@ static void ppc405_soc_instance_init(Object *obj)
 
 object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
 
+object_initialize_child(obj, "i2c", &s->i2c, TYPE_PPC4xx_I2C);
+
 object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
 
 object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA);
@@ -1572,8 +1574,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 }
 
 /* I2C controller */
-sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
- qdev_get_gpio_in(DEVICE(&s->uic), 2));
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
+return;
+}
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, 0xef600500);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
+   qdev_get_gpio_in(DEVICE(&s->uic), 2));
 
 /* GPIO */
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
-- 
2.37.1




[PATCH 12/19] ppc/ppc405: QOM'ify EBC

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 16 +++
 hw/ppc/ppc405_uc.c | 71 +++---
 2 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index bd662b2444ff..f1acb37185f5 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,7 +65,22 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+/* Peripheral controller */
+#define TYPE_PPC405_EBC "ppc405-ebc"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405EbcState, PPC405_EBC);
+struct Ppc405EbcState {
+DeviceState parent_obj;
+
+PowerPCCPU *cpu;
 
+uint32_t addr;
+uint32_t bcr[8];
+uint32_t bap[8];
+uint32_t bear;
+uint32_t besr0;
+uint32_t besr1;
+uint32_t cfg;
+};
 
 /* DMA controller */
 #define TYPE_PPC405_DMA "ppc405-dma"
@@ -203,6 +218,7 @@ struct Ppc405SoCState {
 Ppc405OcmState ocm;
 Ppc405GpioState gpio;
 Ppc405DmaState dma;
+Ppc405EbcState ebc;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 2978a2665a4f..8d73b8c2dff0 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -393,17 +393,6 @@ static void ppc4xx_opba_init(hwaddr base)
 
 /*/
 /* Peripheral controller */
-typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
-struct ppc4xx_ebc_t {
-uint32_t addr;
-uint32_t bcr[8];
-uint32_t bap[8];
-uint32_t bear;
-uint32_t besr0;
-uint32_t besr1;
-uint32_t cfg;
-};
-
 enum {
 EBC0_CFGADDR = 0x012,
 EBC0_CFGDATA = 0x013,
@@ -411,10 +400,9 @@ enum {
 
 static uint32_t dcr_read_ebc (void *opaque, int dcrn)
 {
-ppc4xx_ebc_t *ebc;
+Ppc405EbcState *ebc = PPC405_EBC(opaque);
 uint32_t ret;
 
-ebc = opaque;
 switch (dcrn) {
 case EBC0_CFGADDR:
 ret = ebc->addr;
@@ -496,9 +484,8 @@ static uint32_t dcr_read_ebc (void *opaque, int dcrn)
 
 static void dcr_write_ebc (void *opaque, int dcrn, uint32_t val)
 {
-ppc4xx_ebc_t *ebc;
+Ppc405EbcState *ebc = PPC405_EBC(opaque);
 
-ebc = opaque;
 switch (dcrn) {
 case EBC0_CFGADDR:
 ebc->addr = val;
@@ -554,12 +541,11 @@ static void dcr_write_ebc (void *opaque, int dcrn, 
uint32_t val)
 }
 }
 
-static void ebc_reset (void *opaque)
+static void ppc405_ebc_reset(DeviceState *dev)
 {
-ppc4xx_ebc_t *ebc;
+Ppc405EbcState *ebc = PPC405_EBC(dev);
 int i;
 
-ebc = opaque;
 ebc->addr = 0x;
 ebc->bap[0] = 0x7F8FFE80;
 ebc->bcr[0] = 0xFFE28000;
@@ -572,18 +558,46 @@ static void ebc_reset (void *opaque)
 ebc->cfg = 0x8040;
 }
 
-void ppc405_ebc_init(CPUPPCState *env)
+static void ppc405_ebc_realize(DeviceState *dev, Error **errp)
 {
-ppc4xx_ebc_t *ebc;
+Ppc405EbcState *ebc = PPC405_EBC(dev);
+CPUPPCState *env;
+
+assert(ebc->cpu);
+
+env = &ebc->cpu->env;
 
-ebc = g_new0(ppc4xx_ebc_t, 1);
-qemu_register_reset(&ebc_reset, ebc);
 ppc_dcr_register(env, EBC0_CFGADDR,
  ebc, &dcr_read_ebc, &dcr_write_ebc);
 ppc_dcr_register(env, EBC0_CFGDATA,
  ebc, &dcr_read_ebc, &dcr_write_ebc);
 }
 
+static Property ppc405_ebc_properties[] = {
+DEFINE_PROP_LINK("cpu", Ppc405EbcState, cpu, TYPE_POWERPC_CPU,
+ PowerPCCPU *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_ebc_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = ppc405_ebc_realize;
+dc->user_creatable = false;
+dc->reset = ppc405_ebc_reset;
+device_class_set_props(dc, ppc405_ebc_properties);
+}
+
+void ppc405_ebc_init(CPUPPCState *env)
+{
+PowerPCCPU *cpu = env_archcpu(env);
+DeviceState *dev = qdev_new(TYPE_PPC405_EBC);
+
+object_property_set_link(OBJECT(cpu), "cpu", OBJECT(dev), &error_abort);
+qdev_realize_and_unref(dev, NULL, &error_fatal);
+}
+
 /*/
 /* DMA controller */
 enum {
@@ -1418,6 +1432,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
 
 object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
+
+object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC405_EBC);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
@@ -1492,7 +1508,11 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
   s->ram_bases, s->ram_sizes, s->do_dram_init);
 
 /* External bus controller */
-ppc405_ebc_init(env);
+object_property_set_link(OBJECT(&s->ebc), "cpu", OBJECT(&s->cpu),
+ &error_abort);
+if (!qdev_realize(DEVICE(&s->ebc), NULL, errp)) {
+return;
+}
 
 /* DMA controller */
 object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
@@ -1578,6 +1598,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 

[PATCH 11/19] ppc/ppc405: QOM'ify DMA

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h| 23 +
 hw/ppc/ppc405_uc.c | 80 +-
 2 files changed, 73 insertions(+), 30 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 46366c3b8a19..bd662b2444ff 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -65,6 +65,28 @@ struct ppc4xx_bd_info_t {
 
 typedef struct Ppc405SoCState Ppc405SoCState;
 
+
+
+/* DMA controller */
+#define TYPE_PPC405_DMA "ppc405-dma"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405DmaState, PPC405_DMA);
+struct Ppc405DmaState {
+SysBusDevice parent_obj;
+
+PowerPCCPU *cpu;
+
+qemu_irq irqs[4];
+uint32_t cr[4];
+uint32_t ct[4];
+uint32_t da[4];
+uint32_t sa[4];
+uint32_t sg[4];
+uint32_t sr;
+uint32_t sgc;
+uint32_t slp;
+uint32_t pol;
+};
+
 /* GPIO */
 #define TYPE_PPC405_GPIO "ppc405-gpio"
 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GpioState, PPC405_GPIO);
@@ -180,6 +202,7 @@ struct Ppc405SoCState {
 Ppc405GptState gpt;
 Ppc405OcmState ocm;
 Ppc405GpioState gpio;
+Ppc405DmaState dma;
 };
 
 /* PowerPC 405 core */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index a6c4e6934ffc..2978a2665a4f 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -613,35 +613,20 @@ enum {
 DMA0_POL = 0x126,
 };
 
-typedef struct ppc405_dma_t ppc405_dma_t;
-struct ppc405_dma_t {
-qemu_irq irqs[4];
-uint32_t cr[4];
-uint32_t ct[4];
-uint32_t da[4];
-uint32_t sa[4];
-uint32_t sg[4];
-uint32_t sr;
-uint32_t sgc;
-uint32_t slp;
-uint32_t pol;
-};
-
-static uint32_t dcr_read_dma (void *opaque, int dcrn)
+static uint32_t dcr_read_dma(void *opaque, int dcrn)
 {
 return 0;
 }
 
-static void dcr_write_dma (void *opaque, int dcrn, uint32_t val)
+static void dcr_write_dma(void *opaque, int dcrn, uint32_t val)
 {
 }
 
-static void ppc405_dma_reset (void *opaque)
+static void ppc405_dma_reset(DeviceState *dev)
 {
-ppc405_dma_t *dma;
+Ppc405DmaState *dma = PPC405_DMA(dev);
 int i;
 
-dma = opaque;
 for (i = 0; i < 4; i++) {
 dma->cr[i] = 0x;
 dma->ct[i] = 0x;
@@ -655,13 +640,20 @@ static void ppc405_dma_reset (void *opaque)
 dma->pol = 0x;
 }
 
-static void ppc405_dma_init(CPUPPCState *env, qemu_irq irqs[4])
+static void ppc405_dma_realize(DeviceState *dev, Error **errp)
 {
-ppc405_dma_t *dma;
+Ppc405DmaState *dma = PPC405_DMA(dev);
+CPUPPCState *env;
+int i;
+
+assert(dma->cpu);
+
+env = &dma->cpu->env;
+
+for (i = 0; i < ARRAY_SIZE(dma->irqs); i++) {
+sysbus_init_irq(SYS_BUS_DEVICE(dma), &dma->irqs[i]);
+}
 
-dma = g_new0(ppc405_dma_t, 1);
-memcpy(dma->irqs, irqs, 4 * sizeof(qemu_irq));
-qemu_register_reset(&ppc405_dma_reset, dma);
 ppc_dcr_register(env, DMA0_CR0,
  dma, &dcr_read_dma, &dcr_write_dma);
 ppc_dcr_register(env, DMA0_CT0,
@@ -712,6 +704,22 @@ static void ppc405_dma_init(CPUPPCState *env, qemu_irq 
irqs[4])
  dma, &dcr_read_dma, &dcr_write_dma);
 }
 
+static Property ppc405_dma_properties[] = {
+DEFINE_PROP_LINK("cpu", Ppc405DmaState, cpu, TYPE_POWERPC_CPU,
+ PowerPCCPU *),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc405_dma_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = ppc405_dma_realize;
+dc->user_creatable = false;
+dc->reset = ppc405_dma_reset;
+device_class_set_props(dc, ppc405_dma_properties);
+}
+
 /*/
 static uint64_t ppc405_gpio_read(void *opaque, hwaddr addr, unsigned size)
 {
@@ -1408,12 +1416,14 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "ocm", &s->ocm, TYPE_PPC405_OCM);
 
 object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
+
+object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
 Ppc405SoCState *s = PPC405_SOC(dev);
-qemu_irq dma_irqs[4], mal_irqs[4];
+qemu_irq mal_irqs[4];
 CPUPPCState *env;
 Error *err = NULL;
 int i;
@@ -1485,11 +1495,16 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 ppc405_ebc_init(env);
 
 /* DMA controller */
-dma_irqs[0] = qdev_get_gpio_in(s->uic, 5);
-dma_irqs[1] = qdev_get_gpio_in(s->uic, 6);
-dma_irqs[2] = qdev_get_gpio_in(s->uic, 7);
-dma_irqs[3] = qdev_get_gpio_in(s->uic, 8);
-ppc405_dma_init(env, dma_irqs);
+object_property_set_link(OBJECT(&s->dma), "cpu", OBJECT(&s->cpu),
+ &error_abort);
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->dma), errp)) {
+return;
+}
+
+for (i = 0; i < ARRAY_SIZE(s->dma.irqs); i++) {
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), i,
+   qdev_get_gpio_in(s->uic, 5 + i));
+ 

[PATCH 16/19] ppc/ppc405: QOM'ify MAL

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h |   1 +
 include/hw/ppc/ppc4xx.h |  28 ++
 hw/ppc/ppc405_uc.c  |  20 +--
 hw/ppc/ppc4xx_devs.c| 120 +---
 4 files changed, 118 insertions(+), 51 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 4ff5cdcf5c65..0cbfd977aecf 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -259,6 +259,7 @@ struct Ppc405SoCState {
 Ppc405OpbaState opba;
 Ppc405PobState pob;
 Ppc405PlbState plb;
+Ppc4xxMalState mal;
 };
 
 /* PowerPC 405 core */
diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
index 980f964b5a91..a383560576d7 100644
--- a/include/hw/ppc/ppc4xx.h
+++ b/include/hw/ppc/ppc4xx.h
@@ -26,6 +26,7 @@
 #define PPC4XX_H
 
 #include "hw/ppc/ppc.h"
+#include "hw/sysbus.h"
 #include "exec/memory.h"
 
 /* PowerPC 4xx core initialization */
@@ -44,6 +45,33 @@ void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int 
nbanks,
 hwaddr *ram_sizes,
 int do_init);
 
+/* Memory Access Layer (MAL) */
+#define TYPE_PPC4xx_MAL "ppc4xx-mal"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc4xxMalState, PPC4xx_MAL);
+struct Ppc4xxMalState {
+SysBusDevice parent_obj;
+
+PowerPCCPU *cpu;
+
+qemu_irq irqs[4];
+uint32_t cfg;
+uint32_t esr;
+uint32_t ier;
+uint32_t txcasr;
+uint32_t txcarr;
+uint32_t txeobisr;
+uint32_t txdeir;
+uint32_t rxcasr;
+uint32_t rxcarr;
+uint32_t rxeobisr;
+uint32_t rxdeir;
+uint32_t *txctpr;
+uint32_t *rxctpr;
+uint32_t *rcbs;
+uint8_t  txcnum;
+uint8_t  rxcnum;
+};
+
 void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
  qemu_irq irqs[4]);
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 45bcf3a6dd8a..de2c3c0c747c 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1466,12 +1466,13 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB);
 
 object_initialize_child(obj, "plb", &s->plb, TYPE_PPC405_PLB);
+
+object_initialize_child(obj, "mal", &s->mal, TYPE_PPC4xx_MAL);
 }
 
 static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 {
 Ppc405SoCState *s = PPC405_SOC(dev);
-qemu_irq mal_irqs[4];
 CPUPPCState *env;
 Error *err = NULL;
 int i;
@@ -1612,11 +1613,18 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 }
 
 /* MAL */
-mal_irqs[0] = qdev_get_gpio_in(s->uic, 11);
-mal_irqs[1] = qdev_get_gpio_in(s->uic, 12);
-mal_irqs[2] = qdev_get_gpio_in(s->uic, 13);
-mal_irqs[3] = qdev_get_gpio_in(s->uic, 14);
-ppc4xx_mal_init(env, 4, 2, mal_irqs);
+object_property_set_int(OBJECT(&s->mal), "txc-num", 4, &error_abort);
+object_property_set_int(OBJECT(&s->mal), "rxc-num", 2, &error_abort);
+object_property_set_link(OBJECT(&s->mal), "cpu", OBJECT(&s->cpu),
+ &error_abort);
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->mal), errp)) {
+return;
+}
+
+for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) {
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->mal), i,
+   qdev_get_gpio_in(s->uic, 11 + i));
+}
 
 /* Ethernet */
 /* Uses UIC IRQs 9, 15, 17 */
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 737c0896b4f8..c935a7acf6a0 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -491,32 +491,10 @@ enum {
 MAL0_RCBS1= 0x1E1,
 };
 
-typedef struct ppc4xx_mal_t ppc4xx_mal_t;
-struct ppc4xx_mal_t {
-qemu_irq irqs[4];
-uint32_t cfg;
-uint32_t esr;
-uint32_t ier;
-uint32_t txcasr;
-uint32_t txcarr;
-uint32_t txeobisr;
-uint32_t txdeir;
-uint32_t rxcasr;
-uint32_t rxcarr;
-uint32_t rxeobisr;
-uint32_t rxdeir;
-uint32_t *txctpr;
-uint32_t *rxctpr;
-uint32_t *rcbs;
-uint8_t  txcnum;
-uint8_t  rxcnum;
-};
-
-static void ppc4xx_mal_reset(void *opaque)
+static void ppc4xx_mal_reset(DeviceState *dev)
 {
-ppc4xx_mal_t *mal;
+Ppc4xxMalState *mal = PPC4xx_MAL(dev);
 
-mal = opaque;
 mal->cfg = 0x0007C000;
 mal->esr = 0x;
 mal->ier = 0x;
@@ -530,10 +508,9 @@ static void ppc4xx_mal_reset(void *opaque)
 
 static uint32_t dcr_read_mal(void *opaque, int dcrn)
 {
-ppc4xx_mal_t *mal;
+Ppc4xxMalState *mal = PPC4xx_MAL(opaque);
 uint32_t ret;
 
-mal = opaque;
 switch (dcrn) {
 case MAL0_CFG:
 ret = mal->cfg;
@@ -587,13 +564,12 @@ static uint32_t dcr_read_mal(void *opaque, int dcrn)
 
 static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
 {
-ppc4xx_mal_t *mal;
+Ppc4xxMalState *mal = PPC4xx_MAL(opaque);
 
-mal = opaque;
 switch (dcrn) {
 case MAL0_CFG:
 if (val & 0x8000) {
-ppc4xx_mal_reset(mal);
+ppc4xx_mal_reset(DEVICE(mal));
 }
 mal->cfg = val & 0x00FFC0

[PATCH 18/19] ppc/ppc405: QOM'ify UIC

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h|  3 ++-
 hw/ppc/ppc405_uc.c | 27 ++-
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 0cbfd977aecf..c2cfccb9d106 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -27,6 +27,7 @@
 
 #include "qom/object.h"
 #include "hw/ppc/ppc4xx.h"
+#include "hw/intc/ppc-uic.h"
 
 #define PPC405EP_SDRAM_BASE 0x
 #define PPC405EP_NVRAM_BASE 0xF000
@@ -249,7 +250,7 @@ struct Ppc405SoCState {
 hwaddr ram_size;
 
 PowerPCCPU cpu;
-DeviceState *uic;
+PPCUIC uic;
 Ppc405CpcState cpc;
 Ppc405GptState gpt;
 Ppc405OcmState ocm;
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index de2c3c0c747c..0336d1e08689 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1448,6 +1448,8 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "cpu", &s->cpu,
 POWERPC_CPU_TYPE_NAME("405ep"));
 
+object_initialize_child(obj, "uic", &s->uic, TYPE_PPC_UIC);
+
 object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC);
 object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
 
@@ -1533,22 +1535,21 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(&s->opba), 0, 0xef600600);
 
 /* Universal interrupt controller */
-s->uic = qdev_new(TYPE_PPC_UIC);
-
-object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(&s->cpu),
+object_property_set_link(OBJECT(&s->uic), "cpu", OBJECT(&s->cpu),
  &error_fatal);
-if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->uic), errp)) {
 return;
 }
 
-sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->uic), PPCUIC_OUTPUT_INT,
qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_INT));
-sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->uic), PPCUIC_OUTPUT_CINT,
qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
 /* XXX 405EP has no ECC interrupt */
-ppc4xx_sdram_init(env, qdev_get_gpio_in(s->uic, 17), 2, s->ram_memories,
+ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 2,
+  s->ram_memories,
   s->ram_bases, s->ram_sizes, s->do_dram_init);
 
 /* External bus controller */
@@ -1567,12 +1568,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 
 for (i = 0; i < ARRAY_SIZE(s->dma.irqs); i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), i,
-   qdev_get_gpio_in(s->uic, 5 + i));
+   qdev_get_gpio_in(DEVICE(&s->uic), 5 + i));
 }
 
 /* I2C controller */
 sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
- qdev_get_gpio_in(s->uic, 2));
+ qdev_get_gpio_in(DEVICE(&s->uic), 2));
 
 /* GPIO */
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
@@ -1583,13 +1584,13 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 /* Serial ports */
 if (serial_hd(0) != NULL) {
 serial_mm_init(get_system_memory(), 0xef600300, 0,
-   qdev_get_gpio_in(s->uic, 0),
+   qdev_get_gpio_in(DEVICE(&s->uic), 0),
PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
DEVICE_BIG_ENDIAN);
 }
 if (serial_hd(1) != NULL) {
 serial_mm_init(get_system_memory(), 0xef600400, 0,
-   qdev_get_gpio_in(s->uic, 1),
+   qdev_get_gpio_in(DEVICE(&s->uic), 1),
PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
DEVICE_BIG_ENDIAN);
 }
@@ -1609,7 +1610,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 
 for (i = 0; i < ARRAY_SIZE(s->gpt.irqs); i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), i,
-   qdev_get_gpio_in(s->uic, 19 + i));
+   qdev_get_gpio_in(&s->uic, 19 + i));
 }
 
 /* MAL */
@@ -1623,7 +1624,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 
 for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(&s->mal), i,
-   qdev_get_gpio_in(s->uic, 11 + i));
+   qdev_get_gpio_in(&s->uic, 11 + i));
 }
 
 /* Ethernet */
-- 
2.37.1




[PATCH 17/19] ppc/ppc405: QOM'ify FPGA

2022-08-01 Thread Cédric Le Goater
Signed-off-by: Cédric Le Goater 
---
 hw/ppc/ppc405_boards.c | 55 +-
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 82b51cc457fa..2900c267b7ac 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -71,18 +71,23 @@ OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, 
PPC405_MACHINE);
  * - NVRAM (0xF000)
  * - FPGA  (0xF030)
  */
-typedef struct ref405ep_fpga_t ref405ep_fpga_t;
-struct ref405ep_fpga_t {
+
+#define TYPE_PPC405_FPGA "ppc405-fpga"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405FpgaState, PPC405_FPGA);
+struct Ppc405FpgaState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+
 uint8_t reg0;
 uint8_t reg1;
 };
 
 static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr addr, unsigned size)
 {
-ref405ep_fpga_t *fpga;
+Ppc405FpgaState *fpga = PPC405_FPGA(opaque);
 uint32_t ret;
 
-fpga = opaque;
 switch (addr) {
 case 0x0:
 ret = fpga->reg0;
@@ -101,9 +106,8 @@ static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr 
addr, unsigned size)
 static void ref405ep_fpga_writeb(void *opaque, hwaddr addr, uint64_t value,
  unsigned size)
 {
-ref405ep_fpga_t *fpga;
+Ppc405FpgaState *fpga = PPC405_FPGA(opaque);
 
-fpga = opaque;
 switch (addr) {
 case 0x0:
 /* Read only */
@@ -126,27 +130,39 @@ static const MemoryRegionOps ref405ep_fpga_ops = {
 .endianness = DEVICE_BIG_ENDIAN,
 };
 
-static void ref405ep_fpga_reset (void *opaque)
+static void ref405ep_fpga_reset(DeviceState *dev)
 {
-ref405ep_fpga_t *fpga;
+Ppc405FpgaState *fpga = PPC405_FPGA(dev);
 
-fpga = opaque;
 fpga->reg0 = 0x00;
 fpga->reg1 = 0x0F;
 }
 
-static void ref405ep_fpga_init(MemoryRegion *sysmem, uint32_t base)
+static void ref405ep_fpga_realize(DeviceState *dev, Error **errp)
 {
-ref405ep_fpga_t *fpga;
-MemoryRegion *fpga_memory = g_new(MemoryRegion, 1);
+Ppc405FpgaState *s = PPC405_FPGA(dev);
 
-fpga = g_new0(ref405ep_fpga_t, 1);
-memory_region_init_io(fpga_memory, NULL, &ref405ep_fpga_ops, fpga,
+memory_region_init_io(&s->iomem, OBJECT(s), &ref405ep_fpga_ops, s,
   "fpga", 0x0100);
-memory_region_add_subregion(sysmem, base, fpga_memory);
-qemu_register_reset(&ref405ep_fpga_reset, fpga);
+sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+}
+
+static void ref405ep_fpga_class_init(ObjectClass *oc, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(oc);
+
+dc->realize = ref405ep_fpga_realize;
+dc->user_creatable = false;
+dc->reset = ref405ep_fpga_reset;
 }
 
+static const TypeInfo ref405ep_fpga_type = {
+.name = TYPE_PPC405_FPGA,
+.parent = TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(Ppc405FpgaState),
+.class_init = ref405ep_fpga_class_init,
+};
+
 /*
  * CPU reset handler when booting directly from a loaded kernel
  */
@@ -325,7 +341,11 @@ static void ref405ep_init(MachineState *machine)
 ppc405_init(machine);
 
 /* Register FPGA */
-ref405ep_fpga_init(get_system_memory(), PPC405EP_FPGA_BASE);
+dev = qdev_new(TYPE_PPC405_FPGA);
+object_property_add_child(OBJECT(machine), "fpga", OBJECT(dev));
+sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, PPC405EP_FPGA_BASE);
+
 /* Register NVRAM */
 dev = qdev_new("sysbus-m48t08");
 qdev_prop_set_int32(dev, "base-year", 1968);
@@ -370,6 +390,7 @@ static void ppc405_machine_init(void)
 {
 type_register_static(&ppc405_machine_type);
 type_register_static(&ref405ep_type);
+type_register_static(&ref405ep_fpga_type);
 }
 
 type_init(ppc405_machine_init)
-- 
2.37.1




Re: [PULL V2 19/25] vdpa: Extract get features part from vhost_vdpa_get_max_queue_pairs

2022-08-01 Thread Eugenio Perez Martin
On Mon, Aug 1, 2022 at 5:29 AM Jason Wang  wrote:
>
>
> 在 2022/7/29 22:08, Peter Maydell 写道:
> > On Wed, 20 Jul 2022 at 10:04, Jason Wang  wrote:
> >> From: Eugenio Pérez 
> >>
> >> To know the device features is needed for CVQ SVQ, so SVQ knows if it
> >> can handle all commands or not. Extract from
> >> vhost_vdpa_get_max_queue_pairs so we can reuse it.
> >>
> >> Signed-off-by: Eugenio Pérez 
> >> Acked-by: Jason Wang 
> >> Reviewed-by: Michael S. Tsirkin 
> >> Signed-off-by: Jason Wang 
> > Hi; this change introduces a resource leak in the new
> > error-exit return path in net_init_vhost_vdpa(). Spotted
> > by Coverity, CID 1490785.
> >
> >> @@ -517,10 +521,11 @@ int net_init_vhost_vdpa(const Netdev *netdev, const 
> >> char *name,
> >>   NetClientState *peer, Error **errp)
> >>   {
> >>   const NetdevVhostVDPAOptions *opts;
> >> +uint64_t features;
> >>   int vdpa_device_fd;
> >>   g_autofree NetClientState **ncs = NULL;
> >>   NetClientState *nc;
> >> -int queue_pairs, i, has_cvq = 0;
> >> +int queue_pairs, r, i, has_cvq = 0;
> >>
> >>   assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
> >>   opts = &netdev->u.vhost_vdpa;
> >> @@ -534,7 +539,12 @@ int net_init_vhost_vdpa(const Netdev *netdev, const 
> >> char *name,
> >>   return -errno;
> >>   }
> >>
> >> -queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd,
> >> +r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp);
> >> +if (unlikely(r < 0)) {
> >> +return r;
> > At this point in the code we have allocated the file descriptor
> > vdpa_device_fd, but this return path fails to close it.
>
>
> Exactly.
>

Right, I'll fix.

>
> >
> >> +}
> >> +
> >> +queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd, features,
> >>&has_cvq, errp);
> >>   if (queue_pairs < 0) {
> >>   qemu_close(vdpa_device_fd);
> > Compare this pre-existing error-exit path, which correctly
> > calls qemu_close() on the fd.
> >
> > Related question: is this function supposed to return -1 on
> > failure, or negative-errno ?
>
>
> Kind of either:
>
>if (net_client_init_fun[netdev->type](netdev, netdev->id, peer, errp)
> < 0) {
>  /* FIXME drop when all init functions store an Error */
>  if (errp && !*errp) {
>  error_setg(errp, "Device '%s' could not be initialized",
> NetClientDriver_str(netdev->type));
>  }
>  return -1;
>  }
>
>

We can write errno to errp then, and consistently use the goto for
error handling as you propose. I'll post a fix in a moment.

Thanks!

> >   At the moment it has a mix
> > of both. I think that the sole caller only really wants "<0 on
> > error", in which case the error-exit code paths could probably
> > be tidied up so that instead of explicitly calling
> > qemu_close() and returning r, queue_pairs, or whatever
> > they got back from the function they just called, they
> > could just 'goto err_svq' which will do the "close the fd
> > and return -1" work. Better still, by initializing 'i'
> > to 0 at the top of the function (and naming it something
> > clearer, ideally), all the code paths after the initial
> > qemu_open() succeeds could be made to use 'goto err'
> > for the error-exit case.
>
>
> Yes, having a consistent goto based error handling seems much better.
>
> Eugenio, please post patch to fix this.
>
> Thanks
>
>
> >
> > thanks
> > -- PMM
> >
>




Re: [PATCH 18/19] ppc/ppc405: QOM'ify UIC

2022-08-01 Thread Cédric Le Goater

Daniel,

On 8/1/22 15:10, Cédric Le Goater wrote:

Signed-off-by: Cédric Le Goater 
---
  hw/ppc/ppc405.h|  3 ++-
  hw/ppc/ppc405_uc.c | 27 ++-
  2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 0cbfd977aecf..c2cfccb9d106 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -27,6 +27,7 @@
  
  #include "qom/object.h"

  #include "hw/ppc/ppc4xx.h"
+#include "hw/intc/ppc-uic.h"
  
  #define PPC405EP_SDRAM_BASE 0x

  #define PPC405EP_NVRAM_BASE 0xF000
@@ -249,7 +250,7 @@ struct Ppc405SoCState {
  hwaddr ram_size;
  
  PowerPCCPU cpu;

-DeviceState *uic;
+PPCUIC uic;
  Ppc405CpcState cpc;
  Ppc405GptState gpt;
  Ppc405OcmState ocm;
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index de2c3c0c747c..0336d1e08689 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1448,6 +1448,8 @@ static void ppc405_soc_instance_init(Object *obj)
  object_initialize_child(obj, "cpu", &s->cpu,
  POWERPC_CPU_TYPE_NAME("405ep"));
  
+object_initialize_child(obj, "uic", &s->uic, TYPE_PPC_UIC);

+
  object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC);
  object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
  
@@ -1533,22 +1535,21 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)

  sysbus_mmio_map(SYS_BUS_DEVICE(&s->opba), 0, 0xef600600);
  
  /* Universal interrupt controller */

-s->uic = qdev_new(TYPE_PPC_UIC);
-
-object_property_set_link(OBJECT(s->uic), "cpu", OBJECT(&s->cpu),
+object_property_set_link(OBJECT(&s->uic), "cpu", OBJECT(&s->cpu),
   &error_fatal);
-if (!sysbus_realize(SYS_BUS_DEVICE(s->uic), errp)) {
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->uic), errp)) {
  return;
  }
  
-sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_INT,

+sysbus_connect_irq(SYS_BUS_DEVICE(&s->uic), PPCUIC_OUTPUT_INT,
 qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_INT));
-sysbus_connect_irq(SYS_BUS_DEVICE(s->uic), PPCUIC_OUTPUT_CINT,
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->uic), PPCUIC_OUTPUT_CINT,
 qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

  /* XXX 405EP has no ECC interrupt */
-ppc4xx_sdram_init(env, qdev_get_gpio_in(s->uic, 17), 2, s->ram_memories,
+ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 2,
+  s->ram_memories,
s->ram_bases, s->ram_sizes, s->do_dram_init);
  
  /* External bus controller */

@@ -1567,12 +1568,12 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  
  for (i = 0; i < ARRAY_SIZE(s->dma.irqs); i++) {

  sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), i,
-   qdev_get_gpio_in(s->uic, 5 + i));
+   qdev_get_gpio_in(DEVICE(&s->uic), 5 + i));
  }
  
  /* I2C controller */

  sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500,
- qdev_get_gpio_in(s->uic, 2));
+ qdev_get_gpio_in(DEVICE(&s->uic), 2));
  
  /* GPIO */

  if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
@@ -1583,13 +1584,13 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  /* Serial ports */
  if (serial_hd(0) != NULL) {
  serial_mm_init(get_system_memory(), 0xef600300, 0,
-   qdev_get_gpio_in(s->uic, 0),
+   qdev_get_gpio_in(DEVICE(&s->uic), 0),
 PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
 DEVICE_BIG_ENDIAN);
  }
  if (serial_hd(1) != NULL) {
  serial_mm_init(get_system_memory(), 0xef600400, 0,
-   qdev_get_gpio_in(s->uic, 1),
+   qdev_get_gpio_in(DEVICE(&s->uic), 1),
 PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
 DEVICE_BIG_ENDIAN);
  }
@@ -1609,7 +1610,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  
  for (i = 0; i < ARRAY_SIZE(s->gpt.irqs); i++) {

  sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), i,
-   qdev_get_gpio_in(s->uic, 19 + i));
+   qdev_get_gpio_in(&s->uic, 19 + i));
  }
  
  /* MAL */

@@ -1623,7 +1624,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  
  for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) {

  sysbus_connect_irq(SYS_BUS_DEVICE(&s->mal), i,
-   qdev_get_gpio_in(s->uic, 11 + i));
+   qdev_get_gpio_in(&s->uic, 11 + i));
  }
  
  /* Ethernet */


There is a compile bug in this patch. If you consider applying the patchset,
please fold in the following changes. Sorry about that.

Thanks,

C.


@@ -1616,7 +1616,7 @@ static void ppc405_soc_

race condition in display device caused by run_on_cpu() dropping the iothread lock

2022-08-01 Thread Peter Maydell
I've been debugging a segfault in the raspi3b display device, and I've
tracked it down to a race condition, but I'm not sure what the right
way to fix it is...

The race is that a vCPU thread is handling a guest register write that
says "resize the framebuffer", which it implements by calling
qemu_console_resize(). This ends up doing a qemu_free_displaysurface()
on the old surface and creating a new one.  However, at the same time,
the iothread is in gui_update(), which ends up calling the display
device gfx_update method. This code is thus actively using the old
DisplaySurface, and the crash happens because the memory is freed
while this function is still using it.

I think this happens like this:
 * the iothread runs the gui_update timer callback; it holds the
   iothread lock to do this
 * gui_update eventually calls into the bcm2835_fb.c fb_update_display()
   function
 * That function calls qemu_console_surface(s->con) to
   get the current DisplaySurface, and passes it to
   framebuffer_update_display() to do the work
 * framebuffer_update_display calls memory_region_snapshot_and_clear_dirty()
 * memory_region_snapshot_and_clear_dirty() ends up calling run_on_cpu(),
   which briefly drops the iothread lock.
 * This gives the vCPU thread a chance to dash in, grab the iothread
   lock, run the guest code to resize the fb and destroy the old
   DisplaySurface (and then dropping the iothread lock again)
 * eventually run_on_cpu() does its thing and retakes the iothread lock
 * however, when we get back up into framebuffer_update_display(), this
   function now has a stale DisplaySurface, and when it tries to copy
   the framebuffer pixels into that surface it is writing into freed
   memory, causing a segfault or worse

How is this intended to work? I feel like if run_on_cpu() silently
drops the iothread lock this probably invalidates a lot of assumptions
that QEMU code makes, especially in this kind of setup where
the code making the assumptions is several layers in the callstack
above whatever it is that ends up calling run_on_cpu()...


Here's the full backtraces of the relevant threads. First
the thread that frees the memory:

Thread 3 (Thread 2949085.2949109):
#0  __GI___libc_free (mem=0x73bc5c974010) at malloc.c:3087
#1  0x6ac565853b1d in  () at /usr/lib/x86_64-linux-gnu/libpixman-1.so.0
#2  0x6ac565853a5d in pixman_image_unref () at
/usr/lib/x86_64-linux-gnu/libpixman-1.so.0
#3  0x556260c82aee in qemu_pixman_image_unref
(image=0x556263261830) at ../../ui/qemu-pixman.c:225
#4  0x556260c793fa in qemu_free_displaysurface
(surface=0x5562638c45a0) at ../../ui/console.c:1582
#5  0x556260c79dc0 in dpy_gfx_replace_surface (con=0x5562632eda70,
surface=0x669760020270) at ../../ui/console.c:1808
#6  0x556260c7b967 in qemu_console_resize (s=0x5562632eda70,
width=1024, height=768) at ../../ui/console.c:2588
#7  0x556260d70ac4 in bcm2835_fb_reconfigure (s=0x39284b533bb0,
newconfig=0x5c54602c5600) at ../../hw/display/bcm2835_fb.c:
262
#8  0x556260e11cd8 in bcm2835_property_mbox_push
(s=0x39284b534f10, value=550952) at
../../hw/misc/bcm2835_property.c:301
#9  0x556260e11e52 in bcm2835_property_write
(opaque=0x39284b534f10, offset=0, value=550824, size=4) at
../../hw/misc/bcm28
35_property.c:344
#10 0x556261431bfa in memory_region_write_accessor
(mr=0x39284b5352a0, addr=0, value=0x5c54602c5788, size=4, shift=0,
mask=
4294967295, attrs=...) at ../--Type  for more, q to quit, c to
continue without paging--
../softmmu/memory.c:492
#11 0x556261431e48 in access_with_adjusted_size (addr=0,
value=0x5c54602c5788, size=4, access_size_min=1, access_size_max=4
, access_fn=0x556261431b00 ,
mr=0x39284b5352a0, attrs=...) at ../../softmmu/memory.c:554
#12 0x556261434fd7 in memory_region_dispatch_write
(mr=0x39284b5352a0, addr=0, data=550824, op=MO_32, attrs=...) at
../../s
oftmmu/memory.c:1514
#13 0x5562614450e4 in address_space_stl_internal
(as=0x39284b535b60, addr=128, val=550824, attrs=..., result=0x0,
endian=DEVICE_LITTLE_ENDIAN) at
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/memory_ldst.c.inc:319
#14 0x556261445223 in address_space_stl_le (as=0x39284b535b60,
addr=128, val=550824, attrs=..., result=0x0) at
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/memory_ldst.c.inc:357
#15 0x556260e0f86f in stl_le_phys (as=0x39284b535b60, addr=128,
val=550824) at 
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/include/exec/memory_ldst_phys.h.inc:121
#16 0x556260e102f0 in bcm2835_mbox_write (opaque=0x39284b535830,
offset=160, value=550824, size=4) at ../../hw/misc/bcm2835_mbox.c:227
#17 0x556261431bfa in memory_region_write_accessor
(mr=0x39284b535bc0, addr=160, value=0x5c54602c59d8, size=4, shift=0,
mask=4294967295, attrs=...) at ../../softmmu/memory.c:492
#18 0x556261431e48 in access_with_adjusted_size (addr=160,
value=0x5c54602c59d8, size=4, access_size_min=1, access_size_max=4,
access_fn=0x556261431b00 ,
mr=0x39284b535bc0, attrs=...) at ../../softmmu/memory.c:554
#19 0x00

Re: [PATCH v2 1/1] monitor: Support specified vCPU registers

2022-08-01 Thread Markus Armbruster
zhenwei pi  writes:

> Originally we have to get all the vCPU registers and parse the
> specified one. To improve the performance of this usage, allow user
> specified vCPU id to query registers.
>
> Run a VM with 16 vCPU, use bcc tool to track the latency of
> 'hmp_info_registers':
> 'info registers -a' uses about 3ms;
> 'info registers 12' uses about 150us.
>
> Cc: Darren Kenny 
> Signed-off-by: zhenwei pi 
> ---
>  hmp-commands-info.hx |  7 ---
>  monitor/misc.c   | 18 ++
>  2 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
> index 3ffa24bd67..7a00b4ded3 100644
> --- a/hmp-commands-info.hx
> +++ b/hmp-commands-info.hx
> @@ -100,9 +100,10 @@ ERST
>  
>  {
>  .name   = "registers",
> -.args_type  = "cpustate_all:-a",
> -.params = "[-a]",
> -.help   = "show the cpu registers (-a: all - show register info 
> for all cpus)",
> +.args_type  = "cpustate_all:-a,vcpu:i?",
> +.params = "[-a|vcpu]",
> +.help   = "show the cpu registers (-a: all - show register info 
> for all cpus;"
> +  " vcpu: specific vCPU to query)",

Recommend to document explicitly that it shows the current CPU's
registers when no argument is specified.

>  .cmd= hmp_info_registers,
>  },
>  
> diff --git a/monitor/misc.c b/monitor/misc.c
> index 3d2312ba8d..8e1d4840f2 100644
> --- a/monitor/misc.c
> +++ b/monitor/misc.c
> @@ -307,6 +307,7 @@ int monitor_get_cpu_index(Monitor *mon)
>  static void hmp_info_registers(Monitor *mon, const QDict *qdict)
>  {
>  bool all_cpus = qdict_get_try_bool(qdict, "cpustate_all", false);
> +int vcpu = qdict_get_try_int(qdict, "vcpu", -1);
>  CPUState *cs;
>  
>  if (all_cpus) {
> @@ -314,6 +315,23 @@ static void hmp_info_registers(Monitor *mon, const QDict 
> *qdict)
>  monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
>  cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
>  }
> +} else if (vcpu >= 0) {
> +CPUState *target_cs = NULL;
> +
> +CPU_FOREACH(cs) {
> +if (cs->cpu_index == vcpu) {
> +target_cs = cs;
> +break;
> +}
> +}

Please use qemu_get_cpu().

> +
> +if (!target_cs) {
> +monitor_printf(mon, "CPU#%d not available\n", vcpu);
> +return;
> +}
> +
> +monitor_printf(mon, "\nCPU#%d\n", target_cs->cpu_index);
> +cpu_dump_state(target_cs, NULL, CPU_DUMP_FPU);

We show the CPU number when the user asked for this number, but ...

>  } else {
>  cs = mon_get_cpu(mon);

   if (!cs) {
   monitor_printf(mon, "No CPU available\n");
   return;
   }

   cpu_dump_state(cs, NULL, CPU_DUMP_FPU);

... we don't show it when the user asked for the current CPU.  It's
arguably more relevant then.

   }
   }

Suggest something like

   } else {
   cs = vcpu >= 0 ? qemu_get_cpu(vcpu) : mon_get_cpu(mon);

   if (!cs) {
   monitor_printf(mon, "CPU#%d not available\n", vcpu);
   return;
   }

   monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
   cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
   }




Re: [PULL 0/3] Hexagon bug fixes and test improvements

2022-08-01 Thread Richard Henderson

On 7/31/22 16:32, Taylor Simpson wrote:

The following changes since commit 3916603e0c1d909e14e09d5ebcbdaa9c9e21adf3:

   Merge tag 'pull-la-20220729' of https://gitlab.com/rth7680/qemu into staging 
(2022-07-29 17:39:17 -0700)

are available in the Git repository at:

   https://github.com/quic/qemu tags/pull-hex-20220731

for you to fetch changes up to 7eabb050ea77e529f549ea1ddaaa18e91ae01e34:

   Hexagon (tests/tcg/hexagon) reference file for float_convd (2022-07-31 
16:22:09 -0700)


Hexagon bug fixes and test improvements

1) Fixes a bug in qemu-hexagon
2) Fixes a bug in a test case
3) Adds reference file for float_convd test case


Applied, thanks.  Please update https://wiki.qemu.org/ChangeLog/7.1 as 
appropriate.


r~





Taylor Simpson (3):
   Hexagon (target/hexagon) make VyV operands use a unique temp
   Hexagon (tests/tcg/hexagon) Fix alignment in load_unpack.c
   Hexagon (tests/tcg/hexagon) reference file for float_convd

  tests/tcg/hexagon/hvx_misc.c  |  45 ++
  tests/tcg/hexagon/load_unpack.c   |  14 +-
  target/hexagon/gen_tcg_funcs.py   |   9 +-
  tests/tcg/hexagon/float_convd.ref | 988 ++
  4 files changed, 1044 insertions(+), 12 deletions(-)
  create mode 100644 tests/tcg/hexagon/float_convd.ref





Re: [RFC v5 05/11] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls

2022-08-01 Thread Eric Blake
On Mon, Aug 01, 2022 at 09:33:05AM +0800, Sam Li wrote:
> By adding zone management operations in BlockDriver, storage controller
> emulation can use the new block layer APIs including Report Zone and
> four zone management operations (open, close, finish, reset).
> 
> BlockDriver can get zone information from null_blk device by refreshing
> BLockLimits.
> 
> Signed-off-by: Sam Li 
> ---
>  block/block-backend.c|  47 ++
>  block/coroutines.h   |   6 +
>  block/file-posix.c   | 272 ++-
>  block/io.c   |  57 +++
>  include/block/block-common.h |   1 -
>  include/block/block-io.h |  13 ++
>  include/block/block_int-common.h |  22 ++-
>  include/block/raw-aio.h  |   6 +-
>  meson.build  |   1 +
>  qapi/block-core.json |   7 +-
>  10 files changed, 426 insertions(+), 6 deletions(-)
> 

> +++ b/qapi/block-core.json
> @@ -2955,7 +2955,8 @@
>  'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
>  'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
>  { 'name': 'replication', 'if': 'CONFIG_REPLICATION' },
> -'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
> +'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat',
> +{ 'name': 'zoned_host_device', 'if': 'CONFIG_BLKZONED' } ] }

Missing a documentation line of '# @zoned_host_deivce: Since 7.2'.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org




[PULL] IPMI bug fixes

2022-08-01 Thread Corey Minyard
Not a huge deal, but probably makes mainainers lives a little easier.

Add a change to make Coverity happy.


Corey Minyard (1):
  ipmi:smbus: Add a check around a memcpy

 hw/ipmi/smbus_ipmi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
cminyard@t560:/personal/git/qemu/Z$ git request-pull master origin 
tags/for-qemu-2022-08-01
The following changes since commit cc42559ab129a15554cc485ea9265e34dde7ab5b:

  Merge tag 'pull-ppc-20220728' of https://gitlab.com/danielhb/qemu into 
staging (2022-07-28 15:06:42 -0700)

are available in the Git repository at:

  g...@github.com:cminyard/qemu.git tags/for-qemu-2022-08-01

for you to fetch changes up to 3fde641e7286f9b968bdb3b4b922c6465f2a9abc:

  ipmi:smbus: Add a check around a memcpy (2022-08-01 06:40:50 -0500)


Add a change to make Coverity happy.


Corey Minyard (1):
  ipmi:smbus: Add a check around a memcpy

 hw/ipmi/smbus_ipmi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)




[RFC PATCH] util: add a qemu_backtrace utility function

2022-08-01 Thread Alex Bennée
When debugging failures in CI which can't be replicated locally it can
be useful to dump a backtrace. However ad-hoc debug code is likely to
fail to compile on numerous hosts so lets package up a utility
function with proper compiler detection.

Signed-off-by: Alex Bennée 
---
 configure| 29 +
 include/qemu/backtrace.h | 28 
 util/backtrace.c | 37 +
 util/meson.build |  1 +
 4 files changed, 95 insertions(+)
 create mode 100644 include/qemu/backtrace.h
 create mode 100644 util/backtrace.c

diff --git a/configure b/configure
index 2c19329d58..e3482fc3f6 100755
--- a/configure
+++ b/configure
@@ -1828,6 +1828,27 @@ EOF
   fi
 fi
 
+##
+# check for backtrace support
+
+have_backtrace=no
+
+cat > $TMPC << EOF
+#include 
+#include 
+int main(void) {
+int nptrs;
+void *buffer[100];
+
+nptrs = backtrace(buffer, 100);
+printf("backtrace() returned %d addresses\n", nptrs);
+}
+EOF
+
+if compile_prog "$CPU_CFLAGS -rdynamic" ""; then
+have_backtrace=yes
+fi
+
 ##
 # check for slirp
 
@@ -2276,6 +2297,10 @@ if test "$have_ubsan" = "yes"; then
   QEMU_CFLAGS="-fsanitize=undefined $QEMU_CFLAGS"
   QEMU_LDFLAGS="-fsanitize=undefined $QEMU_LDFLAGS"
 fi
+if test "$have_backtrace" = "yes" ; then
+  QEMU_CFLAGS="-rdynamic $QEMU_CFLAGS"
+  QEMU_LDFLAGS="-rdynamic $QEMU_LDFLAGS"
+fi
 
 ##
 
@@ -2480,6 +2505,10 @@ if test "$have_tsan" = "yes" && test 
"$have_tsan_iface_fiber" = "yes" ; then
 echo "CONFIG_TSAN=y" >> $config_host_mak
 fi
 
+if test "$have_backtrace" = "yes" ; then
+echo "CONFIG_BACKTRACE=y" >> $config_host_mak
+fi
+
 if test "$plugins" = "yes" ; then
 echo "CONFIG_PLUGIN=y" >> $config_host_mak
 fi
diff --git a/include/qemu/backtrace.h b/include/qemu/backtrace.h
new file mode 100644
index 00..5888081b83
--- /dev/null
+++ b/include/qemu/backtrace.h
@@ -0,0 +1,28 @@
+/*
+ * Backtrace Functions
+ *
+ * Copyright (c) 2022 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef _BACKTRACE_H_
+#define _BACKTRACE_H_
+
+#ifdef CONFIG_BACKTRACE
+/**
+ * qemu_backtrace() - return a backtrace of current thread
+ * max: maximum number of lines of backtrace
+ *
+ * Return an allocated GString containing the backtrace of the current
+ * thread. Caller frees the GString once done.
+ */
+GString *qemu_backtrace(int max);
+#else
+static inline GString *qemu_backtrace(int max)
+{
+return NULL;
+}
+#endif
+
+#endif /* _BACKTRACE_H_ */
diff --git a/util/backtrace.c b/util/backtrace.c
new file mode 100644
index 00..880232a0b0
--- /dev/null
+++ b/util/backtrace.c
@@ -0,0 +1,37 @@
+/*
+ * Backtrace abstraction to gloss over the differences between architectures.
+ *
+ * Copyright (c) 2022 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/backtrace.h"
+#include 
+#include 
+#include 
+#include 
+
+#define BT_BUF_SIZE 128
+
+GString *qemu_backtrace(int max)
+{
+int nptrs;
+void *buffer[BT_BUF_SIZE];
+char **strings;
+GString *res = g_string_new("");
+
+nptrs = backtrace(buffer, BT_BUF_SIZE);
+strings = backtrace_symbols(buffer, nptrs);
+if (strings == NULL) {
+g_string_printf(res, "Failed to extract symbols");
+} else {
+for (int j = 0; j < MIN(max, nptrs); j++) {
+g_string_append_printf(res, "%s\n", strings[j]);
+}
+free(strings);
+}
+
+return res;
+}
diff --git a/util/meson.build b/util/meson.build
index 5e282130df..abad5a5377 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -55,6 +55,7 @@ util_ss.add(files('guest-random.c'))
 util_ss.add(files('yank.c'))
 util_ss.add(files('int128.c'))
 util_ss.add(files('memalign.c'))
+util_ss.add(when: 'CONFIG_BACKTRACE', if_true: files('backtrace.c'))
 
 if have_user
   util_ss.add(files('selfmap.c'))
-- 
2.30.2




Re: [PATCH v3 1/2] qapi: Add exit-failure PanicAction

2022-08-01 Thread Markus Armbruster
Ilya Leoshkevich  writes:

> Currently QEMU exits with code 0 on both panic an shutdown. For tests
> it is useful to return 1 on panic, so that it counts as a test
> failure.
>
> Introduce a new exit-failure PanicAction that makes main() return
> EXIT_FAILURE. Tests can use -action panic=exit-failure option to
> activate this behavior.
>
> Signed-off-by: Ilya Leoshkevich 
> Reviewed-by: Richard Henderson 
> Reviewed-by: David Hildenbrand 

[...]

> diff --git a/qapi/run-state.json b/qapi/run-state.json
> index 6e2162d7b3..9273ea6516 100644
> --- a/qapi/run-state.json
> +++ b/qapi/run-state.json
> @@ -364,10 +364,13 @@
   ##
   # @PanicAction:

This is the type of set-action argument @panic, which is documented as
"action taken on guest panic."

   #
   # @none: Continue VM execution

I guess this is effectively "do nothing / ignore".

   #
   # @pause: Pause the VM

Clear enough.

>  #
>  # @shutdown: Shutdown the VM and exit, according to the shutdown action

I guess this is the value of set-action argument @shutdown, which is
can be

* @poweroff, documented as "Shutdown the VM and exit"

  Do we exit successfully, i.e. with zero status?

* @pause, documented as "pause the VM"

  PanicAction's documentation claims "shutdown the VM and exit", but we
  don't, we pause instead.  Not this patch's problem.

>  #
> +# @exit-failure: Shutdown the VM and exit with nonzero status

non-zero

> +#(since 7.1)
> +#
>  # Since: 6.0
>  ##
>  { 'enum': 'PanicAction',
> -  'data': [ 'pause', 'shutdown', 'none' ] }
> +  'data': [ 'pause', 'shutdown', 'exit-failure', 'none' ] }
>  
>  ##
>  # @watchdog-set-action:

Not this patch's problem, but here goes anyway:

   ##
   # @set-action:
   #
   # Set the actions that will be taken by the emulator in response to guest
   # events.
   #
   # @reboot: @RebootAction action taken on guest reboot.
   #
   # @shutdown: @ShutdownAction action taken on guest shutdown.
   #
   # @panic: @PanicAction action taken on guest panic.
   #
   # @watchdog: @WatchdogAction action taken when watchdog timer expires .
   #
   # Returns: Nothing on success.
   #
   # Since: 6.0
   #
   # Example:
   #
   # -> { "execute": "set-action",
   #  "arguments": { "reboot": "shutdown",
   # "shutdown" : "pause",
   # "panic": "pause",
   # "watchdog": "inject-nmi" } }
   # <- { "return": {} }
   ##

The arguments are all optional, but the documentation neglects to spell
out what "absent" means.  I guess it means "no change".

The documentation also neglects to spell out the initial settings,
i.e. behavior when you don't configure an action with set-action.

[...]




Re: [RFC v5 01/11] include: add zoned device structs

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:32, Sam Li  wrote:
>
> Signed-off-by: Sam Li 
> ---
>  include/block/block-common.h | 43 
>  1 file changed, 43 insertions(+)
>
> diff --git a/include/block/block-common.h b/include/block/block-common.h
> index fdb7306e78..c9d28b1c51 100644
> --- a/include/block/block-common.h
> +++ b/include/block/block-common.h
> @@ -49,6 +49,49 @@ typedef struct BlockDriver BlockDriver;
>  typedef struct BdrvChild BdrvChild;
>  typedef struct BdrvChildClass BdrvChildClass;
>
> +typedef enum BlockZoneOp {
> +BLK_ZO_OPEN,
> +BLK_ZO_CLOSE,
> +BLK_ZO_FINISH,
> +BLK_ZO_RESET,
> +} BlockZoneOp;
> +
> +typedef enum BlockZoneModel {
> +BLK_Z_NONE = 0x0, /* Regular block device */
> +BLK_Z_HM = 0x1, /* Host-aware zoned block device */
> +BLK_Z_HA = 0x2, /* Host-managed zoned block device */

The HM and HA comments are swapped.

> +} BlockZoneModel;
> +
> +typedef enum BlockZoneCondition {
> +BLK_ZS_NOT_WP = 0x0,
> +BLK_ZS_EMPTY = 0x1,
> +BLK_ZS_IOPEN = 0x2,
> +BLK_ZS_EOPEN = 0x3,
> +BLK_ZS_CLOSED = 0x4,
> +BLK_ZS_RDONLY = 0xD,
> +BLK_ZS_FULL = 0xE,
> +BLK_ZS_OFFLINE = 0xF,
> +} BlockZoneCondition;
> +
> +typedef enum BlockZoneType {
> +BLK_ZT_CONV = 0x1,

/* Conventional random writes supported */

> +BLK_ZT_SWR = 0x2,

/* Sequential writes required */

> +BLK_ZT_SWP = 0x3,

/* Sequential writes preferred */

> +} BlockZoneType;
> +
> +/*
> + * Zone descriptor data structure.
> + * Provide information on a zone with all position and size values in bytes.

s/Provide/Provides/

Once these items have been addressed feel free to add:

Reviewed-by: Stefan Hajnoczi 



Re: [RFC v5 02/11] include: import virtio_blk headers from linux with zoned storage support

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:33, Sam Li  wrote:
>
> Add file from Dmitry's "virtio-blk:add support for zoned block devices"
> linux patch using scripts/update-linux-headers.sh. There is a link for
> more information: https://github.com/dmitry-fomichev/virtblk-zbd
>
> Signed-off-by: Sam Li 
> ---
>  include/standard-headers/linux/virtio_blk.h | 118 
>  1 file changed, 118 insertions(+)

This version of the  header file is not yet
upstream. Please move this patch and the virtio-blk emulation code
into a separate patch series. It depends on Dmitry's VIRTIO spec
changes being accepted and the Linux code being merged.



Re: [PATCH v4 11/17] dump/dump: Add section string table support

2022-08-01 Thread Janosch Frank

On 7/29/22 21:35, Janis Schoetterl-Glausch wrote:

On 7/26/22 11:22, Janosch Frank wrote:

As sections don't have a type like the notes do we need another way to


Having a string table seems like a good idea to me, as we don't know
the requirements any architecture might have, but sections do have sh_type.
Could we use one of those, e.g. one of the processor specific ones?


I'd like to avoid defining more constants in elf.h if at all possible.


Is
SHT_PROGBITS
The section holds information defined by the program,
whose format and meaning are determined solely by the program.
appropriate for us? It seems to me that our program is the guest and
it doesn't determine the meta information on how to decrypt the dump.


SHT_PROGBITS is being set in the last patch (PV dump) for our arch 
headers. The architecture writes the full shdr into the header buffer 
and can set any type.





determine their contents. The string table allows us to assign each
section an identification string which architectures can then use to
tag their sections with.

There will be no string table if the architecture doesn't add custom
sections which are introduced in a following patch.

Signed-off-by: Janosch Frank 
---

[...]

+/*
+ * String table needs to be last section since strings are added
+ * via arch_sections_write_hdr().
+ */
+write_elf_section_hdr_string(s, buff_hdr);
+if (dump_is_64bit(s)) {
+hdr64->e_shstrndx = cpu_to_dump16(s, s->shdr_num - 1);
+} else {
+hdr32->e_shstrndx = cpu_to_dump16(s, s->shdr_num - 1);
  }


Might want to assert e_shstrndx < SHN_LORESERVE (0xff00) or handle that case 
correctly.


Right, more things to worry about




  }
  
@@ -401,11 +453,18 @@ static void write_elf_sections(DumpState *s, Error **errp)

  {
  int ret;
  
-/* Write section zero */

+/* Write section zero and arch sections */


Since that doesn't concern the string section it seems wrong to change this in 
this patch.


I'm currently doing another round of cleanups anyway :)




[PATCH] tpm_emulator: Avoid double initialization during migration

2022-08-01 Thread Ross Lagerwall via
When resuming after a migration, the backend sends CMD_INIT to the
emulator from the startup callback, then it sends the migration state
from the vmstate to the emulator, then it sends CMD_INIT again. Skip the
first CMD_INIT during a migration to avoid initializing the TPM twice.

Signed-off-by: Ross Lagerwall 
---
 backends/tpm/tpm_emulator.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 87d061e9bb..9b50c5b3e2 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -32,6 +32,7 @@
 #include "qemu/sockets.h"
 #include "qemu/lockable.h"
 #include "io/channel-socket.h"
+#include "sysemu/runstate.h"
 #include "sysemu/tpm_backend.h"
 #include "sysemu/tpm_util.h"
 #include "tpm_int.h"
@@ -383,6 +384,15 @@ err_exit:
 
 static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
 {
+/* TPM startup will be done from post_load hook */
+if (runstate_check(RUN_STATE_INMIGRATE)) {
+if (buffersize != 0) {
+return tpm_emulator_set_buffer_size(tb, buffersize, NULL);
+}
+
+return 0;
+}
+
 return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
 }
 
-- 
2.31.1




Re: [RFC v5 03/11] file-posix: introduce get_sysfs_long_val for the long sysfs attribute

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:39, Sam Li  wrote:
>
> Use sysfs attribute files to get the long value of zoned device
> information.
>
> Signed-off-by: Sam Li 
> ---
>  block/file-posix.c | 23 ---
>  1 file changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 48cd096624..bcf898f0cb 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1210,15 +1210,19 @@ static int hdev_get_max_hw_transfer(int fd, struct 
> stat *st)
>  #endif
>  }
>
> -static int hdev_get_max_segments(int fd, struct stat *st)
> -{
> +/*
> + * Get zoned device information (chunk_sectors, zoned_append_max_bytes,
> + * max_open_zones, max_active_zones) through sysfs attribute files.
> + */
> +static long get_sysfs_long_val(int fd, struct stat *st,
> +   const char *attribute) {
>  #ifdef CONFIG_LINUX
>  char buf[32];
>  const char *end;
>  char *sysfspath = NULL;
>  int ret;
>  int sysfd = -1;
> -long max_segments;
> +long val;
>
>  if (S_ISCHR(st->st_mode)) {
>  if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {

This code is specific to max_segments and not relevant to other
attributes. It's an alternative code path for SCSI generic types of
devices. It should be moved into hdev_get_max_segments() before
get_sysfs_long_val() is called.

> @@ -1231,8 +1235,9 @@ static int hdev_get_max_segments(int fd, struct stat 
> *st)
>  return -ENOTSUP;
>  }
>
> -sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
> -major(st->st_rdev), minor(st->st_rdev));
> +sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
> +major(st->st_rdev), minor(st->st_rdev),
> +attribute);
>  sysfd = open(sysfspath, O_RDONLY);
>  if (sysfd == -1) {
>  ret = -errno;
> @@ -1250,9 +1255,9 @@ static int hdev_get_max_segments(int fd, struct stat 
> *st)
>  }
>  buf[ret] = 0;
>  /* The file is ended with '\n', pass 'end' to accept that. */
> -ret = qemu_strtol(buf, &end, 10, &max_segments);
> +ret = qemu_strtol(buf, &end, 10, &val);
>  if (ret == 0 && end && *end == '\n') {
> -ret = max_segments;
> +ret = val;
>  }
>
>  out:
> @@ -1266,6 +1271,10 @@ out:
>  #endif
>  }
>
> +static int hdev_get_max_segments(int fd, struct stat *st) {
> +return get_sysfs_long_val(fd, st, "max_segments");
> +}
> +
>  static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
>  {
>  BDRVRawState *s = bs->opaque;
> --
> 2.37.1
>
>



Re: [PATCH] tests/qtest/migration-test: Run the dirty ring tests only with the x86 target

2022-08-01 Thread Dr. David Alan Gilbert
* Thomas Huth (th...@redhat.com) wrote:
> kvm_dirty_ring_supported() only checks whether the dirty ring support
> is available on the x86 host, but it ignores whether the target QEMU
> architecture is x86 or not. Thus the test_vcpu_dirty_limit() test
> currently fails with the assert((strcmp(arch, "x86_64") == 0)) statement
> in dirtylimit_start_vm() if the users run e.g. "make check-qtest-aarch64"
> on their x86 host. Fix it by only executing the tests when we're running
> with a x86_64 target QEMU binary with KVM.
> 
> Signed-off-by: Thomas Huth 

I think that corresponds to a bug Juan mentioned where it was failing
with a i386 qemu as well.I guess there should be a more generic way!


Reviewed-by: Dr. David Alan Gilbert 

> ---
>  tests/qtest/migration-test.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
> index 71595a74fd..f83360e0e0 100644
> --- a/tests/qtest/migration-test.c
> +++ b/tests/qtest/migration-test.c
> @@ -2439,6 +2439,7 @@ int main(int argc, char **argv)
>  {
>  char template[] = "/tmp/migration-test-XX";
>  const bool has_kvm = qtest_has_accel("kvm");
> +const char *arch = qtest_get_arch();
>  int ret;
>  
>  g_test_init(&argc, &argv, NULL);
> @@ -2452,7 +2453,7 @@ int main(int argc, char **argv)
>   * is touchy due to race conditions on dirty bits (especially on PPC for
>   * some reason)
>   */
> -if (g_str_equal(qtest_get_arch(), "ppc64") &&
> +if (g_str_equal(arch, "ppc64") &&
>  (!has_kvm || access("/sys/module/kvm_hv", F_OK))) {
>  g_test_message("Skipping test: kvm_hv not available");
>  return g_test_run();
> @@ -2462,7 +2463,7 @@ int main(int argc, char **argv)
>   * Similar to ppc64, s390x seems to be touchy with TCG, so disable it
>   * there until the problems are resolved
>   */
> -if (g_str_equal(qtest_get_arch(), "s390x") && !has_kvm) {
> +if (g_str_equal(arch, "s390x") && !has_kvm) {
>  g_test_message("Skipping test: s390x host with KVM is required");
>  return g_test_run();
>  }
> @@ -2572,7 +2573,7 @@ int main(int argc, char **argv)
>  #endif /* CONFIG_TASN1 */
>  #endif /* CONFIG_GNUTLS */
>  
> -if (kvm_dirty_ring_supported()) {
> +if (g_str_equal(arch, "x86_64") && has_kvm && 
> kvm_dirty_ring_supported()) {
>  qtest_add_func("/migration/dirty_ring",
> test_precopy_unix_dirty_ring);
>  qtest_add_func("/migration/vcpu_dirty_limit",
> -- 
> 2.31.1
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH] tpm_emulator: Avoid double initialization during migration

2022-08-01 Thread Marc-André Lureau
Hi

On Mon, Aug 1, 2022 at 6:28 PM Ross Lagerwall via 
wrote:

> When resuming after a migration, the backend sends CMD_INIT to the
> emulator from the startup callback, then it sends the migration state
> from the vmstate to the emulator, then it sends CMD_INIT again. Skip the
> first CMD_INIT during a migration to avoid initializing the TPM twice.
>
> Signed-off-by: Ross Lagerwall 
>

lgtm
Reviewed-by: Marc-André Lureau 

There are no visible bugs/symptoms, I suppose?


> ---
>  backends/tpm/tpm_emulator.c | 10 ++
>  1 file changed, 10 insertions(+)
>
> diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
> index 87d061e9bb..9b50c5b3e2 100644
> --- a/backends/tpm/tpm_emulator.c
> +++ b/backends/tpm/tpm_emulator.c
> @@ -32,6 +32,7 @@
>  #include "qemu/sockets.h"
>  #include "qemu/lockable.h"
>  #include "io/channel-socket.h"
> +#include "sysemu/runstate.h"
>  #include "sysemu/tpm_backend.h"
>  #include "sysemu/tpm_util.h"
>  #include "tpm_int.h"
> @@ -383,6 +384,15 @@ err_exit:
>
>  static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
>  {
> +/* TPM startup will be done from post_load hook */
> +if (runstate_check(RUN_STATE_INMIGRATE)) {
> +if (buffersize != 0) {
> +return tpm_emulator_set_buffer_size(tb, buffersize, NULL);
> +}
> +
> +return 0;
> +}
> +
>  return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
>  }
>
> --
> 2.31.1
>
>
>

-- 
Marc-André Lureau


Re: [PATCH v7 14/14] memfd_create.2: Describe MFD_INACCESSIBLE flag

2022-08-01 Thread Dave Hansen
This patch does not belong in this series.  It's not a patch to the
kernel.  This is a kernel series.

It would be much more appropriate to put a link to a separately posted
manpage patch in the cover letter.



Re: [RFC v5 04/11] file-posix: introduce get_sysfs_str_val for device zoned model

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:34, Sam Li  wrote:
>
> Use sysfs attribute files to get the string value of device
> zoned model. Then get_sysfs_zoned_model can convert it to
> BlockZoneModel type in QEMU.
>
> Signed-off-by: Sam Li 
> ---
>  block/file-posix.c   | 86 
>  include/block/block_int-common.h |  3 ++
>  2 files changed, 89 insertions(+)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index bcf898f0cb..0d8b4acdc7 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1271,6 +1271,85 @@ out:
>  #endif
>  }
>
> +/*
> + * Convert the zoned attribute file in sysfs to internal value.
> + */
> +static int get_sysfs_str_val(int fd, struct stat *st,
> +  const char *attribute,
> +  char **val) {
> +#ifdef CONFIG_LINUX
> +char buf[32];
> +char *sysfspath = NULL;

This can be g_autofree and then the explicit g_free(sysfspath) call is
no longer necessary.

> +int ret, offset;
> +int sysfd = -1;
> +
> +if (S_ISCHR(st->st_mode)) {
> +if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
> +return ret;
> +}
> +return -ENOTSUP;
> +}

This is for max_segments only. See my comment on the previous patch.

> +
> +if (!S_ISBLK(st->st_mode)) {
> +return -ENOTSUP;
> +}
> +
> +sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
> +major(st->st_rdev), minor(st->st_rdev),
> +attribute);

The code that follows can be replaced by a call to g_file_get_contents():
https://docs.gtk.org/glib/func.file_get_contents.html

Then the caller doesn't need to pre-allocate a 32-byte buffer. Instead
this function returns a string on the heap. The caller can free it
with g_free().

> +sysfd = open(sysfspath, O_RDONLY);
> +if (sysfd == -1) {
> +ret = -errno;
> +goto out;
> +}
> +offset = 0;
> +do {
> +ret = read(sysfd, buf + offset, sizeof(buf) - 1 + offset);
> +if (ret > 0) {
> +offset += ret;
> +}
> +} while (ret == -1);

I think this should be:

  } while (ret == -1 && errno == EINTR);

  if (ret < 0) {
  ret = -errno;
  goto out;
  }

Otherwise there is an infinite loop when an unrecoverable error occurs.

> +/* The file is ended with '\n' */
> +if (buf[ret - 1] == '\n') {
> +buf[ret - 1] = '\0';
> +}
> +
> +if (!strncpy(*val, buf, ret)) {
> +goto out;
> +}
> +
> +out:
> +if (sysfd != -1) {
> +close(sysfd);
> +}
> +g_free(sysfspath);
> +return ret;
> +#else
> +return -ENOTSUP;
> +#endif
> +}
> +
> +static int get_sysfs_zoned_model(int fd, struct stat *st,
> + BlockZoneModel *zoned) {
> +g_autofree char *val = NULL;
> +val = g_malloc(32);
> +get_sysfs_str_val(fd, st, "zoned", &val);
> +if (!val) {
> +return -ENOTSUP;
> +}
> +
> +if (strcmp(val, "host-managed") == 0) {
> +*zoned = BLK_Z_HM;
> +} else if (strcmp(val, "host-aware") == 0) {
> +*zoned = BLK_Z_HA;
> +} else if (strcmp(val, "none") == 0) {
> +*zoned = BLK_Z_NONE;
> +} else {
> +return -ENOTSUP;
> +}
> +return 0;
> +}
> +
>  static int hdev_get_max_segments(int fd, struct stat *st) {
>  return get_sysfs_long_val(fd, st, "max_segments");
>  }
> @@ -1279,6 +1358,8 @@ static void raw_refresh_limits(BlockDriverState *bs, 
> Error **errp)
>  {
>  BDRVRawState *s = bs->opaque;
>  struct stat st;
> +int ret;
> +BlockZoneModel zoned;
>
>  s->needs_alignment = raw_needs_alignment(bs);
>  raw_probe_alignment(bs, s->fd, errp);
> @@ -1316,6 +1397,11 @@ static void raw_refresh_limits(BlockDriverState *bs, 
> Error **errp)
>  bs->bl.max_hw_iov = ret;
>  }
>  }
> +
> +ret = get_sysfs_zoned_model(s->fd, &st, &zoned);
> +if (ret < 0)
> +zoned = BLK_Z_NONE;

QEMU coding style always uses {}:

  if (ret < 0) {
  zoned = BLK_Z_NONE;
  }

> +bs->bl.zoned = zoned;
>  }
>
>  static int check_for_dasd(int fd)
> diff --git a/include/block/block_int-common.h 
> b/include/block/block_int-common.h
> index 8947abab76..7f7863cc9e 100644
> --- a/include/block/block_int-common.h
> +++ b/include/block/block_int-common.h
> @@ -825,6 +825,9 @@ typedef struct BlockLimits {
>
>  /* maximum number of iovec elements */
>  int max_iov;
> +
> +/* device zone model */
> +BlockZoneModel zoned;
>  } BlockLimits;
>
>  typedef struct BdrvOpBlocker BdrvOpBlocker;
> --
> 2.37.1
>
>



[PATCH] vdpa: Fix file descriptor leak on get features error

2022-08-01 Thread Eugenio Pérez
File descriptor vdpa_device_fd is not free in the case of returning
error from vhost_vdpa_get_features. Fixing it by making all errors go to
the same error path.

Resolves: Coverity CID 1490785
Fixes: 8170ab3f43 ("vdpa: Extract get features part from 
vhost_vdpa_get_max_queue_pairs")

Signed-off-by: Eugenio Pérez 
---
 net/vhost-vdpa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 6abad276a6..303447a68e 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -566,7 +566,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char 
*name,
 g_autofree NetClientState **ncs = NULL;
 g_autoptr(VhostIOVATree) iova_tree = NULL;
 NetClientState *nc;
-int queue_pairs, r, i, has_cvq = 0;
+int queue_pairs, r, i = 0, has_cvq = 0;
 
 assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA);
 opts = &netdev->u.vhost_vdpa;
@@ -582,7 +582,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char 
*name,
 
 r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp);
 if (unlikely(r < 0)) {
-return r;
+goto err;
 }
 
 queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd, features,
-- 
2.31.1




Re: [RFC v5 05/11] block: add block layer APIs resembling Linux ZonedBlockDevice ioctls

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:34, Sam Li  wrote:
>
> By adding zone management operations in BlockDriver, storage controller
> emulation can use the new block layer APIs including Report Zone and
> four zone management operations (open, close, finish, reset).
>
> BlockDriver can get zone information from null_blk device by refreshing
> BLockLimits.
>
> Signed-off-by: Sam Li 
> ---
>  block/block-backend.c|  47 ++
>  block/coroutines.h   |   6 +
>  block/file-posix.c   | 272 ++-
>  block/io.c   |  57 +++
>  include/block/block-common.h |   1 -
>  include/block/block-io.h |  13 ++
>  include/block/block_int-common.h |  22 ++-
>  include/block/raw-aio.h  |   6 +-
>  meson.build  |   1 +
>  qapi/block-core.json |   7 +-
>  10 files changed, 426 insertions(+), 6 deletions(-)
>
> diff --git a/block/block-backend.c b/block/block-backend.c
> index d4a5df2ac2..ef6a1f33d5 100644
> --- a/block/block-backend.c
> +++ b/block/block-backend.c
> @@ -1775,6 +1775,53 @@ int coroutine_fn blk_co_flush(BlockBackend *blk)
>  return ret;
>  }
>
> +/*
> + * Send a zone_report command.
> + * offset is a byte offset from the start of the device. No alignment
> + * required for offset.
> + * nr_zones represents IN maximum and OUT actual.
> + */
> +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> +unsigned int *nr_zones,
> +BlockZoneDescriptor *zones)
> +{
> +int ret;
> +IO_CODE();
> +
> +blk_inc_in_flight(blk); /* increase before waiting */
> +blk_wait_while_drained(blk);
> +if (!blk_is_available(blk)) {
> +return -ENOMEDIUM;

Missing blk_dec_in_flight().

> +}
> +ret = bdrv_co_zone_report(blk_bs(blk), offset, nr_zones, zones);
> +blk_dec_in_flight(blk);
> +return ret;
> +}
> +
> +/*
> + * Send a zone_management command.
> + * offset is the starting zone specified as a sector offset.
> + * len is the maximum number of sectors the command should operate on.
> + */
> +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
> +int64_t offset, int64_t len)
> +{
> +int ret;
> +IO_CODE();
> +
> +ret = blk_check_byte_request(blk, offset, len);
> +if (ret < 0)
> +return ret;

QEMU coding style uses {} around the if statement body.

> +blk_inc_in_flight(blk);
> +blk_wait_while_drained(blk);
> +if (!blk_is_available(blk)) {
> +return -ENOMEDIUM;

Missing blk_dec_in_flight().

> +}
> +ret = bdrv_co_zone_mgmt(blk_bs(blk), op, offset, len);
> +blk_dec_in_flight(blk);
> +return ret;
> +}
> +
>  void blk_drain(BlockBackend *blk)
>  {
>  BlockDriverState *bs = blk_bs(blk);
> diff --git a/block/coroutines.h b/block/coroutines.h
> index 3a2bad564f..e3f62d94e5 100644
> --- a/block/coroutines.h
> +++ b/block/coroutines.h
> @@ -63,6 +63,12 @@ nbd_co_do_establish_connection(BlockDriverState *bs, bool 
> blocking,
> Error **errp);
>
>
> +int coroutine_fn blk_co_zone_report(BlockBackend *blk, int64_t offset,
> +unsigned int *nr_zones,
> +BlockZoneDescriptor *zones);
> +int coroutine_fn blk_co_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
> +  int64_t offset, int64_t len);
> +
>  /*
>   * "I/O or GS" API functions. These functions can run without
>   * the BQL, but only in one specific iothread/main loop.
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 0d8b4acdc7..6c045eb6e8 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -67,6 +67,9 @@
>  #include 
>  #include 
>  #include 
> +#if defined(CONFIG_BLKZONED)
> +#include 
> +#endif
>  #include 
>  #include 
>  #include 
> @@ -216,6 +219,13 @@ typedef struct RawPosixAIOData {
>  PreallocMode prealloc;
>  Error **errp;
>  } truncate;
> +struct {
> +unsigned int *nr_zones;
> +BlockZoneDescriptor *zones;
> +} zone_report;
> +struct {
> +BlockZoneOp op;
> +} zone_mgmt;
>  };
>  } RawPosixAIOData;
>
> @@ -1386,7 +1396,7 @@ static void raw_refresh_limits(BlockDriverState *bs, 
> Error **errp)
>  #endif
>
>  if (bs->sg || S_ISBLK(st.st_mode)) {
> -int ret = hdev_get_max_hw_transfer(s->fd, &st);
> +ret = hdev_get_max_hw_transfer(s->fd, &st);
>
>  if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
>  bs->bl.max_hw_transfer = ret;
> @@ -1402,6 +1412,27 @@ static void raw_refresh_limits(BlockDriverState *bs, 
> Error **errp)
>  if (ret < 0)
>  zoned = BLK_Z_NONE;
>  bs->bl.zoned = zoned;
> +if (zoned != BLK_Z_NONE) {
> +ret = get_sysfs_long_val(s->fd, &st, "chunk_sectors");
> +if (ret > 0) {
> +bs->bl.zone_sec

Re: [RFC v5 06/11] raw-format: add zone operations to pass through requests

2022-08-01 Thread Stefan Hajnoczi
Reviewed-by: Stefan Hajnoczi 



Re: [RFC v5 07/11] config: add check to block layer

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:39, Sam Li  wrote:
>
> Putting zoned/non-zoned BlockDrivers on top of each other is not
> allowed.
>
> Signed-off-by: Sam Li 
> ---
>  block.c  | 13 +
>  block/file-posix.c   |  2 ++
>  block/raw-format.c   |  1 +
>  include/block/block_int-common.h | 10 ++
>  4 files changed, 26 insertions(+)
>
> diff --git a/block.c b/block.c
> index bc85f46eed..8a259b158c 100644
> --- a/block.c
> +++ b/block.c
> @@ -7947,6 +7947,19 @@ void bdrv_add_child(BlockDriverState *parent_bs, 
> BlockDriverState *child_bs,
>  return;
>  }
>
> +/*
> + * Non-zoned block drivers do not follow zoned storage constraints
> + * (i.e. sequential writes to zones). Refuse mixing zoned and non-zoned
> + * drivers in a graph.
> + */
> +if (!parent_bs->drv->supports_zoned_children && child_bs->drv->is_zoned) 
> {
> +error_setg(errp, "Cannot add a %s child to a %s parent",
> +   child_bs->drv->is_zoned ? "zoned" : "non-zoned",
> +   parent_bs->drv->supports_zoned_children ?
> +   "support zoned children" : "not support zoned children");
> +return;
> +}
> +
>  if (!QLIST_EMPTY(&child_bs->parents)) {
>  error_setg(errp, "The node %s already has a parent",
> child_bs->node_name);
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 6c045eb6e8..8eb0b7bc9b 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -4023,6 +4023,8 @@ static BlockDriver bdrv_zoned_host_device = {
>  .format_name = "zoned_host_device",
>  .protocol_name = "zoned_host_device",
>  .instance_size = sizeof(BDRVRawState),
> +.is_zoned = true,
> +.supports_zoned_children = true,

zoned_host_device never has children, so supports_zoned_children
should not be set.

>  .bdrv_needs_filename = true,
>  .bdrv_probe_device  = hdev_probe_device,
>  .bdrv_parse_filename = zoned_host_device_parse_filename,
> diff --git a/block/raw-format.c b/block/raw-format.c
> index 6b20bd22ef..9441536819 100644
> --- a/block/raw-format.c
> +++ b/block/raw-format.c
> @@ -614,6 +614,7 @@ static void raw_child_perm(BlockDriverState *bs, 
> BdrvChild *c,
>  BlockDriver bdrv_raw = {
>  .format_name  = "raw",
>  .instance_size= sizeof(BDRVRawState),
> +.supports_zoned_children = true,
>  .bdrv_probe   = &raw_probe,
>  .bdrv_reopen_prepare  = &raw_reopen_prepare,
>  .bdrv_reopen_commit   = &raw_reopen_commit,
> diff --git a/include/block/block_int-common.h 
> b/include/block/block_int-common.h
> index de44c7b6f4..0476cd0491 100644
> --- a/include/block/block_int-common.h
> +++ b/include/block/block_int-common.h
> @@ -126,6 +126,16 @@ struct BlockDriver {
>   */
>  bool is_format;
>
> +/*
> + * Set to true if the BlockDriver is a zoned block driver.
> + */
> +bool is_zoned;
> +
> +/*
> + * Set to true if the BlockDriver supports zoned children.
> + */
> +bool supports_zoned_children;
> +
>  /*
>   * Drivers not implementing bdrv_parse_filename nor bdrv_open should have
>   * this field set to true, except ones that are defined only by their
> --
> 2.37.1
>
>



[PULL 0/3] target-arm queue

2022-08-01 Thread Peter Maydell
Only thing for Arm for rc1 is RTH's fix for the KVM SVE probe code.

-- PMM

The following changes since commit 4e06b3fc1b5e1ec03f22190eabe56891dc9c2236:

  Merge tag 'pull-hex-20220731' of https://github.com/quic/qemu into staging 
(2022-07-31 21:38:54 -0700)

are available in the Git repository at:

  https://git.linaro.org/people/pmaydell/qemu-arm.git 
tags/pull-target-arm-20220801

for you to fetch changes up to 5265d24c981dfdda8d29b44f7e84a514da75eedc:

  target/arm: Move sve probe inside kvm >= 4.15 branch (2022-08-01 16:21:18 
+0100)


target-arm queue:
 * Fix KVM SVE ID register probe code


Richard Henderson (3):
  target/arm: Use kvm_arm_sve_supported in kvm_arm_get_host_cpu_features
  target/arm: Set KVM_ARM_VCPU_SVE while probing the host
  target/arm: Move sve probe inside kvm >= 4.15 branch

 target/arm/kvm64.c | 45 ++---
 1 file changed, 22 insertions(+), 23 deletions(-)



[PULL 3/3] target/arm: Move sve probe inside kvm >= 4.15 branch

2022-08-01 Thread Peter Maydell
From: Richard Henderson 

The test for the IF block indicates no ID registers are exposed, much
less host support for SVE.  Move the SVE probe into the ELSE block.

Signed-off-by: Richard Henderson 
Message-id: 20220726045828.53697-4-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/kvm64.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 43cd7eb8904..9b9dd46d782 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -679,18 +679,18 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures 
*ahcf)
 err |= read_sys_reg64(fdarray[2], &ahcf->isar.reset_pmcr_el0,
   ARM64_SYS_REG(3, 3, 9, 12, 0));
 }
-}
 
-if (sve_supported) {
-/*
- * There is a range of kernels between kernel commit 73433762fcae
- * and f81cb2c3ad41 which have a bug where the kernel doesn't expose
- * SYS_ID_AA64ZFR0_EL1 via the ONE_REG API unless the VM has enabled
- * SVE support, which resulted in an error rather than RAZ.
- * So only read the register if we set KVM_ARM_VCPU_SVE above.
- */
-err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0,
-  ARM64_SYS_REG(3, 0, 0, 4, 4));
+if (sve_supported) {
+/*
+ * There is a range of kernels between kernel commit 73433762fcae
+ * and f81cb2c3ad41 which have a bug where the kernel doesn't
+ * expose SYS_ID_AA64ZFR0_EL1 via the ONE_REG API unless the VM has
+ * enabled SVE support, which resulted in an error rather than RAZ.
+ * So only read the register if we set KVM_ARM_VCPU_SVE above.
+ */
+err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0,
+  ARM64_SYS_REG(3, 0, 0, 4, 4));
+}
 }
 
 kvm_arm_destroy_scratch_host_vcpu(fdarray);
-- 
2.25.1




[PULL 2/3] target/arm: Set KVM_ARM_VCPU_SVE while probing the host

2022-08-01 Thread Peter Maydell
From: Richard Henderson 

Because we weren't setting this flag, our probe of ID_AA64ZFR0
was always returning zero.  This also obviates the adjustment
of ID_AA64PFR0, which had sanitized the SVE field.

The effects of the bug are not visible, because the only thing that
ID_AA64ZFR0 is used for within qemu at present is tcg translation.
The other tests for SVE within KVM are via ID_AA64PFR0.SVE.

Reported-by: Zenghui Yu 
Signed-off-by: Richard Henderson 
Message-id: 20220726045828.53697-3-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/kvm64.c | 27 +--
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index bb1516b3d5a..43cd7eb8904 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -507,7 +507,6 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
 bool sve_supported;
 bool pmu_supported = false;
 uint64_t features = 0;
-uint64_t t;
 int err;
 
 /* Old kernels may not know about the PREFERRED_TARGET ioctl: however
@@ -528,10 +527,17 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures 
*ahcf)
 struct kvm_vcpu_init init = { .target = -1, };
 
 /*
- * Ask for Pointer Authentication if supported. We can't play the
- * SVE trick of synthesising the ID reg as KVM won't tell us
- * whether we have the architected or IMPDEF version of PAuth, so
- * we have to use the actual ID regs.
+ * Ask for SVE if supported, so that we can query ID_AA64ZFR0,
+ * which is otherwise RAZ.
+ */
+sve_supported = kvm_arm_sve_supported();
+if (sve_supported) {
+init.features[0] |= 1 << KVM_ARM_VCPU_SVE;
+}
+
+/*
+ * Ask for Pointer Authentication if supported, so that we get
+ * the unsanitized field values for AA64ISAR1_EL1.
  */
 if (kvm_arm_pauth_supported()) {
 init.features[0] |= (1 << KVM_ARM_VCPU_PTRAUTH_ADDRESS |
@@ -675,20 +681,13 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures 
*ahcf)
 }
 }
 
-sve_supported = kvm_arm_sve_supported();
-
-/* Add feature bits that can't appear until after VCPU init. */
 if (sve_supported) {
-t = ahcf->isar.id_aa64pfr0;
-t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
-ahcf->isar.id_aa64pfr0 = t;
-
 /*
  * There is a range of kernels between kernel commit 73433762fcae
  * and f81cb2c3ad41 which have a bug where the kernel doesn't expose
  * SYS_ID_AA64ZFR0_EL1 via the ONE_REG API unless the VM has enabled
- * SVE support, so we only read it here, rather than together with all
- * the other ID registers earlier.
+ * SVE support, which resulted in an error rather than RAZ.
+ * So only read the register if we set KVM_ARM_VCPU_SVE above.
  */
 err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0,
   ARM64_SYS_REG(3, 0, 0, 4, 4));
-- 
2.25.1




[PULL 1/3] target/arm: Use kvm_arm_sve_supported in kvm_arm_get_host_cpu_features

2022-08-01 Thread Peter Maydell
From: Richard Henderson 

Indication for support for SVE will not depend on whether we
perform the query on the main kvm_state or the temp vcpu.

Signed-off-by: Richard Henderson 
Message-id: 20220726045828.53697-2-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/kvm64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index d16d4ea2500..bb1516b3d5a 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -675,7 +675,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
 }
 }
 
-sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 
0;
+sve_supported = kvm_arm_sve_supported();
 
 /* Add feature bits that can't appear until after VCPU init. */
 if (sve_supported) {
-- 
2.25.1




Re: [RFC v5 08/11] virtio-blk: add zoned storage APIs for zoned devices

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:43, Sam Li  wrote:
>
> This patch extends virtio-blk emulation to handle zoned device commands
> by calling the new block layer APIs to perform zoned device I/O on
> behalf of the guest. It supports Report Zone, and four zone oparations (open,
> close, finish, reset). The virtio-blk zoned device command specifications
> is currently in the reviewing process.
>
> VIRTIO_BLK_F_ZONED will only be set if the host does support zoned block
> devices. The regular block device will not be set. The guest os having
> zoned device support can use blkzone(8) to test those commands.
>
> Signed-off-by: Sam Li 
> ---
>  block/block-backend.c |  92 
>  hw/block/virtio-blk.c | 172 +-
>  include/sysemu/block-backend-io.h |   6 ++
>  3 files changed, 268 insertions(+), 2 deletions(-)
>
> diff --git a/block/block-backend.c b/block/block-backend.c
> index ef6a1f33d5..8f2cfcbd9d 100644
> --- a/block/block-backend.c
> +++ b/block/block-backend.c
> @@ -1431,6 +1431,15 @@ typedef struct BlkRwCo {
>  void *iobuf;
>  int ret;
>  BdrvRequestFlags flags;
> +union {
> +struct {
> +unsigned int *nr_zones;
> +BlockZoneDescriptor *zones;
> +} zone_report;
> +struct {
> +BlockZoneOp op;
> +} zone_mgmt;
> +};
>  } BlkRwCo;
>
>  int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
> @@ -1775,6 +1784,89 @@ int coroutine_fn blk_co_flush(BlockBackend *blk)
>  return ret;
>  }
>
> +static void blk_aio_zone_report_entry(void *opaque) {
> +BlkAioEmAIOCB *acb = opaque;
> +BlkRwCo *rwco = &acb->rwco;
> +
> +rwco->ret = blk_co_zone_report(rwco->blk, rwco->offset,
> +   rwco->zone_report.nr_zones,
> +   rwco->zone_report.zones);
> +blk_aio_complete(acb);
> +}
> +
> +BlockAIOCB *blk_aio_zone_report(BlockBackend *blk, int64_t offset,
> +unsigned int *nr_zones,
> +BlockZoneDescriptor  *zones,
> +BlockCompletionFunc *cb, void *opaque)
> +{
> +BlkAioEmAIOCB *acb;
> +Coroutine *co;
> +
> +blk_inc_in_flight(blk);
> +acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
> +acb->rwco = (BlkRwCo) {
> +.blk= blk,
> +.offset = offset,
> +.ret= NOT_DONE,
> +.zone_report = {
> +.zones = zones,
> +.nr_zones = nr_zones,
> +},
> +};
> +acb->has_returned = false;
> +
> +co = qemu_coroutine_create(blk_aio_zone_report_entry, acb);
> +bdrv_coroutine_enter(blk_bs(blk), co);
> +
> +acb->has_returned = true;
> +if (acb->rwco.ret != NOT_DONE) {
> +replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
> + blk_aio_complete_bh, acb);
> +}
> +
> +return &acb->common;
> +}
> +
> +static void blk_aio_zone_mgmt_entry(void *opaque) {
> +BlkAioEmAIOCB *acb = opaque;
> +BlkRwCo *rwco = &acb->rwco;
> +
> +rwco->ret = blk_co_zone_mgmt(rwco->blk, rwco->zone_mgmt.op,
> + rwco->offset, acb->bytes);
> +blk_aio_complete(acb);
> +}
> +
> +BlockAIOCB *blk_aio_zone_mgmt(BlockBackend *blk, BlockZoneOp op,
> +  int64_t offset, int64_t len,
> +  BlockCompletionFunc *cb, void *opaque) {
> +BlkAioEmAIOCB *acb;
> +Coroutine *co;
> +
> +blk_inc_in_flight(blk);
> +acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);
> +acb->rwco = (BlkRwCo) {
> +.blk= blk,
> +.offset = offset,
> +.ret= NOT_DONE,
> +.zone_mgmt = {
> +.op = op,
> +},
> +};
> +acb->bytes = len;
> +acb->has_returned = false;
> +
> +co = qemu_coroutine_create(blk_aio_zone_mgmt_entry, acb);
> +bdrv_coroutine_enter(blk_bs(blk), co);
> +
> +acb->has_returned = true;
> +if (acb->rwco.ret != NOT_DONE) {
> +replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
> + blk_aio_complete_bh, acb);
> +}
> +
> +return &acb->common;
> +}
> +
>  /*
>   * Send a zone_report command.
>   * offset is a byte offset from the start of the device. No alignment
> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> index e9ba752f6b..9722f447a2 100644
> --- a/hw/block/virtio-blk.c
> +++ b/hw/block/virtio-blk.c
> @@ -37,6 +37,7 @@
>  /* Config size before the discard support (hide associated config fields) */
>  #define VIRTIO_BLK_CFG_SIZE offsetof(struct virtio_blk_config, \
>   max_discard_sectors)
> +
>  /*
>   * Starting from the discard feature, we can use this array to properly
>   * set the config size depending on the features enabled.
>

Re: [RFC v5 09/11] qemu-io: add zoned block device operations.

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:42, Sam Li  wrote:
>
> Add zoned storage commands of the device: zone_report(zrp), zone_open(zo),
> zone_close(zc), zone_reset(zrs), zone_finish(zf).
>
> For example, to test zone_report, use following command:
> $ ./build/qemu-io --image-opts driver=zoned_host_device, filename=/dev/nullb0
> -c "zrp offset nr_zones"
>
> Signed-off-by: Sam Li 
> ---
>  block/io.c |  24 ++---
>  qemu-io-cmds.c | 144 +
>  2 files changed, 148 insertions(+), 20 deletions(-)
>
> diff --git a/block/io.c b/block/io.c
> index a4625fb0e1..de9ec1d740 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -3209,19 +3209,11 @@ int bdrv_co_zone_report(BlockDriverState *bs, int64_t 
> offset,
>  IO_CODE();
>
>  bdrv_inc_in_flight(bs);
> -if (!drv || (!drv->bdrv_co_zone_report)) {
> +if (!drv || !drv->bdrv_co_zone_report) {
>  co.ret = -ENOTSUP;
>  goto out;
>  }
> -
> -if (drv->bdrv_co_zone_report) {
> -co.ret = drv->bdrv_co_zone_report(bs, offset, nr_zones, zones);
> -} else {
> -co.ret = -ENOTSUP;
> -goto out;
> -qemu_coroutine_yield();
> -}
> -
> +co.ret = drv->bdrv_co_zone_report(bs, offset, nr_zones, zones);
>  out:
>  bdrv_dec_in_flight(bs);
>  return co.ret;
> @@ -3237,19 +3229,11 @@ int bdrv_co_zone_mgmt(BlockDriverState *bs, 
> BlockZoneOp op,
>  IO_CODE();
>
>  bdrv_inc_in_flight(bs);
> -if (!drv || (!drv->bdrv_co_zone_mgmt)) {
> +if (!drv || !drv->bdrv_co_zone_mgmt) {
>  co.ret = -ENOTSUP;
>  goto out;
>  }
> -
> -if (drv->bdrv_co_zone_mgmt) {
> -co.ret = drv->bdrv_co_zone_mgmt(bs, op, offset, len);
> -} else {
> -co.ret = -ENOTSUP;
> -goto out;
> -qemu_coroutine_yield();
> -}
> -
> +co.ret = drv->bdrv_co_zone_mgmt(bs, op, offset, len);
>  out:
>  bdrv_dec_in_flight(bs);
>  return co.ret;

Please squash these changes into the earlier patch that introduced
these functions.

Otherwise:

Reviewed-by: Stefan Hajnoczi 



Re: [PULL for-7.1 0/3] hw/nvme fixes

2022-08-01 Thread Richard Henderson

On 8/1/22 03:05, Klaus Jensen wrote:

From: Klaus Jensen 

Hi,

The following changes since commit 3916603e0c1d909e14e09d5ebcbdaa9c9e21adf3:

   Merge tag 'pull-la-20220729' of https://gitlab.com/rth7680/qemu into staging 
(2022-07-29 17:39:17 -0700)

are available in the Git repository at:

   git://git.infradead.org/qemu-nvme.git tags/nvme-next-pull-request

for you to fetch changes up to e2e137f64282a2ee2f359b6df4cd93c83a308e7b:

   hw/nvme: do not enable ioeventfd by default (2022-08-01 12:01:21 +0200)


hw/nvme fixes

Some fixes for hw/nvme ioeventfd support.


Applied, thanks.  Please update https://wiki.qemu.org/ChangeLog/7.1 as 
appropriate.


r~






Klaus Jensen (3):
   hw/nvme: skip queue processing if notifier is cleared
   hw/nvme: unregister the event notifier handler on the main loop
   hw/nvme: do not enable ioeventfd by default

  hw/nvme/ctrl.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)






[PULL 2/7] migration-test: Use migrate_ensure_converge() for auto-converge

2022-08-01 Thread Thomas Huth
From: Peter Xu 

Thomas reported that auto-converge test will timeout on MacOS CI gatings.
Use the migrate_ensure_converge() helper too in the auto-converge as when
Daniel reworked the other test cases.

Since both max_bandwidth / downtime_limit will not be used for converge
calculations, make it simple by removing the remaining check, then we can
completely remove both variables altogether, since migrate_ensure_converge
is used the remaining check won't make much sense anyway.

Reported-by: Thomas Huth 
Suggested-by: Daniel P. Berrange 
Signed-off-by: Peter Xu 
Message-Id: <20220728133516.92061-2-pet...@redhat.com>
Tested-by: Thomas Huth 
Reviewed-by: Daniel P. Berrange 
Signed-off-by: Thomas Huth 
---
 tests/qtest/migration-test.c | 19 ++-
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index 71595a74fd..c1e002087d 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -1768,7 +1768,7 @@ static void test_migrate_auto_converge(void)
 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
 MigrateStart args = {};
 QTestState *from, *to;
-int64_t remaining, percentage;
+int64_t percentage;
 
 /*
  * We want the test to be stable and as fast as possible.
@@ -1776,14 +1776,6 @@ static void test_migrate_auto_converge(void)
  * so we need to decrease a bandwidth.
  */
 const int64_t init_pct = 5, inc_pct = 50, max_pct = 95;
-const int64_t max_bandwidth = 4; /* ~400Mb/s */
-const int64_t downtime_limit = 250; /* 250ms */
-/*
- * We migrate through unix-socket (> 500Mb/s).
- * Thus, expected migration speed ~= bandwidth limit (< 500Mb/s).
- * So, we can predict expected_threshold
- */
-const int64_t expected_threshold = max_bandwidth * downtime_limit / 1000;
 
 if (test_migrate_start(&from, &to, uri, &args)) {
 return;
@@ -1818,8 +1810,7 @@ static void test_migrate_auto_converge(void)
 /* The first percentage of throttling should be equal to init_pct */
 g_assert_cmpint(percentage, ==, init_pct);
 /* Now, when we tested that throttling works, let it converge */
-migrate_set_parameter_int(from, "downtime-limit", downtime_limit);
-migrate_set_parameter_int(from, "max-bandwidth", max_bandwidth);
+migrate_ensure_converge(from);
 
 /*
  * Wait for pre-switchover status to check last throttle percentage
@@ -1830,11 +1821,6 @@ static void test_migrate_auto_converge(void)
 /* The final percentage of throttling shouldn't be greater than max_pct */
 percentage = read_migrate_property_int(from, "cpu-throttle-percentage");
 g_assert_cmpint(percentage, <=, max_pct);
-
-remaining = read_ram_property_int(from, "remaining");
-g_assert_cmpint(remaining, <,
-(expected_threshold + expected_threshold / 100));
-
 migrate_continue(from, "pre-switchover");
 
 qtest_qmp_eventwait(to, "RESUME");
@@ -1842,7 +1828,6 @@ static void test_migrate_auto_converge(void)
 wait_for_serial("dest_serial");
 wait_for_migration_complete(from);
 
-
 test_migrate_end(from, to, true);
 }
 
-- 
2.31.1




[PULL 1/7] tests/tcg/linux-test: Fix random hangs in test_socket

2022-08-01 Thread Thomas Huth
From: Ilya Leoshkevich 

test_socket hangs randomly in connect(), especially when run without
qemu. Apparently the reason is that linux started treating backlog
value of 0 literally instead of rounding it up since v4.4 (commit
ef547f2ac16b).

So set it to 1 instead.

Signed-off-by: Ilya Leoshkevich 
Message-Id: <20220725144251.192720-1-...@linux.ibm.com>
Signed-off-by: Thomas Huth 
---
 tests/tcg/multiarch/linux/linux-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/tcg/multiarch/linux/linux-test.c 
b/tests/tcg/multiarch/linux/linux-test.c
index 019d8175ca..5a2a4f2258 100644
--- a/tests/tcg/multiarch/linux/linux-test.c
+++ b/tests/tcg/multiarch/linux/linux-test.c
@@ -263,7 +263,7 @@ static int server_socket(void)
 sockaddr.sin_port = htons(0); /* choose random ephemeral port) */
 sockaddr.sin_addr.s_addr = 0;
 chk_error(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)));
-chk_error(listen(fd, 0));
+chk_error(listen(fd, 1));
 return fd;
 
 }
-- 
2.31.1




Re: [RFC v5 10/11] qemu-iotests: test new zone operations

2022-08-01 Thread Stefan Hajnoczi
On Sun, 31 Jul 2022 at 21:39, Sam Li  wrote:
>
> We have added new block layer APIs of zoned block devices. Test it with:
> Create a null_blk device, run each zone operation on it and see
> whether reporting right zone information.
>
> Signed-off-by: Sam Li 
> ---
>  tests/qemu-iotests/tests/zoned.out | 53 ++
>  tests/qemu-iotests/tests/zoned.sh  | 86 ++
>  2 files changed, 139 insertions(+)
>  create mode 100644 tests/qemu-iotests/tests/zoned.out
>  create mode 100755 tests/qemu-iotests/tests/zoned.sh

Reviewed-by: Stefan Hajnoczi 



[PULL 4/7] tests/unit/test-qga: Replace the word 'blacklist' in the guest agent unit test

2022-08-01 Thread Thomas Huth
Let's use better, more inclusive wording here.

Message-Id: <20220727092135.302915-4-th...@redhat.com>
Reviewed-by: Konstantin Kostiuk 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Thomas Huth 
---
 tests/unit/test-qga.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c
index 530317044b..b27c77a695 100644
--- a/tests/unit/test-qga.c
+++ b/tests/unit/test-qga.c
@@ -629,7 +629,7 @@ static void test_qga_get_time(gconstpointer fix)
 g_assert_cmpint(time, >, 0);
 }
 
-static void test_qga_blacklist(gconstpointer data)
+static void test_qga_blockedrpcs(gconstpointer data)
 {
 TestFixture fix;
 QDict *ret, *error;
@@ -637,7 +637,7 @@ static void test_qga_blacklist(gconstpointer data)
 
 fixture_setup(&fix, "-b guest-ping,guest-get-time", NULL);
 
-/* check blacklist */
+/* check blocked RPCs */
 ret = qmp_fd(fix.fd, "{'execute': 'guest-ping'}");
 g_assert_nonnull(ret);
 error = qdict_get_qdict(ret, "error");
@@ -968,7 +968,7 @@ int main(int argc, char **argv)
 g_test_add_data_func("/qga/fsfreeze-status", &fix,
  test_qga_fsfreeze_status);
 
-g_test_add_data_func("/qga/blacklist", NULL, test_qga_blacklist);
+g_test_add_data_func("/qga/blockedrpcs", NULL, test_qga_blockedrpcs);
 g_test_add_data_func("/qga/config", NULL, test_qga_config);
 g_test_add_data_func("/qga/guest-exec", &fix, test_qga_guest_exec);
 g_test_add_data_func("/qga/guest-exec-invalid", &fix,
-- 
2.31.1




[PULL 3/7] migration-test: Allow test to run without uffd

2022-08-01 Thread Thomas Huth
From: Peter Xu 

We used to stop running all tests if uffd is not detected.  However
logically that's only needed for postcopy not the rest of tests.

Keep running the rest when still possible.

Signed-off-by: Peter Xu 
Tested-by: Thomas Huth 
Message-Id: <20220728133516.92061-3-pet...@redhat.com>
Reviewed-by: Daniel P. Berrange 
Signed-off-by: Thomas Huth 
---
 tests/qtest/migration-test.c | 48 +++-
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index c1e002087d..10ab7a708c 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -2424,14 +2424,11 @@ int main(int argc, char **argv)
 {
 char template[] = "/tmp/migration-test-XX";
 const bool has_kvm = qtest_has_accel("kvm");
+const bool has_uffd = ufd_version_check();
 int ret;
 
 g_test_init(&argc, &argv, NULL);
 
-if (!ufd_version_check()) {
-return g_test_run();
-}
-
 /*
  * On ppc64, the test only works with kvm-hv, but not with kvm-pr and TCG
  * is touchy due to race conditions on dirty bits (especially on PPC for
@@ -2460,13 +2457,15 @@ int main(int argc, char **argv)
 
 module_call_init(MODULE_INIT_QOM);
 
-qtest_add_func("/migration/postcopy/unix", test_postcopy);
-qtest_add_func("/migration/postcopy/plain", test_postcopy);
-qtest_add_func("/migration/postcopy/recovery/plain",
-   test_postcopy_recovery);
-qtest_add_func("/migration/postcopy/preempt/plain", test_postcopy_preempt);
-qtest_add_func("/migration/postcopy/preempt/recovery/plain",
-test_postcopy_preempt_recovery);
+if (has_uffd) {
+qtest_add_func("/migration/postcopy/unix", test_postcopy);
+qtest_add_func("/migration/postcopy/plain", test_postcopy);
+qtest_add_func("/migration/postcopy/recovery/plain",
+   test_postcopy_recovery);
+qtest_add_func("/migration/postcopy/preempt/plain", 
test_postcopy_preempt);
+qtest_add_func("/migration/postcopy/preempt/recovery/plain",
+   test_postcopy_preempt_recovery);
+}
 
 qtest_add_func("/migration/bad_dest", test_baddest);
 qtest_add_func("/migration/precopy/unix/plain", test_precopy_unix_plain);
@@ -2474,18 +2473,21 @@ int main(int argc, char **argv)
 #ifdef CONFIG_GNUTLS
 qtest_add_func("/migration/precopy/unix/tls/psk",
test_precopy_unix_tls_psk);
-/*
- * NOTE: psk test is enough for postcopy, as other types of TLS
- * channels are tested under precopy.  Here what we want to test is the
- * general postcopy path that has TLS channel enabled.
- */
-qtest_add_func("/migration/postcopy/tls/psk", test_postcopy_tls_psk);
-qtest_add_func("/migration/postcopy/recovery/tls/psk",
-   test_postcopy_recovery_tls_psk);
-qtest_add_func("/migration/postcopy/preempt/tls/psk",
-   test_postcopy_preempt_tls_psk);
-qtest_add_func("/migration/postcopy/preempt/recovery/tls/psk",
-   test_postcopy_preempt_all);
+
+if (has_uffd) {
+/*
+ * NOTE: psk test is enough for postcopy, as other types of TLS
+ * channels are tested under precopy.  Here what we want to test is the
+ * general postcopy path that has TLS channel enabled.
+ */
+qtest_add_func("/migration/postcopy/tls/psk", test_postcopy_tls_psk);
+qtest_add_func("/migration/postcopy/recovery/tls/psk",
+   test_postcopy_recovery_tls_psk);
+qtest_add_func("/migration/postcopy/preempt/tls/psk",
+   test_postcopy_preempt_tls_psk);
+qtest_add_func("/migration/postcopy/preempt/recovery/tls/psk",
+   test_postcopy_preempt_all);
+}
 #ifdef CONFIG_TASN1
 qtest_add_func("/migration/precopy/unix/tls/x509/default-host",
test_precopy_unix_tls_x509_default_host);
-- 
2.31.1




[PULL 6/7] trivial: Fix duplicated words

2022-08-01 Thread Thomas Huth
Some files wrongly contain the same word twice in a row.
One of them should be removed or replaced.

Message-Id: <20220722145859.1952732-1-th...@redhat.com>
Signed-off-by: Thomas Huth 
---
 hw/arm/omap2.c| 2 +-
 hw/misc/mac_via.c | 2 +-
 target/arm/helper.c   | 2 +-
 ui/vdagent.c  | 2 +-
 tests/docker/dockerfiles/debian-native.docker | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index 02b1aa8c97..8571eedd73 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -274,7 +274,7 @@ static void omap_eac_format_update(struct omap_eac_s *s)
 fmt.freq = s->codec.rate;
 /* TODO: signedness possibly depends on the CODEC hardware - or
  * does I2S specify it?  */
-/* All register writes are 16 bits so we we store 16-bit samples
+/* All register writes are 16 bits so we store 16-bit samples
  * in the buffers regardless of AGCFR[B8_16] value.  */
 fmt.fmt = AUDIO_FORMAT_U16;
 
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index fba85a53d7..f42c12755a 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -587,7 +587,7 @@ static void adb_via_poll(void *opaque)
 /*
  * For older Linux kernels that switch to IDLE mode after sending the
  * ADB command, detect if there is an existing response and return that
- * as a a "fake" autopoll reply or bus timeout accordingly
+ * as a "fake" autopoll reply or bus timeout accordingly
  */
 *data = v1s->adb_data_out[0];
 olen = v1s->adb_data_in_size;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 1a8b06410e..e1bdc80c35 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3898,7 +3898,7 @@ static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] 
= {
 };
 
 static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
-/* We never have a a block transfer operation in progress */
+/* We never have a block transfer operation in progress */
 { .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4,
   .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
   .resetvalue = 0 },
diff --git a/ui/vdagent.c b/ui/vdagent.c
index aa6167f0b4..a899eed195 100644
--- a/ui/vdagent.c
+++ b/ui/vdagent.c
@@ -544,7 +544,7 @@ static void vdagent_clipboard_recv_grab(VDAgentChardev *vd, 
uint8_t s, uint32_t
 if (size > sizeof(uint32_t) * 10) {
 /*
  * spice has 6 types as of 2021. Limiting to 10 entries
- * so we we have some wiggle room.
+ * so we have some wiggle room.
  */
 return;
 }
diff --git a/tests/docker/dockerfiles/debian-native.docker 
b/tests/docker/dockerfiles/debian-native.docker
index efd55cb6e0..8dd033097c 100644
--- a/tests/docker/dockerfiles/debian-native.docker
+++ b/tests/docker/dockerfiles/debian-native.docker
@@ -1,7 +1,7 @@
 #
 # Docker Debian Native
 #
-# This this intended to build QEMU on native host systems. Debian is
+# This is intended to build QEMU on native host systems. Debian is
 # chosen due to the broadest range on supported host systems for QEMU.
 #
 # This docker target is based on the docker.io Debian Bullseye base
-- 
2.31.1




  1   2   >