[PATCH v8 3/5] vhost-user-scsi: support reconnect to backend

2023-10-08 Thread Li Feng
If the backend crashes and restarts, the device is broken.
This patch adds reconnect for vhost-user-scsi.

This patch also improves the error messages, and reports some silent errors.

Tested with spdk backend.

Signed-off-by: Li Feng 
---
 hw/scsi/vhost-scsi-common.c   |  16 +-
 hw/scsi/vhost-scsi.c  |   6 +-
 hw/scsi/vhost-user-scsi.c | 201 +++---
 include/hw/virtio/vhost-scsi-common.h |   2 +-
 include/hw/virtio/vhost-user-scsi.h   |   6 +
 5 files changed, 201 insertions(+), 30 deletions(-)

diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
index a61cd0e907..4c8637045d 100644
--- a/hw/scsi/vhost-scsi-common.c
+++ b/hw/scsi/vhost-scsi-common.c
@@ -16,6 +16,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
 #include "hw/virtio/vhost.h"
@@ -25,7 +26,7 @@
 #include "hw/virtio/virtio-access.h"
 #include "hw/fw-path-provider.h"
 
-int vhost_scsi_common_start(VHostSCSICommon *vsc)
+int vhost_scsi_common_start(VHostSCSICommon *vsc, Error **errp)
 {
 int ret, i;
 VirtIODevice *vdev = VIRTIO_DEVICE(vsc);
@@ -35,18 +36,19 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 VirtIOSCSICommon *vs = (VirtIOSCSICommon *)vsc;
 
 if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
+error_setg(errp, "binding does not support guest notifiers");
 return -ENOSYS;
 }
 
 ret = vhost_dev_enable_notifiers(>dev, vdev);
 if (ret < 0) {
+error_setg_errno(errp, -ret, "Error enabling host notifiers");
 return ret;
 }
 
 ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, true);
 if (ret < 0) {
-error_report("Error binding guest notifier");
+error_setg_errno(errp, -ret, "Error binding guest notifier");
 goto err_host_notifiers;
 }
 
@@ -54,7 +56,7 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 
 ret = vhost_dev_prepare_inflight(>dev, vdev);
 if (ret < 0) {
-error_report("Error setting inflight format: %d", -ret);
+error_setg_errno(errp, -ret, "Error setting inflight format");
 goto err_guest_notifiers;
 }
 
@@ -64,21 +66,21 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 vs->conf.virtqueue_size,
 vsc->inflight);
 if (ret < 0) {
-error_report("Error getting inflight: %d", -ret);
+error_setg_errno(errp, -ret, "Error getting inflight");
 goto err_guest_notifiers;
 }
 }
 
 ret = vhost_dev_set_inflight(>dev, vsc->inflight);
 if (ret < 0) {
-error_report("Error setting inflight: %d", -ret);
+error_setg_errno(errp, -ret, "Error setting inflight");
 goto err_guest_notifiers;
 }
 }
 
 ret = vhost_dev_start(>dev, vdev, true);
 if (ret < 0) {
-error_report("Error start vhost dev");
+error_setg_errno(errp, -ret, "Error starting vhost dev");
 goto err_guest_notifiers;
 }
 
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 443f67daa4..95cadb93e7 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -75,6 +75,7 @@ static int vhost_scsi_start(VHostSCSI *s)
 int ret, abi_version;
 VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
 const VhostOps *vhost_ops = vsc->dev.vhost_ops;
+Error *local_err = NULL;
 
 ret = vhost_ops->vhost_scsi_get_abi_version(>dev, _version);
 if (ret < 0) {
@@ -88,14 +89,15 @@ static int vhost_scsi_start(VHostSCSI *s)
 return -ENOSYS;
 }
 
-ret = vhost_scsi_common_start(vsc);
+ret = vhost_scsi_common_start(vsc, _err);
 if (ret < 0) {
+error_reportf_err(local_err, "Error starting vhost-scsi");
 return ret;
 }
 
 ret = vhost_scsi_set_endpoint(s);
 if (ret < 0) {
-error_report("Error setting vhost-scsi endpoint");
+error_reportf_err(local_err, "Error setting vhost-scsi endpoint");
 vhost_scsi_common_stop(vsc);
 }
 
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index df6b66cc1a..1e5d853cdd 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -39,26 +39,56 @@ static const int user_feature_bits[] = {
 VHOST_INVALID_FEATURE_BIT
 };
 
+static int vhost_user_scsi_start(VHostUserSCSI *s, Error **errp)
+{
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+int ret;
+
+ret = vhost_scsi_common_start(vsc, errp);
+s->started_vu = !(ret < 0);
+
+return ret;
+}
+
+static void vhost_user_scsi_stop(VHostUserSCSI *s)
+{
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+
+if (!s->started_vu) {
+return;
+}
+s->started_vu = false;
+
+vhost_scsi_common_stop(vsc);
+}
+
 static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status)
 {
 

[PATCH v8 5/5] vhost-user: fix lost reconnect

2023-10-08 Thread Li Feng
When the vhost-user is reconnecting to the backend, and if the vhost-user fails
at the get_features in vhost_dev_init(), then the reconnect will fail
and it will not be retriggered forever.

The reason is:
When the vhost-user fails at get_features, the vhost_dev_cleanup will be called
immediately.

vhost_dev_cleanup calls 'memset(hdev, 0, sizeof(struct vhost_dev))'.

The reconnect path is:
vhost_user_blk_event
   vhost_user_async_close(.. vhost_user_blk_disconnect ..)
 qemu_chr_fe_set_handlers <- clear the notifier callback
   schedule vhost_user_async_close_bh

The vhost->vdev is null, so the vhost_user_blk_disconnect will not be
called, then the event fd callback will not be reinstalled.

All vhost-user devices have this issue, including vhost-user-blk/scsi.

With this patch, if the vdev->vdev is null, the fd callback will still
be reinstalled.

Fixes: 71e076a07d ("hw/virtio: generalise CHR_EVENT_CLOSED handling")

Signed-off-by: Li Feng 
Reviewed-by: Raphael Norwitz 
---
 hw/block/vhost-user-blk.c  |  2 +-
 hw/scsi/vhost-user-scsi.c  |  3 ++-
 hw/virtio/vhost-user-gpio.c|  2 +-
 hw/virtio/vhost-user.c | 10 --
 include/hw/virtio/vhost-user.h |  3 ++-
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 3c69fa47d5..95c758200d 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -391,7 +391,7 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent 
event)
 case CHR_EVENT_CLOSED:
 /* defer close until later to avoid circular close */
 vhost_user_async_close(dev, >chardev, >dev,
-   vhost_user_blk_disconnect);
+   vhost_user_blk_disconnect, 
vhost_user_blk_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 2457b950e1..61e4050682 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -231,7 +231,8 @@ static void vhost_user_scsi_event(void *opaque, 
QEMUChrEvent event)
 case CHR_EVENT_CLOSED:
 /* defer close until later to avoid circular close */
 vhost_user_async_close(dev, >conf.chardev, >dev,
-   vhost_user_scsi_disconnect);
+   vhost_user_scsi_disconnect,
+   vhost_user_scsi_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index fc784e4213..aff2d7eff6 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -289,7 +289,7 @@ static void vu_gpio_event(void *opaque, QEMUChrEvent event)
 case CHR_EVENT_CLOSED:
 /* defer close until later to avoid circular close */
 vhost_user_async_close(dev, >chardev, >vhost_dev,
-   vu_gpio_disconnect);
+   vu_gpio_disconnect, vu_gpio_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 3766b415f8..7395bfc531 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -2765,6 +2765,7 @@ typedef struct {
 DeviceState *dev;
 CharBackend *cd;
 struct vhost_dev *vhost;
+IOEventHandler *event_cb;
 } VhostAsyncCallback;
 
 static void vhost_user_async_close_bh(void *opaque)
@@ -2779,7 +2780,10 @@ static void vhost_user_async_close_bh(void *opaque)
  */
 if (vhost->vdev) {
 data->cb(data->dev);
-}
+} else if (data->event_cb) {
+qemu_chr_fe_set_handlers(data->cd, NULL, NULL, data->event_cb,
+ NULL, data->dev, NULL, true);
+   }
 
 g_free(data);
 }
@@ -2791,7 +2795,8 @@ static void vhost_user_async_close_bh(void *opaque)
  */
 void vhost_user_async_close(DeviceState *d,
 CharBackend *chardev, struct vhost_dev *vhost,
-vu_async_close_fn cb)
+vu_async_close_fn cb,
+IOEventHandler *event_cb)
 {
 if (!runstate_check(RUN_STATE_SHUTDOWN)) {
 /*
@@ -2807,6 +2812,7 @@ void vhost_user_async_close(DeviceState *d,
 data->dev = d;
 data->cd = chardev;
 data->vhost = vhost;
+data->event_cb = event_cb;
 
 /* Disable any further notifications on the chardev */
 qemu_chr_fe_set_handlers(chardev,
diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h
index 9f9ddf878d..6b06ecb1bd 100644
--- a/include/hw/virtio/vhost-user.h
+++ b/include/hw/virtio/vhost-user.h
@@ -106,6 +106,7 @@ typedef void (*vu_async_close_fn)(DeviceState *cb);
 
 void vhost_user_async_close(DeviceState *d,
 CharBackend *chardev, struct vhost_dev *vhost,
-vu_async_close_fn cb);
+ 

[PATCH v8 1/5] vhost-user-common: send get_inflight_fd once

2023-10-08 Thread Li Feng
Currently the get_inflight_fd will be sent every time the device is started, and
the backend will allocate shared memory to save the inflight state. If the
backend finds that it receives the second get_inflight_fd, it will release the
previous shared memory, which breaks inflight working logic.

This patch is a preparation for the following patches.

Signed-off-by: Li Feng 
Reviewed-by: Raphael Norwitz 
---
 hw/scsi/vhost-scsi-common.c | 37 ++---
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
index a06f01af26..a61cd0e907 100644
--- a/hw/scsi/vhost-scsi-common.c
+++ b/hw/scsi/vhost-scsi-common.c
@@ -52,20 +52,28 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 
 vsc->dev.acked_features = vdev->guest_features;
 
-assert(vsc->inflight == NULL);
-vsc->inflight = g_new0(struct vhost_inflight, 1);
-ret = vhost_dev_get_inflight(>dev,
- vs->conf.virtqueue_size,
- vsc->inflight);
+ret = vhost_dev_prepare_inflight(>dev, vdev);
 if (ret < 0) {
-error_report("Error get inflight: %d", -ret);
+error_report("Error setting inflight format: %d", -ret);
 goto err_guest_notifiers;
 }
 
-ret = vhost_dev_set_inflight(>dev, vsc->inflight);
-if (ret < 0) {
-error_report("Error set inflight: %d", -ret);
-goto err_guest_notifiers;
+if (vsc->inflight) {
+if (!vsc->inflight->addr) {
+ret = vhost_dev_get_inflight(>dev,
+vs->conf.virtqueue_size,
+vsc->inflight);
+if (ret < 0) {
+error_report("Error getting inflight: %d", -ret);
+goto err_guest_notifiers;
+}
+}
+
+ret = vhost_dev_set_inflight(>dev, vsc->inflight);
+if (ret < 0) {
+error_report("Error setting inflight: %d", -ret);
+goto err_guest_notifiers;
+}
 }
 
 ret = vhost_dev_start(>dev, vdev, true);
@@ -85,9 +93,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 return ret;
 
 err_guest_notifiers:
-g_free(vsc->inflight);
-vsc->inflight = NULL;
-
 k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
 err_host_notifiers:
 vhost_dev_disable_notifiers(>dev, vdev);
@@ -111,12 +116,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
 }
 assert(ret >= 0);
 
-if (vsc->inflight) {
-vhost_dev_free_inflight(vsc->inflight);
-g_free(vsc->inflight);
-vsc->inflight = NULL;
-}
-
 vhost_dev_disable_notifiers(>dev, vdev);
 }
 
-- 
2.41.0




[PATCH v8 0/5] Implement reconnect for vhost-user-scsi

2023-10-08 Thread Li Feng
Changes for v8:
- [PATCH 3/5] vhost-user-scsi: support reconnect to backend
  - Fix code style suggested by Manos Pitsidianakis
- [PATCH 4/5] vhost-user-scsi: start vhost when guest kicks
  - Use 'DEVICE()' macro in vhost_user_scsi_handle_output to replace the
'parent_obj.parent_obj.parent_obj.parent_obj'.

Changes for v7:
- [PATCH 3/5] vhost-user-scsi: support reconnect to backend
  - Add reporting the error in vhost-scsi;
  - Rebase to master and fix the conflict.
- Add "Reviewed-by" tags.

Changes for v6:
- [PATCH] vhost-user: fix lost reconnect
  - Fix missing assign event_cb.

Changes for v5:
- No logic has been changed, just move part of the code from patch 4 to patch 5.

Changes for v4:
- Merge
  https://lore.kernel.org/all/20230830045722.611224-1-fen...@smartx.com/ to
  this series.
- Add ERRP_GUARD in vhost_user_scsi_realize;
- Reword the commit messages.

Changes for v3:
- Split the vhost_user_scsi_handle_output to a separate patch;
- Move the started_vu from vhost scsi common header to vhost-user-scsi header;
- Fix a log print error;

Changes for v2:
- Split the v1 patch to small separate patchset;
- New patch for fixing fd leak, which has sent to reviewers in another
  mail;
- Implement the `vhost_user_scsi_handle_output`;
- Add the started_vu safe check;
- Fix error handler;
- Check the inflight before set/get inflight fd.

Li Feng (5):
  vhost-user-common: send get_inflight_fd once
  vhost: move and rename the conn retry times
  vhost-user-scsi: support reconnect to backend
  vhost-user-scsi: start vhost when guest kicks
  vhost-user: fix lost reconnect

 hw/block/vhost-user-blk.c |   6 +-
 hw/scsi/vhost-scsi-common.c   |  47 ++---
 hw/scsi/vhost-scsi.c  |   6 +-
 hw/scsi/vhost-user-scsi.c | 250 +++---
 hw/virtio/vhost-user-gpio.c   |   5 +-
 hw/virtio/vhost-user.c|  10 +-
 include/hw/virtio/vhost-scsi-common.h |   2 +-
 include/hw/virtio/vhost-user-scsi.h   |   6 +
 include/hw/virtio/vhost-user.h|   3 +-
 include/hw/virtio/vhost.h |   2 +
 10 files changed, 277 insertions(+), 60 deletions(-)

-- 
2.41.0




[PATCH v8 4/5] vhost-user-scsi: start vhost when guest kicks

2023-10-08 Thread Li Feng
Let's keep the same behavior as vhost-user-blk.

Some old guests kick virtqueue before setting VIRTIO_CONFIG_S_DRIVER_OK.

Signed-off-by: Li Feng 
Reviewed-by: Raphael Norwitz 
---
 hw/scsi/vhost-user-scsi.c | 48 +++
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 1e5d853cdd..2457b950e1 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -111,8 +111,48 @@ static void vhost_user_scsi_reset(VirtIODevice *vdev)
 }
 }
 
-static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+static void vhost_user_scsi_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 {
+VHostUserSCSI *s = (VHostUserSCSI *)vdev;
+DeviceState *dev = DEVICE(vdev);
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
+
+Error *local_err = NULL;
+int i, ret;
+
+if (!vdev->start_on_kick) {
+return;
+}
+
+if (!s->connected) {
+return;
+}
+
+if (vhost_dev_is_started(>dev)) {
+return;
+}
+
+/*
+ * Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
+ * vhost here instead of waiting for .set_status().
+ */
+ret = vhost_user_scsi_start(s, _err);
+if (ret < 0) {
+error_reportf_err(local_err, "vhost-user-scsi: vhost start failed: ");
+qemu_chr_fe_disconnect(>conf.chardev);
+return;
+}
+
+/* Kick right away to begin processing requests already in vring */
+for (i = 0; i < vsc->dev.nvqs; i++) {
+VirtQueue *kick_vq = virtio_get_queue(vdev, i);
+
+if (!virtio_queue_get_desc_addr(vdev, i)) {
+continue;
+}
+event_notifier_set(virtio_queue_get_host_notifier(kick_vq));
+}
 }
 
 static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
@@ -239,9 +279,9 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-virtio_scsi_common_realize(dev, vhost_dummy_handle_output,
-   vhost_dummy_handle_output,
-   vhost_dummy_handle_output, );
+virtio_scsi_common_realize(dev, vhost_user_scsi_handle_output,
+   vhost_user_scsi_handle_output,
+   vhost_user_scsi_handle_output, );
 if (err != NULL) {
 error_propagate(errp, err);
 return;
-- 
2.41.0




[PATCH v8 2/5] vhost: move and rename the conn retry times

2023-10-08 Thread Li Feng
Multiple devices need this macro, move it to a common header.

Signed-off-by: Li Feng 
Reviewed-by: Raphael Norwitz 
---
 hw/block/vhost-user-blk.c   | 4 +---
 hw/virtio/vhost-user-gpio.c | 3 +--
 include/hw/virtio/vhost.h   | 2 ++
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index eecf3f7a81..3c69fa47d5 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -32,8 +32,6 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/runstate.h"
 
-#define REALIZE_CONNECTION_RETRIES 3
-
 static const int user_feature_bits[] = {
 VIRTIO_BLK_F_SIZE_MAX,
 VIRTIO_BLK_F_SEG_MAX,
@@ -482,7 +480,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, 
Error **errp)
 s->inflight = g_new0(struct vhost_inflight, 1);
 s->vhost_vqs = g_new0(struct vhost_virtqueue, s->num_queues);
 
-retries = REALIZE_CONNECTION_RETRIES;
+retries = VU_REALIZE_CONN_RETRIES;
 assert(!*errp);
 do {
 if (*errp) {
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index 3d7fae3984..fc784e4213 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -15,7 +15,6 @@
 #include "standard-headers/linux/virtio_ids.h"
 #include "trace.h"
 
-#define REALIZE_CONNECTION_RETRIES 3
 #define VHOST_NVQS 2
 
 /* Features required from VirtIO */
@@ -365,7 +364,7 @@ static void vu_gpio_device_realize(DeviceState *dev, Error 
**errp)
 qemu_chr_fe_set_handlers(>chardev, NULL, NULL, vu_gpio_event, NULL,
  dev, NULL, true);
 
-retries = REALIZE_CONNECTION_RETRIES;
+retries = VU_REALIZE_CONN_RETRIES;
 g_assert(!*errp);
 do {
 if (*errp) {
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 6a173cb9fa..ca3131b1af 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -8,6 +8,8 @@
 #define VHOST_F_DEVICE_IOTLB 63
 #define VHOST_USER_F_PROTOCOL_FEATURES 30
 
+#define VU_REALIZE_CONN_RETRIES 3
+
 /* Generic structures common for any vhost based device. */
 
 struct vhost_inflight {
-- 
2.41.0




Re: [PATCH v7 3/5] vhost-user-scsi: support reconnect to backend

2023-10-08 Thread Li Feng
Thanks for your comments, I will submit the v8.

> On 8 Oct 2023, at 6:46 PM, Manos Pitsidianakis 
>  wrote:
> 
> Hello Li, I have some trivial style comments you could possibly address in a 
> next version:
> 
> On Sun, 08 Oct 2023 12:12, Li Feng  wrote:
>> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
>> index df6b66cc1a..5df24faff4 100644
>> --- a/hw/scsi/vhost-user-scsi.c
>> +++ b/hw/scsi/vhost-user-scsi.c
>> @@ -39,26 +39,56 @@ static const int user_feature_bits[] = {
>>VHOST_INVALID_FEATURE_BIT
>> };
>> +static int vhost_user_scsi_start(VHostUserSCSI *s, Error **errp)
>> +{
>> +VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
>> +int ret;
>> +
>> +ret = vhost_scsi_common_start(vsc, errp);
>> +s->started_vu = (ret < 0 ? false : true);
> 
> -+s->started_vu = (ret < 0 ? false : true);
> ++s->started_vu = !(ret < 0);
> 
>> static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status)
>> {
>>VHostUserSCSI *s = (VHostUserSCSI *)vdev;
>> +DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;
> 
> -+DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;
> ++DeviceState *dev = DEVICE(vdev);
> 
>> +static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
>> +{
>> +VirtIODevice *vdev = VIRTIO_DEVICE(dev);
>> +VHostUserSCSI *s = VHOST_USER_SCSI(vdev);
>> +VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
>> +VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
>> +int ret = 0;
>> +
>> +if (s->connected) {
>> +return 0;
>> +}
>> +s->connected = true;
>> +
>> +vsc->dev.num_queues = vs->conf.num_queues;
>> +vsc->dev.nvqs = VIRTIO_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
>> +vsc->dev.vqs = s->vhost_vqs;
>> +vsc->dev.vq_index = 0;
>> +vsc->dev.backend_features = 0;
>> +
>> +ret = vhost_dev_init(>dev, >vhost_user, 
>> VHOST_BACKEND_TYPE_USER, 0,
>> + errp);
>> +if (ret < 0) {
>> +return ret;
>> +}
>> +
>> +/* restore vhost state */
>> +if (virtio_device_started(vdev, vdev->status)) {
>> +ret = vhost_user_scsi_start(s, errp);
>> +if (ret < 0) {
>> +return ret;
>> +}
>> +}
>> +
>> +return 0;
>> +}
> 
> 
> -+if (virtio_device_started(vdev, vdev->status)) {
> -+ret = vhost_user_scsi_start(s, errp);
> -+if (ret < 0) {
> -+return ret;
> -+}
> -+}
> -+
> -+return 0;
> -+}
> ++if (virtio_device_started(vdev, vdev->status)) {
> ++ret = vhost_user_scsi_start(s, errp);
> ++}
> ++
> ++return ret;
> ++}
> 
> [skipping..]
> 
>> +static int vhost_user_scsi_realize_connect(VHostUserSCSI *s, Error **errp)
>> +{
>> +DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;
> 
> 
> -+DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;
> ++DeviceState *dev = DEVICE(s);
> 
>> diff --git a/include/hw/virtio/vhost-user-scsi.h 
>> b/include/hw/virtio/vhost-user-scsi.h
>> index 521b08e559..b405ec952a 100644
>> --- a/include/hw/virtio/vhost-user-scsi.h
>> +++ b/include/hw/virtio/vhost-user-scsi.h
>> @@ -29,6 +29,10 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSCSI, VHOST_USER_SCSI)
>> struct VHostUserSCSI {
>>VHostSCSICommon parent_obj;
>>VhostUserState vhost_user;
>> +bool connected;
>> +bool started_vu;
>> +
>> +struct vhost_virtqueue *vhost_vqs;
> 
> +bool connected;
> +bool started_vu;
> -+
> +struct vhost_virtqueue *vhost_vqs;
> 
> See 
> https://www.qemu.org/docs/master/devel/style.html#qemu-object-model-declarations
> 
> The definition should look like:
> 
> struct VHostUserSCSI {
>   VHostSCSICommon parent_obj;
> 
>   /* Properties */
>   bool connected;
>   bool started_vu;
> 
>   VhostUserState vhost_user;
>   struct vhost_virtqueue *vhost_vqs;
> }




Re: [PATCH 2/2] target/riscv/tcg-cpu.c: add extension properties for all cpus

2023-10-08 Thread Alistair Francis
On Fri, Sep 29, 2023 at 8:39 PM Daniel P. Berrangé  wrote:
>
> On Tue, Sep 26, 2023 at 03:31:09PM -0300, Daniel Henrique Barboza wrote:
> > At this moment we do not expose extension properties for vendor CPUs
> > because that would allow users to change them via command line. The
> > drawback is that if we were to add an API that shows all CPU properties,
> > e.g. qmp-query-cpu-model-expansion, we won't be able to show extensions
> > state of vendor CPUs.
> >
> > We have the required machinery to create extension properties for vendor
> > CPUs while not allowing users to enable extensions. Disabling existing
> > extensions is allowed since it can be useful for debugging.
> >
> > Change the set() callback cpu_set_multi_ext_cfg() to allow enabling
> > extensions only for generic CPUs. In cpu_add_multi_ext_prop() let's not
> > set the default values for the properties if we're not dealing with
> > generic CPUs, otherwise the values set in cpu_init() of vendor CPUs will
> > be overwritten. And finally, in tcg_cpu_instance_init(), add cpu user
> > properties for all CPUs.
> >
> > For the veyron-v1 CPU, we're now able to disable existing extensions
> > like smstateen:
> >
> > $ ./build/qemu-system-riscv64 --nographic -M virt \
> > -cpu veyron-v1,smstateen=false
> >
> > But setting extensions that the CPU didn't set during cpu_init(), like
> > V, is not allowed:
> >
> > $ ./build/qemu-system-riscv64 --nographic -M virt \
> > -cpu veyron-v1,v=true
> > qemu-system-riscv64: can't apply global veyron-v1-riscv-cpu.v=true:
> >   'veyron-v1' CPU does not allow enabling extensions
>
> Why should we block the user if they want to enable an extra
> feature, over and above what is built-in to the CPU model ?

It ends up being tricky to maintain. On top of that we can report a
specific vendor CPU to guests, but then we don't correctly model it
(as extensions might be disabled).

Alistair

> Is there some technical reason that prevents this from working ?
>
> 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 0/6] riscv: RVA22U64 profile support

2023-10-08 Thread Alistair Francis
On Fri, Sep 29, 2023 at 10:54 PM Daniel P. Berrangé  wrote:
>
> On Fri, Sep 29, 2023 at 09:49:47AM -0300, Daniel Henrique Barboza wrote:
> >
> >
> > On 9/29/23 08:55, Daniel P. Berrangé wrote:
> > > On Fri, Sep 29, 2023 at 08:29:08AM -0300, Daniel Henrique Barboza wrote:
> > > >
> > > >
> > > > On 9/29/23 07:46, Daniel P. Berrangé wrote:
> > > > > On Tue, Sep 26, 2023 at 04:49:44PM -0300, Daniel Henrique Barboza 
> > > > > wrote:
> > > > > > Based-on: 20230926183109.165878-1-dbarb...@ventanamicro.com
> > > > > > ("[PATCH 0/2] riscv: add extension properties for all cpus")
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > These patches implements the base profile support for qemu-riscv 
> > > > > > and the
> > > > > > first profile, RVA22U64.
> > > > > >
> > > > > > As discussed in this thread [1] we're aiming for a flag that 
> > > > > > enables all
> > > > > > mandatory extensions of a profile. Optional extensions were left 
> > > > > > behind
> > > > > > and must be enabled by hand if desired. Since this is the first 
> > > > > > profile
> > > > > > we're adding, we'll need to add the base framework as well.
> > > > > >
> > > > > > The RVA22U64 profile was chosen because qemu-riscv implements all 
> > > > > > its
> > > > > > extensions, both mandatory and optional. That includes 'zicntr' and
> > > > > > 'zihpm', which we support for awhile but aren't adverting to 
> > > > > > userspace.
> > > > > >
> > > > > > Other design decisions made:
> > > > > >
> > > > > > - disabling a profile flag does nothing, i.e. we won't mass disable
> > > > > > mandatory extensions of the rva22U64 profile if the user sets
> > > > > > rva22u64=false;
> > > > >
> > > > > Why shouldn't this be allowed ?
> > > > >
> > > > > IIUC, a profile is syntactic sugar for a group of features. If
> > > > > we can disable individual features explicitly, why should we
> > > > > not allow use of the profile as sugar to disable them en-mass ?
> > > >
> > > > In theory there's no harm in allowing mass disabling of extensions but, 
> > > > given
> > > > it's a whole profile, we would end up disabling most/all CPU extensions 
> > > > and
> > > > the guest would do nothing.
> > >
> > > True, that is just user error though.  They could disable a profile
> > > and then manually re-enable individual features, and thus get a
> > > working system.
> > >
> > > > There is a thread in the ML:
> > > >
> > > > https://lore.kernel.org/qemu-riscv/cabjz62nyvnu4z1qmcg7myjkgg_9ywxjufhhwjmoqep6unrr...@mail.gmail.com/
> > > >
> > > > Where we discussed the possibility of having a minimal CPU extension 
> > > > set. We didn't
> > > > reach a consensus because the definition of "minimal CPU extension set" 
> > > > vary between
> > > > OSes (Linux requires IMAFD, FreeBSD might require something differ).
> > > >
> > > > Assuming we reach a consensus on what a minimal set is, we could allow 
> > > > disabling mass
> > > > extensions via probile but keeping this minimal set, for example. At 
> > > > very least we
> > > > shouldn't allow users to disable 'I' because that would kill the CPU, 
> > > > so RV64I is
> > > > the minimum set that I would assume for now.
> > >
> > > I'd probably just call that user error too.
> > >
> > > > >
> > > > > TL;DR: feature groups are pretty error prone if more than
> > > > > one is listed by the user, or they're combined with individual
> > > > > features.
> > > > >
> > > > > >
> > > > > > - profile support for vendor CPUs consists into checking if the CPU
> > > > > > happens to have the mandatory extensions required for it. In 
> > > > > > case it
> > > > > > doesn't we'll error out. This is done to follow the same 
> > > > > > prerogative
> > > > > > we always had of not allowing extensions being enabled for 
> > > > > > vendor
> > > > > > CPUs;
> > > > >
> > > > > Why shouldn't this be allowed ?
> > > >
> > > > There's no technical reason to not allow it. The reason it's forbid is 
> > > > to be
> > > > closer to what the real hardware would do. E.g. the real hardware 
> > > > doesn't allow
> > > > users to enable Vector if the hardware doesn't support it. Vendor CPUs 
> > > > also has
> > > > a privileged spec restriction as well, so if a CPU is running in an 
> > > > older spec
> > > > it can't enable extensions that were added later.
> > >
> > > Real hardware is constrained in not being able to invent arbitrary
> > > new features on chip. Virtual machines  are not constrained, so
> > > I don't think the inability of hardware todo this, is an especially
> > > strong reason to limit software emulation.

I think exposing flexibility in vendor CPUs just creates confusion.

As a user if I start QEMU with "-cpu company-cpu" then I am expecting
to get an emulation of company-cpu.

> > >
> > > What I don't like about this, is that (IIUC) the '$profile=on' option
> > > now has different semantics depending on what CPU it is used with.
> > >
> > > ie  using it with a vendor CPU,   $profile=on  becomes an 

[PATCH 1/3] vfio/pci: Fix a potential memory leak in vfio_listener_region_add

2023-10-08 Thread Zhenzhong Duan
When there is an failure in vfio_listener_region_add() and the section
belongs to a ram device, there is an inaccurate error report which should
never be related to vfio_dma_map failure. The memory holding err is also
incrementally leaked in each failure.

Fix it by reporting the real error and free it.

Fixes: 567b5b309ab ("vfio/pci: Relax DMA map errors for MMIO regions")
Signed-off-by: Zhenzhong Duan 
---
 hw/vfio/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 9e61de03ee..5ff5acf1d8 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -763,7 +763,7 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
 
 fail:
 if (memory_region_is_ram_device(section->mr)) {
-error_report("failed to vfio_dma_map. pci p2p may not work");
+error_reportf_err(err, "PCI p2p may not work: ");
 return;
 }
 /*
-- 
2.34.1




[PATCH 2/3] vfio/ap: Remove pointless apdev variable

2023-10-08 Thread Zhenzhong Duan
No need to double-cast, call VFIO_AP_DEVICE() on DeviceState.

No functional changes.

Signed-off-by: Zhenzhong Duan 
---
 hw/vfio/ap.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c
index 22e564f4f7..e083a19eac 100644
--- a/hw/vfio/ap.c
+++ b/hw/vfio/ap.c
@@ -156,8 +156,7 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
 {
 int ret;
 Error *err = NULL;
-APDevice *apdev = AP_DEVICE(dev);
-VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev);
+VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
 VFIODevice *vbasedev = >vdev;
 
 vbasedev->name = g_path_get_basename(vbasedev->sysfsdev);
@@ -195,8 +194,7 @@ error:
 
 static void vfio_ap_unrealize(DeviceState *dev)
 {
-APDevice *apdev = AP_DEVICE(dev);
-VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev);
+VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
 
 vfio_ap_unregister_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX);
 vfio_detach_device(>vdev);
@@ -211,8 +209,7 @@ static Property vfio_ap_properties[] = {
 static void vfio_ap_reset(DeviceState *dev)
 {
 int ret;
-APDevice *apdev = AP_DEVICE(dev);
-VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev);
+VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
 
 ret = ioctl(vapdev->vdev.fd, VFIO_DEVICE_RESET);
 if (ret) {
-- 
2.34.1




[PATCH 3/3] vfio/ccw: Remove redundant definition of TYPE_VFIO_CCW

2023-10-08 Thread Zhenzhong Duan
No functional changes.

Signed-off-by: Zhenzhong Duan 
---
 include/hw/s390x/vfio-ccw.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h
index 63a909eb7e..4209d27657 100644
--- a/include/hw/s390x/vfio-ccw.h
+++ b/include/hw/s390x/vfio-ccw.h
@@ -22,6 +22,4 @@
 #define TYPE_VFIO_CCW "vfio-ccw"
 OBJECT_DECLARE_SIMPLE_TYPE(VFIOCCWDevice, VFIO_CCW)
 
-#define TYPE_VFIO_CCW "vfio-ccw"
-
 #endif
-- 
2.34.1




[PATCH 0/3] vfio: memory leak fix and code cleanup

2023-10-08 Thread Zhenzhong Duan
Hi,

This trivial patchset fixes a incremental memory leak in rare case,
and some cleanup on ap/ccw.

This patchset is based on vfio-next.

Thanks
Zhenzhong

Zhenzhong Duan (3):
  vfio/pci: Fix a potential memory leak in vfio_listener_region_add
  vfio/ap: Remove pointless apdev variable
  vfio/ccw: Remove redundant definition of TYPE_VFIO_CCW

 hw/vfio/ap.c| 9 +++--
 hw/vfio/common.c| 2 +-
 include/hw/s390x/vfio-ccw.h | 2 --
 3 files changed, 4 insertions(+), 9 deletions(-)

-- 
2.34.1




Re: [PATCH] target/riscv: deprecate capital 'Z' CPU properties

2023-10-08 Thread Alistair Francis
On Sun, Oct 8, 2023 at 3:15 AM Daniel Henrique Barboza
 wrote:
>
> At this moment there are eleven CPU extension properties that starts
> with capital 'Z': Zifencei, Zicsr, Zihintntl, Zihintpause, Zawrs, Zfa,
> Zfh, Zfhmin, Zve32f, Zve64f and Zve64d. All other extensions are named
> with lower-case letters.
>
> We want all properties to be named with lower-case letters since it's
> consistent with the riscv-isa string that we create in the FDT. Having
> these 11 properties to be exceptions can be confusing.
>
> Deprecate all of them. Create their lower-case counterpart to be used as
> maintained CPU properties. When trying to use any deprecated property a
> warning message will be displayed, recommending users to switch to the
> lower-case variant:
>
> ./build/qemu-system-riscv64 -M virt -cpu rv64,Zifencei=true --nographic
> qemu-system-riscv64: warning: CPU property 'Zifencei' is deprecated. Please 
> use 'zifencei' instead
>
> This will give users some time to change their scripts before we remove
> the capital 'Z' properties entirely.
>
> Signed-off-by: Daniel Henrique Barboza 

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  docs/about/deprecated.rst  | 23 ++
>  target/riscv/cpu.c | 39 +++---
>  target/riscv/cpu.h |  1 +
>  target/riscv/tcg/tcg-cpu.c | 31 +-
>  4 files changed, 82 insertions(+), 12 deletions(-)
>
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 694b878f36..331f10f930 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -378,6 +378,29 @@ of generic CPUs: rv32 and rv64 as default CPUs and 'max' 
> as a feature complete
>  CPU for both 32 and 64 bit builds. Users are then discouraged to use the 
> 'any'
>  CPU type starting in 8.2.
>
> +RISC-V CPU properties which start with with capital 'Z' (since 8.2)
> +^^
> +
> +All RISC-V CPU properties which start with capital 'Z' are being deprecated
> +starting in 8.2. The reason is that they were wrongly added with capital 'Z'
> +in the past. CPU properties were later added with lower-case names, which
> +is the format we want to use from now on.
> +
> +Users which try to use these deprecated properties will receive a warning
> +recommending to switch to their stable counterparts:
> +
> +- "Zifencei" should be replaced with "zifencei"
> +- "Zicsr" should be replaced with "zicsr"
> +- "Zihintntl" should be replaced with "zihintntl"
> +- "Zihintpause" should be replaced with "zihintpause"
> +- "Zawrs" should be replaced with "zawrs"
> +- "Zfa" should be replaced with "zfa"
> +- "Zfh" should be replaced with "zfh"
> +- "Zfhmin" should be replaced with "zfhmin"
> +- "Zve32f" should be replaced with "zve32f"
> +- "Zve64f" should be replaced with "zve64f"
> +- "Zve64d" should be replaced with "zve64d"
> +
>  Block device options
>  
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 521bb88538..1cdc3d2609 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1246,17 +1246,17 @@ const char *riscv_get_misa_ext_description(uint32_t 
> bit)
>  const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
>  /* Defaults for standard extensions */
>  MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
> -MULTI_EXT_CFG_BOOL("Zifencei", ext_ifencei, true),
> -MULTI_EXT_CFG_BOOL("Zicsr", ext_icsr, true),
> -MULTI_EXT_CFG_BOOL("Zihintntl", ext_zihintntl, true),
> -MULTI_EXT_CFG_BOOL("Zihintpause", ext_zihintpause, true),
> -MULTI_EXT_CFG_BOOL("Zawrs", ext_zawrs, true),
> -MULTI_EXT_CFG_BOOL("Zfa", ext_zfa, true),
> -MULTI_EXT_CFG_BOOL("Zfh", ext_zfh, false),
> -MULTI_EXT_CFG_BOOL("Zfhmin", ext_zfhmin, false),
> -MULTI_EXT_CFG_BOOL("Zve32f", ext_zve32f, false),
> -MULTI_EXT_CFG_BOOL("Zve64f", ext_zve64f, false),
> -MULTI_EXT_CFG_BOOL("Zve64d", ext_zve64d, false),
> +MULTI_EXT_CFG_BOOL("zifencei", ext_ifencei, true),
> +MULTI_EXT_CFG_BOOL("zicsr", ext_icsr, true),
> +MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
> +MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
> +MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
> +MULTI_EXT_CFG_BOOL("zfa", ext_zfa, true),
> +MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
> +MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
> +MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
> +MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
> +MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
>  MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
>
>  MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
> @@ -1349,6 +1349,23 @@ const RISCVCPUMultiExtConfig 
> riscv_cpu_experimental_exts[] = {
>  DEFINE_PROP_END_OF_LIST(),
>  };
>
> +/* Deprecated entries marked for future removal */
> +const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = {
> +

Re: [PATCH] target/riscv: deprecate capital 'Z' CPU properties

2023-10-08 Thread Alistair Francis
On Sun, Oct 8, 2023 at 3:15 AM Daniel Henrique Barboza
 wrote:
>
> At this moment there are eleven CPU extension properties that starts
> with capital 'Z': Zifencei, Zicsr, Zihintntl, Zihintpause, Zawrs, Zfa,
> Zfh, Zfhmin, Zve32f, Zve64f and Zve64d. All other extensions are named
> with lower-case letters.
>
> We want all properties to be named with lower-case letters since it's
> consistent with the riscv-isa string that we create in the FDT. Having
> these 11 properties to be exceptions can be confusing.
>
> Deprecate all of them. Create their lower-case counterpart to be used as
> maintained CPU properties. When trying to use any deprecated property a
> warning message will be displayed, recommending users to switch to the
> lower-case variant:
>
> ./build/qemu-system-riscv64 -M virt -cpu rv64,Zifencei=true --nographic
> qemu-system-riscv64: warning: CPU property 'Zifencei' is deprecated. Please 
> use 'zifencei' instead
>
> This will give users some time to change their scripts before we remove
> the capital 'Z' properties entirely.
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  docs/about/deprecated.rst  | 23 ++
>  target/riscv/cpu.c | 39 +++---
>  target/riscv/cpu.h |  1 +
>  target/riscv/tcg/tcg-cpu.c | 31 +-
>  4 files changed, 82 insertions(+), 12 deletions(-)
>
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 694b878f36..331f10f930 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -378,6 +378,29 @@ of generic CPUs: rv32 and rv64 as default CPUs and 'max' 
> as a feature complete
>  CPU for both 32 and 64 bit builds. Users are then discouraged to use the 
> 'any'
>  CPU type starting in 8.2.
>
> +RISC-V CPU properties which start with with capital 'Z' (since 8.2)
> +^^
> +
> +All RISC-V CPU properties which start with capital 'Z' are being deprecated
> +starting in 8.2. The reason is that they were wrongly added with capital 'Z'
> +in the past. CPU properties were later added with lower-case names, which
> +is the format we want to use from now on.
> +
> +Users which try to use these deprecated properties will receive a warning
> +recommending to switch to their stable counterparts:
> +
> +- "Zifencei" should be replaced with "zifencei"
> +- "Zicsr" should be replaced with "zicsr"
> +- "Zihintntl" should be replaced with "zihintntl"
> +- "Zihintpause" should be replaced with "zihintpause"
> +- "Zawrs" should be replaced with "zawrs"
> +- "Zfa" should be replaced with "zfa"
> +- "Zfh" should be replaced with "zfh"
> +- "Zfhmin" should be replaced with "zfhmin"
> +- "Zve32f" should be replaced with "zve32f"
> +- "Zve64f" should be replaced with "zve64f"
> +- "Zve64d" should be replaced with "zve64d"
> +
>  Block device options
>  
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 521bb88538..1cdc3d2609 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1246,17 +1246,17 @@ const char *riscv_get_misa_ext_description(uint32_t 
> bit)
>  const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
>  /* Defaults for standard extensions */
>  MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
> -MULTI_EXT_CFG_BOOL("Zifencei", ext_ifencei, true),
> -MULTI_EXT_CFG_BOOL("Zicsr", ext_icsr, true),
> -MULTI_EXT_CFG_BOOL("Zihintntl", ext_zihintntl, true),
> -MULTI_EXT_CFG_BOOL("Zihintpause", ext_zihintpause, true),
> -MULTI_EXT_CFG_BOOL("Zawrs", ext_zawrs, true),
> -MULTI_EXT_CFG_BOOL("Zfa", ext_zfa, true),
> -MULTI_EXT_CFG_BOOL("Zfh", ext_zfh, false),
> -MULTI_EXT_CFG_BOOL("Zfhmin", ext_zfhmin, false),
> -MULTI_EXT_CFG_BOOL("Zve32f", ext_zve32f, false),
> -MULTI_EXT_CFG_BOOL("Zve64f", ext_zve64f, false),
> -MULTI_EXT_CFG_BOOL("Zve64d", ext_zve64d, false),
> +MULTI_EXT_CFG_BOOL("zifencei", ext_ifencei, true),
> +MULTI_EXT_CFG_BOOL("zicsr", ext_icsr, true),
> +MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
> +MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true),
> +MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true),
> +MULTI_EXT_CFG_BOOL("zfa", ext_zfa, true),
> +MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
> +MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
> +MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
> +MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
> +MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
>  MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
>
>  MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
> @@ -1349,6 +1349,23 @@ const RISCVCPUMultiExtConfig 
> riscv_cpu_experimental_exts[] = {
>  DEFINE_PROP_END_OF_LIST(),
>  };
>
> +/* Deprecated entries marked for future removal */
> +const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = {
> +MULTI_EXT_CFG_BOOL("Zifencei", 

Re: [PATCH v2] target/riscv: pmp: Ignore writes when RW=01

2023-10-08 Thread Alistair Francis
On Mon, Sep 25, 2023 at 9:11 PM Mayuresh Chitale
 wrote:
>
> As per the Priv spec: "The R, W, and X fields form a collective WARL
> field for which the combinations with R=0 and W=1 are reserved."
> However currently such writes are not ignored as ought to be. The
> combinations with RW=01 are allowed only when the Smepmp extension
> is enabled and mseccfg.MML is set.
>
> Signed-off-by: Mayuresh Chitale 

Do you mind rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next

Alistair

> ---
>  target/riscv/pmp.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 5b14eb511a..8e25f145e0 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -120,6 +120,11 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t 
> pmp_index, uint8_t val)
>  if (locked) {
>  qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - 
> locked\n");
>  } else {
> +/* If !mseccfg.MML then ignore writes with encoding RW=01 */
> +if ((val & PMP_WRITE) && !(val & PMP_READ) &&
> +!MSECCFG_MML_ISSET(env)) {
> +val &= ~(PMP_WRITE | PMP_READ);
> +}
>  env->pmp_state.pmp[pmp_index].cfg_reg = val;
>  pmp_update_rule(env, pmp_index);
>  }
> --
> 2.34.1
>
>



RE: [PATCH v4 10/15] vfio/ccw: Use vfio_[attach/detach]_device

2023-10-08 Thread Duan, Zhenzhong


>-Original Message-
>From: Eric Auger 
>Sent: Monday, October 9, 2023 1:46 AM
>Subject: Re: [PATCH v4 10/15] vfio/ccw: Use vfio_[attach/detach]_device
>
>Hi Zhenzhong,
>On 10/8/23 12:21, Duan, Zhenzhong wrote:
>> Hi Eric,
>>
>>> -Original Message-
>>> From: Eric Auger 
>>> Sent: Wednesday, October 4, 2023 11:44 PM
>>> Subject: [PATCH v4 10/15] vfio/ccw: Use vfio_[attach/detach]_device
>>>
>>> Let the vfio-ccw device use vfio_attach_device() and
>>> vfio_detach_device(), hence hiding the details of the used
>>> IOMMU backend.
>>>
>>> Note that the migration reduces the following trace
>>> "vfio: subchannel %s has already been attached" (featuring
>>> cssid.ssid.devid) into "device is already attached"
>>>
>>> Also now all the devices have been migrated to use the new
>>> vfio_attach_device/vfio_detach_device API, let's turn the
>>> legacy functions into static functions, local to container.c.
>>>
>>> Signed-off-by: Eric Auger 
>>> Signed-off-by: Yi Liu 
>>> Signed-off-by: Zhenzhong Duan 
>>> Reviewed-by: Matthew Rosato 
>>>
>>> ---
>>>
>>> v3:
>>> - simplified vbasedev->dev setting
>>>
>>> v2 -> v3:
>>> - Hopefully fix confusion beteen vbasedev->name, mdevid and sysfsdev
>>>  while keeping into account Matthew's comment
>>>  https://lore.kernel.org/qemu-devel/6e04ab8f-dc84-e9c2-deea-
>>> 2b6b31678...@linux.ibm.com/
>>> ---
>>> include/hw/vfio/vfio-common.h |   5 --
>>> hw/vfio/ccw.c | 122 +-
>>> hw/vfio/common.c  |  10 +--
>>> 3 files changed, 37 insertions(+), 100 deletions(-)
>>>
>>> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
>>> index 12fbfbc37d..c486bdef2a 100644
>>> --- a/include/hw/vfio/vfio-common.h
>>> +++ b/include/hw/vfio/vfio-common.h
>>> @@ -202,7 +202,6 @@ typedef struct {
>>> hwaddr pages;
>>> } VFIOBitmap;
>>>
>>> -void vfio_put_base_device(VFIODevice *vbasedev);
>>> void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
>>> void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
>>> void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
>>> @@ -220,11 +219,7 @@ void vfio_region_unmap(VFIORegion *region);
>>> void vfio_region_exit(VFIORegion *region);
>>> void vfio_region_finalize(VFIORegion *region);
>>> void vfio_reset_handler(void *opaque);
>>> -VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp);
>>> -void vfio_put_group(VFIOGroup *group);
>>> struct vfio_device_info *vfio_get_device_info(int fd);
>>> -int vfio_get_device(VFIOGroup *group, const char *name,
>>> -VFIODevice *vbasedev, Error **errp);
>>> int vfio_attach_device(char *name, VFIODevice *vbasedev,
>>>AddressSpace *as, Error **errp);
>>> void vfio_detach_device(VFIODevice *vbasedev);
>>> diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
>>> index 1e2fce83b0..6ec35fedc9 100644
>>> --- a/hw/vfio/ccw.c
>>> +++ b/hw/vfio/ccw.c
>>> @@ -572,88 +572,15 @@ static void vfio_ccw_put_region(VFIOCCWDevice
>>> *vcdev)
>>> g_free(vcdev->io_region);
>>> }
>>>
>>> -static void vfio_ccw_put_device(VFIOCCWDevice *vcdev)
>>> -{
>>> -g_free(vcdev->vdev.name);
>>> -vfio_put_base_device(>vdev);
>>> -}
>>> -
>>> -static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev,
>>> -Error **errp)
>>> -{
>>> -S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
>>> -char *name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
>>> - cdev->hostid.ssid,
>>> - cdev->hostid.devid);
>>> -VFIODevice *vbasedev;
>>> -
>>> -QLIST_FOREACH(vbasedev, >device_list, next) {
>>> -if (strcmp(vbasedev->name, name) == 0) {
>>> -error_setg(errp, "vfio: subchannel %s has already been 
>>> attached",
>>> -   name);
>>> -goto out_err;
>>> -}
>>> -}
>>> -
>>> -/*
>>> - * All vfio-ccw devices are believed to operate in a way compatible 
>>> with
>>> - * discarding of memory in RAM blocks, ie. pages pinned in the host are
>>> - * in the current working set of the guest driver and therefore never
>>> - * overlap e.g., with pages available to the guest balloon driver.  
>>> This
>>> - * needs to be set before vfio_get_device() for vfio common to handle
>>> - * ram_block_discard_disable().
>>> - */
>>> -vcdev->vdev.ram_block_discard_allowed = true;
>>> -
>>> -if (vfio_get_device(group, cdev->mdevid, >vdev, errp)) {
>>> -goto out_err;
>>> -}
>>> -
>>> -vcdev->vdev.ops = _ccw_ops;
>>> -vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
>>> -vcdev->vdev.name = name;
>>> -vcdev->vdev.dev = DEVICE(vcdev);
>>> -
>>> -return;
>>> -
>>> -out_err:
>>> -g_free(name);
>>> -}
>>> -
>>> -static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, Error **errp)
>>> -{
>>> -char *tmp, group_path[PATH_MAX];
>>> -ssize_t len;
>>> -int groupid;

Re: [PATCH v2] target/riscv: pmp: Ignore writes when RW=01

2023-10-08 Thread Alistair Francis
On Mon, Sep 25, 2023 at 9:11 PM Mayuresh Chitale
 wrote:
>
> As per the Priv spec: "The R, W, and X fields form a collective WARL
> field for which the combinations with R=0 and W=1 are reserved."
> However currently such writes are not ignored as ought to be. The
> combinations with RW=01 are allowed only when the Smepmp extension
> is enabled and mseccfg.MML is set.
>
> Signed-off-by: Mayuresh Chitale 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/pmp.c | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 5b14eb511a..8e25f145e0 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -120,6 +120,11 @@ static void pmp_write_cfg(CPURISCVState *env, uint32_t 
> pmp_index, uint8_t val)
>  if (locked) {
>  qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - 
> locked\n");
>  } else {
> +/* If !mseccfg.MML then ignore writes with encoding RW=01 */
> +if ((val & PMP_WRITE) && !(val & PMP_READ) &&
> +!MSECCFG_MML_ISSET(env)) {
> +val &= ~(PMP_WRITE | PMP_READ);
> +}
>  env->pmp_state.pmp[pmp_index].cfg_reg = val;
>  pmp_update_rule(env, pmp_index);
>  }
> --
> 2.34.1
>
>



Re: [PATCH v3 4/5] hw/char: riscv_htif: replace exit calls with proper shutdown

2023-10-08 Thread Alistair Francis
On Mon, Oct 2, 2023 at 7:32 PM Clément Chigot  wrote:
>
> On Fri, Sep 22, 2023 at 7:20 AM Alistair Francis  wrote:
> >
> > On Thu, Sep 7, 2023 at 9:26 PM Clément Chigot  wrote:
> > >
> > > This replaces the exit calls by shutdown requests, ensuring a proper
> > > cleanup of Qemu. Otherwise, some connections like gdb could be broken
> > > before its final packet ("Wxx") is being sent. This part, being done
> > > inside qemu_cleanup function, can be reached only when the main loop
> > > exits after a shutdown request.
> > >
> > > Signed-off-by: Clément Chigot 
> >
> > Do you mind rebasing this on:
> > https://github.com/alistair23/qemu/tree/riscv-to-apply.next
>
> Thanks for the review.
> Just a quick question on the procedure side, is there any special tag
> or something to say in the cover letter to state that it has been
> rebased on riscv-to-apply instead of the usual master?

You can use the "Based-on" tag. There is some more details here:

https://www.qemu.org/docs/master/devel/submitting-a-patch.html#id33

Alistair

>
> Clément
>
> > Alistair
> >
> > > ---
> > >  hw/char/riscv_htif.c | 5 -
> > >  1 file changed, 4 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
> > > index 37d3ccc76b..7e9b6fcc98 100644
> > > --- a/hw/char/riscv_htif.c
> > > +++ b/hw/char/riscv_htif.c
> > > @@ -31,6 +31,7 @@
> > >  #include "qemu/error-report.h"
> > >  #include "exec/address-spaces.h"
> > >  #include "sysemu/dma.h"
> > > +#include "sysemu/runstate.h"
> > >
> > >  #define RISCV_DEBUG_HTIF 0
> > >  #define HTIF_DEBUG(fmt, ...) 
> > >   \
> > > @@ -205,7 +206,9 @@ static void htif_handle_tohost_write(HTIFState *s, 
> > > uint64_t val_written)
> > >  g_free(sig_data);
> > >  }
> > >
> > > -exit(exit_code);
> > > +qemu_system_shutdown_request_with_code(
> > > +SHUTDOWN_CAUSE_GUEST_SHUTDOWN, exit_code);
> > > +return;
> > >  } else {
> > >  uint64_t syscall[8];
> > >  cpu_physical_memory_read(payload, syscall, 
> > > sizeof(syscall));
> > > --
> > > 2.25.1
> > >



Re: [PATCH] target/riscv/tcg: remove RVG warning

2023-10-08 Thread Alistair Francis
On Tue, Oct 3, 2023 at 10:26 PM Daniel Henrique Barboza
 wrote:
>
> Vendor CPUs that set RVG are displaying user warnings about other
> extensions that RVG must enable, one warning per CPU. E.g.:
>
> $ ./build/qemu-system-riscv64 -smp 8 -M virt -cpu veyron-v1 -nographic
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
>
> This happens because we decided a while ago that, for simplicity, vendor
> CPUs could set RVG instead of setting each G extension individually in
> their cpu_init(). Our warning isn't taking that into account, and we're
> bugging users with a warning that we're causing ourselves.
>
> In a closer look we conclude that this warning is not warranted in any
> other circumstance since we're just following the ISA [1], which states
> in chapter 24:
>
> "One goal of the RISC-V project is that it be used as a stable software
> development target. For this purpose, we define a combination of a base
> ISA (RV32I or RV64I) plus selected standard extensions (IMAFD, Zicsr,
> Zifencei) as a 'general-purpose' ISA, and we use the abbreviation G for
> the IMAFDZicsr Zifencei combination of instruction-set extensions."
>
> With this in mind, enabling IMAFD_Zicsr_Zifencei if the user explicitly
> enables 'G' is an expected behavior and the warning is unneeded. Any
> user caught by surprise should refer to the ISA.
>
> Remove the warning when handling RVG.
>
> [1] 
> https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf
>
> Reported-by: Paul A. Clarke 
> Suggested-by: Andrew Jones 
> Signed-off-by: Daniel Henrique Barboza 

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  target/riscv/tcg/tcg-cpu.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 08b806dc07..f50ce57602 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -293,7 +293,6 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
> Error **errp)
>  return;
>  }
>
> -warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
>  cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_icsr), true);
>  cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_ifencei), true);
>
> --
> 2.41.0
>
>



Re: [PATCH] target/riscv/tcg: remove RVG warning

2023-10-08 Thread Alistair Francis
On Tue, Oct 3, 2023 at 10:26 PM Daniel Henrique Barboza
 wrote:
>
> Vendor CPUs that set RVG are displaying user warnings about other
> extensions that RVG must enable, one warning per CPU. E.g.:
>
> $ ./build/qemu-system-riscv64 -smp 8 -M virt -cpu veyron-v1 -nographic
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
> qemu-system-riscv64: warning: Setting G will also set IMAFD_Zicsr_Zifencei
>
> This happens because we decided a while ago that, for simplicity, vendor
> CPUs could set RVG instead of setting each G extension individually in
> their cpu_init(). Our warning isn't taking that into account, and we're
> bugging users with a warning that we're causing ourselves.
>
> In a closer look we conclude that this warning is not warranted in any
> other circumstance since we're just following the ISA [1], which states
> in chapter 24:
>
> "One goal of the RISC-V project is that it be used as a stable software
> development target. For this purpose, we define a combination of a base
> ISA (RV32I or RV64I) plus selected standard extensions (IMAFD, Zicsr,
> Zifencei) as a 'general-purpose' ISA, and we use the abbreviation G for
> the IMAFDZicsr Zifencei combination of instruction-set extensions."
>
> With this in mind, enabling IMAFD_Zicsr_Zifencei if the user explicitly
> enables 'G' is an expected behavior and the warning is unneeded. Any
> user caught by surprise should refer to the ISA.
>
> Remove the warning when handling RVG.
>
> [1] 
> https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf
>
> Reported-by: Paul A. Clarke 
> Suggested-by: Andrew Jones 
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/tcg/tcg-cpu.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 08b806dc07..f50ce57602 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -293,7 +293,6 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
> Error **errp)
>  return;
>  }
>
> -warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
>  cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_icsr), true);
>  cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_ifencei), true);
>
> --
> 2.41.0
>
>



Re: [PATCH 0/2] riscv, kvm: support KVM_GET_REG_LIST

2023-10-08 Thread Alistair Francis
On Tue, Oct 3, 2023 at 9:34 PM Daniel Henrique Barboza
 wrote:
>
> Hi,
>
> Starting on Linux 6.6 the QEMU RISC-V KVM driver now supports
> KMV_GET_REG_LIST. This API will make it simpler for the QEMU KVM driver
> to determine whether a KVM reg is present or not.
>
> We'll use this API to fetch ISA_EXT regs during init(). The current
> logic will be put in a legacy() helper and will still be used in case
> the host KVM module does not support get-reg-list.
>
> Patch 1 contains error handling changes in kvm_riscv_init_multiext_cfg()
> where we're using _fatal and errno.
>
>
> Daniel Henrique Barboza (2):
>   target/riscv/kvm: improve 'init_multiext_cfg' error msg
>   target/riscv/kvm: support KVM_GET_REG_LIST

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  target/riscv/kvm/kvm-cpu.c | 100 +++--
>  1 file changed, 95 insertions(+), 5 deletions(-)
>
> --
> 2.41.0
>
>



Re: [PATCH v2 2/2] target/riscv/kvm: support KVM_GET_REG_LIST

2023-10-08 Thread Alistair Francis
On Wed, Oct 4, 2023 at 12:48 AM Daniel Henrique Barboza
 wrote:
>
> KVM for RISC-V started supporting KVM_GET_REG_LIST in Linux 6.6. It
> consists of a KVM ioctl() that retrieves a list of all available regs
> for get_one_reg/set_one_reg. Regs that aren't present in the list aren't
> supported in the host.
>
> This simplifies our lives when initing the KVM regs since we don't have
> to always attempt a KVM_GET_ONE_REG for all regs QEMU knows. We'll only
> attempt a get_one_reg() if we're sure the reg is supported, i.e. it was
> retrieved by KVM_GET_REG_LIST. Any error in get_one_reg() will then
> always considered fatal, instead of having to handle special error codes
> that might indicate a non-fatal failure.
>
> Start by moving the current kvm_riscv_init_multiext_cfg() logic into a
> new kvm_riscv_read_multiext_legacy() helper. We'll prioritize using
> KVM_GET_REG_LIST, so check if we have it available and, in case we
> don't, use the legacy() logic.
>
> Otherwise, retrieve the available reg list and use it to check if the
> host supports our known KVM regs, doing the usual get_one_reg() for
> the supported regs and setting cpu->cfg accordingly.
>
> Signed-off-by: Daniel Henrique Barboza 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/kvm/kvm-cpu.c | 96 +-
>  1 file changed, 95 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
> index c3daf74fe9..090d617627 100644
> --- a/target/riscv/kvm/kvm-cpu.c
> +++ b/target/riscv/kvm/kvm-cpu.c
> @@ -771,7 +771,8 @@ static void kvm_riscv_read_cbomz_blksize(RISCVCPU *cpu, 
> KVMScratchCPU *kvmcpu,
>  }
>  }
>
> -static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
> +static void kvm_riscv_read_multiext_legacy(RISCVCPU *cpu,
> +   KVMScratchCPU *kvmcpu)
>  {
>  CPURISCVState *env = >env;
>  uint64_t val;
> @@ -812,6 +813,99 @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, 
> KVMScratchCPU *kvmcpu)
>  }
>  }
>
> +static int uint64_cmp(const void *a, const void *b)
> +{
> +uint64_t val1 = *(const uint64_t *)a;
> +uint64_t val2 = *(const uint64_t *)b;
> +
> +if (val1 < val2) {
> +return -1;
> +}
> +
> +if (val1 > val2) {
> +return 1;
> +}
> +
> +return 0;
> +}
> +
> +static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
> +{
> +KVMCPUConfig *multi_ext_cfg;
> +struct kvm_one_reg reg;
> +struct kvm_reg_list rl_struct;
> +struct kvm_reg_list *reglist;
> +uint64_t val, reg_id, *reg_search;
> +int i, ret;
> +
> +rl_struct.n = 0;
> +ret = ioctl(kvmcpu->cpufd, KVM_GET_REG_LIST, _struct);
> +
> +/*
> + * If KVM_GET_REG_LIST isn't supported we'll get errno 22
> + * (EINVAL). Use read_legacy() in this case.
> + */
> +if (errno == EINVAL) {
> +return kvm_riscv_read_multiext_legacy(cpu, kvmcpu);
> +} else if (errno != E2BIG) {
> +/*
> + * E2BIG is an expected error message for the API since we
> + * don't know the number of registers. The right amount will
> + * be written in rl_struct.n.
> + *
> + * Error out if we get any other errno.
> + */
> +error_report("Error when accessing get-reg-list, code: %s",
> + strerrorname_np(errno));
> +exit(EXIT_FAILURE);
> +}
> +
> +reglist = g_malloc(sizeof(struct kvm_reg_list) +
> +   rl_struct.n * sizeof(uint64_t));
> +reglist->n = rl_struct.n;
> +ret = ioctl(kvmcpu->cpufd, KVM_GET_REG_LIST, reglist);
> +if (ret) {
> +error_report("Error when reading KVM_GET_REG_LIST, code %s ",
> + strerrorname_np(errno));
> +exit(EXIT_FAILURE);
> +}
> +
> +/* sort reglist to use bsearch() */
> +qsort(>reg, reglist->n, sizeof(uint64_t), uint64_cmp);
> +
> +for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
> +multi_ext_cfg = _multi_ext_cfgs[i];
> +reg_id = kvm_riscv_reg_id(>env, KVM_REG_RISCV_ISA_EXT,
> +  multi_ext_cfg->kvm_reg_id);
> +reg_search = bsearch(_id, reglist->reg, reglist->n,
> + sizeof(uint64_t), uint64_cmp);
> +if (!reg_search) {
> +continue;
> +}
> +
> +reg.id = reg_id;
> +reg.addr = (uint64_t)
> +ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, );
> +if (ret != 0) {
> +error_report("Unable to read ISA_EXT KVM register %s, "
> + "error code: %s", multi_ext_cfg->name,
> + strerrorname_np(errno));
> +exit(EXIT_FAILURE);
> +}
> +
> +multi_ext_cfg->supported = true;
> +kvm_cpu_cfg_set(cpu, multi_ext_cfg, val);
> +}
> +
> +if (cpu->cfg.ext_icbom) {
> +kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, 

Re: [PATCH v2 1/2] target/riscv/kvm: improve 'init_multiext_cfg' error msg

2023-10-08 Thread Alistair Francis
On Wed, Oct 4, 2023 at 12:46 AM Daniel Henrique Barboza
 wrote:
>
> Our error message is returning the value of 'ret', which will be always
> -1 in case of error, and will not be that useful:
>
> qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error -1
>
> Improve the error message by outputting 'errno' instead of 'ret'. Use
> strerrorname_np() to output the error name instead of the error code.
> This will give us what we need to know right away:
>
> qemu-system-riscv64: Unable to read ISA_EXT KVM register ssaia, error code: 
> ENOENT
>
> Given that we're going to exit(1) in this condition instead of
> attempting to recover, remove the 'kvm_riscv_destroy_scratch_vcpu()'
> call.
>
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/kvm/kvm-cpu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
> index c6615cb807..c3daf74fe9 100644
> --- a/target/riscv/kvm/kvm-cpu.c
> +++ b/target/riscv/kvm/kvm-cpu.c
> @@ -792,8 +792,8 @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, 
> KVMScratchCPU *kvmcpu)
>  val = false;
>  } else {
>  error_report("Unable to read ISA_EXT KVM register %s, "
> - "error %d", multi_ext_cfg->name, ret);
> -kvm_riscv_destroy_scratch_vcpu(kvmcpu);
> + "error code: %s", multi_ext_cfg->name,
> + strerrorname_np(errno));
>  exit(EXIT_FAILURE);
>  }
>  } else {
> --
> 2.41.0
>
>



Re: [PATCH 2/3] target/riscv: Support discontinuous PMU counters

2023-10-08 Thread Alistair Francis
On Wed, Oct 4, 2023 at 7:36 PM Rob Bradford  wrote:
>
> Hi Atish,
>
> On Tue, 2023-10-03 at 13:25 -0700, Atish Kumar Patra wrote:
> > On Tue, Oct 3, 2023 at 5:51 AM Rob Bradford 
> > wrote:
> > >
> > > There is no requirement that the enabled counters in the platform
> > > are
> > > continuously numbered. Add a "pmu-mask" property that, if
> > > specified, can
> > > be used to specify the enabled PMUs. In order to avoid ambiguity if
> > > "pmu-mask" is specified then "pmu-num" must also match the number
> > > of
> > > bits set in the mask.
> > >
> > > Signed-off-by: Rob Bradford 
> > > ---
> > >  target/riscv/cpu.c |  1 +
> > >  target/riscv/cpu_cfg.h |  1 +
> > >  target/riscv/pmu.c | 15 +--
> > >  3 files changed, 15 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > > index 9d79c20c1a..b89b006a76 100644
> > > --- a/target/riscv/cpu.c
> > > +++ b/target/riscv/cpu.c
> > > @@ -1817,6 +1817,7 @@ static void
> > > riscv_cpu_add_misa_properties(Object *cpu_obj)
> > >  static Property riscv_cpu_extensions[] = {
> > >  /* Defaults for standard extensions */
> > >  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > > +DEFINE_PROP_UINT32("pmu-mask", RISCVCPU, cfg.pmu_mask, 0),
> > >  DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf,
> > > false),
> > >  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> > >  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> > > diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> > > index 0e6a0f245c..40f7d970bc 100644
> > > --- a/target/riscv/cpu_cfg.h
> > > +++ b/target/riscv/cpu_cfg.h
> > > @@ -124,6 +124,7 @@ struct RISCVCPUConfig {
> > >  bool ext_XVentanaCondOps;
> > >
> > >  uint8_t pmu_num;
> > > +uint32_t pmu_mask;
> > >  char *priv_spec;
> > >  char *user_spec;
> > >  char *bext_spec;
> > > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > > index 13801ccb78..f97e25a1f6 100644
> > > --- a/target/riscv/pmu.c
> > > +++ b/target/riscv/pmu.c
> > > @@ -437,6 +437,13 @@ int riscv_pmu_setup_timer(CPURISCVState *env,
> > > uint64_t value, uint32_t ctr_idx)
> > >  void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
> > >  {
> > >  uint8_t pmu_num = cpu->cfg.pmu_num;
> > > +uint32_t pmu_mask = cpu->cfg.pmu_mask;
> > > +
> > > +if (pmu_mask && ctpop32(pmu_mask) != pmu_num) {
> > > +error_setg(errp, "Mismatch between number of enabled
> > > counters in "
> > > + "\"pmu-mask\" and \"pmu-num\"");
> > > +return;
> > > +}
> > >
> >
> > Is that necessary for the default case? I am thinking of marking
> > pmu-num as deprecated and pmu-mask
> > as the preferred way of doing things as it is more flexible. There is
> > no real benefit carrying both.
> > The default pmu-mask value will change in that case.
> > We can just overwrite pmu-num with ctpop32(pmu_mask) if pmu-mask is
> > available. Thoughts ?
> >
>
> I agree it makes sense to me that there is only one way for the user to
> adjust the PMU count. However i'm not sure how we can handle the
> transition if we choose to deprecate "pmu-num".
>
> If we change the default "pmu-mask" to MAKE_32BIT_MASK(3, 16) then that
> value in the config will always be set - you propose that we overwrite
> "pmu-num" with the popcount of that property. But that will break if

Couldn't we deprecate "pmu-num" and then throw an error if both are
set? Then we can migrate away from "pmu-num"

Alistair

> the user has an existing setup that changes the value of "pmu-num"
> (either as a property at runtime or in the CPU init code).
>
> One option would be to not make the mask configurable as property and
> make choosing the layout of the counters something that the specialised
> CPU init can choose to do.
>
> Cheers,
>
> Rob
>
> > >  if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
> > >  error_setg(errp, "Number of counters exceeds maximum
> > > available");
> > > @@ -449,6 +456,10 @@ void riscv_pmu_init(RISCVCPU *cpu, Error
> > > **errp)
> > >  return;
> > >  }
> > >
> > > -/* Create a bitmask of available programmable counters */
> > > -cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
> > > +/* Create a bitmask of available programmable counters if none
> > > supplied */
> > > +if (pmu_mask) {
> > > +cpu->pmu_avail_ctrs = pmu_mask;
> > > +} else {
> > > +cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
> > > +}
> > >  }
> > > --
> > > 2.41.0
> > >
>
>



Re: [PATCH 1/3] target/riscv: Propagate error from PMU setup

2023-10-08 Thread Alistair Francis
On Tue, Oct 3, 2023 at 10:53 PM Rob Bradford  wrote:
>
> More closely follow the QEMU style by returning an Error and propagating
> it there is an error relating to the PMU setup.
>
> Further simplify the function by removing the num_counters parameter as
> this is available from the passed in cpu pointer.
>
> Signed-off-by: Rob Bradford 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c |  8 +++-
>  target/riscv/pmu.c | 19 +--
>  target/riscv/pmu.h |  3 ++-
>  3 files changed, 18 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 4140899c52..9d79c20c1a 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1488,7 +1488,13 @@ static void riscv_cpu_realize_tcg(DeviceState *dev, 
> Error **errp)
>  }
>
>  if (cpu->cfg.pmu_num) {
> -if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) 
> {
> +riscv_pmu_init(cpu, _err);
> +if (local_err != NULL) {
> +error_propagate(errp, local_err);
> +return;
> +}
> +
> +if (cpu->cfg.ext_sscofpmf) {
>  cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
>riscv_pmu_timer_cb, cpu);
>  }
> diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> index 36f6307d28..13801ccb78 100644
> --- a/target/riscv/pmu.c
> +++ b/target/riscv/pmu.c
> @@ -434,22 +434,21 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t 
> value, uint32_t ctr_idx)
>  }
>
>
> -int riscv_pmu_init(RISCVCPU *cpu, int num_counters)
> +void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
>  {
> -if (num_counters > (RV_MAX_MHPMCOUNTERS - 3)) {
> -return -1;
> +uint8_t pmu_num = cpu->cfg.pmu_num;
> +
> +if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
> +error_setg(errp, "Number of counters exceeds maximum available");
> +return;
>  }
>
>  cpu->pmu_event_ctr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
>  if (!cpu->pmu_event_ctr_map) {
> -/* PMU support can not be enabled */
> -qemu_log_mask(LOG_UNIMP, "PMU events can't be supported\n");
> -cpu->cfg.pmu_num = 0;
> -return -1;
> +error_setg(errp, "Unable to allocate PMU event hash table");
> +return;
>  }
>
>  /* Create a bitmask of available programmable counters */
> -cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, num_counters);
> -
> -return 0;
> +cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
>  }
> diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
> index 2bfb71ba87..88e0713296 100644
> --- a/target/riscv/pmu.h
> +++ b/target/riscv/pmu.h
> @@ -17,13 +17,14 @@
>   */
>
>  #include "cpu.h"
> +#include "qapi/error.h"
>
>  bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
>  uint32_t target_ctr);
>  bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env,
>uint32_t target_ctr);
>  void riscv_pmu_timer_cb(void *priv);
> -int riscv_pmu_init(RISCVCPU *cpu, int num_counters);
> +void riscv_pmu_init(RISCVCPU *cpu, Error **errp);
>  int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
> uint32_t ctr_idx);
>  int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
> --
> 2.41.0
>
>



[PATCH v3 3/3] target/hexagon: avoid shadowing globals

2023-10-08 Thread Brian Cain
The typedef `vaddr` is shadowed by `vaddr` identifiers, so we rename the
identifiers to avoid shadowing the type name.

The global `tcg_env` is shadowed by local `tcg_env` arguments, so we
rename the function arguments to avoid shadowing the global.

Signed-off-by: Brian Cain 
---
 target/hexagon/genptr.c | 56 -
 target/hexagon/genptr.h | 18 
 target/hexagon/mmvec/system_ext_mmvec.c |  4 +-
 target/hexagon/mmvec/system_ext_mmvec.h |  2 +-
 target/hexagon/op_helper.c  |  4 +-
 5 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index dbae6c570a..fa577e05dc 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -334,28 +334,28 @@ void gen_set_byte_i64(int N, TCGv_i64 result, TCGv src)
 tcg_gen_deposit_i64(result, result, src64, N * 8, 8);
 }
 
-static inline void gen_load_locked4u(TCGv dest, TCGv vaddr, int mem_index)
+static inline void gen_load_locked4u(TCGv dest, TCGv v_addr, int mem_index)
 {
-tcg_gen_qemu_ld_tl(dest, vaddr, mem_index, MO_TEUL);
-tcg_gen_mov_tl(hex_llsc_addr, vaddr);
+tcg_gen_qemu_ld_tl(dest, v_addr, mem_index, MO_TEUL);
+tcg_gen_mov_tl(hex_llsc_addr, v_addr);
 tcg_gen_mov_tl(hex_llsc_val, dest);
 }
 
-static inline void gen_load_locked8u(TCGv_i64 dest, TCGv vaddr, int mem_index)
+static inline void gen_load_locked8u(TCGv_i64 dest, TCGv v_addr, int mem_index)
 {
-tcg_gen_qemu_ld_i64(dest, vaddr, mem_index, MO_TEUQ);
-tcg_gen_mov_tl(hex_llsc_addr, vaddr);
+tcg_gen_qemu_ld_i64(dest, v_addr, mem_index, MO_TEUQ);
+tcg_gen_mov_tl(hex_llsc_addr, v_addr);
 tcg_gen_mov_i64(hex_llsc_val_i64, dest);
 }
 
 static inline void gen_store_conditional4(DisasContext *ctx,
-  TCGv pred, TCGv vaddr, TCGv src)
+  TCGv pred, TCGv v_addr, TCGv src)
 {
 TCGLabel *fail = gen_new_label();
 TCGLabel *done = gen_new_label();
 TCGv one, zero, tmp;
 
-tcg_gen_brcond_tl(TCG_COND_NE, vaddr, hex_llsc_addr, fail);
+tcg_gen_brcond_tl(TCG_COND_NE, v_addr, hex_llsc_addr, fail);
 
 one = tcg_constant_tl(0xff);
 zero = tcg_constant_tl(0);
@@ -374,13 +374,13 @@ static inline void gen_store_conditional4(DisasContext 
*ctx,
 }
 
 static inline void gen_store_conditional8(DisasContext *ctx,
-  TCGv pred, TCGv vaddr, TCGv_i64 src)
+  TCGv pred, TCGv v_addr, TCGv_i64 src)
 {
 TCGLabel *fail = gen_new_label();
 TCGLabel *done = gen_new_label();
 TCGv_i64 one, zero, tmp;
 
-tcg_gen_brcond_tl(TCG_COND_NE, vaddr, hex_llsc_addr, fail);
+tcg_gen_brcond_tl(TCG_COND_NE, v_addr, hex_llsc_addr, fail);
 
 one = tcg_constant_i64(0xff);
 zero = tcg_constant_i64(0);
@@ -407,57 +407,57 @@ static TCGv gen_slotval(DisasContext *ctx)
 }
 #endif
 
-void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot)
+void gen_store32(TCGv v_addr, TCGv src, int width, uint32_t slot)
 {
-tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
+tcg_gen_mov_tl(hex_store_addr[slot], v_addr);
 tcg_gen_movi_tl(hex_store_width[slot], width);
 tcg_gen_mov_tl(hex_store_val32[slot], src);
 }
 
-void gen_store1(TCGv_env tcg_env, TCGv vaddr, TCGv src, uint32_t slot)
+void gen_store1(TCGv_env tcg_env_, TCGv v_addr, TCGv src, uint32_t slot)
 {
-gen_store32(vaddr, src, 1, slot);
+gen_store32(v_addr, src, 1, slot);
 }
 
-void gen_store1i(TCGv_env tcg_env, TCGv vaddr, int32_t src, uint32_t slot)
+void gen_store1i(TCGv_env tcg_env_, TCGv v_addr, int32_t src, uint32_t slot)
 {
 TCGv tmp = tcg_constant_tl(src);
-gen_store1(tcg_env, vaddr, tmp, slot);
+gen_store1(tcg_env_, v_addr, tmp, slot);
 }
 
-void gen_store2(TCGv_env tcg_env, TCGv vaddr, TCGv src, uint32_t slot)
+void gen_store2(TCGv_env tcg_env_, TCGv v_addr, TCGv src, uint32_t slot)
 {
-gen_store32(vaddr, src, 2, slot);
+gen_store32(v_addr, src, 2, slot);
 }
 
-void gen_store2i(TCGv_env tcg_env, TCGv vaddr, int32_t src, uint32_t slot)
+void gen_store2i(TCGv_env tcg_env_, TCGv v_addr, int32_t src, uint32_t slot)
 {
 TCGv tmp = tcg_constant_tl(src);
-gen_store2(tcg_env, vaddr, tmp, slot);
+gen_store2(tcg_env_, v_addr, tmp, slot);
 }
 
-void gen_store4(TCGv_env tcg_env, TCGv vaddr, TCGv src, uint32_t slot)
+void gen_store4(TCGv_env tcg_env_, TCGv v_addr, TCGv src, uint32_t slot)
 {
-gen_store32(vaddr, src, 4, slot);
+gen_store32(v_addr, src, 4, slot);
 }
 
-void gen_store4i(TCGv_env tcg_env, TCGv vaddr, int32_t src, uint32_t slot)
+void gen_store4i(TCGv_env tcg_env_, TCGv v_addr, int32_t src, uint32_t slot)
 {
 TCGv tmp = tcg_constant_tl(src);
-gen_store4(tcg_env, vaddr, tmp, slot);
+gen_store4(tcg_env_, v_addr, tmp, slot);
 }
 
-void gen_store8(TCGv_env tcg_env, TCGv vaddr, TCGv_i64 src, uint32_t slot)
+void gen_store8(TCGv_env tcg_env_, TCGv 

[PATCH v3 2/3] target/hexagon: fix some occurrences of -Wshadow=local

2023-10-08 Thread Brian Cain
Of the changes in this commit, the changes in `HELPER(commit_hvx_stores)()`
are less obvious.  They are required because of some macro invocations like
SCATTER_OP_WRITE_TO_MEM().

e.g.:

In file included from ../target/hexagon/op_helper.c:31:
../target/hexagon/mmvec/macros.h:205:18: error: declaration of ‘i’ shadows 
a previous local [-Werror=shadow=compatible-local]
  205 | for (int i = 0; i < sizeof(MMVector); i += sizeof(TYPE)) { \
  |  ^
../target/hexagon/op_helper.c:157:17: note: in expansion of macro 
‘SCATTER_OP_WRITE_TO_MEM’
  157 | SCATTER_OP_WRITE_TO_MEM(uint16_t);
  | ^~~
../target/hexagon/op_helper.c:135:9: note: shadowed declaration is here
  135 | int i;
  | ^
In file included from ../target/hexagon/op_helper.c:31:
../target/hexagon/mmvec/macros.h:204:19: error: declaration of ‘ra’ shadows 
a previous local [-Werror=shadow=compatible-local]
  204 | uintptr_t ra = GETPC(); \
  |   ^~
../target/hexagon/op_helper.c:160:17: note: in expansion of macro 
‘SCATTER_OP_WRITE_TO_MEM’
  160 | SCATTER_OP_WRITE_TO_MEM(uint32_t);
  | ^~~
../target/hexagon/op_helper.c:134:15: note: shadowed declaration is here
  134 | uintptr_t ra = GETPC();
  |   ^~

Reviewed-by: Matheus Tavares Bernardino 
Signed-off-by: Brian Cain 
---
 target/hexagon/imported/alu.idef |  6 +++---
 target/hexagon/mmvec/macros.h|  2 +-
 target/hexagon/op_helper.c   |  9 +++--
 target/hexagon/translate.c   | 10 +-
 4 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/target/hexagon/imported/alu.idef b/target/hexagon/imported/alu.idef
index 12d2aac5d4..b855676989 100644
--- a/target/hexagon/imported/alu.idef
+++ b/target/hexagon/imported/alu.idef
@@ -1142,9 +1142,9 @@ 
Q6INSN(A4_cround_rr,"Rd32=cround(Rs32,Rt32)",ATTRIBS(),"Convergent Round", {RdV
 tmp128 = fSHIFTR128(tmp128, SHIFT);\
 DST =  fCAST16S_8S(tmp128);\
 } else {\
-size16s_t rndbit_128 =  fCAST8S_16S((1LL << (SHIFT - 1))); \
-size16s_t src_128 =  fCAST8S_16S(SRC); \
-size16s_t tmp128 = fADD128(src_128, rndbit_128);\
+rndbit_128 =  fCAST8S_16S((1LL << (SHIFT - 1))); \
+src_128 =  fCAST8S_16S(SRC); \
+tmp128 = fADD128(src_128, rndbit_128);\
 tmp128 = fSHIFTR128(tmp128, SHIFT);\
 DST =  fCAST16S_8S(tmp128);\
 }
diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h
index a655634fd1..1ceb9453ee 100644
--- a/target/hexagon/mmvec/macros.h
+++ b/target/hexagon/mmvec/macros.h
@@ -201,7 +201,7 @@
 } while (0)
 #define SCATTER_OP_WRITE_TO_MEM(TYPE) \
 do { \
-uintptr_t ra = GETPC(); \
+ra = GETPC(); \
 for (int i = 0; i < sizeof(MMVector); i += sizeof(TYPE)) { \
 if (test_bit(i, env->vtcm_log.mask)) { \
 TYPE dst = 0; \
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 8ca3976a65..da10ac5847 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -132,10 +132,9 @@ void HELPER(gather_store)(CPUHexagonState *env, uint32_t 
addr, int slot)
 void HELPER(commit_hvx_stores)(CPUHexagonState *env)
 {
 uintptr_t ra = GETPC();
-int i;
 
 /* Normal (possibly masked) vector store */
-for (i = 0; i < VSTORES_MAX; i++) {
+for (int i = 0; i < VSTORES_MAX; i++) {
 if (env->vstore_pending[i]) {
 env->vstore_pending[i] = 0;
 target_ulong va = env->vstore[i].va;
@@ -162,7 +161,7 @@ void HELPER(commit_hvx_stores)(CPUHexagonState *env)
 g_assert_not_reached();
 }
 } else {
-for (i = 0; i < sizeof(MMVector); i++) {
+for (int i = 0; i < sizeof(MMVector); i++) {
 if (test_bit(i, env->vtcm_log.mask)) {
 cpu_stb_data_ra(env, env->vtcm_log.va[i],
 env->vtcm_log.data.ub[i], ra);
@@ -505,10 +504,8 @@ void HELPER(probe_pkt_scalar_store_s0)(CPUHexagonState 
*env, int args)
 static void probe_hvx_stores(CPUHexagonState *env, int mmu_idx,
 uintptr_t retaddr)
 {
-int i;
-
 /* Normal (possibly masked) vector store */
-for (i = 0; i < VSTORES_MAX; i++) {
+for (int i = 0; i < VSTORES_MAX; i++) {
 if (env->vstore_pending[i]) {
 target_ulong va = env->vstore[i].va;
 int size = env->vstore[i].size;
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 663b7bbc3a..666c061180 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -553,7 +553,7 @@ static void gen_start_packet(DisasContext *ctx)
 /* Preload the predicated registers into 

[PATCH v3 0/3] hexagon: GETPC() fixes, shadowing fixes

2023-10-08 Thread Brian Cain
Changes since v2:
- rebased, suggested by Markus
- s/cpu_env/tcg_env/
- For local shadows: s/tcg_env/tcg_env_/

Brian Cain (2):
  target/hexagon: fix some occurrences of -Wshadow=local
  target/hexagon: avoid shadowing globals

Matheus Tavares Bernardino (1):
  target/hexagon: move GETPC() calls to top level helpers

 target/hexagon/genptr.c | 56 -
 target/hexagon/genptr.h | 18 +++---
 target/hexagon/imported/alu.idef|  6 +-
 target/hexagon/macros.h | 19 +++---
 target/hexagon/mmvec/macros.h   |  2 +-
 target/hexagon/mmvec/system_ext_mmvec.c |  4 +-
 target/hexagon/mmvec/system_ext_mmvec.h |  2 +-
 target/hexagon/op_helper.c  | 84 ++---
 target/hexagon/op_helper.h  |  9 ---
 target/hexagon/translate.c  | 10 +--
 10 files changed, 90 insertions(+), 120 deletions(-)

-- 
2.25.1



[PATCH v3 1/3] target/hexagon: move GETPC() calls to top level helpers

2023-10-08 Thread Brian Cain
From: Matheus Tavares Bernardino 

As docs/devel/loads-stores.rst states:

  ``GETPC()`` should be used with great care: calling
  it in other functions that are *not* the top level
  ``HELPER(foo)`` will cause unexpected behavior. Instead, the
  value of ``GETPC()`` should be read from the helper and passed
  if needed to the functions that the helper calls.

Let's fix the GETPC() usage in Hexagon, making sure it's always called
from top level helpers and passed down to the places where it's
needed. There are a few snippets where that is not currently the case:

- probe_store(), which is only called from two helpers, so it's easy to
  move GETPC() up.

- mem_load*() functions, which are also called directly from helpers,
  but through the MEM_LOAD*() set of macros. Note that this are only
  used when compiling with --disable-hexagon-idef-parser.

  In this case, we also take this opportunity to simplify the code,
  unifying the mem_load*() functions.

- HELPER(probe_hvx_stores), when called from another helper, ends up
  using its own GETPC() expansion instead of the top level caller.

Signed-off-by: Matheus Tavares Bernardino 
Reviewed-by: Taylor Simpson 
Message-Id: 
<2c74c3696946edba7cc5b2942cf296a5af532052.1689070412.git.quic_mathb...@quicinc.com>-ne
Reviewed-by: Brian Cain 
Signed-off-by: Brian Cain 
---
 target/hexagon/macros.h| 19 +-
 target/hexagon/op_helper.c | 75 +++---
 target/hexagon/op_helper.h |  9 -
 3 files changed, 38 insertions(+), 65 deletions(-)

diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index b356d85792..9a51b5709b 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -173,15 +173,6 @@
 #define MEM_STORE8(VA, DATA, SLOT) \
 MEM_STORE8_FUNC(DATA)(tcg_env, VA, DATA, SLOT)
 #else
-#define MEM_LOAD1s(VA) ((int8_t)mem_load1(env, pkt_has_store_s1, slot, VA))
-#define MEM_LOAD1u(VA) ((uint8_t)mem_load1(env, pkt_has_store_s1, slot, VA))
-#define MEM_LOAD2s(VA) ((int16_t)mem_load2(env, pkt_has_store_s1, slot, VA))
-#define MEM_LOAD2u(VA) ((uint16_t)mem_load2(env, pkt_has_store_s1, slot, VA))
-#define MEM_LOAD4s(VA) ((int32_t)mem_load4(env, pkt_has_store_s1, slot, VA))
-#define MEM_LOAD4u(VA) ((uint32_t)mem_load4(env, pkt_has_store_s1, slot, VA))
-#define MEM_LOAD8s(VA) ((int64_t)mem_load8(env, pkt_has_store_s1, slot, VA))
-#define MEM_LOAD8u(VA) ((uint64_t)mem_load8(env, pkt_has_store_s1, slot, VA))
-
 #define MEM_STORE1(VA, DATA, SLOT) log_store32(env, VA, DATA, 1, SLOT)
 #define MEM_STORE2(VA, DATA, SLOT) log_store32(env, VA, DATA, 2, SLOT)
 #define MEM_STORE4(VA, DATA, SLOT) log_store32(env, VA, DATA, 4, SLOT)
@@ -530,8 +521,16 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, 
int shift)
 #ifdef QEMU_GENERATE
 #define fLOAD(NUM, SIZE, SIGN, EA, DST) MEM_LOAD##SIZE##SIGN(DST, EA)
 #else
+#define MEM_LOAD1 cpu_ldub_data_ra
+#define MEM_LOAD2 cpu_lduw_data_ra
+#define MEM_LOAD4 cpu_ldl_data_ra
+#define MEM_LOAD8 cpu_ldq_data_ra
+
 #define fLOAD(NUM, SIZE, SIGN, EA, DST) \
-DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE##SIGN(EA)
+do { \
+check_noshuf(env, pkt_has_store_s1, slot, EA, SIZE, GETPC()); \
+DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE(env, EA, GETPC()); \
+} while (0)
 #endif
 
 #define fMEMOP(NUM, SIZE, SIGN, EA, FNTYPE, VALUE)
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 12967ac21e..8ca3976a65 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -95,9 +95,8 @@ void HELPER(debug_check_store_width)(CPUHexagonState *env, 
int slot, int check)
 }
 }
 
-void HELPER(commit_store)(CPUHexagonState *env, int slot_num)
+static void commit_store(CPUHexagonState *env, int slot_num, uintptr_t ra)
 {
-uintptr_t ra = GETPC();
 uint8_t width = env->mem_log_stores[slot_num].width;
 target_ulong va = env->mem_log_stores[slot_num].va;
 
@@ -119,6 +118,12 @@ void HELPER(commit_store)(CPUHexagonState *env, int 
slot_num)
 }
 }
 
+void HELPER(commit_store)(CPUHexagonState *env, int slot_num)
+{
+uintptr_t ra = GETPC();
+commit_store(env, slot_num, ra);
+}
+
 void HELPER(gather_store)(CPUHexagonState *env, uint32_t addr, int slot)
 {
 mem_gather_store(env, addr, slot);
@@ -467,13 +472,12 @@ int32_t HELPER(cabacdecbin_pred)(int64_t RssV, int64_t 
RttV)
 }
 
 static void probe_store(CPUHexagonState *env, int slot, int mmu_idx,
-bool is_predicated)
+bool is_predicated, uintptr_t retaddr)
 {
 if (!is_predicated || !(env->slot_cancelled & (1 << slot))) {
 size1u_t width = env->mem_log_stores[slot].width;
 target_ulong va = env->mem_log_stores[slot].va;
-uintptr_t ra = GETPC();
-probe_write(env, va, width, mmu_idx, ra);
+probe_write(env, va, width, mmu_idx, retaddr);
 }
 }
 
@@ -494,12 +498,13 @@ void HELPER(probe_pkt_scalar_store_s0)(CPUHexagonState 
*env, int args)
 int mmu_idx = FIELD_EX32(args, 

[PATCH v2] target/riscv: Use a direct cast for better performance

2023-10-08 Thread Richard W.M. Jones
RISCV_CPU(cs) uses a checked cast.  When QOM cast debugging is enabled
this adds about 5% total overhead when emulating RV64 on x86-64 host.

Using a RISC-V guest with 16 vCPUs, 16 GB of guest RAM, virtio-blk
disk.  The guest has a copy of the qemu source tree.  The test
involves compiling the qemu source tree with 'make clean; time make -j16'.

Before making this change the compile step took 449 & 447 seconds over
two consecutive runs.

After making this change, 428 & 422 seconds.

The saving is about 5%.

Thanks: Paolo Bonzini
Signed-off-by: Richard W.M. Jones 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu_helper.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 3a02079290..479d9863ae 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -66,7 +66,11 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
   uint64_t *cs_base, uint32_t *pflags)
 {
 CPUState *cs = env_cpu(env);
-RISCVCPU *cpu = RISCV_CPU(cs);
+/*
+ * Using the checked cast RISCV_CPU(cs) imposes ~ 5% overhead when
+ * QOM cast debugging is enabled, so use a direct cast instead.
+ */
+RISCVCPU *cpu = (RISCVCPU *)cs;
 RISCVExtStatus fs, vs;
 uint32_t flags = 0;
 
-- 
2.41.0




[PATCH v2] target/riscv: Use a direct cast for better performance

2023-10-08 Thread Richard W.M. Jones
v1 was here:
https://lists.nongnu.org/archive/html/qemu-devel/2023-10/msg02021.html

v2 is functionally exactly the same, except I changed
s/qemu cast/QOM cast/ in the comment, and added the Reviewed-by tag
received for the first version.

Rich.





Re: [PATCH 2/3] hw/pci-host: Add emulation of Mai Logic Articia S

2023-10-08 Thread BALATON Zoltan

On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The Articia S is a generic chipset supporting several different CPUs
that were used on some PPC boards. This is a minimal emulation of the
parts needed for emulating the AmigaOne board.

Signed-off-by: BALATON Zoltan 
---
  hw/pci-host/Kconfig   |   5 +
  hw/pci-host/articia.c | 266 ++
  hw/pci-host/meson.build   |   2 +
  include/hw/pci-host/articia.h |  17 +++
  4 files changed, 290 insertions(+)
  create mode 100644 hw/pci-host/articia.c
  create mode 100644 include/hw/pci-host/articia.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index a07070eddf..33014c80a4 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -73,6 +73,11 @@ config SH_PCI
  bool
  select PCI
  +config ARTICIA
+bool
+select PCI
+select I8259
+
  config MV64361
  bool
  select PCI
diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
new file mode 100644
index 00..80558e1c47
--- /dev/null
+++ b/hw/pci-host/articia.c
@@ -0,0 +1,266 @@
+/*
+ * Mai Logic Articia S emulation
+ *
+ * Copyright (c) 2023 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/pci/pci_device.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/i2c/bitbang_i2c.h"
+#include "hw/intc/i8259.h"
+#include "hw/pci-host/articia.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaState, ARTICIA)
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaHostState, ARTICIA_PCI_HOST)
+struct ArticiaHostState {
+PCIDevice parent_obj;
+
+ArticiaState *as;
+};
+
+/* TYPE_ARTICIA */
+
+struct ArticiaState {
+PCIHostState parent_obj;
+
+qemu_irq irq[PCI_NUM_PINS];
+MemoryRegion io;
+MemoryRegion mem;
+MemoryRegion reg;
+
+bitbang_i2c_interface smbus;
+uint32_t gpio; /* bits 0-7 in, 8-15 out, 16-23 direction (0 in, 1 out) 
*/

+hwaddr gpio_base;
+MemoryRegion gpio_reg;
+};


These types above should be in the header file and not in the C file, as per 
our current QOM guidelines.


I don't think there's such a guideline, at least I did not find any 
mention of it in style and qom docs. It was necessary to move some type 
declarations to headers for types that are embedded in other objects 
because C needs the struct size for that, but I don't think that should be 
a general thing when it's not needed.


The reason for that is that moving these to the header exposes internal 
object structure to users that should not need to know that so it breaks 
object encapsulation and also needs moving a bunch of includes to the 
header which then makes the users of this type also include those headers 
when they don't really need them but only need the type defines to 
instantiate the object and that's all they should have access to. So I 
think declaring types in the header should only be done for types that 
aren't full devices and are meant to be embedded as part of another device 
or a SoC but otherwise it's better to keep implementation closed and local 
to the object and not expose it unless really needed, that's why these 
are here.


If you insist I can move these but I don't think there's really such 
recommendation and I don't think that's a good idea because of the above.


Regards,
BALATON Zoltan



Re: [PATCH v8 00/29] Consolidate PIIX south bridges

2023-10-08 Thread Chuck Zmudzinski
On 10/7/23 8:38 AM, Bernhard Beschow wrote:
> This series consolidates the implementations of the PIIX3 and PIIX4 south
> bridges and makes PIIX4 usable in the PC machine via an experimental command
> line parameter. The motivation is to resolve duplicate code between the device
> models as well as resolving the "Frankenstein" PIIX4-PM problem in PIIX3
> discussed on this list before.
> 
> The series is structured as follows:
> 
> Patches 1-8 are preparational patches necessary for moving all sub devices 
> into
> PIIX3, like was done for PIIX4. In isolation these patches can also be seen as
> general x86 machine cleanup sub series which has merit in its own right -- and
> could be applied to master if the remainder of the series takes longer to
> review.
> 
> Patches 9-13 move PIIX3 sub devices into one device model like already
> done for PIIX4. Together with the previous sub series these patches form a
> bigger sub series which also has merit in its own right, and could be applied
> independent of the remainder of this series as well.
> 
> The remainder of this series consolidates the PIIX3 and PIIX4 device models.
> The culmination point is the last commit which makes PIIX4 usable in the PC
> machine.
> 
> One challenge was dealing with optional devices where Peter already gave 
> advice
> in [1] which this series implements. Although PIIX4 is now usable in the PC
> machine it still has a different binary layout in its VM state.
> 
> Testing done:
> * `make check`
> * `qemu-system-x86_64 -M pc -m 2G -accel kvm -cdrom
>  manjaro-kde-21.3.2-220704-linux515.iso`
> * `qemu-system-x86_64 -M pc,x-south-bridge=piix4-isa -m 2G -accel kvm -cdrom
>  manjaro-kde-21.3.2-220704-linux515.iso`
> * `qemu-system-x86_64 -M q35 -m 2G -accel kvm -cdrom
>  manjaro-kde-21.3.2-220704-linux515.iso`
> * `qemu-system-mips64el -M malta -cpu 5KEc -m 1G -kernel kernel -initrd initrd
>  -append "root=LABEL=rootfs console=ttyS0" -drive file=image.qcow2`
> * `qemu-system-mips64el -M malta -bios yamon-02.22.bin`
> * Run HVM domU guest under Xen with manjaro-kde-21.3.2-220704-linux515.iso 
> image

I did some preliminary tests of this patch series on some Xen HVM domU guests I 
have
that use the xenfv / pc machine and depend on the current PIIX3 implementation.
So far there are no regressions in my tests. I use libxl or libvirt to manage 
the
Xen guests.

I have not (yet) tested the experimental option that makes PIIX4 useable in the 
xenfv / pc
machines. IIUC, that would require a patch to hvmloader/pci.c in Xen tools so 
Xen's
hvmloader recognizes the PIIX4 pci device id [1], and a patch to libxl so libxl 
can
optionally launch qemu with the new experimental option enabled.

Since this patch series affects the xenfv machine, I added the Xen x86 
maintainers to
the Cc list and Jason Andryuk who is credited with discovering the necessary 
patch to
hvmloader/pci.c.

[1] 
https://lore.kernel.org/qemu-devel/b0ff78f4-1193-495b-919c-84a1ff8ad...@gmail.com/

> 
> v8:
> - Wire ISA interrupts before device realization
> - Optionally allow a PIC and PIT to be instantiated in PIIX3 for compatiblity
> with PIIX4
> - Touch ICH9 LPC as far as required for PIIX consolidation
> - Make PIIX4 usable in the PC machine via an experimental option
> - Review and rework history, touching every commit and drop R-b tags when
> changes became too large
> 
> v7:
> - Rebase onto master
> - Avoid the PIC proxy (Phil)
>   The motivation for the PIC proxy was to allow for wiring up ISA interrupts 
> in
>   the south bridges. ISA interrupt wiring requires the GPIO lines to be
>   populated already but pc_piix assigned the interrupts only after realizing
>   PIIX3. By shifting interrupt assignment before realizing, the ISA interrupts
>   are already populated during PIIX3's realize phase where the ISA interrupts
>   are wired up.
> - New patches:
>   * hw/isa/piix4: Reuse struct PIIXState from PIIX3
>   * hw/isa/piix4: Create the "intr" property during init() already
> - Patches with substantial changes (Reviewed-by dropped):
>   * hw/isa/piix3: Move ISA bus IRQ assignments into host device
> 
> v6:
> - Fix some comments about TYPE_ISA_PIC (Mark) ... and use it consistently
>   within the patch series.
> - Incorporate series "[PATCH v2 0/3] Decouple INTx-to-LNKx routing from south
>   bridges" [2] for maintainer convenience.
> - Merge v5's 'hw/i386/pc_piix: Associate pci_map_irq_fn as soon as PCI bus is
>   created' into
>   https://lists.nongnu.org/archive/html/qemu-devel/2022-11/msg03312.html . Do
>   similar for Malta.
> - Rebase onto latest master (d6271b657286 "Merge tag 'for_upstream' of
>   https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging")
> 
> v5:
> - Pick up Reviewed-by tags from 
> https://lists.nongnu.org/archive/html/qemu-devel/2023-01/msg00116.html
> - Add patch to make usage of the isa_pic global more type-safe
> - Re-introduce isa-pic as PIC specific proxy (Mark)
> 
> v4:
> - Rebase onto "[PATCH v2 0/3] Decouple 

Re: [PATCH v4 10/15] vfio/ccw: Use vfio_[attach/detach]_device

2023-10-08 Thread Eric Auger
Hi Zhenzhong,
On 10/8/23 12:21, Duan, Zhenzhong wrote:
> Hi Eric,
>
>> -Original Message-
>> From: Eric Auger 
>> Sent: Wednesday, October 4, 2023 11:44 PM
>> Subject: [PATCH v4 10/15] vfio/ccw: Use vfio_[attach/detach]_device
>>
>> Let the vfio-ccw device use vfio_attach_device() and
>> vfio_detach_device(), hence hiding the details of the used
>> IOMMU backend.
>>
>> Note that the migration reduces the following trace
>> "vfio: subchannel %s has already been attached" (featuring
>> cssid.ssid.devid) into "device is already attached"
>>
>> Also now all the devices have been migrated to use the new
>> vfio_attach_device/vfio_detach_device API, let's turn the
>> legacy functions into static functions, local to container.c.
>>
>> Signed-off-by: Eric Auger 
>> Signed-off-by: Yi Liu 
>> Signed-off-by: Zhenzhong Duan 
>> Reviewed-by: Matthew Rosato 
>>
>> ---
>>
>> v3:
>> - simplified vbasedev->dev setting
>>
>> v2 -> v3:
>> - Hopefully fix confusion beteen vbasedev->name, mdevid and sysfsdev
>>  while keeping into account Matthew's comment
>>  https://lore.kernel.org/qemu-devel/6e04ab8f-dc84-e9c2-deea-
>> 2b6b31678...@linux.ibm.com/
>> ---
>> include/hw/vfio/vfio-common.h |   5 --
>> hw/vfio/ccw.c | 122 +-
>> hw/vfio/common.c  |  10 +--
>> 3 files changed, 37 insertions(+), 100 deletions(-)
>>
>> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
>> index 12fbfbc37d..c486bdef2a 100644
>> --- a/include/hw/vfio/vfio-common.h
>> +++ b/include/hw/vfio/vfio-common.h
>> @@ -202,7 +202,6 @@ typedef struct {
>> hwaddr pages;
>> } VFIOBitmap;
>>
>> -void vfio_put_base_device(VFIODevice *vbasedev);
>> void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
>> void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
>> void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
>> @@ -220,11 +219,7 @@ void vfio_region_unmap(VFIORegion *region);
>> void vfio_region_exit(VFIORegion *region);
>> void vfio_region_finalize(VFIORegion *region);
>> void vfio_reset_handler(void *opaque);
>> -VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp);
>> -void vfio_put_group(VFIOGroup *group);
>> struct vfio_device_info *vfio_get_device_info(int fd);
>> -int vfio_get_device(VFIOGroup *group, const char *name,
>> -VFIODevice *vbasedev, Error **errp);
>> int vfio_attach_device(char *name, VFIODevice *vbasedev,
>>AddressSpace *as, Error **errp);
>> void vfio_detach_device(VFIODevice *vbasedev);
>> diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
>> index 1e2fce83b0..6ec35fedc9 100644
>> --- a/hw/vfio/ccw.c
>> +++ b/hw/vfio/ccw.c
>> @@ -572,88 +572,15 @@ static void vfio_ccw_put_region(VFIOCCWDevice
>> *vcdev)
>> g_free(vcdev->io_region);
>> }
>>
>> -static void vfio_ccw_put_device(VFIOCCWDevice *vcdev)
>> -{
>> -g_free(vcdev->vdev.name);
>> -vfio_put_base_device(>vdev);
>> -}
>> -
>> -static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev,
>> -Error **errp)
>> -{
>> -S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
>> -char *name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
>> - cdev->hostid.ssid,
>> - cdev->hostid.devid);
>> -VFIODevice *vbasedev;
>> -
>> -QLIST_FOREACH(vbasedev, >device_list, next) {
>> -if (strcmp(vbasedev->name, name) == 0) {
>> -error_setg(errp, "vfio: subchannel %s has already been 
>> attached",
>> -   name);
>> -goto out_err;
>> -}
>> -}
>> -
>> -/*
>> - * All vfio-ccw devices are believed to operate in a way compatible with
>> - * discarding of memory in RAM blocks, ie. pages pinned in the host are
>> - * in the current working set of the guest driver and therefore never
>> - * overlap e.g., with pages available to the guest balloon driver.  This
>> - * needs to be set before vfio_get_device() for vfio common to handle
>> - * ram_block_discard_disable().
>> - */
>> -vcdev->vdev.ram_block_discard_allowed = true;
>> -
>> -if (vfio_get_device(group, cdev->mdevid, >vdev, errp)) {
>> -goto out_err;
>> -}
>> -
>> -vcdev->vdev.ops = _ccw_ops;
>> -vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
>> -vcdev->vdev.name = name;
>> -vcdev->vdev.dev = DEVICE(vcdev);
>> -
>> -return;
>> -
>> -out_err:
>> -g_free(name);
>> -}
>> -
>> -static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, Error **errp)
>> -{
>> -char *tmp, group_path[PATH_MAX];
>> -ssize_t len;
>> -int groupid;
>> -
>> -tmp = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/%s/iommu_group",
>> -  cdev->hostid.cssid, cdev->hostid.ssid,
>> -  cdev->hostid.devid, cdev->mdevid);
>> -len = readlink(tmp, group_path, sizeof(group_path));
>> -g_free(tmp);

Re: [PATCH 15/19] parallels: Remove unnecessary data_end field

2023-10-08 Thread Alexander Ivanov




On 10/7/23 19:54, Mike Maslenkin wrote:

On Sat, Oct 7, 2023 at 5:30 PM Alexander Ivanov
 wrote:



On 10/7/23 13:21, Mike Maslenkin wrote:

On Sat, Oct 7, 2023 at 1:18 PM Alexander Ivanov
  wrote:

On 10/6/23 21:43, Mike Maslenkin wrote:

On Mon, Oct 2, 2023 at 12:01 PM Alexander Ivanov
  wrote:

Since we have used bitmap, field data_end in BDRVParallelsState is
redundant and can be removed.

Add parallels_data_end() helper and remove data_end handling.

Signed-off-by: Alexander Ivanov
---
block/parallels.c | 33 +
block/parallels.h |  1 -
2 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 48ea5b3f03..80a7171b84 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -265,6 +265,13 @@ static void parallels_free_used_bitmap(BlockDriverState 
*bs)
g_free(s->used_bmap);
}

+static int64_t parallels_data_end(BDRVParallelsState *s)
+{
+int64_t data_end = s->data_start * BDRV_SECTOR_SIZE;
+data_end += s->used_bmap_size * s->cluster_size;
+return data_end;
+}
+
int64_t parallels_allocate_host_clusters(BlockDriverState *bs,
 int64_t *clusters)
{
@@ -275,7 +282,7 @@ int64_t parallels_allocate_host_clusters(BlockDriverState 
*bs,

first_free = find_first_zero_bit(s->used_bmap, s->used_bmap_size);
if (first_free == s->used_bmap_size) {
-host_off = s->data_end * BDRV_SECTOR_SIZE;
+host_off = parallels_data_end(s);
prealloc_clusters = *clusters + s->prealloc_size / s->tracks;
bytes = prealloc_clusters * s->cluster_size;

@@ -297,9 +304,6 @@ int64_t parallels_allocate_host_clusters(BlockDriverState 
*bs,
s->used_bmap = bitmap_zero_extend(s->used_bmap, s->used_bmap_size,
  new_usedsize);
s->used_bmap_size = new_usedsize;
-if (host_off + bytes > s->data_end * BDRV_SECTOR_SIZE) {
-s->data_end = (host_off + bytes) / BDRV_SECTOR_SIZE;
-}
} else {
next_used = find_next_bit(s->used_bmap, s->used_bmap_size, 
first_free);

@@ -315,8 +319,7 @@ int64_t parallels_allocate_host_clusters(BlockDriverState 
*bs,
 * branch. In the other case we are likely re-using hole. 
Preallocate
 * the space if required by the prealloc_mode.
 */
-if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE &&
-host_off < s->data_end * BDRV_SECTOR_SIZE) {
+if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
ret = bdrv_pwrite_zeroes(bs->file, host_off, bytes, 0);
if (ret < 0) {
return ret;
@@ -757,13 +760,7 @@ parallels_check_outside_image(BlockDriverState *bs, 
BdrvCheckResult *res,
}
}

-if (high_off == 0) {
-res->image_end_offset = s->data_end << BDRV_SECTOR_BITS;
-} else {
-res->image_end_offset = high_off + s->cluster_size;
-s->data_end = res->image_end_offset >> BDRV_SECTOR_BITS;
-}
-
+res->image_end_offset = parallels_data_end(s);
return 0;
}

@@ -806,7 +803,6 @@ parallels_check_leak(BlockDriverState *bs, BdrvCheckResult 
*res,
res->check_errors++;
return ret;
}
-s->data_end = res->image_end_offset >> BDRV_SECTOR_BITS;

parallels_free_used_bitmap(bs);
ret = parallels_fill_used_bitmap(bs);
@@ -1361,8 +1357,7 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,
}

s->data_start = data_start;
-s->data_end = s->data_start;
-if (s->data_end < (s->header_size >> BDRV_SECTOR_BITS)) {
+if (s->data_start < (s->header_size >> BDRV_SECTOR_BITS)) {
/*
 * There is not enough unused space to fit to block align between 
BAT
 * and actual data. We can't avoid read-modify-write...
@@ -1403,11 +1398,10 @@ static int parallels_open(BlockDriverState *bs, QDict 
*options, int flags,

for (i = 0; i < s->bat_size; i++) {
sector = bat2sect(s, i);
-if (sector + s->tracks > s->data_end) {
-s->data_end = sector + s->tracks;
+if (sector + s->tracks > file_nb_sectors) {
+need_check = true;
}
}
-need_check = need_check || s->data_end > file_nb_sectors;

ret = parallels_fill_used_bitmap(bs);
if (ret == -ENOMEM) {
@@ -1461,7 +1455,6 @@ static int 
parallels_truncate_unused_clusters(BlockDriverState *bs)
end_off = (end_off + 1) * s->cluster_size;
}
end_off += s->data_start * BDRV_SECTOR_SIZE;
-s->data_end = end_off / BDRV_SECTOR_SIZE;
return bdrv_truncate(bs->file, end_off, true, PREALLOC_MODE_OFF, 0, 
NULL);
}

diff --git a/block/parallels.h b/block/parallels.h
index 18b4f8068e..a6a048d890 100644
--- a/block/parallels.h
+++ 

RE: [PATCH v2 3/3] target/hexagon: avoid shadowing globals

2023-10-08 Thread Brian Cain


> -Original Message-
> From: ltaylorsimp...@gmail.com 
> Sent: Friday, October 6, 2023 11:01 AM
> To: Brian Cain ; qemu-devel@nongnu.org
> Cc: arm...@redhat.com; richard.hender...@linaro.org; phi...@linaro.org;
> peter.mayd...@linaro.org; Matheus Bernardino (QUIC)
> ; stefa...@redhat.com; a...@rev.ng;
> a...@rev.ng; Marco Liebel (QUIC) 
> Subject: RE: [PATCH v2 3/3] target/hexagon: avoid shadowing globals
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> > -Original Message-
> > From: Brian Cain 
> > Sent: Thursday, October 5, 2023 4:22 PM
> > To: qemu-devel@nongnu.org
> > Cc: bc...@quicinc.com; arm...@redhat.com; richard.hender...@linaro.org;
> > phi...@linaro.org; peter.mayd...@linaro.org; quic_mathb...@quicinc.com;
> > stefa...@redhat.com; a...@rev.ng; a...@rev.ng;
> > quic_mlie...@quicinc.com; ltaylorsimp...@gmail.com
> > Subject: [PATCH v2 3/3] target/hexagon: avoid shadowing globals
> >
> > The typedef `vaddr` is shadowed by `vaddr` identifiers, so we rename the
> > identifiers to avoid shadowing the type name.
> >
> > The global `cpu_env` is shadowed by local `cpu_env` arguments, so we
> > rename the function arguments to avoid shadowing the global.
> >
> > Signed-off-by: Brian Cain 
> > ---
> >  target/hexagon/genptr.c | 56 -
> >  target/hexagon/genptr.h | 18 
> >  target/hexagon/mmvec/system_ext_mmvec.c |  4 +-
> > target/hexagon/mmvec/system_ext_mmvec.h |  2 +-
> >  target/hexagon/op_helper.c  |  4 +-
> >  5 files changed, 42 insertions(+), 42 deletions(-)
> >
> > diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index
> > 217bc7bb5a..11377ac92b 100644
> > --- a/target/hexagon/genptr.c
> > +++ b/target/hexagon/genptr.c
> > @@ -334,28 +334,28 @@ void gen_set_byte_i64(int N, TCGv_i64 result,
> TCGv
> > src)
> >  tcg_gen_deposit_i64(result, result, src64, N * 8, 8);  }
> >
> > -static inline void gen_load_locked4u(TCGv dest, TCGv vaddr, int
> > mem_index)
> > +static inline void gen_load_locked4u(TCGv dest, TCGv v_addr, int
> > +mem_index)
> 
> I'd recommend moving both the type and the arg name to the new line, also
> indent the new line.
> static inline void gen_load_locked4u(TCGv dest, TCGv v_addr,
>   int 
> mem_index)
> 
> 
> >
> > -static inline void gen_load_locked8u(TCGv_i64 dest, TCGv vaddr, int
> > mem_index)
> > +static inline void gen_load_locked8u(TCGv_i64 dest, TCGv v_addr, int
> > +mem_index)
> 
> Ditto
> 
> >  static inline void gen_store_conditional4(DisasContext *ctx,
> > -  TCGv pred, TCGv vaddr, TCGv src)
> > +  TCGv pred, TCGv v_addr, TCGv
> > + src)
> 
> Ditto
> 
> >  zero = tcg_constant_tl(0);
> > @@ -374,13 +374,13 @@ static inline void
> > gen_store_conditional4(DisasContext *ctx,  }
> >
> >  static inline void gen_store_conditional8(DisasContext *ctx,
> > -  TCGv pred, TCGv vaddr, TCGv_i64 
> > src)
> > +  TCGv pred, TCGv v_addr,
> > + TCGv_i64 src)
> 
> Indent
> 
> > -void mem_gather_store(CPUHexagonState *env, target_ulong vaddr, int
> > slot)
> > +void mem_gather_store(CPUHexagonState *env, target_ulong v_addr, int
> > +slot)
> 
> Ditto
> 
> > -void mem_gather_store(CPUHexagonState *env, target_ulong vaddr, int
> > slot);
> > +void mem_gather_store(CPUHexagonState *env, target_ulong v_addr, int
> > +slot);
> 
> Ditto

I could be mistaken but AFAICT none of these lines are wrapped in the way 
they're quoted above  in my patch (nor the baseline).  I don't think any of 
these lines exceed 80 columns, so they shouldn't need wrapping, either.

I double checked how it's displayed at the archive 
https://lists.gnu.org/archive/html/qemu-devel/2023-10/msg01667.html to make 
sure that it wasn't a misconfiguration of my mailer.  For another perspective - 
refer to the commit used to create this patch: 
https://github.com/quic/qemu/commit/7f20565d403d16337ab6d69ee663121a3eef71e6

Is your review comment that "these lines should be wrapped and when you do, 
make sure you do it like this"?  Or "if you are going to wrap them, wrap them 
like this"?  Or something else?

> Otherwise,
> Reviewed-by: Taylor Simpson 
> 



[PATCH QEMU] tulip: Fix LXT970 PHY registers

2023-10-08 Thread ~disean
From: Dmitry Borisov 

Fix incorrect MII status value (0xf02c).

Use default values from a 21143-based board:
https://www.beowulf.org/pipermail/tulip-bug/2000-February/000485.html

Signed-off-by: Dmitry Borisov 
---
 hw/net/tulip.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)
 mode change 100644 => 100755 hw/net/tulip.c

diff --git a/hw/net/tulip.c b/hw/net/tulip.c
old mode 100644
new mode 100755
index 915e5fb595..43e8f4bcb5
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -415,14 +415,15 @@ static void tulip_update_rs(TULIPState *s, int state)
 trace_tulip_rx_state(tulip_rx_state_name(state));
 }
 
+/* LEVEL1 LXT970 PHY registers */
 static uint16_t tulip_mdi_default[] = {
 /* MDI Registers 0 - 6, 7 */
-0x3100, 0xf02c, 0x7810, 0x, 0x0501, 0x4181, 0x, 0x,
+0x1000, 0x782d, 0x7810, 0x0001, 0x01e1, 0x41e1, 0x0001, 0x,
 /* MDI Registers 8 - 15 */
 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
 /* MDI Registers 16 - 31 */
-0x0003, 0x, 0x0001, 0x, 0x, 0x, 0x, 0x,
-0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
+0x, 0x, 0x4000, 0x, 0x38c8, 0x0010, 0x, 0x0002,
+0x0001, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
 };
 
 /* Readonly mask for MDI (PHY) registers */
-- 
2.38.5



[PATCH QEMU] tulip: Fix LXT970 PHY registers

2023-10-08 Thread ~disean
From: Dmitry Borisov 

Fix incorrect MII status value (0xf02c).

Use default values from a 21143-based board:
https://www.beowulf.org/pipermail/tulip-bug/2000-February/000485.html

Signed-off-by: Dmitry Borisov 
---
 hw/net/tulip.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)
 mode change 100644 => 100755 hw/net/tulip.c

diff --git a/hw/net/tulip.c b/hw/net/tulip.c
old mode 100644
new mode 100755
index 915e5fb595..43e8f4bcb5
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -415,14 +415,15 @@ static void tulip_update_rs(TULIPState *s, int state)
 trace_tulip_rx_state(tulip_rx_state_name(state));
 }
 
+/* LEVEL1 LXT970 PHY registers */
 static uint16_t tulip_mdi_default[] = {
 /* MDI Registers 0 - 6, 7 */
-0x3100, 0xf02c, 0x7810, 0x, 0x0501, 0x4181, 0x, 0x,
+0x1000, 0x782d, 0x7810, 0x0001, 0x01e1, 0x41e1, 0x0001, 0x,
 /* MDI Registers 8 - 15 */
 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
 /* MDI Registers 16 - 31 */
-0x0003, 0x, 0x0001, 0x, 0x, 0x, 0x, 0x,
-0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
+0x, 0x, 0x4000, 0x, 0x38c8, 0x0010, 0x, 0x0002,
+0x0001, 0x, 0x, 0x, 0x, 0x, 0x, 0x,
 };
 
 /* Readonly mask for MDI (PHY) registers */
-- 
2.38.5



Re: [PATCH v7 3/5] vhost-user-scsi: support reconnect to backend

2023-10-08 Thread Manos Pitsidianakis
Hello Li, I have some trivial style comments you could possibly address 
in a next version:


On Sun, 08 Oct 2023 12:12, Li Feng  wrote:

diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index df6b66cc1a..5df24faff4 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -39,26 +39,56 @@ static const int user_feature_bits[] = {
VHOST_INVALID_FEATURE_BIT
};

+static int vhost_user_scsi_start(VHostUserSCSI *s, Error **errp)
+{
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+int ret;
+
+ret = vhost_scsi_common_start(vsc, errp);
+s->started_vu = (ret < 0 ? false : true);


-+s->started_vu = (ret < 0 ? false : true);
++s->started_vu = !(ret < 0);

static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t 
status)

{
VHostUserSCSI *s = (VHostUserSCSI *)vdev;
+DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;


-+DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;
++DeviceState *dev = DEVICE(vdev);


+static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
+{
+VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+VHostUserSCSI *s = VHOST_USER_SCSI(vdev);
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
+int ret = 0;
+
+if (s->connected) {
+return 0;
+}
+s->connected = true;
+
+vsc->dev.num_queues = vs->conf.num_queues;
+vsc->dev.nvqs = VIRTIO_SCSI_VQ_NUM_FIXED + vs->conf.num_queues;
+vsc->dev.vqs = s->vhost_vqs;
+vsc->dev.vq_index = 0;
+vsc->dev.backend_features = 0;
+
+ret = vhost_dev_init(>dev, >vhost_user, VHOST_BACKEND_TYPE_USER, 0,
+ errp);
+if (ret < 0) {
+return ret;
+}
+
+/* restore vhost state */
+if (virtio_device_started(vdev, vdev->status)) {
+ret = vhost_user_scsi_start(s, errp);
+if (ret < 0) {
+return ret;
+}
+}
+
+return 0;
+}



-+if (virtio_device_started(vdev, vdev->status)) {
-+ret = vhost_user_scsi_start(s, errp);
-+if (ret < 0) {
-+return ret;
-+}
-+}
-+
-+return 0;
-+}
++if (virtio_device_started(vdev, vdev->status)) {
++ret = vhost_user_scsi_start(s, errp);
++}
++
++return ret;
++}

[skipping..]


+static int vhost_user_scsi_realize_connect(VHostUserSCSI *s, Error **errp)
+{
+DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;



-+DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;
++DeviceState *dev = DEVICE(s);


diff --git a/include/hw/virtio/vhost-user-scsi.h 
b/include/hw/virtio/vhost-user-scsi.h
index 521b08e559..b405ec952a 100644
--- a/include/hw/virtio/vhost-user-scsi.h
+++ b/include/hw/virtio/vhost-user-scsi.h
@@ -29,6 +29,10 @@ OBJECT_DECLARE_SIMPLE_TYPE(VHostUserSCSI, VHOST_USER_SCSI)
struct VHostUserSCSI {
VHostSCSICommon parent_obj;
VhostUserState vhost_user;
+bool connected;
+bool started_vu;
+
+struct vhost_virtqueue *vhost_vqs;


+bool connected;
+bool started_vu;
-+
+struct vhost_virtqueue *vhost_vqs;

See 
https://www.qemu.org/docs/master/devel/style.html#qemu-object-model-declarations

The definition should look like:

struct VHostUserSCSI {
   VHostSCSICommon parent_obj;

   /* Properties */
   bool connected;
   bool started_vu;

   VhostUserState vhost_user;
   struct vhost_virtqueue *vhost_vqs;
}



Re: [PATCH] hw/virtio/virtio-gpu: Fix compiler warning when compiling with -Wshadow

2023-10-08 Thread Philippe Mathieu-Daudé

On 8/10/23 10:57, Michael S. Tsirkin wrote:

On Fri, Oct 06, 2023 at 06:45:08PM +0200, Thomas Huth wrote:

Avoid using trivial variable names in macros, otherwise we get
the following compiler warning when compiling with -Wshadow=local:

In file included from ../../qemu/hw/display/virtio-gpu-virgl.c:19:
../../home/thuth/devel/qemu/hw/display/virtio-gpu-virgl.c:
  In function ‘virgl_cmd_submit_3d’:
../../qemu/include/hw/virtio/virtio-gpu.h:228:16: error: declaration of ‘s’
  shadows a previous local [-Werror=shadow=compatible-local]
   228 | size_t s;
   |^
../../qemu/hw/display/virtio-gpu-virgl.c:215:5: note: in expansion of macro
  ‘VIRTIO_GPU_FILL_CMD’
   215 | VIRTIO_GPU_FILL_CMD(cs);
   | ^~~
../../qemu/hw/display/virtio-gpu-virgl.c:213:12: note: shadowed declaration
  is here
   213 | size_t s;
   |^
cc1: all warnings being treated as errors

Signed-off-by: Thomas Huth 
---
  include/hw/virtio/virtio-gpu.h | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 390c4642b8..8b7e3faf01 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -225,13 +225,13 @@ struct VhostUserGPU {
  };
  
  #define VIRTIO_GPU_FILL_CMD(out) do {   \

-size_t s;   \
-s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
+size_t s_;  \
+s_ = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
 , sizeof(out));  \
-if (s != sizeof(out)) { \
+if (s_ != sizeof(out)) {\
  qemu_log_mask(LOG_GUEST_ERROR,  \
"%s: command size incorrect %zu vs %zu\n",\
-  __func__, s, sizeof(out));\
+  __func__, s_, sizeof(out));   \
  return; \
  }   \
  } while (0)


This is not really enough I think. Someone might
use another macro as parameter to this macro and we'll get
a mess. We want something that's specific to this macro.
How about VIRTIO_GPU_FILL_CMD_s ?


Or unmacroize as:

  virtio_gpu_fill_cmd(struct virtio_gpu_ctrl_command *cmd,
  const void *data, size_t size);



[PATCH] migration: Use g_autofree to simplify ram_dirty_bitmap_reload()

2023-10-08 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
Based-on: 
---
 migration/ram.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 982fbbeee1..4cb948cfd0 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -4164,11 +4164,11 @@ bool ram_dirty_bitmap_reload(MigrationState *s, 
RAMBlock *block, Error **errp)
 {
 /* from_dst_file is always valid because we're within rp_thread */
 QEMUFile *file = s->rp_state.from_dst_file;
-unsigned long *le_bitmap, nbits = block->used_length >> TARGET_PAGE_BITS;
+unsigned long *le_bitmap = NULL;
+unsigned long nbits = block->used_length >> TARGET_PAGE_BITS;
 uint64_t local_size = DIV_ROUND_UP(nbits, 8);
 uint64_t size, end_mark;
 RAMState *rs = ram_state;
-bool result = false;
 
 trace_ram_dirty_bitmap_reload_begin(block->idstr);
 
@@ -4193,7 +4193,7 @@ bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock 
*block, Error **errp)
 if (size != local_size) {
 error_setg(errp, "ramblock '%s' bitmap size mismatch (0x%"PRIx64
" != 0x%"PRIx64")", block->idstr, size, local_size);
-goto out;
+return false;
 }
 
 size = qemu_get_buffer(file, (uint8_t *)le_bitmap, local_size);
@@ -4203,13 +4203,13 @@ bool ram_dirty_bitmap_reload(MigrationState *s, 
RAMBlock *block, Error **errp)
 error_setg(errp, "read bitmap failed for ramblock '%s': "
"(size 0x%"PRIx64", got: 0x%"PRIx64")",
block->idstr, local_size, size);
-goto out;
+return false;
 }
 
 if (end_mark != RAMBLOCK_RECV_BITMAP_ENDING) {
 error_setg(errp, "ramblock '%s' end mark incorrect: 0x%"PRIx64,
block->idstr, end_mark);
-goto out;
+return false;
 }
 
 /*
@@ -4241,10 +4241,7 @@ bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock 
*block, Error **errp)
  */
 migration_rp_kick(s);
 
-result = true;
-out:
-g_free(le_bitmap);
-return result;
+return true;
 }
 
 static int ram_resume_prepare(MigrationState *s, void *opaque)
-- 
2.41.0




Re: [PATCH v3 03/10] migration: Refactor error handling in source return path

2023-10-08 Thread Philippe Mathieu-Daudé

On 5/10/23 18:05, Peter Xu wrote:

On Thu, Oct 05, 2023 at 08:11:33AM +0200, Philippe Mathieu-Daudé wrote:

Hi Peter,

On 5/10/23 00:02, Peter Xu wrote:

rp_state.error was a boolean used to show error happened in return path
thread.  That's not only duplicating error reporting (migrate_set_error),
but also not good enough in that we only do error_report() and set it to
true, we never can keep a history of the exact error and show it in
query-migrate.

To make this better, a few things done:

- Use error_setg() rather than error_report() across the whole lifecycle
  of return path thread, keeping the error in an Error*.

- Use migrate_set_error() to apply that captured error to the global
  migration object when error occured in this thread.

- With above, no need to have mark_source_rp_bad(), remove it, alongside
  with rp_state.error itself.

Signed-off-by: Peter Xu 
---
   migration/migration.h  |   1 -
   migration/ram.h|   5 +-
   migration/migration.c  | 123 ++---
   migration/ram.c|  41 +++---
   migration/trace-events |   4 +-
   5 files changed, 79 insertions(+), 95 deletions(-)




-int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block)
+int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *block, Error **errp)
   {
   int ret = -EINVAL;
   /* from_dst_file is always valid because we're within rp_thread */




@@ -4193,16 +4194,16 @@ int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock 
*block)
   ret = qemu_file_get_error(file);
   if (ret || size != local_size) {
-error_report("%s: read bitmap failed for ramblock '%s': %d"
- " (size 0x%"PRIx64", got: 0x%"PRIx64")",
- __func__, block->idstr, ret, local_size, size);
+error_setg(errp, "read bitmap failed for ramblock '%s': %d"
+   " (size 0x%"PRIx64", got: 0x%"PRIx64")",
+   block->idstr, ret, local_size, size);
   ret = -EIO;
   goto out;
   }
   if (end_mark != RAMBLOCK_RECV_BITMAP_ENDING) {
-error_report("%s: ramblock '%s' end mark incorrect: 0x%"PRIx64,
- __func__, block->idstr, end_mark);
+error_setg(errp, "ramblock '%s' end mark incorrect: 0x%"PRIx64,
+   block->idstr, end_mark);
   ret = -EINVAL;
   goto out;
   }


This function returns -EIO/-EINVAL errors, propagated to its 2 callers
  - migrate_handle_rp_recv_bitmap()
  - migrate_handle_rp_resume_ack()


It was only called in migrate_handle_rp_recv_bitmap(), but I think I see
what you meant..


which are only used in source_return_path_thread() where the return
value is only checked as boolean.

Could we simplify them returning a boolean (which is the pattern with
functions taking an Error** as last parameter)?


Yes, with errp passed in, the "int" retcode is slightly duplicated.  I can
add one more patch on top of this as further cleanup, as below.

Thanks,

===8<===
 From b1052befd72beb129012afddf5647339fe4e257c Mon Sep 17 00:00:00 2001
From: Peter Xu 
Date: Thu, 5 Oct 2023 12:03:44 -0400
Subject: [PATCH] migration: Change ram_dirty_bitmap_reload() retval to bool
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Now we have a Error** passed into the return path thread stack, which is
even clearer than an int retval.  Change ram_dirty_bitmap_reload() and the
callers to use a bool instead to replace errnos.

Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Peter Xu 
---
  migration/ram.h   |  2 +-
  migration/migration.c | 18 +-
  migration/ram.c   | 24 +++-
  3 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/migration/ram.h b/migration/ram.h
index 14ed666d58..af0290f8ab 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -72,7 +72,7 @@ void ramblock_recv_bitmap_set(RAMBlock *rb, void *host_addr);
  void ramblock_recv_bitmap_set_range(RAMBlock *rb, void *host_addr, size_t nr);
  int64_t ramblock_recv_bitmap_send(QEMUFile *file,
const char *block_name);
-int ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *rb, Error **errp);
+bool ram_dirty_bitmap_reload(MigrationState *s, RAMBlock *rb, Error **errp);
  bool ramblock_page_is_discarded(RAMBlock *rb, ram_addr_t start);
  void postcopy_preempt_shutdown_file(MigrationState *s);
  void *postcopy_preempt_thread(void *opaque);
diff --git a/migration/migration.c b/migration/migration.c
index 1a7f214fcf..e7375810be 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1837,29 +1837,29 @@ static void migrate_handle_rp_req_pages(MigrationState 
*ms, const char* rbname,
  ram_save_queue_pages(rbname, start, len, errp);
  }
  
-static int migrate_handle_rp_recv_bitmap(MigrationState *s, char *block_name,

- Error **errp)
+static bool 

Re: [PATCH 1/3] via-ide: Fix legacy mode emulation

2023-10-08 Thread BALATON Zoltan

On Sun, 8 Oct 2023, Mark Cave-Ayland wrote:

On 05/10/2023 23:13, BALATON Zoltan wrote:


The initial value for BARs were set in reset method for emulating
legacy mode at start but this does not work because PCI code resets
BARs after calling device reset method.


This is certainly something I've noticed when testing previous versions of 
the VIA patches. Perhaps it's worth a separate thread to the PCI devs?


I think I brought up this back then but was told current PCI code won't 
change and since that could break everything else that makes sense so this 
is something that we should take as given and accomodate that.



Additionally the values
written to BARs were also wrong.


I don't believe this is correct: according to the datasheet the values on 
reset are the ones given in the current reset code, so even if the reset 
function is overridden at a later data during PCI bus reset, I would leave 
these for now since it is a different issue.


Those values are missing the IO space bit for one so they can't be correct 
as a BAR value no matter what the datasheet says. And since they are 
ineffective now I think it's best to remove them to avoid confusion.



Move setting the BARs to a callback on writing the PCI config regsiter
that sets the compatibility mode (which firmwares needing this mode
seem to do) and fix their values to program it to use legacy port
numbers. As noted in a comment, we only do this when the BARs were
unset before, because logs from real machine show this is how real
chip works, even if it contradicts the data sheet which is not very
clear about this.

Signed-off-by: BALATON Zoltan 
---
  hw/ide/via.c | 35 ++-
  1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index fff23803a6..8186190207 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -132,11 +132,6 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
   PCI_STATUS_DEVSEL_MEDIUM);
  -pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, 0x01f0);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_1, 0x03f4);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x0170);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x0374);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0xcc01); /* BMIBA: 
20-23h */

  pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x010e);
/* IDE chip enable, IDE configuration 1/2, IDE FIFO Configuration*/
@@ -159,6 +154,35 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_long(pci_conf + 0xc0, 0x00020001);
  }
  +static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr,
+  uint32_t val, int len)
+{
+pci_default_write_config(pd, addr, val, len);
+/*
+ * Only set BARs if they are unset. Logs from real hardware show that
+ * writing class_prog to enable compatibility mode after BARs were set
+ * (possibly by firmware) it will use ports set by BARs not ISA ports
+ * (e.g. pegasos2 Linux does this and calls it non-100% native mode).


Can you remind me again where the references are to non-100% native mode? The 
only thing I can find in Linux is 
https://github.com/torvalds/linux/blob/master/arch/powerpc/platforms/chrp/pci.c#L360 
but that simply forces a switch to legacy mode, with no mention of "non-100% 
native mode".


It was discussed somewhere in the via-ide thread we had when this was last 
touched for pegasos2 in March 2020. Basically the non-100% native mode is 
when ports are set by BARs but IRQs are still hard coded to 14-15. Linux 
can work with all 3 possible modes: legacy (both ports and IRQs are hard 
coded to ISA values), native (using BARs and PCI config 0x3c for a single 
interrupt for both channels, vt82c686 data sheet does not document this 
but vt8231 has a comment saying native mode only) and non-100% native mode 
where BARs are effective to set port addresses but IRQs don't respect 0x3c 
but use 14-15 as in legacy mode. Some machines only work in non-100% 
native mode such as pegasos2 and Linux has some quirks for this. Other 
OSes running on this machine work with what the firmware has set up and 
can't work with anything else so we need to emulate what those OSes want 
(which matches real hardware) because Linux can usually cope anyway. On 
pegasso2 MorphOS uses BARs but expects IRQ 14-15 which is what the 
firmware also sets up by setting mode to native in the PCI config of the 
IDE func yet IRQs are fixed at 14-15. Linux forces its driver to use 
legacy interrupts by setting mode back to legacy but it still uses BARs 
and this is what it calls non-100% native mode. On amigaone firmware sets 
legacy mode and AmigaOS does not change this but uses it with legacy ports 
and IRQs. Linux finds the same and uses legacy mode on amigaone.


+ * But if 0x8a is written after reset without setting BARs then we 
want

+ * legacy ports (this is done by AmigaOne 

RE: [PATCH v4 10/15] vfio/ccw: Use vfio_[attach/detach]_device

2023-10-08 Thread Duan, Zhenzhong
Hi Eric,

>-Original Message-
>From: Eric Auger 
>Sent: Wednesday, October 4, 2023 11:44 PM
>Subject: [PATCH v4 10/15] vfio/ccw: Use vfio_[attach/detach]_device
>
>Let the vfio-ccw device use vfio_attach_device() and
>vfio_detach_device(), hence hiding the details of the used
>IOMMU backend.
>
>Note that the migration reduces the following trace
>"vfio: subchannel %s has already been attached" (featuring
>cssid.ssid.devid) into "device is already attached"
>
>Also now all the devices have been migrated to use the new
>vfio_attach_device/vfio_detach_device API, let's turn the
>legacy functions into static functions, local to container.c.
>
>Signed-off-by: Eric Auger 
>Signed-off-by: Yi Liu 
>Signed-off-by: Zhenzhong Duan 
>Reviewed-by: Matthew Rosato 
>
>---
>
>v3:
>- simplified vbasedev->dev setting
>
>v2 -> v3:
>- Hopefully fix confusion beteen vbasedev->name, mdevid and sysfsdev
>  while keeping into account Matthew's comment
>  https://lore.kernel.org/qemu-devel/6e04ab8f-dc84-e9c2-deea-
>2b6b31678...@linux.ibm.com/
>---
> include/hw/vfio/vfio-common.h |   5 --
> hw/vfio/ccw.c | 122 +-
> hw/vfio/common.c  |  10 +--
> 3 files changed, 37 insertions(+), 100 deletions(-)
>
>diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
>index 12fbfbc37d..c486bdef2a 100644
>--- a/include/hw/vfio/vfio-common.h
>+++ b/include/hw/vfio/vfio-common.h
>@@ -202,7 +202,6 @@ typedef struct {
> hwaddr pages;
> } VFIOBitmap;
>
>-void vfio_put_base_device(VFIODevice *vbasedev);
> void vfio_disable_irqindex(VFIODevice *vbasedev, int index);
> void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index);
> void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index);
>@@ -220,11 +219,7 @@ void vfio_region_unmap(VFIORegion *region);
> void vfio_region_exit(VFIORegion *region);
> void vfio_region_finalize(VFIORegion *region);
> void vfio_reset_handler(void *opaque);
>-VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp);
>-void vfio_put_group(VFIOGroup *group);
> struct vfio_device_info *vfio_get_device_info(int fd);
>-int vfio_get_device(VFIOGroup *group, const char *name,
>-VFIODevice *vbasedev, Error **errp);
> int vfio_attach_device(char *name, VFIODevice *vbasedev,
>AddressSpace *as, Error **errp);
> void vfio_detach_device(VFIODevice *vbasedev);
>diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
>index 1e2fce83b0..6ec35fedc9 100644
>--- a/hw/vfio/ccw.c
>+++ b/hw/vfio/ccw.c
>@@ -572,88 +572,15 @@ static void vfio_ccw_put_region(VFIOCCWDevice
>*vcdev)
> g_free(vcdev->io_region);
> }
>
>-static void vfio_ccw_put_device(VFIOCCWDevice *vcdev)
>-{
>-g_free(vcdev->vdev.name);
>-vfio_put_base_device(>vdev);
>-}
>-
>-static void vfio_ccw_get_device(VFIOGroup *group, VFIOCCWDevice *vcdev,
>-Error **errp)
>-{
>-S390CCWDevice *cdev = S390_CCW_DEVICE(vcdev);
>-char *name = g_strdup_printf("%x.%x.%04x", cdev->hostid.cssid,
>- cdev->hostid.ssid,
>- cdev->hostid.devid);
>-VFIODevice *vbasedev;
>-
>-QLIST_FOREACH(vbasedev, >device_list, next) {
>-if (strcmp(vbasedev->name, name) == 0) {
>-error_setg(errp, "vfio: subchannel %s has already been attached",
>-   name);
>-goto out_err;
>-}
>-}
>-
>-/*
>- * All vfio-ccw devices are believed to operate in a way compatible with
>- * discarding of memory in RAM blocks, ie. pages pinned in the host are
>- * in the current working set of the guest driver and therefore never
>- * overlap e.g., with pages available to the guest balloon driver.  This
>- * needs to be set before vfio_get_device() for vfio common to handle
>- * ram_block_discard_disable().
>- */
>-vcdev->vdev.ram_block_discard_allowed = true;
>-
>-if (vfio_get_device(group, cdev->mdevid, >vdev, errp)) {
>-goto out_err;
>-}
>-
>-vcdev->vdev.ops = _ccw_ops;
>-vcdev->vdev.type = VFIO_DEVICE_TYPE_CCW;
>-vcdev->vdev.name = name;
>-vcdev->vdev.dev = DEVICE(vcdev);
>-
>-return;
>-
>-out_err:
>-g_free(name);
>-}
>-
>-static VFIOGroup *vfio_ccw_get_group(S390CCWDevice *cdev, Error **errp)
>-{
>-char *tmp, group_path[PATH_MAX];
>-ssize_t len;
>-int groupid;
>-
>-tmp = g_strdup_printf("/sys/bus/css/devices/%x.%x.%04x/%s/iommu_group",
>-  cdev->hostid.cssid, cdev->hostid.ssid,
>-  cdev->hostid.devid, cdev->mdevid);
>-len = readlink(tmp, group_path, sizeof(group_path));
>-g_free(tmp);
>-
>-if (len <= 0 || len >= sizeof(group_path)) {
>-error_setg(errp, "vfio: no iommu_group found");
>-return NULL;
>-}
>-
>-group_path[len] = 0;
>-
>-if (sscanf(basename(group_path), "%d", ) != 1) {
>-error_setg(errp, "vfio: failed to read %s", 

[PATCH v7 1/5] vhost-user-common: send get_inflight_fd once

2023-10-08 Thread Li Feng
Currently the get_inflight_fd will be sent every time the device is started, and
the backend will allocate shared memory to save the inflight state. If the
backend finds that it receives the second get_inflight_fd, it will release the
previous shared memory, which breaks inflight working logic.

This patch is a preparation for the following patches.

Signed-off-by: Li Feng 
Reviewed-by: Raphael Norwitz 
---
 hw/scsi/vhost-scsi-common.c | 37 ++---
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
index a06f01af26..a61cd0e907 100644
--- a/hw/scsi/vhost-scsi-common.c
+++ b/hw/scsi/vhost-scsi-common.c
@@ -52,20 +52,28 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 
 vsc->dev.acked_features = vdev->guest_features;
 
-assert(vsc->inflight == NULL);
-vsc->inflight = g_new0(struct vhost_inflight, 1);
-ret = vhost_dev_get_inflight(>dev,
- vs->conf.virtqueue_size,
- vsc->inflight);
+ret = vhost_dev_prepare_inflight(>dev, vdev);
 if (ret < 0) {
-error_report("Error get inflight: %d", -ret);
+error_report("Error setting inflight format: %d", -ret);
 goto err_guest_notifiers;
 }
 
-ret = vhost_dev_set_inflight(>dev, vsc->inflight);
-if (ret < 0) {
-error_report("Error set inflight: %d", -ret);
-goto err_guest_notifiers;
+if (vsc->inflight) {
+if (!vsc->inflight->addr) {
+ret = vhost_dev_get_inflight(>dev,
+vs->conf.virtqueue_size,
+vsc->inflight);
+if (ret < 0) {
+error_report("Error getting inflight: %d", -ret);
+goto err_guest_notifiers;
+}
+}
+
+ret = vhost_dev_set_inflight(>dev, vsc->inflight);
+if (ret < 0) {
+error_report("Error setting inflight: %d", -ret);
+goto err_guest_notifiers;
+}
 }
 
 ret = vhost_dev_start(>dev, vdev, true);
@@ -85,9 +93,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 return ret;
 
 err_guest_notifiers:
-g_free(vsc->inflight);
-vsc->inflight = NULL;
-
 k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
 err_host_notifiers:
 vhost_dev_disable_notifiers(>dev, vdev);
@@ -111,12 +116,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
 }
 assert(ret >= 0);
 
-if (vsc->inflight) {
-vhost_dev_free_inflight(vsc->inflight);
-g_free(vsc->inflight);
-vsc->inflight = NULL;
-}
-
 vhost_dev_disable_notifiers(>dev, vdev);
 }
 
-- 
2.41.0




[PATCH v7 0/5] Implement reconnect for vhost-user-scsi

2023-10-08 Thread Li Feng
Changes for v7:
- [PATCH 3/5] vhost-user-scsi: support reconnect to backend
  - Add reporting the error in vhost-scsi;
  - Rebase to master and fix the conflict.
- Add "Reviewed-by" tags.

Changes for v6:
- [PATCH] vhost-user: fix lost reconnect
  - Fix missing assign event_cb.

Changes for v5:
- No logic has been changed, just move part of the code from patch 4 to patch 5.

Changes for v4:
- Merge
  https://lore.kernel.org/all/20230830045722.611224-1-fen...@smartx.com/ to
  this series.
- Add ERRP_GUARD in vhost_user_scsi_realize;
- Reword the commit messages.

Changes for v3:
- Split the vhost_user_scsi_handle_output to a separate patch;
- Move the started_vu from vhost scsi common header to vhost-user-scsi header;
- Fix a log print error;

Changes for v2:
- Split the v1 patch to small separate patchset;
- New patch for fixing fd leak, which has sent to reviewers in another
  mail;
- Implement the `vhost_user_scsi_handle_output`;
- Add the started_vu safe check;
- Fix error handler;
- Check the inflight before set/get inflight fd.

Li Feng (5):
  vhost-user-common: send get_inflight_fd once
  vhost: move and rename the conn retry times
  vhost-user-scsi: support reconnect to backend
  vhost-user-scsi: start vhost when guest kicks
  vhost-user: fix lost reconnect

 hw/block/vhost-user-blk.c |   6 +-
 hw/scsi/vhost-scsi-common.c   |  47 ++---
 hw/scsi/vhost-scsi.c  |   6 +-
 hw/scsi/vhost-user-scsi.c | 253 +++---
 hw/virtio/vhost-user-gpio.c   |   5 +-
 hw/virtio/vhost-user.c|  10 +-
 include/hw/virtio/vhost-scsi-common.h |   2 +-
 include/hw/virtio/vhost-user-scsi.h   |   4 +
 include/hw/virtio/vhost-user.h|   3 +-
 include/hw/virtio/vhost.h |   2 +
 10 files changed, 278 insertions(+), 60 deletions(-)

-- 
2.41.0




[PATCH v7 4/5] vhost-user-scsi: start vhost when guest kicks

2023-10-08 Thread Li Feng
Let's keep the same behavior as vhost-user-blk.

Some old guests kick virtqueue before setting VIRTIO_CONFIG_S_DRIVER_OK.

Signed-off-by: Li Feng 
Reviewed-by: Raphael Norwitz 
---
 hw/scsi/vhost-user-scsi.c | 48 +++
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 5df24faff4..5afb514398 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -111,8 +111,48 @@ static void vhost_user_scsi_reset(VirtIODevice *vdev)
 }
 }
 
-static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+static void vhost_user_scsi_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 {
+VHostUserSCSI *s = (VHostUserSCSI *)vdev;
+DeviceState *dev = >parent_obj.parent_obj.parent_obj.parent_obj;
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
+
+Error *local_err = NULL;
+int i, ret;
+
+if (!vdev->start_on_kick) {
+return;
+}
+
+if (!s->connected) {
+return;
+}
+
+if (vhost_dev_is_started(>dev)) {
+return;
+}
+
+/*
+ * Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
+ * vhost here instead of waiting for .set_status().
+ */
+ret = vhost_user_scsi_start(s, _err);
+if (ret < 0) {
+error_reportf_err(local_err, "vhost-user-scsi: vhost start failed: ");
+qemu_chr_fe_disconnect(>conf.chardev);
+return;
+}
+
+/* Kick right away to begin processing requests already in vring */
+for (i = 0; i < vsc->dev.nvqs; i++) {
+VirtQueue *kick_vq = virtio_get_queue(vdev, i);
+
+if (!virtio_queue_get_desc_addr(vdev, i)) {
+continue;
+}
+event_notifier_set(virtio_queue_get_host_notifier(kick_vq));
+}
 }
 
 static int vhost_user_scsi_connect(DeviceState *dev, Error **errp)
@@ -242,9 +282,9 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-virtio_scsi_common_realize(dev, vhost_dummy_handle_output,
-   vhost_dummy_handle_output,
-   vhost_dummy_handle_output, );
+virtio_scsi_common_realize(dev, vhost_user_scsi_handle_output,
+   vhost_user_scsi_handle_output,
+   vhost_user_scsi_handle_output, );
 if (err != NULL) {
 error_propagate(errp, err);
 return;
-- 
2.41.0




[PATCH v7 5/5] vhost-user: fix lost reconnect

2023-10-08 Thread Li Feng
When the vhost-user is reconnecting to the backend, and if the vhost-user fails
at the get_features in vhost_dev_init(), then the reconnect will fail
and it will not be retriggered forever.

The reason is:
When the vhost-user fails at get_features, the vhost_dev_cleanup will be called
immediately.

vhost_dev_cleanup calls 'memset(hdev, 0, sizeof(struct vhost_dev))'.

The reconnect path is:
vhost_user_blk_event
   vhost_user_async_close(.. vhost_user_blk_disconnect ..)
 qemu_chr_fe_set_handlers <- clear the notifier callback
   schedule vhost_user_async_close_bh

The vhost->vdev is null, so the vhost_user_blk_disconnect will not be
called, then the event fd callback will not be reinstalled.

All vhost-user devices have this issue, including vhost-user-blk/scsi.

With this patch, if the vdev->vdev is null, the fd callback will still
be reinstalled.

Fixes: 71e076a07d ("hw/virtio: generalise CHR_EVENT_CLOSED handling")

Signed-off-by: Li Feng 
Reviewed-by: Raphael Norwitz 
---
 hw/block/vhost-user-blk.c  |  2 +-
 hw/scsi/vhost-user-scsi.c  |  3 ++-
 hw/virtio/vhost-user-gpio.c|  2 +-
 hw/virtio/vhost-user.c | 10 --
 include/hw/virtio/vhost-user.h |  3 ++-
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 3c69fa47d5..95c758200d 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -391,7 +391,7 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent 
event)
 case CHR_EVENT_CLOSED:
 /* defer close until later to avoid circular close */
 vhost_user_async_close(dev, >chardev, >dev,
-   vhost_user_blk_disconnect);
+   vhost_user_blk_disconnect, 
vhost_user_blk_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 5afb514398..dbe864c0e5 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -234,7 +234,8 @@ static void vhost_user_scsi_event(void *opaque, 
QEMUChrEvent event)
 case CHR_EVENT_CLOSED:
 /* defer close until later to avoid circular close */
 vhost_user_async_close(dev, >conf.chardev, >dev,
-   vhost_user_scsi_disconnect);
+   vhost_user_scsi_disconnect,
+   vhost_user_scsi_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index fc784e4213..aff2d7eff6 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -289,7 +289,7 @@ static void vu_gpio_event(void *opaque, QEMUChrEvent event)
 case CHR_EVENT_CLOSED:
 /* defer close until later to avoid circular close */
 vhost_user_async_close(dev, >chardev, >vhost_dev,
-   vu_gpio_disconnect);
+   vu_gpio_disconnect, vu_gpio_event);
 break;
 case CHR_EVENT_BREAK:
 case CHR_EVENT_MUX_IN:
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 3766b415f8..7395bfc531 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -2765,6 +2765,7 @@ typedef struct {
 DeviceState *dev;
 CharBackend *cd;
 struct vhost_dev *vhost;
+IOEventHandler *event_cb;
 } VhostAsyncCallback;
 
 static void vhost_user_async_close_bh(void *opaque)
@@ -2779,7 +2780,10 @@ static void vhost_user_async_close_bh(void *opaque)
  */
 if (vhost->vdev) {
 data->cb(data->dev);
-}
+} else if (data->event_cb) {
+qemu_chr_fe_set_handlers(data->cd, NULL, NULL, data->event_cb,
+ NULL, data->dev, NULL, true);
+   }
 
 g_free(data);
 }
@@ -2791,7 +2795,8 @@ static void vhost_user_async_close_bh(void *opaque)
  */
 void vhost_user_async_close(DeviceState *d,
 CharBackend *chardev, struct vhost_dev *vhost,
-vu_async_close_fn cb)
+vu_async_close_fn cb,
+IOEventHandler *event_cb)
 {
 if (!runstate_check(RUN_STATE_SHUTDOWN)) {
 /*
@@ -2807,6 +2812,7 @@ void vhost_user_async_close(DeviceState *d,
 data->dev = d;
 data->cd = chardev;
 data->vhost = vhost;
+data->event_cb = event_cb;
 
 /* Disable any further notifications on the chardev */
 qemu_chr_fe_set_handlers(chardev,
diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h
index 9f9ddf878d..6b06ecb1bd 100644
--- a/include/hw/virtio/vhost-user.h
+++ b/include/hw/virtio/vhost-user.h
@@ -106,6 +106,7 @@ typedef void (*vu_async_close_fn)(DeviceState *cb);
 
 void vhost_user_async_close(DeviceState *d,
 CharBackend *chardev, struct vhost_dev *vhost,
-vu_async_close_fn cb);
+ 

[PATCH v7 2/5] vhost: move and rename the conn retry times

2023-10-08 Thread Li Feng
Multiple devices need this macro, move it to a common header.

Signed-off-by: Li Feng 
Reviewed-by: Raphael Norwitz 
---
 hw/block/vhost-user-blk.c   | 4 +---
 hw/virtio/vhost-user-gpio.c | 3 +--
 include/hw/virtio/vhost.h   | 2 ++
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index eecf3f7a81..3c69fa47d5 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -32,8 +32,6 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/runstate.h"
 
-#define REALIZE_CONNECTION_RETRIES 3
-
 static const int user_feature_bits[] = {
 VIRTIO_BLK_F_SIZE_MAX,
 VIRTIO_BLK_F_SEG_MAX,
@@ -482,7 +480,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, 
Error **errp)
 s->inflight = g_new0(struct vhost_inflight, 1);
 s->vhost_vqs = g_new0(struct vhost_virtqueue, s->num_queues);
 
-retries = REALIZE_CONNECTION_RETRIES;
+retries = VU_REALIZE_CONN_RETRIES;
 assert(!*errp);
 do {
 if (*errp) {
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index 3d7fae3984..fc784e4213 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -15,7 +15,6 @@
 #include "standard-headers/linux/virtio_ids.h"
 #include "trace.h"
 
-#define REALIZE_CONNECTION_RETRIES 3
 #define VHOST_NVQS 2
 
 /* Features required from VirtIO */
@@ -365,7 +364,7 @@ static void vu_gpio_device_realize(DeviceState *dev, Error 
**errp)
 qemu_chr_fe_set_handlers(>chardev, NULL, NULL, vu_gpio_event, NULL,
  dev, NULL, true);
 
-retries = REALIZE_CONNECTION_RETRIES;
+retries = VU_REALIZE_CONN_RETRIES;
 g_assert(!*errp);
 do {
 if (*errp) {
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 6a173cb9fa..ca3131b1af 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -8,6 +8,8 @@
 #define VHOST_F_DEVICE_IOTLB 63
 #define VHOST_USER_F_PROTOCOL_FEATURES 30
 
+#define VU_REALIZE_CONN_RETRIES 3
+
 /* Generic structures common for any vhost based device. */
 
 struct vhost_inflight {
-- 
2.41.0




[PATCH v7 3/5] vhost-user-scsi: support reconnect to backend

2023-10-08 Thread Li Feng
If the backend crashes and restarts, the device is broken.
This patch adds reconnect for vhost-user-scsi.

This patch also improves the error messages, and reports some silent errors.

Tested with spdk backend.

Signed-off-by: Li Feng 
---
 hw/scsi/vhost-scsi-common.c   |  16 +-
 hw/scsi/vhost-scsi.c  |   6 +-
 hw/scsi/vhost-user-scsi.c | 204 +++---
 include/hw/virtio/vhost-scsi-common.h |   2 +-
 include/hw/virtio/vhost-user-scsi.h   |   4 +
 5 files changed, 202 insertions(+), 30 deletions(-)

diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
index a61cd0e907..4c8637045d 100644
--- a/hw/scsi/vhost-scsi-common.c
+++ b/hw/scsi/vhost-scsi-common.c
@@ -16,6 +16,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
 #include "hw/virtio/vhost.h"
@@ -25,7 +26,7 @@
 #include "hw/virtio/virtio-access.h"
 #include "hw/fw-path-provider.h"
 
-int vhost_scsi_common_start(VHostSCSICommon *vsc)
+int vhost_scsi_common_start(VHostSCSICommon *vsc, Error **errp)
 {
 int ret, i;
 VirtIODevice *vdev = VIRTIO_DEVICE(vsc);
@@ -35,18 +36,19 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 VirtIOSCSICommon *vs = (VirtIOSCSICommon *)vsc;
 
 if (!k->set_guest_notifiers) {
-error_report("binding does not support guest notifiers");
+error_setg(errp, "binding does not support guest notifiers");
 return -ENOSYS;
 }
 
 ret = vhost_dev_enable_notifiers(>dev, vdev);
 if (ret < 0) {
+error_setg_errno(errp, -ret, "Error enabling host notifiers");
 return ret;
 }
 
 ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, true);
 if (ret < 0) {
-error_report("Error binding guest notifier");
+error_setg_errno(errp, -ret, "Error binding guest notifier");
 goto err_host_notifiers;
 }
 
@@ -54,7 +56,7 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 
 ret = vhost_dev_prepare_inflight(>dev, vdev);
 if (ret < 0) {
-error_report("Error setting inflight format: %d", -ret);
+error_setg_errno(errp, -ret, "Error setting inflight format");
 goto err_guest_notifiers;
 }
 
@@ -64,21 +66,21 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
 vs->conf.virtqueue_size,
 vsc->inflight);
 if (ret < 0) {
-error_report("Error getting inflight: %d", -ret);
+error_setg_errno(errp, -ret, "Error getting inflight");
 goto err_guest_notifiers;
 }
 }
 
 ret = vhost_dev_set_inflight(>dev, vsc->inflight);
 if (ret < 0) {
-error_report("Error setting inflight: %d", -ret);
+error_setg_errno(errp, -ret, "Error setting inflight");
 goto err_guest_notifiers;
 }
 }
 
 ret = vhost_dev_start(>dev, vdev, true);
 if (ret < 0) {
-error_report("Error start vhost dev");
+error_setg_errno(errp, -ret, "Error starting vhost dev");
 goto err_guest_notifiers;
 }
 
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 443f67daa4..95cadb93e7 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -75,6 +75,7 @@ static int vhost_scsi_start(VHostSCSI *s)
 int ret, abi_version;
 VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
 const VhostOps *vhost_ops = vsc->dev.vhost_ops;
+Error *local_err = NULL;
 
 ret = vhost_ops->vhost_scsi_get_abi_version(>dev, _version);
 if (ret < 0) {
@@ -88,14 +89,15 @@ static int vhost_scsi_start(VHostSCSI *s)
 return -ENOSYS;
 }
 
-ret = vhost_scsi_common_start(vsc);
+ret = vhost_scsi_common_start(vsc, _err);
 if (ret < 0) {
+error_reportf_err(local_err, "Error starting vhost-scsi");
 return ret;
 }
 
 ret = vhost_scsi_set_endpoint(s);
 if (ret < 0) {
-error_report("Error setting vhost-scsi endpoint");
+error_reportf_err(local_err, "Error setting vhost-scsi endpoint");
 vhost_scsi_common_stop(vsc);
 }
 
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index df6b66cc1a..5df24faff4 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -39,26 +39,56 @@ static const int user_feature_bits[] = {
 VHOST_INVALID_FEATURE_BIT
 };
 
+static int vhost_user_scsi_start(VHostUserSCSI *s, Error **errp)
+{
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+int ret;
+
+ret = vhost_scsi_common_start(vsc, errp);
+s->started_vu = (ret < 0 ? false : true);
+
+return ret;
+}
+
+static void vhost_user_scsi_stop(VHostUserSCSI *s)
+{
+VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
+
+if (!s->started_vu) {
+return;
+}
+s->started_vu = false;
+
+vhost_scsi_common_stop(vsc);
+}
+
 static void vhost_user_scsi_set_status(VirtIODevice *vdev, 

Re: [PATCH] contrib/vhost-user-gpu: Fix compiler warning when compiling with -Wshadow

2023-10-08 Thread Michael S. Tsirkin
On Fri, Oct 06, 2023 at 07:35:18PM +0200, Thomas Huth wrote:
> Rename some variables to avoid compiler warnings when compiling
> with -Wshadow=local.
> 
> Signed-off-by: Thomas Huth 
> ---
>  contrib/vhost-user-gpu/vugpu.h  | 8 
>  contrib/vhost-user-gpu/vhost-user-gpu.c | 6 +++---
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h
> index 509b679f03..5cede45134 100644
> --- a/contrib/vhost-user-gpu/vugpu.h
> +++ b/contrib/vhost-user-gpu/vugpu.h
> @@ -164,12 +164,12 @@ struct virtio_gpu_ctrl_command {
>  };
>  
>  #define VUGPU_FILL_CMD(out) do {\
> -size_t s;   \
> -s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
> +size_t s_;  \
> +s_ = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
> , sizeof(out));  \
> -if (s != sizeof(out)) { \
> +if (s_ != sizeof(out)) {\
>  g_critical("%s: command size incorrect %zu vs %zu", \
> -   __func__, s, sizeof(out));   \
> +   __func__, s_, sizeof(out));  \
>  return; \
>  }   \
>  } while (0)

Oh wait this is the same issue. Fixes it now but can start failing
down the road. Let's use something specific to this macro.
VUGPU_FILL_CMD_s ?


> diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c 
> b/contrib/vhost-user-gpu/vhost-user-gpu.c
> index aa304475a0..bb41758e34 100644
> --- a/contrib/vhost-user-gpu/vhost-user-gpu.c
> +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c
> @@ -834,7 +834,7 @@ vg_resource_flush(VuGpu *g,
>  .width = width,
>  .height = height,
>  };
> -pixman_image_t *i =
> +pixman_image_t *img =
>  pixman_image_create_bits(pixman_image_get_format(res->image),
>   msg->payload.update.width,
>   msg->payload.update.height,
> @@ -842,11 +842,11 @@ vg_resource_flush(VuGpu *g,
>payload.update.data),
>   width * bpp);
>  pixman_image_composite(PIXMAN_OP_SRC,
> -   res->image, NULL, i,
> +   res->image, NULL, img,
> extents->x1, extents->y1,
> 0, 0, 0, 0,
> width, height);
> -pixman_image_unref(i);
> +pixman_image_unref(img);
>  vg_send_msg(g, msg, -1);
>  g_free(msg);
>  }
> -- 
> 2.41.0




Re: [PATCH] hw/virtio/virtio-gpu: Fix compiler warning when compiling with -Wshadow

2023-10-08 Thread Michael S. Tsirkin
On Fri, Oct 06, 2023 at 06:45:08PM +0200, Thomas Huth wrote:
> Avoid using trivial variable names in macros, otherwise we get
> the following compiler warning when compiling with -Wshadow=local:
> 
> In file included from ../../qemu/hw/display/virtio-gpu-virgl.c:19:
> ../../home/thuth/devel/qemu/hw/display/virtio-gpu-virgl.c:
>  In function ‘virgl_cmd_submit_3d’:
> ../../qemu/include/hw/virtio/virtio-gpu.h:228:16: error: declaration of ‘s’
>  shadows a previous local [-Werror=shadow=compatible-local]
>   228 | size_t s;
>   |^
> ../../qemu/hw/display/virtio-gpu-virgl.c:215:5: note: in expansion of macro
>  ‘VIRTIO_GPU_FILL_CMD’
>   215 | VIRTIO_GPU_FILL_CMD(cs);
>   | ^~~
> ../../qemu/hw/display/virtio-gpu-virgl.c:213:12: note: shadowed declaration
>  is here
>   213 | size_t s;
>   |^
> cc1: all warnings being treated as errors
> 
> Signed-off-by: Thomas Huth 
> ---
>  include/hw/virtio/virtio-gpu.h | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> index 390c4642b8..8b7e3faf01 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -225,13 +225,13 @@ struct VhostUserGPU {
>  };
>  
>  #define VIRTIO_GPU_FILL_CMD(out) do {   \
> -size_t s;   \
> -s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
> +size_t s_;  \
> +s_ = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
> , sizeof(out));  \
> -if (s != sizeof(out)) { \
> +if (s_ != sizeof(out)) {\
>  qemu_log_mask(LOG_GUEST_ERROR,  \
>"%s: command size incorrect %zu vs %zu\n",\
> -  __func__, s, sizeof(out));\
> +  __func__, s_, sizeof(out));   \
>  return; \
>  }   \
>  } while (0)

This is not really enough I think. Someone might
use another macro as parameter to this macro and we'll get
a mess. We want something that's specific to this macro.
How about VIRTIO_GPU_FILL_CMD_s ?


> -- 
> 2.41.0




Re: [PATCH v6 1/5] vhost-user-common: send get_inflight_fd once

2023-10-08 Thread Li Feng
On Sun, Oct 8, 2023 at 4:51 PM Michael S. Tsirkin  wrote:
>
> On Sun, Oct 08, 2023 at 04:49:05PM +0800, Li Feng wrote:
> > On Fri, Sep 29, 2023 at 8:55 AM Raphael Norwitz
> >  wrote:
> > >
> > >
> > >
> > > > On Sep 22, 2023, at 7:46 AM, Li Feng  wrote:
> > > >
> > > > Currently the get_inflight_fd will be sent every time the device is 
> > > > started, and
> > > > the backend will allocate shared memory to save the inflight state. If 
> > > > the
> > > > backend finds that it receives the second get_inflight_fd, it will 
> > > > release the
> > > > previous shared memory, which breaks inflight working logic.
> > > >
> > > > This patch is a preparation for the following patches.
> > >
> > > This looks identical to the v3 patch I reviewed? If I’ve missed something 
> > > can you please point it out?
> > Yes, nothing changed in this patch.
>
>
> Then you should include tags such as reviewed/acked by for previous
> version. if you drop tags you indicate to people they have to
> re-review.
> also, mentioning which patches changed in the cover letter is
> a courtesy to reviewers.
OK.

>
> > >
> > >
> > > > Signed-off-by: Li Feng 
> > > > ---
> > > > hw/scsi/vhost-scsi-common.c | 37 ++---
> > > > 1 file changed, 18 insertions(+), 19 deletions(-)
> > > >
> > > > diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
> > > > index a06f01af26..a61cd0e907 100644
> > > > --- a/hw/scsi/vhost-scsi-common.c
> > > > +++ b/hw/scsi/vhost-scsi-common.c
> > > > @@ -52,20 +52,28 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> > > >
> > > > vsc->dev.acked_features = vdev->guest_features;
> > > >
> > > > -assert(vsc->inflight == NULL);
> > > > -vsc->inflight = g_new0(struct vhost_inflight, 1);
> > > > -ret = vhost_dev_get_inflight(>dev,
> > > > - vs->conf.virtqueue_size,
> > > > - vsc->inflight);
> > > > +ret = vhost_dev_prepare_inflight(>dev, vdev);
> > > > if (ret < 0) {
> > > > -error_report("Error get inflight: %d", -ret);
> > > > +error_report("Error setting inflight format: %d", -ret);
> > > > goto err_guest_notifiers;
> > > > }
> > > >
> > > > -ret = vhost_dev_set_inflight(>dev, vsc->inflight);
> > > > -if (ret < 0) {
> > > > -error_report("Error set inflight: %d", -ret);
> > > > -goto err_guest_notifiers;
> > > > +if (vsc->inflight) {
> > > > +if (!vsc->inflight->addr) {
> > > > +ret = vhost_dev_get_inflight(>dev,
> > > > +vs->conf.virtqueue_size,
> > > > +vsc->inflight);
> > > > +if (ret < 0) {
> > > > +error_report("Error getting inflight: %d", -ret);
> > > > +goto err_guest_notifiers;
> > > > +}
> > > > +}
> > > > +
> > > > +ret = vhost_dev_set_inflight(>dev, vsc->inflight);
> > > > +if (ret < 0) {
> > > > +error_report("Error setting inflight: %d", -ret);
> > > > +goto err_guest_notifiers;
> > > > +}
> > > > }
> > > >
> > > > ret = vhost_dev_start(>dev, vdev, true);
> > > > @@ -85,9 +93,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> > > > return ret;
> > > >
> > > > err_guest_notifiers:
> > > > -g_free(vsc->inflight);
> > > > -vsc->inflight = NULL;
> > > > -
> > > > k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
> > > > err_host_notifiers:
> > > > vhost_dev_disable_notifiers(>dev, vdev);
> > > > @@ -111,12 +116,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
> > > > }
> > > > assert(ret >= 0);
> > > >
> > > > -if (vsc->inflight) {
> > > > -vhost_dev_free_inflight(vsc->inflight);
> > > > -g_free(vsc->inflight);
> > > > -vsc->inflight = NULL;
> > > > -}
> > > > -
> > > > vhost_dev_disable_notifiers(>dev, vdev);
> > > > }
> > > >
> > > > --
> > > > 2.41.0
> > > >
> > >
>



Re: [PATCH v6 0/5] Implement reconnect for vhost-user-scsi

2023-10-08 Thread Li Feng
On Sun, Oct 8, 2023 at 4:49 PM Michael S. Tsirkin  wrote:
>
> On Fri, Sep 22, 2023 at 07:46:10PM +0800, Li Feng wrote:
> > Changes for v6:
> > - [PATCH] vhost-user: fix lost reconnect
> >   - Fix missing assign event_cb.
>
>
> Pls don't make vN+1 a reply to vN - start a new thread
> with each version please.
OK.

>
> > Changes for v5:
> > - No logic has been changed, just move part of the code from patch 4 to 
> > patch 5.
> >
> > Changes for v4:
> > - Merge
> >   https://lore.kernel.org/all/20230830045722.611224-1-fen...@smartx.com/ to
> >   this series.
> > - Add ERRP_GUARD in vhost_user_scsi_realize;
> > - Reword the commit messages.
> >
> > Changes for v3:
> > - Split the vhost_user_scsi_handle_output to a separate patch;
> > - Move the started_vu from vhost scsi common header to vhost-user-scsi 
> > header;
> > - Fix a log print error;
> >
> > Changes for v2:
> > - Split the v1 patch to small separate patchset;
> > - New patch for fixing fd leak, which has sent to reviewers in another
> >   mail;
> > - Implement the `vhost_user_scsi_handle_output`;
> > - Add the started_vu safe check;
> > - Fix error handler;
> > - Check the inflight before set/get inflight fd.
> >
> > Li Feng (5):
> >   vhost-user-common: send get_inflight_fd once
> >   vhost: move and rename the conn retry times
> >   vhost-user-scsi: support reconnect to backend
> >   vhost-user-scsi: start vhost when guest kicks
> >   vhost-user: fix lost reconnect
> >
> >  hw/block/vhost-user-blk.c |   6 +-
> >  hw/scsi/vhost-scsi-common.c   |  47 ++---
> >  hw/scsi/vhost-scsi.c  |   5 +-
> >  hw/scsi/vhost-user-scsi.c | 253 +++---
> >  hw/virtio/vhost-user-gpio.c   |   5 +-
> >  hw/virtio/vhost-user.c|  10 +-
> >  include/hw/virtio/vhost-scsi-common.h |   2 +-
> >  include/hw/virtio/vhost-user-scsi.h   |   4 +
> >  include/hw/virtio/vhost-user.h|   3 +-
> >  include/hw/virtio/vhost.h |   2 +
> >  10 files changed, 277 insertions(+), 60 deletions(-)
> >
> > --
> > 2.41.0
>



Re: [PATCH] contrib/vhost-user-gpu: Fix compiler warning when compiling with -Wshadow

2023-10-08 Thread Michael S. Tsirkin
On Fri, Oct 06, 2023 at 07:35:18PM +0200, Thomas Huth wrote:
> Rename some variables to avoid compiler warnings when compiling
> with -Wshadow=local.
> 
> Signed-off-by: Thomas Huth 

Reviewed-by: Michael S. Tsirkin 


> ---
>  contrib/vhost-user-gpu/vugpu.h  | 8 
>  contrib/vhost-user-gpu/vhost-user-gpu.c | 6 +++---
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h
> index 509b679f03..5cede45134 100644
> --- a/contrib/vhost-user-gpu/vugpu.h
> +++ b/contrib/vhost-user-gpu/vugpu.h
> @@ -164,12 +164,12 @@ struct virtio_gpu_ctrl_command {
>  };
>  
>  #define VUGPU_FILL_CMD(out) do {\
> -size_t s;   \
> -s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
> +size_t s_;  \
> +s_ = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
> , sizeof(out));  \
> -if (s != sizeof(out)) { \
> +if (s_ != sizeof(out)) {\
>  g_critical("%s: command size incorrect %zu vs %zu", \
> -   __func__, s, sizeof(out));   \
> +   __func__, s_, sizeof(out));  \
>  return; \
>  }   \
>  } while (0)
> diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c 
> b/contrib/vhost-user-gpu/vhost-user-gpu.c
> index aa304475a0..bb41758e34 100644
> --- a/contrib/vhost-user-gpu/vhost-user-gpu.c
> +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c
> @@ -834,7 +834,7 @@ vg_resource_flush(VuGpu *g,
>  .width = width,
>  .height = height,
>  };
> -pixman_image_t *i =
> +pixman_image_t *img =
>  pixman_image_create_bits(pixman_image_get_format(res->image),
>   msg->payload.update.width,
>   msg->payload.update.height,
> @@ -842,11 +842,11 @@ vg_resource_flush(VuGpu *g,
>payload.update.data),
>   width * bpp);
>  pixman_image_composite(PIXMAN_OP_SRC,
> -   res->image, NULL, i,
> +   res->image, NULL, img,
> extents->x1, extents->y1,
> 0, 0, 0, 0,
> width, height);
> -pixman_image_unref(i);
> +pixman_image_unref(img);
>  vg_send_msg(g, msg, -1);
>  g_free(msg);
>  }
> -- 
> 2.41.0




Re: [PATCH v6 1/5] vhost-user-common: send get_inflight_fd once

2023-10-08 Thread Li Feng
On Fri, Sep 29, 2023 at 8:55 AM Raphael Norwitz
 wrote:
>
>
>
> > On Sep 22, 2023, at 7:46 AM, Li Feng  wrote:
> >
> > Currently the get_inflight_fd will be sent every time the device is 
> > started, and
> > the backend will allocate shared memory to save the inflight state. If the
> > backend finds that it receives the second get_inflight_fd, it will release 
> > the
> > previous shared memory, which breaks inflight working logic.
> >
> > This patch is a preparation for the following patches.
>
> This looks identical to the v3 patch I reviewed? If I’ve missed something can 
> you please point it out?
Yes, nothing changed in this patch.

>
>
> > Signed-off-by: Li Feng 
> > ---
> > hw/scsi/vhost-scsi-common.c | 37 ++---
> > 1 file changed, 18 insertions(+), 19 deletions(-)
> >
> > diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
> > index a06f01af26..a61cd0e907 100644
> > --- a/hw/scsi/vhost-scsi-common.c
> > +++ b/hw/scsi/vhost-scsi-common.c
> > @@ -52,20 +52,28 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> >
> > vsc->dev.acked_features = vdev->guest_features;
> >
> > -assert(vsc->inflight == NULL);
> > -vsc->inflight = g_new0(struct vhost_inflight, 1);
> > -ret = vhost_dev_get_inflight(>dev,
> > - vs->conf.virtqueue_size,
> > - vsc->inflight);
> > +ret = vhost_dev_prepare_inflight(>dev, vdev);
> > if (ret < 0) {
> > -error_report("Error get inflight: %d", -ret);
> > +error_report("Error setting inflight format: %d", -ret);
> > goto err_guest_notifiers;
> > }
> >
> > -ret = vhost_dev_set_inflight(>dev, vsc->inflight);
> > -if (ret < 0) {
> > -error_report("Error set inflight: %d", -ret);
> > -goto err_guest_notifiers;
> > +if (vsc->inflight) {
> > +if (!vsc->inflight->addr) {
> > +ret = vhost_dev_get_inflight(>dev,
> > +vs->conf.virtqueue_size,
> > +vsc->inflight);
> > +if (ret < 0) {
> > +error_report("Error getting inflight: %d", -ret);
> > +goto err_guest_notifiers;
> > +}
> > +}
> > +
> > +ret = vhost_dev_set_inflight(>dev, vsc->inflight);
> > +if (ret < 0) {
> > +error_report("Error setting inflight: %d", -ret);
> > +goto err_guest_notifiers;
> > +}
> > }
> >
> > ret = vhost_dev_start(>dev, vdev, true);
> > @@ -85,9 +93,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> > return ret;
> >
> > err_guest_notifiers:
> > -g_free(vsc->inflight);
> > -vsc->inflight = NULL;
> > -
> > k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
> > err_host_notifiers:
> > vhost_dev_disable_notifiers(>dev, vdev);
> > @@ -111,12 +116,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
> > }
> > assert(ret >= 0);
> >
> > -if (vsc->inflight) {
> > -vhost_dev_free_inflight(vsc->inflight);
> > -g_free(vsc->inflight);
> > -vsc->inflight = NULL;
> > -}
> > -
> > vhost_dev_disable_notifiers(>dev, vdev);
> > }
> >
> > --
> > 2.41.0
> >
>



Re: [PATCH v6 1/5] vhost-user-common: send get_inflight_fd once

2023-10-08 Thread Michael S. Tsirkin
On Sun, Oct 08, 2023 at 04:49:05PM +0800, Li Feng wrote:
> On Fri, Sep 29, 2023 at 8:55 AM Raphael Norwitz
>  wrote:
> >
> >
> >
> > > On Sep 22, 2023, at 7:46 AM, Li Feng  wrote:
> > >
> > > Currently the get_inflight_fd will be sent every time the device is 
> > > started, and
> > > the backend will allocate shared memory to save the inflight state. If the
> > > backend finds that it receives the second get_inflight_fd, it will 
> > > release the
> > > previous shared memory, which breaks inflight working logic.
> > >
> > > This patch is a preparation for the following patches.
> >
> > This looks identical to the v3 patch I reviewed? If I’ve missed something 
> > can you please point it out?
> Yes, nothing changed in this patch.


Then you should include tags such as reviewed/acked by for previous
version. if you drop tags you indicate to people they have to
re-review.
also, mentioning which patches changed in the cover letter is
a courtesy to reviewers.

> >
> >
> > > Signed-off-by: Li Feng 
> > > ---
> > > hw/scsi/vhost-scsi-common.c | 37 ++---
> > > 1 file changed, 18 insertions(+), 19 deletions(-)
> > >
> > > diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
> > > index a06f01af26..a61cd0e907 100644
> > > --- a/hw/scsi/vhost-scsi-common.c
> > > +++ b/hw/scsi/vhost-scsi-common.c
> > > @@ -52,20 +52,28 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> > >
> > > vsc->dev.acked_features = vdev->guest_features;
> > >
> > > -assert(vsc->inflight == NULL);
> > > -vsc->inflight = g_new0(struct vhost_inflight, 1);
> > > -ret = vhost_dev_get_inflight(>dev,
> > > - vs->conf.virtqueue_size,
> > > - vsc->inflight);
> > > +ret = vhost_dev_prepare_inflight(>dev, vdev);
> > > if (ret < 0) {
> > > -error_report("Error get inflight: %d", -ret);
> > > +error_report("Error setting inflight format: %d", -ret);
> > > goto err_guest_notifiers;
> > > }
> > >
> > > -ret = vhost_dev_set_inflight(>dev, vsc->inflight);
> > > -if (ret < 0) {
> > > -error_report("Error set inflight: %d", -ret);
> > > -goto err_guest_notifiers;
> > > +if (vsc->inflight) {
> > > +if (!vsc->inflight->addr) {
> > > +ret = vhost_dev_get_inflight(>dev,
> > > +vs->conf.virtqueue_size,
> > > +vsc->inflight);
> > > +if (ret < 0) {
> > > +error_report("Error getting inflight: %d", -ret);
> > > +goto err_guest_notifiers;
> > > +}
> > > +}
> > > +
> > > +ret = vhost_dev_set_inflight(>dev, vsc->inflight);
> > > +if (ret < 0) {
> > > +error_report("Error setting inflight: %d", -ret);
> > > +goto err_guest_notifiers;
> > > +}
> > > }
> > >
> > > ret = vhost_dev_start(>dev, vdev, true);
> > > @@ -85,9 +93,6 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> > > return ret;
> > >
> > > err_guest_notifiers:
> > > -g_free(vsc->inflight);
> > > -vsc->inflight = NULL;
> > > -
> > > k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
> > > err_host_notifiers:
> > > vhost_dev_disable_notifiers(>dev, vdev);
> > > @@ -111,12 +116,6 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
> > > }
> > > assert(ret >= 0);
> > >
> > > -if (vsc->inflight) {
> > > -vhost_dev_free_inflight(vsc->inflight);
> > > -g_free(vsc->inflight);
> > > -vsc->inflight = NULL;
> > > -}
> > > -
> > > vhost_dev_disable_notifiers(>dev, vdev);
> > > }
> > >
> > > --
> > > 2.41.0
> > >
> >




Re: [PATCH v6 0/5] Implement reconnect for vhost-user-scsi

2023-10-08 Thread Michael S. Tsirkin
On Fri, Sep 22, 2023 at 07:46:10PM +0800, Li Feng wrote:
> Changes for v6:
> - [PATCH] vhost-user: fix lost reconnect
>   - Fix missing assign event_cb.


Pls don't make vN+1 a reply to vN - start a new thread
with each version please.

> Changes for v5:
> - No logic has been changed, just move part of the code from patch 4 to patch 
> 5.
> 
> Changes for v4:
> - Merge
>   https://lore.kernel.org/all/20230830045722.611224-1-fen...@smartx.com/ to
>   this series.
> - Add ERRP_GUARD in vhost_user_scsi_realize;
> - Reword the commit messages.
> 
> Changes for v3:
> - Split the vhost_user_scsi_handle_output to a separate patch;
> - Move the started_vu from vhost scsi common header to vhost-user-scsi header;
> - Fix a log print error;
> 
> Changes for v2:
> - Split the v1 patch to small separate patchset;
> - New patch for fixing fd leak, which has sent to reviewers in another
>   mail;
> - Implement the `vhost_user_scsi_handle_output`;
> - Add the started_vu safe check;
> - Fix error handler;
> - Check the inflight before set/get inflight fd.
> 
> Li Feng (5):
>   vhost-user-common: send get_inflight_fd once
>   vhost: move and rename the conn retry times
>   vhost-user-scsi: support reconnect to backend
>   vhost-user-scsi: start vhost when guest kicks
>   vhost-user: fix lost reconnect
> 
>  hw/block/vhost-user-blk.c |   6 +-
>  hw/scsi/vhost-scsi-common.c   |  47 ++---
>  hw/scsi/vhost-scsi.c  |   5 +-
>  hw/scsi/vhost-user-scsi.c | 253 +++---
>  hw/virtio/vhost-user-gpio.c   |   5 +-
>  hw/virtio/vhost-user.c|  10 +-
>  include/hw/virtio/vhost-scsi-common.h |   2 +-
>  include/hw/virtio/vhost-user-scsi.h   |   4 +
>  include/hw/virtio/vhost-user.h|   3 +-
>  include/hw/virtio/vhost.h |   2 +
>  10 files changed, 277 insertions(+), 60 deletions(-)
> 
> -- 
> 2.41.0




Re: [PATCH v6 3/5] vhost-user-scsi: support reconnect to backend

2023-10-08 Thread Li Feng
Sorry, the reply is late due to being on vacation for half a month.

On Fri, Sep 29, 2023 at 8:55 AM Raphael Norwitz
 wrote:
>
> One comment on the logging stuff in vhost-scsi. As far as I can tell the 
> logging in vhost-user-scsi looks good.
>
> Markus - does this look better to you? Otherwise do you think we should also 
> fix up the vhost-user-blk realize function?
>
> > On Sep 22, 2023, at 7:46 AM, Li Feng  wrote:
> >
> > If the backend crashes and restarts, the device is broken.
> > This patch adds reconnect for vhost-user-scsi.
> >
> > This patch also improves the error messages, and reports some silent errors.
> >
> > Tested with spdk backend.
> >
> > Signed-off-by: Li Feng 
> > ---
> > hw/scsi/vhost-scsi-common.c   |  16 +-
> > hw/scsi/vhost-scsi.c  |   5 +-
> > hw/scsi/vhost-user-scsi.c | 204 +++---
> > include/hw/virtio/vhost-scsi-common.h |   2 +-
> > include/hw/virtio/vhost-user-scsi.h   |   4 +
> > 5 files changed, 201 insertions(+), 30 deletions(-)
> >
> > diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
> > index a61cd0e907..4c8637045d 100644
> > --- a/hw/scsi/vhost-scsi-common.c
> > +++ b/hw/scsi/vhost-scsi-common.c
> > @@ -16,6 +16,7 @@
> >  */
> >
> > #include "qemu/osdep.h"
> > +#include "qapi/error.h"
> > #include "qemu/error-report.h"
> > #include "qemu/module.h"
> > #include "hw/virtio/vhost.h"
> > @@ -25,7 +26,7 @@
> > #include "hw/virtio/virtio-access.h"
> > #include "hw/fw-path-provider.h"
> >
> > -int vhost_scsi_common_start(VHostSCSICommon *vsc)
> > +int vhost_scsi_common_start(VHostSCSICommon *vsc, Error **errp)
> > {
> > int ret, i;
> > VirtIODevice *vdev = VIRTIO_DEVICE(vsc);
> > @@ -35,18 +36,19 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> > VirtIOSCSICommon *vs = (VirtIOSCSICommon *)vsc;
> >
> > if (!k->set_guest_notifiers) {
> > -error_report("binding does not support guest notifiers");
> > +error_setg(errp, "binding does not support guest notifiers");
> > return -ENOSYS;
> > }
> >
> > ret = vhost_dev_enable_notifiers(>dev, vdev);
> > if (ret < 0) {
> > +error_setg_errno(errp, -ret, "Error enabling host notifiers");
> > return ret;
> > }
> >
> > ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, true);
> > if (ret < 0) {
> > -error_report("Error binding guest notifier");
> > +error_setg_errno(errp, -ret, "Error binding guest notifier");
> > goto err_host_notifiers;
> > }
> >
> > @@ -54,7 +56,7 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> >
> > ret = vhost_dev_prepare_inflight(>dev, vdev);
> > if (ret < 0) {
> > -error_report("Error setting inflight format: %d", -ret);
> > +error_setg_errno(errp, -ret, "Error setting inflight format");
> > goto err_guest_notifiers;
> > }
> >
> > @@ -64,21 +66,21 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
> > vs->conf.virtqueue_size,
> > vsc->inflight);
> > if (ret < 0) {
> > -error_report("Error getting inflight: %d", -ret);
> > +error_setg_errno(errp, -ret, "Error getting inflight");
> > goto err_guest_notifiers;
> > }
> > }
> >
> > ret = vhost_dev_set_inflight(>dev, vsc->inflight);
> > if (ret < 0) {
> > -error_report("Error setting inflight: %d", -ret);
> > +error_setg_errno(errp, -ret, "Error setting inflight");
> > goto err_guest_notifiers;
> > }
> > }
> >
> > ret = vhost_dev_start(>dev, vdev, true);
> > if (ret < 0) {
> > -error_report("Error start vhost dev");
> > +error_setg_errno(errp, -ret, "Error starting vhost dev");
> > goto err_guest_notifiers;
> > }
> >
> > diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
> > index 443f67daa4..01a3ab4277 100644
> > --- a/hw/scsi/vhost-scsi.c
> > +++ b/hw/scsi/vhost-scsi.c
> > @@ -75,6 +75,7 @@ static int vhost_scsi_start(VHostSCSI *s)
> > int ret, abi_version;
> > VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
> > const VhostOps *vhost_ops = vsc->dev.vhost_ops;
> > +Error *local_err = NULL;
> >
> > ret = vhost_ops->vhost_scsi_get_abi_version(>dev, _version);
> > if (ret < 0) {
> > @@ -88,14 +89,14 @@ static int vhost_scsi_start(VHostSCSI *s)
> > return -ENOSYS;
> > }
> >
> > -ret = vhost_scsi_common_start(vsc);
> > +ret = vhost_scsi_common_start(vsc, _err);
> > if (ret < 0) {
>
> Why aren’t you reporting the error here?
I will add reporting the error in the next version.

>
> > return ret;
> > }
> >
> > ret = vhost_scsi_set_endpoint(s);
> > if (ret < 0) {
> > -error_report("Error setting vhost-scsi endpoint");
> > +error_reportf_err(local_err, "Error setting vhost-scsi endpoint");
> > 

[PULL 1/2] target/loongarch: fix ASXE flag conflict

2023-10-08 Thread Song Gao
From: Jiajie Chen 

HW_FLAGS_EUEN_ASXE acccidentally conflicts with HW_FLAGS_CRMD_PG,
enabling LASX instructions even when CSR_EUEN.ASXE=0.

Closes: https://gitlab.com/qemu-project/qemu/-/issues/1907
Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Reviewed-by: Song Gao 
Message-Id: <20230930112837.1871691-...@jia.je>
Signed-off-by: Song Gao 
---
 target/loongarch/cpu.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 40e70a8119..8b54cf109c 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -458,11 +458,11 @@ static inline void set_pc(CPULoongArchState *env, 
uint64_t value)
  * LoongArch CPUs hardware flags.
  */
 #define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
-#define HW_FLAGS_CRMD_PGR_CSR_CRMD_PG_MASK   /* 0x10 */
 #define HW_FLAGS_EUEN_FPE   0x04
 #define HW_FLAGS_EUEN_SXE   0x08
-#define HW_FLAGS_EUEN_ASXE  0x10
+#define HW_FLAGS_CRMD_PGR_CSR_CRMD_PG_MASK   /* 0x10 */
 #define HW_FLAGS_VA32   0x20
+#define HW_FLAGS_EUEN_ASXE  0x40
 
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
 uint64_t *cs_base, uint32_t *flags)
-- 
2.25.1




[PULL 0/2] loongarch-to-apply queue

2023-10-08 Thread Song Gao
The following changes since commit 2f3913f4b2ad74baeb5a6f1d36efbd9ecdf1057d:

  Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu 
into staging (2023-10-05 09:01:01 -0400)

are available in the Git repository at:

  https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20231008

for you to fetch changes up to e1fc0cf1fb65c5f049bef4661d0e3278e51e2560:

  target/loongarch: Add preldx instruction (2023-10-08 15:02:15 +0800)


pull-loongarch-20231008


Jiajie Chen (1):
  target/loongarch: fix ASXE flag conflict

Song Gao (1):
  target/loongarch: Add preldx instruction

 target/loongarch/cpu.h | 4 ++--
 target/loongarch/disas.c   | 7 +++
 target/loongarch/insn_trans/trans_memory.c.inc | 5 +
 target/loongarch/insns.decode  | 3 +++
 4 files changed, 17 insertions(+), 2 deletions(-)




[PULL 2/2] target/loongarch: Add preldx instruction

2023-10-08 Thread Song Gao
Resolve the issue of starting the Loongnix 20.5[1] system failure.

Logs:
Loading Linux 4.19.0-19-loongson-3 ...
Loading initial ramdisk ...
PROGRESS CODE: V02010004 I0
PROGRESS CODE: V03101019 I0
Error: unknown opcode. 903a3e6c: 0x382c6d82

[1] 
http://pkg.loongnix.cn/loongnix/isos/Loongnix-20.5/Loongnix-20.5.cartoon.gui.loongarch64.en.qcow2

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Song Gao 
Message-Id: <20230905123910.3052023-1-gaos...@loongson.cn>
---
 target/loongarch/disas.c   | 7 +++
 target/loongarch/insn_trans/trans_memory.c.inc | 5 +
 target/loongarch/insns.decode  | 3 +++
 3 files changed, 15 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index c8a29eac2b..2040f3e44d 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -190,6 +190,12 @@ static void output_hint_r_i(DisasContext *ctx, 
arg_hint_r_i *a,
 output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm);
 }
 
+static void output_hint_rr(DisasContext *ctx, arg_hint_rr *a,
+   const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, r%d", a->hint, a->rj, a->rk);
+}
+
 static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
 {
 output(ctx, mnemonic, "%d", a->imm);
@@ -549,6 +555,7 @@ INSN(ld_bu,rr_i)
 INSN(ld_hu,rr_i)
 INSN(ld_wu,rr_i)
 INSN(preld,hint_r_i)
+INSN(preldx,   hint_rr)
 INSN(fld_s,fr_i)
 INSN(fst_s,fr_i)
 INSN(fld_d,fr_i)
diff --git a/target/loongarch/insn_trans/trans_memory.c.inc 
b/target/loongarch/insn_trans/trans_memory.c.inc
index c3de1404ea..42f4e74012 100644
--- a/target/loongarch/insn_trans/trans_memory.c.inc
+++ b/target/loongarch/insn_trans/trans_memory.c.inc
@@ -110,6 +110,11 @@ static bool trans_preld(DisasContext *ctx, arg_preld *a)
 return true;
 }
 
+static bool trans_preldx(DisasContext *ctx, arg_preldx * a)
+{
+return true;
+}
+
 static bool trans_dbar(DisasContext *ctx, arg_dbar * a)
 {
 tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 64b308f9fb..62f58cc541 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -24,6 +24,7 @@
   rd rj rk
 _i rd rj imm
 _r_i hint rj imm
+_rr  hint rj rk
 _sa   rd rj rk sa
 _ms_ls rd rj ms ls
fd fj
@@ -69,6 +70,7 @@
 @rr_i16  .. imm:s16 rj:5 rd:5_i
 @rr_i16s2  ..   rj:5 rd:5_i imm=%offs16
 @hint_r_i12    .. imm:s12 rj:5 hint:5_r_i
+@hint_rr   . rk:5 rj:5 hint:5_rr
 @rrr_sa2p1  ... .. rk:5 rj:5 rd:5_sa  sa=%sa2p1
 @rrr_sa2  ... sa:2 rk:5 rj:5 rd:5_sa
 @rrr_sa3   .. sa:3 rk:5 rj:5 rd:5_sa
@@ -228,6 +230,7 @@ ldx_bu  0011 1010 0 . . .
@rrr
 ldx_hu  0011 1010 01000 . . .@rrr
 ldx_wu  0011 1010 1 . . .@rrr
 preld   0010 101011  . . @hint_r_i12
+preldx  0011 1010 11000 . . .@hint_rr
 dbar0011 1111 00100 ...  @i15
 ibar0011 1111 00101 ...  @i15
 ldptr_w 0010 0100 .. . . @rr_i14s2
-- 
2.25.1




Re: [PATCH] hw/virtio/virtio-gpu: Fix compiler warning when compiling with -Wshadow

2023-10-08 Thread Marc-André Lureau
On Fri, Oct 6, 2023 at 8:46 PM Thomas Huth  wrote:
>
> Avoid using trivial variable names in macros, otherwise we get
> the following compiler warning when compiling with -Wshadow=local:
>
> In file included from ../../qemu/hw/display/virtio-gpu-virgl.c:19:
> ../../home/thuth/devel/qemu/hw/display/virtio-gpu-virgl.c:
>  In function ‘virgl_cmd_submit_3d’:
> ../../qemu/include/hw/virtio/virtio-gpu.h:228:16: error: declaration of ‘s’
>  shadows a previous local [-Werror=shadow=compatible-local]
>   228 | size_t s;
>   |^
> ../../qemu/hw/display/virtio-gpu-virgl.c:215:5: note: in expansion of macro
>  ‘VIRTIO_GPU_FILL_CMD’
>   215 | VIRTIO_GPU_FILL_CMD(cs);
>   | ^~~
> ../../qemu/hw/display/virtio-gpu-virgl.c:213:12: note: shadowed declaration
>  is here
>   213 | size_t s;
>   |^
> cc1: all warnings being treated as errors
>
> Signed-off-by: Thomas Huth 

Reviewed-by: Marc-André Lureau 

> ---
>  include/hw/virtio/virtio-gpu.h | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> index 390c4642b8..8b7e3faf01 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -225,13 +225,13 @@ struct VhostUserGPU {
>  };
>
>  #define VIRTIO_GPU_FILL_CMD(out) do {   \
> -size_t s;   \
> -s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
> +size_t s_;  \
> +s_ = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
> , sizeof(out));  \
> -if (s != sizeof(out)) { \
> +if (s_ != sizeof(out)) {\
>  qemu_log_mask(LOG_GUEST_ERROR,  \
>"%s: command size incorrect %zu vs %zu\n",\
> -  __func__, s, sizeof(out));\
> +  __func__, s_, sizeof(out));   \
>  return; \
>  }   \
>  } while (0)
> --
> 2.41.0
>
>


-- 
Marc-André Lureau



Re: [PATCH] contrib/vhost-user-gpu: Fix compiler warning when compiling with -Wshadow

2023-10-08 Thread Marc-André Lureau
On Fri, Oct 6, 2023 at 9:35 PM Thomas Huth  wrote:
>
> Rename some variables to avoid compiler warnings when compiling
> with -Wshadow=local.
>
> Signed-off-by: Thomas Huth 

Reviewed-by: Marc-André Lureau 

> ---
>  contrib/vhost-user-gpu/vugpu.h  | 8 
>  contrib/vhost-user-gpu/vhost-user-gpu.c | 6 +++---
>  2 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/contrib/vhost-user-gpu/vugpu.h b/contrib/vhost-user-gpu/vugpu.h
> index 509b679f03..5cede45134 100644
> --- a/contrib/vhost-user-gpu/vugpu.h
> +++ b/contrib/vhost-user-gpu/vugpu.h
> @@ -164,12 +164,12 @@ struct virtio_gpu_ctrl_command {
>  };
>
>  #define VUGPU_FILL_CMD(out) do {\
> -size_t s;   \
> -s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
> +size_t s_;  \
> +s_ = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
> , sizeof(out));  \
> -if (s != sizeof(out)) { \
> +if (s_ != sizeof(out)) {\
>  g_critical("%s: command size incorrect %zu vs %zu", \
> -   __func__, s, sizeof(out));   \
> +   __func__, s_, sizeof(out));  \
>  return; \
>  }   \
>  } while (0)
> diff --git a/contrib/vhost-user-gpu/vhost-user-gpu.c 
> b/contrib/vhost-user-gpu/vhost-user-gpu.c
> index aa304475a0..bb41758e34 100644
> --- a/contrib/vhost-user-gpu/vhost-user-gpu.c
> +++ b/contrib/vhost-user-gpu/vhost-user-gpu.c
> @@ -834,7 +834,7 @@ vg_resource_flush(VuGpu *g,
>  .width = width,
>  .height = height,
>  };
> -pixman_image_t *i =
> +pixman_image_t *img =
>  pixman_image_create_bits(pixman_image_get_format(res->image),
>   msg->payload.update.width,
>   msg->payload.update.height,
> @@ -842,11 +842,11 @@ vg_resource_flush(VuGpu *g,
>payload.update.data),
>   width * bpp);
>  pixman_image_composite(PIXMAN_OP_SRC,
> -   res->image, NULL, i,
> +   res->image, NULL, img,
> extents->x1, extents->y1,
> 0, 0, 0, 0,
> width, height);
> -pixman_image_unref(i);
> +pixman_image_unref(img);
>  vg_send_msg(g, msg, -1);
>  g_free(msg);
>  }
> --
> 2.41.0
>




[PULL 14/20] mac_via: work around underflow in TimeDBRA timing loop in SETUPTIMEK

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

The MacOS toolbox ROM calculates the number of branches that can be executed
per millisecond as part of its timer calibration. Since modern hosts are
considerably quicker than original hardware, the negative counter reaches zero
before the calibration completes leading to division by zero later in
CALCULATESLOD.

Instead of trying to fudge the timing loop (which won't work for 
TimeDBRA/TimeSCCDB
anyhow), use the pattern of access to the VIA1 registers to detect when 
SETUPTIMEK
has finished executing and write some well-known good timer values to TimeDBRA
and TimeSCCDB taken from real hardware with a suitable scaling factor.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-15-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/misc/mac_via.h |   3 +
 hw/misc/mac_via.c | 115 ++
 hw/misc/trace-events  |   1 +
 3 files changed, 119 insertions(+)

diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h
index 422da43bf90a..63cdcf7c69c9 100644
--- a/include/hw/misc/mac_via.h
+++ b/include/hw/misc/mac_via.h
@@ -74,6 +74,9 @@ struct MOS6522Q800VIA1State {
 int64_t next_second;
 QEMUTimer *sixty_hz_timer;
 int64_t next_sixty_hz;
+
+/* SETUPTIMEK hack */
+int timer_hack_state;
 };
 
 
diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index e87a1b82d8c5..f2ccb12d643b 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -16,6 +16,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "exec/address-spaces.h"
 #include "migration/vmstate.h"
 #include "hw/sysbus.h"
 #include "hw/irq.h"
@@ -871,6 +872,112 @@ static void via1_auxmode_update(MOS6522Q800VIA1State *v1s)
 }
 }
 
+/*
+ * Addresses and real values for TimeDBRA/TimeSCCB to allow timer calibration
+ * to succeed (NOTE: both values have been multiplied by 3 to cope with the
+ * speed of QEMU execution on a modern host
+ */
+#define MACOS_TIMEDBRA0xd00
+#define MACOS_TIMESCCB0xd02
+
+#define MACOS_TIMEDBRA_VALUE  (0x2a00 * 3)
+#define MACOS_TIMESCCB_VALUE  (0x079d * 3)
+
+static bool via1_is_toolbox_timer_calibrated(void)
+{
+/*
+ * Indicate whether the MacOS toolbox has been calibrated by checking
+ * for the value of our magic constants
+ */
+uint16_t timedbra = lduw_be_phys(_space_memory, MACOS_TIMEDBRA);
+uint16_t timesccdb = lduw_be_phys(_space_memory, MACOS_TIMESCCB);
+
+return (timedbra == MACOS_TIMEDBRA_VALUE &&
+timesccdb == MACOS_TIMESCCB_VALUE);
+}
+
+static void via1_timer_calibration_hack(MOS6522Q800VIA1State *v1s, int addr,
+uint64_t val, int size)
+{
+/*
+ * Work around timer calibration to ensure we that we have non-zero and
+ * known good values for TIMEDRBA and TIMESCCDB.
+ *
+ * This works by attempting to detect the reset and calibration sequence
+ * of writes to VIA1
+ */
+int old_timer_hack_state = v1s->timer_hack_state;
+
+switch (v1s->timer_hack_state) {
+case 0:
+if (addr == VIA_REG_PCR && val == 0x22) {
+/* VIA_REG_PCR: configure VIA1 edge triggering */
+v1s->timer_hack_state = 1;
+}
+break;
+case 1:
+if (addr == VIA_REG_T2CL && val == 0xc) {
+/* VIA_REG_T2CL: low byte of 1ms counter */
+if (!via1_is_toolbox_timer_calibrated()) {
+v1s->timer_hack_state = 2;
+} else {
+v1s->timer_hack_state = 0;
+}
+}
+break;
+case 2:
+if (addr == VIA_REG_T2CH && val == 0x3) {
+/*
+ * VIA_REG_T2CH: high byte of 1ms counter (very likely at the
+ * start of SETUPTIMEK)
+ */
+if (!via1_is_toolbox_timer_calibrated()) {
+v1s->timer_hack_state = 3;
+} else {
+v1s->timer_hack_state = 0;
+}
+}
+break;
+case 3:
+if (addr == VIA_REG_IER && val == 0x20) {
+/*
+ * VIA_REG_IER: update at end of SETUPTIMEK
+ *
+ * Timer calibration has finished: unfortunately the values in
+ * TIMEDBRA (0xd00) and TIMESCCDB (0xd02) are so far out they
+ * cause divide by zero errors.
+ *
+ * Update them with values obtained from a real Q800 but with
+ * a x3 scaling factor which seems to work well
+ */
+stw_be_phys(_space_memory, MACOS_TIMEDBRA,
+MACOS_TIMEDBRA_VALUE);
+stw_be_phys(_space_memory, MACOS_TIMESCCB,
+MACOS_TIMESCCB_VALUE);
+
+v1s->timer_hack_state = 4;
+}
+break;
+case 4:
+/*
+ * This is the normal post-calibration timer state: we should
+ * generally remain here unless we detect the A/UX calibration
+ * 

[PULL 15/20] mac_via: workaround NetBSD ADB bus enumeration issue

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

NetBSD assumes it can send its first ADB command after sending the ADB_BUSRESET
command in ADB_STATE_NEW without changing the state back to ADB_STATE_IDLE
first as detailed in the ADB protocol.

Add a workaround to detect this condition at the start of ADB enumeration
and send the next command written to SR after a ADB_BUSRESET onto the bus
regardless, even if we don't detect a state transition to ADB_STATE_NEW.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-16-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 hw/misc/mac_via.c| 34 ++
 hw/misc/trace-events |  1 +
 2 files changed, 35 insertions(+)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index f2ccb12d643b..9f9c2815d0e9 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -1001,6 +1001,8 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr 
addr, uint64_t val,
 {
 MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
 MOS6522State *ms = MOS6522(v1s);
+int oldstate, state;
+int oldsr = ms->sr;
 
 addr = (addr >> 9) & 0xf;
 
@@ -1016,6 +1018,38 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr 
addr, uint64_t val,
 
 v1s->last_b = ms->b;
 break;
+
+case VIA_REG_SR:
+{
+/*
+ * NetBSD assumes it can send its first ADB command after sending
+ * the ADB_BUSRESET command in ADB_STATE_NEW without changing the
+ * state back to ADB_STATE_IDLE first as detailed in the ADB
+ * protocol.
+ *
+ * Add a workaround to detect this condition at the start of ADB
+ * enumeration and send the next command written to SR after a
+ * ADB_BUSRESET onto the bus regardless, even if we don't detect a
+ * state transition to ADB_STATE_NEW.
+ *
+ * Note that in my tests the NetBSD state machine takes one ADB
+ * operation to recover which means the probe for an ADB device at
+ * address 1 always fails. However since the first device is at
+ * address 2 then this will work fine, without having to come up
+ * with a more complicated and invasive solution.
+ */
+oldstate = (v1s->last_b & VIA1B_vADB_StateMask) >>
+   VIA1B_vADB_StateShift;
+state = (ms->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
+
+if (oldstate == ADB_STATE_NEW && state == ADB_STATE_NEW &&
+(ms->acr & VIA1ACR_vShiftOut) &&
+oldsr == 0 /* ADB_BUSRESET */) {
+trace_via1_adb_netbsd_enum_hack();
+adb_via_send(v1s, state, ms->sr);
+}
+}
+break;
 }
 }
 
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 5a998f5e4e38..24ba7cc4d0e9 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -271,6 +271,7 @@ via1_rtc_cmd_pram_sect_write(int sector, int offset, int 
addr, int value) "secto
 via1_adb_send(const char *state, uint8_t data, const char *vadbint) "state %s 
data=0x%02x vADBInt=%s"
 via1_adb_receive(const char *state, uint8_t data, const char *vadbint, int 
status, int index, int size) "state %s data=0x%02x vADBInt=%s status=0x%x 
index=%d size=%d"
 via1_adb_poll(uint8_t data, const char *vadbint, int status, int index, int 
size) "data=0x%02x vADBInt=%s status=0x%x index=%d size=%d"
+via1_adb_netbsd_enum_hack(void) "using NetBSD enum hack"
 via1_auxmode(int mode) "setting auxmode to %d"
 via1_timer_hack_state(int state) "setting timer_hack_state to %d"
 
-- 
2.41.0




[PULL 07/20] audio: add Apple Sound Chip (ASC) emulation

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

The Apple Sound Chip was primarily used by the Macintosh II to generate sound
in hardware which was previously handled by the toolbox ROM with software
interrupts.

Implement both the standard ASC and also the enhanced ASC (EASC) functionality
which is used in the Quadra 800.

Note that whilst real ASC hardware uses AUDIO_FORMAT_S8, this implementation 
uses
AUDIO_FORMAT_U8 instead because AUDIO_FORMAT_S8 is rarely used and not supported
by some audio backends like PulseAudio and DirectSound when played directly with
-audiodev out.mixing-engine=off.

Co-developed-by: Laurent Vivier 
Co-developed-by: Volker Rümelin 
Signed-off-by: Mark Cave-Ayland 
Message-ID: <20231004083806.757242-8-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 MAINTAINERS|   2 +
 include/hw/audio/asc.h |  84 +
 hw/audio/asc.c | 708 +
 hw/audio/Kconfig   |   3 +
 hw/audio/meson.build   |   1 +
 hw/audio/trace-events  |  10 +
 hw/m68k/Kconfig|   1 +
 7 files changed, 809 insertions(+)
 create mode 100644 include/hw/audio/asc.h
 create mode 100644 hw/audio/asc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 38fc8e0a22b8..ac865c4e5932 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1231,6 +1231,7 @@ F: hw/display/macfb.c
 F: hw/block/swim.c
 F: hw/misc/djmemc.c
 F: hw/misc/iosb.c
+F: hw/audio/asc.c
 F: hw/m68k/bootinfo.h
 F: include/standard-headers/asm-m68k/bootinfo.h
 F: include/standard-headers/asm-m68k/bootinfo-mac.h
@@ -1242,6 +1243,7 @@ F: include/hw/m68k/q800.h
 F: include/hw/m68k/q800-glue.h
 F: include/hw/misc/djmemc.h
 F: include/hw/misc/iosb.h
+F: include/hw/audio/asc.h
 
 virt
 M: Laurent Vivier 
diff --git a/include/hw/audio/asc.h b/include/hw/audio/asc.h
new file mode 100644
index ..d9412815c324
--- /dev/null
+++ b/include/hw/audio/asc.h
@@ -0,0 +1,84 @@
+/*
+ * QEMU Apple Sound Chip emulation
+ *
+ * Apple Sound Chip (ASC) 344S0063
+ * Enhanced Apple Sound Chip (EASC) 343S1063
+ *
+ * Copyright (c) 2012-2018 Laurent Vivier 
+ * Copyright (c) 2022 Mark Cave-Ayland 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_AUDIO_ASC_H
+#define HW_AUDIO_ASC_H
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "audio/audio.h"
+
+#define ASC_FREQ 22257
+
+enum {
+ASC_TYPE_ASC= 0,  /* original discrete Apple Sound Chip */
+ASC_TYPE_EASC   = 1   /* discrete Enhanced Apple Sound Chip */
+};
+
+#define ASC_FIFO_OFFSET0x0
+#define ASC_FIFO_SIZE  0x400
+
+#define ASC_REG_OFFSET 0x800
+#define ASC_REG_SIZE   0x60
+
+#define ASC_EXTREG_OFFSET  0xf00
+#define ASC_EXTREG_SIZE0x20
+
+typedef struct ASCFIFOState {
+int index;
+
+MemoryRegion mem_fifo;
+uint8_t fifo[ASC_FIFO_SIZE];
+uint8_t int_status;
+
+int cnt;
+int wptr;
+int rptr;
+
+MemoryRegion mem_extregs;
+uint8_t extregs[ASC_EXTREG_SIZE];
+
+int xa_cnt;
+uint8_t xa_val;
+uint8_t xa_flags;
+int16_t xa_last[2];
+} ASCFIFOState;
+
+struct ASCState {
+SysBusDevice parent_obj;
+
+uint8_t type;
+MemoryRegion asc;
+MemoryRegion mem_fifo;
+MemoryRegion mem_regs;
+MemoryRegion mem_extregs;
+
+QEMUSoundCard card;
+SWVoiceOut *voice;
+uint8_t *mixbuf;
+int samples;
+int shift;
+
+/* Time when we were last able to generate samples */
+int64_t fifo_empty_ns;
+
+qemu_irq irq;
+
+ASCFIFOState fifos[2];
+
+uint8_t regs[ASC_REG_SIZE];
+};
+
+#define TYPE_ASC "apple-sound-chip"
+OBJECT_DECLARE_SIMPLE_TYPE(ASCState, ASC)
+
+#endif
diff --git a/hw/audio/asc.c b/hw/audio/asc.c
new file mode 100644
index ..9084708eafab
--- /dev/null
+++ b/hw/audio/asc.c
@@ -0,0 +1,708 @@
+/*
+ * QEMU Apple Sound Chip emulation
+ *
+ * Apple Sound Chip (ASC) 344S0063
+ * Enhanced Apple Sound Chip (EASC) 343S1063
+ *
+ * Copyright (c) 2012-2018 Laurent Vivier 
+ * Copyright (c) 2022 Mark Cave-Ayland 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/timer.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "audio/audio.h"
+#include "hw/audio/asc.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+/*
+ * Linux doesn't provide information about ASC, see arch/m68k/mac/macboing.c
+ * and arch/m68k/include/asm/mac_asc.h
+ *
+ * best information is coming from MAME:
+ *   https://github.com/mamedev/mame/blob/master/src/devices/sound/asc.h
+ *   https://github.com/mamedev/mame/blob/master/src/devices/sound/asc.cpp
+ *   Emulation by R. Belmont
+ * or MESS:
+ *   http://mess.redump.net/mess/driver_info/easc
+ *
+ * 0x800: VERSION
+ * 0x801: MODE
+ *1=FIFO mode,
+ *2=wavetable mode
+ * 0x802: CONTROL
+ *bit 0=analog or PWM output,
+ *1=stereo/mono,
+ *7=processing time exceeded
+ * 0x803: FIFO MODE
+ *bit 7=clear FIFO,
+ *bit 

[PULL 10/20] q800: add easc bool machine class property to switch between ASC and EASC

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

This determines whether the Apple Sound Chip (ASC) is set to enhanced mode
(default) or to original mode. The real Q800 hardware used an EASC chip however
a lot of older software only works with the older ASC chip.

Adding this as a machine parameter allows QEMU to be used as an developer aid
for testing and migrating code from ASC to EASC.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-11-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/m68k/q800.h |  1 +
 hw/m68k/q800.c | 30 +-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index 790cf433f38d..fbaacd88bd57 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -47,6 +47,7 @@
 struct Q800MachineState {
 MachineState parent_obj;
 
+bool easc;
 M68kCPU cpu;
 MemoryRegion rom;
 GLUEState glue;
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 249fedde7a92..ac3115d32844 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -484,7 +484,8 @@ static void q800_machine_init(MachineState *machine)
 /* Apple Sound Chip */
 
 object_initialize_child(OBJECT(machine), "asc", >asc, TYPE_ASC);
-qdev_prop_set_uint8(DEVICE(>asc), "asctype", ASC_TYPE_EASC);
+qdev_prop_set_uint8(DEVICE(>asc), "asctype", m->easc ? ASC_TYPE_EASC
+: ASC_TYPE_ASC);
 if (machine->audiodev) {
 qdev_prop_set_string(DEVICE(>asc), "audiodev", machine->audiodev);
 }
@@ -677,6 +678,28 @@ static void q800_machine_init(MachineState *machine)
 }
 }
 
+static bool q800_get_easc(Object *obj, Error **errp)
+{
+Q800MachineState *ms = Q800_MACHINE(obj);
+
+return ms->easc;
+}
+
+static void q800_set_easc(Object *obj, bool value, Error **errp)
+{
+Q800MachineState *ms = Q800_MACHINE(obj);
+
+ms->easc = value;
+}
+
+static void q800_init(Object *obj)
+{
+Q800MachineState *ms = Q800_MACHINE(obj);
+
+/* Default to EASC */
+ms->easc = true;
+}
+
 static GlobalProperty hw_compat_q800[] = {
 { "scsi-hd", "quirk_mode_page_vendor_specific_apple", "on" },
 { "scsi-hd", "vendor", " SEAGATE" },
@@ -710,11 +733,16 @@ static void q800_machine_class_init(ObjectClass *oc, void 
*data)
 mc->default_ram_id = "m68k_mac.ram";
 machine_add_audiodev_property(mc);
 compat_props_add(mc->compat_props, hw_compat_q800, hw_compat_q800_len);
+
+object_class_property_add_bool(oc, "easc", q800_get_easc, q800_set_easc);
+object_class_property_set_description(oc, "easc",
+"Set to off to use ASC rather than EASC");
 }
 
 static const TypeInfo q800_machine_typeinfo = {
 .name   = MACHINE_TYPE_NAME("q800"),
 .parent = TYPE_MACHINE,
+.instance_init = q800_init,
 .instance_size = sizeof(Q800MachineState),
 .class_init = q800_machine_class_init,
 };
-- 
2.41.0




[PULL 03/20] q800: add machine id register

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

MacOS reads this address to identify the hardware.

This is a basic implementation returning the ID of Quadra 800.

Details:

  http://mess.redump.net/mess/driver_info/mac_technical_notes

"There are 3 ID schemes [...]
 The third and most scalable is a machine ID register at 0x5ffc.
 The top word must be 0xa55a to be valid. Then bits 15-11 are 0 for
 consumer Macs, 1 for portables, 2 for high-end 68k, and 3 for high-end
 PowerPC. Bit 10 is 1 if additional ID bits appear elsewhere (e.g. in VIA1).
 The rest of the bits are a per-model identifier.

 Model  Lower 16 bits of ID
...
 Quadra/Centris 610/650/800 0x2BAD"

Co-developed-by: Laurent Vivier 
Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20231004083806.757242-4-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/m68k/q800.h |  1 +
 hw/m68k/q800.c | 29 +
 2 files changed, 30 insertions(+)

diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index f6ae4c1c4fd5..dd7d7a6f2c48 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -60,6 +60,7 @@ struct Q800MachineState {
 DJMEMCState djmemc;
 MemoryRegion macio;
 MemoryRegion macio_alias;
+MemoryRegion machine_id;
 };
 
 #define TYPE_Q800_MACHINE MACHINE_TYPE_NAME("q800")
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index f9ecc1fbb094..ac8509ba6f7e 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -91,6 +91,9 @@
 #define Q800_NUBUS_SLOTS_AVAILABLE(BIT(0x9) | BIT(0xc) | BIT(0xd) | \
BIT(0xe))
 
+/* Quadra 800 machine ID */
+#define Q800_MACHINE_ID0xa55a2bad
+
 
 static void main_cpu_reset(void *opaque)
 {
@@ -192,6 +195,27 @@ static const MemoryRegionOps macio_alias_ops = {
 },
 };
 
+static uint64_t machine_id_read(void *opaque, hwaddr addr, unsigned size)
+{
+return Q800_MACHINE_ID;
+}
+
+static void machine_id_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
+{
+return;
+}
+
+static const MemoryRegionOps machine_id_ops = {
+.read = machine_id_read,
+.write = machine_id_write,
+.endianness = DEVICE_BIG_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
 static void q800_machine_init(MachineState *machine)
 {
 Q800MachineState *m = Q800_MACHINE(machine);
@@ -253,6 +277,11 @@ static void q800_machine_init(MachineState *machine)
 memory_region_add_subregion(get_system_memory(), IO_BASE + IO_SLICE,
 >macio_alias);
 
+memory_region_init_io(>machine_id, NULL, _id_ops, NULL,
+  "Machine ID", 4);
+memory_region_add_subregion(get_system_memory(), 0x5ffc,
+>machine_id);
+
 /* IRQ Glue */
 object_initialize_child(OBJECT(machine), "glue", >glue, TYPE_GLUE);
 object_property_set_link(OBJECT(>glue), "cpu", OBJECT(>cpu),
-- 
2.41.0




[PULL 16/20] mac_via: implement ADB_STATE_IDLE state if shift register in input mode

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

NetBSD switches directly to IDLE state without switching the shift register to
input mode. Duplicate the existing ADB_STATE_IDLE logic in input mode from when
the shift register is in output mode which allows the ADB autopoll handler to
handle the response.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-17-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 hw/misc/mac_via.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 9f9c2815d0e9..3c41d6263d45 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -702,6 +702,12 @@ static void adb_via_send(MOS6522Q800VIA1State *v1s, int 
state, uint8_t data)
 break;
 
 case ADB_STATE_IDLE:
+ms->b |= VIA1B_vADBInt;
+adb_autopoll_unblock(adb_bus);
+
+trace_via1_adb_send("IDLE", data,
+(ms->b & VIA1B_vADBInt) ? "+" : "-");
+
 return;
 }
 
-- 
2.41.0




[PULL 01/20] q800-glue.c: convert to Resettable interface

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

Convert the GLUE device to 3-phase reset. The legacy method
doesn't do anything that's invalid in the hold phase, so the
conversion is simple and not a behaviour change.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-2-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 hw/m68k/q800-glue.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/m68k/q800-glue.c b/hw/m68k/q800-glue.c
index 34c4f0e9876d..710a5c331ec9 100644
--- a/hw/m68k/q800-glue.c
+++ b/hw/m68k/q800-glue.c
@@ -166,9 +166,9 @@ static void glue_nmi_release(void *opaque)
 GLUE_set_irq(s, GLUE_IRQ_IN_NMI, 0);
 }
 
-static void glue_reset(DeviceState *dev)
+static void glue_reset_hold(Object *obj)
 {
-GLUEState *s = GLUE(dev);
+GLUEState *s = GLUE(obj);
 
 s->ipr = 0;
 s->auxmode = 0;
@@ -223,11 +223,12 @@ static void glue_init(Object *obj)
 static void glue_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
+ResettableClass *rc = RESETTABLE_CLASS(klass);
 NMIClass *nc = NMI_CLASS(klass);
 
 dc->vmsd = _glue;
-dc->reset = glue_reset;
 device_class_set_props(dc, glue_properties);
+rc->phases.hold = glue_reset_hold;
 nc->nmi_monitor_handler = glue_nmi;
 }
 
-- 
2.41.0




[PULL 12/20] swim: split into separate IWM and ISM register blocks

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

The swim chip provides an implementation of both Apple's IWM and ISM floppy disk
controllers. Split the existing implementation into separate register banks for
each controller, whilst also switching the IWM registers from 16-bit to 8-bit
as implemented in real hardware.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-13-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/block/swim.h | 15 +++-
 hw/block/swim.c | 85 -
 hw/block/trace-events   |  4 +-
 3 files changed, 58 insertions(+), 46 deletions(-)

diff --git a/include/hw/block/swim.h b/include/hw/block/swim.h
index 9b3dcb029d3f..1bc7635d0212 100644
--- a/include/hw/block/swim.h
+++ b/include/hw/block/swim.h
@@ -43,23 +43,18 @@ typedef struct FDrive {
 } FDrive;
 
 struct SWIMCtrl {
-MemoryRegion iomem;
+MemoryRegion swim;
+MemoryRegion iwm;
+MemoryRegion ism;
 FDrive drives[SWIM_MAX_FD];
 int mode;
 /* IWM mode */
 int iwm_switch;
-uint16_t regs[8];
-#define IWM_PH0   0
-#define IWM_PH1   1
-#define IWM_PH2   2
-#define IWM_PH3   3
-#define IWM_MTR   4
-#define IWM_DRIVE 5
-#define IWM_Q66
-#define IWM_Q77
+uint8_t iwmregs[16];
 uint8_t iwm_data;
 uint8_t iwm_mode;
 /* SWIM mode */
+uint8_t ismregs[16];
 uint8_t swim_phase;
 uint8_t swim_mode;
 SWIMBus bus;
diff --git a/hw/block/swim.c b/hw/block/swim.c
index 7df36ea139cb..505718bdae3f 100644
--- a/hw/block/swim.c
+++ b/hw/block/swim.c
@@ -126,7 +126,14 @@
 #define SWIM_HEDSEL  0x20
 #define SWIM_MOTON   0x80
 
-static const char *swim_reg_names[] = {
+static const char *iwm_reg_names[] = {
+"PH0L", "PH0H", "PH1L", "PH1H",
+"PH2L", "PH2H", "PH3L", "PH3H",
+"MTROFF", "MTRON", "INTDRIVE", "EXTDRIVE",
+"Q6L", "Q6H", "Q7L", "Q7H"
+};
+
+static const char *ism_reg_names[] = {
 "WRITE_DATA", "WRITE_MARK", "WRITE_CRC", "WRITE_PARAMETER",
 "WRITE_PHASE", "WRITE_SETUP", "WRITE_MODE0", "WRITE_MODE1",
 "READ_DATA", "READ_MARK", "READ_ERROR", "READ_PARAMETER",
@@ -274,12 +281,11 @@ static void iwmctrl_write(void *opaque, hwaddr reg, 
uint64_t value,
 
 reg >>= REG_SHIFT;
 
-swimctrl->regs[reg >> 1] = reg & 1;
-trace_swim_iwmctrl_write((reg >> 1), size, (reg & 1));
+swimctrl->iwmregs[reg] = value;
+trace_swim_iwmctrl_write(reg, iwm_reg_names[reg], size, value);
 
-if (swimctrl->regs[IWM_Q6] &&
-swimctrl->regs[IWM_Q7]) {
-if (swimctrl->regs[IWM_MTR]) {
+if (swimctrl->iwmregs[IWM_Q7H]) {
+if (swimctrl->iwmregs[IWM_MTRON]) {
 /* data register */
 swimctrl->iwm_data = value;
 } else {
@@ -307,6 +313,12 @@ static void iwmctrl_write(void *opaque, hwaddr reg, 
uint64_t value,
 swimctrl->mode = SWIM_MODE_SWIM;
 swimctrl->iwm_switch = 0;
 trace_swim_iwm_switch();
+
+/* Switch to ISM registers */
+memory_region_del_subregion(>swim,
+>iwm);
+memory_region_add_subregion(>swim, 0x0,
+>ism);
 }
 break;
 }
@@ -317,28 +329,30 @@ static void iwmctrl_write(void *opaque, hwaddr reg, 
uint64_t value,
 static uint64_t iwmctrl_read(void *opaque, hwaddr reg, unsigned size)
 {
 SWIMCtrl *swimctrl = opaque;
+uint8_t value;
 
 reg >>= REG_SHIFT;
 
-swimctrl->regs[reg >> 1] = reg & 1;
+value = swimctrl->iwmregs[reg];
+trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value);
 
-trace_swim_iwmctrl_read((reg >> 1), size, (reg & 1));
-return 0;
+return value;
 }
 
-static void swimctrl_write(void *opaque, hwaddr reg, uint64_t value,
-   unsigned size)
+static const MemoryRegionOps swimctrl_iwm_ops = {
+.write = iwmctrl_write,
+.read = iwmctrl_read,
+.endianness = DEVICE_BIG_ENDIAN,
+};
+
+static void ismctrl_write(void *opaque, hwaddr reg, uint64_t value,
+  unsigned size)
 {
 SWIMCtrl *swimctrl = opaque;
 
-if (swimctrl->mode == SWIM_MODE_IWM) {
-iwmctrl_write(opaque, reg, value, size);
-return;
-}
-
 reg >>= REG_SHIFT;
 
-trace_swim_swimctrl_write(reg, swim_reg_names[reg], size, value);
+trace_swim_swimctrl_write(reg, ism_reg_names[reg], size, value);
 
 switch (reg) {
 case SWIM_WRITE_PHASE:
@@ -359,15 +373,11 @@ static void swimctrl_write(void *opaque, hwaddr reg, 
uint64_t value,
 }
 }
 
-static uint64_t swimctrl_read(void *opaque, hwaddr reg, unsigned size)
+static uint64_t ismctrl_read(void *opaque, hwaddr reg, unsigned size)
 {
 SWIMCtrl *swimctrl = opaque;
 uint32_t value = 0;
 
-if (swimctrl->mode == SWIM_MODE_IWM) {
-return iwmctrl_read(opaque, reg, size);

[PULL 08/20] asc: generate silence if FIFO empty but engine still running

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

MacOS (un)helpfully leaves the FIFO engine running even when all the samples 
have
been written to the hardware, and expects the FIFO status flags and IRQ to be
updated continuously.

There is an additional problem in that not all audio backends guarantee an
all-zero output when there is no FIFO data available, in particular the Windows
dsound backend which re-uses its internal circular buffer causing the last 
played
sound to loop indefinitely.

Whilst this is effectively a bug in the Windows dsound backend, work around it
for now using a simple heuristic: if the FIFO remains empty for half a cycle
(~23ms) then continuously fill the generated buffer with empty silence.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-9-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/audio/asc.h |  2 ++
 hw/audio/asc.c | 19 +++
 2 files changed, 21 insertions(+)

diff --git a/include/hw/audio/asc.h b/include/hw/audio/asc.h
index d9412815c324..4741f92c4613 100644
--- a/include/hw/audio/asc.h
+++ b/include/hw/audio/asc.h
@@ -68,6 +68,8 @@ struct ASCState {
 int samples;
 int shift;
 
+uint8_t *silentbuf;
+
 /* Time when we were last able to generate samples */
 int64_t fifo_empty_ns;
 
diff --git a/hw/audio/asc.c b/hw/audio/asc.c
index 9084708eafab..0f36b4ce9b6f 100644
--- a/hw/audio/asc.c
+++ b/hw/audio/asc.c
@@ -341,6 +341,21 @@ static void asc_out_cb(void *opaque, int free_b)
 }
 
 if (!generated) {
+/* Workaround for audio underflow bug on Windows dsound backend */
+int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+int silent_samples = muldiv64(now - s->fifo_empty_ns,
+  NANOSECONDS_PER_SECOND, ASC_FREQ);
+
+if (silent_samples > ASC_FIFO_CYCLE_TIME / 2) {
+/*
+ * No new FIFO data within half a cycle time (~23ms) so fill the
+ * entire available buffer with silence. This prevents an issue
+ * with the Windows dsound backend whereby the sound appears to
+ * loop because the FIFO has run out of data, and the driver
+ * reuses the stale content in its circular audio buffer.
+ */
+AUD_write(s->voice, s->silentbuf, samples << s->shift);
+}
 return;
 }
 
@@ -618,6 +633,7 @@ static void asc_unrealize(DeviceState *dev)
 ASCState *s = ASC(dev);
 
 g_free(s->mixbuf);
+g_free(s->silentbuf);
 
 AUD_remove_card(>card);
 }
@@ -642,6 +658,9 @@ static void asc_realize(DeviceState *dev, Error **errp)
 s->samples = AUD_get_buffer_size_out(s->voice) >> s->shift;
 s->mixbuf = g_malloc0(s->samples << s->shift);
 
+s->silentbuf = g_malloc0(s->samples << s->shift);
+memset(s->silentbuf, 0x80, s->samples << s->shift);
+
 /* Add easc registers if required */
 if (s->type == ASC_TYPE_EASC) {
 memory_region_add_subregion(>asc, ASC_EXTREG_OFFSET,
-- 
2.41.0




[PULL 06/20] q800: allow accesses to RAM area even if less memory is available

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

MacOS attempts a series of writes and reads over the entire RAM area in order
to determine the amount of RAM within the machine. Allow accesses to the
entire RAM area ignoring writes and always reading zero for areas where there
is no physical RAM installed to allow MacOS to detect the memory size without
faulting.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-7-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/m68k/q800.h |  1 +
 hw/m68k/q800.c | 30 +-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index 98097165d954..04e4e0bce35a 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -60,6 +60,7 @@ struct Q800MachineState {
 MacfbNubusState macfb;
 DJMEMCState djmemc;
 IOSBState iosb;
+MemoryRegion ramio;
 MemoryRegion macio;
 MemoryRegion macio_alias;
 MemoryRegion machine_id;
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 081b95e9cf66..3209309173f3 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -86,6 +86,9 @@
 
 #define MAC_CLOCK  3686418
 
+/* Size of whole RAM area */
+#define RAM_SIZE  0x4000
+
 /*
  * Slot 0x9 is reserved for use by the in-built framebuffer whilst only
  * slots 0xc, 0xd and 0xe physically exist on the Quadra 800
@@ -218,6 +221,27 @@ static const MemoryRegionOps machine_id_ops = {
 },
 };
 
+static uint64_t ramio_read(void *opaque, hwaddr addr, unsigned size)
+{
+return 0x0;
+}
+
+static void ramio_write(void *opaque, hwaddr addr, uint64_t val,
+unsigned size)
+{
+return;
+}
+
+static const MemoryRegionOps ramio_ops = {
+.read = ramio_read,
+.write = ramio_write,
+.endianness = DEVICE_BIG_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+};
+
 static void q800_machine_init(MachineState *machine)
 {
 Q800MachineState *m = Q800_MACHINE(machine);
@@ -262,7 +286,11 @@ static void q800_machine_init(MachineState *machine)
 qemu_register_reset(main_cpu_reset, >cpu);
 
 /* RAM */
-memory_region_add_subregion(get_system_memory(), 0, machine->ram);
+memory_region_init_io(>ramio, OBJECT(machine), _ops, >ramio,
+  "ram", RAM_SIZE);
+memory_region_add_subregion(get_system_memory(), 0x0, >ramio);
+
+memory_region_add_subregion(>ramio, 0, machine->ram);
 
 /*
  * Create container for all IO devices
-- 
2.41.0




[PULL 05/20] q800: add IOSB subsystem

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

It is needed because it defines the BIOSConfig area.

Co-developed-by: Laurent Vivier 
Signed-off-by: Mark Cave-Ayland 
Reviewed-by: BALATON Zoltan 
Message-ID: <20231004083806.757242-6-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 MAINTAINERS|   2 +
 include/hw/m68k/q800.h |   2 +
 include/hw/misc/iosb.h |  25 
 hw/m68k/q800.c |   9 +++
 hw/misc/iosb.c | 133 +
 hw/m68k/Kconfig|   1 +
 hw/misc/Kconfig|   3 +
 hw/misc/meson.build|   1 +
 hw/misc/trace-events   |   4 ++
 9 files changed, 180 insertions(+)
 create mode 100644 include/hw/misc/iosb.h
 create mode 100644 hw/misc/iosb.c

diff --git a/MAINTAINERS b/MAINTAINERS
index dead0d4a47e3..38fc8e0a22b8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1230,6 +1230,7 @@ F: hw/nubus/*
 F: hw/display/macfb.c
 F: hw/block/swim.c
 F: hw/misc/djmemc.c
+F: hw/misc/iosb.c
 F: hw/m68k/bootinfo.h
 F: include/standard-headers/asm-m68k/bootinfo.h
 F: include/standard-headers/asm-m68k/bootinfo-mac.h
@@ -1240,6 +1241,7 @@ F: include/hw/block/swim.h
 F: include/hw/m68k/q800.h
 F: include/hw/m68k/q800-glue.h
 F: include/hw/misc/djmemc.h
+F: include/hw/misc/iosb.h
 
 virt
 M: Laurent Vivier 
diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index dd7d7a6f2c48..98097165d954 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -37,6 +37,7 @@
 #include "hw/nubus/mac-nubus-bridge.h"
 #include "hw/display/macfb.h"
 #include "hw/misc/djmemc.h"
+#include "hw/misc/iosb.h"
 
 /*
  * The main Q800 machine
@@ -58,6 +59,7 @@ struct Q800MachineState {
 MacNubusBridge mac_nubus_bridge;
 MacfbNubusState macfb;
 DJMEMCState djmemc;
+IOSBState iosb;
 MemoryRegion macio;
 MemoryRegion macio_alias;
 MemoryRegion machine_id;
diff --git a/include/hw/misc/iosb.h b/include/hw/misc/iosb.h
new file mode 100644
index ..377f8ca7e2fa
--- /dev/null
+++ b/include/hw/misc/iosb.h
@@ -0,0 +1,25 @@
+/*
+ * QEMU IOSB emulation
+ *
+ * Copyright (c) 2019 Laurent Vivier
+ * Copyright (c) 2022 Mark Cave-Ayland
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MEM_IOSB_H
+#define HW_MEM_IOSB_H
+
+#define IOSB_REGS 7
+
+struct IOSBState {
+SysBusDevice parent_obj;
+
+MemoryRegion mem_regs;
+uint32_t regs[IOSB_REGS];
+};
+
+#define TYPE_IOSB "IOSB"
+OBJECT_DECLARE_SIMPLE_TYPE(IOSBState, IOSB);
+
+#endif
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index ac8509ba6f7e..081b95e9cf66 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -41,6 +41,7 @@
 #include "hw/m68k/q800-glue.h"
 #include "hw/misc/mac_via.h"
 #include "hw/misc/djmemc.h"
+#include "hw/misc/iosb.h"
 #include "hw/input/adb.h"
 #include "hw/nubus/mac-nubus-bridge.h"
 #include "hw/display/macfb.h"
@@ -71,6 +72,7 @@
 #define ESP_BASE  (IO_BASE + 0x1)
 #define ESP_PDMA  (IO_BASE + 0x10100)
 #define ASC_BASE  (IO_BASE + 0x14000)
+#define IOSB_BASE (IO_BASE + 0x18000)
 #define SWIM_BASE (IO_BASE + 0x1E000)
 
 #define SONIC_PROM_SIZE   0x1000
@@ -296,6 +298,13 @@ static void q800_machine_init(MachineState *machine)
 memory_region_add_subregion(>macio, DJMEMC_BASE - IO_BASE,
 sysbus_mmio_get_region(sysbus, 0));
 
+/* IOSB subsystem */
+object_initialize_child(OBJECT(machine), "iosb", >iosb, TYPE_IOSB);
+sysbus = SYS_BUS_DEVICE(>iosb);
+sysbus_realize_and_unref(sysbus, _fatal);
+memory_region_add_subregion(>macio, IOSB_BASE - IO_BASE,
+sysbus_mmio_get_region(sysbus, 0));
+
 /* VIA 1 */
 object_initialize_child(OBJECT(machine), "via1", >via1,
 TYPE_MOS6522_Q800_VIA1);
diff --git a/hw/misc/iosb.c b/hw/misc/iosb.c
new file mode 100644
index ..e7e9dcca476c
--- /dev/null
+++ b/hw/misc/iosb.c
@@ -0,0 +1,133 @@
+/*
+ * QEMU IOSB emulation
+ *
+ * Copyright (c) 2019 Laurent Vivier
+ * Copyright (c) 2022 Mark Cave-Ayland
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/misc/iosb.h"
+#include "trace.h"
+
+#define IOSB_SIZE  0x2000
+
+#define IOSB_CONFIG0x0
+#define IOSB_CONFIG2   0x100
+#define IOSB_SONIC_SCSI0x200
+#define IOSB_REVISION  0x300
+#define IOSB_SCSI_RESID0x400
+#define IOSB_BRIGHTNESS0x500
+#define IOSB_TIMEOUT   0x600
+
+
+static uint64_t iosb_read(void *opaque, hwaddr addr,
+  unsigned size)
+{
+IOSBState *s = IOSB(opaque);
+uint64_t val = 0;
+
+switch (addr) {
+case IOSB_CONFIG:
+case IOSB_CONFIG2:
+case IOSB_SONIC_SCSI:
+case IOSB_REVISION:
+case IOSB_SCSI_RESID:
+case IOSB_BRIGHTNESS:
+case IOSB_TIMEOUT:
+val = s->regs[addr >> 8];
+break;
+default:
+

Re: [PATCH 1/6] tap: Fix virtio-net header buffer size

2023-10-08 Thread Michael S. Tsirkin
On Sun, Oct 08, 2023 at 02:29:10PM +0900, Akihiko Odaki wrote:
> The largest possible virtio-net header is struct virtio_net_hdr_v1_hash.
> 
> Fixes: fbbdbddec0 ("tap: allow extended virtio header with hash info")
> Signed-off-by: Akihiko Odaki 

This thread is malformed BTW: cover letter seems to be
missing on list.


> ---
>  net/tap.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/tap.c b/net/tap.c
> index c6639d9f20..ea46feeaa8 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -118,7 +118,7 @@ static ssize_t tap_receive_iov(NetClientState *nc, const 
> struct iovec *iov,
>  TAPState *s = DO_UPCAST(TAPState, nc, nc);
>  const struct iovec *iovp = iov;
>  struct iovec iov_copy[iovcnt + 1];
> -struct virtio_net_hdr_mrg_rxbuf hdr = { };
> +struct virtio_net_hdr_v1_hash hdr = { };
>  
>  if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
>  iov_copy[0].iov_base = 
> @@ -136,7 +136,7 @@ static ssize_t tap_receive_raw(NetClientState *nc, const 
> uint8_t *buf, size_t si
>  TAPState *s = DO_UPCAST(TAPState, nc, nc);
>  struct iovec iov[2];
>  int iovcnt = 0;
> -struct virtio_net_hdr_mrg_rxbuf hdr = { };
> +struct virtio_net_hdr_v1_hash hdr = { };
>  
>  if (s->host_vnet_hdr_len) {
>  iov[iovcnt].iov_base = 
> -- 
> 2.42.0
> 
> 




[PULL 09/20] q800: add Apple Sound Chip (ASC) audio to machine

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

The Quadra 800 has the enhanced ASC (EASC) audio chip which supports both the
legacy IRQ routing through VIA2 and also "A/UX" mode routing direct to the
CPU.

Co-developed-by: Laurent Vivier 
Signed-off-by: Mark Cave-Ayland 
Message-ID: <20231004083806.757242-10-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/m68k/q800-glue.h |  4 +++-
 include/hw/m68k/q800.h  |  2 ++
 hw/m68k/q800-glue.c | 11 ++-
 hw/m68k/q800.c  | 21 +
 4 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/include/hw/m68k/q800-glue.h b/include/hw/m68k/q800-glue.h
index a35efc1c534d..ceb916d16c14 100644
--- a/include/hw/m68k/q800-glue.h
+++ b/include/hw/m68k/q800-glue.h
@@ -35,7 +35,7 @@ struct GLUEState {
 M68kCPU *cpu;
 uint8_t ipr;
 uint8_t auxmode;
-qemu_irq irqs[1];
+qemu_irq irqs[2];
 QEMUTimer *nmi_release;
 };
 
@@ -44,7 +44,9 @@ struct GLUEState {
 #define GLUE_IRQ_IN_SONIC  2
 #define GLUE_IRQ_IN_ESCC   3
 #define GLUE_IRQ_IN_NMI4
+#define GLUE_IRQ_IN_ASC5
 
 #define GLUE_IRQ_NUBUS_9   0
+#define GLUE_IRQ_ASC   1
 
 #endif
diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index 04e4e0bce35a..790cf433f38d 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -38,6 +38,7 @@
 #include "hw/display/macfb.h"
 #include "hw/misc/djmemc.h"
 #include "hw/misc/iosb.h"
+#include "hw/audio/asc.h"
 
 /*
  * The main Q800 machine
@@ -60,6 +61,7 @@ struct Q800MachineState {
 MacfbNubusState macfb;
 DJMEMCState djmemc;
 IOSBState iosb;
+ASCState asc;
 MemoryRegion ramio;
 MemoryRegion macio;
 MemoryRegion macio_alias;
diff --git a/hw/m68k/q800-glue.c b/hw/m68k/q800-glue.c
index 710a5c331ec9..f413b1599a2c 100644
--- a/hw/m68k/q800-glue.c
+++ b/hw/m68k/q800-glue.c
@@ -97,6 +97,11 @@ static void GLUE_set_irq(void *opaque, int irq, int level)
 irq = 6;
 break;
 
+case GLUE_IRQ_IN_ASC:
+/* Route to VIA2 instead, negative edge-triggered */
+qemu_set_irq(s->irqs[GLUE_IRQ_ASC], !level);
+return;
+
 default:
 g_assert_not_reached();
 }
@@ -123,6 +128,10 @@ static void GLUE_set_irq(void *opaque, int irq, int level)
 irq = 6;
 break;
 
+case GLUE_IRQ_IN_ASC:
+irq = 4;
+break;
+
 default:
 g_assert_not_reached();
 }
@@ -214,7 +223,7 @@ static void glue_init(Object *obj)
 qdev_init_gpio_in(dev, GLUE_set_irq, 8);
 qdev_init_gpio_in_named(dev, glue_auxmode_set_irq, "auxmode", 1);
 
-qdev_init_gpio_out(dev, s->irqs, 1);
+qdev_init_gpio_out(dev, s->irqs, 2);
 
 /* NMI release timer */
 s->nmi_release = timer_new_ms(QEMU_CLOCK_VIRTUAL, glue_nmi_release, s);
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 3209309173f3..249fedde7a92 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -43,6 +43,7 @@
 #include "hw/misc/djmemc.h"
 #include "hw/misc/iosb.h"
 #include "hw/input/adb.h"
+#include "hw/audio/asc.h"
 #include "hw/nubus/mac-nubus-bridge.h"
 #include "hw/display/macfb.h"
 #include "hw/block/swim.h"
@@ -480,6 +481,25 @@ static void q800_machine_init(MachineState *machine)
 
 scsi_bus_legacy_handle_cmdline(>bus);
 
+/* Apple Sound Chip */
+
+object_initialize_child(OBJECT(machine), "asc", >asc, TYPE_ASC);
+qdev_prop_set_uint8(DEVICE(>asc), "asctype", ASC_TYPE_EASC);
+if (machine->audiodev) {
+qdev_prop_set_string(DEVICE(>asc), "audiodev", machine->audiodev);
+}
+sysbus = SYS_BUS_DEVICE(>asc);
+sysbus_realize_and_unref(sysbus, _fatal);
+memory_region_add_subregion(>macio, ASC_BASE - IO_BASE,
+sysbus_mmio_get_region(sysbus, 0));
+sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(DEVICE(>glue),
+   GLUE_IRQ_IN_ASC));
+
+/* Wire ASC IRQ via GLUE for use in classic mode */
+qdev_connect_gpio_out(DEVICE(>glue), GLUE_IRQ_ASC,
+  qdev_get_gpio_in(DEVICE(>via2),
+   VIA2_IRQ_ASC_BIT));
+
 /* SWIM floppy controller */
 
 object_initialize_child(OBJECT(machine), "swim", >swim,
@@ -688,6 +708,7 @@ static void q800_machine_class_init(ObjectClass *oc, void 
*data)
 mc->max_cpus = 1;
 mc->block_default_type = IF_SCSI;
 mc->default_ram_id = "m68k_mac.ram";
+machine_add_audiodev_property(mc);
 compat_props_add(mc->compat_props, hw_compat_q800, hw_compat_q800_len);
 }
 
-- 
2.41.0




[PULL 02/20] q800: add djMEMC memory controller

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

The djMEMC controller is used to store information related to the physical 
memory
configuration.

Co-developed-by: Laurent Vivier 
Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20231004083806.757242-3-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 MAINTAINERS  |   2 +
 include/hw/m68k/q800.h   |   2 +
 include/hw/misc/djmemc.h |  30 +
 hw/m68k/q800.c   |  10 +++
 hw/misc/djmemc.c | 135 +++
 hw/m68k/Kconfig  |   1 +
 hw/misc/Kconfig  |   3 +
 hw/misc/meson.build  |   1 +
 hw/misc/trace-events |   4 ++
 9 files changed, 188 insertions(+)
 create mode 100644 include/hw/misc/djmemc.h
 create mode 100644 hw/misc/djmemc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ea91f9e80481..dead0d4a47e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1229,6 +1229,7 @@ F: hw/misc/mac_via.c
 F: hw/nubus/*
 F: hw/display/macfb.c
 F: hw/block/swim.c
+F: hw/misc/djmemc.c
 F: hw/m68k/bootinfo.h
 F: include/standard-headers/asm-m68k/bootinfo.h
 F: include/standard-headers/asm-m68k/bootinfo-mac.h
@@ -1238,6 +1239,7 @@ F: include/hw/display/macfb.h
 F: include/hw/block/swim.h
 F: include/hw/m68k/q800.h
 F: include/hw/m68k/q800-glue.h
+F: include/hw/misc/djmemc.h
 
 virt
 M: Laurent Vivier 
diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index b3d77f1cba6e..f6ae4c1c4fd5 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -36,6 +36,7 @@
 #include "hw/block/swim.h"
 #include "hw/nubus/mac-nubus-bridge.h"
 #include "hw/display/macfb.h"
+#include "hw/misc/djmemc.h"
 
 /*
  * The main Q800 machine
@@ -56,6 +57,7 @@ struct Q800MachineState {
 Swim swim;
 MacNubusBridge mac_nubus_bridge;
 MacfbNubusState macfb;
+DJMEMCState djmemc;
 MemoryRegion macio;
 MemoryRegion macio_alias;
 };
diff --git a/include/hw/misc/djmemc.h b/include/hw/misc/djmemc.h
new file mode 100644
index ..82d4e4a2fee2
--- /dev/null
+++ b/include/hw/misc/djmemc.h
@@ -0,0 +1,30 @@
+/*
+ * djMEMC, macintosh memory and interrupt controller
+ * (Quadra 610/650/800 & Centris 610/650)
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MISC_DJMEMC_H
+#define HW_MISC_DJMEMC_H
+
+#include "hw/sysbus.h"
+
+#define DJMEMC_SIZE0x2000
+#define DJMEMC_NUM_REGS(0x38 / sizeof(uint32_t))
+
+#define DJMEMC_MAXBANKS10
+
+struct DJMEMCState {
+SysBusDevice parent_obj;
+
+MemoryRegion mem_regs;
+
+/* Memory controller */
+uint32_t regs[DJMEMC_NUM_REGS];
+};
+
+#define TYPE_DJMEMC "djMEMC"
+OBJECT_DECLARE_SIMPLE_TYPE(DJMEMCState, DJMEMC);
+
+#endif
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index b770b71d5475..f9ecc1fbb094 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -40,6 +40,7 @@
 #include "hw/m68k/q800.h"
 #include "hw/m68k/q800-glue.h"
 #include "hw/misc/mac_via.h"
+#include "hw/misc/djmemc.h"
 #include "hw/input/adb.h"
 #include "hw/nubus/mac-nubus-bridge.h"
 #include "hw/display/macfb.h"
@@ -66,6 +67,7 @@
 #define SONIC_PROM_BASE   (IO_BASE + 0x08000)
 #define SONIC_BASE(IO_BASE + 0x0a000)
 #define SCC_BASE  (IO_BASE + 0x0c020)
+#define DJMEMC_BASE   (IO_BASE + 0x0e000)
 #define ESP_BASE  (IO_BASE + 0x1)
 #define ESP_PDMA  (IO_BASE + 0x10100)
 #define ASC_BASE  (IO_BASE + 0x14000)
@@ -257,6 +259,14 @@ static void q800_machine_init(MachineState *machine)
  _abort);
 sysbus_realize(SYS_BUS_DEVICE(>glue), _fatal);
 
+/* djMEMC memory controller */
+object_initialize_child(OBJECT(machine), "djmemc", >djmemc,
+TYPE_DJMEMC);
+sysbus = SYS_BUS_DEVICE(>djmemc);
+sysbus_realize_and_unref(sysbus, _fatal);
+memory_region_add_subregion(>macio, DJMEMC_BASE - IO_BASE,
+sysbus_mmio_get_region(sysbus, 0));
+
 /* VIA 1 */
 object_initialize_child(OBJECT(machine), "via1", >via1,
 TYPE_MOS6522_Q800_VIA1);
diff --git a/hw/misc/djmemc.c b/hw/misc/djmemc.c
new file mode 100644
index ..fd02640838b8
--- /dev/null
+++ b/hw/misc/djmemc.c
@@ -0,0 +1,135 @@
+/*
+ * djMEMC, macintosh memory and interrupt controller
+ * (Quadra 610/650/800 & Centris 610/650)
+ *
+ *https://mac68k.info/wiki/display/mac68k/djMEMC+Information
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/misc/djmemc.h"
+#include "hw/qdev-properties.h"
+#include "trace.h"
+
+
+#define DJMEMC_INTERLEAVECONF   0x0
+#define DJMEMC_BANK0CONF0x4
+#define DJMEMC_BANK1CONF0x8
+#define DJMEMC_BANK2CONF0xc
+#define DJMEMC_BANK3CONF0x10
+#define DJMEMC_BANK4CONF0x14
+#define DJMEMC_BANK5CONF0x18
+#define DJMEMC_BANK6CONF0x1c
+#define DJMEMC_BANK7CONF0x20
+#define 

[PULL 18/20] q800: add ESCC alias at 0xc000

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

Tests on real Q800 hardware show that the ESCC is addressable at multiple 
locations
within the ESCC memory region - at least 0xc000, 0xc020 (as expected by the 
MacOS
toolbox ROM) and 0xc040.

All released NetBSD kernels before 10 use the 0xc000 address which causes a 
fatal
error when running the MacOS booter. Add a single memory region alias at 0xc000
to enable NetBSD kernels to start booting under QEMU.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-19-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/m68k/q800.h | 1 +
 hw/m68k/q800.c | 6 ++
 2 files changed, 7 insertions(+)

diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index fbaacd88bd57..348eaf4703d0 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -67,6 +67,7 @@ struct Q800MachineState {
 MemoryRegion macio;
 MemoryRegion macio_alias;
 MemoryRegion machine_id;
+MemoryRegion escc_alias;
 };
 
 #define TYPE_Q800_MACHINE MACHINE_TYPE_NAME("q800")
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index ac3115d32844..27a0b3c08a98 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -451,6 +451,12 @@ static void q800_machine_init(MachineState *machine)
 memory_region_add_subregion(>macio, SCC_BASE - IO_BASE,
 sysbus_mmio_get_region(sysbus, 0));
 
+/* Create alias for NetBSD */
+memory_region_init_alias(>escc_alias, OBJECT(machine), "escc-alias",
+ sysbus_mmio_get_region(sysbus, 0), 0, 0x8);
+memory_region_add_subregion(>macio, SCC_BASE - IO_BASE - 0x20,
+>escc_alias);
+
 /* SCSI */
 
 object_initialize_child(OBJECT(machine), "esp", >esp,
-- 
2.41.0




[PULL 20/20] mac_via: extend timer calibration hack to work with A/UX

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

The A/UX timer calibration loop runs continuously until 2 consecutive iterations
differ by at least 0x492 timer ticks. Modern hosts execute the timer calibration
loop so fast that this situation never occurs causing a hang on boot.

Use a similar method to Shoebill which is to randomly add 0x500 to the T2
counter value during calibration to enable it to eventually succeed.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-21-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 hw/misc/mac_via.c | 56 +++
 1 file changed, 56 insertions(+)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 500ece5872bd..b6206ef73ca7 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -983,6 +983,44 @@ static void 
via1_timer_calibration_hack(MOS6522Q800VIA1State *v1s, int addr,
 /* Looks like there has been a reset? */
 v1s->timer_hack_state = 1;
 }
+
+if (addr == VIA_REG_T2CL && val == 0xf0) {
+/* VIA_REG_T2CL: low byte of counter (A/UX) */
+v1s->timer_hack_state = 5;
+}
+break;
+case 5:
+if (addr == VIA_REG_T2CH && val == 0x3c) {
+/*
+ * VIA_REG_T2CH: high byte of counter (A/UX). We are now extremely
+ * likely to be in the A/UX timer calibration routine, so move to
+ * the next state where we enable the calibration hack.
+ */
+v1s->timer_hack_state = 6;
+} else if ((addr == VIA_REG_IER && val == 0x20) ||
+   addr == VIA_REG_T2CH) {
+/* We're doing something else with the timer, not calibration */
+v1s->timer_hack_state = 0;
+}
+break;
+case 6:
+if ((addr == VIA_REG_IER && val == 0x20) || addr == VIA_REG_T2CH) {
+/* End of A/UX timer calibration routine, or another write */
+v1s->timer_hack_state = 7;
+} else {
+v1s->timer_hack_state = 0;
+}
+break;
+case 7:
+/*
+ * This is the normal post-calibration timer state once both the
+ * MacOS toolbox and A/UX have been calibrated, until we see a write
+ * to VIA_REG_PCR to suggest a reset
+ */
+if (addr == VIA_REG_PCR && val == 0x22) {
+/* Looks like there has been a reset? */
+v1s->timer_hack_state = 1;
+}
 break;
 default:
 g_assert_not_reached();
@@ -998,6 +1036,7 @@ static uint64_t mos6522_q800_via1_read(void *opaque, 
hwaddr addr, unsigned size)
 MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
 MOS6522State *ms = MOS6522(s);
 uint64_t ret;
+int64_t now;
 
 addr = (addr >> 9) & 0xf;
 ret = mos6522_read(ms, addr, size);
@@ -1007,6 +1046,23 @@ static uint64_t mos6522_q800_via1_read(void *opaque, 
hwaddr addr, unsigned size)
 /* Quadra 800 Id */
 ret = (ret & ~VIA1A_CPUID_MASK) | VIA1A_CPUID_Q800;
 break;
+case VIA_REG_T2CH:
+if (s->timer_hack_state == 6) {
+/*
+ * The A/UX timer calibration loop runs continuously until 2
+ * consecutive iterations differ by at least 0x492 timer ticks.
+ * Modern hosts execute the timer calibration loop so fast that
+ * this situation never occurs causing a hang on boot. Use a
+ * similar method to Shoebill which is to randomly add 0x500 to
+ * the T2 counter value during calibration to enable it to
+ * eventually succeed.
+ */
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+if (now & 1) {
+ret += 0x5;
+}
+}
+break;
 }
 return ret;
 }
-- 
2.41.0




[PULL 00/20] Q800 for 8.2 patches

2023-10-08 Thread Laurent Vivier
The following changes since commit 2f3913f4b2ad74baeb5a6f1d36efbd9ecdf1057d:

  Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu 
into staging (2023-10-05 09:01:01 -0400)

are available in the Git repository at:

  https://github.com/vivier/qemu-m68k.git tags/q800-for-8.2-pull-request

for you to fetch changes up to b4d3a83b89fba814613f7ead6b6ea92e0b2c3cd8:

  mac_via: extend timer calibration hack to work with A/UX (2023-10-06 10:33:43 
+0200)


Pull request q800 20231008

add support for booting:
  - MacOS 7.1 - 8.1, with or without virtual memory enabled
  - A/UX 3.0.1
  - NetBSD 9.3
  - Linux (via EMILE)



Mark Cave-Ayland (20):
  q800-glue.c: convert to Resettable interface
  q800: add djMEMC memory controller
  q800: add machine id register
  q800: implement additional machine id bits on VIA1 port A
  q800: add IOSB subsystem
  q800: allow accesses to RAM area even if less memory is available
  audio: add Apple Sound Chip (ASC) emulation
  asc: generate silence if FIFO empty but engine still running
  q800: add Apple Sound Chip (ASC) audio to machine
  q800: add easc bool machine class property to switch between ASC and
EASC
  swim: add trace events for IWM and ISM registers
  swim: split into separate IWM and ISM register blocks
  swim: update IWM/ISM register block decoding
  mac_via: work around underflow in TimeDBRA timing loop in SETUPTIMEK
  mac_via: workaround NetBSD ADB bus enumeration issue
  mac_via: implement ADB_STATE_IDLE state if shift register in input
mode
  mac_via: always clear ADB interrupt when switching to A/UX mode
  q800: add ESCC alias at 0xc000
  q800: add alias for MacOS toolbox ROM at 0x4000
  mac_via: extend timer calibration hack to work with A/UX

 MAINTAINERS |   6 +
 include/hw/audio/asc.h  |  86 +
 include/hw/block/swim.h |  21 +-
 include/hw/m68k/q800-glue.h |   4 +-
 include/hw/m68k/q800.h  |  11 +
 include/hw/misc/djmemc.h|  30 ++
 include/hw/misc/iosb.h  |  25 ++
 include/hw/misc/mac_via.h   |   3 +
 hw/audio/asc.c  | 727 
 hw/block/swim.c | 261 -
 hw/m68k/q800-glue.c |  18 +-
 hw/m68k/q800.c  | 138 ++-
 hw/misc/djmemc.c| 135 +++
 hw/misc/iosb.c  | 133 +++
 hw/misc/mac_via.c   | 234 +++-
 hw/audio/Kconfig|   3 +
 hw/audio/meson.build|   1 +
 hw/audio/trace-events   |  10 +
 hw/block/trace-events   |   8 +
 hw/m68k/Kconfig |   3 +
 hw/misc/Kconfig |   6 +
 hw/misc/meson.build |   2 +
 hw/misc/trace-events|  10 +
 23 files changed, 1769 insertions(+), 106 deletions(-)
 create mode 100644 include/hw/audio/asc.h
 create mode 100644 include/hw/misc/djmemc.h
 create mode 100644 include/hw/misc/iosb.h
 create mode 100644 hw/audio/asc.c
 create mode 100644 hw/misc/djmemc.c
 create mode 100644 hw/misc/iosb.c

-- 
2.41.0




[PULL 04/20] q800: implement additional machine id bits on VIA1 port A

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

Co-developed-by: Laurent Vivier 
Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20231004083806.757242-5-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 hw/misc/mac_via.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index f84cc68849ab..e87a1b82d8c5 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -114,6 +114,9 @@
 #define VIA1A_CPUID10x04/* CPU id bit 0 on RBV, others */
 #define VIA1A_CPUID20x10/* CPU id bit 0 on RBV, others */
 #define VIA1A_CPUID30x40/* CPU id bit 0 on RBV, others */
+#define VIA1A_CPUID_MASK (VIA1A_CPUID0 | VIA1A_CPUID1 | \
+  VIA1A_CPUID2 | VIA1A_CPUID3)
+#define VIA1A_CPUID_Q800 (VIA1A_CPUID0 | VIA1A_CPUID2)
 
 /*
  * Info on VIA1B is from Macintosh Family Hardware & MkLinux.
@@ -872,9 +875,18 @@ static uint64_t mos6522_q800_via1_read(void *opaque, 
hwaddr addr, unsigned size)
 {
 MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
 MOS6522State *ms = MOS6522(s);
+uint64_t ret;
 
 addr = (addr >> 9) & 0xf;
-return mos6522_read(ms, addr, size);
+ret = mos6522_read(ms, addr, size);
+switch (addr) {
+case VIA_REG_A:
+case VIA_REG_ANH:
+/* Quadra 800 Id */
+ret = (ret & ~VIA1A_CPUID_MASK) | VIA1A_CPUID_Q800;
+break;
+}
+return ret;
 }
 
 static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val,
-- 
2.41.0




[PULL 13/20] swim: update IWM/ISM register block decoding

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

Update the IWM/ISM register block decoding to match the description given in the
"SWIM Chip Users Reference". This allows us to validate the device response to
the guest OS which currently only does just enough to indicate that the floppy
drive is unavailable.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-14-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/block/swim.h |   8 +-
 hw/block/swim.c | 212 +---
 hw/block/trace-events   |   7 +-
 3 files changed, 143 insertions(+), 84 deletions(-)

diff --git a/include/hw/block/swim.h b/include/hw/block/swim.h
index 1bc7635d0212..5f567e8d5957 100644
--- a/include/hw/block/swim.h
+++ b/include/hw/block/swim.h
@@ -50,13 +50,15 @@ struct SWIMCtrl {
 int mode;
 /* IWM mode */
 int iwm_switch;
-uint8_t iwmregs[16];
-uint8_t iwm_data;
-uint8_t iwm_mode;
+uint8_t iwm_latches;
+uint8_t iwmregs[8];
 /* SWIM mode */
 uint8_t ismregs[16];
 uint8_t swim_phase;
 uint8_t swim_mode;
+uint8_t swim_status;
+uint8_t pram[16];
+uint8_t pram_idx;
 SWIMBus bus;
 };
 
diff --git a/hw/block/swim.c b/hw/block/swim.c
index 505718bdae3f..fd65c59f8a10 100644
--- a/hw/block/swim.c
+++ b/hw/block/swim.c
@@ -21,24 +21,28 @@
 #include "hw/qdev-properties.h"
 #include "trace.h"
 
+
+/* IWM latch bits */
+
+#define IWMLB_PHASE00
+#define IWMLB_PHASE11
+#define IWMLB_PHASE22
+#define IWMLB_PHASE33
+#define IWMLB_MOTORON   4
+#define IWMLB_DRIVESEL  5
+#define IWMLB_L66
+#define IWMLB_L77
+
 /* IWM registers */
 
-#define IWM_PH0L0
-#define IWM_PH0H1
-#define IWM_PH1L2
-#define IWM_PH1H3
-#define IWM_PH2L4
-#define IWM_PH2H5
-#define IWM_PH3L6
-#define IWM_PH3H7
-#define IWM_MTROFF  8
-#define IWM_MTRON   9
-#define IWM_INTDRIVE10
-#define IWM_EXTDRIVE11
-#define IWM_Q6L 12
-#define IWM_Q6H 13
-#define IWM_Q7L 14
-#define IWM_Q7H 15
+#define IWM_READALLONES 0
+#define IWM_READDATA1
+#define IWM_READSTATUS0 2
+#define IWM_READSTATUS1 3
+#define IWM_READWHANDSHAKE0 4
+#define IWM_READWHANDSHAKE1 5
+#define IWM_WRITESETMODE6
+#define IWM_WRITEDATA   7
 
 /* SWIM registers */
 
@@ -62,8 +66,9 @@
 
 #define REG_SHIFT   9
 
-#define SWIM_MODE_IWM  0
-#define SWIM_MODE_SWIM 1
+#define SWIM_MODE_STATUS_BIT6
+#define SWIM_MODE_IWM   0
+#define SWIM_MODE_ISM   1
 
 /* bits in phase register */
 
@@ -127,10 +132,8 @@
 #define SWIM_MOTON   0x80
 
 static const char *iwm_reg_names[] = {
-"PH0L", "PH0H", "PH1L", "PH1H",
-"PH2L", "PH2H", "PH3L", "PH3H",
-"MTROFF", "MTRON", "INTDRIVE", "EXTDRIVE",
-"Q6L", "Q6H", "Q7L", "Q7H"
+"READALLONES", "READDATA", "READSTATUS0", "READSTATUS1",
+"READWHANDSHAKE0", "READWHANDSHAKE1", "WRITESETMODE", "WRITEDATA"
 };
 
 static const char *ism_reg_names[] = {
@@ -274,68 +277,99 @@ static const TypeInfo swim_bus_info = {
 .instance_size = sizeof(SWIMBus),
 };
 
-static void iwmctrl_write(void *opaque, hwaddr reg, uint64_t value,
+static void iwmctrl_write(void *opaque, hwaddr addr, uint64_t value,
   unsigned size)
 {
 SWIMCtrl *swimctrl = opaque;
+uint8_t latch, reg, ism_bit;
 
-reg >>= REG_SHIFT;
+addr >>= REG_SHIFT;
+
+/* A3-A1 select a latch, A0 specifies the value */
+latch = (addr >> 1) & 7;
+if (addr & 1) {
+swimctrl->iwm_latches |= (1 << latch);
+} else {
+swimctrl->iwm_latches &= ~(1 << latch);
+}
+
+reg = (swimctrl->iwm_latches & 0xc0) >> 5 |
+  (swimctrl->iwm_latches & 0x10) >> 4;
 
 swimctrl->iwmregs[reg] = value;
 trace_swim_iwmctrl_write(reg, iwm_reg_names[reg], size, value);
 
-if (swimctrl->iwmregs[IWM_Q7H]) {
-if (swimctrl->iwmregs[IWM_MTRON]) {
-/* data register */
-swimctrl->iwm_data = value;
-} else {
-/* mode register */
-swimctrl->iwm_mode = value;
-/* detect sequence to switch from IWM mode to SWIM mode */
-switch (swimctrl->iwm_switch) {
-case 0:
-if (value == 0x57) {
-swimctrl->iwm_switch++;
-}
-break;
-case 1:
-if (value == 0x17) {
-swimctrl->iwm_switch++;
-}
-break;
-case 2:
-if (value == 0x57) {
-swimctrl->iwm_switch++;
-}
-break;
-case 3:
-

[PULL 19/20] q800: add alias for MacOS toolbox ROM at 0x40000000

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

According to the Apple Quadra 800 Developer Note document, the Quadra 800 ROM
consists of 2 ROM code sections based at offsets 0x0 and 0x80. A/UX attempts
to access the toolbox ROM at the lower offset during startup, so provide a
memory alias to allow the access to succeed.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-20-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 include/hw/m68k/q800.h | 1 +
 hw/m68k/q800.c | 5 +
 2 files changed, 6 insertions(+)

diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index 348eaf4703d0..a9661f65f695 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -50,6 +50,7 @@ struct Q800MachineState {
 bool easc;
 M68kCPU cpu;
 MemoryRegion rom;
+MemoryRegion rom_alias;
 GLUEState glue;
 MOS6522Q800VIA1State via1;
 MOS6522Q800VIA2State via2;
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 27a0b3c08a98..1d7cd5ff1c31 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -660,6 +660,11 @@ static void q800_machine_init(MachineState *machine)
 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
 memory_region_add_subregion(get_system_memory(), MACROM_ADDR, >rom);
 
+memory_region_init_alias(>rom_alias, NULL, "m68k_mac.rom-alias",
+ >rom, 0, MACROM_SIZE);
+memory_region_add_subregion(get_system_memory(), 0x4000,
+>rom_alias);
+
 /* Load MacROM binary */
 if (filename) {
 bios_size = load_image_targphys(filename, MACROM_ADDR, 
MACROM_SIZE);
-- 
2.41.0




[PULL 11/20] swim: add trace events for IWM and ISM registers

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-12-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 hw/block/swim.c   | 14 ++
 hw/block/trace-events |  7 +++
 2 files changed, 21 insertions(+)

diff --git a/hw/block/swim.c b/hw/block/swim.c
index 333da08ce093..7df36ea139cb 100644
--- a/hw/block/swim.c
+++ b/hw/block/swim.c
@@ -19,6 +19,7 @@
 #include "hw/block/block.h"
 #include "hw/block/swim.h"
 #include "hw/qdev-properties.h"
+#include "trace.h"
 
 /* IWM registers */
 
@@ -125,6 +126,13 @@
 #define SWIM_HEDSEL  0x20
 #define SWIM_MOTON   0x80
 
+static const char *swim_reg_names[] = {
+"WRITE_DATA", "WRITE_MARK", "WRITE_CRC", "WRITE_PARAMETER",
+"WRITE_PHASE", "WRITE_SETUP", "WRITE_MODE0", "WRITE_MODE1",
+"READ_DATA", "READ_MARK", "READ_ERROR", "READ_PARAMETER",
+"READ_PHASE", "READ_SETUP", "READ_STATUS", "READ_HANDSHAKE"
+};
+
 static void fd_recalibrate(FDrive *drive)
 {
 }
@@ -267,6 +275,7 @@ static void iwmctrl_write(void *opaque, hwaddr reg, 
uint64_t value,
 reg >>= REG_SHIFT;
 
 swimctrl->regs[reg >> 1] = reg & 1;
+trace_swim_iwmctrl_write((reg >> 1), size, (reg & 1));
 
 if (swimctrl->regs[IWM_Q6] &&
 swimctrl->regs[IWM_Q7]) {
@@ -297,6 +306,7 @@ static void iwmctrl_write(void *opaque, hwaddr reg, 
uint64_t value,
 if (value == 0x57) {
 swimctrl->mode = SWIM_MODE_SWIM;
 swimctrl->iwm_switch = 0;
+trace_swim_iwm_switch();
 }
 break;
 }
@@ -312,6 +322,7 @@ static uint64_t iwmctrl_read(void *opaque, hwaddr reg, 
unsigned size)
 
 swimctrl->regs[reg >> 1] = reg & 1;
 
+trace_swim_iwmctrl_read((reg >> 1), size, (reg & 1));
 return 0;
 }
 
@@ -327,6 +338,8 @@ static void swimctrl_write(void *opaque, hwaddr reg, 
uint64_t value,
 
 reg >>= REG_SHIFT;
 
+trace_swim_swimctrl_write(reg, swim_reg_names[reg], size, value);
+
 switch (reg) {
 case SWIM_WRITE_PHASE:
 swimctrl->swim_phase = value;
@@ -376,6 +389,7 @@ static uint64_t swimctrl_read(void *opaque, hwaddr reg, 
unsigned size)
 break;
 }
 
+trace_swim_swimctrl_read(reg, swim_reg_names[reg], size, value);
 return value;
 }
 
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 34be8b9135f5..c041ec45e312 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -90,3 +90,10 @@ m25p80_read_data(void *s, uint32_t pos, uint8_t v) "[%p] 
Read data 0x%"PRIx32"=0
 m25p80_read_sfdp(void *s, uint32_t addr, uint8_t v) "[%p] Read SFDP 
0x%"PRIx32"=0x%"PRIx8
 m25p80_binding(void *s) "[%p] Binding to IF_MTD drive"
 m25p80_binding_no_bdrv(void *s) "[%p] No BDRV - binding to RAM"
+
+# swim.c
+swim_swimctrl_read(int reg, const char *name, unsigned size, uint64_t value) 
"reg=%d [%s] size=%u value=0x%"PRIx64
+swim_swimctrl_write(int reg, const char *name, unsigned size, uint64_t value) 
"reg=%d [%s] size=%u value=0x%"PRIx64
+swim_iwmctrl_read(int reg, unsigned size, uint64_t value) "reg=%d size=%u 
value=0x%"PRIx64
+swim_iwmctrl_write(int reg, unsigned size, uint64_t value) "reg=%d size=%u 
value=0x%"PRIx64
+swim_iwm_switch(void) "switch from IWM to SWIM mode"
-- 
2.41.0




[PULL 17/20] mac_via: always clear ADB interrupt when switching to A/UX mode

2023-10-08 Thread Laurent Vivier
From: Mark Cave-Ayland 

When the NetBSD kernel initialises it can leave the ADB interrupt asserted
depending upon where in the ADB poll cycle the MacOS ADB interrupt handler
is when the NetBSD kernel disables interrupts.

The NetBSD ADB driver uses the ADB interrupt state to determine if the ADB
is busy and refuses to send ADB commands unless it is clear. To ensure that
this doesn't happen, always clear the ADB interrupt when switching to A/UX
mode to ensure that the bus enumeration always occurs.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Message-ID: <20231004083806.757242-18-mark.cave-ayl...@ilande.co.uk>
Signed-off-by: Laurent Vivier 
---
 hw/misc/mac_via.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index 3c41d6263d45..500ece5872bd 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -875,6 +875,15 @@ static void via1_auxmode_update(MOS6522Q800VIA1State *v1s)
 if (irq != oldirq) {
 trace_via1_auxmode(irq);
 qemu_set_irq(v1s->auxmode_irq, irq);
+
+/*
+ * Clear the ADB interrupt. MacOS can leave VIA1B_vADBInt asserted
+ * (low) if a poll sequence doesn't complete before NetBSD disables
+ * interrupts upon boot. Fortunately NetBSD switches to the so-called
+ * "A/UX" interrupt mode after it initialises, so we can use this as
+ * a convenient place to clear the ADB interrupt for now.
+ */
+s->b |= VIA1B_vADBInt;
 }
 }
 
-- 
2.41.0




Re: [PATCH] libvhost-user: Fix compiler warning with -Wshadow=local

2023-10-08 Thread Michael S. Tsirkin
On Fri, Oct 06, 2023 at 02:11:29PM +0200, Thomas Huth wrote:
> Rename shadowing variables to make this code compilable
> with -Wshadow=local.
> 
> Signed-off-by: Thomas Huth 

Reviewed-by: Michael S. Tsirkin 

> ---
>  subprojects/libvhost-user/libvhost-user.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/subprojects/libvhost-user/libvhost-user.c 
> b/subprojects/libvhost-user/libvhost-user.c
> index 051a611da3..ea2822a44c 100644
> --- a/subprojects/libvhost-user/libvhost-user.c
> +++ b/subprojects/libvhost-user/libvhost-user.c
> @@ -870,10 +870,10 @@ vu_rem_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
>  for (i = 0; i < dev->nregions; i++) {
>  if (reg_equal(>regions[i], msg_region)) {
>  VuDevRegion *r = >regions[i];
> -void *m = (void *) (uintptr_t) r->mmap_addr;
> +void *ma = (void *) (uintptr_t) r->mmap_addr;
>  
> -if (m) {
> -munmap(m, r->size + r->mmap_offset);
> +if (ma) {
> +munmap(ma, r->size + r->mmap_offset);
>  }
>  
>  /*
> @@ -1005,10 +1005,10 @@ vu_set_mem_table_exec(VuDev *dev, VhostUserMsg *vmsg)
>  
>  for (i = 0; i < dev->nregions; i++) {
>  VuDevRegion *r = >regions[i];
> -void *m = (void *) (uintptr_t) r->mmap_addr;
> +void *ma = (void *) (uintptr_t) r->mmap_addr;
>  
> -if (m) {
> -munmap(m, r->size + r->mmap_offset);
> +if (ma) {
> +munmap(ma, r->size + r->mmap_offset);
>  }
>  }
>  dev->nregions = memory->nregions;
> -- 
> 2.41.0




Re: [PATCH 2/3] hw/pci-host: Add emulation of Mai Logic Articia S

2023-10-08 Thread Mark Cave-Ayland

On 05/10/2023 23:13, BALATON Zoltan wrote:


The Articia S is a generic chipset supporting several different CPUs
that were used on some PPC boards. This is a minimal emulation of the
parts needed for emulating the AmigaOne board.

Signed-off-by: BALATON Zoltan 
---
  hw/pci-host/Kconfig   |   5 +
  hw/pci-host/articia.c | 266 ++
  hw/pci-host/meson.build   |   2 +
  include/hw/pci-host/articia.h |  17 +++
  4 files changed, 290 insertions(+)
  create mode 100644 hw/pci-host/articia.c
  create mode 100644 include/hw/pci-host/articia.h

diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index a07070eddf..33014c80a4 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -73,6 +73,11 @@ config SH_PCI
  bool
  select PCI
  
+config ARTICIA

+bool
+select PCI
+select I8259
+
  config MV64361
  bool
  select PCI
diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
new file mode 100644
index 00..80558e1c47
--- /dev/null
+++ b/hw/pci-host/articia.c
@@ -0,0 +1,266 @@
+/*
+ * Mai Logic Articia S emulation
+ *
+ * Copyright (c) 2023 BALATON Zoltan
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/pci/pci_device.h"
+#include "hw/pci/pci_host.h"
+#include "hw/irq.h"
+#include "hw/i2c/bitbang_i2c.h"
+#include "hw/intc/i8259.h"
+#include "hw/pci-host/articia.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaState, ARTICIA)
+
+OBJECT_DECLARE_SIMPLE_TYPE(ArticiaHostState, ARTICIA_PCI_HOST)
+struct ArticiaHostState {
+PCIDevice parent_obj;
+
+ArticiaState *as;
+};
+
+/* TYPE_ARTICIA */
+
+struct ArticiaState {
+PCIHostState parent_obj;
+
+qemu_irq irq[PCI_NUM_PINS];
+MemoryRegion io;
+MemoryRegion mem;
+MemoryRegion reg;
+
+bitbang_i2c_interface smbus;
+uint32_t gpio; /* bits 0-7 in, 8-15 out, 16-23 direction (0 in, 1 out) */
+hwaddr gpio_base;
+MemoryRegion gpio_reg;
+};


These types above should be in the header file and not in the C file, as per our 
current QOM guidelines.



+static uint64_t articia_gpio_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ArticiaState *s = opaque;
+
+return (s->gpio >> (addr * 8)) & 0xff;
+}
+
+static void articia_gpio_write(void *opaque, hwaddr addr, uint64_t val,
+   unsigned int size)
+{
+ArticiaState *s = opaque;
+uint32_t sh = addr * 8;
+
+if (addr == 0) {
+/* in bits read only? */
+return;
+}
+
+if ((s->gpio & (0xff << sh)) != (val & 0xff) << sh) {
+s->gpio &= ~(0xff << sh | 0xff);
+s->gpio |= (val & 0xff) << sh;
+s->gpio |= bitbang_i2c_set(>smbus, BITBANG_I2C_SDA,
+   s->gpio & BIT(16) ?
+   !!(s->gpio & BIT(8)) : 1);
+if ((s->gpio & BIT(17))) {
+s->gpio &= ~BIT(0);
+s->gpio |= bitbang_i2c_set(>smbus, BITBANG_I2C_SCL,
+   !!(s->gpio & BIT(9)));
+}
+}
+}
+
+static const MemoryRegionOps articia_gpio_ops = {
+.read = articia_gpio_read,
+.write = articia_gpio_write,
+.valid.min_access_size = 1,
+.valid.max_access_size = 1,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static uint64_t articia_reg_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ArticiaState *s = opaque;
+uint64_t ret = UINT_MAX;
+
+switch (addr) {
+case 0xc00cf8:
+ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(s), 0, size);
+break;
+case 0xe00cfc ... 0xe00cff:
+ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(s), addr - 0xe00cfc, 
size);
+break;
+case 0xf0:
+ret = pic_read_irq(isa_pic);
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register read 0x%"
+  HWADDR_PRIx " %d\n", __func__, addr, size);
+break;
+}
+return ret;
+}
+
+static void articia_reg_write(void *opaque, hwaddr addr, uint64_t val,
+  unsigned int size)
+{
+ArticiaState *s = opaque;
+
+switch (addr) {
+case 0xc00cf8:
+pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(s), 0, val, size);
+break;
+case 0xe00cfc ... 0xe00cff:
+pci_host_data_le_ops.write(PCI_HOST_BRIDGE(s), addr, val, size);
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register write 0x%"
+  HWADDR_PRIx " %d <- %"PRIx64"\n", __func__, addr, size, 
val);
+break;
+}
+}
+
+static const MemoryRegionOps articia_reg_ops = {
+.read = articia_reg_read,
+.write = articia_reg_write,
+.valid.min_access_size = 1,
+.valid.max_access_size = 4,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void articia_pcihost_set_irq(void *opaque, int n, int level)
+{
+ArticiaState *s = opaque;
+

Re: [PULL 00/26] Audio, source reorg, HVF changes for 2023-10-06

2023-10-08 Thread Paolo Bonzini
Il ven 6 ott 2023, 13:14 Paolo Bonzini  ha scritto:

> The following changes since commit
> da1034094d375afe9e3d8ec8980550ea0f06f7e0:
>
>   Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into
> staging (2023-10-03 07:43:44 -0400)
>
> are available in the Git repository at:
>
>   https://gitlab.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to 0451b622193aa405c4d9f9ef251aa9ce580adc7f:
>
>   audio, qtest: get rid of QEMU_AUDIO_DRV (2023-10-05 18:43:02 +0200)
>

There are conflicts so I will update the tag.

Paolo


> 
> * util/log: re-allow switching away from stderr log file
> * finish audio configuration rework
> * cleanup HVF stubs
> * remove more mentions of softmmu
>
> 
> Fiona Ebner (1):
>   util/log: re-allow switching away from stderr log file
>
> Paolo Bonzini (9):
>   configure: change $softmmu to $system
>   cutils: squelch compiler warnings with custom paths
>   audio: error hints need a trailing \n
>   audio: disable default backends if -audio/-audiodev is used
>   audio: extract audio_define_default
>   audio: extend -audio to allow creating a default backend
>   audio: do not use first -audiodev as default audio device
>   audio: reintroduce default audio backend for VNC
>   audio, qtest: get rid of QEMU_AUDIO_DRV
>
> Philippe Mathieu-Daudé (16):
>   target/i386/hvf: Remove unused includes in 'hvf-i386.h'
>   sysemu/kvm: Restrict hvf_get_supported_cpuid() to x86 targets
>   target/i386: Check for USER_ONLY definition instead of SOFTMMU one
>   softmmu/trace-events: Fix a typo
>   travis-ci: Correct invalid mentions of 'softmmu' by 'system'
>   cpu: Correct invalid mentions of 'softmmu' by 'system-mode'
>   fuzz: Correct invalid mentions of 'softmmu' by 'system'
>   tcg: Correct invalid mentions of 'softmmu' by 'system-mode'
>   accel: Rename accel_softmmu* -> accel_system*
>   gdbstub: Rename 'softmmu' -> 'system'
>   semihosting: Rename softmmu_FOO_user() -> uaccess_FOO_user()
>   target/i386: Rename i386_softmmu_kvm_ss -> i386_kvm_ss
>   hw/virtio/meson: Rename softmmu_virtio_ss -> system_virtio_ss
>   meson: Rename softmmu_mods -> system_mods
>   meson: Rename target_softmmu_arch -> target_system_arch
>   system: Rename softmmu/ directory as system/
>
>  .travis.yml|  4 +-
>  MAINTAINERS| 44 +--
>  accel/accel-common.c   |  2 +-
>  accel/{accel-softmmu.c => accel-system.c}  |  6 +-
>  accel/{accel-softmmu.h => accel-system.h}  |  6 +-
>  accel/meson.build  |  2 +-
>  accel/stubs/meson.build| 10 +--
>  accel/tcg/user-exec.c  |  2 +-
>  audio/audio.c  | 85
> +-
>  audio/audio.h  |  3 +
>  configure  | 10 +--
>  cpu.c  |  2 +-
>  docs/about/deprecated.rst  |  6 --
>  docs/about/removed-features.rst| 20 -
>  docs/devel/build-system.rst|  4 +-
>  docs/devel/qtest.rst   |  2 +-
>  docs/devel/testing.rst |  2 +-
>  gdbstub/internals.h|  4 +-
>  gdbstub/meson.build| 10 +--
>  gdbstub/{softmmu.c => system.c}|  2 +-
>  gdbstub/trace-events   |  2 +-
>  hw/core/cpu-common.c   |  4 +-
>  hw/virtio/meson.build  | 22 +++---
>  include/qemu/atomic128.h   |  4 +-
>  .../semihosting/{softmmu-uaccess.h => uaccess.h}   | 24 +++---
>  include/sysemu/hvf.h   |  3 -
>  include/sysemu/runstate-action.h   |  2 +-
>  include/tcg/tcg-op-common.h|  2 +-
>  meson.build| 22 +++---
>  qemu-options.hx| 29 ++--
>  scripts/checkpatch.pl  |  2 +-
>  scripts/coverity-scan/COMPONENTS.md|  2 +-
>  scripts/get_maintainer.pl  |  2 +-
>  scripts/oss-fuzz/build.sh  |  6 +-
>  semihosting/arm-compat-semi.c  |  4 +-
>  semihosting/config.c   |  2 +-
>  semihosting/guestfd.c  |  2 +-
>  semihosting/syscalls.c |  2 +-
>  semihosting/uaccess.c  | 14 ++--
>  softmmu/trace.h 

Re: [PATCH 1/3] via-ide: Fix legacy mode emulation

2023-10-08 Thread Mark Cave-Ayland

On 05/10/2023 23:13, BALATON Zoltan wrote:


The initial value for BARs were set in reset method for emulating
legacy mode at start but this does not work because PCI code resets
BARs after calling device reset method.


This is certainly something I've noticed when testing previous versions of the VIA 
patches. Perhaps it's worth a separate thread to the PCI devs?



Additionally the values
written to BARs were also wrong.


I don't believe this is correct: according to the datasheet the values on reset are 
the ones given in the current reset code, so even if the reset function is overridden 
at a later data during PCI bus reset, I would leave these for now since it is a 
different issue.



Move setting the BARs to a callback on writing the PCI config regsiter
that sets the compatibility mode (which firmwares needing this mode
seem to do) and fix their values to program it to use legacy port
numbers. As noted in a comment, we only do this when the BARs were
unset before, because logs from real machine show this is how real
chip works, even if it contradicts the data sheet which is not very
clear about this.

Signed-off-by: BALATON Zoltan 
---
  hw/ide/via.c | 35 ++-
  1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/hw/ide/via.c b/hw/ide/via.c
index fff23803a6..8186190207 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -132,11 +132,6 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
   PCI_STATUS_DEVSEL_MEDIUM);
  
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, 0x01f0);

-pci_set_long(pci_conf + PCI_BASE_ADDRESS_1, 0x03f4);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_2, 0x0170);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_3, 0x0374);
-pci_set_long(pci_conf + PCI_BASE_ADDRESS_4, 0xcc01); /* BMIBA: 20-23h 
*/
  pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x010e);
  
  /* IDE chip enable, IDE configuration 1/2, IDE FIFO Configuration*/

@@ -159,6 +154,35 @@ static void via_ide_reset(DeviceState *dev)
  pci_set_long(pci_conf + 0xc0, 0x00020001);
  }
  
+static void via_ide_cfg_write(PCIDevice *pd, uint32_t addr,

+  uint32_t val, int len)
+{
+pci_default_write_config(pd, addr, val, len);
+/*
+ * Only set BARs if they are unset. Logs from real hardware show that
+ * writing class_prog to enable compatibility mode after BARs were set
+ * (possibly by firmware) it will use ports set by BARs not ISA ports
+ * (e.g. pegasos2 Linux does this and calls it non-100% native mode).


Can you remind me again where the references are to non-100% native mode? The only 
thing I can find in Linux is 
https://github.com/torvalds/linux/blob/master/arch/powerpc/platforms/chrp/pci.c#L360 
but that simply forces a switch to legacy mode, with no mention of "non-100% native 
mode".



+ * But if 0x8a is written after reset without setting BARs then we want
+ * legacy ports (this is done by AmigaOne firmware for example).
+ */


What should happen here is that writing 0x8a should *always* switch to legacy mode, 
so the BARs are unused...



+if (addr == PCI_CLASS_PROG && val == 0x8a &&
+pci_get_long(pd->config + PCI_BASE_ADDRESS_0) ==
+PCI_BASE_ADDRESS_SPACE_IO) {
+pci_set_long(pd->config + PCI_BASE_ADDRESS_0, 0x1f0
+ | PCI_BASE_ADDRESS_SPACE_IO);
+pci_set_long(pd->config + PCI_BASE_ADDRESS_1, 0x3f6
+ | PCI_BASE_ADDRESS_SPACE_IO);
+pci_set_long(pd->config + PCI_BASE_ADDRESS_2, 0x170
+ | PCI_BASE_ADDRESS_SPACE_IO);
+pci_set_long(pd->config + PCI_BASE_ADDRESS_3, 0x376
+ | PCI_BASE_ADDRESS_SPACE_IO);
+/* BMIBA: 20-23h */
+pci_set_long(pd->config + PCI_BASE_ADDRESS_4, 0xcc00
+ | PCI_BASE_ADDRESS_SPACE_IO);
+}
+}


... but what you're doing here is effectively forcing the PCI BARs to the legacy 
addresses. The reason we know this is because that is why you have the off-by-2 error 
in BARs 1 and 3.


I could live with this approach for now if you're willing to adjust the comments 
accordingly clarifying that forcing the PCI BARs to the legacy addresses is a hack to 
be replaced in future with proper legacy ioports. At some point I will revive my PoC 
series on top of Bernhard's last series that implements this properly.



  static void via_ide_realize(PCIDevice *dev, Error **errp)
  {
  PCIIDEState *d = PCI_IDE(dev);
@@ -221,6 +245,7 @@ static void via_ide_class_init(ObjectClass *klass, void 
*data)
  /* Reason: only works as function of VIA southbridge */
  dc->user_creatable = false;
  
+k->config_write = via_ide_cfg_write;

  k->realize = via_ide_realize;
  k->exit = via_ide_exitfn;
  k->vendor_id = PCI_VENDOR_ID_VIA;



ATB,

Mark.