Re: [PATCH 06/18] ui/vnc: Require audiodev=

2022-04-27 Thread Paolo Bonzini

On 4/25/22 10:21, Martin Kletzander wrote:

@@ -4188,12 +4188,15 @@ void vnc_display_open(const char *id, Error **errp)
  vd->ledstate = 0;
  
  audiodev = qemu_opt_get(opts, "audiodev");

-if (audiodev) {
-vd->audio_state = audio_state_by_name(audiodev);
-if (!vd->audio_state) {
-error_setg(errp, "Audiodev '%s' not found", audiodev);
-goto fail;
-}
+if (!audiodev) {
+error_setg(errp, "Audiodev parameter for vnc required");
+goto fail;
+}
+


Wouldn't this break "-vnc :0"?  You can just ignore the audio commands 
if vd->audio_state is NULL.


Paolo



Re: [PATCH v2 02/26] Use QEMU_SANITIZE_ADDRESS

2022-04-27 Thread Thomas Huth

On 26/04/2022 11.26, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
---
  tests/qtest/fdc-test.c| 2 +-
  util/coroutine-ucontext.c | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c
index 4aa72f36431f..0b3c2c0d523f 100644
--- a/tests/qtest/fdc-test.c
+++ b/tests/qtest/fdc-test.c
@@ -550,7 +550,7 @@ static void fuzz_registers(void)
  
  static bool qtest_check_clang_sanitizer(void)

  {
-#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
+#ifdef QEMU_SANITIZE_ADDRESS
  return true;
  #else
  g_test_skip("QEMU not configured using --enable-sanitizers");
diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c
index 904b375192ca..ed368e1a3ec3 100644
--- a/util/coroutine-ucontext.c
+++ b/util/coroutine-ucontext.c
@@ -30,7 +30,7 @@
  #include 
  #endif
  
-#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)

+#ifdef QEMU_SANITIZE_ADDRESS
  #ifdef CONFIG_ASAN_IFACE_FIBER
  #define CONFIG_ASAN 1
  #include 


Reviewed-by: Thomas Huth 




Re: [PATCH v2 25/26] tests: replace qemu_set_nonblock()

2022-04-27 Thread Thomas Huth

On 26/04/2022 11.27, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

The call is POSIX-specific. Use the dedicated GLib API.


g_unix_set_fd_nonblocking() is also available on Unix-like systems according 
to its name, I suppose? So what's the advantage of this change?


 Thomas



Signed-off-by: Marc-André Lureau 
---
  tests/qtest/vhost-user-test.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
index ee30f5479648..a2cec8768462 100644
--- a/tests/qtest/vhost-user-test.c
+++ b/tests/qtest/vhost-user-test.c
@@ -302,6 +302,7 @@ static int chr_can_read(void *opaque)
  
  static void chr_read(void *opaque, const uint8_t *buf, int size)

  {
+g_autoptr(GError) err = NULL;
  TestServer *s = opaque;
  CharBackend *chr = &s->chr;
  VhostUserMsg msg;
@@ -394,7 +395,8 @@ static void chr_read(void *opaque, const uint8_t *buf, int 
size)
   * The receive function forces it to be blocking,
   * so revert it back to non-blocking.
   */
-qemu_set_nonblock(fd);
+g_unix_set_fd_nonblocking(fd, true, &err);
+g_assert_no_error(err);
  break;
  
  case VHOST_USER_SET_LOG_BASE:





Re: [PATCH 06/18] ui/vnc: Require audiodev=

2022-04-27 Thread Daniel P . Berrangé
On Wed, Apr 27, 2022 at 11:32:41AM +0200, Paolo Bonzini wrote:
> On 4/25/22 10:21, Martin Kletzander wrote:
> > @@ -4188,12 +4188,15 @@ void vnc_display_open(const char *id, Error **errp)
> >   vd->ledstate = 0;
> >   audiodev = qemu_opt_get(opts, "audiodev");
> > -if (audiodev) {
> > -vd->audio_state = audio_state_by_name(audiodev);
> > -if (!vd->audio_state) {
> > -error_setg(errp, "Audiodev '%s' not found", audiodev);
> > -goto fail;
> > -}
> > +if (!audiodev) {
> > +error_setg(errp, "Audiodev parameter for vnc required");
> > +goto fail;
> > +}
> > +
> 
> Wouldn't this break "-vnc :0"?  You can just ignore the audio commands if
> vd->audio_state is NULL.

Yep, that's wha I suggested with skipping advertizing VNC_ENCODING_AUDIO
when audiodev is NULL

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 :|




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

2022-04-27 Thread Stefan Hajnoczi
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);
+}
 }
 if (csock >= 0) {
 close(csock);
-- 
2.35.1




[PATCH qemu v9 03/14] target/riscv: rvv: Early exit when vstart >= vl

2022-04-27 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 
---
 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 275fded6e4..57953923d5 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();
@@ -1216,6 +1220,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),
@@ -1263,6 +1268,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();
@@ -1427,6 +1433,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();
@@ -1513,6 +1520,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);
@@ -1593,6 +1601,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);
@@ -1670,6 +1679,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); \
@@ -1851,6 +1861,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); \
@@ -2061,6 +2072,7 @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)

[PATCH qemu v9 10/14] target/riscv: rvv: Add tail agnostic for vector fix-point arithmetic instructions

2022-04-27 Thread ~eopxd
From: eopXD 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
---
 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 2b269c2dbe..fd1466ceae 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2080,10 +2080,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 */
@@ -2103,15 +2105,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)
@@ -2161,10 +2165,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);
@@ -2197,10 +2201,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 */
@@ -2220,25 +2226,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)
 {
@@ -2284,19 +2292,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, sadd32)
 RVVCALL(OPIVX2_RM, vsadd_vx_d, OP_SSS_D, H

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

2022-04-27 Thread yangxiaojuan

Hi Mark,

On 2022/4/26 上午12:27, Mark Cave-Ayland wrote:

On 25/04/2022 10:10, Xiaojuan Yang wrote:


This patch realize the EIOINTC interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
  hw/intc/Kconfig    |   3 +
  hw/intc/loongarch_extioi.c | 483 +
  hw/intc/meson.build    |   1 +
  hw/intc/trace-events   |   9 +
  hw/loongarch/Kconfig   |   1 +
  include/hw/intc/loongarch_extioi.h |  60 
  6 files changed, 557 insertions(+)
  create mode 100644 hw/intc/loongarch_extioi.c
  create mode 100644 include/hw/intc/loongarch_extioi.h

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 71c04c328e..28bd1f185d 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -96,3 +96,6 @@ config LOONGARCH_PCH_MSI
  select MSI_NONBROKEN
  bool
  select UNIMP
+
+config LOONGARCH_EXTIOI
+    bool
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
new file mode 100644
index 00..1d9317c5bd
--- /dev/null
+++ b/hw/intc/loongarch_extioi.c
@@ -0,0 +1,483 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongson 3A5000 ext interrupt controller emulation
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "hw/loongarch/virt.h"
+#include "hw/qdev-properties.h"
+#include "exec/address-spaces.h"
+#include "hw/intc/loongarch_extioi.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static void extioi_update_irq(LoongArchExtIOI *s, int irq_num, int 
level)

+{
+    uint64_t ipnum, cpu;
+
+    /*
+ * Routing in group of 32 interrupts.
+ * The default value of csr[0x420][49]
+ * is 0 and nobody will change it,
+ * so 'ipmap' use bitmap function.
+ */
+    ipnum = ldub_p((void *)&s->ipmap + (irq_num / 32)) & 0xf;
+    ipnum = find_first_bit(&ipnum, 4);
+    ipnum = (ipnum == 4) ? 0 : ipnum;
+
+    cpu = ldub_p((void *)s->coremap + irq_num) & 0xf;
+    cpu = find_first_bit(&cpu, 4);
+    cpu = (cpu == 4) ? 0 : cpu;
+
+    if (level) {
+    if (test_bit(irq_num, (unsigned long *)s->enable) == false) {
+    return;
+    }
+    bitmap_set((unsigned long *)s->coreisr[cpu], irq_num, 1);
+    qemu_set_irq(s->parent_irq[cpu][ipnum], level);
+    } else {
+    bitmap_clear((unsigned long *)s->coreisr[cpu], irq_num, 1);
+    qemu_set_irq(s->parent_irq[cpu][ipnum], level);
+    }
+}
+
+static void extioi_setirq(void *opaque, int irq, int level)
+{
+    LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+    trace_loongarch_extioi_setirq(irq, level);
+    extioi_update_irq(s, irq, level);
+}
+
+static uint32_t extioi_readb(void *opaque, hwaddr addr)
+{
+    LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+    unsigned long offset, reg_count;
+    uint8_t ret = 0;
+    int cpu;
+
+    offset = addr & 0x;
+    switch (offset) {
+    case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1:
+    ret = ldub_p((void *)s->enable + (offset - 
EXTIOI_ENABLE_START));

+    break;
+    case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END - 1:
+    ret = ldub_p((void *)s->bounce + (offset - 
EXTIOI_BOUNCE_START));

+    break;
+    case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
+    reg_count = ((offset - EXTIOI_COREISR_START) & 0x1f);
+    cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
+    ret = ldub_p((void *)s->coreisr[cpu] + reg_count);
+    break;
+    case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1:
+    ret = ldub_p((void *)&s->ipmap + (offset - 
EXTIOI_IPMAP_START));

+    break;
+    case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1:
+    ret = ldub_p((void *)s->coremap + (offset - 
EXTIOI_COREMAP_START));

+    break;
+    case EXTIOI_NODETYPE_START ... EXTIOI_NODETYPE_END - 1:
+    ret = ldub_p((void *)s->nodetype + (offset - 
EXTIOI_NODETYPE_START));

+    break;
+    default:
+    break;
+    }
+    trace_loongarch_extioi_readb((uint32_t)addr, ret);
+    return ret;
+}
+
+static uint32_t extioi_readw(void *opaque, hwaddr addr)
+{
+    LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+    unsigned long offset, reg_count;
+    uint32_t ret = 0;
+    int cpu;
+
+    offset = addr & 0x;
+    switch (offset) {
+    case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1:
+    ret = ldl_p((void *)s->enable + (offset - 
EXTIOI_ENABLE_START));

+    break;
+    case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END - 1:
+    ret = ldl_p((void *)s->bounce + (offset - 
EXTIOI_BOUNCE_START));

+    break;
+    case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
+    reg_count = ((offset - EXTIOI_COREISR_START) & 0x1f);
+    cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
+    ret = ldl_p((void *)s->coreisr[cpu] + reg_count);
+    break;
+    case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1:
+   

[PATCH qemu v9 02/14] target/riscv: rvv: Rename ambiguous esz

2022-04-27 Thread ~eopxd
From: eopXD 

No functional change intended in this commit.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
---
 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 e94caf1a3c..d0452a7756 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, MMUAccessType access_type)
+ uint32_t log2_esz, uintptr_t ra, MMUAccessType access_type)
 {
 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, MMUAccessType access_type)
 {
 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, MMUAccessType access_type)
+uint32_t log2_esz, uintptr_t ra, MMUAccessType access_type)
 {
 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));
+  

[PATCH qemu v9 00/14] Add tail agnostic behavior for rvv instructions

2022-04-27 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.

eopXD (14):
  target/riscv: rvv: Prune redundant ESZ, DSZ 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/cpu.c  |1 +
 target/riscv/cpu.h  |2 +
 target/riscv/cpu_helper.c   |2 +
 target/riscv/insn_trans/trans_rvv.c.inc |  176 +++
 target/riscv/internals.h|6 +-
 target/riscv/translate.c|4 +
 target/riscv/vector_helper.c| 1536 ++-
 7 files changed, 1110 insertions(+), 617 deletions(-)

-- 
2.34.2



[PATCH qemu v9 08/14] target/riscv: rvv: Add tail agnostic for vector integer comparison instructions

2022-04-27 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 
---
 target/riscv/vector_helper.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 49accde0bd..e1502c20be 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1345,6 +1345,10 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, 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_all_1s = vext_vta_all_1s(desc);  \
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
@@ -1356,6 +1360,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)
@@ -1394,6 +1405,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_all_1s = vext_vta_all_1s(desc);\
 uint32_t i; \
 \
 for (i = env->vstart; i < vl; i++) {\
@@ -1405,6 +1419,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 v9 05/14] target/riscv: rvv: Add tail agnostic for vector load / store instructions

2022-04-27 Thread ~eopxd
From: eopXD 

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

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

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index cc80bf00ff..99691f1b9f 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);
 }
 
@@ -748,6 +749,7 @@ static bool st_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, true);
 }
 
@@ -774,6 +776,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);
 }
 
@@ -791,6 +795,8 @@ static bool st_us_mask_op(DisasContext *s, arg_vsm_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, true);
 }
 
@@ -862,6 +868,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);
 }
 
@@ -891,6 +898,7 @@ static bool st_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);
 fn = fns[eew];
 if (fn == NULL) {
 return false;
@@ -991,6 +999,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);
 }
 
@@ -1043,6 +1052,7 @@ static bool st_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, true);
 }
 
@@ -1108,6 +1118,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/vector_helper.c b/target/riscv/vector_helper.c
index 396e252179..1541d97b08 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -270,6 +270,8 @@ 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 vta = vext_vta(desc);
 
 for (i = env->vstart; i < env->vl; i++, env->vstart++) {
 if (!vm && !vext_elem_mask(v0, i)) {
@@ -284,6 +286,11 @@ 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, env->vl * esz + k * max_elems,
+  max_elems * esz + k * max_elems);
+}
 }
 
 #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)\
@@ -329,6 +336,8 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState 
*env, uint32_t desc,
 uint32_t i, k;
 uint32_t nf = vext_nf(desc);
 uint32_t max_elems = vext_max_elems

[PATCH qemu v9 14/14] target/riscv: rvv: Add tail agnostic for vector permutation instructions

2022-04-27 Thread ~eopxd
From: eopXD 

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

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ab9f876c28..2c9993844a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3744,6 +3744,16 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr 
*a)
 }
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 int scale = s->lmul - (s->sew + 3);
 int vlmax = scale < 0 ?
s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale;
@@ -3777,6 +3787,16 @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr 
*a)
 }
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 int scale = s->lmul - (s->sew + 3);
 int vlmax = scale < 0 ?
s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale;
@@ -3829,6 +3849,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,
@@ -3934,6 +3955,7 @@ 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, 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 20aa0aee2b..aa1623c52b 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4911,6 +4911,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); \
@@ -4920,6 +4923,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] */
@@ -4935,6 +4940,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);   \
@@ -4951,6 +4959,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2, \
 }

[PATCH qemu v9 07/14] target/riscv: rvv: Add tail agnostic for vector integer shift instructions

2022-04-27 Thread ~eopxd
From: eopXD 

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

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index d15858fc6f..430847b0f9 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1858,6 +1858,16 @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, 
GVecGen2sFn32 *gvec_fn,
 }
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 TCGv_i32 src1 = tcg_temp_new_i32();
 
 tcg_gen_trunc_tl_i32(src1, get_gpr(s, a->rs1, EXT_NONE));
@@ -1916,6 +1926,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 cd2283321f..49accde0bd 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1245,6 +1245,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++) {  \
@@ -1256,6 +1259,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)
@@ -1280,6 +1285,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++) {\
@@ -1290,6 +1299,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 v9 01/14] target/riscv: rvv: Prune redundant ESZ, DSZ parameter passed

2022-04-27 Thread ~eopxd
From: eopXD 

No functional change intended in this commit.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
---
 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 3bd4aac9c9..e94caf1a3c 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_vv_w)
+GEN_VEXT_VV(vwsub_vv_b)
+GEN_VEXT_VV(vwsub_vv_h

[PATCH qemu v9 04/14] target/riscv: rvv: Add tail agnostic for vv instructions

2022-04-27 Thread ~eopxd
From: eopXD 

This is the first commit regarding the tail agnostic behavior.
Added option 'rvv_ta_all_1s' to enable the behavior, the option
is default to false.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
---
 target/riscv/cpu.c  |   1 +
 target/riscv/cpu.h  |   2 +
 target/riscv/cpu_helper.c   |   2 +
 target/riscv/insn_trans/trans_rvv.c.inc |  11 +
 target/riscv/internals.h|   5 +-
 target/riscv/translate.c|   2 +
 target/riscv/vector_helper.c| 296 +---
 7 files changed, 188 insertions(+), 131 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ddda4906ff..cd4cf4b41e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -810,6 +810,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(),
 };
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c069fe85fa..8c4a79b5a0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -369,6 +369,7 @@ struct RISCVCPUConfig {
 bool ext_zhinxmin;
 bool ext_zve32f;
 bool ext_zve64f;
+bool rvv_ta_all_1s;
 
 /* Vendor-specific custom extensions */
 bool ext_XVentanaCondOps;
@@ -516,6 +517,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 1c60fb2e80..2941c88c31 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 57953923d5..cc80bf00ff 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1223,6 +1223,16 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 gvec_fn(s->sew, vreg_ofs(s, a->rd),
 vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1),
 MAXSZ(s), MAXSZ(s));
@@ -1231,6 +1241,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 fac998a6b5..7775dade26 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;
@@ -1083,6 +1084,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_f

[PATCH qemu v9 06/14] target/riscv: rvv: Add tail agnostic for vx, vvm, vxm instructions

2022-04-27 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 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  29 +++
 target/riscv/internals.h|   5 +-
 target/riscv/translate.c|   2 +
 target/riscv/vector_helper.c| 317 +---
 4 files changed, 213 insertions(+), 140 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 99691f1b9f..d15858fc6f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1299,6 +1299,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));
 
@@ -1335,6 +1337,16 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn 
*gvec_fn,
 }
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 TCGv_i64 src1 = tcg_temp_new_i64();
 
 tcg_gen_ext_tl_i64(src1, get_gpr(s, a->rs1, EXT_SIGN));
@@ -1464,6 +1476,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));
 
@@ -1493,6 +1507,16 @@ do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn 
*gvec_fn,
 }
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 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);
@@ -1546,6 +1570,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),
@@ -1627,6 +1652,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),
@@ -1705,6 +1731,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/translate.c b/target/riscv/translate.c
index 7775dade26..58cbb6ded3 100644
--- a/target/

[PATCH qemu v9 09/14] target/riscv: rvv: Add tail agnostic for vector integer merge and move instructions

2022-04-27 Thread ~eopxd
From: eopXD 

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

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 430847b0f9..46ee673040 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2123,11 +2123,22 @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v 
*a)
 /* 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->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 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,
@@ -2163,6 +2174,16 @@ 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->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
 MAXSZ(s), MAXSZ(s), s1);
 } else {
@@ -2170,6 +2191,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,
@@ -2200,6 +,16 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i 
*a)
 vext_check_ss(s, a->rd, 0, 1)) {
 int64_t simm = sextract64(a->rs1, 0, 5);
 if (s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 tcg_gen_gvec_dup_imm(s->sew, vreg_ofs(s, a->rd),
  MAXSZ(s), MAXSZ(s), simm);
 mark_vs_dirty(s);
@@ -2208,6 +2240,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,
@@ -2780,6 +2813,16 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f 
*a)
 TCGv_i64 t1;
 
 if (s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 t1 = tcg_temp_new_i64();
 /* NaN-box f[rs1] */
 do_nanbox(s, t1, cpu_fpr[a->rs1]);
@@ -2791,6 +2834,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);
 sta

Re: [PATCH v3 2/6] 9pfs: fix qemu_mknodat(S_IFSOCK) on macOS

2022-04-27 Thread Greg Kurz
On Mon, 25 Apr 2022 14:20:46 +0200
Christian Schoenebeck  wrote:

> mknod() on macOS does not support creating sockets, so divert to
> call sequence socket(), bind() and chmod() respectively if S_IFSOCK
> was passed with mode argument.
> 
> Link: https://lore.kernel.org/qemu-devel/17933734.zYzKuhC07K@silver/
> Signed-off-by: Christian Schoenebeck 
> Reviewed-by: Will Cohen 
> Reviewed-by: Greg Kurz 
> ---

Nack until the chmod() issue is addressed. :-\

>  hw/9pfs/9p-util-darwin.c | 34 +-
>  1 file changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/9pfs/9p-util-darwin.c b/hw/9pfs/9p-util-darwin.c
> index e24d09763a..63797e60cd 100644
> --- a/hw/9pfs/9p-util-darwin.c
> +++ b/hw/9pfs/9p-util-darwin.c
> @@ -74,6 +74,34 @@ int fsetxattrat_nofollow(int dirfd, const char *filename, 
> const char *name,
>   */
>  #if defined CONFIG_PTHREAD_FCHDIR_NP
>  
> +static int create_socket_file_at_cwd(const char *filename, mode_t mode) {
> +int fd, err;
> +struct sockaddr_un addr = {
> +.sun_family = AF_UNIX
> +};
> +
> +/*
> + * sun_path is only 104 bytes, explicit filename length check required
> + */
> +if (sizeof(addr.sun_path) - 1 < strlen(filename) + 2) {
> +errno = ENAMETOOLONG;
> +return -1;
> +}
> +fd = socket(PF_UNIX, SOCK_DGRAM, 0);
> +if (fd == -1) {
> +return fd;
> +}
> +snprintf(addr.sun_path, sizeof(addr.sun_path), "./%s", filename);
> +err = bind(fd, (struct sockaddr *) &addr, sizeof(addr));
> +if (err == -1) {
> +goto out;
> +}
> +err = chmod(addr.sun_path, mode);
> +out:
> +close_preserve_errno(fd);
> +return err;
> +}
> +
>  int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
>  {
>  int preserved_errno, err;
> @@ -93,7 +121,11 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t 
> mode, dev_t dev)
>  if (pthread_fchdir_np(dirfd) < 0) {
>  return -1;
>  }
> -err = mknod(filename, mode, dev);
> +if (S_ISSOCK(mode)) {
> +err = create_socket_file_at_cwd(filename, mode);
> +} else {
> +err = mknod(filename, mode, dev);
> +}
>  preserved_errno = errno;
>  /* Stop using the thread-local cwd */
>  pthread_fchdir_np(-1);




[PATCH qemu v9 11/14] target/riscv: rvv: Add tail agnostic for vector floating-point instructions

2022-04-27 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 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  15 +
 target/riscv/vector_helper.c| 443 +---
 2 files changed, 262 insertions(+), 196 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 46ee673040..a267945267 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2404,6 +2404,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,   \
@@ -2486,6 +2489,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);   \
 } \
@@ -2524,6 +2530,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, \
@@ -2563,6 +2570,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);  \
 }\
@@ -2599,6 +2607,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,   \
@@ -2638,6 +2647,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);  \
 }\
@@ -2721,6 +2731,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,
@@ -2935,6 +2946,7 @@ 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_

[PATCH qemu v9 12/14] target/riscv: rvv: Add tail agnostic for vector reduction instructions

2022-04-27 Thread ~eopxd
From: eopXD 

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
---
 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 365071bfa9..3c4218d0dc 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4515,6 +4515,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));\
   \
@@ -4527,6 +4530,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[*]) */
@@ -4596,6 +4601,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)); \
\
@@ -4608,6 +4616,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 */
@@ -4632,6 +4642,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));
 
@@ -4645,6 +4658,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,
@@ -4652,6 +4667,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);
 
@@ -4665,6 +4683,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 v9 13/14] target/riscv: rvv: Add tail agnostic for vector mask instructions

2022-04-27 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 
---
 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 a267945267..ab9f876c28 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3209,6 +3209,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,   \
@@ -3313,6 +3315,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,  \
@@ -3350,6 +3354,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,
@@ -3379,6 +3384,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 3c4218d0dc..20aa0aee2b 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4697,6 +4697,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; \
   \
@@ -4706,6 +4708,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))
@@ -4773,6 +4784,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;
 
@@ -4801,6 +4814,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);
+}
+}
 }
 
 void HELPER(vmsbf_m)(void *vd, void *v0, void *vs

Re: [PATCH] 9pfs: local: Do not follow symlink in _nofollow

2022-04-27 Thread Greg Kurz
On Wed, 27 Apr 2022 10:46:31 +0200
Christian Schoenebeck  wrote:

> On Mittwoch, 27. April 2022 04:45:45 CEST Akihiko Odaki wrote:
> > Signed-off-by: Akihiko Odaki 
> > ---
> >  hw/9pfs/9p-local.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
> > index d42ce6d8b82..def8afdb4d6 100644
> > --- a/hw/9pfs/9p-local.c
> > +++ b/hw/9pfs/9p-local.c
> > @@ -365,7 +365,7 @@ static int fchmodat_nofollow(int dirfd, const char
> > *name, mode_t mode) if (fd == -1) {
> >  /* In case the file is writable-only and isn't a directory. */
> >  if (errno == EACCES) {
> > -fd = openat_file(dirfd, name, O_WRONLY, 0);
> > +fd = openat_file(dirfd, name, O_WRONLY | O_NOFOLLOW, 0);
> 
> O_NOFOLLOW flag is always added inside openat_file() implementation:
> 
> https://github.com/qemu/qemu/blob/master/hw/9pfs/9p-util.h#L60
> 
> So this change is not necessary AFAICS.
> 

Right, and with macOS in mind, maybe fchmodat(AT_SYMLINK_NOFOLLOW) just
works unlike with linux ?

> >  }
> >  if (fd == -1 && errno == EISDIR) {
> >  errno = EACCES;
> 
> 




Re: [PATCH 01/18] hw/audio: Remove -soundhw support

2022-04-27 Thread Paolo Bonzini

On 4/25/22 10:21, Martin Kletzander wrote:

One thing I am not sure about is whether to keep the aliases of ac97 and
es1370 in the qdev_alias_table.

Signed-off-by: Martin Kletzander 


I agree that -soundhw is a bad option, but I think we should preserve 
something similarly easy to use.  For example:


 -audio OPTIONS,model=XXX

would expand to

 -audiodev OPTIONS,id=audiodev0

and then call the same init_isa/init_pci functions that already exist; 
except that those would add an audiodev=audiodev0 property.


This way, one can use "-audio pa,model=hda".

Later on we can add a hook in the machines for the case when no model is 
specified, but you don't need to do that now because it's backwards 
compatible.


Let me post a sketch after lunch.

Paolo


---
  docs/about/deprecated.rst |   9 -
  docs/about/removed-features.rst   |  10 +
  docs/qdev-device-use.txt  |  21 +--
  docs/replay.txt   |   2 +-
  hw/audio/ac97.c   |   3 -
  hw/audio/adlib.c  |   2 -
  hw/audio/cs4231a.c|   2 -
  hw/audio/es1370.c |   3 -
  hw/audio/gus.c|   2 -
  hw/audio/intel-hda.c  |  21 ---
  hw/audio/meson.build  |   1 -
  hw/audio/pcspk.c  |  11 --
  hw/audio/sb16.c   |   3 -
  hw/audio/soundhw.c| 177 --
  include/hw/audio/soundhw.h|  15 --
  qemu-options.hx   |  27 ---
  .../codeconverter/test_regexps.py |   1 -
  softmmu/qdev-monitor.c|   2 -
  softmmu/vl.c  |   6 -
  19 files changed, 19 insertions(+), 299 deletions(-)
  delete mode 100644 hw/audio/soundhw.c
  delete mode 100644 include/hw/audio/soundhw.h

diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index cf02ef6821e4..7ba71ebd3435 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -39,15 +39,6 @@ should specify an ``audiodev=`` property.  Additionally, 
when using
  vnc, you should specify an ``audiodev=`` property if you plan to
  transmit audio through the VNC protocol.
  
-Creating sound card devices using ``-soundhw`` (since 5.1)

-''
-
-Sound card devices should be created using ``-device`` instead.  The
-names are the same for most devices.  The exceptions are ``hda`` which
-needs two devices (``-device intel-hda -device hda-duplex``) and
-``pcspk`` which can be activated using ``-machine
-pcspk-audiodev=``.
-
  ``-chardev`` backend aliases ``tty`` and ``parport`` (since 6.0)
  
  
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst

index 4b831ea29176..086ba3edb042 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -336,6 +336,16 @@ for the RISC-V ``virt`` machine and ``sifive_u`` machine.
  The ``-no-quit`` was a synonym for ``-display ...,window-close=off`` which
  should be used instead.
  
+Creating sound card devices using ``-soundhw`` (removed in 7.1)

+'''
+
+Sound card devices should be created using ``-device`` instead.  The
+names are the same for most devices.  The exceptions are ``hda`` which
+needs two devices (``-device intel-hda -device hda-duplex``) and
+``pcspk`` which can be activated using ``-machine
+pcspk-audiodev=``.  And ``AC97`` and ``ES1370`` now have to be
+specified in uppercase.
+
  
  QEMU Machine Protocol (QMP) commands

  
diff --git a/docs/qdev-device-use.txt b/docs/qdev-device-use.txt
index 240888933482..30e7eaa3e66d 100644
--- a/docs/qdev-device-use.txt
+++ b/docs/qdev-device-use.txt
@@ -311,21 +311,16 @@ constraints.
  
  Host and guest part of audio devices have always been separate.
  
-The old way to define guest audio devices is -soundhw C1,...

+Host side (backend) is defined using -audiodev with a specific driver:
  
-The new way is to define each guest audio device separately with

--device.
+spice
+pa
+none
  
-Map from -soundhw sound card name to -device:

-
-ac97-device AC97
-cs4231a -device cs4231a,iobase=IOADDR,irq=IRQ,dma=DMA
-es1370  -device ES1370
-gus -device gus,iobase=IOADDR,irq=IRQ,dma=DMA,freq=F
-hda -device intel-hda,msi=MSI -device hda-duplex
-sb16-device 
sb16,iobase=IOADDR,irq=IRQ,dma=DMA,dma16=DMA16,version=V
-adlib   not yet available with -device
-pcspk   not yet available with -device
+And each guest audio device is then defined with -device with
+audiodev=AUDIODEV_ID that refers to the audio backend above.  E

Re: [PATCH v2 25/26] tests: replace qemu_set_nonblock()

2022-04-27 Thread Marc-André Lureau
Hi

On Wed, Apr 27, 2022 at 1:41 PM Thomas Huth  wrote:
>
> On 26/04/2022 11.27, marcandre.lur...@redhat.com wrote:
> > From: Marc-André Lureau 
> >
> > The call is POSIX-specific. Use the dedicated GLib API.
>
> g_unix_set_fd_nonblocking() is also available on Unix-like systems according
> to its name, I suppose? So what's the advantage of this change?
>

This is a preliminary patch before the last patch
(https://patchew.org/QEMU/20220426092715.3931705-1-marcandre.lur...@redhat.com/20220426092715.3931705-27-marcandre.lur...@redhat.com/)

We should reserve qemu_socket_set_*block() usage to socket-like fd.

thanks


>   Thomas
>
>
> > Signed-off-by: Marc-André Lureau 
> > ---
> >   tests/qtest/vhost-user-test.c | 4 +++-
> >   1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
> > index ee30f5479648..a2cec8768462 100644
> > --- a/tests/qtest/vhost-user-test.c
> > +++ b/tests/qtest/vhost-user-test.c
> > @@ -302,6 +302,7 @@ static int chr_can_read(void *opaque)
> >
> >   static void chr_read(void *opaque, const uint8_t *buf, int size)
> >   {
> > +g_autoptr(GError) err = NULL;
> >   TestServer *s = opaque;
> >   CharBackend *chr = &s->chr;
> >   VhostUserMsg msg;
> > @@ -394,7 +395,8 @@ static void chr_read(void *opaque, const uint8_t *buf, 
> > int size)
> >* The receive function forces it to be blocking,
> >* so revert it back to non-blocking.
> >*/
> > -qemu_set_nonblock(fd);
> > +g_unix_set_fd_nonblocking(fd, true, &err);
> > +g_assert_no_error(err);
> >   break;
> >
> >   case VHOST_USER_SET_LOG_BASE:
>




Re: [PATCH v2 2/5] 9pfs: fix qemu_mknodat(S_IFSOCK) on macOS

2022-04-27 Thread Greg Kurz
On Wed, 27 Apr 2022 11:27:28 +0900
Akihiko Odaki  wrote:

> On 2022/04/26 21:38, Greg Kurz wrote:

[..skip..]

> > 
> > I think Christian's explanation is clear enough. We don't guarantee
> > that v9fs_co_foo() calls run atomically. As a consequence, the client
> > might see transient states or be able to interact with an ongoing
> > request. And to answer your question, we have no specific rationale
> > on security with that.
> > 
> > I'm not sure what the concerns are but unless you come up with a
> > valid scenario [*] I don't see any reason to prevent this patch
> > to go forward.
> > 
> > [*] things like:
> >  - client escaping the shared directory
> >  - QEMU crashing
> >  - QEMU hogging host resources
> >  - client-side unprivileged user gaining elevated privleges
> >in the guest
> 
> I was just not sure if such transient states are safe. The past 
> discussion was about the length of the non-atomic time window where a 
> path name is used to identify a particular file, but if such states are 
> not considered problematic, the length does not matter all and we can 
> confidently say the sequence of bind() and chmod() is safe.
> 
> Considering the transient states are tolerated in 9pfs, we need to 
> design this function to be tolerant with transient states as well. The 
> use of chmod() is not safe when we consider about transient states. A 
> malicious actor may replace the file at the path with a symlink which 
> may escape the shared directory and chmod() will naively follow it. 

You get a point here. Thanks for your tenacity ! :-)

> chmod() should be replaced with fchmodat_nofollow() or something similar.
> 

On a GNU/Linux system, this could be achieved by calling fchmod() on
the socket fd *before* calling bind() but I'm afraid this hack might
not work with a BSDish OS.

Replacing chmod() with fchmodat_nofollow(dirfd, addr.sun_path, mode)
won't make things atomic as above but at least it won't follow a
malicious symbolic link : mknod() on the client will fail with
ELOOP, which is fine when it comes to not breaking out of the shared
directory.

This brings up a new problem I hadn't realized before : the
fchmodat_nofollow() implementation in 9p-local.c is really
a linux only thing to cope with AT_SYMLINK_NOFOLLOW not being
supported with fchmodat(). It looks that this should move to
9p-util-linux.c and a proper version should be added for macOS
in 9p-util-darwin.c

Cheers,

--
Greg

> Regards,
> Akihiko Odaki
> 
> > 
> > Cheers,
> > 
> > --
> > Greg
> > 
> >> Regards,
> >> Akihiko Odaki
> > 
> 




Re: [PATCH] target/arm: Use field names for accessing DBGWCRn

2022-04-27 Thread Alex Bennée


Richard Henderson  writes:

> While defining these names, use the correct field width of 5 not 4 for
> DBGWCR.MASK.  This typo prevented setting a watchpoint larger than 32k.
>
> Reported-by: Chris Howard 
> Signed-off-by: Richard Henderson 

Reviewed-by: Alex Bennée 

-- 
Alex Bennée



Re: [PATCH v2 26/26] util: rename qemu_*block() socket functions

2022-04-27 Thread Marc-André Lureau
Hi Stefan

On Tue, Apr 26, 2022 at 6:33 PM Stefan Hajnoczi  wrote:

> On Tue, Apr 26, 2022 at 01:27:15PM +0400, marcandre.lur...@redhat.com
> wrote:
> > From: Marc-André Lureau 
> >
> > The qemu_*block() functions are meant to be be used with sockets (the
> > win32 implementation expects SOCKET)
> >
> > Over time, those functions where used with Win32 SOCKET or
> > file-descriptors interchangeably. But for portability, they must only be
> > used with socket-like file-descriptors. FDs can use
> > g_unix_set_fd_nonblocking() instead.
> >
> > Rename the functions with "socket" in the name to prevent bad usages.
> >
> > Signed-off-by: Marc-André Lureau 
> > ---
> >  include/qemu/sockets.h  |  6 +++---
> >  chardev/char-socket.c   |  2 +-
> >  contrib/ivshmem-server/ivshmem-server.c |  2 +-
> >  hw/hyperv/syndbg.c  |  2 +-
> >  hw/virtio/vhost-user.c  |  2 +-
> >  io/channel-socket.c |  6 +++---
> >  net/l2tpv3.c|  2 +-
> >  net/socket.c| 10 +-
> >  qga/channel-posix.c |  2 +-
> >  tests/unit/socket-helpers.c |  2 +-
> >  tests/unit/test-crypto-tlssession.c |  8 
> >  util/oslib-posix.c  |  8 
> >  util/oslib-win32.c  |  8 
> >  util/vhost-user-server.c|  4 ++--
> >  14 files changed, 32 insertions(+), 32 deletions(-)
>
> Thanks for fixing this!
>
> Reviewed-by: Stefan Hajnoczi 
>

Thanks, could you also review the preliminary patches 19-25 ? They reduce
the usage of qemu_socket* functions, and use glib API instead.

-- 
Marc-André Lureau


Re: Signing QEMU up for GitLab for Open Source?

2022-04-27 Thread Alex Bennée


Daniel P. Berrangé  writes:

> On Mon, Apr 25, 2022 at 01:53:28PM +0100, Alex Bennée wrote:
>> 
>> Stefan Hajnoczi  writes:
>> 
>> > [[PGP Signed Part:Undecided]]
>> > Hi,
>> > QEMU needs to enroll in GitLab for Open Source before July 1st to
>> > receive 50,000 CI/CD pipeline minutes and GitLab Ultimate features:
>> >
>> > https://about.gitlab.com/blog/2022/02/04/ultimate-perks-for-open-source-projects/
>> > https://about.gitlab.com/solutions/open-source/
>> >
>> > CI/CD minutes also become available to personal forks for open source
>> > repos so contributors can run CI pipelines without hitting CI limits as
>> > easily.
>> >
>> > Alex, Paolo, Peter, and I are qemu-project owners on GitLab. Has anyone
>> > already submitted an application?
>> 
>> No but if we are happy with the terms we should go ahead. I don't recall
>> SFLC having any major objections and GitLab seem to be pretty engaged in
>> ensuring open source projects are well treated.
>
> Yep, they've been pretty receptive to feedback myself & other maintainers
> been giving about the usage & needs of QEMU/libvirt and other major OSS
> projects.
>
> FWIW, I've applied on behalf of the libvirt group today.

OK I'll push the button for the QEMU project.

-- 
Alex Bennée



Re: [PATCH v2 25/26] tests: replace qemu_set_nonblock()

2022-04-27 Thread Thomas Huth

On 27/04/2022 12.33, Marc-André Lureau wrote:

Hi

On Wed, Apr 27, 2022 at 1:41 PM Thomas Huth  wrote:


On 26/04/2022 11.27, marcandre.lur...@redhat.com wrote:

From: Marc-André Lureau 

The call is POSIX-specific. Use the dedicated GLib API.


g_unix_set_fd_nonblocking() is also available on Unix-like systems according
to its name, I suppose? So what's the advantage of this change?



This is a preliminary patch before the last patch
(https://patchew.org/QEMU/20220426092715.3931705-1-marcandre.lur...@redhat.com/20220426092715.3931705-27-marcandre.lur...@redhat.com/)

We should reserve qemu_socket_set_*block() usage to socket-like fd.


Ok, makes sense now, thanks.

Reviewed-by: Thomas Huth 

PS: In case you respin, it might make sense to add a sentence à la "We're 
going to limit qemu_set_nonblock() to sockets only" to the commit description.





[PATCH 1/2] hw/arm/smmuv3: Cache event fault record

2022-04-27 Thread Jean-Philippe Brucker
The Record bit in the Context Descriptor tells the SMMU to report fault
events to the event queue. Since we don't cache the Record bit at the
moment, access faults from a cached Context Descriptor are never
reported. Store the Record bit in the cached SMMUTransCfg.

Fixes: 9bde7f0674fe ("hw/arm/smmuv3: Implement translate callback")
Signed-off-by: Jean-Philippe Brucker 
---
 hw/arm/smmuv3-internal.h |  1 -
 include/hw/arm/smmu-common.h |  1 +
 hw/arm/smmuv3.c  | 14 +++---
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
index d1885ae3f2..6de52bbf4d 100644
--- a/hw/arm/smmuv3-internal.h
+++ b/hw/arm/smmuv3-internal.h
@@ -387,7 +387,6 @@ typedef struct SMMUEventInfo {
 SMMUEventType type;
 uint32_t sid;
 bool recorded;
-bool record_trans_faults;
 bool inval_ste_allowed;
 union {
 struct {
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
index 706be3c6d0..21e62342e9 100644
--- a/include/hw/arm/smmu-common.h
+++ b/include/hw/arm/smmu-common.h
@@ -71,6 +71,7 @@ typedef struct SMMUTransCfg {
 bool disabled; /* smmu is disabled */
 bool bypassed; /* translation is bypassed */
 bool aborted;  /* translation is aborted */
+bool record_faults;/* record fault events */
 uint64_t ttb;  /* TT base address */
 uint8_t oas;   /* output address width */
 uint8_t tbi;   /* Top Byte Ignore */
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 707eb430c2..8b1d8103dc 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -527,7 +527,7 @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, 
SMMUEventInfo *event)
 trace_smmuv3_decode_cd_tt(i, tt->tsz, tt->ttb, tt->granule_sz, 
tt->had);
 }
 
-event->record_trans_faults = CD_R(cd);
+cfg->record_faults = CD_R(cd);
 
 return 0;
 
@@ -680,7 +680,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion 
*mr, hwaddr addr,
 
 tt = select_tt(cfg, addr);
 if (!tt) {
-if (event.record_trans_faults) {
+if (cfg->record_faults) {
 event.type = SMMU_EVT_F_TRANSLATION;
 event.u.f_translation.addr = addr;
 event.u.f_translation.rnw = flag & 0x1;
@@ -696,7 +696,7 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion 
*mr, hwaddr addr,
 if (cached_entry) {
 if ((flag & IOMMU_WO) && !(cached_entry->entry.perm & IOMMU_WO)) {
 status = SMMU_TRANS_ERROR;
-if (event.record_trans_faults) {
+if (cfg->record_faults) {
 event.type = SMMU_EVT_F_PERMISSION;
 event.u.f_permission.addr = addr;
 event.u.f_permission.rnw = flag & 0x1;
@@ -720,28 +720,28 @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion 
*mr, hwaddr addr,
 event.u.f_walk_eabt.addr2 = ptw_info.addr;
 break;
 case SMMU_PTW_ERR_TRANSLATION:
-if (event.record_trans_faults) {
+if (cfg->record_faults) {
 event.type = SMMU_EVT_F_TRANSLATION;
 event.u.f_translation.addr = addr;
 event.u.f_translation.rnw = flag & 0x1;
 }
 break;
 case SMMU_PTW_ERR_ADDR_SIZE:
-if (event.record_trans_faults) {
+if (cfg->record_faults) {
 event.type = SMMU_EVT_F_ADDR_SIZE;
 event.u.f_addr_size.addr = addr;
 event.u.f_addr_size.rnw = flag & 0x1;
 }
 break;
 case SMMU_PTW_ERR_ACCESS:
-if (event.record_trans_faults) {
+if (cfg->record_faults) {
 event.type = SMMU_EVT_F_ACCESS;
 event.u.f_access.addr = addr;
 event.u.f_access.rnw = flag & 0x1;
 }
 break;
 case SMMU_PTW_ERR_PERMISSION:
-if (event.record_trans_faults) {
+if (cfg->record_faults) {
 event.type = SMMU_EVT_F_PERMISSION;
 event.u.f_permission.addr = addr;
 event.u.f_permission.rnw = flag & 0x1;
-- 
2.35.1




Re: [PATCH] 9pfs: local: Do not follow symlink in _nofollow

2022-04-27 Thread Christian Schoenebeck
On Mittwoch, 27. April 2022 12:21:51 CEST Greg Kurz wrote:
> On Wed, 27 Apr 2022 10:46:31 +0200
> 
> Christian Schoenebeck  wrote:
> > On Mittwoch, 27. April 2022 04:45:45 CEST Akihiko Odaki wrote:
> > > Signed-off-by: Akihiko Odaki 
> > > ---
> > > 
> > >  hw/9pfs/9p-local.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
> > > index d42ce6d8b82..def8afdb4d6 100644
> > > --- a/hw/9pfs/9p-local.c
> > > +++ b/hw/9pfs/9p-local.c
> > > @@ -365,7 +365,7 @@ static int fchmodat_nofollow(int dirfd, const char
> > > *name, mode_t mode) if (fd == -1) {
> > > 
> > >  /* In case the file is writable-only and isn't a directory. */
> > >  if (errno == EACCES) {
> > > 
> > > -fd = openat_file(dirfd, name, O_WRONLY, 0);
> > > +fd = openat_file(dirfd, name, O_WRONLY | O_NOFOLLOW, 0);
> > 
> > O_NOFOLLOW flag is always added inside openat_file() implementation:
> > 
> > https://github.com/qemu/qemu/blob/master/hw/9pfs/9p-util.h#L60
> > 
> > So this change is not necessary AFAICS.
> 
> Right, and with macOS in mind, maybe fchmodat(AT_SYMLINK_NOFOLLOW) just
> works unlike with linux ?

Yep, fchmodat(AT_SYMLINK_NOFOLLOW) seems to work on macOS! Like you already 
suggested on the other thread, it would make sense to move current 
implementation of fchmodat_nofollow() to 9p-util-linux.h/.c and let macOS just 
use fchmodat(AT_SYMLINK_NOFOLLOW) instead.

Best regards,
Christian Schoenebeck





[PATCH 2/2] hw/arm/smmuv3: Add space in guest error message

2022-04-27 Thread Jean-Philippe Brucker
Make the translation error message prettier by adding a missing space
before the parenthesis.

Signed-off-by: Jean-Philippe Brucker 
---
 hw/arm/smmuv3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 8b1d8103dc..3a989b09cb 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -786,7 +786,7 @@ epilogue:
 break;
 case SMMU_TRANS_ERROR:
 qemu_log_mask(LOG_GUEST_ERROR,
-  "%s translation failed for iova=0x%"PRIx64"(%s)\n",
+  "%s translation failed for iova=0x%"PRIx64" (%s)\n",
   mr->parent_obj.name, addr, 
smmu_event_string(event.type));
 smmuv3_record_event(s, &event);
 break;
-- 
2.35.1




Re: [PATCH v10 6/7] multifd: Send header packet without flags if zero-copy-send is enabled

2022-04-27 Thread Leonardo Bras Soares Passos
On Tue, Apr 26, 2022 at 8:26 PM Peter Xu  wrote:
>
> On Tue, Apr 26, 2022 at 08:06:55PM -0300, Leonardo Bras wrote:
> > Since d48c3a0445 ("multifd: Use a single writev on the send side"),
> > sending the header packet and the memory pages happens in the same
> > writev, which can potentially make the migration faster.
> >
> > Using channel-socket as example, this works well with the default copying
> > mechanism of sendmsg(), but with zero-copy-send=true, it will cause
> > the migration to often break.
> >
> > This happens because the header packet buffer gets reused quite often,
> > and there is a high chance that by the time the MSG_ZEROCOPY mechanism get
> > to send the buffer, it has already changed, sending the wrong data and
> > causing the migration to abort.
> >
> > It means that, as it is, the buffer for the header packet is not suitable
> > for sending with MSG_ZEROCOPY.
> >
> > In order to enable zero copy for multifd, send the header packet on an
> > individual write(), without any flags, and the remanining pages with a
> > writev(), as it was happening before. This only changes how a migration
> > with zero-copy-send=true works, not changing any current behavior for
> > migrations with zero-copy-send=false.
> >
> > Signed-off-by: Leonardo Bras 
> > ---
> >  migration/multifd.c | 23 ---
> >  1 file changed, 20 insertions(+), 3 deletions(-)
> >
> > diff --git a/migration/multifd.c b/migration/multifd.c
> > index 15fb668e64..07b2e92d8d 100644
> > --- a/migration/multifd.c
> > +++ b/migration/multifd.c
> > @@ -617,6 +617,7 @@ static void *multifd_send_thread(void *opaque)
> >  MultiFDSendParams *p = opaque;
> >  Error *local_err = NULL;
> >  int ret = 0;
> > +bool use_zero_copy_send = migrate_use_zero_copy_send();
> >
> >  trace_multifd_send_thread_start(p->id);
> >  rcu_register_thread();
> > @@ -639,9 +640,14 @@ static void *multifd_send_thread(void *opaque)
> >  if (p->pending_job) {
> >  uint64_t packet_num = p->packet_num;
> >  uint32_t flags = p->flags;
> > -p->iovs_num = 1;
> >  p->normal_num = 0;
> >
> > +if (use_zero_copy_send) {
> > +p->iovs_num = 0;
> > +} else {
> > +p->iovs_num = 1;
> > +}
> > +
> >  for (int i = 0; i < p->pages->num; i++) {
> >  p->normal[p->normal_num] = p->pages->offset[i];
> >  p->normal_num++;
> > @@ -665,8 +671,19 @@ static void *multifd_send_thread(void *opaque)
> >  trace_multifd_send(p->id, packet_num, p->normal_num, flags,
> > p->next_packet_size);
> >
> > -p->iov[0].iov_len = p->packet_len;
> > -p->iov[0].iov_base = p->packet;
> > +if (use_zero_copy_send) {
> > +/* Send header first, without zerocopy */
> > +ret = qio_channel_write_all(p->c, (void *)p->packet,
> > +p->packet_len, &local_err);
> > +if (ret != 0) {
> > +break;
> > +}
> > +
>
> Extra but useless newline.. but not worth a repost.  Looks good here:
>
> Reviewed-by: Peter Xu 
>
> Thanks,

Thanks for reviewing Peter!

Best regards,
Leo

>
> > +} else {
> > +/* Send header using the same writev call */
> > +p->iov[0].iov_len = p->packet_len;
> > +p->iov[0].iov_base = p->packet;
> > +}
> >
> >  ret = qio_channel_writev_all(p->c, p->iov, p->iovs_num,
> >   &local_err);
> > --
> > 2.36.0
> >
>
> --
> Peter Xu
>




Re: [PATCH v10 6/7] multifd: Send header packet without flags if zero-copy-send is enabled

2022-04-27 Thread Leonardo Bras Soares Passos
On Wed, Apr 27, 2022 at 5:44 AM Daniel P. Berrangé  wrote:
>
> On Tue, Apr 26, 2022 at 08:06:55PM -0300, Leonardo Bras wrote:
> > Since d48c3a0445 ("multifd: Use a single writev on the send side"),
> > sending the header packet and the memory pages happens in the same
> > writev, which can potentially make the migration faster.
> >
> > Using channel-socket as example, this works well with the default copying
> > mechanism of sendmsg(), but with zero-copy-send=true, it will cause
> > the migration to often break.
> >
> > This happens because the header packet buffer gets reused quite often,
> > and there is a high chance that by the time the MSG_ZEROCOPY mechanism get
> > to send the buffer, it has already changed, sending the wrong data and
> > causing the migration to abort.
> >
> > It means that, as it is, the buffer for the header packet is not suitable
> > for sending with MSG_ZEROCOPY.
> >
> > In order to enable zero copy for multifd, send the header packet on an
> > individual write(), without any flags, and the remanining pages with a
> > writev(), as it was happening before. This only changes how a migration
> > with zero-copy-send=true works, not changing any current behavior for
> > migrations with zero-copy-send=false.
> >
> > Signed-off-by: Leonardo Bras 
> > ---
> >  migration/multifd.c | 23 ---
> >  1 file changed, 20 insertions(+), 3 deletions(-)
>
> Reviewed-by: Daniel P. Berrangé 
>
>
> With regards,
> Daniel

Thanks for reviewing Daniel!

Best regards,
Leo

> --
> |: 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 v10 7/7] multifd: Implement zero copy write in multifd migration (multifd-zero-copy)

2022-04-27 Thread Leonardo Bras Soares Passos
On Wed, Apr 27, 2022 at 5:46 AM Daniel P. Berrangé  wrote:
>
> On Tue, Apr 26, 2022 at 08:06:56PM -0300, Leonardo Bras wrote:
> > 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 
> > ---
> >  migration/multifd.h   |  2 ++
> >  migration/migration.c | 11 ++-
> >  migration/multifd.c   | 37 +++--
> >  migration/socket.c|  5 +++--
> >  4 files changed, 50 insertions(+), 5 deletions(-)
>
> Reviewed-by: Daniel P. Berrangé 
>
>
> With regards,
> Daniel

Thanks for reviewing, Daniel!

Best regards,
Leo

> --
> |: 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 :|
>




[RFC PATCH 1/6] pc: remove -soundhw pcspk

2022-04-27 Thread Paolo Bonzini
The pcspk device is the only user of isa_register_soundhw, and the only
-soundhw option which does not create a new device (it hacks into the
PCSpkState by hand).  Remove it, since it was deprecated.

Signed-off-by: Paolo Bonzini 
---
 hw/audio/pcspk.c   | 10 --
 hw/audio/soundhw.c | 27 ---
 include/hw/audio/soundhw.h |  3 ---
 3 files changed, 4 insertions(+), 36 deletions(-)

diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index dfc7ebca4e..daf92a4ce1 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -245,18 +245,8 @@ static const TypeInfo pcspk_info = {
 .class_init = pcspk_class_initfn,
 };
 
-static int pcspk_audio_init_soundhw(ISABus *bus)
-{
-PCSpkState *s = pcspk_state;
-
-warn_report("'-soundhw pcspk' is deprecated, "
-"please set a backend using '-machine pcspk-audiodev=' 
instead");
-return pcspk_audio_init(s);
-}
-
 static void pcspk_register(void)
 {
 type_register_static(&pcspk_info);
-isa_register_soundhw("pcspk", "PC speaker", pcspk_audio_init_soundhw);
 }
 type_init(pcspk_register)
diff --git a/hw/audio/soundhw.c b/hw/audio/soundhw.c
index 173b674ff5..f7d94d7dfa 100644
--- a/hw/audio/soundhw.c
+++ b/hw/audio/soundhw.c
@@ -36,26 +36,12 @@ struct soundhw {
 const char *typename;
 int enabled;
 int isa;
-union {
-int (*init_isa) (ISABus *bus);
-int (*init_pci) (PCIBus *bus);
-} init;
+int (*init_pci) (PCIBus *bus);
 };
 
 static struct soundhw soundhw[9];
 static int soundhw_count;
 
-void isa_register_soundhw(const char *name, const char *descr,
-  int (*init_isa)(ISABus *bus))
-{
-assert(soundhw_count < ARRAY_SIZE(soundhw) - 1);
-soundhw[soundhw_count].name = name;
-soundhw[soundhw_count].descr = descr;
-soundhw[soundhw_count].isa = 1;
-soundhw[soundhw_count].init.init_isa = init_isa;
-soundhw_count++;
-}
-
 void pci_register_soundhw(const char *name, const char *descr,
   int (*init_pci)(PCIBus *bus))
 {
@@ -63,7 +49,7 @@ void pci_register_soundhw(const char *name, const char *descr,
 soundhw[soundhw_count].name = name;
 soundhw[soundhw_count].descr = descr;
 soundhw[soundhw_count].isa = 0;
-soundhw[soundhw_count].init.init_pci = init_pci;
+soundhw[soundhw_count].init_pci = init_pci;
 soundhw_count++;
 }
 
@@ -158,18 +144,13 @@ void soundhw_init(void)
 } else {
 pci_create_simple(pci_bus, -1, c->typename);
 }
-} else if (c->isa) {
-if (!isa_bus) {
-error_report("ISA bus not available for %s", c->name);
-exit(1);
-}
-c->init.init_isa(isa_bus);
 } else {
+assert(!c->isa);
 if (!pci_bus) {
 error_report("PCI bus not available for %s", c->name);
 exit(1);
 }
-c->init.init_pci(pci_bus);
+c->init_pci(pci_bus);
 }
 }
 }
diff --git a/include/hw/audio/soundhw.h b/include/hw/audio/soundhw.h
index f09a297854..e68685fcda 100644
--- a/include/hw/audio/soundhw.h
+++ b/include/hw/audio/soundhw.h
@@ -1,9 +1,6 @@
 #ifndef HW_SOUNDHW_H
 #define HW_SOUNDHW_H
 
-void isa_register_soundhw(const char *name, const char *descr,
-  int (*init_isa)(ISABus *bus));
-
 void pci_register_soundhw(const char *name, const char *descr,
   int (*init_pci)(PCIBus *bus));
 void deprecated_register_soundhw(const char *name, const char *descr,
-- 
2.35.1





Re: [PATCH v10 7/7] multifd: Implement zero copy write in multifd migration (multifd-zero-copy)

2022-04-27 Thread Leonardo Bras Soares Passos
On Tue, Apr 26, 2022 at 8:26 PM Peter Xu  wrote:
>
> On Tue, Apr 26, 2022 at 08:06:56PM -0300, Leonardo Bras wrote:
> > 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 
>
> --
> Peter Xu
>

Thanks for reviewing Peter!

Best regards,
Leo




Re: [PATCH v2] Warn user if the vga flag is passed but no vga device is created

2022-04-27 Thread Thomas Huth

On 23/04/2022 15.27, Peter Maydell wrote:

On Sat, 23 Apr 2022 at 11:00, Gautam Agrawal  wrote:


I will make changes in hw/ppc/spapr.c . In hw/hppa/machine.c ,
vga_interface_type is used inside if condition to check for graphics
device creation, but I am not able to find any relation with creation
of vga interface. Could you kindly provide some pointers about it?


It's exactly the same as all the other places that look
at vga_interface_type -- it looks at it and decides
whether to create a graphics device. (Arguably it should
not really be saying "anything except 'none' means create
the 'artist' graphics device", but that's a separate bug;
all you need to care about is "did we create a graphics
device because the user passed a -vga option".)


Agreed, that looks like a separate issue that we should fix one day... 
something for another BiteSizeTask ticket maybe? Same problem exists in the 
hw/mips/fuloong2e.c by the way.


 Thomas




[RFC PATCH 4/6] soundhw: unify initialization for ISA and PCI soundhw

2022-04-27 Thread Paolo Bonzini
Use qdev_new instead of distinguishing isa_create_simple/pci_create_simple.

Signed-off-by: Paolo Bonzini 
---
 hw/audio/soundhw.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/hw/audio/soundhw.c b/hw/audio/soundhw.c
index 0fb64bdc8f..a9d8807b18 100644
--- a/hw/audio/soundhw.c
+++ b/hw/audio/soundhw.c
@@ -114,25 +114,27 @@ void soundhw_init(void)
 struct soundhw *c = selected;
 ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, 
NULL);
 PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, 
NULL);
+BusState *bus;
 
-if (!c) {
-return;
-}
-if (c->typename) {
-warn_report("'-soundhw %s' is deprecated, "
-"please use '-device %s' instead",
-c->name, c->typename);
-if (c->isa) {
-isa_create_simple(isa_bus, c->typename);
-} else {
-pci_create_simple(pci_bus, -1, c->typename);
+if (c->isa) {
+if (!isa_bus) {
+error_report("ISA bus not available for %s", c->name);
+exit(1);
 }
+bus = BUS(isa_bus);
 } else {
-assert(!c->isa);
 if (!pci_bus) {
 error_report("PCI bus not available for %s", c->name);
 exit(1);
 }
+bus = BUS(pci_bus);
+}
+
+if (c->typename) {
+DeviceState *dev = qdev_new(c->typename);
+qdev_realize_and_unref(dev, bus, &error_fatal);
+} else {
+assert(!c->isa);
 c->init_pci(pci_bus);
 }
 }
-- 
2.35.1





[RFC PATCH 0/6] replace -soundhw with -audio

2022-04-27 Thread Paolo Bonzini
While the -soundhw option has been deprecated, the way of creating
audio devices is not as easy as with say -usbdevice or -nic.  This is
true especially of HDA devices.

This series introduces a new option called "-audio", which allows
full configuration of the backend and just the model of the frontend.
It is almost as easy to use as "-soundhw", especially because the
user does not have to know about creating a codec device.

Following the previous experience with those options, keep the easy and
useful cases and remove those that complicate the code unnecessarily; in
this case PC speaker support is removed, because it patches the device
instead of creating it, and so is the ability to create >1 device in
one shot.

Paolo

Paolo Bonzini (6):
  pc: remove -soundhw pcspk
  soundhw: remove ability to create multiple soundcards
  soundhw: extract soundhw help to a separate function
  soundhw: unify initialization for ISA and PCI soundhw
  soundhw: move help handling to vl.c
  vl: introduce -audio as a replacement for -soundhw

 audio/audio.c   |   8 +-
 audio/audio.h   |   1 +
 docs/about/deprecated.rst   |   9 --
 docs/about/removed-features.rst |   7 ++
 hw/audio/intel-hda.c|   5 +-
 hw/audio/pcspk.c|  10 ---
 hw/audio/soundhw.c  | 154 
 include/hw/audio/soundhw.h  |   8 +-
 qemu-options.hx |  51 +--
 softmmu/vl.c|  30 ++-
 10 files changed, 130 insertions(+), 153 deletions(-)

-- 
2.35.1




[RFC PATCH 6/6] vl: introduce -audio as a replacement for -soundhw

2022-04-27 Thread Paolo Bonzini
-audio is used like "-audio pa,model=sb16".  It is almost as simple as
-soundhw, but it reuses the -audiodev parsing machinery and attaches an
audiodev to the newly-created device.  The main 'feature' is that
it knows about adding the codec device for model=intel-hda, and adding
the audiodev to the codec device.

In the future, it could be extended to support default models or
builtin devices, just like -nic, or even a default backend.  For now,
keep it simple.

JSON parsing is not supported for -audio.  This is okay because the
option is targeted at end users, not programs.

Signed-off-by: Paolo Bonzini 
---
 audio/audio.c   |  8 +-
 audio/audio.h   |  1 +
 docs/about/deprecated.rst   |  9 --
 docs/about/removed-features.rst |  7 +
 hw/audio/intel-hda.c|  5 ++--
 hw/audio/soundhw.c  | 12 +---
 include/hw/audio/soundhw.h  |  4 +--
 qemu-options.hx | 51 -
 softmmu/vl.c| 28 --
 9 files changed, 76 insertions(+), 49 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 9e91a5a4f2..a02f3ce5c6 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2099,13 +2099,19 @@ static void audio_validate_opts(Audiodev *dev, Error 
**errp)
 
 void audio_parse_option(const char *opt)
 {
-AudiodevListEntry *e;
 Audiodev *dev = NULL;
 
 Visitor *v = qobject_input_visitor_new_str(opt, "driver", &error_fatal);
 visit_type_Audiodev(v, NULL, &dev, &error_fatal);
 visit_free(v);
 
+audio_define(dev);
+}
+
+void audio_define(Audiodev *dev)
+{
+AudiodevListEntry *e;
+
 audio_validate_opts(dev, &error_fatal);
 
 e = g_new0(AudiodevListEntry, 1);
diff --git a/audio/audio.h b/audio/audio.h
index 3d5ecdecd5..b5e17cd218 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -168,6 +168,7 @@ void audio_sample_to_uint64(const void *samples, int pos,
 void audio_sample_from_uint64(void *samples, int pos,
 uint64_t left, uint64_t right);
 
+void audio_define(Audiodev *audio);
 void audio_parse_option(const char *opt);
 void audio_init_audiodevs(void);
 void audio_legacy_help(void);
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 896e5a97ab..70885d09f3 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -39,15 +39,6 @@ should specify an ``audiodev=`` property.  Additionally, 
when using
 vnc, you should specify an ``audiodev=`` property if you plan to
 transmit audio through the VNC protocol.
 
-Creating sound card devices using ``-soundhw`` (since 5.1)
-''
-
-Sound card devices should be created using ``-device`` instead.  The
-names are the same for most devices.  The exceptions are ``hda`` which
-needs two devices (``-device intel-hda -device hda-duplex``) and
-``pcspk`` which can be activated using ``-machine
-pcspk-audiodev=``.
-
 ``-chardev`` backend aliases ``tty`` and ``parport`` (since 6.0)
 
 
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
index 3f324d0536..eabc6c63ac 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -632,6 +632,13 @@ tripped up the CI testing and was suspected to be quite 
broken. For that
 reason the maintainers strongly suspected no one actually used it.
 
 
+Creating sound card devices using ``-soundhw`` (removed in 7.1)
+''
+
+Sound card devices should be created using ``-device`` or ``-audio``.
+The exception is ``pcspk`` which can be activated using ``-machine
+pcspk-audiodev=``.
+
 TCG introspection features
 --
 
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index bc77e3d8c9..f38117057b 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -1311,17 +1311,16 @@ static const TypeInfo hda_codec_device_type_info = {
  * create intel hda controller with codec attached to it,
  * so '-soundhw hda' works.
  */
-static int intel_hda_and_codec_init(PCIBus *bus)
+static int intel_hda_and_codec_init(PCIBus *bus, const char *audiodev)
 {
 DeviceState *controller;
 BusState *hdabus;
 DeviceState *codec;
 
-warn_report("'-soundhw hda' is deprecated, "
-"please use '-device intel-hda -device hda-duplex' instead");
 controller = DEVICE(pci_create_simple(bus, -1, "intel-hda"));
 hdabus = QLIST_FIRST(&controller->child_bus);
 codec = qdev_new("hda-duplex");
+qdev_prop_set_string(codec, "audiodev", audiodev);
 qdev_realize_and_unref(codec, hdabus, &error_fatal);
 return 0;
 }
diff --git a/hw/audio/soundhw.c b/hw/audio/soundhw.c
index d81ae91136..e979be08ce 100644
--- a/hw/audio/soundhw.c
+++ b/hw/audio/soundhw.c
@@ -27,6 +27,7 @@
 #include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qom/object.h"
+#inclu

[RFC PATCH 2/6] soundhw: remove ability to create multiple soundcards

2022-04-27 Thread Paolo Bonzini
The usefulness of enabling a dozen soundcards is dubious.  Simplify the
code by allowing a single instance of -soundhw, with no support for
parsing either comma-separated values or 'soundhw all'.

Signed-off-by: Paolo Bonzini 
---
 hw/audio/soundhw.c | 88 +-
 1 file changed, 32 insertions(+), 56 deletions(-)

diff --git a/hw/audio/soundhw.c b/hw/audio/soundhw.c
index f7d94d7dfa..097501fee1 100644
--- a/hw/audio/soundhw.c
+++ b/hw/audio/soundhw.c
@@ -25,6 +25,7 @@
 #include "qemu/option.h"
 #include "qemu/help_option.h"
 #include "qemu/error-report.h"
+#include "qapi/error.h"
 #include "qom/object.h"
 #include "hw/isa/isa.h"
 #include "hw/pci/pci.h"
@@ -34,7 +35,6 @@ struct soundhw {
 const char *name;
 const char *descr;
 const char *typename;
-int enabled;
 int isa;
 int (*init_pci) (PCIBus *bus);
 };
@@ -64,10 +64,16 @@ void deprecated_register_soundhw(const char *name, const 
char *descr,
 soundhw_count++;
 }
 
+static struct soundhw *selected = NULL;
+
 void select_soundhw(const char *optarg)
 {
 struct soundhw *c;
 
+if (selected) {
+error_setg(&error_fatal, "only one -soundhw option is allowed");
+}
+
 if (is_help_option(optarg)) {
 show_valid_cards:
 
@@ -84,44 +90,15 @@ void select_soundhw(const char *optarg)
 exit(!is_help_option(optarg));
 }
 else {
-size_t l;
-const char *p;
-char *e;
-int bad_card = 0;
-
-if (!strcmp(optarg, "all")) {
-for (c = soundhw; c->name; ++c) {
-c->enabled = 1;
+for (c = soundhw; c->name; ++c) {
+if (g_str_equal(c->name, optarg)) {
+selected = c;
+break;
 }
-return;
 }
 
-p = optarg;
-while (*p) {
-e = strchr(p, ',');
-l = !e ? strlen(p) : (size_t) (e - p);
-
-for (c = soundhw; c->name; ++c) {
-if (!strncmp(c->name, p, l) && !c->name[l]) {
-c->enabled = 1;
-break;
-}
-}
-
-if (!c->name) {
-if (l > 80) {
-error_report("Unknown sound card name (too big to show)");
-}
-else {
-error_report("Unknown sound card name `%.*s'",
- (int) l, p);
-}
-bad_card = 1;
-}
-p += l + (e != NULL);
-}
-
-if (bad_card) {
+if (!c->name) {
+error_report("Unknown sound card name `%s'", optarg);
 goto show_valid_cards;
 }
 }
@@ -129,30 +106,29 @@ void select_soundhw(const char *optarg)
 
 void soundhw_init(void)
 {
-struct soundhw *c;
+struct soundhw *c = selected;
 ISABus *isa_bus = (ISABus *) object_resolve_path_type("", TYPE_ISA_BUS, 
NULL);
 PCIBus *pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, 
NULL);
 
-for (c = soundhw; c->name; ++c) {
-if (c->enabled) {
-if (c->typename) {
-warn_report("'-soundhw %s' is deprecated, "
-"please use '-device %s' instead",
-c->name, c->typename);
-if (c->isa) {
-isa_create_simple(isa_bus, c->typename);
-} else {
-pci_create_simple(pci_bus, -1, c->typename);
-}
-} else {
-assert(!c->isa);
-if (!pci_bus) {
-error_report("PCI bus not available for %s", c->name);
-exit(1);
-}
-c->init_pci(pci_bus);
-}
+if (!c) {
+return;
+}
+if (c->typename) {
+warn_report("'-soundhw %s' is deprecated, "
+"please use '-device %s' instead",
+c->name, c->typename);
+if (c->isa) {
+isa_create_simple(isa_bus, c->typename);
+} else {
+pci_create_simple(pci_bus, -1, c->typename);
 }
+} else {
+assert(!c->isa);
+if (!pci_bus) {
+error_report("PCI bus not available for %s", c->name);
+exit(1);
+}
+c->init_pci(pci_bus);
 }
 }
 
-- 
2.35.1





[RFC PATCH 3/6] soundhw: extract soundhw help to a separate function

2022-04-27 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 hw/audio/soundhw.c | 33 +++--
 include/hw/audio/soundhw.h |  1 +
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/hw/audio/soundhw.c b/hw/audio/soundhw.c
index 097501fee1..0fb64bdc8f 100644
--- a/hw/audio/soundhw.c
+++ b/hw/audio/soundhw.c
@@ -64,6 +64,21 @@ void deprecated_register_soundhw(const char *name, const 
char *descr,
 soundhw_count++;
 }
 
+void show_valid_soundhw(void)
+{
+struct soundhw *c;
+
+if (soundhw_count) {
+ printf("Valid sound card names (comma separated):\n");
+ for (c = soundhw; c->name; ++c) {
+ printf ("%-11s %s\n", c->name, c->descr);
+ }
+} else {
+ printf("Machine has no user-selectable audio hardware "
+"(it may or may not have always-present audio hardware).\n");
+}
+}
+
 static struct soundhw *selected = NULL;
 
 void select_soundhw(const char *optarg)
@@ -75,19 +90,8 @@ void select_soundhw(const char *optarg)
 }
 
 if (is_help_option(optarg)) {
-show_valid_cards:
-
-if (soundhw_count) {
- printf("Valid sound card names (comma separated):\n");
- for (c = soundhw; c->name; ++c) {
- printf ("%-11s %s\n", c->name, c->descr);
- }
- printf("\n-soundhw all will enable all of the above\n");
-} else {
- printf("Machine has no user-selectable audio hardware "
-"(it may or may not have always-present audio 
hardware).\n");
-}
-exit(!is_help_option(optarg));
+show_valid_soundhw();
+exit(0);
 }
 else {
 for (c = soundhw; c->name; ++c) {
@@ -99,7 +103,8 @@ void select_soundhw(const char *optarg)
 
 if (!c->name) {
 error_report("Unknown sound card name `%s'", optarg);
-goto show_valid_cards;
+show_valid_soundhw();
+exit(1);
 }
 }
 }
diff --git a/include/hw/audio/soundhw.h b/include/hw/audio/soundhw.h
index e68685fcda..dec5c0cdca 100644
--- a/include/hw/audio/soundhw.h
+++ b/include/hw/audio/soundhw.h
@@ -7,6 +7,7 @@ void deprecated_register_soundhw(const char *name, const char 
*descr,
  int isa, const char *typename);
 
 void soundhw_init(void);
+void show_valid_soundhw(void);
 void select_soundhw(const char *optarg);
 
 #endif
-- 
2.35.1





[PATCH 3/4] Revert "main-loop: Disable GLOBAL_STATE_CODE() assertions"

2022-04-27 Thread Hanna Reitz
This reverts commit b1c073490553f80594b903ceedfc7c1aef6b1b19.  (We
wanted to do so once the 7.1 tree opens, which has happened.  The issue
reported in https://gitlab.com/qemu-project/qemu/-/issues/945 should be
fixed by the preceding patches.)

Signed-off-by: Hanna Reitz 
---
 include/qemu/main-loop.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index d3750c8e76..89bd9edefb 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -284,8 +284,7 @@ bool qemu_in_main_thread(void);
 #else
 #define GLOBAL_STATE_CODE() \
 do {\
-/* FIXME: Re-enable after 7.0 release */\
-/* assert(qemu_in_main_thread()); */\
+assert(qemu_in_main_thread());  \
 } while (0)
 #endif /* CONFIG_COCOA */
 
-- 
2.35.1




[PATCH 0/4] Revert "main-loop: Disable GLOBAL_STATE_CODE() assertions"

2022-04-27 Thread Hanna Reitz
Hi,

This assertion was disabled in commit
b1c073490553f80594b903ceedfc7c1aef6b1b19.  We wanted to re-enable it
once the 7.1 tree has opened (which is now), but to do so, we should
also fix the bug reported in
https://gitlab.com/qemu-project/qemu/-/issues/945 .

Patches 1 and 2 fix that problem (I hope), patch 3 re-enables the
assertion, and patch 4 adds a regression test for issue 945.


Hanna Reitz (4):
  block: Classify bdrv_get_flags() as I/O function
  qcow2: Do not reopen data_file in invalidate_cache
  Revert "main-loop: Disable GLOBAL_STATE_CODE() assertions"
  iotests: Add regression test for issue 945

 include/block/block-global-state.h|   1 -
 include/block/block-io.h  |   1 +
 include/qemu/main-loop.h  |   3 +-
 block.c   |   2 +-
 block/qcow2.c | 104 +++---
 .../tests/export-incoming-iothread|  81 ++
 .../tests/export-incoming-iothread.out|   5 +
 7 files changed, 151 insertions(+), 46 deletions(-)
 create mode 100755 tests/qemu-iotests/tests/export-incoming-iothread
 create mode 100644 tests/qemu-iotests/tests/export-incoming-iothread.out

-- 
2.35.1




[PATCH 2/4] qcow2: Do not reopen data_file in invalidate_cache

2022-04-27 Thread Hanna Reitz
qcow2_co_invalidate_cache() closes and opens the qcow2 file, by calling
qcow2_close() and qcow2_do_open().  These two functions must thus be
usable from both a global-state and an I/O context.

As they are, they are not safe to call in an I/O context, because they
use bdrv_unref_child() and bdrv_open_child() to close/open the data_file
child, respectively, both of which are global-state functions.  When
used from qcow2_co_invalidate_cache(), we do not need to close/open the
data_file child, though (we do not do this for bs->file or bs->backing
either), and so we should skip it in the qcow2_co_invalidate_cache()
path.

To do so, add a parameter to qcow2_do_open() and qcow2_close() to make
them skip handling s->data_file, and have qcow2_co_invalidate_cache()
exempt it from the memset() on the BDRVQcow2State.

(Note that the QED driver similarly closes/opens the QED image by
invoking bdrv_qed_close()+bdrv_qed_do_open(), but both functions seem
safe to use in an I/O context.)

Fixes: https://gitlab.com/qemu-project/qemu/-/issues/945
Signed-off-by: Hanna Reitz 
---
 block/qcow2.c | 104 ++
 1 file changed, 62 insertions(+), 42 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index b5c47931ef..4f5e6440fb 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1296,7 +1296,8 @@ static int validate_compression_type(BDRVQcow2State *s, 
Error **errp)
 
 /* Called with s->lock held.  */
 static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
-  int flags, Error **errp)
+  int flags, bool open_data_file,
+  Error **errp)
 {
 ERRP_GUARD();
 BDRVQcow2State *s = bs->opaque;
@@ -1614,50 +1615,52 @@ static int coroutine_fn qcow2_do_open(BlockDriverState 
*bs, QDict *options,
 goto fail;
 }
 
-/* Open external data file */
-s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
-   &child_of_bds, BDRV_CHILD_DATA,
-   true, errp);
-if (*errp) {
-ret = -EINVAL;
-goto fail;
-}
+if (open_data_file) {
+/* Open external data file */
+s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
+   &child_of_bds, BDRV_CHILD_DATA,
+   true, errp);
+if (*errp) {
+ret = -EINVAL;
+goto fail;
+}
 
-if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
-if (!s->data_file && s->image_data_file) {
-s->data_file = bdrv_open_child(s->image_data_file, options,
-   "data-file", bs, &child_of_bds,
-   BDRV_CHILD_DATA, false, errp);
+if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
+if (!s->data_file && s->image_data_file) {
+s->data_file = bdrv_open_child(s->image_data_file, options,
+   "data-file", bs, &child_of_bds,
+   BDRV_CHILD_DATA, false, errp);
+if (!s->data_file) {
+ret = -EINVAL;
+goto fail;
+}
+}
 if (!s->data_file) {
+error_setg(errp, "'data-file' is required for this image");
 ret = -EINVAL;
 goto fail;
 }
-}
-if (!s->data_file) {
-error_setg(errp, "'data-file' is required for this image");
-ret = -EINVAL;
-goto fail;
-}
 
-/* No data here */
-bs->file->role &= ~BDRV_CHILD_DATA;
+/* No data here */
+bs->file->role &= ~BDRV_CHILD_DATA;
 
-/* Must succeed because we have given up permissions if anything */
-bdrv_child_refresh_perms(bs, bs->file, &error_abort);
-} else {
-if (s->data_file) {
-error_setg(errp, "'data-file' can only be set for images with an "
- "external data file");
-ret = -EINVAL;
-goto fail;
-}
+/* Must succeed because we have given up permissions if anything */
+bdrv_child_refresh_perms(bs, bs->file, &error_abort);
+} else {
+if (s->data_file) {
+error_setg(errp, "'data-file' can only be set for images with "
+ "an external data file");
+ret = -EINVAL;
+goto fail;
+}
 
-s->data_file = bs->file;
+s->data_file = bs->file;
 
-if (data_file_is_raw(bs)) {
-error_setg(errp, "data-file-raw requires a data file");
-ret = -EINVAL;
-goto fail;
+if (data_file_is_raw(bs)) {
+error_setg

[RFC PATCH 5/6] soundhw: move help handling to vl.c

2022-04-27 Thread Paolo Bonzini
This will allow processing "-audio model=help" even if the backend
part of the option is missing.

Signed-off-by: Paolo Bonzini 
---
 hw/audio/soundhw.c | 24 +---
 softmmu/vl.c   |  4 
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/hw/audio/soundhw.c b/hw/audio/soundhw.c
index a9d8807b18..d81ae91136 100644
--- a/hw/audio/soundhw.c
+++ b/hw/audio/soundhw.c
@@ -89,23 +89,17 @@ void select_soundhw(const char *optarg)
 error_setg(&error_fatal, "only one -soundhw option is allowed");
 }
 
-if (is_help_option(optarg)) {
-show_valid_soundhw();
-exit(0);
+for (c = soundhw; c->name; ++c) {
+if (g_str_equal(c->name, optarg)) {
+selected = c;
+break;
+}
 }
-else {
-for (c = soundhw; c->name; ++c) {
-if (g_str_equal(c->name, optarg)) {
-selected = c;
-break;
-}
-}
 
-if (!c->name) {
-error_report("Unknown sound card name `%s'", optarg);
-show_valid_soundhw();
-exit(1);
-}
+if (!c->name) {
+error_report("Unknown sound card name `%s'", optarg);
+show_valid_soundhw();
+exit(1);
 }
 }
 
diff --git a/softmmu/vl.c b/softmmu/vl.c
index c2919579fd..5bea0eb3eb 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -3019,6 +3019,10 @@ void qemu_init(int argc, char **argv, char **envp)
 audio_parse_option(optarg);
 break;
 case QEMU_OPTION_soundhw:
+if (is_help_option(optarg)) {
+show_valid_soundhw();
+exit(0);
+}
 select_soundhw (optarg);
 break;
 case QEMU_OPTION_h:
-- 
2.35.1





[PATCH 1/4] block: Classify bdrv_get_flags() as I/O function

2022-04-27 Thread Hanna Reitz
This function is safe to call in an I/O context, and qcow2_do_open()
does so (invoked in an I/O context by qcow2_co_invalidate_cache()).

Signed-off-by: Hanna Reitz 
---
 include/block/block-global-state.h | 1 -
 include/block/block-io.h   | 1 +
 block.c| 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/block/block-global-state.h 
b/include/block/block-global-state.h
index 25bb69bbef..21265e3966 100644
--- a/include/block/block-global-state.h
+++ b/include/block/block-global-state.h
@@ -172,7 +172,6 @@ void bdrv_next_cleanup(BdrvNextIterator *it);
 BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
 void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
  void *opaque, bool read_only);
-int bdrv_get_flags(BlockDriverState *bs);
 char *bdrv_get_full_backing_filename(BlockDriverState *bs, Error **errp);
 char *bdrv_dirname(BlockDriverState *bs, Error **errp);
 
diff --git a/include/block/block-io.h b/include/block/block-io.h
index 5e3f346806..62c84f0519 100644
--- a/include/block/block-io.h
+++ b/include/block/block-io.h
@@ -103,6 +103,7 @@ int bdrv_apply_auto_read_only(BlockDriverState *bs, const 
char *errmsg,
 bool bdrv_is_read_only(BlockDriverState *bs);
 bool bdrv_is_writable(BlockDriverState *bs);
 bool bdrv_is_sg(BlockDriverState *bs);
+int bdrv_get_flags(BlockDriverState *bs);
 bool bdrv_is_inserted(BlockDriverState *bs);
 void bdrv_lock_medium(BlockDriverState *bs, bool locked);
 void bdrv_eject(BlockDriverState *bs, bool eject_flag);
diff --git a/block.c b/block.c
index 8cd16e757e..2c0080 100644
--- a/block.c
+++ b/block.c
@@ -6298,7 +6298,7 @@ const char *bdrv_get_device_or_node_name(const 
BlockDriverState *bs)
 
 int bdrv_get_flags(BlockDriverState *bs)
 {
-GLOBAL_STATE_CODE();
+IO_CODE();
 return bs->open_flags;
 }
 
-- 
2.35.1




[PATCH 4/4] iotests: Add regression test for issue 945

2022-04-27 Thread Hanna Reitz
Create a VM with a BDS in an iothread, add -incoming defer to the
command line, and then export this BDS via NBD.  Doing so should not
fail an assertion.

Signed-off-by: Hanna Reitz 
---
 .../tests/export-incoming-iothread| 81 +++
 .../tests/export-incoming-iothread.out|  5 ++
 2 files changed, 86 insertions(+)
 create mode 100755 tests/qemu-iotests/tests/export-incoming-iothread
 create mode 100644 tests/qemu-iotests/tests/export-incoming-iothread.out

diff --git a/tests/qemu-iotests/tests/export-incoming-iothread 
b/tests/qemu-iotests/tests/export-incoming-iothread
new file mode 100755
index 00..7679e49103
--- /dev/null
+++ b/tests/qemu-iotests/tests/export-incoming-iothread
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+# group: rw quick migration
+#
+# Regression test for issue 945:
+# https://gitlab.com/qemu-project/qemu/-/issues/945
+# Test adding an export on top of an iothread-ed block device while in
+# -incoming defer.
+#
+# Copyright (C) 2022 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+import os
+import iotests
+from iotests import qemu_img_create
+
+
+image_size = 1 * 1024 * 1024
+test_img = os.path.join(iotests.test_dir, 'test.img')
+node_name = 'node0'
+iothread_id = 'iothr0'
+
+nbd_sock = os.path.join(iotests.sock_dir, 'nbd.sock')
+
+
+class TestExportIncomingIothread(iotests.QMPTestCase):
+def setUp(self) -> None:
+qemu_img_create('-f', iotests.imgfmt, test_img, str(image_size))
+
+self.vm = iotests.VM()
+self.vm.add_object(f'iothread,id={iothread_id}')
+self.vm.add_blockdev((
+f'driver={iotests.imgfmt}',
+f'node-name={node_name}',
+'file.driver=file',
+f'file.filename={test_img}'
+))
+self.vm.add_incoming('defer')
+self.vm.launch()
+
+def tearDown(self):
+self.vm.shutdown()
+os.remove(test_img)
+
+def test_export_add(self):
+result = self.vm.qmp('nbd-server-start', {
+'addr': {
+'type': 'unix',
+'data': {
+'path': nbd_sock
+}
+}
+})
+self.assert_qmp(result, 'return', {})
+
+# Regression test for issue 945: This should not fail an assertion
+result = self.vm.qmp('block-export-add', {
+'type': 'nbd',
+'id': 'exp0',
+'node-name': node_name,
+'iothread': iothread_id
+})
+self.assert_qmp(result, 'return', {})
+
+
+if __name__ == '__main__':
+iotests.main(supported_fmts=['generic'],
+ unsupported_fmts=['luks'], # Would need a secret
+ supported_protocols=['file'])
diff --git a/tests/qemu-iotests/tests/export-incoming-iothread.out 
b/tests/qemu-iotests/tests/export-incoming-iothread.out
new file mode 100644
index 00..ae1213e6f8
--- /dev/null
+++ b/tests/qemu-iotests/tests/export-incoming-iothread.out
@@ -0,0 +1,5 @@
+.
+--
+Ran 1 tests
+
+OK
-- 
2.35.1




Re: [PATCH qemu v9 05/14] target/riscv: rvv: Add tail agnostic for vector load / store instructions

2022-04-27 Thread Weiwei Li



在 2022/3/7 下午3:10, ~eopxd 写道:

From: eopXD 

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

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

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index cc80bf00ff..99691f1b9f 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);
  }
  
@@ -748,6 +749,7 @@ static bool st_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, true);
  }
  
@@ -774,6 +776,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);
  }
  
@@ -791,6 +795,8 @@ static bool st_us_mask_op(DisasContext *s, arg_vsm_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, true);
  }
  
@@ -862,6 +868,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);
  }
  
@@ -891,6 +898,7 @@ static bool st_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);
  fn = fns[eew];
  if (fn == NULL) {
  return false;
@@ -991,6 +999,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);
  }
  
@@ -1043,6 +1052,7 @@ static bool st_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, true);
  }
  
@@ -1108,6 +1118,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/vector_helper.c b/target/riscv/vector_helper.c

index 396e252179..1541d97b08 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -270,6 +270,8 @@ 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 vta = vext_vta(desc);
  
  for (i = env->vstart; i < env->vl; i++, env->vstart++) {

  if (!vm && !vext_elem_mask(v0, i)) {
@@ -284,6 +286,11 @@ 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, env->vl * esz + k * max_elems,
+  max_elems * esz + k * max_elems);
+}
  }


It seems incorrect here. I think it should be  k * max_elems * esz. The 
same to following similar case.


Otherwise, this patchset looks good to me.

Reviewed-by: 

Re: [PATCH 7/8] qmp: add filtering of statistics by name

2022-04-27 Thread Dr. David Alan Gilbert
* Paolo Bonzini (pbonz...@redhat.com) wrote:
> Allow retrieving only a subset of statistics.  This can be useful
> for example in order to plot a subset of the statistics many times
> a second.
> 
> KVM publishes ~40 statistics for each vCPU on x86; retrieving and
> serializing all of them would be useless
> 
> Another use will be in HMP in the following patch; implementing the
> filter in the backend is easy enough that it was deemed okay to make
> this a public interface.
> 
> Example:
> 
> { "execute": "query-stats",
>   "arguments": {
> "target": "vcpu",
> "vcpus": [ "/machine/unattached/device[2]",
>"/machine/unattached/device[4]" ],
> "providers": [
>   { "provider": "kvm",
> "names": [ "l1d_flush", "exits" ] } } }

That looks inconsistent to me; I realise that 'names' has to be a child
of providers (since the names are only relevant to a given provider) but
how about making the "target" work similarly:

  
{ "execute": "query-stats",
  "arguments": {
"target": {
  "vcpus": [ "/machine/unattached/device[2]",
 "/machine/unattached/device[4]" ] },
   
"providers": [
   { "provider": "kvm",
 "names": [ "l1d_flush", "exits" ] } } }

It's not clear to me whether the "target" should also be specific
to a given provider.

Dave

> { "return": {
> "vcpus": [
>   { "path": "/machine/unattached/device[2]"
> "providers": [
>   { "provider": "kvm",
> "stats": [ { "name": "l1d_flush", "value": 41213 },
>{ "name": "exits", "value": 74291 } ] } ] },
>   { "path": "/machine/unattached/device[4]"
> "providers": [
>   { "provider": "kvm",
> "stats": [ { "name": "l1d_flush", "value": 16132 },
>{ "name": "exits", "value": 57922 } ] } ] } ] } }
> 
> Extracted from a patch by Mark Kanda.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  accel/kvm/kvm-all.c | 18 +++---
>  include/monitor/stats.h |  4 ++--
>  monitor/qmp-cmds.c  | 10 +++---
>  qapi/stats.json |  4 +++-
>  4 files changed, 23 insertions(+), 13 deletions(-)
> 
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index b42008ac07..67253c5a5c 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -2311,7 +2311,7 @@ bool kvm_dirty_ring_enabled(void)
>  return kvm_state->kvm_dirty_ring_size ? true : false;
>  }
>  
> -static void query_stats_cb(StatsResultList **result, StatsTarget target,
> +static void query_stats_cb(StatsResultList **result, StatsTarget target, 
> strList *names,
> strList *targets, Error **errp);
>  static void query_stats_schemas_cb(StatsSchemaList **result, Error **errp);
>  
> @@ -3713,6 +3713,7 @@ typedef struct StatsArgs {
>  StatsResultList **stats;
>  StatsSchemaList **schema;
>  } result;
> +strList *names;
>  Error **errp;
>  } StatsArgs;
>  
> @@ -3926,7 +3927,7 @@ static StatsDescriptors 
> *find_stats_descriptors(StatsTarget target, int stats_fd
>  return descriptors;
>  }
>  
> -static void query_stats(StatsResultList **result, StatsTarget target,
> +static void query_stats(StatsResultList **result, StatsTarget target, 
> strList *names,
>  int stats_fd, Error **errp)
>  {
>  struct kvm_stats_desc *kvm_stats_desc;
> @@ -3969,6 +3970,9 @@ static void query_stats(StatsResultList **result, 
> StatsTarget target,
>  
>  /* Add entry to the list */
>  stats = (void *)stats_data + pdesc->offset;
> +if (!str_in_list(pdesc->name, names)) {
> +continue;
> +}
>  stats_list = add_kvmstat_entry(pdesc, stats, stats_list, errp);
>  }
>  
> @@ -4030,8 +4034,8 @@ static void query_stats_vcpu(CPUState *cpu, 
> run_on_cpu_data data)
>  error_propagate(kvm_stats_args->errp, local_err);
>  return;
>  }
> -query_stats(kvm_stats_args->result.stats, STATS_TARGET_VCPU, stats_fd,
> -kvm_stats_args->errp);
> +query_stats(kvm_stats_args->result.stats, STATS_TARGET_VCPU,
> +kvm_stats_args->names, stats_fd, kvm_stats_args->errp);
>  close(stats_fd);
>  }
>  
> @@ -4052,7 +4056,7 @@ static void query_stats_schema_vcpu(CPUState *cpu, 
> run_on_cpu_data data)
>  }
>  
>  static void query_stats_cb(StatsResultList **result, StatsTarget target,
> -   strList *targets, Error **errp)
> +   strList *names, strList *targets, Error **errp)
>  {
>  KVMState *s = kvm_state;
>  CPUState *cpu;
> @@ -4066,14 +4070,15 @@ static void query_stats_cb(StatsResultList **result, 
> StatsTarget target,
>  error_setg(errp, "KVM stats: ioctl failed");
>  return;
>  }
> -query_stats(result, target, stats_fd, errp);
> +query_stats(result, target, names, stats_fd, errp);
>  close(stats_fd);
>  break;
>  }
>  case STA

Re: [PATCH 1/8] qmp: Support for querying stats

2022-04-27 Thread Paolo Bonzini

On 4/27/22 11:19, Dr. David Alan Gilbert wrote:

{ "return": [
  { "provider": "kvm",
"stats": [
   { "name": "max_mmu_page_hash_collisions", "value": 0 },
   { "name": "max_mmu_rmap_size", "value": 0 },
   { "name": "nx_lpage_splits", "value": 148 },


Is there any hierarchy to the naming or is it just a big flat name
space?


Within KVM no, but there is a hierarchy of provider->stat.


 { "provider": "kvm",
   "target": "vm",
   "stats": [
 { "name": "max_mmu_page_hash_collisions",
"unit": "none",
"base": 10,
"exponent": 0,
"type": "peak" },
 ... ]
 },


Is there some way to reset the peak or cumulative values?


Not yet, but the plan is to allow pwrite for peak and cumulative 
statistics, and possibly for histograms as well.  Alternatively it could 
be a ioctl.  Indecision about write support is also the reason why mmap 
is not allowed yet.


Paolo


Dave


 { "provider": "xyz",
   "target": "vm",
   "stats": [ ... ]
 }
] }

Signed-off-by: Mark Kanda 
Signed-off-by: Paolo Bonzini 
---
  include/monitor/stats.h |  33 +++
  monitor/qmp-cmds.c  |  71 +++
  qapi/meson.build|   1 +
  qapi/qapi-schema.json   |   1 +
  qapi/stats.json | 192 
  5 files changed, 298 insertions(+)
  create mode 100644 include/monitor/stats.h
  create mode 100644 qapi/stats.json

diff --git a/include/monitor/stats.h b/include/monitor/stats.h
new file mode 100644
index 00..89552ab06f
--- /dev/null
+++ b/include/monitor/stats.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef STATS_H
+#define STATS_H
+
+#include "qapi/qapi-types-stats.h"
+
+typedef void StatRetrieveFunc(StatsResultList **result, StatsTarget target, 
Error **errp);
+typedef void SchemaRetrieveFunc(StatsSchemaList **result, Error **errp);
+
+/*
+ * Register callbacks for the QMP query-stats command.
+ *
+ * @stats_fn: routine to query stats:
+ * @schema_fn: routine to query stat schemas:
+ */
+void add_stats_callbacks(StatRetrieveFunc *stats_fn,
+ SchemaRetrieveFunc *schemas_fn);
+
+/*
+ * Helper routines for adding stats entries to the results lists.
+ */
+void add_stats_entry(StatsResultList **, StatsProvider, const char *id,
+ StatsList *stats_list);
+void add_stats_schema(StatsSchemaList **, StatsProvider, StatsTarget,
+  StatsSchemaValueList *);
+
+#endif /* STATS_H */
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 5e7302cbb9..97825b25fa 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -35,6 +35,7 @@
  #include "qapi/qapi-commands-control.h"
  #include "qapi/qapi-commands-machine.h"
  #include "qapi/qapi-commands-misc.h"
+#include "qapi/qapi-commands-stats.h"
  #include "qapi/qapi-commands-ui.h"
  #include "qapi/type-helpers.h"
  #include "qapi/qmp/qerror.h"
@@ -43,6 +44,7 @@
  #include "hw/acpi/acpi_dev_interface.h"
  #include "hw/intc/intc.h"
  #include "hw/rdma/rdma.h"
+#include "monitor/stats.h"
  
  NameInfo *qmp_query_name(Error **errp)

  {
@@ -426,3 +428,72 @@ HumanReadableText *qmp_x_query_irq(Error **errp)
  
  return human_readable_text_from_str(buf);

  }
+
+typedef struct StatsCallbacks {
+StatRetrieveFunc *stats_cb;
+SchemaRetrieveFunc *schemas_cb;
+QTAILQ_ENTRY(StatsCallbacks) next;
+} StatsCallbacks;
+
+static QTAILQ_HEAD(, StatsCallbacks) stats_callbacks =
+QTAILQ_HEAD_INITIALIZER(stats_callbacks);
+
+void add_stats_callbacks(StatRetrieveFunc *stats_fn,
+ SchemaRetrieveFunc *schemas_fn)
+{
+StatsCallbacks *entry = g_new(StatsCallbacks, 1);
+entry->stats_cb = stats_fn;
+entry->schemas_cb = schemas_fn;
+
+QTAILQ_INSERT_TAIL(&stats_callbacks, entry, next);
+}
+
+StatsResultList *qmp_query_stats(StatsFilter *filter, Error **errp)
+{
+StatsResultList *stats_results = NULL;
+StatsCallbacks *entry;
+
+QTAILQ_FOREACH(entry, &stats_callbacks, next) {
+entry->stats_cb(&stats_results, filter->target, errp);
+}
+
+return stats_results;
+}
+
+StatsSchemaList *qmp_query_stats_schemas(Error **errp)
+{
+StatsSchemaList *stats_results = NULL;
+StatsCallbacks *entry;
+
+QTAILQ_FOREACH(entry, &stats_callbacks, next) {
+entry->schemas_cb(&stats_results, errp);
+}
+
+return stats_results;
+}
+
+void add_stats_entry(StatsResultList **stats_results, StatsProvider provider,
+ const char *qom_path, StatsList *stats_list)
+{
+StatsResult *entry = g_new0(StatsResult, 1);
+entry->provider = provider;
+if (qom_path) {
+entry->has_qom_path = true;
+entry->qom_path = g_strdup(qom_path);
+}
+entry->stats = stats_list;
+
+QAPI_LIST_PREPEND(*sta

Re: [PATCH 7/8] qmp: add filtering of statistics by name

2022-04-27 Thread Paolo Bonzini

On 4/27/22 14:01, Dr. David Alan Gilbert wrote:

 "providers": [
   { "provider": "kvm",
 "names": [ "l1d_flush", "exits" ] } } }

That looks inconsistent to me; I realise that 'names' has to be a child
of providers (since the names are only relevant to a given provider) but
how about making the "target" work similarly:

{ "execute": "query-stats",
   "arguments": {
 "target": {
   "vcpus": [ "/machine/unattached/device[2]",
  "/machine/unattached/device[4]" ] },


This would allow queries for different types of targets in a single 
command, but it would be harder for the client to do filtering:


* with something like "target": { "vcpus": [ array ] }, there is no way 
for the client to say "I want this one statistic, but for all the vCPUs"


* if target is optional, a client might expect relatively small output 
from today's QEMU, yet suddenly get hundreds of KB from targets other 
than VMs and vCPUs (e.g. block devices including all backing files in 
the chain, NIC backends, etc.).



 "providers": [
{ "provider": "kvm",
  "names": [ "l1d_flush", "exits" ] } } }

It's not clear to me whether the "target" should also be specific
to a given provider.


No, the target is a QEMU concept, such as a CPU or a device backend.  It 
is identified by either a QOM path or a unique id.


Paolo



Re: [PATCH v5 1/1] virtio: fix the condition for iommu_platform not supported

2022-04-27 Thread Chenyi Qiang




On 4/22/2022 3:11 PM, Chenyi Qiang wrote:



On 2/7/2022 7:28 PM, Halil Pasic wrote:

The commit 04ceb61a40 ("virtio: Fail if iommu_platform is requested, but
unsupported") claims to fail the device hotplug when iommu_platform
is requested, but not supported by the (vhost) device. On the first
glance the condition for detecting that situation looks perfect, but
because a certain peculiarity of virtio_platform it ain't.

In fact the aforementioned commit introduces a regression. It breaks
virtio-fs support for Secure Execution, and most likely also for AMD SEV
or any other confidential guest scenario that relies encrypted guest
memory.  The same also applies to any other vhost device that does not
support _F_ACCESS_PLATFORM.

The peculiarity is that iommu_platform and _F_ACCESS_PLATFORM collates
"device can not access all of the guest RAM" and "iova != gpa, thus
device needs to translate iova".

Confidential guest technologies currently rely on the device/hypervisor
offering _F_ACCESS_PLATFORM, so that, after the feature has been
negotiated, the guest  grants access to the portions of memory the
device needs to see. So in for confidential guests, generally,
_F_ACCESS_PLATFORM is about the restricted access to memory, but not
about the addresses used being something else than guest physical
addresses.

This is the very reason for which commit f7ef7e6e3b ("vhost: correctly
turn on VIRTIO_F_IOMMU_PLATFORM") fences _F_ACCESS_PLATFORM from the
vhost device that does not need it, because on the vhost interface it
only means "I/O address translation is needed".

This patch takes inspiration from f7ef7e6e3b ("vhost: correctly turn on
VIRTIO_F_IOMMU_PLATFORM"), and uses the same condition for detecting the
situation when _F_ACCESS_PLATFORM is requested, but no I/O translation
by the device, and thus no device capability is needed. In this
situation claiming that the device does not support iommu_plattform=on
is counter-productive. So let us stop doing that!

Signed-off-by: Halil Pasic 
Reported-by: Jakob Naucke 
Fixes: 04ceb61a40 ("virtio: Fail if iommu_platform is requested, but
unsupported")
Acked-by: Cornelia Huck 
Reviewed-by: Daniel Henrique Barboza 
Tested-by: Daniel Henrique Barboza 
Cc: Kevin Wolf 
Cc: qemu-sta...@nongnu.org

---

v4->v5:
* added back the return; so if somebody were to add code to the end of
   the function we are still good
v3->v4:
* Fixed commit message (thanks Connie)
* Removed counter-productive initialization (thanks Connie)
* Added tags
v2->v3:
* Caught a bug: I tired to check if vdev has the feature
    ACCESS_PLATFORM after we have forced it. Moved the check
    to a better place
v1->v2:
* Commit message tweaks. Most notably fixed commit SHA (Michael)

---
---
  hw/virtio/virtio-bus.c | 12 +++-
  1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index d23db98c56..0f69d1c742 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -48,6 +48,7 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, 
Error **errp)

  VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
  VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
  bool has_iommu = virtio_host_has_feature(vdev, 
VIRTIO_F_IOMMU_PLATFORM);

+    bool vdev_has_iommu;
  Error *local_err = NULL;
  DPRINTF("%s: plug device.\n", qbus->name);
@@ -69,11 +70,6 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, 
Error **errp)

  return;
  }
-    if (has_iommu && !virtio_host_has_feature(vdev, 
VIRTIO_F_IOMMU_PLATFORM)) {
-    error_setg(errp, "iommu_platform=true is not supported by the 
device");

-    return;
-    }
-
  if (klass->device_plugged != NULL) {
  klass->device_plugged(qbus->parent, &local_err);
  }
@@ -82,9 +78,15 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, 
Error **errp)

  return;
  }
+    vdev_has_iommu = virtio_host_has_feature(vdev, 
VIRTIO_F_IOMMU_PLATFORM);

  if (klass->get_dma_as != NULL && has_iommu) {
  virtio_add_feature(&vdev->host_features, 
VIRTIO_F_IOMMU_PLATFORM);

  vdev->dma_as = klass->get_dma_as(qbus->parent);
+    if (!vdev_has_iommu && vdev->dma_as != &address_space_memory) {


Hi Pasic,

When testing the virtio-fs in Intel TDX, I met the error report in this 
check. Is it appropriate to compare the dma_as against the 
address_space_memory to detect whether the IOMMU is enabled or not? Per 
the commit ae4003738f(vhost: correctly detect the enabling IOMMU), we 
should call virtio_bus_device_iommu_enabled(vdev) instead here, correct?




Sorry for bothering.

Can virtio-fs work properly in AMD SEV?

IIUC, If get_dma_as() is implemented and in case of PCI, 
pci_get_address_space() is used and returns the bus master as. This 
would fail the check here.



+    error_setg(errp,
+   "iommu_platform=true is not supported by the 
device");

+    return;
+    }
  } else {
  v

Re: [PATCH v2 2/5] 9pfs: fix qemu_mknodat(S_IFSOCK) on macOS

2022-04-27 Thread Christian Schoenebeck
On Mittwoch, 27. April 2022 12:18:10 CEST Greg Kurz wrote:
> On Wed, 27 Apr 2022 11:27:28 +0900
> 
> Akihiko Odaki  wrote:
> > On 2022/04/26 21:38, Greg Kurz wrote:
> [..skip..]
> 
> > > I think Christian's explanation is clear enough. We don't guarantee
> > > that v9fs_co_foo() calls run atomically. As a consequence, the client
> > > might see transient states or be able to interact with an ongoing
> > > request. And to answer your question, we have no specific rationale
> > > on security with that.
> > > 
> > > I'm not sure what the concerns are but unless you come up with a
> > > valid scenario [*] I don't see any reason to prevent this patch
> > > to go forward.
> > > 
> > > [*] things like:
> > >  - client escaping the shared directory
> > >  - QEMU crashing
> > >  - QEMU hogging host resources
> > >  - client-side unprivileged user gaining elevated privleges
> > >  
> > >in the guest
> > 
> > I was just not sure if such transient states are safe. The past
> > discussion was about the length of the non-atomic time window where a
> > path name is used to identify a particular file, but if such states are
> > not considered problematic, the length does not matter all and we can
> > confidently say the sequence of bind() and chmod() is safe.
> > 
> > Considering the transient states are tolerated in 9pfs, we need to
> > design this function to be tolerant with transient states as well. The
> > use of chmod() is not safe when we consider about transient states. A
> > malicious actor may replace the file at the path with a symlink which
> > may escape the shared directory and chmod() will naively follow it.
> 
> You get a point here. Thanks for your tenacity ! :-)

Yep, I send a v4 with fchmodat_nofollow() instead of chmod(), thanks!

BTW, why is it actually allowed for client to create a symlink pointing 
outside exported directory tree with security_model=passthrough/none? Did 
anybody want that?

> > chmod() should be replaced with fchmodat_nofollow() or something similar.
> 
> On a GNU/Linux system, this could be achieved by calling fchmod() on
> the socket fd *before* calling bind() but I'm afraid this hack might
> not work with a BSDish OS.

As you already imagined, this is unfortunately not supported by any BSDs, 
including macOS. I'll file a bug report with Apple though.

> Replacing chmod() with fchmodat_nofollow(dirfd, addr.sun_path, mode)
> won't make things atomic as above but at least it won't follow a
> malicious symbolic link : mknod() on the client will fail with
> ELOOP, which is fine when it comes to not breaking out of the shared
> directory.

Current security_model=passthrough/none already has similar non-atomic 
operations BTW, so this was not something new. E.g.:

static int local_symlink(FsContext *fs_ctx, const char *oldpath,
 V9fsPath *dir_path, const char *name, FsCred *credp)
{
...
} else if (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH ||
   fs_ctx->export_flags & V9FS_SM_NONE) {
err = symlinkat(oldpath, dirfd, name);
if (err) {
goto out;
}
err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
   AT_SYMLINK_NOFOLLOW);
...
}

In general, if you care about a higher degree of security, I'd always 
recommend to use security_model=mapped in the first place.

> This brings up a new problem I hadn't realized before : the
> fchmodat_nofollow() implementation in 9p-local.c is really
> a linux only thing to cope with AT_SYMLINK_NOFOLLOW not being
> supported with fchmodat(). It looks that this should move to
> 9p-util-linux.c and a proper version should be added for macOS
> in 9p-util-darwin.c

Like already agreed on the other thread, yes, that makes sense. But I think 
this can be handled with a follow-up, separate from this series.

Best regards,
Christian Schoenebeck





[PATCH] softmmu/vl: Fence 'xenfb' if Xen support is not compiled in

2022-04-27 Thread Thomas Huth
The 'xenfb' parameter for the '-vga' command line option is currently
always enabled unconditionally (since the xenfb is not a proper QOM
device that could be tested via its class name). That means it also
shows up if Xen is not enabled at all, e.g. like this:

 $ ./qemu-system-sparc -vga help
 none no graphic card
 xenfbXen paravirtualized framebuffer
 tcx  TCX framebuffer (default)
 cg3  CG3 framebuffer

Let's avoid this situation by fencing the parameter with the
CONFIG_XEN_BACKEND switch.

Signed-off-by: Thomas Huth 
---
 softmmu/vl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/softmmu/vl.c b/softmmu/vl.c
index 06a0e342fe..e26421b815 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -934,10 +934,12 @@ static const VGAInterfaceInfo 
vga_interfaces[VGA_TYPE_MAX] = {
 .name = "CG3 framebuffer",
 .class_names = { "cgthree" },
 },
+#ifdef CONFIG_XEN_BACKEND
 [VGA_XENFB] = {
 .opt_name = "xenfb",
 .name = "Xen paravirtualized framebuffer",
 },
+#endif
 };
 
 static bool vga_interface_available(VGAInterfaceType t)
-- 
2.27.0




Re: [PATCH v2 1/5] hw/intc: Move mtimer/mtimecmp to aclint

2022-04-27 Thread Dr. David Alan Gilbert
* Atish Kumar Patra (ati...@rivosinc.com) wrote:
> On Tue, Apr 26, 2022 at 5:50 PM Richard Henderson
>  wrote:
> >
> > On 4/26/22 16:08, Atish Patra wrote:
> > > @@ -334,7 +334,6 @@ const VMStateDescription vmstate_riscv_cpu = {
> > >   VMSTATE_UINTTL(env.mscratch, RISCVCPU),
> > >   VMSTATE_UINT64(env.mfromhost, RISCVCPU),
> > >   VMSTATE_UINT64(env.mtohost, RISCVCPU),
> > > -VMSTATE_UINT64(env.timecmp, RISCVCPU),
> > >
> >
> > Must bump version_id and minimum_version_id.
> >
> 
> Yeah. Fixed that. Thanks.

When you start getting stable machine type versions it'll become harder
and you might have to put dummy entries in to keep compatibility.

Dave

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




Re: [PATCH 7/8] qmp: add filtering of statistics by name

2022-04-27 Thread Dr. David Alan Gilbert
* Paolo Bonzini (pbonz...@redhat.com) wrote:
> On 4/27/22 14:01, Dr. David Alan Gilbert wrote:
> > >  "providers": [
> > >{ "provider": "kvm",
> > >  "names": [ "l1d_flush", "exits" ] } } }
> > That looks inconsistent to me; I realise that 'names' has to be a child
> > of providers (since the names are only relevant to a given provider) but
> > how about making the "target" work similarly:
> > 
> > { "execute": "query-stats",
> >"arguments": {
> >  "target": {
> >"vcpus": [ "/machine/unattached/device[2]",
> >   "/machine/unattached/device[4]" ] },
> 
> This would allow queries for different types of targets in a single command,
> but it would be harder for the client to do filtering:
> 
> * with something like "target": { "vcpus": [ array ] }, there is no way for
> the client to say "I want this one statistic, but for all the vCPUs"
> 
> * if target is optional, a client might expect relatively small output from
> today's QEMU, yet suddenly get hundreds of KB from targets other than VMs
> and vCPUs (e.g. block devices including all backing files in the chain, NIC
> backends, etc.).

If I specify a 'vm' it's not obvious to me whether I'd get NICs and
block devices in the future?
Adding a syntax for 'all' into the vcpus list would fix that?

> >  "providers": [
> > { "provider": "kvm",
> >   "names": [ "l1d_flush", "exits" ] } } }
> > 
> > It's not clear to me whether the "target" should also be specific
> > to a given provider.
> 
> No, the target is a QEMU concept, such as a CPU or a device backend.  It is
> identified by either a QOM path or a unique id.

But doesn't 'kvm' as a provider only make sense for vcpus and VMs; if
you're imagining block devices and other things as targets it would seem
wrong to have that set of providers separate.

Dave

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




Re: [PATCH 02/26] qcow2: remove incorrect coroutine_fn annotations

2022-04-27 Thread Paolo Bonzini

On 4/21/22 12:24, Stefan Hajnoczi wrote:

-int coroutine_fn qcow2_flush_caches(BlockDriverState *bs)
+int qcow2_flush_caches(BlockDriverState *bs)
  {
  int ret = qcow2_write_caches(bs);


Both of these eventually hit qcow2_cache_write, which is not marked
coroutine, so these should not be either.


coroutine_fn may call non-coroutine_fn, so this alone is not a reason
for removing it from qcow2_write_caches().

There must be a call chain where qcow2_write_caches() and
qcow2_flush_caches() are is invoked from outside coroutine_fn.


The main problematic caller is qcow2_inactivate(), which calls these 
functions via qcow2_mark_clean().  Another one is 
update_ext_header_and_dir(), called by 
qcow2_store_persistent_dirty_bitmaps(), called by qcow2_inactivate().


Converting inactivate to run in coroutine context would help.

Paolo



[PATCH 0/3] Cleanup CoQueue restart functions

2022-04-27 Thread Paolo Bonzini
Sending this out now that NBD's incorrect uses have been fixed.

There is no equivalent of qemu_co_queue_enter_next that restarts all
coroutines but that is incorrect because qemu_co_queue_restart_all should
really be a coroutine_fn.  The NBD uses have been fixed by removing the
calls to qemu_co_queue_restart_all; graphic_hw_update_done works just
because it uses the BQL; but the new rwlock for the BlockDriverState
graph will need it.

The series introduces the new function, removes some duplicated code
around it, and marks qemu_co_queue_next and qemu_co_queue_restart_all
as coroutine_fn.

Paolo

Paolo Bonzini (3):
  coroutine-lock: qemu_co_queue_next is a coroutine-only
qemu_co_enter_next
  coroutine-lock: introduce qemu_co_queue_enter_all
  coroutine-lock: qemu_co_queue_restart_all is a coroutine-only
qemu_co_enter_all

 block/io.c |  2 +-
 include/qemu/coroutine.h   | 27 +-
 ui/console.c   |  2 +-
 util/qemu-coroutine-lock.c | 47 +++---
 4 files changed, 42 insertions(+), 36 deletions(-)

-- 
2.35.1




[PATCH 1/3] coroutine-lock: qemu_co_queue_next is a coroutine-only qemu_co_enter_next

2022-04-27 Thread Paolo Bonzini
qemu_co_queue_next is basically the same as qemu_co_enter_next but
without a QemuLockable argument.  That's perfectly fine, but only
as long as the function is marked coroutine_fn.  If used outside
coroutine context, qemu_co_queue_wait will attempt to take the lock
and that is just broken: if you are calling qemu_co_queue_next outside
coroutine context, the lock is going to be a QemuMutex which cannot be
taken twice by the same thread.

The patch adds the marker and reimplements qemu_co_queue_next in terms of
qemu_co_enter_next_impl, to remove duplicated code and to clarify that the
latter also works in coroutine context.

Signed-off-by: Paolo Bonzini 
---
 include/qemu/coroutine.h   |  7 ---
 util/qemu-coroutine-lock.c | 21 +++--
 2 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index 284571badb..c23d41e1ff 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -208,11 +208,12 @@ void qemu_co_queue_init(CoQueue *queue);
 void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock);
 
 /**
- * Removes the next coroutine from the CoQueue, and wake it up.
+ * Removes the next coroutine from the CoQueue, and queue it to run after
+ * the currently-running coroutine yields.
  * Returns true if a coroutine was removed, false if the queue is empty.
- * OK to run from coroutine and non-coroutine context.
+ * Used from coroutine context, use qemu_co_enter_next outside.
  */
-bool qemu_co_queue_next(CoQueue *queue);
+bool coroutine_fn qemu_co_queue_next(CoQueue *queue);
 
 /**
  * Empties the CoQueue; all coroutines are woken up.
diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c
index 2669403839..5705cfea2e 100644
--- a/util/qemu-coroutine-lock.c
+++ b/util/qemu-coroutine-lock.c
@@ -67,7 +67,7 @@ void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, 
QemuLockable *lock)
 }
 }
 
-static bool qemu_co_queue_do_restart(CoQueue *queue, bool single)
+void qemu_co_queue_restart_all(CoQueue *queue)
 {
 Coroutine *next;
 
@@ -78,23 +78,10 @@ static bool qemu_co_queue_do_restart(CoQueue *queue, bool 
single)
 while ((next = QSIMPLEQ_FIRST(&queue->entries)) != NULL) {
 QSIMPLEQ_REMOVE_HEAD(&queue->entries, co_queue_next);
 aio_co_wake(next);
-if (single) {
-break;
-}
 }
 return true;
 }
 
-bool qemu_co_queue_next(CoQueue *queue)
-{
-return qemu_co_queue_do_restart(queue, true);
-}
-
-void qemu_co_queue_restart_all(CoQueue *queue)
-{
-qemu_co_queue_do_restart(queue, false);
-}
-
 bool qemu_co_enter_next_impl(CoQueue *queue, QemuLockable *lock)
 {
 Coroutine *next;
@@ -115,6 +102,12 @@ bool qemu_co_enter_next_impl(CoQueue *queue, QemuLockable 
*lock)
 return true;
 }
 
+bool coroutine_fn qemu_co_queue_next(CoQueue *queue)
+{
+/* No unlock/lock needed in coroutine context.  */
+return qemu_co_enter_next_impl(queue, NULL);
+}
+
 bool qemu_co_queue_empty(CoQueue *queue)
 {
 return QSIMPLEQ_FIRST(&queue->entries) == NULL;
-- 
2.35.1





[PATCH 3/3] coroutine-lock: qemu_co_queue_restart_all is a coroutine-only qemu_co_enter_all

2022-04-27 Thread Paolo Bonzini
qemu_co_queue_restart_all is basically the same as qemu_co_enter_all
but without a QemuLockable argument.  That's perfectly fine, but only as
long as the function is marked coroutine_fn.  If used outside coroutine
context, qemu_co_queue_wait will attempt to take the lock and that
is just broken: if you are calling qemu_co_queue_restart_all outside
coroutine context, the lock is going to be a QemuMutex which cannot be
taken twice by the same thread.

The patch adds the marker to qemu_co_queue_restart_all and to its sole
non-coroutine_fn caller; it then reimplements the function in terms of
qemu_co_enter_all_impl, to remove duplicated code and to clarify that the
latter also works in coroutine context.

Signed-off-by: Paolo Bonzini 
---
 block/io.c |  2 +-
 include/qemu/coroutine.h   |  7 ---
 util/qemu-coroutine-lock.c | 21 ++---
 3 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/block/io.c b/block/io.c
index 9769ec53b0..789e6373d5 100644
--- a/block/io.c
+++ b/block/io.c
@@ -751,7 +751,7 @@ void bdrv_drain_all(void)
  *
  * This function should be called when a tracked request is completing.
  */
-static void tracked_request_end(BdrvTrackedRequest *req)
+static void coroutine_fn tracked_request_end(BdrvTrackedRequest *req)
 {
 if (req->serialising) {
 qatomic_dec(&req->bs->serialising_in_flight);
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index e5954635f6..43df7a7e66 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -216,10 +216,11 @@ void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, 
QemuLockable *lock);
 bool coroutine_fn qemu_co_queue_next(CoQueue *queue);
 
 /**
- * Empties the CoQueue; all coroutines are woken up.
- * OK to run from coroutine and non-coroutine context.
+ * Empties the CoQueue and queues the coroutine to run after
+ * the currently-running coroutine yields.
+ * Used from coroutine context, use qemu_co_enter_all outside.
  */
-void qemu_co_queue_restart_all(CoQueue *queue);
+void coroutine_fn qemu_co_queue_restart_all(CoQueue *queue);
 
 /**
  * Removes the next coroutine from the CoQueue, and wake it up.  Unlike
diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c
index 5b0342faed..9ad24ab1af 100644
--- a/util/qemu-coroutine-lock.c
+++ b/util/qemu-coroutine-lock.c
@@ -67,21 +67,6 @@ void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, 
QemuLockable *lock)
 }
 }
 
-void qemu_co_queue_restart_all(CoQueue *queue)
-{
-Coroutine *next;
-
-if (QSIMPLEQ_EMPTY(&queue->entries)) {
-return false;
-}
-
-while ((next = QSIMPLEQ_FIRST(&queue->entries)) != NULL) {
-QSIMPLEQ_REMOVE_HEAD(&queue->entries, co_queue_next);
-aio_co_wake(next);
-}
-return true;
-}
-
 bool qemu_co_enter_next_impl(CoQueue *queue, QemuLockable *lock)
 {
 Coroutine *next;
@@ -115,6 +100,12 @@ void qemu_co_enter_all_impl(CoQueue *queue, QemuLockable 
*lock)
 }
 }
 
+void coroutine_fn qemu_co_queue_restart_all(CoQueue *queue)
+{
+/* No unlock/lock needed in coroutine context.  */
+qemu_co_enter_all_impl(queue, NULL);
+}
+
 bool qemu_co_queue_empty(CoQueue *queue)
 {
 return QSIMPLEQ_FIRST(&queue->entries) == NULL;
-- 
2.35.1




[PATCH 2/3] coroutine-lock: introduce qemu_co_queue_enter_all

2022-04-27 Thread Paolo Bonzini
Because qemu_co_queue_restart_all does not release the lock, it should
be used only in coroutine context.  Introduce a new function that,
like qemu_co_enter_next, does release the lock, and use it whenever
qemu_co_queue_restart_all was used outside coroutine context.

Signed-off-by: Paolo Bonzini 
---
 include/qemu/coroutine.h   | 13 +
 ui/console.c   |  2 +-
 util/qemu-coroutine-lock.c |  7 +++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index c23d41e1ff..e5954635f6 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -234,6 +234,19 @@ void qemu_co_queue_restart_all(CoQueue *queue);
 qemu_co_enter_next_impl(queue, QEMU_MAKE_LOCKABLE(lock))
 bool qemu_co_enter_next_impl(CoQueue *queue, QemuLockable *lock);
 
+/**
+ * Empties the CoQueue, waking the waiting coroutine one at a time.  Unlike
+ * qemu_co_queue_all, this function releases the lock during aio_co_wake
+ * because it is meant to be used outside coroutine context; in that case, the
+ * coroutine is entered immediately, before qemu_co_enter_all returns.
+ *
+ * If used in coroutine context, qemu_co_enter_all is equivalent to
+ * qemu_co_queue_all.
+ */
+#define qemu_co_enter_all(queue, lock) \
+qemu_co_enter_all_impl(queue, QEMU_MAKE_LOCKABLE(lock))
+void qemu_co_enter_all_impl(CoQueue *queue, QemuLockable *lock);
+
 /**
  * Checks if the CoQueue is empty.
  */
diff --git a/ui/console.c b/ui/console.c
index 1752f2ec88..afe3159394 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -218,7 +218,7 @@ static void gui_setup_refresh(DisplayState *ds)
 void graphic_hw_update_done(QemuConsole *con)
 {
 if (con) {
-qemu_co_queue_restart_all(&con->dump_queue);
+qemu_co_enter_all(&con->dump_queue, NULL);
 }
 }
 
diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c
index 5705cfea2e..5b0342faed 100644
--- a/util/qemu-coroutine-lock.c
+++ b/util/qemu-coroutine-lock.c
@@ -108,6 +108,13 @@ bool coroutine_fn qemu_co_queue_next(CoQueue *queue)
 return qemu_co_enter_next_impl(queue, NULL);
 }
 
+void qemu_co_enter_all_impl(CoQueue *queue, QemuLockable *lock)
+{
+while (qemu_co_enter_next_impl(queue, lock)) {
+/* just loop */
+}
+}
+
 bool qemu_co_queue_empty(CoQueue *queue)
 {
 return QSIMPLEQ_FIRST(&queue->entries) == NULL;
-- 
2.35.1





Re: [PATCH 1/4] block: Classify bdrv_get_flags() as I/O function

2022-04-27 Thread Eric Blake
On Wed, Apr 27, 2022 at 01:40:54PM +0200, Hanna Reitz wrote:
> This function is safe to call in an I/O context, and qcow2_do_open()
> does so (invoked in an I/O context by qcow2_co_invalidate_cache()).
> 
> Signed-off-by: Hanna Reitz 
> ---
>  include/block/block-global-state.h | 1 -
>  include/block/block-io.h   | 1 +
>  block.c| 2 +-
>  3 files changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Eric Blake 

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




Re: [PATCH 2/4] qcow2: Do not reopen data_file in invalidate_cache

2022-04-27 Thread Eric Blake
On Wed, Apr 27, 2022 at 01:40:55PM +0200, Hanna Reitz wrote:
> qcow2_co_invalidate_cache() closes and opens the qcow2 file, by calling
> qcow2_close() and qcow2_do_open().  These two functions must thus be
> usable from both a global-state and an I/O context.
> 
> As they are, they are not safe to call in an I/O context, because they
> use bdrv_unref_child() and bdrv_open_child() to close/open the data_file
> child, respectively, both of which are global-state functions.  When
> used from qcow2_co_invalidate_cache(), we do not need to close/open the
> data_file child, though (we do not do this for bs->file or bs->backing
> either), and so we should skip it in the qcow2_co_invalidate_cache()
> path.
> 
> To do so, add a parameter to qcow2_do_open() and qcow2_close() to make
> them skip handling s->data_file, and have qcow2_co_invalidate_cache()
> exempt it from the memset() on the BDRVQcow2State.
> 
> (Note that the QED driver similarly closes/opens the QED image by
> invoking bdrv_qed_close()+bdrv_qed_do_open(), but both functions seem
> safe to use in an I/O context.)
> 
> Fixes: https://gitlab.com/qemu-project/qemu/-/issues/945
> Signed-off-by: Hanna Reitz 
> ---
>  block/qcow2.c | 104 ++
>  1 file changed, 62 insertions(+), 42 deletions(-)

Reviewed-by: Eric Blake 

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




Re: [PATCH v4 4/6] vduse-blk: implements vduse-blk export

2022-04-27 Thread Kevin Wolf
Am 27.04.2022 um 05:11 hat Yongji Xie geschrieben:
> On Wed, Apr 27, 2022 at 1:03 AM Kevin Wolf  wrote:
> >
> > Am 06.04.2022 um 09:59 hat Xie Yongji geschrieben:
> > > This implements a VDUSE block backends based on
> > > the libvduse library. We can use it to export the BDSs
> > > for both VM and container (host) usage.
> > >
> > > The new command-line syntax is:
> > >
> > > $ qemu-storage-daemon \
> > > --blockdev file,node-name=drive0,filename=test.img \
> > > --export vduse-blk,node-name=drive0,id=vduse-export0,writable=on
> > >
> > > After the qemu-storage-daemon started, we need to use
> > > the "vdpa" command to attach the device to vDPA bus:
> > >
> > > $ vdpa dev add name vduse-export0 mgmtdev vduse
> > >
> > > Also the device must be removed via the "vdpa" command
> > > before we stop the qemu-storage-daemon.
> > >
> > > Signed-off-by: Xie Yongji 
> >
> > The request handling code is almos the same as for the vhost-user-blk
> > export. I wonder if we could share this code instead of copying.
> >
> 
> I think we can. Will do it v5.
> 
> > The main difference seems to be that you chose not to support discard
> > and write_zeroes yet. I'm curious if there is a reason why the
> > vhost-user-blk code wouldn't work for vdpa there?
> >
> 
> They are different protocols. The data plane is similar, so we can
> share some codes. But the control plane is different, e.g., vhost-user
> can only work for guests but vdpa can work for both guests and hosts.

Yes, sure, but discard/write_zeroes are part of the data plane, no?
You're already sharing (or at the moment copying) the code for the other
request types mostly unchanged, so I wondered what is different about
discard/write_zeroes.

Kevin




Re: [PATCH 3/4] Revert "main-loop: Disable GLOBAL_STATE_CODE() assertions"

2022-04-27 Thread Eric Blake
On Wed, Apr 27, 2022 at 01:40:56PM +0200, Hanna Reitz wrote:
> This reverts commit b1c073490553f80594b903ceedfc7c1aef6b1b19.  (We
> wanted to do so once the 7.1 tree opens, which has happened.  The issue
> reported in https://gitlab.com/qemu-project/qemu/-/issues/945 should be
> fixed by the preceding patches.)
> 
> Signed-off-by: Hanna Reitz 
> ---
>  include/qemu/main-loop.h | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

Reviewed-by: Eric Blake 

[Here's hoping we don't have to re-disable it because it finds more
bugs - but maximizing the soak time during development with it enabled
is good]

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




Re: [PATCH v2 2/5] 9pfs: fix qemu_mknodat(S_IFSOCK) on macOS

2022-04-27 Thread Greg Kurz
On Wed, 27 Apr 2022 14:32:53 +0200
Christian Schoenebeck  wrote:

> On Mittwoch, 27. April 2022 12:18:10 CEST Greg Kurz wrote:
> > On Wed, 27 Apr 2022 11:27:28 +0900
> > 
> > Akihiko Odaki  wrote:
> > > On 2022/04/26 21:38, Greg Kurz wrote:
> > [..skip..]
> > 
> > > > I think Christian's explanation is clear enough. We don't guarantee
> > > > that v9fs_co_foo() calls run atomically. As a consequence, the client
> > > > might see transient states or be able to interact with an ongoing
> > > > request. And to answer your question, we have no specific rationale
> > > > on security with that.
> > > > 
> > > > I'm not sure what the concerns are but unless you come up with a
> > > > valid scenario [*] I don't see any reason to prevent this patch
> > > > to go forward.
> > > > 
> > > > [*] things like:
> > > >  - client escaping the shared directory
> > > >  - QEMU crashing
> > > >  - QEMU hogging host resources
> > > >  - client-side unprivileged user gaining elevated privleges
> > > >  
> > > >in the guest
> > > 
> > > I was just not sure if such transient states are safe. The past
> > > discussion was about the length of the non-atomic time window where a
> > > path name is used to identify a particular file, but if such states are
> > > not considered problematic, the length does not matter all and we can
> > > confidently say the sequence of bind() and chmod() is safe.
> > > 
> > > Considering the transient states are tolerated in 9pfs, we need to
> > > design this function to be tolerant with transient states as well. The
> > > use of chmod() is not safe when we consider about transient states. A
> > > malicious actor may replace the file at the path with a symlink which
> > > may escape the shared directory and chmod() will naively follow it.
> > 
> > You get a point here. Thanks for your tenacity ! :-)
> 
> Yep, I send a v4 with fchmodat_nofollow() instead of chmod(), thanks!
> 
> BTW, why is it actually allowed for client to create a symlink pointing 
> outside exported directory tree with security_model=passthrough/none? Did 
> anybody want that?
> 

The target argument to symlink() is merely a string that is stored in
the inode. It is only evaluated as a path at the time an action is
made on the link. Checking at symlink() time is thus useless.

Anyway, we're safe on this side since it's the client's job to
resolve links and we explicitly don't follow them in the server.

> > > chmod() should be replaced with fchmodat_nofollow() or something similar.
> > 
> > On a GNU/Linux system, this could be achieved by calling fchmod() on
> > the socket fd *before* calling bind() but I'm afraid this hack might
> > not work with a BSDish OS.
> 
> As you already imagined, this is unfortunately not supported by any BSDs, 
> including macOS. I'll file a bug report with Apple though.
> 

I'm not sure if this is documented and supported behavior on linux either.

> > Replacing chmod() with fchmodat_nofollow(dirfd, addr.sun_path, mode)
> > won't make things atomic as above but at least it won't follow a
> > malicious symbolic link : mknod() on the client will fail with
> > ELOOP, which is fine when it comes to not breaking out of the shared
> > directory.
> 
> Current security_model=passthrough/none already has similar non-atomic 
> operations BTW, so this was not something new. E.g.:
> 
> static int local_symlink(FsContext *fs_ctx, const char *oldpath,
>  V9fsPath *dir_path, const char *name, FsCred *credp)
> {
> ...
> } else if (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH ||
>fs_ctx->export_flags & V9FS_SM_NONE) {
> err = symlinkat(oldpath, dirfd, name);
> if (err) {
> goto out;
> }
> err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
>AT_SYMLINK_NOFOLLOW);
> ...
> }
> 

Yes similar window but this is secure since fchownat() supports
AT_SYMLINK_NOFOLLOW.

> In general, if you care about a higher degree of security, I'd always 
> recommend to use security_model=mapped in the first place.
> 
> > This brings up a new problem I hadn't realized before : the
> > fchmodat_nofollow() implementation in 9p-local.c is really
> > a linux only thing to cope with AT_SYMLINK_NOFOLLOW not being
> > supported with fchmodat(). It looks that this should move to
> > 9p-util-linux.c and a proper version should be added for macOS
> > in 9p-util-darwin.c
> 
> Like already agreed on the other thread, yes, that makes sense. But I think 
> this can be handled with a follow-up, separate from this series.
> 

Fair enough if you want to handle fchmodat_nofollow() later but you
must at least use fchmodat(AT_SYMLINK_NOFOLLOW) in this patch
instead of chmod().

> Best regards,
> Christian Schoenebeck
> 
> 




[PATCH] qemu-options: Limit the -xen options to x86 and arm

2022-04-27 Thread Thomas Huth
The Xen hypervisor is only available on x86 and arm - thus let's
limit the related options to these targets.

Signed-off-by: Thomas Huth 
---
 qemu-options.hx | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 1764eebfaf..cc3a39d21a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4184,16 +4184,17 @@ SRST
 ERST
 
 DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid,
-"-xen-domid id   specify xen guest domain id\n", QEMU_ARCH_ALL)
+"-xen-domid id   specify xen guest domain id\n",
+QEMU_ARCH_ARM | QEMU_ARCH_I386)
 DEF("xen-attach", 0, QEMU_OPTION_xen_attach,
 "-xen-attach attach to existing xen domain\n"
 "libxl will use this when starting QEMU\n",
-QEMU_ARCH_ALL)
+QEMU_ARCH_ARM | QEMU_ARCH_I386)
 DEF("xen-domid-restrict", 0, QEMU_OPTION_xen_domid_restrict,
 "-xen-domid-restrict restrict set of available xen operations\n"
 "to specified domain id. (Does not affect\n"
 "xenpv machine type).\n",
-QEMU_ARCH_ALL)
+QEMU_ARCH_ARM | QEMU_ARCH_I386)
 SRST
 ``-xen-domid id``
 Specify xen guest domain id (XEN only).
-- 
2.27.0




Re: [PATCH] softmmu/vl: Fence 'xenfb' if Xen support is not compiled in

2022-04-27 Thread Anthony PERARD via
On Wed, Apr 27, 2022 at 02:33:16PM +0200, Thomas Huth wrote:
> The 'xenfb' parameter for the '-vga' command line option is currently
> always enabled unconditionally (since the xenfb is not a proper QOM
> device that could be tested via its class name). That means it also
> shows up if Xen is not enabled at all, e.g. like this:
> 
>  $ ./qemu-system-sparc -vga help
>  none no graphic card
>  xenfbXen paravirtualized framebuffer
>  tcx  TCX framebuffer (default)
>  cg3  CG3 framebuffer
> 
> Let's avoid this situation by fencing the parameter with the
> CONFIG_XEN_BACKEND switch.
> 
> Signed-off-by: Thomas Huth 

Acked-by: Anthony PERARD 

Thanks,

-- 
Anthony PERARD



Re: [RFC PATCH 6/6] vl: introduce -audio as a replacement for -soundhw

2022-04-27 Thread Mark Cave-Ayland

On 27/04/2022 12:32, Paolo Bonzini wrote:


-audio is used like "-audio pa,model=sb16".  It is almost as simple as
-soundhw, but it reuses the -audiodev parsing machinery and attaches an
audiodev to the newly-created device.  The main 'feature' is that
it knows about adding the codec device for model=intel-hda, and adding
the audiodev to the codec device.

In the future, it could be extended to support default models or
builtin devices, just like -nic, or even a default backend.  For now,
keep it simple.

JSON parsing is not supported for -audio.  This is okay because the
option is targeted at end users, not programs.

Signed-off-by: Paolo Bonzini 
---
  audio/audio.c   |  8 +-
  audio/audio.h   |  1 +
  docs/about/deprecated.rst   |  9 --
  docs/about/removed-features.rst |  7 +
  hw/audio/intel-hda.c|  5 ++--
  hw/audio/soundhw.c  | 12 +---
  include/hw/audio/soundhw.h  |  4 +--
  qemu-options.hx | 51 -
  softmmu/vl.c| 28 --
  9 files changed, 76 insertions(+), 49 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 9e91a5a4f2..a02f3ce5c6 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2099,13 +2099,19 @@ static void audio_validate_opts(Audiodev *dev, Error 
**errp)
  
  void audio_parse_option(const char *opt)

  {
-AudiodevListEntry *e;
  Audiodev *dev = NULL;
  
  Visitor *v = qobject_input_visitor_new_str(opt, "driver", &error_fatal);

  visit_type_Audiodev(v, NULL, &dev, &error_fatal);
  visit_free(v);
  
+audio_define(dev);

+}
+
+void audio_define(Audiodev *dev)
+{
+AudiodevListEntry *e;
+
  audio_validate_opts(dev, &error_fatal);
  
  e = g_new0(AudiodevListEntry, 1);

diff --git a/audio/audio.h b/audio/audio.h
index 3d5ecdecd5..b5e17cd218 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -168,6 +168,7 @@ void audio_sample_to_uint64(const void *samples, int pos,
  void audio_sample_from_uint64(void *samples, int pos,
  uint64_t left, uint64_t right);
  
+void audio_define(Audiodev *audio);

  void audio_parse_option(const char *opt);
  void audio_init_audiodevs(void);
  void audio_legacy_help(void);
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 896e5a97ab..70885d09f3 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -39,15 +39,6 @@ should specify an ``audiodev=`` property.  Additionally, 
when using
  vnc, you should specify an ``audiodev=`` property if you plan to
  transmit audio through the VNC protocol.
  
-Creating sound card devices using ``-soundhw`` (since 5.1)

-''
-
-Sound card devices should be created using ``-device`` instead.  The
-names are the same for most devices.  The exceptions are ``hda`` which
-needs two devices (``-device intel-hda -device hda-duplex``) and
-``pcspk`` which can be activated using ``-machine
-pcspk-audiodev=``.
-
  ``-chardev`` backend aliases ``tty`` and ``parport`` (since 6.0)
  
  
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst

index 3f324d0536..eabc6c63ac 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -632,6 +632,13 @@ tripped up the CI testing and was suspected to be quite 
broken. For that
  reason the maintainers strongly suspected no one actually used it.
  
  
+Creating sound card devices using ``-soundhw`` (removed in 7.1)

+''
+
+Sound card devices should be created using ``-device`` or ``-audio``.
+The exception is ``pcspk`` which can be activated using ``-machine
+pcspk-audiodev=``.
+
  TCG introspection features
  --
  
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c

index bc77e3d8c9..f38117057b 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -1311,17 +1311,16 @@ static const TypeInfo hda_codec_device_type_info = {
   * create intel hda controller with codec attached to it,
   * so '-soundhw hda' works.
   */
-static int intel_hda_and_codec_init(PCIBus *bus)
+static int intel_hda_and_codec_init(PCIBus *bus, const char *audiodev)
  {
  DeviceState *controller;
  BusState *hdabus;
  DeviceState *codec;
  
-warn_report("'-soundhw hda' is deprecated, "

-"please use '-device intel-hda -device hda-duplex' instead");
  controller = DEVICE(pci_create_simple(bus, -1, "intel-hda"));
  hdabus = QLIST_FIRST(&controller->child_bus);
  codec = qdev_new("hda-duplex");
+qdev_prop_set_string(codec, "audiodev", audiodev);
  qdev_realize_and_unref(codec, hdabus, &error_fatal);
  return 0;
  }
diff --git a/hw/audio/soundhw.c b/hw/audio/soundhw.c
index d81ae91136..e979be08ce 100644
--- a/hw/audio/soundhw.c
+++ b/hw/audio/soundhw.

Re: [PATCH v4 4/6] vduse-blk: implements vduse-blk export

2022-04-27 Thread Yongji Xie
On Wed, Apr 27, 2022 at 9:22 PM Kevin Wolf  wrote:
>
> Am 27.04.2022 um 05:11 hat Yongji Xie geschrieben:
> > On Wed, Apr 27, 2022 at 1:03 AM Kevin Wolf  wrote:
> > >
> > > Am 06.04.2022 um 09:59 hat Xie Yongji geschrieben:
> > > > This implements a VDUSE block backends based on
> > > > the libvduse library. We can use it to export the BDSs
> > > > for both VM and container (host) usage.
> > > >
> > > > The new command-line syntax is:
> > > >
> > > > $ qemu-storage-daemon \
> > > > --blockdev file,node-name=drive0,filename=test.img \
> > > > --export vduse-blk,node-name=drive0,id=vduse-export0,writable=on
> > > >
> > > > After the qemu-storage-daemon started, we need to use
> > > > the "vdpa" command to attach the device to vDPA bus:
> > > >
> > > > $ vdpa dev add name vduse-export0 mgmtdev vduse
> > > >
> > > > Also the device must be removed via the "vdpa" command
> > > > before we stop the qemu-storage-daemon.
> > > >
> > > > Signed-off-by: Xie Yongji 
> > >
> > > The request handling code is almos the same as for the vhost-user-blk
> > > export. I wonder if we could share this code instead of copying.
> > >
> >
> > I think we can. Will do it v5.
> >
> > > The main difference seems to be that you chose not to support discard
> > > and write_zeroes yet. I'm curious if there is a reason why the
> > > vhost-user-blk code wouldn't work for vdpa there?
> > >
> >
> > They are different protocols. The data plane is similar, so we can
> > share some codes. But the control plane is different, e.g., vhost-user
> > can only work for guests but vdpa can work for both guests and hosts.
>
> Yes, sure, but discard/write_zeroes are part of the data plane, no?
> You're already sharing (or at the moment copying) the code for the other
> request types mostly unchanged, so I wondered what is different about
> discard/write_zeroes.
>

I get your point. There is no limitation on discard/write_zeroes
support for vduse. I will do it in v5.

Thanks,
Yongji



[PATCH] qemu-options: Limit the -enable-kvm option to the targets that support it

2022-04-27 Thread Thomas Huth
There is no need to present the user with -enable-kvm if there
is no support for KVM on the corresponding target.

Signed-off-by: Thomas Huth 
---
 qemu-options.hx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index cc3a39d21a..af1c8feda6 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4176,7 +4176,9 @@ SRST
 ERST
 
 DEF("enable-kvm", 0, QEMU_OPTION_enable_kvm, \
-"-enable-kvm enable KVM full virtualization support\n", QEMU_ARCH_ALL)
+"-enable-kvm enable KVM full virtualization support\n",
+QEMU_ARCH_ARM | QEMU_ARCH_I386 | QEMU_ARCH_MIPS | QEMU_ARCH_PPC |
+QEMU_ARCH_RISCV | QEMU_ARCH_S390X)
 SRST
 ``-enable-kvm``
 Enable KVM full virtualization support. This option is only
-- 
2.27.0




Re: [PATCH] qemu-options: Limit the -xen options to x86 and arm

2022-04-27 Thread Anthony PERARD via
On Wed, Apr 27, 2022 at 03:31:56PM +0200, Thomas Huth wrote:
> The Xen hypervisor is only available on x86 and arm - thus let's
> limit the related options to these targets.
> 
> Signed-off-by: Thomas Huth 

Acked-by: Anthony PERARD 

Thanks,

-- 
Anthony PERARD



Re: [PATCH 4/4] iotests: Add regression test for issue 945

2022-04-27 Thread Eric Blake
On Wed, Apr 27, 2022 at 01:40:57PM +0200, Hanna Reitz wrote:
> Create a VM with a BDS in an iothread, add -incoming defer to the
> command line, and then export this BDS via NBD.  Doing so should not
> fail an assertion.
> 
> Signed-off-by: Hanna Reitz 
> ---
>  .../tests/export-incoming-iothread| 81 +++
>  .../tests/export-incoming-iothread.out|  5 ++
>  2 files changed, 86 insertions(+)
>  create mode 100755 tests/qemu-iotests/tests/export-incoming-iothread
>  create mode 100644 tests/qemu-iotests/tests/export-incoming-iothread.out

The test looks sane, and appears to match the formula posted in issue
945.  When applying just patches 3-4 (skipping 1-2), './check
export-incoming-iothread' passed, but './check -qcow2
export-incoming-iothread' failed; so the image format is important.
And the failure was rather verbose, which is a GOOD thing - our
efforts to make the python framework point out abnormal exits is
working!

+WARNING:qemu.machine.machine:qemu received signal 6; command: 
"/home/eblake/qemu/build/tests/qemu-iotests/...
...
+Traceback (most recent call last):
+  File "/home/eblake/qemu/tests/qemu-iotests/tests/export-incoming-iothread", 
line 69, in test_export_add
+result = self.vm.qmp('block-export-add', {
...
+  File "/home/eblake/qemu/python/qemu/qmp/qmp_client.py", line 463, in _reply
+raise result
+qemu.qmp.qmp_client.ExecInterruptedError: Disconnected
+
+==
+ERROR: test_export_add (__main__.TestExportIncomingIothread)
+--
+Traceback (most recent call last):
+  File "/home/eblake/qemu/python/qemu/machine/machine.py", line 533, in 
_soft_shutdown
+self.qmp('quit')
...
+qemu.qmp.protocol.StateError: QMPClient is disconnecting. Call disconnect() to 
return to IDLE state.
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+  File "/home/eblake/qemu/python/qemu/machine/machine.py", line 554, in 
_do_shutdown
+self._soft_shutdown(timeout)
...
+  File "/home/eblake/qemu/python/qemu/qmp/protocol.py", line 968, in _readline
+raise EOFError
+EOFError
+
+The above exception was the direct cause of the following exception:
+
+Traceback (most recent call last):
+  File "/home/eblake/qemu/tests/qemu-iotests/tests/export-incoming-iothread", 
line 54, in tearDown
+self.vm.shutdown()
+  File "/home/eblake/qemu/python/qemu/machine/machine.py", line 583, in 
shutdown
+self._do_shutdown(timeout)
+  File "/home/eblake/qemu/python/qemu/machine/machine.py", line 557, in 
_do_shutdown
+raise AbnormalShutdown("Could not perform graceful shutdown") \
+qemu.machine.machine.AbnormalShutdown: Could not perform graceful shutdown
+
 --
 Ran 1 tests

-OK
+FAILED (errors=2)


Then applying patches 1-2 and repeating the test passed, so your test
is a good proof that we identified and fixed the problem at hand.

Reviewed-by: Eric Blake 
Tested-by: Eric Blake 

Given that it is visible with NBD, I'm happy to queue this series
through my tree if no one else grabs it first.

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




Re: [PATCH 1/3] coroutine-lock: qemu_co_queue_next is a coroutine-only qemu_co_enter_next

2022-04-27 Thread Eric Blake
On Wed, Apr 27, 2022 at 03:08:28PM +0200, Paolo Bonzini wrote:
> qemu_co_queue_next is basically the same as qemu_co_enter_next but
> without a QemuLockable argument.  That's perfectly fine, but only
> as long as the function is marked coroutine_fn.  If used outside
> coroutine context, qemu_co_queue_wait will attempt to take the lock
> and that is just broken: if you are calling qemu_co_queue_next outside
> coroutine context, the lock is going to be a QemuMutex which cannot be
> taken twice by the same thread.
> 
> The patch adds the marker and reimplements qemu_co_queue_next in terms of
> qemu_co_enter_next_impl, to remove duplicated code and to clarify that the
> latter also works in coroutine context.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  include/qemu/coroutine.h   |  7 ---
>  util/qemu-coroutine-lock.c | 21 +++--
>  2 files changed, 11 insertions(+), 17 deletions(-)

Reviewed-by: Eric Blake 

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




Re: [PATCH 2/3] coroutine-lock: introduce qemu_co_queue_enter_all

2022-04-27 Thread Eric Blake
On Wed, Apr 27, 2022 at 03:08:29PM +0200, Paolo Bonzini wrote:
> Because qemu_co_queue_restart_all does not release the lock, it should
> be used only in coroutine context.  Introduce a new function that,
> like qemu_co_enter_next, does release the lock, and use it whenever
> qemu_co_queue_restart_all was used outside coroutine context.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  include/qemu/coroutine.h   | 13 +
>  ui/console.c   |  2 +-
>  util/qemu-coroutine-lock.c |  7 +++
>  3 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
> index c23d41e1ff..e5954635f6 100644
> --- a/include/qemu/coroutine.h
> +++ b/include/qemu/coroutine.h
> @@ -234,6 +234,19 @@ void qemu_co_queue_restart_all(CoQueue *queue);
>  qemu_co_enter_next_impl(queue, QEMU_MAKE_LOCKABLE(lock))
>  bool qemu_co_enter_next_impl(CoQueue *queue, QemuLockable *lock);
>  
> +/**
> + * Empties the CoQueue, waking the waiting coroutine one at a time.  Unlike

maybe s/coroutine/coroutine(s)/

> + * qemu_co_queue_all, this function releases the lock during aio_co_wake
> + * because it is meant to be used outside coroutine context; in that case, 
> the
> + * coroutine is entered immediately, before qemu_co_enter_all returns.
> + *
> + * If used in coroutine context, qemu_co_enter_all is equivalent to
> + * qemu_co_queue_all.
> + */
> +#define qemu_co_enter_all(queue, lock) \
> +qemu_co_enter_all_impl(queue, QEMU_MAKE_LOCKABLE(lock))
> +void qemu_co_enter_all_impl(CoQueue *queue, QemuLockable *lock);
> +

Reviewed-by: Eric Blake 

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




Re: [PATCH 7/8] qmp: add filtering of statistics by name

2022-04-27 Thread Paolo Bonzini

On 4/27/22 14:34, Dr. David Alan Gilbert wrote:

If I specify a 'vm' it's not obvious to me whether I'd get NICs and
block devices in the future?


VM would not get those (it's global statistics), but the size could 
balloon if you specify no target at all.



Adding a syntax for 'all' into the vcpus list would fix that?


I don't like having special syntax.  The current QAPI just doesn't 
filter what is not in the arguments.



  "providers": [
 { "provider": "kvm",
   "names": [ "l1d_flush", "exits" ] } } }

It's not clear to me whether the "target" should also be specific
to a given provider.


No, the target is a QEMU concept, such as a CPU or a device backend.  It is
identified by either a QOM path or a unique id.


But doesn't 'kvm' as a provider only make sense for vcpus and VMs; if
you're imagining block devices and other things as targets it would seem
wrong to have that set of providers separate.


Yes, those would have different providers.  But a single target can 
support multiple providers.


Paolo



Re: [PATCH 02/26] qcow2: remove incorrect coroutine_fn annotations

2022-04-27 Thread Paolo Bonzini

On 4/27/22 14:36, Paolo Bonzini wrote:

On 4/21/22 12:24, Stefan Hajnoczi wrote:

-int coroutine_fn qcow2_flush_caches(BlockDriverState *bs)
+int qcow2_flush_caches(BlockDriverState *bs)
  {
  int ret = qcow2_write_caches(bs);


Both of these eventually hit qcow2_cache_write, which is not marked
coroutine, so these should not be either.


coroutine_fn may call non-coroutine_fn, so this alone is not a reason
for removing it from qcow2_write_caches().

There must be a call chain where qcow2_write_caches() and
qcow2_flush_caches() are is invoked from outside coroutine_fn.


The main problematic caller is qcow2_inactivate(), which calls these 
functions via qcow2_mark_clean().  Another one is 
update_ext_header_and_dir(), called by 
qcow2_store_persistent_dirty_bitmaps(), called by qcow2_inactivate().


Converting inactivate to run in coroutine context would help.


Or maybe not so much because bdrv_close also calls the same paths.

Paolo




Re: [PATCH] qemu-options: Limit the -enable-kvm option to the targets that support it

2022-04-27 Thread Paolo Bonzini
Queued, thanks.

Paolo





Re: [PATCH 3/3] coroutine-lock: qemu_co_queue_restart_all is a coroutine-only qemu_co_enter_all

2022-04-27 Thread Eric Blake
On Wed, Apr 27, 2022 at 03:08:30PM +0200, Paolo Bonzini wrote:
> qemu_co_queue_restart_all is basically the same as qemu_co_enter_all
> but without a QemuLockable argument.  That's perfectly fine, but only as
> long as the function is marked coroutine_fn.  If used outside coroutine
> context, qemu_co_queue_wait will attempt to take the lock and that
> is just broken: if you are calling qemu_co_queue_restart_all outside
> coroutine context, the lock is going to be a QemuMutex which cannot be
> taken twice by the same thread.
> 
> The patch adds the marker to qemu_co_queue_restart_all and to its sole
> non-coroutine_fn caller; it then reimplements the function in terms of
> qemu_co_enter_all_impl, to remove duplicated code and to clarify that the
> latter also works in coroutine context.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  block/io.c |  2 +-
>  include/qemu/coroutine.h   |  7 ---
>  util/qemu-coroutine-lock.c | 21 ++---
>  3 files changed, 11 insertions(+), 19 deletions(-)
>

Reviewed-by: Eric Blake 

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




Re: [RFC PATCH 6/6] vl: introduce -audio as a replacement for -soundhw

2022-04-27 Thread Paolo Bonzini

On 4/27/22 15:41, Mark Cave-Ayland wrote:

+    select_soundhw(model, dev->id);
+    g_free(model);
  break;
+    }
  case QEMU_OPTION_h:
  help(0);
  break;


Is it possible to change select_soundhw() to take an AudioDev pointer 
rather than a string, and then add a new qdev_prop_set_audiodev() 
function similar to qdev_prop_set_chr() and qdev_prop_set_netdev()?


In reality the underlying QOM property is still a string, but I think 
having the stronger typing for AudioDev properties is useful and 
potentially allows for the various *dev backend properties to become QOM 
links in future.


I didn't consider that because there are just two uses and I don't 
expect them to grow much, but yes it's possible.


Paolo



Re: [PATCH 1/2] acpi/nvdimm: Create _LS{I,R,W} method for NVDIMM device

2022-04-27 Thread Igor Mammedov
On Tue, 12 Apr 2022 14:57:52 +0800
Robert Hoo  wrote:

> Since ACPI 6.2, previous NVDIMM/_DSM funcions "Get Namespace Label Data
> Size (function index 4)", "Get Namespace Label Data (function index 5)",
> "Set Namespace Label Data (function index 6)" has been deprecated by ACPI

where it's said that old way was deprecated, should be mentioned here including
pointer to spec where it came into effect.

> standard method _LSI, _LSR, _LSW respectively. Functions semantics are
> almost identical, so my implementation is to reuse existing _DSMs, just
> create _LS{I,R,W} interfaces and constructs parameters and call _DSMs.
> 
> Only child NVDIMM devices has these methods, rather Root device.
> 
> By this patch, new NVDIMM sub device in ACPI namespace will be like this:
> 
> Device (NV00)
> {
>   Name (_ADR, One)  // _ADR: Address
> Method (_LSI, 0, NotSerialized)  // _LSI: Label Storage Information
> {
>  Return (NCAL (ToUUID ("4309ac30-0d11-11e4-9191-0800200c9a66"), 
> 0x02, 0x04, Zero, One))
> }
> 
> Method (_LSR, 2, Serialized)  // _LSR: Label Storage Read
> {
>   CreateDWordField (BUFF, Zero, DWD0)
> CreateDWordField (BUFF, 0x04, DWD1)
> Name (PKG1, Package (0x01)
> {
> BUFF
> })
> DWD0 = Arg0
> DWD1 = Arg1
> Return (NCAL (ToUUID 
> ("4309ac30-0d11-11e4-9191-0800200c9a66"), 0x02, 0x05, PKG1, One))
> }
> 
> Method (_LSW, 3, Serialized)  // _LSW: Label Storage Write
> {
> CreateDWordField (BUFF, Zero, DWD0)
> CreateDWordField (BUFF, 0x04, DWD1)
> CreateField (BUFF, 0x40, 0x7FA0, FILD)
> Name (PKG1, Package (0x01)
> {
> BUFF
> })
> DWD0 = Arg0
> DWD1 = Arg1
> FILD = Arg2
> Return (NCAL (ToUUID 
> ("4309ac30-0d11-11e4-9191-0800200c9a66"), 0x02, 0x06, PKG1, One))
>  }
> 
>  Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
>  {
> Return (NCAL (Arg0, Arg1, Arg2, Arg3, One))
>  }
> }
> 
> Signed-off-by: Robert Hoo 
> Reviewed-by: Jingqi Liu
> ---
>  hw/acpi/nvdimm.c | 56 
>  1 file changed, 52 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
> index 0d43da19ea..7cc419401b 100644
> --- a/hw/acpi/nvdimm.c
> +++ b/hw/acpi/nvdimm.c
> @@ -848,10 +848,10 @@ nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t 
> val, unsigned size)
>  
>  nvdimm_debug("Revision 0x%x Handler 0x%x Function 0x%x.\n", in->revision,
>   in->handle, in->function);
> -
> -if (in->revision != 0x1 /* Currently we only support DSM Spec Rev1. */) {
> -nvdimm_debug("Revision 0x%x is not supported, expect 0x%x.\n",
> - in->revision, 0x1);
> +/* Currently we only support DSM Spec Rev1 and Rev2. */

where does revision 2 come from? It would be better to add a pointer to 
relevant spec.

> +if (in->revision != 0x1 && in->revision != 0x2) {
> +nvdimm_debug("Revision 0x%x is not supported, expect 0x1 or 0x2.\n",
> + in->revision);

since you are touching nvdimm_debug(), please replace it with tracing,
see docs/devel/tracing.rst and any commit that adds tracing calls
(functions starting with 'trace_').

>  nvdimm_dsm_no_payload(NVDIMM_DSM_RET_STATUS_UNSUPPORT, dsm_mem_addr);
>  goto exit;
>  }


this whole hunk should be a separate patch, properly documented


also I wonder if DSM

> @@ -1247,6 +1247,11 @@ static void nvdimm_build_fit(Aml *dev)
>  static void nvdimm_build_nvdimm_devices(Aml *root_dev, uint32_t ram_slots)
>  {
>  uint32_t slot;
> +Aml *method, *pkg, *buff;
> +
> +/* Build common shared buffer for params pass in/out */
> +buff = aml_buffer(4096, NULL);
> +aml_append(root_dev, aml_name_decl("BUFF", buff));

is there a reason to use global variable instead of LocalX?

>  
>  for (slot = 0; slot < ram_slots; slot++) {
>  uint32_t handle = nvdimm_slot_to_handle(slot);
> @@ -1264,6 +1269,49 @@ static void nvdimm_build_nvdimm_devices(Aml *root_dev, 
> uint32_t ram_slots)
>   */
>  aml_append(nvdimm_dev, aml_name_decl("_ADR", aml_int(handle)));
>  
> +/* Build _LSI, _LSR, _LSW */

should be 1 comment per method with spec/ver and chapter where it's defined

> +method = aml_method("_LSI", 0, AML_NOTSERIALIZED);
> +aml_append(method, aml_return(aml_call5(NVDIMM_COMMON_DSM,
> +
> aml_touuid("4309AC30-0D11-11E4-9191-0800200C9A66"),
> +aml_int(2), aml_int(4), aml_int(0),
> +aml_int(handle;
> +aml_append(nvdimm_dev, method);

_LSI should return 

[PATCH 0/6] virtio-scsi: fix 100% CPU consumption in IOThread

2022-04-27 Thread Stefan Hajnoczi
Nir Soffer reported that virtio-scsi,iothread=... consumes 100% CPU in QEMU
7.0. This patch series addresses two bugs in hw/scsi/virtio-scsi.c (see patches
1 & 2) and follows up with code cleanups.

Stefan Hajnoczi (6):
  virtio-scsi: fix ctrl and event handler functions in dataplane mode
  virtio-scsi: don't waste CPU polling the event virtqueue
  virtio-scsi: clean up virtio_scsi_handle_event_vq()
  virtio-scsi: clean up virtio_scsi_handle_ctrl_vq()
  virtio-scsi: clean up virtio_scsi_handle_cmd_vq()
  virtio-scsi: move request-related items from .h to .c

 include/hw/virtio/virtio-scsi.h |  43 --
 include/hw/virtio/virtio.h  |   1 +
 hw/scsi/virtio-scsi-dataplane.c |   2 +-
 hw/scsi/virtio-scsi.c   | 101 ++--
 hw/virtio/virtio.c  |  13 
 5 files changed, 86 insertions(+), 74 deletions(-)

-- 
2.35.1




[PATCH 1/6] virtio-scsi: fix ctrl and event handler functions in dataplane mode

2022-04-27 Thread Stefan Hajnoczi
Commit f34e8d8b8d48d73f36a67b6d5e492ef9784b5012 ("virtio-scsi: prepare
virtio_scsi_handle_cmd for dataplane") prepared the virtio-scsi cmd
virtqueue handler function to by used in both the dataplane and
non-datpalane code paths.

It failed to convert the ctrl and event virtqueue handler functions,
which are not designed to be called from the dataplane code path but
will be since the ioeventfd is set up for those virtqueues when
dataplane starts.

Convert the ctrl and event virtqueue handler functions now so they
operate correctly when called from the dataplane code path. Avoid code
duplication by extracting this code into a helper function.

Fixes: f34e8d8b8d48d73f36a67b6d5e492ef9784b5012 ("virtio-scsi: prepare 
virtio_scsi_handle_cmd for dataplane")
Signed-off-by: Stefan Hajnoczi 
---
 hw/scsi/virtio-scsi.c | 42 +++---
 1 file changed, 27 insertions(+), 15 deletions(-)

diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 34a968ecfb..417fbc71d6 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -472,16 +472,32 @@ bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue 
*vq)
 return progress;
 }
 
+/*
+ * If dataplane is configured but not yet started, do so now and return true on
+ * success.
+ *
+ * Dataplane is started by the core virtio code but virtqueue handler functions
+ * can also be invoked when a guest kicks before DRIVER_OK, so this helper
+ * function helps us deal with manually starting ioeventfd in that case.
+ */
+static bool virtio_scsi_defer_to_dataplane(VirtIOSCSI *s)
+{
+if (!s->ctx || s->dataplane_started) {
+return false;
+}
+
+virtio_device_start_ioeventfd(&s->parent_obj.parent_obj);
+return !s->dataplane_fenced;
+}
+
 static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
 {
 VirtIOSCSI *s = (VirtIOSCSI *)vdev;
 
-if (s->ctx) {
-virtio_device_start_ioeventfd(vdev);
-if (!s->dataplane_fenced) {
-return;
-}
+if (virtio_scsi_defer_to_dataplane(s)) {
+return;
 }
+
 virtio_scsi_acquire(s);
 virtio_scsi_handle_ctrl_vq(s, vq);
 virtio_scsi_release(s);
@@ -720,12 +736,10 @@ static void virtio_scsi_handle_cmd(VirtIODevice *vdev, 
VirtQueue *vq)
 /* use non-QOM casts in the data path */
 VirtIOSCSI *s = (VirtIOSCSI *)vdev;
 
-if (s->ctx && !s->dataplane_started) {
-virtio_device_start_ioeventfd(vdev);
-if (!s->dataplane_fenced) {
-return;
-}
+if (virtio_scsi_defer_to_dataplane(s)) {
+return;
 }
+
 virtio_scsi_acquire(s);
 virtio_scsi_handle_cmd_vq(s, vq);
 virtio_scsi_release(s);
@@ -855,12 +869,10 @@ static void virtio_scsi_handle_event(VirtIODevice *vdev, 
VirtQueue *vq)
 {
 VirtIOSCSI *s = VIRTIO_SCSI(vdev);
 
-if (s->ctx) {
-virtio_device_start_ioeventfd(vdev);
-if (!s->dataplane_fenced) {
-return;
-}
+if (virtio_scsi_defer_to_dataplane(s)) {
+return;
 }
+
 virtio_scsi_acquire(s);
 virtio_scsi_handle_event_vq(s, vq);
 virtio_scsi_release(s);
-- 
2.35.1




[PATCH 5/6] virtio-scsi: clean up virtio_scsi_handle_cmd_vq()

2022-04-27 Thread Stefan Hajnoczi
virtio_scsi_handle_cmd_vq() is only called from hw/scsi/virtio-scsi.c
now and its return value is no longer used. Remove the function
prototype from virtio-scsi.h and drop the return value.

Signed-off-by: Stefan Hajnoczi 
---
 include/hw/virtio/virtio-scsi.h | 1 -
 hw/scsi/virtio-scsi.c   | 5 +
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index 44dc3b81ec..2497530064 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -151,7 +151,6 @@ void virtio_scsi_common_realize(DeviceState *dev,
 Error **errp);
 
 void virtio_scsi_common_unrealize(DeviceState *dev);
-bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
 void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
 void virtio_scsi_free_req(VirtIOSCSIReq *req);
 void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index eefda16e4b..12c6a21202 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -685,12 +685,11 @@ static void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI 
*s, VirtIOSCSIReq *req)
 scsi_req_unref(sreq);
 }
 
-bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
+static void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
 {
 VirtIOSCSIReq *req, *next;
 int ret = 0;
 bool suppress_notifications = virtio_queue_get_notification(vq);
-bool progress = false;
 
 QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
 
@@ -700,7 +699,6 @@ bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
 }
 
 while ((req = virtio_scsi_pop_req(s, vq))) {
-progress = true;
 ret = virtio_scsi_handle_cmd_req_prepare(s, req);
 if (!ret) {
 QTAILQ_INSERT_TAIL(&reqs, req, next);
@@ -725,7 +723,6 @@ bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)
 QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {
 virtio_scsi_handle_cmd_req_submit(s, req);
 }
-return progress;
 }
 
 static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
-- 
2.35.1




[PATCH 2/6] virtio-scsi: don't waste CPU polling the event virtqueue

2022-04-27 Thread Stefan Hajnoczi
The virtio-scsi event virtqueue is not emptied by its handler function.
This is typical for rx virtqueues where the device uses buffers when
some event occurs (e.g. a packet is received, an error condition
happens, etc).

Polling non-empty virtqueues wastes CPU cycles. We are not waiting for
new buffers to become available, we are waiting for an event to occur,
so it's a misuse of CPU resources to poll for buffers.

Introduce the new virtio_queue_aio_attach_host_notifier_no_poll() API,
which is identical to virtio_queue_aio_attach_host_notifier() except
that it does not poll the virtqueue.

Before this patch the following command-line consumed 100% CPU in the
IOThread polling and calling virtio_scsi_handle_event():

  $ qemu-system-x86_64 -M accel=kvm -m 1G -cpu host \
  --object iothread,id=iothread0 \
  --device virtio-scsi-pci,iothread=iothread0 \
  --blockdev 
file,filename=test.img,aio=native,cache.direct=on,node-name=drive0 \
  --device scsi-hd,drive=drive0

After this patch CPU is no longer wasted.

Reported-by: Nir Soffer 
Signed-off-by: Stefan Hajnoczi 
---
 include/hw/virtio/virtio.h  |  1 +
 hw/scsi/virtio-scsi-dataplane.c |  2 +-
 hw/virtio/virtio.c  | 13 +
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b31c4507f5..b62a35fdca 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -317,6 +317,7 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue 
*vq);
 void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
 void virtio_queue_host_notifier_read(EventNotifier *n);
 void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx);
+void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext 
*ctx);
 void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx);
 VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector);
 VirtQueue *virtio_vector_next_queue(VirtQueue *vq);
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 29575cbaf6..8bb6e6acfc 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -138,7 +138,7 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
 
 aio_context_acquire(s->ctx);
 virtio_queue_aio_attach_host_notifier(vs->ctrl_vq, s->ctx);
-virtio_queue_aio_attach_host_notifier(vs->event_vq, s->ctx);
+virtio_queue_aio_attach_host_notifier_no_poll(vs->event_vq, s->ctx);
 
 for (i = 0; i < vs->conf.num_queues; i++) {
 virtio_queue_aio_attach_host_notifier(vs->cmd_vqs[i], s->ctx);
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 9d637e043e..67a873f54a 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3534,6 +3534,19 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue 
*vq, AioContext *ctx)
 virtio_queue_host_notifier_aio_poll_end);
 }
 
+/*
+ * Same as virtio_queue_aio_attach_host_notifier() but without polling. Use
+ * this for rx virtqueues and similar cases where the virtqueue handler
+ * function does not pop all elements. When the virtqueue is left non-empty
+ * polling consumes CPU cycles and should not be used.
+ */
+void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext 
*ctx)
+{
+aio_set_event_notifier(ctx, &vq->host_notifier, true,
+   virtio_queue_host_notifier_read,
+   NULL, NULL);
+}
+
 void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx)
 {
 aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL, NULL, NULL);
-- 
2.35.1




[PATCH 3/6] virtio-scsi: clean up virtio_scsi_handle_event_vq()

2022-04-27 Thread Stefan Hajnoczi
virtio_scsi_handle_event_vq() is only called from hw/scsi/virtio-scsi.c
now and its return value is no longer used. Remove the function
prototype from virtio-scsi.h and drop the return value.

Signed-off-by: Stefan Hajnoczi 
---
 include/hw/virtio/virtio-scsi.h | 1 -
 hw/scsi/virtio-scsi.c   | 4 +---
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index 543681bc18..5957597825 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -151,7 +151,6 @@ void virtio_scsi_common_realize(DeviceState *dev,
 Error **errp);
 
 void virtio_scsi_common_unrealize(DeviceState *dev);
-bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq);
 bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
 bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq);
 void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 417fbc71d6..aa03a713d8 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -856,13 +856,11 @@ void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice 
*dev,
 virtio_scsi_complete_req(req);
 }
 
-bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq)
+static void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq)
 {
 if (s->events_dropped) {
 virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
-return true;
 }
-return false;
 }
 
 static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
-- 
2.35.1




[PATCH 6/6] virtio-scsi: move request-related items from .h to .c

2022-04-27 Thread Stefan Hajnoczi
There is no longer a need to expose the request and related APIs in
virtio-scsi.h since there are no callers outside virtio-scsi.c.

Note the block comment in VirtIOSCSIReq has been adjusted to meet the
coding style.

Signed-off-by: Stefan Hajnoczi 
---
 include/hw/virtio/virtio-scsi.h | 40 -
 hw/scsi/virtio-scsi.c   | 45 ++---
 2 files changed, 41 insertions(+), 44 deletions(-)

diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index 2497530064..abdda2cbd0 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -94,42 +94,6 @@ struct VirtIOSCSI {
 uint32_t host_features;
 };
 
-typedef struct VirtIOSCSIReq {
-/* Note:
- * - fields up to resp_iov are initialized by virtio_scsi_init_req;
- * - fields starting at vring are zeroed by virtio_scsi_init_req.
- * */
-VirtQueueElement elem;
-
-VirtIOSCSI *dev;
-VirtQueue *vq;
-QEMUSGList qsgl;
-QEMUIOVector resp_iov;
-
-union {
-/* Used for two-stage request submission */
-QTAILQ_ENTRY(VirtIOSCSIReq) next;
-
-/* Used for cancellation of request during TMFs */
-int remaining;
-};
-
-SCSIRequest *sreq;
-size_t resp_size;
-enum SCSIXferMode mode;
-union {
-VirtIOSCSICmdResp cmd;
-VirtIOSCSICtrlTMFResp tmf;
-VirtIOSCSICtrlANResp  an;
-VirtIOSCSIEvent   event;
-} resp;
-union {
-VirtIOSCSICmdReq  cmd;
-VirtIOSCSICtrlTMFReq  tmf;
-VirtIOSCSICtrlANReq   an;
-} req;
-} VirtIOSCSIReq;
-
 static inline void virtio_scsi_acquire(VirtIOSCSI *s)
 {
 if (s->ctx) {
@@ -151,10 +115,6 @@ void virtio_scsi_common_realize(DeviceState *dev,
 Error **errp);
 
 void virtio_scsi_common_unrealize(DeviceState *dev);
-void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
-void virtio_scsi_free_req(VirtIOSCSIReq *req);
-void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
-uint32_t event, uint32_t reason);
 
 void virtio_scsi_dataplane_setup(VirtIOSCSI *s, Error **errp);
 int virtio_scsi_dataplane_start(VirtIODevice *s);
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 12c6a21202..db54d104be 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -29,6 +29,43 @@
 #include "hw/virtio/virtio-access.h"
 #include "trace.h"
 
+typedef struct VirtIOSCSIReq {
+/*
+ * Note:
+ * - fields up to resp_iov are initialized by virtio_scsi_init_req;
+ * - fields starting at vring are zeroed by virtio_scsi_init_req.
+ */
+VirtQueueElement elem;
+
+VirtIOSCSI *dev;
+VirtQueue *vq;
+QEMUSGList qsgl;
+QEMUIOVector resp_iov;
+
+union {
+/* Used for two-stage request submission */
+QTAILQ_ENTRY(VirtIOSCSIReq) next;
+
+/* Used for cancellation of request during TMFs */
+int remaining;
+};
+
+SCSIRequest *sreq;
+size_t resp_size;
+enum SCSIXferMode mode;
+union {
+VirtIOSCSICmdResp cmd;
+VirtIOSCSICtrlTMFResp tmf;
+VirtIOSCSICtrlANResp  an;
+VirtIOSCSIEvent   event;
+} resp;
+union {
+VirtIOSCSICmdReq  cmd;
+VirtIOSCSICtrlTMFReq  tmf;
+VirtIOSCSICtrlANReq   an;
+} req;
+} VirtIOSCSIReq;
+
 static inline int virtio_scsi_get_lun(uint8_t *lun)
 {
 return ((lun[2] << 8) | lun[3]) & 0x3FFF;
@@ -45,7 +82,7 @@ static inline SCSIDevice *virtio_scsi_device_get(VirtIOSCSI 
*s, uint8_t *lun)
 return scsi_device_get(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun));
 }
 
-void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req)
+static void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq 
*req)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(s);
 const size_t zero_skip =
@@ -58,7 +95,7 @@ void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, 
VirtIOSCSIReq *req)
 memset((uint8_t *)req + zero_skip, 0, sizeof(*req) - zero_skip);
 }
 
-void virtio_scsi_free_req(VirtIOSCSIReq *req)
+static void virtio_scsi_free_req(VirtIOSCSIReq *req)
 {
 qemu_iovec_destroy(&req->resp_iov);
 qemu_sglist_destroy(&req->qsgl);
@@ -801,8 +838,8 @@ static void virtio_scsi_reset(VirtIODevice *vdev)
 s->events_dropped = false;
 }
 
-void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
-uint32_t event, uint32_t reason)
+static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
+   uint32_t event, uint32_t reason)
 {
 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
 VirtIOSCSIReq *req;
-- 
2.35.1




[PATCH 4/6] virtio-scsi: clean up virtio_scsi_handle_ctrl_vq()

2022-04-27 Thread Stefan Hajnoczi
virtio_scsi_handle_ctrl_vq() is only called from hw/scsi/virtio-scsi.c
now and its return value is no longer used. Remove the function
prototype from virtio-scsi.h and drop the return value.

Signed-off-by: Stefan Hajnoczi 
---
 include/hw/virtio/virtio-scsi.h | 1 -
 hw/scsi/virtio-scsi.c   | 5 +
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index 5957597825..44dc3b81ec 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -152,7 +152,6 @@ void virtio_scsi_common_realize(DeviceState *dev,
 
 void virtio_scsi_common_unrealize(DeviceState *dev);
 bool virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq);
-bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq);
 void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req);
 void virtio_scsi_free_req(VirtIOSCSIReq *req);
 void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index aa03a713d8..eefda16e4b 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -460,16 +460,13 @@ static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, 
VirtIOSCSIReq *req)
 }
 }
 
-bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)
+static void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)
 {
 VirtIOSCSIReq *req;
-bool progress = false;
 
 while ((req = virtio_scsi_pop_req(s, vq))) {
-progress = true;
 virtio_scsi_handle_ctrl_req(s, req);
 }
-return progress;
 }
 
 /*
-- 
2.35.1




Re: [RESEND][PATCH 0/2] acpi/nvdimm: support NVDIMM _LS{I,R,W} methods

2022-04-27 Thread Igor Mammedov
On Tue, 12 Apr 2022 14:57:51 +0800
Robert Hoo  wrote:

> The original NVDIMM _DSM functions (index 4~6) for label operations have
> been deprecated by new ACPI methods _LS{I,R,W}[1][2].
> 
> Patch 1 implements the new _LS{I,R,W} methods, on top of old _DSM
> implementation.
> 
> Patch 2 fixes some typo of logical and/or with bitwise and/or, though
> functionally they haven't causing trouble.

generic requirement for ACPI patches,
the should pass bios-tables-test (part of 'make check')

for that you need to update testcase expected data,
see tests/qtest/bios-tables-test.c for the process
also see https://www.mail-archive.com/qemu-devel@nongnu.org/msg875304.html for 
example

> 
> [1] https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/index.html, 6.5.10 NVDIMM 
> Label Methods
> [2] https://pmem.io/documents/IntelOptanePMem_DSM_Interface-V2.0.pdf, 3.10 
> Deprecated Functions
> 
> ---
> Resend for previous failed delivery to "qemu-devel@nongnu.org" due to
> 550-'Message headers fail syntax check'. 
> 
> Robert Hoo (2):
>   acpi/nvdimm: Create _LS{I,R,W} method for NVDIMM device
>   acpi/nvdimm: Fix aml_or() and aml_and() in if clause
> 
>  hw/acpi/nvdimm.c | 60 +++-
>  1 file changed, 54 insertions(+), 6 deletions(-)
> 
> 
> base-commit: 95a3fcc7487e5bef262e1f937ed8636986764c4e




[PATCH qemu v10 03/14] target/riscv: rvv: Early exit when vstart >= vl

2022-04-27 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 
---
 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 275fded6e4..57953923d5 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();
@@ -1216,6 +1220,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),
@@ -1263,6 +1268,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();
@@ -1427,6 +1433,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();
@@ -1513,6 +1520,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);
@@ -1593,6 +1601,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);
@@ -1670,6 +1679,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); \
@@ -1851,6 +1861,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); \
@@ -2061,6 +2072,7 @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)

[PATCH qemu v10 00/14] Add tail agnostic behavior for rvv instructions

2022-04-27 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

eopXD (14):
  target/riscv: rvv: Prune redundant ESZ, DSZ 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/cpu.c  |1 +
 target/riscv/cpu.h  |2 +
 target/riscv/cpu_helper.c   |2 +
 target/riscv/insn_trans/trans_rvv.c.inc |  176 +++
 target/riscv/internals.h|6 +-
 target/riscv/translate.c|4 +
 target/riscv/vector_helper.c| 1536 ++-
 7 files changed, 1110 insertions(+), 617 deletions(-)

-- 
2.34.2



[PATCH qemu v10 08/14] target/riscv: rvv: Add tail agnostic for vector integer comparison instructions

2022-04-27 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 
---
 target/riscv/vector_helper.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 8755671449..6356b6b0ef 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1345,6 +1345,10 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, 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_all_1s = vext_vta_all_1s(desc);  \
 uint32_t i;   \
   \
 for (i = env->vstart; i < vl; i++) {  \
@@ -1356,6 +1360,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)
@@ -1394,6 +1405,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_all_1s = vext_vta_all_1s(desc);\
 uint32_t i; \
 \
 for (i = env->vstart; i < vl; i++) {\
@@ -1405,6 +1419,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 v10 06/14] target/riscv: rvv: Add tail agnostic for vx, vvm, vxm instructions

2022-04-27 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 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  29 +++
 target/riscv/internals.h|   5 +-
 target/riscv/vector_helper.c| 317 +---
 3 files changed, 211 insertions(+), 140 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 99691f1b9f..d15858fc6f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1299,6 +1299,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));
 
@@ -1335,6 +1337,16 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn 
*gvec_fn,
 }
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 TCGv_i64 src1 = tcg_temp_new_i64();
 
 tcg_gen_ext_tl_i64(src1, get_gpr(s, a->rs1, EXT_SIGN));
@@ -1464,6 +1476,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));
 
@@ -1493,6 +1507,16 @@ do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn 
*gvec_fn,
 }
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 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);
@@ -1546,6 +1570,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),
@@ -1627,6 +1652,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),
@@ -1705,6 +1731,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 d186bf9512..4ecdf955f3 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/

[PATCH qemu v10 02/14] target/riscv: rvv: Rename ambiguous esz

2022-04-27 Thread ~eopxd
From: eopXD 

No functional change intended in this commit.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
---
 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 e94caf1a3c..d0452a7756 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, MMUAccessType access_type)
+ uint32_t log2_esz, uintptr_t ra, MMUAccessType access_type)
 {
 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, MMUAccessType access_type)
 {
 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, MMUAccessType access_type)
+uint32_t log2_esz, uintptr_t ra, MMUAccessType access_type)
 {
 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));
+  

[PATCH qemu v10 04/14] target/riscv: rvv: Add tail agnostic for vv instructions

2022-04-27 Thread ~eopxd
From: eopXD 

This is the first commit regarding the tail agnostic behavior.
Added option 'rvv_ta_all_1s' to enable the behavior, the option
is default to false.

Signed-off-by: eop Chen 
Reviewed-by: Frank Chang 
---
 target/riscv/cpu.c  |   1 +
 target/riscv/cpu.h  |   2 +
 target/riscv/cpu_helper.c   |   2 +
 target/riscv/insn_trans/trans_rvv.c.inc |  11 +
 target/riscv/internals.h|   5 +-
 target/riscv/translate.c|   2 +
 target/riscv/vector_helper.c| 296 +---
 7 files changed, 188 insertions(+), 131 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ddda4906ff..cd4cf4b41e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -810,6 +810,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(),
 };
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c069fe85fa..8c4a79b5a0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -369,6 +369,7 @@ struct RISCVCPUConfig {
 bool ext_zhinxmin;
 bool ext_zve32f;
 bool ext_zve64f;
+bool rvv_ta_all_1s;
 
 /* Vendor-specific custom extensions */
 bool ext_XVentanaCondOps;
@@ -516,6 +517,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 1c60fb2e80..2941c88c31 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 57953923d5..cc80bf00ff 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1223,6 +1223,16 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 gvec_fn(s->sew, vreg_ofs(s, a->rd),
 vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1),
 MAXSZ(s), MAXSZ(s));
@@ -1231,6 +1241,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 fac998a6b5..7775dade26 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;
@@ -1083,6 +1084,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_f

[PATCH qemu v10 07/14] target/riscv: rvv: Add tail agnostic for vector integer shift instructions

2022-04-27 Thread ~eopxd
From: eopXD 

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

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index d15858fc6f..430847b0f9 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1858,6 +1858,16 @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, 
GVecGen2sFn32 *gvec_fn,
 }
 
 if (a->vm && s->vl_eq_vlmax) {
+if (s->vta && s->lmul < 0) {
+/*
+ * tail elements may pass vlmax when lmul < 0
+ * set tail elements to 1s
+ */
+uint32_t vlenb = s->cfg_ptr->vlen >> 3;
+tcg_gen_gvec_ori(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rd), -1,
+ vlenb, vlenb);
+}
 TCGv_i32 src1 = tcg_temp_new_i32();
 
 tcg_gen_trunc_tl_i32(src1, get_gpr(s, a->rs1, EXT_NONE));
@@ -1916,6 +1926,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 4ecdf955f3..8755671449 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1245,6 +1245,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++) {  \
@@ -1256,6 +1259,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)
@@ -1280,6 +1285,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++) {\
@@ -1290,6 +1299,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 v10 05/14] target/riscv: rvv: Add tail agnostic for vector load / store instructions

2022-04-27 Thread ~eopxd
From: eopXD 

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

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

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index cc80bf00ff..99691f1b9f 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);
 }
 
@@ -748,6 +749,7 @@ static bool st_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, true);
 }
 
@@ -774,6 +776,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);
 }
 
@@ -791,6 +795,8 @@ static bool st_us_mask_op(DisasContext *s, arg_vsm_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, true);
 }
 
@@ -862,6 +868,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);
 }
 
@@ -891,6 +898,7 @@ static bool st_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);
 fn = fns[eew];
 if (fn == NULL) {
 return false;
@@ -991,6 +999,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);
 }
 
@@ -1043,6 +1052,7 @@ static bool st_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, true);
 }
 
@@ -1108,6 +1118,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 7775dade26..58cbb6ded3 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;
@@ -1085,6 +1086,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 396e252179..d186bf9512 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -270,6 +270,8 @@ vext_ldst_stride(void *vd, 

  1   2   3   >