[PATCH v13 6/8] multifd: multifd_send_sync_main now returns negative on error

2022-05-13 Thread Leonardo Bras
Even though multifd_send_sync_main() currently emits error_reports, it's
callers don't really check it before continuing.

Change multifd_send_sync_main() to return -1 on error and 0 on success.
Also change all it's callers to make use of this change and possibly fail
earlier.

(This change is important to next patch on  multifd zero copy
implementation, to make it sure an error in zero-copy flush does not go
unnoticed.

Signed-off-by: Leonardo Bras 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Peter Xu 
---
 migration/multifd.h |  2 +-
 migration/multifd.c | 10 ++
 migration/ram.c | 29 ++---
 3 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/migration/multifd.h b/migration/multifd.h
index 7d0effcb03..bcf5992945 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -20,7 +20,7 @@ int multifd_load_cleanup(Error **errp);
 bool multifd_recv_all_channels_created(void);
 bool multifd_recv_new_channel(QIOChannel *ioc, Error **errp);
 void multifd_recv_sync_main(void);
-void multifd_send_sync_main(QEMUFile *f);
+int multifd_send_sync_main(QEMUFile *f);
 int multifd_queue_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset);
 
 /* Multifd Compression flags */
diff --git a/migration/multifd.c b/migration/multifd.c
index 2a8c8570c3..15fb668e64 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -566,17 +566,17 @@ void multifd_save_cleanup(void)
 multifd_send_state = NULL;
 }
 
-void multifd_send_sync_main(QEMUFile *f)
+int multifd_send_sync_main(QEMUFile *f)
 {
 int i;
 
 if (!migrate_use_multifd()) {
-return;
+return 0;
 }
 if (multifd_send_state->pages->num) {
 if (multifd_send_pages(f) < 0) {
 error_report("%s: multifd_send_pages fail", __func__);
-return;
+return -1;
 }
 }
 for (i = 0; i < migrate_multifd_channels(); i++) {
@@ -589,7 +589,7 @@ void multifd_send_sync_main(QEMUFile *f)
 if (p->quit) {
 error_report("%s: channel %d has already quit", __func__, i);
 qemu_mutex_unlock(&p->mutex);
-return;
+return -1;
 }
 
 p->packet_num = multifd_send_state->packet_num++;
@@ -608,6 +608,8 @@ void multifd_send_sync_main(QEMUFile *f)
 qemu_sem_wait(&p->sem_sync);
 }
 trace_multifd_send_sync_main(multifd_send_state->packet_num);
+
+return 0;
 }
 
 static void *multifd_send_thread(void *opaque)
diff --git a/migration/ram.c b/migration/ram.c
index a2489a2699..5f5e37f64d 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2909,6 +2909,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 {
 RAMState **rsp = opaque;
 RAMBlock *block;
+int ret;
 
 if (compress_threads_save_setup()) {
 return -1;
@@ -2943,7 +2944,11 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 ram_control_before_iterate(f, RAM_CONTROL_SETUP);
 ram_control_after_iterate(f, RAM_CONTROL_SETUP);
 
-multifd_send_sync_main(f);
+ret =  multifd_send_sync_main(f);
+if (ret < 0) {
+return ret;
+}
+
 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
 qemu_fflush(f);
 
@@ -3052,7 +3057,11 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 out:
 if (ret >= 0
 && migration_is_setup_or_active(migrate_get_current()->state)) {
-multifd_send_sync_main(rs->f);
+ret = multifd_send_sync_main(rs->f);
+if (ret < 0) {
+return ret;
+}
+
 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
 qemu_fflush(f);
 ram_transferred_add(8);
@@ -3112,13 +3121,19 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
 ram_control_after_iterate(f, RAM_CONTROL_FINISH);
 }
 
-if (ret >= 0) {
-multifd_send_sync_main(rs->f);
-qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
-qemu_fflush(f);
+if (ret < 0) {
+return ret;
 }
 
-return ret;
+ret = multifd_send_sync_main(rs->f);
+if (ret < 0) {
+return ret;
+}
+
+qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
+qemu_fflush(f);
+
+return 0;
 }
 
 static void ram_save_pending(QEMUFile *f, void *opaque, uint64_t max_size,
-- 
2.36.1




Re: [PATCH v2] block/gluster: correctly set max_pdiscard

2022-05-13 Thread Fabian Ebner
Am 12.05.22 um 18:05 schrieb Stefano Garzarella:
> On Thu, May 12, 2022 at 05:44:13PM +0200, Stefano Garzarella wrote:
>> On Thu, May 12, 2022 at 12:30:48PM +0200, Fabian Ebner wrote:
>>> On 64-bit platforms, SIZE_MAX is too large for max_pdiscard, which is
>>
>> The main problem is that SIZE_MAX for an int64_t is a negative value.
>>

Yes, I should've stated that directly.

>>> int64_t, and the following assertion would be triggered:
>>> qemu-system-x86_64: ../block/io.c:3166: bdrv_co_pdiscard: Assertion
>>> `max_pdiscard >= bs->bl.request_alignment' failed.
>>>
>>> Fixes: 0c8022876f ("block: use int64_t instead of int in driver
>>> discard handlers")
>>> Cc: qemu-sta...@nongnu.org
>>> Signed-off-by: Fabian Ebner 
>>> ---
>>> block/gluster.c | 4 ++--
>>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/block/gluster.c b/block/gluster.c
>>> index 398976bc66..f711bf0bd6 100644
>>> --- a/block/gluster.c
>>> +++ b/block/gluster.c
>>> @@ -891,7 +891,7 @@ out:
>>> static void qemu_gluster_refresh_limits(BlockDriverState *bs, Error
>>> **errp)
>>> {
>>>    bs->bl.max_transfer = GLUSTER_MAX_TRANSFER;
>>> -    bs->bl.max_pdiscard = SIZE_MAX;
>>> +    bs->bl.max_pdiscard = MIN(SIZE_MAX, INT64_MAX);
>>
>> What would be the problem if we use INT64_MAX?
> 
> Okay, I just saw Eric's answer to v1 and I think this is right.
> 

Sorry for not mentioning the changes from v1.

> Please explain it in the commit message and also the initial problem
> that is SIZE_MAX on a 64-bit platform is a negative number for int64_t,
> so the assert fails.
> 

I'll try and improve the commit message for v3.

> Thanks,
> Stefano
> 
>> (I guess the intention of the original patch was to set the maximum
>> value in drivers that do not have a specific maximum).
>>
>> Or we can set to 0, since in block/io.c we have this code:
>>
>>    max_pdiscard = QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_pdiscard,
>> INT64_MAX),
>>   align);
>>    assert(max_pdiscard >= bs->bl.request_alignment);
>>
>> Where `max_pdiscard` is set to INT64_MAX (and aligned) if
>> bs->bl.max_pdiscard is 0.
>>
>>> }
>>>
>>> static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
>>> @@ -1304,7 +1304,7 @@ static coroutine_fn int
>>> qemu_gluster_co_pdiscard(BlockDriverState *bs,
>>>    GlusterAIOCB acb;
>>>    BDRVGlusterState *s = bs->opaque;
>>>
>>> -    assert(bytes <= SIZE_MAX); /* rely on max_pdiscard */
>>> +    assert(bytes <= MIN(SIZE_MAX, INT64_MAX)); /* rely on
>>> max_pdiscard */
>>
>> Can we use bs->bl.max_pdiscard directly here?
>>

Now I'm thinking that the assert is actually for checking that the value
can be passed to glfs_discard_async(), which takes a size_t for the
argument in question. So maybe it's best to keep assert(bytes <=
SIZE_MAX) as is?

>> Thanks,
>> Stefano
> 
> 
> 




Re: [PATCH 0/9] vfio/migration: Implement VFIO migration protocol v2

2022-05-13 Thread Cornelia Huck
On Thu, May 12 2022, Alex Williamson  wrote:

> On Thu, 12 May 2022 18:43:11 +0300
> Avihai Horon  wrote:
>
>> Hello,
>> 
>> Following VFIO migration protocol v2 acceptance in kernel, this series
>> implements VFIO migration according to the new v2 protocol and replaces
>> the now deprecated v1 implementation.
>
> Let's not bottleneck others waiting on a linux header file update on
> also incorporating v2 support.  In the short term we just need the
> first two patches here.
>
> Are there any objections to folding those patches together for the sake
> of bisection?  Thanks,
>
> Alex

I think folding the headers update and the fixup together makes a lot of
sense. And yes, I'd like to see it in QEMU quickly in order to unblock
other series.




[PATCH v13 8/8] multifd: Implement zero copy write in multifd migration (multifd-zero-copy)

2022-05-13 Thread Leonardo Bras
Implement zero copy send on nocomp_send_write(), by making use of QIOChannel
writev + flags & flush interface.

Change multifd_send_sync_main() so flush_zero_copy() can be called
after each iteration in order to make sure all dirty pages are sent before
a new iteration is started. It will also flush at the beginning and at the
end of migration.

Also make it return -1 if flush_zero_copy() fails, in order to cancel
the migration process, and avoid resuming the guest in the target host
without receiving all current RAM.

This will work fine on RAM migration because the RAM pages are not usually 
freed,
and there is no problem on changing the pages content between 
writev_zero_copy() and
the actual sending of the buffer, because this change will dirty the page and
cause it to be re-sent on a next iteration anyway.

A lot of locked memory may be needed in order to use multifd migration
with zero-copy enabled, so disabling the feature should be necessary for
low-privileged users trying to perform multifd migrations.

Signed-off-by: Leonardo Bras 
Reviewed-by: Peter Xu 
Reviewed-by: Daniel P. Berrangé 
---
 migration/multifd.h   |  2 ++
 migration/migration.c | 11 ++-
 migration/multifd.c   | 37 +++--
 migration/socket.c|  5 +++--
 4 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/migration/multifd.h b/migration/multifd.h
index bcf5992945..4d8d89e5e5 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -92,6 +92,8 @@ typedef struct {
 uint32_t packet_len;
 /* pointer to the packet */
 MultiFDPacket_t *packet;
+/* multifd flags for sending ram */
+int write_flags;
 /* multifd flags for each packet */
 uint32_t flags;
 /* size of the next packet that contains pages */
diff --git a/migration/migration.c b/migration/migration.c
index 4b6df2eb5e..31739b2af9 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1497,7 +1497,16 @@ static bool migrate_params_check(MigrationParameters 
*params, Error **errp)
 error_prepend(errp, "Invalid mapping given for block-bitmap-mapping: 
");
 return false;
 }
-
+#ifdef CONFIG_LINUX
+if (params->zero_copy_send &&
+(!migrate_use_multifd() ||
+ params->multifd_compression != MULTIFD_COMPRESSION_NONE ||
+ (params->tls_creds && *params->tls_creds))) {
+error_setg(errp,
+   "Zero copy only available for non-compressed non-TLS 
multifd migration");
+return false;
+}
+#endif
 return true;
 }
 
diff --git a/migration/multifd.c b/migration/multifd.c
index 2541cd2322..9282ab6aa4 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -569,6 +569,7 @@ void multifd_save_cleanup(void)
 int multifd_send_sync_main(QEMUFile *f)
 {
 int i;
+bool flush_zero_copy;
 
 if (!migrate_use_multifd()) {
 return 0;
@@ -579,6 +580,20 @@ int multifd_send_sync_main(QEMUFile *f)
 return -1;
 }
 }
+
+/*
+ * When using zero-copy, it's necessary to flush the pages before any of
+ * the pages can be sent again, so we'll make sure the new version of the
+ * pages will always arrive _later_ than the old pages.
+ *
+ * Currently we achieve this by flushing the zero-page requested writes
+ * per ram iteration, but in the future we could potentially optimize it
+ * to be less frequent, e.g. only after we finished one whole scanning of
+ * all the dirty bitmaps.
+ */
+
+flush_zero_copy = migrate_use_zero_copy_send();
+
 for (i = 0; i < migrate_multifd_channels(); i++) {
 MultiFDSendParams *p = &multifd_send_state->params[i];
 
@@ -600,6 +615,17 @@ int multifd_send_sync_main(QEMUFile *f)
 ram_counters.transferred += p->packet_len;
 qemu_mutex_unlock(&p->mutex);
 qemu_sem_post(&p->sem);
+
+if (flush_zero_copy && p->c) {
+int ret;
+Error *err = NULL;
+
+ret = qio_channel_flush(p->c, &err);
+if (ret < 0) {
+error_report_err(err);
+return -1;
+}
+}
 }
 for (i = 0; i < migrate_multifd_channels(); i++) {
 MultiFDSendParams *p = &multifd_send_state->params[i];
@@ -684,8 +710,8 @@ static void *multifd_send_thread(void *opaque)
 p->iov[0].iov_base = p->packet;
 }
 
-ret = qio_channel_writev_all(p->c, p->iov, p->iovs_num,
- &local_err);
+ret = qio_channel_writev_full_all(p->c, p->iov, p->iovs_num, NULL,
+  0, p->write_flags, &local_err);
 if (ret != 0) {
 break;
 }
@@ -913,6 +939,13 @@ int multifd_save_setup(Error **errp)
 /* We need one extra place for the packet header */
 p->iov = g_new0(struct iovec, page_count + 1);
 p->normal = g_new0(ram_addr_t, page_count);
+
+if (migrate_use

Re: [PATCH] qga-vss: Add auto generated headers to dependencies

2022-05-13 Thread Paolo Bonzini
Queued, thanks.

Paolo




Re: [PATCH] qga-vss: Use a proper function for free memory

2022-05-13 Thread Paolo Bonzini
Queued, thanks.

Paolo




Re: [PATCH v5 3/4] vdpa: add vdpa-dev support

2022-05-13 Thread Stefano Garzarella

On Fri, May 13, 2022 at 10:17:41AM +0800, Longpeng (Mike, Cloud Infrastructure 
Service Product Dept.) wrote:



在 2022/5/12 22:36, Stefano Garzarella 写道:

On Thu, May 12, 2022 at 02:21:02PM +0800, Longpeng(Mike) wrote:

From: Longpeng 

Supports vdpa-dev, we can use the deivce directly:

-M microvm -m 512m -smp 2 -kernel ... -initrd ... -device \
vhost-vdpa-device,vhostdev=/dev/vhost-vdpa-x

Signed-off-by: Longpeng 
---
hw/virtio/Kconfig    |   5 +
hw/virtio/meson.build    |   1 +
hw/virtio/vdpa-dev.c | 377 +++
include/hw/virtio/vdpa-dev.h |  43 
4 files changed, 426 insertions(+)
create mode 100644 hw/virtio/vdpa-dev.c
create mode 100644 include/hw/virtio/vdpa-dev.h

diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index c144d42f9b..724eb58a32 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -68,3 +68,8 @@ config VHOST_USER_RNG
    bool
    default y
    depends on VIRTIO && VHOST_USER
+
+config VHOST_VDPA_DEV
+    bool
+    default y
+    depends on VIRTIO && VHOST_VDPA && LINUX
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 67dc77e00f..8f6f86db71 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -29,6 +29,7 @@ virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', 
if_true: files('vhost-user-i2c.c'))
virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 
'CONFIG_VHOST_USER_I2C'], if_true: files('vhost-user-i2c-pci.c'))
virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: 
files('vhost-user-rng.c'))
virtio_ss.add(when: ['CONFIG_VHOST_USER_RNG', 
'CONFIG_VIRTIO_PCI'], if_true: files('vhost-user-rng-pci.c'))
+virtio_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: 
files('vdpa-dev.c'))


virtio_pci_ss = ss.source_set()
virtio_pci_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: 
files('vhost-vsock-pci.c'))

diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
new file mode 100644
index 00..56597c881a
--- /dev/null
+++ b/hw/virtio/vdpa-dev.c
@@ -0,0 +1,377 @@
+/*
+ * Vhost Vdpa Device
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights 
Reserved.

+ *
+ * Authors:
+ *   Longpeng 
+ *
+ * Largely based on the "vhost-user-blk-pci.c" and 
"vhost-user-blk.c" implemented by:

+ *   Changpeng Liu 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 
2 or later.

+ * See the COPYING.LIB file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include 
+#include 
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/cutils.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-access.h"
+#include "hw/virtio/vdpa-dev.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
+
+static void
+vhost_vdpa_device_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+    /* Nothing to do */
+}
+
+static uint32_t
+vhost_vdpa_device_get_u32(int fd, unsigned long int cmd, Error **errp)
+{
+    uint32_t val = (uint32_t)-1;
+
+    if (ioctl(fd, cmd, &val) < 0) {
+    error_setg(errp, "vhost-vdpa-device: cmd 0x%lx failed: %s",
+   cmd, strerror(errno));
+    }
+
+    return val;
+}
+
+static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VhostVdpaDevice *v = VHOST_VDPA_DEVICE(vdev);
+    uint16_t max_queue_size;
+    struct vhost_virtqueue *vqs;
+    int i, ret;
+
+    if (!v->vhostdev) {
+    error_setg(errp, "vhost-vdpa-device: vhostdev are missing");
+    return;
+    }
+
+    v->vhostfd = qemu_open(v->vhostdev, O_RDWR, errp);
+    if (*errp) {
+    return;
+    }
+    v->vdpa.device_fd = v->vhostfd;
+
+    v->vdev_id = vhost_vdpa_device_get_u32(v->vhostfd,
+   
VHOST_VDPA_GET_DEVICE_ID, errp);

+    if (*errp) {
+    goto out;
+    }
+
+    max_queue_size = vhost_vdpa_device_get_u32(v->vhostfd,
+   
VHOST_VDPA_GET_VRING_NUM, errp);

+    if (*errp) {
+    goto out;
+    }
+
+    if (v->queue_size > max_queue_size) {
+    error_setg(errp, "vhost-vdpa-device: invalid queue_size: 
%u (max:%u)",

+   v->queue_size, max_queue_size);
+    goto out;
+    } else if (!v->queue_size) {
+    v->queue_size = max_queue_size;
+    }
+
+    v->num_queues = vhost_vdpa_device_get_u32(v->vhostfd,
+  
VHOST_VDPA_GET_VQS_COUNT, errp);

+    if (*errp) {
+    goto out;
+    }
+
+    if (!v->num_queues || v->num_queues > VIRTIO_QUEUE_MAX) {
+    error_setg(errp, "invalid number of virtqueues: %u (max:%u)",
+   v->num_queues, VIRTIO_QUEUE_MAX);
+    goto out;
+    }
+
+    v->dev.nvqs = v->num_queues;
+    vqs = g_new0(struct vhost_virtqueue, v->dev.nvqs);
+    v->dev.vqs = vqs;
+    v->dev.vq_index = 0;
+    v->dev.vq_index_end = v->d

Re: [PATCH 2/9] vfio: Fix compilation errors caused by VFIO migration v1 deprecation

2022-05-13 Thread Cornelia Huck
On Thu, May 12 2022, Alex Williamson  wrote:

> On Thu, 12 May 2022 18:43:13 +0300
> Avihai Horon  wrote:
>
>> @@ -767,9 +767,10 @@ static void vfio_migration_state_notifier(Notifier 
>> *notifier, void *data)
>>  case MIGRATION_STATUS_CANCELLED:
>>  case MIGRATION_STATUS_FAILED:
>>  bytes_transferred = 0;
>> -ret = vfio_migration_set_state(vbasedev,
>> -  ~(VFIO_DEVICE_STATE_SAVING | 
>> VFIO_DEVICE_STATE_RESUMING),
>> -  VFIO_DEVICE_STATE_RUNNING);
>> +ret = vfio_migration_set_state(
>> +vbasedev,
>> +~(VFIO_DEVICE_STATE_V1_SAVING | VFIO_DEVICE_STATE_V1_RESUMING),
>> +VFIO_DEVICE_STATE_V1_RUNNING);
>
> Yikes!  Please follow the line wrapping used elsewhere.  There's no need
> to put the first arg on a new line and subsequent wrapped lines should
> be indented to match the previous line, or at least to avoid wrapping
> itself.  Here we can use something like:
>
> ret = vfio_migration_set_state(vbasedev,
>~(VFIO_DEVICE_STATE_V1_SAVING |
>  VFIO_DEVICE_STATE_V1_RESUMING),
>VFIO_DEVICE_STATE_V1_RUNNING);

FWIW, I'd prefer this variant as well.




Re: [PATCH 7/7] block: Add bdrv_co_pwrite_sync()

2022-05-13 Thread Paolo Bonzini

On 5/13/22 01:51, Alberto Faria wrote:

Also convert bdrv_pwrite_sync() to being implemented using
generated_co_wrapper.

Signed-off-by: Alberto Faria 
---
  block/io.c   | 5 +++--
  include/block/block-io.h | 8 ++--
  2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/block/io.c b/block/io.c
index ecd1c2a53c..19f9251c11 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1109,8 +1109,9 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags 
flags)
   *
   * Returns 0 on success, -errno in error cases.
   */
-int bdrv_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes,
- const void *buf, BdrvRequestFlags flags)
+int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
+ int64_t bytes, const void *buf,
+ BdrvRequestFlags flags)
  {
  int ret;
  IO_CODE();


Please change the implementation to use bdrv_co_ functions as well 
(bdrv_co_pwrite, bdrv_co_flush).


Some callers could be changed to bdrv_co_pwrite_sync, for example 
qcow2_shrink_reftable[1], but that can be done later (and preferably in 
a somewhat automated way).


Paolo

[1] qcow2_shrink_reftable could be a coroutine_fn because it is only 
called from qcow2_co_truncate



diff --git a/include/block/block-io.h b/include/block/block-io.h
index c81739ad16..ae90d1e588 100644
--- a/include/block/block-io.h
+++ b/include/block/block-io.h
@@ -49,8 +49,12 @@ int generated_co_wrapper bdrv_pread(BdrvChild *child, 
int64_t offset,
  int generated_co_wrapper bdrv_pwrite(BdrvChild *child, int64_t offset,
   int64_t bytes, const void *buf,
   BdrvRequestFlags flags);
-int bdrv_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes,
- const void *buf, BdrvRequestFlags flags);
+int generated_co_wrapper bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
+  int64_t bytes, const void *buf,
+  BdrvRequestFlags flags);
+int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
+ int64_t bytes, const void *buf,
+ BdrvRequestFlags flags);
  /*
   * Efficiently zero a region of the disk image.  Note that this is a regular
   * I/O request like read or write and should have a reasonable size.  This





Re: [PULL v2 18/24] ACPI ERST: support for ACPI ERST feature

2022-05-13 Thread Ani Sinha
On Thu, May 12, 2022 at 9:59 PM Peter Maydell  wrote:
>
> On Sun, 6 Feb 2022 at 09:38, Michael S. Tsirkin  wrote:
> >
> > From: Eric DeVolder 
> >
> > This implements a PCI device for ACPI ERST. This implements the
> > non-NVRAM "mode" of operation for ERST as it is supported by
> > Linux and Windows.
> >
> > Signed-off-by: Eric DeVolder 
> > Reviewed-by: Ani Sinha 
> > Message-Id: <1643402289-22216-6-git-send-email-eric.devol...@oracle.com>
> > Reviewed-by: Michael S. Tsirkin 
> > Signed-off-by: Michael S. Tsirkin 
> > ---
>
> Hi; Coverity points out a bug in this function (CID 1487125):
>
> > +static void check_erst_backend_storage(ERSTDeviceState *s, Error **errp)
> > +{
> > +ERSTStorageHeader *header;
> > +uint32_t record_size;
> > +
> > +header = memory_region_get_ram_ptr(s->hostmem_mr);
> > +s->header = header;
> > +
> > +/* Ensure pointer to header is 64-bit aligned */
> > +g_assert(QEMU_PTR_IS_ALIGNED(header, sizeof(uint64_t)));
> > +
> > +/*
> > + * Check if header is uninitialized; HostMemoryBackend inits to 0
> > + */
> > +if (le64_to_cpu(header->magic) == 0UL) {
> > +make_erst_storage_header(s);
> > +}
> > +
> > +/* Validity check record_size */
> > +record_size = le32_to_cpu(header->record_size);
> > +if (!(
> > +(record_size) && /* non zero */
> > +(record_size >= UEFI_CPER_RECORD_MIN_SIZE) &&
> > +(((record_size - 1) & record_size) == 0) && /* is power of 2 */
> > +(record_size >= 4096) /* PAGE_SIZE */
> > +)) {
> > +error_setg(errp, "ERST record_size %u is invalid", record_size);
>
> Here we check that record_size is sensible, including that it is
> not zero. But we forget to return early after error_setg(), which means...
>
> > +}
> > +
> > +/* Validity check header */
> > +if (!(
> > +(le64_to_cpu(header->magic) == ERST_STORE_MAGIC) &&
> > +((le32_to_cpu(header->storage_offset) % record_size) == 0) &&
> > +(le16_to_cpu(header->version) == 0x0100) &&
> > +(le16_to_cpu(header->reserved) == 0)
> > +)) {
> > +error_setg(errp, "ERST backend storage header is invalid");
> > +}
> > +
> > +/* Check storage_size against record_size */
> > +if (((s->storage_size % record_size) != 0) ||
>
> ...that we fall through to here, where we will divide by zero if
> record_size is 0.
>
> > + (record_size > s->storage_size)) {
> > +error_setg(errp, "ACPI ERST requires storage size be multiple of "
> > +"record size (%uKiB)", record_size);
> > +}
> > +
> > +/* Compute offset of first and last record storage slot */
> > +s->first_record_index = le32_to_cpu(header->storage_offset)
> > +/ record_size;
> > +s->last_record_index = (s->storage_size / record_size);
> > +}
> > +
>
> The fix is probably simply to add return statements after each error_setg()
> in the function.

Ah yes. OK I will send a patch as soon as I am able.



Re: [PATCH 5/7] block: Make 'bytes' param of bdrv_co_{pread, pwrite, preadv, pwritev}() an int64_t

2022-05-13 Thread Paolo Bonzini

On 5/13/22 01:51, Alberto Faria wrote:

For consistency with other I/O functions, and in preparation to
implement bdrv_{pread,pwrite}() using generated_co_wrapper.

unsigned int fits in int64_t, so all callers remain correct.


Reviewed-by: Paolo Bonzini 


Signed-off-by: Alberto Faria 
---
  block/coroutines.h   | 4 ++--
  include/block/block_int-io.h | 4 ++--
  2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/block/coroutines.h b/block/coroutines.h
index 830ecaa733..3f41238b33 100644
--- a/block/coroutines.h
+++ b/block/coroutines.h
@@ -91,11 +91,11 @@ int coroutine_fn blk_co_do_flush(BlockBackend *blk);
   */
  
  int generated_co_wrapper

-bdrv_preadv(BdrvChild *child, int64_t offset, unsigned int bytes,
+bdrv_preadv(BdrvChild *child, int64_t offset, int64_t bytes,
  QEMUIOVector *qiov, BdrvRequestFlags flags);
  
  int generated_co_wrapper

-bdrv_pwritev(BdrvChild *child, int64_t offset, unsigned int bytes,
+bdrv_pwritev(BdrvChild *child, int64_t offset, int64_t bytes,
   QEMUIOVector *qiov, BdrvRequestFlags flags);
  
  int generated_co_wrapper

diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
index d4d3bed783..d1a6970dc6 100644
--- a/include/block/block_int-io.h
+++ b/include/block/block_int-io.h
@@ -56,7 +56,7 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
  QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
  
  static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,

-int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
+int64_t offset, int64_t bytes, void *buf, BdrvRequestFlags flags)
  {
  QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
  IO_CODE();
@@ -65,7 +65,7 @@ static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
  }
  
  static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,

-int64_t offset, unsigned int bytes, const void *buf, BdrvRequestFlags 
flags)
+int64_t offset, int64_t bytes, const void *buf, BdrvRequestFlags flags)
  {
  QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
  IO_CODE();




Re: [PATCH 1/7] block: Add a 'flags' param to bdrv_{pread, pwrite, pwrite_sync}()

2022-05-13 Thread Paolo Bonzini

On 5/13/22 01:38, Alberto Faria wrote:

For consistency with other I/O functions, and in preparation to
implement them using generated_co_wrapper.

Callers were updated using this Coccinelle script:

 @@ expression child, offset, buf, bytes; @@
 - bdrv_pread(child, offset, buf, bytes)
 + bdrv_pread(child, offset, buf, bytes, 0)

 @@ expression child, offset, buf, bytes; @@
 - bdrv_pwrite(child, offset, buf, bytes)
 + bdrv_pwrite(child, offset, buf, bytes, 0)

 @@ expression child, offset, buf, bytes; @@
 - bdrv_pwrite_sync(child, offset, buf, bytes)
 + bdrv_pwrite_sync(child, offset, buf, bytes, 0)

Resulting overly-long lines were then fixed by hand.

Signed-off-by: Alberto Faria 
---
  block/blklogwrites.c |  4 +--
  block/bochs.c|  6 ++--
  block/cloop.c| 10 +++---
  block/crypto.c   |  4 +--
  block/dmg.c  | 24 +++---
  block/io.c   | 13 
  block/parallels-ext.c|  4 +--
  block/parallels.c| 12 +++
  block/qcow.c | 27 ---
  block/qcow2-bitmap.c | 14 
  block/qcow2-cache.c  |  7 ++--
  block/qcow2-cluster.c| 21 ++--
  block/qcow2-refcount.c   | 42 +++
  block/qcow2-snapshot.c   | 39 +++---
  block/qcow2.c| 44 
  block/qed.c  |  8 ++---
  block/vdi.c  | 10 +++---
  block/vhdx-log.c | 19 +--
  block/vhdx.c | 32 ++
  block/vmdk.c | 57 ++--
  block/vpc.c  | 19 ++-
  block/vvfat.c|  7 ++--
  include/block/block-io.h |  7 ++--
  tests/unit/test-block-iothread.c |  8 ++---
  24 files changed, 219 insertions(+), 219 deletions(-)

diff --git a/block/blklogwrites.c b/block/blklogwrites.c
index f7a251e91f..c5c021e6f8 100644
--- a/block/blklogwrites.c
+++ b/block/blklogwrites.c
@@ -108,7 +108,7 @@ static uint64_t 
blk_log_writes_find_cur_log_sector(BdrvChild *log,
  
  while (cur_idx < nr_entries) {

  int read_ret = bdrv_pread(log, cur_sector << sector_bits, &cur_entry,
-  sizeof(cur_entry));
+  sizeof(cur_entry), 0);
  if (read_ret < 0) {
  error_setg_errno(errp, -read_ret,
   "Failed to read log entry %"PRIu64, cur_idx);
@@ -190,7 +190,7 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict 
*options, int flags,
  log_sb.nr_entries = cpu_to_le64(0);
  log_sb.sectorsize = cpu_to_le32(BDRV_SECTOR_SIZE);
  } else {
-ret = bdrv_pread(s->log_file, 0, &log_sb, sizeof(log_sb));
+ret = bdrv_pread(s->log_file, 0, &log_sb, sizeof(log_sb), 0);
  if (ret < 0) {
  error_setg_errno(errp, -ret, "Could not read log superblock");
  goto fail_log;
diff --git a/block/bochs.c b/block/bochs.c
index 4d68658087..46d0f6a693 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -116,7 +116,7 @@ static int bochs_open(BlockDriverState *bs, QDict *options, 
int flags,
  return -EINVAL;
  }
  
-ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));

+ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs), 0);
  if (ret < 0) {
  return ret;
  }
@@ -151,7 +151,7 @@ static int bochs_open(BlockDriverState *bs, QDict *options, 
int flags,
  }
  
  ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,

- s->catalog_size * 4);
+ s->catalog_size * 4, 0);
  if (ret < 0) {
  goto fail;
  }
@@ -225,7 +225,7 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t 
sector_num)
  
  /* read in bitmap for current extent */

  ret = bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8),
- &bitmap_entry, 1);
+ &bitmap_entry, 1, 0);
  if (ret < 0) {
  return ret;
  }
diff --git a/block/cloop.c b/block/cloop.c
index b8c6d0eccd..208a58ebb1 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -78,7 +78,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, 
int flags,
  }
  
  /* read header */

-ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
+ret = bdrv_pread(bs->file, 128, &s->block_size, 4, 0);
  if (ret < 0) {
  return ret;
  }
@@ -104,7 +104,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, 
int flags,
  return -EINVAL;
  }
  
-ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);

+ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4, 0);
  if (ret < 0) {
  return ret;
  }
@@ -135,7 +135,7

Re: [PATCH 4/7] block: Make bdrv_co_pwrite() take a const buffer

2022-05-13 Thread Paolo Bonzini

On 5/13/22 01:51, Alberto Faria wrote:

It does not mutate the buffer.

Signed-off-by: Alberto Faria 
---
  include/block/block_int-io.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
index bb454200e5..d4d3bed783 100644
--- a/include/block/block_int-io.h
+++ b/include/block/block_int-io.h
@@ -65,7 +65,7 @@ static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
  }
  
  static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,

-int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
+int64_t offset, unsigned int bytes, const void *buf, BdrvRequestFlags 
flags)
  {
  QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
  IO_CODE();


Reviewed-by: Paolo Bonzini 



Re: [PATCH 2/7] block: Change bdrv_{pread, pwrite, pwrite_sync}() param order

2022-05-13 Thread Paolo Bonzini

On 5/13/22 01:38, Alberto Faria wrote:

Swap 'buf' and 'bytes' around for consistency with
bdrv_co_{pread,pwrite}(), and in preparation to implement these
functions using generated_co_wrapper.

Callers were updated using this Coccinelle script:

 @@ expression child, offset, buf, bytes, flags; @@
 - bdrv_pread(child, offset, buf, bytes, flags)
 + bdrv_pread(child, offset, bytes, buf, flags)

 @@ expression child, offset, buf, bytes, flags; @@
 - bdrv_pwrite(child, offset, buf, bytes, flags)
 + bdrv_pwrite(child, offset, bytes, buf, flags)

 @@ expression child, offset, buf, bytes, flags; @@
 - bdrv_pwrite_sync(child, offset, buf, bytes, flags)
 + bdrv_pwrite_sync(child, offset, bytes, buf, flags)

Resulting overly-long lines were then fixed by hand.

Signed-off-by: Alberto Faria 
---
  block/blklogwrites.c |  6 ++--
  block/bochs.c| 10 +++---
  block/cloop.c| 10 +++---
  block/crypto.c   |  4 +--
  block/dmg.c  | 26 +++
  block/io.c   | 12 +++
  block/parallels-ext.c|  6 ++--
  block/parallels.c| 10 +++---
  block/qcow.c | 34 +--
  block/qcow2-bitmap.c | 14 
  block/qcow2-cache.c  |  8 ++---
  block/qcow2-cluster.c| 22 ++---
  block/qcow2-refcount.c   | 56 +---
  block/qcow2-snapshot.c   | 48 +--
  block/qcow2.c| 47 ++-
  block/qed.c  |  8 ++---
  block/vdi.c  | 14 
  block/vhdx-log.c | 18 +-
  block/vhdx.c | 28 
  block/vmdk.c | 50 ++--
  block/vpc.c  | 22 ++---
  block/vvfat.c| 10 +++---
  include/block/block-io.h | 10 +++---
  tests/unit/test-block-iothread.c |  8 ++---
  24 files changed, 242 insertions(+), 239 deletions(-)

diff --git a/block/blklogwrites.c b/block/blklogwrites.c
index c5c021e6f8..e3c6c4039c 100644
--- a/block/blklogwrites.c
+++ b/block/blklogwrites.c
@@ -107,8 +107,8 @@ static uint64_t 
blk_log_writes_find_cur_log_sector(BdrvChild *log,
  struct log_write_entry cur_entry;
  
  while (cur_idx < nr_entries) {

-int read_ret = bdrv_pread(log, cur_sector << sector_bits, &cur_entry,
-  sizeof(cur_entry), 0);
+int read_ret = bdrv_pread(log, cur_sector << sector_bits,
+  sizeof(cur_entry), &cur_entry, 0);
  if (read_ret < 0) {
  error_setg_errno(errp, -read_ret,
   "Failed to read log entry %"PRIu64, cur_idx);
@@ -190,7 +190,7 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict 
*options, int flags,
  log_sb.nr_entries = cpu_to_le64(0);
  log_sb.sectorsize = cpu_to_le32(BDRV_SECTOR_SIZE);
  } else {
-ret = bdrv_pread(s->log_file, 0, &log_sb, sizeof(log_sb), 0);
+ret = bdrv_pread(s->log_file, 0, sizeof(log_sb), &log_sb, 0);
  if (ret < 0) {
  error_setg_errno(errp, -ret, "Could not read log superblock");
  goto fail_log;
diff --git a/block/bochs.c b/block/bochs.c
index 46d0f6a693..b76f34fe03 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -116,7 +116,7 @@ static int bochs_open(BlockDriverState *bs, QDict *options, 
int flags,
  return -EINVAL;
  }
  
-ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs), 0);

+ret = bdrv_pread(bs->file, 0, sizeof(bochs), &bochs, 0);
  if (ret < 0) {
  return ret;
  }
@@ -150,8 +150,8 @@ static int bochs_open(BlockDriverState *bs, QDict *options, 
int flags,
  return -ENOMEM;
  }
  
-ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,

- s->catalog_size * 4, 0);
+ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_size * 4,
+ s->catalog_bitmap, 0);
  if (ret < 0) {
  goto fail;
  }
@@ -224,8 +224,8 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t 
sector_num)
  (s->extent_blocks + s->bitmap_blocks));
  
  /* read in bitmap for current extent */

-ret = bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8),
- &bitmap_entry, 1, 0);
+ret = bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8), 1,
+ &bitmap_entry, 0);
  if (ret < 0) {
  return ret;
  }
diff --git a/block/cloop.c b/block/cloop.c
index 208a58ebb1..9a2334495e 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -78,7 +78,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, 
int flags,
  }
  
  /* read header */

-

Re: [PATCH 6/7] block: Implement bdrv_{pread, pwrite, pwrite_zeroes}() using generated_co_wrapper

2022-05-13 Thread Paolo Bonzini

On 5/13/22 01:51, Alberto Faria wrote:

Signed-off-by: Alberto Faria 
---
  block/io.c   | 41 
  include/block/block-io.h | 15 +--
  2 files changed, 9 insertions(+), 47 deletions(-)

diff --git a/block/io.c b/block/io.c
index 78a289192e..ecd1c2a53c 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1061,14 +1061,6 @@ static int bdrv_check_request32(int64_t offset, int64_t 
bytes,
  return 0;
  }
  
-int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,

-   int64_t bytes, BdrvRequestFlags flags)
-{
-IO_CODE();
-return bdrv_pwritev(child, offset, bytes, NULL,
-BDRV_REQ_ZERO_WRITE | flags);
-}


This is different from bdrv_co_pwrite_zeroes in that it does not clear 
BDRV_REQ_MAY_UNMAP; but that's a bugfix really.


It also doesn't call trace_bdrv_co_pwrite_zeroes, which is another bugfix.

Reviewed-by: Paolo Bonzini 


  /*
   * Completely zero out a block device with the help of bdrv_pwrite_zeroes.
   * The operation is sped up by checking the block status and only writing
@@ -,39 +1103,6 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags 
flags)
  }
  }
  
-/* See bdrv_pwrite() for the return codes */

-int bdrv_pread(BdrvChild *child, int64_t offset, int64_t bytes, void *buf,
-   BdrvRequestFlags flags)
-{
-QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
-IO_CODE();
-
-if (bytes < 0) {
-return -EINVAL;
-}
-
-return bdrv_preadv(child, offset, bytes, &qiov, flags);
-}
-
-/* Return no. of bytes on success or < 0 on error. Important errors are:
-  -EIO generic I/O error (may happen for all errors)
-  -ENOMEDIUM   No media inserted.
-  -EINVAL  Invalid offset or number of bytes
-  -EACCES  Trying to write a read-only device
-*/
-int bdrv_pwrite(BdrvChild *child, int64_t offset, int64_t bytes,
-const void *buf, BdrvRequestFlags flags)
-{
-QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
-IO_CODE();
-
-if (bytes < 0) {
-return -EINVAL;
-}
-
-return bdrv_pwritev(child, offset, bytes, &qiov, flags);
-}
-
  /*
   * Writes to the file and ensures that no writes are reordered across this
   * request (acts as a barrier)
diff --git a/include/block/block-io.h b/include/block/block-io.h
index 879221cebe..c81739ad16 100644
--- a/include/block/block-io.h
+++ b/include/block/block-io.h
@@ -39,13 +39,16 @@
   * to catch when they are accidentally called by the wrong API.
   */
  
-int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,

-   int64_t bytes, BdrvRequestFlags flags);
+int generated_co_wrapper bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
+int64_t bytes,
+BdrvRequestFlags flags);
  int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags);
-int bdrv_pread(BdrvChild *child, int64_t offset, int64_t bytes, void *buf,
-   BdrvRequestFlags flags);
-int bdrv_pwrite(BdrvChild *child, int64_t offset, int64_t bytes,
-const void *buf, BdrvRequestFlags flags);
+int generated_co_wrapper bdrv_pread(BdrvChild *child, int64_t offset,
+int64_t bytes, void *buf,
+BdrvRequestFlags flags);
+int generated_co_wrapper bdrv_pwrite(BdrvChild *child, int64_t offset,
+ int64_t bytes, const void *buf,
+ BdrvRequestFlags flags);
  int bdrv_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes,
   const void *buf, BdrvRequestFlags flags);
  /*





Re: [RFC PATCH qemu] spapr/docs: Add a few words about x-vof

2022-05-13 Thread Alexey Kardashevskiy




On 5/12/22 23:40, Daniel Henrique Barboza wrote:



On 5/12/22 00:10, Alexey Kardashevskiy wrote:



On 5/12/22 06:42, Daniel Henrique Barboza wrote:



On 5/6/22 02:51, Alexey Kardashevskiy wrote:

The alternative small firmware needs a few words of what it can and
absolutely cannot do; this adds those words.

Signed-off-by: Alexey Kardashevskiy 
---
  docs/system/ppc/pseries.rst | 28 
  1 file changed, 28 insertions(+)

diff --git a/docs/system/ppc/pseries.rst b/docs/system/ppc/pseries.rst
index d9b65ad4e850..4c98a94f9add 100644
--- a/docs/system/ppc/pseries.rst
+++ b/docs/system/ppc/pseries.rst
@@ -32,14 +32,42 @@ Missing devices
  Firmware
  
+The pSeries platform in QEMU comes with 2 firmwares:
+
  `SLOF `_ (Slimline Open Firmware) is an
  implementation of the `IEEE 1275-1994, Standard for Boot 
(Initialization

  Configuration) Firmware: Core Requirements and Practices
  `_.
+SLOF performs bus scanning, PCI resource allocation, provides the 
client

+interface to boot from block devices and network.
+
  QEMU includes a prebuilt image of SLOF which is updated when a 
more recent

  version is required.
+VOF (Virtual Open Firmware) is a minimalistic firmware to work with
+``-machine pseries,x-vof=on``. When enabled, the firmware acts as a 
slim
+shim and QEMU implements parts of the IEEE 1275 Open Firmware 
interface.

+
+VOF does not have device drivers, does not do PCI resource 
allocation and

+relies on ``-kernel`` used with Linux kernels recent enough (v5.4+)
+to PCI resource assignment. It is ideal to use with petitboot.
+
+Booting via ``-kernel`` supports the following:
++---+---+--+
+| kernel    | pseries,x-vof=off | pseries,x-vof=on |
++===+===+==+
+| vmlinux BE    | ✓ | ✓    |
++---+---+--+
+| vmlinux LE    | ✓ | ✓    |
++---+---+--+
+| zImage.pseries BE | x | ✓¹   |
++---+---+--+
+| zImage.pseries LE | ✓ | ✓    |
++---+---+--+


You need an empty line at the start and at the end of the table. 
Otherwise it'll

be rendered as regular text.


How do you build htmls from these btw?


Had to do this yesterday because I changed machines recently. In a 
Fedora 35

system I did this:


sudo dnf install python3-sphinx
sudo dnf install python-sphinx_rtd_theme-doc
pip install sphinx_rtd_theme



I only needed the last one, compiles htmls now. I was trying to figure 
out in Makefiles where is that "html" target and I just could not :)





(not sure if all steps are needed)

Then the generated docs will be under build/docs/manual .







+Notes:


I also don't believe you need the "Notes:" addendum here. It's clear 
that you're

making an observation about the zImage.pseries BE and x-vof=on case.


But only this combination needs kernel-addr=0, other images do not 
need that with SLOF or VOF.



I mentioned about the "Notes:" string. We can remove it and leave just the

+¹ must set kernel-addr=0


Since it's clear that you're making a note about that item in the table.








Everything else LGTM. If no one else has any comment, and you're ok 
with these

changes I mentioned, I can amend it myself with my R-b.


I'll probably repost after the other patch with kernel-addr is merged 
into your tree. Thanks,


I already picked it (just waiting some tests to finish). But feel free to
send a v2 if you want to play around generating the docs to see how
your patch looks like in the finished HTML.



Nah, the changes you made are fine so I am not planning on posting 
another version. Thanks for fixing it up.






Thanks,


Daniel








Thanks,


Daniel



+¹ must set kernel-addr=0
+
  Build directions
  




--
Alexey



Re: [PATCH v5 10/10] test: tpm-tis: Add Sysbus TPM-TIS device test

2022-05-13 Thread Igor Mammedov
On Thu, 12 May 2022 17:05:41 +0100
Peter Maydell  wrote:

> On Thu, 12 May 2022 at 16:59, Eric Auger  wrote:
> >
> > Hi Peter,
> >
> > On 5/12/22 15:08, Peter Maydell wrote:  
> > > On Thu, 5 Mar 2020 at 16:52, Eric Auger  wrote:  
> > >> The tests themselves are the same as the ISA device ones.
> > >> Only the main() changes as the "tpm-tis-device" device gets
> > >> instantiated. Also the base address of the device is not
> > >> 0xFED4 anymore but matches the base address of the
> > >> ARM virt platform bus.
> > >>
> > >> Signed-off-by: Eric Auger 
> > >> Reviewed-by: Stefan Berger   
> > > Hi Eric; the commit adding this test is from back in 2020, but I've
> > > just noticed something a bit odd about it:
> > >  
> > >> +args = g_strdup_printf(
> > >> +"-machine virt,gic-version=max -accel tcg "
> > >> +"-chardev socket,id=chr,path=%s "
> > >> +"-tpmdev emulator,id=dev,chardev=chr "
> > >> +"-device tpm-tis-device,tpmdev=dev",
> > >> +test.addr->u.q_unix.path);  
> > > This 'virt' command line doesn't specify a CPU type, so it
> > > will end up running with a Cortex-A15 (32-bit). Was
> > > that intended? Also, it will get a GICv3, which is a
> > > definitely odd combination with an A15, which was a GICv2 CPU...  
> > no it is not intended. I guess it should include "-cpu max" too
> > as arm-cpu-features.c does?  
> 
> Seems like a reasonable thing to set, yes.
> 
> > > I noticed this because I have some recent GICv3 patches which
> > > end up asserting if the GICv3 and a non-GICv3 CPU are used together,
> > > and this test case triggers them. Since the user can also cause
> > > an assert with that kind of command line I'm going to rework them
> > > (either to make the virt board fail cleanly or else to make the
> > > GICv3 code do something plausible even if the real hardware CPU
> > > nominally didn't have a GICv3). But maybe we should make this
> > > test case not use a non-standard combination anyway? (The meson
> > > conversion seems to have resulted in this test being run under
> > > qemu-system-arm as well, incidentally, so I guess we would want
> > > it to specify either 'a 64 bit CPU and GICv3' or 'a 32 bit
> > > CPU and GICv2' accordingly. Or limit the test to aarch64...)  
> > limiting the test to aarch64 may be enough?  
> 
> Mmm, if running the test under 'qemu-system-arm' isn't giving
> us interesting extra coverage we might as well save the CI cycles.

agreed,
we probably should limit all ARM tests in bios-tables-test to aarch64
'qemu-system-arm' doesn't give us anything extra on top of what aarch64
already does.

> 
> -- PMM
> 




Re: [PATCH 3/7] block: Make bdrv_{pread, pwrite}() return 0 on success

2022-05-13 Thread Paolo Bonzini

On 5/13/22 01:38, Alberto Faria wrote:


@@ -113,7 +113,7 @@ static ssize_t qcow2_crypto_hdr_read_func(QCryptoBlock 
*block, size_t offset,
 error_setg_errno(errp, -ret, "Could not read encryption header");
 return -1;
 }
-return ret;
+return buflen;
 }
 
 
@@ -174,7 +174,7 @@ static ssize_t qcow2_crypto_hdr_write_func(QCryptoBlock *block, size_t offset,

 error_setg_errno(errp, -ret, "Could not read encryption header");
 return -1;
 }
-return ret;
+return buflen;
 }
 
 static QDict*


As a follow-up you could change the calling convention of readfunc and 
writefunc in crypto/block-luks.c and crypto/block-qcow.c.


More in general, crypto/block-luks.c and crypto/block-qcow.c should be 
annotated for coroutine_fn.  Let's put it on the todo list.



@@ -88,6 +88,7 @@ static int vhdx_log_peek_hdr(BlockDriverState *bs, 
VHDXLogEntries *log,
 if (ret < 0) {
 goto exit;
 }
+ret = sizeof(VHDXLogEntryHeader);
 vhdx_log_entry_hdr_le_import(hdr);
 
 exit:


The callers only check the return code of vhdx_log_peek_hdr, 
vhdx_log_read_sectors, vhdx_log_write_sectors with ret < 0.  But looking 
at the callers:


- vhdx_log_read_desc propagates ret directly from a successful 
vhdx_log_read_sectors, but its callers don't care about which 
nonnegative result is returned


- vhdx_validate_log_entry might occasionally return ret directly from a 
successful vhdx_log_read_desc or vhdx_log_read_sectors, but 
vhdx_log_search, the caller of vhdx_validate_log_entry, also doesn't 
care about which nonnegative result is returned


- vhdx_log_flush only returns a successful return value from bdrv_flush

- vhdx_log_write propagates ret directly from a successful 
vhdx_log_write_sectors, but vhdx_log_write_and_flush only returns a 
successful return value from vhdx_log_flush


So (perhaps as a separate patch?) you can remove the three assignments 
of ret.



A possible cleanup is missing in vdi_co_pwritev:


ret = bdrv_pwrite(bs->file, offset * SECTOR_SIZE, base,
  n_sectors * SECTOR_SIZE);
}

return ret < 0 ? ret : 0;


ret is returned by either bdrv_pwrite or bdrv_co_writev, so it can be 
simplified to just "return ret".



As an aside, while reviewing I noticed this in qcow2_mark_dirty:

ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, 
incompatible_features),

  &val, sizeof(val));
if (ret < 0) {
return ret;
}
ret = bdrv_flush(bs->file->bs);
if (ret < 0) {
return ret;
}

I'm not sure if there are other occurrencies, perhaps you can try using 
Coccinelle to find them and change them to a bdrv_pwrite_sync.


But anyway:

Reviewed-by: Paolo Bonzini 

Paolo



Re: [RFC PATCH 2/9] tests: add "TESTS_PYTHON" variable to Makefile

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

This is a convenience feature: $(PYTHON) points to the Python executable
we were instructed to use by the configure script. We use that Python to
create a virtual environment with the "check-venv" target in
tests/Makefile.include.

$(TESTS_PYTHON) points to the Python executable belonging to the virtual
environment tied to the build. This Python executable is a symlink to
the binary used to create the venv, which will be the version provided
at configure time.

Using $(TESTS_PYTHON) therefore uses the $(PYTHON) executable, but with
paths modified to use packages installed to the venv.

Signed-off-by: John Snow 
---
  tests/Makefile.include | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index ec84b2ebc04..146aaa96a00 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -89,6 +89,7 @@ TARGETS=$(patsubst libqemu-%.fa, %, $(filter libqemu-%.fa, 
$(ninja-targets)))
  TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
  TESTS_VENV_REQ=$(SRC_PATH)/tests/requirements.txt
  TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
+TESTS_PYTHON=$(TESTS_VENV_DIR)/bin/python
  ifndef AVOCADO_TESTS
AVOCADO_TESTS=tests/avocado
  endif
@@ -108,7 +109,7 @@ $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
  $(PYTHON) -m venv $@, \
  VENV, $@)
$(call quiet-command, \
-$(TESTS_VENV_DIR)/bin/python -m pip -q install -r 
$(TESTS_VENV_REQ), \
+$(TESTS_PYTHON) -m pip -q install -r $(TESTS_VENV_REQ), \
  PIP, $(TESTS_VENV_REQ))
$(call quiet-command, touch $@)
  
@@ -126,7 +127,7 @@ FEDORA_31_DOWNLOAD=$(filter $(FEDORA_31_ARCHES),$(FEDORA_31_ARCHES_CANDIDATES))

  # download one specific Fedora 31 image
  get-vm-image-fedora-31-%: check-venv
$(call quiet-command, \
- $(TESTS_VENV_DIR)/bin/python -m avocado vmimage get \
+ $(TESTS_PYTHON) -m avocado vmimage get \
   --distro=fedora --distro-version=31 --arch=$*, \
"AVOCADO", "Downloading avocado tests VM image for $*")
  
@@ -135,7 +136,7 @@ get-vm-images: check-venv $(patsubst %,get-vm-image-fedora-31-%, $(FEDORA_31_DOW
  
  check-avocado: check-venv $(TESTS_RESULTS_DIR) get-vm-images

$(call quiet-command, \
-$(TESTS_VENV_DIR)/bin/python -m avocado \
+$(TESTS_PYTHON) -m avocado \
  --show=$(AVOCADO_SHOW) run --job-results-dir=$(TESTS_RESULTS_DIR) 
\
  $(if $(AVOCADO_TAGS),, --filter-by-tags-include-empty \
--filter-by-tags-include-empty-key) \


Reviewed-by: Paolo Bonzini 



Re: [RFC PATCH 3/9] tests: install "qemu" namespace package into venv

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

diff --git a/tests/requirements.txt b/tests/requirements.txt
index a21b59b4439..0ba561b6bdf 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -1,5 +1,6 @@
  # Add Python module requirements, one per line, to be installed
  # in the tests/venv Python virtual environment. For more info,
  # refer to: https://pip.pypa.io/en/stable/user_guide/#id1
+# Note that qemu.git/python/ is always implicitly installed.
  avocado-framework==88.1
  pycdlib==1.11.0


Any reason not to put ./python here?  But anyway,

Reviewed-by: Paolo Bonzini 

Paolo



Re: [RFC PATCH 4/9] tests: silence pip upgrade warnings during venv creation

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

diff --git a/tests/Makefile.include b/tests/Makefile.include
index dbbf1ba535b..dfb678d379f 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -109,11 +109,11 @@ $(TESTS_VENV_DIR): $(TESTS_VENV_REQ) 
$(SRC_PATH)/python/setup.cfg
 $(PYTHON) -m venv $@, \
 VENV, $@)
$(call quiet-command, \
-$(TESTS_PYTHON) -m pip -q install \
+$(TESTS_PYTHON) -m pip -q --disable-pip-version-check install \
 -e "$(SRC_PATH)/python/", PIP, "$(SRC_PATH)/python/")
$(call quiet-command, \
-$(TESTS_PYTHON) -m pip -q install -r $(TESTS_VENV_REQ), \
-PIP, $(TESTS_VENV_REQ))
+$(TESTS_PYTHON) -m pip -q --disable-pip-version-check install \
+-r $(TESTS_VENV_REQ), PIP, $(TESTS_VENV_REQ))
$(call quiet-command, touch $@)


Really nitpicking but I would have placed this change before adding the 
second invocation of pip. :)


Paolo



Re: [PATCH v3 34/43] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC)

2022-05-13 Thread yangxiaojuan


On 2022/5/10 上午1:56, Richard Henderson wrote:

On 5/9/22 04:38, yangxiaojuan wrote:
You are not considering CSR[0x420][49], which changes the format of 
this mapping.


Thanks very much, I will consider the mapping format by read 
iocsr[0x420][49] like this:

static uint64_t map_format(void)
{
 LoongArchCPU *cpu;
 CPULoongArchState *env;
 uint64_t val;

 cpu = LOONGARCH_CPU(current_cpu);
 env = &(cpu->env);

 val = address_space_ldq(&env->address_space_iocsr, 0x420,
  MEMTXATTRS_UNSPECIFIED, NULL);
 val &= 1 << 49;
 return val;
}


I'm not 100% sure how this "Other configuration control register" 
should be handled, but definitely not like this. 
Could we use the bitmapping as the default cpu or ip map format? Becaue 
we emulate iocsr[0x420] as a default value, and it does not support to 
write. We will add 'TOOD' logs and continue to modify them when using 
other routing methods later.

What do you think of this idea?

Thanks.
Xiaojuan


Re: [RFC PATCH 5/9] tests: use tests/venv to run basevm.py-based scripts

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

This patch co-opts the virtual environment being used by avocado tests
to also run the basevm.py tests. This is being done in preparation for
for the qemu.qmp package being removed from qemu.git.

As part of the change, remove any sys.path() hacks and treat "qemu" as a
normal third-party import.


That's already a good reason to do it, independent of qemu.qmp being 
removed from qemu.git.


Reviewed-by: Paolo Bonzini 


Signed-off-by: John Snow 
---
  tests/vm/Makefile.include | 13 +++--
  tests/vm/basevm.py|  6 +++---
  2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include
index ae91f5043e5..588bc999cc9 100644
--- a/tests/vm/Makefile.include
+++ b/tests/vm/Makefile.include
@@ -84,10 +84,11 @@ vm-clean-all:
  
  $(IMAGES_DIR)/%.img:	$(SRC_PATH)/tests/vm/% \

$(SRC_PATH)/tests/vm/basevm.py \
-   $(SRC_PATH)/tests/vm/Makefile.include
+   $(SRC_PATH)/tests/vm/Makefile.include \
+   check-venv
@mkdir -p $(IMAGES_DIR)
$(call quiet-command, \
-   $(PYTHON) $< \
+   $(TESTS_PYTHON) $< \
$(if $(V)$(DEBUG), --debug) \
$(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \
$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
@@ -101,9 +102,9 @@ $(IMAGES_DIR)/%.img:$(SRC_PATH)/tests/vm/% \
  
  
  # Build in VM $(IMAGE)

-vm-build-%: $(IMAGES_DIR)/%.img
+vm-build-%: $(IMAGES_DIR)/%.img check-venv
$(call quiet-command, \
-   $(PYTHON) $(SRC_PATH)/tests/vm/$* \
+   $(TESTS_PYTHON) $(SRC_PATH)/tests/vm/$* \
$(if $(V)$(DEBUG), --debug) \
$(if $(DEBUG), --interactive) \
$(if $(J),--jobs $(J)) \
@@ -127,9 +128,9 @@ vm-boot-serial-%: $(IMAGES_DIR)/%.img
-device virtio-net-pci,netdev=vnet \
|| true
  
-vm-boot-ssh-%: $(IMAGES_DIR)/%.img

+vm-boot-ssh-%: $(IMAGES_DIR)/%.img check-venv
$(call quiet-command, \
-   $(PYTHON) $(SRC_PATH)/tests/vm/$* \
+   $(TESTS_PYTHON) $(SRC_PATH)/tests/vm/$* \
$(if $(J),--jobs $(J)) \
$(if $(V)$(DEBUG), --debug) \
$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 254e11c932b..d7d0413df35 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -18,9 +18,6 @@
  import logging
  import time
  import datetime
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.machine import QEMUMachine
-from qemu.utils import get_info_usernet_hostfwd_port, kvm_available
  import subprocess
  import hashlib
  import argparse
@@ -31,6 +28,9 @@
  import traceback
  import shlex
  
+from qemu.machine import QEMUMachine

+from qemu.utils import get_info_usernet_hostfwd_port, kvm_available
+
  SSH_KEY_FILE = os.path.join(os.path.dirname(__file__),
 "..", "keys", "id_rsa")
  SSH_PUB_KEY_FILE = os.path.join(os.path.dirname(__file__),





Re: [RFC PATCH 8/9] iotests: fix source directory location

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

  # called from the source tree
-self.source_iotests = os.getcwd()
+self.source_iotests = str(Path(__file__, '../').resolve())


'../' could be just '..', otherwise

Reviewed-by: Paolo Bonzini 

Paolo



Re: [RFC PATCH 0/9] tests: run python tests under the build/tests/venv environment

2022-05-13 Thread Daniel P . Berrangé
On Thu, May 12, 2022 at 08:06:00PM -0400, John Snow wrote:
> RFC: This is a very early, crude attempt at switching over to an
> external Python package dependency for QMP. This series does not
> actually make the switch in and of itself, but instead just switches to
> the paradigm of using a venv in general to install the QEMU python
> packages instead of using PYTHONPATH to load them from the source tree.
> 
> (By installing the package, we can process dependencies.)
> 
> I'm sending it to the list so I can show you some of what's ugly so far
> and my notes on how I might make it less ugly.
> 
> (1) This doesn't trigger venv creation *from* iotests, it merely prints
> a friendly error message if "make check-venv" has not been run
> first. Not the greatest.

So if we run the sequence

  mkdir build
  cd build
  ../configure
  make
  ./tests/qemu-iotests/check 001

It won't work anymore, until we 'make check-venv' (or simply
'make check') ?

I'm somewhat inclined to say that venv should be created
unconditionally by default. ie a plain 'make' should always
everything needed to be able to invoke the tests directly.

> (2) This isn't acceptable for SRPM builds, because it uses PyPI to fetch
> packages just-in-time. My thought is to use an environment variable like
> QEMU_CHECK_NO_INTERNET that changes the behavior of the venv setup
> process. We can use "--system-site-packages" as an argument to venv
> creation and "--no-index" as an argument to pip installation to achieve
> good behavior in SRPM building scenarios. It'd be up to the spec-writer
> to opt into that behavior.

I think I'd expect --system-site-packages to be the default behaviour.
We expect QEMU to be compatible with the packages available in the
distros that we're targetting. So if the dev has the python packages
installed from their distro, we should be using them preferentially.

This is similar to how we bundle slirp/capstone/etc, but will
preferentially use the distro version if it is available.

> (3) Using one venv for *all* tests means that avocado comes as a pre-req
> for iotests -- which adds avocado as a BuildRequires for the Fedora
> SRPM. That's probably not ideal. It may be better to model the test venv
> as something that can be created in stages: the "core" venv first, and
> the avocado packages only when needed.
> 
> You can see in these patches that I wasn't really sure how to tie the
> check-venv step as a dependency of 'check' or 'check-block', and it
> winds up feeling kind of hacky and fragile as a result.

See above, I'm inclined to say the venv should be created unconditionally

> (Patches 6 and 7 feel particularly fishy.)
> 
> What I think I would like to do is replace the makefile logic with a
> Python bootstrapping script. This will allow me to add in environment
> variable logic to accommodate #2 pretty easily. It will also allow
> iotests to call into the bootstrap script whenever it detects the venv
> isn't set up, which it needed to do anyway in order to print a
> user-friendly error message. Lastly, it will make it easier to create a
> "tiered" venv that layers in the avocado dependencies only as-needed,
> which avoids us having to bloat the SRPM build dependencies.

The tests is an area where we still have too much taking place in
Makefiles, as opposed to meson. Can we put a rule in
tests/meson.build to trigger the ven creation ? Gets us closer to
being able to run ninja without using make as a wrapper.

> In the end, I think that approach will:
> 
> - Allow us to run iotests without having to run a manual prep step
> - Keep additional SRPM deps to a minimum
> - Keep makefile hacks to a minimum
> 
> The only downside I am really frowning at is that I will have to
> replicate some "update the venv if it's outdated" logic that is usually
> handled by the Make system in the venv bootstrapper. Still, I think it's
> probably the only way to hit all of the requirements here without trying
> to concoct a fairly complex Makefile.

The only reason we need to update the venv is if a python dependancy
changes right ? If we're using system packages by default that's
a non-issue. If we're using the python-qemu.qmp as a git submodule,
we presumably only need to re-create the venv if we see that the
git submodule hash has changed. IOW, we don't need to worry about
tracking whether individual python deps are outdated.


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




Re: [RFC PATCH 9/9] iotests: use tests/venv for running tests

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

Essentially, this:

(A) adjusts the python binary to be the one found in the venv (which is
a symlink to the python binary chosen at configure time)

(B) adds a new VIRTUAL_ENV export variable

(C) changes PATH to front-load the venv binary directory.

If the venv directory isn't found, raise a friendly exception that tries
to give the human operator a friendly clue as to what's gone wrong. In
the very near future, I'd like to teach iotests how to fix this problem
entirely of its own volition, but that's a trick for a little later.

Signed-off-by: John Snow 
---
  tests/qemu-iotests/testenv.py | 24 +---
  1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 0007da3f06c..fd3720ed7e7 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -65,8 +65,9 @@ class TestEnv(ContextManager['TestEnv']):
  # lot of them. Silence pylint:
  # pylint: disable=too-many-instance-attributes
  
-env_variables = ['PYTHONPATH', 'TEST_DIR', 'SOCK_DIR', 'SAMPLE_IMG_DIR',

- 'PYTHON', 'QEMU_PROG', 'QEMU_IMG_PROG',
+env_variables = ['PYTHONPATH', 'VIRTUAL_ENV', 'PYTHON',
+ 'TEST_DIR', 'SOCK_DIR', 'SAMPLE_IMG_DIR',
+ 'QEMU_PROG', 'QEMU_IMG_PROG',
   'QEMU_IO_PROG', 'QEMU_NBD_PROG', 'QSD_PROG',
   'QEMU_OPTIONS', 'QEMU_IMG_OPTIONS',
   'QEMU_IO_OPTIONS', 'QEMU_IO_OPTIONS_NO_FMT',
@@ -98,6 +99,10 @@ def get_env(self) -> Dict[str, str]:
  if val is not None:
  env[v] = val
  
+env['PATH'] = os.pathsep.join((

+os.path.join(self.virtual_env, 'bin'),
+os.environ['PATH']
+))
  return env
  
  def init_directories(self) -> None:

@@ -107,13 +112,17 @@ def init_directories(self) -> None:
   SOCK_DIR
   SAMPLE_IMG_DIR
  """
-
-# Path where qemu goodies live in this source tree.
-qemu_srctree_path = Path(__file__, '../../../python').resolve()
+venv_path = Path(self.build_root, 'tests/venv/')
+if not venv_path.exists():
+raise FileNotFoundError(
+f"Virtual environment \"{venv_path!s}\" isn't found."
+" (Maybe you need to run 'make check-venv'"
+" from the build dir?)"
+)
+self.virtual_env: str = str(venv_path)
  
  self.pythonpath = os.pathsep.join(filter(None, (

  self.source_iotests,
-str(qemu_srctree_path),
  os.getenv('PYTHONPATH'),
  )))
  
@@ -138,7 +147,7 @@ def init_binaries(self) -> None:

   PYTHON (for bash tests)
   QEMU_PROG, QEMU_IMG_PROG, QEMU_IO_PROG, QEMU_NBD_PROG, QSD_PROG
  """
-self.python = sys.executable
+self.python: str = os.path.join(self.virtual_env, 'bin', 'python3')


Is this guaranteed even if, say, only a /usr/bin/python3.9 exists? 
os.path.basename(sys.executable) might be more weirdness-proof than 
'python3'.


Paolo



Re: [RFC PATCH 6/9] tests: add check-venv as a dependency of check and check-block

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

  meson, create the python venv for block tests.
+.PHONY: check-block
+check-block: check-venv
+   @echo  # Without some rule, this doesn't run at all. Why?
+
+
  # Consolidated targets
  
  .PHONY: check check-clean get-vm-images

-check:
+check: check-venv
+   @echo # ???
  


I think you need instead:

# The do-meson-check and do-meson-bench targets are defined in Makefile.mtest
do-meson-check do-meson-bench: check-venv

and I would even add "all" to the targets that create the virtual environment.

Paolo



Re: [RFC PATCH 1/9] python: update for mypy 0.950

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

typeshed (included in mypy) recently updated to improve the typing for
WriteTransport objects. I was working around this, but now there's a
version where I shouldn't work around it.

Unfortunately this creates some minor ugliness if I want to support both
pre- and post-0.950 versions. For now, for my sanity, just disable the
unused-ignores warning.

Signed-off-by: John Snow 


Whatever floats your boat :)

Reviewed-by: Paolo Bonzini 

Paolo



Re: [PATCH v3 34/43] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC)

2022-05-13 Thread yangxiaojuan



On 2022/5/12 上午9:58, maobibo wrote:


在 2022/5/11 22:14, Richard Henderson 写道:

On 5/11/22 02:54, yangxiaojuan wrote:

On 2022/5/10 上午1:56, Richard Henderson wrote:

+    case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1:
+    index = (offset - EXTIOI_IPMAP_START) >> 2;
+    s->ipmap[index] = val;
+    break;

Do you need to recompute the entire interrupt map when ipmap changes?


Sorry, could you explain it in more detail? i can not understand the meanning 
of 'the entire interrupt map'?

I mean, ipmap[*] and coremap[*] controls how isr[*] maps to the various cpus, 
as coreisr[*].  If either ipmap or coremap changes, do you need to re-compute 
coreisr[*] from the input isr[*]?

I think the interrupt has been handled by the core before set coremap or ipmap, 
and coreisr[*] also has been set and cleard by original core.
So,  the new mapped core need not  to update the coreisr[*].


Why do you believe that the core to which the interrupt is directed has 
interrupts enabled?  Why do you believe the core to which the interrupt is 
directed is the one that is changing the interrupt mapping?
I think there is no interrupt enable registers of percpu in extioi 
device. So, i think we need not to consider the core to which the 
interrupt is directed if has interrupts enabled.
If the core to which the interrupt is directed is diffrent from the core 
that is changing the mapping, Should we copy the status value of 
coreisr[old_core][irq_num] to coreisr[new_core][irq_num]?
Ip mapping could not affect coreisr[cpu][irq_num], Should we still need 
to update the interrupt?


Thanks.
xiaojuan

By my understanding, irq bit of coreisr will be set even if the interrupt is 
disabled on the core, interrupt has been posted to core already, only that it 
is not serviced by the core. After irq affinity is changed, new interrupt may 
arrived to new core, one interrupt will be serviced by old core and new core at 
the same time. However it is the problem of guest kernel, guest kernel system 
should disable the irq and wait until irq finishes to be serviced on the old 
core when irq affinity is changing.


I think your assumption is not correct.


r~





Re: [RFC PATCH 7/9] tests: add check-venv to build-tcg-disabled CI recipe

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

Signed-off-by: John Snow 
---
  .gitlab-ci.d/buildtest.yml | 1 +
  1 file changed, 1 insertion(+)

diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index 0aea7ab84c2..5c6201847f1 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -245,6 +245,7 @@ build-tcg-disabled:
  - make -j"$JOBS"
  - make check-unit
  - make check-qapi-schema
+- make check-venv
  - cd tests/qemu-iotests/
  - ./check -raw 001 002 003 004 005 008 009 010 011 012 021 025 032 033 048
  052 063 077 086 101 104 106 113 148 150 151 152 157 159 160 163


Reviewed-by: Paolo Bonzini 

(unless you add it to "all").

Paolo



[RFC PATCH v4 1/4] target/riscv: Add smstateen support

2022-05-13 Thread Mayuresh Chitale
Smstateen extension specifies a mechanism to close
the potential covert channels that could cause security issues.

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

Signed-off-by: Mayuresh Chitale 
---
 target/riscv/cpu.c  |   2 +
 target/riscv/cpu.h  |   4 +
 target/riscv/cpu_bits.h |  36 +++
 target/riscv/csr.c  | 210 
 target/riscv/machine.c  |  21 
 5 files changed, 273 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 25a4ba3e22..3be2c644f9 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -870,6 +870,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
+DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false),
 
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
 DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
@@ -1062,6 +1063,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char 
**isa_str, int max_str_len)
 ISA_EDATA_ENTRY(svinval, ext_svinval),
 ISA_EDATA_ENTRY(svnapot, ext_svnapot),
 ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
+ISA_EDATA_ENTRY(smstateen, ext_smstateen),
 };
 
 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index a55c918274..d6fdc63ff2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -327,6 +327,9 @@ struct CPUArchState {
 
 /* CSRs for execution enviornment configuration */
 uint64_t menvcfg;
+uint64_t mstateen[SMSTATEEN_MAX_COUNT];
+uint64_t hstateen[SMSTATEEN_MAX_COUNT];
+uint64_t sstateen[SMSTATEEN_MAX_COUNT];
 target_ulong senvcfg;
 uint64_t henvcfg;
 #endif
@@ -411,6 +414,7 @@ struct RISCVCPUConfig {
 bool ext_zhinxmin;
 bool ext_zve32f;
 bool ext_zve64f;
+bool ext_smstateen;
 
 uint32_t mvendorid;
 uint64_t marchid;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 4a55c6a709..2a3ef26d21 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -208,6 +208,12 @@
 /* Supervisor Configuration CSRs */
 #define CSR_SENVCFG 0x10A
 
+/* Supervisor state CSRs */
+#define CSR_SSTATEEN0   0x10C
+#define CSR_SSTATEEN1   0x10D
+#define CSR_SSTATEEN2   0x10E
+#define CSR_SSTATEEN3   0x10F
+
 /* Supervisor Trap Handling */
 #define CSR_SSCRATCH0x140
 #define CSR_SEPC0x141
@@ -257,6 +263,16 @@
 #define CSR_HENVCFG 0x60A
 #define CSR_HENVCFGH0x61A
 
+/* Hypervisor state CSRs */
+#define CSR_HSTATEEN0   0x60C
+#define CSR_HSTATEEN0H  0x61C
+#define CSR_HSTATEEN1   0x60D
+#define CSR_HSTATEEN1H  0x61D
+#define CSR_HSTATEEN2   0x60E
+#define CSR_HSTATEEN2H  0x61E
+#define CSR_HSTATEEN3   0x60F
+#define CSR_HSTATEEN3H  0x61F
+
 /* Virtual CSRs */
 #define CSR_VSSTATUS0x200
 #define CSR_VSIE0x204
@@ -304,6 +320,26 @@
 #define CSR_MENVCFG 0x30A
 #define CSR_MENVCFGH0x31A
 
+/* Machine state CSRs */
+#define CSR_MSTATEEN0   0x30C
+#define CSR_MSTATEEN0H  0x31C
+#define CSR_MSTATEEN1   0x30D
+#define CSR_MSTATEEN1H  0x31D
+#define CSR_MSTATEEN2   0x30E
+#define CSR_MSTATEEN2H  0x31E
+#define CSR_MSTATEEN3   0x30F
+#define CSR_MSTATEEN3H  0x31F
+
+/* Common defines for all smstateen */
+#define SMSTATEEN_MAX_COUNT 4
+#define SMSTATEEN0_CS   0
+#define SMSTATEEN0_FCSR 0
+#define SMSTATEEN0_IMSIC58
+#define SMSTATEEN0_AIA  59
+#define SMSTATEEN0_SVSLCT   60
+#define SMSTATEEN0_HSENVCFG 62
+#define SMSTATEEN_STATEN63
+
 /* Enhanced Physical Memory Protection (ePMP) */
 #define CSR_MSECCFG 0x747
 #define CSR_MSECCFGH0x757
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e144ce7135..fea5cdd178 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -247,6 +247,42 @@ static RISCVException hmode32(CPURISCVState *env, int 
csrno)
 
 }
 
+static RISCVException mstateen(CPURISCVState *env, int csrno)
+{
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return any(env, csrno);
+}
+
+static RISCVException hstateen(CPURISCVState *env, int csrno)
+{
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return hmode(env, csrno);
+}
+
+static RISCVException sstateen(CPURISCVState *env, int csrno)
+{
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return smode(env, csrno);
+}
+
 /* Checks if PointerMasking registers could be accessed */
 s

[RFC PATCH v4 0/4] RISC-V Smstateen support

2022-05-13 Thread Mayuresh Chitale
This series adds support for the Smstateen specification which provides
a mechanism plug potential covert channels which are opened by extensions
that add to processor state that may not get context-switched. Currently
access to AIA registers, *envcfg registers and floating point(fcsr) is
controlled via smstateen.

This series depends on the following series from Anup:
https://lists.nongnu.org/archive/html/qemu-riscv/2022-05/msg00139.html

Changes in v4:
- Fix build issue with riscv32/riscv64-linux-user targets

Changes in v3:
- Fix coding style issues
- Fix *stateen0h index calculation

Changes in v2:
- Make h/s/envcfg bits in m/h/stateen registers as writeable by default.

Mayuresh Chitale (4):
  target/riscv: Add smstateen support
  target/riscv: smstateen check for h/senvcfg
  target/riscv: smstateen check for fcsr
  target/riscv: smstateen check for AIA/IMSIC

 target/riscv/cpu.c  |   2 +
 target/riscv/cpu.h  |   4 +
 target/riscv/cpu_bits.h |  36 +++
 target/riscv/csr.c  | 555 +++-
 target/riscv/machine.c  |  21 ++
 5 files changed, 615 insertions(+), 3 deletions(-)

-- 
2.25.1




[RFC PATCH v4 3/4] target/riscv: smstateen check for fcsr

2022-05-13 Thread Mayuresh Chitale
If smstateen is implemented and sstateen0.fcsr is clear
then the floating point operations must return illegal
instruction exception.

Signed-off-by: Mayuresh Chitale 
---
 target/riscv/csr.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d4920b3fa4..5032e48517 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -77,6 +77,10 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 !RISCV_CPU(env_cpu(env))->cfg.ext_zfinx) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
+
+if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
+return smstateen_acc_ok(env, PRV_U, SMSTATEEN0_FCSR);
+}
 #endif
 return RISCV_EXCP_NONE;
 }
@@ -1700,6 +1704,10 @@ static RISCVException write_mstateen(CPURISCVState *env, 
int csrno,
(1UL << SMSTATEEN0_HSENVCFG);
 
 reg = &env->mstateen[csrno - CSR_MSTATEEN0];
+if (riscv_has_ext(env, RVF)) {
+wr_mask |= 1UL << SMSTATEEN0_FCSR;
+}
+
 write_smstateen(env, reg, wr_mask, new_val);
 
 return RISCV_EXCP_NONE;
@@ -1724,6 +1732,10 @@ static RISCVException write_mstateenh(CPURISCVState 
*env, int csrno,
 reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
 val = (uint64_t)new_val << 32;
 val |= *reg & 0x;
+if (riscv_has_ext(env, RVF)) {
+wr_mask |= 1UL << SMSTATEEN0_FCSR;
+}
+
 write_smstateen(env, reg, wr_mask, val);
 
 return RISCV_EXCP_NONE;
@@ -1745,6 +1757,10 @@ static RISCVException write_hstateen(CPURISCVState *env, 
int csrno,
(1UL << SMSTATEEN0_HSENVCFG);
 int index = csrno - CSR_HSTATEEN0;
 
+if (riscv_has_ext(env, RVF)) {
+wr_mask |= 1UL << SMSTATEEN0_FCSR;
+}
+
 reg = &env->hstateen[index];
 wr_mask &= env->mstateen[index];
 write_smstateen(env, reg, wr_mask, new_val);
@@ -1769,6 +1785,10 @@ static RISCVException write_hstateenh(CPURISCVState 
*env, int csrno,
 uint64_t wr_mask = (1UL << SMSTATEEN_STATEN) |
(1UL << SMSTATEEN0_HSENVCFG);
 
+if (riscv_has_ext(env, RVF)) {
+wr_mask |= 1UL << SMSTATEEN0_FCSR;
+}
+
 reg = &env->hstateen[index];
 val = (uint64_t)new_val << 32;
 val |= *reg & 0x;
@@ -1794,6 +1814,10 @@ static RISCVException write_sstateen(CPURISCVState *env, 
int csrno,
 int index = csrno - CSR_SSTATEEN0;
 bool virt = riscv_cpu_virt_enabled(env);
 
+if (riscv_has_ext(env, RVF)) {
+wr_mask |= 1UL << SMSTATEEN0_FCSR;
+}
+
 reg = &env->sstateen[index];
 if (virt) {
 wr_mask &= env->mstateen[index];
-- 
2.25.1




[RFC PATCH v4 2/4] target/riscv: smstateen check for h/senvcfg

2022-05-13 Thread Mayuresh Chitale
Accesses to henvcfg, henvcfgh and senvcfg are allowed
only if corresponding bit in mstateen0/hstateen0 is
enabled. Otherwise an illegal instruction trap is
generated.

Signed-off-by: Mayuresh Chitale 
---
 target/riscv/csr.c | 84 ++
 1 file changed, 78 insertions(+), 6 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fea5cdd178..d4920b3fa4 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -39,6 +39,37 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 }
 
 /* Predicates */
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int mode, int bit)
+{
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
+bool virt = riscv_cpu_virt_enabled(env);
+
+if (!cpu->cfg.ext_smstateen) {
+return RISCV_EXCP_NONE;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+if (!(env->mstateen[0] & 1UL << bit)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+if (virt) {
+if (!(env->hstateen[0] & 1UL << bit)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+}
+
+if (mode == PRV_U) {
+if (!(env->sstateen[0] & 1UL << bit)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
 static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -1557,6 +1588,13 @@ static RISCVException write_menvcfgh(CPURISCVState *env, 
int csrno,
 static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->senvcfg;
 return RISCV_EXCP_NONE;
 }
@@ -1565,15 +1603,27 @@ static RISCVException write_senvcfg(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
+RISCVException ret;
 
-env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
+ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
+env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
 return RISCV_EXCP_NONE;
 }
 
 static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->henvcfg;
 return RISCV_EXCP_NONE;
 }
@@ -1582,6 +1632,12 @@ static RISCVException write_henvcfg(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
 if (riscv_cpu_mxl(env) == MXL_RV64) {
 mask |= HENVCFG_PBMTE | HENVCFG_STCE;
@@ -1595,6 +1651,13 @@ static RISCVException write_henvcfg(CPURISCVState *env, 
int csrno,
 static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
  target_ulong *val)
 {
+RISCVException ret;
+
+ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+
 *val = env->henvcfg >> 32;
 return RISCV_EXCP_NONE;
 }
@@ -1604,9 +1667,14 @@ static RISCVException write_henvcfgh(CPURISCVState *env, 
int csrno,
 {
 uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
 uint64_t valh = (uint64_t)val << 32;
+RISCVException ret;
 
-env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
+ret = smstateen_acc_ok(env, PRV_S, SMSTATEEN0_HSENVCFG);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
+env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
 return RISCV_EXCP_NONE;
 }
 
@@ -1628,7 +1696,8 @@ static RISCVException write_mstateen(CPURISCVState *env, 
int csrno,
  target_ulong new_val)
 {
 uint64_t *reg;
-uint64_t wr_mask = 1UL << SMSTATEEN_STATEN;
+uint64_t wr_mask = (1UL << SMSTATEEN_STATEN) |
+   (1UL << SMSTATEEN0_HSENVCFG);
 
 reg = &env->mstateen[csrno - CSR_MSTATEEN0];
 write_smstateen(env, reg, wr_mask, new_val);
@@ -1649,7 +1718,8 @@ static RISCVException write_mstateenh(CPURISCVState *env, 
int csrno,
 {
 uint64_t *reg;
 uint64_t val;
-uint64_t wr_mask = 1UL << SMSTATEEN_STATEN;
+uint64_t wr_mask = (1UL << SMSTATEEN_STATEN) |
+   (1UL << SMSTATEEN0_HSENVCFG);
 
 reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
 val = (uint64_t)new_val << 32;
@@ -1671,7 +1741,8 @@ static RISCVException write_hstateen(CPURISCVState *env, 
int csrno,
   

[RFC PATCH v4 4/4] target/riscv: smstateen check for AIA/IMSIC

2022-05-13 Thread Mayuresh Chitale
If smstateen is implemented then accesses to AIA
registers CSRS, IMSIC CSRs and other IMSIC registers
is controlled by setting of corresponding bits in
mstateen/hstateen registers. Otherwise an illegal
instruction trap or virtual instruction trap is
generated.

Signed-off-by: Mayuresh Chitale 
---
 target/riscv/csr.c | 253 -
 1 file changed, 248 insertions(+), 5 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5032e48517..e73b93cd12 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -39,6 +39,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 }
 
 /* Predicates */
+#if !defined(CONFIG_USER_ONLY)
 static RISCVException smstateen_acc_ok(CPURISCVState *env, int mode, int bit)
 {
 CPUState *cs = env_cpu(env);
@@ -49,7 +50,6 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, 
int mode, int bit)
 return RISCV_EXCP_NONE;
 }
 
-#if !defined(CONFIG_USER_ONLY)
 if (!(env->mstateen[0] & 1UL << bit)) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
@@ -65,11 +65,57 @@ static RISCVException smstateen_acc_ok(CPURISCVState *env, 
int mode, int bit)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 }
-#endif
-
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException smstateen_aia_acc_ok(CPURISCVState *env, int csrno)
+{
+int bit, mode;
+
+switch (csrno) {
+case CSR_SSETEIPNUM:
+case CSR_SCLREIPNUM:
+case CSR_SSETEIENUM:
+case CSR_SCLREIENUM:
+case CSR_STOPEI:
+case CSR_VSSETEIPNUM:
+case CSR_VSCLREIPNUM:
+case CSR_VSSETEIENUM:
+case CSR_VSCLREIENUM:
+case CSR_VSTOPEI:
+case CSR_HSTATUS:
+mode = PRV_S;
+bit = SMSTATEEN0_IMSIC;
+break;
+
+case CSR_SIEH:
+case CSR_SIPH:
+case CSR_HVIPH:
+case CSR_HVICTL:
+case CSR_HVIPRIO1:
+case CSR_HVIPRIO2:
+case CSR_HVIPRIO1H:
+case CSR_HVIPRIO2H:
+case CSR_VSIEH:
+case CSR_VSIPH:
+mode = PRV_S;
+bit = SMSTATEEN0_AIA;
+break;
+
+case CSR_SISELECT:
+case CSR_VSISELECT:
+mode = PRV_S;
+bit = SMSTATEEN0_SVSLCT;
+break;
+
+default:
+return RISCV_EXCP_NONE;
+}
+
+return smstateen_acc_ok(env, mode, bit);
+}
+#endif
+
 static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -1130,6 +1176,13 @@ static int rmw_xiselect(CPURISCVState *env, int csrno, 
target_ulong *val,
 target_ulong new_val, target_ulong wr_mask)
 {
 target_ulong *iselect;
+RISCVException ret;
+
+/* Check if smstateen is enabled and this access is allowed */
+ret = smstateen_aia_acc_ok(env, csrno);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
 
 /* Translate CSR number for VS-mode */
 csrno = aia_xlate_vs_csrno(env, csrno);
@@ -1212,7 +1265,9 @@ static int rmw_xireg(CPURISCVState *env, int csrno, 
target_ulong *val,
 bool virt;
 uint8_t *iprio;
 int ret = -EINVAL;
-target_ulong priv, isel, vgein;
+target_ulong priv, isel, vgein = 0;
+CPUState *cs = env_cpu(env);
+RISCVCPU *cpu = RISCV_CPU(cs);
 
 /* Translate CSR number for VS-mode */
 csrno = aia_xlate_vs_csrno(env, csrno);
@@ -1241,11 +1296,20 @@ static int rmw_xireg(CPURISCVState *env, int csrno, 
target_ulong *val,
 };
 
 /* Find the selected guest interrupt file */
-vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
+if (virt) {
+if (!cpu->cfg.ext_smstateen ||
+(env->hstateen[0] & 1UL << SMSTATEEN0_IMSIC)) {
+vgein = get_field(env->hstatus, HSTATUS_VGEIN);
+}
+}
 
 if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) {
 /* Local interrupt priority registers not available for VS-mode */
 if (!virt) {
+if (priv == PRV_S && cpu->cfg.ext_smstateen &&
+!(env->hstateen[0] & 1UL << SMSTATEEN0_AIA)) {
+goto done;
+}
 ret = rmw_iprio(riscv_cpu_mxl_bits(env),
 isel, iprio, val, new_val, wr_mask,
 (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT);
@@ -1279,6 +1343,13 @@ static int rmw_xsetclreinum(CPURISCVState *env, int 
csrno, target_ulong *val,
 int ret = -EINVAL;
 bool set, pend, virt;
 target_ulong priv, isel, vgein, xlen, nval, wmask;
+RISCVException excp;
+
+/* Check if smstateen is enabled and this access is allowed */
+excp = smstateen_aia_acc_ok(env, csrno);
+if (excp != RISCV_EXCP_NONE) {
+return excp;
+}
 
 /* Translate CSR number for VS-mode */
 csrno = aia_xlate_vs_csrno(env, csrno);
@@ -1397,6 +1468,13 @@ static int rmw_xtopei(CPURISCVState *env, int csrno, 
target_ulong *val,
 bool virt;
 int ret = -EINVAL;
 target_ulong priv, vgein;
+RISCVException excp;
+
+/* Check if smstateen is enabled and this access is allowed */
+excp = smsta

Re: [RFC PATCH 0/9] tests: run python tests under the build/tests/venv environment

2022-05-13 Thread Paolo Bonzini

On 5/13/22 10:35, Daniel P. Berrangé wrote:

The tests is an area where we still have too much taking place in
Makefiles, as opposed to meson. Can we put a rule in
tests/meson.build to trigger the ven creation ? Gets us closer to
being able to run ninja without using make as a wrapper.


I don't think this is or even should be a goal, because we have multiple 
projects under the QEMU tree:


- the QEMU binaries proper (emulators, tools, etc.)

- the firmware (pc-bios/{vof,s390-ccw,optionrom} with sources, the rest 
as submodules)


- tests/tcg


Each of these has its own build system and it's not possible to unify 
them under a single meson-based build:


- tests/tcg supports cross compilation for a different target, and 
pc-bios/ firmware will soon follow suit (which is why these directories 
haven't been converted to Meson, even though patches exist)


- firmware outside pc-bios/ consists of many external projects each with 
its own build system; right now it is not even buildable except by magic 
invocations that no one really knows


On top of this, there's support for building Docker images for 
cross-compilation which obviously doesn't fit the Meson usecases either.


In other words, Meson is the build system for QEMU *executables* (and 
that's why tests for the QEMU executables are being moved from configure 
to meson), but not for QEMU as a whole.



So I don't expect configure and Make to disappear.  Meson is great at 
building a C program as big as QEMU; but QEMU is not just a C program, 
and isolating the C parts into Meson lets Make handle the rest of the 
complexity better than before, for example with cross compiled firmware 
support.


Likewise, we're now using "meson test" for "make check" and a custom 
runner for "make check-block"; but perhaps one day Avocado could replace 
both runners via custom Avocado resolvers (basically JSON emitters 
similar to Meson introspection data).  That of course depends on whether 
Avocado has feature parity with "meson test".


Paolo



[PATCH 2/5] target/riscv: Disable "G" by default

2022-05-13 Thread Tsukasa OI
Because "G" virtual extension expands to "IMAFD", we cannot separately
disable extensions like "F" or "D" without disabling "G".  Because all
"IMAFD" are enabled by default, it's harmless to disable "G" by default.

Signed-off-by: Tsukasa OI 
---
 target/riscv/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 00bf26ec8b..3ea68d5cd7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -812,7 +812,7 @@ static Property riscv_cpu_properties[] = {
 /* Defaults for standard extensions */
 DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
 DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
-DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, true),
+DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, false),
 DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true),
 DEFINE_PROP_BOOL("a", RISCVCPU, cfg.ext_a, true),
 DEFINE_PROP_BOOL("f", RISCVCPU, cfg.ext_f, true),
-- 
2.34.1




[PATCH 4/5] target/riscv: FP extension requirements

2022-05-13 Thread Tsukasa OI
QEMU allowed inconsistent configurations that made floating point
arithmetic effectively unusable.

This commit adds certain checks for consistent FP arithmetic:

-   F requires Zicsr
-   Zfinx requires Zicsr
-   Zfh/Zfhmin require F
-   D requires F
-   V requires D

Because F/D/Zicsr are enabled by default (and an error will not occur unless
we manually disable one or more of prerequisites), this commit just enforces
the user to give consistent combinations.

Signed-off-by: Tsukasa OI 
---
 target/riscv/cpu.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0854ca9103..5371b0fd17 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -610,6 +610,31 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 cpu->cfg.ext_ifencei = true;
 }
 
+if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
+error_setg(errp, "F extension requires Zicsr");
+return;
+}
+
+if (cpu->cfg.ext_zfinx && !cpu->cfg.ext_icsr) {
+error_setg(errp, "Zfinx extension requires Zicsr");
+return;
+}
+
+if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
+error_setg(errp, "Zfh/Zfhmin extensions require F extension");
+return;
+}
+
+if (cpu->cfg.ext_d && !cpu->cfg.ext_f) {
+error_setg(errp, "D extension requires F extension");
+return;
+}
+
+if (cpu->cfg.ext_v && !cpu->cfg.ext_d) {
+error_setg(errp, "V extension requires D extension");
+return;
+}
+
 if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
 cpu->cfg.ext_zhinxmin) {
 cpu->cfg.ext_zfinx = true;
-- 
2.34.1




[PATCH 5/5] target/riscv: Move/refactor ISA extension checks

2022-05-13 Thread Tsukasa OI
We should separate "check" and "configure" steps as possible.
This commit separates both steps except vector/Zfinx-related checks.

Signed-off-by: Tsukasa OI 
---
 target/riscv/cpu.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5371b0fd17..f654a6727f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -635,11 +635,23 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) {
+error_setg(errp, "Zve32f/Zve64f extensions require F extension");
+return;
+}
+
+/* Set the ISA extensions, checks should have happened above */
 if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
 cpu->cfg.ext_zhinxmin) {
 cpu->cfg.ext_zfinx = true;
 }
 
+if (cpu->cfg.ext_zfinx && !cpu->cfg.ext_f) {
+error_setg(errp,
+"Zfinx cannot be supported together with F extension");
+return;
+}
+
 if (cpu->cfg.ext_zk) {
 cpu->cfg.ext_zkn = true;
 cpu->cfg.ext_zkr = true;
@@ -663,7 +675,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 cpu->cfg.ext_zksh = true;
 }
 
-/* Set the ISA extensions, checks should have happened above */
 if (cpu->cfg.ext_i) {
 ext |= RVI;
 }
@@ -734,20 +745,9 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 set_vext_version(env, vext_version);
 }
-if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) {
-error_setg(errp, "Zve32f/Zve64f extension depends upon RVF.");
-return;
-}
 if (cpu->cfg.ext_j) {
 ext |= RVJ;
 }
-if (cpu->cfg.ext_zfinx && ((ext & (RVF | RVD)) || cpu->cfg.ext_zfh ||
-   cpu->cfg.ext_zfhmin)) {
-error_setg(errp,
-"'Zfinx' cannot be supported together with 'F', 'D', 
'Zfh',"
-" 'Zfhmin'");
-return;
-}
 
 set_misa(env, env->misa_mxl, ext);
 }
-- 
2.34.1




[PATCH 0/5] target/riscv: Enhanced ISA extension checks

2022-05-13 Thread Tsukasa OI
Hello,

This is another patchset for RISC-V ISA extension / feature handling.

Aside from coding style fix / refactoring patch (PATCH 1 and 5), this
patchset contains two changes:



1. "G" extension handling

1.A. "G" extension expansion (PATCH 3)

On ISA version 20190608 or later, "G" expands to "IMAFD_Zicsr_Zifencei",
not just "IMAFD" (this is because "Zicsr" and "Zifencei" extensions are
splitted from "I").  Because both "Zicsr" and "Zifencei" are enabled by
default, it should be safe to change "G" extension expansion.

1.B. Disable "G" by default (PATCH 2)

This seems quite odd but I have a good reason.  While "G" is enabled by
default, all "I", "M", "A", "F", "D", "Zicsr" and "Zifencei" are also
enabled by default, making default "G" expansion useless.

There's more.  If we want to change detailed configuration of a RV32/RV64
CPU and want to disable some, for example, "F" and "D", we must also
disable "G".  This is obviously bloat.

This doesn't work:
-cpu rv64,f=off,d=off

This does work (but bloat):
-cpu rv64,g=off,f=off,d=off

Disabling "G" suppresses such problem and mostly harmless, too.



2. Floating point arithmetic consistency (PATCH 4)

With -cpu option, we can configure details of RISC-V CPU emulated by QEMU.
However, we can set some invalid combinations that would make FP arithmetic
effectively unusable (and invalid on RISC-V ISA specification).

-   F requires Zicsr
-   Zfinx requires Zicsr
-   Zfh/Zfhmin require F
-   D requires F
-   V requires D

Reproducing this kind of problem requires manually disabling certain
extensions (because all "Zicsr", "F" and "D" are enabled by default).  So,
I consider that just making an error message (when unsatisfied) should be
enough, not implying related extensions like "zk*" properties.


Note that this checking only works on any, rv32 and rv64.  On other CPUs
(for example, sifive-u54), it sets nonzero `misa' value on corresponding
`set_misa' call (c.f. in rv64_sifive_u_cpu_init in target/riscv/cpu.c) and
consistency checks are skipped (because nonzero `misa' value is set prior
to RISC-V CPU realization process).

I think we generally use generic "rv32" or "rv64" on heavy customizing so I
don't think this is not a big problem.  Still, we could fix this later
(e.g. by setting properties on CPU init function or by checking some
consistency problems even if previously-set `misa' is nonzero).




Tsukasa OI (5):
  target/riscv: Fix "G" extension expansion typing
  target/riscv: Disable "G" by default
  target/riscv: Change "G" expansion
  target/riscv: FP extension requirements
  target/riscv: Move/refactor ISA extension checks

 target/riscv/cpu.c | 62 +-
 1 file changed, 45 insertions(+), 17 deletions(-)


base-commit: 178bacb66d98d9ee7a702b9f2a4dfcd88b72a9ab
-- 
2.34.1




[PATCH 3/5] target/riscv: Change "G" expansion

2022-05-13 Thread Tsukasa OI
On ISA version 20190608 or later, "G" expands to "IMAFD_Zicsr_Zifencei".
Both "Zicsr" and "Zifencei" are enabled by default and "G" is supposed to
be (virtually) enabled as well, it should be safe to change its expansion.

Signed-off-by: Tsukasa OI 
---
 target/riscv/cpu.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3ea68d5cd7..0854ca9103 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -598,13 +598,16 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 
 if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
 cpu->cfg.ext_a && cpu->cfg.ext_f &&
-cpu->cfg.ext_d)) {
-warn_report("Setting G will also set IMAFD");
+cpu->cfg.ext_d &&
+cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
+warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
 cpu->cfg.ext_i = true;
 cpu->cfg.ext_m = true;
 cpu->cfg.ext_a = true;
 cpu->cfg.ext_f = true;
 cpu->cfg.ext_d = true;
+cpu->cfg.ext_icsr = true;
+cpu->cfg.ext_ifencei = true;
 }
 
 if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
-- 
2.34.1




Re: [PATCH] hw/adc/zynq-xadc: Use qemu_irq typedef

2022-05-13 Thread Peter Maydell
On Mon, 9 May 2022 at 21:20, Philippe Mathieu-Daudé
 wrote:
>
> From: Philippe Mathieu-Daudé 
>
> Except hw/core/irq.c which implements the forward-declared opaque
> qemu_irq structure, hw/adc/zynq-xadc.{c,h} are the only files not
> using the typedef. Fix this single exception.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/adc/zynq-xadc.c | 4 ++--
>  include/hw/adc/zynq-xadc.h | 3 +--
>  2 files changed, 3 insertions(+), 4 deletions(-)



Applied to target-arm.next, thanks.

-- PMM



[PATCH 1/5] target/riscv: Fix "G" extension expansion typing

2022-05-13 Thread Tsukasa OI
Because ext_? members are in bool type, operator `&&' should be used
instead of `&'.

Signed-off-by: Tsukasa OI 
---
 target/riscv/cpu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ccacdee215..00bf26ec8b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -596,8 +596,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m &
-cpu->cfg.ext_a & cpu->cfg.ext_f &
+if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
+cpu->cfg.ext_a && cpu->cfg.ext_f &&
 cpu->cfg.ext_d)) {
 warn_report("Setting G will also set IMAFD");
 cpu->cfg.ext_i = true;
-- 
2.34.1




[RFC PATCH 0/1] target/riscv: Make property names lowercase and add capitalized aliases

2022-05-13 Thread Tsukasa OI
Hello,

While I'm reviewing Dao Lu's Zihintpause patch, I noticed something.

c.f. 

While some CPU configuration properties have capitalized names but others
have lowercase names.  See riscv_cpu_properties in target/riscv/cpu.c
for example:

DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, true),

...

DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),

...

DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true),

...

I think this is not good.  Property names should have some sort of
consistency (especially when those names are case sensitive).  This is
what happens when invalid property is specified:

Invalid: -cpu rv64,counters=off
Valid  : -cpu rv64,Counters=off

qemu-system-riscv64: can't apply global rv64-riscv-cpu.counters=off: 
Property 'rv64-riscv-cpu.counters' not found

But we can't just remove such names for compatibility.

I found a way to make "property aliases" and that way, we can make both
"Counters" and "counters" valid.  I chose lowercase names (because of
number of properties implemented) as primary ones and capitalized names
are defined as aliases.

For instance, I'll show how both "counters" and "Counters" are implemented
below. They share three arguments but on alias (the second one),:

-   it uses DEFINE_PROP on alias to disable setting default value and
-   it defines property type (that is generally set by DEFINE_PROP_BOOL but
must be set manually because the alias uses DEFINE_PROP).

DEFINE_PROP_BOOL("counters", RISCVCPU, cfg.ext_counters, true),
DEFINE_PROP ("Counters", RISCVCPU, cfg.ext_counters, qdev_prop_bool, 
bool),




Tsukasa OI (1):
  target/riscv: Make property names lowercase

 target/riscv/cpu.c | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)


base-commit: 178bacb66d98d9ee7a702b9f2a4dfcd88b72a9ab
-- 
2.34.1




[RFC PATCH 1/1] target/riscv: Make property names lowercase

2022-05-13 Thread Tsukasa OI
Many properties for extension names are just in lowercase.  On the other
hand, following extension properties and "Counters" are capitalized.

-   Zifencei
-   Zicsr
-   Zfh
-   Zfhmin
-   Zve32f
-   Zve64f

This commit chooses lowercase as primary property names but keeps
capitalized names as aliases for compatibility.

Signed-off-by: Tsukasa OI 
---
 target/riscv/cpu.c | 23 ---
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ccacdee215..16227a1ac5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -822,17 +822,26 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
 DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
-DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
-DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
-DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
-DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
-DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
-DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
-DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
+DEFINE_PROP_BOOL("counters", RISCVCPU, cfg.ext_counters, true),
+DEFINE_PROP_BOOL("zifencei", RISCVCPU, cfg.ext_ifencei, true),
+DEFINE_PROP_BOOL("zicsr", RISCVCPU, cfg.ext_icsr, true),
+DEFINE_PROP_BOOL("zfh", RISCVCPU, cfg.ext_zfh, false),
+DEFINE_PROP_BOOL("zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
+DEFINE_PROP_BOOL("zve32f", RISCVCPU, cfg.ext_zve32f, false),
+DEFINE_PROP_BOOL("zve64f", RISCVCPU, cfg.ext_zve64f, false),
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
 
+/* Capitalized aliases */
+DEFINE_PROP("Counters", RISCVCPU, cfg.ext_counters, qdev_prop_bool, bool),
+DEFINE_PROP("Zifencei", RISCVCPU, cfg.ext_ifencei, qdev_prop_bool, bool),
+DEFINE_PROP("Zicsr", RISCVCPU, cfg.ext_icsr, qdev_prop_bool, bool),
+DEFINE_PROP("Zfh", RISCVCPU, cfg.ext_zfh, qdev_prop_bool, bool),
+DEFINE_PROP("Zfhmin", RISCVCPU, cfg.ext_zfhmin, qdev_prop_bool, bool),
+DEFINE_PROP("Zve32f", RISCVCPU, cfg.ext_zve32f, qdev_prop_bool, bool),
+DEFINE_PROP("Zve64f", RISCVCPU, cfg.ext_zve64f, qdev_prop_bool, bool),
+
 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),
-- 
2.34.1




[PATCH 1/2] target/riscv: Make CPU config error handling generous (virt/spike)

2022-05-13 Thread Tsukasa OI
If specified CPU configuration is not valid, not just it prints error
message, it aborts and generates core dumps (depends on the operating
system).  This kind of error handling should be used only when a serious
runtime error occurs.

This commit makes error handling on CPU configuration more generous on
virt/spike machines.  It now just prints error message and quits (without
coredumps and aborts).

Signed-off-by: Tsukasa OI 
---
 hw/riscv/spike.c | 2 +-
 hw/riscv/virt.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 068ba3493e..e41b6aa9f0 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -230,7 +230,7 @@ static void spike_board_init(MachineState *machine)
 base_hartid, &error_abort);
 object_property_set_int(OBJECT(&s->soc[i]), "num-harts",
 hart_count, &error_abort);
-sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort);
+sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_fatal);
 
 /* Core Local Interruptor (timer and IPI) for each socket */
 riscv_aclint_swi_create(
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 3326f4db96..244d6408b5 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1351,7 +1351,7 @@ static void virt_machine_init(MachineState *machine)
 base_hartid, &error_abort);
 object_property_set_int(OBJECT(&s->soc[i]), "num-harts",
 hart_count, &error_abort);
-sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort);
+sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_fatal);
 
 if (!kvm_enabled()) {
 if (s->have_aclint) {
-- 
2.34.1




[PATCH 0/2] hw/riscv: Make CPU config error handling generous

2022-05-13 Thread Tsukasa OI
Hello,

This patchset involves error handling on RISC-V CPU configuration error.

For instance:

-cpu rv64,f=on,zfinx=on

This is an example of invalid CPU configuration because "F" and "Zfinx"
cannot coexist.  Detecting such error is a good thing.

The bad thing is, it aborts when such invalid configuration is detected.
I'm making changes to QEMU on Ubuntu 22.04 LTS but once I got a pop-up
window asking whether to send a crash report.  Even if not, it generates
core dumps.  That's not what I wanted.

Example of error message before this patchset:
Unexpected error in riscv_cpu_realize() at 
../../../../src/qemu/target/riscv/cpu.c:718:
qemu-system-riscv64: 'Zfinx' cannot be supported together with 'F', 'D', 
'Zfh', 'Zfhmin'
Aborted (core dumped)
$ (returns to shell but may show error report window on some OS)

Such extreme error handling should be only used on serious runtime errors,
not for minor user-configuration mistakes (that can be easily and *safely*
detectable).

Example of error message after this patchset:
qemu-system-riscv64: 'Zfinx' cannot be supported together with 'F', 'D', 
'Zfh', 'Zfhmin'
$ (returns to shell with error status [$?] of 1)

This patchset resolves this problem on following machines, changing error
handling structure from `error_abort' (aborts and generates core dumps
[depends on OS] on error) to `error_fatal' (shows error message and quits
with error status 1 on error):

-   spike (QEMU default)
-   virt
-   sifive_e
-   sifive_u
-   opentitan (RV32 only)

`error_abort' on CPU realization exists on following machines:

-   shakti_c (RV64 only)
-   microchip-icicle-kit (RV64 only)

...but since CPU realization on those machine currently never fails
(because they require fixed CPU), I didn't touch those (may be a TODO).




Tsukasa OI (2):
  target/riscv: Make CPU config error handling generous (virt/spike)
  target/riscv: Make CPU config error handling generous
(sifive_e/u/opentitan)

 hw/riscv/opentitan.c | 2 +-
 hw/riscv/sifive_e.c  | 2 +-
 hw/riscv/sifive_u.c  | 4 ++--
 hw/riscv/spike.c | 2 +-
 hw/riscv/virt.c  | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)


base-commit: 178bacb66d98d9ee7a702b9f2a4dfcd88b72a9ab
-- 
2.34.1




[PATCH 2/2] target/riscv: Make CPU config error handling generous (sifive_e/u/opentitan)

2022-05-13 Thread Tsukasa OI
If specified CPU configuration is not valid, not just it prints error
message, it aborts and generates core dumps (depends on the operating
system).  This kind of error handling should be used only when a serious
runtime error occurs.

This commit makes error handling on CPU configuration more generous on
sifive_e/u and opentitan machines.  It now just prints error message and
quits (without coredumps and aborts).

This is separate from spike/virt because it involves different type
(TYPE_RISCV_HART_ARRAY) on sifive_e/u and opentitan machines.

Signed-off-by: Tsukasa OI 
---
 hw/riscv/opentitan.c | 2 +-
 hw/riscv/sifive_e.c  | 2 +-
 hw/riscv/sifive_u.c  | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 2d401dcb23..4495a2c039 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -142,7 +142,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
 &error_abort);
 object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x8080, 
&error_abort);
-sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_abort);
+sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
 
 /* Boot ROM */
 memory_region_init_rom(&s->rom, OBJECT(dev_soc), "riscv.lowrisc.ibex.rom",
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index dcb87b6cfd..d65d2fd869 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -195,7 +195,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error 
**errp)
 
 object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type,
 &error_abort);
-sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_abort);
+sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
 
 /* Mask ROM */
 memory_region_init_rom(&s->mask_rom, OBJECT(dev), "riscv.sifive.e.mrom",
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index cc8c7637cb..a2495b5ae7 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -830,8 +830,8 @@ static void sifive_u_soc_realize(DeviceState *dev, Error 
**errp)
 qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", s->cpu_type);
 qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
 
-sysbus_realize(SYS_BUS_DEVICE(&s->e_cpus), &error_abort);
-sysbus_realize(SYS_BUS_DEVICE(&s->u_cpus), &error_abort);
+sysbus_realize(SYS_BUS_DEVICE(&s->e_cpus), &error_fatal);
+sysbus_realize(SYS_BUS_DEVICE(&s->u_cpus), &error_fatal);
 /*
  * The cluster must be realized after the RISC-V hart array container,
  * as the container's CPU object is only created on realize, and the
-- 
2.34.1




Re: [RFC PATCH v4 1/4] target/riscv: Add smstateen support

2022-05-13 Thread Tsukasa OI
On 2022/05/13 17:51, Mayuresh Chitale wrote:
> Smstateen extension specifies a mechanism to close
> the potential covert channels that could cause security issues.
> 
> This patch adds the CSRs defined in the specification and
> the corresponding predicates and read/write functions.
> 
> Signed-off-by: Mayuresh Chitale 
> ---
>  target/riscv/cpu.c  |   2 +
>  target/riscv/cpu.h  |   4 +
>  target/riscv/cpu_bits.h |  36 +++
>  target/riscv/csr.c  | 210 
>  target/riscv/machine.c  |  21 
>  5 files changed, 273 insertions(+)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 25a4ba3e22..3be2c644f9 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -870,6 +870,7 @@ static Property riscv_cpu_properties[] = {
>  DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
>  DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
>  DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
> +DEFINE_PROP_BOOL("smstateen", RISCVCPU, cfg.ext_smstateen, false),
>  
>  DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
>  DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
> @@ -1062,6 +1063,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char 
> **isa_str, int max_str_len)
>  ISA_EDATA_ENTRY(svinval, ext_svinval),
>  ISA_EDATA_ENTRY(svnapot, ext_svnapot),
>  ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
> +ISA_EDATA_ENTRY(smstateen, ext_smstateen),

isa_edata_arr must be arranged by canonical ordering.
In this case, following comment (above those entries) applies:

>  * 3. Standard supervisor-level extensions (starts with 'S') should be
>  *listed after standard unprivileged extensions.  If multiple
>  *supervisor-level extensions are listed, they should be ordered
>  *alphabetically.

That means, you should put Smstateen extension line between zve64f and
svinval.  Other than that, your changes looks good to me.

Thanks,

Tsukasa

>  };
>  
>  for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index a55c918274..d6fdc63ff2 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -327,6 +327,9 @@ struct CPUArchState {
>  
>  /* CSRs for execution enviornment configuration */
>  uint64_t menvcfg;
> +uint64_t mstateen[SMSTATEEN_MAX_COUNT];
> +uint64_t hstateen[SMSTATEEN_MAX_COUNT];
> +uint64_t sstateen[SMSTATEEN_MAX_COUNT];
>  target_ulong senvcfg;
>  uint64_t henvcfg;
>  #endif
> @@ -411,6 +414,7 @@ struct RISCVCPUConfig {
>  bool ext_zhinxmin;
>  bool ext_zve32f;
>  bool ext_zve64f;
> +bool ext_smstateen;
>  
>  uint32_t mvendorid;
>  uint64_t marchid;
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index 4a55c6a709..2a3ef26d21 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -208,6 +208,12 @@
>  /* Supervisor Configuration CSRs */
>  #define CSR_SENVCFG 0x10A
>  
> +/* Supervisor state CSRs */
> +#define CSR_SSTATEEN0   0x10C
> +#define CSR_SSTATEEN1   0x10D
> +#define CSR_SSTATEEN2   0x10E
> +#define CSR_SSTATEEN3   0x10F
> +
>  /* Supervisor Trap Handling */
>  #define CSR_SSCRATCH0x140
>  #define CSR_SEPC0x141
> @@ -257,6 +263,16 @@
>  #define CSR_HENVCFG 0x60A
>  #define CSR_HENVCFGH0x61A
>  
> +/* Hypervisor state CSRs */
> +#define CSR_HSTATEEN0   0x60C
> +#define CSR_HSTATEEN0H  0x61C
> +#define CSR_HSTATEEN1   0x60D
> +#define CSR_HSTATEEN1H  0x61D
> +#define CSR_HSTATEEN2   0x60E
> +#define CSR_HSTATEEN2H  0x61E
> +#define CSR_HSTATEEN3   0x60F
> +#define CSR_HSTATEEN3H  0x61F
> +
>  /* Virtual CSRs */
>  #define CSR_VSSTATUS0x200
>  #define CSR_VSIE0x204
> @@ -304,6 +320,26 @@
>  #define CSR_MENVCFG 0x30A
>  #define CSR_MENVCFGH0x31A
>  
> +/* Machine state CSRs */
> +#define CSR_MSTATEEN0   0x30C
> +#define CSR_MSTATEEN0H  0x31C
> +#define CSR_MSTATEEN1   0x30D
> +#define CSR_MSTATEEN1H  0x31D
> +#define CSR_MSTATEEN2   0x30E
> +#define CSR_MSTATEEN2H  0x31E
> +#define CSR_MSTATEEN3   0x30F
> +#define CSR_MSTATEEN3H  0x31F
> +
> +/* Common defines for all smstateen */
> +#define SMSTATEEN_MAX_COUNT 4
> +#define SMSTATEEN0_CS   0
> +#define SMSTATEEN0_FCSR 0
> +#define SMSTATEEN0_IMSIC58
> +#define SMSTATEEN0_AIA  59
> +#define SMSTATEEN0_SVSLCT   60
> +#define SMSTATEEN0_HSENVCFG 62
> +#define SMSTATEEN_STATEN63
> +
>  /* Enhanced Physical Memory Protection (ePMP) */
>  #define CSR_MSECCFG 0x747
>  #define CSR_MSECCFGH0x757
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index e144ce7135..fea5cdd178 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -247,6 +247,42 @@ static RISCVException hmode32(CPURISCVState *env, int 
> csrno)
>  
>  }
>  
> +static RISCVExce

Re: [PATCH] Fix aarch64 debug register names.

2022-05-13 Thread Peter Maydell
On Thu, 12 May 2022 at 10:42, Chris Howard  wrote:
>
> From 5de17d5aacb9cf21de4c9736b227b0498c607709 Mon Sep 17 00:00:00 2001
> From: CHRIS HOWARD 
> Date: Thu, 12 May 2022 11:35:17 +0200
> Subject: [PATCH] Fix aarch64 debug register names.
>
> Signed-off-by: CHRIS HOWARD 

Thanks for sending the patch -- I've applied it
to target-arm.next.

-- PMM



Re: [PATCH v2 07/15] qga: use qemu_open_cloexec() for safe_open_or_create()

2022-05-13 Thread Marc-André Lureau
Hi

On Thu, May 5, 2022 at 1:33 PM Markus Armbruster  wrote:
>
> marcandre.lur...@redhat.com writes:
>
> > From: Marc-André Lureau 
> >
> > The function takes care of setting CLOEXEC, and reporting error.
> >
> > Signed-off-by: Marc-André Lureau 
> > ---
> >  qga/commands-posix.c | 11 +++
> >  1 file changed, 3 insertions(+), 8 deletions(-)
> >
> > diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> > index 0ef049650e31..8ebc327c5e02 100644
> > --- a/qga/commands-posix.c
> > +++ b/qga/commands-posix.c
> > @@ -370,21 +370,16 @@ safe_open_or_create(const char *path, const char 
> > *mode, Error **errp)
> >   * open() is decisive and its third argument is ignored, and the second
> >   * open() and the fchmod() are never called.
> >   */
> > -fd = open(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 0);
> > +fd = qemu_open_cloexec(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 
> > 0, errp);
> >  if (fd == -1 && errno == EEXIST) {
> > +g_clear_pointer(errp, error_free);
>
> Aha, this is where you really need ERRP_GUARD().
>
> Elsewhere, we use
>
>error_free(errp);
>errp = NULL;
>

More like:

error_free(*errp);
*errp = NULL;

compared to:

   g_clear_pointer(errp, error_free);

I have a preference ;) but I will switch to the former for now.

> If one of these two ways is superior, we should use the superior one
> everywhere.
>
> If it's a wash, we should stick to the prevalent way.
>
> >  oflag &= ~(unsigned)O_CREAT;
> > -fd = open(path, oflag);
> > +fd = qemu_open_cloexec(path, oflag, 0, errp);
> >  }
> >  if (fd == -1) {
> > -error_setg_errno(errp, errno,
> > - "failed to open file '%s' "
> > - "(mode: '%s')",
> > - path, mode);
>
> This changes the error message, doesn't it?
>
> Not an objection, just something that might be worth noting in the
> commit message.
>

ok

> >  goto end;
> >  }
> >
> > -qemu_set_cloexec(fd);
> > -
> >  if ((oflag & O_CREAT) && fchmod(fd, DEFAULT_NEW_FILE_MODE) == -1) {
> >  error_setg_errno(errp, errno,
> >   "failed to set permission 0%03o on new file '%s' 
> > (mode: '%s')",
>




Emulating CPUs with larger atomic accesses

2022-05-13 Thread Florian Weimer
What's QEMU's approach to emulating CPU instructions that atomatically
operate on values larger than what is supported by the host CPU?

I assume that for full system emulation, this is not a problem, but
qemu-user will not achieve atomic behavior on shared memory mappings.
How much of a problem is this in practice?

Thanks,
Florian




Re: [PATCH 1/2] target/arm: Enable FEAT_HCX for -cpu max

2022-05-13 Thread Peter Maydell
On Tue, 10 May 2022 at 01:05, Richard Henderson
 wrote:
>
> This feature adds a new register, HCRX_EL2, which controls
> many of the newer AArch64 features.  So far the register is
> effectively RES0, because none of the new features are done.
>
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/cpu.h| 20 ++
>  target/arm/cpu64.c  |  1 +
>  target/arm/helper.c | 50 +
>  3 files changed, 71 insertions(+)

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH v5 0/8] Support exporting BDSs via VDUSE

2022-05-13 Thread Michael S. Tsirkin
On Wed, May 04, 2022 at 03:40:43PM +0800, Xie Yongji wrote:
> Hi all,
> 
> Last few months ago, VDUSE (vDPA Device in Userspace) [1] has
> been merged into Linux kernel as a framework that make it
> possible to emulate a vDPA device in userspace. This series
> aimed at implementing a VDUSE block backend based on the
> qemu-storage-daemon infrastructure.
> 
> To support that, we firstly introduce a VDUSE library as a
> subproject (like what libvhost-user does) to help implementing
> VDUSE backends in QEMU. Then a VDUSE block export is implemented
> based on this library. At last, we add resize and reconnect support
> to the VDUSE block export and VDUSE library.
> 
> Since we don't support vdpa-blk in QEMU currently, the VM case is
> tested with my previous patchset [2].
> 
> [1] https://www.kernel.org/doc/html/latest/userspace-api/vduse.html
> [2] https://www.mail-archive.com/qemu-devel@nongnu.org/msg797569.html
> 
> Please review, thanks!

This needs review by storage maintainers.

> V4 to V5:
> - Abstract out the logic for virito-blk I/O process from
>   vhost-user-blk-server and reuse it [Kevin]
> - Fix missing VIRTIO_BLK_F_FLUSH [Kevin]
> - Support discard and write_zeroes [Kevin]
> - Rebase to the newest tree
> 
> V3 to V4:
> - Fix some comments on QAPI [Eric]
> 
> V2 to V3:
> - Introduce vduse_get_virtio_features() [Stefan]
> - Update MAINTAINERS file [Stefan]
> - Fix handler of VIRTIO_BLK_T_GET_ID request [Stefan]
> - Add barrier for vduse_queue_inflight_get() [Stefan]
> 
> V1 to V2:
> - Move vduse header to linux-headers [Stefan]
> - Add two new API to support creating device from /dev/vduse/$NAME or
>   file descriptor [Stefan]
> - Check VIRTIO_F_VERSION_1 during intialization [Stefan]
> - Replace malloc() + memset to calloc() [Stefan]
> - Increase default queue size to 256 for vduse-blk [Stefan]
> - Zero-initialize virtio-blk config space [Stefan]
> - Add a patch to support reset blk->dev_ops
> - Validate vq->log->inflight fields [Stefan]
> - Add vduse_set_reconnect_log_file() API to support specifing the
>   reconnect log file
> - Fix some bugs [Stefan]
> 
> Xie Yongji (8):
>   block: Support passing NULL ops to blk_set_dev_ops()
>   block-backend: Introduce blk_get_guest_block_size()
>   block/export: Abstract out the logic of virtio-blk I/O process
>   linux-headers: Add vduse.h
>   libvduse: Add VDUSE (vDPA Device in Userspace) library
>   vduse-blk: Implement vduse-blk export
>   vduse-blk: Add vduse-blk resize support
>   libvduse: Add support for reconnecting
> 
>  MAINTAINERS |9 +
>  block/block-backend.c   |8 +-
>  block/export/export.c   |6 +
>  block/export/meson.build|7 +-
>  block/export/vduse-blk.c|  346 +
>  block/export/vduse-blk.h|   20 +
>  block/export/vhost-user-blk-server.c|  249 +---
>  block/export/virtio-blk-handler.c   |  237 
>  block/export/virtio-blk-handler.h   |   33 +
>  include/sysemu/block-backend-io.h   |1 +
>  linux-headers/linux/vduse.h |  306 
>  meson.build |   28 +
>  meson_options.txt   |4 +
>  qapi/block-export.json  |   25 +-
>  scripts/meson-buildoptions.sh   |7 +
>  scripts/update-linux-headers.sh |2 +-
>  subprojects/libvduse/include/atomic.h   |1 +
>  subprojects/libvduse/include/compiler.h |1 +
>  subprojects/libvduse/libvduse.c | 1386 +++
>  subprojects/libvduse/libvduse.h |  247 
>  subprojects/libvduse/linux-headers/linux|1 +
>  subprojects/libvduse/meson.build|   10 +
>  subprojects/libvduse/standard-headers/linux |1 +
>  23 files changed, 2695 insertions(+), 240 deletions(-)
>  create mode 100644 block/export/vduse-blk.c
>  create mode 100644 block/export/vduse-blk.h
>  create mode 100644 block/export/virtio-blk-handler.c
>  create mode 100644 block/export/virtio-blk-handler.h
>  create mode 100644 linux-headers/linux/vduse.h
>  create mode 12 subprojects/libvduse/include/atomic.h
>  create mode 12 subprojects/libvduse/include/compiler.h
>  create mode 100644 subprojects/libvduse/libvduse.c
>  create mode 100644 subprojects/libvduse/libvduse.h
>  create mode 12 subprojects/libvduse/linux-headers/linux
>  create mode 100644 subprojects/libvduse/meson.build
>  create mode 12 subprojects/libvduse/standard-headers/linux
> 
> -- 
> 2.20.1




Re: [PATCH 2/2] target/arm: Use FIELD definitions for CPACR, CPTR_ELx

2022-05-13 Thread Peter Maydell
On Tue, 10 May 2022 at 01:06, Richard Henderson
 wrote:
>
> We had a few CPTR_* bits defined, but missed quite a few.
> Complete all of the fields up to ARMv9.2.
> Use FIELD_EX64 instead of manual extract32.
>
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/cpu.h| 44 +++-
>  hw/arm/boot.c   |  2 +-
>  target/arm/cpu.c| 11 ++---
>  target/arm/helper.c | 54 ++---
>  4 files changed, 75 insertions(+), 36 deletions(-)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index b35b117fe7..c44acd8b84 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -1259,11 +1259,45 @@ void pmu_init(ARMCPU *cpu);
>  #define SCTLR_SPINTMASK (1ULL << 62) /* FEAT_NMI */
>  #define SCTLR_TIDCP   (1ULL << 63) /* FEAT_TIDCP1 */
>
> -#define CPTR_TCPAC(1U << 31)
> -#define CPTR_TTA  (1U << 20)
> -#define CPTR_TFP  (1U << 10)
> -#define CPTR_TZ   (1U << 8)   /* CPTR_EL2 */
> -#define CPTR_EZ   (1U << 8)   /* CPTR_EL3 */
> +/* Bit definitions for CPACR (AArch32 only) */
> +FIELD(CPACR, CP10, 20, 2)
> +FIELD(CPACR, CP11, 22, 2)
> +FIELD(CPACR, TRCDIS, 28, 1)/* matches CPACR_EL1.TTA */
> +FIELD(CPACR, D32DIS, 31, 1)/* up to v7; RAZ in v8 */
> +FIELD(CPACR, ASEDIS, 31, 1)

D32DIS is bit 30, not 31.

> +
> +/* Bit definitions for CPACR_EL1 (AArch64 only) */
> +FIELD(CPACR_EL1, ZEN, 16, 2)
> +FIELD(CPACR_EL1, FPEN, 20, 2)
> +FIELD(CPACR_EL1, SMEN, 24, 2)
> +FIELD(CPACR_EL1, TTA, 28, 1)   /* matches CPACR.TRCDIS */
> +
> +/* Bit definitions for HCPTR (AArch32 only) */
> +FIELD(HCPTR, TCP10, 10, 1)
> +FIELD(HCPTR, TCP11, 11, 1)
> +FIELD(HCPTR, TSAE, 15, 1)

This is TASE, not TSAE.

Otherwise
Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH v1 00/13] various virtio docs, fixes and tweaks

2022-05-13 Thread Michael S. Tsirkin
On Mon, Mar 21, 2022 at 03:30:24PM +, Alex Bennée wrote:
>   contrib/vhost-user-blk: fix 32 bit build and enable

I applied up to this point. Pls respond to Philippe's comment.

-- 
MST




Re: [PATCH v10 00/45] CXl 2.0 emulation Support

2022-05-13 Thread Michael S. Tsirkin
On Fri, Apr 29, 2022 at 03:40:25PM +0100, Jonathan Cameron wrote:
> Note that due to a bug in the kernel handling of Mem_Enable
> in the CXL Device DVSEC a fix is needed to sucessfully use these
> patches with Linux.
> https://lore.kernel.org/linux-cxl/capcyv4gfww9s6r9kuol-_p9qnazsjbmz+ecmfy+0g1nhrjq...@mail.gmail.com/T/#t
> 
> Note the issue was detected using this emulation.
> 
> Changes since v9:
> 
> Thanks to Tong Zhang and Markus Armbruster for review of v9.
> - Fixed return of all 1s on HDM decoder not matching.
> - Off by one error in an assert for register writes.
> - Write masks for both PCI config space structures and
>   registers in MMIO space. These were partly queued up
>   for a future patch set, but after review comment from
>   Tong, I decided it was best to put these in place from
>   the start.  Note I was a bit undecided on whether to drop
>   review tags for this (it's quit a bit of code, but very
>   simple).  Alex, and Adam if you want to take another look
>   at patch 2 in particular that would be great. 
> - Tag from Markus added.
> - Fix for wrong setting of Mem_Enable as described in the
>   thread linked above.
> 
> The series can be applied in parts if that makes sense:
> 
> Possible partial sets:
> 1-15 (end with the test of the pxb-cxl host bridge)
> 16-22 (end with the test for root port and type3 device)
> 23-39 (end with tests on x86 pc for CFMWS including BIOS table updates)
> 40-41 (arm64 virt support + simple test case)
> 42 (documentation - we could pull this forwards to before the arm support)
> 43-45 (switch support)

OK, I picked up 1-39 and 42. Let's see how it goes, then arm
people can apply the arm bits.
I did my best with review but my knowledge is limited.

> gitlab tree at gitlab.com/jic23/qemu cxl-v10-draft-2
> 
> As before that tree has additional patches on top that will form
> part of future postings. This time it has SPDM support via
> a socket connection to DMTF/spdm_emu / libspdm. I'll send an RFC
> on that topic as it's a discussion that can go on in parallel.
> 
> Several people have asked about contributing additional features.
> As those come in I'll apply them on top of this series and handle
> rebases etc as necessary whilst we seek to get this first set
> of patches upstream.
> 
> Updated background info:
> 
> Looking in particular for:
> * Review of the PCI interactions
> * x86 and ARM machine interactions (particularly the memory maps)
> * Review of the interleaving approach - is the basic idea
>   acceptable?
> * Review of the command line interface.
> * CXL related review welcome but much of that got reviewed
>   in earlier versions and hasn't changed substantially.
> 
> TODOs:
> 
> * Volatile memory devices (easy but it's more code so left for now).
> * Hotplug?  May not need much but it's not tested yet!
> * More tests and tighter verification that values written to hardware
>   are actually valid - stuff that real hardware would check.
> * Testing, testing and more testing.  I have been running a basic
>   set of ARM and x86 tests on this, but there is always room for
>   more tests and greater automation.
> * CFMWS flags as requested by Ben.
> * Parititioning support - ability to change the balance of volatile
>   and non volatile memory on demand.
> * Trace points as suggested my Mark to help with debugging memory
>   interleaving setup.
> 
> Why do we want QEMU emulation of CXL?
> 
> As Ben stated in V3, QEMU support has been critical to getting OS
> software written given lack of availability of hardware supporting the
> latest CXL features (coupled with very high demand for support being
> ready in a timely fashion). What has become clear since Ben's v3
> is that situation is a continuous one. Whilst we can't talk about
> them yet, CXL 3.0 features and OS support have been prototyped on
> top of this support and a lot of the ongoing kernel work is being
> tested against these patches. The kernel CXL mocking code allows
> some forms of testing, but QEMU provides a more versatile and
> extensible platform.
> 
> Other features on the qemu-list that build on these include PCI-DOE
> /CDAT support from the Avery Design team further showing how this
> code is useful. Whilst not directly related this is also the test
> platform for work on PCI IDE/CMA + related DMTF SPDM as CXL both
> utilizes and extends those technologies and is likely to be an early
> adopter.
> Refs:
> CMA Kernel: 
> https://lore.kernel.org/all/20210804161839.3492053-1-jonathan.came...@huawei.com/
> CMA Qemu: 
> https://lore.kernel.org/qemu-devel/1624665723-5169-1-git-send-email-cbr...@avery-design.com/
> DOE Qemu: 
> https://lore.kernel.org/qemu-devel/162332-15662-1-git-send-email-cbr...@avery-design.com/
> 
> As can be seen there is non trivial interaction with other areas of
> Qemu, particularly PCI and keeping this set up to date is proving
> a burden we'd rather do without :)
> 
> Ben mentioned a few other good reasons in v3:
> https://lore.kernel.org/qemu-devel

Re: [PATCH v5 0/9] Introduce akcipher service for virtio-crypto

2022-05-13 Thread Michael S. Tsirkin
On Thu, Apr 28, 2022 at 09:59:34PM +0800, zhenwei pi wrote:
> Hi, Lei & MST
> 
> Daniel has started to review the akcipher framework and nettle & gcrypt
> implementation, this part seems to be ready soon. Thanks a lot to Daniel!
> 
> And the last patch "crypto: Introduce RSA algorithm" handles akcipher
> requests from guest and uses the new akcipher service. The new feature
> can be used to test by the builtin driver. I would appreciate it if you
> could review patch.


I applied the first 6 patches. Tests need to address Daniel's comments.

> v4 -> v5:
> - Move QCryptoAkCipher into akcipherpriv.h, and modify the related comments.
> - Rename asn1_decoder.c to der.c.
> - Code style fix: use 'cleanup' & 'error' lables.
> - Allow autoptr type to auto-free.
> - Add test cases for rsakey to handle DER error.
> - Other minor fixes.
> 
> v3 -> v4:
> - Coding style fix: Akcipher -> AkCipher, struct XXX -> XXX, Rsa -> RSA,
> XXX-alg -> XXX-algo.
> - Change version info in qapi/crypto.json, from 7.0 -> 7.1.
> - Remove ecdsa from qapi/crypto.json, it would be introduced with the 
> implemetion later.
> - Use QCryptoHashAlgothrim instead of QCryptoRSAHashAlgorithm(removed) in 
> qapi/crypto.json.
> - Rename arguments of qcrypto_akcipher_XXX to keep aligned with 
> qcrypto_cipher_XXX(dec/enc/sign/vefiry -> in/out/in2), and add 
> qcrypto_akcipher_max_XXX APIs.
> - Add new API: qcrypto_akcipher_supports.
> - Change the return value of qcrypto_akcipher_enc/dec/sign, these functions 
> return the actual length of result.
> - Separate ASN.1 source code and test case clean.
> - Disable RSA raw encoding for akcipher-nettle.
> - Separate RSA key parser into rsakey.{hc}, and implememts it with 
> builtin-asn1-decoder and nettle respectivly.
> - Implement RSA(pkcs1 and raw encoding) algorithm by gcrypt. This has higher 
> priority than nettle.
> - For some akcipher operations(eg, decryption of pkcs1pad(rsa)), the length 
> of returned result maybe less than the dst buffer size, return the actual 
> length of result instead of the buffer length to the guest side. (in function 
> virtio_crypto_akcipher_input_data_helper)
> - Other minor changes.
> 
> Thanks to Daniel!
> 
> Eric pointed out this missing part of use case, send it here again.
> 
> In our plan, the feature is designed for HTTPS offloading case and other 
> applications which use kernel RSA/ecdsa by keyctl syscall. The full picture 
> shows bellow:
> 
> 
>   Nginx/openssl[1] ... Apps
> Guest   -
>virtio-crypto driver[2]
> -
>virtio-crypto backend[3]
> Host-
>   /  |  \
>   builtin[4]   vhost keyctl[5] ...
> 
> 
> [1] User applications can offload RSA calculation to kernel by keyctl 
> syscall. There is no keyctl engine in openssl currently, we developed a 
> engine and tried to contribute it to openssl upstream, but openssl 1.x does 
> not accept new feature. Link:
> https://github.com/openssl/openssl/pull/16689
> 
> This branch is available and maintained by Lei 
> https://github.com/TousakaRin/openssl/tree/OpenSSL_1_1_1-kctl_engine
> 
> We tested nginx(change config file only) with openssl keyctl engine, it works 
> fine.
> 
> [2] virtio-crypto driver is used to communicate with host side, send requests 
> to host side to do asymmetric calculation.
> https://lkml.org/lkml/2022/3/1/1425
> 
> [3] virtio-crypto backend handles requests from guest side, and forwards 
> request to crypto backend driver of QEMU.
> 
> [4] Currently RSA is supported only in builtin driver. This driver is 
> supposed to test the full feature without other software(Ex vhost process) 
> and hardware dependence. ecdsa is introduced into qapi type without 
> implementation, this may be implemented in Q3-2022 or later. If ecdsa type 
> definition should be added with the implementation together, I'll remove this 
> in next version.
> 
> [5] keyctl backend is in development, we will post this feature in Q2-2022. 
> keyctl backend can use hardware acceleration(Ex, Intel QAT).
> 
> Setup the full environment, tested with Intel QAT on host side, the QPS of 
> HTTPS increase to ~200% in a guest.
> 
> VS PCI passthrough: the most important benefit of this solution makes the VM 
> migratable.
> 
> v2 -> v3:
> - Introduce akcipher types to qapi
> - Add test/benchmark suite for akcipher class
> - Seperate 'virtio_crypto: Support virtio crypto asym operation' into:
>   - crypto: Introduce akcipher crypto class
>   - virtio-crypto: Introduce RSA algorithm
> 
> v1 -> v2:
> - Update virtio_crypto.h from v2 version of related kernel patch.
> 
> v1:
> - Support akcipher for virtio-crypto.
> - Introduce akcipher class.
> - Introduce ASN1 decoder into QEMU.
> - Implement RSA backend by nettle/hogweed.
> 
> Lei He (6):
>   qapi: crypto-akcipher: Introduce akcipher types 

Re: [RFC PATCH 0/9] tests: run python tests under the build/tests/venv environment

2022-05-13 Thread Paolo Bonzini

On 5/13/22 02:06, John Snow wrote:

The only downside I am really frowning at is that I will have to
replicate some "update the venv if it's outdated" logic that is usually
handled by the Make system in the venv bootstrapper. Still, I think it's
probably the only way to hit all of the requirements here without trying
to concoct a fairly complex Makefile.

any thoughts? If not, I'll just move on to trying to hack up that
version next instead.


I would not even bother with keeping the venv up to date.  Just initialize
it in configure, this is exactly what configure remains useful for in the
Meson-based world:

- add configure options --enable-python-qemu={enabled,system,internal,pip,
auto}/--disable-python-qemu (auto means system>internal>pip>disabled; enabled 
means
system>internal>pip>error) and matching CONFIG_PYTHON_QEMU=y to
config-host.mak

- use CONFIG_PYTHON_QEMU to enable/disable iotests in 
tests/qemu-iotests/meson.build

- add a configure option --enable-avocado=
{system,pip,auto,enabled}/--disable-avocado and matching
CONFIG_AVOCADO=y to config-host.mak

- use it to enable/disable acceptance tests in tests/Makefile.include

- build the venv in configure and use the options to pick the right pip install
commands, like

has_python_module() {
  $python -c "import $1" > /dev/null 2>&1
}

# do_pip VENV-PATH VAR PACKAGE [PATH] -- PIP-OPTIONS
do_pip() {
local num_args source
num_args=5
test $4 = '--' && num_args=4
eval source=\$$2
# Try to resolve the package using a system install
case $source in
  enabled|auto|system)
if has_python_module $3; then
  source=system
elif test $source = system; then
  error_exit "Python package $3 not installed"
fi
esac
# See if a bundled copy is present
case $source in
  enabled|auto|internal)
if test $num_args = 5 && test -f $4/setup.cfg; then
  source=internal
elif test $source = internal; then
  error_exit "Sources for Python package $3 not found in the QEMU source 
tree"
fi
esac
# Install the bundled copy or let pip download the package
case $source in
  internal)
# The Pip error message should be clear enough
(cd $1 && . bin/activate && pip install "$@") || exit 1
  ;;
  enabled|auto|pip)
shift $num_args
if (cd $1 && . bin/activate && pip install "$@"); then
  source=pip
elif test $source = auto; then
  source=disabled
else
  # The Pip error message should be clear enough
  exit 1
fi
  ;;
esac
eval $2=\$source
}

rm -rf venv/
$python -m venv venv/
do_pip venv/ enable_python_qemu qemu.qmp python/qemu -- qemu.qmp
do_pip venv/ enable_avocado avocado -- -r tests/requirements.txt



Re: [PATCH v5 0/9] Introduce akcipher service for virtio-crypto

2022-05-13 Thread Michael S. Tsirkin
On Fri, May 13, 2022 at 06:19:10AM -0400, Michael S. Tsirkin wrote:
> On Thu, Apr 28, 2022 at 09:59:34PM +0800, zhenwei pi wrote:
> > Hi, Lei & MST
> > 
> > Daniel has started to review the akcipher framework and nettle & gcrypt
> > implementation, this part seems to be ready soon. Thanks a lot to Daniel!
> > 
> > And the last patch "crypto: Introduce RSA algorithm" handles akcipher
> > requests from guest and uses the new akcipher service. The new feature
> > can be used to test by the builtin driver. I would appreciate it if you
> > could review patch.
> 
> 
> I applied the first 6 patches. Tests need to address Daniel's comments.

Oh sorry, spoke too soon - I noticed mingw issues, and in fact Daniel noticed 
them too.
Pls address and repost the series. Thanks!

> > v4 -> v5:
> > - Move QCryptoAkCipher into akcipherpriv.h, and modify the related comments.
> > - Rename asn1_decoder.c to der.c.
> > - Code style fix: use 'cleanup' & 'error' lables.
> > - Allow autoptr type to auto-free.
> > - Add test cases for rsakey to handle DER error.
> > - Other minor fixes.
> > 
> > v3 -> v4:
> > - Coding style fix: Akcipher -> AkCipher, struct XXX -> XXX, Rsa -> RSA,
> > XXX-alg -> XXX-algo.
> > - Change version info in qapi/crypto.json, from 7.0 -> 7.1.
> > - Remove ecdsa from qapi/crypto.json, it would be introduced with the 
> > implemetion later.
> > - Use QCryptoHashAlgothrim instead of QCryptoRSAHashAlgorithm(removed) in 
> > qapi/crypto.json.
> > - Rename arguments of qcrypto_akcipher_XXX to keep aligned with 
> > qcrypto_cipher_XXX(dec/enc/sign/vefiry -> in/out/in2), and add 
> > qcrypto_akcipher_max_XXX APIs.
> > - Add new API: qcrypto_akcipher_supports.
> > - Change the return value of qcrypto_akcipher_enc/dec/sign, these functions 
> > return the actual length of result.
> > - Separate ASN.1 source code and test case clean.
> > - Disable RSA raw encoding for akcipher-nettle.
> > - Separate RSA key parser into rsakey.{hc}, and implememts it with 
> > builtin-asn1-decoder and nettle respectivly.
> > - Implement RSA(pkcs1 and raw encoding) algorithm by gcrypt. This has 
> > higher priority than nettle.
> > - For some akcipher operations(eg, decryption of pkcs1pad(rsa)), the length 
> > of returned result maybe less than the dst buffer size, return the actual 
> > length of result instead of the buffer length to the guest side. (in 
> > function virtio_crypto_akcipher_input_data_helper)
> > - Other minor changes.
> > 
> > Thanks to Daniel!
> > 
> > Eric pointed out this missing part of use case, send it here again.
> > 
> > In our plan, the feature is designed for HTTPS offloading case and other 
> > applications which use kernel RSA/ecdsa by keyctl syscall. The full picture 
> > shows bellow:
> > 
> > 
> >   Nginx/openssl[1] ... Apps
> > Guest   -
> >virtio-crypto driver[2]
> > -
> >virtio-crypto backend[3]
> > Host-
> >   /  |  \
> >   builtin[4]   vhost keyctl[5] ...
> > 
> > 
> > [1] User applications can offload RSA calculation to kernel by keyctl 
> > syscall. There is no keyctl engine in openssl currently, we developed a 
> > engine and tried to contribute it to openssl upstream, but openssl 1.x does 
> > not accept new feature. Link:
> > https://github.com/openssl/openssl/pull/16689
> > 
> > This branch is available and maintained by Lei 
> > https://github.com/TousakaRin/openssl/tree/OpenSSL_1_1_1-kctl_engine
> > 
> > We tested nginx(change config file only) with openssl keyctl engine, it 
> > works fine.
> > 
> > [2] virtio-crypto driver is used to communicate with host side, send 
> > requests to host side to do asymmetric calculation.
> > https://lkml.org/lkml/2022/3/1/1425
> > 
> > [3] virtio-crypto backend handles requests from guest side, and forwards 
> > request to crypto backend driver of QEMU.
> > 
> > [4] Currently RSA is supported only in builtin driver. This driver is 
> > supposed to test the full feature without other software(Ex vhost process) 
> > and hardware dependence. ecdsa is introduced into qapi type without 
> > implementation, this may be implemented in Q3-2022 or later. If ecdsa type 
> > definition should be added with the implementation together, I'll remove 
> > this in next version.
> > 
> > [5] keyctl backend is in development, we will post this feature in Q2-2022. 
> > keyctl backend can use hardware acceleration(Ex, Intel QAT).
> > 
> > Setup the full environment, tested with Intel QAT on host side, the QPS of 
> > HTTPS increase to ~200% in a guest.
> > 
> > VS PCI passthrough: the most important benefit of this solution makes the 
> > VM migratable.
> > 
> > v2 -> v3:
> > - Introduce akcipher types to qapi
> > - Add test/benchmark suite for akcipher class
> > - Seperate 'virtio_crypto: Support virtio crypto asym operation' 

Re: [RFC PATCH 0/9] tests: run python tests under the build/tests/venv environment

2022-05-13 Thread Daniel P . Berrangé
On Fri, May 13, 2022 at 09:35:23AM +0100, Daniel P. Berrangé wrote:
> On Thu, May 12, 2022 at 08:06:00PM -0400, John Snow wrote:
> > RFC: This is a very early, crude attempt at switching over to an
> > external Python package dependency for QMP. This series does not
> > actually make the switch in and of itself, but instead just switches to
> > the paradigm of using a venv in general to install the QEMU python
> > packages instead of using PYTHONPATH to load them from the source tree.
> > 
> > (By installing the package, we can process dependencies.)
> > 
> > I'm sending it to the list so I can show you some of what's ugly so far
> > and my notes on how I might make it less ugly.
> > 
> > (1) This doesn't trigger venv creation *from* iotests, it merely prints
> > a friendly error message if "make check-venv" has not been run
> > first. Not the greatest.
> 
> So if we run the sequence
> 
>   mkdir build
>   cd build
>   ../configure
>   make
>   ./tests/qemu-iotests/check 001
> 
> It won't work anymore, until we 'make check-venv' (or simply
> 'make check') ?
> 
> I'm somewhat inclined to say that venv should be created
> unconditionally by default. ie a plain 'make' should always
> everything needed to be able to invoke the tests directly.
> 
> > (2) This isn't acceptable for SRPM builds, because it uses PyPI to fetch
> > packages just-in-time. My thought is to use an environment variable like
> > QEMU_CHECK_NO_INTERNET that changes the behavior of the venv setup
> > process. We can use "--system-site-packages" as an argument to venv
> > creation and "--no-index" as an argument to pip installation to achieve
> > good behavior in SRPM building scenarios. It'd be up to the spec-writer
> > to opt into that behavior.
> 
> I think I'd expect --system-site-packages to be the default behaviour.
> We expect QEMU to be compatible with the packages available in the
> distros that we're targetting. So if the dev has the python packages
> installed from their distro, we should be using them preferentially.
> 
> This is similar to how we bundle slirp/capstone/etc, but will
> preferentially use the distro version if it is available.

AFAICT from testing it, when '--system-site-packages' is set
for the venv, then 'pip install' appears to end up being a
no-op if the package is already present in the host, but
installs it if missing.

IOW, if we default to --system-site-packages, but still
also run 'pip install', we should "do the right thing".
It'll use any  distro packages that are available, and
augment with stuff from pip. In the no-op case, pip will
still try to consult the pipy servers to fetch version
info IIUC, so we need to be able to stop that. So I'd
suggest a  --python-env arg taking three values

 * "auto" (the default) - add --system-site-packages, but
   also run 'pip install'. Good for developers day-to-day

 * "system" - add --system-site-packages but never run
   'pip install'.  Good for formal package builds.

 * "pip"  - don't add --system-site-packages, always run
   'pip install'. Good for testing compatibility with
   bleeding edge python versions, or if explicit full
   independance from host python install is desired.

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




Re: [PATCH 01/11] hw/rtc/mc146818rtc: Inline isa_connect_gpio_out() and remove it

2022-05-13 Thread Bernhard Beschow
Am 11. Mai 2022 10:24:58 UTC schrieb Mark Cave-Ayland
:
>On 05/05/2022 17:17, Bernhard Beschow wrote:
>
>> Commit 250263033c5343012b2cd6f01210ffb5b908a159 'isa: introduce wrapper
>> isa_connect_gpio_out' introduced it in 2016. Since then, its only user
>> remained mc146818rtc. Remove this one-off solution.
>>
>> Signed-off-by: Bernhard Beschow 
>> ---
>>   hw/isa/isa-bus.c | 6 --
>>   hw/rtc/mc146818rtc.c | 3 ++-
>>   include/hw/isa/isa.h | 1 -
>>   3 files changed, 2 insertions(+), 8 deletions(-)
>>
>> diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
>> index 0ad1c5fd65..59eb1af9e3 100644
>> --- a/hw/isa/isa-bus.c
>> +++ b/hw/isa/isa-bus.c
>> @@ -85,12 +85,6 @@ qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq)
>>   return isabus->irqs[isairq];
>>   }
>>   -void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq)
>> -{
>> -qemu_irq irq = isa_get_irq(isadev, isairq);
>> -qdev_connect_gpio_out(DEVICE(isadev), gpioirq, irq);
>> -}
>> -
>>   void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16)
>>   {
>>   assert(bus && dma8 && dma16);
>> diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
>> index f235c2ddbe..79c43391cb 100644
>> --- a/hw/rtc/mc146818rtc.c
>> +++ b/hw/rtc/mc146818rtc.c
>> @@ -972,7 +972,8 @@ ISADevice *mc146818_rtc_init(ISABus *bus, int base_year, 
>> qemu_irq intercept_irq)
>>   if (intercept_irq) {
>>   qdev_connect_gpio_out(dev, 0, intercept_irq);
>>   } else {
>> -isa_connect_gpio_out(isadev, 0, s->isairq);
>> +qemu_irq irq = isa_get_irq(isadev, s->isairq);
>> +qdev_connect_gpio_out(dev, 0, irq);
>>   }
>> object_property_add_alias(qdev_get_machine(), "rtc-time", 
>> OBJECT(isadev),
>> diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
>> index 034d706ba1..1b758ae1ab 100644
>> --- a/include/hw/isa/isa.h
>> +++ b/include/hw/isa/isa.h
>> @@ -90,7 +90,6 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion 
>> *address_space,
>>   MemoryRegion *address_space_io, Error **errp);
>>   void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
>>   qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq);
>> -void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq);
>>   void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16);
>>   IsaDma *isa_get_dma(ISABus *bus, int nchan);
>>   MemoryRegion *isa_address_space(ISADevice *dev);
>
>Hi Bernhard,

Hi Mark,

>I've been tinkering again with trying to improve QEMU's ISA implementation to 
>use gpios, and actually I believe as per the comment in isa-bus.c that 
>isa_connect_gpio_out() will be the preferred way to wire up ISA devices. So 
>really we should be trying to use this function more rather than removing it.
>
>BTW if you are interested in helping to work on ISA bus improvements, I can 
>certainly come up with a TODO list of useful tasks :)

Yes, that'd be great!

As expressed earlier [1] I'd like to remove the isabus global in
isa-bus.c. Meanwhile, I implemented a POC [2]. While the result seems
to work for the PC and Malta boards, some of the changes required
don't seem quite clean. So yeah, I'd be interested in the bigger
picture regarding ISA improvements and would like to help out as time
permits, too.

Best regards,
Bernhard

[1] https://lists.nongnu.org/archive/html/qemu-devel/2022-03/msg05955.html
[2] https://github.com/shentok/qemu/commits/isa

>
>ATB,
>
>Mark.



Re: [PATCH v5 8/9] tests/crypto: Add test suite for RSA keys

2022-05-13 Thread Daniel P . Berrangé
On Thu, Apr 28, 2022 at 09:59:42PM +0800, zhenwei pi wrote:
> From: Lei He 
> 
> As Daniel suggested, Add tests suite for rsakey, as a way to prove
> that we can handle DER errors correctly.
> 
> Signed-off-by: lei he 
> ---
>  tests/unit/test-crypto-akcipher.c | 285 +-
>  1 file changed, 282 insertions(+), 3 deletions(-)

Reviewed-by: Daniel P. Berrangé 


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




Re: [PATCH RESEND 0/2] Resolve some redundant property accessors

2022-05-13 Thread Bernhard Beschow
Am 5. Mai 2022 16:52:13 UTC schrieb Bernhard Beschow :
>Am 1. März 2022 22:52:18 UTC schrieb Bernhard Beschow :
>>No changes. Just also CC'ed to qemu-trivial.
>>
>>The QOM API already provides appropriate accessors, so reuse them.
>>
>>Testing done:
>>
>>  :$ make check
>>  Ok: 570
>>  Expected Fail:  0
>>  Fail:   0
>>  Unexpected Pass:0
>>  Skipped:178
>>  Timeout:0
>>
>>
>>Bernhard Beschow (2):
>>  hw/vfio/pci-quirks: Resolve redundant property getters
>>  hw/riscv/sifive_u: Resolve redundant property accessors
>>
>> hw/riscv/sifive_u.c  | 24 
>> hw/vfio/pci-quirks.c | 34 +-
>> 2 files changed, 13 insertions(+), 45 deletions(-)
>>
>
>Ping
>
>First round of trivial patches went already in for 7.1, hence a reminder.
>
>Best regards,
>Bernhard
Ping 2



[PATCH v2] qga: add guest-get-diskstats command for Linux guests

2022-05-13 Thread luzhipeng
Add a new 'guest-get-diskstats' command for report disk io statistics
for Linux guests. This can be usefull for getting io flow or handling
IO fault, no need to enter guests.

Signed-off-by: luzhipeng 

---
Changes v1->v2:
 v1:https://patchew.org/QEMU/20220512011930.214-1-luzhip...@cestc.cn/

 qga/commands-posix.c | 97 
 qga/commands-win32.c |  6 +++
 qga/qapi-schema.json | 86 +++
 3 files changed, 189 insertions(+)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 69f209af87..7a16d84e3a 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -2783,6 +2783,96 @@ GuestMemoryBlockInfo 
*qmp_guest_get_memory_block_info(Error **errp)
 return info;
 }
 
+#define MAX_NAME_LEN 128
+static GuestDiskStatsInfoList *guest_get_diskstats(Error **errp)
+{
+#ifdef CONFIG_LINUX
+GuestDiskStatsInfoList *head = NULL, **tail = &head;
+const char *diskstats = "/proc/diskstats";
+FILE *fp;
+size_t n;
+char *line = NULL;
+char dev_name[MAX_NAME_LEN];
+int i;
+unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks, dc_ticks, fl_ticks;
+unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios;
+unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec;
+unsigned long dc_ios, dc_merges, dc_sec, fl_ios;
+unsigned int major, minor;
+
+fp = fopen(diskstats, "r");
+if (fp  == NULL) {
+error_setg_errno(errp, errno, "open(\"%s\")", diskstats);
+return NULL;
+}
+while (getline(&line, &n, fp) != -1) {
+GuestDiskStatsInfo *diskstatinfo;
+GuestDiskStats *diskstat;
+i = sscanf(line, "%u %u %s %lu %lu %lu"
+   "%lu %lu %lu %lu %u %u %u %u"
+   "%lu %lu %lu %u %lu %u",
+  &major, &minor, dev_name,
+  &rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios,
+  &rd_ticks_or_wr_sec, &wr_ios, &wr_merges, &wr_sec,
+  &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks,
+  &dc_ios, &dc_merges, &dc_sec, &dc_ticks,
+  &fl_ios, &fl_ticks);
+
+diskstatinfo = g_new0(GuestDiskStatsInfo, 1);
+diskstat = g_new0(GuestDiskStats, 1);
+if (i < 7) {
+continue;
+}
+diskstatinfo->name = g_strdup(dev_name);
+diskstatinfo->major = major;
+diskstatinfo->minor = minor;
+if (i == 7) {
+diskstat->read_ios = rd_ios;
+diskstat->read_sectors = rd_merges_or_rd_sec;
+diskstat->write_ios = rd_sec_or_wr_ios;
+diskstat->write_sectors = rd_ticks_or_wr_sec;
+}
+if (i >= 14) {
+diskstat->read_ios = rd_ios;
+diskstat->read_sectors = rd_sec_or_wr_ios;
+diskstat->read_merges = rd_merges_or_rd_sec;
+diskstat->read_ticks = rd_ticks_or_wr_sec;
+diskstat->write_ios = wr_ios;
+diskstat->write_sectors = wr_sec;
+diskstat->write_merges = wr_merges;
+diskstat->write_ticks = wr_ticks;
+diskstat->ios_pgr = ios_pgr;
+diskstat->total_ticks = tot_ticks;
+diskstat->weight_ticks = rq_ticks;
+}
+if (i >= 18) {
+diskstat->discard_ios = dc_ios;
+diskstat->discard_merges = dc_merges;
+diskstat->discard_sectors = dc_sec;
+diskstat->discard_ticks = dc_ticks;
+}
+if (i >= 20) {
+diskstat->flush_ios = fl_ios;
+diskstat->flush_ticks = fl_ticks;
+}
+
+diskstatinfo->stats = diskstat;
+QAPI_LIST_APPEND(tail, diskstatinfo);
+}
+g_free(line);
+fclose(fp);
+return head;
+#else
+g_debug("disk stats reporting available only for Linux");
+return NULL;
+#endif
+}
+
+GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp)
+{
+return guest_get_diskstats(errp);
+}
+
 #else /* defined(__linux__) */
 
 void qmp_guest_suspend_disk(Error **errp)
@@ -3131,6 +3221,13 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
 return NULL;
 }
 
+GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp)
+{
+error_setg(errp, QERR_UNSUPPORTED);
+return NULL;
+}
+
+
 #endif /* CONFIG_FSFREEZE */
 
 #if !defined(CONFIG_FSTRIM)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index d56b5fd2a7..dcdeb76a68 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -2532,3 +2532,9 @@ char *qga_get_host_name(Error **errp)
 
 return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL);
 }
+
+GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp)
+{
+error_setg(errp, QERR_UNSUPPORTED);
+return NULL;
+}
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 4d8e506c9e..94aad4f2ae 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -1490,3 +1490,89 @@
 { 'command': 'guest-ssh-remove-authorized-keys',
   'data': { 'username': 'str', 'keys': [

Re: [PATCH 2/5] virtio-net: prepare for variable RSS key and indir table lengths

2022-05-13 Thread Michael S. Tsirkin
On Fri, Apr 15, 2022 at 01:39:04PM +0800, Jason Wang wrote:
> 
> 在 2022/4/8 20:28, Maxime Coquelin 写道:
> > This patch is a preliminary rework to support RSS with
> > Vhost-user backends. It enables supporting different types
> > of hashes, key lengths and indirection table lengths.
> > 
> > This patch does not introduces behavioral changes.
> > 
> > Signed-off-by: Maxime Coquelin 
> > ---
> >   ebpf/ebpf_rss.c|  8 
> >   hw/net/virtio-net.c| 35 +-
> >   include/hw/virtio/virtio-net.h | 16 +---
> >   include/migration/vmstate.h| 10 ++
> >   4 files changed, 53 insertions(+), 16 deletions(-)
> > 
> > diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
> > index 4a63854175..f03be5f919 100644
> > --- a/ebpf/ebpf_rss.c
> > +++ b/ebpf/ebpf_rss.c
> > @@ -96,7 +96,7 @@ static bool ebpf_rss_set_indirections_table(struct 
> > EBPFRSSContext *ctx,
> >   uint32_t i = 0;
> >   if (!ebpf_rss_is_loaded(ctx) || indirections_table == NULL ||
> > -   len > VIRTIO_NET_RSS_MAX_TABLE_LEN) {
> > +   len > VIRTIO_NET_RSS_DEFAULT_TABLE_LEN) {
> >   return false;
> >   }
> > @@ -116,13 +116,13 @@ static bool ebpf_rss_set_toepliz_key(struct 
> > EBPFRSSContext *ctx,
> >   uint32_t map_key = 0;
> >   /* prepare toeplitz key */
> > -uint8_t toe[VIRTIO_NET_RSS_MAX_KEY_SIZE] = {};
> > +uint8_t toe[VIRTIO_NET_RSS_DEFAULT_KEY_SIZE] = {};
> >   if (!ebpf_rss_is_loaded(ctx) || toeplitz_key == NULL ||
> > -len != VIRTIO_NET_RSS_MAX_KEY_SIZE) {
> > +len != VIRTIO_NET_RSS_DEFAULT_KEY_SIZE) {
> >   return false;
> >   }
> > -memcpy(toe, toeplitz_key, VIRTIO_NET_RSS_MAX_KEY_SIZE);
> > +memcpy(toe, toeplitz_key, VIRTIO_NET_RSS_DEFAULT_KEY_SIZE);
> >   *(uint32_t *)toe = ntohl(*(uint32_t *)toe);
> >   if (bpf_map_update_elem(ctx->map_toeplitz_key, &map_key, toe,
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index 73145d6390..38436e472b 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -137,12 +137,11 @@ static void virtio_net_get_config(VirtIODevice *vdev, 
> > uint8_t *config)
> >   memcpy(netcfg.mac, n->mac, ETH_ALEN);
> >   virtio_stl_p(vdev, &netcfg.speed, n->net_conf.speed);
> >   netcfg.duplex = n->net_conf.duplex;
> > -netcfg.rss_max_key_size = VIRTIO_NET_RSS_MAX_KEY_SIZE;
> > +netcfg.rss_max_key_size = n->rss_capa.max_key_size;
> >   virtio_stw_p(vdev, &netcfg.rss_max_indirection_table_length,
> > - virtio_host_has_feature(vdev, VIRTIO_NET_F_RSS) ?
> > - VIRTIO_NET_RSS_MAX_TABLE_LEN : 1);
> > + n->rss_capa.max_indirection_len);
> >   virtio_stl_p(vdev, &netcfg.supported_hash_types,
> > - VIRTIO_NET_RSS_SUPPORTED_HASHES);
> > + n->rss_capa.supported_hashes);
> >   memcpy(config, &netcfg, n->config_size);
> >   /*
> > @@ -1202,7 +1201,7 @@ static bool virtio_net_attach_epbf_rss(VirtIONet *n)
> >   if (!ebpf_rss_set_all(&n->ebpf_rss, &config,
> > n->rss_data.indirections_table, n->rss_data.key,
> > -  VIRTIO_NET_RSS_MAX_KEY_SIZE)) {
> > +  n->rss_data.key_len)) {
> >   return false;
> >   }
> > @@ -1277,7 +1276,7 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
> >   err_value = n->rss_data.indirections_len;
> >   goto error;
> >   }
> > -if (n->rss_data.indirections_len > VIRTIO_NET_RSS_MAX_TABLE_LEN) {
> > +if (n->rss_data.indirections_len > n->rss_capa.max_indirection_len) {
> >   err_msg = "Too large indirection table";
> >   err_value = n->rss_data.indirections_len;
> >   goto error;
> > @@ -1323,7 +1322,7 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
> >   err_value = queue_pairs;
> >   goto error;
> >   }
> > -if (temp.b > VIRTIO_NET_RSS_MAX_KEY_SIZE) {
> > +if (temp.b > n->rss_capa.max_key_size) {
> >   err_msg = "Invalid key size";
> >   err_value = temp.b;
> >   goto error;
> > @@ -1339,6 +1338,14 @@ static uint16_t virtio_net_handle_rss(VirtIONet *n,
> >   }
> >   offset += size_get;
> >   size_get = temp.b;
> > +n->rss_data.key_len = temp.b;
> > +g_free(n->rss_data.key);
> > +n->rss_data.key = g_malloc(size_get);
> > +if (!n->rss_data.key) {
> > +err_msg = "Can't allocate key";
> > +err_value = n->rss_data.key_len;
> > +goto error;
> > +}
> >   s = iov_to_buf(iov, iov_cnt, offset, n->rss_data.key, size_get);
> >   if (s != size_get) {
> >   err_msg = "Can get key buffer";
> > @@ -3093,8 +3100,9 @@ static const VMStateDescription 
> > vmstate_virtio_net_rss = {
> >   VMSTATE_UINT32(rss_data.hash_types, VirtIONet),
> >   VMSTATE_UINT16(rss_data.indirections_len, VirtIONet),
> >   VMSTATE_UINT1

Re: [PATCH v2] qga: add guest-get-diskstats command for Linux guests

2022-05-13 Thread Konstantin Kostiuk
On Fri, May 13, 2022 at 1:40 PM luzhipeng  wrote:

> Add a new 'guest-get-diskstats' command for report disk io statistics
> for Linux guests. This can be usefull for getting io flow or handling
> IO fault, no need to enter guests.
>
> Signed-off-by: luzhipeng 
>
> ---
> Changes v1->v2:
>  v1:https://patchew.org/QEMU/20220512011930.214-1-luzhip...@cestc.cn/
>
>  qga/commands-posix.c | 97 
>  qga/commands-win32.c |  6 +++
>  qga/qapi-schema.json | 86 +++
>  3 files changed, 189 insertions(+)
>
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index 69f209af87..7a16d84e3a 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -2783,6 +2783,96 @@ GuestMemoryBlockInfo
> *qmp_guest_get_memory_block_info(Error **errp)
>  return info;
>  }
>
> +#define MAX_NAME_LEN 128
> +static GuestDiskStatsInfoList *guest_get_diskstats(Error **errp)
> +{
> +#ifdef CONFIG_LINUX
> +GuestDiskStatsInfoList *head = NULL, **tail = &head;
> +const char *diskstats = "/proc/diskstats";
> +FILE *fp;
> +size_t n;
> +char *line = NULL;
> +char dev_name[MAX_NAME_LEN];
> +int i;
> +unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks, dc_ticks,
> fl_ticks;
> +unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios;
> +unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec;
> +unsigned long dc_ios, dc_merges, dc_sec, fl_ios;
> +unsigned int major, minor;
> +
> +fp = fopen(diskstats, "r");
> +if (fp  == NULL) {
> +error_setg_errno(errp, errno, "open(\"%s\")", diskstats);
> +return NULL;
> +}
> +while (getline(&line, &n, fp) != -1) {
> +GuestDiskStatsInfo *diskstatinfo;
> +GuestDiskStats *diskstat;
> +i = sscanf(line, "%u %u %s %lu %lu %lu"
> +   "%lu %lu %lu %lu %u %u %u %u"
> +   "%lu %lu %lu %u %lu %u",
> +  &major, &minor, dev_name,
> +  &rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios,
> +  &rd_ticks_or_wr_sec, &wr_ios, &wr_merges, &wr_sec,
> +  &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks,
> +  &dc_ios, &dc_merges, &dc_sec, &dc_ticks,
> +  &fl_ios, &fl_ticks);
> +
> +diskstatinfo = g_new0(GuestDiskStatsInfo, 1);
> +diskstat = g_new0(GuestDiskStats, 1);
>
+if (i < 7) {
>

diskstatinfo and diskstat pointers do not have g_autoptr attribute and
will be not added to the results list.
So, looks like we have a memory leak in this case.


> +continue;
> +}
> +diskstatinfo->name = g_strdup(dev_name);
> +diskstatinfo->major = major;
> +diskstatinfo->minor = minor;
> +if (i == 7) {
> +diskstat->read_ios = rd_ios;
> +diskstat->read_sectors = rd_merges_or_rd_sec;
> +diskstat->write_ios = rd_sec_or_wr_ios;
> +diskstat->write_sectors = rd_ticks_or_wr_sec;
> +}
> +if (i >= 14) {
> +diskstat->read_ios = rd_ios;
> +diskstat->read_sectors = rd_sec_or_wr_ios;
> +diskstat->read_merges = rd_merges_or_rd_sec;
> +diskstat->read_ticks = rd_ticks_or_wr_sec;
> +diskstat->write_ios = wr_ios;
> +diskstat->write_sectors = wr_sec;
> +diskstat->write_merges = wr_merges;
> +diskstat->write_ticks = wr_ticks;
> +diskstat->ios_pgr = ios_pgr;
> +diskstat->total_ticks = tot_ticks;
> +diskstat->weight_ticks = rq_ticks;
> +}
> +if (i >= 18) {
> +diskstat->discard_ios = dc_ios;
> +diskstat->discard_merges = dc_merges;
> +diskstat->discard_sectors = dc_sec;
> +diskstat->discard_ticks = dc_ticks;
> +}
> +if (i >= 20) {
> +diskstat->flush_ios = fl_ios;
> +diskstat->flush_ticks = fl_ticks;
> +}
> +
> +diskstatinfo->stats = diskstat;
> +QAPI_LIST_APPEND(tail, diskstatinfo);
> +}
> +g_free(line);
> +fclose(fp);
> +return head;
> +#else
> +g_debug("disk stats reporting available only for Linux");
> +return NULL;
> +#endif
> +}
> +
> +GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp)
> +{
> +return guest_get_diskstats(errp);
> +}
> +
>  #else /* defined(__linux__) */
>
>  void qmp_guest_suspend_disk(Error **errp)
> @@ -3131,6 +3221,13 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
>  return NULL;
>  }
>
> +GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp)
> +{
> +error_setg(errp, QERR_UNSUPPORTED);
> +return NULL;
> +}
> +
> +
>  #endif /* CONFIG_FSFREEZE */
>
>  #if !defined(CONFIG_FSTRIM)
> diff --git a/qga/commands-win32.c b/qga/commands-win32.c
> index d56b5fd2a7..dcdeb76a68 100644
> --- a/qga/commands-win32.c
> +++ b/qga/commands-win32.c
> @@ -2532,3 +2532,9 @@ char *qga_get_

Re: [PATCH v5 5/9] crypto: Implement RSA algorithm by hogweed

2022-05-13 Thread Daniel P . Berrangé
On Thu, Apr 28, 2022 at 09:59:39PM +0800, zhenwei pi wrote:
> From: Lei He 
> 
> Implement RSA algorithm by hogweed from nettle. Thus QEMU supports
> a 'real' RSA backend to handle request from guest side. It's
> important to test RSA offload case without OS & hardware requirement.
> 
> Signed-off-by: lei he 
> Signed-off-by: zhenwei pi 
> ---
>  crypto/akcipher-nettle.c.inc | 432 +++
>  crypto/akcipher.c|   4 +
>  crypto/meson.build   |   4 +
>  crypto/rsakey-builtin.c.inc  | 209 +
>  crypto/rsakey-nettle.c.inc   | 154 +
>  crypto/rsakey.c  |  44 
>  crypto/rsakey.h  |  94 
>  meson.build  |  11 +
>  8 files changed, 952 insertions(+)
>  create mode 100644 crypto/akcipher-nettle.c.inc
>  create mode 100644 crypto/rsakey-builtin.c.inc
>  create mode 100644 crypto/rsakey-nettle.c.inc
>  create mode 100644 crypto/rsakey.c
>  create mode 100644 crypto/rsakey.h
> 


> +
> +static void wrap_nettle_random_func(void *ctx, size_t len, uint8_t *out)
> +{
> +/* TODO: check result */
> +qcrypto_random_bytes(out, len, NULL);
> +}

Unfortunate meson requires this function to be void.

Since we've no way to report errors, then our only option is assume
qcrypto_random_bytes will never fail, and enforce that assumptiomn
by passing '&error_abort' for the last parameter.

> +
> +static int qcrypto_nettle_rsa_encrypt(QCryptoAkCipher *akcipher,
> +  const void *data, size_t data_len,
> +  void *enc, size_t enc_len,
> +  Error **errp)
> +{
> +
> +QCryptoNettleRSA *rsa = (QCryptoNettleRSA *)akcipher;
> +mpz_t c;
> +int ret = -1;
> +
> +if (data_len > rsa->pub.size || enc_len != rsa->pub.size) {
> +error_setg(errp, "Invalid buffer size");
> +return ret;
> +}

Can you report the invalid & expect buffer sizes, as it'll
make debugging much easier. You'll need a separate check
and error reporting for enc_len and data_len.

> +
> +/* Nettle do not support RSA encryption without any padding */
> +switch (rsa->padding_alg) {
> +case QCRYPTO_RSA_PADDING_ALG_RAW:
> +error_setg(errp, "RSA with raw padding is not supported");
> +break;
> +
> +case QCRYPTO_RSA_PADDING_ALG_PKCS1:
> +mpz_init(c);
> +if (rsa_encrypt(&rsa->pub, NULL, wrap_nettle_random_func,
> +  data_len, (uint8_t *)data, c) != 1) {
> +error_setg(errp, "Failed to encrypt");
> +} else {
> +nettle_mpz_get_str_256(enc_len, (uint8_t *)enc, c);
> +ret = enc_len;
> +}
> +mpz_clear(c);
> +break;
> +
> +default:
> +error_setg(errp, "Unknown padding");
> +}
> +
> +return ret;
> +}
> +
> +static int qcrypto_nettle_rsa_decrypt(QCryptoAkCipher *akcipher,
> +  const void *enc, size_t enc_len,
> +  void *data, size_t data_len,
> +  Error **errp)
> +{
> +QCryptoNettleRSA *rsa = (QCryptoNettleRSA *)akcipher;
> +mpz_t c;
> +int ret = -1;
> +if (enc_len > rsa->priv.size) {
> +error_setg(errp, "Invalid buffer size");
> +return ret;
> +}

Again please report the invalid & expected sizes in the message

We don't need to validate 'data_len' in the decrypt case,
as you did in encrypt ?

> +
> +switch (rsa->padding_alg) {
> +case QCRYPTO_RSA_PADDING_ALG_RAW:
> +error_setg(errp, "RSA with raw padding is not supported");
> +break;
> +
> +case QCRYPTO_RSA_PADDING_ALG_PKCS1:
> +nettle_mpz_init_set_str_256_u(c, enc_len, enc);
> +if (!rsa_decrypt(&rsa->priv, &data_len, (uint8_t *)data, c)) {
> +error_setg(errp, "Failed to decrypt");
> +} else {
> +ret = data_len;
> +}
> +
> +mpz_clear(c);
> +break;
> +
> +default:
> +ret = -1;

'ret' was initialized to '-1' at time of declaration

> +error_setg(errp, "Unknown padding");
> +}
> +
> +return ret;
> +}
> +
> +static int qcrypto_nettle_rsa_sign(QCryptoAkCipher *akcipher,
> +   const void *data, size_t data_len,
> +   void *sig, size_t sig_len, Error **errp)
> +{
> +QCryptoNettleRSA *rsa = (QCryptoNettleRSA *)akcipher;
> +int ret;

For consistency with the earlier methods, initialize this to -1

> +mpz_t s;
> +
> +/**
> + * The RSA algorithm cannot be used for signature/verification
> + * without padding.
> + */
> +if (rsa->padding_alg == QCRYPTO_RSA_PADDING_ALG_RAW) {
> +error_setg(errp, "Try to make signature without padding");
> +return -1;
> +}
> +
> +if (data_len > rsa->priv.size || sig_len != rsa->priv.size) {
> +error_setg(errp

[PATCH] vhost-user: more master/slave things

2022-05-13 Thread Michael S. Tsirkin
we switched to front-end/back-end, but newer patches
reintroduced old language. Fix this up.

Signed-off-by: Michael S. Tsirkin 
---
 docs/interop/vhost-user.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 73e710fe32..3c12607517 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -340,7 +340,7 @@ drivers cannot negotiate it.
 
 This reserved feature bit was reused by the vhost-user protocol to add
 vhost-user protocol feature negotiation in a backwards compatible
-fashion. Old vhost-user master and slave implementations continue to
+fashion. Old vhost-user front-end and back-end implementations continue to
 work even though they are not aware of vhost-user protocol feature
 negotiation.
 
-- 
MST




Re: [PATCH v5 6/9] crypto: Implement RSA algorithm by gcrypt

2022-05-13 Thread Daniel P . Berrangé
On Thu, Apr 28, 2022 at 09:59:40PM +0800, zhenwei pi wrote:
> From: Lei He 
> 
> Added gcryt implementation of RSA algorithm, RSA algorithm
> implemented by gcrypt has a higher priority than nettle because
> it supports raw padding.
> 
> Signed-off-by: lei he 
> ---
>  crypto/akcipher-gcrypt.c.inc | 520 +++
>  crypto/akcipher.c|   4 +-
>  2 files changed, 523 insertions(+), 1 deletion(-)
>  create mode 100644 crypto/akcipher-gcrypt.c.inc
> 
> diff --git a/crypto/akcipher-gcrypt.c.inc b/crypto/akcipher-gcrypt.c.inc
> new file mode 100644
> index 00..32ff502f71
> --- /dev/null
> +++ b/crypto/akcipher-gcrypt.c.inc
> @@ -0,0 +1,520 @@
> +/*
> + * QEMU Crypto akcipher algorithms
> + *
> + * Copyright (c) 2022 Bytedance
> + * Author: lei he 
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see 
> .
> + *
> + */
> +
> +#include 
> +
> +#include "qemu/osdep.h"
> +#include "qemu/host-utils.h"
> +#include "crypto/akcipher.h"
> +#include "crypto/random.h"
> +#include "qapi/error.h"
> +#include "sysemu/cryptodev.h"
> +#include "rsakey.h"
> +
> +typedef struct QCryptoGcryptRSA {
> +QCryptoAkCipher akcipher;
> +gcry_sexp_t key;
> +QCryptoRSAPaddingAlgorithm padding_alg;
> +QCryptoHashAlgorithm hash_alg;
> +} QCryptoGcryptRSA;
> +
> +static void qcrypto_gcrypt_rsa_free(QCryptoAkCipher *akcipher)
> +{
> +QCryptoGcryptRSA *rsa = (QCryptoGcryptRSA *)akcipher;
> +if (!rsa) {
> +return;
> +}
> +
> +gcry_sexp_release(rsa->key);
> +g_free(rsa);
> +}
> +
> +static QCryptoGcryptRSA *qcrypto_gcrypt_rsa_new(
> +const QCryptoAkCipherOptionsRSA *opt,
> +QCryptoAkCipherKeyType type,
> +const uint8_t *key,  size_t keylen,
> +Error **errp);
> +
> +QCryptoAkCipher *qcrypto_akcipher_new(const QCryptoAkCipherOptions *opts,
> +  QCryptoAkCipherKeyType type,
> +  const uint8_t *key, size_t keylen,
> +  Error **errp)
> +{
> +switch (opts->alg) {
> +case QCRYPTO_AKCIPHER_ALG_RSA:
> +return (QCryptoAkCipher *)qcrypto_gcrypt_rsa_new(
> +&opts->u.rsa, type, key, keylen, errp);
> +
> +default:
> +error_setg(errp, "Unsupported algorithm: %u", opts->alg);
> +return NULL;
> +}
> +
> +return NULL;
> +}
> +
> +static void qcrypto_gcrypt_set_rsa_size(QCryptoAkCipher *akcipher, 
> gcry_mpi_t n)
> +{
> +size_t key_size = (gcry_mpi_get_nbits(n) + 7) / 8;
> +akcipher->max_plaintext_len = key_size;
> +akcipher->max_ciphertext_len = key_size;
> +akcipher->max_dgst_len = key_size;
> +akcipher->max_signature_len = key_size;
> +}
> +
> +static int qcrypto_gcrypt_parse_rsa_private_key(
> +QCryptoGcryptRSA *rsa,
> +const uint8_t *key, size_t keylen)
> +{
> +g_autoptr(QCryptoAkCipherRSAKey) rsa_key = qcrypto_akcipher_rsakey_parse(
> +QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE, key, keylen);
> +gcry_mpi_t n = NULL, e = NULL, d = NULL, p = NULL, q = NULL, u = NULL;
> +bool compute_mul_inv = false;
> +int ret = -1;
> +gcry_error_t err;
> +
> +if (!rsa_key) {
> +return ret;
> +}

If qcrypto_akcipher_rsakey_parse can fail, we need to get a
'Error **errp' in/out of it

> +
> +err = gcry_mpi_scan(&n, GCRYMPI_FMT_STD,
> +rsa_key->n.data, rsa_key->n.len, NULL);
> +if (gcry_err_code(err) != 0) {
> +goto cleanup;
> +}

Please add an 'Error **errp' parameter to this method, and
populate it with an error message that includes the output
of gcry_

> +
> +err = gcry_mpi_scan(&e, GCRYMPI_FMT_STD,
> +rsa_key->e.data, rsa_key->e.len, NULL);
> +if (gcry_err_code(err) != 0) {
> +goto cleanup;
> +}
> +
> +err = gcry_mpi_scan(&d, GCRYMPI_FMT_STD,
> +rsa_key->d.data, rsa_key->d.len, NULL);
> +if (gcry_err_code(err) != 0) {
> +goto cleanup;
> +}
> +
> +err = gcry_mpi_scan(&p, GCRYMPI_FMT_STD,
> +rsa_key->p.data, rsa_key->p.len, NULL);
> +if (gcry_err_code(err) != 0) {
> +goto cleanup;
> +}
> +
> +err = gcry_mpi_scan(&q, GCRYMPI_FMT_STD,
> +rsa_key->q.data, rsa_key->q.len, NULL);
> +if (gcry_err_code(err) != 0)

Re: [PATCH] vhost-user-scsi: avoid unlink(NULL) with fd passing

2022-05-13 Thread Michael S. Tsirkin
On Thu, May 12, 2022 at 04:57:13PM +0100, Peter Maydell wrote:
> On Wed, 27 Apr 2022 at 11:04, Stefan Hajnoczi  wrote:
> >
> > Commit 747421e949fc1eb3ba66b5fcccdb7ba051918241 ("Implements Backend
> > Program conventions for vhost-user-scsi") introduced fd-passing support
> > as part of implementing the vhost-user backend program conventions.
> >
> > When fd passing is used the UNIX domain socket path is NULL and we must
> > not call unlink(2).
> >
> > Fixes: Coverity CID 1488353
> > Fixes: 747421e949fc1eb3ba66b5fcccdb7ba051918241 ("Implements Backend 
> > Program conventions for vhost-user-scsi")
> > Signed-off-by: Stefan Hajnoczi 
> > ---
> >  contrib/vhost-user-scsi/vhost-user-scsi.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/contrib/vhost-user-scsi/vhost-user-scsi.c 
> > b/contrib/vhost-user-scsi/vhost-user-scsi.c
> > index b2c0f98253..08335d4b2b 100644
> > --- a/contrib/vhost-user-scsi/vhost-user-scsi.c
> > +++ b/contrib/vhost-user-scsi/vhost-user-scsi.c
> > @@ -433,7 +433,9 @@ out:
> >  if (vdev_scsi) {
> >  g_main_loop_unref(vdev_scsi->loop);
> >  g_free(vdev_scsi);
> > -unlink(opt_socket_path);
> > +if (opt_socket_path) {
> > +unlink(opt_socket_path);
> > +}
> >  }
> 
> Shouldn't this check-and-unlink be one level up, outside the
> "if (vdev_scsi)" ? There are error exit paths which get us to
> the 'out:' label where we have called unix_sock_new() but
> not yet done the g_new0() of vdev_scsi(). The only thing
> that needs to be guarded by "if (vdev_scsi)" is the
> g_main_loop_unref() (the g_free of vdev_scsi itself could
> be inside or outside, since g_free(NULL) is a nop).
> 
> thanks
> -- PMM

Stefan, want to respond?

-- 
MST




Re: [RFC PATCH v2 2/8] qapi: net: introduce a way to bypass qemu_opts_parse_noisily()

2022-05-13 Thread Markus Armbruster
Laurent Vivier  writes:

> As qemu_opts_parse_noisily() flattens the QAPI structures ("type" field
> of Netdev structure can collides with "type" field of SocketAddress),

To remember how this works, I have to write a more verbose version of
the above.  Why not post it then, so here goes.

qemu_init() passes the argument of -netdev, -nic, and -net to
net_client_parse().

net_client_parse() parses with qemu_opts_parse_noisily(), passing
QemuOptsList qemu_netdev_opts for -netdev, qemu_nic_opts for -nic, and
qemu_net_opts for -net.  Their desc[] are all empty, which means any
keys are accepted.  The result of the parse (a QemuOpts) is stored in
the QemuOptsList.

Note that QemuOpts is flat by design.  In some places, we layer non-flat
on top using dotted keys convention, but not here.

net_init_clients() iterates over the stored QemuOpts, and passes them to
net_init_netdev(), net_param_nic(), or net_init_client(), respectively.

These functions pass the QemuOpts to net_client_init().  They also do
other things with the QemuOpts, which we can ignore here.

net_client_init() uses the opts visitor to convert the (flat) QemOpts to
a (non-flat) QAPI object Netdev.  Netdev is also the argument of QMP
command netdev_add.

The opts visitor was an early attempt to support QAPI in
(QemuOpts-based) CLI.  It restricts QAPI types to a certain shape; see
commit eb7ee2cbeb "qapi: introduce OptsVisitor".

A more modern way to support QAPI is qobject_input_visitor_new_str().
It uses keyval_parse() instead of QemuOpts for KEY=VALUE,... syntax, and
it also supports JSON syntax.  The former isn't quite as expressive as
JSON, but it's a lot closer than QemuOpts + opts visitor.

> we introduce a way to bypass qemu_opts_parse_noisily() and use directly
> visit_type_Netdev() to parse the backend parameters.

This commit paves the way to use of the modern way instead.

> Signed-off-by: Laurent Vivier 
> ---
>  net/net.c | 54 ++
>  1 file changed, 54 insertions(+)
>
> diff --git a/net/net.c b/net/net.c
> index 58c05c200622..2aab7167316c 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -54,6 +54,7 @@
>  #include "net/colo-compare.h"
>  #include "net/filter.h"
>  #include "qapi/string-output-visitor.h"
> +#include "qapi/qobject-input-visitor.h"
>  
>  /* Net bridge is currently not supported for W32. */
>  #if !defined(_WIN32)
> @@ -63,6 +64,17 @@
>  static VMChangeStateEntry *net_change_state_entry;
>  static QTAILQ_HEAD(, NetClientState) net_clients;
>  
> +typedef struct NetdevQueueEntry {
> +bool is_netdev;
> +Netdev *nd;
> +Location loc;
> +QSIMPLEQ_ENTRY(NetdevQueueEntry) entry;
> +} NetdevQueueEntry;
> +
> +typedef QSIMPLEQ_HEAD(, NetdevQueueEntry) NetdevQueue;
> +
> +static NetdevQueue nd_queue = QSIMPLEQ_HEAD_INITIALIZER(nd_queue);
> +
>  /***/
>  /* network device redirectors */
>  
> @@ -1559,6 +1571,19 @@ int net_init_clients(Error **errp)
>  
>  QTAILQ_INIT(&net_clients);
>  
> +while (!QSIMPLEQ_EMPTY(&nd_queue)) {
> +NetdevQueueEntry *nd = QSIMPLEQ_FIRST(&nd_queue);
> +
> +QSIMPLEQ_REMOVE_HEAD(&nd_queue, entry);
> +loc_push_restore(&nd->loc);
> +if (net_client_init1(nd->nd, nd->is_netdev, errp) < 0) {

I think you need to loc_pop() here.

> +return -1;
> +}

Since the only caller passes &error_fatal, I'd be tempted to ditch the
@errp argument, and simply do

   net_client_init1(nd->nd, nd->is_netdev, &error_fatal);

It's what we do for -blockdev, -device, and -object.

> +loc_pop(&nd->loc);
> +qapi_free_Netdev(nd->nd);
> +g_free(nd);
> +}
> +
>  if (qemu_opts_foreach(qemu_find_opts("netdev"),
>net_init_netdev, NULL, errp)) {
>  return -1;
> @@ -1575,8 +1600,37 @@ int net_init_clients(Error **errp)
>  return 0;
>  }
>  
> +/*
> + * netdev_is_modern() returns true when the backend needs to bypass
> + * qemu_opts_parse_noisily()
> + */
> +static bool netdev_is_modern(const char *optarg)
> +{
> +return false;
> +}
> +
>  int net_client_parse(QemuOptsList *opts_list, const char *optarg)
>  {
> +if (netdev_is_modern(optarg)) {
> +/*
> + * We need to bypass qemu_opts_parse_noisily() to accept
> + * new style object like addr.type=inet in SocketAddress
> + */

I'm not sure this will makes sense to future readers.

What about "Use modern, more expressive syntax"?

> +Visitor *v;
> +NetdevQueueEntry *nd;
> +
> +v = qobject_input_visitor_new_str(optarg, "type",
> +  &error_fatal);
> +nd = g_new(NetdevQueueEntry, 1);
> +visit_type_Netdev(v, NULL, &nd->nd, &error_fatal);
> +visit_free(v);
> +loc_save(&nd->loc);
> +nd->is_netdev = strcmp(opts_list->name, "netdev") == 0;
> +
> + 

Re: [PATCH] pc: q35: Bump max_cpus to 512

2022-05-13 Thread Michael S. Tsirkin
On Mon, May 09, 2022 at 09:12:49AM +0200, Igor Mammedov wrote:
> On Wed, 4 May 2022 08:16:39 -0500
> Suravee Suthikulpanit  wrote:
> 
> > This is the maximum number of vCPU supported by
> > the AMD x2APIC virtualization.
> > 
> > Signed-off-by: Suravee Suthikulpanit 
> > ---
> >  hw/i386/pc_q35.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > index 302288342a..e82b1c690d 100644
> > --- a/hw/i386/pc_q35.c
> > +++ b/hw/i386/pc_q35.c
> > @@ -357,7 +357,7 @@ static void pc_q35_machine_options(MachineClass *m)
> >  machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE);
> >  machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
> >  machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
> > -m->max_cpus = 288;
> > +m->max_cpus = 512;
> 
> Maybe we should bump it to KVM VCPU maximum,
> and make sure we error out if asked for combination of
> hardware/irqchip is not usable.

So what happens if one does 710 and then tries to use AMD x2APIC?
We'd like that to error out, right?

> 
> >  }
> >  
> >  static void pc_q35_7_1_machine_options(MachineClass *m)




Re: [PATCH 1/3] hw/ide/piix: Remove redundant "piix3-ide-xen" device class

2022-05-13 Thread Michael S. Tsirkin
On Sun, May 08, 2022 at 12:34:30PM +0200, Bernhard Beschow wrote:
> Commit 0f8445820f11a69154309863960328dda3dc1ad4 'xen: piix reuse pci
> generic class init function' already resolved redundant code which in
> turn rendered piix3-ide-xen redundant.
> 
> Signed-off-by: Bernhard Beschow 

Cc xen maintainers for review please.

> ---
>  hw/i386/pc_piix.c | 3 +--
>  hw/ide/piix.c | 7 ---
>  2 files changed, 1 insertion(+), 9 deletions(-)
> 
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index 4c185c72d0..27dfde4917 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -244,8 +244,7 @@ static void pc_init1(MachineState *machine,
>  if (pcmc->pci_enabled) {
>  PCIDevice *dev;
>  
> -dev = pci_create_simple(pci_bus, piix3_devfn + 1,
> -xen_enabled() ? "piix3-ide-xen" : 
> "piix3-ide");
> +dev = pci_create_simple(pci_bus, piix3_devfn + 1, "piix3-ide");
>  pci_ide_create_devs(dev);
>  idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
>  idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index ce89fd0aa3..2345fe9e1d 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -241,12 +241,6 @@ static const TypeInfo piix3_ide_info = {
>  .class_init= piix3_ide_class_init,
>  };
>  
> -static const TypeInfo piix3_ide_xen_info = {
> -.name  = "piix3-ide-xen",
> -.parent= TYPE_PCI_IDE,
> -.class_init= piix3_ide_class_init,
> -};
> -
>  /* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */
>  static void piix4_ide_class_init(ObjectClass *klass, void *data)
>  {
> @@ -272,7 +266,6 @@ static const TypeInfo piix4_ide_info = {
>  static void piix_ide_register_types(void)
>  {
>  type_register_static(&piix3_ide_info);
> -type_register_static(&piix3_ide_xen_info);
>  type_register_static(&piix4_ide_info);
>  }
>  
> -- 
> 2.36.1




Re: [PATCH 00/11] Random cleanup patches

2022-05-13 Thread Michael S. Tsirkin
On Thu, May 05, 2022 at 06:17:54PM +0200, Bernhard Beschow wrote:
> This patch series contains random cleanups that I made while studying the 
> code.
> 
> Bernhard Beschow (11):
>   hw/rtc/mc146818rtc: Inline isa_connect_gpio_out() and remove it
>   hw: Reuse TYPE_I8042 define
>   hw/audio/cs4231a: Const'ify global tables
>   hw/i386/pc: Unexport PC_CPU_MODEL_IDS macro
>   hw/i386/pc: Unexport functions used only internally
>   hw/i386/pc: Remove orphan declarations
>   hw/ppc/e500: Remove unused BINARY_DEVICE_TREE_FILE
>   hw/net/fsl_etsec/etsec: Remove obsolete and unused etsec_create()
>   accel/tcg/cpu-exec: Unexport dump_drift_info()
>   accel/tcg: Inline dump_opcount_info() and remove it
>   docs/devel: Fix link to developer mailing lists

pc changes looks like trivial tree material.
Acked-by: Michael S. Tsirkin 


>  accel/tcg/cpu-exec.c  |  4 ++--
>  accel/tcg/translate-all.c |  5 -
>  docs/devel/submitting-a-patch.rst |  6 +++---
>  hw/audio/cs4231a.c|  8 
>  hw/i386/pc.c  | 17 +
>  hw/isa/isa-bus.c  |  6 --
>  hw/net/fsl_etsec/etsec.c  | 23 ---
>  hw/net/fsl_etsec/etsec.h  |  7 ---
>  hw/ppc/e500.c |  1 -
>  hw/rtc/mc146818rtc.c  |  3 ++-
>  hw/sparc64/sun4u.c|  2 +-
>  include/exec/cpu-all.h|  3 ---
>  include/hw/i386/pc.h  | 14 --
>  include/hw/isa/isa.h  |  1 -
>  14 files changed, 25 insertions(+), 75 deletions(-)
> 
> -- 
> 2.36.0
> 
> 
> 




Re: [RFC PATCH v2 3/8] qapi: net: add stream and dgram netdevs

2022-05-13 Thread Markus Armbruster
Laurent Vivier  writes:

> Copied from socket netdev file and modified to use SocketAddress
> to be able to introduce new features like unix socket.
>
> "udp" and "mcast" are squashed into dgram netdev, multicast is detected
> according to the IP address type.
> "listen" and "connect" modes are managed by stream netdev. An optional
> parameter "server" defines the mode (server by default)
>
> Signed-off-by: Laurent Vivier 
> ---
>  hmp-commands.hx |   2 +-
>  net/clients.h   |   6 +
>  net/dgram.c | 630 
>  net/hub.c   |   2 +
>  net/meson.build |   2 +
>  net/net.c   |  24 +-
>  net/stream.c| 425 
>  qapi/net.json   |  38 ++-
>  8 files changed, 1125 insertions(+), 4 deletions(-)
>  create mode 100644 net/dgram.c
>  create mode 100644 net/stream.c
>
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 03e6a73d1f55..172dbab1dfed 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1269,7 +1269,7 @@ ERST
>  {
>  .name   = "netdev_add",
>  .args_type  = "netdev:O",
> -.params = 
> "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
> +.params = 
> "[user|tap|socket|stream|dgram|vde|bridge|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
>  .help   = "add host network device",
>  .cmd= hmp_netdev_add,
>  .command_completion = netdev_add_completion,

Does qemu-options.hx need an update, too?

> diff --git a/net/clients.h b/net/clients.h
> index 92f9b59aedce..c1b51d79b147 100644
> --- a/net/clients.h
> +++ b/net/clients.h
> @@ -40,6 +40,12 @@ int net_init_hubport(const Netdev *netdev, const char 
> *name,
>  int net_init_socket(const Netdev *netdev, const char *name,
>  NetClientState *peer, Error **errp);
>  
> +int net_init_stream(const Netdev *netdev, const char *name,
> +NetClientState *peer, Error **errp);
> +
> +int net_init_dgram(const Netdev *netdev, const char *name,
> +   NetClientState *peer, Error **errp);
> +
>  int net_init_tap(const Netdev *netdev, const char *name,
>   NetClientState *peer, Error **errp);
>  
> diff --git a/net/dgram.c b/net/dgram.c
> new file mode 100644
> index ..aa4240501ed0
> --- /dev/null
> +++ b/net/dgram.c
> @@ -0,0 +1,630 @@
> +/*
> + * QEMU System Emulator
> + *
> + * Copyright (c) 2003-2008 Fabrice Bellard
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */

Blank line here, please.

Why not GPLv2+?

> +#include "qemu/osdep.h"

[...]

> diff --git a/net/net.c b/net/net.c
> index 2aab7167316c..fd6b30a10c57 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -1015,6 +1015,8 @@ static int (* const 
> net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
>  #endif
>  [NET_CLIENT_DRIVER_TAP]   = net_init_tap,
>  [NET_CLIENT_DRIVER_SOCKET]= net_init_socket,
> +[NET_CLIENT_DRIVER_STREAM]= net_init_stream,
> +[NET_CLIENT_DRIVER_DGRAM] = net_init_dgram,
>  #ifdef CONFIG_VDE
>  [NET_CLIENT_DRIVER_VDE]   = net_init_vde,
>  #endif
> @@ -1097,6 +1099,8 @@ void show_netdevs(void)
>  int idx;
>  const char *available_netdevs[] = {
>  "socket",
> +"stream",
> +"dgram",
>  "hubport",
>  "tap",
>  #ifdef CONFIG_SLIRP
> @@ -1606,7 +1610,25 @@ int net_init_clients(Error **errp)
>   */
>  static bool netdev_is_modern(const char *optarg)
>  {
> -return false;
> +static QemuOptsList dummy_opts = {
> +.name = "netdev",
> +.implied_opt_name = "type",
> +.head = QTAILQ_HEAD_INITIALIZER(dummy_opts.head),
> +.desc = { { } },
> +};
> +const char *netdev;
> +QemuOpts *opts;
> +bool is_modern;
> +
> +opts = qemu_opts_parse(&dummy_opts, optarg, true, &error_fatal);

[PATCH qemu v18 02/16] target/riscv: rvv: Prune redundant access_type parameter passed

2022-05-13 Thread ~eopxd
From: eopXD 

No functional change intended in this commit.

Signed-off-by: eop Chen 
---
 target/riscv/vector_helper.c | 35 ---
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 85dd611cd9..60840325c4 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -231,7 +231,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
  target_ulong stride, CPURISCVState *env,
  uint32_t desc, uint32_t vm,
  vext_ldst_elem_fn *ldst_elem,
- uint32_t esz, uintptr_t ra, MMUAccessType access_type)
+ uint32_t esz, uintptr_t ra)
 {
 uint32_t i, k;
 uint32_t nf = vext_nf(desc);
@@ -259,7 +259,7 @@ void HELPER(NAME)(void *vd, void * v0, target_ulong base,   
\
 {   \
 uint32_t vm = vext_vm(desc);\
 vext_ldst_stride(vd, v0, base, stride, env, desc, vm, LOAD_FN,  \
- ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD);  \
+ ctzl(sizeof(ETYPE)), GETPC()); \
 }
 
 GEN_VEXT_LD_STRIDE(vlse8_v,  int8_t,  lde_b)
@@ -274,7 +274,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base,
\
 {   \
 uint32_t vm = vext_vm(desc);\
 vext_ldst_stride(vd, v0, base, stride, env, desc, vm, STORE_FN, \
- ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \
+ ctzl(sizeof(ETYPE)), GETPC()); \
 }
 
 GEN_VEXT_ST_STRIDE(vsse8_v,  int8_t,  ste_b)
@@ -290,7 +290,7 @@ GEN_VEXT_ST_STRIDE(vsse64_v, int64_t, ste_d)
 static void
 vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
  vext_ldst_elem_fn *ldst_elem, uint32_t esz, uint32_t evl,
- uintptr_t ra, MMUAccessType access_type)
+ uintptr_t ra)
 {
 uint32_t i, k;
 uint32_t nf = vext_nf(desc);
@@ -319,14 +319,14 @@ void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong 
base, \
 {   \
 uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE)); \
 vext_ldst_stride(vd, v0, base, stride, env, desc, false, LOAD_FN,   \
- ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD);  \
+ ctzl(sizeof(ETYPE)), GETPC()); \
 }   \
 \
 void HELPER(NAME)(void *vd, void *v0, target_ulong base,\
   CPURISCVState *env, uint32_t desc)\
 {   \
 vext_ldst_us(vd, base, env, desc, LOAD_FN,  \
- ctzl(sizeof(ETYPE)), env->vl, GETPC(), MMU_DATA_LOAD); \
+ ctzl(sizeof(ETYPE)), env->vl, GETPC());\
 }
 
 GEN_VEXT_LD_US(vle8_v,  int8_t,  lde_b)
@@ -340,14 +340,14 @@ void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong 
base,  \
 {\
 uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE));  \
 vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN,   \
- ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE);  \
+ ctzl(sizeof(ETYPE)), GETPC());  \
 }\
  \
 void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
   CPURISCVState *env, uint32_t desc) \
 {\
 vext_ldst_us(vd, base, env, desc, STORE_FN,  \
- ctzl(sizeof(ETYPE)), env->vl, GETPC(), MMU_DATA_STORE); \
+ ctzl(sizeof(ETYPE)), env->vl, GETPC()); \
 }
 
 GEN_VEXT_ST_US(vse8_v,  int8_t,  ste_b)
@@ -364,7 +364,7 @@ void HELPER(vlm_v)(void *vd, void *v0, target_ulong base,
 /* evl = ceil(vl/8) */
 uint8_t evl = (env->vl + 7) >> 3;
 vext_ldst_us(vd, base, env, desc, lde_b,
- 0, evl, GETPC(), MMU_DATA_LOAD);
+ 0, evl, GETPC());
 }
 
 void HELPER(vsm_v)(void *vd, void *v0, target_ulong base,
@@ -373,7 +373,7 @@ void HELPER(vsm_v)(void *vd, void *v0, target_ulong base,
 /* evl = ceil(vl/8) */
 uint8_t evl = (env->vl + 7) >> 3;
 vext_ldst_us(vd, base, env, desc, ste_b,
-

[PATCH qemu v18 08/16] target/riscv: rvv: Add tail agnostic for vector integer shift instructions

2022-05-13 Thread ~eopxd
From: eopXD 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  3 ++-
 target/riscv/vector_helper.c| 11 +++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 81f227f074..b03d459d84 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1827,7 +1827,7 @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, 
GVecGen2sFn32 *gvec_fn,
 return false;
 }
 
-if (a->vm && s->vl_eq_vlmax) {
+if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 TCGv_i32 src1 = tcg_temp_new_i32();
 
 tcg_gen_trunc_tl_i32(src1, get_gpr(s, a->rs1, EXT_NONE));
@@ -1886,6 +1886,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1),\
vreg_ofs(s, a->rs2), cpu_env,   \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 3bcde37e28..9738c50222 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1270,6 +1270,9 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
+uint32_t esz = sizeof(TS1);   \
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);  \
+uint32_t vta = vext_vta(desc);\
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
@@ -1281,6 +1284,8 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
 *((TS1 *)vd + HS1(i)) = OP(s2, s1 & MASK);\
 } \
 env->vstart = 0;  \
+/* set tail elements to 1s */ \
+vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);  \
 }
 
 GEN_VEXT_SHIFT_VV(vsll_vv_b, uint8_t,  uint8_t, H1, H1, DO_SLL, 0x7)
@@ -1305,6 +1310,10 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1,   
   \
 {   \
 uint32_t vm = vext_vm(desc);\
 uint32_t vl = env->vl;  \
+uint32_t esz = sizeof(TD);  \
+uint32_t total_elems =  \
+vext_get_total_elems(env, desc, esz);   \
+uint32_t vta = vext_vta(desc);  \
 uint32_t i; \
 \
 for (i = env->vstart; i < vl; i++) {\
@@ -1315,6 +1324,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1,
  \
 *((TD *)vd + HD(i)) = OP(s2, s1 & MASK);\
 }   \
 env->vstart = 0;\
+/* set tail elements to 1s */   \
+vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);\
 }
 
 GEN_VEXT_SHIFT_VX(vsll_vx_b, uint8_t, int8_t, H1, H1, DO_SLL, 0x7)
-- 
2.34.2




[PATCH qemu v18 04/16] target/riscv: rvv: Early exit when vstart >= vl

2022-05-13 Thread ~eopxd
From: eopXD 

According to v-spec (section 5.4):
When vstart ≥ vl, there are no body elements, and no elements are
updated in any destination vector register group, including that
no tail elements are updated with agnostic values.

vmsbf.m, vmsif.m, vmsof.m, viota.m, vcompress instructions themselves
require vstart to be zero. So they don't need the early exit.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 27 +
 1 file changed, 27 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 90327509f7..4d5dfa794a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -652,6 +652,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
@@ -818,6 +819,7 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, 
uint32_t rs2,
 
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
@@ -925,6 +927,7 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2,
 
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
@@ -1067,6 +1070,7 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
@@ -1221,6 +1225,7 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 }
 
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 if (a->vm && s->vl_eq_vlmax) {
 gvec_fn(s->sew, vreg_ofs(s, a->rd),
@@ -1268,6 +1273,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2, uint32_t vm,
 
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
@@ -1432,6 +1438,7 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, 
uint32_t vs2, uint32_t vm,
 
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
@@ -1518,6 +1525,7 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
@@ -1598,6 +1606,7 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
@@ -1675,6 +1684,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 }; \
 TCGLabel *over = gen_new_label();  \
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -1856,6 +1866,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 }; \
 TCGLabel *over = gen_new_label();  \
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
@@ -2066,6 +2077,7 @@ static bool trans_v

[PATCH qemu v18 03/16] target/riscv: rvv: Rename ambiguous esz

2022-05-13 Thread ~eopxd
From: eopXD 

No functional change intended in this commit.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 76 ++--
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 60840325c4..3b79b9cbc2 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -125,9 +125,9 @@ static inline int32_t vext_lmul(uint32_t desc)
 /*
  * Get the maximum number of elements can be operated.
  *
- * esz: log2 of element size in bytes.
+ * log2_esz: log2 of element size in bytes.
  */
-static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz)
+static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
 {
 /*
  * As simd_desc support at most 2048 bytes, the max vlen is 1024 bits.
@@ -136,7 +136,7 @@ static inline uint32_t vext_max_elems(uint32_t desc, 
uint32_t esz)
 uint32_t vlenb = simd_maxsz(desc);
 
 /* Return VLMAX */
-int scale = vext_lmul(desc) - esz;
+int scale = vext_lmul(desc) - log2_esz;
 return scale < 0 ? vlenb >> -scale : vlenb << scale;
 }
 
@@ -231,11 +231,11 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
  target_ulong stride, CPURISCVState *env,
  uint32_t desc, uint32_t vm,
  vext_ldst_elem_fn *ldst_elem,
- uint32_t esz, uintptr_t ra)
+ uint32_t log2_esz, uintptr_t ra)
 {
 uint32_t i, k;
 uint32_t nf = vext_nf(desc);
-uint32_t max_elems = vext_max_elems(desc, esz);
+uint32_t max_elems = vext_max_elems(desc, log2_esz);
 
 for (i = env->vstart; i < env->vl; i++, env->vstart++) {
 if (!vm && !vext_elem_mask(v0, i)) {
@@ -244,7 +244,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
 
 k = 0;
 while (k < nf) {
-target_ulong addr = base + stride * i + (k << esz);
+target_ulong addr = base + stride * i + (k << log2_esz);
 ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
 }
@@ -289,18 +289,18 @@ GEN_VEXT_ST_STRIDE(vsse64_v, int64_t, ste_d)
 /* unmasked unit-stride load and store operation*/
 static void
 vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
- vext_ldst_elem_fn *ldst_elem, uint32_t esz, uint32_t evl,
+ vext_ldst_elem_fn *ldst_elem, uint32_t log2_esz, uint32_t evl,
  uintptr_t ra)
 {
 uint32_t i, k;
 uint32_t nf = vext_nf(desc);
-uint32_t max_elems = vext_max_elems(desc, esz);
+uint32_t max_elems = vext_max_elems(desc, log2_esz);
 
 /* load bytes from guest memory */
 for (i = env->vstart; i < evl; i++, env->vstart++) {
 k = 0;
 while (k < nf) {
-target_ulong addr = base + ((i * nf + k) << esz);
+target_ulong addr = base + ((i * nf + k) << log2_esz);
 ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
 }
@@ -399,12 +399,12 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
 void *vs2, CPURISCVState *env, uint32_t desc,
 vext_get_index_addr get_index_addr,
 vext_ldst_elem_fn *ldst_elem,
-uint32_t esz, uintptr_t ra)
+uint32_t log2_esz, uintptr_t ra)
 {
 uint32_t i, k;
 uint32_t nf = vext_nf(desc);
 uint32_t vm = vext_vm(desc);
-uint32_t max_elems = vext_max_elems(desc, esz);
+uint32_t max_elems = vext_max_elems(desc, log2_esz);
 
 /* load bytes from guest memory */
 for (i = env->vstart; i < env->vl; i++, env->vstart++) {
@@ -414,7 +414,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
 
 k = 0;
 while (k < nf) {
-abi_ptr addr = get_index_addr(base, i, vs2) + (k << esz);
+abi_ptr addr = get_index_addr(base, i, vs2) + (k << log2_esz);
 ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
 }
@@ -480,13 +480,13 @@ static inline void
 vext_ldff(void *vd, void *v0, target_ulong base,
   CPURISCVState *env, uint32_t desc,
   vext_ldst_elem_fn *ldst_elem,
-  uint32_t esz, uintptr_t ra)
+  uint32_t log2_esz, uintptr_t ra)
 {
 void *host;
 uint32_t i, k, vl = 0;
 uint32_t nf = vext_nf(desc);
 uint32_t vm = vext_vm(desc);
-uint32_t max_elems = vext_max_elems(desc, esz);
+uint32_t max_elems = vext_max_elems(desc, log2_esz);
 target_ulong addr, offset, remain;
 
 /* probe every access*/
@@ -494,12 +494,12 @@ vext_ldff(void *vd, void *v0, target_ulong base,
 if (!vm && !vext_elem_mask(v0, i)) {
 continue;
 }
-addr = adjust_addr(env, base + i * (nf << esz));
+addr = adjust_addr(env, base + i * (nf << log2_esz));
 if (i == 0)

[PATCH qemu v18 00/16] Add tail agnostic behavior for rvv instructions

2022-05-13 Thread ~eopxd
According to v-spec, tail agnostic behavior can be either kept as
undisturbed or set elements' bits to all 1s. To distinguish the
difference of tail policies, QEMU should be able to simulate the tail
agnostic behavior as "set tail elements' bits to all 1s". An option
'rvv_ta_all_1s' is added to enable the behavior, it is default as
disabled.

There are multiple possibility for agnostic elements according to
v-spec. The main intent of this patch-set tries to add option that
can distinguish between tail policies. Setting agnostic elements to
all 1s makes things simple and allow QEMU to express this.

We may explore other possibility of agnostic behavior by adding
other options in the future. Please understand that this patch-set
is limited.

v2 updates:
- Addressed comments from Weiwei Li
- Added commit tail agnostic on load / store instructions (which
  I forgot to include into the patch-set)

v3 updates:
- Missed the very 1st commit, adding it back

v4 updates:
- Renamed vlmax to total_elems
- Deal with tail element when vl_eq_vlmax == true

v5 updates:
- Let `vext_get_total_elems` take `desc` and `esz`
- Utilize `simd_maxsz(desc)` to get `vlenb`
- Fix alignments to code

v6 updates:
- Fix `vext_get_total_elems`

v7 updates:
- Reuse `max_elems` for vector load / store helper functions. The
  translation sets desc's `lmul` to `min(1, lmul)`, making
  `vext_max_elems` equivalent to `vext_get_total_elems`.

v8 updates:
- Simplify `vext_set_elems_1s`, don't need `vext_set_elems_1s_fns`
- Fix `vext_get_total_elems`, it should derive upon EMUL instead
  of LMUL

v9 updates:
- Let instructions that is tail agnostic regardless of vta respect the
  option and not the vta.

v10 updates:
- Correct range to set element to 1s for load instructions

v11 updates:
- Separate addition of option 'rvv_ta_all_1s' as a new (last) commit
- Add description to show intent of the option in first commit for the
  optional tail agnostic behavior
- Tag WeiWei as Reviewed-by for all commits
- Tag Alistair as Reviewed-by for commit 01, 02
- Tag Alistair as Acked-by for commit 03

v12 updates:
- Add missing space in WeiWei's "Reviewed-by" tag

v13 updates:
- Fix tail agnostic for vext_ldst_us. The function operates on input
  parameter 'evl' rather than 'env->vl'.
- Fix tail elements for vector segment load / store instructions
  A vector segment load / store instruction may contain fractional
  lmul with nf * lmul > 1. The rest of the elements in the last
  register should be treated as tail elements.
- Fix tail agnostic length for instructions with mask destination
  register. Instructions with mask destination register should have
  'vlen - vl' tail elements.

v14 updates:
- Pass lmul information to into vector helper function.
  `vext_get_total_elems` needs it.

v15 updates:
- Rebase to latest `master`
- Tag Alistair as Acked by for commit 04 ~ 14
- Tag Alistair as Acked by for commit 15

v16 updates:
- Fix bug, when encountering situation when lmul < 0 and vl_eq_vlmax,
  the original version will override on `vd` but the computation will
  override again, meaning the tail elements will not be set correctly.
  Now, we don't use TCG functions if we are trying to simulate all 1s
  for agnostic and use vector helpers instead.

v17 updates:
- Add "Prune access_type parameter" commit to cleanup vector load/
  store functions. Then add parameter `is_load` in vector helper
  functions to enable vta behavior in the commit for adding vta on
  vector load/store functions.

v18 updates:
- Don't use `is_load` parameter in vector helper. Don't let vta pass
   through in `trans_rvv.inc`

eopXD (16):
  target/riscv: rvv: Prune redundant ESZ, DSZ parameter passed
  target/riscv: rvv: Prune redundant access_type parameter passed
  target/riscv: rvv: Rename ambiguous esz
  target/riscv: rvv: Early exit when vstart >= vl
  target/riscv: rvv: Add tail agnostic for vv instructions
  target/riscv: rvv: Add tail agnostic for vector load / store
instructions
  target/riscv: rvv: Add tail agnostic for vx, vvm, vxm instructions
  target/riscv: rvv: Add tail agnostic for vector integer shift
instructions
  target/riscv: rvv: Add tail agnostic for vector integer comparison
instructions
  target/riscv: rvv: Add tail agnostic for vector integer merge and move
instructions
  target/riscv: rvv: Add tail agnostic for vector fix-point arithmetic
instructions
  target/riscv: rvv: Add tail agnostic for vector floating-point
instructions
  target/riscv: rvv: Add tail agnostic for vector reduction instructions
  target/riscv: rvv: Add tail agnostic for vector mask instructions
  target/riscv: rvv: Add tail agnostic for vector permutation
instructions
  target/riscv: rvv: Add option 'rvv_ta_all_1s' to enable optional tail
agnostic behavior

 target/riscv/cpu.c  |1 +
 target/riscv/cpu.h  |2 +
 target/riscv/cpu_helper.c   |2 +
 target/riscv/insn_trans/trans_rvv.c.inc |   94 +-
 

[PATCH qemu v18 10/16] target/riscv: rvv: Add tail agnostic for vector integer merge and move instructions

2022-05-13 Thread ~eopxd
From: eopXD 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 
 target/riscv/vector_helper.c| 20 
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index b03d459d84..50f874ceae 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2082,12 +2082,13 @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v 
*a)
 vext_check_isa_ill(s) &&
 /* vmv.v.v has rs2 = 0 and vm = 1 */
 vext_check_sss(s, a->rd, a->rs1, 0, 1)) {
-if (s->vl_eq_vlmax) {
+if (s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 tcg_gen_gvec_mov(s->sew, vreg_ofs(s, a->rd),
  vreg_ofs(s, a->rs1),
  MAXSZ(s), MAXSZ(s));
 } else {
 uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 static gen_helper_gvec_2_ptr * const fns[4] = {
 gen_helper_vmv_v_v_b, gen_helper_vmv_v_v_h,
 gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
@@ -2122,7 +2123,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
 
 s1 = get_gpr(s, a->rs1, EXT_SIGN);
 
-if (s->vl_eq_vlmax) {
+if (s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
 MAXSZ(s), MAXSZ(s), s1);
 } else {
@@ -2130,6 +2131,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
 TCGv_i64 s1_i64 = tcg_temp_new_i64();
 TCGv_ptr dest = tcg_temp_new_ptr();
 uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 static gen_helper_vmv_vx * const fns[4] = {
 gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
 gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
@@ -2159,7 +2161,7 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
 /* vmv.v.i has rs2 = 0 and vm = 1 */
 vext_check_ss(s, a->rd, 0, 1)) {
 int64_t simm = sextract64(a->rs1, 0, 5);
-if (s->vl_eq_vlmax) {
+if (s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 tcg_gen_gvec_dup_imm(s->sew, vreg_ofs(s, a->rd),
  MAXSZ(s), MAXSZ(s), simm);
 mark_vs_dirty(s);
@@ -2168,6 +2170,7 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
 TCGv_i64 s1;
 TCGv_ptr dest;
 uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 static gen_helper_vmv_vx * const fns[4] = {
 gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
 gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
@@ -2739,7 +2742,7 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f 
*a)
 
 TCGv_i64 t1;
 
-if (s->vl_eq_vlmax) {
+if (s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 t1 = tcg_temp_new_i64();
 /* NaN-box f[rs1] */
 do_nanbox(s, t1, cpu_fpr[a->rs1]);
@@ -2751,6 +2754,7 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f 
*a)
 TCGv_ptr dest;
 TCGv_i32 desc;
 uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 static gen_helper_vmv_vx * const fns[3] = {
 gen_helper_vmv_v_x_h,
 gen_helper_vmv_v_x_w,
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index b964b01a15..2bf670920a 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1968,6 +1968,9 @@ void HELPER(NAME)(void *vd, void *vs1, CPURISCVState 
*env,   \
   uint32_t desc) \
 {\
 uint32_t vl = env->vl;   \
+uint32_t esz = sizeof(ETYPE);\
+uint32_t total_elems = vext_get_total_elems(env, desc, esz); \
+uint32_t vta = vext_vta(desc);   \
 uint32_t i;  \
  \
 for (i = env->vstart; i < vl; i++) { \
@@ -1975,6 +1978,8 @@ void HELPER(NAME)(void *vd, void *vs1, CPURISCVState 
*env,   \
 *((ETYPE *)vd + H(i)) = s1;  \
 }\
 env->vstart = 0;  

[PATCH qemu v18 01/16] target/riscv: rvv: Prune redundant ESZ, DSZ parameter passed

2022-05-13 Thread ~eopxd
From: eopXD 

No functional change intended in this commit.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 1132 +-
 1 file changed, 565 insertions(+), 567 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 576b14e5a3..85dd611cd9 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -710,7 +710,6 @@ RVVCALL(OPIVV2, vsub_vv_d, OP_SSS_D, H8, H8, H8, DO_SUB)
 
 static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
CPURISCVState *env, uint32_t desc,
-   uint32_t esz, uint32_t dsz,
opivv2_fn *fn)
 {
 uint32_t vm = vext_vm(desc);
@@ -727,23 +726,23 @@ static void do_vext_vv(void *vd, void *v0, void *vs1, 
void *vs2,
 }
 
 /* generate the helpers for OPIVV */
-#define GEN_VEXT_VV(NAME, ESZ, DSZ)   \
+#define GEN_VEXT_VV(NAME) \
 void HELPER(NAME)(void *vd, void *v0, void *vs1,  \
   void *vs2, CPURISCVState *env,  \
   uint32_t desc)  \
 { \
-do_vext_vv(vd, v0, vs1, vs2, env, desc, ESZ, DSZ, \
+do_vext_vv(vd, v0, vs1, vs2, env, desc,   \
do_##NAME);\
 }
 
-GEN_VEXT_VV(vadd_vv_b, 1, 1)
-GEN_VEXT_VV(vadd_vv_h, 2, 2)
-GEN_VEXT_VV(vadd_vv_w, 4, 4)
-GEN_VEXT_VV(vadd_vv_d, 8, 8)
-GEN_VEXT_VV(vsub_vv_b, 1, 1)
-GEN_VEXT_VV(vsub_vv_h, 2, 2)
-GEN_VEXT_VV(vsub_vv_w, 4, 4)
-GEN_VEXT_VV(vsub_vv_d, 8, 8)
+GEN_VEXT_VV(vadd_vv_b)
+GEN_VEXT_VV(vadd_vv_h)
+GEN_VEXT_VV(vadd_vv_w)
+GEN_VEXT_VV(vadd_vv_d)
+GEN_VEXT_VV(vsub_vv_b)
+GEN_VEXT_VV(vsub_vv_h)
+GEN_VEXT_VV(vsub_vv_w)
+GEN_VEXT_VV(vsub_vv_d)
 
 typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
 
@@ -773,7 +772,6 @@ RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB)
 
 static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
CPURISCVState *env, uint32_t desc,
-   uint32_t esz, uint32_t dsz,
opivx2_fn fn)
 {
 uint32_t vm = vext_vm(desc);
@@ -790,27 +788,27 @@ static void do_vext_vx(void *vd, void *v0, target_long 
s1, void *vs2,
 }
 
 /* generate the helpers for OPIVX */
-#define GEN_VEXT_VX(NAME, ESZ, DSZ)   \
+#define GEN_VEXT_VX(NAME) \
 void HELPER(NAME)(void *vd, void *v0, target_ulong s1,\
   void *vs2, CPURISCVState *env,  \
   uint32_t desc)  \
 { \
-do_vext_vx(vd, v0, s1, vs2, env, desc, ESZ, DSZ,  \
+do_vext_vx(vd, v0, s1, vs2, env, desc,\
do_##NAME);\
 }
 
-GEN_VEXT_VX(vadd_vx_b, 1, 1)
-GEN_VEXT_VX(vadd_vx_h, 2, 2)
-GEN_VEXT_VX(vadd_vx_w, 4, 4)
-GEN_VEXT_VX(vadd_vx_d, 8, 8)
-GEN_VEXT_VX(vsub_vx_b, 1, 1)
-GEN_VEXT_VX(vsub_vx_h, 2, 2)
-GEN_VEXT_VX(vsub_vx_w, 4, 4)
-GEN_VEXT_VX(vsub_vx_d, 8, 8)
-GEN_VEXT_VX(vrsub_vx_b, 1, 1)
-GEN_VEXT_VX(vrsub_vx_h, 2, 2)
-GEN_VEXT_VX(vrsub_vx_w, 4, 4)
-GEN_VEXT_VX(vrsub_vx_d, 8, 8)
+GEN_VEXT_VX(vadd_vx_b)
+GEN_VEXT_VX(vadd_vx_h)
+GEN_VEXT_VX(vadd_vx_w)
+GEN_VEXT_VX(vadd_vx_d)
+GEN_VEXT_VX(vsub_vx_b)
+GEN_VEXT_VX(vsub_vx_h)
+GEN_VEXT_VX(vsub_vx_w)
+GEN_VEXT_VX(vsub_vx_d)
+GEN_VEXT_VX(vrsub_vx_b)
+GEN_VEXT_VX(vrsub_vx_h)
+GEN_VEXT_VX(vrsub_vx_w)
+GEN_VEXT_VX(vrsub_vx_d)
 
 void HELPER(vec_rsubs8)(void *d, void *a, uint64_t b, uint32_t desc)
 {
@@ -889,30 +887,30 @@ RVVCALL(OPIVV2, vwadd_wv_w, WOP_WSSS_W, H8, H4, H4, 
DO_ADD)
 RVVCALL(OPIVV2, vwsub_wv_b, WOP_WSSS_B, H2, H1, H1, DO_SUB)
 RVVCALL(OPIVV2, vwsub_wv_h, WOP_WSSS_H, H4, H2, H2, DO_SUB)
 RVVCALL(OPIVV2, vwsub_wv_w, WOP_WSSS_W, H8, H4, H4, DO_SUB)
-GEN_VEXT_VV(vwaddu_vv_b, 1, 2)
-GEN_VEXT_VV(vwaddu_vv_h, 2, 4)
-GEN_VEXT_VV(vwaddu_vv_w, 4, 8)
-GEN_VEXT_VV(vwsubu_vv_b, 1, 2)
-GEN_VEXT_VV(vwsubu_vv_h, 2, 4)
-GEN_VEXT_VV(vwsubu_vv_w, 4, 8)
-GEN_VEXT_VV(vwadd_vv_b, 1, 2)
-GEN_VEXT_VV(vwadd_vv_h, 2, 4)
-GEN_VEXT_VV(vwadd_vv_w, 4, 8)
-GEN_VEXT_VV(vwsub_vv_b, 1, 2)
-GEN_VEXT_VV(vwsub_vv_h, 2, 4)
-GEN_VEXT_VV(vwsub_vv_w, 4, 8)
-GEN_VEXT_VV(vwaddu_wv_b, 1, 2)
-GEN_VEXT_VV(vwaddu_wv_h, 2, 4)
-GEN_VEXT_VV(vwaddu_wv_w, 4, 8)
-GEN_VEXT_VV(vwsubu_wv_b, 1, 2)
-GEN_VEXT_VV(vwsubu_wv_h, 2, 4)
-GEN_VEXT_VV(vwsubu_wv_w, 4, 8)
-GEN_VEXT_VV(vwadd_wv_b, 1, 2)
-GEN_VEXT_VV(vwadd_wv_h, 2, 4)
-GEN_VEXT_VV(vwadd_wv_w, 4, 8)
-GEN_VEXT_VV(vwsub_wv_b, 1, 2)
-GEN_VEXT_VV(vwsub_wv_h, 2, 4)
-GEN_VEXT_VV(vwsub_wv_w, 4, 8)
+GEN_VEXT_VV(vwaddu_vv_b)
+GEN_VEXT_VV(vwaddu_vv_h)
+GEN_VEXT_VV(vwaddu_vv_w)
+GEN_VEXT_VV(vwsubu_vv_b)
+GEN_VEXT_VV(vwsubu_vv_h)
+GEN_VEXT_VV(vwsubu_vv_w)
+GEN_VEXT_VV(vwadd_vv_b)
+GEN_VEXT_VV(vwadd_vv_h)
+GEN_VEXT_VV(vwadd

[PATCH qemu v18 05/16] target/riscv: rvv: Add tail agnostic for vv instructions

2022-05-13 Thread ~eopxd
From: eopXD 

According to v-spec, tail agnostic behavior can be either kept as
undisturbed or set elements' bits to all 1s. To distinguish the
difference of tail policies, QEMU should be able to simulate the tail
agnostic behavior as "set tail elements' bits to all 1s".

There are multiple possibility for agnostic elements according to
v-spec. The main intent of this patch-set tries to add option that
can distinguish between tail policies. Setting agnostic elements to
all 1s allows QEMU to express this.

This is the first commit regarding the optional tail agnostic
behavior. Follow-up commits will add this optional behavior
for all rvv instructions.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/cpu.h  |   2 +
 target/riscv/cpu_helper.c   |   2 +
 target/riscv/insn_trans/trans_rvv.c.inc |   3 +-
 target/riscv/internals.h|   5 +-
 target/riscv/translate.c|   2 +
 target/riscv/vector_helper.c| 295 +---
 6 files changed, 177 insertions(+), 132 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fe6c9a2c92..61552408b5 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -405,6 +405,7 @@ struct RISCVCPUConfig {
 bool ext_zhinxmin;
 bool ext_zve32f;
 bool ext_zve64f;
+bool rvv_ta_all_1s;
 
 uint32_t mvendorid;
 uint64_t marchid;
@@ -557,6 +558,7 @@ FIELD(TB_FLAGS, XL, 20, 2)
 /* If PointerMasking should be applied */
 FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
 FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
+FIELD(TB_FLAGS, VTA, 24, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e1aa4f2097..c0641b63cc 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -65,6 +65,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 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));
 } else {
 flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
 }
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 4d5dfa794a..efdf5d6d81 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1227,7 +1227,7 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
-if (a->vm && s->vl_eq_vlmax) {
+if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 gvec_fn(s->sew, vreg_ofs(s, a->rd),
 vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1),
 MAXSZ(s), MAXSZ(s));
@@ -1236,6 +1236,7 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
cpu_env, s->cfg_ptr->vlen / 8,
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index dbb322bfa7..512c6c30cf 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -24,8 +24,9 @@
 /* share data between vector helpers and decode code */
 FIELD(VDATA, VM, 0, 1)
 FIELD(VDATA, LMUL, 1, 3)
-FIELD(VDATA, NF, 4, 4)
-FIELD(VDATA, WD, 4, 1)
+FIELD(VDATA, VTA, 4, 1)
+FIELD(VDATA, NF, 5, 4)
+FIELD(VDATA, WD, 5, 1)
 
 /* float point classify helpers */
 target_ulong fclass_h(uint64_t frs1);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0cd1d9ee94..832353be54 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -94,6 +94,7 @@ typedef struct DisasContext {
  */
 int8_t lmul;
 uint8_t sew;
+uint8_t vta;
 target_ulong vstart;
 bool vl_eq_vlmax;
 uint8_t ntemp;
@@ -1091,6 +1092,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
 ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
 ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);
+ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s;
 ctx->vstart = env->vstart;
 ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
 ctx->misa_mxl_max = env->misa_mxl_max;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 3b79b9cbc2..2248f0cbee 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c

[PATCH qemu v18 06/16] target/riscv: rvv: Add tail agnostic for vector load / store instructions

2022-05-13 Thread ~eopxd
From: eopXD 

Destination register of unit-stride mask load and store instructions are
always written with a tail-agnostic policy.

A vector segment load / store instruction may contain fractional lmul
with nf * lmul > 1. The rest of the elements in the last register should
be treated as tail elements.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  6 +++
 target/riscv/translate.c|  2 +
 target/riscv/vector_helper.c| 60 +
 3 files changed, 68 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index efdf5d6d81..4da06b859b 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -711,6 +711,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
 }
 
@@ -774,6 +775,8 @@ static bool ld_us_mask_op(DisasContext *s, arg_vlm_v *a, 
uint8_t eew)
 /* EMUL = 1, NFIELDS = 1 */
 data = FIELD_DP32(data, VDATA, LMUL, 0);
 data = FIELD_DP32(data, VDATA, NF, 1);
+/* Mask destination register are always tail-agnostic */
+data = FIELD_DP32(data, VDATA, VTA, s->cfg_vta_all_1s);
 return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
 }
 
@@ -862,6 +865,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
 
@@ -991,6 +995,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
 
@@ -1108,6 +1113,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 return ldff_trans(a->rd, a->rs1, data, fn, s);
 }
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 832353be54..384ffcc0fa 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -95,6 +95,7 @@ typedef struct DisasContext {
 int8_t lmul;
 uint8_t sew;
 uint8_t vta;
+bool cfg_vta_all_1s;
 target_ulong vstart;
 bool vl_eq_vlmax;
 uint8_t ntemp;
@@ -1093,6 +1094,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
 ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);
 ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s;
+ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
 ctx->vstart = env->vstart;
 ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
 ctx->misa_mxl_max = env->misa_mxl_max;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 2248f0cbee..cb14c321ea 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -269,6 +269,9 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
 uint32_t i, k;
 uint32_t nf = vext_nf(desc);
 uint32_t max_elems = vext_max_elems(desc, log2_esz);
+uint32_t esz = 1 << log2_esz;
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vta = vext_vta(desc);
 
 for (i = env->vstart; i < env->vl; i++, env->vstart++) {
 if (!vm && !vext_elem_mask(v0, i)) {
@@ -283,6 +286,18 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
 }
 }
 env->vstart = 0;
+/* set tail elements to 1s */
+for (k = 0; k < nf; ++k) {
+vext_set_elems_1s(vd, vta, (k * max_elems + env->vl) * esz,
+  (k * max_elems + max_elems) * esz);
+}
+if (nf * max_elems % total_elems != 0) {
+uint32_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+uint32_t registers_used =
+((nf * max_elems) * esz + (vlenb - 1)) / vlenb;
+vext_set_elems_1s(vd, vta, (nf * max_elems) * esz,
+  registers_used * vlenb);
+}
 }
 
 #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)\
@@ -328,6 +343,9 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 uint32_t i, k;
 uint32_t nf = 

[PATCH qemu v18 12/16] target/riscv: rvv: Add tail agnostic for vector floating-point instructions

2022-05-13 Thread ~eopxd
From: eopXD 

Compares write mask registers, and so always operate under a tail-
agnostic policy.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  17 +
 target/riscv/vector_helper.c| 440 +---
 2 files changed, 261 insertions(+), 196 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 50f874ceae..76dee1ba20 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2334,6 +2334,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
+data = \
+FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1),\
vreg_ofs(s, a->rs2), cpu_env,   \
@@ -2416,6 +2419,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
\
 gen_set_rm(s, RISCV_FRM_DYN); \
 data = FIELD_DP32(data, VDATA, VM, a->vm);\
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);\
+data = FIELD_DP32(data, VDATA, VTA, s->vta);  \
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S,\
+  s->cfg_vta_all_1s); \
 return opfvf_trans(a->rd, a->rs1, a->rs2, data,   \
fns[s->sew - 1], s);   \
 } \
@@ -2454,6 +2460,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
  \
 data = FIELD_DP32(data, VDATA, VM, a->vm);   \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);   \
+data = FIELD_DP32(data, VDATA, VTA, s->vta); \
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),   \
vreg_ofs(s, a->rs1),  \
vreg_ofs(s, a->rs2), cpu_env, \
@@ -2493,6 +2500,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
 gen_set_rm(s, RISCV_FRM_DYN);\
 data = FIELD_DP32(data, VDATA, VM, a->vm);   \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);   \
+data = FIELD_DP32(data, VDATA, VTA, s->vta); \
 return opfvf_trans(a->rd, a->rs1, a->rs2, data,  \
fns[s->sew - 1], s);  \
 }\
@@ -2529,6 +2537,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1),\
vreg_ofs(s, a->rs2), cpu_env,   \
@@ -2568,6 +2577,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
 gen_set_rm(s, RISCV_FRM_DYN);\
 data = FIELD_DP32(data, VDATA, VM, a->vm);   \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);   \
+data = FIELD_DP32(data, VDATA, VTA, s->vta); \
 return opfvf_trans(a->rd, a->rs1, a->rs2, data,  \
fns[s->sew - 1], s);  \
 }\
@@ -2651,6 +2661,7 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs2), cpu_env,
s->cfg_ptr->vlen / 8,
@@ -2855,6 +2866,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) 
 \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, 

[PATCH qemu v18 07/16] target/riscv: rvv: Add tail agnostic for vx, vvm, vxm instructions

2022-05-13 Thread ~eopxd
From: eopXD 

`vmadc` and `vmsbc` produces a mask value, they always operate with
a tail agnostic policy.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  13 +-
 target/riscv/internals.h|   5 +-
 target/riscv/vector_helper.c| 314 +---
 3 files changed, 190 insertions(+), 142 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 4da06b859b..81f227f074 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1289,6 +1289,8 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2, uint32_t vm,
 
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
 desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
   s->cfg_ptr->vlen / 8, data));
 
@@ -1324,7 +1326,7 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn 
*gvec_fn,
 return false;
 }
 
-if (a->vm && s->vl_eq_vlmax) {
+if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 TCGv_i64 src1 = tcg_temp_new_i64();
 
 tcg_gen_ext_tl_i64(src1, get_gpr(s, a->rs1, EXT_SIGN));
@@ -1454,6 +1456,8 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, 
uint32_t vs2, uint32_t vm,
 
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
 desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
   s->cfg_ptr->vlen / 8, data));
 
@@ -1482,7 +1486,7 @@ do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn 
*gvec_fn,
 return false;
 }
 
-if (a->vm && s->vl_eq_vlmax) {
+if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
 extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
 mark_vs_dirty(s);
@@ -1536,6 +1540,7 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1),
vreg_ofs(s, a->rs2),
@@ -1617,6 +1622,7 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1),
vreg_ofs(s, a->rs2),
@@ -1695,6 +1701,9 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
+data = \
+FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1),\
vreg_ofs(s, a->rs2), cpu_env,   \
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 512c6c30cf..193ce57a6d 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -25,8 +25,9 @@
 FIELD(VDATA, VM, 0, 1)
 FIELD(VDATA, LMUL, 1, 3)
 FIELD(VDATA, VTA, 4, 1)
-FIELD(VDATA, NF, 5, 4)
-FIELD(VDATA, WD, 5, 1)
+FIELD(VDATA, VTA_ALL_1S, 5, 1)
+FIELD(VDATA, NF, 6, 4)
+FIELD(VDATA, WD, 6, 1)
 
 /* float point classify helpers */
 target_ulong fclass_h(uint64_t frs1);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index cb14c321ea..3bcde37e28 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -127,6 +127,11 @@ static inline uint32_t vext_vta(uint32_t desc)
 return FIELD_EX32(simd_data(desc), VDATA, VTA);
 }
 
+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.
  *
@@ -866,10 +871,12 @@ RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB)
 
 static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
CPURISCVState *env, uint32_t desc,
-

[PATCH qemu v4 01/10] target/riscv: rvv: Add mask agnostic for vv instructions

2022-05-13 Thread ~eopxd
From: Yueh-Ting (eop) Chen 

According to v-spec, mask agnostic behavior can be either kept as
undisturbed or set elements' bits to all 1s. To distinguish the
difference of mask policies, QEMU should be able to simulate the mask
agnostic behavior as "set mask elements' bits to all 1s".

There are multiple possibility for agnostic elements according to
v-spec. The main intent of this patch-set tries to add option that
can distinguish between mask policies. Setting agnostic elements to
all 1s allows QEMU to express this.

This is the first commit regarding the optional mask agnostic
behavior. Follow-up commits will add this optional behavior
for all rvv instructions.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
---
 target/riscv/cpu.h  | 2 ++
 target/riscv/cpu_helper.c   | 2 ++
 target/riscv/insn_trans/trans_rvv.c.inc | 3 +++
 target/riscv/internals.h| 5 +++--
 target/riscv/translate.c| 2 ++
 target/riscv/vector_helper.c| 8 
 6 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 61552408b5..4bce3798fc 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -406,6 +406,7 @@ struct RISCVCPUConfig {
 bool ext_zve32f;
 bool ext_zve64f;
 bool rvv_ta_all_1s;
+bool rvv_ma_all_1s;
 
 uint32_t mvendorid;
 uint64_t marchid;
@@ -559,6 +560,7 @@ FIELD(TB_FLAGS, XL, 20, 2)
 FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
 FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
 FIELD(TB_FLAGS, VTA, 24, 1)
+FIELD(TB_FLAGS, VMA, 25, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c0641b63cc..ba66b70bd1 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -67,6 +67,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 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));
 } else {
 flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
 }
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 6e8ed7694c..df5a892150 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1243,6 +1243,7 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
cpu_env, s->cfg_ptr->vlen / 8,
@@ -1541,6 +1542,7 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1),
vreg_ofs(s, a->rs2),
@@ -1623,6 +1625,7 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1),
vreg_ofs(s, a->rs2),
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 193ce57a6d..5620fbffb6 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -26,8 +26,9 @@ FIELD(VDATA, VM, 0, 1)
 FIELD(VDATA, LMUL, 1, 3)
 FIELD(VDATA, VTA, 4, 1)
 FIELD(VDATA, VTA_ALL_1S, 5, 1)
-FIELD(VDATA, NF, 6, 4)
-FIELD(VDATA, WD, 6, 1)
+FIELD(VDATA, VMA, 6, 1)
+FIELD(VDATA, NF, 7, 4)
+FIELD(VDATA, WD, 7, 1)
 
 /* float point classify helpers */
 target_ulong fclass_h(uint64_t frs1);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 384ffcc0fa..c7e841da1c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -95,6 +95,7 @@ typedef struct DisasContext {
 int8_t lmul;
 uint8_t sew;
 uint8_t vta;
+uint8_t vma;
 bool cfg_vta_all_1s;
 target_ulong vstart;
 bool vl_eq_vlmax;
@@ -1094,6 +1095,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
 ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLA

[PATCH qemu v18 13/16] target/riscv: rvv: Add tail agnostic for vector reduction instructions

2022-05-13 Thread ~eopxd
From: eopXD 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 8ac7fabb05..2ab4308ef0 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4534,6 +4534,9 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
+uint32_t esz = sizeof(TD);\
+uint32_t vlenb = simd_maxsz(desc);\
+uint32_t vta = vext_vta(desc);\
 uint32_t i;   \
 TD s1 =  *((TD *)vs1 + HD(0));\
   \
@@ -4546,6 +4549,8 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
 } \
 *((TD *)vd + HD(0)) = s1; \
 env->vstart = 0;  \
+/* set tail elements to 1s */ \
+vext_set_elems_1s(vd, vta, esz, vlenb);   \
 }
 
 /* vd[0] = sum(vs1[0], vs2[*]) */
@@ -4615,6 +4620,9 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
 \
 {  \
 uint32_t vm = vext_vm(desc);   \
 uint32_t vl = env->vl; \
+uint32_t esz = sizeof(TD); \
+uint32_t vlenb = simd_maxsz(desc); \
+uint32_t vta = vext_vta(desc); \
 uint32_t i;\
 TD s1 =  *((TD *)vs1 + HD(0)); \
\
@@ -4627,6 +4635,8 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
 \
 }  \
 *((TD *)vd + HD(0)) = s1;  \
 env->vstart = 0;   \
+/* set tail elements to 1s */  \
+vext_set_elems_1s(vd, vta, esz, vlenb);\
 }
 
 /* Unordered sum */
@@ -4651,6 +4661,9 @@ void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1,
 {
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
+uint32_t esz = sizeof(uint32_t);
+uint32_t vlenb = simd_maxsz(desc);
+uint32_t vta = vext_vta(desc);
 uint32_t i;
 uint32_t s1 =  *((uint32_t *)vs1 + H4(0));
 
@@ -4664,6 +4677,8 @@ void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1,
 }
 *((uint32_t *)vd + H4(0)) = s1;
 env->vstart = 0;
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, esz, vlenb);
 }
 
 void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1,
@@ -4671,6 +4686,9 @@ void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1,
 {
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
+uint32_t esz = sizeof(uint64_t);
+uint32_t vlenb = simd_maxsz(desc);
+uint32_t vta = vext_vta(desc);
 uint32_t i;
 uint64_t s1 =  *((uint64_t *)vs1);
 
@@ -4684,6 +4702,8 @@ void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1,
 }
 *((uint64_t *)vd) = s1;
 env->vstart = 0;
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, esz, vlenb);
 }
 
 /*
-- 
2.34.2




[PATCH qemu v18 11/16] target/riscv: rvv: Add tail agnostic for vector fix-point arithmetic instructions

2022-05-13 Thread ~eopxd
From: eopXD 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 220 ++-
 1 file changed, 114 insertions(+), 106 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 2bf670920a..db221797c6 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2102,10 +2102,12 @@ static inline void
 vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2,
  CPURISCVState *env,
  uint32_t desc,
- opivv2_rm_fn *fn)
+ opivv2_rm_fn *fn, uint32_t esz)
 {
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vta = vext_vta(desc);
 
 switch (env->vxrm) {
 case 0: /* rnu */
@@ -2125,15 +2127,17 @@ vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2,
  env, vl, vm, 3, fn);
 break;
 }
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
 }
 
 /* generate helpers for fixed point instructions with OPIVV format */
-#define GEN_VEXT_VV_RM(NAME)\
+#define GEN_VEXT_VV_RM(NAME, ESZ)   \
 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
   CPURISCVState *env, uint32_t desc)\
 {   \
 vext_vv_rm_2(vd, v0, vs1, vs2, env, desc,   \
- do_##NAME);\
+ do_##NAME, ESZ);   \
 }
 
 static inline uint8_t saddu8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t 
b)
@@ -2183,10 +2187,10 @@ RVVCALL(OPIVV2_RM, vsaddu_vv_b, OP_UUU_B, H1, H1, H1, 
saddu8)
 RVVCALL(OPIVV2_RM, vsaddu_vv_h, OP_UUU_H, H2, H2, H2, saddu16)
 RVVCALL(OPIVV2_RM, vsaddu_vv_w, OP_UUU_W, H4, H4, H4, saddu32)
 RVVCALL(OPIVV2_RM, vsaddu_vv_d, OP_UUU_D, H8, H8, H8, saddu64)
-GEN_VEXT_VV_RM(vsaddu_vv_b)
-GEN_VEXT_VV_RM(vsaddu_vv_h)
-GEN_VEXT_VV_RM(vsaddu_vv_w)
-GEN_VEXT_VV_RM(vsaddu_vv_d)
+GEN_VEXT_VV_RM(vsaddu_vv_b, 1)
+GEN_VEXT_VV_RM(vsaddu_vv_h, 2)
+GEN_VEXT_VV_RM(vsaddu_vv_w, 4)
+GEN_VEXT_VV_RM(vsaddu_vv_d, 8)
 
 typedef void opivx2_rm_fn(void *vd, target_long s1, void *vs2, int i,
   CPURISCVState *env, int vxrm);
@@ -2219,10 +2223,12 @@ static inline void
 vext_vx_rm_2(void *vd, void *v0, target_long s1, void *vs2,
  CPURISCVState *env,
  uint32_t desc,
- opivx2_rm_fn *fn)
+ opivx2_rm_fn *fn, uint32_t esz)
 {
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);
+uint32_t vta = vext_vta(desc);
 
 switch (env->vxrm) {
 case 0: /* rnu */
@@ -2242,25 +2248,27 @@ vext_vx_rm_2(void *vd, void *v0, target_long s1, void 
*vs2,
  env, vl, vm, 3, fn);
 break;
 }
+/* set tail elements to 1s */
+vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
 }
 
 /* generate helpers for fixed point instructions with OPIVX format */
-#define GEN_VEXT_VX_RM(NAME)  \
+#define GEN_VEXT_VX_RM(NAME, ESZ) \
 void HELPER(NAME)(void *vd, void *v0, target_ulong s1,\
 void *vs2, CPURISCVState *env, uint32_t desc) \
 { \
 vext_vx_rm_2(vd, v0, s1, vs2, env, desc,  \
- do_##NAME);  \
+ do_##NAME, ESZ); \
 }
 
 RVVCALL(OPIVX2_RM, vsaddu_vx_b, OP_UUU_B, H1, H1, saddu8)
 RVVCALL(OPIVX2_RM, vsaddu_vx_h, OP_UUU_H, H2, H2, saddu16)
 RVVCALL(OPIVX2_RM, vsaddu_vx_w, OP_UUU_W, H4, H4, saddu32)
 RVVCALL(OPIVX2_RM, vsaddu_vx_d, OP_UUU_D, H8, H8, saddu64)
-GEN_VEXT_VX_RM(vsaddu_vx_b)
-GEN_VEXT_VX_RM(vsaddu_vx_h)
-GEN_VEXT_VX_RM(vsaddu_vx_w)
-GEN_VEXT_VX_RM(vsaddu_vx_d)
+GEN_VEXT_VX_RM(vsaddu_vx_b, 1)
+GEN_VEXT_VX_RM(vsaddu_vx_h, 2)
+GEN_VEXT_VX_RM(vsaddu_vx_w, 4)
+GEN_VEXT_VX_RM(vsaddu_vx_d, 8)
 
 static inline int8_t sadd8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
 {
@@ -2306,19 +2314,19 @@ RVVCALL(OPIVV2_RM, vsadd_vv_b, OP_SSS_B, H1, H1, H1, 
sadd8)
 RVVCALL(OPIVV2_RM, vsadd_vv_h, OP_SSS_H, H2, H2, H2, sadd16)
 RVVCALL(OPIVV2_RM, vsadd_vv_w, OP_SSS_W, H4, H4, H4, sadd32)
 RVVCALL(OPIVV2_RM, vsadd_vv_d, OP_SSS_D, H8, H8, H8, sadd64)
-GEN_VEXT_VV_RM(vsadd_vv_b)
-GEN_VEXT_VV_RM(vsadd_vv_h)
-GEN_VEXT_VV_RM(vsadd_vv_w)
-GEN_VEXT_VV_RM(vsadd_vv_d)
+GEN_VEXT_VV_RM(vsadd_vv_b, 1)
+GEN_VEXT_VV_RM(vsadd_vv_h, 2)
+GEN_VEXT_VV_RM(vsadd_vv_w, 4)
+GEN_VEXT_VV_RM(vsadd_vv_d, 8)
 
 RVVCALL(OPIVX2_RM, vsadd_vx_b, OP_SSS_B, H1, H1, sadd8)
 RVVCALL(OPIVX2_RM, vsadd_vx_h, OP_SSS_H, H2, H2, sadd16)
 RVVCALL(OPIVX2_RM, vsadd_vx_w, OP_SSS_W, H4, H4,

[PATCH qemu v4 02/10] target/riscv: rvv: Add mask agnostic for vector load / store instructions

2022-05-13 Thread ~eopxd
From: Yueh-Ting (eop) Chen 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  5 
 target/riscv/vector_helper.c| 35 +
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index df5a892150..a6daf20714 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -712,6 +712,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
 }
 
@@ -777,6 +778,7 @@ static bool ld_us_mask_op(DisasContext *s, arg_vlm_v *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, NF, 1);
 /* Mask destination register are always tail-agnostic */
 data = FIELD_DP32(data, VDATA, VTA, s->cfg_vta_all_1s);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
 }
 
@@ -866,6 +868,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
 
@@ -996,6 +999,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
 
@@ -1114,6 +1118,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t eew)
 data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 return ldff_trans(a->rd, a->rs1, data, fn, s);
 }
 
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 6c55d5a750..5d392d084e 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -282,14 +282,18 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
 uint32_t esz = 1 << log2_esz;
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);
 uint32_t vta = vext_vta(desc);
+uint32_t vma = vext_vma(desc);
 
 for (i = env->vstart; i < env->vl; i++, env->vstart++) {
-if (!vm && !vext_elem_mask(v0, i)) {
-continue;
-}
-
 k = 0;
 while (k < nf) {
+if (!vm && !vext_elem_mask(v0, i)) {
+/* set masked-off elements to 1s */
+vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
+  (i + k * max_elems + 1) * esz);
+k++;
+continue;
+}
 target_ulong addr = base + stride * i + (k << log2_esz);
 ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
@@ -481,15 +485,19 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
 uint32_t esz = 1 << log2_esz;
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);
 uint32_t vta = vext_vta(desc);
+uint32_t vma = vext_vma(desc);
 
 /* load bytes from guest memory */
 for (i = env->vstart; i < env->vl; i++, env->vstart++) {
-if (!vm && !vext_elem_mask(v0, i)) {
-continue;
-}
-
 k = 0;
 while (k < nf) {
+if (!vm && !vext_elem_mask(v0, i)) {
+/* set masked-off elements to 1s */
+vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
+  (i + k * max_elems + 1) * esz);
+k++;
+continue;
+}
 abi_ptr addr = get_index_addr(base, i, vs2) + (k << log2_esz);
 ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
 k++;
@@ -578,6 +586,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
 uint32_t esz = 1 << log2_esz;
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);
 uint32_t vta = vext_vta(desc);
+uint32_t vma = vext_vma(desc);
 target_ulong addr, offset, remain;
 
 /* probe every access*/
@@ -623,10 +632,14 @@ ProbeSuccess:
 }
 for (i = env->vstart; i < env->vl; i++) {
 k = 0;
-if (!vm && !vext_elem_mask(v0, i)) {
-continue;
-}
 while (k < nf) {
+if (!vm && !vext_elem_mask(v0, i)) {
+/* set masked-off elements to 1s */
+vext_set_elems_1s(vd, vm

[PATCH qemu v4 04/10] target/riscv: rvv: Add mask agnostic for vector integer shift instructions

2022-05-13 Thread ~eopxd
From: Yueh-Ting (eop) Chen 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 1 +
 target/riscv/vector_helper.c| 7 +++
 2 files changed, 8 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index a0ffb86974..22f8dc6f0e 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1897,6 +1897,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
 data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
+data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1),\
vreg_ofs(s, a->rs2), cpu_env,   \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7da3938905..667a66afa3 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1297,10 +1297,13 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,
  \
 uint32_t esz = sizeof(TS1);   \
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);  \
 uint32_t vta = vext_vta(desc);\
+uint32_t vma = vext_vma(desc);\
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
 if (!vm && !vext_elem_mask(v0, i)) {  \
+/* set masked-off elements to 1s */   \
+vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);   \
 continue; \
 } \
 TS1 s1 = *((TS1 *)vs1 + HS1(i));  \
@@ -1338,10 +1341,14 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1,  
\
 uint32_t total_elems =  \
 vext_get_total_elems(env, desc, esz);   \
 uint32_t vta = vext_vta(desc);  \
+uint32_t vma = vext_vma(desc);  \
 uint32_t i; \
 \
 for (i = env->vstart; i < vl; i++) {\
 if (!vm && !vext_elem_mask(v0, i)) {\
+/* set masked-off elements to 1s */ \
+vext_set_elems_1s(vd, vma, i * esz, \
+  (i + 1) * esz);   \
 continue;   \
 }   \
 TS2 s2 = *((TS2 *)vs2 + HS2(i));\
-- 
2.34.2




[PATCH qemu v4 05/10] target/riscv: rvv: Add mask agnostic for vector integer comparison instructions

2022-05-13 Thread ~eopxd
From: Yueh-Ting (eop) Chen 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  1 +
 target/riscv/vector_helper.c| 10 ++
 2 files changed, 11 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 22f8dc6f0e..f87780264f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1714,6 +1714,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 data = FIELD_DP32(data, VDATA, VTA, s->vta);   \
 data = \
 FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
+data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1),\
vreg_ofs(s, a->rs2), cpu_env,   \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 667a66afa3..3324ca4872 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1403,12 +1403,17 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 uint32_t vl = env->vl;\
 uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
 uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
+uint32_t vma = vext_vma(desc);\
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
 ETYPE s1 = *((ETYPE *)vs1 + H(i));\
 ETYPE s2 = *((ETYPE *)vs2 + H(i));\
 if (!vm && !vext_elem_mask(v0, i)) {  \
+/* set masked-off elements to 1s */   \
+if (vma) {\
+vext_set_elem_mask(vd, i, 1); \
+} \
 continue; \
 } \
 vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \
@@ -1461,11 +1466,16 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
 uint32_t vl = env->vl;  \
 uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
 uint32_t vta_all_1s = vext_vta_all_1s(desc);\
+uint32_t vma = vext_vma(desc);  \
 uint32_t i; \
 \
 for (i = env->vstart; i < vl; i++) {\
 ETYPE s2 = *((ETYPE *)vs2 + H(i));  \
 if (!vm && !vext_elem_mask(v0, i)) {\
+/* set masked-off elements to 1s */ \
+if (vma) {  \
+vext_set_elem_mask(vd, i, 1);   \
+}   \
 continue;   \
 }   \
 vext_set_elem_mask(vd, i,   \
-- 
2.34.2




[PATCH qemu v18 09/16] target/riscv: rvv: Add tail agnostic for vector integer comparison instructions

2022-05-13 Thread ~eopxd
From: eopXD 

Compares write mask registers, and so always operate under a tail-
agnostic policy.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 9738c50222..b964b01a15 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1370,6 +1370,8 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
+uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
+uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
@@ -1381,6 +1383,13 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \
 } \
 env->vstart = 0;  \
+/* mask destination register are always tail-agnostic */  \
+/* set tail elements to 1s */ \
+if (vta_all_1s) { \
+for (; i < total_elems; i++) {\
+vext_set_elem_mask(vd, i, 1); \
+} \
+} \
 }
 
 GEN_VEXT_CMP_VV(vmseq_vv_b, uint8_t,  H1, DO_MSEQ)
@@ -1419,6 +1428,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
 {   \
 uint32_t vm = vext_vm(desc);\
 uint32_t vl = env->vl;  \
+uint32_t total_elems = env_archcpu(env)->cfg.vlen;  \
+uint32_t vta_all_1s = vext_vta_all_1s(desc);\
 uint32_t i; \
 \
 for (i = env->vstart; i < vl; i++) {\
@@ -1430,6 +1441,13 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
 DO_OP(s2, (ETYPE)(target_long)s1)); \
 }   \
 env->vstart = 0;\
+/* mask destination register are always tail-agnostic */\
+/* set tail elements to 1s */   \
+if (vta_all_1s) {   \
+for (; i < total_elems; i++) {  \
+vext_set_elem_mask(vd, i, 1);   \
+}   \
+}   \
 }
 
 GEN_VEXT_CMP_VX(vmseq_vx_b, uint8_t,  H1, DO_MSEQ)
-- 
2.34.2




[PATCH qemu v18 15/16] target/riscv: rvv: Add tail agnostic for vector permutation instructions

2022-05-13 Thread ~eopxd
From: eopXD 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  7 +++--
 target/riscv/vector_helper.c| 40 +
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 430d4e4460..6e8ed7694c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3665,7 +3665,7 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr 
*a)
 return false;
 }
 
-if (a->vm && s->vl_eq_vlmax) {
+if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 int scale = s->lmul - (s->sew + 3);
 int vlmax = s->cfg_ptr->vlen >> -scale;
 TCGv_i64 dest = tcg_temp_new_i64();
@@ -3697,7 +3697,7 @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr 
*a)
 return false;
 }
 
-if (a->vm && s->vl_eq_vlmax) {
+if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
 int scale = s->lmul - (s->sew + 3);
 int vlmax = s->cfg_ptr->vlen >> -scale;
 if (a->rs1 >= vlmax) {
@@ -3749,6 +3749,7 @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
cpu_env, s->cfg_ptr->vlen / 8,
@@ -3849,6 +3850,8 @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, 
uint8_t seq)
 }
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 
 tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
vreg_ofs(s, a->rs2), cpu_env,
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 5c2d1c02f4..2afbac6e37 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4930,6 +4930,9 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2, \
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
+uint32_t esz = sizeof(ETYPE); \
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);  \
+uint32_t vta = vext_vta(desc);\
 target_ulong offset = s1, i_min, i;   \
   \
 i_min = MAX(env->vstart, offset); \
@@ -4939,6 +4942,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2, \
 } \
 *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset));  \
 } \
+/* set tail elements to 1s */ \
+vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);  \
 }
 
 /* vslideup.vx vd, vs2, rs1, vm # vd[i+rs1] = vs2[i] */
@@ -4954,6 +4959,9 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2, \
 uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE)));   \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
+uint32_t esz = sizeof(ETYPE); \
+uint32_t total_elems = vext_get_total_elems(env, desc, esz);  \
+uint32_t vta = vext_vta(desc);\
 target_ulong i_max, i;\
   \
 i_max = MAX(MIN(s1 < vlmax ? vlmax - s1 : 0, vl), env->vstart);   \
@@ -4970,6 +4978,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2, \
 } \
   \
 env->vstart = 0;  \
+/* set tail elements to 1s */ \
+vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);  \
 }
 
 /* vslidedown.vx vd, vs2, rs1, vm # vd[i] = vs2[i+rs1] */
@@ -4985,6 +4995,9 @@ static void vslide1up_##BITWIDTH(void *vd, void *v0, 
target_ulong s1,   \
 typedef uint#

[PATCH qemu v4 06/10] target/riscv: rvv: Add mask agnostic for vector fix-point arithmetic instructions

2022-05-13 Thread ~eopxd
From: Yueh-Ting (eop) Chen 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
---
 target/riscv/vector_helper.c | 26 --
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 3324ca4872..4a1d6bdde3 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2128,10 +2128,12 @@ static inline void
 vext_vv_rm_1(void *vd, void *v0, void *vs1, void *vs2,
  CPURISCVState *env,
  uint32_t vl, uint32_t vm, int vxrm,
- opivv2_rm_fn *fn)
+ opivv2_rm_fn *fn, uint32_t vma, uint32_t esz)
 {
 for (uint32_t i = env->vstart; i < vl; i++) {
 if (!vm && !vext_elem_mask(v0, i)) {
+/* set masked-off elements to 1s */
+vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
 continue;
 }
 fn(vd, vs1, vs2, i, env, vxrm);
@@ -2149,23 +2151,24 @@ vext_vv_rm_2(void *vd, void *v0, void *vs1, void *vs2,
 uint32_t vl = env->vl;
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);
 uint32_t vta = vext_vta(desc);
+uint32_t vma = vext_vma(desc);
 
 switch (env->vxrm) {
 case 0: /* rnu */
 vext_vv_rm_1(vd, v0, vs1, vs2,
- env, vl, vm, 0, fn);
+ env, vl, vm, 0, fn, vma, esz);
 break;
 case 1: /* rne */
 vext_vv_rm_1(vd, v0, vs1, vs2,
- env, vl, vm, 1, fn);
+ env, vl, vm, 1, fn, vma, esz);
 break;
 case 2: /* rdn */
 vext_vv_rm_1(vd, v0, vs1, vs2,
- env, vl, vm, 2, fn);
+ env, vl, vm, 2, fn, vma, esz);
 break;
 default: /* rod */
 vext_vv_rm_1(vd, v0, vs1, vs2,
- env, vl, vm, 3, fn);
+ env, vl, vm, 3, fn, vma, esz);
 break;
 }
 /* set tail elements to 1s */
@@ -2249,10 +2252,12 @@ static inline void
 vext_vx_rm_1(void *vd, void *v0, target_long s1, void *vs2,
  CPURISCVState *env,
  uint32_t vl, uint32_t vm, int vxrm,
- opivx2_rm_fn *fn)
+ opivx2_rm_fn *fn, uint32_t vma, uint32_t esz)
 {
 for (uint32_t i = env->vstart; i < vl; i++) {
 if (!vm && !vext_elem_mask(v0, i)) {
+/* set masked-off elements to 1s */
+vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
 continue;
 }
 fn(vd, s1, vs2, i, env, vxrm);
@@ -2270,23 +2275,24 @@ vext_vx_rm_2(void *vd, void *v0, target_long s1, void 
*vs2,
 uint32_t vl = env->vl;
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);
 uint32_t vta = vext_vta(desc);
+uint32_t vma = vext_vma(desc);
 
 switch (env->vxrm) {
 case 0: /* rnu */
 vext_vx_rm_1(vd, v0, s1, vs2,
- env, vl, vm, 0, fn);
+ env, vl, vm, 0, fn, vma, esz);
 break;
 case 1: /* rne */
 vext_vx_rm_1(vd, v0, s1, vs2,
- env, vl, vm, 1, fn);
+ env, vl, vm, 1, fn, vma, esz);
 break;
 case 2: /* rdn */
 vext_vx_rm_1(vd, v0, s1, vs2,
- env, vl, vm, 2, fn);
+ env, vl, vm, 2, fn, vma, esz);
 break;
 default: /* rod */
 vext_vx_rm_1(vd, v0, s1, vs2,
- env, vl, vm, 3, fn);
+ env, vl, vm, 3, fn, vma, esz);
 break;
 }
 /* set tail elements to 1s */
-- 
2.34.2




[PATCH qemu v18 14/16] target/riscv: rvv: Add tail agnostic for vector mask instructions

2022-05-13 Thread ~eopxd
From: eopXD 

The tail elements in the destination mask register are updated under
a tail-agnostic policy.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  6 +
 target/riscv/vector_helper.c| 30 +
 2 files changed, 36 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 76dee1ba20..430d4e4460 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3131,6 +3131,8 @@ static bool trans_##NAME(DisasContext *s, arg_r *a)   
 \
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
\
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = \
+FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
vreg_ofs(s, a->rs1),\
vreg_ofs(s, a->rs2), cpu_env,   \
@@ -3235,6 +3237,8 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) 
 \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+data = \
+FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
 tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
vreg_ofs(s, 0), vreg_ofs(s, a->rs2),\
cpu_env, s->cfg_ptr->vlen / 8,  \
@@ -3272,6 +3276,7 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 static gen_helper_gvec_3_ptr * const fns[4] = {
 gen_helper_viota_m_b, gen_helper_viota_m_h,
 gen_helper_viota_m_w, gen_helper_viota_m_d,
@@ -3301,6 +3306,7 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
 
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, VTA, s->vta);
 static gen_helper_gvec_2_ptr * const fns[4] = {
 gen_helper_vid_v_b, gen_helper_vid_v_h,
 gen_helper_vid_v_w, gen_helper_vid_v_d,
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 2ab4308ef0..5c2d1c02f4 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4716,6 +4716,8 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
   uint32_t desc)  \
 { \
 uint32_t vl = env->vl;\
+uint32_t total_elems = env_archcpu(env)->cfg.vlen;\
+uint32_t vta_all_1s = vext_vta_all_1s(desc);  \
 uint32_t i;   \
 int a, b; \
   \
@@ -4725,6 +4727,15 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, 
 \
 vext_set_elem_mask(vd, i, OP(b, a));  \
 } \
 env->vstart = 0;  \
+/* mask destination register are always tail- \
+ * agnostic   \
+ */   \
+/* set tail elements to 1s */ \
+if (vta_all_1s) { \
+for (; i < total_elems; i++) {\
+vext_set_elem_mask(vd, i, 1); \
+} \
+} \
 }
 
 #define DO_NAND(N, M)  (!(N & M))
@@ -4792,6 +4803,8 @@ static void vmsetm(void *vd, void *v0, void *vs2, 
CPURISCVState *env,
 {
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
+uint32_t total_elems = env_archcpu(env)->cfg.vlen;
+uint32_t vta_all_1s = vext_vta_all_1s(desc);
 int i;
 bool first_mask_bit = false;
 
@@ -4820,6 +4833,13 @@ static void vmsetm(void *vd, void *v0, void *vs2, 
CPURISCVState *env,
 }
 }
 env->vstart = 0;
+/* mask destination register are always tail-agnostic */
+/* set tail elements to 1s */
+if (vta_all_1s) {
+for (; i < total_elems; i++) {
+vext_set_elem_mask(vd, i, 1);
+}
+}
 }

[PATCH qemu v4 08/10] target/riscv: rvv: Add mask agnostic for vector mask instructions

2022-05-13 Thread ~eopxd
From: Yueh-Ting (eop) Chen 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  3 +++
 target/riscv/vector_helper.c| 11 +++
 2 files changed, 14 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index f37040f278..333c6f5ef5 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3263,6 +3263,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) 
 \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
 data = \
 FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
+data = FIELD_DP32(data, VDATA, VMA, s->vma);   \
 tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
vreg_ofs(s, 0), vreg_ofs(s, a->rs2),\
cpu_env, s->cfg_ptr->vlen / 8,  \
@@ -3301,6 +3302,7 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 static gen_helper_gvec_3_ptr * const fns[4] = {
 gen_helper_viota_m_b, gen_helper_viota_m_h,
 gen_helper_viota_m_w, gen_helper_viota_m_d,
@@ -3331,6 +,7 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 static gen_helper_gvec_2_ptr * const fns[4] = {
 gen_helper_vid_v_b, gen_helper_vid_v_h,
 gen_helper_vid_v_w, gen_helper_vid_v_d,
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index bcac0a9f1b..e4c6530dfa 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4878,11 +4878,16 @@ static void vmsetm(void *vd, void *v0, void *vs2, 
CPURISCVState *env,
 uint32_t vl = env->vl;
 uint32_t total_elems = env_archcpu(env)->cfg.vlen;
 uint32_t vta_all_1s = vext_vta_all_1s(desc);
+uint32_t vma = vext_vma(desc);
 int i;
 bool first_mask_bit = false;
 
 for (i = env->vstart; i < vl; i++) {
 if (!vm && !vext_elem_mask(v0, i)) {
+/* set masked-off elements to 1s */
+if (vma) {
+vext_set_elem_mask(vd, i, 1);
+}
 continue;
 }
 /* write a zero to all following active elements */
@@ -4943,11 +4948,14 @@ void HELPER(NAME)(void *vd, void *v0, void *vs2, 
CPURISCVState *env,  \
 uint32_t esz = sizeof(ETYPE); \
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);  \
 uint32_t vta = vext_vta(desc);\
+uint32_t vma = vext_vma(desc);\
 uint32_t sum = 0; \
 int i;\
   \
 for (i = env->vstart; i < vl; i++) {  \
 if (!vm && !vext_elem_mask(v0, i)) {  \
+/* set masked-off elements to 1s */   \
+vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);   \
 continue; \
 } \
 *((ETYPE *)vd + H(i)) = sum;  \
@@ -4974,10 +4982,13 @@ void HELPER(NAME)(void *vd, void *v0, CPURISCVState 
*env, uint32_t desc)  \
 uint32_t esz = sizeof(ETYPE); \
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);  \
 uint32_t vta = vext_vta(desc);\
+uint32_t vma = vext_vma(desc);\
 int i;\
   \
 for (i = env->vstart; i < vl; i++) {  \
 if (!vm && !vext_elem_mask(v0, i)) {  \
+/* set masked-off elements to 1s */   \
+vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);   \
 continue; \
 } \
   

[PATCH qemu v18 16/16] target/riscv: rvv: Add option 'rvv_ta_all_1s' to enable optional tail agnostic behavior

2022-05-13 Thread ~eopxd
From: eopXD 

According to v-spec, tail agnostic behavior can be either kept as
undisturbed or set elements' bits to all 1s. To distinguish the
difference of tail policies, QEMU should be able to simulate the tail
agnostic behavior as "set tail elements' bits to all 1s".

There are multiple possibility for agnostic elements according to
v-spec. The main intent of this patch-set tries to add option that
can distinguish between tail policies. Setting agnostic elements to
all 1s allows QEMU to express this.

This commit adds option 'rvv_ta_all_1s' is added to enable the
behavior, it is default as disabled.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ccacdee215..720c8b9e5c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -879,6 +879,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false),
 
 DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
+DEFINE_PROP_BOOL("rvv_ta_all_1s", RISCVCPU, cfg.rvv_ta_all_1s, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.34.2



[PATCH qemu v4 03/10] target/riscv: rvv: Add mask agnostic for vx instructions

2022-05-13 Thread ~eopxd
From: Yueh-Ting (eop) Chen 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
Reviewed-by: Weiwei Li 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 2 ++
 target/riscv/vector_helper.c| 3 +++
 2 files changed, 5 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index a6daf20714..a0ffb86974 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1297,6 +1297,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2, uint32_t vm,
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
 data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
   s->cfg_ptr->vlen / 8, data));
 
@@ -1464,6 +1465,7 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, 
uint32_t vs2, uint32_t vm,
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, VTA, s->vta);
 data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
+data = FIELD_DP32(data, VDATA, VMA, s->vma);
 desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlen / 8,
   s->cfg_ptr->vlen / 8, data));
 
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 5d392d084e..7da3938905 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -898,10 +898,13 @@ static void do_vext_vx(void *vd, void *v0, target_long 
s1, void *vs2,
 uint32_t vl = env->vl;
 uint32_t total_elems = vext_get_total_elems(env, desc, esz);
 uint32_t vta = vext_vta(desc);
+uint32_t vma = vext_vma(desc);
 uint32_t i;
 
 for (i = env->vstart; i < vl; i++) {
 if (!vm && !vext_elem_mask(v0, i)) {
+/* set masked-off elements to 1s */
+vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
 continue;
 }
 fn(vd, s1, vs2, i);
-- 
2.34.2




  1   2   3   >