[PATCH v3 3/3] Implement audio capture in virtio-snd device

2023-07-18 Thread Manos Pitsidianakis


Signed-off-by: Emmanouil Pitsidianakis 
---
 hw/virtio/trace-events |   3 +-
 hw/virtio/virtio-snd.c | 238 +++--
 2 files changed, 205 insertions(+), 36 deletions(-)

diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 8f3953dc28..3e7b259aef 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -165,7 +165,8 @@ virtio_snd_handle_pcm_set_params(int stream) 
"VIRTIO_SND_PCM_SET_PARAMS called f
 virtio_snd_handle_pcm_start_stop(const char *code, int stream) "%s called for 
stream %d"
 virtio_snd_handle_pcm_release(int stream) "VIRTIO_SND_PCM_RELEASE called for 
stream %d"
 virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
-virtio_snd_handle_xfer(void) "tx/rx queue callback called"
+virtio_snd_handle_tx_xfer(void) "tx queue callback called"
+virtio_snd_handle_rx_xfer(void) "rx queue callback called"
 virtio_snd_handle_event(void) "event queue callback called"
 virtio_snd_realize(void *snd) "snd %p: realize"
 virtio_snd_unrealize(void *snd) "snd %p: unrealize"
diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c
index dbf8d8162f..a6ac9d8ce0 100644
--- a/hw/virtio/virtio-snd.c
+++ b/hw/virtio/virtio-snd.c
@@ -27,7 +27,7 @@
 #define VIRTIO_SOUND_VM_VERSION 1
 
 #define VIRTIO_SOUND_JACK_DEFAULT 0
-#define VIRTIO_SOUND_STREAM_DEFAULT 1
+#define VIRTIO_SOUND_STREAM_DEFAULT 2
 #define VIRTIO_SOUND_CHMAP_DEFAULT 0
 
 #define VIRTIO_SOUND_HDA_FN_NID 0
@@ -114,12 +114,16 @@ virtio_snd_set_config(VirtIODevice *vdev, const uint8_t 
*config)
 }
 
 static void virtio_snd_process_cmdq(VirtIOSound *s);
-static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream);
+static void virtio_snd_pcm_out_flush(VirtIOSoundPCMStream *stream);
+static void virtio_snd_pcm_in_flush(VirtIOSoundPCMStream *stream);
 static void virtio_snd_pcm_out_cb(void *data, int available);
-static uint32_t virtio_snd_pcm_read_write(VirtIOSoundPCMStream *stream,
+static void virtio_snd_pcm_in_cb(void *data, int available);
+static uint32_t virtio_snd_pcm_write(VirtIOSoundPCMStream *stream,
   VirtQueue *vq,
-  VirtQueueElement *element,
-  bool read);
+  VirtQueueElement *element);
+static uint32_t virtio_snd_pcm_read(VirtIOSoundPCMStream *stream,
+  VirtQueue *vq,
+  VirtQueueElement *element);
 
 /*
  * Get a specific stream from the virtio sound card device.
@@ -421,15 +425,12 @@ static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound 
*s, uint32_t stream_id)
  &as);
 
 } else {
-qemu_log_mask(LOG_UNIMP, "virtio_snd: input/capture is 
unimplemented.");
-/*
- * stream->voice.in = AUD_open_in(&s->card,
- *stream->voice.in,
- *"virtio_snd_card",
- *stream,
- *virtio_snd_input_cb,
- *&as);
- */
+stream->voice.in = AUD_open_in(&s->card,
+stream->voice.in,
+"virtio_snd_card",
+stream,
+virtio_snd_pcm_in_cb,
+&as);
 }
 
 stream->as = as;
@@ -502,6 +503,8 @@ static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s,
 if (stream) {
 if (stream->direction == VIRTIO_SND_D_OUTPUT) {
 AUD_set_active_out(stream->voice.out, start);
+} else {
+AUD_set_active_in(stream->voice.in, start);
 }
 } else {
 error_report("Invalid stream id: %d", req.stream_id);
@@ -552,7 +555,11 @@ static uint32_t 
virtio_snd_pcm_release_impl(VirtIOSoundPCMStream *stream,
  */
 virtio_snd_process_cmdq(stream->s);
 trace_virtio_snd_pcm_stream_flush(stream_id);
-virtio_snd_pcm_flush(stream);
+if (stream->direction == VIRTIO_SND_D_OUTPUT) {
+virtio_snd_pcm_out_flush(stream);
+} else {
+virtio_snd_pcm_in_flush(stream);
+}
 }
 
 return VIRTIO_SND_S_OK;
@@ -738,7 +745,7 @@ static void virtio_snd_handle_event(VirtIODevice *vdev, 
VirtQueue *vq)
  * @vdev: VirtIOSound device
  * @vq: tx virtqueue
  */
-static void virtio_snd_handle_xfer(VirtIODevice *vdev, VirtQueue *vq)
+static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
 {
 VirtIOSound *s = VIRTIO_SND(vdev);
 VirtIOSoundPCMStream *stream = NULL;
@@ -747,7 +754,7 @@ static void virtio_snd_handle_xfer(VirtIODevice *vdev, 
VirtQueue *vq)
 virtio_snd_pcm_xfer hdr;
 virtio_snd_pcm_status resp = { 0 };
 
-trace_virtio_snd_handle_xfer();
+trace_virti

[PATCH v3 1/3] Add virtio-sound device

2023-07-18 Thread Manos Pitsidianakis


This patch adds an audio device implementing the recent virtio sound
spec (1.2).

PCM functionality is implemented, and jack[0], chmaps[1] messages are
at the moment left unimplemented.

PS2: This patch was based on a draft patch posted by OpenSynergy in 2019. [2]

[0]: https://www.kernel.org/doc/html/latest/sound/designs/jack-controls.html
[1]: 
https://www.kernel.org/doc/html/latest/sound/designs/channel-mapping-api.html
[2]: 
https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471#diff-fa5c10be8476fb5385a280885d527b0b40dfc11ddcc74369fce085d8b5b17bbd

Signed-off-by: Emmanouil Pitsidianakis 
Signed-off-by: Igor Skalkin 
Signed-off-by: Anton Yakovlev 
base-commit: 361d539735
---
 MAINTAINERS|6 +
 hw/virtio/Kconfig  |5 +
 hw/virtio/meson.build  |1 +
 hw/virtio/trace-events |   21 +
 hw/virtio/virtio-snd.c | 1121 
 include/hw/virtio/virtio-snd.h |  194 ++
 6 files changed, 1348 insertions(+)
 create mode 100644 hw/virtio/virtio-snd.c
 create mode 100644 include/hw/virtio/virtio-snd.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 12e59b6b27..2bed60f9c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2245,6 +2245,12 @@ F: hw/virtio/virtio-mem-pci.h
 F: hw/virtio/virtio-mem-pci.c
 F: include/hw/virtio/virtio-mem.h
 
+virtio-snd
+M: Manos Pitsidianakis 
+S: Supported
+F: hw/virtio/virtio-snd*.c
+F: include/hw/virtio/virtio-snd.h
+
 nvme
 M: Keith Busch 
 M: Klaus Jensen 
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index 92c9cf6c96..d6f20657b3 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -17,6 +17,11 @@ config VIRTIO_PCI
 depends on PCI
 select VIRTIO
 
+config VIRTIO_SND
+bool
+default y
+depends on VIRTIO
+
 config VIRTIO_MMIO
 bool
 select VIRTIO
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 13e7c6c272..120d4bfa0a 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -31,6 +31,7 @@ specific_virtio_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: 
files('vhost-vsock.c
 specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_VSOCK', if_true: 
files('vhost-user-vsock.c'))
 specific_virtio_ss.add(when: 'CONFIG_VIRTIO_RNG', if_true: 
files('virtio-rng.c'))
 specific_virtio_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: 
files('virtio-mem.c'))
+specific_virtio_ss.add(when: 'CONFIG_VIRTIO_SND', if_true: 
files('virtio-snd.c'))
 specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: 
files('vhost-user-i2c.c'))
 specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: 
files('vhost-user-rng.c'))
 specific_virtio_ss.add(when: 'CONFIG_VHOST_USER_GPIO', if_true: 
files('vhost-user-gpio.c'))
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 7109cf1a3b..8f3953dc28 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -154,3 +154,24 @@ virtio_pmem_flush_done(int type) "fsync return=%d"
 virtio_gpio_start(void) "start"
 virtio_gpio_stop(void) "stop"
 virtio_gpio_set_status(uint8_t status) "0x%x"
+
+#virtio-snd.c
+virtio_snd_pcm_stream_flush(int stream) "flushing stream %d"
+virtio_snd_handle_ctrl(void *vdev, void *vq) "snd %p: handle ctrl event for 
queue %p"
+#virtio_snd_handle_jack_info(int jack) "VIRTIO_SND_JACK_INFO called for jack 
%d"
+#virtio_snd_handle_jack_remap(void) "VIRTIO_SND_PCM_JACK_REMAP called"
+virtio_snd_handle_pcm_info(int stream) "VIRTIO_SND_R_PCM_INFO called for 
stream %d"
+virtio_snd_handle_pcm_set_params(int stream) "VIRTIO_SND_PCM_SET_PARAMS called 
for stream %d"
+virtio_snd_handle_pcm_start_stop(const char *code, int stream) "%s called for 
stream %d"
+virtio_snd_handle_pcm_release(int stream) "VIRTIO_SND_PCM_RELEASE called for 
stream %d"
+virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
+virtio_snd_handle_xfer(void) "tx/rx queue callback called"
+virtio_snd_handle_event(void) "event queue callback called"
+virtio_snd_realize(void *snd) "snd %p: realize"
+virtio_snd_unrealize(void *snd) "snd %p: unrealize"
+virtio_snd_get_features(void *vdev, uint64_t features) "snd %p: get_features 
0x%"PRIx64
+virtio_snd_get_config(void *vdev, uint32_t jacks, uint32_t streams, uint32_t 
chmaps) "snd %p: get_config jacks=%d streams=%d chmaps=%d"
+virtio_snd_set_config(void *vdev, uint32_t jacks, uint32_t new_jacks, uint32_t 
streams, uint32_t new_streams, uint32_t chmaps, uint32_t new_chmaps) "snd %p: 
set_config jacks from %d->%d, streams from %d->%d, chmaps from %d->%d"
+virtio_snd_vm_state_running(void) "vm state running"
+virtio_snd_vm_state_stopped(void) "vm state stopped"
+virtio_snd_handle_code(int val, const char *code) "ctrl code msg val = %d == 
%s"
diff --git a/hw/virtio/virtio-snd.c b/hw/virtio/virtio-snd.c
new file mode 100644
index 00..dbf8d8162f
--- /dev/null
+++ b/hw/virtio/virtio-snd.c
@@ -0,0 +1,1121 @@
+/*
+ * VIRTIO Sound Device conforming to
+ *
+ * "Virtual I/O Device (VIRTIO) Version 1.2
+ * Committee Specification Draft 01
+ * 09

Re: [PATCH 4/6] linux-user: Fix signed math overflow in brk() syscall

2023-07-18 Thread Helge Deller

On 7/18/23 00:02, Philippe Mathieu-Daudé wrote:

On 17/7/23 23:35, Helge Deller wrote:

Fix the math overflow when calculating the new_malloc_size.

new_host_brk_page and brk_page are unsigned integers. If userspace
reduces the heap, new_host_brk_page is lower than brk_page which results
in a huge positive number (but should actually be negative).

Fix it by adding a proper check and as such make the code more readable.

Signed-off-by: Helge Deller 
Tested-by: Markus F.X.J. Oberhumer 


Tested-by: Markus F.X.J. Oberhumer 


Ok.



Fixes: 86f04735ac ("linux-user: Fix brk() to release pages")


Hmm isn't it:

Fixes: ef4330c23b ("linux-user: Handle brk() attempts with very large sizes")


It's really 86f04735ac because this one introduced freeing of memory which
can lead to new_host_brk_page becoming smaller than  brk_page.


Buglink: https://github.com/upx/upx/issues/683


Also:

Cc: qemu-sta...@nongnu.org


Yep.




---
  linux-user/syscall.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 92d146f8fb..aa906bedcc 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -860,12 +860,13 @@ abi_long do_brk(abi_ulong brk_val)
   * itself); instead we treat "mapped but at wrong address" as
   * a failure and unmap again.
   */
-    new_alloc_size = new_host_brk_page - brk_page;
-    if (new_alloc_size) {
+    if (new_host_brk_page > brk_page) {
+    new_alloc_size = new_host_brk_page - brk_page;
  mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
  PROT_READ|PROT_WRITE,
  MAP_ANON|MAP_PRIVATE, 0, 0));
  } else {
+    new_alloc_size = 0;
  mapped_addr = brk_page;
  }

--
2.41.0


Alternatively:

-- >8 --
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1464151826..aafb13f3b4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -814,7 +814,7 @@ void target_set_brk(abi_ulong new_brk)
  abi_long do_brk(abi_ulong brk_val)
  {
  abi_long mapped_addr;
-    abi_ulong new_alloc_size;
+    abi_long new_alloc_size;
  abi_ulong new_brk, new_host_brk_page;

  /* brk pointers are always untagged */
@@ -857,8 +857,8 @@ abi_long do_brk(abi_ulong brk_val)
   * a failure and unmap again.
   */
  new_alloc_size = new_host_brk_page - brk_page;
-    if (new_alloc_size) {
-    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
+    if (new_alloc_size > 0) {
+    mapped_addr = get_errno(target_mmap(brk_page, 
(abi_ulong)new_alloc_size,
  PROT_READ|PROT_WRITE,
  MAP_ANON|MAP_PRIVATE, 0, 0));
  } else {


possible, but I like my patch more.


Anyhow,

Reviewed-by: Philippe Mathieu-Daudé 


Thanks!

Helge




[PATCH for-8.1] virtio-iommu: Standardize granule extraction and formatting

2023-07-18 Thread Eric Auger
At several locations we compute the granule from the config
page_size_mask using ctz() and then format it in traces using
BIT(). As the page_size_mask is 64b we should use ctz64 and
BIT_ULL() for formatting. We failed to be consistent.

Note the page_size_mask is garanteed to be non null. The spec
mandates the device to set at least one bit, so ctz64 cannot
return 64. This is garanteed by the fact the device
initializes the page_size_mask to qemu_target_page_mask()
and then the page_size_mask is further constrained by
virtio_iommu_set_page_size_mask() callback which can't
result in a new mask being null. So if Coverity complains
round those ctz64/BIT_ULL with CID 1517772 this is a false
positive

Signed-off-by: Eric Auger 
Fixes: 94df5b2180 ("virtio-iommu: Fix 64kB host page size VFIO device 
assignment")
---
 hw/virtio/virtio-iommu.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 201127c488..c6ee4d7a3c 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -852,17 +852,19 @@ static IOMMUTLBEntry 
virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
 VirtIOIOMMUEndpoint *ep;
 uint32_t sid, flags;
 bool bypass_allowed;
+int granule;
 bool found;
 int i;
 
 interval.low = addr;
 interval.high = addr + 1;
+granule = ctz64(s->config.page_size_mask);
 
 IOMMUTLBEntry entry = {
 .target_as = &address_space_memory,
 .iova = addr,
 .translated_addr = addr,
-.addr_mask = (1 << ctz32(s->config.page_size_mask)) - 1,
+.addr_mask = BIT_ULL(granule) - 1,
 .perm = IOMMU_NONE,
 };
 
@@ -1115,7 +1117,7 @@ static int 
virtio_iommu_set_page_size_mask(IOMMUMemoryRegion *mr,
 if (s->granule_frozen) {
 int cur_granule = ctz64(cur_mask);
 
-if (!(BIT(cur_granule) & new_mask)) {
+if (!(BIT_ULL(cur_granule) & new_mask)) {
 error_setg(errp, "virtio-iommu %s does not support frozen granule 
0x%llx",
mr->parent_obj.name, BIT_ULL(cur_granule));
 return -1;
@@ -1161,7 +1163,7 @@ static void virtio_iommu_freeze_granule(Notifier 
*notifier, void *data)
 }
 s->granule_frozen = true;
 granule = ctz64(s->config.page_size_mask);
-trace_virtio_iommu_freeze_granule(BIT(granule));
+trace_virtio_iommu_freeze_granule(BIT_ULL(granule));
 }
 
 static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
-- 
2.38.1




Re: [PATCH v2 2/4] vhost-user: Interface for migration state transfer

2023-07-18 Thread Stefan Hajnoczi
On Wed, Jul 12, 2023 at 01:17:00PM +0200, Hanna Czenczek wrote:
> Add the interface for transferring the back-end's state during migration
> as defined previously in vhost-user.rst.
> 
> Signed-off-by: Hanna Czenczek 
> ---
>  include/hw/virtio/vhost-backend.h |  24 +
>  include/hw/virtio/vhost.h |  79 
>  hw/virtio/vhost-user.c| 147 ++
>  hw/virtio/vhost.c |  37 
>  4 files changed, 287 insertions(+)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH v2 3/4] vhost: Add high-level state save/load functions

2023-07-18 Thread Stefan Hajnoczi
On Wed, Jul 12, 2023 at 01:17:01PM +0200, Hanna Czenczek wrote:
> vhost_save_backend_state() and vhost_load_backend_state() can be used by
> vhost front-ends to easily save and load the back-end's state to/from
> the migration stream.
> 
> Because we do not know the full state size ahead of time,
> vhost_save_backend_state() simply reads the data in 1 MB chunks, and
> writes each chunk consecutively into the migration stream, prefixed by
> its length.  EOF is indicated by a 0-length chunk.
> 
> Signed-off-by: Hanna Czenczek 
> ---
>  include/hw/virtio/vhost.h |  35 +++
>  hw/virtio/vhost.c | 204 ++
>  2 files changed, 239 insertions(+)
> 
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index d8877496e5..0c282abd4e 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -425,4 +425,39 @@ int vhost_set_device_state_fd(struct vhost_dev *dev,
>   */
>  int vhost_check_device_state(struct vhost_dev *dev, Error **errp);
>  
> +/**
> + * vhost_save_backend_state(): High-level function to receive a vhost
> + * back-end's state, and save it in `f`.  Uses

I think the GtkDoc syntax is @f instead of `f`.

> + * `vhost_set_device_state_fd()` to get the data from the back-end, and
> + * stores it in consecutive chunks that are each prefixed by their
> + * respective length (be32).  The end is marked by a 0-length chunk.
> + *
> + * Must only be called while the device and all its vrings are stopped
> + * (`VHOST_TRANSFER_STATE_PHASE_STOPPED`).
> + *
> + * @dev: The vhost device from which to save the state
> + * @f: Migration stream in which to save the state
> + * @errp: Potential error message
> + *
> + * Returns 0 on success, and -errno otherwise.
> + */
> +int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error 
> **errp);
> +
> +/**
> + * vhost_load_backend_state(): High-level function to load a vhost
> + * back-end's state from `f`, and send it over to the back-end.  Reads
> + * the data from `f` in the format used by `vhost_save_state()`, and
> + * uses `vhost_set_device_state_fd()` to transfer it to the back-end.
> + *
> + * Must only be called while the device and all its vrings are stopped
> + * (`VHOST_TRANSFER_STATE_PHASE_STOPPED`).
> + *
> + * @dev: The vhost device to which to send the sate
> + * @f: Migration stream from which to load the state
> + * @errp: Potential error message
> + *
> + * Returns 0 on success, and -errno otherwise.
> + */
> +int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, Error 
> **errp);
> +
>  #endif
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 756b6d55a8..332d49a310 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -2128,3 +2128,207 @@ int vhost_check_device_state(struct vhost_dev *dev, 
> Error **errp)
> "vhost transport does not support migration state transfer");
>  return -ENOSYS;
>  }
> +
> +int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error 
> **errp)
> +{
> +/* Maximum chunk size in which to transfer the state */
> +const size_t chunk_size = 1 * 1024 * 1024;
> +void *transfer_buf = NULL;
> +g_autoptr(GError) g_err = NULL;
> +int pipe_fds[2], read_fd = -1, write_fd = -1, reply_fd = -1;
> +int ret;
> +
> +/* [0] for reading (our end), [1] for writing (back-end's end) */
> +if (!g_unix_open_pipe(pipe_fds, FD_CLOEXEC, &g_err)) {
> +error_setg(errp, "Failed to set up state transfer pipe: %s",
> +   g_err->message);
> +ret = -EINVAL;
> +goto fail;
> +}
> +
> +read_fd = pipe_fds[0];
> +write_fd = pipe_fds[1];
> +
> +/*
> + * VHOST_TRANSFER_STATE_PHASE_STOPPED means the device must be stopped.
> + * We cannot check dev->suspended, because the back-end may not support
> + * suspending.
> + */
> +assert(!dev->started);
> +
> +/* Transfer ownership of write_fd to the back-end */
> +ret = vhost_set_device_state_fd(dev,
> +VHOST_TRANSFER_STATE_DIRECTION_SAVE,
> +VHOST_TRANSFER_STATE_PHASE_STOPPED,
> +write_fd,
> +&reply_fd,
> +errp);
> +if (ret < 0) {
> +error_prepend(errp, "Failed to initiate state transfer: ");
> +goto fail;
> +}
> +
> +/* If the back-end wishes to use a different pipe, switch over */
> +if (reply_fd >= 0) {
> +close(read_fd);
> +read_fd = reply_fd;
> +}
> +
> +transfer_buf = g_malloc(chunk_size);
> +
> +while (true) {
> +ssize_t read_ret;
> +
> +read_ret = read(read_fd, transfer_buf, chunk_size);
> +if (read_ret < 0) {

Is it necessary to handle -EINTR?

> +ret = -errno;
> +error_setg_errno(errp, -ret, "Failed to receive state");
> +goto fail;
> +}
> +
> + 

Re: [PATCH v2 4/4] vhost-user-fs: Implement internal migration

2023-07-18 Thread Stefan Hajnoczi
On Wed, Jul 12, 2023 at 01:17:02PM +0200, Hanna Czenczek wrote:
> A virtio-fs device's VM state consists of:
> - the virtio device (vring) state (VMSTATE_VIRTIO_DEVICE)
> - the back-end's (virtiofsd's) internal state
> 
> We get/set the latter via the new vhost operations to transfer migratory
> state.  It is its own dedicated subsection, so that for external
> migration, it can be disabled.
> 
> Signed-off-by: Hanna Czenczek 
> ---
>  hw/virtio/vhost-user-fs.c | 101 +-
>  1 file changed, 100 insertions(+), 1 deletion(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH for-8.2 v3 0/8] target/riscv: add 'max' CPU, deprecate

2023-07-18 Thread Daniel Henrique Barboza

Alistair,

I'm doing some overly complicated stuff here w.r.t to KVM specific code
that are biting me back in further cleanups I'm working on.

I'll do some changes in this series and re-send. Thanks,


Daniel

On 7/14/23 14:43, Daniel Henrique Barboza wrote:

Hi,

This version has changes suggested in v2. The most significant change is
the deprecation of the 'any' CPU in patch 8.

The reasoning behind it is that Alistair mentioned that the 'any' CPU
intended to work like the newly added 'max' CPU, so we're better of
removing the 'any' CPU since it'll be out of place. We can't just
remove the CPU out of the gate so we'll have to make it do with
deprecation first.

Patches missing review: 5,6,7,8

Changes from v2:
- patches 1, 3, 4:
   - remove "DEFINE_PROP_END_OF_LIST()" at the end of each prop array;
   - use ARRAY_SIZE() in the for loop
- patch 5:
   - remove the trailing '/' in the last line of the macro
   - wrap the macro in "do {} while (0)"
- patch 8 (new):
   - deprecate the 'any' CPU
- v2 link: 
https://lore.kernel.org/qemu-riscv/20230712205748.446931-1-dbarb...@ventanamicro.com/

Daniel Henrique Barboza (8):
   target/riscv/cpu.c: split CPU options from riscv_cpu_extensions[]
   target/riscv/cpu.c: skip 'bool' check when filtering KVM props
   target/riscv/cpu.c: split vendor exts from riscv_cpu_extensions[]
   target/riscv/cpu.c: split non-ratified exts from
 riscv_cpu_extensions[]
   target/riscv/cpu.c: add a ADD_CPU_PROPERTIES_ARRAY() macro
   target/riscv: add 'max' CPU type
   avocado, risc-v: add opensbi tests for 'max' CPU
   target/riscv: deprecate the 'any' CPU type

  docs/about/deprecated.rst  |  12 
  target/riscv/cpu-qom.h |   1 +
  target/riscv/cpu.c | 114 ++---
  tests/avocado/riscv_opensbi.py |  16 +
  4 files changed, 121 insertions(+), 22 deletions(-)





[PATCH v2 5/5] linux-user: Fix qemu-arm to run static armhf binaries

2023-07-18 Thread Helge Deller
qemu-user crashes immediately when running static binaries on the armhf
architecture. The problem is the memory layout where the executable is
loaded before the interpreter library, in which case the reserved brk
region clashes with the interpreter code and is released before qemu
tries to start the program.

At load time qemu calculates a brk value for interpreter and executable
each.  The fix is to choose the higher one of both.

Signed-off-by: Helge Deller 
Cc: Andreas Schwab 
Cc: qemu-sta...@nongnu.org
Reported-by:  venkata.p...@toshiba-tsip.com
Closes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1040981
---
 linux-user/elfload.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a26200d9f3..94951630b1 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -3615,6 +3615,13 @@ int load_elf_binary(struct linux_binprm *bprm, struct 
image_info *info)

 if (elf_interpreter) {
 load_elf_interp(elf_interpreter, &interp_info, bprm->buf);
+/*
+ * adjust brk address if the interpreter was loaded above the main
+ * executable, e.g. happens with static binaries on armhf
+ */
+if (interp_info.brk > info->brk) {
+info->brk = interp_info.brk;
+}

 /* If the program interpreter is one of these two, then assume
an iBCS2 image.  Otherwise assume a native linux image.  */
--
2.41.0




[PATCH v2 1/5] linux-user: Fix qemu brk() to not zero bytes on current page

2023-07-18 Thread Helge Deller
The qemu brk() implementation is too aggressive and cleans remaining bytes
on the current page above the last brk address.

But some existing applications are buggy and read/write bytes above their
current heap address. On a phyiscal machine this does not trigger a
runtime error as long as the access happens on the same page. Additionally
the Linux kernel allocates only full pages and does no zeroing on already
allocated pages, even if the brk address is lowered.

Fix qemu to behave the same way as the kernel does. Do not touch already
allocated pages, and - when running with different page sizes of guest and
host - zero out only those memory areas where the host page size is bigger
than the guest page size.

Signed-off-by: Helge Deller 
Tested-by: "Markus F.X.J. Oberhumer" 
Fixes: 86f04735ac ("linux-user: Fix brk() to release pages")
Cc: qemu-sta...@nongnu.org
Buglink: https://github.com/upx/upx/issues/683
---
 linux-user/syscall.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c99ef9c01e..ee54eed33b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -829,10 +829,8 @@ abi_long do_brk(abi_ulong brk_val)

 /* brk_val and old target_brk might be on the same page */
 if (new_brk == TARGET_PAGE_ALIGN(target_brk)) {
-if (brk_val > target_brk) {
-/* empty remaining bytes in (possibly larger) host page */
-memset(g2h_untagged(target_brk), 0, new_host_brk_page - 
target_brk);
-}
+/* empty remaining bytes in (possibly larger) host page */
+memset(g2h_untagged(new_brk), 0, new_host_brk_page - new_brk);
 target_brk = brk_val;
 return target_brk;
 }
@@ -840,7 +838,7 @@ abi_long do_brk(abi_ulong brk_val)
 /* Release heap if necesary */
 if (new_brk < target_brk) {
 /* empty remaining bytes in (possibly larger) host page */
-memset(g2h_untagged(brk_val), 0, new_host_brk_page - brk_val);
+memset(g2h_untagged(new_brk), 0, new_host_brk_page - new_brk);

 /* free unused host pages and set new brk_page */
 target_munmap(new_host_brk_page, brk_page - new_host_brk_page);
@@ -873,7 +871,7 @@ abi_long do_brk(abi_ulong brk_val)
  * come from the remaining part of the previous page: it may
  * contains garbage data due to a previous heap usage (grown
  * then shrunken).  */
-memset(g2h_untagged(target_brk), 0, brk_page - target_brk);
+memset(g2h_untagged(brk_page), 0, HOST_PAGE_ALIGN(brk_page) - 
brk_page);

 target_brk = brk_val;
 brk_page = new_host_brk_page;
--
2.41.0




[PATCH v2 0/5] linux-user: brk() syscall fixes and armhf static binary fix

2023-07-18 Thread Helge Deller
Commit 86f04735ac ("linux-user: Fix brk() to release pages") introduced
the possibility for userspace applications to reduce memory footprint by
calling brk() with a lower address and as such free up memory, the same
way as the Linux kernel allows on physical machines.

This change introduced some failures for applications with errors like
- accesing bytes above the brk heap address on the same page,
- freeing memory below the initial brk address,
and introduced a behaviour which isn't done by the kernel (e.g. zeroing
memory above brk).

This patch series fixes those issues and has been tested with existing
programs (e.g. upx).

Additionally one patch fixes running static armhf executables (e.g. fstype)
which was broken since qemu-8.0.

Changes in v2:
- dropped patch to revert d28b3c90cfad ("linux-user: Make sure initial brk(0)
  is page-aligned")
- rephrased some commit messages
- fixed Cc email addresses, added new ones
- added R-b tags

Helge

Helge Deller (5):
  linux-user: Fix qemu brk() to not zero bytes on current page
  linux-user: Prohibit brk() to to shrink below initial heap address
  linux-user: Fix signed math overflow in brk() syscall
  linux-user: Fix strace output for old_mmap
  linux-user: Fix qemu-arm to run static armhf binaries

 linux-user/elfload.c |  7 +++
 linux-user/strace.c  | 49 
 linux-user/syscall.c | 23 +
 3 files changed, 66 insertions(+), 13 deletions(-)

--
2.41.0




[PATCH v2 2/5] linux-user: Prohibit brk() to to shrink below initial heap address

2023-07-18 Thread Helge Deller
Since commit 86f04735ac ("linux-user: Fix brk() to release pages") it's
possible for userspace applications to reduce their memory footprint by
calling brk() with a lower address and free up memory. Before that commit
guest heap memory was never unmapped.

But the Linux kernel prohibits to reduce brk() below the initial memory
address which is set at startup by the set_brk() function in binfmt_elf.c.
Such a range check was missed in commit 86f04735ac.

This patch adds the missing check by storing the initial brk value in
initial_target_brk and verify any new brk addresses against that value.

Tested with the i386 upx binary from
https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-i386_linux.tar.xz

Signed-off-by: Helge Deller 
Tested-by: "Markus F.X.J. Oberhumer" 
Fixes: 86f04735ac ("linux-user: Fix brk() to release pages")
Cc: qemu-sta...@nongnu.org
Buglink: https://github.com/upx/upx/issues/683
---
 linux-user/syscall.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ee54eed33b..125fcbe423 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -801,12 +801,13 @@ static inline int host_to_target_sock_type(int host_type)
 return target_type;
 }

-static abi_ulong target_brk;
+static abi_ulong target_brk, initial_target_brk;
 static abi_ulong brk_page;

 void target_set_brk(abi_ulong new_brk)
 {
 target_brk = TARGET_PAGE_ALIGN(new_brk);
+initial_target_brk = target_brk;
 brk_page = HOST_PAGE_ALIGN(target_brk);
 }

@@ -824,6 +825,11 @@ abi_long do_brk(abi_ulong brk_val)
 return target_brk;
 }

+/* do not allow to shrink below initial brk value */
+if (brk_val < initial_target_brk) {
+brk_val = initial_target_brk;
+}
+
 new_brk = TARGET_PAGE_ALIGN(brk_val);
 new_host_brk_page = HOST_PAGE_ALIGN(brk_val);

--
2.41.0




[PATCH v2 3/5] linux-user: Fix signed math overflow in brk() syscall

2023-07-18 Thread Helge Deller
Fix the math overflow when calculating the new_malloc_size.

new_host_brk_page and brk_page are unsigned integers. If userspace
reduces the heap, new_host_brk_page is lower than brk_page which results
in a huge positive number (but should actually be negative).

Fix it by adding a proper check and as such make the code more readable.

Signed-off-by: Helge Deller 
Tested-by: "Markus F.X.J. Oberhumer" 
Reviewed-by: Philippe Mathieu-Daudé 
Fixes: 86f04735ac ("linux-user: Fix brk() to release pages")
Cc: qemu-sta...@nongnu.org
Buglink: https://github.com/upx/upx/issues/683
---
 linux-user/syscall.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 125fcbe423..95727a816a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -860,12 +860,13 @@ abi_long do_brk(abi_ulong brk_val)
  * itself); instead we treat "mapped but at wrong address" as
  * a failure and unmap again.
  */
-new_alloc_size = new_host_brk_page - brk_page;
-if (new_alloc_size) {
+if (new_host_brk_page > brk_page) {
+new_alloc_size = new_host_brk_page - brk_page;
 mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
 PROT_READ|PROT_WRITE,
 MAP_ANON|MAP_PRIVATE, 0, 0));
 } else {
+new_alloc_size = 0;
 mapped_addr = brk_page;
 }

--
2.41.0




[PATCH v2 4/5] linux-user: Fix strace output for old_mmap

2023-07-18 Thread Helge Deller
The old_mmap syscall (e.g. on i386) hands over the parameters in
a struct. Adjust the strace output to print the correct values.

Signed-off-by: Helge Deller 
Reported-by: John Reiser 
Closes: https://gitlab.com/qemu-project/qemu/-/issues/1760
---
 linux-user/strace.c | 49 +
 1 file changed, 45 insertions(+), 4 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index bbd29148d4..e0ab8046ec 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -3767,10 +3767,24 @@ print_utimensat(CPUArchState *cpu_env, const struct 
syscallname *name,

 #if defined(TARGET_NR_mmap) || defined(TARGET_NR_mmap2)
 static void
-print_mmap(CPUArchState *cpu_env, const struct syscallname *name,
+print_mmap_both(CPUArchState *cpu_env, const struct syscallname *name,
abi_long arg0, abi_long arg1, abi_long arg2,
-   abi_long arg3, abi_long arg4, abi_long arg5)
-{
+   abi_long arg3, abi_long arg4, abi_long arg5,
+   bool is_old_mmap)
+{
+if (is_old_mmap) {
+abi_ulong *v;
+abi_ulong argp = arg0;
+if (!(v = lock_user(VERIFY_READ, argp, 6 * sizeof(abi_ulong), 1)))
+return;
+arg0 = tswapal(v[0]);
+arg1 = tswapal(v[1]);
+arg2 = tswapal(v[2]);
+arg3 = tswapal(v[3]);
+arg4 = tswapal(v[4]);
+arg5 = tswapal(v[5]);
+unlock_user(v, argp, 0);
+}
 print_syscall_prologue(name);
 print_pointer(arg0, 0);
 print_raw_param("%d", arg1, 0);
@@ -3780,7 +3794,34 @@ print_mmap(CPUArchState *cpu_env, const struct 
syscallname *name,
 print_raw_param("%#x", arg5, 1);
 print_syscall_epilogue(name);
 }
-#define print_mmap2 print_mmap
+#endif
+
+#if defined(TARGET_NR_mmap)
+static void
+print_mmap(CPUArchState *cpu_env, const struct syscallname *name,
+   abi_long arg0, abi_long arg1, abi_long arg2,
+   abi_long arg3, abi_long arg4, abi_long arg5)
+{
+return print_mmap_both(cpu_env, name, arg0, arg1, arg2, arg3,
+   arg4, arg5,
+#if defined(TARGET_NR_mmap2)
+true
+#else
+false
+#endif
+);
+}
+#endif
+
+#if defined(TARGET_NR_mmap2)
+static void
+print_mmap2(CPUArchState *cpu_env, const struct syscallname *name,
+   abi_long arg0, abi_long arg1, abi_long arg2,
+   abi_long arg3, abi_long arg4, abi_long arg5)
+{
+return print_mmap_both(cpu_env, name, arg0, arg1, arg2, arg3,
+   arg4, arg5, false);
+}
 #endif

 #ifdef TARGET_NR_mprotect
--
2.41.0




Re: PING: [PATCH v4 0/3] hw/ufs: Add Universal Flash Storage (UFS) support

2023-07-18 Thread Stefan Hajnoczi
On Tue, Jul 11, 2023 at 07:31:02PM +0900, Jeuk Kim wrote:
> Hi,
> Any more reviews...?
> 
> Dear Stefan
> If you don't mind, Could you give it "reviewed-by"?
> And is there anything else I should do...?

Sorry for the late reply. I was on vacation and am working my way
through pending code review and bug reports.

I have started reviewing this series and should be finish on Wednesday
or Thursday.

Stefan


signature.asc
Description: PGP signature


Re: [PATCH 04/10] hw/riscv: virt: Add PCIe HIGHMEM in memmap

2023-07-18 Thread Daniel Henrique Barboza




On 7/12/23 13:39, Sunil V L wrote:

PCIe High MMIO base is actually dynamic and fixed at
run time based on the RAM configured. Currently, this is
not part of the memmap and kept in separate static variable
in virt.c. However, ACPI code also needs this information
to populate DSDT. So, once the base is discovered, merge
this into the final memmap which can be used to create
ACPI tables later.

Signed-off-by: Sunil V L 
---
  hw/riscv/virt.c | 31 ++-
  include/hw/riscv/virt.h |  9 +++--
  2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index f6067db8ec..7aee06f021 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -84,6 +84,22 @@ static const MemMapEntry virt_memmap[] = {
  
  static MemMapEntry virt_high_pcie_memmap;
  
+/*

+ * virt_memmap doesn't include floating High Mem IO address entry. To enable
+ * code organization in multiple files (ex: ACPI), it is better to have single
+ * memmap which has complete information.
+ *
+ * VIRT_HIGH_PCIE_MMIO is always greater than the last memmap entry and hence
+ * full_virt_memmap is capable of holding both virt_memmap and
+ * VIRT_HIGH_PCIE_MMIO entry.
+ *
+ * The values for these floating entries will be updated when top of RAM is
+ * discovered.
+ */
+static MemMapEntry full_virt_memmap[] = {
+[VIRT_HIGH_PCIE_MMIO] = { 0x0, 0 },
+};
+
  #define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
  
  static PFlashCFI01 *virt_flash_create1(RISCVVirtState *s,

@@ -1444,7 +1460,20 @@ static void virt_machine_init(MachineState *machine)
  ROUND_UP(virt_high_pcie_memmap.base, virt_high_pcie_memmap.size);
  }
  
-s->memmap = virt_memmap;

+/*
+ * Initialize the floating values in full memory map
+ */
+full_virt_memmap[VIRT_HIGH_PCIE_MMIO].base = virt_high_pcie_memmap.base;
+full_virt_memmap[VIRT_HIGH_PCIE_MMIO].size = virt_high_pcie_memmap.size;
+
+s->memmap = full_virt_memmap;
+/*
+ * Copy the base virt_memmap entries to full memmap
+ */
+for (i = 0; i < ARRAY_SIZE(virt_memmap); i++) {
+s->memmap[i] = virt_memmap[i];
+}
+


This change here kind of convinces me of the point I made earlier in patch 2:
we can simplify gpex_pcie_init() to use just the RISCVVirtState as a parameter
and get everything else from it.

It's also something for a follow-up. As for this patch:

Reviewed-by: Daniel Henrique Barboza 

  
  /* register system main memory (actual RAM) */

  memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base,
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 00c22492a7..1d7ddf5df0 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -60,7 +60,7 @@ struct RISCVVirtState {
  char *oem_id;
  char *oem_table_id;
  OnOffAuto acpi;
-const MemMapEntry *memmap;
+MemMapEntry *memmap;
  PCIBus *bus;
  };
  
@@ -84,7 +84,12 @@ enum {

  VIRT_PCIE_MMIO,
  VIRT_PCIE_PIO,
  VIRT_PLATFORM_BUS,
-VIRT_PCIE_ECAM
+VIRT_PCIE_ECAM,
+VIRT_LAST_MEMMAP /* Keep this entry always last */
+};
+
+enum {
+VIRT_HIGH_PCIE_MMIO = VIRT_LAST_MEMMAP,
  };
  
  enum {




Re: [PATCH 05/10] hw/riscv/virt-acpi-build.c: Add AIA support in RINTC

2023-07-18 Thread Daniel Henrique Barboza




On 7/12/23 13:39, Sunil V L wrote:

Update the RINTC structure in MADT with AIA related fields.

Signed-off-by: Sunil V L 
---


Reviewed-by: Daniel Henrique Barboza 


  hw/riscv/virt-acpi-build.c | 66 +++---
  1 file changed, 62 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 01843e4509..12b8ef0352 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -37,6 +37,7 @@
  #include "hw/intc/riscv_aclint.h"
  
  #define ACPI_BUILD_TABLE_SIZE 0x2

+#define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index))
  
  typedef struct AcpiBuildState {

  /* Copy of table in RAM (for patching) */
@@ -57,18 +58,42 @@ static void acpi_align_size(GArray *blob, unsigned align)
  }
  
  static void riscv_acpi_madt_add_rintc(uint32_t uid,

+  uint32_t local_cpu_id,
const CPUArchIdList *arch_ids,
-  GArray *entry)
+  GArray *entry,
+  RISCVVirtAIAType aia_type,
+  uint64_t imsic_addr,
+  uint32_t imsic_size)
  {
  uint64_t hart_id = arch_ids->cpus[uid].arch_id;
  
  build_append_int_noprefix(entry, 0x18, 1);   /* Type */

-build_append_int_noprefix(entry, 20, 1); /* Length   */
+build_append_int_noprefix(entry, 36, 1); /* Length   */
  build_append_int_noprefix(entry, 1, 1);  /* Version  */
  build_append_int_noprefix(entry, 0, 1);  /* Reserved */
  build_append_int_noprefix(entry, 0x1, 4);/* Flags*/
  build_append_int_noprefix(entry, hart_id, 8);/* Hart ID  */
  build_append_int_noprefix(entry, uid, 4);/* ACPI Processor UID */
+/* External Interrupt Controller ID */
+if (aia_type == VIRT_AIA_TYPE_APLIC) {
+build_append_int_noprefix(entry,
+  ACPI_BUILD_INTC_ID(
+  arch_ids->cpus[uid].props.node_id,
+  local_cpu_id),
+  4);
+} else {
+build_append_int_noprefix(entry, 0, 4);
+}
+
+if (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
+/* IMSIC Base address */
+build_append_int_noprefix(entry, imsic_addr, 8);
+/* IMSIC Size */
+build_append_int_noprefix(entry, imsic_size, 4);
+} else {
+build_append_int_noprefix(entry, 0, 8);
+build_append_int_noprefix(entry, 0, 4);
+}
  }
  
  static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s)

@@ -76,6 +101,11 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState 
*s)
  MachineClass *mc = MACHINE_GET_CLASS(s);
  MachineState *ms = MACHINE(s);
  const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
+uint64_t imsic_socket_addr, imsic_addr;
+uint8_t  guest_index_bits;
+uint32_t imsic_size, local_cpu_id, socket_id;
+
+guest_index_bits = imsic_num_bits(s->aia_guests + 1);
  
  for (int i = 0; i < arch_ids->len; i++) {

  Aml *dev;
@@ -86,8 +116,19 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState 
*s)
  aml_append(dev, aml_name_decl("_UID",
 aml_int(arch_ids->cpus[i].arch_id)));
  
+socket_id = arch_ids->cpus[i].props.node_id;

+local_cpu_id = (arch_ids->cpus[i].arch_id -
+riscv_socket_first_hartid(ms, socket_id)) %
+riscv_socket_hart_count(ms, socket_id);
  /* build _MAT object */
-riscv_acpi_madt_add_rintc(i, arch_ids, madt_buf);
+imsic_socket_addr = s->memmap[VIRT_IMSIC_S].base +
+(socket_id * VIRT_IMSIC_GROUP_MAX_SIZE);
+imsic_addr = imsic_socket_addr +
+ local_cpu_id * IMSIC_HART_SIZE(guest_index_bits);
+imsic_size = IMSIC_HART_SIZE(guest_index_bits);
+
+riscv_acpi_madt_add_rintc(i, local_cpu_id, arch_ids, madt_buf,
+  s->aia_type, imsic_addr, imsic_size);
  aml_append(dev, aml_name_decl("_MAT",
aml_buffer(madt_buf->len,
(uint8_t *)madt_buf->data)));
@@ -226,6 +267,7 @@ static void build_dsdt(GArray *table_data,
   * 5.2.12 Multiple APIC Description Table (MADT)
   * REF: https://github.com/riscv-non-isa/riscv-acpi/issues/15
   *  https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view
+ *  https://drive.google.com/file/d/1oMGPyOD58JaPgMl1pKasT-VKsIKia7zR/view
   */
  static void build_madt(GArray *table_data,
 BIOSLinker *linker,
@@ -234,6 +276,12 @@ static void build_madt(GArray *table_

Re: [PATCH 06/10] hw/riscv/virt-acpi-build.c: Add IMSIC in the MADT

2023-07-18 Thread Daniel Henrique Barboza




On 7/12/23 13:39, Sunil V L wrote:

Add IMSIC structure in MADT when IMSIC is configured.

Signed-off-by: Sunil V L 
---


Reviewed-by: Daniel Henrique Barboza 


  hw/riscv/virt-acpi-build.c | 34 ++
  1 file changed, 34 insertions(+)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 12b8ef0352..ebdc3bffea 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -280,8 +280,20 @@ static void build_madt(GArray *table_data,
  uint8_t  guest_index_bits;
  uint32_t imsic_size;
  uint32_t local_cpu_id, socket_id;
+uint8_t  hart_index_bits, group_index_bits, group_index_shift;
+uint16_t imsic_max_hart_per_socket = 0;
+uint8_t  socket;
+
+for (socket = 0; socket < riscv_socket_count(ms); socket++) {
+if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
+imsic_max_hart_per_socket = s->soc[socket].num_harts;
+}
+}
  
  guest_index_bits = imsic_num_bits(s->aia_guests + 1);

+hart_index_bits = imsic_num_bits(imsic_max_hart_per_socket);
+group_index_bits = imsic_num_bits(riscv_socket_count(ms));
+group_index_shift = IMSIC_MMIO_GROUP_MIN_SHIFT;
  
  AcpiTable table = { .sig = "APIC", .rev = 6, .oem_id = s->oem_id,

  .oem_table_id = s->oem_table_id };
@@ -306,6 +318,28 @@ static void build_madt(GArray *table_data,
s->aia_type, imsic_addr, imsic_size);
  }
  
+/* IMSIC */

+if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
+/* IMSIC */
+build_append_int_noprefix(table_data, 0x19, 1); /* Type */
+build_append_int_noprefix(table_data, 16, 1);   /* Length */
+build_append_int_noprefix(table_data, 1, 1);/* Version */
+build_append_int_noprefix(table_data, 0, 1);/* Reserved */
+build_append_int_noprefix(table_data, 0, 4);/* Flags */
+/* Number of supervisor mode Interrupt Identities */
+build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_MSIS, 2);
+/* Number of guest mode Interrupt Identities */
+build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_MSIS, 2);
+/* Guest Index Bits */
+build_append_int_noprefix(table_data, guest_index_bits, 1);
+/* Hart Index Bits */
+build_append_int_noprefix(table_data, hart_index_bits, 1);
+/* Group Index Bits */
+build_append_int_noprefix(table_data, group_index_bits, 1);
+/* Group Index Shift */
+build_append_int_noprefix(table_data, group_index_shift, 1);
+}
+
  acpi_table_end(linker, &table);
  }
  




Re: [PATCH 07/10] hw/riscv/virt-acpi-build.c: Add APLIC in the MADT

2023-07-18 Thread Daniel Henrique Barboza




On 7/12/23 13:39, Sunil V L wrote:

Add APLIC structures for each socket in the MADT when
system is configured with APLIC as the external wired
interrupt controller.

Signed-off-by: Sunil V L 
---


Reviewed-by: Daniel Henrique Barboza 


  hw/riscv/virt-acpi-build.c | 36 ++--
  1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index ebdc3bffea..9f2d0c92b0 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -276,9 +276,9 @@ static void build_madt(GArray *table_data,
  MachineClass *mc = MACHINE_GET_CLASS(s);
  MachineState *ms = MACHINE(s);
  const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
-uint64_t imsic_socket_addr, imsic_addr;
+uint64_t imsic_socket_addr, imsic_addr, aplic_addr;
+uint32_t imsic_size, gsi_base;
  uint8_t  guest_index_bits;
-uint32_t imsic_size;
  uint32_t local_cpu_id, socket_id;
  uint8_t  hart_index_bits, group_index_bits, group_index_shift;
  uint16_t imsic_max_hart_per_socket = 0;
@@ -340,6 +340,38 @@ static void build_madt(GArray *table_data,
  build_append_int_noprefix(table_data, group_index_shift, 1);
  }
  
+if (s->aia_type != VIRT_AIA_TYPE_NONE) {

+/* APLICs */
+for (socket = 0; socket < riscv_socket_count(ms); socket++) {
+aplic_addr = s->memmap[VIRT_APLIC_S].base +
+ s->memmap[VIRT_APLIC_S].size * socket;
+gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket;
+build_append_int_noprefix(table_data, 0x1A, 1);/* Type */
+build_append_int_noprefix(table_data, 36, 1);  /* Length */
+build_append_int_noprefix(table_data, 1, 1);   /* Version */
+build_append_int_noprefix(table_data, socket, 1);  /* APLIC ID */
+build_append_int_noprefix(table_data, 0, 4);   /* Flags */
+build_append_int_noprefix(table_data, 0, 8);   /* Hardware ID 
*/
+/* Number of IDCs */
+if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
+build_append_int_noprefix(table_data,
+  s->soc[socket].num_harts,
+  2);
+} else {
+build_append_int_noprefix(table_data, 0, 2);
+}
+/* Total External Interrupt Sources Supported */
+build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_SOURCES, 2);
+/* Global System Interrupt Base */
+build_append_int_noprefix(table_data, gsi_base, 4);
+/* APLIC Address */
+build_append_int_noprefix(table_data, aplic_addr, 8);
+/* APLIC size */
+build_append_int_noprefix(table_data,
+  s->memmap[VIRT_APLIC_S].size, 4);
+}
+}
+
  acpi_table_end(linker, &table);
  }
  




Re: [PATCH 08/10] hw/riscv/virt-acpi-build.c: Add CMO information in RHCT

2023-07-18 Thread Daniel Henrique Barboza




On 7/12/23 13:39, Sunil V L wrote:

When CMO related extensions like Zicboz, Zicbom and Zicbop
are enabled, the block size for those extensions need to be
communicated via CMO node in RHCT. Add CMO node in RHCT if
any of those CMO extensions are detected.

Signed-off-by: Sunil V L 
---


Reviewed-by: Daniel Henrique Barboza 


  hw/riscv/virt-acpi-build.c | 64 +-
  1 file changed, 56 insertions(+), 8 deletions(-)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 9f2d0c92b0..2d2bd3b970 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -146,6 +146,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState 
*s)
   * 5.2.36 RISC-V Hart Capabilities Table (RHCT)
   * REF: https://github.com/riscv-non-isa/riscv-acpi/issues/16
   *  https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view
+ *  https://drive.google.com/file/d/1sKbOa8m1UZw1JkquZYe3F1zQBN1xXsaf/view
   */
  static void build_rhct(GArray *table_data,
 BIOSLinker *linker,
@@ -155,8 +156,8 @@ static void build_rhct(GArray *table_data,
  MachineState *ms = MACHINE(s);
  const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
  size_t len, aligned_len;
-uint32_t isa_offset, num_rhct_nodes;
-RISCVCPU *cpu;
+uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0;
+RISCVCPU *cpu = &s->soc[0].harts[0];
  char *isa;
  
  AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id,

@@ -172,6 +173,9 @@ static void build_rhct(GArray *table_data,
  
  /* ISA + N hart info */

  num_rhct_nodes = 1 + ms->smp.cpus;
+if (cpu->cfg.ext_icbom || cpu->cfg.ext_icboz) {
+num_rhct_nodes++;
+}
  
  /* Number of RHCT nodes*/

  build_append_int_noprefix(table_data, num_rhct_nodes, 4);
@@ -183,7 +187,6 @@ static void build_rhct(GArray *table_data,
  isa_offset = table_data->len - table.table_offset;
  build_append_int_noprefix(table_data, 0, 2);   /* Type 0 */
  
-cpu = &s->soc[0].harts[0];

  isa = riscv_isa_string(cpu);
  len = 8 + strlen(isa) + 1;
  aligned_len = (len % 2) ? (len + 1) : len;
@@ -199,14 +202,59 @@ static void build_rhct(GArray *table_data,
  build_append_int_noprefix(table_data, 0x0, 1);   /* Optional Padding 
*/
  }
  
+/* CMO node */

+if (cpu->cfg.ext_icbom || cpu->cfg.ext_icboz) {
+cmo_offset = table_data->len - table.table_offset;
+build_append_int_noprefix(table_data, 1, 2);/* Type */
+build_append_int_noprefix(table_data, 10, 2);   /* Total Length */
+build_append_int_noprefix(table_data, 0x1, 2);  /* Revision */
+build_append_int_noprefix(table_data, 0, 1);/* Reserved */
+
+/* CBOM block size */
+if (cpu->cfg.cbom_blocksize) {
+build_append_int_noprefix(table_data,
+  __builtin_ctz(cpu->cfg.cbom_blocksize),
+  1);
+} else {
+build_append_int_noprefix(table_data, 0, 1);
+}
+
+/* CBOP block size */
+build_append_int_noprefix(table_data, 0, 1);
+
+/* CBOZ block size */
+if (cpu->cfg.cboz_blocksize) {
+build_append_int_noprefix(table_data,
+  __builtin_ctz(cpu->cfg.cboz_blocksize),
+  1);
+} else {
+build_append_int_noprefix(table_data, 0, 1);
+}
+}
+
  /* Hart Info Node */
  for (int i = 0; i < arch_ids->len; i++) {
+len = 16;
+int num_offsets = 1;
  build_append_int_noprefix(table_data, 0x, 2);  /* Type */
-build_append_int_noprefix(table_data, 16, 2);  /* Length */
-build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
-build_append_int_noprefix(table_data, 1, 2);/* Number of offsets */
-build_append_int_noprefix(table_data, i, 4);/* ACPI Processor UID 
*/
-build_append_int_noprefix(table_data, isa_offset, 4); /* Offsets[0] */
+
+/* Length */
+if (cmo_offset) {
+len += 4;
+num_offsets++;
+}
+
+build_append_int_noprefix(table_data, len, 2);
+build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
+/* Number of offsets */
+build_append_int_noprefix(table_data, num_offsets, 2);
+build_append_int_noprefix(table_data, i, 4);   /* ACPI Processor UID */
+
+/* Offsets */
+build_append_int_noprefix(table_data, isa_offset, 4);
+if (cmo_offset) {
+build_append_int_noprefix(table_data, cmo_offset, 4);
+}
  }
  
  acpi_table_end(linker, &table);




Re: [PATCH 09/10] hw/riscv/virt-acpi-build.c: Add MMU node in RHCT

2023-07-18 Thread Daniel Henrique Barboza




On 7/12/23 13:39, Sunil V L wrote:

MMU type information is available via MMU node in RHCT.
Add this node in RHCT.

Signed-off-by: Sunil V L 
---



Reviewed-by: Daniel Henrique Barboza 



  hw/riscv/virt-acpi-build.c | 36 
  1 file changed, 36 insertions(+)

diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 2d2bd3b970..25745eee4c 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -158,6 +158,8 @@ static void build_rhct(GArray *table_data,
  size_t len, aligned_len;
  uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0;
  RISCVCPU *cpu = &s->soc[0].harts[0];
+uint32_t mmu_offset = 0;
+uint8_t satp_mode_max;
  char *isa;
  
  AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id,

@@ -177,6 +179,10 @@ static void build_rhct(GArray *table_data,
  num_rhct_nodes++;
  }
  
+if (cpu->cfg.satp_mode.supported != 0) {

+num_rhct_nodes++;
+}
+
  /* Number of RHCT nodes*/
  build_append_int_noprefix(table_data, num_rhct_nodes, 4);
  
@@ -202,6 +208,26 @@ static void build_rhct(GArray *table_data,

  build_append_int_noprefix(table_data, 0x0, 1);   /* Optional Padding 
*/
  }
  
+/* MMU node structure */

+if (cpu->cfg.satp_mode.supported != 0) {
+satp_mode_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
+mmu_offset = table_data->len - table.table_offset;
+build_append_int_noprefix(table_data, 1, 2);/* Type */
+build_append_int_noprefix(table_data, 8, 2);/* Total Length */
+build_append_int_noprefix(table_data, 0x1, 2);  /* Revision */
+build_append_int_noprefix(table_data, 0, 1);/* Reserved */
+/* Virtual Address Scheme */
+if (satp_mode_max == VM_1_10_SV57) {
+build_append_int_noprefix(table_data, 2, 1);/* Sv57 */
+} else if (satp_mode_max == VM_1_10_SV48) {
+build_append_int_noprefix(table_data, 1, 1);/* Sv48 */
+} else if (satp_mode_max == VM_1_10_SV39) {
+build_append_int_noprefix(table_data, 0, 1);/* Sv39 */
+} else {
+assert(1);
+}
+}
+
  /* CMO node */
  if (cpu->cfg.ext_icbom || cpu->cfg.ext_icboz) {
  cmo_offset = table_data->len - table.table_offset;
@@ -244,6 +270,11 @@ static void build_rhct(GArray *table_data,
  num_offsets++;
  }
  
+if (mmu_offset) {

+len += 4;
+num_offsets++;
+}
+
  build_append_int_noprefix(table_data, len, 2);
  build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
  /* Number of offsets */
@@ -252,9 +283,14 @@ static void build_rhct(GArray *table_data,
  
  /* Offsets */

  build_append_int_noprefix(table_data, isa_offset, 4);
+
  if (cmo_offset) {
  build_append_int_noprefix(table_data, cmo_offset, 4);
  }
+
+if (mmu_offset) {
+build_append_int_noprefix(table_data, mmu_offset, 4);
+}
  }
  
  acpi_table_end(linker, &table);




Re: [PATCH 10/10] hw/riscv/virt-acpi-build.c: Add IO controllers and devices

2023-07-18 Thread Daniel Henrique Barboza




On 7/12/23 13:39, Sunil V L wrote:

Add basic IO controllers and devices like PCI, VirtIO and UART
in the ACPI namespace.

Signed-off-by: Sunil V L 
---


Reviewed-by: Daniel Henrique Barboza 


  hw/riscv/Kconfig   |  1 +
  hw/riscv/virt-acpi-build.c | 87 ++
  2 files changed, 88 insertions(+)

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index b6a5eb4452..a50717be87 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -45,6 +45,7 @@ config RISCV_VIRT
  select FW_CFG_DMA
  select PLATFORM_BUS
  select ACPI
+select ACPI_PCI
  
  config SHAKTI_C

  bool
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
index 25745eee4c..91f06fdc97 100644
--- a/hw/riscv/virt-acpi-build.c
+++ b/hw/riscv/virt-acpi-build.c
@@ -27,6 +27,7 @@
  #include "hw/acpi/acpi-defs.h"
  #include "hw/acpi/acpi.h"
  #include "hw/acpi/aml-build.h"
+#include "hw/acpi/pci.h"
  #include "hw/acpi/utils.h"
  #include "qapi/error.h"
  #include "qemu/error-report.h"
@@ -35,6 +36,7 @@
  #include "hw/riscv/virt.h"
  #include "hw/riscv/numa.h"
  #include "hw/intc/riscv_aclint.h"
+#include "hw/pci-host/gpex.h"
  
  #define ACPI_BUILD_TABLE_SIZE 0x2

  #define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index))
@@ -138,6 +140,55 @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState 
*s)
  }
  }
  
+static void

+acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
+uint32_t uart_irq)
+{
+Aml *dev = aml_device("COM0");
+aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
+aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(uart_memmap->base,
+ uart_memmap->size, AML_READ_WRITE));
+aml_append(crs,
+aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
+   AML_EXCLUSIVE, &uart_irq, 1));
+aml_append(dev, aml_name_decl("_CRS", crs));
+
+Aml *pkg = aml_package(2);
+aml_append(pkg, aml_string("clock-frequency"));
+aml_append(pkg, aml_int(3686400));
+
+Aml *UUID = aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301");
+
+Aml *pkg1 = aml_package(1);
+aml_append(pkg1, pkg);
+
+Aml *package = aml_package(2);
+aml_append(package, UUID);
+aml_append(package, pkg1);
+
+aml_append(dev, aml_name_decl("_DSD", package));
+aml_append(scope, dev);
+}
+
+static void
+acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
+   uint32_t irq, RISCVVirtState *s)
+{
+struct GPEXConfig cfg = {
+.mmio32 = memmap[VIRT_PCIE_MMIO],
+.mmio64 = memmap[VIRT_HIGH_PCIE_MMIO],
+.pio = memmap[VIRT_PCIE_PIO],
+.ecam = memmap[VIRT_PCIE_ECAM],
+.irq = irq,
+.bus = s->bus,
+};
+
+acpi_dsdt_add_gpex(scope, &cfg);
+}
+
  /* RHCT Node[N] starts at offset 56 */
  #define RHCT_NODE_ARRAY_OFFSET 56
  
@@ -318,6 +369,8 @@ static void build_dsdt(GArray *table_data,

 RISCVVirtState *s)
  {
  Aml *scope, *dsdt;
+MachineState *ms = MACHINE(s);
+uint8_t socket_count;
  const MemMapEntry *memmap = s->memmap;
  AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = s->oem_id,
  .oem_table_id = s->oem_table_id };
@@ -337,6 +390,30 @@ static void build_dsdt(GArray *table_data,
  
  acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
  
+socket_count = riscv_socket_count(ms);

+
+acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0], UART0_IRQ);
+
+if (socket_count == 1) {
+acpi_dsdt_add_virtio(scope, &memmap[VIRT_VIRTIO],
+ VIRTIO_IRQ, VIRTIO_COUNT);
+acpi_dsdt_add_pci(scope, memmap, PCIE_IRQ, s);
+} else if (socket_count == 2) {
+acpi_dsdt_add_virtio(scope, &memmap[VIRT_VIRTIO],
+ VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES,
+ VIRTIO_COUNT);
+acpi_dsdt_add_pci(scope, memmap,
+  PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES,
+  s);
+} else {
+acpi_dsdt_add_virtio(scope, &memmap[VIRT_VIRTIO],
+ VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES,
+ VIRTIO_COUNT);
+acpi_dsdt_add_pci(scope, memmap,
+  PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2,
+  s);
+}
+
  aml_append(dsdt, scope);
  
  /* copy AML table into ACPI tables blob and patch header there */

@@ -486,6 +563,16 @@ static void virt_acpi_build(RISCVVirtState *s, 
AcpiBuildTables *tables)
  acpi_add_table(table_offsets, tables_blob);
  build_rhct(tables_blob, tables->linker, s);
  
+acpi_add_table(table_offsets, tables_blob);

+{
+AcpiMcfgInfo mcfg = {
+   .base = s->memmap[VIRT_PCIE_MMIO].base,
+   .size = s

Re: [PATCH v4 1/3] hw/ufs: Initial commit for emulated Universal-Flash-Storage

2023-07-18 Thread Stefan Hajnoczi
On Tue, Jul 04, 2023 at 05:33:57PM +0900, Jeuk Kim wrote:
> From: Jeuk Kim 
> 
> Universal Flash Storage (UFS) is a high-performance mass storage device
> with a serial interface. It is primarily used as a high-performance
> data storage device for embedded applications.
> 
> This commit contains code for UFS device to be recognized
> as a UFS PCI device.
> Patches to handle UFS logical unit and Transfer Request will follow.
> 
> Signed-off-by: Jeuk Kim 
> ---
>  MAINTAINERS  |6 +
>  docs/specs/pci-ids.rst   |2 +
>  hw/Kconfig   |1 +
>  hw/meson.build   |1 +
>  hw/ufs/Kconfig   |4 +
>  hw/ufs/meson.build   |1 +
>  hw/ufs/trace-events  |   33 ++
>  hw/ufs/trace.h   |1 +
>  hw/ufs/ufs.c |  304 +++
>  hw/ufs/ufs.h |   42 ++
>  include/block/ufs.h  | 1048 ++
>  include/hw/pci/pci.h |1 +
>  include/hw/pci/pci_ids.h |1 +
>  meson.build  |1 +
>  14 files changed, 1446 insertions(+)
>  create mode 100644 hw/ufs/Kconfig
>  create mode 100644 hw/ufs/meson.build
>  create mode 100644 hw/ufs/trace-events
>  create mode 100644 hw/ufs/trace.h
>  create mode 100644 hw/ufs/ufs.c
>  create mode 100644 hw/ufs/ufs.h
>  create mode 100644 include/block/ufs.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4feea49a6e..756aae8623 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2237,6 +2237,12 @@ F: tests/qtest/nvme-test.c
>  F: docs/system/devices/nvme.rst
>  T: git git://git.infradead.org/qemu-nvme.git nvme-next
>  
> +ufs
> +M: Jeuk Kim 
> +S: Supported
> +F: hw/ufs/*
> +F: include/block/ufs.h
> +
>  megasas
>  M: Hannes Reinecke 
>  L: qemu-bl...@nongnu.org
> diff --git a/docs/specs/pci-ids.rst b/docs/specs/pci-ids.rst
> index e302bea484..d6707fa069 100644
> --- a/docs/specs/pci-ids.rst
> +++ b/docs/specs/pci-ids.rst
> @@ -92,6 +92,8 @@ PCI devices (other than virtio):
>PCI PVPanic device (``-device pvpanic-pci``)
>  1b36:0012
>PCI ACPI ERST device (``-device acpi-erst``)
> +1b36:0013
> +  PCI UFS device (``-device ufs``)
>  
>  All these devices are documented in :doc:`index`.
>  
> diff --git a/hw/Kconfig b/hw/Kconfig
> index ba62ff6417..9ca7b38c31 100644
> --- a/hw/Kconfig
> +++ b/hw/Kconfig
> @@ -38,6 +38,7 @@ source smbios/Kconfig
>  source ssi/Kconfig
>  source timer/Kconfig
>  source tpm/Kconfig
> +source ufs/Kconfig
>  source usb/Kconfig
>  source virtio/Kconfig
>  source vfio/Kconfig
> diff --git a/hw/meson.build b/hw/meson.build
> index c7ac7d3d75..f01fac4617 100644
> --- a/hw/meson.build
> +++ b/hw/meson.build
> @@ -37,6 +37,7 @@ subdir('smbios')
>  subdir('ssi')
>  subdir('timer')
>  subdir('tpm')
> +subdir('ufs')
>  subdir('usb')
>  subdir('vfio')
>  subdir('virtio')
> diff --git a/hw/ufs/Kconfig b/hw/ufs/Kconfig
> new file mode 100644
> index 00..b7b3392e85
> --- /dev/null
> +++ b/hw/ufs/Kconfig
> @@ -0,0 +1,4 @@
> +config UFS_PCI
> +bool
> +default y if PCI_DEVICES
> +depends on PCI
> diff --git a/hw/ufs/meson.build b/hw/ufs/meson.build
> new file mode 100644
> index 00..eb5164bde9
> --- /dev/null
> +++ b/hw/ufs/meson.build
> @@ -0,0 +1 @@
> +system_ss.add(when: 'CONFIG_UFS_PCI', if_true: files('ufs.c'))
> diff --git a/hw/ufs/trace-events b/hw/ufs/trace-events
> new file mode 100644
> index 00..17793929b1
> --- /dev/null
> +++ b/hw/ufs/trace-events
> @@ -0,0 +1,33 @@
> +# ufs.c
> +ufs_irq_raise(void) "INTx"
> +ufs_irq_lower(void) "INTx"
> +ufs_mmio_read(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx64" 
> data 0x%"PRIx64" size %d"
> +ufs_mmio_write(uint64_t addr, uint64_t data, unsigned size) "addr 
> 0x%"PRIx64" data 0x%"PRIx64" size %d"
> +ufs_process_db(uint32_t slot) "UTRLDBR slot %"PRIu32""
> +ufs_process_req(uint32_t slot) "UTRLDBR slot %"PRIu32""
> +ufs_complete_req(uint32_t slot) "UTRLDBR slot %"PRIu32""
> +ufs_sendback_req(uint32_t slot) "UTRLDBR slot %"PRIu32""
> +ufs_exec_nop_cmd(uint32_t slot) "UTRLDBR slot %"PRIu32""
> +ufs_exec_scsi_cmd(uint32_t slot, uint8_t lun, uint8_t opcode) "slot 
> %"PRIu32", lun 0x%"PRIx8", opcode 0x%"PRIx8""
> +ufs_exec_query_cmd(uint32_t slot, uint8_t opcode) "slot %"PRIu32", opcode 
> 0x%"PRIx8""
> +ufs_process_uiccmd(uint32_t uiccmd, uint32_t ucmdarg1, uint32_t ucmdarg2, 
> uint32_t ucmdarg3) "uiccmd 0x%"PRIx32", ucmdarg1 0x%"PRIx32", ucmdarg2 
> 0x%"PRIx32", ucmdarg3 0x%"PRIx32""
> +
> +# error condition
> +ufs_err_memory_allocation(void) "failed to allocate memory"
> +ufs_err_dma_read_utrd(uint32_t slot, uint64_t addr) "failed to read utrd. 
> UTRLDBR slot %"PRIu32", UTRD dma addr %"PRIu64""
> +ufs_err_dma_read_req_upiu(uint32_t slot, uint64_t addr) "failed to read req 
> upiu. UTRLDBR slot %"PRIu32", request upiu addr %"PRIu64""
> +ufs_err_dma_read_prdt(uint32_t slot, uint64_t addr) "failed to read prdt. 
> UTRLDBR slot %"PRIu32", prdt addr %"PRIu64""
> +ufs_err_dma_write_utrd(uint32_t slot, uint64_t addr) "failed to wr

Re: [PATCH v4 2/3] hw/ufs: Support for Query Transfer Requests

2023-07-18 Thread Stefan Hajnoczi
On Tue, Jul 04, 2023 at 05:33:58PM +0900, Jeuk Kim wrote:
> +static MemTxResult ufs_dma_read_prdt(UfsRequest *req)
> +{
> +UfsHc *u = req->hc;
> +uint16_t prdt_len = le16_to_cpu(req->utrd.prd_table_length);
> +uint16_t prdt_byte_off =
> +le16_to_cpu(req->utrd.prd_table_offset) * sizeof(uint32_t);
> +uint32_t prdt_size = prdt_len * sizeof(UfshcdSgEntry);
> +g_autofree UfshcdSgEntry *prd_entries = NULL;
> +hwaddr req_upiu_base_addr, prdt_base_addr;
> +int err;
> +
> +assert(!req->sg);
> +
> +if (prdt_len == 0) {
> +return MEMTX_OK;
> +}
> +
> +prd_entries = g_new(UfshcdSgEntry, prdt_size);
> +if (!prd_entries) {

g_new() never returns NULL. The process aborts if there is not enough
memory available.

Use g_try_new() if you want to handle memory allocation failure.

> +trace_ufs_err_memory_allocation();
> +return MEMTX_ERROR;
> +}
> +
> +req_upiu_base_addr = ufs_get_req_upiu_base_addr(&req->utrd);
> +prdt_base_addr = req_upiu_base_addr + prdt_byte_off;
> +
> +err = ufs_addr_read(u, prdt_base_addr, prd_entries, prdt_size);
> +if (err) {
> +trace_ufs_err_dma_read_prdt(req->slot, prdt_base_addr);
> +return err;
> +}
> +
> +req->sg = g_malloc0(sizeof(QEMUSGList));
> +if (!req->sg) {

g_malloc0() never returns NULL. The process aborts if there is not
enough memory available.



signature.asc
Description: PGP signature


Re: [PATCH v4 3/3] hw/ufs: Support for UFS logical unit

2023-07-18 Thread Stefan Hajnoczi
On Tue, Jul 04, 2023 at 05:33:59PM +0900, Jeuk Kim wrote:
> +static Property ufs_lu_props[] = {
> +DEFINE_PROP_DRIVE_IOTHREAD("drive", UfsLu, qdev.conf.blk),

This device is not aware of IOThreads, so I think DEFINE_PROP_DRIVE()
should be used instead.


signature.asc
Description: PGP signature


[PATCH for-8.2 v4 00/11] riscv: add 'max' CPU, deprecate 'any'

2023-07-18 Thread Daniel Henrique Barboza
Hi,

This new version has some adjustments w.r.t the KVM code that got a bit
neglected in the last 3 versions. The most notable change is in patch 3,
a new patch where we're moving the KVM property handling into an
exclusive helper. This helped to unclog riscv_cpu_add_user_properties()
a lot, making it easier for future cleanups we're planning to do in this
code.

Patch 4 (new) helped to padronize the code even more, allowing for more
macro usages to reduce repetition. Patch 8 (new) is basically patch 7
for KVM properties.

Patches missing review: 3, 4, 8, 10, 11 

Changes from v3:
- patch 1:
  - skip existing riscv_cpu_options before calling qdev_prop_add_static()
- patch 3 (new):
  - move kvm CPU property handling to riscv_cpu_add_kvm_properties()
- patch 4 (new):
  - remove DEFINE_PROP_END_OF_LIST() for riscv_cpu_extensions[]
- patch 7 (former 5):
  - rename macro to ADD_CPU_QDEV_PROPERTIES_ARRAY()
- patch 8 (new):
  - add ADD_UNAVAIL_KVM_PROP_ARRAY macro
- v3 link: 
https://lore.kernel.org/qemu-riscv/20230714174311.672359-1-dbarb...@ventanamicro.com/

Daniel Henrique Barboza (11):
  target/riscv/cpu.c: split CPU options from riscv_cpu_extensions[]
  target/riscv/cpu.c: skip 'bool' check when filtering KVM props
  target/riscv/cpu.c: split kvm prop handling to its own helper
  target/riscv/cpu.c: del DEFINE_PROP_END_OF_LIST() from
riscv_cpu_extensions
  target/riscv/cpu.c: split vendor exts from riscv_cpu_extensions[]
  target/riscv/cpu.c: split non-ratified exts from
riscv_cpu_extensions[]
  target/riscv/cpu.c: add ADD_CPU_QDEV_PROPERTIES_ARRAY() macro
  target/riscv/cpu.c: add ADD_UNAVAIL_KVM_PROP_ARRAY() macro
  target/riscv: add 'max' CPU type
  avocado, risc-v: add opensbi tests for 'max' CPU
  target/riscv: deprecate the 'any' CPU type

 docs/about/deprecated.rst  |  12 +++
 target/riscv/cpu-qom.h |   1 +
 target/riscv/cpu.c | 169 +
 tests/avocado/riscv_opensbi.py |  16 
 4 files changed, 160 insertions(+), 38 deletions(-)

-- 
2.41.0




[PATCH for-8.2 v4 01/11] target/riscv/cpu.c: split CPU options from riscv_cpu_extensions[]

2023-07-18 Thread Daniel Henrique Barboza
We'll add a new CPU type that will enable a considerable amount of
extensions. To make it easier for us we'll do a few cleanups in our
existing riscv_cpu_extensions[] array.

Start by splitting all CPU non-boolean options from it. Create a new
riscv_cpu_options[] array for them. Add all these properties in
riscv_cpu_add_user_properties() as it is already being done today.

No functional changes made.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 28 
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9339c0241d..587a5a9548 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1751,7 +1751,6 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 
 static Property riscv_cpu_extensions[] = {
 /* Defaults for standard extensions */
-DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
 DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
@@ -1767,11 +1766,6 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
 
-DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
-DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
-DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
-DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
-
 DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false),
 DEFINE_PROP_BOOL("svadu", RISCVCPU, cfg.ext_svadu, true),
 DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false),
@@ -1802,9 +1796,7 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
 
 DEFINE_PROP_BOOL("zicbom", RISCVCPU, cfg.ext_icbom, true),
-DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
 DEFINE_PROP_BOOL("zicboz", RISCVCPU, cfg.ext_icboz, true),
-DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
 
 DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
 
@@ -1848,6 +1840,18 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_END_OF_LIST(),
 };
 
+static Property riscv_cpu_options[] = {
+DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
+
+DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
+DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
+
+DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
+DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
+
+DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64),
+DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64),
+};
 
 #ifndef CONFIG_USER_ONLY
 static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
@@ -1916,6 +1920,14 @@ static void riscv_cpu_add_user_properties(Object *obj)
 #endif
 qdev_property_add_static(dev, prop);
 }
+
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
+/* Check if KVM created the property already */
+if (object_property_find(obj, riscv_cpu_options[i].name)) {
+continue;
+}
+qdev_property_add_static(dev, &riscv_cpu_options[i]);
+}
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.41.0




[PATCH for-8.2 v4 10/11] avocado, risc-v: add opensbi tests for 'max' CPU

2023-07-18 Thread Daniel Henrique Barboza
Add smoke tests to ensure that we'll not break the 'max' CPU type when
adding new ratified extensions to be enabled.

Signed-off-by: Daniel Henrique Barboza 
---
 tests/avocado/riscv_opensbi.py | 16 
 1 file changed, 16 insertions(+)

diff --git a/tests/avocado/riscv_opensbi.py b/tests/avocado/riscv_opensbi.py
index bfff9cc3c3..15fd57fe51 100644
--- a/tests/avocado/riscv_opensbi.py
+++ b/tests/avocado/riscv_opensbi.py
@@ -61,3 +61,19 @@ def test_riscv64_virt(self):
 :avocado: tags=machine:virt
 """
 self.boot_opensbi()
+
+def test_riscv32_virt_maxcpu(self):
+"""
+:avocado: tags=arch:riscv32
+:avocado: tags=machine:virt
+:avocado: tags=cpu:max
+"""
+self.boot_opensbi()
+
+def test_riscv64_virt_maxcpu(self):
+"""
+:avocado: tags=arch:riscv64
+:avocado: tags=machine:virt
+:avocado: tags=cpu:max
+"""
+self.boot_opensbi()
-- 
2.41.0




[PATCH for-8.2 v4 05/11] target/riscv/cpu.c: split vendor exts from riscv_cpu_extensions[]

2023-07-18 Thread Daniel Henrique Barboza
Our goal is to make riscv_cpu_extensions[] hold only ratified,
non-vendor extensions.

Create a new riscv_cpu_vendor_exts[] array for them, changing
riscv_cpu_add_user_properties() and riscv_cpu_add_kvm_properties()
accordingly.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 918acb9e6c..b59b06cddd 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1808,20 +1808,6 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
 DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
 
-/* Vendor-specific custom extensions */
-DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
-DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
-DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
-DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
-DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
-DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false),
-DEFINE_PROP_BOOL("xtheadfmv", RISCVCPU, cfg.ext_xtheadfmv, false),
-DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
-DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
-DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
-DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
-DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, 
false),
-
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
 
@@ -1838,6 +1824,21 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
 };
 
+static Property riscv_cpu_vendor_exts[] = {
+DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
+DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
+DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
+DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
+DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
+DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false),
+DEFINE_PROP_BOOL("xtheadfmv", RISCVCPU, cfg.ext_xtheadfmv, false),
+DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
+DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
+DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
+DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
+DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, 
false),
+};
+
 static Property riscv_cpu_options[] = {
 DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
 
@@ -1899,6 +1900,10 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
 riscv_cpu_add_kvm_unavail_prop(obj, riscv_cpu_extensions[i].name);
 }
 
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_vendor_exts); i++) {
+riscv_cpu_add_kvm_unavail_prop(obj, riscv_cpu_vendor_exts[i].name);
+}
+
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
 /* Check if KVM created the property already */
 if (object_property_find(obj, riscv_cpu_options[i].name)) {
@@ -1937,6 +1942,10 @@ static void riscv_cpu_add_user_properties(Object *obj)
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
 qdev_property_add_static(dev, &riscv_cpu_options[i]);
 }
+
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_vendor_exts); i++) {
+qdev_property_add_static(dev, &riscv_cpu_vendor_exts[i]);
+}
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.41.0




[PATCH for-8.2 v4 09/11] target/riscv: add 'max' CPU type

2023-07-18 Thread Daniel Henrique Barboza
The 'max' CPU type is used by tooling to determine what's the most
capable CPU a current QEMU version implements. Other archs such as ARM
implements this type. Let's add it to RISC-V.

What we consider "most capable CPU" in this context are related to
ratified, non-vendor extensions. This means that we want the 'max' CPU
to enable all (possible) ratified extensions by default. The reasoning
behind this design is (1) vendor extensions can conflict with each other
and we won't play favorities deciding which one is default or not and
(2) non-ratified extensions are always prone to changes, not being
stable enough to be enabled by default.

All this said, we're still not able to enable all ratified extensions
due to conflicts between them. Zfinx and all its dependencies aren't
enabled because of a conflict with RVF. zce, zcmp and zcmt are also
disabled due to RVD conflicts. When running with 64 bits we're also
disabling zcf.

MISA bits RVG, RVJ and RVV are also being set manually since they're
default disabled.

This is the resulting 'riscv,isa' DT for this new CPU:

rv64imafdcvh_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_
zfh_zfhmin_zca_zcb_zcd_zba_zbb_zbc_zbkb_zbkc_zbkx_zbs_zk_zkn_zknd_
zkne_zknh_zkr_zks_zksed_zksh_zkt_zve32f_zve64f_zve64d_
smstateen_sscofpmf_sstc_svadu_svinval_svnapot_svpbmt

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
---
 target/riscv/cpu-qom.h |  1 +
 target/riscv/cpu.c | 53 ++
 2 files changed, 54 insertions(+)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index 04af50983e..f3fbe37a2c 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -30,6 +30,7 @@
 #define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
 
 #define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
+#define TYPE_RISCV_CPU_MAX  RISCV_CPU_TYPE_NAME("max")
 #define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
 #define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
 #define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("x-rv128")
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7f79585bd1..7fdde68dee 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -248,6 +248,7 @@ static const char * const riscv_intr_names[] = {
 };
 
 static void riscv_cpu_add_user_properties(Object *obj);
+static void riscv_init_max_cpu_extensions(Object *obj);
 
 const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
 {
@@ -374,6 +375,25 @@ static void riscv_any_cpu_init(Object *obj)
 cpu->cfg.pmp = true;
 }
 
+static void riscv_max_cpu_init(Object *obj)
+{
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = &cpu->env;
+RISCVMXL mlx = MXL_RV64;
+
+#ifdef TARGET_RISCV32
+mlx = MXL_RV32;
+#endif
+set_misa(env, mlx, 0);
+riscv_cpu_add_user_properties(obj);
+riscv_init_max_cpu_extensions(obj);
+env->priv_ver = PRIV_VERSION_LATEST;
+#ifndef CONFIG_USER_ONLY
+set_satp_mode_max_supported(RISCV_CPU(obj), mlx == MXL_RV32 ?
+VM_1_10_SV32 : VM_1_10_SV57);
+#endif
+}
+
 #if defined(TARGET_RISCV64)
 static void rv64_base_cpu_init(Object *obj)
 {
@@ -1953,6 +1973,38 @@ static void riscv_cpu_add_user_properties(Object *obj)
 ADD_CPU_QDEV_PROPERTIES_ARRAY(dev, riscv_cpu_experimental_exts);
 }
 
+/*
+ * The 'max' type CPU will have all possible ratified
+ * non-vendor extensions enabled.
+ */
+static void riscv_init_max_cpu_extensions(Object *obj)
+{
+RISCVCPU *cpu = RISCV_CPU(obj);
+CPURISCVState *env = &cpu->env;
+Property *prop;
+
+/* Enable RVG, RVJ and RVV that are disabled by default */
+set_misa(env, env->misa_mxl, env->misa_ext | RVG | RVJ | RVV);
+
+for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
+object_property_set_bool(obj, prop->name, true, NULL);
+}
+
+/* Zfinx is not compatible with F. Disable it */
+object_property_set_bool(obj, "zfinx", false, NULL);
+object_property_set_bool(obj, "zdinx", false, NULL);
+object_property_set_bool(obj, "zhinx", false, NULL);
+object_property_set_bool(obj, "zhinxmin", false, NULL);
+
+object_property_set_bool(obj, "zce", false, NULL);
+object_property_set_bool(obj, "zcmp", false, NULL);
+object_property_set_bool(obj, "zcmt", false, NULL);
+
+if (env->misa_mxl != MXL_RV32) {
+object_property_set_bool(obj, "zcf", false, NULL);
+}
+}
+
 static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
 
@@ -2291,6 +2343,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 .abstract = true,
 },
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
+DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX,  riscv_max_cpu_init),
 #if defined(CONFIG_KVM)
 DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init),
 #endif
-- 
2.41.0




[PATCH for-8.2 v4 04/11] target/riscv/cpu.c: del DEFINE_PROP_END_OF_LIST() from riscv_cpu_extensions

2023-07-18 Thread Daniel Henrique Barboza
This last blank element is used by the 'for' loop to check if a property
has a valid name.

Remove it and use ARRAY_SIZE() instead like riscv_cpu_options is already
using. All future arrays will also do the same and we'll able to
encapsulate more repetitions in macros later on.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1b6d546522..918acb9e6c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1836,8 +1836,6 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("x-zfbfmin", RISCVCPU, cfg.ext_zfbfmin, false),
 DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
 DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
-
-DEFINE_PROP_END_OF_LIST(),
 };
 
 static Property riscv_cpu_options[] = {
@@ -1892,14 +1890,13 @@ static void riscv_cpu_add_kvm_unavail_prop(Object *obj, 
const char *prop_name)
 
 static void riscv_cpu_add_kvm_properties(Object *obj)
 {
-Property *prop;
 DeviceState *dev = DEVICE(obj);
 
 kvm_riscv_init_user_properties(obj);
 riscv_cpu_add_misa_properties(obj);
 
-for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
-riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_extensions); i++) {
+riscv_cpu_add_kvm_unavail_prop(obj, riscv_cpu_extensions[i].name);
 }
 
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
@@ -1920,7 +1917,6 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
  */
 static void riscv_cpu_add_user_properties(Object *obj)
 {
-Property *prop;
 DeviceState *dev = DEVICE(obj);
 
 #ifndef CONFIG_USER_ONLY
@@ -1934,8 +1930,8 @@ static void riscv_cpu_add_user_properties(Object *obj)
 
 riscv_cpu_add_misa_properties(obj);
 
-for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
-qdev_property_add_static(dev, prop);
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_extensions); i++) {
+qdev_property_add_static(dev, &riscv_cpu_extensions[i]);
 }
 
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
-- 
2.41.0




[PATCH for-8.2 v4 07/11] target/riscv/cpu.c: add ADD_CPU_QDEV_PROPERTIES_ARRAY() macro

2023-07-18 Thread Daniel Henrique Barboza
The code inside riscv_cpu_add_user_properties() became quite repetitive
after recent changes. Add a macro to hide the repetition away.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
---
 target/riscv/cpu.c | 26 +++---
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4d78276058..58cbe410e2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1873,6 +1873,13 @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor 
*v,
 }
 #endif
 
+#define ADD_CPU_QDEV_PROPERTIES_ARRAY(_dev, _array) \
+do { \
+for (int i = 0; i < ARRAY_SIZE(_array); i++) { \
+qdev_property_add_static(_dev, &_array[i]); \
+} \
+} while (0)
+
 #ifndef CONFIG_USER_ONLY
 static void riscv_cpu_add_kvm_unavail_prop(Object *obj, const char *prop_name)
 {
@@ -1942,21 +1949,10 @@ static void riscv_cpu_add_user_properties(Object *obj)
 
 riscv_cpu_add_misa_properties(obj);
 
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_extensions); i++) {
-qdev_property_add_static(dev, &riscv_cpu_extensions[i]);
-}
-
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
-qdev_property_add_static(dev, &riscv_cpu_options[i]);
-}
-
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_vendor_exts); i++) {
-qdev_property_add_static(dev, &riscv_cpu_vendor_exts[i]);
-}
-
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_experimental_exts); i++) {
-qdev_property_add_static(dev, &riscv_cpu_experimental_exts[i]);
-}
+ADD_CPU_QDEV_PROPERTIES_ARRAY(dev, riscv_cpu_extensions);
+ADD_CPU_QDEV_PROPERTIES_ARRAY(dev, riscv_cpu_options);
+ADD_CPU_QDEV_PROPERTIES_ARRAY(dev, riscv_cpu_vendor_exts);
+ADD_CPU_QDEV_PROPERTIES_ARRAY(dev, riscv_cpu_experimental_exts);
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.41.0




[PATCH for-8.2 v4 02/11] target/riscv/cpu.c: skip 'bool' check when filtering KVM props

2023-07-18 Thread Daniel Henrique Barboza
After the introduction of riscv_cpu_options[] all properties in
riscv_cpu_extensions[] are booleans. This check is now obsolete.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 587a5a9548..29f2543f6d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1905,17 +1905,11 @@ static void riscv_cpu_add_user_properties(Object *obj)
  * Set the default to disabled for every extension
  * unknown to KVM and error out if the user attempts
  * to enable any of them.
- *
- * We're giving a pass for non-bool properties since they're
- * not related to the availability of extensions and can be
- * safely ignored as is.
  */
-if (prop->info == &qdev_prop_bool) {
-object_property_add(obj, prop->name, "bool",
-NULL, cpu_set_cfg_unavailable,
-NULL, (void *)prop->name);
-continue;
-}
+object_property_add(obj, prop->name, "bool",
+NULL, cpu_set_cfg_unavailable,
+NULL, (void *)prop->name);
+continue;
 }
 #endif
 qdev_property_add_static(dev, prop);
-- 
2.41.0




[PATCH for-8.2 v4 11/11] target/riscv: deprecate the 'any' CPU type

2023-07-18 Thread Daniel Henrique Barboza
The 'any' CPU type was introduced in commit dc5bd18fa5725 ("RISC-V CPU
Core Definition"), being around since the beginning. It's not an easy
CPU to use: it's undocumented and its name doesn't tell users much about
what the CPU is supposed to bring. 'git log' doesn't help us either in
knowing what was the original design of this CPU type.

The closest we have is a comment from Alistair [1] where he recalls from
memory that the 'any' CPU is supposed to behave like the newly added
'max' CPU. He also suggested that the 'any' CPU should be removed.

The default CPUs are rv32 and rv64, so removing the 'any' CPU will have
impact only on users that might have a script that uses '-cpu any'.
And those users are better off using the default CPUs or the new 'max'
CPU.

We would love to just remove the code and be done with it, but one does
not simply remove a feature in QEMU. We'll put the CPU in quarantine
first, letting users know that we have the intent of removing it in the
future.

[1] https://lists.gnu.org/archive/html/qemu-devel/2023-07/msg02891.html

Signed-off-by: Daniel Henrique Barboza 
---
 docs/about/deprecated.rst | 12 
 target/riscv/cpu.c|  5 +
 2 files changed, 17 insertions(+)

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 02ea5a839f..68afa43fd0 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -371,6 +371,18 @@ QEMU's ``vhost`` feature, which would eliminate the high 
latency costs under
 which the 9p ``proxy`` backend currently suffers. However as of to date nobody
 has indicated plans for such kind of reimplemention unfortunately.
 
+RISC-V 'any' CPU type ``-cpu any`` (since 8.2)
+^^
+
+The 'any' CPU type was introduced back in 2018 and has been around since the
+initial RISC-V QEMU port. Its usage has always been unclear: users don't know
+what to expect from a CPU called 'any', and in fact the CPU does not do 
anything
+special that aren't already done by the default CPUs rv32/rv64.
+
+After the introduction of the 'max' CPU type RISC-V now has a good coverage
+of generic CPUs: rv32 and rv64 as default CPUs and 'max' as a feature complete
+CPU for both 32 and 64 bit builds. Users are then discouraged to use the 'any'
+CPU type starting in 8.2.
 
 Block device options
 
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7fdde68dee..edf3b95a14 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1470,6 +1470,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
 Error *local_err = NULL;
 
+if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_ANY) != NULL) {
+warn_report("The 'any' CPU is deprecated and will be "
+"removed in the future.");
+}
+
 cpu_exec_realizefn(cs, &local_err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
-- 
2.41.0




[PATCH for-8.2 v4 06/11] target/riscv/cpu.c: split non-ratified exts from riscv_cpu_extensions[]

2023-07-18 Thread Daniel Henrique Barboza
Create a new riscv_cpu_experimental_exts[] to store the non-ratified
extensions properties. Once they are ratified we'll move them back to
riscv_cpu_extensions[].

riscv_cpu_add_user_properties() and riscv_cpu_add_kvm_properties() are
changed to keep adding non-ratified properties to users.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 41 ++---
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b59b06cddd..4d78276058 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1807,21 +1807,6 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
 DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
 DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
-
-/* These are experimental so mark with 'x-' */
-DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
-
-/* ePMP 0.9.3 */
-DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
-DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
-DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false),
-
-DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false),
-DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false),
-
-DEFINE_PROP_BOOL("x-zfbfmin", RISCVCPU, cfg.ext_zfbfmin, false),
-DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
-DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
 };
 
 static Property riscv_cpu_vendor_exts[] = {
@@ -1839,6 +1824,23 @@ static Property riscv_cpu_vendor_exts[] = {
 DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, 
false),
 };
 
+/* These are experimental so mark with 'x-' */
+static Property riscv_cpu_experimental_exts[] = {
+DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
+
+/* ePMP 0.9.3 */
+DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
+DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
+DEFINE_PROP_BOOL("x-ssaia", RISCVCPU, cfg.ext_ssaia, false),
+
+DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false),
+DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false),
+
+DEFINE_PROP_BOOL("x-zfbfmin", RISCVCPU, cfg.ext_zfbfmin, false),
+DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
+DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
+};
+
 static Property riscv_cpu_options[] = {
 DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
 
@@ -1904,6 +1906,11 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
 riscv_cpu_add_kvm_unavail_prop(obj, riscv_cpu_vendor_exts[i].name);
 }
 
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_experimental_exts); i++) {
+riscv_cpu_add_kvm_unavail_prop(obj,
+   riscv_cpu_experimental_exts[i].name);
+}
+
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
 /* Check if KVM created the property already */
 if (object_property_find(obj, riscv_cpu_options[i].name)) {
@@ -1946,6 +1953,10 @@ static void riscv_cpu_add_user_properties(Object *obj)
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_vendor_exts); i++) {
 qdev_property_add_static(dev, &riscv_cpu_vendor_exts[i]);
 }
+
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_experimental_exts); i++) {
+qdev_property_add_static(dev, &riscv_cpu_experimental_exts[i]);
+}
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.41.0




[PATCH for-8.2 v4 03/11] target/riscv/cpu.c: split kvm prop handling to its own helper

2023-07-18 Thread Daniel Henrique Barboza
Future patches will split the existing Property arrays even further, and
the existing code in riscv_cpu_add_user_properties() will start to scale
bad with it because it's dealing with KVM constraints mixed in with TCG
constraints. We're going to pay a high price to share a couple of common
lines of code between the two.

Create a new riscv_cpu_add_kvm_properties() that will be forked from
riscv_cpu_add_user_properties() if we're running KVM. The helper
includes all properties that a KVM CPU will add. The rest of
riscv_cpu_add_user_properties() body will then be relieved from having
to deal with KVM constraints.

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 65 ++
 1 file changed, 42 insertions(+), 23 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 29f2543f6d..1b6d546522 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1872,6 +1872,46 @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor 
*v,
 }
 #endif
 
+#ifndef CONFIG_USER_ONLY
+static void riscv_cpu_add_kvm_unavail_prop(Object *obj, const char *prop_name)
+{
+/* Check if KVM created the property already */
+if (object_property_find(obj, prop_name)) {
+return;
+}
+
+/*
+ * Set the default to disabled for every extension
+ * unknown to KVM and error out if the user attempts
+ * to enable any of them.
+ */
+object_property_add(obj, prop_name, "bool",
+NULL, cpu_set_cfg_unavailable,
+NULL, (void *)prop_name);
+}
+
+static void riscv_cpu_add_kvm_properties(Object *obj)
+{
+Property *prop;
+DeviceState *dev = DEVICE(obj);
+
+kvm_riscv_init_user_properties(obj);
+riscv_cpu_add_misa_properties(obj);
+
+for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
+riscv_cpu_add_kvm_unavail_prop(obj, prop->name);
+}
+
+for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
+/* Check if KVM created the property already */
+if (object_property_find(obj, riscv_cpu_options[i].name)) {
+continue;
+}
+qdev_property_add_static(dev, &riscv_cpu_options[i]);
+}
+}
+#endif
+
 /*
  * Add CPU properties with user-facing flags.
  *
@@ -1887,39 +1927,18 @@ static void riscv_cpu_add_user_properties(Object *obj)
 riscv_add_satp_mode_properties(obj);
 
 if (kvm_enabled()) {
-kvm_riscv_init_user_properties(obj);
+riscv_cpu_add_kvm_properties(obj);
+return;
 }
 #endif
 
 riscv_cpu_add_misa_properties(obj);
 
 for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
-#ifndef CONFIG_USER_ONLY
-if (kvm_enabled()) {
-/* Check if KVM created the property already */
-if (object_property_find(obj, prop->name)) {
-continue;
-}
-
-/*
- * Set the default to disabled for every extension
- * unknown to KVM and error out if the user attempts
- * to enable any of them.
- */
-object_property_add(obj, prop->name, "bool",
-NULL, cpu_set_cfg_unavailable,
-NULL, (void *)prop->name);
-continue;
-}
-#endif
 qdev_property_add_static(dev, prop);
 }
 
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
-/* Check if KVM created the property already */
-if (object_property_find(obj, riscv_cpu_options[i].name)) {
-continue;
-}
 qdev_property_add_static(dev, &riscv_cpu_options[i]);
 }
 }
-- 
2.41.0




[PATCH for-8.2 v4 08/11] target/riscv/cpu.c: add ADD_UNAVAIL_KVM_PROP_ARRAY() macro

2023-07-18 Thread Daniel Henrique Barboza
Use a macro in riscv_cpu_add_kvm_properties() to eliminate some of its
code repetition, similar to what we're already doing with
ADD_CPU_QDEV_PROPERTIES_ARRAY().

Signed-off-by: Daniel Henrique Barboza 
---
 target/riscv/cpu.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 58cbe410e2..7f79585bd1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1898,6 +1898,13 @@ static void riscv_cpu_add_kvm_unavail_prop(Object *obj, 
const char *prop_name)
 NULL, (void *)prop_name);
 }
 
+#define ADD_UNAVAIL_KVM_PROP_ARRAY(_obj, _array) \
+do { \
+for (int i = 0; i < ARRAY_SIZE(_array); i++) { \
+riscv_cpu_add_kvm_unavail_prop(_obj, _array[i].name); \
+} \
+} while (0)
+
 static void riscv_cpu_add_kvm_properties(Object *obj)
 {
 DeviceState *dev = DEVICE(obj);
@@ -1905,18 +1912,9 @@ static void riscv_cpu_add_kvm_properties(Object *obj)
 kvm_riscv_init_user_properties(obj);
 riscv_cpu_add_misa_properties(obj);
 
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_extensions); i++) {
-riscv_cpu_add_kvm_unavail_prop(obj, riscv_cpu_extensions[i].name);
-}
-
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_vendor_exts); i++) {
-riscv_cpu_add_kvm_unavail_prop(obj, riscv_cpu_vendor_exts[i].name);
-}
-
-for (int i = 0; i < ARRAY_SIZE(riscv_cpu_experimental_exts); i++) {
-riscv_cpu_add_kvm_unavail_prop(obj,
-   riscv_cpu_experimental_exts[i].name);
-}
+ADD_UNAVAIL_KVM_PROP_ARRAY(obj, riscv_cpu_extensions);
+ADD_UNAVAIL_KVM_PROP_ARRAY(obj, riscv_cpu_vendor_exts);
+ADD_UNAVAIL_KVM_PROP_ARRAY(obj, riscv_cpu_experimental_exts);
 
 for (int i = 0; i < ARRAY_SIZE(riscv_cpu_options); i++) {
 /* Check if KVM created the property already */
-- 
2.41.0




[PATCH 07/14] target/s390x: Fix assertion failure in VFMIN/VFMAX with reserved type

2023-07-18 Thread Ilya Leoshkevich
Passing reserved type to VFMIN/VFMAX causes an assertion failure in
vfmin_res() and vfmax_res(). These instructions should raise a
specification exception in this case.

Cc: qemu-sta...@nongnu.org
Fixes: da4807527f3b ("s390x/tcg: Implement VECTOR FP (MAXIMUM|MINIMUM)")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/vec_fpu_helper.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/target/s390x/tcg/vec_fpu_helper.c 
b/target/s390x/tcg/vec_fpu_helper.c
index 75cf605b9f4..f1671679879 100644
--- a/target/s390x/tcg/vec_fpu_helper.c
+++ b/target/s390x/tcg/vec_fpu_helper.c
@@ -915,7 +915,7 @@ static void vfminmax32(S390Vector *v1, const S390Vector *v2,
 float32 b = s390_vec_read_float32(v3, i);
 float32 result;
 
-if (type != S390_MINMAX_TYPE_IEEE) {
+if (type > S390_MINMAX_TYPE_IEEE && type <= S390_MINMAX_TYPE_F) {
 S390MinMaxRes res;
 
 if (is_abs) {
@@ -944,12 +944,14 @@ static void vfminmax32(S390Vector *v1, const S390Vector 
*v2,
 default:
 g_assert_not_reached();
 }
-} else if (!is_abs) {
+} else if (type == S390_MINMAX_TYPE_IEEE && !is_abs) {
 result = is_min ? float32_minnum(a, b, &env->fpu_status) :
   float32_maxnum(a, b, &env->fpu_status);
-} else {
+} else if (type == S390_MINMAX_TYPE_IEEE) {
 result = is_min ? float32_minnummag(a, b, &env->fpu_status) :
   float32_maxnummag(a, b, &env->fpu_status);
+} else {
+tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
 }
 
 s390_vec_write_float32(&tmp, i, result);
@@ -977,7 +979,7 @@ static void vfminmax64(S390Vector *v1, const S390Vector *v2,
 float64 b = s390_vec_read_float64(v3, i);
 float64 result;
 
-if (type != S390_MINMAX_TYPE_IEEE) {
+if (type > S390_MINMAX_TYPE_IEEE && type <= S390_MINMAX_TYPE_F) {
 S390MinMaxRes res;
 
 if (is_abs) {
@@ -1006,12 +1008,14 @@ static void vfminmax64(S390Vector *v1, const S390Vector 
*v2,
 default:
 g_assert_not_reached();
 }
-} else if (!is_abs) {
+} else if (type == S390_MINMAX_TYPE_IEEE && !is_abs) {
 result = is_min ? float64_minnum(a, b, &env->fpu_status) :
   float64_maxnum(a, b, &env->fpu_status);
-} else {
+} else if (type == S390_MINMAX_TYPE_IEEE) {
 result = is_min ? float64_minnummag(a, b, &env->fpu_status) :
   float64_maxnummag(a, b, &env->fpu_status);
+} else {
+tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
 }
 
 s390_vec_write_float64(&tmp, i, result);
@@ -1035,7 +1039,7 @@ static void vfminmax128(S390Vector *v1, const S390Vector 
*v2,
 uint8_t vxc, vec_exc = 0;
 float128 result;
 
-if (type != S390_MINMAX_TYPE_IEEE) {
+if (type > S390_MINMAX_TYPE_IEEE && type <= S390_MINMAX_TYPE_F) {
 S390MinMaxRes res;
 
 if (is_abs) {
@@ -1064,12 +1068,14 @@ static void vfminmax128(S390Vector *v1, const 
S390Vector *v2,
 default:
 g_assert_not_reached();
 }
-} else if (!is_abs) {
+} else if (type == S390_MINMAX_TYPE_IEEE && !is_abs) {
 result = is_min ? float128_minnum(a, b, &env->fpu_status) :
   float128_maxnum(a, b, &env->fpu_status);
-} else {
+} else if (type == S390_MINMAX_TYPE_IEEE) {
 result = is_min ? float128_minnummag(a, b, &env->fpu_status) :
   float128_maxnummag(a, b, &env->fpu_status);
+} else {
+tcg_s390_program_interrupt(env, PGM_SPECIFICATION, retaddr);
 }
 
 vxc = check_ieee_exc(env, 0, false, &vec_exc);
-- 
2.41.0




[PATCH 09/14] tests/tcg/s390x: Test CLGEBR and CGEBRA

2023-07-18 Thread Ilya Leoshkevich
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/s390x/Makefile.target |  5 +
 tests/tcg/s390x/cgebra.c| 32 
 tests/tcg/s390x/clgebr.c| 32 
 3 files changed, 69 insertions(+)
 create mode 100644 tests/tcg/s390x/cgebra.c
 create mode 100644 tests/tcg/s390x/clgebr.c

diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index 19fbbc6e531..71bf39b78d3 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -39,12 +39,17 @@ TESTS+=mxdb
 TESTS+=epsw
 TESTS+=larl
 TESTS+=mdeb
+TESTS+=cgebra
+TESTS+=clgebr
 
 cdsg: CFLAGS+=-pthread
 cdsg: LDFLAGS+=-pthread
 
 rxsbg: CFLAGS+=-O2
 
+cgebra: LDFLAGS+=-lm
+clgebr: LDFLAGS+=-lm
+
 include $(S390X_SRC)/pgm-specification.mak
 $(PGM_SPECIFICATION_TESTS): pgm-specification-user.o
 $(PGM_SPECIFICATION_TESTS): LDFLAGS+=pgm-specification-user.o
diff --git a/tests/tcg/s390x/cgebra.c b/tests/tcg/s390x/cgebra.c
new file mode 100644
index 000..f91e10d2d3c
--- /dev/null
+++ b/tests/tcg/s390x/cgebra.c
@@ -0,0 +1,32 @@
+/*
+ * Test the CGEBRA instruction.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include 
+#include 
+#include 
+
+int main(void)
+{
+float r2 = 1E+300;
+long long r1;
+int cc;
+
+feclearexcept(FE_ALL_EXCEPT);
+asm("cgebra %[r1],%[m3],%[r2],%[m4]\n"
+"ipm %[cc]\n"
+: [r1] "=r" (r1)
+, [cc] "=r" (cc)
+: [m3] "i" (5) /* round toward 0 */
+, [r2] "f" (r2)
+, [m4] "i" (8) /* bit 0 is set, but must be ignored; XxC is not set */
+: "cc");
+cc >>= 28;
+
+assert(r1 == 0x7fffLL);
+assert(cc == 3);
+assert(fetestexcept(FE_ALL_EXCEPT) == (FE_INVALID | FE_INEXACT));
+
+return EXIT_SUCCESS;
+}
diff --git a/tests/tcg/s390x/clgebr.c b/tests/tcg/s390x/clgebr.c
new file mode 100644
index 000..d491899b56e
--- /dev/null
+++ b/tests/tcg/s390x/clgebr.c
@@ -0,0 +1,32 @@
+/*
+ * Test the CLGEBR instruction.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include 
+#include 
+#include 
+
+int main(void)
+{
+float r2 = -1;
+long long r1;
+int cc;
+
+feclearexcept(FE_ALL_EXCEPT);
+asm("clgebr %[r1],%[m3],%[r2],%[m4]\n"
+"ipm %[cc]\n"
+: [r1] "=r" (r1)
+, [cc] "=r" (cc)
+: [m3] "i" (5) /* round toward 0 */
+, [r2] "f" (r2)
+, [m4] "i" (8) /* bit 0 is set, but must be ignored; XxC is not set */
+: "cc");
+cc >>= 28;
+
+assert(r1 == 0);
+assert(cc == 3);
+assert(fetestexcept(FE_ALL_EXCEPT) == (FE_INVALID | FE_INEXACT));
+
+return EXIT_SUCCESS;
+}
-- 
2.41.0




[PATCH 00/14] target/s390x: Miscellaneous TCG fixes, part 2

2023-07-18 Thread Ilya Leoshkevich
Hi,

Here is another set of fixes for issues found by randomized testing.

Most of them have to do with simple insufficient error handling or
corner cases, but 3/14 and 6/14 took a while to figure out, and
hopefully I got the fixes right. 13/14 is a test for an issue that
Richard has already fixed, but I thought it would be helpful to have it
anyway.

Best regards,
Ilya

Ilya Leoshkevich (14):
  target/s390x: Make CKSM raise an exception if R2 is odd
  target/s390x: Fix CLM with M3=0
  target/s390x: Fix CONVERT TO LOGICAL/FIXED with out-of-range inputs
  target/s390x: Fix ICM with M3=0
  target/s390x: Make MC raise specification exception when class >= 16
  tcg/{i386,s390x}: Add earlyclobber to the op_add2's first output
  target/s390x: Fix assertion failure in VFMIN/VFMAX with reserved type
  tests/tcg/s390x: Test CKSM
  tests/tcg/s390x: Test CLGEBR and CGEBRA
  tests/tcg/s390x: Test CLM
  tests/tcg/s390x: Test ICM
  tests/tcg/s390x: Test MC
  tests/tcg/s390x: Test STPQ
  tests/tcg/s390x: Test VCKSM

 target/s390x/tcg/excp_helper.c  |  2 +-
 target/s390x/tcg/fpu_helper.c   |  3 +-
 target/s390x/tcg/mem_helper.c   |  5 +++
 target/s390x/tcg/translate.c| 21 --
 target/s390x/tcg/vec_fpu_helper.c   | 24 +++
 tcg/i386/tcg-target-con-set.h   |  2 +-
 tcg/i386/tcg-target.c.inc   |  2 +-
 tcg/s390x/tcg-target-con-set.h  |  5 +--
 tcg/s390x/tcg-target.c.inc  |  4 +-
 tcg/tcg.c   |  8 +++-
 tests/tcg/s390x/Makefile.softmmu-target |  5 +++
 tests/tcg/s390x/Makefile.target |  6 +++
 tests/tcg/s390x/cgebra.c| 32 ++
 tests/tcg/s390x/cksm.S  | 29 +
 tests/tcg/s390x/clgebr.c| 32 ++
 tests/tcg/s390x/clm.S   | 29 +
 tests/tcg/s390x/icm.S   | 32 ++
 tests/tcg/s390x/mc.S| 56 +
 tests/tcg/s390x/stpq.S  | 20 +
 tests/tcg/s390x/vcksm.c | 31 ++
 tests/tcg/s390x/vx.h|  2 +
 21 files changed, 327 insertions(+), 23 deletions(-)
 create mode 100644 tests/tcg/s390x/cgebra.c
 create mode 100644 tests/tcg/s390x/cksm.S
 create mode 100644 tests/tcg/s390x/clgebr.c
 create mode 100644 tests/tcg/s390x/clm.S
 create mode 100644 tests/tcg/s390x/icm.S
 create mode 100644 tests/tcg/s390x/mc.S
 create mode 100644 tests/tcg/s390x/stpq.S
 create mode 100644 tests/tcg/s390x/vcksm.c

-- 
2.41.0




[PATCH 08/14] tests/tcg/s390x: Test CKSM

2023-07-18 Thread Ilya Leoshkevich
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/s390x/Makefile.softmmu-target |  1 +
 tests/tcg/s390x/cksm.S  | 29 +
 2 files changed, 30 insertions(+)
 create mode 100644 tests/tcg/s390x/cksm.S

diff --git a/tests/tcg/s390x/Makefile.softmmu-target 
b/tests/tcg/s390x/Makefile.softmmu-target
index 242c7b0f83c..e813e318db9 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -16,6 +16,7 @@ LDFLAGS=-nostdlib -static
 
 ASM_TESTS =
\
 bal
\
+cksm   
\
 exrl-ssm-early 
\
 sam
\
 lpsw   
\
diff --git a/tests/tcg/s390x/cksm.S b/tests/tcg/s390x/cksm.S
new file mode 100644
index 000..a45f3ef6bfd
--- /dev/null
+++ b/tests/tcg/s390x/cksm.S
@@ -0,0 +1,29 @@
+.org 0x8e
+program_interruption_code:
+.org 0x1d0 /* program new PSW */
+.quad 0,pgm
+.org 0x200 /* lowcore padding */
+.globl _start
+_start:
+lmg %r0,%r1,cksm_args
+cksm %r2,%r0
+c %r2,cksm_exp
+jne failure
+cksm %r2,%r15
+failure:
+lpswe failure_psw
+pgm:
+chhsi program_interruption_code,6  /* specification exception? */
+jne failure
+lpswe success_psw
+cksm_args:
+.quad cksm_buf, 16
+cksm_buf:
+.quad 0x, 0x12345678
+cksm_exp:
+.long 0x89ab1234
+.align 8
+success_psw:
+.quad 0x2,0xfff/* see is_special_wait_psw() */
+failure_psw:
+.quad 0x2,0/* disabled wait */
-- 
2.41.0




[PATCH 12/14] tests/tcg/s390x: Test MC

2023-07-18 Thread Ilya Leoshkevich
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/s390x/Makefile.softmmu-target |  1 +
 tests/tcg/s390x/mc.S| 56 +
 2 files changed, 57 insertions(+)
 create mode 100644 tests/tcg/s390x/mc.S

diff --git a/tests/tcg/s390x/Makefile.softmmu-target 
b/tests/tcg/s390x/Makefile.softmmu-target
index 58684d7da71..145e0bfde16 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -24,6 +24,7 @@ ASM_TESTS =   
 \
 lpsw   
\
 lpswe-early
\
 lra
\
+mc 
\
 ssm-early  
\
 stosm-early
\
 unaligned-lowcore
diff --git a/tests/tcg/s390x/mc.S b/tests/tcg/s390x/mc.S
new file mode 100644
index 000..e7466bb4b57
--- /dev/null
+++ b/tests/tcg/s390x/mc.S
@@ -0,0 +1,56 @@
+.org 0x8d
+ilc:
+.org 0x8e
+program_interruption_code:
+.org 0x94
+monitor_class:
+.org 0xb0
+monitor_code:
+.org 0x150
+program_old_psw:
+.org 0x1d0  /* program new PSW */
+.quad 0x18000,pgm   /* 64-bit mode */
+.org 0x200  /* lowcore padding */
+.globl _start
+_start:
+stctg %c8,%c8,c8/* enable only monitor class 1 */
+mvhhi c8+6,0x4000
+lctlg %c8,%c8,c8
+mc_nop:
+mc 123,0
+mc_monitor_event:
+mc 321,1
+j failure
+mc_specification:
+mc 333,16
+j failure
+pgm:
+lgrl %r0,program_old_psw+8  /* ilc adjustment */
+llgc %r1,ilc
+sgr %r0,%r1
+larl %r1,mc_monitor_event   /* dispatch based on old PSW */
+cgrje %r0,%r1,pgm_monitor_event
+larl %r1,mc_specification
+cgrje %r0,%r1,pgm_specification
+j failure
+pgm_monitor_event:
+chhsi program_interruption_code,0x40/* monitor event? */
+jne failure
+chhsi monitor_class,1   /* class from mc_monitor_event? */
+jne failure
+cghsi monitor_code,321  /* code from mc_monitor_event? */
+jne failure
+j mc_specification  /* next test */
+pgm_specification:
+chhsi program_interruption_code,6   /* specification exception? */
+jne failure
+lpswe success_psw
+failure:
+lpswe failure_psw
+.align 8
+c8:
+.quad 0
+success_psw:
+.quad 0x2,0xfff /* see is_special_wait_psw() */
+failure_psw:
+.quad 0x2,0 /* disabled wait */
-- 
2.41.0




[PATCH 06/14] tcg/{i386, s390x}: Add earlyclobber to the op_add2's first output

2023-07-18 Thread Ilya Leoshkevich
i386 and s390x implementations of op_add2 require an earlyclobber,
which is currently missing. This breaks VCKSM in s390x guests. E.g., on
x86_64 the following op:

add2_i32 tmp2,tmp3,tmp2,tmp3,tmp3,tmp2   dead: 0 2 3 4 5  pref=none,0x

is translated to:

addl %ebx, %r12d
adcl %r12d, %ebx

Introduce a new C_N1_O1_I4 constraint, and make sure that earlyclobber
of aliased outputs is honored.

Cc: qemu-sta...@nongnu.org
Fixes: 82790a870992 ("tcg: Add markup for output requires new register")
Signed-off-by: Ilya Leoshkevich 
---
 tcg/i386/tcg-target-con-set.h  | 2 +-
 tcg/i386/tcg-target.c.inc  | 2 +-
 tcg/s390x/tcg-target-con-set.h | 5 ++---
 tcg/s390x/tcg-target.c.inc | 4 ++--
 tcg/tcg.c  | 8 +++-
 5 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/tcg/i386/tcg-target-con-set.h b/tcg/i386/tcg-target-con-set.h
index 91ceb0e1da2..cb4b25263e9 100644
--- a/tcg/i386/tcg-target-con-set.h
+++ b/tcg/i386/tcg-target-con-set.h
@@ -53,4 +53,4 @@ C_O2_I1(r, r, L)
 C_O2_I2(a, d, a, r)
 C_O2_I2(r, r, L, L)
 C_O2_I3(a, d, 0, 1, r)
-C_O2_I4(r, r, 0, 1, re, re)
+C_N1_O1_I4(r, r, 0, 1, re, re)
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index ab997b5fb39..77482da0709 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -3335,7 +3335,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_add2_i64:
 case INDEX_op_sub2_i32:
 case INDEX_op_sub2_i64:
-return C_O2_I4(r, r, 0, 1, re, re);
+return C_N1_O1_I4(r, r, 0, 1, re, re);
 
 case INDEX_op_ctz_i32:
 case INDEX_op_ctz_i64:
diff --git a/tcg/s390x/tcg-target-con-set.h b/tcg/s390x/tcg-target-con-set.h
index cbad91b2b56..ce779e8b44a 100644
--- a/tcg/s390x/tcg-target-con-set.h
+++ b/tcg/s390x/tcg-target-con-set.h
@@ -41,6 +41,5 @@ C_O2_I1(o, m, r)
 C_O2_I2(o, m, 0, r)
 C_O2_I2(o, m, r, r)
 C_O2_I3(o, m, 0, 1, r)
-C_O2_I4(r, r, 0, 1, rA, r)
-C_O2_I4(r, r, 0, 1, ri, r)
-C_O2_I4(r, r, 0, 1, r, r)
+C_N1_O1_I4(r, r, 0, 1, ri, r)
+C_N1_O1_I4(r, r, 0, 1, rA, r)
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
index a878acd8ca6..a94f7908d64 100644
--- a/tcg/s390x/tcg-target.c.inc
+++ b/tcg/s390x/tcg-target.c.inc
@@ -3229,11 +3229,11 @@ static TCGConstraintSetIndex 
tcg_target_op_def(TCGOpcode op)
 
 case INDEX_op_add2_i32:
 case INDEX_op_sub2_i32:
-return C_O2_I4(r, r, 0, 1, ri, r);
+return C_N1_O1_I4(r, r, 0, 1, ri, r);
 
 case INDEX_op_add2_i64:
 case INDEX_op_sub2_i64:
-return C_O2_I4(r, r, 0, 1, rA, r);
+return C_N1_O1_I4(r, r, 0, 1, rA, r);
 
 case INDEX_op_st_vec:
 return C_O0_I2(v, r);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 652e8ea6b93..ddfe9a96cb7 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -648,6 +648,7 @@ static void tcg_out_movext3(TCGContext *s, const 
TCGMovExtend *i1,
 #define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2),
 #define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3),
 #define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, 
I4),
+#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_n1_o1_i4_, O1, O2, I1, I2, 
I3, I4),
 
 typedef enum {
 #include "tcg-target-con-set.h"
@@ -668,6 +669,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
 #undef C_O2_I2
 #undef C_O2_I3
 #undef C_O2_I4
+#undef C_N1_O1_I4
 
 /* Put all of the constraint sets into an array, indexed by the enum. */
 
@@ -687,6 +689,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode);
 #define C_O2_I2(O1, O2, I1, I2) { .args_ct_str = { #O1, #O2, #I1, #I2 
} },
 #define C_O2_I3(O1, O2, I1, I2, I3) { .args_ct_str = { #O1, #O2, #I1, #I2, 
#I3 } },
 #define C_O2_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { #O1, #O2, #I1, #I2, 
#I3, #I4 } },
+#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) { .args_ct_str = { "&" #O1, #O2, 
#I1, #I2, #I3, #I4 } },
 
 static const TCGTargetOpDef constraint_sets[] = {
 #include "tcg-target-con-set.h"
@@ -706,6 +709,7 @@ static const TCGTargetOpDef constraint_sets[] = {
 #undef C_O2_I2
 #undef C_O2_I3
 #undef C_O2_I4
+#undef C_N1_O1_I4
 
 /* Expand the enumerator to be returned from tcg_target_op_def(). */
 
@@ -725,6 +729,7 @@ static const TCGTargetOpDef constraint_sets[] = {
 #define C_O2_I2(O1, O2, I1, I2) C_PFX4(c_o2_i2_, O1, O2, I1, I2)
 #define C_O2_I3(O1, O2, I1, I2, I3) C_PFX5(c_o2_i3_, O1, O2, I1, I2, I3)
 #define C_O2_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_o2_i4_, O1, O2, I1, I2, I3, 
I4)
+#define C_N1_O1_I4(O1, O2, I1, I2, I3, I4) C_PFX6(c_n1_o1_i4_, O1, O2, I1, I2, 
I3, I4)
 
 #include "tcg-target.c.inc"
 
@@ -4703,7 +4708,8 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp 
*op)
  * dead after the instruction, we must allocate a new
  * register and move it.
  */
-if (temp_readonly(ts) || !IS_DEAD_ARG(i)) {
+if (temp_readonly(ts) || 

[PATCH 11/14] tests/tcg/s390x: Test ICM

2023-07-18 Thread Ilya Leoshkevich
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/s390x/Makefile.softmmu-target |  1 +
 tests/tcg/s390x/icm.S   | 32 +
 2 files changed, 33 insertions(+)
 create mode 100644 tests/tcg/s390x/icm.S

diff --git a/tests/tcg/s390x/Makefile.softmmu-target 
b/tests/tcg/s390x/Makefile.softmmu-target
index 062d8e368aa..58684d7da71 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -19,6 +19,7 @@ ASM_TESTS =   
 \
 cksm   
\
 clm
\
 exrl-ssm-early 
\
+icm
\
 sam
\
 lpsw   
\
 lpswe-early
\
diff --git a/tests/tcg/s390x/icm.S b/tests/tcg/s390x/icm.S
new file mode 100644
index 000..d24d1f52fb8
--- /dev/null
+++ b/tests/tcg/s390x/icm.S
@@ -0,0 +1,32 @@
+.org 0x8e
+program_interruption_code:
+.org 0x1d0 /* program new PSW */
+.quad 0,pgm
+.org 0x200 /* lowcore padding */
+.globl _start
+_start:
+lgrl %r0,op1
+icm %r0,10,op2
+cg %r0,exp
+jne failure
+lgrl %r1,bad_addr
+icm %r0,0,0(%r1)
+failure:
+lpswe failure_psw
+pgm:
+chhsi program_interruption_code,5  /* addressing exception? */
+jne failure
+lpswe success_psw
+.align 8
+op1:
+.quad 0x1234567887654321
+op2:
+.quad 0x0011223344556677
+exp:
+.quad 0x1234567800651121
+bad_addr:
+.quad 0x
+success_psw:
+.quad 0x2,0xfff/* see is_special_wait_psw() */
+failure_psw:
+.quad 0x2,0/* disabled wait */
-- 
2.41.0




[PATCH 05/14] target/s390x: Make MC raise specification exception when class >= 16

2023-07-18 Thread Ilya Leoshkevich
MC requires bit positions 8-11 (upper 4 bits of class) to be zeros,
otherwise it must raise a specification exception.

Cc: qemu-sta...@nongnu.org
Fixes: 20d143e2cab8 ("s390x/tcg: Implement MONITOR CALL")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/excp_helper.c | 2 +-
 target/s390x/tcg/translate.c   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c
index 228aa9f2373..3da337f7c72 100644
--- a/target/s390x/tcg/excp_helper.c
+++ b/target/s390x/tcg/excp_helper.c
@@ -639,7 +639,7 @@ void monitor_event(CPUS390XState *env,
 void HELPER(monitor_call)(CPUS390XState *env, uint64_t monitor_code,
   uint32_t monitor_class)
 {
-g_assert(monitor_class <= 0xff);
+g_assert(monitor_class <= 0xf);
 
 if (env->cregs[8] & (0x8000 >> monitor_class)) {
 monitor_event(env, monitor_code, monitor_class, GETPC());
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 2d7cc8963b4..4b32c2333c2 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -3184,9 +3184,9 @@ static DisasJumpType op_lcbb(DisasContext *s, DisasOps *o)
 
 static DisasJumpType op_mc(DisasContext *s, DisasOps *o)
 {
-const uint16_t monitor_class = get_field(s, i2);
+const uint8_t monitor_class = get_field(s, i2);
 
-if (monitor_class & 0xff00) {
+if (monitor_class & 0xf0) {
 gen_program_exception(s, PGM_SPECIFICATION);
 return DISAS_NORETURN;
 }
-- 
2.41.0




[PATCH 03/14] target/s390x: Fix CONVERT TO LOGICAL/FIXED with out-of-range inputs

2023-07-18 Thread Ilya Leoshkevich
CONVERT TO LOGICAL/FIXED deviate from IEEE 754 in that they raise an
inexact exception on out-of-range inputs. float_flag_invalid_cvti
aligns nicely with that behavior, so convert it to
S390_IEEE_MASK_INEXACT.

Cc: qemu-sta...@nongnu.org
Fixes: defb0e3157af ("s390x: Implement opcode helpers")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/fpu_helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/s390x/tcg/fpu_helper.c b/target/s390x/tcg/fpu_helper.c
index 4b7fa58af3e..3d941ed2d28 100644
--- a/target/s390x/tcg/fpu_helper.c
+++ b/target/s390x/tcg/fpu_helper.c
@@ -52,7 +52,8 @@ uint8_t s390_softfloat_exc_to_ieee(unsigned int exc)
 s390_exc |= (exc & float_flag_divbyzero) ? S390_IEEE_MASK_DIVBYZERO : 0;
 s390_exc |= (exc & float_flag_overflow) ? S390_IEEE_MASK_OVERFLOW : 0;
 s390_exc |= (exc & float_flag_underflow) ? S390_IEEE_MASK_UNDERFLOW : 0;
-s390_exc |= (exc & float_flag_inexact) ? S390_IEEE_MASK_INEXACT : 0;
+s390_exc |= (exc & (float_flag_inexact | float_flag_invalid_cvti)) ?
+S390_IEEE_MASK_INEXACT : 0;
 
 return s390_exc;
 }
-- 
2.41.0




[PATCH 04/14] target/s390x: Fix ICM with M3=0

2023-07-18 Thread Ilya Leoshkevich
When the mask is zero, access exceptions should still be recognized for
1 byte at the second-operand address. CC should be set to 0.

Cc: qemu-sta...@nongnu.org
Fixes: e023e832d0ac ("s390x: translate engine for s390x CPU")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/translate.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 2f61e879878..2d7cc8963b4 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -2516,6 +2516,12 @@ static DisasJumpType op_icm(DisasContext *s, DisasOps *o)
 len = 8;
 goto one_insert;
 
+case 0:
+/* Recognize access exceptions for the first byte.  */
+tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_UB);
+gen_op_movi_cc(s, 0);
+return DISAS_NEXT;
+
 one_insert:
 pos = base + ctz32(m3) * 8;
 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, len);
-- 
2.41.0




[PATCH 14/14] tests/tcg/s390x: Test VCKSM

2023-07-18 Thread Ilya Leoshkevich
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/s390x/Makefile.target |  1 +
 tests/tcg/s390x/vcksm.c | 31 +++
 tests/tcg/s390x/vx.h|  2 ++
 3 files changed, 34 insertions(+)
 create mode 100644 tests/tcg/s390x/vcksm.c

diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index 71bf39b78d3..1fc98099070 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -58,6 +58,7 @@ TESTS += $(PGM_SPECIFICATION_TESTS)
 Z13_TESTS=vistr
 Z13_TESTS+=lcbb
 Z13_TESTS+=locfhr
+Z13_TESTS+=vcksm
 $(Z13_TESTS): CFLAGS+=-march=z13 -O2
 TESTS+=$(Z13_TESTS)
 
diff --git a/tests/tcg/s390x/vcksm.c b/tests/tcg/s390x/vcksm.c
new file mode 100644
index 000..452daaae6ce
--- /dev/null
+++ b/tests/tcg/s390x/vcksm.c
@@ -0,0 +1,31 @@
+/*
+ * Test the VCKSM instruction.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include 
+#include 
+#include 
+#include "vx.h"
+
+int main(void)
+{
+S390Vector v1;
+S390Vector v2 = {
+.d[0] = 0xb2261c8140edce49ULL,
+.d[1] = 0x387bf5a433af39d1ULL,
+};
+S390Vector v3 = {
+.d[0] = 0x73b03d2c7f9e654eULL,
+.d[1] = 0x23d74e51fb479877ULL,
+};
+S390Vector exp = {.d[0] = 0xdedd7f8eULL, .d[1] = 0ULL};
+
+asm volatile("vcksm %[v1],%[v2],%[v3]"
+ : [v1] "=v" (v1.v)
+ : [v2] "v" (v2.v)
+ , [v3] "v" (v3.v));
+assert(memcmp(&v1, &exp, sizeof(v1)) == 0);
+
+return EXIT_SUCCESS;
+}
diff --git a/tests/tcg/s390x/vx.h b/tests/tcg/s390x/vx.h
index 02e7fd518a8..00701dbe35f 100644
--- a/tests/tcg/s390x/vx.h
+++ b/tests/tcg/s390x/vx.h
@@ -1,6 +1,8 @@
 #ifndef QEMU_TESTS_S390X_VX_H
 #define QEMU_TESTS_S390X_VX_H
 
+#include 
+
 typedef union S390Vector {
 uint64_t d[2];  /* doubleword */
 uint32_t w[4];  /* word */
-- 
2.41.0




[PATCH 10/14] tests/tcg/s390x: Test CLM

2023-07-18 Thread Ilya Leoshkevich
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/s390x/Makefile.softmmu-target |  1 +
 tests/tcg/s390x/clm.S   | 29 +
 2 files changed, 30 insertions(+)
 create mode 100644 tests/tcg/s390x/clm.S

diff --git a/tests/tcg/s390x/Makefile.softmmu-target 
b/tests/tcg/s390x/Makefile.softmmu-target
index e813e318db9..062d8e368aa 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -17,6 +17,7 @@ LDFLAGS=-nostdlib -static
 ASM_TESTS =
\
 bal
\
 cksm   
\
+clm
\
 exrl-ssm-early 
\
 sam
\
 lpsw   
\
diff --git a/tests/tcg/s390x/clm.S b/tests/tcg/s390x/clm.S
new file mode 100644
index 000..17156a81f2a
--- /dev/null
+++ b/tests/tcg/s390x/clm.S
@@ -0,0 +1,29 @@
+.org 0x8e
+program_interruption_code:
+.org 0x1d0 /* program new PSW */
+.quad 0,pgm
+.org 0x200 /* lowcore padding */
+.globl _start
+_start:
+lgrl %r0,op1
+clm %r0,6,op2
+jle failure
+lgrl %r1,bad_addr
+clm %r0,0,0(%r1)
+failure:
+lpswe failure_psw
+pgm:
+chhsi program_interruption_code,5  /* addressing exception? */
+jne failure
+lpswe success_psw
+.align 8
+op1:
+.quad 0x1234567887654321
+op2:
+.quad 0x3456789abcdef012
+bad_addr:
+.quad 0x
+success_psw:
+.quad 0x2,0xfff/* see is_special_wait_psw() */
+failure_psw:
+.quad 0x2,0/* disabled wait */
-- 
2.41.0




[PATCH 02/14] target/s390x: Fix CLM with M3=0

2023-07-18 Thread Ilya Leoshkevich
When the mask is zero, access exceptions should still be recognized for
1 byte at the second-operand address. CC should be set to 0.

Cc: qemu-sta...@nongnu.org
Fixes: defb0e3157af ("s390x: Implement opcode helpers")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/mem_helper.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/s390x/tcg/mem_helper.c b/target/s390x/tcg/mem_helper.c
index f417fb1183c..d6dc8b32620 100644
--- a/target/s390x/tcg/mem_helper.c
+++ b/target/s390x/tcg/mem_helper.c
@@ -667,6 +667,11 @@ uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, 
uint32_t mask,
 HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
mask, addr);
 
+if (!mask) {
+/* Recognize access exceptions for the first byte */
+cpu_ldub_data_ra(env, addr, ra);
+}
+
 while (mask) {
 if (mask & 8) {
 uint8_t d = cpu_ldub_data_ra(env, addr, ra);
-- 
2.41.0




[PATCH 01/14] target/s390x: Make CKSM raise an exception if R2 is odd

2023-07-18 Thread Ilya Leoshkevich
R2 designates an even-odd register pair; the instruction should raise
a specification exception when R2 is not even.

Cc: qemu-sta...@nongnu.org
Fixes: e023e832d0ac ("s390x: translate engine for s390x CPU")
Signed-off-by: Ilya Leoshkevich 
---
 target/s390x/tcg/translate.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 6661b27efa4..2f61e879878 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -1991,11 +1991,18 @@ static DisasJumpType op_cxlgb(DisasContext *s, DisasOps 
*o)
 static DisasJumpType op_cksm(DisasContext *s, DisasOps *o)
 {
 int r2 = get_field(s, r2);
-TCGv_i128 pair = tcg_temp_new_i128();
-TCGv_i64 len = tcg_temp_new_i64();
+TCGv_i128 pair;
+TCGv_i64 len;
+
+if (r2 & 1) {
+gen_program_exception(s, PGM_SPECIFICATION);
+return DISAS_NORETURN;
+}
 
+pair = tcg_temp_new_i128();
 gen_helper_cksm(pair, cpu_env, o->in1, o->in2, regs[r2 + 1]);
 set_cc_static(s);
+len = tcg_temp_new_i64();
 tcg_gen_extr_i128_i64(o->out, len, pair);
 
 tcg_gen_add_i64(regs[r2], regs[r2], len);
-- 
2.41.0




Re: [RFC PATCH 10/17] misc/i2c_mctp_cxl: Initial device emulation

2023-07-18 Thread Gregory Price
On Mon, Jul 17, 2023 at 06:16:39PM +0100, Jonathan Cameron wrote:
> @@ -397,8 +401,9 @@ struct CXLType3Dev {
>  AddressSpace hostpmem_as;
>  CXLComponentState cxl_cstate;
>  CXLDeviceState cxl_dstate;
> -CXLCCI cci;
> -
> +CXLCCI cci; /* Primary PCI mailbox CCI */
> +CXLCCI oob_mctp_cci; /* Initialized only if targetted */
> +

I've been humming and hawing over this on the MHD stuff because I wanted
to figure out how to "add a CCI command" to a type-3 device without
either having a billion definitions for CCI command sets - or doing
something like this.

I don't hate this design pattern, I just want to ask whether your
intent is to end up with CXLType3Dev hosting many CXLCCI's based on what
wrapper types you have. 

Example: a type-3 device with mctp pass through and the MHD command set

CXLType3Dev {
...
CXLCCI cci;
CXLCCI oob_mctp_cci;
CXLCCI mhd_cci;
...
}

Instantiate:
-device cxl-type3,bus=swport0,memdev=cxl-mem1,id=cxl-pmem1,lsa=cxl-lsa1,sn=3 
-device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=5,target=cxl-pmem1
-device cxl-mhd,target=cxl-pmem1,...whatever else...

where the MHD code is contained within its own type/file, and the type3
device hosts the CCI for it.  Similar to how you've implemented the MTCP
stuff here.

The reason I ask is because certain CCI's don't necessarily get
associated with "a bus" so much as "a device".  the MHD example - it's
still part of "the device", but it's optional.   So does it make sense
to create this wrapper without a bus association, or to just pile it on
top CXLType3Dev and have to duplicate the code across any other
multi-headed devices that folks may conjur up?

~Gregory



[PATCH 13/14] tests/tcg/s390x: Test STPQ

2023-07-18 Thread Ilya Leoshkevich
Add a small test to prevent regressions.

Signed-off-by: Ilya Leoshkevich 
---
 tests/tcg/s390x/Makefile.softmmu-target |  1 +
 tests/tcg/s390x/stpq.S  | 20 
 2 files changed, 21 insertions(+)
 create mode 100644 tests/tcg/s390x/stpq.S

diff --git a/tests/tcg/s390x/Makefile.softmmu-target 
b/tests/tcg/s390x/Makefile.softmmu-target
index 145e0bfde16..76345b6e643 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -27,6 +27,7 @@ ASM_TESTS =   
 \
 mc 
\
 ssm-early  
\
 stosm-early
\
+stpq   
\
 unaligned-lowcore
 
 include $(S390X_SRC)/pgm-specification.mak
diff --git a/tests/tcg/s390x/stpq.S b/tests/tcg/s390x/stpq.S
new file mode 100644
index 000..687a52eafa7
--- /dev/null
+++ b/tests/tcg/s390x/stpq.S
@@ -0,0 +1,20 @@
+.org 0x200 /* lowcore padding */
+.globl _start
+_start:
+lgrl %r0,value
+lgrl %r1,value+8
+stpq %r0,stored_value
+clc stored_value(16),value
+jne failure
+lpswe success_psw
+failure:
+lpswe failure_psw
+.align 16
+value:
+.quad 0x1234567887654321, 0x8765432112345678
+stored_value:
+.quad 0, 0
+success_psw:
+.quad 0x2,0xfff/* see is_special_wait_psw() */
+failure_psw:
+.quad 0x2,0/* disabled wait */
-- 
2.41.0




Re: [PATCH v2] plugins: Set final instruction count in plugin_gen_tb_end

2023-07-18 Thread Alex Bennée


Matt Borgerson  writes:

> Thanks Alex!
>
>
> On Mon, Jul 17, 2023 at 8:34 AM Alex Bennée  wrote:
>>
>>
>> Alex Bennée  writes:
>>
>> > Matt Borgerson  writes:
>> >
>> >> Translation logic may partially decode an instruction, then abort and
>> >> remove the instruction from the TB. This can happen for example when an
>> >> instruction spans two pages. In this case, plugins may get an incorrect
>> >> result when calling qemu_plugin_tb_n_insns to query for the number of
>> >> instructions in the TB. This patch updates plugin_gen_tb_end to set the
>> >> final instruction count.
>> >
>> > For some reason this fails to apply cleanly:
>> >
>> >   git am 
>> > ./v2_20230714_contact_plugins_set_final_instruction_count_in_plugin_gen_tb_end.mbx
>> >   Applying: plugins: Set final instruction count in plugin_gen_tb_end
>> >   error: corrupt patch at line 31
>> >   Patch failed at 0001 plugins: Set final instruction count in
>> >   plugin_gen_tb_end
>>
>> I think some newlines crept in, I was able to fix. Queued to
>> for-8.1/misc-fixes with the assert added.

Hmm so I ran into an issue:

  ./qemu-sh4 -plugin tests/plugin/libbb.so -d plugin 
./tests/tcg/sh4-linux-user/testthread
  ERROR:../../accel/tcg/plugin-gen.c:874:plugin_gen_tb_end: assertion failed: 
(num_insns <= ptb->n)
  Bail out! ERROR:../../accel/tcg/plugin-gen.c:874:plugin_gen_tb_end: assertion 
failed: (num_insns <= ptb->n)
  qemu: uncaught target signal 11 (Segmentation fault) - core dumped
  bb's: 9202, insns: 42264
  fish: Job 1, './qemu-sh4 -plugin tests/plugin…' terminated by signal SIGSEGV 
(Address boundary error)

Further investigation shows that gUSA sequences can cause the number of
instructions to run ahead, which also makes the setting of the ptb->n =
num_insns unsafe, running ahead of the number of instructions signalled
by plugin_gen_insn_start/plugin_gen_insn_end.

  Thread 1 hit Hardware watchpoint 5: *(int *) 0x7ffd410a2904
  Old value = 4
  New value = 1
  0x55f148c00ea8 in decode_gusa (ctx=0x7ffd410a28f0, env=0x55f14a4106e8) at 
../../target/sh4/translate.c:2167
  2167ctx->base.num_insns += max_insns - 1;
  (rr) p max_insns
  $6 = 4
  (rr) p max_insns -1
  $7 = 3
  (rr) p ctx->base.num_insns
  $8 = 1

So I think we have to drop this for now until we can either fix
decode_gusa or find something else.

Richard,

Any ideas?



-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: PING: [PATCH v4 0/3] hw/ufs: Add Universal Flash Storage (UFS) support

2023-07-18 Thread Jeuk Kim

On 2023-07-19 오전 3:56, Stefan Hajnoczi wrote:

On Tue, Jul 11, 2023 at 07:31:02PM +0900, Jeuk Kim wrote:

Hi,
Any more reviews...?

Dear Stefan
If you don't mind, Could you give it "reviewed-by"?
And is there anything else I should do...?


Sorry for the late reply. I was on vacation and am working my way
through pending code review and bug reports.

I have started reviewing this series and should be finish on Wednesday
or Thursday.

Stefan


Thank you for your review.
I have seen your comments on PATCH v4.
I'll send you a patch v5 as soon as I fix the things you commented on.

Thanks again.
Jeuk



Re: [PATCH qemu 2/2] dump: Only use the makedumpfile flattened format when necessary

2023-07-18 Thread Stephen Brennan
Marc-André Lureau  writes:
> Hi
>
> On Mon, Jul 17, 2023 at 8:45 PM Stephen Brennan <
> stephen.s.bren...@oracle.com> wrote:
>
>> The flattened format is used by makedumpfile only when it is outputting
>> a vmcore to a file which is not seekable. The flattened format functions
>> essentially as a set of instructions of the form "seek to the given
>> offset, then write the given bytes out".
>>
>> The flattened format can be reconstructed using makedumpfile -R, or
>> makedumpfile-R.pl, but it is a slow process beacuse it requires copying
>> the entire vmcore. The flattened format can also be directly read by
>> crash, but still, it requires a lengthy reassembly phase.
>>
>> To sum up, the flattened format is not an ideal one: it should only be
>> used on files which are actually not seekable. This is the exact
>> strategy which makedumpfile uses, as seen in the implementation of
>> "write_buffer()" in makedumpfile [1].
>>
>> So, update the "dump-guest-memory" monitor command implementation so
>> that it will directly do the seeks and writes, in the same strategy as
>> makedumpfile. However, if the file is not seekable, then we can fall
>> back to the flattened format.
>>
>> [1]:
>> https://github.com/makedumpfile/makedumpfile/blob/f23bb943568188a2746dbf9b6692668f5a2ac3b6/makedumpfile.c#L5008-L5040
>>
>> Signed-off-by: Stephen Brennan 
>>
>
> Reviewed-by: Marc-André Lureau 
> Tested-by: Marc-André Lureau 
>
> I am a bit reluctant to change the dump format by default. But since the
> flatten format is more "complicated" than the "normal" format, perhaps we
> can assume all users will handle it.
>
> The change is probably late for 8.1 though..

Thank you for your review and testing!

I totally understand the concern about making the change by default. I
do believe that nobody should notice too much because the normal format
should be easier to work with, and more broadly compatible. I don't know
of any tool which deals with the flattened format that can't handle the
normal format, except for "makedumpfile -R" itself.

If it's a blocker, I can go ahead and add a new flag to the command to
enable the behavior. However there are a few good justifications not to
add a new flag. I think it's going to be difficult to explain the
difference between the two formats in documentation, as the
implementation of the formats is a bit "into the weeds". The libvirt API
also specifies each format separately (kdump-zlib, kdump-lzo,
kdump-snappy) and so adding several new options there would be
unfortunate for end-users as well.

At the end of the day, it's your judgment call, and I'll implement it
how you prefer.

Thanks,
Stephen

>>  dump/dump.c   | 30 +-
>>  include/sysemu/dump.h |  1 +
>>  2 files changed, 26 insertions(+), 5 deletions(-)
>>
>> diff --git a/dump/dump.c b/dump/dump.c
>> index 2708ddc135..384d275e39 100644
>> --- a/dump/dump.c
>> +++ b/dump/dump.c
>> @@ -813,6 +813,13 @@ static int write_start_flat_header(DumpState *s)
>>  {
>>  MakedumpfileHeader *mh;
>>  int ret = 0;
>> +loff_t offset = lseek(s->fd, 0, SEEK_CUR);
>> +
>> +/* If the file is seekable, don't output flattened header */
>> +if (offset == 0) {
>> +s->seekable = true;
>> +return 0;
>> +}
>>
>>  QEMU_BUILD_BUG_ON(sizeof *mh > MAX_SIZE_MDF_HEADER);
>>  mh = g_malloc0(MAX_SIZE_MDF_HEADER);
>> @@ -837,6 +844,10 @@ static int write_end_flat_header(DumpState *s)
>>  {
>>  MakedumpfileDataHeader mdh;
>>
>> +if (s->seekable) {
>> +return 0;
>> +}
>> +
>>  mdh.offset = END_FLAG_FLAT_HEADER;
>>  mdh.buf_size = END_FLAG_FLAT_HEADER;
>>
>> @@ -853,13 +864,21 @@ static int write_buffer(DumpState *s, off_t offset,
>> const void *buf, size_t size
>>  {
>>  size_t written_size;
>>  MakedumpfileDataHeader mdh;
>> +loff_t seek_loc;
>>
>> -mdh.offset = cpu_to_be64(offset);
>> -mdh.buf_size = cpu_to_be64(size);
>> +if (s->seekable) {
>> +seek_loc = lseek(s->fd, offset, SEEK_SET);
>> +if (seek_loc == (off_t) -1) {
>> +return -1;
>> +}
>> +} else {
>> +mdh.offset = cpu_to_be64(offset);
>> +mdh.buf_size = cpu_to_be64(size);
>>
>> -written_size = qemu_write_full(s->fd, &mdh, sizeof(mdh));
>> -if (written_size != sizeof(mdh)) {
>> -return -1;
>> +written_size = qemu_write_full(s->fd, &mdh, sizeof(mdh));
>> +if (written_size != sizeof(mdh)) {
>> +return -1;
>> +}
>>  }
>>
>>  written_size = qemu_write_full(s->fd, buf, size);
>> @@ -1786,6 +1805,7 @@ static void dump_init(DumpState *s, int fd, bool
>> has_format,
>>  s->has_format = has_format;
>>  s->format = format;
>>  s->written_size = 0;
>> +s->seekable = false;
>>
>>  /* kdump-compressed is conflict with paging and filter */
>>  if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
>> diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h

[PATCH 2/3] ppc/pegasos2: Fix reg property of ROM BARs

2023-07-18 Thread BALATON Zoltan
The register offset of the ROM BAR is 0x30 not 0x28. This fixes the
reg property entry of the ROM region in the device tree.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/pegasos2.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 4a2ab35f19..8ed13a42a2 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -766,7 +766,11 @@ static void add_pci_device(PCIBus *bus, PCIDevice *d, void 
*opaque)
 if (!d->io_regions[i].size) {
 continue;
 }
-cells[j] = cpu_to_be32(d->devfn << 8 | (PCI_BASE_ADDRESS_0 + i * 4));
+cells[j] = PCI_BASE_ADDRESS_0 + i * 4;
+if (cells[j] == 0x28) {
+cells[j] = 0x30;
+}
+cells[j] = cpu_to_be32(d->devfn << 8 | cells[j]);
 if (d->io_regions[i].type & PCI_BASE_ADDRESS_SPACE_IO) {
 cells[j] |= cpu_to_be32(1 << 24);
 } else {
-- 
2.30.9




[PATCH 3/3] ppc/pegasos2: Fix naming of device tree nodes

2023-07-18 Thread BALATON Zoltan
The board firmware names devices by their class so match that for
common devices. Also make sure the /rtas node has a name. This is
needed because VOF otherwise does not include it in results got by
nextprop which is how AmigaOS queries it and fails if no name property
is found.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/pegasos2.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 8ed13a42a2..6475acfbed 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -739,6 +739,13 @@ static void add_pci_device(PCIBus *bus, PCIDevice *d, void 
*opaque)
  pci_get_word(&d->config[PCI_VENDOR_ID]),
  pci_get_word(&d->config[PCI_DEVICE_ID]));
 
+if (pci_get_word(&d->config[PCI_CLASS_DEVICE])  ==
+PCI_CLASS_NETWORK_ETHERNET) {
+name = "ethernet";
+} else if (pci_get_word(&d->config[PCI_CLASS_DEVICE]) >> 8 ==
+PCI_BASE_CLASS_DISPLAY) {
+name = "display";
+}
 for (i = 0; device_map[i].id; i++) {
 if (!strcmp(pn, device_map[i].id)) {
 name = device_map[i].name;
@@ -929,6 +936,7 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
 qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-display-device", 0);
 qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size", 20);
 qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-version", 1);
+qemu_fdt_setprop_string(fdt, "/rtas", "name", "rtas");
 
 /* cpus */
 qemu_fdt_add_subnode(fdt, "/cpus");
-- 
2.30.9




[PATCH 0/3] pegasos2 fixes for 8.1

2023-07-18 Thread BALATON Zoltan
These are some small fixes when using pegasos2 with the QEMU built in
VOF instead of the non-free board firmware that fix bugs in the
generated device tree and matches the board firmware in the reset
state of on-board USB devices. This fixes booting AmigaOS with VOF and
only touches parts that are used with VOF only so I'd like these to be
merged for 8.1.

Regards,

BALATON Zoltan (3):
  ppc/pegasos2: Fix reset state of USB functions
  ppc/pegasos2: Fix reg property of ROM BARs
  ppc/pegasos2: Fix naming of device tree nodes

 hw/ppc/pegasos2.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

-- 
2.30.9




[PATCH 1/3] ppc/pegasos2: Fix reset state of USB functions

2023-07-18 Thread BALATON Zoltan
The original non-free board firmware sets the command register of the
USB functions to 7 and some guests rely on this for working USB. Match
what the board firmware does when using VOF instead.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/pegasos2.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 4447bbe8ec..4a2ab35f19 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -324,9 +324,13 @@ static void pegasos2_machine_reset(MachineState *machine, 
ShutdownCause reason)
 
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 2) << 8) |
   PCI_INTERRUPT_LINE, 2, 0x409);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 2) << 8) |
+  PCI_COMMAND, 2, 0x7);
 
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 3) << 8) |
   PCI_INTERRUPT_LINE, 2, 0x409);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 3) << 8) |
+  PCI_COMMAND, 2, 0x7);
 
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 4) << 8) |
   PCI_INTERRUPT_LINE, 2, 0x9);
-- 
2.30.9




Re: [PATCH v8 01/15] target/riscv: Refactor some of the generic vector functionality

2023-07-18 Thread Alistair Francis
On Wed, Jul 12, 2023 at 2:59 AM Max Chou  wrote:
>
> From: Kiran Ostrolenk 
>
> Take some functions/macros out of `vector_helper` and put them in a new
> module called `vector_internals`. This ensures they can be used by both
> vector and vector-crypto helpers (latter implemented in proceeding
> commits).
>
> Signed-off-by: Kiran Ostrolenk 
> Reviewed-by: Weiwei Li 
> Signed-off-by: Max Chou 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/meson.build|   1 +
>  target/riscv/vector_helper.c| 201 +---
>  target/riscv/vector_internals.c |  81 +
>  target/riscv/vector_internals.h | 182 +
>  4 files changed, 265 insertions(+), 200 deletions(-)
>  create mode 100644 target/riscv/vector_internals.c
>  create mode 100644 target/riscv/vector_internals.h
>
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index 7f56c5f88d4..c3801ee5e04 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -16,6 +16,7 @@ riscv_ss.add(files(
>'gdbstub.c',
>'op_helper.c',
>'vector_helper.c',
> +  'vector_internals.c',
>'bitmanip_helper.c',
>'translate.c',
>'m128_helper.c',
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 71bb9b4457b..6434fd2f7e8 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -26,6 +26,7 @@
>  #include "fpu/softfloat.h"
>  #include "tcg/tcg-gvec-desc.h"
>  #include "internals.h"
> +#include "vector_internals.h"
>  #include 
>
>  target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
> @@ -72,68 +73,6 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
> target_ulong s1,
>  return vl;
>  }
>
> -/*
> - * Note that vector data is stored in host-endian 64-bit chunks,
> - * so addressing units smaller than that needs a host-endian fixup.
> - */
> -#if HOST_BIG_ENDIAN
> -#define H1(x)   ((x) ^ 7)
> -#define H1_2(x) ((x) ^ 6)
> -#define H1_4(x) ((x) ^ 4)
> -#define H2(x)   ((x) ^ 3)
> -#define H4(x)   ((x) ^ 1)
> -#define H8(x)   ((x))
> -#else
> -#define H1(x)   (x)
> -#define H1_2(x) (x)
> -#define H1_4(x) (x)
> -#define H2(x)   (x)
> -#define H4(x)   (x)
> -#define H8(x)   (x)
> -#endif
> -
> -static inline uint32_t vext_nf(uint32_t desc)
> -{
> -return FIELD_EX32(simd_data(desc), VDATA, NF);
> -}
> -
> -static inline uint32_t vext_vm(uint32_t desc)
> -{
> -return FIELD_EX32(simd_data(desc), VDATA, VM);
> -}
> -
> -/*
> - * Encode LMUL to lmul as following:
> - * LMULvlmullmul
> - *  1   000   0
> - *  2   001   1
> - *  4   010   2
> - *  8   011   3
> - *  -   100   -
> - * 1/8  101  -3
> - * 1/4  110  -2
> - * 1/2  111  -1
> - */
> -static inline int32_t vext_lmul(uint32_t desc)
> -{
> -return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
> -}
> -
> -static inline uint32_t vext_vta(uint32_t desc)
> -{
> -return FIELD_EX32(simd_data(desc), VDATA, VTA);
> -}
> -
> -static inline uint32_t vext_vma(uint32_t desc)
> -{
> -return FIELD_EX32(simd_data(desc), VDATA, VMA);
> -}
> -
> -static inline uint32_t vext_vta_all_1s(uint32_t desc)
> -{
> -return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
> -}
> -
>  /*
>   * Get the maximum number of elements can be operated.
>   *
> @@ -152,21 +91,6 @@ static inline uint32_t vext_max_elems(uint32_t desc, 
> uint32_t log2_esz)
>  return scale < 0 ? vlenb >> -scale : vlenb << scale;
>  }
>
> -/*
> - * Get number of total elements, including prestart, body and tail elements.
> - * Note that when LMUL < 1, the tail includes the elements past VLMAX that
> - * are held in the same vector register.
> - */
> -static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t 
> desc,
> -uint32_t esz)
> -{
> -uint32_t vlenb = simd_maxsz(desc);
> -uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
> -int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
> -  ctzl(esz) - ctzl(sew) + vext_lmul(desc);
> -return (vlenb << emul) / esz;
> -}
> -
>  static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
>  {
>  return (addr & ~env->cur_pmmask) | env->cur_pmbase;
> @@ -199,20 +123,6 @@ static void probe_pages(CPURISCVState *env, target_ulong 
> addr,
>  }
>  }
>
> -/* set agnostic elements to 1s */
> -static void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
> -  uint32_t tot)
> -{
> -if (is_agnostic == 0) {
> -/* policy undisturbed */
> -return;
> -}
> -if (tot - cnt == 0) {
> -return;
> -}
> -memset(base + cnt, -1, tot - cnt);
> -}
> -
>  static inline void vext_set_elem_mask(void *v0, int index,
>uint8_t value)
>  {
> @@ -222,18 +132,6 @@ static inline

Re: [PATCH v2 08/16] target/riscv: Move TCG-specific cpu_get_tb_cpu_state() to tcg/cpu.c

2023-07-18 Thread Alistair Francis
On Tue, Jul 4, 2023 at 4:34 AM Philippe Mathieu-Daudé  wrote:
>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_helper.c| 84 ---
>  target/riscv/tcg/cpu.c   | 98 
>  target/riscv/tcg/meson.build |  1 +
>  3 files changed, 99 insertions(+), 84 deletions(-)
>  create mode 100644 target/riscv/tcg/cpu.c
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 597c47bc56..6f8778c6d3 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -64,90 +64,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
>  #endif
>  }
>
> -void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
> -  uint64_t *cs_base, uint32_t *pflags)
> -{
> -CPUState *cs = env_cpu(env);
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -RISCVExtStatus fs, vs;
> -uint32_t flags = 0;
> -
> -*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
> -*cs_base = 0;
> -
> -if (cpu->cfg.ext_zve32f) {
> -/*
> - * If env->vl equals to VLMAX, we can use generic vector operation
> - * expanders (GVEC) to accerlate the vector operations.
> - * However, as LMUL could be a fractional number. The maximum
> - * vector size can be operated might be less than 8 bytes,
> - * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
> - * only when maxsz >= 8 bytes.
> - */
> -uint32_t vlmax = vext_get_vlmax(cpu, env->vtype);
> -uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
> -uint32_t maxsz = vlmax << sew;
> -bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
> -   (maxsz >= 8);
> -flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
> -flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
> -flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
> -   FIELD_EX64(env->vtype, VTYPE, VLMUL));
> -flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
> -flags = FIELD_DP32(flags, TB_FLAGS, VTA,
> -   FIELD_EX64(env->vtype, VTYPE, VTA));
> -flags = FIELD_DP32(flags, TB_FLAGS, VMA,
> -   FIELD_EX64(env->vtype, VTYPE, VMA));
> -flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 
> 0);
> -} else {
> -flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
> -}
> -
> -#ifdef CONFIG_USER_ONLY
> -fs = EXT_STATUS_DIRTY;
> -vs = EXT_STATUS_DIRTY;
> -#else
> -flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
> -
> -flags |= cpu_mmu_index(env, 0);
> -fs = get_field(env->mstatus, MSTATUS_FS);
> -vs = get_field(env->mstatus, MSTATUS_VS);
> -
> -if (env->virt_enabled) {
> -flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1);
> -/*
> - * Merge DISABLED and !DIRTY states using MIN.
> - * We will set both fields when dirtying.
> - */
> -fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS));
> -vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
> -}
> -
> -/* With Zfinx, floating point is enabled/disabled by Smstateen. */
> -if (!riscv_has_ext(env, RVF)) {
> -fs = (smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR) == RISCV_EXCP_NONE)
> - ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED;
> -}
> -
> -if (cpu->cfg.debug && !icount_enabled()) {
> -flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
> -}
> -#endif
> -
> -flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
> -flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
> -flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
> -flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env));
> -if (env->cur_pmmask != 0) {
> -flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
> -}
> -if (env->cur_pmbase != 0) {
> -flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
> -}
> -
> -*pflags = flags;
> -}
> -
>  void riscv_cpu_update_mask(CPURISCVState *env)
>  {
>  target_ulong mask = 0, base = 0;
> diff --git a/target/riscv/tcg/cpu.c b/target/riscv/tcg/cpu.c
> new file mode 100644
> index 00..2ae6919b80
> --- /dev/null
> +++ b/target/riscv/tcg/cpu.c
> @@ -0,0 +1,98 @@
> +/*
> + * RISC-V CPU helpers (TCG specific)
> + *
> + * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
> + * Copyright (c) 2017-2018 SiFive, Inc.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +#ifndef CONFIG_USER_ONLY
> +#include "sysemu/cpu-timers.h"
> +#endif
> +
> +void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
> +  uint64_t *cs_base, uint32_t *pflags)
> +{
> +CPUState *cs = env_cpu(env);
> +RISCVCPU *cpu = RISCV_CPU(cs);
> +RISCVExtStatus

Re: [PATCH v3 07/16] target/riscv: Move TCG-specific files to target/riscv/tcg/

2023-07-18 Thread Alistair Francis
On Tue, Jul 11, 2023 at 10:21 PM Philippe Mathieu-Daudé
 wrote:
>
> Move TCG-specific files to the a new 'tcg' sub-directory. Add
> stubs for riscv_cpu_[get/set]_fflags and riscv_raise_exception().
> Adapt meson rules.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/{ => tcg}/XVentanaCondOps.decode |  0
>  target/riscv/{ => tcg}/insn16.decode  |  0
>  target/riscv/{ => tcg}/insn32.decode  |  0
>  target/riscv/{ => tcg}/xthead.decode  |  0
>  target/riscv/{ => tcg}/bitmanip_helper.c  |  0
>  target/riscv/{ => tcg}/crypto_helper.c|  0
>  target/riscv/{ => tcg}/fpu_helper.c   |  0
>  target/riscv/{ => tcg}/m128_helper.c  |  0
>  target/riscv/{ => tcg}/op_helper.c|  0
>  target/riscv/tcg/tcg-stub.c   | 25 +++
>  target/riscv/{ => tcg}/translate.c|  0
>  target/riscv/{ => tcg}/vector_helper.c|  0
>  target/riscv/{ => tcg}/zce_helper.c   |  0
>  target/riscv/meson.build  | 18 +
>  target/riscv/tcg/meson.build  | 19 ++
>  15 files changed, 45 insertions(+), 17 deletions(-)
>  rename target/riscv/{ => tcg}/XVentanaCondOps.decode (100%)
>  rename target/riscv/{ => tcg}/insn16.decode (100%)
>  rename target/riscv/{ => tcg}/insn32.decode (100%)
>  rename target/riscv/{ => tcg}/xthead.decode (100%)
>  rename target/riscv/{ => tcg}/bitmanip_helper.c (100%)
>  rename target/riscv/{ => tcg}/crypto_helper.c (100%)
>  rename target/riscv/{ => tcg}/fpu_helper.c (100%)
>  rename target/riscv/{ => tcg}/m128_helper.c (100%)
>  rename target/riscv/{ => tcg}/op_helper.c (100%)
>  create mode 100644 target/riscv/tcg/tcg-stub.c
>  rename target/riscv/{ => tcg}/translate.c (100%)
>  rename target/riscv/{ => tcg}/vector_helper.c (100%)
>  rename target/riscv/{ => tcg}/zce_helper.c (100%)
>  create mode 100644 target/riscv/tcg/meson.build
>
> diff --git a/target/riscv/XVentanaCondOps.decode 
> b/target/riscv/tcg/XVentanaCondOps.decode
> similarity index 100%
> rename from target/riscv/XVentanaCondOps.decode
> rename to target/riscv/tcg/XVentanaCondOps.decode
> diff --git a/target/riscv/insn16.decode b/target/riscv/tcg/insn16.decode
> similarity index 100%
> rename from target/riscv/insn16.decode
> rename to target/riscv/tcg/insn16.decode
> diff --git a/target/riscv/insn32.decode b/target/riscv/tcg/insn32.decode
> similarity index 100%
> rename from target/riscv/insn32.decode
> rename to target/riscv/tcg/insn32.decode
> diff --git a/target/riscv/xthead.decode b/target/riscv/tcg/xthead.decode
> similarity index 100%
> rename from target/riscv/xthead.decode
> rename to target/riscv/tcg/xthead.decode
> diff --git a/target/riscv/bitmanip_helper.c 
> b/target/riscv/tcg/bitmanip_helper.c
> similarity index 100%
> rename from target/riscv/bitmanip_helper.c
> rename to target/riscv/tcg/bitmanip_helper.c
> diff --git a/target/riscv/crypto_helper.c b/target/riscv/tcg/crypto_helper.c
> similarity index 100%
> rename from target/riscv/crypto_helper.c
> rename to target/riscv/tcg/crypto_helper.c
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/tcg/fpu_helper.c
> similarity index 100%
> rename from target/riscv/fpu_helper.c
> rename to target/riscv/tcg/fpu_helper.c
> diff --git a/target/riscv/m128_helper.c b/target/riscv/tcg/m128_helper.c
> similarity index 100%
> rename from target/riscv/m128_helper.c
> rename to target/riscv/tcg/m128_helper.c
> diff --git a/target/riscv/op_helper.c b/target/riscv/tcg/op_helper.c
> similarity index 100%
> rename from target/riscv/op_helper.c
> rename to target/riscv/tcg/op_helper.c
> diff --git a/target/riscv/tcg/tcg-stub.c b/target/riscv/tcg/tcg-stub.c
> new file mode 100644
> index 00..dfe42ae2ac
> --- /dev/null
> +++ b/target/riscv/tcg/tcg-stub.c
> @@ -0,0 +1,25 @@
> +/*
> + * QEMU RISC-V TCG stubs
> + *
> + * Copyright (c) 2023 Linaro
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +
> +target_ulong riscv_cpu_get_fflags(CPURISCVState *env)
> +{
> +g_assert_not_reached();
> +}
> +
> +void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong)
> +{
> +g_assert_not_reached();
> +}
> +
> +G_NORETURN void riscv_raise_exception(CPURISCVState *env,
> +  uint32_t exception, uintptr_t pc)
> +{
> +g_assert_not_reached();
> +}
> diff --git a/target/riscv/translate.c b/target/riscv/tcg/translate.c
> similarity index 100%
> rename from target/riscv/translate.c
> rename to target/riscv/tcg/translate.c
> diff --git a/target/riscv/vector_helper.c b/target/riscv/tcg/vector_helper.c
> similarity index 100%
> rename from target/riscv/vector_helper.c
> rename to target/riscv/tcg/vector_helper.c
> diff --git a/target/riscv/zce_helper.c b/target/riscv/tcg/zce_helper.c
> similarity index 100%
> rename from target/riscv/zce_helper.c
> rename to target/riscv/tcg/zce_helper.c

Re: [PATCH v3 08/16] target/riscv: Move TCG-specific cpu_get_tb_cpu_state() to tcg/cpu.c

2023-07-18 Thread Alistair Francis
On Tue, Jul 11, 2023 at 10:18 PM Philippe Mathieu-Daudé
 wrote:
>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu_helper.c| 84 ---
>  target/riscv/tcg/cpu.c   | 98 
>  target/riscv/tcg/meson.build |  1 +
>  3 files changed, 99 insertions(+), 84 deletions(-)
>  create mode 100644 target/riscv/tcg/cpu.c
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 597c47bc56..6f8778c6d3 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -64,90 +64,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
>  #endif
>  }
>
> -void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
> -  uint64_t *cs_base, uint32_t *pflags)
> -{
> -CPUState *cs = env_cpu(env);
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -RISCVExtStatus fs, vs;
> -uint32_t flags = 0;
> -
> -*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
> -*cs_base = 0;
> -
> -if (cpu->cfg.ext_zve32f) {
> -/*
> - * If env->vl equals to VLMAX, we can use generic vector operation
> - * expanders (GVEC) to accerlate the vector operations.
> - * However, as LMUL could be a fractional number. The maximum
> - * vector size can be operated might be less than 8 bytes,
> - * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
> - * only when maxsz >= 8 bytes.
> - */
> -uint32_t vlmax = vext_get_vlmax(cpu, env->vtype);
> -uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
> -uint32_t maxsz = vlmax << sew;
> -bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
> -   (maxsz >= 8);
> -flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
> -flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
> -flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
> -   FIELD_EX64(env->vtype, VTYPE, VLMUL));
> -flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
> -flags = FIELD_DP32(flags, TB_FLAGS, VTA,
> -   FIELD_EX64(env->vtype, VTYPE, VTA));
> -flags = FIELD_DP32(flags, TB_FLAGS, VMA,
> -   FIELD_EX64(env->vtype, VTYPE, VMA));
> -flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 
> 0);
> -} else {
> -flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
> -}
> -
> -#ifdef CONFIG_USER_ONLY
> -fs = EXT_STATUS_DIRTY;
> -vs = EXT_STATUS_DIRTY;
> -#else
> -flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
> -
> -flags |= cpu_mmu_index(env, 0);
> -fs = get_field(env->mstatus, MSTATUS_FS);
> -vs = get_field(env->mstatus, MSTATUS_VS);
> -
> -if (env->virt_enabled) {
> -flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1);
> -/*
> - * Merge DISABLED and !DIRTY states using MIN.
> - * We will set both fields when dirtying.
> - */
> -fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS));
> -vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
> -}
> -
> -/* With Zfinx, floating point is enabled/disabled by Smstateen. */
> -if (!riscv_has_ext(env, RVF)) {
> -fs = (smstateen_acc_ok(env, 0, SMSTATEEN0_FCSR) == RISCV_EXCP_NONE)
> - ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED;
> -}
> -
> -if (cpu->cfg.debug && !icount_enabled()) {
> -flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
> -}
> -#endif
> -
> -flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
> -flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
> -flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
> -flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env));
> -if (env->cur_pmmask != 0) {
> -flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
> -}
> -if (env->cur_pmbase != 0) {
> -flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
> -}
> -
> -*pflags = flags;
> -}
> -
>  void riscv_cpu_update_mask(CPURISCVState *env)
>  {
>  target_ulong mask = 0, base = 0;
> diff --git a/target/riscv/tcg/cpu.c b/target/riscv/tcg/cpu.c
> new file mode 100644
> index 00..2ae6919b80
> --- /dev/null
> +++ b/target/riscv/tcg/cpu.c
> @@ -0,0 +1,98 @@
> +/*
> + * RISC-V CPU helpers (TCG specific)
> + *
> + * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
> + * Copyright (c) 2017-2018 SiFive, Inc.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +#ifndef CONFIG_USER_ONLY
> +#include "sysemu/cpu-timers.h"
> +#endif
> +
> +void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
> +  uint64_t *cs_base, uint32_t *pflags)
> +{
> +CPUState *cs = env_cpu(env);
> +RISCVCPU *cpu = RISCV_CPU(cs);
> +RISCVExtStat

Re: [PATCH v3 09/16] target/riscv: Expose some 'trigger' prototypes from debug.c

2023-07-18 Thread Alistair Francis
On Tue, Jul 11, 2023 at 10:16 PM Philippe Mathieu-Daudé
 wrote:
>
> We want to extract TCG-specific code from debug.c, but some
> functions call get_trigger_type() / do_trigger_action().
> Expose these prototypes in "debug.h".
>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/debug.h | 4 
>  target/riscv/debug.c | 5 ++---
>  2 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/debug.h b/target/riscv/debug.h
> index c471748d5a..65cd45b8f3 100644
> --- a/target/riscv/debug.h
> +++ b/target/riscv/debug.h
> @@ -147,4 +147,8 @@ void riscv_trigger_init(CPURISCVState *env);
>
>  bool riscv_itrigger_enabled(CPURISCVState *env);
>  void riscv_itrigger_update_priv(CPURISCVState *env);
> +
> +target_ulong get_trigger_type(CPURISCVState *env, target_ulong 
> trigger_index);
> +void do_trigger_action(CPURISCVState *env, target_ulong trigger_index);
> +
>  #endif /* RISCV_DEBUG_H */
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index 75ee1c4971..5676f2c57e 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -88,8 +88,7 @@ static inline target_ulong 
> extract_trigger_type(CPURISCVState *env,
>  }
>  }
>
> -static inline target_ulong get_trigger_type(CPURISCVState *env,
> -target_ulong trigger_index)
> +target_ulong get_trigger_type(CPURISCVState *env, target_ulong trigger_index)
>  {
>  return extract_trigger_type(env, env->tdata1[trigger_index]);
>  }
> @@ -217,7 +216,7 @@ static inline void warn_always_zero_bit(target_ulong val, 
> target_ulong mask,
>  }
>  }
>
> -static void do_trigger_action(CPURISCVState *env, target_ulong trigger_index)
> +void do_trigger_action(CPURISCVState *env, target_ulong trigger_index)
>  {
>  trigger_action_t action = get_trigger_action(env, trigger_index);
>
> --
> 2.38.1
>
>



Re: [PATCH for-8.0] tcg/sparc64: Disable direct linking for goto_tb

2023-07-18 Thread Jordan Niethe




On 5/4/23 1:04 am, Richard Henderson wrote:

Something is wrong with this code, and also wrong with gdb on the
sparc systems to which I have access, so I cannot debug it either.
Disable for now, so the release is not broken.


I'm not sure if it is the entire problem but it looks like the broken 
code had the same race as on ppc [1] between loading TCG_REG_TB and 
patching and executing the direct branch.


[1] 
https://lore.kernel.org/qemu-devel/20230717093001.13167-1-jniet...@gmail.com/#t




Signed-off-by: Richard Henderson 
---
  tcg/sparc64/tcg-target.c.inc | 30 --
  1 file changed, 4 insertions(+), 26 deletions(-)

diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index ccc4144f7c..694f2b9dd4 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -1445,12 +1445,12 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
  {
  ptrdiff_t off = tcg_tbrel_diff(s, (void *)get_jmp_target_addr(s, which));
  
-/* Direct branch will be patched by tb_target_set_jmp_target. */

+/* Load link and indirect branch. */
  set_jmp_insn_offset(s, which);
-tcg_out32(s, CALL);
-/* delay slot */
-tcg_debug_assert(check_fit_ptr(off, 13));
  tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TB, TCG_REG_TB, off);
+tcg_out_arithi(s, TCG_REG_G0, TCG_REG_TB, 0, JMPL);
+/* delay slot */
+tcg_out_nop(s);
  set_jmp_reset_offset(s, which);
  
  /*

@@ -1469,28 +1469,6 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
  void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
uintptr_t jmp_rx, uintptr_t jmp_rw)
  {
-uintptr_t addr = tb->jmp_target_addr[n];
-intptr_t br_disp = (intptr_t)(addr - jmp_rx) >> 2;
-tcg_insn_unit insn;
-
-br_disp >>= 2;
-if (check_fit_ptr(br_disp, 19)) {
-/* ba,pt %icc, addr */
-insn = deposit32(INSN_OP(0) | INSN_OP2(1) | INSN_COND(COND_A)
- | BPCC_ICC | BPCC_PT, 0, 19, br_disp);
-} else if (check_fit_ptr(br_disp, 22)) {
-/* ba addr */
-insn = deposit32(INSN_OP(0) | INSN_OP2(2) | INSN_COND(COND_A),
- 0, 22, br_disp);
-} else {
-/* The code_gen_buffer can't be larger than 2GB.  */
-tcg_debug_assert(check_fit_ptr(br_disp, 30));
-/* call addr */
-insn = deposit32(CALL, 0, 30, br_disp);
-}
-
-qatomic_set((uint32_t *)jmp_rw, insn);
-flush_idcache_range(jmp_rx, jmp_rw, 4);
  }
  
  static void tcg_out_op(TCGContext *s, TCGOpcode opc,






Re: [PATCH v3 10/16] target/riscv: Extract TCG-specific code from debug.c

2023-07-18 Thread Alistair Francis
On Tue, Jul 11, 2023 at 10:21 PM Philippe Mathieu-Daudé
 wrote:
>
> Extract TCG-specific code from debug.c to tcg/sysemu/debug.c,
> restrict the prototypes to TCG, adapt meson rules.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/debug.h|   2 +
>  target/riscv/debug.c| 148 -
>  target/riscv/tcg/sysemu/debug.c | 165 
>  target/riscv/tcg/meson.build|   2 +
>  target/riscv/tcg/sysemu/meson.build |   3 +
>  5 files changed, 172 insertions(+), 148 deletions(-)
>  create mode 100644 target/riscv/tcg/sysemu/debug.c
>  create mode 100644 target/riscv/tcg/sysemu/meson.build
>
> diff --git a/target/riscv/debug.h b/target/riscv/debug.h
> index 65cd45b8f3..0b3bdd5be1 100644
> --- a/target/riscv/debug.h
> +++ b/target/riscv/debug.h
> @@ -139,9 +139,11 @@ void tdata_csr_write(CPURISCVState *env, int 
> tdata_index, target_ulong val);
>
>  target_ulong tinfo_csr_read(CPURISCVState *env);
>
> +#ifdef CONFIG_TCG
>  void riscv_cpu_debug_excp_handler(CPUState *cs);
>  bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
>  bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
> +#endif
>
>  void riscv_trigger_init(CPURISCVState *env);
>
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index 5676f2c57e..45a2605d8a 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -754,154 +754,6 @@ target_ulong tinfo_csr_read(CPURISCVState *env)
> BIT(TRIGGER_TYPE_AD_MATCH6);
>  }
>
> -void riscv_cpu_debug_excp_handler(CPUState *cs)
> -{
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = &cpu->env;
> -
> -if (cs->watchpoint_hit) {
> -if (cs->watchpoint_hit->flags & BP_CPU) {
> -do_trigger_action(env, DBG_ACTION_BP);
> -}
> -} else {
> -if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
> -do_trigger_action(env, DBG_ACTION_BP);
> -}
> -}
> -}
> -
> -bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
> -{
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = &cpu->env;
> -CPUBreakpoint *bp;
> -target_ulong ctrl;
> -target_ulong pc;
> -int trigger_type;
> -int i;
> -
> -QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> -for (i = 0; i < RV_MAX_TRIGGERS; i++) {
> -trigger_type = get_trigger_type(env, i);
> -
> -switch (trigger_type) {
> -case TRIGGER_TYPE_AD_MATCH:
> -/* type 2 trigger cannot be fired in VU/VS mode */
> -if (env->virt_enabled) {
> -return false;
> -}
> -
> -ctrl = env->tdata1[i];
> -pc = env->tdata2[i];
> -
> -if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
> -/* check U/S/M bit against current privilege level */
> -if ((ctrl >> 3) & BIT(env->priv)) {
> -return true;
> -}
> -}
> -break;
> -case TRIGGER_TYPE_AD_MATCH6:
> -ctrl = env->tdata1[i];
> -pc = env->tdata2[i];
> -
> -if ((ctrl & TYPE6_EXEC) && (bp->pc == pc)) {
> -if (env->virt_enabled) {
> -/* check VU/VS bit against current privilege level */
> -if ((ctrl >> 23) & BIT(env->priv)) {
> -return true;
> -}
> -} else {
> -/* check U/S/M bit against current privilege level */
> -if ((ctrl >> 3) & BIT(env->priv)) {
> -return true;
> -}
> -}
> -}
> -break;
> -default:
> -/* other trigger types are not supported or irrelevant */
> -break;
> -}
> -}
> -}
> -
> -return false;
> -}
> -
> -bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
> -{
> -RISCVCPU *cpu = RISCV_CPU(cs);
> -CPURISCVState *env = &cpu->env;
> -target_ulong ctrl;
> -target_ulong addr;
> -int trigger_type;
> -int flags;
> -int i;
> -
> -for (i = 0; i < RV_MAX_TRIGGERS; i++) {
> -trigger_type = get_trigger_type(env, i);
> -
> -switch (trigger_type) {
> -case TRIGGER_TYPE_AD_MATCH:
> -/* type 2 trigger cannot be fired in VU/VS mode */
> -if (env->virt_enabled) {
> -return false;
> -}
> -
> -ctrl = env->tdata1[i];
> -addr = env->tdata2[i];
> -flags = 0;
> -
> -if (ctrl & TYPE2_LOAD) {
> -flags |= BP_MEM_READ;
> -}
> -if (ctrl & TYPE2_STORE) {
> -flags |= BP_MEM_WRITE;
> -   

Re: [PATCH v3 11/16] target/riscv: Move sysemu-specific debug files to target/riscv/sysemu/

2023-07-18 Thread Alistair Francis
On Tue, Jul 11, 2023 at 10:22 PM Philippe Mathieu-Daudé
 wrote:
>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h| 2 +-
>  target/riscv/{ => sysemu}/debug.h | 0
>  target/riscv/cpu_helper.c | 2 +-
>  target/riscv/{ => sysemu}/debug.c | 0
>  target/riscv/meson.build  | 4 
>  target/riscv/sysemu/meson.build   | 1 +
>  6 files changed, 3 insertions(+), 6 deletions(-)
>  rename target/riscv/{ => sysemu}/debug.h (100%)
>  rename target/riscv/{ => sysemu}/debug.c (100%)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 0602b948d4..8d8e30d6c1 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -94,7 +94,7 @@ typedef enum {
>
>  #if !defined(CONFIG_USER_ONLY)
>  #include "sysemu/pmp.h"
> -#include "debug.h"
> +#include "sysemu/debug.h"
>  #endif
>
>  #define RV_VLEN_MAX 1024
> diff --git a/target/riscv/debug.h b/target/riscv/sysemu/debug.h
> similarity index 100%
> rename from target/riscv/debug.h
> rename to target/riscv/sysemu/debug.h
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 6f8778c6d3..6c773000a5 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -32,7 +32,7 @@
>  #include "sysemu/cpu-timers.h"
>  #endif
>  #include "cpu_bits.h"
> -#include "debug.h"
> +#include "sysemu/debug.h"
>  #include "tcg/oversized-guest.h"
>
>  int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> diff --git a/target/riscv/debug.c b/target/riscv/sysemu/debug.c
> similarity index 100%
> rename from target/riscv/debug.c
> rename to target/riscv/sysemu/debug.c
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index 8ef47f43f9..49cdcde679 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -8,10 +8,6 @@ riscv_ss.add(files(
>'gdbstub.c',
>  ))
>
> -riscv_system_ss.add(files(
> -  'debug.c',
> -))
> -
>  subdir('tcg')
>  subdir('sysemu')
>
> diff --git a/target/riscv/sysemu/meson.build b/target/riscv/sysemu/meson.build
> index 64de0256a5..e902ba2dad 100644
> --- a/target/riscv/sysemu/meson.build
> +++ b/target/riscv/sysemu/meson.build
> @@ -1,5 +1,6 @@
>  riscv_system_ss.add(files(
>'arch_dump.c',
> +  'debug.c',
>'machine.c',
>'monitor.c',
>'pmp.c',
> --
> 2.38.1
>
>



Re: [PATCH v3 12/16] target/riscv: Expose riscv_cpu_pending_to_irq() from cpu_helper.c

2023-07-18 Thread Alistair Francis
On Tue, Jul 11, 2023 at 10:22 PM Philippe Mathieu-Daudé
 wrote:
>
> We want to extract TCG/sysemu-specific code from cpu_helper.c,
> but some functions call riscv_cpu_pending_to_irq(). Expose the
> prototype in "internals.h".
>
> Signed-off-by: Philippe Mathieu-Daudé 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/internals.h  | 4 
>  target/riscv/cpu_helper.c | 6 +++---
>  2 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/internals.h b/target/riscv/internals.h
> index b5f823c7ec..b6881b4815 100644
> --- a/target/riscv/internals.h
> +++ b/target/riscv/internals.h
> @@ -72,6 +72,10 @@ target_ulong fclass_d(uint64_t frs1);
>
>  #ifndef CONFIG_USER_ONLY
>  extern const VMStateDescription vmstate_riscv_cpu;
> +
> +int riscv_cpu_pending_to_irq(CPURISCVState *env,
> + int extirq, unsigned int extirq_def_prio,
> + uint64_t pending, uint8_t *iprio);
>  #endif
>
>  enum {
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 6c773000a5..e73cf56e5c 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -256,9 +256,9 @@ uint8_t riscv_cpu_default_priority(int irq)
>  return default_iprio[irq] ? default_iprio[irq] : IPRIO_MMAXIPRIO;
>  };
>
> -static int riscv_cpu_pending_to_irq(CPURISCVState *env,
> -int extirq, unsigned int extirq_def_prio,
> -uint64_t pending, uint8_t *iprio)
> +int riscv_cpu_pending_to_irq(CPURISCVState *env,
> + int extirq, unsigned int extirq_def_prio,
> + uint64_t pending, uint8_t *iprio)
>  {
>  int irq, best_irq = RISCV_EXCP_NONE;
>  unsigned int prio, best_prio = UINT_MAX;
> --
> 2.38.1
>
>



Re: [PATCH] target/riscv/cpu.c: check priv_ver before auto-enable zca/zcd/zcf

2023-07-18 Thread Alistair Francis
On Tue, Jul 18, 2023 at 1:42 AM Daniel Henrique Barboza
 wrote:
>
> Commit bd30559568 made changes in how we're checking and disabling
> extensions based on env->priv_ver. One of the changes was to move the
> extension disablement code to the end of realize(), being able to
> disable extensions after we've auto-enabled some of them.
>
> An unfortunate side effect of this change started to happen with CPUs
> that has an older priv version, like sifive-u54. Starting on commit
> 2288a5ce43e5 we're auto-enabling zca, zcd and zcf if RVC is enabled,
> but these extensions are priv version 1.12.0. When running a cpu that
> has an older priv ver (like sifive-u54) the user is spammed with
> warnings like these:
>
> qemu-system-riscv64: warning: disabling zca extension for hart 
> 0x because privilege spec version does not match
> qemu-system-riscv64: warning: disabling zcd extension for hart 
> 0x because privilege spec version does not match
>
> The warnings are part of the code that disables the extension, but in this
> case we're throwing user warnings for stuff that we enabled on our own,
> without user intervention. Users are left wondering what they did wrong.
>
> A quick 8.1 fix for this nuisance is to check the CPU priv spec before
> auto-enabling zca/zcd/zcf. A more appropriate fix will include a more
> robust framework that will account for both priv_ver and user choice
> when auto-enabling/disabling extensions, but for 8.1 we'll make it do
> with this simple check.
>
> It's also worth noticing that this is the only case where we're
> auto-enabling extensions based on a criteria (in this case RVC) that
> doesn't match the priv spec of the extensions we're enabling. There's no
> need for more 8.1 band-aids.
>
> Cc: Conor Dooley 
> Fixes: 2288a5ce43e5 ("target/riscv: add cfg properties for Zc* extension")
> Signed-off-by: Daniel Henrique Barboza 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9339c0241d..6b93b04453 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1225,7 +1225,8 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
> Error **errp)
>  }
>  }
>
> -if (riscv_has_ext(env, RVC)) {
> +/* zca, zcd and zcf has a PRIV 1.12.0 restriction */
> +if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
>  cpu->cfg.ext_zca = true;
>  if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
>  cpu->cfg.ext_zcf = true;
> --
> 2.41.0
>
>



Re: Tips for local testing guestfwd

2023-07-18 Thread Felix Wu
Hi all,

I am continuing debugging the ipv6 guestfwd feature, and I would like to
understand the behavior of slirp better.

Progress I've made:
Let QEMU take parameter like following:
guestfwd=tcp:[fec0::105]:54322-tcp:[::1]:6655
For slirp side, I basically searched for the appearance of gfwd_list and
made all code traverse the fwd list compatible with ipv6.
With these change, now I can see the packets coming out of the guest OS to
the assigned guest server port via tcpdump:
```
00:38:18.831831 IP6 fdb5:481:10ce:0:8c41:aaff:fea9:f674.52190 >
fec0::105.54322: tcp 0
0x:  600a 1f94 0028 0640 fdb5 0481 10ce   `(.@
0x0010:  8c41 aaff fea9 f674 fec0     .A.t
0x0020:     0105 cbde d432 df6d 8332  ...2.m.2
0x0030:    a0*02* fd20 535f  0204 05a0  S_..
0x0040:  0402 080a b87b fd3b   0103 0307  .{.;
```
02 == SYN so it looks good. But both tcpdump and wireshark (looking into
packet dump provided by QEMU invocation) didn't see any response and this
packet never reached the host.
I added multiple prints inside slirp and confirmed the ipv6 version of [1]
was reached.
in tcp_output function [2], I got following print:
qemu-system-aarch64: info: Slirp: AF_INET6 out dst ip =
fdb5:481:10ce:0:8c41:aaff:fea9:f674, port = 52190
qemu-system-aarch64: info: Slirp: AF_INET6 out src ip = fec0::105, port =
54322
It looks like there should be something being sent back to the guest,
unless my understanding of tcp_output is wrong.

To understand the datapath of guestfwd better, I have the following
questions:
1. What's the meaning of tcp_input and tcp_output? My guess is the
following graph, but I would like to confirm.
   tcp_input tcp_output
QEMU > slirp --> host
<   <--
 tcp_output   tcp_input

2. I don't see port 6655 in the above process. How does slirp know 6655 is
the port that needs to be visited on the host side?

Thanks in advance, Felix
[1].
https://gitlab.freedesktop.org/slirp/libslirp/-/blob/master/src/tcp_input.c#L630
[2].
https://gitlab.freedesktop.org/slirp/libslirp/-/blob/master/src/tcp_output.c#L477


On Mon, Jun 26, 2023 at 3:08 AM Samuel Thibault 
wrote:

> Hello,
>
> Felix Wu  wrote:
> > 2. I want to understand what ip I should use. Currently I have following
> > formats for the QEMU invocation in ipv6:
> > ```
> > guestfwd=tcp:[::1]:1234-tcp:[my:host:ip:from:ifconfig]:22
> > ```
> > I know the general form is `guestfwd=tcp:server:port-dev`, where
> > server:port is for guest,
>
> Yes, the address to be used within the guest network. So it needs to be
> within the guest network.
>
> > Is the aforementioned invocation correct?
>
> No, because ::1 isn't in the guest network.
>
> > Or in this case [::1] is the local host address and I should put qemu
> > address for it instead?
>
> You can use whatever IP you want, as long as it's in the guest network.
> e.g. [fec0::1234] if you're with the default fec0::/64 network.
>
> > 3. Is there a default ipv6 address for QEMU instance? I think I need it
> in
> > the invocation.
>
> By default it's address 2 within the prefix, i.e. fec0::2 with the
> default fec0::/64 network.
>
> Samuel
>


Re: [PATCH] target/riscv/cpu.c: check priv_ver before auto-enable zca/zcd/zcf

2023-07-18 Thread Alistair Francis
On Tue, Jul 18, 2023 at 7:50 PM Daniel Henrique Barboza
 wrote:
>
>
>
> On 7/17/23 22:36, LIU Zhiwei wrote:
> >
> > On 2023/7/17 23:41, Daniel Henrique Barboza wrote:
> >> Commit bd30559568 made changes in how we're checking and disabling
> >> extensions based on env->priv_ver. One of the changes was to move the
> >> extension disablement code to the end of realize(), being able to
> >> disable extensions after we've auto-enabled some of them.
> >>
> >> An unfortunate side effect of this change started to happen with CPUs
> >> that has an older priv version, like sifive-u54. Starting on commit
> >> 2288a5ce43e5 we're auto-enabling zca, zcd and zcf if RVC is enabled,
> >> but these extensions are priv version 1.12.0. When running a cpu that
> >> has an older priv ver (like sifive-u54) the user is spammed with
> >> warnings like these:
> >>
> >> qemu-system-riscv64: warning: disabling zca extension for hart 
> >> 0x because privilege spec version does not match
> >> qemu-system-riscv64: warning: disabling zcd extension for hart 
> >> 0x because privilege spec version does not match
> >>
> >> The warnings are part of the code that disables the extension, but in this
> >> case we're throwing user warnings for stuff that we enabled on our own,
> >> without user intervention. Users are left wondering what they did wrong.
> >>
> >> A quick 8.1 fix for this nuisance is to check the CPU priv spec before
> >> auto-enabling zca/zcd/zcf. A more appropriate fix will include a more
> >> robust framework that will account for both priv_ver and user choice
> >> when auto-enabling/disabling extensions, but for 8.1 we'll make it do
> >> with this simple check.
> >>
> >> It's also worth noticing that this is the only case where we're
> >> auto-enabling extensions based on a criteria (in this case RVC) that
> >> doesn't match the priv spec of the extensions we're enabling. There's no
> >> need for more 8.1 band-aids.
> >>
> >> Cc: Conor Dooley 
> >> Fixes: 2288a5ce43e5 ("target/riscv: add cfg properties for Zc* extension")
> >> Signed-off-by: Daniel Henrique Barboza 
> >> ---
> >>   target/riscv/cpu.c | 3 ++-
> >>   1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> >> index 9339c0241d..6b93b04453 100644
> >> --- a/target/riscv/cpu.c
> >> +++ b/target/riscv/cpu.c
> >> @@ -1225,7 +1225,8 @@ void riscv_cpu_validate_set_extensions(RISCVCPU 
> >> *cpu, Error **errp)
> >>   }
> >>   }
> >> -if (riscv_has_ext(env, RVC)) {
> >> +/* zca, zcd and zcf has a PRIV 1.12.0 restriction */
> >
> > I think the Zca/zcd/zcf doesn't have much relationship with the privilege 
> > specification. The privilege specification doesn't define any
> > CSR or rules that Zca/zcd/zcf depend on. Maybe I missed something.  Does 
> > anyone  know why we should check PRIV_VERSION_1_12_0 for zca/zcf/zcd?
>
> I always thought about this priv spec filter as a way to determine the time
> window that the extension was ratified/defined. In this example it's been used
> to filter out zca/zcd/zcf from the sifive-u54 chip because this chip is older
> than those extensions, so it doesn't make sense to enable them.

That's true. The priv spec check is also there because we needed newer
versions of the priv spec for some extensions, and if we are going to
check some it's simpler to just check all of them.

>
> >
> > I think we should remove the check for priv_ver for many user mode 
> > extensions. We should set the checking privilege specification version for 
> > these extensions to PRIV_VERSION_1_10_0.
>
> I think it's hard to pick and choose which extensions will have a priv 
> version check
> or not. If we're bothered with the priv spec check per se then we should 
> remove it

Agreed

> entirely. Here's my plan to do it:

I think that'll work

>
> - remove cfg.priv_ver. This is a very old attribute that allow users to set 
> the priv_ver
> for generic CPUs like rv64. I'm doing changes in the user options for TCG 
> flags and the
> very existence of this option forces me to make priv checks for all 
> extensions we're
> auto-enabling during realize() (because I can't be sure whether the user 
> changed the
> priv_ver of rv64 to something older);

I'm not sure about that though. As we see more CPUs being released and
then future spec changes I feel like differentiating between priv
specs is a useful feature.

Alistair

>
> - split the realize() functions between generic and vendor CPUs again. It was 
> merged together
> earlier this year (I did it) because, back then, we were doing too much stuff 
> during
> realize() that was needed for named CPUs, but the side effect is what we're 
> seeing now:
> the common code is enabling unwanted extensions for vendor CPUs. The code is 
> very different
> now, and I believe that we can at least skip validate_set_extensions() for 
> vendor CPUs;
>
> - at this point, vendor CPUs aren't auto-enabling any features and gen

Re: [PATCH] target/riscv/cpu.c: check priv_ver before auto-enable zca/zcd/zcf

2023-07-18 Thread Alistair Francis
On Tue, Jul 18, 2023 at 1:42 AM Daniel Henrique Barboza
 wrote:
>
> Commit bd30559568 made changes in how we're checking and disabling
> extensions based on env->priv_ver. One of the changes was to move the
> extension disablement code to the end of realize(), being able to
> disable extensions after we've auto-enabled some of them.
>
> An unfortunate side effect of this change started to happen with CPUs
> that has an older priv version, like sifive-u54. Starting on commit
> 2288a5ce43e5 we're auto-enabling zca, zcd and zcf if RVC is enabled,
> but these extensions are priv version 1.12.0. When running a cpu that
> has an older priv ver (like sifive-u54) the user is spammed with
> warnings like these:
>
> qemu-system-riscv64: warning: disabling zca extension for hart 
> 0x because privilege spec version does not match
> qemu-system-riscv64: warning: disabling zcd extension for hart 
> 0x because privilege spec version does not match
>
> The warnings are part of the code that disables the extension, but in this
> case we're throwing user warnings for stuff that we enabled on our own,
> without user intervention. Users are left wondering what they did wrong.
>
> A quick 8.1 fix for this nuisance is to check the CPU priv spec before
> auto-enabling zca/zcd/zcf. A more appropriate fix will include a more
> robust framework that will account for both priv_ver and user choice
> when auto-enabling/disabling extensions, but for 8.1 we'll make it do
> with this simple check.
>
> It's also worth noticing that this is the only case where we're
> auto-enabling extensions based on a criteria (in this case RVC) that
> doesn't match the priv spec of the extensions we're enabling. There's no
> need for more 8.1 band-aids.
>
> Cc: Conor Dooley 
> Fixes: 2288a5ce43e5 ("target/riscv: add cfg properties for Zc* extension")
> Signed-off-by: Daniel Henrique Barboza 

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  target/riscv/cpu.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9339c0241d..6b93b04453 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1225,7 +1225,8 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
> Error **errp)
>  }
>  }
>
> -if (riscv_has_ext(env, RVC)) {
> +/* zca, zcd and zcf has a PRIV 1.12.0 restriction */
> +if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
>  cpu->cfg.ext_zca = true;
>  if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
>  cpu->cfg.ext_zcf = true;
> --
> 2.41.0
>
>



Re: [PATCH] hw/riscv: Fix topo field in error_report

2023-07-18 Thread Alistair Francis
On Tue, Jul 18, 2023 at 5:57 PM Zhao Liu  wrote:
>
> From: Zhao Liu 
>
> "smp.cpus" means the number of online CPUs and "smp.max_cpus" means the
> total number of CPUs.
>
> riscv_numa_get_default_cpu_node_id() checks "smp.cpus" and the
> "available CPUs" description in the next error message also indicates
> online CPUs.
>
> So report "smp.cpus" in error_report() instand of "smp.max_cpus".
>
> Since "smp.cpus" is "unsigned int", use "%u".
>
> Signed-off-by: Zhao Liu 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/numa.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
> index e0414d5b1b73..d319aefb4511 100644
> --- a/hw/riscv/numa.c
> +++ b/hw/riscv/numa.c
> @@ -209,8 +209,8 @@ int64_t riscv_numa_get_default_cpu_node_id(const 
> MachineState *ms, int idx)
>
>  if (ms->numa_state->num_nodes > ms->smp.cpus) {
>  error_report("Number of NUMA nodes (%d)"
> - " cannot exceed the number of available CPUs (%d).",
> - ms->numa_state->num_nodes, ms->smp.max_cpus);
> + " cannot exceed the number of available CPUs (%u).",
> + ms->numa_state->num_nodes, ms->smp.cpus);
>  exit(EXIT_FAILURE);
>  }
>  if (ms->numa_state->num_nodes) {
> --
> 2.34.1
>
>



Re: [PATCH v2] target/riscv: Fix LMUL check to use VLEN

2023-07-18 Thread Weiwei Li



On 2023/7/18 21:11, Rob Bradford wrote:

The previous check was failing with:

VLEN=128 ELEN = 64 SEW = 16 and LMUL = 1/8 which is a
valid combination.

Fix the check to allow valid combinations when VLEN is a multiple of
ELEN.

 From the specification:

"In general, the requirement is to support LMUL ≥ SEWMIN/ELEN, where
SEWMIN is the narrowest supported SEW value and ELEN is the widest
supported SEW value. In the standard extensions, SEWMIN=8. For standard
vector extensions with ELEN=32, fractional LMULs of 1/2 and 1/4 must be
supported. For standard vector extensions with ELEN=64, fractional LMULs
of 1/2, 1/4, and 1/8 must be supported." Elsewhere in the specification
it makes clear that VLEN>=ELEN.

 From inspection this new check allows:

VLEN=ELEN=64 1/2, 1/4, 1/8 for SEW >=8
VLEN=ELEN=32 1/2, 1/4 for SEW >=8

Fixes: d9b7609a1fb2 ("target/riscv: rvv-1.0: configure instructions")

Signed-off-by: Rob Bradford 
---
V2: Switch check to use VLEN and active SEW vs ELEN and minimum SEW
---


Reviewed-by: Weiwei Li 

Weiwei Li


  target/riscv/vector_helper.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index cfacf2ebba..4d06754826 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -43,9 +43,9 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong 
s1,
  xlen - 1 - 
R_VTYPE_RESERVED_SHIFT);
  
  if (lmul & 4) {

-/* Fractional LMUL. */
+/* Fractional LMUL - check LMUL * VLEN >= SEW */
  if (lmul == 4 ||
-cpu->cfg.elen >> (8 - lmul) < sew) {
+cpu->cfg.vlen >> (8 - lmul) < sew) {
  vill = true;
  }
  }





Re: [PATCH 1/3] target/riscv: Add cycle & instret privilege mode filtering properties

2023-07-18 Thread Weiwei Li



On 2023/7/19 06:47, Kaiwen Xue wrote:

This adds the properties for ISA extension smcntrpmf. Patches
implementing it will follow.

Signed-off-by: Kaiwen Xue 
Signed-off-by: Kaiwen Xue 
---
  target/riscv/cpu.c | 2 ++
  target/riscv/cpu_cfg.h | 1 +
  2 files changed, 3 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9339c0241d..31a1862561 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -132,6 +132,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
  ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
  ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
  ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
+ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
  ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
  ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
  ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
@@ -1753,6 +1754,7 @@ static Property riscv_cpu_extensions[] = {
  /* Defaults for standard extensions */
  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
  DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
+DEFINE_PROP_BOOL("smcntrpmf", RISCVCPU, cfg.ext_smcntrpmf, false),


Normally, property should be exposed to user at last after the function 
is implemented.


Regards,

Weiwei Li


  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),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 2bd9510ba3..424246cbec 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -69,6 +69,7 @@ struct RISCVCPUConfig {
  bool ext_zihintpause;
  bool ext_smstateen;
  bool ext_sstc;
+bool ext_smcntrpmf;
  bool ext_svadu;
  bool ext_svinval;
  bool ext_svnapot;





Re: [PATCH] hw/riscv: Fix topo field in error_report

2023-07-18 Thread Alistair Francis
On Tue, Jul 18, 2023 at 5:57 PM Zhao Liu  wrote:
>
> From: Zhao Liu 
>
> "smp.cpus" means the number of online CPUs and "smp.max_cpus" means the
> total number of CPUs.
>
> riscv_numa_get_default_cpu_node_id() checks "smp.cpus" and the
> "available CPUs" description in the next error message also indicates
> online CPUs.
>
> So report "smp.cpus" in error_report() instand of "smp.max_cpus".
>
> Since "smp.cpus" is "unsigned int", use "%u".
>
> Signed-off-by: Zhao Liu 

I fixed up the typo in the commit title

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  hw/riscv/numa.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
> index e0414d5b1b73..d319aefb4511 100644
> --- a/hw/riscv/numa.c
> +++ b/hw/riscv/numa.c
> @@ -209,8 +209,8 @@ int64_t riscv_numa_get_default_cpu_node_id(const 
> MachineState *ms, int idx)
>
>  if (ms->numa_state->num_nodes > ms->smp.cpus) {
>  error_report("Number of NUMA nodes (%d)"
> - " cannot exceed the number of available CPUs (%d).",
> - ms->numa_state->num_nodes, ms->smp.max_cpus);
> + " cannot exceed the number of available CPUs (%u).",
> + ms->numa_state->num_nodes, ms->smp.cpus);
>  exit(EXIT_FAILURE);
>  }
>  if (ms->numa_state->num_nodes) {
> --
> 2.34.1
>
>



[PATCH 2/3] target/riscv: Add cycle & instret privilege mode filtering definitions

2023-07-18 Thread Kaiwen Xue
This adds the definitions for ISA extension smcntrpmf.

Signed-off-by: Kaiwen Xue 
Signed-off-by: Kaiwen Xue 
---
 target/riscv/cpu.h  |  6 ++
 target/riscv/cpu_bits.h | 29 +
 2 files changed, 35 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6ea22e0eea..3cdf5d09f7 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -283,6 +283,12 @@ struct CPUArchState {
 
 target_ulong mcountinhibit;
 
+/* PMU cycle & instret privilege mode filtering */
+target_ulong mcyclecfg;
+target_ulong mcyclecfgh;
+target_ulong minstretcfg;
+target_ulong minstretcfgh;
+
 /* PMU counter state */
 PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 59f0ffd9e1..0a25fb276b 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -401,6 +401,10 @@
 /* Machine counter-inhibit register */
 #define CSR_MCOUNTINHIBIT   0x320
 
+/* Machine counter configuration registers */
+#define CSR_MCYCLECFG   0x321
+#define CSR_MINSTRETCFG 0x322
+
 #define CSR_MHPMEVENT3  0x323
 #define CSR_MHPMEVENT4  0x324
 #define CSR_MHPMEVENT5  0x325
@@ -431,6 +435,9 @@
 #define CSR_MHPMEVENT30 0x33e
 #define CSR_MHPMEVENT31 0x33f
 
+#define CSR_MCYCLECFGH  0x721
+#define CSR_MINSTRETCFGH0x722
+
 #define CSR_MHPMEVENT3H 0x723
 #define CSR_MHPMEVENT4H 0x724
 #define CSR_MHPMEVENT5H 0x725
@@ -879,6 +886,28 @@ typedef enum RISCVException {
 /* PMU related bits */
 #define MIE_LCOFIE (1 << IRQ_PMU_OVF)
 
+#define MCYCLECFG_BIT_MINH BIT_ULL(62)
+#define MCYCLECFGH_BIT_MINHBIT(30)
+#define MCYCLECFG_BIT_SINH BIT_ULL(61)
+#define MCYCLECFGH_BIT_SINHBIT(29)
+#define MCYCLECFG_BIT_UINH BIT_ULL(60)
+#define MCYCLECFGH_BIT_UINHBIT(28)
+#define MCYCLECFG_BIT_VSINHBIT_ULL(59)
+#define MCYCLECFGH_BIT_VSINH   BIT(27)
+#define MCYCLECFG_BIT_VUINHBIT_ULL(58)
+#define MCYCLECFGH_BIT_VUINH   BIT(26)
+
+#define MINSTRETCFG_BIT_MINH   BIT_ULL(62)
+#define MINSTRETCFGH_BIT_MINH  BIT(30)
+#define MINSTRETCFG_BIT_SINH   BIT_ULL(61)
+#define MINSTRETCFGH_BIT_SINH  BIT(29)
+#define MINSTRETCFG_BIT_UINH   BIT_ULL(60)
+#define MINSTRETCFGH_BIT_UINH  BIT(28)
+#define MINSTRETCFG_BIT_VSINH  BIT_ULL(59)
+#define MINSTRETCFGH_BIT_VSINH BIT(27)
+#define MINSTRETCFG_BIT_VUINH  BIT_ULL(58)
+#define MINSTRETCFGH_BIT_VUINH BIT(26)
+
 #define MHPMEVENT_BIT_OF   BIT_ULL(63)
 #define MHPMEVENTH_BIT_OF  BIT(31)
 #define MHPMEVENT_BIT_MINH BIT_ULL(62)
-- 
2.34.1




[PATCH 3/3] target/riscv: Add cycle & instret privilege mode filtering support

2023-07-18 Thread Kaiwen Xue
QEMU only calculates dummy cycles and instructions, so there is no
actual means to stop the icount in QEMU. Hence this patch merely adds
the functionality of accessing the cfg registers, and cause no actual
effects on the counting of cycle and instret counters.

Signed-off-by: Kaiwen Xue 
Signed-off-by: Kaiwen Xue 
---
 target/riscv/csr.c | 73 ++
 1 file changed, 73 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ea7585329e..b1d5e85a79 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -218,6 +218,17 @@ static RISCVException sscofpmf(CPURISCVState *env, int 
csrno)
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException smcntrpmf(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+
+if (!cpu->cfg.ext_smcntrpmf) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return RISCV_EXCP_NONE;
+}
+
 static RISCVException any(CPURISCVState *env, int csrno)
 {
 return RISCV_EXCP_NONE;
@@ -800,6 +811,54 @@ static int read_hpmcounterh(CPURISCVState *env, int csrno, 
target_ulong *val)
 
 #else /* CONFIG_USER_ONLY */
 
+static int read_mcyclecfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->mcyclecfg;
+return RISCV_EXCP_NONE;
+}
+
+static int write_mcyclecfg(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->mcyclecfg = val;
+return RISCV_EXCP_NONE;
+}
+
+static int read_mcyclecfgh(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->mcyclecfgh;
+return RISCV_EXCP_NONE;
+}
+
+static int write_mcyclecfgh(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->mcyclecfgh = val;
+return RISCV_EXCP_NONE;
+}
+
+static int read_minstretcfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->minstretcfg;
+return RISCV_EXCP_NONE;
+}
+
+static int write_minstretcfg(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->minstretcfg = val;
+return RISCV_EXCP_NONE;
+}
+
+static int read_minstretcfgh(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->minstretcfgh;
+return RISCV_EXCP_NONE;
+}
+
+static int write_minstretcfgh(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->minstretcfgh = val;
+return RISCV_EXCP_NONE;
+}
+
 static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
 {
 int evt_index = csrno - CSR_MCOUNTINHIBIT;
@@ -4506,6 +4565,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
  write_mcountinhibit,
  .min_priv_ver = PRIV_VERSION_1_11_0   },
 
+[CSR_MCYCLECFG]  = { "mcyclecfg",   smcntrpmf, read_mcyclecfg,
+ write_mcyclecfg,
+ .min_priv_ver = PRIV_VERSION_1_12_0   },
+[CSR_MINSTRETCFG]= { "minstretcfg", smcntrpmf, read_minstretcfg,
+ write_minstretcfg,
+ .min_priv_ver = PRIV_VERSION_1_12_0   },
+
 [CSR_MHPMEVENT3] = { "mhpmevent3", any,read_mhpmevent,
  write_mhpmevent   },
 [CSR_MHPMEVENT4] = { "mhpmevent4", any,read_mhpmevent,
@@ -4565,6 +4631,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_MHPMEVENT31]= { "mhpmevent31",any,read_mhpmevent,
  write_mhpmevent   },
 
+[CSR_MCYCLECFGH] = { "mcyclecfgh",   smcntrpmf, read_mcyclecfgh,
+ write_mcyclecfgh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
+[CSR_MINSTRETCFGH]   = { "minstretcfgh", smcntrpmf, read_minstretcfgh,
+ write_minstretcfgh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
+
 [CSR_MHPMEVENT3H]= { "mhpmevent3h",sscofpmf,  read_mhpmeventh,
  write_mhpmeventh,
  .min_priv_ver = PRIV_VERSION_1_12_0},
-- 
2.34.1




[PATCH 1/3] target/riscv: Add cycle & instret privilege mode filtering properties

2023-07-18 Thread Kaiwen Xue
This adds the properties for ISA extension smcntrpmf. Patches
implementing it will follow.

Signed-off-by: Kaiwen Xue 
Signed-off-by: Kaiwen Xue 
---
 target/riscv/cpu.c | 2 ++
 target/riscv/cpu_cfg.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9339c0241d..31a1862561 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -132,6 +132,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
 ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
 ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
+ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
 ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
 ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
 ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
@@ -1753,6 +1754,7 @@ static Property riscv_cpu_extensions[] = {
 /* Defaults for standard extensions */
 DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
 DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
+DEFINE_PROP_BOOL("smcntrpmf", RISCVCPU, cfg.ext_smcntrpmf, false),
 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),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 2bd9510ba3..424246cbec 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -69,6 +69,7 @@ struct RISCVCPUConfig {
 bool ext_zihintpause;
 bool ext_smstateen;
 bool ext_sstc;
+bool ext_smcntrpmf;
 bool ext_svadu;
 bool ext_svinval;
 bool ext_svnapot;
-- 
2.34.1




[PATCH 0/3] risc-v: Add ISA extension smcntrpmf support

2023-07-18 Thread Kaiwen Xue
This patch series adds the support for RISC-V ISA extension smcntrpmf (cycle and
privilege mode filtering) [1]. QEMU only calculates dummy cycles and
instructions, so there is no actual means to stop the icount in QEMU. Therefore,
this series only add the read/write behavior of the relevant CSRs such that the
implemented firmware support [2] can work without causing unnecessary illegal
instruction exceptions.

[1] https://github.com/riscv/riscv-smcntrpmf
[2] https://github.com/rivosinc/opensbi/tree/dev/kaiwenx/smcntrpmf_upstream

Kaiwen Xue (3):
  target/riscv: Add cycle & instret privilege mode filtering properties
  target/riscv: Add cycle & instret privilege mode filtering definitions
  target/riscv: Add cycle & instret privilege mode filtering support

 target/riscv/cpu.c  |  2 ++
 target/riscv/cpu.h  |  6 
 target/riscv/cpu_bits.h | 29 
 target/riscv/cpu_cfg.h  |  1 +
 target/riscv/csr.c  | 73 +
 5 files changed, 111 insertions(+)

-- 
2.34.1




Re: [PATCH 3/3] target/riscv: Add cycle & instret privilege mode filtering support

2023-07-18 Thread Weiwei Li



On 2023/7/19 06:47, Kaiwen Xue wrote:

QEMU only calculates dummy cycles and instructions, so there is no
actual means to stop the icount in QEMU. Hence this patch merely adds
the functionality of accessing the cfg registers, and cause no actual
effects on the counting of cycle and instret counters.

Maybe you can record/accumulate them when privilege mode changes/switchs.


Signed-off-by: Kaiwen Xue 
Signed-off-by: Kaiwen Xue 
---
  target/riscv/csr.c | 73 ++
  1 file changed, 73 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index ea7585329e..b1d5e85a79 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -218,6 +218,17 @@ static RISCVException sscofpmf(CPURISCVState *env, int 
csrno)
  return RISCV_EXCP_NONE;
  }
  
+static RISCVException smcntrpmf(CPURISCVState *env, int csrno)

+{
+RISCVCPU *cpu = env_archcpu(env);
+
+if (!cpu->cfg.ext_smcntrpmf) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return RISCV_EXCP_NONE;
+}
+
  static RISCVException any(CPURISCVState *env, int csrno)
  {
  return RISCV_EXCP_NONE;
@@ -800,6 +811,54 @@ static int read_hpmcounterh(CPURISCVState *env, int csrno, 
target_ulong *val)
  
  #else /* CONFIG_USER_ONLY */
  
+static int read_mcyclecfg(CPURISCVState *env, int csrno, target_ulong *val)

+{
+*val = env->mcyclecfg;
+return RISCV_EXCP_NONE;
+}
+
+static int write_mcyclecfg(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->mcyclecfg = val;
+return RISCV_EXCP_NONE;
+}
+
+static int read_mcyclecfgh(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->mcyclecfgh;
+return RISCV_EXCP_NONE;
+}
+
+static int write_mcyclecfgh(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->mcyclecfgh = val;
+return RISCV_EXCP_NONE;
+}
+
+static int read_minstretcfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->minstretcfg;
+return RISCV_EXCP_NONE;
+}
+
+static int write_minstretcfg(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->minstretcfg = val;
+return RISCV_EXCP_NONE;
+}
+
+static int read_minstretcfgh(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->minstretcfgh;
+return RISCV_EXCP_NONE;
+}
+
+static int write_minstretcfgh(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->minstretcfgh = val;
+return RISCV_EXCP_NONE;
+}
+
  static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
  {
  int evt_index = csrno - CSR_MCOUNTINHIBIT;
@@ -4506,6 +4565,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
   write_mcountinhibit,
   .min_priv_ver = PRIV_VERSION_1_11_0   },
  
+[CSR_MCYCLECFG]  = { "mcyclecfg",   smcntrpmf, read_mcyclecfg,

+ write_mcyclecfg,
+ .min_priv_ver = PRIV_VERSION_1_12_0   },
+[CSR_MINSTRETCFG]= { "minstretcfg", smcntrpmf, read_minstretcfg,
+ write_minstretcfg,
+ .min_priv_ver = PRIV_VERSION_1_12_0   },
+
  [CSR_MHPMEVENT3] = { "mhpmevent3", any,read_mhpmevent,
   write_mhpmevent   },
  [CSR_MHPMEVENT4] = { "mhpmevent4", any,read_mhpmevent,
@@ -4565,6 +4631,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
  [CSR_MHPMEVENT31]= { "mhpmevent31",any,read_mhpmevent,
   write_mhpmevent   },
  
+[CSR_MCYCLECFGH] = { "mcyclecfgh",   smcntrpmf, read_mcyclecfgh,

+ write_mcyclecfgh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},
+[CSR_MINSTRETCFGH]   = { "minstretcfgh", smcntrpmf, read_minstretcfgh,
+ write_minstretcfgh,
+ .min_priv_ver = PRIV_VERSION_1_12_0},


This two CSRs are RV32-only, they cannot directly share the same 
predicate as MCYCLECFG/MINSTRETCFG.


Regards,

Weiwei Li


+
  [CSR_MHPMEVENT3H]= { "mhpmevent3h",sscofpmf,  read_mhpmeventh,
   write_mhpmeventh,
   .min_priv_ver = PRIV_VERSION_1_12_0},





Re: Boot failure after QEMU's upgrade to OpenSBI v1.3 (was Re: [PATCH for-8.2 6/7] target/riscv: add 'max' CPU type)

2023-07-18 Thread Alistair Francis
On Sat, Jul 15, 2023 at 7:14 PM Atish Patra  wrote:
>
> On Fri, Jul 14, 2023 at 5:29 AM Conor Dooley  wrote:
> >
> > On Fri, Jul 14, 2023 at 11:19:34AM +0100, Conor Dooley wrote:
> > > On Fri, Jul 14, 2023 at 10:00:19AM +0530, Anup Patel wrote:
> > >
> > > > > > OpenSBI v1.3
> > > > > >_  _
> > > > > >   / __ \  / |  _ \_   _|
> > > > > >  | |  | |_ __   ___ _ __ | (___ | |_) || |
> > > > > >  | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
> > > > > >  | |__| | |_) |  __/ | | |) | |_) || |_
> > > > > >   \/| .__/ \___|_| |_|_/|___/_|
> > > > > > | |
> > > > > > |_|
> > > > > >
> > > > > > init_coldboot: ipi init failed (error -1009)
> > > > > >
> > > > > > Just to note, because we use our own firmware that vendors in 
> > > > > > OpenSBI
> > > > > > and compiles only a significantly cut down number of files from it, 
> > > > > > we
> > > > > > do not use the fw_dynamic etc flow on our hardware. As a result, we 
> > > > > > have
> > > > > > not tested v1.3, nor do we have any immediate plans to change our
> > > > > > platform firmware to vendor v1.3 either.
> > > > > >
> > > > > > I unless there's something obvious to you, it sounds like I will 
> > > > > > need to
> > > > > > go and bisect OpenSBI. That's a job for another day though, given 
> > > > > > the
> > > > > > time.
> > > > > >
> > > >
> > > > The real issue is some CPU/HART DT nodes marked as disabled in the
> > > > DT passed to OpenSBI 1.3.
> > > >
> > > > This issue does not exist in any of the DTs generated by QEMU but some
> > > > of the DTs in the kernel (such as microchip and SiFive board DTs) have
> > > > the E-core disabled.
> > > >
> > > > I had discovered this issue in a totally different context after the 
> > > > OpenSBI 1.3
> > > > release happened. This issue is already fixed in the latest OpenSBI by 
> > > > the
> > > > following commit c6a35733b74aeff612398f274ed19a74f81d1f37 ("lib: utils:
> > > > Fix sbi_hartid_to_scratch() usage in ACLINT drivers").
> > >
> > > Great, thanks Anup! I thought I had tested tip-of-tree too, but
> > > obviously not.
> > >
> > > > I always assumed that Microchip hss.bin is the preferred BIOS for the
> > > > QEMU microchip-icicle-kit machine but I guess that's not true.
> > >
> > > Unfortunately the HSS has not worked in QEMU for a long time, and while
> > > I would love to fix it, but am pretty stretched for spare time to begin
> > > with.
> > > I usually just do direct kernel boots, which use the OpenSBI that comes
> > > with QEMU, as I am sure you already know :)
> > >
> > > > At this point, you can either:
> > > > 1) Use latest OpenSBI on QEMU microchip-icicle-kit machine
> >
> > I forgot to reply to this point, wondering what should be done with
> > QEMU. Bumping to v1.3 in QEMU introduces a regression here, regardless
> > of whether I can go and build a fixed version of OpenSBI.
> >
> FYI: The no-map fix went in OpenSBI v1.3. Without the upgrade, any
> user using the latest kernel (> v6.4)
> may hit those random linear map related issues (in hibernation or EFI
> booting path).
>
> There are three possible scenarios:
>
> 1. Upgrade to OpenSBI v1.3: Any user of microchip-icicle-kit machine
> or sifive fu540 machine users
> may hit this issue if the device tree has the disabled hart (e core).
> 2. No upgrade to OpenSBI v1.2. Any user using hibernation or UEFI may
> have issues [1]
> 3. Include a non-release version OpenSBI in Qemu with the fix as an exception.
>
> #3 probably deviates from policy and sets a bad precedent. So I am not
> advocating for it though ;)
> For both #1 & #2, the solution would be to use the latest OpenSBI in
> -bios argument instead of the stock one.
> I could be wrong but my guess is the number of users facing #2 would
> be higher than #1.

Thanks for that info Atish!

We are stuck in a bad situation.

The best solution would be if OpenSBI can release a 1.3.1, @Anup Patel
do you think you could do that?

Otherwise I think we should stick with OpenSBI 1.3. Considering that
it fixes UEFI boot issues for the virt board (which would be the most
used) it seems like a best call to make. People using the other boards
are unfortunately stuck building their own OpenSBI release.

If there is no OpenSBI 1.3.1 release we should add something to the
release notes. @Conor Dooley are you able to give a clear sentence on
how the boot fails?

Alistair

>
> [1] 
> https://lore.kernel.org/linux-riscv/20230625140931.1266216-1-songshuaish...@tinylab.org/
> > > > 2) Ensure CPU0 DT node is enabled in DT when booting on QEMU
> > > > microchip-icicle-kit machine with OpenSBI 1.3
> > >
> > > Will OpenSBI disable it? If not, I think option 2) needs to be remove
> > > the DT node. I'll just use tip-of-tree myself & up to the
> >
> > Clearly didn't finish this comment. It was meant to say "up to the QEMU
> > maintainers what they want to do on the QEMU side of things".
> >
> > Thanks,
> > Conor.
>
>
>
> --
> Rega

Re: [PATCH v2] target/riscv: Fix LMUL check to use VLEN

2023-07-18 Thread Alistair Francis
On Tue, Jul 18, 2023 at 11:14 PM Rob Bradford  wrote:
>
> The previous check was failing with:
>
> VLEN=128 ELEN = 64 SEW = 16 and LMUL = 1/8 which is a
> valid combination.
>
> Fix the check to allow valid combinations when VLEN is a multiple of
> ELEN.
>
> From the specification:
>
> "In general, the requirement is to support LMUL ≥ SEWMIN/ELEN, where
> SEWMIN is the narrowest supported SEW value and ELEN is the widest
> supported SEW value. In the standard extensions, SEWMIN=8. For standard
> vector extensions with ELEN=32, fractional LMULs of 1/2 and 1/4 must be
> supported. For standard vector extensions with ELEN=64, fractional LMULs
> of 1/2, 1/4, and 1/8 must be supported." Elsewhere in the specification
> it makes clear that VLEN>=ELEN.
>
> From inspection this new check allows:
>
> VLEN=ELEN=64 1/2, 1/4, 1/8 for SEW >=8
> VLEN=ELEN=32 1/2, 1/4 for SEW >=8
>
> Fixes: d9b7609a1fb2 ("target/riscv: rvv-1.0: configure instructions")
>
> Signed-off-by: Rob Bradford 

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
> V2: Switch check to use VLEN and active SEW vs ELEN and minimum SEW
> ---
>  target/riscv/vector_helper.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index cfacf2ebba..4d06754826 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -43,9 +43,9 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
> target_ulong s1,
>  xlen - 1 - 
> R_VTYPE_RESERVED_SHIFT);
>
>  if (lmul & 4) {
> -/* Fractional LMUL. */
> +/* Fractional LMUL - check LMUL * VLEN >= SEW */
>  if (lmul == 4 ||
> -cpu->cfg.elen >> (8 - lmul) < sew) {
> +cpu->cfg.vlen >> (8 - lmul) < sew) {
>  vill = true;
>  }
>  }
> --
> 2.41.0
>
>



Re: [PATCH] vhost: disable VHOST_OPS_DEBUG by default

2023-07-18 Thread Zhu, Lingshan




On 7/17/2023 6:14 PM, Philippe Mathieu-Daudé wrote:

Hi,

On 17/7/23 19:44, Zhu Lingshan wrote:

This commit disables VHOST_OPS_DEBUG by default
These information are ususally only required in development
environment

Signed-off-by: Zhu Lingshan 
---
  hw/virtio/vhost.c | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 82394331bf..ec435a3079 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -29,7 +29,9 @@
  #include "trace.h"
    /* enabled until disconnected backend stabilizes */
-#define _VHOST_DEBUG 1
+
+/* uncomment macro _VHOST_DEBUG to enable VHOST_OPS_DEBUG */
+/* #define _VHOST_DEBUG 1 */


Since you are looking at this, it would be more useful to
convert VHOST_OPS_DEBUG() to trace events (see for example
commit 163b8663b8 and other "Convert DPRINTF() debug macro
to trace events" commits).

Thanks Phil, I will look into this


Regards,

Phil.






[PATCH v5 0/3] hw/ufs: Add Universal Flash Storage (UFS) support

2023-07-18 Thread Jeuk Kim
Since v4:
Addressed review comment from Stefan Hajnoczi. The fixes are as
follows.
- Keep u->reg fields in host endian (Removed little-endian helper 
  functions from MemoryRegionOps)
- Remove unnecessary NULL checks for g_new and g_malloc0
- Replace DEFINE_PROP_DRIVE_IOTHREAD -> DEFINE_PROP_DRIVE

In case you were wondering, ufs and ufs-lu have been tested for the
following behaviours.
1. Checked ufs device recognition in Windows10 environment
2. Verified ufs device recognition in Ubuntu 22.04 environment
3. Verified io behaviour via fio in Ubuntu 22.04 environment
4. Verified query request via ufs-tools in Ubuntu 22.04 environment

Since v3:
- Replace softmmu_ss -> system_ss in meson

Since v2:
Addressed review comment from Stefan Hajnoczi. The main fixes are as
follows.
- Use of SPDX licence identifiers
- fixed endianness error
- removed memory leak
- fixed DMA error handling logic

Since v1:
- use macros of "hw/registerfields.h" (Addressed Philippe's review
  comments)

This patch series adds support for a new PCI-based UFS device.

The UFS pci device id (PCI_DEVICE_ID_REDHAT_UFS) is not registered
in the Linux kernel yet, so it does not work right away, but I confirmed
that it works with Linux when the UFS pci device id is registered.

I have also verified that it works with Windows 10.

Jeuk Kim (3):
  hw/ufs: Initial commit for emulated Universal-Flash-Storage
  hw/ufs: Support for Query Transfer Requests
  hw/ufs: Support for UFS logical unit

 MAINTAINERS  |6 +
 docs/specs/pci-ids.rst   |2 +
 hw/Kconfig   |1 +
 hw/meson.build   |1 +
 hw/ufs/Kconfig   |4 +
 hw/ufs/lu.c  | 1439 
 hw/ufs/meson.build   |1 +
 hw/ufs/trace-events  |   58 ++
 hw/ufs/trace.h   |1 +
 hw/ufs/ufs.c | 1494 ++
 hw/ufs/ufs.h |  131 
 include/block/ufs.h  | 1048 ++
 include/hw/pci/pci.h |1 +
 include/hw/pci/pci_ids.h |1 +
 include/scsi/constants.h |1 +
 meson.build  |1 +
 16 files changed, 4190 insertions(+)
 create mode 100644 hw/ufs/Kconfig
 create mode 100644 hw/ufs/lu.c
 create mode 100644 hw/ufs/meson.build
 create mode 100644 hw/ufs/trace-events
 create mode 100644 hw/ufs/trace.h
 create mode 100644 hw/ufs/ufs.c
 create mode 100644 hw/ufs/ufs.h
 create mode 100644 include/block/ufs.h

-- 
2.34.1




[PATCH v5 2/3] hw/ufs: Support for Query Transfer Requests

2023-07-18 Thread Jeuk Kim
From: Jeuk Kim 

This commit makes the UFS device support query
and nop out transfer requests.

The next patch would be support for UFS logical
unit and scsi command transfer request.

Signed-off-by: Jeuk Kim 
---
 hw/ufs/trace-events |   1 +
 hw/ufs/ufs.c| 980 +++-
 hw/ufs/ufs.h|  46 +++
 3 files changed, 1025 insertions(+), 2 deletions(-)

diff --git a/hw/ufs/trace-events b/hw/ufs/trace-events
index d1badcad10..665e1a942b 100644
--- a/hw/ufs/trace-events
+++ b/hw/ufs/trace-events
@@ -18,6 +18,7 @@ ufs_err_dma_read_req_upiu(uint32_t slot, uint64_t addr) 
"failed to read req upiu
 ufs_err_dma_read_prdt(uint32_t slot, uint64_t addr) "failed to read prdt. 
UTRLDBR slot %"PRIu32", prdt addr %"PRIu64""
 ufs_err_dma_write_utrd(uint32_t slot, uint64_t addr) "failed to write utrd. 
UTRLDBR slot %"PRIu32", UTRD dma addr %"PRIu64""
 ufs_err_dma_write_rsp_upiu(uint32_t slot, uint64_t addr) "failed to write rsp 
upiu. UTRLDBR slot %"PRIu32", response upiu addr %"PRIu64""
+ufs_err_utrl_slot_error(uint32_t slot) "UTRLDBR slot %"PRIu32" is in error"
 ufs_err_utrl_slot_busy(uint32_t slot) "UTRLDBR slot %"PRIu32" is busy"
 ufs_err_unsupport_register_offset(uint32_t offset) "Register offset 
0x%"PRIx32" is not yet supported"
 ufs_err_invalid_register_offset(uint32_t offset) "Register offset 0x%"PRIx32" 
is invalid"
diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c
index 101082a8a3..cd33af2cde 100644
--- a/hw/ufs/ufs.c
+++ b/hw/ufs/ufs.c
@@ -15,10 +15,221 @@
 #include "ufs.h"
 
 /* The QEMU-UFS device follows spec version 3.1 */
-#define UFS_SPEC_VER 0x0310
+#define UFS_SPEC_VER 0x0310
 #define UFS_MAX_NUTRS 32
 #define UFS_MAX_NUTMRS 8
 
+static MemTxResult ufs_addr_read(UfsHc *u, hwaddr addr, void *buf, int size)
+{
+hwaddr hi = addr + size - 1;
+
+if (hi < addr) {
+return MEMTX_DECODE_ERROR;
+}
+
+if (!FIELD_EX32(u->reg.cap, CAP, 64AS) && (hi >> 32)) {
+return MEMTX_DECODE_ERROR;
+}
+
+return pci_dma_read(PCI_DEVICE(u), addr, buf, size);
+}
+
+static MemTxResult ufs_addr_write(UfsHc *u, hwaddr addr, const void *buf,
+  int size)
+{
+hwaddr hi = addr + size - 1;
+if (hi < addr) {
+return MEMTX_DECODE_ERROR;
+}
+
+if (!FIELD_EX32(u->reg.cap, CAP, 64AS) && (hi >> 32)) {
+return MEMTX_DECODE_ERROR;
+}
+
+return pci_dma_write(PCI_DEVICE(u), addr, buf, size);
+}
+
+static void ufs_complete_req(UfsRequest *req, UfsReqResult req_result);
+
+static inline hwaddr ufs_get_utrd_addr(UfsHc *u, uint32_t slot)
+{
+hwaddr utrl_base_addr = (((hwaddr)u->reg.utrlbau) << 32) + u->reg.utrlba;
+hwaddr utrd_addr = utrl_base_addr + slot * sizeof(UtpTransferReqDesc);
+
+return utrd_addr;
+}
+
+static inline hwaddr ufs_get_req_upiu_base_addr(const UtpTransferReqDesc *utrd)
+{
+uint32_t cmd_desc_base_addr_lo =
+le32_to_cpu(utrd->command_desc_base_addr_lo);
+uint32_t cmd_desc_base_addr_hi =
+le32_to_cpu(utrd->command_desc_base_addr_hi);
+
+return (((hwaddr)cmd_desc_base_addr_hi) << 32) + cmd_desc_base_addr_lo;
+}
+
+static inline hwaddr ufs_get_rsp_upiu_base_addr(const UtpTransferReqDesc *utrd)
+{
+hwaddr req_upiu_base_addr = ufs_get_req_upiu_base_addr(utrd);
+uint32_t rsp_upiu_byte_off =
+le16_to_cpu(utrd->response_upiu_offset) * sizeof(uint32_t);
+return req_upiu_base_addr + rsp_upiu_byte_off;
+}
+
+static MemTxResult ufs_dma_read_utrd(UfsRequest *req)
+{
+UfsHc *u = req->hc;
+hwaddr utrd_addr = ufs_get_utrd_addr(u, req->slot);
+MemTxResult ret;
+
+ret = ufs_addr_read(u, utrd_addr, &req->utrd, sizeof(req->utrd));
+if (ret) {
+trace_ufs_err_dma_read_utrd(req->slot, utrd_addr);
+}
+return ret;
+}
+
+static MemTxResult ufs_dma_read_req_upiu(UfsRequest *req)
+{
+UfsHc *u = req->hc;
+hwaddr req_upiu_base_addr = ufs_get_req_upiu_base_addr(&req->utrd);
+UtpUpiuReq *req_upiu = &req->req_upiu;
+uint32_t copy_size;
+uint16_t data_segment_length;
+MemTxResult ret;
+
+/*
+ * To know the size of the req_upiu, we need to read the
+ * data_segment_length in the header first.
+ */
+ret = ufs_addr_read(u, req_upiu_base_addr, &req_upiu->header,
+sizeof(UtpUpiuHeader));
+if (ret) {
+trace_ufs_err_dma_read_req_upiu(req->slot, req_upiu_base_addr);
+return ret;
+}
+data_segment_length = be16_to_cpu(req_upiu->header.data_segment_length);
+
+copy_size = sizeof(UtpUpiuHeader) + UFS_TRANSACTION_SPECIFIC_FIELD_SIZE +
+data_segment_length;
+
+ret = ufs_addr_read(u, req_upiu_base_addr, &req->req_upiu, copy_size);
+if (ret) {
+trace_ufs_err_dma_read_req_upiu(req->slot, req_upiu_base_addr);
+}
+return ret;
+}
+
+static MemTxResult ufs_dma_read_prdt(UfsRequest *req)
+{
+UfsHc *u = req->hc;
+uint16_t prdt_len = le16_to_cpu(req->utrd.prd_table_length);
+uint16_t prdt_byte_off 

[PATCH v5 1/3] hw/ufs: Initial commit for emulated Universal-Flash-Storage

2023-07-18 Thread Jeuk Kim
From: Jeuk Kim 

Universal Flash Storage (UFS) is a high-performance mass storage device
with a serial interface. It is primarily used as a high-performance
data storage device for embedded applications.

This commit contains code for UFS device to be recognized
as a UFS PCI device.
Patches to handle UFS logical unit and Transfer Request will follow.

Signed-off-by: Jeuk Kim 
---
 MAINTAINERS  |6 +
 docs/specs/pci-ids.rst   |2 +
 hw/Kconfig   |1 +
 hw/meson.build   |1 +
 hw/ufs/Kconfig   |4 +
 hw/ufs/meson.build   |1 +
 hw/ufs/trace-events  |   32 ++
 hw/ufs/trace.h   |1 +
 hw/ufs/ufs.c |  278 ++
 hw/ufs/ufs.h |   42 ++
 include/block/ufs.h  | 1048 ++
 include/hw/pci/pci.h |1 +
 include/hw/pci/pci_ids.h |1 +
 meson.build  |1 +
 14 files changed, 1419 insertions(+)
 create mode 100644 hw/ufs/Kconfig
 create mode 100644 hw/ufs/meson.build
 create mode 100644 hw/ufs/trace-events
 create mode 100644 hw/ufs/trace.h
 create mode 100644 hw/ufs/ufs.c
 create mode 100644 hw/ufs/ufs.h
 create mode 100644 include/block/ufs.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 12e59b6b27..0c8a955b42 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2256,6 +2256,12 @@ F: tests/qtest/nvme-test.c
 F: docs/system/devices/nvme.rst
 T: git git://git.infradead.org/qemu-nvme.git nvme-next
 
+ufs
+M: Jeuk Kim 
+S: Supported
+F: hw/ufs/*
+F: include/block/ufs.h
+
 megasas
 M: Hannes Reinecke 
 L: qemu-bl...@nongnu.org
diff --git a/docs/specs/pci-ids.rst b/docs/specs/pci-ids.rst
index e302bea484..d6707fa069 100644
--- a/docs/specs/pci-ids.rst
+++ b/docs/specs/pci-ids.rst
@@ -92,6 +92,8 @@ PCI devices (other than virtio):
   PCI PVPanic device (``-device pvpanic-pci``)
 1b36:0012
   PCI ACPI ERST device (``-device acpi-erst``)
+1b36:0013
+  PCI UFS device (``-device ufs``)
 
 All these devices are documented in :doc:`index`.
 
diff --git a/hw/Kconfig b/hw/Kconfig
index ba62ff6417..9ca7b38c31 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -38,6 +38,7 @@ source smbios/Kconfig
 source ssi/Kconfig
 source timer/Kconfig
 source tpm/Kconfig
+source ufs/Kconfig
 source usb/Kconfig
 source virtio/Kconfig
 source vfio/Kconfig
diff --git a/hw/meson.build b/hw/meson.build
index c7ac7d3d75..f01fac4617 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -37,6 +37,7 @@ subdir('smbios')
 subdir('ssi')
 subdir('timer')
 subdir('tpm')
+subdir('ufs')
 subdir('usb')
 subdir('vfio')
 subdir('virtio')
diff --git a/hw/ufs/Kconfig b/hw/ufs/Kconfig
new file mode 100644
index 00..b7b3392e85
--- /dev/null
+++ b/hw/ufs/Kconfig
@@ -0,0 +1,4 @@
+config UFS_PCI
+bool
+default y if PCI_DEVICES
+depends on PCI
diff --git a/hw/ufs/meson.build b/hw/ufs/meson.build
new file mode 100644
index 00..eb5164bde9
--- /dev/null
+++ b/hw/ufs/meson.build
@@ -0,0 +1 @@
+system_ss.add(when: 'CONFIG_UFS_PCI', if_true: files('ufs.c'))
diff --git a/hw/ufs/trace-events b/hw/ufs/trace-events
new file mode 100644
index 00..d1badcad10
--- /dev/null
+++ b/hw/ufs/trace-events
@@ -0,0 +1,32 @@
+# ufs.c
+ufs_irq_raise(void) "INTx"
+ufs_irq_lower(void) "INTx"
+ufs_mmio_read(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx64" 
data 0x%"PRIx64" size %d"
+ufs_mmio_write(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx64" 
data 0x%"PRIx64" size %d"
+ufs_process_db(uint32_t slot) "UTRLDBR slot %"PRIu32""
+ufs_process_req(uint32_t slot) "UTRLDBR slot %"PRIu32""
+ufs_complete_req(uint32_t slot) "UTRLDBR slot %"PRIu32""
+ufs_sendback_req(uint32_t slot) "UTRLDBR slot %"PRIu32""
+ufs_exec_nop_cmd(uint32_t slot) "UTRLDBR slot %"PRIu32""
+ufs_exec_scsi_cmd(uint32_t slot, uint8_t lun, uint8_t opcode) "slot %"PRIu32", 
lun 0x%"PRIx8", opcode 0x%"PRIx8""
+ufs_exec_query_cmd(uint32_t slot, uint8_t opcode) "slot %"PRIu32", opcode 
0x%"PRIx8""
+ufs_process_uiccmd(uint32_t uiccmd, uint32_t ucmdarg1, uint32_t ucmdarg2, 
uint32_t ucmdarg3) "uiccmd 0x%"PRIx32", ucmdarg1 0x%"PRIx32", ucmdarg2 
0x%"PRIx32", ucmdarg3 0x%"PRIx32""
+
+# error condition
+ufs_err_dma_read_utrd(uint32_t slot, uint64_t addr) "failed to read utrd. 
UTRLDBR slot %"PRIu32", UTRD dma addr %"PRIu64""
+ufs_err_dma_read_req_upiu(uint32_t slot, uint64_t addr) "failed to read req 
upiu. UTRLDBR slot %"PRIu32", request upiu addr %"PRIu64""
+ufs_err_dma_read_prdt(uint32_t slot, uint64_t addr) "failed to read prdt. 
UTRLDBR slot %"PRIu32", prdt addr %"PRIu64""
+ufs_err_dma_write_utrd(uint32_t slot, uint64_t addr) "failed to write utrd. 
UTRLDBR slot %"PRIu32", UTRD dma addr %"PRIu64""
+ufs_err_dma_write_rsp_upiu(uint32_t slot, uint64_t addr) "failed to write rsp 
upiu. UTRLDBR slot %"PRIu32", response upiu addr %"PRIu64""
+ufs_err_utrl_slot_busy(uint32_t slot) "UTRLDBR slot %"PRIu32" is busy"
+ufs_err_unsupport_register_offset(uint32_t offset) "Register offset 
0x%"PRIx32" is not yet supported"
+ufs_err_invalid_register_

[PATCH v5 3/3] hw/ufs: Support for UFS logical unit

2023-07-18 Thread Jeuk Kim
From: Jeuk Kim 

This commit adds support for ufs logical unit.
The LU handles processing for the SCSI command,
unit descriptor query request.

This commit enables the UFS device to process
IO requests.

Signed-off-by: Jeuk Kim 
---
 hw/ufs/lu.c  | 1439 ++
 hw/ufs/meson.build   |2 +-
 hw/ufs/trace-events  |   25 +
 hw/ufs/ufs.c |  252 ++-
 hw/ufs/ufs.h |   43 ++
 include/scsi/constants.h |1 +
 6 files changed, 1755 insertions(+), 7 deletions(-)
 create mode 100644 hw/ufs/lu.c

diff --git a/hw/ufs/lu.c b/hw/ufs/lu.c
new file mode 100644
index 00..ab40f42190
--- /dev/null
+++ b/hw/ufs/lu.c
@@ -0,0 +1,1439 @@
+/*
+ * QEMU UFS Logical Unit
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Written by Jeuk Kim 
+ *
+ * This code is licensed under the GNU GPL v2 or later.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qemu/memalign.h"
+#include "hw/scsi/scsi.h"
+#include "scsi/constants.h"
+#include "sysemu/block-backend.h"
+#include "qemu/cutils.h"
+#include "trace.h"
+#include "ufs.h"
+
+/*
+ * The code below handling SCSI commands is copied from hw/scsi/scsi-disk.c,
+ * with minor adjustments to make it work for UFS.
+ */
+
+#define SCSI_DMA_BUF_SIZE (128 * KiB)
+#define SCSI_MAX_INQUIRY_LEN 256
+#define SCSI_INQUIRY_DATA_SIZE 36
+#define SCSI_MAX_MODE_LEN 256
+
+typedef struct UfsSCSIReq {
+SCSIRequest req;
+/* Both sector and sector_count are in terms of BDRV_SECTOR_SIZE bytes.  */
+uint64_t sector;
+uint32_t sector_count;
+uint32_t buflen;
+bool started;
+bool need_fua_emulation;
+struct iovec iov;
+QEMUIOVector qiov;
+BlockAcctCookie acct;
+} UfsSCSIReq;
+
+static void ufs_scsi_free_request(SCSIRequest *req)
+{
+UfsSCSIReq *r = DO_UPCAST(UfsSCSIReq, req, req);
+
+qemu_vfree(r->iov.iov_base);
+}
+
+static void scsi_check_condition(UfsSCSIReq *r, SCSISense sense)
+{
+trace_ufs_scsi_check_condition(r->req.tag, sense.key, sense.asc,
+   sense.ascq);
+scsi_req_build_sense(&r->req, sense);
+scsi_req_complete(&r->req, CHECK_CONDITION);
+}
+
+static int ufs_scsi_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf,
+ uint32_t outbuf_len)
+{
+UfsHc *u = UFS(req->bus->qbus.parent);
+UfsLu *lu = DO_UPCAST(UfsLu, qdev, req->dev);
+uint8_t page_code = req->cmd.buf[2];
+int start, buflen = 0;
+
+if (outbuf_len < SCSI_INQUIRY_DATA_SIZE) {
+return -1;
+}
+
+outbuf[buflen++] = lu->qdev.type & 0x1f;
+outbuf[buflen++] = page_code;
+outbuf[buflen++] = 0x00;
+outbuf[buflen++] = 0x00;
+start = buflen;
+
+switch (page_code) {
+case 0x00: /* Supported page codes, mandatory */
+{
+trace_ufs_scsi_emulate_vpd_page_00(req->cmd.xfer);
+outbuf[buflen++] = 0x00; /* list of supported pages (this page) */
+if (u->params.serial) {
+outbuf[buflen++] = 0x80; /* unit serial number */
+}
+outbuf[buflen++] = 0x87; /* mode page policy */
+break;
+}
+case 0x80: /* Device serial number, optional */
+{
+int l;
+
+if (!u->params.serial) {
+trace_ufs_scsi_emulate_vpd_page_80_not_supported();
+return -1;
+}
+
+l = strlen(u->params.serial);
+if (l > SCSI_INQUIRY_DATA_SIZE) {
+l = SCSI_INQUIRY_DATA_SIZE;
+}
+
+trace_ufs_scsi_emulate_vpd_page_80(req->cmd.xfer);
+memcpy(outbuf + buflen, u->params.serial, l);
+buflen += l;
+break;
+}
+case 0x87: /* Mode Page Policy, mandatory */
+{
+trace_ufs_scsi_emulate_vpd_page_87(req->cmd.xfer);
+outbuf[buflen++] = 0x3f; /* apply to all mode pages and subpages */
+outbuf[buflen++] = 0xff;
+outbuf[buflen++] = 0; /* shared */
+outbuf[buflen++] = 0;
+break;
+}
+default:
+return -1;
+}
+/* done with EVPD */
+assert(buflen - start <= 255);
+outbuf[start - 1] = buflen - start;
+return buflen;
+}
+
+static int ufs_scsi_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf,
+uint32_t outbuf_len)
+{
+int buflen = 0;
+
+if (outbuf_len < SCSI_INQUIRY_DATA_SIZE) {
+return -1;
+}
+
+if (req->cmd.buf[1] & 0x1) {
+/* Vital product data */
+return ufs_scsi_emulate_vpd_page(req, outbuf, outbuf_len);
+}
+
+/* Standard INQUIRY data */
+if (req->cmd.buf[2] != 0) {
+return -1;
+}
+
+/* PAGE CODE == 0 */
+buflen = req->cmd.xfer;
+if (buflen > SCSI_MAX_INQUIRY_LEN) {
+buflen = SCSI_MAX_INQUIRY_LEN;
+}
+
+if (is_wlun(req->lun)) {
+outbuf[0] = TYPE_WLUN;
+} else {
+outbuf[0] = 0;
+}
+outbuf[1] = 0;
+
+strpadcpy((char *)&outbuf[16], 16, "QEMU UFS",

Re: [PATCH 04/10] hw/riscv: virt: Add PCIe HIGHMEM in memmap

2023-07-18 Thread Sunil V L
On Tue, Jul 18, 2023 at 05:05:12PM -0300, Daniel Henrique Barboza wrote:
> 
> 
> On 7/12/23 13:39, Sunil V L wrote:
> > PCIe High MMIO base is actually dynamic and fixed at
> > run time based on the RAM configured. Currently, this is
> > not part of the memmap and kept in separate static variable
> > in virt.c. However, ACPI code also needs this information
> > to populate DSDT. So, once the base is discovered, merge
> > this into the final memmap which can be used to create
> > ACPI tables later.
> > 
> > Signed-off-by: Sunil V L 
> > ---
> >   hw/riscv/virt.c | 31 ++-
> >   include/hw/riscv/virt.h |  9 +++--
> >   2 files changed, 37 insertions(+), 3 deletions(-)
> > 
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index f6067db8ec..7aee06f021 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -84,6 +84,22 @@ static const MemMapEntry virt_memmap[] = {
> >   static MemMapEntry virt_high_pcie_memmap;
> > +/*
> > + * virt_memmap doesn't include floating High Mem IO address entry. To 
> > enable
> > + * code organization in multiple files (ex: ACPI), it is better to have 
> > single
> > + * memmap which has complete information.
> > + *
> > + * VIRT_HIGH_PCIE_MMIO is always greater than the last memmap entry and 
> > hence
> > + * full_virt_memmap is capable of holding both virt_memmap and
> > + * VIRT_HIGH_PCIE_MMIO entry.
> > + *
> > + * The values for these floating entries will be updated when top of RAM is
> > + * discovered.
> > + */
> > +static MemMapEntry full_virt_memmap[] = {
> > +[VIRT_HIGH_PCIE_MMIO] = { 0x0, 0 },
> > +};
> > +
> >   #define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
> >   static PFlashCFI01 *virt_flash_create1(RISCVVirtState *s,
> > @@ -1444,7 +1460,20 @@ static void virt_machine_init(MachineState *machine)
> >   ROUND_UP(virt_high_pcie_memmap.base, 
> > virt_high_pcie_memmap.size);
> >   }
> > -s->memmap = virt_memmap;
> > +/*
> > + * Initialize the floating values in full memory map
> > + */
> > +full_virt_memmap[VIRT_HIGH_PCIE_MMIO].base = 
> > virt_high_pcie_memmap.base;
> > +full_virt_memmap[VIRT_HIGH_PCIE_MMIO].size = 
> > virt_high_pcie_memmap.size;
> > +
> > +s->memmap = full_virt_memmap;
> > +/*
> > + * Copy the base virt_memmap entries to full memmap
> > + */
> > +for (i = 0; i < ARRAY_SIZE(virt_memmap); i++) {
> > +s->memmap[i] = virt_memmap[i];
> > +}
> > +
> 
> This change here kind of convinces me of the point I made earlier in patch 2:
> we can simplify gpex_pcie_init() to use just the RISCVVirtState as a parameter
> and get everything else from it.
> 
> It's also something for a follow-up. As for this patch:
> 
> Reviewed-by: Daniel Henrique Barboza 
> 
Thanks Daniel. I agree. I can send another follow-up patch to simplify
gpex_pcie_init.

Thanks,
Sunil





Re: [PATCH QEMU v8 4/9] migration: Introduce dirty-limit capability

2023-07-18 Thread Yong Huang
On Tue, Jul 18, 2023 at 7:04 PM Markus Armbruster  wrote:

> Yong Huang  writes:
>
> > On Thu, Jul 13, 2023 at 8:44 PM Markus Armbruster 
> wrote:
> >
> >> ~hyman  writes:
> >>
> >> > From: Hyman Huang(黄勇) 
> >> >
> >> > Introduce migration dirty-limit capability, which can
> >> > be turned on before live migration and limit dirty
> >> > page rate durty live migration.
> >> >
> >> > Introduce migrate_dirty_limit function to help check
> >> > if dirty-limit capability enabled during live migration.
> >> >
> >> > Meanwhile, refactor vcpu_dirty_rate_stat_collect
> >> > so that period can be configured instead of hardcoded.
> >> >
> >> > dirty-limit capability is kind of like auto-converge
> >> > but using dirty limit instead of traditional cpu-throttle
> >> > to throttle guest down. To enable this feature, turn on
> >> > the dirty-limit capability before live migration using
> >> > migrate-set-capabilities, and set the parameters
> >> > "x-vcpu-dirty-limit-period", "vcpu-dirty-limit" suitably
> >> > to speed up convergence.
> >> >
> >> > Signed-off-by: Hyman Huang(黄勇) 
> >> > Acked-by: Peter Xu 
> >> > Reviewed-by: Juan Quintela 
> >>
> >> [...]
> >>
> >> > diff --git a/qapi/migration.json b/qapi/migration.json
> >> > index e43371955a..031832cde5 100644
> >> > --- a/qapi/migration.json
> >> > +++ b/qapi/migration.json
> >> > @@ -497,6 +497,15 @@
> >> >  # are present.  'return-path' capability must be enabled to use
> >> >  # it.  (since 8.1)
> >> >  #
> >> > +# @dirty-limit: If enabled, migration will use the dirty-limit
> >> > +# algorithm to throttle down guest instead of auto-converge
> >> > +# algorithm. This algorithm only works when vCPU's dirtyrate
> >>
> >> Two spaces after sentence-ending punctuation, please.
> >>
> >> "dirty rate" with a space, because that's how we spell it elsewhere.
> >>
> >> > +# greater than 'vcpu-dirty-limit', read processes in guest os
> >> > +# aren't penalized any more, so the algorithm can improve
> >> > +# performance of vCPU during live migration. This is an optional
> >> > +# performance feature and should not affect the correctness of
> the
> >> > +# existing auto-converge algorithm. (since 8.1)
> >> > +#
> >>
> >> I'm still confused.
> >>
> >> The text suggests there are two separate algorithms "to throttle down
> >> guest": "auto converge" and "dirty limit", and we get to pick one.
> >> Correct?
> >>
> > Yes, indeed !
> >
> >>
> >> If it is correct, then the last sentence feels redundant: picking
> >> another algorithm can't affect the algorithm we're *not* using.  What
> >> are you trying to express here?
> >>
> > What i want to express is that the new algorithm implementation does
> > not affect the original algorithm, leaving it in the comments seems
> > redundant indeed.  I'll drop this in the next version.
>
> Works for me.
>
> >> When do we use "auto converge", and when do we use "dirty limit"?
> >>
> >> What does the user really need to know about these algorithms?  Enough
> >> to pick one, I guess.  That means advantages and disadvantages of the
> >> two algorithms.  Which are?
> >
> > 1. The implementation of dirty-limit is based on dirty-ring, which is
> > qualified
> >to big systems with huge memories and can improve huge guest VM
> > responsiveness remarkably during live migration. As a consequence,
> > dirty-limit
> > is recommended on platforms with huge guest VMs as is the way with
> > dirty-ring.
> > 2. dirty-limit convergence algorithm does not affect the "read-process"
> in
> > guest
> >VM, so guest VM gains the equal read performance nearly as it runs on
> > host
> >during the live migration. As a result, dirty-limit is recommended if
> > the guest
> > VM requires a stable read performance.
> > The above explanation is about the recommendation of dirty-limit, please
> > review,
> > if it's ok, i'll place it in the comment of the dirty-limit capability.
>
> Yes, please.  But before that, I have still more questions.  "This
> algorithm only works when vCPU's dirtyrate greater than
> 'vcpu-dirty-limit'" is a condition: "FEATURE only works when CONDITION".
>
I failed to express my meaning again : ( .  "Throttle algo only works when
vCPU's  dirtyrate greater than 'vcpu-dirty-limit' " should change to
"vCPU throttle only works when vCPU's dirtyrate greater than
'vcpu-dirty-limit'".
Not the whole "algo" !

> What happens when the condition is not met?  How can the user ensure the
> condition is met?
>
> [...]
>
>

-- 
Best regards


[PULL 2/5] riscv/disas: Fix disas output of upper immediates

2023-07-18 Thread Alistair Francis
From: Christoph Müllner 

The GNU assembler produces the following output for instructions
with upper immediates:
2597auipc   a1,0x2
24b7lui s1,0x2
6409lui s0,0x2 # c.lui

The immediate operands of upper immediates are not shifted.

However, the QEMU disassembler prints them shifted:
2597  auipc   a1,8192
24b7  lui s1,8192
6409  lui s0,8192 # c.lui

The current implementation extracts the immediate bits and shifts the by 12,
so the internal representation of the immediate is the actual immediate.
However, the immediates are later printed using rv_fmt_rd_imm or
rv_fmt_rd_offset, which don't undo the shift.

Let's fix this by using specific output formats for instructions
with upper immediates, that take care of the shift.

Signed-off-by: Christoph Müllner 
Acked-by: Alistair Francis 
Message-Id: <20230711075051.1531007-1-christoph.muell...@vrull.eu>
Signed-off-by: Alistair Francis 
---
 disas/riscv.h |  2 ++
 disas/riscv.c | 19 ---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/disas/riscv.h b/disas/riscv.h
index 9cf901fc1e..8abb578b51 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -227,7 +227,9 @@ enum {
 #define rv_fmt_pred_succ  "O\tp,s"
 #define rv_fmt_rs1_rs2"O\t1,2"
 #define rv_fmt_rd_imm "O\t0,i"
+#define rv_fmt_rd_uimm"O\t0,Ui"
 #define rv_fmt_rd_offset  "O\t0,o"
+#define rv_fmt_rd_uoffset "O\t0,Uo"
 #define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
 #define rv_fmt_frd_rs1"O\t3,1"
 #define rv_fmt_frd_rs1_rs2"O\t3,1,2"
diff --git a/disas/riscv.c b/disas/riscv.c
index cd7b6e86a7..3873a69157 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -1135,8 +1135,8 @@ static const rv_comp_data rvcp_fsgnjx_q[] = {
 
 const rv_opcode_data rvi_opcode_data[] = {
 { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
-{ "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
-{ "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
+{ "lui", rv_codec_u, rv_fmt_rd_uimm, NULL, 0, 0, 0 },
+{ "auipc", rv_codec_u, rv_fmt_rd_uoffset, NULL, 0, 0, 0 },
 { "jal", rv_codec_uj, rv_fmt_rd_offset, rvcp_jal, 0, 0, 0 },
 { "jalr", rv_codec_i, rv_fmt_rd_rs1_offset, rvcp_jalr, 0, 0, 0 },
 { "beq", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_beq, 0, 0, 0 },
@@ -1382,7 +1382,7 @@ const rv_opcode_data rvi_opcode_data[] = {
   rv_op_addi },
 { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
   rv_op_addi, rv_op_addi, rvcd_imm_nz },
-{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui,
+{ "c.lui", rv_codec_ci_lui, rv_fmt_rd_uimm, NULL, rv_op_lui, rv_op_lui,
   rv_op_lui, rvcd_imm_nz },
 { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli,
   rv_op_srli, rv_op_srli, rvcd_imm_nz },
@@ -4694,6 +4694,19 @@ static void format_inst(char *buf, size_t buflen, size_t 
tab, rv_decode *dec)
 dec->pc + dec->imm);
 append(buf, tmp, buflen);
 break;
+case 'U':
+fmt++;
+snprintf(tmp, sizeof(tmp), "%d", dec->imm >> 12);
+append(buf, tmp, buflen);
+if (*fmt == 'o') {
+while (strlen(buf) < tab * 2) {
+append(buf, " ", buflen);
+}
+snprintf(tmp, sizeof(tmp), "# 0x%" PRIx64,
+dec->pc + dec->imm);
+append(buf, tmp, buflen);
+}
+break;
 case 'c': {
 const char *name = csr_name(dec->imm & 0xfff);
 if (name) {
-- 
2.40.1




[PULL 0/5] riscv-to-apply queue

2023-07-18 Thread Alistair Francis
The following changes since commit 361d5397355276e3007825cc17217c1e4d4320f7:

  Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into 
staging (2023-07-17 15:49:27 +0100)

are available in the Git repository at:

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

for you to fetch changes up to 32be32509987fbe42cf5c2fd3cea3c2ad6eae179:

  target/riscv: Fix LMUL check to use VLEN (2023-07-19 14:37:26 +1000)


Fourth RISC-V PR for 8.1

* Fix LMUL check to use VLEN
* Fix typo field in NUMA error_report
* check priv_ver before auto-enable zca/zcd/zcf
* Fix disas output of upper immediates
* tidy CPU firmware section


Christoph Müllner (1):
  riscv/disas: Fix disas output of upper immediates

Daniel Henrique Barboza (2):
  docs/system/target-riscv.rst: tidy CPU firmware section
  target/riscv/cpu.c: check priv_ver before auto-enable zca/zcd/zcf

Rob Bradford (1):
  target/riscv: Fix LMUL check to use VLEN

Zhao Liu (1):
  hw/riscv: Fix typo field in error_report

 docs/system/target-riscv.rst | 24 
 disas/riscv.h|  2 ++
 disas/riscv.c| 19 ---
 hw/riscv/numa.c  |  4 ++--
 target/riscv/cpu.c   |  3 ++-
 target/riscv/vector_helper.c |  4 ++--
 6 files changed, 40 insertions(+), 16 deletions(-)



[PULL 4/5] hw/riscv: Fix typo field in error_report

2023-07-18 Thread Alistair Francis
From: Zhao Liu 

"smp.cpus" means the number of online CPUs and "smp.max_cpus" means the
total number of CPUs.

riscv_numa_get_default_cpu_node_id() checks "smp.cpus" and the
"available CPUs" description in the next error message also indicates
online CPUs.

So report "smp.cpus" in error_report() instand of "smp.max_cpus".

Since "smp.cpus" is "unsigned int", use "%u".

Signed-off-by: Zhao Liu 
Reviewed-by: Alistair Francis 
Message-Id: <20230718080712.50-1-zhao1@linux.intel.com>
Signed-off-by: Alistair Francis 
---
 hw/riscv/numa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
index e0414d5b1b..d319aefb45 100644
--- a/hw/riscv/numa.c
+++ b/hw/riscv/numa.c
@@ -209,8 +209,8 @@ int64_t riscv_numa_get_default_cpu_node_id(const 
MachineState *ms, int idx)
 
 if (ms->numa_state->num_nodes > ms->smp.cpus) {
 error_report("Number of NUMA nodes (%d)"
- " cannot exceed the number of available CPUs (%d).",
- ms->numa_state->num_nodes, ms->smp.max_cpus);
+ " cannot exceed the number of available CPUs (%u).",
+ ms->numa_state->num_nodes, ms->smp.cpus);
 exit(EXIT_FAILURE);
 }
 if (ms->numa_state->num_nodes) {
-- 
2.40.1




[PULL 5/5] target/riscv: Fix LMUL check to use VLEN

2023-07-18 Thread Alistair Francis
From: Rob Bradford 

The previous check was failing with:

VLEN=128 ELEN = 64 SEW = 16 and LMUL = 1/8 which is a
valid combination.

Fix the check to allow valid combinations when VLEN is a multiple of
ELEN.

>From the specification:

"In general, the requirement is to support LMUL ≥ SEWMIN/ELEN, where
SEWMIN is the narrowest supported SEW value and ELEN is the widest
supported SEW value. In the standard extensions, SEWMIN=8. For standard
vector extensions with ELEN=32, fractional LMULs of 1/2 and 1/4 must be
supported. For standard vector extensions with ELEN=64, fractional LMULs
of 1/2, 1/4, and 1/8 must be supported." Elsewhere in the specification
it makes clear that VLEN>=ELEN.

>From inspection this new check allows:

VLEN=ELEN=64 1/2, 1/4, 1/8 for SEW >=8
VLEN=ELEN=32 1/2, 1/4 for SEW >=8

Fixes: d9b7609a1fb2 ("target/riscv: rvv-1.0: configure instructions")
Signed-off-by: Rob Bradford 
Reviewed-by: Weiwei Li 
Message-Id: <20230718131316.12283-2-rbradf...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index cfacf2ebba..4d06754826 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -43,9 +43,9 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong 
s1,
 xlen - 1 - R_VTYPE_RESERVED_SHIFT);
 
 if (lmul & 4) {
-/* Fractional LMUL. */
+/* Fractional LMUL - check LMUL * VLEN >= SEW */
 if (lmul == 4 ||
-cpu->cfg.elen >> (8 - lmul) < sew) {
+cpu->cfg.vlen >> (8 - lmul) < sew) {
 vill = true;
 }
 }
-- 
2.40.1




[PULL 1/5] docs/system/target-riscv.rst: tidy CPU firmware section

2023-07-18 Thread Alistair Francis
From: Daniel Henrique Barboza 

This is how the content of the "RISC-V CPU firmware" section is
displayed after the html is generated:

"When using the sifive_u or virt machine there are three different
firmware boot options: 1. -bios default - This is the default behaviour
if no -bios option is included. (...) 3. -bios  - Tells QEMU to
load the specified file as the firmware."

It's all in the same paragraph, in a numbered list, and no special
formatting for the options.

Tidy it a bit by adding line breaks between items and its description.
Remove the numbered list. And apply formatting for the options cited in
the middle of the text.

Cc: qemu-triv...@nongnu.org
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Message-Id: <20230712143728.383528-1-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 docs/system/target-riscv.rst | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
index 89a866e4f4..ba195f1518 100644
--- a/docs/system/target-riscv.rst
+++ b/docs/system/target-riscv.rst
@@ -76,11 +76,19 @@ RISC-V CPU firmware
 
 When using the ``sifive_u`` or ``virt`` machine there are three different
 firmware boot options:
-1. ``-bios default`` - This is the default behaviour if no -bios option
-is included. This option will load the default OpenSBI firmware automatically.
-The firmware is included with the QEMU release and no user interaction is
-required. All a user needs to do is specify the kernel they want to boot
-with the -kernel option
-2. ``-bios none`` - QEMU will not automatically load any firmware. It is up
-to the user to load all the images they need.
-3. ``-bios `` - Tells QEMU to load the specified file as the firmware.
+
+* ``-bios default``
+
+This is the default behaviour if no ``-bios`` option is included. This option
+will load the default OpenSBI firmware automatically. The firmware is included
+with the QEMU release and no user interaction is required. All a user needs to
+do is specify the kernel they want to boot with the ``-kernel`` option
+
+* ``-bios none``
+
+QEMU will not automatically load any firmware. It is up to the user to load all
+the images they need.
+
+* ``-bios ``
+
+Tells QEMU to load the specified file as the firmware.
-- 
2.40.1




[PULL 3/5] target/riscv/cpu.c: check priv_ver before auto-enable zca/zcd/zcf

2023-07-18 Thread Alistair Francis
From: Daniel Henrique Barboza 

Commit bd30559568 made changes in how we're checking and disabling
extensions based on env->priv_ver. One of the changes was to move the
extension disablement code to the end of realize(), being able to
disable extensions after we've auto-enabled some of them.

An unfortunate side effect of this change started to happen with CPUs
that has an older priv version, like sifive-u54. Starting on commit
2288a5ce43e5 we're auto-enabling zca, zcd and zcf if RVC is enabled,
but these extensions are priv version 1.12.0. When running a cpu that
has an older priv ver (like sifive-u54) the user is spammed with
warnings like these:

qemu-system-riscv64: warning: disabling zca extension for hart 
0x because privilege spec version does not match
qemu-system-riscv64: warning: disabling zcd extension for hart 
0x because privilege spec version does not match

The warnings are part of the code that disables the extension, but in this
case we're throwing user warnings for stuff that we enabled on our own,
without user intervention. Users are left wondering what they did wrong.

A quick 8.1 fix for this nuisance is to check the CPU priv spec before
auto-enabling zca/zcd/zcf. A more appropriate fix will include a more
robust framework that will account for both priv_ver and user choice
when auto-enabling/disabling extensions, but for 8.1 we'll make it do
with this simple check.

It's also worth noticing that this is the only case where we're
auto-enabling extensions based on a criteria (in this case RVC) that
doesn't match the priv spec of the extensions we're enabling. There's no
need for more 8.1 band-aids.

Cc: Conor Dooley 
Fixes: 2288a5ce43e5 ("target/riscv: add cfg properties for Zc* extension")
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Conor Dooley 
Message-Id: <20230717154141.60898-1-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9339c0241d..6b93b04453 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1225,7 +1225,8 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 }
 }
 
-if (riscv_has_ext(env, RVC)) {
+/* zca, zcd and zcf has a PRIV 1.12.0 restriction */
+if (riscv_has_ext(env, RVC) && env->priv_ver >= PRIV_VERSION_1_12_0) {
 cpu->cfg.ext_zca = true;
 if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
 cpu->cfg.ext_zcf = true;
-- 
2.40.1




Re: [PATCH QEMU v8 4/9] migration: Introduce dirty-limit capability

2023-07-18 Thread Markus Armbruster
Yong Huang  writes:

> On Tue, Jul 18, 2023 at 7:04 PM Markus Armbruster  wrote:
>
>> Yong Huang  writes:
>>
>> > On Thu, Jul 13, 2023 at 8:44 PM Markus Armbruster 
>> wrote:
>> >
>> >> ~hyman  writes:
>> >>
>> >> > From: Hyman Huang(黄勇) 
>> >> >
>> >> > Introduce migration dirty-limit capability, which can
>> >> > be turned on before live migration and limit dirty
>> >> > page rate durty live migration.
>> >> >
>> >> > Introduce migrate_dirty_limit function to help check
>> >> > if dirty-limit capability enabled during live migration.
>> >> >
>> >> > Meanwhile, refactor vcpu_dirty_rate_stat_collect
>> >> > so that period can be configured instead of hardcoded.
>> >> >
>> >> > dirty-limit capability is kind of like auto-converge
>> >> > but using dirty limit instead of traditional cpu-throttle
>> >> > to throttle guest down. To enable this feature, turn on
>> >> > the dirty-limit capability before live migration using
>> >> > migrate-set-capabilities, and set the parameters
>> >> > "x-vcpu-dirty-limit-period", "vcpu-dirty-limit" suitably
>> >> > to speed up convergence.
>> >> >
>> >> > Signed-off-by: Hyman Huang(黄勇) 
>> >> > Acked-by: Peter Xu 
>> >> > Reviewed-by: Juan Quintela 
>> >>
>> >> [...]
>> >>
>> >> > diff --git a/qapi/migration.json b/qapi/migration.json
>> >> > index e43371955a..031832cde5 100644
>> >> > --- a/qapi/migration.json
>> >> > +++ b/qapi/migration.json
>> >> > @@ -497,6 +497,15 @@
>> >> >  # are present.  'return-path' capability must be enabled to use
>> >> >  # it.  (since 8.1)
>> >> >  #
>> >> > +# @dirty-limit: If enabled, migration will use the dirty-limit
>> >> > +# algorithm to throttle down guest instead of auto-converge
>> >> > +# algorithm. This algorithm only works when vCPU's dirtyrate
>> >>
>> >> Two spaces after sentence-ending punctuation, please.
>> >>
>> >> "dirty rate" with a space, because that's how we spell it elsewhere.
>> >>
>> >> > +# greater than 'vcpu-dirty-limit', read processes in guest os
>> >> > +# aren't penalized any more, so the algorithm can improve
>> >> > +# performance of vCPU during live migration. This is an optional
>> >> > +# performance feature and should not affect the correctness of
>> the
>> >> > +# existing auto-converge algorithm. (since 8.1)
>> >> > +#
>> >>
>> >> I'm still confused.
>> >>
>> >> The text suggests there are two separate algorithms "to throttle down
>> >> guest": "auto converge" and "dirty limit", and we get to pick one.
>> >> Correct?
>> >>
>> > Yes, indeed !
>> >
>> >>
>> >> If it is correct, then the last sentence feels redundant: picking
>> >> another algorithm can't affect the algorithm we're *not* using.  What
>> >> are you trying to express here?
>> >>
>> > What i want to express is that the new algorithm implementation does
>> > not affect the original algorithm, leaving it in the comments seems
>> > redundant indeed.  I'll drop this in the next version.
>>
>> Works for me.
>>
>> >> When do we use "auto converge", and when do we use "dirty limit"?
>> >>
>> >> What does the user really need to know about these algorithms?  Enough
>> >> to pick one, I guess.  That means advantages and disadvantages of the
>> >> two algorithms.  Which are?
>> >
>> > 1. The implementation of dirty-limit is based on dirty-ring, which is
>> > qualified
>> >to big systems with huge memories and can improve huge guest VM
>> > responsiveness remarkably during live migration. As a consequence,
>> > dirty-limit
>> > is recommended on platforms with huge guest VMs as is the way with
>> > dirty-ring.
>> > 2. dirty-limit convergence algorithm does not affect the "read-process"
>> in
>> > guest
>> >VM, so guest VM gains the equal read performance nearly as it runs on
>> > host
>> >during the live migration. As a result, dirty-limit is recommended if
>> > the guest
>> > VM requires a stable read performance.
>> > The above explanation is about the recommendation of dirty-limit, please
>> > review,
>> > if it's ok, i'll place it in the comment of the dirty-limit capability.
>>
>> Yes, please.  But before that, I have still more questions.  "This
>> algorithm only works when vCPU's dirtyrate greater than
>> 'vcpu-dirty-limit'" is a condition: "FEATURE only works when CONDITION".
>>
> I failed to express my meaning again : ( .  "Throttle algo only works when
> vCPU's  dirtyrate greater than 'vcpu-dirty-limit' " should change to
> "vCPU throttle only works when vCPU's dirtyrate greater than
> 'vcpu-dirty-limit'".
> Not the whole "algo" !

Let me paraphrase to make sure I got it...  The vCPU is throttled as
needed to keep its dirty rate within the limit set with
set-vcpu-dirty-limit.  Correct?

What happens when I enable the dirty limit convergence algorithm without
setting a limit with set-vcpu-dirty-limit?

>> What happens when the condition is not met?  How can the user ensure the
>> condition is met?
>>
>> [...]
>>
>>




[PATCH] ppc: Add stub implementation of TRIG SPRs

2023-07-18 Thread Joel Stanley
Linux sets these to control cache flush behaviour on Power9. Supervisor
and hypervisor are allowed to write, and reads are noops.

Add implementations to avoid noisy messages when booting Linux under the
pseries machine with guest_errors enabled.

Reviewed-by: Nicholas Piggin 
Signed-off-by: Joel Stanley 
---
 target/ppc/cpu.h  |  2 ++
 target/ppc/cpu_init.c | 10 ++
 2 files changed, 12 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 25fac9577aa4..6826702ea658 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1897,7 +1897,9 @@ void ppc_compat_add_property(Object *obj, const char 
*name,
 #define SPR_PSSCR (0x357)
 #define SPR_440_INV0  (0x370)
 #define SPR_440_INV1  (0x371)
+#define SPR_TRIG1 (0x371)
 #define SPR_440_INV2  (0x372)
+#define SPR_TRIG2 (0x372)
 #define SPR_440_INV3  (0x373)
 #define SPR_440_ITV0  (0x374)
 #define SPR_440_ITV1  (0x375)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 02b7aad9b0e3..3b6ccb5ea4e6 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -5660,6 +5660,16 @@ static void register_power_common_book4_sprs(CPUPPCState 
*env)
  SPR_NOACCESS, SPR_NOACCESS,
  &spr_read_tfmr, &spr_write_tfmr,
  0x);
+spr_register_hv(env, SPR_TRIG1, "TRIG1",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_access_nop, &spr_write_generic,
+ &spr_access_nop, &spr_write_generic,
+ 0x);
+spr_register_hv(env, SPR_TRIG2, "TRIG2",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_access_nop, &spr_write_generic,
+ &spr_access_nop, &spr_write_generic,
+ 0x);
 #endif
 }
 
-- 
2.40.1




Re: Boot failure after QEMU's upgrade to OpenSBI v1.3 (was Re: [PATCH for-8.2 6/7] target/riscv: add 'max' CPU type)

2023-07-18 Thread Anup Patel
On Wed, Jul 19, 2023 at 7:03 AM Alistair Francis  wrote:
>
> On Sat, Jul 15, 2023 at 7:14 PM Atish Patra  wrote:
> >
> > On Fri, Jul 14, 2023 at 5:29 AM Conor Dooley  wrote:
> > >
> > > On Fri, Jul 14, 2023 at 11:19:34AM +0100, Conor Dooley wrote:
> > > > On Fri, Jul 14, 2023 at 10:00:19AM +0530, Anup Patel wrote:
> > > >
> > > > > > > OpenSBI v1.3
> > > > > > >_  _
> > > > > > >   / __ \  / |  _ \_   _|
> > > > > > >  | |  | |_ __   ___ _ __ | (___ | |_) || |
> > > > > > >  | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
> > > > > > >  | |__| | |_) |  __/ | | |) | |_) || |_
> > > > > > >   \/| .__/ \___|_| |_|_/|___/_|
> > > > > > > | |
> > > > > > > |_|
> > > > > > >
> > > > > > > init_coldboot: ipi init failed (error -1009)
> > > > > > >
> > > > > > > Just to note, because we use our own firmware that vendors in 
> > > > > > > OpenSBI
> > > > > > > and compiles only a significantly cut down number of files from 
> > > > > > > it, we
> > > > > > > do not use the fw_dynamic etc flow on our hardware. As a result, 
> > > > > > > we have
> > > > > > > not tested v1.3, nor do we have any immediate plans to change our
> > > > > > > platform firmware to vendor v1.3 either.
> > > > > > >
> > > > > > > I unless there's something obvious to you, it sounds like I will 
> > > > > > > need to
> > > > > > > go and bisect OpenSBI. That's a job for another day though, given 
> > > > > > > the
> > > > > > > time.
> > > > > > >
> > > > >
> > > > > The real issue is some CPU/HART DT nodes marked as disabled in the
> > > > > DT passed to OpenSBI 1.3.
> > > > >
> > > > > This issue does not exist in any of the DTs generated by QEMU but some
> > > > > of the DTs in the kernel (such as microchip and SiFive board DTs) have
> > > > > the E-core disabled.
> > > > >
> > > > > I had discovered this issue in a totally different context after the 
> > > > > OpenSBI 1.3
> > > > > release happened. This issue is already fixed in the latest OpenSBI 
> > > > > by the
> > > > > following commit c6a35733b74aeff612398f274ed19a74f81d1f37 ("lib: 
> > > > > utils:
> > > > > Fix sbi_hartid_to_scratch() usage in ACLINT drivers").
> > > >
> > > > Great, thanks Anup! I thought I had tested tip-of-tree too, but
> > > > obviously not.
> > > >
> > > > > I always assumed that Microchip hss.bin is the preferred BIOS for the
> > > > > QEMU microchip-icicle-kit machine but I guess that's not true.
> > > >
> > > > Unfortunately the HSS has not worked in QEMU for a long time, and while
> > > > I would love to fix it, but am pretty stretched for spare time to begin
> > > > with.
> > > > I usually just do direct kernel boots, which use the OpenSBI that comes
> > > > with QEMU, as I am sure you already know :)
> > > >
> > > > > At this point, you can either:
> > > > > 1) Use latest OpenSBI on QEMU microchip-icicle-kit machine
> > >
> > > I forgot to reply to this point, wondering what should be done with
> > > QEMU. Bumping to v1.3 in QEMU introduces a regression here, regardless
> > > of whether I can go and build a fixed version of OpenSBI.
> > >
> > FYI: The no-map fix went in OpenSBI v1.3. Without the upgrade, any
> > user using the latest kernel (> v6.4)
> > may hit those random linear map related issues (in hibernation or EFI
> > booting path).
> >
> > There are three possible scenarios:
> >
> > 1. Upgrade to OpenSBI v1.3: Any user of microchip-icicle-kit machine
> > or sifive fu540 machine users
> > may hit this issue if the device tree has the disabled hart (e core).
> > 2. No upgrade to OpenSBI v1.2. Any user using hibernation or UEFI may
> > have issues [1]
> > 3. Include a non-release version OpenSBI in Qemu with the fix as an 
> > exception.
> >
> > #3 probably deviates from policy and sets a bad precedent. So I am not
> > advocating for it though ;)
> > For both #1 & #2, the solution would be to use the latest OpenSBI in
> > -bios argument instead of the stock one.
> > I could be wrong but my guess is the number of users facing #2 would
> > be higher than #1.
>
> Thanks for that info Atish!
>
> We are stuck in a bad situation.
>
> The best solution would be if OpenSBI can release a 1.3.1, @Anup Patel
> do you think you could do that?

OpenSBI has a major number and minor number in the version but it does
not have release/patch number so best would be to treat OpenSBI vX.Y.Z
as bug fixes on-top-of OpenSBI vX.Y. In other words, supervisor software
won't be able to differentiate between OpenSBI vX.Y.Z and OpenSBI vX.Y
using sbi_get_impl_version().

There are only three commits between the ACLINT fix and OpenSBI v1.3
so as one-of case I will go ahead create OpenSBI v1.3.1 containing only
four commits on-top of OpenSBI v1.3

Does this sound okay ?

>
> Otherwise I think we should stick with OpenSBI 1.3. Considering that
> it fixes UEFI boot issues for the virt board (which would be the most
> used) it seems like a best call to make. People using the other boards
> ar

  1   2   3   >