Re: [PATCH-for-8.0 v2 6/6] hw/virtio: Extract QMP related code virtio-qmp.c

2022-12-21 Thread Philippe Mathieu-Daudé

On 19/12/22 14:31, Jonah Palmer wrote:


On 12/13/22 06:17, Philippe Mathieu-Daudé wrote:

The monitor decoders are the only functions using the CONFIG_xxx
definitions declared in the target specific CONFIG_DEVICES header.

Signed-off-by: Philippe Mathieu-Daudé
---
  hw/virtio/meson.build  |   2 +-
  hw/virtio/virtio-qmp.c | 659 +
  hw/virtio/virtio-qmp.h |  20 ++
  hw/virtio/virtio.c | 635 +--
  4 files changed, 682 insertions(+), 634 deletions(-)
  create mode 100644 hw/virtio/virtio-qmp.c
  create mode 100644 hw/virtio/virtio-qmp.h



I haven't tried this myself, but is there a reason why we're not also including
the 'qmp_decode_vring_desc_flags' function here?


Because we use VirtQueue as an opaque forward-declared structure.

The structure is declared in hw/virtio/virtio.c, which is where
the internal fields are accessed.

If I move qmp_x_query_virtio_queue_status() and
qmp_x_query_virtio_queue_element(), which calls
qmp_decode_vring_desc_flags(), I get:

../hw/virtio/virtio-qmp.c:874:35: error: subscript of pointer to 
incomplete type 'VirtQueue' (aka 'struct VirtQueue')

status->queue_index = vdev->vq[queue].queue_index;
  ^
include/hw/virtio/virtio.h:39:8: note: forward declaration of 'struct 
VirtQueue'

struct VirtQueue;
   ^

Now you are right the QOM-generic functions (qmp_x_query_virtio,
qmp_x_query_virtio_status and qmp_x_query_virtio_vhost_queue_status)
can be moved.

Thanks for your review,

Phil.



[PATCH] chardev: clean up chardev-parallel.c

2022-12-21 Thread Paolo Bonzini
Replace HAVE_CHARDEV_PARPORT with a Meson conditional, remove unnecessary
defines, and close the file descriptor on FreeBSD/DragonFly.

Signed-off-by: Paolo Bonzini 
---
 chardev/char-parallel.c | 15 ++-
 chardev/meson.build |  5 -
 include/qemu/osdep.h|  5 -
 3 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/chardev/char-parallel.c b/chardev/char-parallel.c
index 05e7efbd6ca9..a5164f975af3 100644
--- a/chardev/char-parallel.c
+++ b/chardev/char-parallel.c
@@ -238,7 +238,6 @@ static void qemu_chr_open_pp_fd(Chardev *chr,
 }
 #endif
 
-#ifdef HAVE_CHARDEV_PARPORT
 static void qmp_chardev_open_parallel(Chardev *chr,
   ChardevBackend *backend,
   bool *be_opened,
@@ -276,29 +275,21 @@ static void char_parallel_class_init(ObjectClass *oc, 
void *data)
 
 cc->parse = qemu_chr_parse_parallel;
 cc->open = qmp_chardev_open_parallel;
-#if defined(__linux__)
 cc->chr_ioctl = pp_ioctl;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
-defined(__DragonFly__)
-cc->chr_ioctl = pp_ioctl;
-#endif
 }
 
 static void char_parallel_finalize(Object *obj)
 {
-#if defined(__linux__)
 Chardev *chr = CHARDEV(obj);
 ParallelChardev *drv = PARALLEL_CHARDEV(chr);
 int fd = drv->fd;
 
+#if defined(__linux__)
 pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
 ioctl(fd, PPRELEASE);
+#endif
 close(fd);
 qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
-defined(__DragonFly__)
-/* FIXME: close fd? */
-#endif
 }
 
 static const TypeInfo char_parallel_type_info = {
@@ -315,5 +306,3 @@ static void register_types(void)
 }
 
 type_init(register_types);
-
-#endif
diff --git a/chardev/meson.build b/chardev/meson.build
index 664f77b8879a..ceedb68d4f95 100644
--- a/chardev/meson.build
+++ b/chardev/meson.build
@@ -14,9 +14,12 @@ chardev_ss.add(files(
 ))
 chardev_ss.add(when: 'CONFIG_POSIX', if_true: [files(
   'char-fd.c',
-  'char-parallel.c',
   'char-pty.c',
 ), util])
+if targetos in ['linux', 'gnu/kfreebsd', 'freebsd', 'dragonfly']
+  'char-parallel.c',
+endif
+
 chardev_ss.add(when: 'CONFIG_WIN32', if_true: files(
   'char-console.c',
   'char-win-stdio.c',
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index b9c4307779c5..4886361be6a7 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -421,11 +421,6 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #define HAVE_CHARDEV_SERIAL 1
 #endif
 
-#if defined(__linux__) || defined(__FreeBSD__) ||   \
-defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-#define HAVE_CHARDEV_PARPORT 1
-#endif
-
 #if defined(__HAIKU__)
 #define SIGIO SIGPOLL
 #endif
-- 
2.38.1




[PATCH v21 06/10] virtio: add support for configure interrupt

2022-12-21 Thread Cindy Lu
Add the functions to support the configure interrupt in virtio
The function virtio_config_guest_notifier_read will notify the
guest if there is an configure interrupt.
The function virtio_config_set_guest_notifier_fd_handler is
to set the fd hander for the notifier

Signed-off-by: Cindy Lu 
---
 hw/virtio/virtio.c | 29 +
 include/hw/virtio/virtio.h |  4 
 2 files changed, 33 insertions(+)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index eb6347ab5d..34e9c5d141 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -4012,7 +4012,14 @@ static void 
virtio_queue_guest_notifier_read(EventNotifier *n)
 virtio_irq(vq);
 }
 }
+static void virtio_config_guest_notifier_read(EventNotifier *n)
+{
+VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier);
 
+if (event_notifier_test_and_clear(n)) {
+virtio_notify_config(vdev);
+}
+}
 void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
 bool with_irqfd)
 {
@@ -4029,6 +4036,23 @@ void 
virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
 }
 }
 
+void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev,
+ bool assign, bool with_irqfd)
+{
+EventNotifier *n;
+n = >config_notifier;
+if (assign && !with_irqfd) {
+event_notifier_set_handler(n, virtio_config_guest_notifier_read);
+} else {
+event_notifier_set_handler(n, NULL);
+}
+if (!assign) {
+/* Test and clear notifier before closing it,*/
+/* in case poll callback didn't have time to run. */
+virtio_config_guest_notifier_read(n);
+}
+}
+
 EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
 {
 return >guest_notifier;
@@ -4109,6 +4133,11 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue 
*vq)
 return >host_notifier;
 }
 
+EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev)
+{
+return >config_notifier;
+}
+
 void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled)
 {
 vq->host_notifier_enabled = enabled;
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 1f4a41b958..9c3a4642f2 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -138,6 +138,7 @@ struct VirtIODevice
 AddressSpace *dma_as;
 QLIST_HEAD(, VirtQueue) *vector_queues;
 QTAILQ_ENTRY(VirtIODevice) next;
+EventNotifier config_notifier;
 };
 
 struct VirtioDeviceClass {
@@ -360,6 +361,9 @@ void 
virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ct
 void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx);
 VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
 VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
+EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev);
+void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev,
+ bool assign, bool with_irqfd);
 
 static inline void virtio_add_feature(uint64_t *features, unsigned int fbit)
 {
-- 
2.34.3




Re: [PATCH v3 0/5] coroutine: Clean up includes

2022-12-21 Thread Philippe Mathieu-Daudé

On 22/12/22 06:21, Markus Armbruster wrote:

Philippe Mathieu-Daudé  writes:



PS: While looking for commits that caused these conflicts, I saw

commit 28b629ab4aa93b9b7ec79c7e480611e4554586be
 Signed-off-by: Philippe Mathieu-Daudé mailto:phi...@linaro.org;>phi...@linaro.org

commit 69779192acfeb9480183fd076be7480de56b1009
 Signed-off-by: Philippe Mathieu-Daudé mailto:phi...@linaro.org;>phi...@linaro.org

commit f983e598e5a4eada5bfa4731c9db9fba1943e4e6
 Suggested-by: Richard Henderson mailto:richard.hender...@linaro.org;>richard.hender...@linaro.org
 Signed-off-by: Philippe Mathieu-Daudé mailto:phi...@linaro.org;>phi...@linaro.org

Please stop that :)


The original patch looks fine:
https://lore.kernel.org/qemu-devel/20221213111707.34921-7-phi...@linaro.org/

Michael, did you change something in your workflow?



[PATCH v21 07/10] vhost: add support for configure interrupt

2022-12-21 Thread Cindy Lu
Add functions to support configure interrupt.
The configure interrupt process will start in vhost_dev_start
and stop in vhost_dev_stop.

Also add the functions to support vhost_config_pending and
vhost_config_mask.

Signed-off-by: Cindy Lu 
---
 hw/virtio/vhost.c | 78 ++-
 include/hw/virtio/vhost.h |  4 ++
 2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 7fb008bc9e..84dbb39e07 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1596,7 +1596,68 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, 
VirtIODevice *vdev, int n,
 file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n);
 r = hdev->vhost_ops->vhost_set_vring_call(hdev, );
 if (r < 0) {
-VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed");
+error_report("vhost_set_vring_call failed %d", -r);
+}
+}
+
+bool vhost_config_pending(struct vhost_dev *hdev)
+{
+assert(hdev->vhost_ops);
+if ((hdev->started == false) ||
+(hdev->vhost_ops->vhost_set_config_call == NULL)) {
+return false;
+}
+
+EventNotifier *notifier =
+>vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
+return event_notifier_test_and_clear(notifier);
+}
+
+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask)
+{
+int fd;
+int r;
+EventNotifier *notifier =
+>vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier;
+EventNotifier *config_notifier = >config_notifier;
+assert(hdev->vhost_ops);
+
+if ((hdev->started == false) ||
+(hdev->vhost_ops->vhost_set_config_call == NULL)) {
+return;
+}
+if (mask) {
+assert(vdev->use_guest_notifier_mask);
+fd = event_notifier_get_fd(notifier);
+} else {
+fd = event_notifier_get_fd(config_notifier);
+}
+r = hdev->vhost_ops->vhost_set_config_call(hdev, fd);
+if (r < 0) {
+error_report("vhost_set_config_call failed %d", -r);
+}
+}
+
+static void vhost_stop_config_intr(struct vhost_dev *dev)
+{
+int fd = -1;
+assert(dev->vhost_ops);
+if (dev->vhost_ops->vhost_set_config_call) {
+dev->vhost_ops->vhost_set_config_call(dev, fd);
+}
+}
+
+static void vhost_start_config_intr(struct vhost_dev *dev)
+{
+int r;
+
+assert(dev->vhost_ops);
+int fd = event_notifier_get_fd(>vdev->config_notifier);
+if (dev->vhost_ops->vhost_set_config_call) {
+r = dev->vhost_ops->vhost_set_config_call(dev, fd);
+if (!r) {
+event_notifier_set(>vdev->config_notifier);
+}
 }
 }
 
@@ -1836,6 +1897,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice 
*vdev, bool vrings)
 }
 }
 
+r = event_notifier_init(
+>vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0);
+if (r < 0) {
+return r;
+}
+event_notifier_test_and_clear(
+>vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
+if (!vdev->use_guest_notifier_mask) {
+vhost_config_mask(hdev, vdev, true);
+}
 if (hdev->log_enabled) {
 uint64_t log_base;
 
@@ -1874,6 +1945,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice 
*vdev, bool vrings)
 vhost_device_iotlb_miss(hdev, vq->used_phys, true);
 }
 }
+vhost_start_config_intr(hdev);
 return 0;
 fail_start:
 if (vrings) {
@@ -1903,6 +1975,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice 
*vdev, bool vrings)
 
 /* should only be called after backend is connected */
 assert(hdev->vhost_ops);
+event_notifier_test_and_clear(
+>vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier);
+event_notifier_test_and_clear(>config_notifier);
 
 trace_vhost_dev_stop(hdev, vdev->name, vrings);
 
@@ -1925,6 +2000,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice 
*vdev, bool vrings)
 }
 memory_listener_unregister(>iommu_listener);
 }
+vhost_stop_config_intr(hdev);
 vhost_log_put(hdev, true);
 hdev->started = false;
 vdev->vhost_started = false;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 67a6807fac..05bedb2416 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -33,6 +33,7 @@ struct vhost_virtqueue {
 unsigned used_size;
 EventNotifier masked_notifier;
 EventNotifier error_notifier;
+EventNotifier masked_config_notifier;
 struct vhost_dev *dev;
 };
 
@@ -41,6 +42,7 @@ typedef unsigned long vhost_log_chunk_t;
 #define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t))
 #define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)
 #define VHOST_INVALID_FEATURE_BIT   (0xff)
+#define VHOST_QUEUE_NUM_CONFIG_INR 0
 
 struct vhost_log {
 unsigned long long size;
@@ -168,6 +170,8 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, 
VirtIODevice *vdev);
  * Disable direct notifications to vhost device.
  */
 void 

[PATCH v21 08/10] virtio-net: add support for configure interrupt

2022-12-21 Thread Cindy Lu
Add functions to support configure interrupt in virtio_net
Add the functions to support vhost_net_config_pending
and vhost_net_config_mask.

Signed-off-by: Cindy Lu 
---
 hw/net/vhost_net-stub.c | 9 +
 hw/net/vhost_net.c  | 9 +
 hw/net/virtio-net.c | 4 ++--
 include/net/vhost_net.h | 2 ++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c
index 9f7daae99c..c36f258201 100644
--- a/hw/net/vhost_net-stub.c
+++ b/hw/net/vhost_net-stub.c
@@ -82,6 +82,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, 
VirtIODevice *dev,
 {
 }
 
+bool vhost_net_config_pending(VHostNetState *net)
+{
+return false;
+}
+
+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask)
+{
+}
+
 int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr)
 {
 return -1;
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 043058ff43..6a55f5a473 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -478,6 +478,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, 
VirtIODevice *dev,
 vhost_virtqueue_mask(>dev, dev, idx, mask);
 }
 
+bool vhost_net_config_pending(VHostNetState *net)
+{
+return vhost_config_pending(>dev);
+}
+
+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask)
+{
+vhost_config_mask(>dev, dev, mask);
+}
 VHostNetState *get_vhost_net(NetClientState *nc)
 {
 VHostNetState *vhost_net = 0;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index bee35d6f9f..ec974f7a76 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3323,7 +3323,7 @@ static bool 
virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
  */
 
 if (idx == VIRTIO_CONFIG_IRQ_IDX) {
-return false;
+return vhost_net_config_pending(get_vhost_net(nc->peer));
 }
 return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
 }
@@ -3355,9 +3355,9 @@ static void virtio_net_guest_notifier_mask(VirtIODevice 
*vdev, int idx,
  */
 
 if (idx == VIRTIO_CONFIG_IRQ_IDX) {
+vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask);
 return;
 }
-
 vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
 }
 
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 40b9a40074..dbbd0dc04e 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -39,6 +39,8 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t 
*data,
 bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
   int idx, bool mask);
+bool vhost_net_config_pending(VHostNetState *net);
+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask);
 int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
 VHostNetState *get_vhost_net(NetClientState *nc);
 
-- 
2.34.3




[PATCH v21 09/10] virtio-mmio: add support for configure interrupt

2022-12-21 Thread Cindy Lu
Add configure interrupt support in virtio-mmio bus.
add function to set configure guest notifier.

Signed-off-by: Cindy Lu 
---
 hw/virtio/virtio-mmio.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index d240efef97..103260ec15 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -670,7 +670,30 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, 
int n, bool assign,
 
 return 0;
 }
+static int virtio_mmio_set_config_guest_notifier(DeviceState *d, bool assign,
+ bool with_irqfd)
+{
+VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
+VirtIODevice *vdev = virtio_bus_get_device(>bus);
+VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
+EventNotifier *notifier = virtio_config_get_guest_notifier(vdev);
+int r = 0;
 
+if (assign) {
+r = event_notifier_init(notifier, 0);
+if (r < 0) {
+return r;
+}
+virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
+} else {
+virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
+event_notifier_cleanup(notifier);
+}
+if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) {
+vdc->guest_notifier_mask(vdev, VIRTIO_CONFIG_IRQ_IDX, !assign);
+}
+return r;
+}
 static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs,
bool assign)
 {
@@ -692,6 +715,10 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, 
int nvqs,
 goto assign_error;
 }
 }
+r = virtio_mmio_set_config_guest_notifier(d, assign, with_irqfd);
+if (r < 0) {
+goto assign_error;
+}
 
 return 0;
 
-- 
2.34.3




[PATCH v21 10/10] virtio-pci: add support for configure interrupt

2022-12-21 Thread Cindy Lu
Add process to handle the configure interrupt, The function's
logic is the same with vq interrupt.Add extra process to check
the configure interrupt

Signed-off-by: Cindy Lu 
---
 hw/virtio/virtio-pci.c | 118 +++--
 include/hw/virtio/virtio-pci.h |   4 +-
 2 files changed, 102 insertions(+), 20 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index ec816ea367..3f00e91718 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -751,7 +751,8 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, 
int queue_no,
 VirtQueue *vq;
 
 if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
-return -1;
+*n = virtio_config_get_guest_notifier(vdev);
+*vector = vdev->config_vector;
 } else {
 if (!virtio_queue_get_num(vdev, queue_no)) {
 return -1;
@@ -811,7 +812,7 @@ undo:
 }
 return ret;
 }
-static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
+static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs)
 {
 int queue_no;
 int ret = 0;
@@ -826,6 +827,10 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy 
*proxy, int nvqs)
 return ret;
 }
 
+static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy)
+{
+return kvm_virtio_pci_vector_use_one(proxy, VIRTIO_CONFIG_IRQ_IDX);
+}
 
 static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy,
   int queue_no)
@@ -850,7 +855,7 @@ static void 
kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy,
 kvm_virtio_pci_vq_vector_release(proxy, vector);
 }
 
-static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
+static void kvm_virtio_pci_vector_vq_release(VirtIOPCIProxy *proxy, int nvqs)
 {
 int queue_no;
 VirtIODevice *vdev = virtio_bus_get_device(>bus);
@@ -863,6 +868,11 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy 
*proxy, int nvqs)
 }
 }
 
+static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy)
+{
+kvm_virtio_pci_vector_release_one(proxy, VIRTIO_CONFIG_IRQ_IDX);
+}
+
 static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy,
unsigned int queue_no,
unsigned int vector,
@@ -944,9 +954,19 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, 
unsigned vector,
 }
 vq = virtio_vector_next_queue(vq);
 }
-
+/* unmask config intr */
+if (vector == vdev->config_vector) {
+n = virtio_config_get_guest_notifier(vdev);
+ret = virtio_pci_one_vector_unmask(proxy, VIRTIO_CONFIG_IRQ_IDX, 
vector,
+   msg, n);
+if (ret < 0) {
+goto undo_config;
+}
+}
 return 0;
-
+undo_config:
+n = virtio_config_get_guest_notifier(vdev);
+virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n);
 undo:
 vq = virtio_vector_first_queue(vdev, vector);
 while (vq && unmasked >= 0) {
@@ -980,6 +1000,11 @@ static void virtio_pci_vector_mask(PCIDevice *dev, 
unsigned vector)
 }
 vq = virtio_vector_next_queue(vq);
 }
+
+if (vector == vdev->config_vector) {
+n = virtio_config_get_guest_notifier(vdev);
+virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n);
+}
 }
 
 static void virtio_pci_vector_poll(PCIDevice *dev,
@@ -1011,6 +1036,34 @@ static void virtio_pci_vector_poll(PCIDevice *dev,
 msix_set_pending(dev, vector);
 }
 }
+/* poll the config intr */
+ret = virtio_pci_get_notifier(proxy, VIRTIO_CONFIG_IRQ_IDX, ,
+  );
+if (ret < 0) {
+return;
+}
+if (vector < vector_start || vector >= vector_end ||
+!msix_is_masked(dev, vector)) {
+return;
+}
+if (k->guest_notifier_pending) {
+if (k->guest_notifier_pending(vdev, VIRTIO_CONFIG_IRQ_IDX)) {
+msix_set_pending(dev, vector);
+}
+} else if (event_notifier_test_and_clear(notifier)) {
+msix_set_pending(dev, vector);
+}
+}
+
+void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue 
*vq,
+  int n, bool assign,
+  bool with_irqfd)
+{
+if (n == VIRTIO_CONFIG_IRQ_IDX) {
+virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd);
+} else {
+virtio_queue_set_guest_notifier_fd_handler(vq, assign, with_irqfd);
+}
 }
 
 static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
@@ -1019,17 +1072,25 @@ static int virtio_pci_set_guest_notifier(DeviceState 
*d, int n, bool assign,
 VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
 VirtIODevice *vdev = virtio_bus_get_device(>bus);
 VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
-VirtQueue *vq = 

[PATCH v21 05/10] vhost-vdpa: add support for config interrupt

2022-12-21 Thread Cindy Lu
Add new call back function in vhost-vdpa, The function
vhost_set_config_call can set the event fd to kernel.
This function will be called in the vhost_dev_start
and vhost_dev_stop

Signed-off-by: Cindy Lu 
---
 hw/virtio/trace-events | 1 +
 hw/virtio/vhost-vdpa.c | 8 
 2 files changed, 9 insertions(+)

diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 14fc5b9bb2..46f2faf04e 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -62,6 +62,7 @@ vhost_vdpa_get_features(void *dev, uint64_t features) "dev: 
%p features: 0x%"PRI
 vhost_vdpa_set_owner(void *dev) "dev: %p"
 vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t 
avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 
0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
 vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p 
first: 0x%"PRIx64" last: 0x%"PRIx64
+vhost_vdpa_set_config_call(void *dev, int fd)"dev: %p fd: %d"
 
 # virtio.c
 virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned 
out_num) "elem %p size %zd in_num %u out_num %u"
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 7468e44b87..c5be2645b0 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -754,6 +754,13 @@ static int vhost_vdpa_set_vring_ready(struct vhost_dev 
*dev)
 return 0;
 }
 
+static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
+   int fd)
+{
+trace_vhost_vdpa_set_config_call(dev, fd);
+return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, );
+}
+
 static void vhost_vdpa_dump_config(struct vhost_dev *dev, const uint8_t 
*config,
uint32_t config_len)
 {
@@ -1310,4 +1317,5 @@ const VhostOps vdpa_ops = {
 .vhost_get_device_id = vhost_vdpa_get_device_id,
 .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
 .vhost_force_iommu = vhost_vdpa_force_iommu,
+.vhost_set_config_call = vhost_vdpa_set_config_call,
 };
-- 
2.34.3




[PATCH v21 03/10] virtio-pci: decouple the single vector from the interrupt process

2022-12-21 Thread Cindy Lu
To reuse the interrupt process in configure interrupt
Need to decouple the single vector from the interrupt process.
We add new function kvm_virtio_pci_vector_use_one and _release_one.
These functions are used for the single vector, the whole process will
finish in the loop with vq number.

Signed-off-by: Cindy Lu 
---
 hw/virtio/virtio-pci.c | 131 +++--
 1 file changed, 73 insertions(+), 58 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 52c7692fff..ec816ea367 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -699,7 +699,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
 }
 
 static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
-unsigned int queue_no,
 unsigned int vector)
 {
 VirtIOIRQFD *irqfd = >vector_irqfd[vector];
@@ -764,87 +763,103 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy 
*proxy, int queue_no,
 return 0;
 }
 
-static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
+static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no)
 {
+unsigned int vector;
+int ret;
+EventNotifier *n;
 PCIDevice *dev = >pci_dev;
 VirtIODevice *vdev = virtio_bus_get_device(>bus);
 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-unsigned int vector;
-int ret, queue_no;
-EventNotifier *n;
-for (queue_no = 0; queue_no < nvqs; queue_no++) {
-if (!virtio_queue_get_num(vdev, queue_no)) {
-break;
-}
-ret = virtio_pci_get_notifier(proxy, queue_no, , );
-if (ret < 0) {
-break;
-}
-if (vector >= msix_nr_vectors_allocated(dev)) {
-continue;
-}
-ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
+
+ret = virtio_pci_get_notifier(proxy, queue_no, , );
+if (ret < 0) {
+return ret;
+}
+if (vector >= msix_nr_vectors_allocated(dev)) {
+return 0;
+}
+ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
+if (ret < 0) {
+goto undo;
+}
+/*
+ * If guest supports masking, set up irqfd now.
+ * Otherwise, delay until unmasked in the frontend.
+ */
+if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
+ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
 if (ret < 0) {
+kvm_virtio_pci_vq_vector_release(proxy, vector);
 goto undo;
 }
-/* If guest supports masking, set up irqfd now.
- * Otherwise, delay until unmasked in the frontend.
- */
-if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
-if (ret < 0) {
-kvm_virtio_pci_vq_vector_release(proxy, vector);
-goto undo;
-}
-}
 }
-return 0;
 
+return 0;
 undo:
-while (--queue_no >= 0) {
-vector = virtio_queue_vector(vdev, queue_no);
-if (vector >= msix_nr_vectors_allocated(dev)) {
-continue;
+
+vector = virtio_queue_vector(vdev, queue_no);
+if (vector >= msix_nr_vectors_allocated(dev)) {
+return ret;
+}
+if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
+ret = virtio_pci_get_notifier(proxy, queue_no, , );
+if (ret < 0) {
+return ret;
 }
-if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-ret = virtio_pci_get_notifier(proxy, queue_no, , );
-if (ret < 0) {
-break;
-}
-kvm_virtio_pci_irqfd_release(proxy, n, vector);
+kvm_virtio_pci_irqfd_release(proxy, n, vector);
+}
+return ret;
+}
+static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
+{
+int queue_no;
+int ret = 0;
+VirtIODevice *vdev = virtio_bus_get_device(>bus);
+
+for (queue_no = 0; queue_no < nvqs; queue_no++) {
+if (!virtio_queue_get_num(vdev, queue_no)) {
+return -1;
 }
-kvm_virtio_pci_vq_vector_release(proxy, vector);
+ret = kvm_virtio_pci_vector_use_one(proxy, queue_no);
 }
 return ret;
 }
 
-static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
+
+static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy,
+  int queue_no)
 {
-PCIDevice *dev = >pci_dev;
 VirtIODevice *vdev = virtio_bus_get_device(>bus);
 unsigned int vector;
-int queue_no;
-VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
 EventNotifier *n;
-int ret ;
+int ret;
+VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+PCIDevice *dev = >pci_dev;
+
+ret = virtio_pci_get_notifier(proxy, queue_no, , );
+if (ret < 0) {
+return;
+}
+if (vector >= 

[PATCH v21 01/10] virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX

2022-12-21 Thread Cindy Lu
To support configure interrupt for vhost-vdpa
Introduce VIRTIO_CONFIG_IRQ_IDX -1 as configure interrupt's queue index,
Then we can reuse the functions guest_notifier_mask and guest_notifier_pending.
Add the check of queue index in these drivers, if the driver does not support
configure interrupt, the function will just return

Signed-off-by: Cindy Lu 
---
 hw/display/vhost-user-gpu.c| 18 ++
 hw/net/virtio-net.c| 22 --
 hw/virtio/vhost-user-fs.c  | 18 ++
 hw/virtio/vhost-user-gpio.c| 10 ++
 hw/virtio/vhost-vsock-common.c | 18 ++
 hw/virtio/virtio-crypto.c  | 18 ++
 include/hw/virtio/virtio.h |  3 +++
 7 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 19c0e20103..4380a5e672 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -486,6 +486,15 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, 
int idx)
 {
 VhostUserGPU *g = VHOST_USER_GPU(vdev);
 
+/*
+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
+ * as the Marco of configure interrupt's IDX, If this driver does not
+ * support, the function will return
+ */
+
+if (idx == VIRTIO_CONFIG_IRQ_IDX) {
+return false;
+}
 return vhost_virtqueue_pending(>vhost->dev, idx);
 }
 
@@ -494,6 +503,15 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int 
idx, bool mask)
 {
 VhostUserGPU *g = VHOST_USER_GPU(vdev);
 
+/*
+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
+ * as the Marco of configure interrupt's IDX, If this driver does not
+ * support, the function will return
+ */
+
+if (idx == VIRTIO_CONFIG_IRQ_IDX) {
+return;
+}
 vhost_virtqueue_mask(>vhost->dev, vdev, idx, mask);
 }
 
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index aba12759d5..bee35d6f9f 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3316,6 +3316,15 @@ static bool 
virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
 } else {
 nc = qemu_get_subqueue(n->nic, vq2q(idx));
 }
+/*
+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
+ * as the Marco of configure interrupt's IDX, If this driver does not
+ * support, the function will return false
+ */
+
+if (idx == VIRTIO_CONFIG_IRQ_IDX) {
+return false;
+}
 return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
 }
 
@@ -3339,8 +3348,17 @@ static void virtio_net_guest_notifier_mask(VirtIODevice 
*vdev, int idx,
 } else {
 nc = qemu_get_subqueue(n->nic, vq2q(idx));
 }
-vhost_net_virtqueue_mask(get_vhost_net(nc->peer),
- vdev, idx, mask);
+/*
+ *Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
+ * as the Marco of configure interrupt's IDX, If this driver does not
+ * support, the function will return
+ */
+
+if (idx == VIRTIO_CONFIG_IRQ_IDX) {
+return;
+}
+
+vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
 }
 
 static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features)
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index d97b179e6f..f5049735ac 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -159,6 +159,15 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, 
int idx,
 {
 VHostUserFS *fs = VHOST_USER_FS(vdev);
 
+/*
+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
+ * as the Marco of configure interrupt's IDX, If this driver does not
+ * support, the function will return
+ */
+
+if (idx == VIRTIO_CONFIG_IRQ_IDX) {
+return;
+}
 vhost_virtqueue_mask(>vhost_dev, vdev, idx, mask);
 }
 
@@ -166,6 +175,15 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, 
int idx)
 {
 VHostUserFS *fs = VHOST_USER_FS(vdev);
 
+/*
+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
+ * as the Marco of configure interrupt's IDX, If this driver does not
+ * support, the function will return
+ */
+
+if (idx == VIRTIO_CONFIG_IRQ_IDX) {
+return false;
+}
 return vhost_virtqueue_pending(>vhost_dev, idx);
 }
 
diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c
index b7b82a1099..fe3da32c74 100644
--- a/hw/virtio/vhost-user-gpio.c
+++ b/hw/virtio/vhost-user-gpio.c
@@ -191,6 +191,16 @@ static void vu_gpio_guest_notifier_mask(VirtIODevice 
*vdev, int idx, bool mask)
 {
 VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
 
+/*
+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
+ * as the Marco of configure interrupt's IDX, If this driver does not
+ * support, the function will return
+ */
+
+if (idx == 

[PATCH v21 00/10] vhost-vdpa: add support for configure interrupt

2022-12-21 Thread Cindy Lu
These patches introduced the support for configure interrupt 

These codes are tested on x86_64 and aarch64 platforms.  

the test scenario is based on vp-vdpa/vdpa_sim_net /vhost/vhost_user/testpmd,
with/without irqfd.

Tested in virtio-pci bus and virtio-mmio bus


Change in v2:
Add support for virtio-mmio bus
active the notifier while the backend support configure interrupt
misc fixes from v1

Change in v3
fix the coding style problems

Change in v4
misc fixes from v3
merge the set_config_notifier to set_guest_notifier
when vdpa start, check the feature by VIRTIO_NET_F_STATUS

Change in v5
misc fixes from v4
split the code to introduce configure interrupt type and the callback function
will init the configure interrupt in all virtio-pci and virtio-mmio bus, but 
will
only active while using vhost-vdpa driver

Change in v6
misc fixes from v5
decouple vq from interrupt setting and misc process
fix the bug in virtio_net_handle_rx

Change in v7
misc fixes from v6
decouple vq from interrupt setting and misc process
decouple vq from vector use/release process
decouple vq from set notifier fd handler process
move config_notifier and masked_config_notifier to VirtIODevice
fix the bug in virtio_net_handle_rx, add more information
add VIRTIO_CONFIG_IRQ_IDX as the queue number for configure interrupt 

Change in v8
misc fixes from v7
decouple vq from interrupt setting and misc process
decouple vq from vector use/release process
decouple vq from set notifier fd handler process
move the vhost configure interrupt to vhost_net

Change in v9
misc fixes from v8
address the comments from v8

Change in v10
fix the hang issue in qtest
address the comments from v9

Change in v11
fix the crash in aarch64 plateform.
fix the crash upstream reported

Change in v12
fix the typo and the comments

changes in v13
re-send the patches by git-publish

changes in v14
rebased the code based on upstream

changes in v15
rebased the code based on upstream

changes in v16
resend the patch, seems there not send successfully

changes in v18
fix the crash in qtest
Because hw/virtio/vhost-user-gpio.c is a new device,So I missed 
to add the VIRTIO_CONFIG_IRQ_IDX check in notifier_mask

changes in v19
fix the crash in qtest
rebased the code based on upstream

changes in v20
fix the compile issue in mingw32

Cindy Lu (10):
  virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX
  virtio-pci: decouple notifier from interrupt process
  virtio-pci: decouple the single vector from the interrupt process
  vhost: introduce new VhostOps vhost_set_config_call
  vhost-vdpa: add support for config interrupt
  virtio: add support for configure interrupt
  vhost: add support for configure interrupt
  virtio-net: add support for configure interrupt
  virtio-mmio: add support for configure interrupt
  virtio-pci: add support for configure interrupt

 hw/display/vhost-user-gpu.c   |  18 ++
 hw/net/vhost_net-stub.c   |   9 +
 hw/net/vhost_net.c|   9 +
 hw/net/virtio-net.c   |  22 ++-
 hw/virtio/trace-events|   1 +
 hw/virtio/vhost-user-fs.c |  18 ++
 hw/virtio/vhost-user-gpio.c   |  10 +
 hw/virtio/vhost-vdpa.c|   8 +
 hw/virtio/vhost-vsock-common.c|  18 ++
 hw/virtio/vhost.c |  78 +++-
 hw/virtio/virtio-crypto.c |  18 ++
 hw/virtio/virtio-mmio.c   |  27 +++
 hw/virtio/virtio-pci.c| 291 +-
 hw/virtio/virtio.c|  29 +++
 include/hw/virtio/vhost-backend.h |   3 +
 include/hw/virtio/vhost.h |   4 +
 include/hw/virtio/virtio-pci.h|   4 +-
 include/hw/virtio/virtio.h|   7 +
 include/net/vhost_net.h   |   2 +
 19 files changed, 487 insertions(+), 89 deletions(-)

-- 
2.34.3




[PATCH v21 04/10] vhost: introduce new VhostOps vhost_set_config_call

2022-12-21 Thread Cindy Lu
This patch introduces new VhostOps vhost_set_config_call.
This function allows the qemu to set the config
event fd to kernel driver.

Signed-off-by: Cindy Lu 
---
 include/hw/virtio/vhost-backend.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/hw/virtio/vhost-backend.h 
b/include/hw/virtio/vhost-backend.h
index eab46d7f0b..c5ab49051e 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -128,6 +128,8 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev 
*dev, uint32_t *dev_id);
 
 typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
 
+typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev,
+   int fd);
 typedef struct VhostOps {
 VhostBackendType backend_type;
 vhost_backend_init vhost_backend_init;
@@ -174,6 +176,7 @@ typedef struct VhostOps {
 vhost_vq_get_addr_op  vhost_vq_get_addr;
 vhost_get_device_id_op vhost_get_device_id;
 vhost_force_iommu_op vhost_force_iommu;
+vhost_set_config_call_op vhost_set_config_call;
 } VhostOps;
 
 int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
-- 
2.34.3




[PATCH v21 02/10] virtio-pci: decouple notifier from interrupt process

2022-12-21 Thread Cindy Lu
To reuse the notifier process. We add the virtio_pci_get_notifier
to get the notifier and vector. The INPUT for this function is IDX,
The OUTPUT is the notifier and the vector

Signed-off-by: Cindy Lu 
---
 hw/virtio/virtio-pci.c | 88 +++---
 1 file changed, 57 insertions(+), 31 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index a1c9dfa7bb..52c7692fff 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -728,29 +728,41 @@ static void 
kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
 }
 
 static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
- unsigned int queue_no,
+ EventNotifier *n,
  unsigned int vector)
 {
 VirtIOIRQFD *irqfd = >vector_irqfd[vector];
-VirtIODevice *vdev = virtio_bus_get_device(>bus);
-VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-EventNotifier *n = virtio_queue_get_guest_notifier(vq);
 return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq);
 }
 
 static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
-  unsigned int queue_no,
+  EventNotifier *n ,
   unsigned int vector)
 {
-VirtIODevice *vdev = virtio_bus_get_device(>bus);
-VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-EventNotifier *n = virtio_queue_get_guest_notifier(vq);
 VirtIOIRQFD *irqfd = >vector_irqfd[vector];
 int ret;
 
 ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq);
 assert(ret == 0);
 }
+static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no,
+  EventNotifier **n, unsigned int *vector)
+{
+VirtIODevice *vdev = virtio_bus_get_device(>bus);
+VirtQueue *vq;
+
+if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
+return -1;
+} else {
+if (!virtio_queue_get_num(vdev, queue_no)) {
+return -1;
+}
+*vector = virtio_queue_vector(vdev, queue_no);
+vq = virtio_get_queue(vdev, queue_no);
+*n = virtio_queue_get_guest_notifier(vq);
+}
+return 0;
+}
 
 static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
 {
@@ -759,12 +771,15 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy 
*proxy, int nvqs)
 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
 unsigned int vector;
 int ret, queue_no;
-
+EventNotifier *n;
 for (queue_no = 0; queue_no < nvqs; queue_no++) {
 if (!virtio_queue_get_num(vdev, queue_no)) {
 break;
 }
-vector = virtio_queue_vector(vdev, queue_no);
+ret = virtio_pci_get_notifier(proxy, queue_no, , );
+if (ret < 0) {
+break;
+}
 if (vector >= msix_nr_vectors_allocated(dev)) {
 continue;
 }
@@ -776,7 +791,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, 
int nvqs)
  * Otherwise, delay until unmasked in the frontend.
  */
 if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
+ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
 if (ret < 0) {
 kvm_virtio_pci_vq_vector_release(proxy, vector);
 goto undo;
@@ -792,7 +807,11 @@ undo:
 continue;
 }
 if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
+ret = virtio_pci_get_notifier(proxy, queue_no, , );
+if (ret < 0) {
+break;
+}
+kvm_virtio_pci_irqfd_release(proxy, n, vector);
 }
 kvm_virtio_pci_vq_vector_release(proxy, vector);
 }
@@ -806,12 +825,16 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy 
*proxy, int nvqs)
 unsigned int vector;
 int queue_no;
 VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
-
+EventNotifier *n;
+int ret ;
 for (queue_no = 0; queue_no < nvqs; queue_no++) {
 if (!virtio_queue_get_num(vdev, queue_no)) {
 break;
 }
-vector = virtio_queue_vector(vdev, queue_no);
+ret = virtio_pci_get_notifier(proxy, queue_no, , );
+if (ret < 0) {
+break;
+}
 if (vector >= msix_nr_vectors_allocated(dev)) {
 continue;
 }
@@ -819,21 +842,20 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy 
*proxy, int nvqs)
  * Otherwise, it was cleaned when masked in the frontend.
  */
 if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
+kvm_virtio_pci_irqfd_release(proxy, n, vector);
 }
 

Re: [PATCH 0/5] include/hw/pci include/hw/cxl: Clean up includes

2022-12-21 Thread Markus Armbruster
"Michael S. Tsirkin"  writes:

> On Fri, Dec 09, 2022 at 02:47:57PM +0100, Markus Armbruster wrote:
>> Back in 2016, we discussed[1] rules for headers, and these were
>> generally liked:
>> 
>> 1. Have a carefully curated header that's included everywhere first.  We
>>got that already thanks to Peter: osdep.h.
>> 
>> 2. Headers should normally include everything they need beyond osdep.h.
>>If exceptions are needed for some reason, they must be documented in
>>the header.  If all that's needed from a header is typedefs, put
>>those into qemu/typedefs.h instead of including the header.
>> 
>> 3. Cyclic inclusion is forbidden.
>
> Looks like this breaks fuzzer build:
>
> https://gitlab.com/mstredhat/qemu/-/jobs/3506121308

Will be fixed in v2, thanks!




Re: [PATCH] meson: Clean up some dependencies regarding qemu-system

2022-12-21 Thread Helge Deller

On 12/21/22 08:49, Michael Tokarev wrote:

20.12.2022 23:56, Helge Deller wrote:
..

Given that info, would it then make sense to keep as is:
    --enable-system
    --enable-user
    --enable-tools -> qemu-bridge-helper, vhost-user-gpu, virtfs-proxy-helper, 
virtiofsd
    --enable-guest-agent -> guest agents  (option is there already, but not 
used)
and additonally add:
    --enable-utils  -> qemu-img, qemu-io, qemu-nbd


tools and utils is confusing, it smells like it's the same thing.

I understand that in theory, eg virtiofsd can be used without qemu, with some
other software, but in practice there's no such software, and I don't think
it will emerge in a (near) future. All the "tools" listed above are system-mode
helpers really, this is why I package them in qemu-SYSTEM-common in Debian.
They're not very useful for now without some of qemu-system-xx.  To my view,
these should be part of --enable-system, at least for now. Maybe with a
separate --enable-system-helpers to turn them off if needed but I don't
think it's necessary.

The new "utils" category above actually *is* useful by its own, especially
qemu-nbd, for example to access .qcow2 images from the host OS. This is what
eg Redhat is shipping in qemu-io package.  And these are good to have without
--enable-system.


Michael, please note, that the patch I initially sent in this thread is
*exactly* doing what you summarize here.

Helge



Re: [PATCH v3 0/5] coroutine: Clean up includes

2022-12-21 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> On 21/12/22 14:14, Markus Armbruster wrote:
>> v3:
>> * PATCH 4: Unnecessary hunks dropped
>> v2:
>> * Rebased
>> * PATCH 4: Rewritten [Paolo]
>> * PATCH 5: New
>> Markus Armbruster (5):
>>coroutine: Clean up superfluous inclusion of qemu/coroutine.h
>>coroutine: Move coroutine_fn to qemu/osdep.h, trim includes
>>coroutine: Clean up superfluous inclusion of qemu/lockable.h
>>coroutine: Split qemu/coroutine-core.h off qemu/coroutine.h
>>coroutine: Use Coroutine typedef name instead of structure tag
>
> I had to add:
>
> -- >8 --
> diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
> index fb7591d6ab..b09fce9377 100644
> --- a/hw/pci/pci-hmp-cmds.c
> +++ b/hw/pci/pci-hmp-cmds.c
> @@ -15,6 +15,7 @@
>
>  #include "qemu/osdep.h"
>  #include "hw/pci/pci.h"
> +#include "hw/pci/pci_device.h"
>  #include "monitor/hmp.h"
>  #include "monitor/monitor.h"
>  #include "pci-internal.h"
> diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c
> index 8e7282658f..3d4497da99 100644
> --- a/hw/virtio/virtio-qmp.c
> +++ b/hw/virtio/virtio-qmp.c
> @@ -11,6 +11,7 @@
>
>  #include "qemu/osdep.h"
>  #include "hw/virtio/virtio.h"
> +#include "hw/virtio/vhost.h"
>  #include "virtio-qmp.h"
>
> ---
>
> Otherwise I get:
>
> ../hw/pci/pci-hmp-cmds.c: In function ‘pcibus_dev_print’:
> ../hw/pci/pci-hmp-cmds.c:129:31: error: invalid use of incomplete typedef 
> ‘PCIDevice’
>   129 | int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
>   |   ^~
>
> ../hw/virtio/virtio-qmp.c:187:19: error: ‘VHOST_USER_F_PROTOCOL_FEATURES’ 
> undeclared here (not in a function); 
> did you mean ‘VHOST_USER_PROTOCOL_F_RARP’?
>   187 | FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
>   |   ^~
>
>
> Maybe some recently merged change?

Yes.  I'll rebase.

> Otherwise:
> Tested-by: Philippe Mathieu-Daudé 

Thanks!


PS: While looking for commits that caused these conflicts, I saw

commit 28b629ab4aa93b9b7ec79c7e480611e4554586be
Signed-off-by: Philippe Mathieu-Daudé mailto:phi...@linaro.org;>phi...@linaro.org

commit 69779192acfeb9480183fd076be7480de56b1009
Signed-off-by: Philippe Mathieu-Daudé mailto:phi...@linaro.org;>phi...@linaro.org

commit f983e598e5a4eada5bfa4731c9db9fba1943e4e6
Suggested-by: Richard Henderson mailto:richard.hender...@linaro.org;>richard.hender...@linaro.org
Signed-off-by: Philippe Mathieu-Daudé mailto:phi...@linaro.org;>phi...@linaro.org

Please stop that :)




[PATCH] linux-user: Allow 64-bit offsets in mmap2() syscall on 32-bit targets

2022-12-21 Thread Helge Deller
The mmap2() syscall allows 32-bit guests to specify the offset into a
mapping in 4096-byte units (instead of bytes, as is done by mmap(2)).
This enables applications that use a 32-bit off_t to map large files
(up to 2^44 bytes).

So when emulating the mmap2 syscall the offset parameter is shifted by
12 bits, which then may exceed what the abi_ulong (32-bit) type of the
offset parameter in target_mmap() can hold.

Overcome this possible issue by switching hard to uint64_t in
target_mmap() and mmap_frag().

Note: compile-tested only.

Signed-off-by: Helge Deller 
---
 linux-user/mmap.c  | 9 +
 linux-user/syscall.c   | 2 +-
 linux-user/user-mmap.h | 2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index c75342108c..43fbd8d957 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -192,7 +192,7 @@ error:
 /* map an incomplete host page */
 static int mmap_frag(abi_ulong real_start,
  abi_ulong start, abi_ulong end,
- int prot, int flags, int fd, abi_ulong offset)
+ int prot, int flags, int fd, uint64_t offset)
 {
 abi_ulong real_end, addr;
 void *host_start;
@@ -430,9 +430,10 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, 
abi_ulong align)

 /* NOTE: all the constants are the HOST ones */
 abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
- int flags, int fd, abi_ulong offset)
+ int flags, int fd, uint64_t offset)
 {
-abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len,
+uint64_t host_offset;
+abi_ulong ret, end, real_start, real_end, retaddr, host_len,
   passthrough_start = -1, passthrough_end = -1;
 int page_flags, host_prot;

@@ -621,7 +622,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
target_prot,
 /* map the middle (easier) */
 if (real_start < real_end) {
 void *p;
-unsigned long offset1;
+uint64_t offset1;
 if (flags & MAP_ANONYMOUS)
 offset1 = 0;
 else
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 52693b4239..4fee882cd7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10144,7 +10144,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 #endif
 ret = target_mmap(arg1, arg2, arg3,
   target_to_host_bitmask(arg4, mmap_flags_tbl),
-  arg5, arg6 << MMAP_SHIFT);
+  arg5, ((uint64_t)arg6) << MMAP_SHIFT);
 return get_errno(ret);
 #endif
 case TARGET_NR_munmap:
diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h
index 480ce1c114..0aed3df2c4 100644
--- a/linux-user/user-mmap.h
+++ b/linux-user/user-mmap.h
@@ -20,7 +20,7 @@

 int target_mprotect(abi_ulong start, abi_ulong len, int prot);
 abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
- int flags, int fd, abi_ulong offset);
+ int flags, int fd, uint64_t offset);
 int target_munmap(abi_ulong start, abi_ulong len);
 abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
abi_ulong new_size, unsigned long flags,
--
2.38.1




Re: [PATCH v3 3/4] vdpa: handle VIRTIO_NET_CTRL_ANNOUNCE in vhost_vdpa_net_handle_ctrl_avail

2022-12-21 Thread Jason Wang
On Wed, Dec 21, 2022 at 7:50 PM Eugenio Pérez  wrote:
>
> Since this capability is emulated by qemu shadowed CVQ cannot forward it
> to the device. Process all that command within qemu.
>
> Signed-off-by: Eugenio Pérez 

Acked-by: Jason Wang 

Thanks

> ---
>  net/vhost-vdpa.c | 15 ---
>  1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> index 260e474863..0b0712cd8a 100644
> --- a/net/vhost-vdpa.c
> +++ b/net/vhost-vdpa.c
> @@ -489,9 +489,18 @@ static int 
> vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq,
>  out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0,
>   s->cvq_cmd_out_buffer,
>   vhost_vdpa_net_cvq_cmd_len());
> -dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status));
> -if (unlikely(dev_written < 0)) {
> -goto out;
> +if (*(uint8_t *)s->cvq_cmd_out_buffer == VIRTIO_NET_CTRL_ANNOUNCE) {
> +/*
> + * Guest announce capability is emulated by qemu, so don't forward to
> + * the device.
> + */
> +dev_written = sizeof(status);
> +*s->status = VIRTIO_NET_OK;
> +} else {
> +dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status));
> +if (unlikely(dev_written < 0)) {
> +goto out;
> +}
>  }
>
>  if (unlikely(dev_written < sizeof(status))) {
> --
> 2.31.1
>




Re: [PATCH v3 2/4] virtio_net: copy VIRTIO_NET_S_ANNOUNCE if device model has it

2022-12-21 Thread Jason Wang
On Wed, Dec 21, 2022 at 7:50 PM Eugenio Pérez  wrote:
>
> Status part of the emulated feature. It will follow device model, so we
> must copy it as long as NIC device model has it set.
>
> Signed-off-by: Eugenio Pérez 

Acked-by: Jason Wang 

Thanks

> ---
> v3: Add virtio byte swapping writing net config status.
> ---
>  hw/net/virtio-net.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> index b30038d130..122eac25ee 100644
> --- a/hw/net/virtio-net.c
> +++ b/hw/net/virtio-net.c
> @@ -183,6 +183,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, 
> uint8_t *config)
>  memcpy(netcfg.mac, n->mac, ETH_ALEN);
>  }
>
> +netcfg.status |= virtio_tswap16(vdev,
> +n->status & VIRTIO_NET_S_ANNOUNCE);
>  memcpy(config, , n->config_size);
>  }
>  }
> --
> 2.31.1
>




[PATCH v2 8/8] hw/cxl/events: Add in inject general media event

2022-12-21 Thread Ira Weiny
To facilitate testing provide a QMP command to inject a general media
event.  The event can be added to the log specified.

Signed-off-by: Ira Weiny 

---
Changes from RFC:
Add all fields for this event
irq happens automatically when log transitions from 0 to 1
---
 hw/mem/cxl_type3.c  | 93 +
 hw/mem/cxl_type3_stubs.c|  8 
 include/hw/cxl/cxl_events.h | 20 ++
 qapi/cxl.json   | 25 
 4 files changed, 146 insertions(+)

diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index a43949cab120..bedd09e500ba 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -916,6 +916,99 @@ static CXLPoisonList *get_poison_list(CXLType3Dev *ct3d)
 return >poison_list;
 }
 
+static void cxl_assign_event_header(struct cxl_event_record_hdr *hdr,
+QemuUUID *uuid, uint8_t flags,
+uint8_t length)
+{
+hdr->flags[0] = flags;
+hdr->length = length;
+memcpy(>id, uuid, sizeof(hdr->id));
+hdr->timestamp = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+}
+
+QemuUUID gen_media_uuid = {
+.data = UUID(0xfbcd0a77, 0xc260, 0x417f,
+ 0x85, 0xa9, 0x08, 0x8b, 0x16, 0x21, 0xeb, 0xa6),
+};
+
+#define CXL_GMER_VALID_CHANNEL  BIT(0)
+#define CXL_GMER_VALID_RANK BIT(1)
+#define CXL_GMER_VALID_DEVICE   BIT(2)
+#define CXL_GMER_VALID_COMPONENTBIT(3)
+
+/*
+ * For channel, rank, and device; any value inside of the fields valid range
+ * will flag that field to be valid.  IE pass -1 to mark the field invalid.
+ *
+ * Component ID is device specific.  Define this as a string.
+ */
+void qmp_cxl_inject_gen_media_event(const char *path, uint8_t log,
+uint8_t flags, uint64_t physaddr,
+uint8_t descriptor, uint8_t type,
+uint8_t transaction_type,
+int16_t channel, int16_t rank,
+int32_t device,
+const char *component_id,
+Error **errp)
+{
+Object *obj = object_resolve_path(path, NULL);
+struct cxl_event_gen_media gem;
+struct cxl_event_record_hdr *hdr = 
+CXLDeviceState *cxlds;
+CXLType3Dev *ct3d;
+uint16_t valid_flags = 0;
+
+if (log >= CXL_EVENT_TYPE_MAX) {
+error_setg(errp, "Invalid log type: %d", log);
+return;
+}
+if (!obj) {
+error_setg(errp, "Unable to resolve path");
+return;
+}
+if (!object_dynamic_cast(obj, TYPE_CXL_TYPE3)) {
+error_setg(errp, "Path does not point to a CXL type 3 device");
+}
+ct3d = CXL_TYPE3(obj);
+cxlds = >cxl_dstate;
+
+memset(, 0, sizeof(gem));
+cxl_assign_event_header(hdr, _media_uuid, flags,
+sizeof(struct cxl_event_gen_media));
+
+gem.phys_addr = physaddr;
+gem.descriptor = descriptor;
+gem.type = type;
+gem.transaction_type = transaction_type;
+
+if (0 <= channel && channel <= 0xFF) {
+gem.channel = channel;
+valid_flags |= CXL_GMER_VALID_CHANNEL;
+}
+
+if (0 <= rank && rank <= 0xFF) {
+gem.rank = rank;
+valid_flags |= CXL_GMER_VALID_RANK;
+}
+
+if (0 <= device && device <= 0xFF) {
+st24_le_p(gem.device, device);
+valid_flags |= CXL_GMER_VALID_DEVICE;
+}
+
+if (component_id && strcmp(component_id, "")) {
+strncpy((char *)gem.component_id, component_id,
+sizeof(gem.component_id) - 1);
+valid_flags |= CXL_GMER_VALID_COMPONENT;
+}
+
+stw_le_p(gem.validity_flags, valid_flags);
+
+if (cxl_event_insert(cxlds, log, (struct cxl_event_record_raw *))) {
+cxl_event_irq_assert(ct3d);
+}
+}
+
 void qmp_cxl_inject_poison(const char *path, uint64_t start, uint64_t length,
Error **errp)
 {
diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c
index f2c9f48f4010..62f04d487031 100644
--- a/hw/mem/cxl_type3_stubs.c
+++ b/hw/mem/cxl_type3_stubs.c
@@ -2,6 +2,14 @@
 #include "qemu/osdep.h"
 #include "qapi/qapi-commands-cxl.h"
 
+void qmp_cxl_inject_gen_media_event(const char *path, uint8_t log,
+uint8_t flags, uint64_t physaddr,
+uint8_t descriptor, uint8_t type,
+uint8_t transaction_type,
+int16_t channel, int16_t rank,
+int32_t device,
+char *component_id,
+Error **errp) {}
 void qmp_cxl_inject_poison(const char *path, uint64_t start, uint64_t length,
Error **errp) {}
 void 

[PATCH v2 0/8] QEMU CXL Provide mock CXL events and irq support

2022-12-21 Thread Ira Weiny
CXL Event records inform the OS of various CXL device events.  Thus far CXL
memory devices are emulated and therefore don't naturally generate events.

Add an event infrastructure and mock event injection.  Previous versions
included a bulk insertion of lots of events.  However, this series focuses on
providing the ability to inject individual events through QMP.  Only the
General Media Event is included in this series as an example.  Other events can
be added pretty easily once the infrastructure is acceptable.

In addition, this version updates the code to be in line with the
specification based on discussions around the kernel patches.

This series is based on Jonathan's CXL branch here:
https://gitlab.com/jic23/qemu/-/tree/cxl-2022-11-17

Kernel code found here:
https://lore.kernel.org/all/20221212070627.1372402-1-ira.we...@intel.com/

Previous RFC (V1) version:
https://lore.kernel.org/linux-cxl/20221010222944.3923556-1-ira.we...@intel.com/

Instructions:

Add qmp option to qemu:

 $ qemu-system-x86_64 ... -qmp 
unix:/tmp/run_qemu_qmp_0,server,nowait ...

OR

 $ run_qemu.sh ... --qmp ...

Enable tracing of events within the guest:

 $ echo "" > /sys/kernel/tracing/trace
 $ echo 1 > /sys/kernel/tracing/events/cxl/enable
 $ echo 1 > /sys/kernel/tracing/tracing_on

OPTIONAL: set up ndctl to monitor for events (events will show up as
  they are injected)

 $ /cxl monitor

Trigger event generation and interrupts in the host:

 $ qmpcmd="${qemusrcdir}/build/scripts/qmp/qmp-shell 
/tmp/run_qemu_qmp_0"

 $ echo "cxl-inject-gen-media-event path=cxl-dev0 log=0 flags=1 \
physaddr=1000 descriptor=127 type=3 transactiontype=192 
\
channel=3 rank=-1 device=5 componentid='Iras mem'" | 
$qmpcmd



View events on the guest:

 $ cat /sys/kernel/tracing/trace

To: Jonathan Cameron 
Cc: Michael Tsirkin 
Cc: Ben Widawsky 
Cc: Ira Weiny 
Cc: qemu-devel@nongnu.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ira Weiny 

---
Ira Weiny (8):
  qemu/bswap: Add const_le64()
  qemu/uuid: Add UUID static initializer
  hw/cxl/mailbox: Use new UUID network order define for cel_uuid
  hw/cxl/events: Add event status register
  hw/cxl/events: Wire up get/clear event mailbox commands
  hw/cxl/events: Add event interrupt support
  bswap: Add the ability to store to an unaligned 24 bit field
  hw/cxl/events: Add in inject general media event

 hw/cxl/cxl-device-utils.c   |  54 --
 hw/cxl/cxl-events.c | 252 
 hw/cxl/cxl-mailbox-utils.c  | 160 ++--
 hw/cxl/meson.build  |   1 +
 hw/mem/cxl_type3.c  |  96 -
 hw/mem/cxl_type3_stubs.c|   8 ++
 include/hw/cxl/cxl_device.h |  56 +-
 include/hw/cxl/cxl_events.h | 126 ++
 include/qemu/bswap.h|  40 +++
 include/qemu/uuid.h |  12 +++
 qapi/cxl.json   |  25 +
 11 files changed, 785 insertions(+), 45 deletions(-)
---
base-commit: 1b4133103d20fc3fea05c7ceca4a242468a5179d
change-id: 20221221-ira-cxl-events-2022-11-17-fef53f9b9ac2

Best regards,
-- 
Ira Weiny 



[PATCH v2 4/8] hw/cxl/events: Add event status register

2022-12-21 Thread Ira Weiny
The device status register block was defined.  However, there were no
individual registers nor any data wired up.

Define the event status register [CXL 3.0; 8.2.8.3.1] as part of the
device status register block.  Wire up the register and initialize the
event status for each log.

To support CXL 3.0 the version of the device status register block needs
to be 2.  Change the macro to allow for setting the version.

Signed-off-by: Ira Weiny 

---
Changes from RFC:
New patch to cover this register which was not being used
before.
---
 hw/cxl/cxl-device-utils.c   | 50 +
 include/hw/cxl/cxl_device.h | 23 ++---
 include/hw/cxl/cxl_events.h | 28 +
 3 files changed, 90 insertions(+), 11 deletions(-)

diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index 34697064714e..7f29d40be04a 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -41,7 +41,20 @@ static uint64_t caps_reg_read(void *opaque, hwaddr offset, 
unsigned size)
 
 static uint64_t dev_reg_read(void *opaque, hwaddr offset, unsigned size)
 {
-return 0;
+CXLDeviceState *cxl_dstate = opaque;
+
+switch (size) {
+case 1:
+return cxl_dstate->dev_reg_state[offset];
+case 2:
+return cxl_dstate->dev_reg_state16[offset / size];
+case 4:
+return cxl_dstate->dev_reg_state32[offset / size];
+case 8:
+return cxl_dstate->dev_reg_state64[offset / size];
+default:
+g_assert_not_reached();
+}
 }
 
 static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
@@ -236,7 +249,28 @@ void cxl_device_register_block_init(Object *obj, 
CXLDeviceState *cxl_dstate)
 _dstate->memory_device);
 }
 
-static void device_reg_init_common(CXLDeviceState *cxl_dstate) { }
+void cxl_event_set_status(CXLDeviceState *cxl_dstate,
+  enum cxl_event_log_type log_type,
+  bool available)
+{
+if (available) {
+cxl_dstate->event_status |= (1 << log_type);
+} else {
+cxl_dstate->event_status &= ~(1 << log_type);
+}
+
+ARRAY_FIELD_DP64(cxl_dstate->dev_reg_state64, CXL_DEV_EVENT_STATUS,
+ EVENT_STATUS, cxl_dstate->event_status);
+}
+
+static void device_reg_init_common(CXLDeviceState *cxl_dstate)
+{
+enum cxl_event_log_type log;
+
+for (log = 0; log < CXL_EVENT_TYPE_MAX; log++) {
+cxl_event_set_status(cxl_dstate, log, false);
+}
+}
 
 static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
 {
@@ -258,13 +292,13 @@ void cxl_device_register_init_common(CXLDeviceState 
*cxl_dstate)
 ARRAY_FIELD_DP64(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_VERSION, 1);
 ARRAY_FIELD_DP64(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_COUNT, cap_count);
 
-cxl_device_cap_init(cxl_dstate, DEVICE_STATUS, 1);
+cxl_device_cap_init(cxl_dstate, DEVICE_STATUS, 1, 2);
 device_reg_init_common(cxl_dstate);
 
-cxl_device_cap_init(cxl_dstate, MAILBOX, 2);
+cxl_device_cap_init(cxl_dstate, MAILBOX, 2, 1);
 mailbox_reg_init_common(cxl_dstate);
 
-cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000);
+cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000, 1);
 memdev_reg_init_common(cxl_dstate);
 
 cxl_initialize_mailbox(cxl_dstate, false);
@@ -280,13 +314,13 @@ void cxl_device_register_init_swcci(CXLDeviceState 
*cxl_dstate)
 ARRAY_FIELD_DP64(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_VERSION, 1);
 ARRAY_FIELD_DP64(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_COUNT, cap_count);
 
-cxl_device_cap_init(cxl_dstate, DEVICE_STATUS, 1);
+cxl_device_cap_init(cxl_dstate, DEVICE_STATUS, 1, 2);
 device_reg_init_common(cxl_dstate);
 
-cxl_device_cap_init(cxl_dstate, MAILBOX, 2);
+cxl_device_cap_init(cxl_dstate, MAILBOX, 2, 1);
 mailbox_reg_init_common(cxl_dstate);
 
-cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000);
+cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000, 1);
 memdev_reg_init_common(cxl_dstate);
 
 cxl_initialize_mailbox(cxl_dstate, true);
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 3be2e37b3e4c..7180fc225e29 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -147,7 +147,16 @@ typedef struct cxl_device_state {
 
 MemoryRegion cpmu_registers[CXL_NUM_CPMU_INSTANCES];
 /* mmio for device capabilities array - 8.2.8.2 */
-MemoryRegion device;
+struct {
+MemoryRegion device;
+union {
+uint8_t dev_reg_state[CXL_DEVICE_STATUS_REGISTERS_LENGTH];
+uint16_t dev_reg_state16[CXL_DEVICE_STATUS_REGISTERS_LENGTH / 2];
+uint32_t dev_reg_state32[CXL_DEVICE_STATUS_REGISTERS_LENGTH / 4];
+uint64_t dev_reg_state64[CXL_DEVICE_STATUS_REGISTERS_LENGTH / 8];
+};
+uint64_t event_status;
+};
 MemoryRegion memory_device;
 struct {
 MemoryRegion 

[PATCH v2 6/8] hw/cxl/events: Add event interrupt support

2022-12-21 Thread Ira Weiny
Replace the stubbed out CXL Get/Set Event interrupt policy mailbox
commands.  Enable those commands to control interrupts for each of the
event log types.

Skip the standard input mailbox length on the Set command due to DCD
being optional.  Perform the checks separately.

Signed-off-by: Ira Weiny 

---
NOTE As the spec changes it may be wise to change the standard mailbox
processing to allow for various input length checks.  But I'm not going
try and tackle that in this series.

Changes from RFC:
Squashed mailbox and irq patches together to support event
interrupts as a whole
Remove redundant event_vector array
---
 hw/cxl/cxl-events.c |  33 +-
 hw/cxl/cxl-mailbox-utils.c  | 106 +++-
 hw/mem/cxl_type3.c  |   4 +-
 include/hw/cxl/cxl_device.h |   5 ++-
 include/hw/cxl/cxl_events.h |  23 ++
 5 files changed, 146 insertions(+), 25 deletions(-)

diff --git a/hw/cxl/cxl-events.c b/hw/cxl/cxl-events.c
index f40c9372704e..53ec8447236e 100644
--- a/hw/cxl/cxl-events.c
+++ b/hw/cxl/cxl-events.c
@@ -13,6 +13,8 @@
 #include "qemu/bswap.h"
 #include "qemu/typedefs.h"
 #include "qemu/error-report.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/msix.h"
 #include "hw/cxl/cxl.h"
 #include "hw/cxl/cxl_events.h"
 
@@ -26,7 +28,7 @@ static void reset_overflow(struct cxl_event_log *log)
 log->last_overflow_timestamp = 0;
 }
 
-void cxl_event_init(CXLDeviceState *cxlds)
+void cxl_event_init(CXLDeviceState *cxlds, int start_msg_num)
 {
 struct cxl_event_log *log;
 int i;
@@ -37,9 +39,16 @@ void cxl_event_init(CXLDeviceState *cxlds)
 log->overflow_err_count = 0;
 log->first_overflow_timestamp = 0;
 log->last_overflow_timestamp = 0;
+log->irq_enabled = false;
+log->irq_vec = start_msg_num++;
 qemu_mutex_init(>lock);
 QSIMPLEQ_INIT(>events);
 }
+
+/* Override -- Dynamic Capacity uses the same vector as info */
+cxlds->event_logs[CXL_EVENT_TYPE_DYNAMIC_CAP].irq_vec =
+  cxlds->event_logs[CXL_EVENT_TYPE_INFO].irq_vec;
+
 }
 
 static CXLEvent *cxl_event_get_head(struct cxl_event_log *log)
@@ -219,3 +228,25 @@ ret_code cxl_event_clear_records(CXLDeviceState *cxlds,
 
 return CXL_MBOX_SUCCESS;
 }
+
+void cxl_event_irq_assert(CXLType3Dev *ct3d)
+{
+CXLDeviceState *cxlds = >cxl_dstate;
+PCIDevice *pdev = >parent_obj;
+int i;
+
+for (i = 0; i < CXL_EVENT_TYPE_MAX; i++) {
+struct cxl_event_log *log = >event_logs[i];
+
+if (!log->irq_enabled || cxl_event_empty(log)) {
+continue;
+}
+
+/*  Notifies interrupt, legacy IRQ is not supported */
+if (msix_enabled(pdev)) {
+msix_notify(pdev, log->irq_vec);
+} else if (msi_enabled(pdev)) {
+msi_notify(pdev, log->irq_vec);
+}
+}
+}
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 97cf6db8582d..ff94191a956a 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -74,25 +74,6 @@ enum {
 #define IDENTIFY_SWITCH_DEVICE  0x0
 };
 
-#define DEFINE_MAILBOX_HANDLER_ZEROED(name, size) \
-uint16_t __zero##name = size; \
-static ret_code cmd_##name(struct cxl_cmd *cmd,   \
-   CXLDeviceState *cxl_dstate, uint16_t *len) \
-{ \
-*len = __zero##name;  \
-memset(cmd->payload, 0, *len);\
-return CXL_MBOX_SUCCESS;  \
-}
-#define DEFINE_MAILBOX_HANDLER_NOP(name)  \
-static ret_code cmd_##name(struct cxl_cmd *cmd,   \
-   CXLDeviceState *cxl_dstate, uint16_t *len) \
-{ \
-return CXL_MBOX_SUCCESS;  \
-}
-
-DEFINE_MAILBOX_HANDLER_ZEROED(events_get_interrupt_policy, 4);
-DEFINE_MAILBOX_HANDLER_NOP(events_set_interrupt_policy);
-
 static void find_cxl_usp(PCIBus *b, PCIDevice *d, void *opaque)
 {
 PCIDevice **found_dev = opaque;
@@ -288,6 +269,88 @@ static ret_code cmd_events_clear_records(struct cxl_cmd 
*cmd,
 return cxl_event_clear_records(cxlds, pl);
 }
 
+static ret_code cmd_events_get_interrupt_policy(struct cxl_cmd *cmd,
+CXLDeviceState *cxlds,
+uint16_t *len)
+{
+struct cxl_event_interrupt_policy *policy;
+struct cxl_event_log *log;
+
+policy = (struct cxl_event_interrupt_policy *)cmd->payload;
+memset(policy, 0, sizeof(*policy));
+
+log = >event_logs[CXL_EVENT_TYPE_INFO];
+if 

[PATCH v2 1/8] qemu/bswap: Add const_le64()

2022-12-21 Thread Ira Weiny
Gcc requires constant versions of cpu_to_le* calls.

Add a 64 bit version.

Reviewed-by: Jonathan Cameron 
Reviewed-by: Peter Maydell 
Signed-off-by: Ira Weiny 

---
Changes from RFC:
Peter
Change order of the definitions, 64-32-16
---
 include/qemu/bswap.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 346d05f2aab3..e1eca22f2548 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -187,6 +187,15 @@ CPU_CONVERT(le, 64, uint64_t)
  * used to initialize static variables.
  */
 #if HOST_BIG_ENDIAN
+# define const_le64(_x)  \
+_x) & 0x00ffU) << 56) |  \
+ (((_x) & 0xff00U) << 40) |  \
+ (((_x) & 0x00ffU) << 24) |  \
+ (((_x) & 0xff00U) <<  8) |  \
+ (((_x) & 0x00ffU) >>  8) |  \
+ (((_x) & 0xff00U) >> 24) |  \
+ (((_x) & 0x00ffU) >> 40) |  \
+ (((_x) & 0xff00U) >> 56))
 # define const_le32(_x)  \
 _x) & 0x00ffU) << 24) |  \
  (((_x) & 0xff00U) <<  8) |  \
@@ -196,6 +205,7 @@ CPU_CONVERT(le, 64, uint64_t)
 _x) & 0x00ff) << 8) |\
  (((_x) & 0xff00) >> 8))
 #else
+# define const_le64(_x) (_x)
 # define const_le32(_x) (_x)
 # define const_le16(_x) (_x)
 #endif

-- 
2.38.1



[PATCH v2 2/8] qemu/uuid: Add UUID static initializer

2022-12-21 Thread Ira Weiny
UUID's are defined as network byte order fields.  No static initializer
was available for UUID's in their standard big endian format.

Define a big endian initializer for UUIDs.

Reviewed-by: Jonathan Cameron 
Signed-off-by: Ira Weiny 
---
 include/qemu/uuid.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/qemu/uuid.h b/include/qemu/uuid.h
index 9925febfa54d..dc40ee1fc998 100644
--- a/include/qemu/uuid.h
+++ b/include/qemu/uuid.h
@@ -61,6 +61,18 @@ typedef struct {
 (clock_seq_hi_and_reserved), (clock_seq_low), (node0), (node1), (node2),\
 (node3), (node4), (node5) }
 
+/* Normal (network byte order) UUID */
+#define UUID(time_low, time_mid, time_hi_and_version,\
+  clock_seq_hi_and_reserved, clock_seq_low, node0, node1, node2, \
+  node3, node4, node5)   \
+  { ((time_low) >> 24) & 0xff, ((time_low) >> 16) & 0xff,\
+((time_low) >> 8) & 0xff, (time_low) & 0xff, \
+((time_mid) >> 8) & 0xff, (time_mid) & 0xff, \
+((time_hi_and_version) >> 8) & 0xff, (time_hi_and_version) & 0xff,   \
+(clock_seq_hi_and_reserved), (clock_seq_low),\
+(node0), (node1), (node2), (node3), (node4), (node5) \
+  }
+
 #define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-" \
  "%02hhx%02hhx-%02hhx%02hhx-" \
  "%02hhx%02hhx-" \

-- 
2.38.1



[PATCH v2 5/8] hw/cxl/events: Wire up get/clear event mailbox commands

2022-12-21 Thread Ira Weiny
CXL testing is benefited from an artificial event log injection
mechanism.

Add an event log infrastructure to insert, get, and clear events from
the various logs available on a device.

Replace the stubbed out CXL Get/Clear Event mailbox commands with
commands that operate on the new infrastructure.

Signed-off-by: Ira Weiny 

---
Change from RFC:
Process multiple records per Get/Set per the spec
Rework all the calls to be within events.c
Add locking around the event logs to ensure that the log
integrity is maintained
---
 hw/cxl/cxl-events.c | 221 
 hw/cxl/cxl-mailbox-utils.c  |  40 +++-
 hw/cxl/meson.build  |   1 +
 hw/mem/cxl_type3.c  |   1 +
 include/hw/cxl/cxl_device.h |  28 ++
 include/hw/cxl/cxl_events.h |  55 +++
 6 files changed, 344 insertions(+), 2 deletions(-)

diff --git a/hw/cxl/cxl-events.c b/hw/cxl/cxl-events.c
new file mode 100644
index ..f40c9372704e
--- /dev/null
+++ b/hw/cxl/cxl-events.c
@@ -0,0 +1,221 @@
+/*
+ * CXL Event processing
+ *
+ * Copyright(C) 2022 Intel Corporation.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See the
+ * COPYING file in the top-level directory.
+ */
+
+#include 
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "qemu/typedefs.h"
+#include "qemu/error-report.h"
+#include "hw/cxl/cxl.h"
+#include "hw/cxl/cxl_events.h"
+
+/* Artificial limit on the number of events a log can hold */
+#define CXL_TEST_EVENT_OVERFLOW 8
+
+static void reset_overflow(struct cxl_event_log *log)
+{
+log->overflow_err_count = 0;
+log->first_overflow_timestamp = 0;
+log->last_overflow_timestamp = 0;
+}
+
+void cxl_event_init(CXLDeviceState *cxlds)
+{
+struct cxl_event_log *log;
+int i;
+
+for (i = 0; i < CXL_EVENT_TYPE_MAX; i++) {
+log = >event_logs[i];
+log->next_handle = 1;
+log->overflow_err_count = 0;
+log->first_overflow_timestamp = 0;
+log->last_overflow_timestamp = 0;
+qemu_mutex_init(>lock);
+QSIMPLEQ_INIT(>events);
+}
+}
+
+static CXLEvent *cxl_event_get_head(struct cxl_event_log *log)
+{
+return QSIMPLEQ_FIRST(>events);
+}
+
+static CXLEvent *cxl_event_get_next(CXLEvent *entry)
+{
+return QSIMPLEQ_NEXT(entry, node);
+}
+
+static int cxl_event_count(struct cxl_event_log *log)
+{
+CXLEvent *event;
+int rc = 0;
+
+QSIMPLEQ_FOREACH(event, >events, node) {
+rc++;
+}
+
+return rc;
+}
+
+static bool cxl_event_empty(struct cxl_event_log *log)
+{
+return QSIMPLEQ_EMPTY(>events);
+}
+
+static void cxl_event_delete_head(CXLDeviceState *cxlds,
+  enum cxl_event_log_type log_type,
+  struct cxl_event_log *log)
+{
+CXLEvent *entry = cxl_event_get_head(log);
+
+reset_overflow(log);
+QSIMPLEQ_REMOVE_HEAD(>events, node);
+if (cxl_event_empty(log)) {
+cxl_event_set_status(cxlds, log_type, false);
+}
+g_free(entry);
+}
+
+/*
+ * return if an interrupt should be generated as a result of inserting this
+ * event.
+ */
+bool cxl_event_insert(CXLDeviceState *cxlds,
+  enum cxl_event_log_type log_type,
+  struct cxl_event_record_raw *event)
+{
+uint64_t time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+struct cxl_event_log *log;
+CXLEvent *entry;
+
+if (log_type >= CXL_EVENT_TYPE_MAX) {
+return false;
+}
+
+log = >event_logs[log_type];
+
+QEMU_LOCK_GUARD(>lock);
+
+if (cxl_event_count(log) >= CXL_TEST_EVENT_OVERFLOW) {
+if (log->overflow_err_count == 0) {
+log->first_overflow_timestamp = time;
+}
+log->overflow_err_count++;
+log->last_overflow_timestamp = time;
+return false;
+}
+
+entry = g_new0(CXLEvent, 1);
+if (!entry) {
+error_report("Failed to allocate memory for event log entry");
+return false;
+}
+
+memcpy(>data, event, sizeof(*event));
+
+entry->data.hdr.handle = cpu_to_le16(log->next_handle);
+log->next_handle++;
+/* 0 handle is never valid */
+if (log->next_handle == 0) {
+log->next_handle++;
+}
+entry->data.hdr.timestamp = cpu_to_le64(time);
+
+QSIMPLEQ_INSERT_TAIL(>events, entry, node);
+cxl_event_set_status(cxlds, log_type, true);
+
+/* Count went from 0 to 1 */
+return cxl_event_count(log) == 1;
+}
+
+ret_code cxl_event_get_records(CXLDeviceState *cxlds,
+   struct cxl_get_event_payload *pl,
+   uint8_t log_type, int max_recs,
+   uint16_t *len)
+{
+struct cxl_event_log *log;
+CXLEvent *entry;
+uint16_t nr;
+
+if (log_type >= CXL_EVENT_TYPE_MAX) {
+return CXL_MBOX_INVALID_INPUT;
+}
+
+log = >event_logs[log_type];
+
+QEMU_LOCK_GUARD(>lock);
+
+entry = 

[PATCH v2 3/8] hw/cxl/mailbox: Use new UUID network order define for cel_uuid

2022-12-21 Thread Ira Weiny
The cel_uuid was programatically generated previously because there was
no static initializer for network order UUIDs.

Use the new network order initializer for cel_uuid.  Adjust
cxl_initialize_mailbox() because it can't fail now.

Update specification reference.

Signed-off-by: Ira Weiny 

---
Changes from RFC:
New patch.
---
 hw/cxl/cxl-device-utils.c   |  4 ++--
 hw/cxl/cxl-mailbox-utils.c  | 14 +++---
 include/hw/cxl/cxl_device.h |  2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index 21845dbfd050..34697064714e 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -267,7 +267,7 @@ void cxl_device_register_init_common(CXLDeviceState 
*cxl_dstate)
 cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000);
 memdev_reg_init_common(cxl_dstate);
 
-assert(cxl_initialize_mailbox(cxl_dstate, false) == 0);
+cxl_initialize_mailbox(cxl_dstate, false);
 }
 
 void cxl_device_register_init_swcci(CXLDeviceState *cxl_dstate)
@@ -289,5 +289,5 @@ void cxl_device_register_init_swcci(CXLDeviceState 
*cxl_dstate)
 cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000);
 memdev_reg_init_common(cxl_dstate);
 
-assert(cxl_initialize_mailbox(cxl_dstate, true) == 0);
+cxl_initialize_mailbox(cxl_dstate, true);
 }
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index c1183614b9a4..157c01255ee3 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -321,7 +321,11 @@ static ret_code cmd_timestamp_set(struct cxl_cmd *cmd,
 return CXL_MBOX_SUCCESS;
 }
 
-static QemuUUID cel_uuid;
+/* CXL 3.0 8.2.9.5.2.1 Command Effects Log (CEL) */
+static QemuUUID cel_uuid = {
+.data = UUID(0x0da9c0b5, 0xbf41, 0x4b78, 0x8f, 0x79,
+ 0x96, 0xb1, 0x62, 0x3b, 0x3f, 0x17)
+};
 
 /* 8.2.9.4.1 */
 static ret_code cmd_logs_get_supported(struct cxl_cmd *cmd,
@@ -684,16 +688,14 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
  DOORBELL, 0);
 }
 
-int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate, bool switch_cci)
+void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate, bool switch_cci)
 {
-/* CXL 2.0: Table 169 Get Supported Logs Log Entry */
-const char *cel_uuidstr = "0da9c0b5-bf41-4b78-8f79-96b1623b3f17";
-
 if (!switch_cci) {
 cxl_dstate->cxl_cmd_set = cxl_cmd_set;
 } else {
 cxl_dstate->cxl_cmd_set = cxl_cmd_set_sw;
 }
+
 for (int set = 0; set < 256; set++) {
 for (int cmd = 0; cmd < 256; cmd++) {
 if (cxl_dstate->cxl_cmd_set[set][cmd].handler) {
@@ -707,6 +709,4 @@ int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate, bool 
switch_cci)
 }
 }
 }
-
-return qemu_uuid_parse(cel_uuidstr, _uuid);
 }
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 1b366b739c62..3be2e37b3e4c 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -238,7 +238,7 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE,
   CXL_DEVICE_CAP_HDR1_OFFSET +
   CXL_DEVICE_CAP_REG_SIZE * 2)
 
-int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate, bool switch_cci);
+void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate, bool switch_cci);
 void cxl_process_mailbox(CXLDeviceState *cxl_dstate);
 
 #define cxl_device_cap_init(dstate, reg, cap_id)   \

-- 
2.38.1



[PATCH v2 7/8] bswap: Add the ability to store to an unaligned 24 bit field

2022-12-21 Thread Ira Weiny
CXL has 24 bit unaligned fields which need to be stored to.  CXL is
specified as little endian.

Define st24_le_p() and the supporting functions to store such a field
from a 32 bit host native value.

The use of b, w, l, q as the size specifier is limiting.  So "24" was
used for the size part of the function name.

Signed-off-by: Ira Weiny 
---
 include/qemu/bswap.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index e1eca22f2548..8af4d4a75eb6 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -25,6 +25,13 @@ static inline uint16_t bswap16(uint16_t x)
 return bswap_16(x);
 }
 
+static inline uint32_t bswap24(uint32_t x)
+{
+return (((x & 0x00ffU) << 16) |
+((x & 0xff00U) <<  0) |
+((x & 0x00ffU) >> 16));
+}
+
 static inline uint32_t bswap32(uint32_t x)
 {
 return bswap_32(x);
@@ -43,6 +50,13 @@ static inline uint16_t bswap16(uint16_t x)
 ((x & 0xff00) >> 8));
 }
 
+static inline uint32_t bswap24(uint32_t x)
+{
+return (((x & 0x00ffU) << 16) |
+((x & 0xff00U) <<  0) |
+((x & 0x00ffU) >> 16));
+}
+
 static inline uint32_t bswap32(uint32_t x)
 {
 return (((x & 0x00ffU) << 24) |
@@ -72,6 +86,11 @@ static inline void bswap16s(uint16_t *s)
 *s = bswap16(*s);
 }
 
+static inline void bswap24s(uint32_t *s)
+{
+*s = bswap24(*s);
+}
+
 static inline void bswap32s(uint32_t *s)
 {
 *s = bswap32(*s);
@@ -233,6 +252,7 @@ CPU_CONVERT(le, 64, uint64_t)
  * size is:
  *   b: 8 bits
  *   w: 16 bits
+ *   24: 24 bits
  *   l: 32 bits
  *   q: 64 bits
  *
@@ -305,6 +325,11 @@ static inline void stw_he_p(void *ptr, uint16_t v)
 __builtin_memcpy(ptr, , sizeof(v));
 }
 
+static inline void st24_he_p(void *ptr, uint32_t v)
+{
+__builtin_memcpy(ptr, , 3);
+}
+
 static inline int ldl_he_p(const void *ptr)
 {
 int32_t r;
@@ -354,6 +379,11 @@ static inline void stw_le_p(void *ptr, uint16_t v)
 stw_he_p(ptr, le_bswap(v, 16));
 }
 
+static inline void st24_le_p(void *ptr, uint32_t v)
+{
+st24_he_p(ptr, le_bswap(v, 24));
+}
+
 static inline void stl_le_p(void *ptr, uint32_t v)
 {
 stl_he_p(ptr, le_bswap(v, 32));

-- 
2.38.1



Re: [RFC PATCH-for-8.0 2/3] hw/ppc/spapr: Replace tswap64(HPTE) by cpu_to_be64(HPTE)

2022-12-21 Thread David Gibson
On Wed, Dec 21, 2022 at 10:15:28PM +, Peter Maydell wrote:
> On Wed, 21 Dec 2022 at 16:03, Cédric Le Goater  wrote:
> >
> > On 12/21/22 13:33, Peter Maydell wrote:
> > > On Wed, 21 Dec 2022 at 01:35, David Gibson  
> > > wrote:
> > >> On Mon, Dec 19, 2022 at 10:39:40AM +, Peter Maydell wrote:
> > >>> OK. I still think we should consistently change all the places that are
> > >>> accessing this data structure, though, not just half of them.
> > >>
> > >> Yes, that makes sense.  Although what exactly constitutes "this data
> > >> structure" is a bit complex here.  If we mean just the spapr specific
> > >> "external HPT", then there are only a few more references to it.  If
> > >> we mean all instances of a powerpc hashed page table, then there are a
> > >> bunch more in the cpu target code.
> > >
> > > I had in mind "places where we write this specific array of bytes
> > > spapr->htab".

Seems a reasonable amount to tackle for now.

> > spapr_store_hpte() seems to be the most annoying part. It is used
> > by hcalls h_enter, h_remove, h_protect. Reworking the interface
> > to present pte0/pte1 as BE variables means reworking the whole
> > hw/ppc/spapr_softmmu.c file. That's feasible but not a small task
> > since the changes will root down in the target hash mmu code which
> > is shared by all platforms ... :/
> 
> Don't you just need to change spapr_store_hpte() to use stq_be_p()
> instead of stq_p() ?

I think Peter is right.  The values passed to the function are "host
endian" (really, they don't have an endianness since they'll be in
registers).

> > spapr_hpte_set_c() are spapr_hpte_set_r() are of a different kind.
> 
> That code seems to suggest we already implicitly assume that
> spapr->htab fields have a given endianness...

Yes, we absolutely do.  We rely on the HPTE always being big-endian.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH-for-8.0 4/4] hw/ppc/spapr_ovec: Avoid target_ulong spapr_ovec_parse_vector()

2022-12-21 Thread David Gibson
On Wed, Dec 21, 2022 at 10:26:51AM -0300, Daniel Henrique Barboza wrote:
> 
> 
> On 12/21/22 06:46, Cédric Le Goater wrote:
> > On 12/16/22 17:47, Daniel Henrique Barboza wrote:
> > > 
> > > 
> > > On 12/13/22 09:35, Philippe Mathieu-Daudé wrote:
> > > > spapr_ovec.c is a device, but it uses target_ulong which is
> > > > target specific. The hwaddr type (declared in "exec/hwaddr.h")
> > > > better fits hardware addresses.
> > > 
> > > As said by Harsh, spapr_ovec is in fact a data structure that stores 
> > > platform
> > > options that are supported by the guest.
> > > 
> > > That doesn't mean that I oppose the change made here. Aside from 
> > > semantics - which
> > > I also don't have a strong opinion about it - I don't believe it matters 
> > > that
> > > much - spapr is 64 bit only, so hwaddr will always be == target_ulong.
> > > 
> > > Cedric/David/Greg, let me know if you have any restriction/thoughts about 
> > > this.
> > > I'm inclined to accept it as is.
> > 
> > Well, I am not sure.
> > 
> > The vector table variable is the result of a ppc64_phys_to_real() conversion
> > of the CAS hcall parameter, which is a target_ulong, but 
> > ppc64_phys_to_real()
> > returns a uint64_t.
> > 
> > The code is not consistent in another places :
> > 
> >    hw/ppc/spapr_tpm_proxy.c uses a uint64_t
> >    hw/ppc/spapr_hcall.c, a target_ulong
> >    hw/ppc/spapr_rtas.c, a hwaddr
> >    hw/ppc/spapr_drc.c, a hwaddr indirectly
> > 
> > Should we change ppc64_phys_to_real() to return an hwaddr (also) ?
> 
> It makes sense to me a function called ppc64_phys_to_real() returning
> a hwaddr type.

Yes, I also think that makes sense.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH v20 08/10] virtio-net: add support for configure interrupt

2022-12-21 Thread Cindy Lu
On Wed, 21 Dec 2022 at 19:25, Michael S. Tsirkin  wrote:
>
> On Mon, Dec 12, 2022 at 01:20:40AM +0800, Cindy Lu wrote:
> > Add functions to support configure interrupt in virtio_net
> > Add the functions to support vhost_net_config_pending
> > and vhost_net_config_mask.
> >
> > Signed-off-by: Cindy Lu 
>
>
>
> Causes a bunch of failures including mingw.
> See:
> https://gitlab.com/mstredhat/qemu/-/pipelines/728492799/failures
>
> lots of:
> /builds/mstredhat/qemu/build/../hw/net/virtio-net.c:3366: undefined reference 
> to `vhost_net_config_mask'
>
> Pls fix and repost.
>
Sorry,  Michael, will post a new version soon
>
> > ---
> >  hw/net/vhost_net.c  | 9 +
> >  hw/net/virtio-net.c | 4 ++--
> >  include/net/vhost_net.h | 2 ++
> >  3 files changed, 13 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > index 043058ff43..6a55f5a473 100644
> > --- a/hw/net/vhost_net.c
> > +++ b/hw/net/vhost_net.c
> > @@ -478,6 +478,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, 
> > VirtIODevice *dev,
> >  vhost_virtqueue_mask(>dev, dev, idx, mask);
> >  }
> >
> > +bool vhost_net_config_pending(VHostNetState *net)
> > +{
> > +return vhost_config_pending(>dev);
> > +}
> > +
> > +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool 
> > mask)
> > +{
> > +vhost_config_mask(>dev, dev, mask);
> > +}
> >  VHostNetState *get_vhost_net(NetClientState *nc)
> >  {
> >  VHostNetState *vhost_net = 0;
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index bee35d6f9f..ec974f7a76 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -3323,7 +3323,7 @@ static bool 
> > virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
> >   */
> >
> >  if (idx == VIRTIO_CONFIG_IRQ_IDX) {
> > -return false;
> > +return vhost_net_config_pending(get_vhost_net(nc->peer));
> >  }
> >  return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx);
> >  }
> > @@ -3355,9 +3355,9 @@ static void 
> > virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
> >   */
> >
> >  if (idx == VIRTIO_CONFIG_IRQ_IDX) {
> > +vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask);
> >  return;
> >  }
> > -
> >  vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask);
> >  }
> >
> > diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
> > index 40b9a40074..dbbd0dc04e 100644
> > --- a/include/net/vhost_net.h
> > +++ b/include/net/vhost_net.h
> > @@ -39,6 +39,8 @@ int vhost_net_set_config(struct vhost_net *net, const 
> > uint8_t *data,
> >  bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
> >  void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
> >int idx, bool mask);
> > +bool vhost_net_config_pending(VHostNetState *net);
> > +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool 
> > mask);
> >  int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr);
> >  VHostNetState *get_vhost_net(NetClientState *nc);
> >
> > --
> > 2.34.3
>




Re: Re: [for-8.0 v2 00/11] Refactor cryptodev

2022-12-21 Thread zhenwei pi




On 12/20/22 23:36, Michael S. Tsirkin wrote:

On Tue, Nov 22, 2022 at 10:07:45PM +0800, zhenwei pi wrote:

v1 -> v2:
- fix coding style and use 'g_strjoin()' instead of 'char services[128]'
   (suggested by Dr. David Alan Gilbert)
- wrapper function 'cryptodev_backend_account' to record statistics, and
   allocate sym_stat/asym_stat in cryptodev base class. see patch:
   'cryptodev: Support statistics'.
- add more arguments into struct CryptoDevBackendOpInfo, then
   cryptodev_backend_crypto_operation() uses *op_info only.
- support cryptodev QoS settings(BPS), both QEMU command line and QMP
   command works fine.
- add myself as the maintainer for cryptodev.

v1:
- introduce cryptodev.json to describe the attributes of crypto device, then
   drop duplicated type declare, remove some virtio related dependence.
- add statistics: OPS and bandwidth.
- add QMP command: query-cryptodev
- add HMP info command: cryptodev
- misc fix: detect akcipher capability instead of exposing akcipher service
   unconditionally.



Can we get ACK on QAPI things please?
Thanks!



Hi, Markus & Michael

Could you please review the changes of QAPI part?


Zhenwei Pi (11):
   cryptodev: Introduce cryptodev.json
   cryptodev: Remove 'name' & 'model' fields
   cryptodev: Introduce cryptodev alg type in QAPI
   cryptodev: Introduce server type in QAPI
   cryptodev: Introduce 'query-cryptodev' QMP command
   cryptodev: Support statistics
   cryptodev-builtin: Detect akcipher capability
   hmp: add cryptodev info command
   cryptodev: Use CryptoDevBackendOpInfo for operation
   cryptodev: support QoS
   MAINTAINERS: add myself as the maintainer for cryptodev

  MAINTAINERS |   2 +
  backends/cryptodev-builtin.c|  42 +++--
  backends/cryptodev-lkcf.c   |  19 +-
  backends/cryptodev-vhost-user.c |  13 +-
  backends/cryptodev-vhost.c  |   4 +-
  backends/cryptodev.c| 295 +---
  hmp-commands-info.hx|  14 ++
  hw/virtio/virtio-crypto.c   |  48 --
  include/monitor/hmp.h   |   1 +
  include/sysemu/cryptodev.h  |  94 +-
  monitor/hmp-cmds.c  |  36 
  qapi/cryptodev.json | 144 
  qapi/meson.build|   1 +
  qapi/qapi-schema.json   |   1 +
  qapi/qom.json   |   8 +-
  15 files changed, 604 insertions(+), 118 deletions(-)
  create mode 100644 qapi/cryptodev.json

--
2.20.1




--
zhenwei pi



Re: [PATCH v10 1/9] mm: Introduce memfd_restricted system call to create restricted user memory

2022-12-21 Thread Huang, Kai
On Wed, 2022-12-21 at 21:39 +0800, Chao Peng wrote:
> > On Tue, Dec 20, 2022 at 08:33:05AM +, Huang, Kai wrote:
> > > > On Tue, 2022-12-20 at 15:22 +0800, Chao Peng wrote:
> > > > > > On Mon, Dec 19, 2022 at 08:48:10AM +, Huang, Kai wrote:
> > > > > > > > On Mon, 2022-12-19 at 15:53 +0800, Chao Peng wrote:
> > > > > > > > > > > > 
> > > > > > > > > > > > [...]
> > > > > > > > > > > > 
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +   /*
> > > > > > > > > > > > > > +* These pages are currently unmovable so don't 
> > > > > > > > > > > > > > place them into
> > > > > > > > > > > > > > movable
> > > > > > > > > > > > > > +* pageblocks (e.g. CMA and ZONE_MOVABLE).
> > > > > > > > > > > > > > +*/
> > > > > > > > > > > > > > +   mapping = memfd->f_mapping;
> > > > > > > > > > > > > > +   mapping_set_unevictable(mapping);
> > > > > > > > > > > > > > +   mapping_set_gfp_mask(mapping,
> > > > > > > > > > > > > > +    mapping_gfp_mask(mapping) 
> > > > > > > > > > > > > > & ~__GFP_MOVABLE);
> > > > > > > > > > > > 
> > > > > > > > > > > > But, IIUC removing __GFP_MOVABLE flag here only makes 
> > > > > > > > > > > > page allocation from
> > > > > > > > > > > > non-
> > > > > > > > > > > > movable zones, but doesn't necessarily prevent page 
> > > > > > > > > > > > from being migrated.  My
> > > > > > > > > > > > first glance is you need to implement either 
> > > > > > > > > > > > a_ops->migrate_folio() or just
> > > > > > > > > > > > get_page() after faulting in the page to prevent.
> > > > > > > > > > 
> > > > > > > > > > The current api restrictedmem_get_page() already does this, 
> > > > > > > > > > after the
> > > > > > > > > > caller calling it, it holds a reference to the page. The 
> > > > > > > > > > caller then
> > > > > > > > > > decides when to call put_page() appropriately.
> > > > > > > > 
> > > > > > > > I tried to dig some history. Perhaps I am missing something, 
> > > > > > > > but it seems Kirill
> > > > > > > > said in v9 that this code doesn't prevent page migration, and 
> > > > > > > > we need to
> > > > > > > > increase page refcount in restrictedmem_get_page():
> > > > > > > > 
> > > > > > > > https://lore.kernel.org/linux-mm/20221129112139.usp6dqhbih47q...@box.shutemov.name/
> > > > > > > > 
> > > > > > > > But looking at this series it seems restrictedmem_get_page() in 
> > > > > > > > this v10 is
> > > > > > > > identical to the one in v9 (except v10 uses 'folio' instead of 
> > > > > > > > 'page')?
> > > > > > 
> > > > > > restrictedmem_get_page() increases page refcount several versions 
> > > > > > ago so
> > > > > > no change in v10 is needed. You probably missed my reply:
> > > > > > 
> > > > > > https://lore.kernel.org/linux-mm/20221129135844.ga902...@chaop.bj.intel.com/
> > > > 
> > > > But for non-restricted-mem case, it is correct for KVM to decrease 
> > > > page's
> > > > refcount after setting up mapping in the secondary mmu, otherwise the 
> > > > page will
> > > > be pinned by KVM for normal VM (since KVM uses GUP to get the page).
> > 
> > That's true. Actually even true for restrictedmem case, most likely we
> > will still need the kvm_release_pfn_clean() for KVM generic code. On one
> > side, other restrictedmem users like pKVM may not require page pinning
> > at all. On the other side, see below.

OK. Agreed.

> > 
> > > > 
> > > > So what we are expecting is: for KVM if the page comes from restricted 
> > > > mem, then
> > > > KVM cannot decrease the refcount, otherwise for normal page via GUP KVM 
> > > > should.
> > 
> > I argue that this page pinning (or page migration prevention) is not
> > tied to where the page comes from, instead related to how the page will
> > be used. Whether the page is restrictedmem backed or GUP() backed, once
> > it's used by current version of TDX then the page pinning is needed. So
> > such page migration prevention is really TDX thing, even not KVM generic
> > thing (that's why I think we don't need change the existing logic of
> > kvm_release_pfn_clean()). 
> > 

This essentially boils down to who "owns" page migration handling, and sadly,
page migration is kinda "owned" by the core-kernel, i.e. KVM cannot handle page
migration by itself -- it's just a passive receiver.

For normal pages, page migration is totally done by the core-kernel (i.e. it
unmaps page from VMA, allocates a new page, and uses migrate_pape() or a_ops-
>migrate_page() to actually migrate the page).

In the sense of TDX, conceptually it should be done in the same way. The more
important thing is: yes KVM can use get_page() to prevent page migration, but
when KVM wants to support it, KVM cannot just remove get_page(), as the core-
kernel will still just do migrate_page() which won't work for TDX (given
restricted_memfd doesn't have a_ops->migrate_page() implemented).

So I think the restricted_memfd filesystem should own page migration handling,
(i.e. by implementing a_ops->migrate_page() to either just reject page 

Re: [PATCH v4 00/30] This series consolidates the implementations of the PIIX3 and PIIX4 south

2022-12-21 Thread Bernhard Beschow



Am 21. Dezember 2022 19:15:04 UTC schrieb "Philippe Mathieu-Daudé" 
:
>On 21/12/22 17:59, Bernhard Beschow wrote:
>> code as possible and to bring both device models to feature parity such that
>> perhaps PIIX4 can become a drop-in-replacement for PIIX3 in the pc machine. 
>> This
>> could resolve the "Frankenstein" PIIX4-PM problem in PIIX3 discussed on this
>> list before.
>> 
>> The series is structured as follows: First, PIIX3 is changed to instantiate
>> internal devices itself, like PIIX4 does already. Second, PIIX3 gets prepared
>> for the merge with PIIX4 which includes some fixes, cleanups, and renamings.
>> Third, the same is done for PIIX4. In step four the implementations are 
>> merged.
>> Since some consolidations could be done easier with merged implementations, 
>> the
>> consolidation continues in step five which concludes the series.
>> 
>> One particular challenge in this series was that the PIC of PIIX3 used to be
>> instantiated outside of the south bridge while some sub functions require a 
>> PIC
>> with populated qemu_irqs. This has been solved by introducing a proxy PIC 
>> which
>> furthermore allows PIIX3 to be agnostic towards the virtualization technology
>> used (KVM, TCG, Xen). Due to consolidation PIIX4 gained the proxy PIC as 
>> well.
>> 
>> Another challenge was dealing with optional devices where Peter already gave
>> advice in [1] which this series implements.
>> 
>> Last but not least there might be some opportunity to consolidate VM state
>> handling, probably by reusing the one from PIIX3. Since I'm not very familiar
>> with the requirements I didn't touch it so far.
>> 
>> v4:
>> - Rebase onto "[PATCH v2 0/3] Decouple INTx-to-LNKx routing from south 
>> bridges"
>>since it is already queued via mips-next. This eliminates patches
>>'hw/isa/piix3: Prefix pci_slot_get_pirq() with "piix3_"' and 
>> 'hw/isa/piix4:
>>Prefix pci_slot_get_pirq() with "piix4_"'.
>> - Squash 'hw/isa/piix: Drop the "3" from the PIIX base class' into
>>'hw/isa/piix3: Rename typedef PIIX3State to PIIXState'. I originally only
>>split these patches since I wasn't sure whether renaming a type was 
>> allowed.
>> - Add new patch 'hw/i386/pc_piix: Associate pci_map_irq_fn as soon as PCI 
>> bus is
>>created' for forther cleanup of INTx-to-LNKx route decoupling.
>
>Sigh I did the rebase this morning and was waiting for the test suite...
>https://gitlab.com/philmd/qemu/-/commits/mips-testing/

Hmm, I'm a little confused. I thought to do the rebase myself in order to help 
which I announced yesterday.

AFAICS the nanoMIPS bootloader still needs to be adapted before this series can 
be queued and tested. Let me know if I could help.

>Anyway I'll double-check with this series.

Thank you!

Best regards,
Bernhard



[PULL v2 45/45] hw/intc: sifive_plic: Fix the pending register range check

2022-12-21 Thread Alistair Francis
From: Bin Meng 

The pending register upper limit is currently set to
plic->num_sources >> 3, which is wrong, e.g.: considering
plic->num_sources is 7, the upper limit becomes 0 which fails
the range check if reading the pending register at pending_base.

Fixes: 1e24429e40df ("SiFive RISC-V PLIC Block")
Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-16-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 1a792cc3f5..5522ede2cf 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -143,7 +143,8 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, 
unsigned size)
 uint32_t irq = (addr - plic->priority_base) >> 2;
 
 return plic->source_priority[irq];
-} else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) 
{
+} else if (addr_between(addr, plic->pending_base,
+(plic->num_sources + 31) >> 3)) {
 uint32_t word = (addr - plic->pending_base) >> 2;
 
 return plic->pending[word];
@@ -202,7 +203,7 @@ static void sifive_plic_write(void *opaque, hwaddr addr, 
uint64_t value,
 sifive_plic_update(plic);
 }
 } else if (addr_between(addr, plic->pending_base,
-plic->num_sources >> 3)) {
+(plic->num_sources + 31) >> 3)) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: invalid pending write: 0x%" HWADDR_PRIx "",
   __func__, addr);
-- 
2.38.1




[PULL v2 33/45] hw/riscv: Sort machines Kconfig options in alphabetical order

2022-12-21 Thread Alistair Francis
From: Bin Meng 

SHAKTI_C machine Kconfig option was inserted in disorder. Fix it.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Wilfred Mallawa 
Message-Id: <20221211030829.802437-4-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/Kconfig | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 1e4b58024f..4550b3b938 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -4,6 +4,8 @@ config RISCV_NUMA
 config IBEX
 bool
 
+# RISC-V machines in alphabetical order
+
 config MICROCHIP_PFSOC
 bool
 select CADENCE_SDHCI
@@ -22,13 +24,6 @@ config OPENTITAN
 select SIFIVE_PLIC
 select UNIMP
 
-config SHAKTI_C
-bool
-select UNIMP
-select SHAKTI_UART
-select RISCV_ACLINT
-select SIFIVE_PLIC
-
 config RISCV_VIRT
 bool
 imply PCI_DEVICES
@@ -50,6 +45,13 @@ config RISCV_VIRT
 select FW_CFG_DMA
 select PLATFORM_BUS
 
+config SHAKTI_C
+bool
+select RISCV_ACLINT
+select SHAKTI_UART
+select SIFIVE_PLIC
+select UNIMP
+
 config SIFIVE_E
 bool
 select RISCV_ACLINT
-- 
2.38.1




[PATCH 0/4] exagon (target/hexagon) Add overrides for COF insns

2022-12-21 Thread Taylor Simpson
The idef-parser skips the change-of-flow (COF) instructions, so add
overrides

Taylor Simpson (4):
  Hexagon (target/hexagon) Add overrides for jumpr31 instructions
  Hexagon (target/hexagon) Add overrides for callr
  Hexagon (target/hexagon) Add overrides for endloop1/endloop01
  Hexagon (target/hexagon) Add overrides for dealloc-return instructions

 target/hexagon/gen_tcg.h   |  77 +++
 target/hexagon/macros.h|  10 --
 target/hexagon/genptr.c| 193 +
 target/hexagon/op_helper.c |  24 -
 4 files changed, 270 insertions(+), 34 deletions(-)

-- 
2.17.1



[PULL v2 36/45] hw/intc: sifive_plic: Improve robustness of the PLIC config parser

2022-12-21 Thread Alistair Francis
From: Bin Meng 

At present the PLIC config parser can only handle legal config string
like "MS,MS". However if a config string like ",MS,MS,,MS,MS,," is
given the parser won't get the correct configuration.

This commit improves the config parser to make it more robust.

Signed-off-by: Bin Meng 
Acked-by: Alistair Francis 
Message-Id: <20221211030829.802437-7-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 936dcf74bc..c9af94a888 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -290,7 +290,7 @@ static void sifive_plic_reset(DeviceState *dev)
  */
 static void parse_hart_config(SiFivePLICState *plic)
 {
-int addrid, hartid, modes;
+int addrid, hartid, modes, m;
 const char *p;
 char c;
 
@@ -299,11 +299,13 @@ static void parse_hart_config(SiFivePLICState *plic)
 p = plic->hart_config;
 while ((c = *p++)) {
 if (c == ',') {
-addrid += ctpop8(modes);
-modes = 0;
-hartid++;
+if (modes) {
+addrid += ctpop8(modes);
+hartid++;
+modes = 0;
+}
 } else {
-int m = 1 << char_to_mode(c);
+m = 1 << char_to_mode(c);
 if (modes == (modes | m)) {
 error_report("plic: duplicate mode '%c' in config: %s",
  c, plic->hart_config);
@@ -314,8 +316,9 @@ static void parse_hart_config(SiFivePLICState *plic)
 }
 if (modes) {
 addrid += ctpop8(modes);
+hartid++;
+modes = 0;
 }
-hartid++;
 
 plic->num_addrs = addrid;
 plic->num_harts = hartid;
@@ -326,11 +329,16 @@ static void parse_hart_config(SiFivePLICState *plic)
 p = plic->hart_config;
 while ((c = *p++)) {
 if (c == ',') {
-hartid++;
+if (modes) {
+hartid++;
+modes = 0;
+}
 } else {
+m = char_to_mode(c);
 plic->addr_config[addrid].addrid = addrid;
 plic->addr_config[addrid].hartid = hartid;
-plic->addr_config[addrid].mode = char_to_mode(c);
+plic->addr_config[addrid].mode = m;
+modes |= (1 << m);
 addrid++;
 }
 }
-- 
2.38.1




[PULL v2 03/45] hw/ssi/ibex_spi: implement `FIELD32_1CLEAR` macro

2022-12-21 Thread Alistair Francis
From: Wilfred Mallawa 

use the `FIELD32_1CLEAR` macro to implement register
`rw1c` functionality to `ibex_spi`.

This change was tested by running the `SPI_HOST` from TockOS.

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221017054950.317584-3-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 hw/ssi/ibex_spi_host.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c
index 57df462e3c..0a456cd1ed 100644
--- a/hw/ssi/ibex_spi_host.c
+++ b/hw/ssi/ibex_spi_host.c
@@ -342,7 +342,7 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
 {
 IbexSPIHostState *s = opaque;
 uint32_t val32 = val64;
-uint32_t shift_mask = 0xff, status = 0, data = 0;
+uint32_t shift_mask = 0xff, status = 0;
 uint8_t txqd_len;
 
 trace_ibex_spi_host_write(addr, size, val64);
@@ -355,12 +355,11 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
 case IBEX_SPI_HOST_INTR_STATE:
 /* rw1c status register */
 if (FIELD_EX32(val32, INTR_STATE, ERROR)) {
-data = FIELD_DP32(data, INTR_STATE, ERROR, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, ERROR);
 }
 if (FIELD_EX32(val32, INTR_STATE, SPI_EVENT)) {
-data = FIELD_DP32(data, INTR_STATE, SPI_EVENT, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, 
SPI_EVENT);
 }
-s->regs[addr] = data;
 break;
 case IBEX_SPI_HOST_INTR_ENABLE:
 s->regs[addr] = val32;
@@ -505,27 +504,25 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
  *  When an error occurs, the corresponding bit must be cleared
  *  here before issuing any further commands
  */
-status = s->regs[addr];
 /* rw1c status register */
 if (FIELD_EX32(val32, ERROR_STATUS, CMDBUSY)) {
-status = FIELD_DP32(status, ERROR_STATUS, CMDBUSY, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
CMDBUSY);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, OVERFLOW)) {
-status = FIELD_DP32(status, ERROR_STATUS, OVERFLOW, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
OVERFLOW);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, UNDERFLOW)) {
-status = FIELD_DP32(status, ERROR_STATUS, UNDERFLOW, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
UNDERFLOW);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, CMDINVAL)) {
-status = FIELD_DP32(status, ERROR_STATUS, CMDINVAL, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
CMDINVAL);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, CSIDINVAL)) {
-status = FIELD_DP32(status, ERROR_STATUS, CSIDINVAL, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
CSIDINVAL);
 }
 if (FIELD_EX32(val32, ERROR_STATUS, ACCESSINVAL)) {
-status = FIELD_DP32(status, ERROR_STATUS, ACCESSINVAL, 0);
+s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, 
ACCESSINVAL);
 }
-s->regs[addr] = status;
 break;
 case IBEX_SPI_HOST_EVENT_ENABLE:
 /* Controls which classes of SPI events raise an interrupt. */
-- 
2.38.1




[PULL v2 25/45] target/riscv: Fix mret exception cause when no pmp rule is configured

2022-12-21 Thread Alistair Francis
From: Bin Meng 

The priv spec v1.12 says:

  If no PMP entry matches an M-mode access, the access succeeds. If
  no PMP entry matches an S-mode or U-mode access, but at least one
  PMP entry is implemented, the access fails. Failed accesses generate
  an instruction, load, or store access-fault exception.

At present the exception cause is set to 'illegal instruction' but
should have been 'instruction access fault'.

Fixes: d102f19a2085 ("target/riscv/pmp: Raise exception if no PMP entry is 
configured")
Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221205065303.204095-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 09f1f5185d..d7af7f056b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -202,7 +202,7 @@ target_ulong helper_mret(CPURISCVState *env)
 
 if (riscv_feature(env, RISCV_FEATURE_PMP) &&
 !pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
-riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
 }
 
 target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
-- 
2.38.1




[PULL v2 32/45] hw/riscv: Fix opentitan dependency to SIFIVE_PLIC

2022-12-21 Thread Alistair Francis
From: Bin Meng 

Since commit ef6310064820 ("hw/riscv: opentitan: Update to the latest build")
the IBEX PLIC model was replaced with the SiFive PLIC model in the
'opentitan' machine but we forgot the add the dependency there.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-3-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 167dc4cca6..1e4b58024f 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -19,6 +19,7 @@ config MICROCHIP_PFSOC
 config OPENTITAN
 bool
 select IBEX
+select SIFIVE_PLIC
 select UNIMP
 
 config SHAKTI_C
-- 
2.38.1




[PULL v2 26/45] target/riscv: Set pc_succ_insn for !rvc illegal insn

2022-12-21 Thread Alistair Francis
From: Richard Henderson 

Failure to set pc_succ_insn may result in a TB covering zero bytes,
which triggers an assert within the code generator.

Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1224
Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221203175744.151365-1-richard.hender...@linaro.org>
[ Changes by AF:
 - Add missing run-plugin-test-noc-% line
]
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c  | 12 
 tests/tcg/Makefile.target |  2 ++
 tests/tcg/riscv64/Makefile.target |  6 ++
 tests/tcg/riscv64/test-noc.S  | 32 +++
 4 files changed, 44 insertions(+), 8 deletions(-)
 create mode 100644 tests/tcg/riscv64/test-noc.S

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index cd5eb25ee8..160aefc3df 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1096,14 +1096,10 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 ctx->virt_inst_excp = false;
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
-if (!has_ext(ctx, RVC)) {
-gen_exception_illegal(ctx);
-} else {
-ctx->opcode = opcode;
-ctx->pc_succ_insn = ctx->base.pc_next + 2;
-if (decode_insn16(ctx, opcode)) {
-return;
-}
+ctx->opcode = opcode;
+ctx->pc_succ_insn = ctx->base.pc_next + 2;
+if (has_ext(ctx, RVC) && decode_insn16(ctx, opcode)) {
+return;
 }
 } else {
 uint32_t opcode32 = opcode;
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
index 75257f2b29..14bc013181 100644
--- a/tests/tcg/Makefile.target
+++ b/tests/tcg/Makefile.target
@@ -117,6 +117,8 @@ endif
 
 %: %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+%: %.S
+   $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
 else
 # For softmmu targets we include a different Makefile fragement as the
 # build options for bare programs are usually pretty different. They
diff --git a/tests/tcg/riscv64/Makefile.target 
b/tests/tcg/riscv64/Makefile.target
index b5b89dfb0e..cc3ed65ffd 100644
--- a/tests/tcg/riscv64/Makefile.target
+++ b/tests/tcg/riscv64/Makefile.target
@@ -4,3 +4,9 @@
 VPATH += $(SRC_PATH)/tests/tcg/riscv64
 TESTS += test-div
 TESTS += noexec
+
+# Disable compressed instructions for test-noc
+TESTS += test-noc
+test-noc: LDFLAGS = -nostdlib -static
+run-test-noc: QEMU_OPTS += -cpu rv64,c=false
+run-plugin-test-noc-%: QEMU_OPTS += -cpu rv64,c=false
diff --git a/tests/tcg/riscv64/test-noc.S b/tests/tcg/riscv64/test-noc.S
new file mode 100644
index 00..e29d60c8b3
--- /dev/null
+++ b/tests/tcg/riscv64/test-noc.S
@@ -0,0 +1,32 @@
+#include 
+
+   .text
+   .globl _start
+_start:
+   .option norvc
+   li  a0, 4   /* SIGILL */
+   la  a1, sa
+   li  a2, 0
+   li  a3, 8
+   li  a7, __NR_rt_sigaction
+   scall
+
+   .option rvc
+   li  a0, 1
+   j   exit
+   .option norvc
+
+pass:
+   li  a0, 0
+exit:
+   li  a7, __NR_exit
+   scall
+
+   .data
+   /* struct kernel_sigaction sa = { .sa_handler = pass }; */
+   .type   sa, @object
+   .size   sa, 32
+sa:
+   .dword  pass
+   .zero   24
+
-- 
2.38.1




[PULL v2 09/45] target/riscv: Add smstateen support

2022-12-21 Thread Alistair Francis
From: Mayuresh Chitale 

Smstateen extension specifies a mechanism to close
the potential covert channels that could cause security issues.

This patch adds the CSRs defined in the specification and
the corresponding predicates and read/write functions.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20221016124726.102129-2-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  |   4 +
 target/riscv/cpu_bits.h |  37 +
 target/riscv/csr.c  | 316 
 target/riscv/machine.c  |  21 +++
 4 files changed, 378 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 443d15a47c..5cac0c5eec 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -366,6 +366,9 @@ struct CPUArchState {
 
 /* CSRs for execution enviornment configuration */
 uint64_t menvcfg;
+uint64_t mstateen[SMSTATEEN_MAX_COUNT];
+uint64_t hstateen[SMSTATEEN_MAX_COUNT];
+uint64_t sstateen[SMSTATEEN_MAX_COUNT];
 target_ulong senvcfg;
 uint64_t henvcfg;
 #endif
@@ -441,6 +444,7 @@ struct RISCVCPUConfig {
 bool ext_ifencei;
 bool ext_icsr;
 bool ext_zihintpause;
+bool ext_smstateen;
 bool ext_sstc;
 bool ext_svinval;
 bool ext_svnapot;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index d8f5f0abed..8b0d7e20ea 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -197,6 +197,12 @@
 /* Supervisor Configuration CSRs */
 #define CSR_SENVCFG 0x10A
 
+/* Supervisor state CSRs */
+#define CSR_SSTATEEN0   0x10C
+#define CSR_SSTATEEN1   0x10D
+#define CSR_SSTATEEN2   0x10E
+#define CSR_SSTATEEN3   0x10F
+
 /* Supervisor Trap Handling */
 #define CSR_SSCRATCH0x140
 #define CSR_SEPC0x141
@@ -244,6 +250,16 @@
 #define CSR_HENVCFG 0x60A
 #define CSR_HENVCFGH0x61A
 
+/* Hypervisor state CSRs */
+#define CSR_HSTATEEN0   0x60C
+#define CSR_HSTATEEN0H  0x61C
+#define CSR_HSTATEEN1   0x60D
+#define CSR_HSTATEEN1H  0x61D
+#define CSR_HSTATEEN2   0x60E
+#define CSR_HSTATEEN2H  0x61E
+#define CSR_HSTATEEN3   0x60F
+#define CSR_HSTATEEN3H  0x61F
+
 /* Virtual CSRs */
 #define CSR_VSSTATUS0x200
 #define CSR_VSIE0x204
@@ -289,6 +305,27 @@
 #define CSR_MENVCFG 0x30A
 #define CSR_MENVCFGH0x31A
 
+/* Machine state CSRs */
+#define CSR_MSTATEEN0   0x30C
+#define CSR_MSTATEEN0H  0x31C
+#define CSR_MSTATEEN1   0x30D
+#define CSR_MSTATEEN1H  0x31D
+#define CSR_MSTATEEN2   0x30E
+#define CSR_MSTATEEN2H  0x31E
+#define CSR_MSTATEEN3   0x30F
+#define CSR_MSTATEEN3H  0x31F
+
+/* Common defines for all smstateen */
+#define SMSTATEEN_MAX_COUNT 4
+#define SMSTATEEN0_CS   (1ULL << 0)
+#define SMSTATEEN0_FCSR (1ULL << 1)
+#define SMSTATEEN0_HSCONTXT (1ULL << 57)
+#define SMSTATEEN0_IMSIC(1ULL << 58)
+#define SMSTATEEN0_AIA  (1ULL << 59)
+#define SMSTATEEN0_SVSLCT   (1ULL << 60)
+#define SMSTATEEN0_HSENVCFG (1ULL << 62)
+#define SMSTATEEN_STATEEN   (1ULL << 63)
+
 /* Enhanced Physical Memory Protection (ePMP) */
 #define CSR_MSECCFG 0x747
 #define CSR_MSECCFGH0x757
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5c9a7ee287..c861424e85 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -283,6 +283,72 @@ static RISCVException umode32(CPURISCVState *env, int 
csrno)
 return umode(env, csrno);
 }
 
+static RISCVException mstateen(CPURISCVState *env, int csrno)
+{
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return any(env, csrno);
+}
+
+static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
+{
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (env->priv < PRV_M) {
+if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+
+return hmode(env, csrno);
+}
+
+static RISCVException hstateen(CPURISCVState *env, int csrno)
+{
+return hstateen_pred(env, csrno, CSR_HSTATEEN0);
+}
+
+static RISCVException hstateenh(CPURISCVState *env, int csrno)
+{
+return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
+}
+
+static RISCVException sstateen(CPURISCVState *env, int csrno)
+{
+bool virt = riscv_cpu_virt_enabled(env);
+int index = csrno - CSR_SSTATEEN0;
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (env->priv < PRV_M) {
+if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (virt) {
+if (!(env->hstateen[index] & 

[PULL v2 39/45] hw/riscv: microchip_pfsoc: Fix the number of interrupt sources of PLIC

2022-12-21 Thread Alistair Francis
From: Bin Meng 

Per chapter 6.5.2 in [1], the number of interupt sources including
interrupt source 0 should be 187.

[1] PolarFire SoC MSS TRM:
https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/ReferenceManuals/PolarFire_SoC_FPGA_MSS_Technical_Reference_Manual_VC.pdf

Fixes: 56f6e31e7b7e ("hw/riscv: Initial support for Microchip PolarFire SoC 
Icicle Kit board")
Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Reviewed-by: Conor Dooley 
Message-Id: <20221211030829.802437-10-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/microchip_pfsoc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index 69a686b54a..577efad0c4 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -153,7 +153,7 @@ enum {
 #define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT1
 #define MICROCHIP_PFSOC_COMPUTE_CPU_COUNT   4
 
-#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES185
+#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES187
 #define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
 #define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE  0x04
 #define MICROCHIP_PFSOC_PLIC_PENDING_BASE   0x1000
-- 
2.38.1




[PULL v2 38/45] hw/intc: sifive_plic: Update "num-sources" property default value

2022-12-21 Thread Alistair Francis
From: Bin Meng 

At present the default value of "num-sources" property is zero,
which does not make a lot of sense, as in sifive_plic_realize()
we see s->bitfield_words is calculated by:

  s->bitfield_words = (s->num_sources + 31) >> 5;

if the we don't configure "num-sources" property its default value
zero makes s->bitfield_words zero too, which isn't true because
interrupt source 0 still occupies one word.

Let's change the default value to 1 meaning that only interrupt
source 0 is supported by default and a sanity check in realize().

While we are here, add a comment to describe the exact meaning of
this property that the number should include interrupt source 0.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-9-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 9cb4c6d6d4..1edeb1e1ed 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -363,6 +363,11 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 
 parse_hart_config(s);
 
+if (!s->num_sources) {
+error_setg(errp, "plic: invalid number of interrupt sources");
+return;
+}
+
 s->bitfield_words = (s->num_sources + 31) >> 5;
 s->num_enables = s->bitfield_words * s->num_addrs;
 s->source_priority = g_new0(uint32_t, s->num_sources);
@@ -420,7 +425,8 @@ static const VMStateDescription vmstate_sifive_plic = {
 static Property sifive_plic_properties[] = {
 DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
 DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
-DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
+/* number of interrupt sources including interrupt source 0 */
+DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
 DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
 DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
 DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
-- 
2.38.1




[PULL v2 15/45] target/riscv: Add itrigger_enabled field to CPURISCVState

2022-12-21 Thread Alistair Francis
From: LIU Zhiwei 

Avoid calling riscv_itrigger_enabled() when calculate the tbflags.
As the itrigger enable status can only be changed when write
tdata1, migration load or itrigger fire, update env->itrigger_enabled
at these places.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221013062946.7530-5-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  1 +
 target/riscv/cpu_helper.c |  3 +--
 target/riscv/debug.c  |  3 +++
 target/riscv/machine.c| 15 +++
 4 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b0b4048de9..37f9516941 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -331,6 +331,7 @@ struct CPUArchState {
 struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
 QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
 int64_t last_icount;
+bool itrigger_enabled;
 
 /* machine specific rdtime callback */
 uint64_t (*rdtime_fn)(void *);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 6230f65f70..427d4d4386 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -106,8 +106,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
get_field(env->mstatus_hs, MSTATUS_VS));
 }
 if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
-flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
-   riscv_itrigger_enabled(env));
+flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
 }
 #endif
 
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index b3574b250f..bf4840a6a3 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -563,6 +563,7 @@ void helper_itrigger_match(CPURISCVState *env)
 }
 itrigger_set_count(env, i, count--);
 if (!count) {
+env->itrigger_enabled = riscv_itrigger_enabled(env);
 do_trigger_action(env, i);
 }
 }
@@ -660,6 +661,8 @@ static void itrigger_reg_write(CPURISCVState *env, 
target_ulong index,
 /* set the count to timer */
 timer_mod(env->itrigger_timer[index],
   env->last_icount + itrigger_get_count(env, index));
+} else {
+env->itrigger_enabled = riscv_itrigger_enabled(env);
 }
 }
 break;
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index e687f9fce0..65a8549ec2 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -21,6 +21,8 @@
 #include "qemu/error-report.h"
 #include "sysemu/kvm.h"
 #include "migration/cpu.h"
+#include "sysemu/cpu-timers.h"
+#include "debug.h"
 
 static bool pmp_needed(void *opaque)
 {
@@ -229,11 +231,24 @@ static bool debug_needed(void *opaque)
 return riscv_feature(env, RISCV_FEATURE_DEBUG);
 }
 
+static int debug_post_load(void *opaque, int version_id)
+{
+RISCVCPU *cpu = opaque;
+CPURISCVState *env = >env;
+
+if (icount_enabled()) {
+env->itrigger_enabled = riscv_itrigger_enabled(env);
+}
+
+return 0;
+}
+
 static const VMStateDescription vmstate_debug = {
 .name = "cpu/debug",
 .version_id = 2,
 .minimum_version_id = 2,
 .needed = debug_needed,
+.post_load = debug_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
 VMSTATE_UINTTL_ARRAY(env.tdata1, RISCVCPU, RV_MAX_TRIGGERS),
-- 
2.38.1




[PULL v2 35/45] hw/intc: sifive_plic: Drop PLICMode_H

2022-12-21 Thread Alistair Francis
From: Bin Meng 

H-mode has been removed since priv spec 1.10. Drop it.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-6-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/intc/sifive_plic.h | 1 -
 hw/intc/sifive_plic.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
index 134cf39a96..d3f45ec248 100644
--- a/include/hw/intc/sifive_plic.h
+++ b/include/hw/intc/sifive_plic.h
@@ -33,7 +33,6 @@ DECLARE_INSTANCE_CHECKER(SiFivePLICState, SIFIVE_PLIC,
 typedef enum PLICMode {
 PLICMode_U,
 PLICMode_S,
-PLICMode_H,
 PLICMode_M
 } PLICMode;
 
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 0c7696520d..936dcf74bc 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -42,7 +42,6 @@ static PLICMode char_to_mode(char c)
 switch (c) {
 case 'U': return PLICMode_U;
 case 'S': return PLICMode_S;
-case 'H': return PLICMode_H;
 case 'M': return PLICMode_M;
 default:
 error_report("plic: invalid mode '%c'", c);
-- 
2.38.1




[PULL v2 12/45] target/riscv: Add itrigger support when icount is not enabled

2022-12-21 Thread Alistair Francis
From: LIU Zhiwei 

When icount is not enabled, there is no API in QEMU that can get the
guest instruction number.

Translate the guest code in a way that each TB only has one instruction.
After executing the instruction, decrease the count by 1 until it reaches 0
where the itrigger fires.

Note that only when priviledge matches the itrigger configuration,
the count will decrease.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221013062946.7530-2-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  2 +
 target/riscv/debug.h  | 12 
 target/riscv/helper.h |  2 +
 target/riscv/cpu_helper.c |  6 ++
 target/riscv/debug.c  | 71 +++
 target/riscv/translate.c  | 33 -
 .../riscv/insn_trans/trans_privileged.c.inc   |  4 +-
 target/riscv/insn_trans/trans_rvi.c.inc   |  8 +--
 target/riscv/insn_trans/trans_rvv.c.inc   |  4 +-
 9 files changed, 131 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5cac0c5eec..c32e484c0b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -625,6 +625,8 @@ FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
 FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
 FIELD(TB_FLAGS, VTA, 24, 1)
 FIELD(TB_FLAGS, VMA, 25, 1)
+/* Native debug itrigger */
+FIELD(TB_FLAGS, ITRIGGER, 26, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index a1226b4d29..cc3358e69b 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -118,6 +118,17 @@ enum {
 SIZE_NUM = 16
 };
 
+/* itrigger filed masks */
+#define ITRIGGER_ACTION   0x3f
+#define ITRIGGER_UBIT(6)
+#define ITRIGGER_SBIT(7)
+#define ITRIGGER_PENDING  BIT(8)
+#define ITRIGGER_MBIT(9)
+#define ITRIGGER_COUNT(0x3fff << 10)
+#define ITRIGGER_HIT  BIT(24)
+#define ITRIGGER_VU   BIT(25)
+#define ITRIGGER_VS   BIT(26)
+
 bool tdata_available(CPURISCVState *env, int tdata_index);
 
 target_ulong tselect_csr_read(CPURISCVState *env);
@@ -134,4 +145,5 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp);
 
 void riscv_trigger_init(CPURISCVState *env);
 
+bool riscv_itrigger_enabled(CPURISCVState *env);
 #endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a03014fe67..227c7122ef 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -109,6 +109,8 @@ DEF_HELPER_1(sret, tl, env)
 DEF_HELPER_1(mret, tl, env)
 DEF_HELPER_1(wfi, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
+/* Native Debug */
+DEF_HELPER_1(itrigger_match, void, env)
 #endif
 
 /* Hypervisor functions */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 5d66246c2c..9d1d1bf9f1 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -27,7 +27,9 @@
 #include "tcg/tcg-op.h"
 #include "trace.h"
 #include "semihosting/common-semi.h"
+#include "sysemu/cpu-timers.h"
 #include "cpu_bits.h"
+#include "debug.h"
 
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 {
@@ -103,6 +105,10 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
get_field(env->mstatus_hs, MSTATUS_VS));
 }
+if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
+flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
+   riscv_itrigger_enabled(env));
+}
 #endif
 
 flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index e44848d0d7..036161649f 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -29,6 +29,7 @@
 #include "cpu.h"
 #include "trace.h"
 #include "exec/exec-all.h"
+#include "exec/helper-proto.h"
 
 /*
  * The following M-mode trigger CSRs are implemented:
@@ -496,6 +497,76 @@ static void type6_reg_write(CPURISCVState *env, 
target_ulong index,
 return;
 }
 
+/* icount trigger type */
+static inline int
+itrigger_get_count(CPURISCVState *env, int index)
+{
+return get_field(env->tdata1[index], ITRIGGER_COUNT);
+}
+
+static inline void
+itrigger_set_count(CPURISCVState *env, int index, int value)
+{
+env->tdata1[index] = set_field(env->tdata1[index],
+   ITRIGGER_COUNT, value);
+}
+
+static bool check_itrigger_priv(CPURISCVState *env, int index)
+{
+target_ulong tdata1 = env->tdata1[index];
+if (riscv_cpu_virt_enabled(env)) {
+/* check VU/VS bit against current privilege level */
+return (get_field(tdata1, ITRIGGER_VS) == env->priv) ||
+   (get_field(tdata1, ITRIGGER_VU) == env->priv);
+} else {
+/* check U/S/M bit against current privilege level */
+return 

[PATCH 1/4] Hexagon (target/hexagon) Add overrides for jumpr31 instructions

2022-12-21 Thread Taylor Simpson
Add overrides for
SL2_jumpr31Unconditional
SL2_jumpr31_t  Predicated true (old value)
SL2_jumpr31_f  Predicated false (old value)
SL2_jumpr31_tnew   Predicated true (new value)
SL2_jumpr31_fnew   Predicated false (new value)

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h | 13 +
 target/hexagon/genptr.c  |  8 
 2 files changed, 21 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 19697b42a5..3ee530f5d9 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -1015,6 +1015,19 @@
 #define fGEN_TCG_S2_asl_r_r_sat(SHORTCODE) \
 gen_asl_r_r_sat(RdV, RsV, RtV)
 
+#define fGEN_TCG_SL2_jumpr31(SHORTCODE) \
+gen_jumpr(ctx, hex_gpr[HEX_REG_LR])
+
+#define fGEN_TCG_SL2_jumpr31_t(SHORTCODE) \
+gen_cond_jumpr31(ctx, TCG_COND_EQ, hex_pred[0])
+#define fGEN_TCG_SL2_jumpr31_f(SHORTCODE) \
+gen_cond_jumpr31(ctx, TCG_COND_NE, hex_pred[0])
+
+#define fGEN_TCG_SL2_jumpr31_tnew(SHORTCODE) \
+gen_cond_jumpr31(ctx, TCG_COND_EQ, hex_new_pred_value[0])
+#define fGEN_TCG_SL2_jumpr31_fnew(SHORTCODE) \
+gen_cond_jumpr31(ctx, TCG_COND_NE, hex_new_pred_value[0])
+
 /* Floating point */
 #define fGEN_TCG_F2_conv_sf2df(SHORTCODE) \
 gen_helper_conv_sf2df(RddV, cpu_env, RsV)
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 6cf2e0ed43..ee67cb0069 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -553,6 +553,14 @@ static void gen_cond_jumpr(DisasContext *ctx, TCGv dst_pc,
 gen_write_new_pc_addr(ctx, dst_pc, cond, pred);
 }
 
+static void gen_cond_jumpr31(DisasContext *ctx, TCGCond cond, TCGv pred)
+{
+TCGv LSB = tcg_temp_new();
+tcg_gen_andi_tl(LSB, pred, 1);
+gen_cond_jumpr(ctx, hex_gpr[HEX_REG_LR], cond, LSB);
+tcg_temp_free(LSB);
+}
+
 static void gen_cond_jump(DisasContext *ctx, TCGCond cond, TCGv pred,
   int pc_off)
 {
-- 
2.17.1



[PATCH 2/4] Hexagon (target/hexagon) Add overrides for callr

2022-12-21 Thread Taylor Simpson
Add overrides for
J2_callr
J2_callrt
J2_callrf

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h |  6 ++
 target/hexagon/macros.h  | 10 --
 target/hexagon/genptr.c  | 20 
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 3ee530f5d9..231654e6c1 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -614,11 +614,17 @@
 
 #define fGEN_TCG_J2_call(SHORTCODE) \
 gen_call(ctx, riV)
+#define fGEN_TCG_J2_callr(SHORTCODE) \
+gen_callr(ctx, RsV)
 
 #define fGEN_TCG_J2_callt(SHORTCODE) \
 gen_cond_call(ctx, PuV, TCG_COND_EQ, riV)
 #define fGEN_TCG_J2_callf(SHORTCODE) \
 gen_cond_call(ctx, PuV, TCG_COND_NE, riV)
+#define fGEN_TCG_J2_callrt(SHORTCODE) \
+gen_cond_callr(ctx, TCG_COND_EQ, PuV, RsV)
+#define fGEN_TCG_J2_callrf(SHORTCODE) \
+gen_cond_callr(ctx, TCG_COND_NE, PuV, RsV)
 
 #define fGEN_TCG_J2_endloop0(SHORTCODE) \
 gen_endloop0(ctx)
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index cd64bb8eec..f6cc0e950c 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -421,16 +421,6 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, 
int shift)
 #define fBRANCH(LOC, TYPE)  fWRITE_NPC(LOC)
 #define fJUMPR(REGNO, TARGET, TYPE) fBRANCH(TARGET, COF_TYPE_JUMPR)
 #define fHINTJR(TARGET) { /* Not modelled in qemu */}
-#define fCALL(A) \
-do { \
-fWRITE_LR(fREAD_NPC()); \
-fBRANCH(A, COF_TYPE_CALL); \
-} while (0)
-#define fCALLR(A) \
-do { \
-fWRITE_LR(fREAD_NPC()); \
-fBRANCH(A, COF_TYPE_CALLR); \
-} while (0)
 #define fWRITE_LOOP_REGS0(START, COUNT) \
 do { \
 WRITE_RREG(HEX_REG_LC0, COUNT);  \
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index ee67cb0069..9e31f3418b 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -670,6 +670,14 @@ static void gen_call(DisasContext *ctx, int pc_off)
 gen_write_new_pc_pcrel(ctx, pc_off, TCG_COND_ALWAYS, NULL);
 }
 
+static void gen_callr(DisasContext *ctx, TCGv new_pc)
+{
+TCGv next_PC =
+tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes);
+gen_log_reg_write(HEX_REG_LR, next_PC);
+gen_write_new_pc_addr(ctx, new_pc, TCG_COND_ALWAYS, NULL);
+}
+
 static void gen_cond_call(DisasContext *ctx, TCGv pred,
   TCGCond cond, int pc_off)
 {
@@ -686,6 +694,18 @@ static void gen_cond_call(DisasContext *ctx, TCGv pred,
 gen_set_label(skip);
 }
 
+static void gen_cond_callr(DisasContext *ctx,
+   TCGCond cond, TCGv pred, TCGv new_pc)
+{
+TCGv lsb = tcg_temp_new();
+TCGLabel *skip = gen_new_label();
+tcg_gen_andi_tl(lsb, pred, 1);
+tcg_gen_brcondi_tl(cond, lsb, 0, skip);
+tcg_temp_free(lsb);
+gen_callr(ctx, new_pc);
+gen_set_label(skip);
+}
+
 static void gen_endloop0(DisasContext *ctx)
 {
 TCGv lpcfg = tcg_temp_local_new();
-- 
2.17.1



[PULL v2 44/45] hw/riscv: opentitan: Drop "hartid-base" and "priority-base" initialization

2022-12-21 Thread Alistair Francis
From: Bin Meng 

"hartid-base" and "priority-base" are zero by default. There is no
need to initialize them to zero again.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-15-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/opentitan.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 78f895d773..85ffdac5be 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -173,10 +173,8 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 
 /* PLIC */
 qdev_prop_set_string(DEVICE(>plic), "hart-config", "M");
-qdev_prop_set_uint32(DEVICE(>plic), "hartid-base", 0);
 qdev_prop_set_uint32(DEVICE(>plic), "num-sources", 180);
 qdev_prop_set_uint32(DEVICE(>plic), "num-priorities", 3);
-qdev_prop_set_uint32(DEVICE(>plic), "priority-base", 0x00);
 qdev_prop_set_uint32(DEVICE(>plic), "pending-base", 0x1000);
 qdev_prop_set_uint32(DEVICE(>plic), "enable-base", 0x2000);
 qdev_prop_set_uint32(DEVICE(>plic), "enable-stride", 32);
-- 
2.38.1




[PULL v2 37/45] hw/intc: sifive_plic: Use error_setg() to propagate the error up via errp in sifive_plic_realize()

2022-12-21 Thread Alistair Francis
From: Bin Meng 

The realize() callback has an errp for us to propagate the error up.
While we are here, correct the wrong multi-line comment format.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221211030829.802437-8-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index c9af94a888..9cb4c6d6d4 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -379,7 +379,8 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
 qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
 
-/* We can't allow the supervisor to control SEIP as this would allow the
+/*
+ * We can't allow the supervisor to control SEIP as this would allow the
  * supervisor to clear a pending external interrupt which will result in
  * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
  * hardware controlled when a PLIC is attached.
@@ -387,8 +388,8 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 for (i = 0; i < s->num_harts; i++) {
 RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
 if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
-error_report("SEIP already claimed");
-exit(1);
+error_setg(errp, "SEIP already claimed");
+return;
 }
 }
 
-- 
2.38.1




[PATCH 4/4] Hexagon (target/hexagon) Add overrides for dealloc-return instructions

2022-12-21 Thread Taylor Simpson
These instructions perform a deallocframe+return (jumpr r31)

Add overrides for
L4_return
SL2_return
L4_return_t
L4_return_f
L4_return_tnew_pt
L4_return_fnew_pt
L4_return_tnew_pnt
L4_return_fnew_pnt
SL2_return_t
SL2_return_f
SL2_return_tnew
SL2_return_fnew

This patch eliminates the last helper that uses write_new_pc, so we
remove it from op_helper.c

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h   | 54 
 target/hexagon/genptr.c| 86 ++
 target/hexagon/op_helper.c | 24 ---
 3 files changed, 140 insertions(+), 24 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 1ac23b75a0..b54036655a 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -508,6 +508,60 @@
 #define fGEN_TCG_S2_storerinew_pcr(SHORTCODE) \
 fGEN_TCG_STORE_pcr(2, fSTORE(1, 4, EA, NtN))
 
+/*
+ * dealloc_return
+ * Assembler mapped to
+ * r31:30 = dealloc_return(r30):raw
+ */
+#define fGEN_TCG_L4_return(SHORTCODE) \
+gen_return(ctx, RddV, RsV)
+
+/*
+ * sub-instruction version (no RddV, so handle it manually)
+ */
+#define fGEN_TCG_SL2_return(SHORTCODE) \
+do { \
+TCGv_i64 RddV = tcg_temp_new_i64(); \
+gen_return(ctx, RddV, hex_gpr[HEX_REG_FP]); \
+gen_log_reg_write_pair(HEX_REG_FP, RddV); \
+tcg_temp_free_i64(RddV); \
+} while (0)
+
+/*
+ * Conditional returns follow this naming convention
+ * _t predicate true
+ * _f predicate false
+ * _tnew_pt   predicate.new true predict taken
+ * _fnew_pt   predicate.new false predict taken
+ * _tnew_pnt  predicate.new true predict not taken
+ * _fnew_pnt  predicate.new false predict not taken
+ * Predictions are not modelled in QEMU
+ *
+ * Example:
+ * if (p1) r31:30 = dealloc_return(r30):raw
+ */
+#define fGEN_TCG_L4_return_t(SHORTCODE) \
+gen_cond_return(ctx, RddV, RsV, PvV, TCG_COND_EQ);
+#define fGEN_TCG_L4_return_f(SHORTCODE) \
+gen_cond_return(ctx, RddV, RsV, PvV, TCG_COND_NE)
+#define fGEN_TCG_L4_return_tnew_pt(SHORTCODE) \
+gen_cond_return(ctx, RddV, RsV, PvN, TCG_COND_EQ)
+#define fGEN_TCG_L4_return_fnew_pt(SHORTCODE) \
+gen_cond_return(ctx, RddV, RsV, PvN, TCG_COND_NE)
+#define fGEN_TCG_L4_return_tnew_pnt(SHORTCODE) \
+gen_cond_return(ctx, RddV, RsV, PvN, TCG_COND_EQ)
+#define fGEN_TCG_L4_return_fnew_pnt(SHORTCODE) \
+gen_cond_return(ctx, RddV, RsV, PvN, TCG_COND_NE)
+
+#define fGEN_TCG_SL2_return_t(SHORTCODE) \
+gen_cond_return_subinsn(ctx, TCG_COND_EQ, hex_pred[0])
+#define fGEN_TCG_SL2_return_f(SHORTCODE) \
+gen_cond_return_subinsn(ctx, TCG_COND_NE, hex_pred[0])
+#define fGEN_TCG_SL2_return_tnew(SHORTCODE) \
+gen_cond_return_subinsn(ctx, TCG_COND_EQ, hex_new_pred_value[0])
+#define fGEN_TCG_SL2_return_fnew(SHORTCODE) \
+gen_cond_return_subinsn(ctx, TCG_COND_NE, hex_new_pred_value[0])
+
 /*
  * Mathematical operations with more than one definition require
  * special handling
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 0eef2a2068..1544d181f1 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -706,6 +706,92 @@ static void gen_cond_callr(DisasContext *ctx,
 gen_set_label(skip);
 }
 
+/* frame ^= (int64_t)FRAMEKEY << 32 */
+static void gen_frame_unscramble(TCGv_i64 frame)
+{
+TCGv_i64 framekey = tcg_temp_new_i64();
+tcg_gen_extu_i32_i64(framekey, hex_gpr[HEX_REG_FRAMEKEY]);
+tcg_gen_shli_i64(framekey, framekey, 32);
+tcg_gen_xor_i64(frame, frame, framekey);
+tcg_temp_free_i64(framekey);
+}
+
+static void gen_load_frame(DisasContext *ctx, TCGv_i64 frame, TCGv EA)
+{
+Insn *insn = ctx->insn;  /* Needed for CHECK_NOSHUF */
+CHECK_NOSHUF(EA, 8);
+tcg_gen_qemu_ld64(frame, EA, ctx->mem_idx);
+}
+
+static void gen_return_base(DisasContext *ctx, TCGv_i64 dst, TCGv src,
+TCGv r29)
+{
+/*
+ * frame = *src
+ * dst = frame_unscramble(frame)
+ * SP = src + 8
+ * PC = dst.w[1]
+ */
+TCGv_i64 frame = tcg_temp_new_i64();
+TCGv r31 = tcg_temp_new();
+
+gen_load_frame(ctx, frame, src);
+gen_frame_unscramble(frame);
+tcg_gen_mov_i64(dst, frame);
+tcg_gen_addi_tl(r29, src, 8);
+tcg_gen_extrh_i64_i32(r31, dst);
+gen_jumpr(ctx, r31);
+
+tcg_temp_free_i64(frame);
+tcg_temp_free(r31);
+}
+
+static void gen_return(DisasContext *ctx, TCGv_i64 dst, TCGv src)
+{
+TCGv r29 = tcg_temp_new();
+gen_return_base(ctx, dst, src, r29);
+gen_log_reg_write(HEX_REG_SP, r29);
+tcg_temp_free(r29);
+}
+
+/* if (pred) dst = dealloc_return(src):raw */
+static void gen_cond_return(DisasContext *ctx, TCGv_i64 dst, TCGv src,
+TCGv pred, TCGCond cond)
+{
+TCGv LSB = tcg_temp_new();
+TCGv mask = tcg_temp_new();
+TCGv r29 = tcg_temp_local_new();
+TCGLabel 

[PULL v2 31/45] hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers

2022-12-21 Thread Alistair Francis
From: Bin Meng 

hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
controllers regardless of how MSI is implemented. msi_nonbroken is
initialized to true in both riscv_aplic_realize() and
riscv_imsic_realize().

Select MSI_NONBROKEN in RISCV_APLIC and RISCV_IMSIC.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221211030829.802437-2-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 1d4573e803..21441d0a0c 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -72,9 +72,11 @@ config RISCV_ACLINT
 
 config RISCV_APLIC
 bool
+select MSI_NONBROKEN
 
 config RISCV_IMSIC
 bool
+select MSI_NONBROKEN
 
 config SIFIVE_PLIC
 bool
-- 
2.38.1




[PULL v2 13/45] target/riscv: Add itrigger support when icount is enabled

2022-12-21 Thread Alistair Francis
From: LIU Zhiwei 

The max count in itrigger can be 0x3FFF, which will cause a no trivial
translation and execution overload.

When icount is enabled, QEMU provides API that can fetch guest
instruction number. Thus, we can set an timer for itrigger with
the count as deadline.

Only when timer expires or priviledge mode changes, do lazy update
to count.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221013062946.7530-3-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  2 ++
 target/riscv/debug.h  |  1 +
 target/riscv/cpu_helper.c |  3 ++
 target/riscv/debug.c  | 59 +++
 4 files changed, 65 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c32e484c0b..b0b4048de9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -329,6 +329,8 @@ struct CPUArchState {
 target_ulong tdata3[RV_MAX_TRIGGERS];
 struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
 struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
+QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
+int64_t last_icount;
 
 /* machine specific rdtime callback */
 uint64_t (*rdtime_fn)(void *);
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index cc3358e69b..c471748d5a 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -146,4 +146,5 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp);
 void riscv_trigger_init(CPURISCVState *env);
 
 bool riscv_itrigger_enabled(CPURISCVState *env);
+void riscv_itrigger_update_priv(CPURISCVState *env);
 #endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9d1d1bf9f1..6230f65f70 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -676,6 +676,9 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
 if (newpriv == PRV_H) {
 newpriv = PRV_U;
 }
+if (icount_enabled() && newpriv != env->priv) {
+riscv_itrigger_update_priv(env);
+}
 /* tlb_flush is unnecessary as mode is contained in mmu_idx */
 env->priv = newpriv;
 env->xl = cpu_recompute_xl(env);
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 036161649f..371862cf38 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -30,6 +30,7 @@
 #include "trace.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
+#include "sysemu/cpu-timers.h"
 
 /*
  * The following M-mode trigger CSRs are implemented:
@@ -567,6 +568,62 @@ void helper_itrigger_match(CPURISCVState *env)
 }
 }
 
+static void riscv_itrigger_update_count(CPURISCVState *env)
+{
+int count, executed;
+/*
+ * Record last icount, so that we can evaluate the executed instructions
+ * since last priviledge mode change or timer expire.
+ */
+int64_t last_icount = env->last_icount, current_icount;
+current_icount = env->last_icount = icount_get_raw();
+
+for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
+if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
+continue;
+}
+count = itrigger_get_count(env, i);
+if (!count) {
+continue;
+}
+/*
+ * Only when priviledge is changed or itrigger timer expires,
+ * the count field in itrigger tdata1 register is updated.
+ * And the count field in itrigger only contains remaining value.
+ */
+if (check_itrigger_priv(env, i)) {
+/*
+ * If itrigger enabled in this priviledge mode, the number of
+ * executed instructions since last priviledge change
+ * should be reduced from current itrigger count.
+ */
+executed = current_icount - last_icount;
+itrigger_set_count(env, i, count - executed);
+if (count == executed) {
+do_trigger_action(env, i);
+}
+} else {
+/*
+ * If itrigger is not enabled in this priviledge mode,
+ * the number of executed instructions will be discard and
+ * the count field in itrigger will not change.
+ */
+timer_mod(env->itrigger_timer[i],
+  current_icount + count);
+}
+}
+}
+
+static void riscv_itrigger_timer_cb(void *opaque)
+{
+riscv_itrigger_update_count((CPURISCVState *)opaque);
+}
+
+void riscv_itrigger_update_priv(CPURISCVState *env)
+{
+riscv_itrigger_update_count(env);
+}
+
 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
 {
 switch (tdata_index) {
@@ -796,5 +853,7 @@ void riscv_trigger_init(CPURISCVState *env)
 env->tdata3[i] = 0;
 env->cpu_breakpoint[i] = NULL;
 env->cpu_watchpoint[i] = NULL;
+env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+  riscv_itrigger_timer_cb, env);
 }
 }
-- 
2.38.1




[PULL v2 42/45] hw/riscv: virt: Fix the value of "riscv, ndev" in the dtb

2022-12-21 Thread Alistair Francis
From: Bin Meng 

Commit 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt 
machine")
changed the value of VIRT_IRQCHIP_NUM_SOURCES from 127 to 53, which
is VIRTIO_NDEV and also used as the value of "riscv,ndev" property
in the dtb. Unfortunately this is wrong as VIRT_IRQCHIP_NUM_SOURCES
should include interrupt source 0 but "riscv,ndev" does not.

While we are here, we also fix the comments of platform bus irq range
which is now "64 to 96", but should be "64 to 95", introduced since
commit 1832b7cb3f64 ("hw/riscv: virt: Create a platform bus").

Fixes: 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt 
machine")
Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-13-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/virt.h | 5 ++---
 hw/riscv/virt.c | 3 ++-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 62513e075c..e1ce0048af 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -87,14 +87,13 @@ enum {
 VIRTIO_IRQ = 1, /* 1 to 8 */
 VIRTIO_COUNT = 8,
 PCIE_IRQ = 0x20, /* 32 to 35 */
-VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 96 */
-VIRTIO_NDEV = 96 /* Arbitrary maximum number of interrupts */
+VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */
 };
 
 #define VIRT_PLATFORM_BUS_NUM_IRQS 32
 
 #define VIRT_IRQCHIP_NUM_MSIS 255
-#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
+#define VIRT_IRQCHIP_NUM_SOURCES 96
 #define VIRT_IRQCHIP_NUM_PRIO_BITS 3
 #define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
 #define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 6cf9355b99..94ff2a1584 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -468,7 +468,8 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
 plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg",
 0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
-qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev", VIRTIO_NDEV);
+qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
+  VIRT_IRQCHIP_NUM_SOURCES - 1);
 riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket);
 qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
 plic_phandles[socket]);
-- 
2.38.1




[PULL v2 10/45] target/riscv: smstateen check for h/s/envcfg

2022-12-21 Thread Alistair Francis
From: Mayuresh Chitale 

Accesses to henvcfg, henvcfgh and senvcfg are allowed only if the corresponding
bit in mstateen0/hstateen0 is enabled. Otherwise an illegal instruction trap is
generated.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Weiwei Li
Reviewed-by: Alistair Francis 
Message-Id: <20221016124726.102129-3-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 87 ++
 1 file changed, 80 insertions(+), 7 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c861424e85..71236f2b5d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -41,6 +41,42 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 }
 
 /* Predicates */
+#if !defined(CONFIG_USER_ONLY)
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
+   uint64_t bit)
+{
+bool virt = riscv_cpu_virt_enabled(env);
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_NONE;
+}
+
+if (!(env->mstateen[index] & bit)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (virt) {
+if (!(env->hstateen[index] & bit)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+
+if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+}
+
+if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
+if (!(env->sstateen[index] & bit)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+
+return RISCV_EXCP_NONE;
+}
+#endif
+
 static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -1874,6 +1910,13 @@ static RISCVException write_menvcfgh(CPURISCVState *env, 
int csrno,
 static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->senvcfg;
 return RISCV_EXCP_NONE;
 }
@@ -1882,15 +1925,27 @@ static RISCVException write_senvcfg(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
+RISCVException ret;
 
-env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
+env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
 return RISCV_EXCP_NONE;
 }
 
 static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->henvcfg;
 return RISCV_EXCP_NONE;
 }
@@ -1899,6 +1954,12 @@ static RISCVException write_henvcfg(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
 if (riscv_cpu_mxl(env) == MXL_RV64) {
 mask |= HENVCFG_PBMTE | HENVCFG_STCE;
@@ -1912,6 +1973,13 @@ static RISCVException write_henvcfg(CPURISCVState *env, 
int csrno,
 static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->henvcfg >> 32;
 return RISCV_EXCP_NONE;
 }
@@ -1921,9 +1989,14 @@ static RISCVException write_henvcfgh(CPURISCVState *env, 
int csrno,
 {
 uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
 uint64_t valh = (uint64_t)val << 32;
+RISCVException ret;
 
-env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
+ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
+env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
 return RISCV_EXCP_NONE;
 }
 
@@ -1949,7 +2022,7 @@ static RISCVException write_mstateen(CPURISCVState *env, 
int csrno,
 static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
   target_ulong new_val)
 {
-uint64_t wr_mask = SMSTATEEN_STATEEN;
+uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
 
 return write_mstateen(env, csrno, wr_mask, new_val);
 }
@@ -1984,7 +2057,7 @@ static RISCVException write_mstateenh(CPURISCVState *env, 
int csrno,
 static RISCVException 

[PULL v2 27/45] target/riscv: Simplify helper_sret() a little bit

2022-12-21 Thread Alistair Francis
From: Bin Meng 

There are 2 paths in helper_sret() and the same mstatus update codes
are replicated. Extract the common parts to simplify it a little bit.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221207090037.281452-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index d7af7f056b..a047d38152 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -149,21 +149,21 @@ target_ulong helper_sret(CPURISCVState *env)
 }
 
 mstatus = env->mstatus;
+prev_priv = get_field(mstatus, MSTATUS_SPP);
+mstatus = set_field(mstatus, MSTATUS_SIE,
+get_field(mstatus, MSTATUS_SPIE));
+mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
+mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+env->mstatus = mstatus;
 
 if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
 /* We support Hypervisor extensions and virtulisation is disabled */
 target_ulong hstatus = env->hstatus;
 
-prev_priv = get_field(mstatus, MSTATUS_SPP);
 prev_virt = get_field(hstatus, HSTATUS_SPV);
 
 hstatus = set_field(hstatus, HSTATUS_SPV, 0);
-mstatus = set_field(mstatus, MSTATUS_SPP, 0);
-mstatus = set_field(mstatus, SSTATUS_SIE,
-get_field(mstatus, SSTATUS_SPIE));
-mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
 
-env->mstatus = mstatus;
 env->hstatus = hstatus;
 
 if (prev_virt) {
@@ -171,14 +171,6 @@ target_ulong helper_sret(CPURISCVState *env)
 }
 
 riscv_cpu_set_virt_enabled(env, prev_virt);
-} else {
-prev_priv = get_field(mstatus, MSTATUS_SPP);
-
-mstatus = set_field(mstatus, MSTATUS_SIE,
-get_field(mstatus, MSTATUS_SPIE));
-mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
-mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
-env->mstatus = mstatus;
 }
 
 riscv_cpu_set_mode(env, prev_priv);
-- 
2.38.1




[PULL v2 08/45] hw/riscv/opentitan: add aon_timer base unimpl

2022-12-21 Thread Alistair Francis
From: Wilfred Mallawa 

Adds the updated `aon_timer` base as an unimplemented device. This is
used by TockOS, patch ensures the guest doesn't hit load faults.

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221025043335.339815-3-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h | 1 +
 hw/riscv/opentitan.c | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 1fc055cdff..7659d1bc5b 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -81,6 +81,7 @@ enum {
 IBEX_DEV_RSTMGR,
 IBEX_DEV_CLKMGR,
 IBEX_DEV_PINMUX,
+IBEX_DEV_AON_TIMER,
 IBEX_DEV_USBDEV,
 IBEX_DEV_FLASH_CTRL,
 IBEX_DEV_PLIC,
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 92493c629d..78f895d773 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -56,6 +56,7 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_RSTMGR] = {  0x4041,  0x1000  },
 [IBEX_DEV_CLKMGR] = {  0x4042,  0x1000  },
 [IBEX_DEV_PINMUX] = {  0x4046,  0x1000  },
+[IBEX_DEV_AON_TIMER] =  {  0x4047,  0x1000  },
 [IBEX_DEV_SENSOR_CTRL] ={  0x4049,  0x1000  },
 [IBEX_DEV_FLASH_CTRL] = {  0x4100,  0x1000  },
 [IBEX_DEV_AES] ={  0x4110,  0x1000  },
@@ -272,6 +273,8 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
 create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
 memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
+create_unimplemented_device("riscv.lowrisc.ibex.aon_timer",
+memmap[IBEX_DEV_AON_TIMER].base, memmap[IBEX_DEV_AON_TIMER].size);
 create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
 memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
 create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
-- 
2.38.1




[PULL v2 40/45] hw/riscv: sifive_e: Fix the number of interrupt sources of PLIC

2022-12-21 Thread Alistair Francis
From: Bin Meng 

Per chapter 10 in Freedom E310 manuals [1][2][3], E310 G002 and G003
supports 52 interrupt sources while G000 supports 51 interrupt sources.

We use the value of G002 and G003, so it is 53 (including source 0).

[1] G000 manual:
https://sifive.cdn.prismic.io/sifive/4faf3e34-4a42-4c2f-be9e-c77baa4928c7_fe310-g000-manual-v3p2.pdf

[2] G002 manual:
https://sifive.cdn.prismic.io/sifive/034760b5-ac6a-4b1c-911c-f4148bb2c4a5_fe310-g002-v1p5.pdf

[3] G003 manual:
https://sifive.cdn.prismic.io/sifive/3af39c59-6498-471e-9dab-5355a0d539eb_fe310-g003-manual.pdf

Fixes: eb637edb1241 ("SiFive Freedom E Series RISC-V Machine")
Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-11-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/sifive_e.h | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index d738745925..9e58247fd8 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -82,7 +82,12 @@ enum {
 };
 
 #define SIFIVE_E_PLIC_HART_CONFIG "M"
-#define SIFIVE_E_PLIC_NUM_SOURCES 127
+/*
+ * Freedom E310 G002 and G003 supports 52 interrupt sources while
+ * Freedom E310 G000 supports 51 interrupt sources. We use the value
+ * of G002 and G003, so it is 53 (including interrupt source 0).
+ */
+#define SIFIVE_E_PLIC_NUM_SOURCES 53
 #define SIFIVE_E_PLIC_NUM_PRIORITIES 7
 #define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
 #define SIFIVE_E_PLIC_PENDING_BASE 0x1000
-- 
2.38.1




[PULL v2 29/45] RISC-V: Add Zawrs ISA extension support

2022-12-21 Thread Alistair Francis
From: Christoph Muellner 

This patch adds support for the Zawrs ISA extension.
Given the current (incomplete) implementation of reservation sets
there seems to be no way to provide a full emulation of the WRS
instruction (wake on reservation set invalidation or timeout or
interrupt). Therefore, we just exit the TB and return to the main loop.

The specification can be found here:
  https://github.com/riscv/riscv-zawrs/blob/main/zawrs.adoc

Note, that the Zawrs extension is frozen, but not ratified yet.

Changes since v3:
* Remove "RFC" since the extension is frozen
* Rebase on master and fix integration issues
* Fix entry ordering in extension list

Changes since v2:
* Rebase on master and resolve conflicts
* Adjustments according to a specification change
* Inline REQUIRE_ZAWRS() since it has only one user

Changes since v1:
* Adding zawrs to the ISA string that is passed to the kernel

Signed-off-by: Christoph Müllner 
Reviewed-by: Alistair Francis 
Message-Id: <20221005144948.3421504-1-christoph.muell...@vrull.eu>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  |  1 +
 target/riscv/insn32.decode  |  4 ++
 target/riscv/cpu.c  |  7 +++
 target/riscv/translate.c|  1 +
 target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 +
 5 files changed, 64 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 37f9516941..f5609b62a2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -453,6 +453,7 @@ struct RISCVCPUConfig {
 bool ext_svnapot;
 bool ext_svpbmt;
 bool ext_zdinx;
+bool ext_zawrs;
 bool ext_zfh;
 bool ext_zfhmin;
 bool ext_zfinx;
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d0253b8104..b7e7613ea2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -718,6 +718,10 @@ vsetvli 0 ... . 111 . 1010111  
@r2_zimm11
 vsetivli11 .. . 111 . 1010111  @r2_zimm10
 vsetvl  100 . . 111 . 1010111  @r
 
+# *** Zawrs Standard Extension ***
+wrs_nto1101 0 000 0 1110011
+wrs_sto00011101 0 000 0 1110011
+
 # *** RV32 Zba Standard Extension ***
 sh1add 001 .. 010 . 0110011 @r
 sh2add 001 .. 100 . 0110011 @r
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b2c132e269..cc75ca7667 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -76,6 +76,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
 ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
 ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, 
ext_zihintpause),
+ISA_EXT_DATA_ENTRY(zawrs, true, PRIV_VERSION_1_12_0, ext_zawrs),
 ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
 ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
 ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
@@ -766,6 +767,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
+error_setg(errp, "Zawrs extension requires A extension");
+return;
+}
+
 if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
 error_setg(errp, "Zfh/Zfhmin extensions require F extension");
 return;
@@ -1021,6 +1027,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
 DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
+DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
 DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
 DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 160aefc3df..df38db7553 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1060,6 +1060,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvh.c.inc"
 #include "insn_trans/trans_rvv.c.inc"
 #include "insn_trans/trans_rvb.c.inc"
+#include "insn_trans/trans_rvzawrs.c.inc"
 #include "insn_trans/trans_rvzfh.c.inc"
 #include "insn_trans/trans_rvk.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc 
b/target/riscv/insn_trans/trans_rvzawrs.c.inc
new file mode 100644
index 00..8254e7dfe2
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
@@ -0,0 +1,51 @@
+/*
+ * RISC-V translation routines for the RISC-V Zawrs Extension.
+ *
+ * 

[PULL v2 07/45] hw/riscv/opentitan: bump opentitan

2022-12-21 Thread Alistair Francis
From: Wilfred Mallawa 

This patch updates the OpenTitan model to match
the specified register layout as per [1]. Which is also the latest
commit of OpenTitan supported by TockOS.

Note: Pinmux and Padctrl has been merged into Pinmux [2][3], this patch removes
any references to Padctrl. Note: OpenTitan doc [2] has not yet specified
much detail regarding this, except for a note that states `TODO: this
section needs to be updated to reflect the pinmux/padctrl merger`

[1] 
https://github.com/lowRISC/opentitan/blob/d072ac505f82152678d6e04be95c72b728a347b8/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
[2] https://docs.opentitan.org/hw/top_earlgrey/doc/design/
[3] https://docs.opentitan.org/hw/ip/pinmux/doc/#overview

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
Message-Id: <20221025043335.339815-2-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h |  9 -
 hw/riscv/opentitan.c | 21 +
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 6665cd5794..1fc055cdff 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -81,7 +81,6 @@ enum {
 IBEX_DEV_RSTMGR,
 IBEX_DEV_CLKMGR,
 IBEX_DEV_PINMUX,
-IBEX_DEV_PADCTRL,
 IBEX_DEV_USBDEV,
 IBEX_DEV_FLASH_CTRL,
 IBEX_DEV_PLIC,
@@ -109,10 +108,10 @@ enum {
 IBEX_UART0_RX_TIMEOUT_IRQ = 7,
 IBEX_UART0_RX_PARITY_ERR_IRQ  = 8,
 IBEX_TIMER_TIMEREXPIRED0_0= 127,
-IBEX_SPI_HOST0_ERR_IRQ= 151,
-IBEX_SPI_HOST0_SPI_EVENT_IRQ  = 152,
-IBEX_SPI_HOST1_ERR_IRQ= 153,
-IBEX_SPI_HOST1_SPI_EVENT_IRQ  = 154,
+IBEX_SPI_HOST0_ERR_IRQ= 134,
+IBEX_SPI_HOST0_SPI_EVENT_IRQ  = 135,
+IBEX_SPI_HOST1_ERR_IRQ= 136,
+IBEX_SPI_HOST1_SPI_EVENT_IRQ  = 137,
 };
 
 #endif
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index be7ff1eea0..92493c629d 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -28,8 +28,16 @@
 #include "qemu/units.h"
 #include "sysemu/sysemu.h"
 
+/*
+ * This version of the OpenTitan machine currently supports
+ * OpenTitan RTL version:
+ * 
+ *
+ * MMIO mapping as per (specified commit):
+ * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
+ */
 static const MemMapEntry ibex_memmap[] = {
-[IBEX_DEV_ROM] ={  0x8000,   0x8000 },
+[IBEX_DEV_ROM] ={  0x8000,  0x8000 },
 [IBEX_DEV_RAM] ={  0x1000,  0x2 },
 [IBEX_DEV_FLASH] =  {  0x2000,  0x10 },
 [IBEX_DEV_UART] =   {  0x4000,  0x1000  },
@@ -38,17 +46,17 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_I2C] ={  0x4008,  0x1000  },
 [IBEX_DEV_PATTGEN] ={  0x400e,  0x1000  },
 [IBEX_DEV_TIMER] =  {  0x4010,  0x1000  },
-[IBEX_DEV_SENSOR_CTRL] ={  0x4011,  0x1000  },
 [IBEX_DEV_OTP_CTRL] =   {  0x4013,  0x4000  },
 [IBEX_DEV_LC_CTRL] ={  0x4014,  0x1000  },
-[IBEX_DEV_USBDEV] = {  0x4015,  0x1000  },
+[IBEX_DEV_ALERT_HANDLER] =  {  0x4015,  0x1000  },
 [IBEX_DEV_SPI_HOST0] =  {  0x4030,  0x1000  },
 [IBEX_DEV_SPI_HOST1] =  {  0x4031,  0x1000  },
+[IBEX_DEV_USBDEV] = {  0x4032,  0x1000  },
 [IBEX_DEV_PWRMGR] = {  0x4040,  0x1000  },
 [IBEX_DEV_RSTMGR] = {  0x4041,  0x1000  },
 [IBEX_DEV_CLKMGR] = {  0x4042,  0x1000  },
 [IBEX_DEV_PINMUX] = {  0x4046,  0x1000  },
-[IBEX_DEV_PADCTRL] ={  0x4047,  0x1000  },
+[IBEX_DEV_SENSOR_CTRL] ={  0x4049,  0x1000  },
 [IBEX_DEV_FLASH_CTRL] = {  0x4100,  0x1000  },
 [IBEX_DEV_AES] ={  0x4110,  0x1000  },
 [IBEX_DEV_HMAC] =   {  0x4111,  0x1000  },
@@ -59,10 +67,9 @@ static const MemMapEntry ibex_memmap[] = {
 [IBEX_DEV_ENTROPY] ={  0x4116,  0x1000  },
 [IBEX_DEV_EDNO] =   {  0x4117,  0x1000  },
 [IBEX_DEV_EDN1] =   {  0x4118,  0x1000  },
-[IBEX_DEV_ALERT_HANDLER] =  {  0x411b,  0x1000  },
 [IBEX_DEV_NMI_GEN] ={  0x411c,  0x1000  },
 [IBEX_DEV_PERI] =   {  0x411f,  0x1 },
-[IBEX_DEV_PLIC] =   {  0x4800,  0x4005000  },
+[IBEX_DEV_PLIC] =   {  0x4800,  0x4005000 },
 [IBEX_DEV_FLASH_VIRTUAL] =  {  0x8000,  0x8 },
 };
 
@@ -265,8 +272,6 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
 create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
 memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
-create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
-

[PULL v2 11/45] target/riscv: generate virtual instruction exception

2022-12-21 Thread Alistair Francis
From: Mayuresh Chitale 

This patch adds a mechanism to generate a virtual instruction
instruction exception instead of an illegal instruction exception
during instruction decode when virt is enabled.

Signed-off-by: Mayuresh Chitale 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20221016124726.102129-4-mchit...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index db123da5ec..8b0bd38bb2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -76,6 +76,7 @@ typedef struct DisasContext {
to reset this known value.  */
 int frm;
 RISCVMXL ol;
+bool virt_inst_excp;
 bool virt_enabled;
 const RISCVCPUConfig *cfg_ptr;
 bool hlsx;
@@ -243,7 +244,11 @@ static void gen_exception_illegal(DisasContext *ctx)
 {
 tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
offsetof(CPURISCVState, bins));
-generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
+if (ctx->virt_inst_excp) {
+generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
+} else {
+generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
+}
 }
 
 static void gen_exception_inst_addr_mis(DisasContext *ctx)
@@ -1062,6 +1067,7 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
 };
 
+ctx->virt_inst_excp = false;
 /* Check for compressed insn */
 if (insn_len(opcode) == 2) {
 if (!has_ext(ctx, RVC)) {
-- 
2.38.1




[PULL v2 22/45] hw/riscv: pfsoc: add missing FICs as unimplemented

2022-12-21 Thread Alistair Francis
From: Conor Dooley 

The Fabric Interconnect Controllers provide interfaces between the FPGA
fabric and the core complex. There are 5 FICs on PolarFire SoC, numbered
0 through 4. FIC2 is an AXI4 slave interface from the FPGA fabric and
does not show up on the MSS memory map. FIC4 is dedicated to the User
Crypto Processor and does not show up on the MSS memory map either.

FIC 0, 1 & 3 do show up in the MSS memory map and neither FICs 0 or 1
are represented in QEMU, leading to load access violations while booting
Linux for Icicle if PCIe is enabled as the root port is connected via
either FIC 0 or 1.

Acked-by: Alistair Francis 
Signed-off-by: Conor Dooley 
Message-Id: <20221117225518.4102575-3-co...@kernel.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/microchip_pfsoc.h |   2 +
 hw/riscv/microchip_pfsoc.c | 115 -
 2 files changed, 65 insertions(+), 52 deletions(-)

diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index a757b240e0..7e7950dd36 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -121,6 +121,8 @@ enum {
 MICROCHIP_PFSOC_USB,
 MICROCHIP_PFSOC_QSPI_XIP,
 MICROCHIP_PFSOC_IOSCB,
+MICROCHIP_PFSOC_FABRIC_FIC0,
+MICROCHIP_PFSOC_FABRIC_FIC1,
 MICROCHIP_PFSOC_FABRIC_FIC3,
 MICROCHIP_PFSOC_DRAM_LO,
 MICROCHIP_PFSOC_DRAM_LO_ALIAS,
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index a821263d4f..2a24e3437a 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -86,58 +86,61 @@
  * describes the complete IOSCB modules memory maps
  */
 static const MemMapEntry microchip_pfsoc_memmap[] = {
-[MICROCHIP_PFSOC_RSVD0] =   {0x0,  0x100 },
-[MICROCHIP_PFSOC_DEBUG] =   {  0x100,  0xf00 },
-[MICROCHIP_PFSOC_E51_DTIM] ={  0x100, 0x2000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT0] ={  0x170, 0x1000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT1] ={  0x1701000, 0x1000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT2] ={  0x1702000, 0x1000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT3] ={  0x1703000, 0x1000 },
-[MICROCHIP_PFSOC_BUSERR_UNIT4] ={  0x1704000, 0x1000 },
-[MICROCHIP_PFSOC_CLINT] =   {  0x200,0x1 },
-[MICROCHIP_PFSOC_L2CC] ={  0x201, 0x1000 },
-[MICROCHIP_PFSOC_DMA] = {  0x300,   0x10 },
-[MICROCHIP_PFSOC_L2LIM] =   {  0x800,  0x200 },
-[MICROCHIP_PFSOC_PLIC] ={  0xc00,  0x400 },
-[MICROCHIP_PFSOC_MMUART0] = { 0x2000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG0] =   { 0x20001000, 0x1000 },
-[MICROCHIP_PFSOC_SYSREG] =  { 0x20002000, 0x2000 },
-[MICROCHIP_PFSOC_AXISW] =   { 0x20004000, 0x1000 },
-[MICROCHIP_PFSOC_MPUCFG] =  { 0x20005000, 0x1000 },
-[MICROCHIP_PFSOC_FMETER] =  { 0x20006000, 0x1000 },
-[MICROCHIP_PFSOC_DDR_SGMII_PHY] =   { 0x20007000, 0x1000 },
-[MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
-[MICROCHIP_PFSOC_DDR_CFG] = { 0x2008,0x4 },
-[MICROCHIP_PFSOC_MMUART1] = { 0x2010, 0x1000 },
-[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
-[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
-[MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG1] =   { 0x20101000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG2] =   { 0x20103000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG3] =   { 0x20105000, 0x1000 },
-[MICROCHIP_PFSOC_WDOG4] =   { 0x20106000, 0x1000 },
-[MICROCHIP_PFSOC_SPI0] ={ 0x20108000, 0x1000 },
-[MICROCHIP_PFSOC_SPI1] ={ 0x20109000, 0x1000 },
-[MICROCHIP_PFSOC_I2C0] ={ 0x2010a000, 0x1000 },
-[MICROCHIP_PFSOC_I2C1] ={ 0x2010b000, 0x1000 },
-[MICROCHIP_PFSOC_CAN0] ={ 0x2010c000, 0x1000 },
-[MICROCHIP_PFSOC_CAN1] ={ 0x2010d000, 0x1000 },
-[MICROCHIP_PFSOC_GEM0] ={ 0x2011, 0x2000 },
-[MICROCHIP_PFSOC_GEM1] ={ 0x20112000, 0x2000 },
-[MICROCHIP_PFSOC_GPIO0] =   { 0x2012, 0x1000 },
-[MICROCHIP_PFSOC_GPIO1] =   { 0x20121000, 0x1000 },
-[MICROCHIP_PFSOC_GPIO2] =   { 0x20122000, 0x1000 },
-[MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
-[MICROCHIP_PFSOC_ENVM_CFG] ={ 0x2020, 0x1000 },
-[MICROCHIP_PFSOC_ENVM_DATA] =   { 0x2022,0x2 },
-[MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
-[MICROCHIP_PFSOC_QSPI_XIP] ={ 0x2100,  0x100 },
-[MICROCHIP_PFSOC_IOSCB] =   { 0x3000, 0x1000 },
-[MICROCHIP_PFSOC_FABRIC_FIC3] = 

[PULL v2 19/45] target/riscv: support cache-related PMU events in virtual mode

2022-12-21 Thread Alistair Francis
From: Jim Shu 

let tlb_fill() function also increments PMU counter when it is from
two-stage translation, so QEMU could also monitor these PMU events when
CPU runs in VS/VU mode (like running guest OS).

Signed-off-by: Jim Shu 
Reviewed-by: Alistair Francis 
Message-Id: <20221123090635.6574-1-jim@sifive.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 427d4d4386..1ff6ab5746 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1258,6 +1258,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 }
 
+pmu_tlb_fill_incr_ctr(cpu, access_type);
 if (riscv_cpu_virt_enabled(env) ||
 ((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
  access_type != MMU_INST_FETCH)) {
@@ -1321,7 +1322,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 }
 }
 } else {
-pmu_tlb_fill_incr_ctr(cpu, access_type);
 /* Single stage lookup */
 ret = get_physical_address(env, , , address, NULL,
access_type, mmu_idx, true, false, false);
-- 
2.38.1




[PULL v2 34/45] hw/riscv: spike: Remove misleading comments

2022-12-21 Thread Alistair Francis
From: Bin Meng 

PLIC is not included in the 'spike' machine.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-5-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/spike.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 1e1d752c00..13946acf0d 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -8,7 +8,6 @@
  *
  * 0) HTIF Console and Poweroff
  * 1) CLINT (Timer and IPI)
- * 2) PLIC (Platform Level Interrupt Controller)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
-- 
2.38.1




[PULL v2 43/45] hw/intc: sifive_plic: Change "priority-base" to start from interrupt source 0

2022-12-21 Thread Alistair Francis
From: Bin Meng 

At present the SiFive PLIC model "priority-base" expects interrupt
priority register base starting from source 1 instead source 0,
that's why on most platforms "priority-base" is set to 0x04 except
'opentitan' machine. 'opentitan' should have set "priority-base"
to 0x04 too.

Note the irq number calculation in sifive_plic_{read,write} is
correct as the codes make up for the irq number by adding 1.

Let's simply update "priority-base" to start from interrupt source
0 and add a comment to make it crystal clear.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Wilfred Mallawa 
Message-Id: <20221211030829.802437-14-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/microchip_pfsoc.h | 2 +-
 include/hw/riscv/shakti_c.h| 2 +-
 include/hw/riscv/sifive_e.h| 2 +-
 include/hw/riscv/sifive_u.h| 2 +-
 include/hw/riscv/virt.h| 2 +-
 hw/intc/sifive_plic.c  | 5 +++--
 6 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index 577efad0c4..e65ffeb02d 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -155,7 +155,7 @@ enum {
 
 #define MICROCHIP_PFSOC_PLIC_NUM_SOURCES187
 #define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
-#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE  0x04
+#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE  0x00
 #define MICROCHIP_PFSOC_PLIC_PENDING_BASE   0x1000
 #define MICROCHIP_PFSOC_PLIC_ENABLE_BASE0x2000
 #define MICROCHIP_PFSOC_PLIC_ENABLE_STRIDE  0x80
diff --git a/include/hw/riscv/shakti_c.h b/include/hw/riscv/shakti_c.h
index daf0aae13f..539fe1156d 100644
--- a/include/hw/riscv/shakti_c.h
+++ b/include/hw/riscv/shakti_c.h
@@ -65,7 +65,7 @@ enum {
 #define SHAKTI_C_PLIC_NUM_SOURCES 28
 /* Excluding Priority 0 */
 #define SHAKTI_C_PLIC_NUM_PRIORITIES 2
-#define SHAKTI_C_PLIC_PRIORITY_BASE 0x04
+#define SHAKTI_C_PLIC_PRIORITY_BASE 0x00
 #define SHAKTI_C_PLIC_PENDING_BASE 0x1000
 #define SHAKTI_C_PLIC_ENABLE_BASE 0x2000
 #define SHAKTI_C_PLIC_ENABLE_STRIDE 0x80
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
index 9e58247fd8..b824a79e2d 100644
--- a/include/hw/riscv/sifive_e.h
+++ b/include/hw/riscv/sifive_e.h
@@ -89,7 +89,7 @@ enum {
  */
 #define SIFIVE_E_PLIC_NUM_SOURCES 53
 #define SIFIVE_E_PLIC_NUM_PRIORITIES 7
-#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
+#define SIFIVE_E_PLIC_PRIORITY_BASE 0x00
 #define SIFIVE_E_PLIC_PENDING_BASE 0x1000
 #define SIFIVE_E_PLIC_ENABLE_BASE 0x2000
 #define SIFIVE_E_PLIC_ENABLE_STRIDE 0x80
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index 8f63a183c4..e680d61ece 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -158,7 +158,7 @@ enum {
 
 #define SIFIVE_U_PLIC_NUM_SOURCES 54
 #define SIFIVE_U_PLIC_NUM_PRIORITIES 7
-#define SIFIVE_U_PLIC_PRIORITY_BASE 0x04
+#define SIFIVE_U_PLIC_PRIORITY_BASE 0x00
 #define SIFIVE_U_PLIC_PENDING_BASE 0x1000
 #define SIFIVE_U_PLIC_ENABLE_BASE 0x2000
 #define SIFIVE_U_PLIC_ENABLE_STRIDE 0x80
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index e1ce0048af..3407c9e8dd 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -98,7 +98,7 @@ enum {
 #define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
 #define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
 
-#define VIRT_PLIC_PRIORITY_BASE 0x04
+#define VIRT_PLIC_PRIORITY_BASE 0x00
 #define VIRT_PLIC_PENDING_BASE 0x1000
 #define VIRT_PLIC_ENABLE_BASE 0x2000
 #define VIRT_PLIC_ENABLE_STRIDE 0x80
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 1edeb1e1ed..1a792cc3f5 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -140,7 +140,7 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, 
unsigned size)
 SiFivePLICState *plic = opaque;
 
 if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
-uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
+uint32_t irq = (addr - plic->priority_base) >> 2;
 
 return plic->source_priority[irq];
 } else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) 
{
@@ -187,7 +187,7 @@ static void sifive_plic_write(void *opaque, hwaddr addr, 
uint64_t value,
 SiFivePLICState *plic = opaque;
 
 if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
-uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
+uint32_t irq = (addr - plic->priority_base) >> 2;
 
 if (((plic->num_priorities + 1) & plic->num_priorities) == 0) {
 /*
@@ -428,6 +428,7 @@ static Property sifive_plic_properties[] = {
 /* number of interrupt sources including interrupt source 0 */
 DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
 DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
+/* interrupt priority register base 

[PULL v2 20/45] target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state()

2022-12-21 Thread Alistair Francis
From: Bin Meng 

sstatus register dump is currently missing in riscv_cpu_dump_state().
As sstatus is a copy of mstatus, which is described in the priv spec,
it seems redundant to print the same information twice.

Add some comments for this to let people know this is intentional.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221125050354.3166023-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6fe176e483..b2c132e269 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -382,6 +382,10 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, 
int flags)
 CSR_MHARTID,
 CSR_MSTATUS,
 CSR_MSTATUSH,
+/*
+ * CSR_SSTATUS is intentionally omitted here as its value
+ * can be figured out by looking at CSR_MSTATUS
+ */
 CSR_HSTATUS,
 CSR_VSSTATUS,
 CSR_MIP,
-- 
2.38.1




[PULL v2 28/45] target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+

2022-12-21 Thread Alistair Francis
From: Bin Meng 

Since priv spec v1.12, MRET and SRET now clear mstatus.MPRV when
leaving M-mode.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Message-Id: <20221207090037.281452-2-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index a047d38152..878bcb03b8 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -154,6 +154,9 @@ target_ulong helper_sret(CPURISCVState *env)
 get_field(mstatus, MSTATUS_SPIE));
 mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
 mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
+if (env->priv_ver >= PRIV_VERSION_1_12_0) {
+mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
+}
 env->mstatus = mstatus;
 
 if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
@@ -203,6 +206,9 @@ target_ulong helper_mret(CPURISCVState *env)
 mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
 mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
 mstatus = set_field(mstatus, MSTATUS_MPV, 0);
+if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
+mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
+}
 env->mstatus = mstatus;
 riscv_cpu_set_mode(env, prev_priv);
 
-- 
2.38.1




[PULL v2 30/45] hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC

2022-12-21 Thread Alistair Francis
From: Bin Meng 

hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
controllers regardless of how MSI is implemented. msi_nonbroken is
initialized to true in sifive_plic_realize().

Let SIFIVE_PLIC select MSI_NONBROKEN and drop the selection from
RISC-V machines.

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Wilfred Mallawa 
Message-Id: <20221211030829.802437-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/intc/Kconfig  | 1 +
 hw/riscv/Kconfig | 5 -
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index ecd2883ceb..1d4573e803 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -78,6 +78,7 @@ config RISCV_IMSIC
 
 config SIFIVE_PLIC
 bool
+select MSI_NONBROKEN
 
 config GOLDFISH_PIC
 bool
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index 79ff61c464..167dc4cca6 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -11,7 +11,6 @@ config MICROCHIP_PFSOC
 select MCHP_PFSOC_IOSCB
 select MCHP_PFSOC_MMUART
 select MCHP_PFSOC_SYSREG
-select MSI_NONBROKEN
 select RISCV_ACLINT
 select SIFIVE_PDMA
 select SIFIVE_PLIC
@@ -37,7 +36,6 @@ config RISCV_VIRT
 imply TPM_TIS_SYSBUS
 select RISCV_NUMA
 select GOLDFISH_RTC
-select MSI_NONBROKEN
 select PCI
 select PCI_EXPRESS_GENERIC_BRIDGE
 select PFLASH_CFI01
@@ -53,7 +51,6 @@ config RISCV_VIRT
 
 config SIFIVE_E
 bool
-select MSI_NONBROKEN
 select RISCV_ACLINT
 select SIFIVE_GPIO
 select SIFIVE_PLIC
@@ -64,7 +61,6 @@ config SIFIVE_E
 config SIFIVE_U
 bool
 select CADENCE
-select MSI_NONBROKEN
 select RISCV_ACLINT
 select SIFIVE_GPIO
 select SIFIVE_PDMA
@@ -82,6 +78,5 @@ config SPIKE
 bool
 select RISCV_NUMA
 select HTIF
-select MSI_NONBROKEN
 select RISCV_ACLINT
 select SIFIVE_PLIC
-- 
2.38.1




[PULL v2 05/45] tcg/riscv: Fix reg overlap case in tcg_out_addsub2

2022-12-21 Thread Alistair Francis
From: Richard Henderson 

There was a typo using opc_addi instead of opc_add with the
two registers.  While we're at it, simplify the gating test
to al == bl to improve dynamic scheduling even when the
output register does not overlap the inputs.

Reported-by: LIU Zhiwei 
Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20221020233836.2341671-1-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 tcg/riscv/tcg-target.c.inc | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 191197853f..2a84c57bec 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -700,9 +700,15 @@ static void tcg_out_addsub2(TCGContext *s,
 if (cbl) {
 tcg_out_opc_imm(s, opc_addi, rl, al, bl);
 tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, rl, bl);
-} else if (rl == al && rl == bl) {
+} else if (al == bl) {
+/*
+ * If the input regs overlap, this is a simple doubling
+ * and carry-out is the input msb.  This special case is
+ * required when the output reg overlaps the input,
+ * but we might as well use it always.
+ */
 tcg_out_opc_imm(s, OPC_SLTI, TCG_REG_TMP0, al, 0);
-tcg_out_opc_reg(s, opc_addi, rl, al, bl);
+tcg_out_opc_reg(s, opc_add, rl, al, al);
 } else {
 tcg_out_opc_reg(s, opc_add, rl, al, bl);
 tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0,
-- 
2.38.1




[PULL v2 04/45] tcg/riscv: Fix range matched by TCG_CT_CONST_M12

2022-12-21 Thread Alistair Francis
From: Richard Henderson 

We were matching a signed 13-bit range, not a 12-bit range.
Expand the commentary within the function and be explicit
about all of the ranges.

Reported-by: LIU Zhiwei 
Signed-off-by: Richard Henderson 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221022095821.2441874-1-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 tcg/riscv/tcg-target.c.inc | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 81a83e45b1..191197853f 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -154,13 +154,26 @@ static bool tcg_target_const_match(int64_t val, TCGType 
type, int ct)
 if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
 return 1;
 }
-if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
+/*
+ * Sign extended from 12 bits: [-0x800, 0x7ff].
+ * Used for most arithmetic, as this is the isa field.
+ */
+if ((ct & TCG_CT_CONST_S12) && val >= -0x800 && val <= 0x7ff) {
 return 1;
 }
-if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
+/*
+ * Sign extended from 12 bits, negated: [-0x7ff, 0x800].
+ * Used for subtraction, where a constant must be handled by ADDI.
+ */
+if ((ct & TCG_CT_CONST_N12) && val >= -0x7ff && val <= 0x800) {
 return 1;
 }
-if ((ct & TCG_CT_CONST_M12) && val >= -0xfff && val <= 0xfff) {
+/*
+ * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
+ * Used by addsub2, which may need the negative operation,
+ * and requires the modified constant to be representable.
+ */
+if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
 return 1;
 }
 return 0;
-- 
2.38.1




[PULL v2 16/45] hw/intc: sifive_plic: Renumber the S irqs for numa support

2022-12-21 Thread Alistair Francis
From: Frédéric Pétrot 

Commit 40244040a7a changed the way the S irqs are numbered. This breaks when
using numa configuration, e.g.:
./qemu-system-riscv64 -nographic -machine virt,dumpdtb=numa-tree.dtb \
  -m 2G -smp cpus=16 \
  -object memory-backend-ram,id=mem0,size=512M \
  -object memory-backend-ram,id=mem1,size=512M \
  -object memory-backend-ram,id=mem2,size=512M \
  -object memory-backend-ram,id=mem3,size=512M \
  -numa node,cpus=0-3,memdev=mem0,nodeid=0 \
  -numa node,cpus=4-7,memdev=mem1,nodeid=1 \
  -numa node,cpus=8-11,memdev=mem2,nodeid=2 \
  -numa node,cpus=12-15,memdev=mem3,nodeid=3
leads to:
Unexpected error in object_property_find_err() at ../qom/object.c:1304:
qemu-system-riscv64: Property 'riscv.sifive.plic.unnamed-gpio-out[8]' not
found

This patch makes the nubering of the S irqs identical to what it was before.

Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Frédéric Pétrot 
Message-Id: <20221114135122.1668703-1-frederic.pet...@univ-grenoble-alpes.fr>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index c2dfacf028..b4949bef97 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -476,11 +476,11 @@ DeviceState *sifive_plic_create(hwaddr addr, char 
*hart_config,
 CPUState *cpu = qemu_get_cpu(cpu_num);
 
 if (plic->addr_config[i].mode == PLICMode_M) {
-qdev_connect_gpio_out(dev, num_harts - plic->hartid_base + cpu_num,
+qdev_connect_gpio_out(dev, cpu_num - hartid_base + num_harts,
   qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
 }
 if (plic->addr_config[i].mode == PLICMode_S) {
-qdev_connect_gpio_out(dev, cpu_num,
+qdev_connect_gpio_out(dev, cpu_num - hartid_base,
   qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
 }
 }
-- 
2.38.1




[PULL v2 41/45] hw/riscv: sifive_u: Avoid using magic number for "riscv, ndev"

2022-12-21 Thread Alistair Francis
From: Bin Meng 

At present magic number is used to create "riscv,ndev" property
in the dtb. Let's use the macro SIFIVE_U_PLIC_NUM_SOURCES that
is used to instantiate the PLIC model instead.

Signed-off-by: Bin Meng 
Reviewed-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221211030829.802437-12-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_u.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index b139824aab..b40a4767e2 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -287,7 +287,8 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry 
*memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg",
 0x0, memmap[SIFIVE_U_DEV_PLIC].base,
 0x0, memmap[SIFIVE_U_DEV_PLIC].size);
-qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
+qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
+  SIFIVE_U_PLIC_NUM_SOURCES - 1);
 qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
 plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
 g_free(cells);
-- 
2.38.1




[PULL v2 18/45] hw/riscv: virt: Remove the redundant ipi-id property

2022-12-21 Thread Alistair Francis
From: Atish Patra 

The imsic DT binding[1] has changed and no longer require an ipi-id.
The latest IMSIC driver dynamically allocates ipi id if slow-ipi
is not defined.

Get rid of the unused dt property which may lead to confusion.

[1] 
https://lore.kernel.org/lkml/2022044207.1478350-5-apa...@ventanamicro.com/

Signed-off-by: Atish Patra 
Reviewed-by: Alistair Francis 
Message-Id: <20221122080529.1692533-1-ati...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/riscv/virt.h | 1 -
 hw/riscv/virt.c | 4 
 2 files changed, 5 deletions(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index be4ab8fe7f..62513e075c 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -93,7 +93,6 @@ enum {
 
 #define VIRT_PLATFORM_BUS_NUM_IRQS 32
 
-#define VIRT_IRQCHIP_IPI_MSI 1
 #define VIRT_IRQCHIP_NUM_MSIS 255
 #define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
 #define VIRT_IRQCHIP_NUM_PRIO_BITS 3
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a5bc7353b4..6cf9355b99 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -546,8 +546,6 @@ static void create_fdt_imsic(RISCVVirtState *s, const 
MemMapEntry *memmap,
 riscv_socket_count(mc) * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
 VIRT_IRQCHIP_NUM_MSIS);
-qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
-VIRT_IRQCHIP_IPI_MSI);
 if (riscv_socket_count(mc) > 1) {
 qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
 imsic_num_bits(imsic_max_hart_per_socket));
@@ -597,8 +595,6 @@ static void create_fdt_imsic(RISCVVirtState *s, const 
MemMapEntry *memmap,
 riscv_socket_count(mc) * sizeof(uint32_t) * 4);
 qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
 VIRT_IRQCHIP_NUM_MSIS);
-qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
-VIRT_IRQCHIP_IPI_MSI);
 if (imsic_guest_bits) {
 qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
 imsic_guest_bits);
-- 
2.38.1




[PATCH 3/4] Hexagon (target/hexagon) Add overrides for endloop1/endloop01

2022-12-21 Thread Taylor Simpson
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h |  4 ++
 target/hexagon/genptr.c  | 79 
 2 files changed, 83 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 231654e6c1..1ac23b75a0 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -628,6 +628,10 @@
 
 #define fGEN_TCG_J2_endloop0(SHORTCODE) \
 gen_endloop0(ctx)
+#define fGEN_TCG_J2_endloop1(SHORTCODE) \
+gen_endloop1(ctx)
+#define fGEN_TCG_J2_endloop01(SHORTCODE) \
+gen_endloop01(ctx)
 
 /*
  * Compound compare and jump instructions
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 9e31f3418b..0eef2a2068 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -763,6 +763,85 @@ static void gen_endloop0(DisasContext *ctx)
 tcg_temp_free(lpcfg);
 }
 
+static void gen_endloop1(DisasContext *ctx)
+{
+/*
+ *if (hex_gpr[HEX_REG_LC1] > 1) {
+ *PC = hex_gpr[HEX_REG_SA1];
+ *hex_new_value[HEX_REG_LC1] = hex_gpr[HEX_REG_LC1] - 1;
+ *}
+ */
+TCGLabel *label = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC1], 1, label);
+{
+gen_jumpr(ctx, hex_gpr[HEX_REG_SA1]);
+tcg_gen_subi_tl(hex_new_value[HEX_REG_LC1], hex_gpr[HEX_REG_LC1], 1);
+}
+gen_set_label(label);
+}
+
+static void gen_endloop01(DisasContext *ctx)
+{
+TCGv lpcfg = tcg_temp_local_new();
+
+GET_USR_FIELD(USR_LPCFG, lpcfg);
+
+/*
+ *if (lpcfg == 1) {
+ *hex_new_pred_value[3] = 0xff;
+ *hex_pred_written |= 1 << 3;
+ *}
+ */
+TCGLabel *label1 = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_NE, lpcfg, 1, label1);
+{
+tcg_gen_movi_tl(hex_new_pred_value[3], 0xff);
+tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << 3);
+}
+gen_set_label(label1);
+
+/*
+ *if (lpcfg) {
+ *SET_USR_FIELD(USR_LPCFG, lpcfg - 1);
+ *}
+ */
+TCGLabel *label2 = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, lpcfg, 0, label2);
+{
+tcg_gen_subi_tl(lpcfg, lpcfg, 1);
+SET_USR_FIELD(USR_LPCFG, lpcfg);
+}
+gen_set_label(label2);
+
+/*
+ *if (hex_gpr[HEX_REG_LC0] > 1) {
+ *PC = hex_gpr[HEX_REG_SA0];
+ *hex_new_value[HEX_REG_LC0] = hex_gpr[HEX_REG_LC0] - 1;
+ *} else {
+ *if (hex_gpr[HEX_REG_LC1] > 1) {
+ *hex_next_pc = hex_gpr[HEX_REG_SA1];
+ *hex_new_value[HEX_REG_LC1] = hex_gpr[HEX_REG_LC1] - 1;
+ *}
+ *}
+ */
+TCGLabel *label3 = gen_new_label();
+TCGLabel *done = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC0], 1, label3);
+{
+gen_jumpr(ctx, hex_gpr[HEX_REG_SA0]);
+tcg_gen_subi_tl(hex_new_value[HEX_REG_LC0], hex_gpr[HEX_REG_LC0], 1);
+tcg_gen_br(done);
+}
+gen_set_label(label3);
+tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC1], 1, done);
+{
+gen_jumpr(ctx, hex_gpr[HEX_REG_SA1]);
+tcg_gen_subi_tl(hex_new_value[HEX_REG_LC1], hex_gpr[HEX_REG_LC1], 1);
+}
+gen_set_label(done);
+tcg_temp_free(lpcfg);
+}
+
 static void gen_cmp_jumpnv(DisasContext *ctx,
TCGCond cond, TCGv val, TCGv src, int pc_off)
 {
-- 
2.17.1



[PULL v2 01/45] target/riscv: Fix PMP propagation for tlb

2022-12-21 Thread Alistair Francis
From: LIU Zhiwei 

Only the pmp index that be checked by pmp_hart_has_privs can be used
by pmp_get_tlb_size to avoid an error pmp index.

Before modification, we may use an error pmp index. For example,
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
will return true;

However, this checked pmp index is discarded as pmp_hart_has_privs
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
rules. The tlb_sa will be 0x0, and tlb_ea will be 0xfff. If there is
a pmp rule [0x10, 0x14), it will be misused as it is legal in
pmp_get_tlb_size.

As we have already known the correct pmp index, just remove the
remove the pmp_is_range_in_tlb and get tlb size directly from
pmp_get_tlb_size.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221012060016.30856-1-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/pmp.h|  6 +--
 target/riscv/cpu_helper.c | 16 ---
 target/riscv/pmp.c| 90 +--
 3 files changed, 42 insertions(+), 70 deletions(-)

diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index a8dd797476..da32c61c85 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -72,11 +72,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
 void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
 target_ulong val);
 target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
 target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
 target_ulong mode);
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
- target_ulong *tlb_size);
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
+  target_ulong tlb_sa, target_ulong tlb_ea);
 void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
 void pmp_update_rule_nums(CPURISCVState *env);
 uint32_t pmp_get_num_rules(CPURISCVState *env);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 278d163803..5d66246c2c 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -706,24 +706,26 @@ static int get_physical_address_pmp(CPURISCVState *env, 
int *prot,
 int mode)
 {
 pmp_priv_t pmp_priv;
-target_ulong tlb_size_pmp = 0;
+int pmp_index = -1;
 
 if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TRANSLATE_SUCCESS;
 }
 
-if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, _priv,
-mode)) {
+pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
+   _priv, mode);
+if (pmp_index < 0) {
 *prot = 0;
 return TRANSLATE_PMP_FAIL;
 }
 
 *prot = pmp_priv_to_page_prot(pmp_priv);
-if (tlb_size != NULL) {
-if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), _size_pmp)) {
-*tlb_size = tlb_size_pmp;
-}
+if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
+target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
+target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
+
+*tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
 }
 
 return TRANSLATE_SUCCESS;
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 2b43e399b8..d1126a6066 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -292,8 +292,11 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, 
target_ulong addr,
 
 /*
  * Check if the address has required RWX privs to complete desired operation
+ * Return PMP rule index if a pmp rule match
+ * Return MAX_RISCV_PMPS if default match
+ * Return negtive value if no match
  */
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
 target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
 target_ulong mode)
 {
@@ -305,8 +308,10 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 
 /* Short cut if no rules */
 if (0 == pmp_get_num_rules(env)) {
-return pmp_hart_has_privs_default(env, addr, size, privs,
-  allowed_privs, mode);
+if (pmp_hart_has_privs_default(env, addr, size, privs,
+   allowed_privs, mode)) {
+ret = MAX_RISCV_PMPS;
+}
 }
 
 if (size == 0) {
@@ -333,7 +338,7 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 if ((s + e) == 1) {
 qemu_log_mask(LOG_GUEST_ERROR,
   "pmp violation - access is partially inside\n");
-ret = 0;
+ret = -1;

[PULL v2 02/45] hw/registerfields: add `FIELDx_1CLEAR()` macro

2022-12-21 Thread Alistair Francis
From: Wilfred Mallawa 

Adds a helper macro that implements the register `w1c`
functionality.

Ex:
  uint32_t data = FIELD32_1CLEAR(val, REG, FIELD);

If ANY bits of the specified `FIELD` is set
then the respective field is cleared and returned to `data`.

If the field is cleared (0), then no change and
val is returned.

Signed-off-by: Wilfred Mallawa 
Reviewed-by: Alistair Francis 
Message-Id: <20221017054950.317584-2-wilfred.mall...@opensource.wdc.com>
Signed-off-by: Alistair Francis 
---
 include/hw/registerfields.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
index 1330ca77de..0b8404c2f7 100644
--- a/include/hw/registerfields.h
+++ b/include/hw/registerfields.h
@@ -115,6 +115,28 @@
   R_ ## reg ## _ ## field ## _LENGTH, _v.v);  \
 _d; })
 
+/*
+ * Clear the specified field in storage if
+ * any field bits are set, else no changes made. Implements
+ * single/multi-bit `w1c`
+ *
+ */
+#define FIELD8_1CLEAR(storage, reg, field)\
+(FIELD_EX8(storage, reg, field) ? \
+FIELD_DP8(storage, reg, field, 0x00) : storage)
+
+#define FIELD16_1CLEAR(storage, reg, field)   \
+(FIELD_EX16(storage, reg, field) ?\
+FIELD_DP16(storage, reg, field, 0x00) : storage)
+
+#define FIELD32_1CLEAR(storage, reg, field)   \
+(FIELD_EX32(storage, reg, field) ?\
+FIELD_DP32(storage, reg, field, 0x00) : storage)
+
+#define FIELD64_1CLEAR(storage, reg, field)   \
+(FIELD_EX64(storage, reg, field) ?\
+FIELD_DP64(storage, reg, field, 0x00) : storage)
+
 #define FIELD_SDP8(storage, reg, field, val) ({   \
 struct {  \
 signed int v:R_ ## reg ## _ ## field ## _LENGTH;  \
-- 
2.38.1




[PULL v2 23/45] hw/{misc, riscv}: pfsoc: add system controller as unimplemented

2022-12-21 Thread Alistair Francis
From: Conor Dooley 

The system controller on PolarFire SoC is access via a mailbox. The
control registers for this mailbox lie in the "IOSCB" region & the
interrupt is cleared via write to the "SYSREG" region. It also has a
QSPI controller, usually connected to a flash chip, that is used for
storing FPGA bitstreams and used for In-Application Programming (IAP).

Linux has an implementation of the system controller, through which the
hwrng is accessed, leading to load/store access faults.

Add the QSPI as unimplemented and a very basic (effectively
unimplemented) version of the system controller's mailbox. Rather than
purely marking the regions as unimplemented, service the mailbox
requests by reporting failures and raising the interrupt so a guest can
better handle the lack of support.

Signed-off-by: Conor Dooley 
Acked-by: Alistair Francis 
Message-Id: <20221117225518.4102575-4-co...@kernel.org>
Signed-off-by: Alistair Francis 
---
 include/hw/misc/mchp_pfsoc_ioscb.h  |  3 ++
 include/hw/misc/mchp_pfsoc_sysreg.h |  1 +
 include/hw/riscv/microchip_pfsoc.h  |  1 +
 hw/misc/mchp_pfsoc_ioscb.c  | 72 -
 hw/misc/mchp_pfsoc_sysreg.c | 18 ++--
 hw/riscv/microchip_pfsoc.c  |  6 +++
 6 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h 
b/include/hw/misc/mchp_pfsoc_ioscb.h
index 687b213742..a1104862c8 100644
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
@@ -29,6 +29,8 @@ typedef struct MchpPfSoCIoscbState {
 MemoryRegion lane01;
 MemoryRegion lane23;
 MemoryRegion ctrl;
+MemoryRegion qspixip;
+MemoryRegion mailbox;
 MemoryRegion cfg;
 MemoryRegion ccc;
 MemoryRegion pll_mss;
@@ -41,6 +43,7 @@ typedef struct MchpPfSoCIoscbState {
 MemoryRegion cfm_sgmii;
 MemoryRegion bc_sgmii;
 MemoryRegion io_calib_sgmii;
+qemu_irq irq;
 } MchpPfSoCIoscbState;
 
 #define TYPE_MCHP_PFSOC_IOSCB "mchp.pfsoc.ioscb"
diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h 
b/include/hw/misc/mchp_pfsoc_sysreg.h
index 546ba68f6a..3cebe40ea9 100644
--- a/include/hw/misc/mchp_pfsoc_sysreg.h
+++ b/include/hw/misc/mchp_pfsoc_sysreg.h
@@ -28,6 +28,7 @@
 typedef struct MchpPfSoCSysregState {
 SysBusDevice parent;
 MemoryRegion sysreg;
+qemu_irq irq;
 } MchpPfSoCSysregState;
 
 #define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg"
diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index 7e7950dd36..69a686b54a 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -147,6 +147,7 @@ enum {
 MICROCHIP_PFSOC_MMUART2_IRQ = 92,
 MICROCHIP_PFSOC_MMUART3_IRQ = 93,
 MICROCHIP_PFSOC_MMUART4_IRQ = 94,
+MICROCHIP_PFSOC_MAILBOX_IRQ = 96,
 };
 
 #define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT1
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
index f976e42f72..a71d134295 100644
--- a/hw/misc/mchp_pfsoc_ioscb.c
+++ b/hw/misc/mchp_pfsoc_ioscb.c
@@ -24,6 +24,7 @@
 #include "qemu/bitops.h"
 #include "qemu/log.h"
 #include "qapi/error.h"
+#include "hw/irq.h"
 #include "hw/sysbus.h"
 #include "hw/misc/mchp_pfsoc_ioscb.h"
 
@@ -34,6 +35,9 @@
 #define IOSCB_WHOLE_REG_SIZE0x1000
 #define IOSCB_SUBMOD_REG_SIZE   0x1000
 #define IOSCB_CCC_REG_SIZE  0x200
+#define IOSCB_CTRL_REG_SIZE 0x800
+#define IOSCB_QSPIXIP_REG_SIZE  0x200
+
 
 /*
  * There are many sub-modules in the IOSCB module.
@@ -45,6 +49,8 @@
 #define IOSCB_LANE01_BASE   0x0650
 #define IOSCB_LANE23_BASE   0x0651
 #define IOSCB_CTRL_BASE 0x0702
+#define IOSCB_QSPIXIP_BASE  0x07020100
+#define IOSCB_MAILBOX_BASE  0x07020800
 #define IOSCB_CFG_BASE  0x0708
 #define IOSCB_CCC_BASE  0x0800
 #define IOSCB_PLL_MSS_BASE  0x0E001000
@@ -143,6 +149,58 @@ static const MemoryRegionOps mchp_pfsoc_io_calib_ddr_ops = 
{
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+#define SERVICES_CR 0x50
+#define SERVICES_SR 0x54
+#define SERVICES_STATUS_SHIFT   16
+
+static uint64_t mchp_pfsoc_ctrl_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+uint32_t val = 0;
+
+switch (offset) {
+case SERVICES_SR:
+/*
+ * Although some services have no error codes, most do. All services
+ * that do implement errors, begin their error codes at 1. Treat all
+ * service requests as failures & return 1.
+ * See the "PolarFire® FPGA and PolarFire SoC FPGA System Services"
+ * user guide for more information on service error codes.
+ */
+val = 1u << SERVICES_STATUS_SHIFT;
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
+  "(size %d, offset 0x%" HWADDR_PRIx ")\n",
+  __func__, size, offset);
+}
+

[PULL v2 21/45] hw/misc: pfsoc: add fabric clocks to ioscb

2022-12-21 Thread Alistair Francis
From: Conor Dooley 

On PolarFire SoC, some peripherals (eg the PCI root port) are clocked by
"Clock Conditioning Circuitry" in the FPGA. The specific clock depends
on the FPGA bitstream & can be locked to one particular {D,P}LL - in the
Icicle Kit Reference Design v2022.09 or later this is/will be the case.

Linux v6.1+ will have a driver for this peripheral and devicetrees that
previously relied on "fixed-frequency" clock nodes have been switched
over to clock-controller nodes. The IOSCB region is represented in QEMU,
but the specific region of it that the CCCs occupy has not so v6.1-rcN
kernels fail to boot in QEMU.

Add the regions as unimplemented so that the status-quo in terms of boot
is maintained.

Acked-by: Alistair Francis 
Signed-off-by: Conor Dooley 
Message-Id: <20221117225518.4102575-2-co...@kernel.org>
Signed-off-by: Alistair Francis 
---
 include/hw/misc/mchp_pfsoc_ioscb.h | 1 +
 hw/misc/mchp_pfsoc_ioscb.c | 6 ++
 2 files changed, 7 insertions(+)

diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h 
b/include/hw/misc/mchp_pfsoc_ioscb.h
index 9235523e33..687b213742 100644
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
@@ -30,6 +30,7 @@ typedef struct MchpPfSoCIoscbState {
 MemoryRegion lane23;
 MemoryRegion ctrl;
 MemoryRegion cfg;
+MemoryRegion ccc;
 MemoryRegion pll_mss;
 MemoryRegion cfm_mss;
 MemoryRegion pll_ddr;
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
index f4fd55a0e5..f976e42f72 100644
--- a/hw/misc/mchp_pfsoc_ioscb.c
+++ b/hw/misc/mchp_pfsoc_ioscb.c
@@ -33,6 +33,7 @@
  */
 #define IOSCB_WHOLE_REG_SIZE0x1000
 #define IOSCB_SUBMOD_REG_SIZE   0x1000
+#define IOSCB_CCC_REG_SIZE  0x200
 
 /*
  * There are many sub-modules in the IOSCB module.
@@ -45,6 +46,7 @@
 #define IOSCB_LANE23_BASE   0x0651
 #define IOSCB_CTRL_BASE 0x0702
 #define IOSCB_CFG_BASE  0x0708
+#define IOSCB_CCC_BASE  0x0800
 #define IOSCB_PLL_MSS_BASE  0x0E001000
 #define IOSCB_CFM_MSS_BASE  0x0E002000
 #define IOSCB_PLL_DDR_BASE  0x0E01
@@ -168,6 +170,10 @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, 
Error **errp)
   "mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
 memory_region_add_subregion(>container, IOSCB_CFG_BASE, >cfg);
 
+memory_region_init_io(>ccc, OBJECT(s), _pfsoc_dummy_ops, s,
+  "mchp.pfsoc.ioscb.ccc", IOSCB_CCC_REG_SIZE);
+memory_region_add_subregion(>container, IOSCB_CCC_BASE, >ccc);
+
 memory_region_init_io(>pll_mss, OBJECT(s), _pfsoc_pll_ops, s,
   "mchp.pfsoc.ioscb.pll_mss", IOSCB_SUBMOD_REG_SIZE);
 memory_region_add_subregion(>container, IOSCB_PLL_MSS_BASE, 
>pll_mss);
-- 
2.38.1




[PULL v2 24/45] hw/intc: sifive_plic: fix out-of-bound access of source_priority array

2022-12-21 Thread Alistair Francis
From: Jim Shu 

If the number of interrupt is not multiple of 32, PLIC will have
out-of-bound access to source_priority array. Compute the number of
interrupt in the last word to avoid this out-of-bound access of array.

Signed-off-by: Jim Shu 
Reviewed-by: Bin Meng 
Message-Id: <20221127165753.30533-1-jim@sifive.com>
Signed-off-by: Alistair Francis 
---
 hw/intc/sifive_plic.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index b4949bef97..0c7696520d 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -78,6 +78,7 @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, 
uint32_t addrid)
 uint32_t max_irq = 0;
 uint32_t max_prio = plic->target_priority[addrid];
 int i, j;
+int num_irq_in_word = 32;
 
 for (i = 0; i < plic->bitfield_words; i++) {
 uint32_t pending_enabled_not_claimed =
@@ -88,7 +89,16 @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, 
uint32_t addrid)
 continue;
 }
 
-for (j = 0; j < 32; j++) {
+if (i == (plic->bitfield_words - 1)) {
+/*
+ * If plic->num_sources is not multiple of 32, num-of-irq in last
+ * word is not 32. Compute the num-of-irq of last word to avoid
+ * out-of-bound access of source_priority array.
+ */
+num_irq_in_word = plic->num_sources - ((plic->bitfield_words - 1) 
<< 5);
+}
+
+for (j = 0; j < num_irq_in_word; j++) {
 int irq = (i << 5) + j;
 uint32_t prio = plic->source_priority[irq];
 int enabled = pending_enabled_not_claimed & (1 << j);
-- 
2.38.1




[PULL v2 14/45] target/riscv: Enable native debug itrigger

2022-12-21 Thread Alistair Francis
From: LIU Zhiwei 

When QEMU is not in icount mode, execute instruction one by one. The
tdata1 can be read directly.

When QEMU is in icount mode, use a timer to simulate the itrigger. The
tdata1 may be not right because of lazy update of count in tdata1. Thus,
We should pack the adjusted count into tdata1 before read it back.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20221013062946.7530-4-zhiwei_...@linux.alibaba.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/debug.c | 72 
 1 file changed, 72 insertions(+)

diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 371862cf38..b3574b250f 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -624,10 +624,80 @@ void riscv_itrigger_update_priv(CPURISCVState *env)
 riscv_itrigger_update_count(env);
 }
 
+static target_ulong itrigger_validate(CPURISCVState *env,
+  target_ulong ctrl)
+{
+target_ulong val;
+
+/* validate the generic part first */
+val = tdata1_validate(env, ctrl, TRIGGER_TYPE_INST_CNT);
+
+/* validate unimplemented (always zero) bits */
+warn_always_zero_bit(ctrl, ITRIGGER_ACTION, "action");
+warn_always_zero_bit(ctrl, ITRIGGER_HIT, "hit");
+warn_always_zero_bit(ctrl, ITRIGGER_PENDING, "pending");
+
+/* keep the mode and attribute bits */
+val |= ctrl & (ITRIGGER_VU | ITRIGGER_VS | ITRIGGER_U | ITRIGGER_S |
+   ITRIGGER_M | ITRIGGER_COUNT);
+
+return val;
+}
+
+static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
+   int tdata_index, target_ulong val)
+{
+target_ulong new_val;
+
+switch (tdata_index) {
+case TDATA1:
+/* set timer for icount */
+new_val = itrigger_validate(env, val);
+if (new_val != env->tdata1[index]) {
+env->tdata1[index] = new_val;
+if (icount_enabled()) {
+env->last_icount = icount_get_raw();
+/* set the count to timer */
+timer_mod(env->itrigger_timer[index],
+  env->last_icount + itrigger_get_count(env, index));
+}
+}
+break;
+case TDATA2:
+qemu_log_mask(LOG_UNIMP,
+  "tdata2 is not supported for icount trigger\n");
+break;
+case TDATA3:
+qemu_log_mask(LOG_UNIMP,
+  "tdata3 is not supported for icount trigger\n");
+break;
+default:
+g_assert_not_reached();
+}
+
+return;
+}
+
+static int itrigger_get_adjust_count(CPURISCVState *env)
+{
+int count = itrigger_get_count(env, env->trigger_cur), executed;
+if ((count != 0) && check_itrigger_priv(env, env->trigger_cur)) {
+executed = icount_get_raw() - env->last_icount;
+count += executed;
+}
+return count;
+}
+
 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
 {
+int trigger_type;
 switch (tdata_index) {
 case TDATA1:
+trigger_type = extract_trigger_type(env, 
env->tdata1[env->trigger_cur]);
+if ((trigger_type == TRIGGER_TYPE_INST_CNT) && icount_enabled()) {
+return deposit64(env->tdata1[env->trigger_cur], 10, 14,
+ itrigger_get_adjust_count(env));
+}
 return env->tdata1[env->trigger_cur];
 case TDATA2:
 return env->tdata2[env->trigger_cur];
@@ -656,6 +726,8 @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, 
target_ulong val)
 type6_reg_write(env, env->trigger_cur, tdata_index, val);
 break;
 case TRIGGER_TYPE_INST_CNT:
+itrigger_reg_write(env, env->trigger_cur, tdata_index, val);
+break;
 case TRIGGER_TYPE_INT:
 case TRIGGER_TYPE_EXCP:
 case TRIGGER_TYPE_EXT_SRC:
-- 
2.38.1




[PULL v2 17/45] target/riscv: Typo fix in sstc() predicate

2022-12-21 Thread Alistair Francis
From: Anup Patel 

We should use "&&" instead of "&" when checking hcounteren.TM and
henvcfg.STCE bits.

Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
Signed-off-by: Anup Patel 
Reviewed-by: Alistair Francis 
Message-Id: <20221108125703.1463577-2-apa...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 71236f2b5d..0db2c233e5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -940,7 +940,7 @@ static RISCVException sstc(CPURISCVState *env, int csrno)
 }
 
 if (riscv_cpu_virt_enabled(env)) {
-if (!(get_field(env->hcounteren, COUNTEREN_TM) &
+if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
   get_field(env->henvcfg, HENVCFG_STCE))) {
 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
 }
-- 
2.38.1




[PULL v2 00/45] riscv-to-apply queue

2022-12-21 Thread Alistair Francis
From: Alistair Francis 

The following changes since commit 222059a0fccf4af3be776fe35a5ea2d6a68f9a0b:

  Merge tag 'pull-ppc-20221221' of https://gitlab.com/danielhb/qemu into 
staging (2022-12-21 18:08:09 +)

are available in the Git repository at:

  https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20221222-1

for you to fetch changes up to 71a9bc59728a054036f3db7dd82dab8f8bd2baf9:

  hw/intc: sifive_plic: Fix the pending register range check (2022-12-22 
08:36:30 +1000)


First RISC-V PR for QEMU 8.0

* Fix PMP propagation for tlb
* Collection of bug fixes
* Add the `FIELDx_1CLEAR()` macro
* Bump the OpenTitan supported version
* Add smstateen support
* Support native debug icount trigger
* Remove the redundant ipi-id property in the virt machine
* Support cache-related PMU events in virtual mode
* Add some missing PolarFire SoC io regions
* Fix mret exception cause when no pmp rule is configured
* Fix bug where disabling compressed instructions would crash QEMU
* Add Zawrs ISA extension support
* A range of code refactoring and cleanups


Anup Patel (1):
  target/riscv: Typo fix in sstc() predicate

Atish Patra (1):
  hw/riscv: virt: Remove the redundant ipi-id property

Bin Meng (20):
  target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state()
  target/riscv: Fix mret exception cause when no pmp rule is configured
  target/riscv: Simplify helper_sret() a little bit
  target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+
  hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC
  hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers
  hw/riscv: Fix opentitan dependency to SIFIVE_PLIC
  hw/riscv: Sort machines Kconfig options in alphabetical order
  hw/riscv: spike: Remove misleading comments
  hw/intc: sifive_plic: Drop PLICMode_H
  hw/intc: sifive_plic: Improve robustness of the PLIC config parser
  hw/intc: sifive_plic: Use error_setg() to propagate the error up via errp 
in sifive_plic_realize()
  hw/intc: sifive_plic: Update "num-sources" property default value
  hw/riscv: microchip_pfsoc: Fix the number of interrupt sources of PLIC
  hw/riscv: sifive_e: Fix the number of interrupt sources of PLIC
  hw/riscv: sifive_u: Avoid using magic number for "riscv, ndev"
  hw/riscv: virt: Fix the value of "riscv, ndev" in the dtb
  hw/intc: sifive_plic: Change "priority-base" to start from interrupt 
source 0
  hw/riscv: opentitan: Drop "hartid-base" and "priority-base" initialization
  hw/intc: sifive_plic: Fix the pending register range check

Christoph Muellner (1):
  RISC-V: Add Zawrs ISA extension support

Conor Dooley (3):
  hw/misc: pfsoc: add fabric clocks to ioscb
  hw/riscv: pfsoc: add missing FICs as unimplemented
  hw/{misc, riscv}: pfsoc: add system controller as unimplemented

Frédéric Pétrot (1):
  hw/intc: sifive_plic: Renumber the S irqs for numa support

Jim Shu (2):
  target/riscv: support cache-related PMU events in virtual mode
  hw/intc: sifive_plic: fix out-of-bound access of source_priority array

LIU Zhiwei (5):
  target/riscv: Fix PMP propagation for tlb
  target/riscv: Add itrigger support when icount is not enabled
  target/riscv: Add itrigger support when icount is enabled
  target/riscv: Enable native debug itrigger
  target/riscv: Add itrigger_enabled field to CPURISCVState

Mayuresh Chitale (3):
  target/riscv: Add smstateen support
  target/riscv: smstateen check for h/s/envcfg
  target/riscv: generate virtual instruction exception

Richard Henderson (4):
  tcg/riscv: Fix range matched by TCG_CT_CONST_M12
  tcg/riscv: Fix reg overlap case in tcg_out_addsub2
  tcg/riscv: Fix base register for user-only qemu_ld/st
  target/riscv: Set pc_succ_insn for !rvc illegal insn

Wilfred Mallawa (4):
  hw/registerfields: add `FIELDx_1CLEAR()` macro
  hw/ssi/ibex_spi: implement `FIELD32_1CLEAR` macro
  hw/riscv/opentitan: bump opentitan
  hw/riscv/opentitan: add aon_timer base unimpl

 include/hw/intc/sifive_plic.h  |   1 -
 include/hw/misc/mchp_pfsoc_ioscb.h |   4 +
 include/hw/misc/mchp_pfsoc_sysreg.h|   1 +
 include/hw/registerfields.h|  22 ++
 include/hw/riscv/microchip_pfsoc.h |   7 +-
 include/hw/riscv/opentitan.h   |  10 +-
 include/hw/riscv/shakti_c.h|   2 +-
 include/hw/riscv/sifive_e.h|   9 +-
 include/hw/riscv/sifive_u.h|   2 +-
 include/hw/riscv/virt.h|   8 +-
 target/riscv/cpu.h |  10 +
 target/riscv/cpu_bits.h|  37 +++
 target/riscv/debu

[PULL v2 06/45] tcg/riscv: Fix base register for user-only qemu_ld/st

2022-12-21 Thread Alistair Francis
From: Richard Henderson 

When guest_base != 0, we were not coordinating the usage of
TCG_REG_TMP0 as base properly, leading to a previous zero-extend
of the input address being discarded.

Shuffle the alignment check to the front, because that does not
depend on the zero-extend, and it keeps the register usage clear.
Set base after each step of the address arithmetic instead of before.

Return the base register used from tcg_out_tlb_load, so as to
keep that register choice localized to that function.

Reported-by: LIU Zhiwei 
Signed-off-by: Richard Henderson 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <2022102327.2846860-1-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 tcg/riscv/tcg-target.c.inc | 39 +-
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 2a84c57bec..e3b608034f 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -923,9 +923,9 @@ static void tcg_out_goto(TCGContext *s, const tcg_insn_unit 
*target)
 tcg_debug_assert(ok);
 }
 
-static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
- TCGReg addrh, MemOpIdx oi,
- tcg_insn_unit **label_ptr, bool is_load)
+static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
+   TCGReg addrh, MemOpIdx oi,
+   tcg_insn_unit **label_ptr, bool is_load)
 {
 MemOp opc = get_memop(oi);
 unsigned s_bits = opc & MO_SIZE;
@@ -975,6 +975,7 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
 addrl = TCG_REG_TMP0;
 }
 tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addrl);
+return TCG_REG_TMP0;
 }
 
 static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi,
@@ -1177,7 +1178,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is_64)
 #else
 unsigned a_bits;
 #endif
-TCGReg base = TCG_REG_TMP0;
+TCGReg base;
 
 data_regl = *args++;
 data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
@@ -1187,23 +1188,25 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is_64)
 opc = get_memop(oi);
 
 #if defined(CONFIG_SOFTMMU)
-tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
+base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
 tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
 add_qemu_ldst_label(s, 1, oi,
 (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
 data_regl, data_regh, addr_regl, addr_regh,
 s->code_ptr, label_ptr);
 #else
-if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
-tcg_out_ext32u(s, base, addr_regl);
-addr_regl = base;
-}
 a_bits = get_alignment_bits(opc);
 if (a_bits) {
 tcg_out_test_alignment(s, true, addr_regl, a_bits);
 }
+base = addr_regl;
+if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+tcg_out_ext32u(s, TCG_REG_TMP0, base);
+base = TCG_REG_TMP0;
+}
 if (guest_base != 0) {
-tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
+tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
+base = TCG_REG_TMP0;
 }
 tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
 #endif
@@ -1249,7 +1252,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 #else
 unsigned a_bits;
 #endif
-TCGReg base = TCG_REG_TMP0;
+TCGReg base;
 
 data_regl = *args++;
 data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
@@ -1259,23 +1262,25 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is_64)
 opc = get_memop(oi);
 
 #if defined(CONFIG_SOFTMMU)
-tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
+base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
 tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
 add_qemu_ldst_label(s, 0, oi,
 (is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
 data_regl, data_regh, addr_regl, addr_regh,
 s->code_ptr, label_ptr);
 #else
-if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
-tcg_out_ext32u(s, base, addr_regl);
-addr_regl = base;
-}
 a_bits = get_alignment_bits(opc);
 if (a_bits) {
 tcg_out_test_alignment(s, false, addr_regl, a_bits);
 }
+base = addr_regl;
+if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+tcg_out_ext32u(s, TCG_REG_TMP0, base);
+base = TCG_REG_TMP0;
+}
 if (guest_base != 0) {
-tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
+tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
+base = TCG_REG_TMP0;
 }
 

Re: [RFC PATCH-for-8.0 2/3] hw/ppc/spapr: Replace tswap64(HPTE) by cpu_to_be64(HPTE)

2022-12-21 Thread Peter Maydell
On Wed, 21 Dec 2022 at 16:03, Cédric Le Goater  wrote:
>
> On 12/21/22 13:33, Peter Maydell wrote:
> > On Wed, 21 Dec 2022 at 01:35, David Gibson  
> > wrote:
> >> On Mon, Dec 19, 2022 at 10:39:40AM +, Peter Maydell wrote:
> >>> OK. I still think we should consistently change all the places that are
> >>> accessing this data structure, though, not just half of them.
> >>
> >> Yes, that makes sense.  Although what exactly constitutes "this data
> >> structure" is a bit complex here.  If we mean just the spapr specific
> >> "external HPT", then there are only a few more references to it.  If
> >> we mean all instances of a powerpc hashed page table, then there are a
> >> bunch more in the cpu target code.
> >
> > I had in mind "places where we write this specific array of bytes
> > spapr->htab".
>
>
> spapr_store_hpte() seems to be the most annoying part. It is used
> by hcalls h_enter, h_remove, h_protect. Reworking the interface
> to present pte0/pte1 as BE variables means reworking the whole
> hw/ppc/spapr_softmmu.c file. That's feasible but not a small task
> since the changes will root down in the target hash mmu code which
> is shared by all platforms ... :/

Don't you just need to change spapr_store_hpte() to use stq_be_p()
instead of stq_p() ?

> spapr_hpte_set_c() are spapr_hpte_set_r() are of a different kind.

That code seems to suggest we already implicitly assume that
spapr->htab fields have a given endianness...

thanks
-- PMM



Re: [PULL v2 00/14] ppc queue

2022-12-21 Thread Peter Maydell
On Wed, 21 Dec 2022 at 17:21, Daniel Henrique Barboza
 wrote:
>
> v2: removed patch that was breaking clang tests. Thanks,
>
> Daniel
>
> --
>
> The following changes since commit 700ce3b1bb52da4acbbf1ad8f6256baaf52c7953:
>
>   Merge tag 'pull-tcg-20221220' of https://gitlab.com/rth7680/qemu into 
> staging (2022-12-21 14:15:18 +)
>
> are available in the Git repository at:
>
>   https://gitlab.com/danielhb/qemu.git tags/pull-ppc-20221221
>
> for you to fetch changes up to 4091fabfeb54f02762bdecba7344353c56533873:
>
>   target/ppc: Check DEXCR on hash{st, chk} instructions (2022-12-21 14:17:55 
> -0300)
>
> 
> ppc patch queue for 2022-12-21:
>
> This queue contains a MAINTAINERS update, the implementation of the Freescale 
> eSDHC,
> the introduction of the DEXCR/HDEXCR instructions and other assorted fixes 
> (most of
> them for the e500 board).
>
> 


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/8.0
for any user-visible changes.

-- PMM



Re: [PATCH v3 0/5] coroutine: Clean up includes

2022-12-21 Thread Philippe Mathieu-Daudé

On 21/12/22 14:14, Markus Armbruster wrote:

v3:
* PATCH 4: Unnecessary hunks dropped

v2:
* Rebased
* PATCH 4: Rewritten [Paolo]
* PATCH 5: New

Markus Armbruster (5):
   coroutine: Clean up superfluous inclusion of qemu/coroutine.h
   coroutine: Move coroutine_fn to qemu/osdep.h, trim includes
   coroutine: Clean up superfluous inclusion of qemu/lockable.h
   coroutine: Split qemu/coroutine-core.h off qemu/coroutine.h
   coroutine: Use Coroutine typedef name instead of structure tag


I had to add:

-- >8 --
diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c
index fb7591d6ab..b09fce9377 100644
--- a/hw/pci/pci-hmp-cmds.c
+++ b/hw/pci/pci-hmp-cmds.c
@@ -15,6 +15,7 @@

 #include "qemu/osdep.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_device.h"
 #include "monitor/hmp.h"
 #include "monitor/monitor.h"
 #include "pci-internal.h"
diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c
index 8e7282658f..3d4497da99 100644
--- a/hw/virtio/virtio-qmp.c
+++ b/hw/virtio/virtio-qmp.c
@@ -11,6 +11,7 @@

 #include "qemu/osdep.h"
 #include "hw/virtio/virtio.h"
+#include "hw/virtio/vhost.h"
 #include "virtio-qmp.h"

---

Otherwise I get:

../hw/pci/pci-hmp-cmds.c: In function ‘pcibus_dev_print’:
../hw/pci/pci-hmp-cmds.c:129:31: error: invalid use of incomplete 
typedef ‘PCIDevice’

  129 | int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
  |   ^~

../hw/virtio/virtio-qmp.c:187:19: error: 
‘VHOST_USER_F_PROTOCOL_FEATURES’ undeclared here (not in a function); 
did you mean ‘VHOST_USER_PROTOCOL_F_RARP’?

  187 | FEATURE_ENTRY(VHOST_USER_F_PROTOCOL_FEATURES, \
  |   ^~


Maybe some recently merged change?

Otherwise:
Tested-by: Philippe Mathieu-Daudé 




Re: [PATCH v2 1/5] exec/memory: Expose memory_region_access_valid()

2022-12-21 Thread Eric Farman
On Sat, 2022-12-17 at 16:24 +0100, Philippe Mathieu-Daudé wrote:
> Instead of having hardware device poking into memory
> internal API, expose memory_region_access_valid().
> 
> Reviewed-by: Richard Henderson 
> Signed-off-by: Philippe Mathieu-Daudé 

That's the only memory_region_ function s390 calls that isn't already
in memory.h, so makes sense to me.

Reviewed-by: Eric Farman 

> ---
>  hw/s390x/s390-pci-inst.c   | 2 +-
>  include/exec/memory-internal.h | 4 
>  include/exec/memory.h  | 4 
>  3 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
> index 66e764f901..35dbe4 100644
> --- a/hw/s390x/s390-pci-inst.c
> +++ b/hw/s390x/s390-pci-inst.c
> @@ -13,7 +13,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "exec/memop.h"
> -#include "exec/memory-internal.h"
> +#include "exec/memory.h"
>  #include "qemu/error-report.h"
>  #include "sysemu/hw_accel.h"
>  #include "hw/s390x/s390-pci-inst.h"
> diff --git a/include/exec/memory-internal.h b/include/exec/memory-
> internal.h
> index 9fcc2af25c..100c1237ac 100644
> --- a/include/exec/memory-internal.h
> +++ b/include/exec/memory-internal.h
> @@ -38,10 +38,6 @@ void flatview_unref(FlatView *view);
>  
>  extern const MemoryRegionOps unassigned_mem_ops;
>  
> -bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
> -    unsigned size, bool is_write,
> -    MemTxAttrs attrs);
> -
>  void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection
> *section);
>  AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
>  void address_space_dispatch_compact(AddressSpaceDispatch *d);
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index 91f8a2395a..c37ffdbcd1 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -2442,6 +2442,10 @@ void memory_global_dirty_log_stop(unsigned int
> flags);
>  
>  void mtree_info(bool flatview, bool dispatch_tree, bool owner, bool
> disabled);
>  
> +bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
> +    unsigned size, bool is_write,
> +    MemTxAttrs attrs);
> +
>  /**
>   * memory_region_dispatch_read: perform a read directly to the
> specified
>   * MemoryRegion.




RE: [PATCH v2] Hexagon (target/hexagon) implement mutability mask for GPRs

2022-12-21 Thread Marco Liebel
> > +#define WRITE_REG_IN_PACKET(reg_name, output, input) \
> > +asm volatile("{ " reg_name " = %1 }\n\t" \
> 
> This is no different from the WRITE_REG above.  Instructions on a line with
> no curly braces are a single packet.
> 

Understood. The feedback on Brian's patch said to write tests that do transfers
in a packet. Should I write some? (Just not in the way I did it above)

> > +
> > +/*
> > + * Instruction word: { pc = r0 }
> > + *
> > + * This instruction is barred by the assembler.
> > + *
> > + *3   2   1
> > + *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
> > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > + * |Opc[A2_tfrrcr]   | Src[R0] |P P| |  C9/PC  |
> > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > + */
> > +#define PC_EQ_R0".word 0x6220c009\n\t"
> > +#define GP_EQ_R0".word 0x6220c00b\n\t"
> > +#define UPCYCLELO_EQ_R0 ".word 0x6220c00e\n\t"
> > +#define UPCYCLEHI_EQ_R0 ".word 0x6220c00f\n\t"
> > +#define UTIMERLO_EQ_R0  ".word 0x6220c01e\n\t"
> > +#define UTIMERHI_EQ_R0  ".word 0x6220c01f\n\t"
> > +
> > +#define C9_8_EQ_R1_0".word 0x6320c008\n\t"
> > +#define C11_10_EQ_R1_0  ".word 0x6320c00a\n\t"
> > +#define C15_14_EQ_R1_0  ".word 0x6320c00e\n\t"
> > +#define C31_30_EQ_R1_0  ".word 0x6320c01e\n\t"
> 
> Only the assignment to PC and C9 (which is an alias for PC) are not allowed by
> the assembler.  For the others, use the normal assembly syntax.
> 

I used the regular names at first, but when running `make check-tcg` it 
generates
errors. For example:
 error: unknown register name 'gp' in asm WRITE_REG(result, "gp", 
0x);

Should I use them anyway?



Re: [PATCH v3 1/2] tpm: convert tpmdev options processing to new visitor format

2022-12-21 Thread James Bottomley
On Wed, 2022-12-21 at 16:32 +, Daniel P. Berrangé wrote:
> This isn't a valid change todo, as it affects the public facing
> data structure for the  query-tpm command.
> 
> I understand why you're doing it though, to get rid fo the
> extra nesting, which is a hangover from earlier QAPI days
> where we couldn't cope with flat unions.
> 
> Instead of changing TpmTypeOptions, you'll need to introduce
> a new TpmTypeCreateOptions that eliminates the wrapping, and
> use that in the CLI creation path, leaving the query-tpm
> command unchanged.


Well, it makes the diffstat less favourable, but how about this (I'm
also assuming I don't need to wrapper the new mssim options)?

James

---

 backends/tpm/tpm_emulator.c| 24 -
 backends/tpm/tpm_passthrough.c | 27 +++---
 include/sysemu/tpm.h   |  4 +-
 include/sysemu/tpm_backend.h   |  2 +-
 qapi/tpm.json  | 19 +++
 softmmu/tpm.c  | 90 ++
 softmmu/vl.c   | 19 +--
 7 files changed, 76 insertions(+), 109 deletions(-)

diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 49cc3d749d..cb6bf9d7c2 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -584,33 +584,28 @@ err_exit:
 return -1;
 }
 
-static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, QemuOpts 
*opts)
+static int tpm_emulator_handle_device_opts(TPMEmulator *tpm_emu, 
TpmCreateOptions *opts)
 {
-const char *value;
 Error *err = NULL;
 Chardev *dev;
 
-value = qemu_opt_get(opts, "chardev");
-if (!value) {
-error_report("tpm-emulator: parameter 'chardev' is missing");
-goto err;
-}
+tpm_emu->options = QAPI_CLONE(TPMEmulatorOptions, >u.emulator);
+tpm_emu->data_ioc = NULL;
 
-dev = qemu_chr_find(value);
+dev = qemu_chr_find(opts->u.emulator.chardev);
 if (!dev) {
-error_report("tpm-emulator: tpm chardev '%s' not found", value);
+error_report("tpm-emulator: tpm chardev '%s' not found",
+opts->u.emulator.chardev);
 goto err;
 }
 
 if (!qemu_chr_fe_init(_emu->ctrl_chr, dev, )) {
 error_prepend(, "tpm-emulator: No valid chardev found at '%s':",
-  value);
+  opts->u.emulator.chardev);
 error_report_err(err);
 goto err;
 }
 
-tpm_emu->options->chardev = g_strdup(value);
-
 if (tpm_emulator_prepare_data_fd(tpm_emu) < 0) {
 goto err;
 }
@@ -649,7 +644,7 @@ err:
 return -1;
 }
 
-static TPMBackend *tpm_emulator_create(QemuOpts *opts)
+static TPMBackend *tpm_emulator_create(TpmCreateOptions *opts)
 {
 TPMBackend *tb = TPM_BACKEND(object_new(TYPE_TPM_EMULATOR));
 
@@ -972,7 +967,6 @@ static void tpm_emulator_inst_init(Object *obj)
 
 trace_tpm_emulator_inst_init();
 
-tpm_emu->options = g_new0(TPMEmulatorOptions, 1);
 tpm_emu->cur_locty_number = ~0;
 qemu_mutex_init(_emu->mutex);
 tpm_emu->vmstate =
@@ -990,7 +984,7 @@ static void tpm_emulator_shutdown(TPMEmulator *tpm_emu)
 {
 ptm_res res;
 
-if (!tpm_emu->options->chardev) {
+if (!tpm_emu->data_ioc) {
 /* was never properly initialized */
 return;
 }
diff --git a/backends/tpm/tpm_passthrough.c b/backends/tpm/tpm_passthrough.c
index 5a2f74db1b..f9771eaf1f 100644
--- a/backends/tpm/tpm_passthrough.c
+++ b/backends/tpm/tpm_passthrough.c
@@ -252,23 +252,11 @@ static int 
tpm_passthrough_open_sysfs_cancel(TPMPassthruState *tpm_pt)
 }
 
 static int
-tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, QemuOpts *opts)
+tpm_passthrough_handle_device_opts(TPMPassthruState *tpm_pt, TpmCreateOptions 
*opts)
 {
-const char *value;
+tpm_pt->options = QAPI_CLONE(TPMPassthroughOptions, >u.passthrough);
 
-value = qemu_opt_get(opts, "cancel-path");
-if (value) {
-tpm_pt->options->cancel_path = g_strdup(value);
-tpm_pt->options->has_cancel_path = true;
-}
-
-value = qemu_opt_get(opts, "path");
-if (value) {
-tpm_pt->options->has_path = true;
-tpm_pt->options->path = g_strdup(value);
-}
-
-tpm_pt->tpm_dev = value ? value : TPM_PASSTHROUGH_DEFAULT_DEVICE;
+tpm_pt->tpm_dev = opts->u.passthrough.has_path ? opts->u.passthrough.path 
: TPM_PASSTHROUGH_DEFAULT_DEVICE;
 tpm_pt->tpm_fd = qemu_open_old(tpm_pt->tpm_dev, O_RDWR);
 if (tpm_pt->tpm_fd < 0) {
 error_report("Cannot access TPM device using '%s': %s",
@@ -290,11 +278,11 @@ tpm_passthrough_handle_device_opts(TPMPassthruState 
*tpm_pt, QemuOpts *opts)
 return 0;
 }
 
-static TPMBackend *tpm_passthrough_create(QemuOpts *opts)
+static TPMBackend *tpm_passthrough_create(TpmCreateOptions *tco)
 {
 Object *obj = object_new(TYPE_TPM_PASSTHROUGH);
 
-if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), opts)) {
+if (tpm_passthrough_handle_device_opts(TPM_PASSTHROUGH(obj), tco)) {
 

RE: [PATCH v2] Hexagon (target/hexagon) implement mutability mask for GPRs

2022-12-21 Thread Taylor Simpson



> -Original Message-
> From: Marco Liebel 
> Sent: Wednesday, December 21, 2022 1:34 PM
> To: Taylor Simpson ; Marco Liebel (QUIC)
> ; qemu-devel@nongnu.org
> Cc: Brian Cain 
> Subject: RE: [PATCH v2] Hexagon (target/hexagon) implement mutability
> mask for GPRs
> 
> > > +#define WRITE_REG_IN_PACKET(reg_name, output, input) \
> > > +asm volatile("{ " reg_name " = %1 }\n\t" \
> >
> > This is no different from the WRITE_REG above.  Instructions on a line
> > with no curly braces are a single packet.
> >
> 
> Understood. The feedback on Brian's patch said to write tests that do
> transfers in a packet. Should I write some? (Just not in the way I did it 
> above)

Put some more instructions in the packet with the assignment.  I recommend a 
read from the same register and verify you get the old value.

> 
> > > +
> > > +/*
> > > + * Instruction word: { pc = r0 }
> > > + *
> > > + * This instruction is barred by the assembler.
> > > + *
> > > + *3   2   1
> > > + *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
> > > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > > + * |Opc[A2_tfrrcr]   | Src[R0] |P P| |  C9/PC  |
> > > + *
> > > ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > > + */
> > > +#define PC_EQ_R0".word 0x6220c009\n\t"
> > > +#define GP_EQ_R0".word 0x6220c00b\n\t"
> > > +#define UPCYCLELO_EQ_R0 ".word 0x6220c00e\n\t"
> > > +#define UPCYCLEHI_EQ_R0 ".word 0x6220c00f\n\t"
> > > +#define UTIMERLO_EQ_R0  ".word 0x6220c01e\n\t"
> > > +#define UTIMERHI_EQ_R0  ".word 0x6220c01f\n\t"
> > > +
> > > +#define C9_8_EQ_R1_0".word 0x6320c008\n\t"
> > > +#define C11_10_EQ_R1_0  ".word 0x6320c00a\n\t"
> > > +#define C15_14_EQ_R1_0  ".word 0x6320c00e\n\t"
> > > +#define C31_30_EQ_R1_0  ".word 0x6320c01e\n\t"
> >
> > Only the assignment to PC and C9 (which is an alias for PC) are not
> > allowed by the assembler.  For the others, use the normal assembly syntax.
> >
> 
> I used the regular names at first, but when running `make check-tcg` it
> generates errors. For example:
>  error: unknown register name 'gp' in asm WRITE_REG(result, "gp",
> 0x);
> 
> Should I use them anyway?

Don't use the WRITE_REG macro because that puts reg_name in the clobbers list 
and the compiler doesn't know about these registers.  If you use the 
WRITE_REG_ENCODED macro, it should work - though you might want to change the 
name of the macro to WRITE_REG_NOCLOBBER.

Thanks,
Taylor





[PATCH RFC v2 0/1] tests: add wasmtime testsuite

2022-12-21 Thread Ilya Leoshkevich
Hi,

I made some updates based on the feedback from Alex.

At the moment it mostly works for me on top of 6394578984da: aarch64,
riscv64 and s390x are clean, but there are some failures on x86_64.
With qemu-user vma rework it unfortunately fails in more places;
I haven't analyzed these failures yet.

v1: https://lists.gnu.org/archive/html/qemu-devel/2022-07/msg00657.html
https://lists.gnu.org/archive/html/qemu-devel/2022-12/msg02612.html

v1 -> v2:
* Drop gitlab jobs.
* Move to tests/third-party/.
* Use avocado. To be honest, I'm not sure how much value it brings
  here; I hoped that TAPRunner would at least print the number of
  passed tests, but it only checks whether at least one test failed).
* Add various check-* Makefile targets.
* Add json -> TAP 14 conversion.
* Add documentation.
* Move test binaries to the host system.
  This prevents unnecessary full rebuilds of the Docker image.
* Add riscv64; bump Rust and Wasmtime versions.
* Do not use docker.py; unfortunately this leads to reimplementing some
  of its features: docker command detection based on $(ENGINE) and
  injecting the current user into the image.
* Disable core dumps.

Best regards,
Ilya

Ilya Leoshkevich (1):
  tests: add wasmtime testsuite

 Makefile |  1 +
 docs/devel/testing.rst   |  9 +++
 tests/Makefile.include   |  6 ++
 tests/third-party/Makefile.include   | 50 
 tests/third-party/wasmtime/Dockerfile| 32 
 tests/third-party/wasmtime/Makefile.include  | 49 
 tests/third-party/wasmtime/avocado-wrapper   | 38 +
 tests/third-party/wasmtime/avocado.cfg   |  3 +
 tests/third-party/wasmtime/json2tap  | 77 ++
 tests/third-party/wasmtime/run-tests-wrapper | 82 
 tests/third-party/wasmtime/test  | 48 
 11 files changed, 395 insertions(+)
 create mode 100644 tests/third-party/Makefile.include
 create mode 100644 tests/third-party/wasmtime/Dockerfile
 create mode 100644 tests/third-party/wasmtime/Makefile.include
 create mode 100755 tests/third-party/wasmtime/avocado-wrapper
 create mode 100644 tests/third-party/wasmtime/avocado.cfg
 create mode 100755 tests/third-party/wasmtime/json2tap
 create mode 100755 tests/third-party/wasmtime/run-tests-wrapper
 create mode 100755 tests/third-party/wasmtime/test

-- 
2.38.1




[PATCH RFC v2 1/1] tests: add wasmtime testsuite

2022-12-21 Thread Ilya Leoshkevich
wasmtime is a WebAssembly runtime, which includes a large testsuite.
This testsuite uses qemu-user (aarch64, riscv64, s390x and x86_64 are
supported) in order to exercise foreign architectures. Over time it
found several regressions in qemu itself, and it would be beneficial to
catch the similar ones earlier.

To this end, this patch introduces Makefile targets that run stable
wasmtime testsuite against qemu-{aarch64,riscv64,s390x,x86_64}.

Signed-off-by: Ilya Leoshkevich 
---
 Makefile |  1 +
 docs/devel/testing.rst   |  9 +++
 tests/Makefile.include   |  6 ++
 tests/third-party/Makefile.include   | 50 
 tests/third-party/wasmtime/Dockerfile| 32 
 tests/third-party/wasmtime/Makefile.include  | 49 
 tests/third-party/wasmtime/avocado-wrapper   | 38 +
 tests/third-party/wasmtime/avocado.cfg   |  3 +
 tests/third-party/wasmtime/json2tap  | 77 ++
 tests/third-party/wasmtime/run-tests-wrapper | 82 
 tests/third-party/wasmtime/test  | 48 
 11 files changed, 395 insertions(+)
 create mode 100644 tests/third-party/Makefile.include
 create mode 100644 tests/third-party/wasmtime/Dockerfile
 create mode 100644 tests/third-party/wasmtime/Makefile.include
 create mode 100755 tests/third-party/wasmtime/avocado-wrapper
 create mode 100644 tests/third-party/wasmtime/avocado.cfg
 create mode 100755 tests/third-party/wasmtime/json2tap
 create mode 100755 tests/third-party/wasmtime/run-tests-wrapper
 create mode 100755 tests/third-party/wasmtime/test

diff --git a/Makefile b/Makefile
index a48103cc8a1..3a5250d3e46 100644
--- a/Makefile
+++ b/Makefile
@@ -287,6 +287,7 @@ export DESTDIR
 include $(SRC_PATH)/tests/lcitool/Makefile.include
 include $(SRC_PATH)/tests/docker/Makefile.include
 include $(SRC_PATH)/tests/vm/Makefile.include
+include $(SRC_PATH)/tests/third-party/Makefile.include
 
 print-help-run = printf "  %-30s - %s\\n" "$1" "$2"
 print-help = @$(call print-help-run,$1,$2)
diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index e10c47b5a7c..0cbbcae4bcd 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -1475,3 +1475,12 @@ coverage-html`` which will create
 Further analysis can be conducted by running the ``gcov`` command
 directly on the various .gcda output files. Please read the ``gcov``
 documentation for more information.
+
+Third-party testsuites
+~~
+
+Various third-party projects contain testsuites that exercise non-trivial
+machine instructions or Linux kernel interfaces. While they may be too big for
+the gating CI, developers can use the corresponding make targets to verify
+their changes. The list of these targets can be found in the "Third-party
+testing targets" section of ``make check-help`` output.
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 9422ddaece5..506fe5ab16a 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -22,6 +22,12 @@ endif
@echo " $(MAKE) check-venv Creates a Python venv for tests"
@echo " $(MAKE) check-cleanClean the tests and related data"
@echo
+   @echo "Third-party testing targets:"
+   @echo " $(MAKE) check-third-party Run third-party tests for all 
supported targets"
+   @echo " $(MAKE) check-third-party-TARGET  Run third-party tests for 
given target"
+   @echo " $(MAKE) check-wasmtimeRun wasmtime tests for all 
supported targets"
+   @echo " $(MAKE) check-wasmtime-TARGET Run wasmtime tests for given 
target"
+   @echo
@echo "The following are useful for CI builds"
@echo " $(MAKE) check-buildBuild most test binaries"
@echo " $(MAKE) get-vm-images  Downloads all images used by 
avocado tests, according to configured targets (~350 MB each, 1.5 GB max)"
diff --git a/tests/third-party/Makefile.include 
b/tests/third-party/Makefile.include
new file mode 100644
index 000..2d45d7c4260
--- /dev/null
+++ b/tests/third-party/Makefile.include
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Makefile for testing QEMU with third-party testsuites.
+
+# Known docker-like commands.
+DOCKER_COMMAND_PODMAN = podman
+DOCKER_COMMAND_DOCKER = docker
+DOCKER_COMMAND_SUDO_DOCKER = sudo -n docker
+DOCKER_COMMAND_NONE = /bin/false
+
+# Mapping from $(ENGINE) to the respective docker-like commands.
+DOCKER_COMMAND_CANDIDATES_auto = PODMAN DOCKER SUDO_DOCKER
+DOCKER_COMMAND_CANDIDATES_podman = PODMAN
+DOCKER_COMMAND_CANDIDATES_docker = DOCKER SUDO_DOCKER
+
+# Select the docker-like command based on $(ENGINE).
+DOCKER_COMMAND = $(DOCKER_COMMAND_NONE)
+define try_docker_command
+ifeq ($(DOCKER_COMMAND),$(DOCKER_COMMAND_NONE))
+ifeq ($(shell $(DOCKER_COMMAND_$(1)) version >/dev/null 2>&1 || echo ?),)
+DOCKER_COMMAND = $(DOCKER_COMMAND_$(1))
+endif
+endif

Re: [PATCH v4 00/30] This series consolidates the implementations of the PIIX3 and PIIX4 south

2022-12-21 Thread Philippe Mathieu-Daudé

On 21/12/22 17:59, Bernhard Beschow wrote:

code as possible and to bring both device models to feature parity such that
perhaps PIIX4 can become a drop-in-replacement for PIIX3 in the pc machine. This
could resolve the "Frankenstein" PIIX4-PM problem in PIIX3 discussed on this
list before.

The series is structured as follows: First, PIIX3 is changed to instantiate
internal devices itself, like PIIX4 does already. Second, PIIX3 gets prepared
for the merge with PIIX4 which includes some fixes, cleanups, and renamings.
Third, the same is done for PIIX4. In step four the implementations are merged.
Since some consolidations could be done easier with merged implementations, the
consolidation continues in step five which concludes the series.

One particular challenge in this series was that the PIC of PIIX3 used to be
instantiated outside of the south bridge while some sub functions require a PIC
with populated qemu_irqs. This has been solved by introducing a proxy PIC which
furthermore allows PIIX3 to be agnostic towards the virtualization technology
used (KVM, TCG, Xen). Due to consolidation PIIX4 gained the proxy PIC as well.

Another challenge was dealing with optional devices where Peter already gave
advice in [1] which this series implements.

Last but not least there might be some opportunity to consolidate VM state
handling, probably by reusing the one from PIIX3. Since I'm not very familiar
with the requirements I didn't touch it so far.

v4:
- Rebase onto "[PATCH v2 0/3] Decouple INTx-to-LNKx routing from south bridges"
   since it is already queued via mips-next. This eliminates patches
   'hw/isa/piix3: Prefix pci_slot_get_pirq() with "piix3_"' and 'hw/isa/piix4:
   Prefix pci_slot_get_pirq() with "piix4_"'.
- Squash 'hw/isa/piix: Drop the "3" from the PIIX base class' into
   'hw/isa/piix3: Rename typedef PIIX3State to PIIXState'. I originally only
   split these patches since I wasn't sure whether renaming a type was allowed.
- Add new patch 'hw/i386/pc_piix: Associate pci_map_irq_fn as soon as PCI bus is
   created' for forther cleanup of INTx-to-LNKx route decoupling.


Sigh I did the rebase this morning and was waiting for the test suite...
https://gitlab.com/philmd/qemu/-/commits/mips-testing/

Anyway I'll double-check with this series.



Re: [PATCH v2 0/7] Clean up dependencies of ACPI controllers

2022-12-21 Thread Michael S. Tsirkin
On Wed, Dec 21, 2022 at 05:56:56PM +, Bernhard Beschow wrote:
> 
> 
> Am 16. Dezember 2022 13:03:48 UTC schrieb Bernhard Beschow 
> :
> >This small series establishes consistency between ICH9, PIIX4 and VT82C686 
> >ACPI
> >
> >controllers to select ACPI, ACPI_SMBUS and APM since they are provided by the
> >
> >device models.
> >
> >
> >
> >Due to the PIIX4 PM cleanup PEGASOS2's dependency can be reduced to just 
> >ACPI,
> >
> >eliminating 9 dependencies from the softmmu-ppc build.
> >
> 
> Ping
> 
> Looks like all patches are reviewed, i.e. ready to be queued.
> 
> Best regards,
> Bernhard


Sure, next pull.

> >
> >
> >v2:
> >
> >- Turn "depends on ACPI" into "select ACPI" (Phil)
> >
> >- Remove "select ACPI" from PEGASOS2 (Phil)
> >
> >- Move already reviewed patches to bottom
> >
> >- Split some patches into "add missing dependencies" and "remove redundant
> >
> >  dependencies" for ease of review
> >
> >
> >
> >Bernhard Beschow (7):
> >
> >  hw/acpi/Kconfig: Rename ACPI_X86_ICH to ACPI_ICH9
> >
> >  hw/acpi/Kconfig: Add missing dependencies to ACPI_ICH9
> >
> >  hw/acpi/Kconfig: Do not needlessly build TYPE_PIIX4_PM in non-PC/Malta
> >
> >machines
> >
> >  hw/acpi/Kconfig: Add missing dependencies to ACPI_PIIX4
> >
> >  hw/isa/Kconfig: Add missing dependency to VT82C686
> >
> >  i386, mips: Resolve redundant ACPI and APM dependencies
> >
> >  hw/ppc/Kconfig: Remove unused dependencies from PEGASOS2
> >
> >
> >
> > configs/devices/mips-softmmu/common.mak | 3 ---
> >
> > hw/acpi/Kconfig | 9 ++---
> >
> > hw/acpi/meson.build | 2 +-
> >
> > hw/i2c/meson.build  | 2 +-
> >
> > hw/i386/Kconfig | 3 +--
> >
> > hw/isa/Kconfig  | 4 ++--
> >
> > hw/ppc/Kconfig  | 2 --
> >
> > 7 files changed, 11 insertions(+), 14 deletions(-)
> >
> >
> >
> >-- >
> >2.39.0
> >
> >
> >




Re: [RFC PATCH 3/6] hw/cxl/cxl-events: Add CXL mock events

2022-12-21 Thread Ira Weiny
On Mon, Dec 19, 2022 at 10:07:23AM +, Jonathan Cameron wrote:
> On Mon, 10 Oct 2022 15:29:41 -0700
> ira.we...@intel.com wrote:
> 
> > From: Ira Weiny 
> > 
> > To facilitate testing of guest software add mock events and code to
> > support iterating through the event logs.
> > 
> > Signed-off-by: Ira Weiny 
> 
> An FYI for the next version as I hit an issue with this when
> testing resets (there are lots of other issues with resets
> but this one crashed QEMU :)
> 
> > ---
> 
> > +static void event_store_add_event(CXLDeviceState *cxlds,
> > +  enum cxl_event_log_type log_type,
> > +  struct cxl_event_record_raw *event)
> > +{
> > +struct cxl_event_log *log;
> > +
> > +assert(log_type < CXL_EVENT_TYPE_MAX);
> > +
> > +log = >event_logs[log_type];
> > +assert(log->nr_events < CXL_TEST_EVENT_CNT_MAX);
> 
> This assert triggers on a reset as the function is called without
> clearing the buffer first.

Not quite sure what happened there. But this code is completely gone in the new
version.  As is the mass insertion of events at start up.  I've jettisoned all
that in favor of the QMP injection of individual events.

I should be sending out a new version today.  It is based on cxl-2022-11-17.  I
I believe it is much cleaner.  But I'm only supporting general media event
right now.  The others can be added pretty easily but I want to get the
infrastructure settled before working on those.

Ira

> 
> I'd suggest moving the setup of any dummy events over to a code
> path that isn't run on reset.
> 
> 
> > +
> > +log->events[log->nr_events] = event;
> > +log->nr_events++;
> > +}
> 



[PATCH] hw/net: Fix read of uninitialized memory in imx_fec.

2022-12-21 Thread Stephen Longfield
Size is used at lines 1088/1188 for the loop, which reads the last 4
bytes from the crc_ptr so it does need to get increased, however it
shouldn't be increased before the buffer is passed to CRC computation,
or the crc32 function will access uninitialized memory.

This was pointed out to me by c...@kaod.org during the code review of
a similar patch to hw/net/ftgmac100.c

Change-Id: Ib0464303b191af1e28abeb2f5105eb25aadb5e9b
Signed-off-by: Stephen Longfield 
Reviewed-by: Patrick Venture 
---
 hw/net/imx_fec.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 8c11b237de..c862d96593 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1068,9 +1068,9 @@ static ssize_t imx_fec_receive(NetClientState *nc, const 
uint8_t *buf,
 return 0;
 }

-/* 4 bytes for the CRC.  */
-size += 4;
 crc = cpu_to_be32(crc32(~0, buf, size));
+/* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */
+size += 4;
 crc_ptr = (uint8_t *) 

 /* Huge frames are truncated.  */
@@ -1164,9 +1164,9 @@ static ssize_t imx_enet_receive(NetClientState *nc, const 
uint8_t *buf,
 return 0;
 }

-/* 4 bytes for the CRC.  */
-size += 4;
 crc = cpu_to_be32(crc32(~0, buf, size));
+/* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */
+size += 4;
 crc_ptr = (uint8_t *) 

 if (shift16) {
--
2.39.0.314.g84b9a713c41-goog




[PATCH 01/15] tests/avocado: add RISC-V opensbi boot test

2022-12-21 Thread Daniel Henrique Barboza
This test is used to do a quick sanity check to ensure that we're able
to run the existing QEMU FW image.

'sifive_u', 'spike' and 'virt' riscv64 machines, and 'sifive_u' and
'virt' 32 bit machines are able to run the default RISCV64_BIOS_BIN |
RISCV32_BIOS_BIN firmware with minimal options.

Cc: Cleber Rosa 
Cc: Philippe Mathieu-Daudé 
Cc: Wainer dos Santos Moschetta 
Cc: Beraldo Leal 
Signed-off-by: Daniel Henrique Barboza 
---
 tests/avocado/riscv_opensbi.py | 65 ++
 1 file changed, 65 insertions(+)
 create mode 100644 tests/avocado/riscv_opensbi.py

diff --git a/tests/avocado/riscv_opensbi.py b/tests/avocado/riscv_opensbi.py
new file mode 100644
index 00..abc99ced30
--- /dev/null
+++ b/tests/avocado/riscv_opensbi.py
@@ -0,0 +1,65 @@
+# opensbi boot test for RISC-V machines
+#
+# Copyright (c) 2022, Ventana Micro
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later.  See the COPYING file in the top-level directory.
+
+from avocado_qemu import QemuSystemTest
+from avocado_qemu import wait_for_console_pattern
+
+class RiscvOpensbi(QemuSystemTest):
+"""
+:avocado: tags=accel:tcg
+"""
+timeout = 5
+
+def test_riscv64_virt(self):
+"""
+:avocado: tags=arch:riscv64
+:avocado: tags=machine:virt
+"""
+self.vm.set_console()
+self.vm.launch()
+wait_for_console_pattern(self, 'Platform Name')
+wait_for_console_pattern(self, 'Boot HART MEDELEG')
+
+def test_riscv64_spike(self):
+"""
+:avocado: tags=arch:riscv64
+:avocado: tags=machine:spike
+"""
+self.vm.set_console()
+self.vm.launch()
+wait_for_console_pattern(self, 'Platform Name')
+wait_for_console_pattern(self, 'Boot HART MEDELEG')
+
+def test_riscv64_sifive_u(self):
+"""
+:avocado: tags=arch:riscv64
+:avocado: tags=machine:sifive_u
+"""
+self.vm.set_console()
+self.vm.launch()
+wait_for_console_pattern(self, 'Platform Name')
+wait_for_console_pattern(self, 'Boot HART MEDELEG')
+
+def test_riscv32_virt(self):
+"""
+:avocado: tags=arch:riscv32
+:avocado: tags=machine:virt
+"""
+self.vm.set_console()
+self.vm.launch()
+wait_for_console_pattern(self, 'Platform Name')
+wait_for_console_pattern(self, 'Boot HART MEDELEG')
+
+def test_riscv32_sifive_u(self):
+"""
+:avocado: tags=arch:riscv32
+:avocado: tags=machine:sifive_u
+"""
+self.vm.set_console()
+self.vm.launch()
+wait_for_console_pattern(self, 'Platform Name')
+wait_for_console_pattern(self, 'Boot HART MEDELEG')
-- 
2.38.1




  1   2   3   4   >