[PATCH v2 04/12] block: Split BlockNodeInfo off of ImageInfo

2022-06-20 Thread Hanna Reitz
ImageInfo sometimes contains flat information, and sometimes it does
not.  Split off a BlockNodeInfo struct, which only contains information
about a single node and has no link to the backing image.

We do this so we can extend BlockNodeInfo to a BlockGraphInfo struct,
which has links to all child nodes, not just the backing node.  It would
be strange to base BlockGraphInfo on ImageInfo, because then this
extended struct would have two links to the backing node (one in
BlockGraphInfo as one of all the child links, and one in ImageInfo).

Furthermore, it is quite common to ignore the backing-image field
altogether: bdrv_query_image_info() does not set it, and
bdrv_image_info_dump() does not evaluate it.  That signals that we
should have different structs for describing a single node and one that
has a link to the backing image.

Still, bdrv_query_image_info() and bdrv_image_info_dump() are not
changed too much in this patch.  Follow-up patches will handle them.

Signed-off-by: Hanna Reitz 
---
I hope this is not an incompatible change, but I'm not sure, I have to
admit.
---
 qapi/block-core.json | 22 +---
 include/block/qapi.h |  3 ++
 block/qapi.c | 86 
 3 files changed, 84 insertions(+), 27 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index e0c8f07932..8c06deacdf 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -251,7 +251,7 @@
   } }
 
 ##
-# @ImageInfo:
+# @BlockNodeInfo:
 #
 # Information about a QEMU image file
 #
@@ -279,22 +279,34 @@
 #
 # @snapshots: list of VM snapshots
 #
-# @backing-image: info of the backing image (since 1.6)
-#
 # @format-specific: structure supplying additional format-specific
 #   information (since 1.7)
 #
 # Since: 1.3
 ##
-{ 'struct': 'ImageInfo',
+{ 'struct': 'BlockNodeInfo',
   'data': {'filename': 'str', 'format': 'str', '*dirty-flag': 'bool',
'*actual-size': 'int', 'virtual-size': 'int',
'*cluster-size': 'int', '*encrypted': 'bool', '*compressed': 'bool',
'*backing-filename': 'str', '*full-backing-filename': 'str',
'*backing-filename-format': 'str', '*snapshots': ['SnapshotInfo'],
-   '*backing-image': 'ImageInfo',
'*format-specific': 'ImageInfoSpecific' } }
 
+##
+# @ImageInfo:
+#
+# Information about a QEMU image file, and potentially its backing image
+#
+# @backing-image: info of the backing image
+#
+# Since: 7.1
+##
+{ 'struct': 'ImageInfo',
+  'base': 'BlockNodeInfo',
+  'data': {
+  '*backing-image': 'ImageInfo'
+  } }
+
 ##
 # @ImageCheck:
 #
diff --git a/include/block/qapi.h b/include/block/qapi.h
index c09859ea78..c7de4e3fa9 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -35,6 +35,9 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
 int bdrv_query_snapshot_info_list(BlockDriverState *bs,
   SnapshotInfoList **p_list,
   Error **errp);
+void bdrv_query_block_node_info(BlockDriverState *bs,
+BlockNodeInfo **p_info,
+Error **errp);
 void bdrv_query_image_info(BlockDriverState *bs,
ImageInfo **p_info,
Error **errp);
diff --git a/block/qapi.c b/block/qapi.c
index 51202b470a..e5022b4481 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -241,30 +241,18 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs,
 }
 
 /**
- * bdrv_query_image_info:
- * @bs: block device to examine
- * @p_info: location to store image information
- * @errp: location to store error information
- *
- * Store "flat" image information in @p_info.
- *
- * "Flat" means it does *not* query backing image information,
- * i.e. (*pinfo)->has_backing_image will be set to false and
- * (*pinfo)->backing_image to NULL even when the image does in fact have
- * a backing image.
- *
- * @p_info will be set only on success. On error, store error in @errp.
+ * Helper function for other query info functions.  Store information about @bs
+ * in @info, setting @errp on error.
  */
-void bdrv_query_image_info(BlockDriverState *bs,
-   ImageInfo **p_info,
-   Error **errp)
+static void bdrv_do_query_node_info(BlockDriverState *bs,
+BlockNodeInfo *info,
+Error **errp)
 {
 int64_t size;
 const char *backing_filename;
 BlockDriverInfo bdi;
 int ret;
 Error *err = NULL;
-ImageInfo *info;
 
 aio_context_acquire(bdrv_get_aio_context(bs));
 
@@ -277,7 +265,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
 
 bdrv_refresh_filename(bs);
 
-info = g_new0(ImageInfo, 1);
 info->filename= g_strdup(bs->filename);
 info->format  = g_strdup(bdrv_get_format_name(bs));
 info->virtual_size= size;
@@ -298,7 +285,6 @@ void 

Re: Building tools on unsupported cpu/arch

2022-06-20 Thread Thomas Huth

On 20/06/2022 12.54, Michael Tokarev wrote:

20.06.2022 13:31, Thomas Huth write:

On 30/04/2022 16.11, Michael Tokarev wrote:

Hello!

Previously, it was possible to build qemu tools (such as qemu-img, or 
qemu-ga)

on an unsupported cpu/architecture.  In a hackish way, by specifying
--enable-tcg-interpreter on the ./configure line.

Today (with 7.0), it does not work anymore, with the following error
during configure:

  common-user/meson.build:1:0: ERROR: Include dir host/unknown does not 
exist.


Did you ever send a patch for this? I something like this should do the job:

diff a/common-user/meson.build b/common-user/meson.build
--- a/common-user/meson.build
+++ b/common-user/meson.build
@@ -1,3 +1,7 @@
+if not have_user
+   subdir_done()
+endif
+


https://salsa.debian.org/qemu-team/qemu/-/blob/master/debian/patches/common-user-no-user.patch 



I dunno which one is right - "have_user" or "have_linux_user & have_bsd_user".


Both should be fine - have_user is just a shortcut:

$ grep have_user meson.build
have_user = have_linux_user or have_bsd_user
...

Could you send it as a proper patch? (otherwise I could assemble a patch, 
too, if you prefer that)


 Thanks,
  Thomas




[PATCH v3 3/4] target/mips: implement Octeon-specific arithmetic instructions

2022-06-20 Thread Pavel Dovgalyuk
This patch implements several Octeon-specific instructions:
- BADDU
- DMUL
- EXTS/EXTS32
- CINS/CINS32
- POP/DPOP
- SEQ/SEQI
- SNE/SNEI

Signed-off-by: Pavel Dovgalyuk 

--

v3 changes:
   - Fixed length field for EXTS/CINS
 (bug found by Richard Henderson)
v2 changes:
   - Using existing tcg instructions for exts, cins, pop
 (suggested by Richard Henderson)
---
 target/mips/tcg/octeon.decode  |   26 ++
 target/mips/tcg/octeon_translate.c |  155 
 2 files changed, 181 insertions(+)

diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
index 8062715578..8929ad088e 100644
--- a/target/mips/tcg/octeon.decode
+++ b/target/mips/tcg/octeon.decode
@@ -13,3 +13,29 @@
 
 %bbit_p  28:1 16:5
 BBIT 11 set:1 . 10 rs:5 . offset:16 p=%bbit_p
+
+# Arithmetic
+# BADDU rd, rs, rt
+# DMUL rd, rs, rt
+# EXTS rt, rs, p, lenm1
+# EXTS32 rt, rs, p, lenm1
+# CINS rt, rs, p, lenm1
+# CINS32 rt, rs, p, lenm1
+# DPOP rd, rs
+# POP rd, rs
+# SEQ rd, rs, rt
+# SEQI rt, rs, immediate
+# SNE rd, rs, rt
+# SNEI rt, rs, immediate
+
+@r3  .. rs:5 rt:5 rd:5 . ..
+%bitfield_p  0:1 6:5
+@bitfield.. rs:5 rt:5 lenm1:5 . . . p=%bitfield_p
+
+BADDU011100 . . . 0 101000 @r3
+DMUL 011100 . . . 0 11 @r3
+EXTS 011100 . . . . 11101 . @bitfield
+CINS 011100 . . . . 11001 . @bitfield
+POP  011100 rs:5 0 rd:5 0 10110 dw:1
+SEQNE011100 rs:5 rt:5 rd:5 0 10101 ne:1
+SEQNEI   011100 rs:5 rt:5 imm:s10 10111 ne:1
diff --git a/target/mips/tcg/octeon_translate.c 
b/target/mips/tcg/octeon_translate.c
index 1558f74a8e..6a207d2e7e 100644
--- a/target/mips/tcg/octeon_translate.c
+++ b/target/mips/tcg/octeon_translate.c
@@ -44,3 +44,158 @@ static bool trans_BBIT(DisasContext *ctx, arg_BBIT *a)
 tcg_temp_free(t0);
 return true;
 }
+
+static bool trans_BADDU(DisasContext *ctx, arg_BADDU *a)
+{
+TCGv t0, t1;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+gen_load_gpr(t1, a->rt);
+
+tcg_gen_add_tl(t0, t0, t1);
+tcg_gen_andi_i64(cpu_gpr[a->rd], t0, 0xff);
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+
+return true;
+}
+
+static bool trans_DMUL(DisasContext *ctx, arg_DMUL *a)
+{
+TCGv t0, t1;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+gen_load_gpr(t1, a->rt);
+
+tcg_gen_mul_i64(cpu_gpr[a->rd], t0, t1);
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+
+return true;
+}
+
+static bool trans_EXTS(DisasContext *ctx, arg_EXTS *a)
+{
+TCGv t0;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+tcg_gen_sextract_tl(t0, t0, a->p, a->lenm1 + 1);
+gen_store_gpr(t0, a->rt);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool trans_CINS(DisasContext *ctx, arg_CINS *a)
+{
+TCGv t0;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+tcg_gen_deposit_z_tl(t0, t0, a->p, a->lenm1 + 1);
+gen_store_gpr(t0, a->rt);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool trans_POP(DisasContext *ctx, arg_POP *a)
+{
+TCGv t0;
+
+if (a->rd == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+gen_load_gpr(t0, a->rs);
+if (!a->dw) {
+tcg_gen_andi_i64(t0, t0, 0x);
+}
+tcg_gen_ctpop_tl(t0, t0);
+gen_store_gpr(t0, a->rd);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool trans_SEQNE(DisasContext *ctx, arg_SEQNE *a)
+{
+TCGv t0, t1;
+
+if (a->rd == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+
+gen_load_gpr(t0, a->rs);
+gen_load_gpr(t1, a->rt);
+
+if (a->ne) {
+tcg_gen_setcond_tl(TCG_COND_NE, cpu_gpr[a->rd], t1, t0);
+} else {
+tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr[a->rd], t1, t0);
+}
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+
+return true;
+}
+
+static bool trans_SEQNEI(DisasContext *ctx, arg_SEQNEI *a)
+{
+TCGv t0;
+
+if (a->rt == 0) {
+/* nop */
+return true;
+}
+
+t0 = tcg_temp_new();
+
+gen_load_gpr(t0, a->rs);
+
+/* Sign-extend to 64 bit value */
+target_ulong imm = a->imm;
+if (a->ne) {
+tcg_gen_setcondi_tl(TCG_COND_NE, cpu_gpr[a->rt], t0, imm);
+} else {
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr[a->rt], t0, imm);
+}
+
+tcg_temp_free(t0);
+
+return true;
+}




Re: [PATCH 1/4] qdev: add DEVICE_RUNTIME_ERROR event

2022-06-20 Thread Roman Kagan
On Mon, May 30, 2022 at 06:04:32PM +0300, Roman Kagan wrote:
> On Mon, May 30, 2022 at 01:28:17PM +0200, Markus Armbruster wrote:
> > Roman Kagan  writes:
> > 
> > > On Wed, May 25, 2022 at 12:54:47PM +0200, Markus Armbruster wrote:
> > >> Konstantin Khlebnikov  writes:
> > >> 
> > >> > This event represents device runtime errors to give time and
> > >> > reason why device is broken.
> > >> 
> > >> Can you give an or more examples of the "device runtime errors" you have
> > >> in mind?
> > >
> > > Initially we wanted to address a situation when a vhost device
> > > discovered an inconsistency during virtqueue processing and silently
> > > stopped the virtqueue.  This resulted in device stall (partial for
> > > multiqueue devices) and we were the last to notice that.
> > >
> > > The solution appeared to be to employ errfd and, upon receiving a
> > > notification through it, to emit a QMP event which is actionable in the
> > > management layer or further up the stack.
> > >
> > > Then we observed that virtio (non-vhost) devices suffer from the same
> > > issue: they only log the error but don't signal it to the management
> > > layer.  The case was very similar so we thought it would make sense to
> > > share the infrastructure and the QMP event between virtio and vhost.
> > >
> > > Then Konstantin went a bit further and generalized the concept into
> > > generic "device runtime error".  I'm personally not completely convinced
> > > this generalization is appropriate here; we'd appreciate the opinions
> > > from the community on the matter.
> > 
> > "Device emulation sending an even on entering certain error states, so
> > that a management application can do something about it" feels
> > reasonable enough to me as a general concept.
> > 
> > The key point is of course "can do something": the event needs to be
> > actionable.  Can you describe possible actions for the cases you
> > implement?
> 
> The first one that we had in mind was informational, like triggering an
> alert in the monitoring system and/or painting the VM as malfunctioning
> in the owner's UI.
> 
> There can be more advanced scenarios like autorecovery by resetting the
> faulty VM, or fencing it if it's a cluster member.

The discussion kind of stalled here.  Do you think the approach makes
sense or not?  Should we try and resubmit the series with a proper cover
letter and possibly other improvements or is it a dead end?

Thanks,
Roman.



[PATCH v8 03/12] s390x/cpu_topology: implementating Store Topology System Information

2022-06-20 Thread Pierre Morel
The handling of STSI is enhanced with the interception of the
function code 15 for storing CPU topology.

Using the objects built during the plugging of CPU, we build the
SYSIB 15_1_x structures.

With this patch the maximum MNEST level is 2, this is also
the only level allowed and only SYSIB 15_1_2 will be built.

Signed-off-by: Pierre Morel 
---
 target/s390x/cpu.h  |   2 +
 target/s390x/cpu_topology.c | 112 
 target/s390x/kvm/kvm.c  |   5 ++
 target/s390x/meson.build|   1 +
 4 files changed, 120 insertions(+)
 create mode 100644 target/s390x/cpu_topology.c

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 216adfde26..9d48087b71 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -890,4 +890,6 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
 
 #include "exec/cpu-all.h"
 
+void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar);
+
 #endif
diff --git a/target/s390x/cpu_topology.c b/target/s390x/cpu_topology.c
new file mode 100644
index 00..9f656d7e51
--- /dev/null
+++ b/target/s390x/cpu_topology.c
@@ -0,0 +1,112 @@
+/*
+ * QEMU S390x CPU Topology
+ *
+ * Copyright IBM Corp. 2022
+ * Author(s): Pierre Morel 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/s390x/pv.h"
+#include "hw/sysbus.h"
+#include "hw/s390x/cpu-topology.h"
+
+static int stsi_15_container(void *p, int nl, int id)
+{
+SysIBTl_container *tle = (SysIBTl_container *)p;
+
+tle->nl = nl;
+tle->id = id;
+
+return sizeof(*tle);
+}
+
+static int stsi_15_cpus(void *p, S390TopologyCores *cd)
+{
+SysIBTl_cpu *tle = (SysIBTl_cpu *)p;
+
+tle->nl = 0;
+tle->dedicated = cd->dedicated;
+tle->polarity = cd->polarity;
+tle->type = cd->cputype;
+tle->origin = be16_to_cpu(cd->origin);
+tle->mask = be64_to_cpu(cd->mask);
+
+return sizeof(*tle);
+}
+
+static int set_socket(const MachineState *ms, void *p,
+  S390TopologySocket *socket)
+{
+BusChild *kid;
+int l, len = 0;
+
+len += stsi_15_container(p, 1, socket->socket_id);
+p += len;
+
+QTAILQ_FOREACH_REVERSE(kid, >bus->children, sibling) {
+l = stsi_15_cpus(p, S390_TOPOLOGY_CORES(kid->child));
+p += l;
+len += l;
+}
+return len;
+}
+
+static void setup_stsi(const MachineState *ms, void *p, int level)
+{
+S390TopologyBook *book;
+SysIB_151x *sysib;
+BusChild *kid;
+int len, l;
+
+sysib = (SysIB_151x *)p;
+sysib->mnest = level;
+sysib->mag[TOPOLOGY_NR_MAG2] = ms->smp.sockets;
+sysib->mag[TOPOLOGY_NR_MAG1] = ms->smp.cores * ms->smp.threads;
+
+book = s390_get_topology();
+len = sizeof(SysIB_151x);
+p += len;
+
+QTAILQ_FOREACH_REVERSE(kid, >bus->children, sibling) {
+l = set_socket(ms, p, S390_TOPOLOGY_SOCKET(kid->child));
+p += l;
+len += l;
+}
+
+sysib->length = be16_to_cpu(len);
+}
+
+void insert_stsi_15_1_x(S390CPU *cpu, int sel2, __u64 addr, uint8_t ar)
+{
+const MachineState *machine = MACHINE(qdev_get_machine());
+void *p;
+int ret;
+
+/*
+ * Until the SCLP STSI Facility reporting the MNEST value is used,
+ * a sel2 value of 2 is the only value allowed in STSI 15.1.x.
+ */
+if (sel2 != 2) {
+setcc(cpu, 3);
+return;
+}
+
+p = g_malloc0(TARGET_PAGE_SIZE);
+
+setup_stsi(machine, p, 2);
+
+if (s390_is_pv()) {
+ret = s390_cpu_pv_mem_write(cpu, 0, p, TARGET_PAGE_SIZE);
+} else {
+ret = s390_cpu_virt_mem_write(cpu, addr, ar, p, TARGET_PAGE_SIZE);
+}
+
+setcc(cpu, ret ? 3 : 0);
+g_free(p);
+}
+
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index 7bd8db0e7b..563bf5ac60 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -51,6 +51,7 @@
 #include "hw/s390x/s390-virtio-ccw.h"
 #include "hw/s390x/s390-virtio-hcall.h"
 #include "hw/s390x/pv.h"
+#include "hw/s390x/cpu-topology.h"
 
 #ifndef DEBUG_KVM
 #define DEBUG_KVM  0
@@ -1918,6 +1919,10 @@ static int handle_stsi(S390CPU *cpu)
 /* Only sysib 3.2.2 needs post-handling for now. */
 insert_stsi_3_2_2(cpu, run->s390_stsi.addr, run->s390_stsi.ar);
 return 0;
+case 15:
+insert_stsi_15_1_x(cpu, run->s390_stsi.sel2, run->s390_stsi.addr,
+   run->s390_stsi.ar);
+return 0;
 default:
 return 0;
 }
diff --git a/target/s390x/meson.build b/target/s390x/meson.build
index 84c1402a6a..890ccfa789 100644
--- a/target/s390x/meson.build
+++ b/target/s390x/meson.build
@@ -29,6 +29,7 @@ s390x_softmmu_ss.add(files(
   'sigp.c',
   'cpu-sysemu.c',
   'cpu_models_sysemu.c',
+  'cpu_topology.c',
 ))
 
 s390x_user_ss = ss.source_set()
-- 
2.31.1




Re: [PATCH] sphinx: change default language to 'en'

2022-06-20 Thread Peter Maydell
On Fri, 17 Jun 2022 at 15:02, Martin Liška  wrote:
>
> Fixes the following Sphinx warning (treated as error) starting
> with 5.0 release:
>
> Warning, treated as error:
> Invalid configuration value found: 'language = None'. Update your 
> configuration to a valid langauge code. Falling back to 'en' (English).

(The typo here ("langauge") is present in the upstream Sphinx error message.)

Reviewed-by: Peter Maydell 

and applied to target-arm.next; thanks.

(I also checked that this didn't break any of the older sphinx
versions we need to continue supporting.)

-- PMM



[PATCH 7/7] target/xtensa: use semihosting_exit_request on semihosted exit syscall

2022-06-20 Thread Luc Michel
Use the new semihosting_exit_request instead of a call to exit when
handling a semihosted exit syscall.

Signed-off-by: Luc Michel 
---
 target/xtensa/xtensa-semi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c
index fa21b7e11f..0e9a9edc16 100644
--- a/target/xtensa/xtensa-semi.c
+++ b/target/xtensa/xtensa-semi.c
@@ -193,11 +193,11 @@ void HELPER(simcall)(CPUXtensaState *env)
 CPUState *cs = env_cpu(env);
 uint32_t *regs = env->regs;
 
 switch (regs[2]) {
 case TARGET_SYS_exit:
-exit(regs[3]);
+semihosting_exit_request(regs[3]);
 break;
 
 case TARGET_SYS_read:
 case TARGET_SYS_write:
 {
-- 
2.17.1




Re: [PATCH v2 12/21] migration: hardcode assumption that QEMUFile is backed with QIOChannel

2022-06-20 Thread Juan Quintela
Daniel P. Berrangé  wrote:
> The only callers of qemu_fopen_ops pass 'true' for the 'has_ioc'
> parameter, so hardcode this assumption in QEMUFile, by passing in
> the QIOChannel object as a non-opaque parameter.
>
> Reviewed-by: Dr. David Alan Gilbert 
> Signed-off-by: Daniel P. Berrangé 

Reviewed-by: Juan Quintela 

nice cleanup




Re: [PATCH v4 2/4] QIOChannelSocket: Fix zero-copy send so socket flush works

2022-06-20 Thread Peter Xu
On Mon, Jun 20, 2022 at 02:39:43AM -0300, Leonardo Bras wrote:
> Somewhere between v6 and v7 the of the zero-copy-send patchset a crucial
> part of the flushing mechanism got missing: incrementing zero_copy_queued.
> 
> Without that, the flushing interface becomes a no-op, and there is no
> guarantee the buffer is really sent.
> 
> This can go as bad as causing a corruption in RAM during migration.
> 
> Fixes: 2bc58ffc2926 ("QIOChannelSocket: Implement io_writev zero copy flag & 
> io_flush for CONFIG_LINUX")
> Reported-by: 徐闯 
> Signed-off-by: Leonardo Bras 
> Reviewed-by: Daniel P. Berrangé 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v2 14/21] migration: remove unused QEMUFileGetFD typedef / qemu_get_fd method

2022-06-20 Thread Juan Quintela
Daniel P. Berrangé  wrote:
> Reviewed-by: Dr. David Alan Gilbert 
> Signed-off-by: Daniel P. Berrangé 

Reviewed-by: Juan Quintela 




Re: [PATCH v4 4/4] migration: Change zero_copy_send from migration parameter to migration capability

2022-06-20 Thread Peter Xu
On Mon, Jun 20, 2022 at 02:39:45AM -0300, Leonardo Bras wrote:
> When originally implemented, zero_copy_send was designed as a Migration
> paramenter.
> 
> But taking into account how is that supposed to work, and how
> the difference between a capability and a parameter, it only makes sense
> that zero-copy-send would work better as a capability.
> 
> Taking into account how recently the change got merged, it was decided
> that it's still time to make it right, and convert zero_copy_send into
> a Migration capability.
> 
> Signed-off-by: Leonardo Bras 

I assume this is a request from Libvirt? We don't have a release yet so
yeah probably we still have time..

Acked-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v4 3/4] migration: zero-copy flush only at the end of bitmap scanning

2022-06-20 Thread Peter Xu
On Mon, Jun 20, 2022 at 11:23:53AM +0200, Juan Quintela wrote:
> Once discussed this, what I asked in the past is that you are having too
> much dirty memory on zero_copy.  When you have a Multiterabyte guest, in
> a single round you have a "potentially" dirty memory on each channel of:
> 
>total_amount_memory / number of channels.
> 
> In a Multiterabyte guest, this is going to be more that probably in the
> dozens of gigabytes.  As far as I know there is no card/driver that will
> benefit for so many pages in zero_copy, and kernel will move to
> synchronous copy at some point.  (In older threads, daniel showed how to
> test for this case).

I was wondering whether the kernel needs to cache a lot of messages for
zero copy if we don't flush it for a long time, as recvmsg(MSG_ERRQUEUE)
seems to be fetching one message from the kernel one at a time.  And,
whether that queue has a limit in length or something.

Does it mean that when the kernel could have cached enough of these
messages then it'll fallback to the no-zero-copy mode?  And probably that's
the way how kernel protects itself from using too much buffer for the error
msgs?

This reminded me - Leo, have you considered adding the patch altogether to
detect the "fallback to non-zero-copy" condition?  Because when with it and
when the fallback happens at some point (e.g. when the guest memory is
larger than some value) we'll know.

Thanks,

-- 
Peter Xu




[PATCH v2 00/12] qemu-img info: Show protocol-level information

2022-06-20 Thread Hanna Reitz
Hi,

This series is a v2 to:

https://lists.nongnu.org/archive/html/qemu-block/2022-05/msg00042.html

Like v1, the purpose is to have qemu-img info print the extent-size-hint
for images on filesystems that support it.  In contrast to v1, it does
so in a more complicated way.

v1 printed this information by adding protocol-specific information to
ImageInfo, which Kevin disliked and instead proposed to have ImageInfo
point to full ImageInfo objects for the respective node’s children.

I considered two possible solutions:
(A) Ignore the proposal, but not add protocol-specific information to
ImageInfo.  Instead, have img_info() itself try to find a clearly
identifiable protocol node and print its driver-specific information
alongside the rest of the information.
I discarded that idea because --output=json is supposed to produce a
QAPI type, and so this additional information wouldn’t be there.  It
wouldn’t be great to print more information with --output=human than
with --output=json.

(B) Somehow let qemu-img info print the block graph.

This implements (B).  I decided against simply putting recursive
ImageInfo objects into ImageInfo, for three reasons:
1. Extremely personal and unsubstantiated opinion: I don’t like it for
   block query functions to return a whole graph.  I prefer query
   functions to work on single nodes and users to manually walk the
   graph if they need information about multiple nodes.

2. ImageInfo already has a link to the backing node’s ImageInfo.  It
   would be strange to link the backing node’s ImageInfo twice (once in
   backing-image, once in the list of all child nodes).

3. query-named-block-nodes returns a list of BlockDeviceInfo objects,
   and every such object has an ImageInfo field.  I think it would be a
   mistake for these ImageInfo fields to be full block subgraphs.
   Now, query-named-block-nodes already has a @flat parameter that can
   be used to suppress the backing-image information that is in
   ImageInfo.  Still, it would be a bad idea to surprise users that
   don’t set it to true (it defaults to false) by blowing up the data
   they get back.  We could add another parameter @nested that needs to
   be explicitly set to true or users will not get the child
   information; but having both @flat and @nested is kind of a bad
   interface.

So I decided to split a new structure BlockNodeInfo off of ImageInfo,
where BlockNodeInfo contains everything that ImageInfo did except for
the backing-image link.  We can then create another structure
BlockGraphInfo that builds on BlockNodeInfo, and in contrast to
ImageInfo has link to all children instead of just backing-image.  We
then let qemu-img info output BlockGraphInfo objects, which works well
because qemu-img info has always ensured the backing-image field would
not be used (so the ImageInfo objects it emitted effectively always were
what are now BlockNodeInfo objects).

(I hope this reorganization isn’t an incompatible change, but I’m not
sure, I have to admit...)

This gets around having to deal with QMP changes relating to ImageInfo
or BlockDeviceInfo (e.g. with query-named-block-nodes), and we don’t
have to worry about the fact that the backing node’s ImageInfo were
duplicated.


There is another potential duplication problem, though: VMDK’s
format-specific info (ImageInfoSpecificVmdk) contains an array of
ImageInfo objects for its extent files.  Just like with backing-image,
it seems not great to duplicate these links.

On closer inspection, however, it turns out that these objects aren’t
actually the extent nodes’ ImageInfo data at all.  These objects are
filled by the VMDK driver with custom information that actually does not
fit the ImageInfo structure, for example, the @format field is not a
block driver type, but a VMDK format, like "SPARSE" or "FLAT".
Therefore, the child links in the new BlockGraphInfo object actually
would not link to duplicate information.

I decided to make that explicit by changing the extent information type
from ImageInfo to a new VmdkExtentInfo type.  I don’t know whether that
is technically an incompatible change, and I don’t know whether it even
matters.  We can skip that type change, and this series should still
work, but I feel like it would have been better for these objects to
have had their own type from the start.


So the final state is that despite the QAPI changes, hopefully only the
qemu-img info output changes, and it now prints every image node’s
subgraph.  This results in an output like the following (for a qcow2
image):

image: test.qcow2
file format: qcow2
virtual size: 64 MiB (67108864 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
Child node '/file':
filename: test.qcow2
protocol type: file
file length: 192 KiB (197120 bytes)

[PATCH v2 05/12] qemu-img: Use BlockNodeInfo

2022-06-20 Thread Hanna Reitz
qemu-img info never uses ImageInfo's backing-image field, because it
opens the backing chain one by one with BDRV_O_NO_BACKING, and prints
all backing chain nodes' information consecutively.  Use BlockNodeInfo
to make it clear that we only print information about a single node, and
that we are not using the backing-image field.

Notably, bdrv_image_info_dump() does not evaluate the backing-image
field, so we can easily make it take a BlockNodeInfo pointer (and
consequentially rename it to bdrv_node_info_dump()).  It makes more
sense this way, because again, the interface now makes it syntactically
clear that backing-image is ignored by this function.

Signed-off-by: Hanna Reitz 
---
 qapi/block-core.json   |  4 +--
 include/block/qapi.h   |  2 +-
 block/monitor/block-hmp-cmds.c |  2 +-
 block/qapi.c   |  2 +-
 qemu-img.c | 48 +-
 5 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 8c06deacdf..d5d1c8ff15 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -5680,9 +5680,9 @@
 ##
 # @DummyBlockCoreForceArrays:
 #
-# Not used by QMP; hack to let us use ImageInfoList internally
+# Not used by QMP; hack to let us use BlockNodeInfoList internally
 #
 # Since: 7.1
 ##
 { 'struct': 'DummyBlockCoreForceArrays',
-  'data': { 'unused-image-info': ['ImageInfo'] } }
+  'data': { 'unused-block-node-info': ['BlockNodeInfo'] } }
diff --git a/include/block/qapi.h b/include/block/qapi.h
index c7de4e3fa9..22198dcd0c 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -45,5 +45,5 @@ void bdrv_query_image_info(BlockDriverState *bs,
 void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
 void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
const char *prefix);
-void bdrv_image_info_dump(ImageInfo *info);
+void bdrv_node_info_dump(BlockNodeInfo *info);
 #endif
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index bfb3c043a0..d286f2d1c5 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -734,7 +734,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
 monitor_printf(mon, "\nImages:\n");
 image_info = inserted->image;
 while (1) {
-bdrv_image_info_dump(image_info);
+bdrv_node_info_dump(qapi_ImageInfo_base(image_info));
 if (image_info->has_backing_image) {
 image_info = image_info->backing_image;
 } else {
diff --git a/block/qapi.c b/block/qapi.c
index e5022b4481..ad88bf9b38 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -865,7 +865,7 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific 
*info_spec,
 visit_free(v);
 }
 
-void bdrv_image_info_dump(ImageInfo *info)
+void bdrv_node_info_dump(BlockNodeInfo *info)
 {
 char *size_buf, *dsize_buf;
 if (!info->has_actual_size) {
diff --git a/qemu-img.c b/qemu-img.c
index 4cf4d2423d..3b1f950c85 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2800,13 +2800,13 @@ static void dump_snapshots(BlockDriverState *bs)
 g_free(sn_tab);
 }
 
-static void dump_json_image_info_list(ImageInfoList *list)
+static void dump_json_block_node_info_list(BlockNodeInfoList *list)
 {
 GString *str;
 QObject *obj;
 Visitor *v = qobject_output_visitor_new();
 
-visit_type_ImageInfoList(v, NULL, , _abort);
+visit_type_BlockNodeInfoList(v, NULL, , _abort);
 visit_complete(v, );
 str = qobject_to_json_pretty(obj, true);
 assert(str != NULL);
@@ -2816,13 +2816,13 @@ static void dump_json_image_info_list(ImageInfoList 
*list)
 g_string_free(str, true);
 }
 
-static void dump_json_image_info(ImageInfo *info)
+static void dump_json_block_node_info(BlockNodeInfo *info)
 {
 GString *str;
 QObject *obj;
 Visitor *v = qobject_output_visitor_new();
 
-visit_type_ImageInfo(v, NULL, , _abort);
+visit_type_BlockNodeInfo(v, NULL, , _abort);
 visit_complete(v, );
 str = qobject_to_json_pretty(obj, true);
 assert(str != NULL);
@@ -2832,9 +2832,9 @@ static void dump_json_image_info(ImageInfo *info)
 g_string_free(str, true);
 }
 
-static void dump_human_image_info_list(ImageInfoList *list)
+static void dump_human_image_info_list(BlockNodeInfoList *list)
 {
-ImageInfoList *elem;
+BlockNodeInfoList *elem;
 bool delim = false;
 
 for (elem = list; elem; elem = elem->next) {
@@ -2843,7 +2843,7 @@ static void dump_human_image_info_list(ImageInfoList 
*list)
 }
 delim = true;
 
-bdrv_image_info_dump(elem->value);
+bdrv_node_info_dump(elem->value);
 }
 }
 
@@ -2853,24 +2853,24 @@ static gboolean str_equal_func(gconstpointer a, 
gconstpointer b)
 }
 
 /**
- * Open an image file chain and return an ImageInfoList
+ * Open an image file chain and return an BlockNodeInfoList
  *
  * @filename: topmost image filename
  * @fmt: topmost 

[PATCH v2 12/12] qemu-img: Change info key names for protocol nodes

2022-06-20 Thread Hanna Reitz
Currently, when querying a qcow2 image, qemu-img info reports something
like this:

image: test.qcow2
file format: qcow2
virtual size: 64 MiB (67108864 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information:
compat: 1.1
compression type: zlib
lazy refcounts: false
refcount bits: 16
corrupt: false
extended l2: false
Child node '/file':
image: test.qcow2
file format: file
virtual size: 192 KiB (197120 bytes)
disk size: 196 KiB
Format specific information:
extent size hint: 1048576

Notably, the way the keys are named is specific for image files: The
filename is shown under "image", the BDS driver under "file format", and
the BDS length under "virtual size".  This does not make much sense for
nodes that are not actually supposed to be guest images, like the /file
child node shown above.

Give bdrv_node_info_dump() a @protocol parameter that gives a hint that
the respective node is probably just used for data storage and does not
necessarily present the data for a VM guest disk.  This renames the keys
so that with this patch, the output becomes:

image: test.qcow2
[...]
Child node '/file':
filename: test.qcow2
protocol type: file
file length: 192 KiB (197120 bytes)
disk size: 196 KiB
Format specific information:
extent size hint: 1048576

(Perhaps we should also rename "Format specific information", but I
could not come up with anything better that will not become problematic
if we guess wrong with the protocol "heuristic".)

This change affects iotest 302, which has protocol node information in
its reference output.

Signed-off-by: Hanna Reitz 
---
This patch is completely optional and just based on personal
preference.  I just don't like e.g. how the child node is called an
"image" when it's pretty much unusable as a guest image, or how "virtual
size" is there twice but with different values.
---
 include/block/qapi.h   |  2 +-
 block/monitor/block-hmp-cmds.c |  2 +-
 block/qapi.c   | 39 --
 qemu-img.c |  3 ++-
 tests/qemu-iotests/302.out |  6 +++---
 5 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/include/block/qapi.h b/include/block/qapi.h
index 38855f2ae9..26113da21a 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -51,5 +51,5 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
 void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
const char *prefix,
int indentation);
-void bdrv_node_info_dump(BlockNodeInfo *info, int indentation);
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol);
 #endif
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index a63c25c208..a8067846b2 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -734,7 +734,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
 monitor_printf(mon, "\nImages:\n");
 image_info = inserted->image;
 while (1) {
-bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0);
+bdrv_node_info_dump(qapi_ImageInfo_base(image_info), 0, false);
 if (image_info->has_backing_image) {
 image_info = image_info->backing_image;
 } else {
diff --git a/block/qapi.c b/block/qapi.c
index 3e35603f0c..56f398c500 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -934,24 +934,49 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific 
*info_spec,
 visit_free(v);
 }
 
-void bdrv_node_info_dump(BlockNodeInfo *info, int indentation)
+/**
+ * Print the given @info object in human-readable form.  Every field is 
indented
+ * using the given @indentation (four spaces per indentation level).
+ *
+ * When using this to print a whole block graph, @protocol can be set to true 
to
+ * signify that the given information is associated with a protocol node, i.e.
+ * just data storage for an image, such that the data it presents is not really
+ * a full VM disk.  If so, several fields change name: For example, "virtual
+ * size" is printed as "file length".
+ * (Consider a qcow2 image, which is represented by a qcow2 node and a file
+ * node.  Printing a "virtual size" for the file node does not make sense,
+ * because without the qcow2 node, it is not really a guest disk, so it does 
not
+ * have a "virtual size".  Therefore, we call it "file length" instead.)
+ *
+ * @protocol is ignored when @indentation is 0, because we take that to mean
+ * that the associated node is the root node in the queried block graph, and
+ * thus is always to be interpreted as a standalone guest disk.
+ */
+void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol)
 {
 char *size_buf, *dsize_buf;
 g_autofree char *ind_s = g_strdup_printf("%*s", indentation * 4, "");
 
+if (indentation == 0) {
+/* Top 

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

2022-06-20 Thread Laurent Vivier

On 20/06/2022 13:22, Markus Armbruster wrote:

Laurent Vivier  writes:


On 15/06/2022 13:46, Markus Armbruster wrote:

Laurent Vivier  writes:


On 13/05/2022 13:44, Markus Armbruster wrote:

Laurent Vivier  writes:


Copied from socket netdev file and modified to use SocketAddress
to be able to introduce new features like unix socket.

"udp" and "mcast" are squashed into dgram netdev, multicast is detected
according to the IP address type.
"listen" and "connect" modes are managed by stream netdev. An optional
parameter "server" defines the mode (server by default)

Signed-off-by: Laurent Vivier 
---
hmp-commands.hx |   2 +-
net/clients.h   |   6 +
net/dgram.c | 630 
net/hub.c   |   2 +
net/meson.build |   2 +
net/net.c   |  24 +-
net/stream.c| 425 
qapi/net.json   |  38 ++-
8 files changed, 1125 insertions(+), 4 deletions(-)
create mode 100644 net/dgram.c
create mode 100644 net/stream.c


...

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


Crashes when user neglects to pass "type".


I think "type" is always passed because of the '.implied_opt_name = "type"'. Am 
I wrong?


.implied_opt_name = "type" lets you shorten "type=T,..." to "T,...".  It
doesn't make key "type" mandatory.  "-netdev id=foo" is still permitted.
Even "-netdev ''" is.



In fact type is checked before by QAPI definition:

{ 'union': 'Netdev',
'base': { 'id': 'str', 'type': 'NetClientDriver' },
'discriminator': 'type',
...

As it's the discriminator it must be there.

$ qemu-system-x86_64 -netdev id=foo
qemu-system-x86_64: -netdev id=foo: Parameter 'type' is missing


It does crash for me:

 (gdb) bt
 #0  0x74d25dcb in __strcmp_avx2 () at /lib64/libc.so.6
 #1  0x55b4574b in netdev_is_modern (optarg=0x7fffe2ae "id=foo")
 at ../net/net.c:1626
 #2  0x55b457ad in net_client_parse
 (opts_list=0x56563780 , optarg=0x7fffe2ae 
"id=foo") at ../net/net.c:1636
 #3  0x55ad98de in qemu_init (argc=3, argv=0x7fffdf08, envp=0x0)
 at ../softmmu/vl.c:2901
 #4  0x55842c01 in qemu_main (argc=3, argv=0x7fffdf08, envp=0x0)
 at ../softmmu/main.c:35
 #5  0x55842c37 in main (argc=3, argv=0x7fffdf08)
 at ../softmmu/main.c:45
 (gdb) up
 #1  0x55b4574b in netdev_is_modern (optarg=0x7fffe2ae "id=foo")
 at ../net/net.c:1626
 1626   is_modern = strcmp(netdev, "stream") == 0 ||
 (gdb) p netdev
 $1 = 0x0

This is

  https://github.com/patchew-project/qemu 
tags/patchew/20220512080932.735962-1-lviv...@redhat.com

I suspect you tested with your v3, which doesn't crash for me, either.



Yes, thank you. So this is fixed now :)

Laurent




Re: [RFC PATCH v3 03/11] qapi: net: introduce a way to bypass qemu_opts_parse_noisily()

2022-06-20 Thread Markus Armbruster
Laurent Vivier  writes:

> As qemu_opts_parse_noisily() flattens the QAPI structures ("type" field
> of Netdev structure can collides with "type" field of SocketAddress),
> we introduce a way to bypass qemu_opts_parse_noisily() and use directly
> visit_type_Netdev() to parse the backend parameters.
>
> More details from Markus:
>
> qemu_init() passes the argument of -netdev, -nic, and -net to
> net_client_parse().
>
> net_client_parse() parses with qemu_opts_parse_noisily(), passing
> QemuOptsList qemu_netdev_opts for -netdev, qemu_nic_opts for -nic, and
> qemu_net_opts for -net.  Their desc[] are all empty, which means any
> keys are accepted.  The result of the parse (a QemuOpts) is stored in
> the QemuOptsList.
>
> Note that QemuOpts is flat by design.  In some places, we layer non-flat
> on top using dotted keys convention, but not here.
>
> net_init_clients() iterates over the stored QemuOpts, and passes them to
> net_init_netdev(), net_param_nic(), or net_init_client(), respectively.
>
> These functions pass the QemuOpts to net_client_init().  They also do
> other things with the QemuOpts, which we can ignore here.
>
> net_client_init() uses the opts visitor to convert the (flat) QemOpts to
> a (non-flat) QAPI object Netdev.  Netdev is also the argument of QMP
> command netdev_add.
>
> The opts visitor was an early attempt to support QAPI in
> (QemuOpts-based) CLI.  It restricts QAPI types to a certain shape; see
> commit eb7ee2cbeb "qapi: introduce OptsVisitor".
>
> A more modern way to support QAPI is qobject_input_visitor_new_str().
> It uses keyval_parse() instead of QemuOpts for KEY=VALUE,... syntax, and
> it also supports JSON syntax.  The former isn't quite as expressive as
> JSON, but it's a lot closer than QemuOpts + opts visitor.
>
> This commit paves the way to use of the modern way instead.
>
> Signed-off-by: Laurent Vivier 
> ---
>  include/net/net.h |  1 +
>  net/net.c | 60 +++
>  softmmu/vl.c  |  3 ++-
>  3 files changed, 63 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/net.h b/include/net/net.h
> index c53c64ac18c4..4ae8ed480f73 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -214,6 +214,7 @@ extern NICInfo nd_table[MAX_NICS];
>  extern const char *host_net_devices[];
>  
>  /* from net.c */
> +int netdev_parse_modern(const char *optarg);
>  int net_client_parse(QemuOptsList *opts_list, const char *str);
>  void show_netdevs(void);
>  void net_init_clients(void);
> diff --git a/net/net.c b/net/net.c
> index 15958f881776..c337d3d753fe 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -54,6 +54,7 @@
>  #include "net/colo-compare.h"
>  #include "net/filter.h"
>  #include "qapi/string-output-visitor.h"
> +#include "qapi/qobject-input-visitor.h"
>  
>  /* Net bridge is currently not supported for W32. */
>  #if !defined(_WIN32)
> @@ -63,6 +64,16 @@
>  static VMChangeStateEntry *net_change_state_entry;
>  static QTAILQ_HEAD(, NetClientState) net_clients;
>  
> +typedef struct NetdevQueueEntry {
> +Netdev *nd;
> +Location loc;
> +QSIMPLEQ_ENTRY(NetdevQueueEntry) entry;
> +} NetdevQueueEntry;
> +
> +typedef QSIMPLEQ_HEAD(, NetdevQueueEntry) NetdevQueue;
> +
> +static NetdevQueue nd_queue = QSIMPLEQ_HEAD_INITIALIZER(nd_queue);
> +
>  /***/
>  /* network device redirectors */
>  
> @@ -1562,6 +1573,20 @@ out:
>  return ret;
>  }
>  
> +static void netdev_init_modern(void)
> +{
> +while (!QSIMPLEQ_EMPTY(_queue)) {
> +NetdevQueueEntry *nd = QSIMPLEQ_FIRST(_queue);
> +
> +QSIMPLEQ_REMOVE_HEAD(_queue, entry);
> +loc_push_restore(>loc);
> +net_client_init1(nd->nd, true, _fatal);
> +loc_pop(>loc);
> +qapi_free_Netdev(nd->nd);
> +g_free(nd);
> +}
> +}
> +
>  void net_init_clients(void)
>  {
>  net_change_state_entry =
> @@ -1569,6 +1594,8 @@ void net_init_clients(void)
>  
>  QTAILQ_INIT(_clients);
>  
> +netdev_init_modern();
> +
>  qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL,
>_fatal);
>  
> @@ -1579,6 +1606,39 @@ void net_init_clients(void)
>_fatal);
>  }
>  
> +/*
> + * netdev_is_modern() returns true when the backend needs to bypass
> + * qemu_opts_parse_noisily()
> + */
> +static bool netdev_is_modern(const char *optarg)
> +{
> +return false;
> +}
> +
> +/*
> + * netdev_parse_modern() uses modern, more expressive syntax than
> + * net_client_parse(), supports only the netdev option.
> + */
> +int netdev_parse_modern(const char *optarg)
> +{
> +Visitor *v;
> +NetdevQueueEntry *nd;
> +
> +if (!netdev_is_modern(optarg)) {
> +return -1;
> +}
> +
> +v = qobject_input_visitor_new_str(optarg, "type", _fatal);
> +nd = g_new(NetdevQueueEntry, 1);
> +visit_type_Netdev(v, NULL, >nd, _fatal);
> +visit_free(v);
> +loc_save(>loc);
> +
> +

Re: [PATCH v2 01/21] io: add a QIOChannelNull equivalent to /dev/null

2022-06-20 Thread Juan Quintela
Daniel P. Berrangé  wrote:
> This is for code which needs a portable equivalent to a QIOChannelFile
> connected to /dev/null.
>
> Signed-off-by: Daniel P. Berrangé 

Reviewed-by: Juan Quintela 




Re: [PATCH v2 02/21] migration: switch to use QIOChannelNull for dummy channel

2022-06-20 Thread Juan Quintela
Daniel P. Berrangé  wrote:
> This removes one further custom impl of QEMUFile, in favour of a
> QIOChannel based impl.
>
> Reviewed-by: Eric Blake 
> Signed-off-by: Daniel P. Berrangé 

Reviewed-by: Juan Quintela 




Re: [PATCH v2] memory: prevent dma-reentracy issues

2022-06-20 Thread Alexander Bulekov
On 220609 0958, Alexander Bulekov wrote:
> Add a flag to the DeviceState, when a device is engaged in PIO/MMIO/DMA.
> This flag is set/checked prior to calling a device's MemoryRegion
> handlers, and set when device code initiates DMA.  The purpose of this
> flag is to prevent two types of DMA-based reentrancy issues:
> 
> 1.) mmio -> dma -> mmio case
> 2.) bh -> dma write -> mmio case
> 
> These issues have led to problems such as stack-exhaustion and
> use-after-frees.
> 
> Summary of the problem from Peter Maydell:
> https://lore.kernel.org/qemu-devel/cafeaca_23vc7he3iam-jva6w38lk4hjowae5kcknhprd5fp...@mail.gmail.com
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/62
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/540
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/541
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/556
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/557
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/827
> Signed-off-by: Alexander Bulekov 
> ---
>  include/hw/pci/pci.h   | 13 +++--
>  include/hw/qdev-core.h |  3 +++
>  softmmu/dma-helpers.c  | 12 
>  softmmu/memory.c   | 15 +++
>  softmmu/trace-events   |  1 +
>  5 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index 44dacfa224..ab1ad0f7a8 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -834,8 +834,17 @@ static inline MemTxResult pci_dma_rw(PCIDevice *dev, 
> dma_addr_t addr,
>   void *buf, dma_addr_t len,
>   DMADirection dir, MemTxAttrs attrs)
>  {
> -return dma_memory_rw(pci_get_address_space(dev), addr, buf, len,
> - dir, attrs);
> +bool prior_engaged_state;
> +MemTxResult result;
> +
> +prior_engaged_state = dev->qdev.engaged_in_io;
> +
> +dev->qdev.engaged_in_io = true;
> +result = dma_memory_rw(pci_get_address_space(dev), addr, buf, len,
> +   dir, attrs);
> +dev->qdev.engaged_in_io = prior_engaged_state;
> +
> +return result;
>  }
>  
>  /**
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 92c3d65208..6474dc51fa 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -193,6 +193,9 @@ struct DeviceState {
>  int instance_id_alias;
>  int alias_required_for_version;
>  ResettableState reset;
> +
> +/* Is the device currently in mmio/pio/dma? Used to prevent re-entrancy 
> */
> +int engaged_in_io;
>  };
>  
>  struct DeviceListener {
> diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
> index 7820fec54c..7a4f1fb9b3 100644
> --- a/softmmu/dma-helpers.c
> +++ b/softmmu/dma-helpers.c
> @@ -288,8 +288,16 @@ static MemTxResult dma_buf_rw(void *buf, dma_addr_t len, 
> dma_addr_t *residual,
>  uint8_t *ptr = buf;
>  dma_addr_t xresidual;
>  int sg_cur_index;
> +DeviceState *dev;
> +bool prior_engaged_state;
>  MemTxResult res = MEMTX_OK;
>  
> +dev = sg->dev;
> +if (dev) {
> +prior_engaged_state = dev->engaged_in_io;
> +dev->engaged_in_io = true;
> +}
> +
>  xresidual = sg->size;
>  sg_cur_index = 0;
>  len = MIN(len, xresidual);
> @@ -302,6 +310,10 @@ static MemTxResult dma_buf_rw(void *buf, dma_addr_t len, 
> dma_addr_t *residual,
>  xresidual -= xfer;
>  }
>  
> +if (dev) {
> +dev->engaged_in_io = prior_engaged_state;
> +}
> +
>  if (residual) {
>  *residual = xresidual;
>  }
> diff --git a/softmmu/memory.c b/softmmu/memory.c
> index 7ba2048836..44a14bb4f5 100644
> --- a/softmmu/memory.c
> +++ b/softmmu/memory.c
> @@ -532,6 +532,7 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
>  uint64_t access_mask;
>  unsigned access_size;
>  unsigned i;
> +DeviceState *dev = NULL;
>  MemTxResult r = MEMTX_OK;
>  
>  if (!access_size_min) {
> @@ -541,6 +542,17 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
>  access_size_max = 4;
>  }
>  
> +/* Do not allow more than one simultanous access to a device's IO 
> Regions */
> +if (mr->owner &&
> +!mr->ram_device && !mr->ram && !mr->rom_device && !mr->readonly) {
> +dev = (DeviceState *) object_dynamic_cast(mr->owner, TYPE_DEVICE);
> +if (dev->engaged_in_io) {
> +trace_memory_region_reentrant_io(get_cpu_index(), mr, addr, 
> size);
> +return MEMTX_ERROR;
> +}
> +dev->engaged_in_io = true;
> +}
> +
>  /* FIXME: support unaligned access? */
>  access_size = MAX(MIN(size, access_size_max), access_size_min);
>  access_mask = MAKE_64BIT_MASK(0, access_size * 8);
> @@ -555,6 +567,9 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
>  access_mask, attrs);
>  }
>  }
> +if (dev) {
> +

Re: [PATCH 0/7] semihosting: proper QEMU exit on semihosted exit syscall

2022-06-20 Thread Peter Maydell
On Mon, 20 Jun 2022 at 15:25, Luc Michel  wrote:
> This series implements a clean way for semihosted exit syscalls to
> terminate QEMU with a given return code.
>
> Until now, exit syscalls implementations consisted in calling exit()
> with the wanted return code. The problem with this approach is that
> other CPUs are not properly stopped, leading to possible crashes in
> MTTCG mode, especially when at_exit callbacks have been registered. This
> can be the case e.g., when plugins are in use. Plugins can register
> at_exit callbacks. Those will be called on the CPU thread the exit
> syscall is comming from, while other CPUs can continue to run and thus
> call other plugin callbacks.

The other option would be to say "if you register an atexit
callback in your plugin that's your problem to sort out" :-)
There's lots of situations where code inside QEMU might just
call exit(), not just this one. (Mostly these are "we detected
an error and decided to just bail out" codepaths.)

Is there a situation where we get a crash that doesn't involve
code in a plugin doing something odd?

thanks
-- PMM



[PATCH 6/7] target/nios2: use semihosting_exit_request on semihosted exit syscall

2022-06-20 Thread Luc Michel
Use the new semihosting_exit_request instead of a call to exit when
handling a semihosted exit syscall.

Signed-off-by: Luc Michel 
---
 target/nios2/nios2-semi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/nios2/nios2-semi.c b/target/nios2/nios2-semi.c
index ec88474a73..2624ef1539 100644
--- a/target/nios2/nios2-semi.c
+++ b/target/nios2/nios2-semi.c
@@ -29,10 +29,11 @@
 #include "qemu.h"
 #else
 #include "exec/softmmu-semi.h"
 #endif
 #include "qemu/log.h"
+#include "semihosting/semihost.h"
 
 #define HOSTED_EXIT  0
 #define HOSTED_INIT_SIM 1
 #define HOSTED_OPEN 2
 #define HOSTED_CLOSE 3
@@ -212,12 +213,11 @@ void do_nios2_semihosting(CPUNios2State *env)
 
 nr = env->regs[R_ARG0];
 args = env->regs[R_ARG1];
 switch (nr) {
 case HOSTED_EXIT:
-gdb_exit(env->regs[R_ARG0]);
-exit(env->regs[R_ARG0]);
+semihosting_exit_request(env->regs[R_ARG0]);
 case HOSTED_OPEN:
 GET_ARG(0);
 GET_ARG(1);
 GET_ARG(2);
 GET_ARG(3);
-- 
2.17.1




Re: proposed 7.1 release schedule

2022-06-20 Thread Richard Henderson

On 6/20/22 03:50, Peter Maydell wrote:

On Mon, 23 May 2022 at 16:08, Richard Henderson
 wrote:


On 5/23/22 02:53, Peter Maydell wrote:

I just put some proposed dates into the 7.1 schedule page:
https://wiki.qemu.org/Planning/7.1#Release_Schedule

* 2022-07-12  Softfreeze
* 2022-07-19  Hardfreeze. Tag rc0
* 2022-07-26  Tag rc1
* 2022-08-02  Tag rc2
* 2022-08-09  Tag rc3
* 2022-08-16  Release; or tag rc4 if needed
* 2022-08-23  Release if we needed an rc4

Does this work for people? I just worked backwards
from a final release date about 4 months after 7.0; easy
enough to shift it forward or back by a week or so if
that works better for some reason.


Shifting later a week or so would be better. I'm on holiday from 13-22 July -- 
unless
someone would like to manage merges in that period?


I've updated the wiki page to move the dates all one week
later, and removed the "tentative" label.


Thanks.


Ping me when we get closer to your holiday to remind
me that I agreed to do merges then :-)


Will do.  :-)


r~




Re: [PATCH v2 06/21] migration: rename qemu_ftell to qemu_file_total_transferred

2022-06-20 Thread Juan Quintela
Daniel P. Berrangé  wrote:
> The name 'ftell' gives the misleading impression that the QEMUFile
> objects are seekable. This is not the case, as in general we just
> have an opaque stream. The users of this method are only interested
> in the total bytes processed. This switches to a new name that
> reflects the intended usage.
>
> Reviewed-by: Dr. David Alan Gilbert 
> Signed-off-by: Daniel P. Berrangé 

Reviewed-by: Juan Quintela 




Re: [PATCH v2 11/21] migration: stop passing 'opaque' parameter to QEMUFile hooks

2022-06-20 Thread Juan Quintela
Daniel P. Berrangé  wrote:
> The only user of the hooks is RDMA which provides a QIOChannel backed
> impl of QEMUFile. It can thus use the qemu_file_get_ioc() method.
>
> Reviewed-by: Dr. David Alan Gilbert 
> Signed-off-by: Daniel P. Berrangé 

Reviewed-by: Juan Quintela 




Re: [PATCH v4 1/4] QIOChannelSocket: Introduce assert and reduce ifdefs to improve readability

2022-06-20 Thread Peter Xu
On Mon, Jun 20, 2022 at 02:39:42AM -0300, Leonardo Bras wrote:
> During implementation of MSG_ZEROCOPY feature, a lot of #ifdefs were
> introduced, particularly at qio_channel_socket_writev().
> 
> Rewrite some of those changes so it's easier to read.
> 
> Also, introduce an assert to help detect incorrect zero-copy usage is when
> it's disabled on build.
> 
> Signed-off-by: Leonardo Bras 
> Reviewed-by: Daniel P. Berrangé 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v2 18/21] migration: remove the QEMUFileOps 'get_buffer' callback

2022-06-20 Thread Juan Quintela
Daniel P. Berrangé  wrote:
> This directly implements the get_buffer logic using QIOChannel APIs.
>
> Reviewed-by: Dr. David Alan Gilbert 
> Signed-off-by: Daniel P. Berrangé 

Reviewed-by: Juan Quintela 




[PATCH] target/arm: Catch invalid kvm state also for hvf

2022-06-20 Thread Alexander Graf
Some features such as running in EL3 or running M profile code are
incompatible with virtualization as QEMU implements it today. To prevent
users from picking invalid configurations on Hvf as well, let's run the
same checks there as well.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1073
Signed-off-by: Alexander Graf 
---
 target/arm/cpu.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1b5d535788..03510f29f9 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1490,7 +1490,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 }
 }
 
-if (kvm_enabled()) {
+if (kvm_enabled() || hvf_enabled()) {
 /*
  * Catch all the cases which might cause us to create more than one
  * address space for the CPU (otherwise we will assert() later in
@@ -1498,17 +1498,17 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
  */
 if (arm_feature(env, ARM_FEATURE_M)) {
 error_setg(errp,
-   "Cannot enable KVM when using an M-profile guest CPU");
+   "Cannot enable KVM or HVF when using an M-profile guest 
CPU");
 return;
 }
 if (cpu->has_el3) {
 error_setg(errp,
-   "Cannot enable KVM when guest CPU has EL3 enabled");
+   "Cannot enable KVM or HVF when guest CPU has EL3 
enabled");
 return;
 }
 if (cpu->tag_memory) {
 error_setg(errp,
-   "Cannot enable KVM when guest CPUs has MTE enabled");
+   "Cannot enable KVM or HVF when guest CPUs has MTE 
enabled");
 return;
 }
 }
-- 
2.32.1 (Apple Git-133)




[PATCH v2 02/12] block/file: Add file-specific image info

2022-06-20 Thread Hanna Reitz
Add some (optional) information that the file driver can provide for
image files, namely the extent size hint.

Signed-off-by: Hanna Reitz 
---
 qapi/block-core.json | 26 --
 block/file-posix.c   | 30 ++
 2 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 457df16638..40fb307e2d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -139,16 +139,29 @@
   '*encryption-format': 'RbdImageEncryptionFormat'
   } }
 
+##
+# @ImageInfoSpecificFile:
+#
+# @extent-size-hint: Extent size hint (if available)
+#
+# Since: 7.1
+##
+{ 'struct': 'ImageInfoSpecificFile',
+  'data': {
+  '*extent-size-hint': 'size'
+  } }
+
 ##
 # @ImageInfoSpecificKind:
 #
 # @luks: Since 2.7
 # @rbd: Since 6.1
+# @file: Since 7.1
 #
 # Since: 1.7
 ##
 { 'enum': 'ImageInfoSpecificKind',
-  'data': [ 'qcow2', 'vmdk', 'luks', 'rbd' ] }
+  'data': [ 'qcow2', 'vmdk', 'luks', 'rbd', 'file' ] }
 
 ##
 # @ImageInfoSpecificQCow2Wrapper:
@@ -185,6 +198,14 @@
 { 'struct': 'ImageInfoSpecificRbdWrapper',
   'data': { 'data': 'ImageInfoSpecificRbd' } }
 
+##
+# @ImageInfoSpecificFileWrapper:
+#
+# Since: 7.1
+##
+{ 'struct': 'ImageInfoSpecificFileWrapper',
+  'data': { 'data': 'ImageInfoSpecificFile' } }
+
 ##
 # @ImageInfoSpecific:
 #
@@ -199,7 +220,8 @@
   'qcow2': 'ImageInfoSpecificQCow2Wrapper',
   'vmdk': 'ImageInfoSpecificVmdkWrapper',
   'luks': 'ImageInfoSpecificLUKSWrapper',
-  'rbd': 'ImageInfoSpecificRbdWrapper'
+  'rbd': 'ImageInfoSpecificRbdWrapper',
+  'file': 'ImageInfoSpecificFileWrapper'
   } }
 
 ##
diff --git a/block/file-posix.c b/block/file-posix.c
index 48cd096624..74a649b409 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -3083,6 +3083,34 @@ static int raw_get_info(BlockDriverState *bs, 
BlockDriverInfo *bdi)
 return 0;
 }
 
+static ImageInfoSpecific *raw_get_specific_info(BlockDriverState *bs,
+Error **errp)
+{
+BDRVRawState *s = bs->opaque;
+ImageInfoSpecificFile *file_info = g_new0(ImageInfoSpecificFile, 1);
+ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
+
+*spec_info = (ImageInfoSpecific){
+.type = IMAGE_INFO_SPECIFIC_KIND_FILE,
+.u.file.data = file_info,
+};
+
+#ifdef FS_IOC_FSGETXATTR
+{
+struct fsxattr attr;
+int ret;
+
+ret = ioctl(s->fd, FS_IOC_FSGETXATTR, );
+if (!ret && attr.fsx_extsize != 0) {
+file_info->has_extent_size_hint = true;
+file_info->extent_size_hint = attr.fsx_extsize;
+}
+}
+#endif
+
+return spec_info;
+}
+
 static BlockStatsSpecificFile get_blockstats_specific_file(BlockDriverState 
*bs)
 {
 BDRVRawState *s = bs->opaque;
@@ -3316,6 +3344,7 @@ BlockDriver bdrv_file = {
 .bdrv_co_truncate = raw_co_truncate,
 .bdrv_getlength = raw_getlength,
 .bdrv_get_info = raw_get_info,
+.bdrv_get_specific_info = raw_get_specific_info,
 .bdrv_get_allocated_file_size
 = raw_get_allocated_file_size,
 .bdrv_get_specific_stats = raw_get_specific_stats,
@@ -3688,6 +3717,7 @@ static BlockDriver bdrv_host_device = {
 .bdrv_co_truncate   = raw_co_truncate,
 .bdrv_getlength= raw_getlength,
 .bdrv_get_info = raw_get_info,
+.bdrv_get_specific_info = raw_get_specific_info,
 .bdrv_get_allocated_file_size
 = raw_get_allocated_file_size,
 .bdrv_get_specific_stats = hdev_get_specific_stats,
-- 
2.35.3




[PATCH v2 10/12] iotests/106, 214, 308: Read only one size line

2022-06-20 Thread Hanna Reitz
These tests read size information (sometimes disk size, sometimes
virtual size) from qemu-img info's output.  Once qemu-img starts
printing info about child nodes, we are going to see multiple instances
of that per image, but these tests are only interested in the first one,
so use "head -n 1" to get it.

Signed-off-by: Hanna Reitz 
---
 tests/qemu-iotests/106 | 4 ++--
 tests/qemu-iotests/214 | 6 --
 tests/qemu-iotests/308 | 4 ++--
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
index 9d6adb542d..ae0fc46691 100755
--- a/tests/qemu-iotests/106
+++ b/tests/qemu-iotests/106
@@ -66,7 +66,7 @@ for create_mode in off falloc full; do
 expected_size=$((expected_size + $GROWTH_SIZE))
 fi
 
-actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk 
size')
+actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk 
size' | head -n 1)
 actual_size=$(echo "$actual_size" | sed -e 
's/^[^0-9]*\([0-9]\+\).*$/\1/')
 
 # The actual size may exceed the expected size, depending on the file
@@ -105,7 +105,7 @@ for growth_mode in falloc full; do
 _make_test_img -o "extent_size_hint=0" 2G
 $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" 
+${GROWTH_SIZE}K
 
-actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size')
+actual_size=$($QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep 'disk size' | 
head -n 1)
 actual_size=$(echo "$actual_size" | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/')
 
 if [ $actual_size -lt $GROWTH_SIZE ]; then
diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214
index c66e246ba2..55ffcd7f44 100755
--- a/tests/qemu-iotests/214
+++ b/tests/qemu-iotests/214
@@ -102,7 +102,8 @@ let data_size="8 * $cluster_size"
 $QEMU_IO -c "write -P 0xaa 0 $data_size" "$TEST_IMG" \
  2>&1 | _filter_qemu_io | _filter_testdir
 sizeA=$($QEMU_IMG info --output=json "$TEST_IMG" |
-sed -n '/"actual-size":/ s/[^0-9]//gp')
+sed -n '/"actual-size":/ s/[^0-9]//gp' |
+head -n 1)
 
 _make_test_img 2M -o cluster_size=$cluster_size
 echo "Write compressed data:"
@@ -124,7 +125,8 @@ $QEMU_IO -c "write -P 0xcc $offset $data_size" "json:{\
   _filter_qemu_io | _filter_testdir
 
 sizeB=$($QEMU_IMG info --output=json "$TEST_IMG" |
-sed -n '/"actual-size":/ s/[^0-9]//gp')
+sed -n '/"actual-size":/ s/[^0-9]//gp' |
+head -n 1)
 
 if [ $sizeA -lt $sizeB ]
 then
diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308
index bde4aac2fa..09275e9a10 100755
--- a/tests/qemu-iotests/308
+++ b/tests/qemu-iotests/308
@@ -217,12 +217,12 @@ echo
 echo '=== Remove export ==='
 
 # Double-check that $EXT_MP appears as a non-empty file (the raw image)
-$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size'
+$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size' | head -n 1
 
 fuse_export_del 'export-mp'
 
 # See that the file appears empty again
-$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size'
+$QEMU_IMG info -f raw "$EXT_MP" | grep 'virtual size' | head -n 1
 
 echo
 echo '=== Writable export ==='
-- 
2.35.3




Re: [PATCH] target/arm: Catch invalid kvm state also for hvf

2022-06-20 Thread Richard Henderson

On 6/20/22 09:08, Alexander Graf wrote:

-if (kvm_enabled()) {
+if (kvm_enabled() || hvf_enabled()) {


I think this should be !tcg_enabled().  No hw virtualization can use EL3 (or M-profile), 
only full emulation from TCG.  There is such a thing as ARM on Windows, so I can imagine 
that WHPX may make a future appearance here.


(MTE may eventually be supported by virtualization, but it's not there yet.)



 if (arm_feature(env, ARM_FEATURE_M)) {
 error_setg(errp,
-   "Cannot enable KVM when using an M-profile guest CPU");
+   "Cannot enable KVM or HVF when using an M-profile guest 
CPU");
 return;
 }


You can get the accelerator name from

AccelClass *ac = ACCEL_GET_CLASS(current_accel());
const char *name = ac->name;


r~



[PATCH v3 03/51] target/arm: Add syn_smetrap

2022-06-20 Thread Richard Henderson
This will be used for raising various traps for SME.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/syndrome.h | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
index c105f9e6ba..73df5e3793 100644
--- a/target/arm/syndrome.h
+++ b/target/arm/syndrome.h
@@ -48,6 +48,7 @@ enum arm_exception_class {
 EC_AA64_SMC   = 0x17,
 EC_SYSTEMREGISTERTRAP = 0x18,
 EC_SVEACCESSTRAP  = 0x19,
+EC_SMETRAP= 0x1d,
 EC_INSNABORT  = 0x20,
 EC_INSNABORT_SAME_EL  = 0x21,
 EC_PCALIGNMENT= 0x22,
@@ -68,6 +69,13 @@ enum arm_exception_class {
 EC_AA64_BKPT  = 0x3c,
 };
 
+typedef enum {
+SME_ET_AccessTrap,
+SME_ET_Streaming,
+SME_ET_NotStreaming,
+SME_ET_InactiveZA,
+} SMEExceptionType;
+
 #define ARM_EL_EC_SHIFT 26
 #define ARM_EL_IL_SHIFT 25
 #define ARM_EL_ISV_SHIFT 24
@@ -207,6 +215,12 @@ static inline uint32_t syn_sve_access_trap(void)
 return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
 }
 
+static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
+{
+return (EC_SMETRAP << ARM_EL_EC_SHIFT)
+| (is_16bit ? 0 : ARM_EL_IL) | etype;
+}
+
 static inline uint32_t syn_pactrap(void)
 {
 return EC_PACTRAP << ARM_EL_EC_SHIFT;
-- 
2.34.1




[PATCH v3 04/51] target/arm: Add ARM_CP_SME

2022-06-20 Thread Richard Henderson
This will be used for controlling access to SME cpregs.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpregs.h|  5 +
 target/arm/translate-a64.c | 18 ++
 2 files changed, 23 insertions(+)

diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
index d9b678c2f1..d30758ee71 100644
--- a/target/arm/cpregs.h
+++ b/target/arm/cpregs.h
@@ -113,6 +113,11 @@ enum {
 ARM_CP_EL3_NO_EL2_UNDEF  = 1 << 16,
 ARM_CP_EL3_NO_EL2_KEEP   = 1 << 17,
 ARM_CP_EL3_NO_EL2_C_NZ   = 1 << 18,
+/*
+ * Flag: Access check for this sysreg is constrained by the
+ * ARM pseudocode function CheckSMEAccess().
+ */
+ARM_CP_SME   = 1 << 19,
 };
 
 /*
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 9a285dd177..8f609f46b6 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1187,6 +1187,22 @@ bool sve_access_check(DisasContext *s)
 return fp_access_check(s);
 }
 
+/*
+ * Check that SME access is enabled, raise an exception if not.
+ * Note that this function corresponds to CheckSMEAccess and is
+ * only used directly for cpregs.
+ */
+static bool sme_access_check(DisasContext *s)
+{
+if (s->sme_excp_el) {
+gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF,
+  syn_smetrap(SME_ET_AccessTrap, false),
+  s->sme_excp_el);
+return false;
+}
+return true;
+}
+
 /*
  * This utility function is for doing register extension with an
  * optional shift. You will likely want to pass a temporary for the
@@ -1958,6 +1974,8 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 return;
 } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
 return;
+} else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
+return;
 }
 
 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
-- 
2.34.1




[PATCH v3 31/51] target/arm: Implement BFMOPA, BFMOPS

2022-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-sme.h|  2 ++
 target/arm/sme.decode  |  2 ++
 target/arm/sme_helper.c| 52 ++
 target/arm/translate-sme.c | 29 +
 4 files changed, 85 insertions(+)

diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
index 727095a3eb..6b36542133 100644
--- a/target/arm/helper-sme.h
+++ b/target/arm/helper-sme.h
@@ -124,3 +124,5 @@ DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_6(sme_bfmopa, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, ptr, i32)
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
index ba4774d174..afd9c0dffd 100644
--- a/target/arm/sme.decode
+++ b/target/arm/sme.decode
@@ -73,3 +73,5 @@ ADDVA_d 1100 11 01000 1 ... ... . 00 ...  
  @adda_64
 
 FMOPA_s 1000 100 . ... ... . . 00 ..@op_32
 FMOPA_d 1000 110 . ... ... . . 0 ...@op_64
+
+BFMOPA  1001 100 . ... ... . . 00 ..@op_32
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
index 62d9690cae..61bab73cb7 100644
--- a/target/arm/sme_helper.c
+++ b/target/arm/sme_helper.c
@@ -964,3 +964,55 @@ void HELPER(sme_fmopa_d)(void *vza, void *vzn, void *vzm, 
void *vpn,
 
 set_default_nan_mode(save_dn, vst);
 }
+
+/*
+ * Alter PAIR as needed for controlling predicates being false,
+ * and for NEG on an enabled row element.
+ */
+static inline uint32_t f16mop_adj_pair(uint32_t pair, uint32_t pg, uint32_t 
neg)
+{
+pair ^= neg;
+if (!(pg & 1)) {
+pair &= 0xu;
+}
+if (!(pg & 4)) {
+pair &= 0xu;
+}
+return pair;
+}
+
+void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
+void *vpm, uint32_t desc)
+{
+intptr_t row, col, oprsz = simd_maxsz(desc);
+uint32_t neg = simd_data(desc) << 15;
+uint16_t *pn = vpn, *pm = vpm;
+
+for (row = 0; row < oprsz; ) {
+uint16_t pa = pn[H2(row >> 4)];
+do {
+void *vza_row = vza + row * sizeof(ARMVectorReg);
+uint32_t n = *(uint32_t *)(vzn + row);
+
+n = f16mop_adj_pair(n, pa, neg);
+
+for (col = 0; col < oprsz; ) {
+uint16_t pb = pm[H2(col >> 4)];
+do {
+if ((pa & 0b0101) == 0b0101 || (pb & 0b0101) == 0b0101) {
+uint32_t *a = vza_row + col;
+uint32_t m = *(uint32_t *)(vzm + col);
+
+m = f16mop_adj_pair(m, pb, neg);
+*a = bfdotadd(*a, n, m);
+
+col += 4;
+pb >>= 4;
+}
+} while (col & 15);
+}
+row += 4;
+pa >>= 4;
+} while (row & 15);
+}
+}
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
index e6e4541e76..581bf9174f 100644
--- a/target/arm/translate-sme.c
+++ b/target/arm/translate-sme.c
@@ -274,6 +274,32 @@ TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, 
gen_helper_sme_addva_s)
 TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d)
 TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d)
 
+static bool do_outprod(DisasContext *s, arg_op *a, MemOp esz,
+   gen_helper_gvec_5 *fn)
+{
+uint32_t desc = simd_desc(s->svl, s->svl, a->sub);
+TCGv_ptr za, zn, zm, pn, pm;
+
+if (!sme_smza_enabled_check(s)) {
+return true;
+}
+
+/* Sum XZR+zad to find ZAd. */
+za = get_tile_rowcol(s, esz, 31, a->zad, false);
+zn = vec_full_reg_ptr(s, a->zn);
+zm = vec_full_reg_ptr(s, a->zm);
+pn = pred_full_reg_ptr(s, a->pn);
+pm = pred_full_reg_ptr(s, a->pm);
+
+fn(za, zn, zm, pn, pm, tcg_constant_i32(desc));
+
+tcg_temp_free_ptr(za);
+tcg_temp_free_ptr(zn);
+tcg_temp_free_ptr(pn);
+tcg_temp_free_ptr(pm);
+return true;
+}
+
 static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
 gen_helper_gvec_5_ptr *fn)
 {
@@ -306,3 +332,6 @@ TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst,
a, MO_32, gen_helper_sme_fmopa_s)
 TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst,
a, MO_64, gen_helper_sme_fmopa_d)
+
+/* TODO: FEAT_EBF16 */
+TRANS_FEAT(BFMOPA, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_bfmopa)
-- 
2.34.1




[PATCH v3 23/51] target/arm: Implement SME RDSVL, ADDSVL, ADDSPL

2022-06-20 Thread Richard Henderson
These SME instructions are nominally within the SVE decode space,
so we add them to sve.decode and translate-sve.c.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.h |  1 +
 target/arm/sve.decode  |  5 -
 target/arm/translate-a64.c | 15 +++
 target/arm/translate-sve.c | 38 ++
 4 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index 789b6e8e78..6bd1b2eb4b 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -29,6 +29,7 @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
 bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
 unsigned int imms, unsigned int immr);
 bool sve_access_check(DisasContext *s);
+bool sme_enabled_check(DisasContext *s);
 TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
 TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
 bool tag_checked, int log2_size);
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index a54feb2f61..bbdaac6ac7 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -449,14 +449,17 @@ INDEX_ri0100 esz:2 1 imm:s5 010001 rn:5 rd:5
 # SVE index generation (register start, register increment)
 INDEX_rr0100 .. 1 . 010011 . .  @rd_rn_rm
 
-### SVE Stack Allocation Group
+### SVE / Streaming SVE Stack Allocation Group
 
 # SVE stack frame adjustment
 ADDVL   0100 001 . 01010 .. .   @rd_rn_i6
+ADDSVL  0100 001 . 01011 .. .   @rd_rn_i6
 ADDPL   0100 011 . 01010 .. .   @rd_rn_i6
+ADDSPL  0100 011 . 01011 .. .   @rd_rn_i6
 
 # SVE stack frame size
 RDVL0100 101 1 01010 imm:s6 rd:5
+RDSVL   0100 101 1 01011 imm:s6 rd:5
 
 ### SVE Bitwise Shift - Unpredicated Group
 
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index efcfb919ff..498970f653 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1216,6 +1216,21 @@ static bool sme_access_check(DisasContext *s)
 return true;
 }
 
+/* Note that this function corresponds to CheckSMEEnabled. */
+bool sme_enabled_check(DisasContext *s)
+{
+/*
+ * Note that unlike sve_excp_el, we have not constrained sme_excp_el
+ * to be zero when fp_excp_el has priority.  This is because we need
+ * sme_excp_el by itself for cpregs access checks.
+ */
+if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
+s->fp_access_checked = true;
+return sme_access_check(s);
+}
+return fp_access_check_only(s);
+}
+
 /*
  * This utility function is for doing register extension with an
  * optional shift. You will likely want to pass a temporary for the
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 62b5f3040c..13bdd027a5 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1286,6 +1286,19 @@ static bool trans_ADDVL(DisasContext *s, arg_ADDVL *a)
 return true;
 }
 
+static bool trans_ADDSVL(DisasContext *s, arg_ADDSVL *a)
+{
+if (!dc_isar_feature(aa64_sme, s)) {
+return false;
+}
+if (sme_enabled_check(s)) {
+TCGv_i64 rd = cpu_reg_sp(s, a->rd);
+TCGv_i64 rn = cpu_reg_sp(s, a->rn);
+tcg_gen_addi_i64(rd, rn, a->imm * s->svl);
+}
+return true;
+}
+
 static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
 {
 if (!dc_isar_feature(aa64_sve, s)) {
@@ -1299,6 +1312,19 @@ static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
 return true;
 }
 
+static bool trans_ADDSPL(DisasContext *s, arg_ADDSPL *a)
+{
+if (!dc_isar_feature(aa64_sme, s)) {
+return false;
+}
+if (sme_enabled_check(s)) {
+TCGv_i64 rd = cpu_reg_sp(s, a->rd);
+TCGv_i64 rn = cpu_reg_sp(s, a->rn);
+tcg_gen_addi_i64(rd, rn, a->imm * (s->svl / 8));
+}
+return true;
+}
+
 static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
 {
 if (!dc_isar_feature(aa64_sve, s)) {
@@ -1311,6 +1337,18 @@ static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
 return true;
 }
 
+static bool trans_RDSVL(DisasContext *s, arg_RDSVL *a)
+{
+if (!dc_isar_feature(aa64_sme, s)) {
+return false;
+}
+if (sme_enabled_check(s)) {
+TCGv_i64 reg = cpu_reg(s, a->rd);
+tcg_gen_movi_i64(reg, a->imm * s->svl);
+}
+return true;
+}
+
 /*
  *** SVE Compute Vector Address Group
  */
-- 
2.34.1




[PATCH v3 42/51] linux-user/aarch64: Tidy target_restore_sigframe error return

2022-06-20 Thread Richard Henderson
Fold the return value setting into the goto, so each
point of failure need not do both.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/signal.c | 26 +++---
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 3cef2f44cf..8b352abb97 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -287,7 +287,6 @@ static int target_restore_sigframe(CPUARMState *env,
 struct target_sve_context *sve = NULL;
 uint64_t extra_datap = 0;
 bool used_extra = false;
-bool err = false;
 int vq = 0, sve_size = 0;
 
 target_restore_general_frame(env, sf);
@@ -301,8 +300,7 @@ static int target_restore_sigframe(CPUARMState *env,
 switch (magic) {
 case 0:
 if (size != 0) {
-err = true;
-goto exit;
+goto err;
 }
 if (used_extra) {
 ctx = NULL;
@@ -314,8 +312,7 @@ static int target_restore_sigframe(CPUARMState *env,
 
 case TARGET_FPSIMD_MAGIC:
 if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
-err = true;
-goto exit;
+goto err;
 }
 fpsimd = (struct target_fpsimd_context *)ctx;
 break;
@@ -329,13 +326,11 @@ static int target_restore_sigframe(CPUARMState *env,
 break;
 }
 }
-err = true;
-goto exit;
+goto err;
 
 case TARGET_EXTRA_MAGIC:
 if (extra || size != sizeof(struct target_extra_context)) {
-err = true;
-goto exit;
+goto err;
 }
 __get_user(extra_datap,
&((struct target_extra_context *)ctx)->datap);
@@ -348,8 +343,7 @@ static int target_restore_sigframe(CPUARMState *env,
 /* Unknown record -- we certainly didn't generate it.
  * Did we in fact get out of sync?
  */
-err = true;
-goto exit;
+goto err;
 }
 ctx = (void *)ctx + size;
 }
@@ -358,17 +352,19 @@ static int target_restore_sigframe(CPUARMState *env,
 if (fpsimd) {
 target_restore_fpsimd_record(env, fpsimd);
 } else {
-err = true;
+goto err;
 }
 
 /* SVE data, if present, overwrites FPSIMD data.  */
 if (sve) {
 target_restore_sve_record(env, sve, vq);
 }
-
- exit:
 unlock_user(extra, extra_datap, 0);
-return err;
+return 0;
+
+ err:
+unlock_user(extra, extra_datap, 0);
+return 1;
 }
 
 static abi_ulong get_sigframe(struct target_sigaction *ka,
-- 
2.34.1




[PATCH v3 51/51] linux-user/aarch64: Add SME related hwcap entries

2022-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/elfload.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index f7eae357f4..8135960305 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -601,6 +601,18 @@ enum {
 ARM_HWCAP2_A64_RNG  = 1 << 16,
 ARM_HWCAP2_A64_BTI  = 1 << 17,
 ARM_HWCAP2_A64_MTE  = 1 << 18,
+ARM_HWCAP2_A64_ECV  = 1 << 19,
+ARM_HWCAP2_A64_AFP  = 1 << 20,
+ARM_HWCAP2_A64_RPRES= 1 << 21,
+ARM_HWCAP2_A64_MTE3 = 1 << 22,
+ARM_HWCAP2_A64_SME  = 1 << 23,
+ARM_HWCAP2_A64_SME_I16I64   = 1 << 24,
+ARM_HWCAP2_A64_SME_F64F64   = 1 << 25,
+ARM_HWCAP2_A64_SME_I8I32= 1 << 26,
+ARM_HWCAP2_A64_SME_F16F32   = 1 << 27,
+ARM_HWCAP2_A64_SME_B16F32   = 1 << 28,
+ARM_HWCAP2_A64_SME_F32F32   = 1 << 29,
+ARM_HWCAP2_A64_SME_FA64 = 1 << 30,
 };
 
 #define ELF_HWCAP   get_elf_hwcap()
@@ -670,6 +682,14 @@ static uint32_t get_elf_hwcap2(void)
 GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
 GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
 GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
+GET_FEATURE_ID(aa64_sme, (ARM_HWCAP2_A64_SME |
+  ARM_HWCAP2_A64_SME_F32F32 |
+  ARM_HWCAP2_A64_SME_B16F32 |
+  ARM_HWCAP2_A64_SME_F16F32 |
+  ARM_HWCAP2_A64_SME_I8I32));
+GET_FEATURE_ID(aa64_sme_f64f64, ARM_HWCAP2_A64_SME_F64F64);
+GET_FEATURE_ID(aa64_sme_i16i64, ARM_HWCAP2_A64_SME_I16I64);
+GET_FEATURE_ID(aa64_sme_fa64, ARM_HWCAP2_A64_SME_FA64);
 
 return hwcaps;
 }
-- 
2.34.1




[PATCH v3 39/51] linux-user/aarch64: Clear tpidr2_el0 if CLONE_SETTLS

2022-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_cpu.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
index 97a477bd3e..f90359faf2 100644
--- a/linux-user/aarch64/target_cpu.h
+++ b/linux-user/aarch64/target_cpu.h
@@ -34,10 +34,13 @@ static inline void cpu_clone_regs_parent(CPUARMState *env, 
unsigned flags)
 
 static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
 {
-/* Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
+/*
+ * Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
  * different from AArch32 Linux, which uses TPIDRRO.
  */
 env->cp15.tpidr_el[0] = newtls;
+/* TPIDR2_EL0 is cleared with CLONE_SETTLS. */
+env->cp15.tpidr2_el0 = 0;
 }
 
 static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
-- 
2.34.1




[PATCH v3 45/51] linux-user/aarch64: Move sve record checks into restore

2022-06-20 Thread Richard Henderson
Move the checks out of the parsing loop and into the
restore function.  This more closely mirrors the code
structure in the kernel, and is slightly clearer.

Reject rather than silently skip incorrect VL and SVE record sizes.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/signal.c | 51 +
 1 file changed, 35 insertions(+), 16 deletions(-)

diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 9ff79da4be..22d0b8b4ec 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -250,12 +250,36 @@ static void target_restore_fpsimd_record(CPUARMState *env,
 }
 }
 
-static void target_restore_sve_record(CPUARMState *env,
-  struct target_sve_context *sve, int vq)
+static bool target_restore_sve_record(CPUARMState *env,
+  struct target_sve_context *sve,
+  int size)
 {
-int i, j;
+int i, j, vl, vq;
 
-/* Note that SVE regs are stored as a byte stream, with each byte element
+if (!cpu_isar_feature(aa64_sve, env_archcpu(env))) {
+return false;
+}
+
+__get_user(vl, >vl);
+vq = sve_vq(env);
+
+/* Reject mismatched VL. */
+if (vl != vq * TARGET_SVE_VQ_BYTES) {
+return false;
+}
+
+/* Accept empty record -- used to clear PSTATE.SM. */
+if (size <= sizeof(*sve)) {
+return true;
+}
+
+/* Reject non-empty but incomplete record. */
+if (size < TARGET_SVE_SIG_CONTEXT_SIZE(vq)) {
+return false;
+}
+
+/*
+ * Note that SVE regs are stored as a byte stream, with each byte element
  * at a subsequent address.  This corresponds to a little-endian load
  * of our 64-bit hunks.
  */
@@ -277,6 +301,7 @@ static void target_restore_sve_record(CPUARMState *env,
 }
 }
 }
+return true;
 }
 
 static int target_restore_sigframe(CPUARMState *env,
@@ -287,7 +312,7 @@ static int target_restore_sigframe(CPUARMState *env,
 struct target_sve_context *sve = NULL;
 uint64_t extra_datap = 0;
 bool used_extra = false;
-int vq = 0, sve_size = 0;
+int sve_size = 0;
 
 target_restore_general_frame(env, sf);
 
@@ -321,15 +346,9 @@ static int target_restore_sigframe(CPUARMState *env,
 if (sve || size < sizeof(struct target_sve_context)) {
 goto err;
 }
-if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
-vq = sve_vq(env);
-sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
-if (size == sve_size) {
-sve = (struct target_sve_context *)ctx;
-break;
-}
-}
-goto err;
+sve = (struct target_sve_context *)ctx;
+sve_size = size;
+break;
 
 case TARGET_EXTRA_MAGIC:
 if (extra || size != sizeof(struct target_extra_context)) {
@@ -362,8 +381,8 @@ static int target_restore_sigframe(CPUARMState *env,
 }
 
 /* SVE data, if present, overwrites FPSIMD data.  */
-if (sve) {
-target_restore_sve_record(env, sve, vq);
+if (sve && !target_restore_sve_record(env, sve, sve_size)) {
+goto err;
 }
 unlock_user(extra, extra_datap, 0);
 return 0;
-- 
2.34.1




Re: [PATCH 07/10] bsd-user: Implement chroot and flock

2022-06-20 Thread Richard Henderson

On 6/20/22 10:42, Warner Losh wrote:

Signed-off-by: Stacey Son
Signed-off-by: Warner Losh
---
  bsd-user/bsd-file.h   | 19 +++
  bsd-user/freebsd/os-syscall.c |  8 
  2 files changed, 27 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 08/10] bsd-user: Implement mkfifo and mkfifoat

2022-06-20 Thread Richard Henderson

On 6/20/22 10:42, Warner Losh wrote:

Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
  bsd-user/bsd-file.h   | 27 +++
  bsd-user/freebsd/os-syscall.c |  8 
  2 files changed, 35 insertions(+)


Reviewed-by: Richard Henderson 

r~




[PATCH v2 2/2] target/arm: Catch invalid kvm state also for hvf

2022-06-20 Thread Alexander Graf
Some features such as running in EL3 or running M profile code are
incompatible with virtualization as QEMU implements it today. To prevent
users from picking invalid configurations on other virt solutions like
Hvf, let's run the same checks there too.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1073
Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - Use current_accel_name()
  - Use !tcg_enabled()
---
 target/arm/cpu.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1b5d535788..0862dcd63c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1490,7 +1490,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 }
 }
 
-if (kvm_enabled()) {
+if (!tcg_enabled()) {
 /*
  * Catch all the cases which might cause us to create more than one
  * address space for the CPU (otherwise we will assert() later in
@@ -1498,17 +1498,20 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
  */
 if (arm_feature(env, ARM_FEATURE_M)) {
 error_setg(errp,
-   "Cannot enable KVM when using an M-profile guest CPU");
+   "Cannot enable %s when using an M-profile guest CPU",
+   current_accel_name());
 return;
 }
 if (cpu->has_el3) {
 error_setg(errp,
-   "Cannot enable KVM when guest CPU has EL3 enabled");
+   "Cannot enable %s when guest CPU has EL3 enabled",
+   current_accel_name());
 return;
 }
 if (cpu->tag_memory) {
 error_setg(errp,
-   "Cannot enable KVM when guest CPUs has MTE enabled");
+   "Cannot enable %s when guest CPUs has MTE enabled",
+   current_accel_name());
 return;
 }
 }
-- 
2.32.1 (Apple Git-133)




[PATCH v2 1/2] accel: Introduce current_accel_name()

2022-06-20 Thread Alexander Graf
We need to fetch the name of the current accelerator in flexible error
messages more going forward. Let's create a helper that gives it to us
without casting in the target code.

Signed-off-by: Alexander Graf 
---
 accel/accel-common.c | 8 
 include/qemu/accel.h | 1 +
 softmmu/vl.c | 3 +--
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/accel/accel-common.c b/accel/accel-common.c
index 7b8ec7e0f7..50035bda55 100644
--- a/accel/accel-common.c
+++ b/accel/accel-common.c
@@ -49,6 +49,14 @@ AccelClass *accel_find(const char *opt_name)
 return ac;
 }
 
+/* Return the name of the current accelerator */
+const char *current_accel_name(void)
+{
+AccelClass *ac = ACCEL_GET_CLASS(current_accel());
+
+return ac->name;
+}
+
 static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque)
 {
 CPUClass *cc = CPU_CLASS(klass);
diff --git a/include/qemu/accel.h b/include/qemu/accel.h
index 4f4c283f6f..be56da1b99 100644
--- a/include/qemu/accel.h
+++ b/include/qemu/accel.h
@@ -68,6 +68,7 @@ typedef struct AccelClass {
 
 AccelClass *accel_find(const char *opt_name);
 AccelState *current_accel(void);
+const char *current_accel_name(void);
 
 void accel_init_interfaces(AccelClass *ac);
 
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 54e920ada1..3dca5936c7 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2271,8 +2271,7 @@ static void configure_accelerators(const char *progname)
 }
 
 if (init_failed && !qtest_chrdev) {
-AccelClass *ac = ACCEL_GET_CLASS(current_accel());
-error_report("falling back to %s", ac->name);
+error_report("falling back to %s", current_accel_name());
 }
 
 if (icount_enabled() && !tcg_enabled()) {
-- 
2.32.1 (Apple Git-133)




Re: [PATCH 03/10] bsd-user: implement chmod, fchmod, lchmod and fchmodat

2022-06-20 Thread Richard Henderson

On 6/20/22 10:42, Warner Losh wrote:

Signed-off-by: Stacey Son
Signed-off-by: Warner Losh
---
  bsd-user/bsd-file.h   | 46 +++
  bsd-user/freebsd/os-syscall.c | 16 
  2 files changed, 62 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH] target/avr: Drop avr_cpu_memory_rw_debug()

2022-06-20 Thread Richard Henderson

On 3/22/22 02:50, Bin Meng wrote:

CPUClass::memory_rw_debug() holds a callback for GDB memory access.
If not provided, cpu_memory_rw_debug() is used by the GDB stub.
Drop avr_cpu_memory_rw_debug() which does nothing special.

Signed-off-by: Bin Meng 


Queued to tcg-next, for lack of anything better.


r~



[PATCH 3/3] target/ppc: Check page dir/table base alignment

2022-06-20 Thread Leandro Lupori
Check if each page dir/table base address is properly aligned and
log a guest error if not, as real hardware behave incorrectly in
this case.

These checks are only performed when DEBUG_MMU is defined, to avoid
hurting the performance.

Signed-off-by: Leandro Lupori 
---
 target/ppc/mmu-radix64.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 2f0bcbfe2e..80d945a7c3 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -28,6 +28,8 @@
 #include "mmu-radix64.h"
 #include "mmu-book3s-v3.h"
 
+/* #define DEBUG_MMU */
+
 static bool ppc_radix64_get_fully_qualified_addr(const CPUPPCState *env,
  vaddr eaddr,
  uint64_t *lpid, uint64_t *pid)
@@ -277,6 +279,16 @@ static int ppc_radix64_next_level(AddressSpace *as, vaddr 
eaddr,
 if (!(pde & R_PTE_LEAF)) { /* Prepare for next iteration */
 ++*level;
 *nls = pde & R_PDE_NLS;
+
+#ifdef DEBUG_MMU
+if ((pde & R_PDE_NLB) & MAKE_64BIT_MASK(0, *nls + 3)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: misaligned page dir/table base: 0x%"VADDR_PRIx
+" page dir size: 0x%"PRIx64" level: %d\n",
+__func__, (pde & R_PDE_NLB), BIT(*nls + 3), *level);
+}
+#endif
+
 index = eaddr >> (*psize - *nls);   /* Shift */
 index &= ((1UL << *nls) - 1);   /* Mask */
 *pte_addr = (pde & R_PDE_NLB) + (index * sizeof(pde));
@@ -297,6 +309,15 @@ static int ppc_radix64_walk_tree(AddressSpace *as, vaddr 
eaddr,
 return 1;
 }
 
+#ifdef DEBUG_MMU
+if (base_addr & MAKE_64BIT_MASK(0, nls + 3)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+"%s: misaligned page dir base: 0x%"VADDR_PRIx
+" page dir size: 0x%"PRIx64"\n",
+__func__, base_addr, BIT(nls + 3));
+}
+#endif
+
 index = eaddr >> (*psize - nls);/* Shift */
 index &= ((1UL << nls) - 1);   /* Mask */
 *pte_addr = base_addr + (index * sizeof(pde));
-- 
2.25.1




Re: [PATCH 04/10] bsd-user: Implement freebsd11_mknod, freebsd11_mknodat and mknodat

2022-06-20 Thread Warner Losh
On Mon, Jun 20, 2022 at 1:13 PM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 6/20/22 10:42, Warner Losh wrote:
> > These implement both the old-pre INO64 mknod variations, as well as the
> > now current INO64 variant. To implement the old stuff, we use some
> > linker magic to bind to the old versions of these functions.
> >
> > Signed-off-by: Stacey Son 
> > Signed-off-by: Michal Meloun 
> > Signed-off-by: Warner Losh 
> > ---
> >   bsd-user/bsd-file.h   | 59 +++
> >   bsd-user/freebsd/os-syscall.c | 15 +
> >   2 files changed, 74 insertions(+)
> >
> > diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
> > index 0585f6a2a40..3be832b2a74 100644
> > --- a/bsd-user/bsd-file.h
> > +++ b/bsd-user/bsd-file.h
> > @@ -51,6 +51,16 @@ do {\
> >   unlock_user(p1, arg1, 0);   \
> >   } while (0)
> >
> > +#ifndef BSD_HAVE_INO64
> > +#define freebsd11_mknod mknod
> > +#define freebsd11_mknodat   mknodat
> > +#else
> > +int freebsd11_mknod(char *path, mode_t mode, uint32_t dev);
> > +__sym_compat(mknod, freebsd11_mknod, FBSD_1.0);
> > +int freebsd11_mknodat(int fd, char *path, mode_t mode, uint32_t dev);
> > +__sym_compat(mknodat, freebsd11_mknodat, FBSD_1.1);
> > +#endif
>
> Where does BSD_HAVE_INO64 come from?  I can't find it defined in freebsd
> git.
>

It used to be defined conditionally on FreeBSD 12 vs earlier. Now it's
defined unconditionally
in a file that wasn't part of the upstreaming. I'll rework now that it's
unconditional because
there's no way we could run on a FreeBSD 11 system. Normally we'd just
retire these older
system calls to limit the scope of what we need to maintain, but we have to
have the old FreeBSD-11
era pre-INO64 system calls (here and elsewhere) to support rust since it
doesn't use libc at all.


> You should probably avoid the linker tricks and use direct syscalls of
> SYS_freebsd11_mknodat etc
>

Yea, on pre-ino64 systems, there were no system calls like that. Now that
we have them, I think
you are right that we'd be better off just using the system call directly
rather than needing this hack
to get the old system calls. the old symbols will be around forever, but
it's better to be more direct here.
There's nothing hidden in the libc versions of these symbols.

tl;dr: It's always defined now, so I'll unifdef it.

Warner


[PATCH v3] ui/cocoa: Take refresh rate into account

2022-06-20 Thread Akihiko Odaki
Retreieve the refresh rate of the display and reflect it with
dpy_set_ui_info() and update_displaychangelistener(), allowing the
guest and DisplayChangeListener to consume the information.

Signed-off-by: Akihiko Odaki 
---
 meson.build |  3 ++-
 ui/cocoa.m  | 12 
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 0c2e11ff071..0f83f3730af 100644
--- a/meson.build
+++ b/meson.build
@@ -575,7 +575,8 @@ if get_option('attr').allowed()
   endif
 endif
 
-cocoa = dependency('appleframeworks', modules: 'Cocoa', required: 
get_option('cocoa'))
+cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
+   required: get_option('cocoa'))
 if cocoa.found() and get_option('sdl').enabled()
   error('Cocoa and SDL cannot be enabled at the same time')
 endif
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 84c84e98fc5..a3949c6 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -561,8 +561,20 @@ - (void) updateUIInfoLocked
 CGDirectDisplayID display = [[description 
objectForKey:@"NSScreenNumber"] unsignedIntValue];
 NSSize screenSize = [[[self window] screen] frame].size;
 CGSize screenPhysicalSize = CGDisplayScreenSize(display);
+CVDisplayLinkRef displayLink;
 
 frameSize = isFullscreen ? screenSize : [self frame].size;
+
+if (!CVDisplayLinkCreateWithCGDisplay(display, )) {
+CVTime period = 
CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink);
+CVDisplayLinkRelease(displayLink);
+if (!(period.flags & kCVTimeIsIndefinite)) {
+update_displaychangelistener(,
+ 1000 * period.timeValue / 
period.timeScale);
+info.refresh_rate = (int64_t)1000 * period.timeScale / 
period.timeValue;
+}
+}
+
 info.width_mm = frameSize.width / screenSize.width * 
screenPhysicalSize.width;
 info.height_mm = frameSize.height / screenSize.height * 
screenPhysicalSize.height;
 } else {
-- 
2.32.1 (Apple Git-133)




Re: [PATCH 3/4] slirp: Add mfr-id to -netdev options

2022-06-20 Thread Peter Delevoryas


On Jun 20, 2022, at 12:16 AM, Markus Armbruster 
mailto:arm...@redhat.com>> wrote:

Peter Delevoryas mailto:p...@fb.com>> writes:

This lets you set the manufacturer's ID for a slirp netdev, which can be
queried from the guest through the Get Version ID NC-SI command. For
example, by setting the manufacturer's ID to 0x8119:

   wget 
https://github.com/facebook/openbmc/releases/download/openbmc-e2294ff5d31d/fby35.mtd
   qemu-system-arm -machine fby35-bmc \
   -drive file=fby35.mtd,format=raw,if=mtd -nographic \
   -netdev user,id=nic,mfr-id=0x8119,hostfwd=::-:22 \
   -net nic,model=ftgmac100,netdev=nic
   ...
   username: root
   password: 0penBmc
   ...
   root@bmc-oob:~# ncsi-util 0x15
   NC-SI Command Response:
   cmd: GET_VERSION_ID(0x15)
   Response: COMMAND_COMPLETED(0x)  Reason: NO_ERROR(0x)
   Payload length = 40

   20: 0xf1 0xf0 0xf0 0x00
   24: 0x00 0x00 0x00 0x00
   28: 0x00 0x00 0x00 0x00
   32: 0x00 0x00 0x00 0x00
   36: 0x00 0x00 0x00 0x00
   40: 0x00 0x00 0x00 0x00
   44: 0x00 0x00 0x00 0x00
   48: 0x00 0x00 0x00 0x00
   52: 0x00 0x00 0x81 0x19

Signed-off-by: Peter Delevoryas mailto:p...@fb.com>>
---

[...]

diff --git a/qapi/net.json b/qapi/net.json
index d6f7cfd4d6..efc5cb3fb6 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -167,6 +167,8 @@
#
# @tftp-server-name: RFC2132 "TFTP server name" string (Since 3.1)
#
+# @mfr-id: Manufacturer ID (Private Enterprise Number: IANA)
+#

Is 'mfr-id' an established technical term, or an abbreviation you came
up with?  If the latter, please use @manufacturer-id instead.

I don’t think so, I used that particular variable name throughout these patches
because that’s what the Linux kernel driver was using, but you’re right, we 
should
not use an abbreviation, in v2 I’ll change it to @manufacturer-id.


Documentation is rather terse.  It basically provides a bunch of
keywords you can throw at the search engine of your choice.  Can we cut
out that middle man and point straight to a suitable resource?

Erg, yeah, sorry about that, you’re right, it would probably be more useful
to point to the NC-SI specification directly:

https://www.dmtf.org/sites/default/files/standards/documents/DSP0222_1.0.0.pdf

Note: there have been some newer revisions to the specification lately, and the
full list of spec versions is here:

https://www.dmtf.org/dsp/DSP0222

Get Version ID and the OEM Vendor extension are both specified in 1.0.0, so I
think it should be ok to link to 1.0.0.

I’m not totally sure if I should directly link to the actual URL, but I’ll
definitely say: “This is defined in DMTF NC-SI 1.0.0” or something like that.
Unless URL’s in the code would be preferred. Theoretically, the DMTF
spec URL should be pretty long-lasting.

Thanks,
Peter


# Since: 1.2
##
{ 'struct': 'NetdevUserOptions',
@@ -192,7 +194,8 @@
'*smbserver': 'str',
'*hostfwd':   ['String'],
'*guestfwd':  ['String'],
-'*tftp-server-name': 'str' } }
+'*tftp-server-name': 'str',
+'*mfr-id': 'uint32' } }

##
# @NetdevTapOptions:




Re: [PATCH] migration: Remove RDMA_UNREGISTRATION_EXAMPLE

2022-06-20 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> Nobody has ever showed up to unregister individual pages, and another
> set of patches written by Daniel P. Berrangé 
> just remove qemu_rdma_signal_unregister() function needed here.
> 
> Signed-off-by: Juan Quintela 

Reviewed-by: Dr. David Alan Gilbert 

> ---
>  migration/rdma.c | 41 -
>  1 file changed, 41 deletions(-)
> 
> diff --git a/migration/rdma.c b/migration/rdma.c
> index 672d1958a9..8504152f39 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -1370,30 +1370,6 @@ const char *print_wrid(int wrid)
>  return wrid_desc[wrid];
>  }
>  
> -/*
> - * RDMA requires memory registration (mlock/pinning), but this is not good 
> for
> - * overcommitment.
> - *
> - * In preparation for the future where LRU information or workload-specific
> - * writable writable working set memory access behavior is available to QEMU
> - * it would be nice to have in place the ability to UN-register/UN-pin
> - * particular memory regions from the RDMA hardware when it is determine that
> - * those regions of memory will likely not be accessed again in the near 
> future.
> - *
> - * While we do not yet have such information right now, the following
> - * compile-time option allows us to perform a non-optimized version of this
> - * behavior.
> - *
> - * By uncommenting this option, you will cause *all* RDMA transfers to be
> - * unregistered immediately after the transfer completes on both sides of the
> - * connection. This has no effect in 'rdma-pin-all' mode, only regular mode.
> - *
> - * This will have a terrible impact on migration performance, so until future
> - * workload information or LRU information is available, do not attempt to 
> use
> - * this feature except for basic testing.
> - */
> -/* #define RDMA_UNREGISTRATION_EXAMPLE */
> -
>  /*
>   * Perform a non-optimized memory unregistration after every transfer
>   * for demonstration purposes, only if pin-all is not requested.
> @@ -1571,18 +1547,6 @@ static uint64_t qemu_rdma_poll(RDMAContext *rdma, 
> struct ibv_cq *cq,
>  if (rdma->nb_sent > 0) {
>  rdma->nb_sent--;
>  }
> -
> -if (!rdma->pin_all) {
> -/*
> - * FYI: If one wanted to signal a specific chunk to be 
> unregistered
> - * using LRU or workload-specific information, this is the 
> function
> - * you would call to do so. That chunk would then get 
> asynchronously
> - * unregistered later.
> - */
> -#ifdef RDMA_UNREGISTRATION_EXAMPLE
> -qemu_rdma_signal_unregister(rdma, index, chunk, wc.wr_id);
> -#endif
> -}
>  } else {
>  trace_qemu_rdma_poll_other(print_wrid(wr_id), wr_id, rdma->nb_sent);
>  }
> @@ -2137,11 +2101,6 @@ retry:
>  
>  chunk_end = ram_chunk_end(block, chunk + chunks);
>  
> -if (!rdma->pin_all) {
> -#ifdef RDMA_UNREGISTRATION_EXAMPLE
> -qemu_rdma_unregister_waiting(rdma);
> -#endif
> -}
>  
>  while (test_bit(chunk, block->transit_bitmap)) {
>  (void)count;
> -- 
> 2.35.3
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




[PATCH 08/10] bsd-user: Implement mkfifo and mkfifoat

2022-06-20 Thread Warner Losh
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-file.h   | 27 +++
 bsd-user/freebsd/os-syscall.c |  8 
 2 files changed, 35 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index f11369655a0..0b4b89c8d5c 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -880,4 +880,31 @@ static abi_long do_bsd_flock(abi_long arg1, abi_long arg2)
 return get_errno(flock(arg1, arg2));
 }
 
+/* mkfifo(2) */
+static abi_long do_bsd_mkfifo(abi_long arg1, abi_long arg2)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(mkfifo(p, arg2)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* mkfifoat(2) */
+static abi_long do_bsd_mkfifoat(abi_long arg1, abi_long arg2,
+abi_long arg3)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg2);
+ret = get_errno(mkfifoat(arg1, p, arg3));
+UNLOCK_PATH(p, arg2);
+
+return ret;
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index f3fb585b7ec..ff3893b9197 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -469,6 +469,14 @@ static abi_long freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 ret = do_bsd_flock(arg1, arg2);
 break;
 
+case TARGET_FREEBSD_NR_mkfifo: /* mkfifo(2) */
+ret = do_bsd_mkfifo(arg1, arg2);
+break;
+
+case TARGET_FREEBSD_NR_mkfifoat: /* mkfifoat(2) */
+ret = do_bsd_mkfifoat(arg1, arg2, arg3);
+break;
+
 default:
 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
 ret = -TARGET_ENOSYS;
-- 
2.33.1




[PATCH 06/10] bsd-user: Implement chflags, lchflags and fchflags

2022-06-20 Thread Warner Losh
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-file.h   | 32 
 bsd-user/freebsd/os-syscall.c | 12 
 2 files changed, 44 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index 152579ad541..f5375a39a2c 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -829,4 +829,36 @@ static abi_long do_bsd_fchownat(abi_long arg1, abi_long 
arg2,
 return ret;
 }
 
+/* chflags(2) */
+static abi_long do_bsd_chflags(abi_long arg1, abi_long arg2)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(chflags(p, arg2)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* lchflags(2) */
+static abi_long do_bsd_lchflags(abi_long arg1, abi_long arg2)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(lchflags(p, arg2)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* fchflags(2) */
+static abi_long do_bsd_fchflags(abi_long arg1, abi_long arg2)
+{
+return get_errno(fchflags(arg1, arg2));
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 4d10334ef21..d10635eae05 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -449,6 +449,18 @@ static abi_long freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 ret = do_bsd_fchownat(arg1, arg2, arg3, arg4, arg5);
 break;
 
+case TARGET_FREEBSD_NR_chflags: /* chflags(2) */
+ret = do_bsd_chflags(arg1, arg2);
+break;
+
+case TARGET_FREEBSD_NR_lchflags: /* lchflags(2) */
+ret = do_bsd_lchflags(arg1, arg2);
+break;
+
+case TARGET_FREEBSD_NR_fchflags: /* fchflags(2) */
+ret = do_bsd_fchflags(arg1, arg2);
+break;
+
 default:
 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
 ret = -TARGET_ENOSYS;
-- 
2.33.1




[PATCH 10/10] bsd-user: Implement undelete

2022-06-20 Thread Warner Losh
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-file.h   | 13 +
 bsd-user/freebsd/os-syscall.c |  4 
 2 files changed, 17 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index 79eb5a73a9b..94e756ae550 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -939,4 +939,17 @@ static abi_long do_bsd_fpathconf(abi_long arg1, abi_long 
arg2)
 return get_errno(fpathconf(arg1, arg2));
 }
 
+/* undelete(2) */
+static abi_long do_bsd_undelete(abi_long arg1)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(undelete(p)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index ee08b74bdd5..7d791aeb91b 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -489,6 +489,10 @@ static abi_long freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 ret = do_bsd_fpathconf(arg1, arg2);
 break;
 
+case TARGET_FREEBSD_NR_undelete: /* undelete(2) */
+ret = do_bsd_undelete(arg1);
+break;
+
 default:
 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
 ret = -TARGET_ENOSYS;
-- 
2.33.1




[PATCH v3 08/51] target/arm: Add PSTATE.{SM,ZA} to TB flags

2022-06-20 Thread Richard Henderson
These are required to determine if various insns
are allowed to issue.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   | 2 ++
 target/arm/translate.h | 4 
 target/arm/helper.c| 4 
 target/arm/translate-a64.c | 2 ++
 4 files changed, 12 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index dec52c6c3b..05d369e690 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3160,6 +3160,8 @@ FIELD(TBFLAG_A64, TCMA, 16, 2)
 FIELD(TBFLAG_A64, MTE_ACTIVE, 18, 1)
 FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
 FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
+FIELD(TBFLAG_A64, PSTATE_SM, 22, 1)
+FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
 
 /*
  * Helpers for using the above.
diff --git a/target/arm/translate.h b/target/arm/translate.h
index c88c953325..93766649f7 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -97,6 +97,10 @@ typedef struct DisasContext {
 bool align_mem;
 /* True if PSTATE.IL is set */
 bool pstate_il;
+/* True if PSTATE.SM is set. */
+bool pstate_sm;
+/* True if PSTATE.ZA is set. */
+bool pstate_za;
 /* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
 bool mve_no_pred;
 /*
diff --git a/target/arm/helper.c b/target/arm/helper.c
index bbd04fbd67..e06c054c3d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11335,6 +11335,10 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState 
*env, int el, int fp_el,
 }
 if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
 DP_TBFLAG_A64(flags, SMEEXC_EL, sme_exception_el(env, el));
+if (FIELD_EX64(env->svcr, SVCR, SM)) {
+DP_TBFLAG_A64(flags, PSTATE_SM, 1);
+}
+DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA));
 }
 
 sctlr = regime_sctlr(env, stage1);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 8f609f46b6..5cf4a283ba 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14630,6 +14630,8 @@ static void 
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
 dc->ata = EX_TBFLAG_A64(tb_flags, ATA);
 dc->mte_active[0] = EX_TBFLAG_A64(tb_flags, MTE_ACTIVE);
 dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
+dc->pstate_sm = EX_TBFLAG_A64(tb_flags, PSTATE_SM);
+dc->pstate_za = EX_TBFLAG_A64(tb_flags, PSTATE_ZA);
 dc->vec_len = 0;
 dc->vec_stride = 0;
 dc->cp_regs = arm_cpu->cp_regs;
-- 
2.34.1




[PATCH v3 06/51] target/arm: Add SMCR_ELx

2022-06-20 Thread Richard Henderson
These cpregs control the streaming vector length and whether the
full a64 instruction set is allowed while in streaming mode.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h|  8 ++--
 target/arm/helper.c | 41 +
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bb8cb959d1..dec52c6c3b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -669,8 +669,8 @@ typedef struct CPUArchState {
 float_status standard_fp_status;
 float_status standard_fp_status_f16;
 
-/* ZCR_EL[1-3] */
-uint64_t zcr_el[4];
+uint64_t zcr_el[4];   /* ZCR_EL[1-3] */
+uint64_t smcr_el[4];  /* SMCR_EL[1-3] */
 } vfp;
 uint64_t exclusive_addr;
 uint64_t exclusive_val;
@@ -1434,6 +1434,10 @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
 FIELD(SVCR, SM, 0, 1)
 FIELD(SVCR, ZA, 1, 1)
 
+/* Fields for SMCR_ELx. */
+FIELD(SMCR, LEN, 0, 4)
+FIELD(SMCR, FA64, 31, 1)
+
 /* Write a new value to v7m.exception, thus transitioning into or out
  * of Handler mode; this may result in a change of active stack pointer.
  */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3acc1dc378..2072f2a550 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5879,6 +5879,8 @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU 
*cpu)
  */
 { K(3, 0,  1, 2, 0), K(3, 4,  1, 2, 0), K(3, 5, 1, 2, 0),
   "ZCR_EL1", "ZCR_EL2", "ZCR_EL12", isar_feature_aa64_sve },
+{ K(3, 0,  1, 2, 6), K(3, 4,  1, 2, 6), K(3, 5, 1, 2, 6),
+  "SMCR_EL1", "SMCR_EL2", "SMCR_EL12", isar_feature_aa64_sme },
 
 { K(3, 0,  5, 6, 0), K(3, 4,  5, 6, 0), K(3, 5, 5, 6, 0),
   "TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
@@ -6357,6 +6359,30 @@ static void svcr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 env->svcr = value;
 }
 
+static void smcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+   uint64_t value)
+{
+int cur_el = arm_current_el(env);
+int old_len = sve_vqm1_for_el(env, cur_el);
+int new_len;
+
+QEMU_BUILD_BUG_ON(ARM_MAX_VQ > R_SMCR_LEN_MASK + 1);
+value &= R_SMCR_LEN_MASK | R_SMCR_FA64_MASK;
+raw_write(env, ri, value);
+
+/*
+ * Note that it is CONSTRAINED UNPREDICTABLE what happens to ZA storage
+ * when SVL is widened (old values kept, or zeros).  Choose to keep the
+ * current values for simplicity.  But for QEMU internals, we must still
+ * apply the narrower SVL to the Zregs and Pregs -- see the comment
+ * above aarch64_sve_narrow_vq.
+ */
+new_len = sve_vqm1_for_el(env, cur_el);
+if (new_len < old_len) {
+aarch64_sve_narrow_vq(env, new_len + 1);
+}
+}
+
 static const ARMCPRegInfo sme_reginfo[] = {
 { .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
@@ -6367,6 +6393,21 @@ static const ARMCPRegInfo sme_reginfo[] = {
   .access = PL0_RW, .type = ARM_CP_SME,
   .fieldoffset = offsetof(CPUARMState, svcr),
   .writefn = svcr_write, .raw_writefn = raw_write },
+{ .name = "SMCR_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 6,
+  .access = PL1_RW, .type = ARM_CP_SME,
+  .fieldoffset = offsetof(CPUARMState, vfp.smcr_el[1]),
+  .writefn = smcr_write, .raw_writefn = raw_write },
+{ .name = "SMCR_EL2", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 6,
+  .access = PL2_RW, .type = ARM_CP_SME,
+  .fieldoffset = offsetof(CPUARMState, vfp.smcr_el[2]),
+  .writefn = smcr_write, .raw_writefn = raw_write },
+{ .name = "SMCR_EL3", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 6,
+  .access = PL3_RW, .type = ARM_CP_SME,
+  .fieldoffset = offsetof(CPUARMState, vfp.smcr_el[3]),
+  .writefn = smcr_write, .raw_writefn = raw_write },
 };
 #endif /* TARGET_AARCH64 */
 
-- 
2.34.1




[PATCH v3 14/51] target/arm: Generalize cpu_arm_{get, set}_default_vec_len

2022-06-20 Thread Richard Henderson
Rename from cpu_arm_{get,set}_sve_default_vec_len,
and take the pointer to default_vq from opaque.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu64.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 1a3cb953bf..b15a0d398a 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -638,11 +638,11 @@ static void cpu_arm_set_sve(Object *obj, bool value, 
Error **errp)
 
 #ifdef CONFIG_USER_ONLY
 /* Mirror linux /proc/sys/abi/sve_default_vector_length. */
-static void cpu_arm_set_sve_default_vec_len(Object *obj, Visitor *v,
-const char *name, void *opaque,
-Error **errp)
+static void cpu_arm_set_default_vec_len(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
 {
-ARMCPU *cpu = ARM_CPU(obj);
+uint32_t *ptr_default_vq = opaque;
 int32_t default_len, default_vq, remainder;
 
 if (!visit_type_int32(v, name, _len, errp)) {
@@ -651,7 +651,7 @@ static void cpu_arm_set_sve_default_vec_len(Object *obj, 
Visitor *v,
 
 /* Undocumented, but the kernel allows -1 to indicate "maximum". */
 if (default_len == -1) {
-cpu->sve_default_vq = ARM_MAX_VQ;
+*ptr_default_vq = ARM_MAX_VQ;
 return;
 }
 
@@ -675,15 +675,15 @@ static void cpu_arm_set_sve_default_vec_len(Object *obj, 
Visitor *v,
 return;
 }
 
-cpu->sve_default_vq = default_vq;
+*ptr_default_vq = default_vq;
 }
 
-static void cpu_arm_get_sve_default_vec_len(Object *obj, Visitor *v,
-const char *name, void *opaque,
-Error **errp)
+static void cpu_arm_get_default_vec_len(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
 {
-ARMCPU *cpu = ARM_CPU(obj);
-int32_t value = cpu->sve_default_vq * 16;
+uint32_t *ptr_default_vq = opaque;
+int32_t value = *ptr_default_vq * 16;
 
 visit_type_int32(v, name, , errp);
 }
@@ -706,8 +706,9 @@ void aarch64_add_sve_properties(Object *obj)
 #ifdef CONFIG_USER_ONLY
 /* Mirror linux /proc/sys/abi/sve_default_vector_length. */
 object_property_add(obj, "sve-default-vector-length", "int32",
-cpu_arm_get_sve_default_vec_len,
-cpu_arm_set_sve_default_vec_len, NULL, NULL);
+cpu_arm_get_default_vec_len,
+cpu_arm_set_default_vec_len, NULL,
+>sve_default_vq);
 #endif
 }
 
-- 
2.34.1




[PATCH v3 16/51] target/arm: Unexport aarch64_add_*_properties

2022-06-20 Thread Richard Henderson
These functions are not used outside cpu64.c,
so make them static.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   | 3 ---
 target/arm/cpu64.c | 4 ++--
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d8ff78d96d..c73f289125 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1097,8 +1097,6 @@ int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t 
*buf, int reg);
 void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
 void aarch64_sve_change_el(CPUARMState *env, int old_el,
int new_el, bool el0_a64);
-void aarch64_add_sve_properties(Object *obj);
-void aarch64_add_pauth_properties(Object *obj);
 void arm_reset_sve_state(CPUARMState *env);
 
 /*
@@ -1130,7 +1128,6 @@ static inline void aarch64_sve_narrow_vq(CPUARMState 
*env, unsigned vq) { }
 static inline void aarch64_sve_change_el(CPUARMState *env, int o,
  int n, bool a)
 { }
-static inline void aarch64_add_sve_properties(Object *obj) { }
 #endif
 
 void aarch64_sync_32_to_64(CPUARMState *env);
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index b15a0d398a..6f6ee57a91 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -689,7 +689,7 @@ static void cpu_arm_get_default_vec_len(Object *obj, 
Visitor *v,
 }
 #endif
 
-void aarch64_add_sve_properties(Object *obj)
+static void aarch64_add_sve_properties(Object *obj)
 {
 ARMCPU *cpu = ARM_CPU(obj);
 uint32_t vq;
@@ -752,7 +752,7 @@ static Property arm_cpu_pauth_property =
 static Property arm_cpu_pauth_impdef_property =
 DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
 
-void aarch64_add_pauth_properties(Object *obj)
+static void aarch64_add_pauth_properties(Object *obj)
 {
 ARMCPU *cpu = ARM_CPU(obj);
 
-- 
2.34.1




[PATCH v3 09/51] target/arm: Add the SME ZA storage to CPUARMState

2022-06-20 Thread Richard Henderson
Place this late in the resettable section of the structure,
to keep the most common element offsets from being > 64k.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h |  8 
 target/arm/machine.c | 34 ++
 2 files changed, 42 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 05d369e690..c3c7ec697d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -694,6 +694,14 @@ typedef struct CPUArchState {
 } keys;
 
 uint64_t scxtnum_el[4];
+
+/*
+ * SME ZA storage -- 256 x 256 byte array, with bytes in host word order,
+ * as we do with vfp.zregs[].  Because this is so large, keep this toward
+ * the end of the reset area, to keep the offsets into the rest of the
+ * structure smaller.
+ */
+ARMVectorReg zarray[ARM_MAX_VQ * 16];
 #endif
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target/arm/machine.c b/target/arm/machine.c
index 285e387d2c..54c5c62433 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -167,6 +167,39 @@ static const VMStateDescription vmstate_sve = {
 VMSTATE_END_OF_LIST()
 }
 };
+
+static const VMStateDescription vmstate_vreg = {
+.name = "vreg",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT64_ARRAY(d, ARMVectorReg, ARM_MAX_VQ * 2),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static bool za_needed(void *opaque)
+{
+ARMCPU *cpu = opaque;
+
+/*
+ * When ZA storage is disabled, its contents are discarded.
+ * It will be zeroed when ZA storage is re-enabled.
+ */
+return FIELD_EX64(cpu->env.svcr, SVCR, ZA);
+}
+
+static const VMStateDescription vmstate_za = {
+.name = "cpu/sme",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = za_needed,
+.fields = (VMStateField[]) {
+VMSTATE_STRUCT_ARRAY(env.zarray, ARMCPU, ARM_MAX_VQ * 16, 0,
+ vmstate_vreg, ARMVectorReg),
+VMSTATE_END_OF_LIST()
+}
+};
 #endif /* AARCH64 */
 
 static bool serror_needed(void *opaque)
@@ -884,6 +917,7 @@ const VMStateDescription vmstate_arm_cpu = {
 _m_security,
 #ifdef TARGET_AARCH64
 _sve,
+_za,
 #endif
 _serror,
 _irq_line_state,
-- 
2.34.1




[PATCH v3 32/51] target/arm: Implement FMOPA, FMOPS (widening)

2022-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-sme.h|  2 ++
 target/arm/sme.decode  |  1 +
 target/arm/sme_helper.c| 74 ++
 target/arm/translate-sme.c |  2 ++
 4 files changed, 79 insertions(+)

diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
index 6b36542133..ecc957be14 100644
--- a/target/arm/helper-sme.h
+++ b/target/arm/helper-sme.h
@@ -120,6 +120,8 @@ DEF_HELPER_FLAGS_5(sme_addva_s, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_7(sme_fmopa_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
index afd9c0dffd..e8d27fd8a0 100644
--- a/target/arm/sme.decode
+++ b/target/arm/sme.decode
@@ -75,3 +75,4 @@ FMOPA_s 1000 100 . ... ... . . 00 ..  
  @op_32
 FMOPA_d 1000 110 . ... ... . . 0 ...@op_64
 
 BFMOPA  1001 100 . ... ... . . 00 ..@op_32
+FMOPA_h 1001 101 . ... ... . . 00 ..@op_32
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
index 61bab73cb7..6863a204d4 100644
--- a/target/arm/sme_helper.c
+++ b/target/arm/sme_helper.c
@@ -981,6 +981,80 @@ static inline uint32_t f16mop_adj_pair(uint32_t pair, 
uint32_t pg, uint32_t neg)
 return pair;
 }
 
+static float32 f16_dotadd(float32 sum, uint32_t e1, uint32_t e2,
+  float_status *s)
+{
+float64 e1r = float16_to_float64(e1 & 0x, true, s);
+float64 e1c = float16_to_float64(e1 >> 16, true, s);
+float64 e2r = float16_to_float64(e2 & 0x, true, s);
+float64 e2c = float16_to_float64(e2 >> 16, true, s);
+float64 t64;
+float32 t32;
+
+/*
+ * The ARM pseudocode function FPDot performs both multiplies
+ * and the add with a single rounding operation.  Emulate this
+ * by performing the first multiply in round-to-odd, then doing
+ * the second multiply as fused multiply-add, and rounding to
+ * float32 all in one step.
+ */
+FloatRoundMode old_rm = get_float_rounding_mode(s);
+set_float_rounding_mode(float_round_to_odd, s);
+
+t64 = float64_mul(e1r, e2r, s);
+
+set_float_rounding_mode(old_rm, s);
+
+t64 = float64r32_muladd(e1c, e2c, t64, 0, s);
+
+/* This conversion is exact, because we've already rounded. */
+t32 = float64_to_float32(t64, s);
+
+/* The final accumulation step is not fused. */
+return float32_add(sum, t32, s);
+}
+
+void HELPER(sme_fmopa_h)(void *vza, void *vzn, void *vzm, void *vpn,
+ void *vpm, void *vst, uint32_t desc)
+{
+intptr_t row, col, oprsz = simd_maxsz(desc);
+uint32_t neg = simd_data(desc) << 15;
+uint16_t *pn = vpn, *pm = vpm;
+
+bool save_dn = get_default_nan_mode(vst);
+set_default_nan_mode(true, vst);
+
+for (row = 0; row < oprsz; ) {
+uint16_t pa = pn[H2(row >> 4)];
+do {
+void *vza_row = vza + row * sizeof(ARMVectorReg);
+uint32_t n = *(uint32_t *)(vzn + row);
+
+n = f16mop_adj_pair(n, pa, neg);
+
+for (col = 0; col < oprsz; ) {
+uint16_t pb = pm[H2(col >> 4)];
+do {
+if ((pa & 0b0101) == 0b0101 || (pb & 0b0101) == 0b0101) {
+uint32_t *a = vza_row + col;
+uint32_t m = *(uint32_t *)(vzm + col);
+
+m = f16mop_adj_pair(m, pb, neg);
+*a = f16_dotadd(*a, n, m, vst);
+
+col += 4;
+pb >>= 4;
+}
+} while (col & 15);
+}
+row += 4;
+pa >>= 4;
+} while (row & 15);
+}
+
+set_default_nan_mode(save_dn, vst);
+}
+
 void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
 void *vpm, uint32_t desc)
 {
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
index 581bf9174f..847f2274b1 100644
--- a/target/arm/translate-sme.c
+++ b/target/arm/translate-sme.c
@@ -328,6 +328,8 @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, 
MemOp esz,
 return true;
 }
 
+TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_fpst,
+   a, MO_32, gen_helper_sme_fmopa_h)
 TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst,
a, MO_32, gen_helper_sme_fmopa_s)
 TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst,
-- 
2.34.1




[PATCH v3 12/51] target/arm: Create ARMVQMap

2022-06-20 Thread Richard Henderson
Pull the three sve_vq_* values into a structure.
This will be reused for SME.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h| 29 ++---
 target/arm/cpu64.c  | 22 +++---
 target/arm/helper.c |  2 +-
 target/arm/kvm64.c  |  2 +-
 4 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 2e049291da..ece720a757 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -793,6 +793,19 @@ typedef enum ARMPSCIState {
 
 typedef struct ARMISARegisters ARMISARegisters;
 
+/*
+ * In map, each set bit is a supported vector length of (bit-number + 1) * 16
+ * bytes, i.e. each bit number + 1 is the vector length in quadwords.
+ *
+ * While processing properties during initialization, corresponding init bits
+ * are set for bits in sve_vq_map that have been set by properties.
+ *
+ * Bits set in supported represent valid vector lengths for the CPU type.
+ */
+typedef struct {
+uint32_t map, init, supported;
+} ARMVQMap;
+
 /**
  * ARMCPU:
  * @env: #CPUARMState
@@ -1041,21 +1054,7 @@ struct ArchCPU {
 uint32_t sve_default_vq;
 #endif
 
-/*
- * In sve_vq_map each set bit is a supported vector length of
- * (bit-number + 1) * 16 bytes, i.e. each bit number + 1 is the vector
- * length in quadwords.
- *
- * While processing properties during initialization, corresponding
- * sve_vq_init bits are set for bits in sve_vq_map that have been
- * set by properties.
- *
- * Bits set in sve_vq_supported represent valid vector lengths for
- * the CPU type.
- */
-uint32_t sve_vq_map;
-uint32_t sve_vq_init;
-uint32_t sve_vq_supported;
+ARMVQMap sve_vq;
 
 /* Generic timer counter frequency, in Hz */
 uint64_t gt_cntfrq_hz;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index a46e40f4f2..cadc401c7e 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -355,8 +355,8 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
  * any of the above.  Finally, if SVE is not disabled, then at least one
  * vector length must be enabled.
  */
-uint32_t vq_map = cpu->sve_vq_map;
-uint32_t vq_init = cpu->sve_vq_init;
+uint32_t vq_map = cpu->sve_vq.map;
+uint32_t vq_init = cpu->sve_vq.init;
 uint32_t vq_supported;
 uint32_t vq_mask = 0;
 uint32_t tmp, vq, max_vq = 0;
@@ -369,14 +369,14 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
  */
 if (kvm_enabled()) {
 if (kvm_arm_sve_supported()) {
-cpu->sve_vq_supported = kvm_arm_sve_get_vls(CPU(cpu));
-vq_supported = cpu->sve_vq_supported;
+cpu->sve_vq.supported = kvm_arm_sve_get_vls(CPU(cpu));
+vq_supported = cpu->sve_vq.supported;
 } else {
 assert(!cpu_isar_feature(aa64_sve, cpu));
 vq_supported = 0;
 }
 } else {
-vq_supported = cpu->sve_vq_supported;
+vq_supported = cpu->sve_vq.supported;
 }
 
 /*
@@ -534,7 +534,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
 
 /* From now on sve_max_vq is the actual maximum supported length. */
 cpu->sve_max_vq = max_vq;
-cpu->sve_vq_map = vq_map;
+cpu->sve_vq.map = vq_map;
 }
 
 static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
@@ -595,7 +595,7 @@ static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, 
const char *name,
 if (!cpu_isar_feature(aa64_sve, cpu)) {
 value = false;
 } else {
-value = extract32(cpu->sve_vq_map, vq - 1, 1);
+value = extract32(cpu->sve_vq.map, vq - 1, 1);
 }
 visit_type_bool(v, name, , errp);
 }
@@ -611,8 +611,8 @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
-cpu->sve_vq_map = deposit32(cpu->sve_vq_map, vq - 1, 1, value);
-cpu->sve_vq_init |= 1 << (vq - 1);
+cpu->sve_vq.map = deposit32(cpu->sve_vq.map, vq - 1, 1, value);
+cpu->sve_vq.init |= 1 << (vq - 1);
 }
 
 static bool cpu_arm_get_sve(Object *obj, Error **errp)
@@ -974,7 +974,7 @@ static void aarch64_max_initfn(Object *obj)
 cpu->dcz_blocksize = 7; /*  512 bytes */
 #endif
 
-cpu->sve_vq_supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
+cpu->sve_vq.supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
 
 aarch64_add_pauth_properties(obj);
 aarch64_add_sve_properties(obj);
@@ -1023,7 +1023,7 @@ static void aarch64_a64fx_initfn(Object *obj)
 
 /* The A64FX supports only 128, 256 and 512 bit vector lengths */
 aarch64_add_sve_properties(obj);
-cpu->sve_vq_supported = (1 << 0)  /* 128bit */
+cpu->sve_vq.supported = (1 << 0)  /* 128bit */
   | (1 << 1)  /* 256bit */
   | (1 << 3); /* 512bit */
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 88d96f7991..a80ca461e5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6287,7 +6287,7 @@ 

[PATCH v3 17/51] target/arm: Add cpu properties for SME

2022-06-20 Thread Richard Henderson
Mirror the properties for SVE.  The main difference is
that any arbitrary set of powers of 2 may be supported,
and not the stricter constraints that apply to SVE.

Include a property to control FEAT_SME_FA64, as failing
to restrict the runtime to the proper subset of insns
could be a major point for bugs.

Signed-off-by: Richard Henderson 
---
 docs/system/arm/cpu-features.rst |  56 +++
 target/arm/cpu.h |   2 +
 target/arm/internals.h   |   1 +
 target/arm/cpu.c |  14 +++-
 target/arm/cpu64.c   | 114 +--
 5 files changed, 180 insertions(+), 7 deletions(-)

diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
index 3e626c4b68..3fd76fa0b4 100644
--- a/docs/system/arm/cpu-features.rst
+++ b/docs/system/arm/cpu-features.rst
@@ -372,6 +372,31 @@ verbose command lines.  However, the recommended way to 
select vector
 lengths is to explicitly enable each desired length.  Therefore only
 example's (1), (4), and (6) exhibit recommended uses of the properties.
 
+SME CPU Property Examples
+-
+
+  1) Disable SME::
+
+ $ qemu-system-aarch64 -M virt -cpu max,sme=off
+
+  2) Implicitly enable all vector lengths for the ``max`` CPU type::
+
+ $ qemu-system-aarch64 -M virt -cpu max
+
+  3) Only enable the 256-bit vector length::
+
+ $ qemu-system-aarch64 -M virt -cpu max,sme256=on
+
+  3) Enable the 256-bit and 1024-bit vector lengths::
+
+ $ qemu-system-aarch64 -M virt -cpu max,sme256=on,sme1024=on
+
+  4) Disable the 512-bit vector length.  This results in all the other
+ lengths supported by ``max`` defaulting to enabled
+ (128, 256, 1024 and 2048)::
+
+ $ qemu-system-aarch64 -M virt -cpu max,sve512=off
+
 SVE User-mode Default Vector Length Property
 
 
@@ -387,3 +412,34 @@ length supported by QEMU is 256.
 
 If this property is set to ``-1`` then the default vector length
 is set to the maximum possible length.
+
+SME CPU Properties
+==
+
+The SME CPU properties are much like the SVE properties: ``sme`` is
+used to enable or disable the entire SME feature, and ``sme`` is
+used to enable or disable specific vector lengths.  Finally,
+``sme_fa64`` is used to enable or disable ``FEAT_SME_FA64``, which
+allows execution of the "full a64" instruction set while Streaming
+SVE mode is enabled.
+
+SME is not supported by KVM at this time.
+
+At least one vector length must be enabled when ``sme`` is enabled,
+and all vector lengths must be powers of 2.  The maximum vector
+length supported by qemu is 2048 bits.  Otherwise, there are no
+additional constraints on the set of vector lengths supported by SME.
+
+SME User-mode Default Vector Length Property
+
+
+For qemu-aarch64, the cpu propery ``sme-default-vector-length=N`` is
+defined to mirror the Linux kernel parameter file
+``/proc/sys/abi/sme_default_vector_length``.  The default length, ``N``,
+is in units of bytes and must be between 16 and 8192.
+If not specified, the default vector length is 32.
+
+As with ``sve-default-vector-length``, if the default length is larger
+than the maximum vector length enabled, the actual vector length will
+be reduced.  If this property is set to ``-1`` then the default vector
+length is set to the maximum possible length.
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c73f289125..8b00d29af4 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1046,9 +1046,11 @@ struct ArchCPU {
 #ifdef CONFIG_USER_ONLY
 /* Used to set the default vector length at process start. */
 uint32_t sve_default_vq;
+uint32_t sme_default_vq;
 #endif
 
 ARMVQMap sve_vq;
+ARMVQMap sme_vq;
 
 /* Generic timer counter frequency, in Hz */
 uint64_t gt_cntfrq_hz;
diff --git a/target/arm/internals.h b/target/arm/internals.h
index aef568adf7..c66f74a0db 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1289,6 +1289,7 @@ int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, 
int reg);
 int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
 int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
 void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
+void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp);
 void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
 void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
 #endif
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index b5276fa944..75295a14a3 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1122,11 +1122,13 @@ static void arm_cpu_initfn(Object *obj)
 #ifdef CONFIG_USER_ONLY
 # ifdef TARGET_AARCH64
 /*
- * The linux kernel defaults to 512-bit vectors, when sve is supported.
- * See documentation for /proc/sys/abi/sve_default_vector_length, and
- * our corresponding sve-default-vector-length cpu property.
+ * The linux kernel 

[PATCH v3 24/51] target/arm: Implement SME ZERO

2022-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-sme.h|  2 ++
 target/arm/translate-a64.h |  1 +
 target/arm/sme.decode  |  4 
 target/arm/sme_helper.c| 25 +
 target/arm/translate-a64.c | 14 ++
 target/arm/translate-sme.c | 13 +
 6 files changed, 59 insertions(+)

diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
index 3bd48c235f..c4ee1f09e4 100644
--- a/target/arm/helper-sme.h
+++ b/target/arm/helper-sme.h
@@ -19,3 +19,5 @@
 
 DEF_HELPER_FLAGS_2(set_pstate_sm, TCG_CALL_NO_RWG, void, env, i32)
 DEF_HELPER_FLAGS_2(set_pstate_za, TCG_CALL_NO_RWG, void, env, i32)
+
+DEF_HELPER_FLAGS_3(sme_zero, TCG_CALL_NO_RWG, void, env, i32, i32)
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index 6bd1b2eb4b..ec5d580ba0 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -30,6 +30,7 @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int 
immn,
 unsigned int imms, unsigned int immr);
 bool sve_access_check(DisasContext *s);
 bool sme_enabled_check(DisasContext *s);
+bool sme_za_enabled_check(DisasContext *s);
 TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
 TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
 bool tag_checked, int log2_size);
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
index c25c031a71..6e4483fdce 100644
--- a/target/arm/sme.decode
+++ b/target/arm/sme.decode
@@ -18,3 +18,7 @@
 #
 # This file is processed by scripts/decodetree.py
 #
+
+### SME Misc
+
+ZERO1100 00 001 000 imm:8
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
index b215725594..e5b5723a15 100644
--- a/target/arm/sme_helper.c
+++ b/target/arm/sme_helper.c
@@ -59,3 +59,28 @@ void helper_set_pstate_za(CPUARMState *env, uint32_t i)
 memset(env->zarray, 0, sizeof(env->zarray));
 }
 }
+
+void helper_sme_zero(CPUARMState *env, uint32_t imm, uint32_t svl)
+{
+uint32_t i;
+
+/*
+ * Special case clearing the entire ZA space.
+ * This falls into the CONSTRAINED UNPREDICTABLE zeroing of any
+ * parts of the ZA storage outside of SVL.
+ */
+if (imm == 0xff) {
+memset(env->zarray, 0, sizeof(env->zarray));
+return;
+}
+
+/*
+ * Recall that ZAnH.D[m] is spread across ZA[n+8*m].
+ * Unless SVL == ARM_MAX_VQ, each row is discontiguous.
+ */
+for (i = 0; i < svl; i++) {
+if (imm & (1 << (i % 8))) {
+memset(>zarray[i], 0, svl);
+}
+}
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 498970f653..df9fc42635 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1231,6 +1231,20 @@ bool sme_enabled_check(DisasContext *s)
 return fp_access_check_only(s);
 }
 
+/* Note that this function corresponds to CheckSMEAndZAEnabled. */
+bool sme_za_enabled_check(DisasContext *s)
+{
+if (!sme_enabled_check(s)) {
+return false;
+}
+if (!s->pstate_za) {
+gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
+   syn_smetrap(SME_ET_InactiveZA, false));
+return false;
+}
+return true;
+}
+
 /*
  * This utility function is for doing register extension with an
  * optional shift. You will likely want to pass a temporary for the
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
index 786c93fb2d..d526c74456 100644
--- a/target/arm/translate-sme.c
+++ b/target/arm/translate-sme.c
@@ -33,3 +33,16 @@
  */
 
 #include "decode-sme.c.inc"
+
+
+static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
+{
+if (!dc_isar_feature(aa64_sme, s)) {
+return false;
+}
+if (sme_za_enabled_check(s)) {
+gen_helper_sme_zero(cpu_env, tcg_constant_i32(a->imm),
+tcg_constant_i32(s->svl));
+}
+return true;
+}
-- 
2.34.1




[PATCH v3 34/51] target/arm: Implement PSEL

2022-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/sve.decode  | 20 +
 target/arm/translate-sve.c | 57 ++
 2 files changed, 77 insertions(+)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index bbdaac6ac7..bf561c270a 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -1674,3 +1674,23 @@ BFMLALT_zzxw01100100 11 1 . 0100.1 . .   
  @rrxr_3a esz=2
 
 ### SVE2 floating-point bfloat16 dot-product (indexed)
 BFDOT_zzxz  01100100 01 1 . 01 . . @rrxr_2 esz=2
+
+### SVE broadcast predicate element
+
+   esz pd pn pm rv imm
+%psel_rv16:2 !function=plus_12
+%psel_imm_b 22:2 19:2
+%psel_imm_h 22:2 20:1
+%psel_imm_s 22:2
+%psel_imm_d 23:1
+@psel    .. . ... .. .. pn:4 . pm:4 . pd:4  \
+ rv=%psel_rv
+
+PSEL00100101 .. 1 ..1 .. 01  0  0   \
+@psel esz=0 imm=%psel_imm_b
+PSEL00100101 .. 1 .10 .. 01  0  0   \
+@psel esz=1 imm=%psel_imm_h
+PSEL00100101 .. 1 100 .. 01  0  0   \
+@psel esz=2 imm=%psel_imm_s
+PSEL00100101 .1 1 000 .. 01  0  0   \
+@psel esz=3 imm=%psel_imm_d
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index adf0cd3e68..58d0894e15 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7379,3 +7379,60 @@ static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz 
*a, bool sel)
 
 TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false)
 TRANS_FEAT(BFMLALT_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, true)
+
+static bool trans_PSEL(DisasContext *s, arg_psel *a)
+{
+int vl = vec_full_reg_size(s);
+int pl = pred_gvec_reg_size(s);
+int elements = vl >> a->esz;
+TCGv_i64 tmp, didx, dbit;
+TCGv_ptr ptr;
+
+if (!dc_isar_feature(aa64_sme, s)) {
+return false;
+}
+if (!sve_access_check(s)) {
+return true;
+}
+
+tmp = tcg_temp_new_i64();
+dbit = tcg_temp_new_i64();
+didx = tcg_temp_new_i64();
+ptr = tcg_temp_new_ptr();
+
+/* Compute the predicate element. */
+tcg_gen_addi_i64(tmp, cpu_reg(s, a->rv), a->imm);
+if (is_power_of_2(elements)) {
+tcg_gen_andi_i64(tmp, tmp, elements - 1);
+} else {
+tcg_gen_remu_i64(tmp, tmp, tcg_constant_i64(elements));
+}
+
+/* Extract the predicate byte and bit indices. */
+tcg_gen_shli_i64(tmp, tmp, a->esz);
+tcg_gen_andi_i64(dbit, tmp, 7);
+tcg_gen_shri_i64(didx, tmp, 3);
+if (HOST_BIG_ENDIAN) {
+tcg_gen_xori_i64(didx, didx, 7);
+}
+
+/* Load the predicate word. */
+tcg_gen_trunc_i64_ptr(ptr, didx);
+tcg_gen_add_ptr(ptr, ptr, cpu_env);
+tcg_gen_ld8u_i64(tmp, ptr, pred_full_reg_offset(s, a->pm));
+
+/* Extract the predicate bit and replicate to MO_64. */
+tcg_gen_shr_i64(tmp, tmp, dbit);
+tcg_gen_andi_i64(tmp, tmp, 1);
+tcg_gen_neg_i64(tmp, tmp);
+
+/* Apply to either copy the source, or write zeros. */
+tcg_gen_gvec_ands(MO_64, pred_full_reg_offset(s, a->pd),
+  pred_full_reg_offset(s, a->pn), tmp, pl, pl);
+
+tcg_temp_free_i64(tmp);
+tcg_temp_free_i64(dbit);
+tcg_temp_free_i64(didx);
+tcg_temp_free_ptr(ptr);
+return true;
+}
-- 
2.34.1




[PATCH v3 43/51] linux-user/aarch64: Do not allow duplicate or short sve records

2022-06-20 Thread Richard Henderson
In parse_user_sigframe, the kernel rejects duplicate sve records,
or records that are smaller than the header.  We were silently
allowing these cases to pass, dropping the record.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/signal.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 8b352abb97..8fbe98d72f 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -318,10 +318,13 @@ static int target_restore_sigframe(CPUARMState *env,
 break;
 
 case TARGET_SVE_MAGIC:
+if (sve || size < sizeof(struct target_sve_context)) {
+goto err;
+}
 if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
 vq = sve_vq(env);
 sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
-if (!sve && size == sve_size) {
+if (size == sve_size) {
 sve = (struct target_sve_context *)ctx;
 break;
 }
-- 
2.34.1




[PATCH v3 26/51] target/arm: Implement SME LD1, ST1

2022-06-20 Thread Richard Henderson
We cannot reuse the SVE functions for LD[1-4] and ST[1-4],
because those functions accept only a Zreg register number.
For SME, we want to pass a pointer into ZA storage.

Signed-off-by: Richard Henderson 
---
 target/arm/helper-sme.h|  82 +
 target/arm/sme.decode  |   9 +
 target/arm/sme_helper.c| 615 +
 target/arm/translate-sme.c |  69 +
 4 files changed, 775 insertions(+)

diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
index 600346e08c..5cca01f372 100644
--- a/target/arm/helper-sme.h
+++ b/target/arm/helper-sme.h
@@ -32,3 +32,85 @@ DEF_HELPER_FLAGS_4(sme_mova_avz_d, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sme_mova_zav_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sme_mova_avz_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sme_mova_zav_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_5(sme_ld1b_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1b_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1b_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1b_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+
+DEF_HELPER_FLAGS_5(sme_ld1h_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1h_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1h_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1h_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1h_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1h_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1h_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1h_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+
+DEF_HELPER_FLAGS_5(sme_ld1s_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1s_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1s_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1s_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1s_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1s_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1s_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1s_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+
+DEF_HELPER_FLAGS_5(sme_ld1d_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1d_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1d_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1d_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1d_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1d_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1d_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1d_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+
+DEF_HELPER_FLAGS_5(sme_ld1q_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1q_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1q_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1q_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_ld1q_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1q_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1q_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_ld1q_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+
+DEF_HELPER_FLAGS_5(sme_st1b_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_st1b_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_st1b_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_st1b_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+
+DEF_HELPER_FLAGS_5(sme_st1h_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_st1h_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_st1h_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_st1h_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_5(sme_st1h_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_st1h_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_st1h_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+DEF_HELPER_FLAGS_5(sme_st1h_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, 
i32)
+
+DEF_HELPER_FLAGS_5(sme_st1s_be_h, TCG_CALL_NO_WG, void, env, ptr, 

[PATCH v3 30/51] target/arm: Implement FMOPA, FMOPS (non-widening)

2022-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-sme.h|  5 +++
 target/arm/sme.decode  |  9 +
 target/arm/sme_helper.c| 67 ++
 target/arm/translate-sme.c | 33 +++
 4 files changed, 114 insertions(+)

diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
index 6f0fce7e2c..727095a3eb 100644
--- a/target/arm/helper-sme.h
+++ b/target/arm/helper-sme.h
@@ -119,3 +119,8 @@ DEF_HELPER_FLAGS_5(sme_addha_s, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(sme_addva_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
index 8cb6c4053c..ba4774d174 100644
--- a/target/arm/sme.decode
+++ b/target/arm/sme.decode
@@ -64,3 +64,12 @@ ADDHA_s 1100 10 01000 0 ... ... . 000 .. 
   @adda_32
 ADDVA_s 1100 10 01000 1 ... ... . 000 ..@adda_32
 ADDHA_d 1100 11 01000 0 ... ... . 00 ...@adda_64
 ADDVA_d 1100 11 01000 1 ... ... . 00 ...@adda_64
+
+### SME Outer Product
+
+ zad zn zm pm pn sub:bool
+@op_32   ... zm:5 pm:3 pn:3 zn:5 sub:1 .. zad:2 
+@op_64   ... zm:5 pm:3 pn:3 zn:5 sub:1 .  zad:3 
+
+FMOPA_s 1000 100 . ... ... . . 00 ..@op_32
+FMOPA_d 1000 110 . ... ... . . 0 ...@op_64
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
index 799e44c047..62d9690cae 100644
--- a/target/arm/sme_helper.c
+++ b/target/arm/sme_helper.c
@@ -25,6 +25,7 @@
 #include "exec/cpu_ldst.h"
 #include "exec/exec-all.h"
 #include "qemu/int128.h"
+#include "fpu/softfloat.h"
 #include "vec_internal.h"
 #include "sve_ldst_internal.h"
 
@@ -897,3 +898,69 @@ void HELPER(sme_addva_d)(void *vzda, void *vzn, void *vpn,
 }
 }
 }
+
+void HELPER(sme_fmopa_s)(void *vza, void *vzn, void *vzm, void *vpn,
+ void *vpm, void *vst, uint32_t desc)
+{
+intptr_t row, col, oprsz = simd_maxsz(desc);
+uint32_t neg = simd_data(desc) << 31;
+uint16_t *pn = vpn, *pm = vpm;
+
+bool save_dn = get_default_nan_mode(vst);
+set_default_nan_mode(true, vst);
+
+for (row = 0; row < oprsz; ) {
+uint16_t pa = pn[H2(row >> 4)];
+do {
+if (pa & 1) {
+void *vza_row = vza + row * sizeof(ARMVectorReg);
+uint32_t n = *(uint32_t *)(vzn + row) ^ neg;
+
+for (col = 0; col < oprsz; ) {
+uint16_t pb = pm[H2(col >> 4)];
+do {
+if (pb & 1) {
+uint32_t *a = vza_row + col;
+uint32_t *m = vzm + col;
+*a = float32_muladd(n, *m, *a, 0, vst);
+}
+col += 4;
+pb >>= 4;
+} while (col & 15);
+}
+}
+row += 4;
+pa >>= 4;
+} while (row & 15);
+}
+
+set_default_nan_mode(save_dn, vst);
+}
+
+void HELPER(sme_fmopa_d)(void *vza, void *vzn, void *vzm, void *vpn,
+ void *vpm, void *vst, uint32_t desc)
+{
+intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
+uint64_t neg = (uint64_t)simd_data(desc) << 63;
+uint64_t *za = vza, *zn = vzn, *zm = vzm;
+uint8_t *pn = vpn, *pm = vpm;
+
+bool save_dn = get_default_nan_mode(vst);
+set_default_nan_mode(true, vst);
+
+for (row = 0; row < oprsz; ++row) {
+if (pn[H1(row)] & 1) {
+uint64_t *za_row = [row * sizeof(ARMVectorReg)];
+uint64_t n = zn[row] ^ neg;
+
+for (col = 0; col < oprsz; ++col) {
+if (pm[H1(col)] & 1) {
+uint64_t *a = _row[col];
+*a = float64_muladd(n, zm[col], *a, 0, vst);
+}
+}
+}
+}
+
+set_default_nan_mode(save_dn, vst);
+}
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
index e9676b2415..e6e4541e76 100644
--- a/target/arm/translate-sme.c
+++ b/target/arm/translate-sme.c
@@ -273,3 +273,36 @@ TRANS_FEAT(ADDHA_s, aa64_sme, do_adda, a, MO_32, 
gen_helper_sme_addha_s)
 TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addva_s)
 TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d)
 TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d)
+
+static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
+   

[PATCH v3 48/51] linux-user/aarch64: Implement PR_SME_GET_VL, PR_SME_SET_VL

2022-06-20 Thread Richard Henderson
These prctl set the Streaming SVE vector length, which may
be completely different from the Normal SVE vector length.

Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/target_prctl.h | 48 +++
 linux-user/syscall.c  | 16 +++
 2 files changed, 64 insertions(+)

diff --git a/linux-user/aarch64/target_prctl.h 
b/linux-user/aarch64/target_prctl.h
index 40481e6663..f8f8f88992 100644
--- a/linux-user/aarch64/target_prctl.h
+++ b/linux-user/aarch64/target_prctl.h
@@ -10,6 +10,7 @@ static abi_long do_prctl_sve_get_vl(CPUArchState *env)
 {
 ARMCPU *cpu = env_archcpu(env);
 if (cpu_isar_feature(aa64_sve, cpu)) {
+/* PSTATE.SM is always unset on syscall entry. */
 return sve_vq(env) * 16;
 }
 return -TARGET_EINVAL;
@@ -27,6 +28,7 @@ static abi_long do_prctl_sve_set_vl(CPUArchState *env, 
abi_long arg2)
 && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
 uint32_t vq, old_vq;
 
+/* PSTATE.SM is always unset on syscall entry. */
 old_vq = sve_vq(env);
 
 /*
@@ -49,6 +51,52 @@ static abi_long do_prctl_sve_set_vl(CPUArchState *env, 
abi_long arg2)
 }
 #define do_prctl_sve_set_vl do_prctl_sve_set_vl
 
+static abi_long do_prctl_sme_get_vl(CPUArchState *env)
+{
+ARMCPU *cpu = env_archcpu(env);
+if (cpu_isar_feature(aa64_sme, cpu)) {
+return sme_vq(env) * 16;
+}
+return -TARGET_EINVAL;
+}
+#define do_prctl_sme_get_vl do_prctl_sme_get_vl
+
+static abi_long do_prctl_sme_set_vl(CPUArchState *env, abi_long arg2)
+{
+/*
+ * We cannot support either PR_SME_SET_VL_ONEXEC or PR_SME_VL_INHERIT.
+ * Note the kernel definition of sve_vl_valid allows for VQ=512,
+ * i.e. VL=8192, even though the architectural maximum is VQ=16.
+ */
+if (cpu_isar_feature(aa64_sme, env_archcpu(env))
+&& arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
+int vq, old_vq;
+
+old_vq = sme_vq(env);
+
+/*
+ * Bound the value of vq, so that we know that it fits into
+ * the 4-bit field in SMCR_EL1.  Because PSTATE.SM is cleared
+ * on syscall entry, we are not modifying the current SVE
+ * vector length.
+ */
+vq = MAX(arg2 / 16, 1);
+vq = MIN(vq, 16);
+env->vfp.smcr_el[1] =
+FIELD_DP64(env->vfp.smcr_el[1], SMCR, LEN, vq - 1);
+vq = sme_vq(env);
+
+if (old_vq != vq) {
+/* PSTATE.ZA state is cleared on any change to VQ. */
+env->svcr = FIELD_DP64(env->svcr, SVCR, ZA, 0);
+arm_rebuild_hflags(env);
+}
+return vq * 16;
+}
+return -TARGET_EINVAL;
+}
+#define do_prctl_sme_set_vl do_prctl_sme_set_vl
+
 static abi_long do_prctl_reset_keys(CPUArchState *env, abi_long arg2)
 {
 ARMCPU *cpu = env_archcpu(env);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index a7f41ef0ac..e8d6e20b85 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6346,6 +6346,12 @@ abi_long do_arch_prctl(CPUX86State *env, int code, 
abi_ulong addr)
 #ifndef PR_SET_SYSCALL_USER_DISPATCH
 # define PR_SET_SYSCALL_USER_DISPATCH 59
 #endif
+#ifndef PR_SME_SET_VL
+# define PR_SME_SET_VL  63
+# define PR_SME_GET_VL  64
+# define PR_SME_VL_LEN_MASK  0x
+# define PR_SME_VL_INHERIT   (1 << 17)
+#endif
 
 #include "target_prctl.h"
 
@@ -6386,6 +6392,12 @@ static abi_long do_prctl_inval1(CPUArchState *env, 
abi_long arg2)
 #ifndef do_prctl_set_unalign
 #define do_prctl_set_unalign do_prctl_inval1
 #endif
+#ifndef do_prctl_sme_get_vl
+#define do_prctl_sme_get_vl do_prctl_inval0
+#endif
+#ifndef do_prctl_sme_set_vl
+#define do_prctl_sme_set_vl do_prctl_inval1
+#endif
 
 static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
  abi_long arg3, abi_long arg4, abi_long arg5)
@@ -6437,6 +6449,10 @@ static abi_long do_prctl(CPUArchState *env, abi_long 
option, abi_long arg2,
 return do_prctl_sve_get_vl(env);
 case PR_SVE_SET_VL:
 return do_prctl_sve_set_vl(env, arg2);
+case PR_SME_GET_VL:
+return do_prctl_sme_get_vl(env);
+case PR_SME_SET_VL:
+return do_prctl_sme_set_vl(env, arg2);
 case PR_PAC_RESET_KEYS:
 if (arg3 || arg4 || arg5) {
 return -TARGET_EINVAL;
-- 
2.34.1




Re: [PATCH 02/10] bsd-user: Implement symlink, symlinkat, readlink and readlinkat

2022-06-20 Thread Richard Henderson

On 6/20/22 10:42, Warner Losh wrote:

+static abi_long do_bsd_readlink(CPUArchState *env, abi_long arg1,
+abi_long arg2, abi_long arg3)
+{
+abi_long ret;
+void *p1, *p2;
+
+LOCK_PATH(p1, arg1);
+p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+if (p2 == NULL) {
+UNLOCK_PATH(p1, arg1);
+return -TARGET_EFAULT;
+}
+#ifdef __FreeBSD__
+if (strcmp(p1, "/proc/curproc/file") == 0) {
+CPUState *cpu = env_cpu(env);
+TaskState *ts = (TaskState *)cpu->opaque;
+strncpy(p2, ts->bprm->fullpath, arg3);
+ret = MIN((abi_long)strlen(ts->bprm->fullpath), arg3);
+} else
+#endif


Unfortunate ifdef.  Do we really need it while the other bsds are presumably still 
non-functional?  I see that HOST_DEFAULT_BSD_TYPE isn't hooked up either...



r~



[PATCH v3 38/51] target/arm: Enable SME for -cpu max

2022-06-20 Thread Richard Henderson
Note that SME remains effectively disabled for user-only,
because we do not yet set CPACR_EL1.SMEN.  This needs to
wait until the kernel ABI is implemented.

Signed-off-by: Richard Henderson 
---
 docs/system/arm/emulation.rst |  4 
 target/arm/cpu64.c| 11 +++
 2 files changed, 15 insertions(+)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 83b4410065..8e494c8bea 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -65,6 +65,10 @@ the following architecture extensions:
 - FEAT_SHA512 (Advanced SIMD SHA512 instructions)
 - FEAT_SM3 (Advanced SIMD SM3 instructions)
 - FEAT_SM4 (Advanced SIMD SM4 instructions)
+- FEAT_SME (Scalable Matrix Extension)
+- FEAT_SME_FA64 (Full A64 instruction set in Streaming SVE mode)
+- FEAT_SME_F64F64 (Double-precision floating-point outer product instructions)
+- FEAT_SME_I16I64 (16-bit to 64-bit integer widening outer product 
instructions)
 - FEAT_SPECRES (Speculation restriction instructions)
 - FEAT_SSBS (Speculative Store Bypass Safe)
 - FEAT_TLBIOS (TLB invalidate instructions in Outer Shareable domain)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 19188d6cc2..40a0f043d0 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -1018,6 +1018,7 @@ static void aarch64_max_initfn(Object *obj)
  */
 t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3);   /* FEAT_MTE3 */
 t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0);  /* FEAT_RASv1p1 + 
FEAT_DoubleFault */
+t = FIELD_DP64(t, ID_AA64PFR1, SME, 1);   /* FEAT_SME */
 t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
 cpu->isar.id_aa64pfr1 = t;
 
@@ -1068,6 +1069,16 @@ static void aarch64_max_initfn(Object *obj)
 t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5);/* FEAT_PMUv3p4 */
 cpu->isar.id_aa64dfr0 = t;
 
+t = cpu->isar.id_aa64smfr0;
+t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1);   /* FEAT_SME */
+t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1);   /* FEAT_SME */
+t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1);   /* FEAT_SME */
+t = FIELD_DP64(t, ID_AA64SMFR0, I8I32, 0xf);  /* FEAT_SME */
+t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1);   /* FEAT_SME_F64F64 */
+t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf); /* FEAT_SME_I16I64 */
+t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1); /* FEAT_SME_FA64 */
+cpu->isar.id_aa64smfr0 = t;
+
 /* Replicate the same data to the 32-bit id registers.  */
 aa32_max_features(cpu);
 
-- 
2.34.1




Re: [PATCH v2 3/9] ppc/pnv: use dev->parent_bus->parent to get the PHB

2022-06-20 Thread Daniel Henrique Barboza




On 6/20/22 04:27, Mark Cave-Ayland wrote:

On 18/06/2022 12:01, Daniel Henrique Barboza wrote:


It is not advisable to execute an object_dynamic_cast() to poke into
bus->qbus.parent and follow it up with a C cast into the PnvPHB type we
think we got.

A better way is to access the PnvPHB object via a QOM macro accessing
the existing parent links of the DeviceState. For a given
pnv-phb3/4-root-port 'dev', dev->parent_bus will give us the PHB bus,
and dev->parent_bus->parent is the PHB. Use the adequate QOM macro to
assert the type, and keep the NULL check in case we didn't get the
object we were expecting.

Signed-off-by: Daniel Henrique Barboza 
---
  hw/pci-host/pnv_phb3.c | 10 +++---
  hw/pci-host/pnv_phb4.c | 10 +++---
  2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index 4ba660f8b9..5e7f827415 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -1139,12 +1139,16 @@ static void pnv_phb3_root_port_realize(DeviceState 
*dev, Error **errp)
  {
  PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
  PCIDevice *pci = PCI_DEVICE(dev);
-    PCIBus *bus = pci_get_bus(pci);
  PnvPHB3 *phb = NULL;
  Error *local_err = NULL;
-    phb = (PnvPHB3 *) object_dynamic_cast(OBJECT(bus->qbus.parent),
-  TYPE_PNV_PHB3);
+    /*
+ * dev->parent_bus gives access to the pnv-phb-root bus.
+ * The PnvPHB3 is the owner (parent) of the bus.
+ */
+    if (dev->parent_bus) {


Here dev->parent_bus shouldn't be accessed directly: you should use 
qdev_get_parent_bus() instead.


+    phb = PNV_PHB3(dev->parent_bus->parent);
+    }


This one is a bit trickier, since part of the qdev design is that devices should only 
be aware of their immediate bus, and not the device parenting that bus i.e. 
dev->parent_bus->parent shouldn't be allowed.

What is really needed here is to use QOM links (or embed the device as a 
suitable QOM child) to get the PHB reference which I imagine will be changed as 
part of the follow-up series. So I think this can be left as-is for now, and 
fixed later.



In the previous patch (2) I've put the root port as a child of the bus,
giving us this hierarchy:


/pnv-phb3[0] (pnv-phb3)  <== PHB
  /lsi (ics)
  /msi (phb3-msi)
  /msi32[0] (memory-region)
  /msi64[0] (memory-region)
  /pbcq (pnv-pbcq)
(...)
  /phb3_iommu[0] (pnv-phb3-iommu-memory-region)
  /pnv-phb3-root.0 (pnv-phb3-root)  <=== bus
/pnv-phb3-root-port[0] (pnv-phb3-root-port) < root-port
  /bus master container[0] (memory-region)
  /bus master[0] (memory-region)
  /pci_bridge_io[0] (memory-region)
  /pci_bridge_io[1] (memory-region)
  /pci_bridge_mem[0] (memory-region)
  /pci_bridge_pci[0] (memory-region)
  /pci_bridge_pref_mem[0] (memory-region)
  /pci_bridge_vga_io_hi[0] (memory-region)
  /pci_bridge_vga_io_lo[0] (memory-region)
  /pci_bridge_vga_mem[0] (memory-region)
  /pcie.0 (PCIE)


I did it like this instead of the PHB for no particular reason. If the root 
port of
other PHBs are located as a direct child of the PHB I can change it.


All that said, thinking more about it, since I need to access the PHB just
to set "chassis" and "slot" of the device, and I'm already setting a QOM
parent for it, I guess I'll just set that before root_port_realize() and spare 
us
from having to accessing the parent of the parent bus of the root_port.



Thanks,


Daniel




  if (!phb) {
  error_setg(errp,
diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c
index ffd9d8a947..a0ee52e820 100644
--- a/hw/pci-host/pnv_phb4.c
+++ b/hw/pci-host/pnv_phb4.c
@@ -1782,12 +1782,16 @@ static void pnv_phb4_root_port_realize(DeviceState 
*dev, Error **errp)
  {
  PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
  PCIDevice *pci = PCI_DEVICE(dev);
-    PCIBus *bus = pci_get_bus(pci);
  PnvPHB4 *phb = NULL;
  Error *local_err = NULL;
-    phb = (PnvPHB4 *) object_dynamic_cast(OBJECT(bus->qbus.parent),
-  TYPE_PNV_PHB4);
+    /*
+ * dev->parent_bus gives access to the pnv-phb-root bus.
+ * The PnvPHB4 is the owner (parent) of the bus.
+ */
+    if (dev->parent_bus) {
+    phb = PNV_PHB4(dev->parent_bus->parent);
+    }
  if (!phb) {
  error_setg(errp, "%s must be connected to pnv-phb4 buses", dev->id);


I've had a quick look over the rest of the series and from what I can see this 
is definitely heading in the right direction :)


ATB,

Mark.




[PATCH v3 49/51] target/arm: Only set ZEN in reset if SVE present

2022-06-20 Thread Richard Henderson
There's no reason to set CPACR_EL1.ZEN if SVE disabled.

Signed-off-by: Richard Henderson 
---
 target/arm/cpu.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 75295a14a3..5cb9f9f02c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -203,11 +203,10 @@ static void arm_cpu_reset(DeviceState *dev)
 /* and to the FP/Neon instructions */
 env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
  CPACR_EL1, FPEN, 3);
-/* and to the SVE instructions */
-env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
- CPACR_EL1, ZEN, 3);
-/* with reasonable vector length */
+/* and to the SVE instructions, with default vector length */
 if (cpu_isar_feature(aa64_sve, cpu)) {
+env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
+ CPACR_EL1, ZEN, 3);
 env->vfp.zcr_el[1] = cpu->sve_default_vq - 1;
 }
 /*
-- 
2.34.1




Re: [PATCH 10/10] bsd-user: Implement undelete

2022-06-20 Thread Richard Henderson

On 6/20/22 10:42, Warner Losh wrote:

Signed-off-by: Stacey Son
Signed-off-by: Warner Losh
---
  bsd-user/bsd-file.h   | 13 +
  bsd-user/freebsd/os-syscall.c |  4 
  2 files changed, 17 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 01/10] bsd-user: Implement mount, umount and nmount

2022-06-20 Thread Richard Henderson

On 6/20/22 10:42, Warner Losh wrote:

+/*
+ * XXX arg4 should be locked, but it isn't clear how to do that
+ * since it's it may be not be a NULL-terminated string.


it's it.

Unless you meant https://www.itsiticecream.com/  ;-)

Reviewed-by: Richard Henderson 


r~



Re: [PATCH] softmmu: Always initialize xlat in address_space_translate_for_iotlb

2022-06-20 Thread Richard Henderson

On 6/20/22 05:52, Peter Maydell wrote:

On Wed, 15 Jun 2022 at 17:43, Richard Henderson
 wrote:


The bug is an uninitialized memory read, along the translate_fail
path, which results in garbage being read from iotlb_to_section,
which can lead to a crash in io_readx/io_writex.

The bug may be fixed by writing any value with zero
in ~TARGET_PAGE_MASK, so that the call to iotlb_to_section using
the xlat'ed address returns io_mem_unassigned, as desired by the
translate_fail path.

It is most useful to record the original physical page address,
which will eventually be logged by memory_region_access_valid
when the access is rejected by unassigned_mem_accepts.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1065
Signed-off-by: Richard Henderson 
---
  softmmu/physmem.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 657841eed0..fb0f0709b5 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -681,6 +681,9 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, 
hwaddr addr,
  AddressSpaceDispatch *d =
  qatomic_rcu_read(>cpu_ases[asidx].memory_dispatch);

+/* Record the original phys page for use by the translate_fail path. */
+*xlat = addr;


There's no doc comment for address_space_translate_for_iotlb(),
so there's nothing that says explicitly that addr is obliged
to be page aligned, although it happens that its only caller
does pass a page-aligned address. Were we already implicitly
requiring a page-aligned address here, or does not masking
addr before assigning to *xlat impose a new requirement ?


I have no idea.  The whole lookup process is both undocumented and twistedly complex.  I'm 
willing to add an extra masking operation here, if it seems necessary?



r~



Re: [PATCH 0/8] Add some functions for LoongArch

2022-06-20 Thread Richard Henderson

On 6/20/22 01:04, Xiaojuan Yang wrote:

In order to start the latest community BIOS and kernel of LoongArch,
we have added the following patches.

This series add some functions for LoongArch, and fix some errors.
Add bios, kernel, fdt, smbios and acpi options support.

The kernel file:
* https://github.com/loongson/linux/tree/loongarch-next
The bios file:
* https://github.com/loongson/edk2
* https://github.com/loongson/edk2-platforms


Xiaojuan Yang (8):
   hw/loongarch: Add default bios startup support
   hw/loongarch: Add -kernel and -initrd options support
   hw/loongarch: Add LoongArch smbios support
   hw/loongarch: Add LoongArch acpi support
   hw/loongarch: Add fdt support
   hw/loongarch: Fix loongarch ipi device
   target/loongarch: Fix vector size of exception entry address
   target/loongarch: Fix csrwr timer clear


Please fill in the patch descriptions for each of these.


r~



[PATCH 07/10] bsd-user: Implement chroot and flock

2022-06-20 Thread Warner Losh
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-file.h   | 19 +++
 bsd-user/freebsd/os-syscall.c |  8 
 2 files changed, 27 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index f5375a39a2c..f11369655a0 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -861,4 +861,23 @@ static abi_long do_bsd_fchflags(abi_long arg1, abi_long 
arg2)
 return get_errno(fchflags(arg1, arg2));
 }
 
+/* chroot(2) */
+static abi_long do_bsd_chroot(abi_long arg1)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(chroot(p)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* flock(2) */
+static abi_long do_bsd_flock(abi_long arg1, abi_long arg2)
+{
+return get_errno(flock(arg1, arg2));
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index d10635eae05..f3fb585b7ec 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -461,6 +461,14 @@ static abi_long freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 ret = do_bsd_fchflags(arg1, arg2);
 break;
 
+case TARGET_FREEBSD_NR_chroot: /* chroot(2) */
+ret = do_bsd_chroot(arg1);
+break;
+
+case TARGET_FREEBSD_NR_flock: /* flock(2) */
+ret = do_bsd_flock(arg1, arg2);
+break;
+
 default:
 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
 ret = -TARGET_ENOSYS;
-- 
2.33.1




[PATCH 05/10] bsd-user: Implement chown, fchown, lchown and fchownat

2022-06-20 Thread Warner Losh
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-file.h   | 48 +++
 bsd-user/freebsd/os-syscall.c | 16 
 2 files changed, 64 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index 3be832b2a74..152579ad541 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -781,4 +781,52 @@ static abi_long do_bsd_mknodat(void *cpu_env, abi_long 
arg1,
 }
 #endif
 
+/* chown(2) */
+static abi_long do_bsd_chown(abi_long arg1, abi_long arg2, abi_long arg3)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(chown(p, arg2, arg3)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* fchown(2) */
+static abi_long do_bsd_fchown(abi_long arg1, abi_long arg2,
+abi_long arg3)
+{
+return get_errno(fchown(arg1, arg2, arg3));
+}
+
+/* lchown(2) */
+static abi_long do_bsd_lchown(abi_long arg1, abi_long arg2,
+abi_long arg3)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(lchown(p, arg2, arg3)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* fchownat(2) */
+static abi_long do_bsd_fchownat(abi_long arg1, abi_long arg2,
+abi_long arg3, abi_long arg4, abi_long arg5)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg2);
+ret = get_errno(fchownat(arg1, p, arg3, arg4, arg5)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg2);
+
+return ret;
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index fea6a857b78..4d10334ef21 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -433,6 +433,22 @@ static abi_long freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 break;
 #endif
 
+case TARGET_FREEBSD_NR_chown: /* chown(2) */
+ret = do_bsd_chown(arg1, arg2, arg3);
+break;
+
+case TARGET_FREEBSD_NR_fchown: /* fchown(2) */
+ret = do_bsd_fchown(arg1, arg2, arg3);
+break;
+
+case TARGET_FREEBSD_NR_lchown: /* lchown(2) */
+ret = do_bsd_lchown(arg1, arg2, arg3);
+break;
+
+case TARGET_FREEBSD_NR_fchownat: /* fchownat(2) */
+ret = do_bsd_fchownat(arg1, arg2, arg3, arg4, arg5);
+break;
+
 default:
 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
 ret = -TARGET_ENOSYS;
-- 
2.33.1




[PATCH 03/10] bsd-user: implement chmod, fchmod, lchmod and fchmodat

2022-06-20 Thread Warner Losh
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-file.h   | 46 +++
 bsd-user/freebsd/os-syscall.c | 16 
 2 files changed, 62 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index e5133268546..0585f6a2a40 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -676,4 +676,50 @@ static abi_long do_bsd_readlinkat(abi_long arg1, abi_long 
arg2,
 return ret;
 }
 
+/* chmod(2) */
+static abi_long do_bsd_chmod(abi_long arg1, abi_long arg2)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(chmod(p, arg2)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* fchmod(2) */
+static abi_long do_bsd_fchmod(abi_long arg1, abi_long arg2)
+{
+return get_errno(fchmod(arg1, arg2));
+}
+
+/* lchmod(2) */
+static abi_long do_bsd_lchmod(abi_long arg1, abi_long arg2)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(lchmod(p, arg2)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* fchmodat(2) */
+static abi_long do_bsd_fchmodat(abi_long arg1, abi_long arg2,
+abi_long arg3, abi_long arg4)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg2);
+ret = get_errno(fchmodat(arg1, p, arg3, arg4));
+UNLOCK_PATH(p, arg2);
+
+return ret;
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index 80ec9dd4954..b33d548a4b6 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -402,6 +402,22 @@ static abi_long freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 ret = do_bsd_readlinkat(arg1, arg2, arg3, arg4);
 break;
 
+case TARGET_FREEBSD_NR_chmod: /* chmod(2) */
+ret = do_bsd_chmod(arg1, arg2);
+break;
+
+case TARGET_FREEBSD_NR_fchmod: /* fchmod(2) */
+ret = do_bsd_fchmod(arg1, arg2);
+break;
+
+case TARGET_FREEBSD_NR_lchmod: /* lchmod(2) */
+ret = do_bsd_lchmod(arg1, arg2);
+break;
+
+case TARGET_FREEBSD_NR_fchmodat: /* fchmodat(2) */
+ret = do_bsd_fchmodat(arg1, arg2, arg3, arg4);
+break;
+
 default:
 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
 ret = -TARGET_ENOSYS;
-- 
2.33.1




[PATCH 09/10] bsd-user: Implement pathconf, lpathconf and fpathconf

2022-06-20 Thread Warner Losh
Signed-off-by: Stacey Son 
Signed-off-by: Warner Losh 
---
 bsd-user/bsd-file.h   | 32 
 bsd-user/freebsd/os-syscall.c | 12 
 2 files changed, 44 insertions(+)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index 0b4b89c8d5c..79eb5a73a9b 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -907,4 +907,36 @@ static abi_long do_bsd_mkfifoat(abi_long arg1, abi_long 
arg2,
 return ret;
 }
 
+/* pathconf(2) */
+static abi_long do_bsd_pathconf(abi_long arg1, abi_long arg2)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(pathconf(p, arg2)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* lpathconf(2) */
+static abi_long do_bsd_lpathconf(abi_long arg1, abi_long arg2)
+{
+abi_long ret;
+void *p;
+
+LOCK_PATH(p, arg1);
+ret = get_errno(lpathconf(p, arg2)); /* XXX path(p)? */
+UNLOCK_PATH(p, arg1);
+
+return ret;
+}
+
+/* fpathconf(2) */
+static abi_long do_bsd_fpathconf(abi_long arg1, abi_long arg2)
+{
+return get_errno(fpathconf(arg1, arg2));
+}
+
 #endif /* BSD_FILE_H */
diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c
index ff3893b9197..ee08b74bdd5 100644
--- a/bsd-user/freebsd/os-syscall.c
+++ b/bsd-user/freebsd/os-syscall.c
@@ -477,6 +477,18 @@ static abi_long freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 ret = do_bsd_mkfifoat(arg1, arg2, arg3);
 break;
 
+case TARGET_FREEBSD_NR_pathconf: /* pathconf(2) */
+ret = do_bsd_pathconf(arg1, arg2);
+break;
+
+case TARGET_FREEBSD_NR_lpathconf: /* lpathconf(2) */
+ret = do_bsd_lpathconf(arg1, arg2);
+break;
+
+case TARGET_FREEBSD_NR_fpathconf: /* fpathconf(2) */
+ret = do_bsd_fpathconf(arg1, arg2);
+break;
+
 default:
 qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
 ret = -TARGET_ENOSYS;
-- 
2.33.1




[PATCH v3 02/51] target/arm: Add SMEEXC_EL to TB flags

2022-06-20 Thread Richard Henderson
This is CheckSMEAccess, which is the basis for a set of
related tests for various SME cpregs and instructions.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   |  2 ++
 target/arm/translate.h |  1 +
 target/arm/helper.c| 52 ++
 target/arm/translate-a64.c |  1 +
 4 files changed, 56 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 05d1e2e8dd..e99de18097 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1134,6 +1134,7 @@ void aarch64_sync_64_to_32(CPUARMState *env);
 
 int fp_exception_el(CPUARMState *env, int cur_el);
 int sve_exception_el(CPUARMState *env, int cur_el);
+int sme_exception_el(CPUARMState *env, int cur_el);
 
 /**
  * sve_vqm1_for_el:
@@ -3148,6 +3149,7 @@ FIELD(TBFLAG_A64, ATA, 15, 1)
 FIELD(TBFLAG_A64, TCMA, 16, 2)
 FIELD(TBFLAG_A64, MTE_ACTIVE, 18, 1)
 FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
+FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
 
 /*
  * Helpers for using the above.
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 88dc18a034..c88c953325 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -42,6 +42,7 @@ typedef struct DisasContext {
 bool ns;/* Use non-secure CPREG bank on access */
 int fp_excp_el; /* FP exception EL or 0 if enabled */
 int sve_excp_el; /* SVE exception EL or 0 if enabled */
+int sme_excp_el; /* SME exception EL or 0 if enabled */
 int vl;  /* current vector length in bytes */
 bool vfp_enabled; /* FP enabled via FPSCR.EN */
 int vec_len;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index d21ba7ab83..2c080c6cac 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6218,6 +6218,55 @@ int sve_exception_el(CPUARMState *env, int el)
 return 0;
 }
 
+/*
+ * Return the exception level to which exceptions should be taken for SME.
+ * C.f. the ARM pseudocode function CheckSMEAccess.
+ */
+int sme_exception_el(CPUARMState *env, int el)
+{
+#ifndef CONFIG_USER_ONLY
+if (el <= 1 && !el_is_in_host(env, el)) {
+switch (FIELD_EX64(env->cp15.cpacr_el1, CPACR_EL1, SMEN)) {
+case 1:
+if (el != 0) {
+break;
+}
+/* fall through */
+case 0:
+case 2:
+return 1;
+}
+}
+
+if (el <= 2 && arm_is_el2_enabled(env)) {
+/* CPTR_EL2 changes format with HCR_EL2.E2H (regardless of TGE). */
+if (env->cp15.hcr_el2 & HCR_E2H) {
+switch (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, SMEN)) {
+case 1:
+if (el != 0 || !(env->cp15.hcr_el2 & HCR_TGE)) {
+break;
+}
+/* fall through */
+case 0:
+case 2:
+return 2;
+}
+} else {
+if (FIELD_EX64(env->cp15.cptr_el[2], CPTR_EL2, TSM)) {
+return 2;
+}
+}
+}
+
+/* CPTR_EL3.  Since ESM is negative we must check for EL3.  */
+if (arm_feature(env, ARM_FEATURE_EL3)
+&& !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, ESM)) {
+return 3;
+}
+#endif
+return 0;
+}
+
 /*
  * Given that SVE is enabled, return the vector length for EL.
  */
@@ -11197,6 +11246,9 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState 
*env, int el, int fp_el,
 }
 DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
 }
+if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
+DP_TBFLAG_A64(flags, SMEEXC_EL, sme_exception_el(env, el));
+}
 
 sctlr = regime_sctlr(env, stage1);
 
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 4c64546090..9a285dd177 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14603,6 +14603,7 @@ static void 
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
 dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
 dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
 dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
+dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
 dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
 dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
 dc->bt = EX_TBFLAG_A64(tb_flags, BT);
-- 
2.34.1




[PATCH v3 01/51] target/arm: Implement TPIDR2_EL0

2022-06-20 Thread Richard Henderson
This register is part of SME, but isn't closely related to the
rest of the extension.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h|  1 +
 target/arm/helper.c | 32 
 2 files changed, 33 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index df677b2d5d..05d1e2e8dd 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -474,6 +474,7 @@ typedef struct CPUArchState {
 };
 uint64_t tpidr_el[4];
 };
+uint64_t tpidr2_el0;
 /* The secure banks of these registers don't map anywhere */
 uint64_t tpidrurw_s;
 uint64_t tpidrprw_s;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6457e6301c..d21ba7ab83 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6279,6 +6279,35 @@ static const ARMCPRegInfo zcr_reginfo[] = {
   .writefn = zcr_write, .raw_writefn = raw_write },
 };
 
+#ifdef TARGET_AARCH64
+static CPAccessResult access_tpidr2(CPUARMState *env, const ARMCPRegInfo *ri,
+bool isread)
+{
+int el = arm_current_el(env);
+
+if (el == 0) {
+uint64_t sctlr = arm_sctlr(env, el);
+if (!(sctlr & SCTLR_EnTP2)) {
+return CP_ACCESS_TRAP;
+}
+}
+/* TODO: FEAT_FGT */
+if (el < 3
+&& arm_feature(env, ARM_FEATURE_EL3)
+&& !(env->cp15.scr_el3 & SCR_ENTP2)) {
+return CP_ACCESS_TRAP_EL3;
+}
+return CP_ACCESS_OK;
+}
+
+static const ARMCPRegInfo sme_reginfo[] = {
+{ .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
+  .access = PL0_RW, .accessfn = access_tpidr2,
+  .fieldoffset = offsetof(CPUARMState, cp15.tpidr2_el0) },
+};
+#endif /* TARGET_AARCH64 */
+
 void hw_watchpoint_update(ARMCPU *cpu, int n)
 {
 CPUARMState *env = >env;
@@ -8440,6 +8469,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 }
 
 #ifdef TARGET_AARCH64
+if (cpu_isar_feature(aa64_sme, cpu)) {
+define_arm_cp_regs(cpu, sme_reginfo);
+}
 if (cpu_isar_feature(aa64_pauth, cpu)) {
 define_arm_cp_regs(cpu, pauth_reginfo);
 }
-- 
2.34.1




[PATCH v3 18/51] target/arm: Introduce sve_vqm1_for_el_sm

2022-06-20 Thread Richard Henderson
When Streaming SVE mode is enabled, the size is taken from
SMCR_ELx instead of ZCR_ELx.  The format is shared, but the
set of vector lengths is not.  Further, Streaming SVE does
not require any particular length to be supported.

Adjust sve_vqm1_for_el to pass the current value of PSTATE.SM
to the new function.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h|  9 +++--
 target/arm/helper.c | 32 +---
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 8b00d29af4..244f8428e9 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1140,13 +1140,18 @@ int sve_exception_el(CPUARMState *env, int cur_el);
 int sme_exception_el(CPUARMState *env, int cur_el);
 
 /**
- * sve_vqm1_for_el:
+ * sve_vqm1_for_el_sm:
  * @env: CPUARMState
  * @el: exception level
+ * @sm: streaming mode
  *
- * Compute the current SVE vector length for @el, in units of
+ * Compute the current vector length for @el & @sm, in units of
  * Quadwords Minus 1 -- the same scale used for ZCR_ELx.LEN.
+ * If @sm, compute for SVL, otherwise NVL.
  */
+uint32_t sve_vqm1_for_el_sm(CPUARMState *env, int el, bool sm);
+
+/* Likewise, but using @sm = PSTATE.SM. */
 uint32_t sve_vqm1_for_el(CPUARMState *env, int el);
 
 static inline bool is_a64(CPUARMState *env)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index a80ca461e5..2e4e739969 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6272,23 +6272,41 @@ int sme_exception_el(CPUARMState *env, int el)
 /*
  * Given that SVE is enabled, return the vector length for EL.
  */
-uint32_t sve_vqm1_for_el(CPUARMState *env, int el)
+uint32_t sve_vqm1_for_el_sm(CPUARMState *env, int el, bool sm)
 {
 ARMCPU *cpu = env_archcpu(env);
-uint32_t len = cpu->sve_max_vq - 1;
+uint64_t *cr = env->vfp.zcr_el;
+uint32_t map = cpu->sve_vq.map;
+uint32_t len = ARM_MAX_VQ - 1;
+
+if (sm) {
+cr = env->vfp.smcr_el;
+map = cpu->sme_vq.map;
+}
 
 if (el <= 1 && !el_is_in_host(env, el)) {
-len = MIN(len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
+len = MIN(len, 0xf & (uint32_t)cr[1]);
 }
 if (el <= 2 && arm_feature(env, ARM_FEATURE_EL2)) {
-len = MIN(len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
+len = MIN(len, 0xf & (uint32_t)cr[2]);
 }
 if (arm_feature(env, ARM_FEATURE_EL3)) {
-len = MIN(len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
+len = MIN(len, 0xf & (uint32_t)cr[3]);
 }
 
-len = 31 - clz32(cpu->sve_vq.map & MAKE_64BIT_MASK(0, len + 1));
-return len;
+map &= MAKE_64BIT_MASK(0, len + 1);
+if (map != 0) {
+return 31 - clz32(map);
+}
+
+/* Bit 0 is always set for Normal SVE -- not so for Streaming SVE. */
+assert(sm);
+return ctz32(cpu->sme_vq.map);
+}
+
+uint32_t sve_vqm1_for_el(CPUARMState *env, int el)
+{
+return sve_vqm1_for_el_sm(env, el, FIELD_EX64(env->svcr, SVCR, SM));
 }
 
 static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
-- 
2.34.1




[PATCH v3 13/51] target/arm: Generalize cpu_arm_{get,set}_vq

2022-06-20 Thread Richard Henderson
Rename from cpu_arm_{get,set}_sve_vq, and take the
ARMVQMap as the opaque parameter.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu64.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index cadc401c7e..1a3cb953bf 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -579,15 +579,15 @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor 
*v, const char *name,
 }
 
 /*
- * Note that cpu_arm_get/set_sve_vq cannot use the simpler
- * object_property_add_bool interface because they make use
- * of the contents of "name" to determine which bit on which
- * to operate.
+ * Note that cpu_arm_{get,set}_vq cannot use the simpler
+ * object_property_add_bool interface because they make use of the
+ * contents of "name" to determine which bit on which to operate.
  */
-static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, const char *name,
-   void *opaque, Error **errp)
+static void cpu_arm_get_vq(Object *obj, Visitor *v, const char *name,
+   void *opaque, Error **errp)
 {
 ARMCPU *cpu = ARM_CPU(obj);
+ARMVQMap *vq_map = opaque;
 uint32_t vq = atoi([3]) / 128;
 bool value;
 
@@ -595,15 +595,15 @@ static void cpu_arm_get_sve_vq(Object *obj, Visitor *v, 
const char *name,
 if (!cpu_isar_feature(aa64_sve, cpu)) {
 value = false;
 } else {
-value = extract32(cpu->sve_vq.map, vq - 1, 1);
+value = extract32(vq_map->map, vq - 1, 1);
 }
 visit_type_bool(v, name, , errp);
 }
 
-static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
-   void *opaque, Error **errp)
+static void cpu_arm_set_vq(Object *obj, Visitor *v, const char *name,
+   void *opaque, Error **errp)
 {
-ARMCPU *cpu = ARM_CPU(obj);
+ARMVQMap *vq_map = opaque;
 uint32_t vq = atoi([3]) / 128;
 bool value;
 
@@ -611,8 +611,8 @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
-cpu->sve_vq.map = deposit32(cpu->sve_vq.map, vq - 1, 1, value);
-cpu->sve_vq.init |= 1 << (vq - 1);
+vq_map->map = deposit32(vq_map->map, vq - 1, 1, value);
+vq_map->init |= 1 << (vq - 1);
 }
 
 static bool cpu_arm_get_sve(Object *obj, Error **errp)
@@ -691,6 +691,7 @@ static void cpu_arm_get_sve_default_vec_len(Object *obj, 
Visitor *v,
 
 void aarch64_add_sve_properties(Object *obj)
 {
+ARMCPU *cpu = ARM_CPU(obj);
 uint32_t vq;
 
 object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve);
@@ -698,8 +699,8 @@ void aarch64_add_sve_properties(Object *obj)
 for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
 char name[8];
 sprintf(name, "sve%d", vq * 128);
-object_property_add(obj, name, "bool", cpu_arm_get_sve_vq,
-cpu_arm_set_sve_vq, NULL, NULL);
+object_property_add(obj, name, "bool", cpu_arm_get_vq,
+cpu_arm_set_vq, NULL, >sve_vq);
 }
 
 #ifdef CONFIG_USER_ONLY
-- 
2.34.1




[PATCH v3 25/51] target/arm: Implement SME MOVA

2022-06-20 Thread Richard Henderson
We can reuse the SVE functions for implementing moves to/from
horizontal tile slices, but we need new ones for moves to/from
vertical tile slices.

Signed-off-by: Richard Henderson 
---
 target/arm/helper-sme.h|  11 
 target/arm/helper-sve.h|   2 +
 target/arm/translate-a64.h |   9 +++
 target/arm/translate.h |   5 ++
 target/arm/sme.decode  |  15 +
 target/arm/sme_helper.c| 110 -
 target/arm/sve_helper.c|  12 
 target/arm/translate-a64.c |  19 +++
 target/arm/translate-sme.c | 105 +++
 9 files changed, 287 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
index c4ee1f09e4..600346e08c 100644
--- a/target/arm/helper-sme.h
+++ b/target/arm/helper-sme.h
@@ -21,3 +21,14 @@ DEF_HELPER_FLAGS_2(set_pstate_sm, TCG_CALL_NO_RWG, void, 
env, i32)
 DEF_HELPER_FLAGS_2(set_pstate_za, TCG_CALL_NO_RWG, void, env, i32)
 
 DEF_HELPER_FLAGS_3(sme_zero, TCG_CALL_NO_RWG, void, env, i32, i32)
+
+DEF_HELPER_FLAGS_4(sme_mova_avz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_zav_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_avz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_zav_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_avz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_zav_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_avz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_zav_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_avz_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sme_mova_zav_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
index dc629f851a..ab0333400f 100644
--- a/target/arm/helper-sve.h
+++ b/target/arm/helper-sve.h
@@ -325,6 +325,8 @@ DEF_HELPER_FLAGS_5(sve_sel_zpzz_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(sve_sel_zpzz_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(sve_sel_zpzz_q, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(sve2_addp_zpzz_b, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index ec5d580ba0..c341c95582 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -31,6 +31,7 @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int 
immn,
 bool sve_access_check(DisasContext *s);
 bool sme_enabled_check(DisasContext *s);
 bool sme_za_enabled_check(DisasContext *s);
+bool sme_smza_enabled_check(DisasContext *s);
 TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
 TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
 bool tag_checked, int log2_size);
@@ -147,6 +148,14 @@ static inline int pred_gvec_reg_size(DisasContext *s)
 return size_for_gvec(pred_full_reg_size(s));
 }
 
+/* Return a newly allocated pointer to the predicate register.  */
+static inline TCGv_ptr pred_full_reg_ptr(DisasContext *s, int regno)
+{
+TCGv_ptr ret = tcg_temp_new_ptr();
+tcg_gen_addi_ptr(ret, cpu_env, pred_full_reg_offset(s, regno));
+return ret;
+}
+
 bool disas_sve(DisasContext *, uint32_t);
 bool disas_sme(DisasContext *, uint32_t);
 
diff --git a/target/arm/translate.h b/target/arm/translate.h
index ef158a75c6..0c0c6641bb 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -155,6 +155,11 @@ static inline int plus_2(DisasContext *s, int x)
 return x + 2;
 }
 
+static inline int plus_12(DisasContext *s, int x)
+{
+return x + 12;
+}
+
 static inline int times_2(DisasContext *s, int x)
 {
 return x * 2;
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
index 6e4483fdce..241b4895b7 100644
--- a/target/arm/sme.decode
+++ b/target/arm/sme.decode
@@ -22,3 +22,18 @@
 ### SME Misc
 
 ZERO1100 00 001 000 imm:8
+
+### SME Move into/from Array
+
+%mova_rs13:2 !function=plus_12
+   esz rs pg zr za_imm v:bool to_vec:bool
+
+MOVA1100 esz:2 0 0 v:1 .. pg:3 zr:5 0 za_imm:4  \
+ to_vec=0 rs=%mova_rs
+MOVA1100 110 1 v:1 .. pg:3 zr:5 0 za_imm:4  \
+ to_vec=0 rs=%mova_rs esz=4
+
+MOVA1100 esz:2 1 0 v:1 .. pg:3 0 za_imm:4 zr:5  \
+ to_vec=1 rs=%mova_rs
+MOVA1100 111 1 v:1 .. pg:3 0 za_imm:4 zr:5  \
+ to_vec=1 rs=%mova_rs esz=4
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
index e5b5723a15..99524ead4d 100644
--- a/target/arm/sme_helper.c
+++ b/target/arm/sme_helper.c
@@ -19,8 +19,10 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
-#include 

[PATCH v3 37/51] target/arm: Reset streaming sve state on exception boundaries

2022-06-20 Thread Richard Henderson
We can handle both exception entry and exception return by
hooking into aarch64_sve_change_el.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 26f4a4bc26..9c5b1a10eb 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11754,6 +11754,19 @@ void aarch64_sve_change_el(CPUARMState *env, int 
old_el,
 return;
 }
 
+old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
+new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
+
+/*
+ * Both AArch64.TakeException and AArch64.ExceptionReturn
+ * invoke ResetSVEState when taking an exception from, or
+ * returning to, AArch32 state when PSTATE.SM is enabled.
+ */
+if (old_a64 != new_a64 && FIELD_EX64(env->svcr, SVCR, SM)) {
+arm_reset_sve_state(env);
+return;
+}
+
 /*
  * DDI0584A.d sec 3.2: "If SVE instructions are disabled or trapped
  * at ELx, or not available because the EL is in AArch32 state, then
@@ -11766,10 +11779,8 @@ void aarch64_sve_change_el(CPUARMState *env, int 
old_el,
  * we already have the correct register contents when encountering the
  * vq0->vq0 transition between EL0->EL1.
  */
-old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
 old_len = (old_a64 && !sve_exception_el(env, old_el)
? sve_vqm1_for_el(env, old_el) : 0);
-new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
 new_len = (new_a64 && !sve_exception_el(env, new_el)
? sve_vqm1_for_el(env, new_el) : 0);
 
-- 
2.34.1




Re: [PATCH v5 4/5] i386/pc: relocate 4g start to 1T where applicable

2022-06-20 Thread Joao Martins
On 6/20/22 17:36, Joao Martins wrote:
> On 6/20/22 15:27, Igor Mammedov wrote:
>> On Fri, 17 Jun 2022 14:33:02 +0100
>> Joao Martins  wrote:
>>> On 6/17/22 13:32, Igor Mammedov wrote:
 On Fri, 17 Jun 2022 13:18:38 +0100
 Joao Martins  wrote:  
> On 6/16/22 15:23, Igor Mammedov wrote:  
>> On Fri, 20 May 2022 11:45:31 +0100
>> Joao Martins  wrote:  
>>> +hwaddr above_4g_mem_start,
>>> +uint64_t pci_hole64_size)
>>> +{
>>> +PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
>>> +X86MachineState *x86ms = X86_MACHINE(pcms);
>>> +MachineState *machine = MACHINE(pcms);
>>> +ram_addr_t device_mem_size = 0;
>>> +hwaddr base;
>>> +
>>> +if (!x86ms->above_4g_mem_size) {
>>> +   /*
>>> +* 32-bit pci hole goes from
>>> +* end-of-low-ram (@below_4g_mem_size) to IOAPIC.
>>> +*/
>>> +return IO_APIC_DEFAULT_ADDRESS - 1;
>>
>> lack of above_4g_mem, doesn't mean absence of device_mem_size or 
>> anything else
>> that's located above it.
>> 
>
> True. But the intent is to fix 32-bit boundaries as one of the qtests was 
> failing
> otherwise. We won't hit the 1T hole, hence a nop.  

 I don't get the reasoning, can you clarify it pls?
   
>>>
>>> I was trying to say that what lead me here was a couple of qtests failures 
>>> (from v3->v4).
>>>
>>> I was doing this before based on pci_hole64. phys-bits=32 was for example 
>>> one
>>> of the test failures, and pci-hole64 sits above what 32-bit can reference.
>>
>> if user sets phys-bits=32, then nothing above 4Gb should work (be usable)
>> (including above-4g-ram, hotplug region or pci64 hole or sgx or cxl)
>>
>> and this doesn't look to me as AMD specific issue
>>
>> perhaps do a phys-bits check as a separate patch
>> that will error out if max_used_gpa is above phys-bits limit
>> (maybe at machine_done time)
>> (i.e. defining max_gpa and checking if compatible with configured cpu
>> are 2 different things)
>>
>> (it might be possible that tests need to be fixed too to account for it)
>>
> 
> My old notes (from v3) tell me with such a check these tests were exiting 
> early thanks to
> that error:
> 
>  1/56 qemu:qtest+qtest-x86_64 / qtest-x86_64/qom-test   ERROR 
>   0.07s
>   killed by signal 6 SIGABRT
>  4/56 qemu:qtest+qtest-x86_64 / qtest-x86_64/test-hmp   ERROR 
>   0.07s
>   killed by signal 6 SIGABRT
>  7/56 qemu:qtest+qtest-x86_64 / qtest-x86_64/boot-serial-test   ERROR 
>   0.07s
>   killed by signal 6 SIGABRT
> 44/56 qemu:qtest+qtest-x86_64 / qtest-x86_64/test-x86-cpuid-compat  ERROR 
>   0.09s
>   killed by signal 6 SIGABRT
> 45/56 qemu:qtest+qtest-x86_64 / qtest-x86_64/numa-test  ERROR 
>   0.17s
>   killed by signal 6 SIGABRT
> 
> But the real reason these fail is not at all related to CPU phys bits,
> but because we just don't handle the case where no pci_hole64 is supposed to 
> exist (which
> is what that other check is trying to do) e.g. A VM with -m 1G would
> observe the same thing i.e. the computations after that conditional are all 
> for the pci
> hole64, which acounts for SGX/CXL/hotplug or etc which consequently means 
> it's *errousnly*
> bigger than phys-bits=32 (by definition). So the error_report is just telling 
> me that
> pc_max_used_gpa() is just incorrect without the !x86ms->above_4g_mem_size 
> check.
> 
> If you're not fond of:
> 
> +if (!x86ms->above_4g_mem_size) {
> +   /*
> +* 32-bit pci hole goes from
> +* end-of-low-ram (@below_4g_mem_size) to IOAPIC.
> + */
> +return IO_APIC_DEFAULT_ADDRESS - 1;
> +}
> 
> Then what should I use instead of the above?
> 
> 'IO_APIC_DEFAULT_ADDRESS - 1' is the size of the 32-bit PCI hole, which is
> also what is used for i440fx/q35 code. I could move it to a macro (e.g.
> PCI_HOST_HOLE32_SIZE) to make it a bit readable and less hardcoded. Or
> perhaps your problem is on !x86ms->above_4g_mem_size and maybe I should check
> in addition for hotplug/CXL/etc existence?
> 
>  Unless we plan on using
> pc_max_used_gpa() for something else other than this.  

 Even if '!above_4g_mem_sizem', we can still have hotpluggable memory region
 present and that can  hit 1Tb. The same goes for pci64_hole if it's 
 configured
 large enough on CLI.
   
>>> So hotpluggable memory seems to assume it sits above 4g mem.
>>>
>>> pci_hole64 likewise as it uses similar computations as hotplug.
>>>
>>> Unless I am misunderstanding something here.
>>>
 Looks like guesstimate we could use is taking pci64_hole_end as max used 
 GPA
   
>>> I think this was what I had before (v3[0]) and did not work.
>>
>> that had been tied to host's phys-bits directly, all in one patch
>> and duplicating existing 

[PATCH v3 35/51] target/arm: Implement REVD

2022-06-20 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-sve.h|  2 ++
 target/arm/sve.decode  |  1 +
 target/arm/sve_helper.c| 16 
 target/arm/translate-sve.c |  2 ++
 4 files changed, 21 insertions(+)

diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
index ab0333400f..cc4e1d8948 100644
--- a/target/arm/helper-sve.h
+++ b/target/arm/helper-sve.h
@@ -719,6 +719,8 @@ DEF_HELPER_FLAGS_4(sve_revh_d, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_4(sve_revw_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_4(sme_revd_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 DEF_HELPER_FLAGS_4(sve_rbit_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sve_rbit_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sve_rbit_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index bf561c270a..d1e229fd6e 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -652,6 +652,7 @@ REVB0101 .. 1001 00 100 ... . . 
@rd_pg_rn
 REVH0101 .. 1001 01 100 ... . . @rd_pg_rn
 REVW0101 .. 1001 10 100 ... . . @rd_pg_rn
 RBIT0101 .. 1001 11 100 ... . . @rd_pg_rn
+REVD0101 00 1011 10 100 ... . . @rd_pg_rn_e0
 
 # SVE vector splice (predicated, destructive)
 SPLICE  0101 .. 101 100 100 ... . . @rdn_pg_rm
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 9a26f253e0..5de82696b5 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -931,6 +931,22 @@ DO_ZPZ_D(sve_revh_d, uint64_t, hswap64)
 
 DO_ZPZ_D(sve_revw_d, uint64_t, wswap64)
 
+void HELPER(sme_revd_q)(void *vd, void *vn, void *vg, uint32_t desc)
+{
+intptr_t i, opr_sz = simd_oprsz(desc) / 8;
+uint64_t *d = vd, *n = vn;
+uint8_t *pg = vg;
+
+for (i = 0; i < opr_sz; i += 2) {
+if (pg[H1(i)] & 1) {
+uint64_t n0 = n[i + 0];
+uint64_t n1 = n[i + 1];
+d[i + 0] = n1;
+d[i + 1] = n0;
+}
+}
+}
+
 DO_ZPZ(sve_rbit_b, uint8_t, H1, revbit8)
 DO_ZPZ(sve_rbit_h, uint16_t, H1_2, revbit16)
 DO_ZPZ(sve_rbit_s, uint32_t, H1_4, revbit32)
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 58d0894e15..1129f1fc56 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2896,6 +2896,8 @@ TRANS_FEAT(REVH, aa64_sve, gen_gvec_ool_arg_zpz, 
revh_fns[a->esz], a, 0)
 TRANS_FEAT(REVW, aa64_sve, gen_gvec_ool_arg_zpz,
a->esz == 3 ? gen_helper_sve_revw_d : NULL, a, 0)
 
+TRANS_FEAT(REVD, aa64_sme, gen_gvec_ool_arg_zpz, gen_helper_sme_revd_q, a, 0)
+
 TRANS_FEAT(SPLICE, aa64_sve, gen_gvec_ool_arg_zpzz,
gen_helper_sve_splice, a, a->esz)
 
-- 
2.34.1




Re: [PATCH v4 06/13] accel/tcg: Reorganize tcg_accel_ops_init()

2022-06-20 Thread Richard Henderson

On 3/23/22 10:17, Philippe Mathieu-Daudé wrote:

From: Philippe Mathieu-Daudé 

Reorg TCG AccelOpsClass initialization to emphasis icount
mode share more code with single-threaded TCG.

Signed-off-by: Philippe Mathieu-Daudé 
---
  accel/tcg/tcg-accel-ops.c | 15 ---
  1 file changed, 8 insertions(+), 7 deletions(-)


Queued to tcg-next.


r~



[PATCH] linux-user: Add partial support for MADV_DONTNEED

2022-06-20 Thread Ilya Leoshkevich
Currently QEMU ignores madvise(MADV_DONTNEED), which break apps that
rely on this for zeroing out memory [1]. Improve the situation by doing
a passthrough when the range in question is a host-page-aligned
anonymous mapping.

This is based on the patches from Simon Hausmann [2] and Chris Fallin
[3]. The structure is taken from Simon's patch. The PAGE_MAP_ANONYMOUS
bits are superseded by commit 26bab757d41b ("linux-user: Introduce
PAGE_ANON"). In the end the patch acts like the one from Chris: we
either pass-through the entire syscall, or do nothing, since doing this
only partially would not help the affected applications much. Finally,
add some extra checks to match the behavior of the Linux kernel [4].

[1] https://gitlab.com/qemu-project/qemu/-/issues/326
[2] https://patchew.org/QEMU/20180827084037.25316-1-simon.hausm...@qt.io/
[3] 
https://github.com/bytecodealliance/wasmtime/blob/v0.37.0/ci/qemu-madvise.patch
[4] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/madvise.c?h=v5.19-rc3#n1368

Signed-off-by: Ilya Leoshkevich 
---
 linux-user/mmap.c  | 68 ++
 linux-user/syscall.c   |  6 +---
 linux-user/user-mmap.h |  1 +
 3 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 48e1373796..900df7b28c 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -835,3 +835,71 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong 
old_size,
 mmap_unlock();
 return new_addr;
 }
+
+static bool can_passthrough_madv_dontneed(abi_ulong start, abi_ulong end)
+{
+ulong addr;
+
+if ((start | end) & ~qemu_host_page_mask) {
+return false;
+}
+
+for (addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+if (!(page_get_flags(addr) & PAGE_ANON)) {
+return false;
+}
+}
+
+return true;
+}
+
+int target_madvise(abi_ulong start, abi_ulong len_in, int advice)
+{
+abi_ulong len, end;
+int ret = 0;
+
+if (start & ~TARGET_PAGE_MASK) {
+errno = EINVAL;
+return -1;
+}
+len = TARGET_PAGE_ALIGN(len_in);
+
+if (len_in && !len) {
+errno = EINVAL;
+return -1;
+}
+
+end = start + len;
+if (end < start) {
+errno = EINVAL;
+return -1;
+}
+
+if (end == start) {
+return 0;
+}
+
+if (!guest_range_valid_untagged(start, len)) {
+errno = EINVAL;
+return -1;
+}
+
+/*
+ * A straight passthrough may not be safe because qemu sometimes turns
+ * private file-backed mappings into anonymous mappings.
+ *
+ * This is a hint, so ignoring and returning success is ok.
+ *
+ * This breaks MADV_DONTNEED, completely implementing which is quite
+ * complicated. However, there is one low-hanging fruit: host-page-aligned
+ * anonymous mappings. In this case passthrough is safe, so do it.
+ */
+mmap_lock();
+if ((advice & MADV_DONTNEED) &&
+can_passthrough_madv_dontneed(start, end)) {
+ret = madvise(g2h_untagged(start), len, MADV_DONTNEED);
+}
+mmap_unlock();
+
+return ret;
+}
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f55cdebee5..d25759b992 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11807,11 +11807,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int 
num, abi_long arg1,
 
 #ifdef TARGET_NR_madvise
 case TARGET_NR_madvise:
-/* A straight passthrough may not be safe because qemu sometimes
-   turns private file-backed mappings into anonymous mappings.
-   This will break MADV_DONTNEED.
-   This is a hint, so ignoring and returning success is ok.  */
-return 0;
+return get_errno(target_madvise(arg1, arg2, arg3));
 #endif
 #ifdef TARGET_NR_fcntl64
 case TARGET_NR_fcntl64:
diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h
index d1dec99c02..41cd358c7a 100644
--- a/linux-user/user-mmap.h
+++ b/linux-user/user-mmap.h
@@ -25,6 +25,7 @@ int target_munmap(abi_ulong start, abi_ulong len);
 abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
abi_ulong new_size, unsigned long flags,
abi_ulong new_addr);
+int target_madvise(abi_ulong start, abi_ulong len_in, int advice);
 extern unsigned long last_brk;
 extern abi_ulong mmap_next_start;
 abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong);
-- 
2.35.3




Re: [RFC PATCH v3 04/11] qapi: net: add stream and dgram netdevs

2022-06-20 Thread Laurent Vivier

On 20/06/2022 17:21, Markus Armbruster wrote:

Laurent Vivier  writes:


Copied from socket netdev file and modified to use SocketAddress
to be able to introduce new features like unix socket.

"udp" and "mcast" are squashed into dgram netdev, multicast is detected
according to the IP address type.
"listen" and "connect" modes are managed by stream netdev. An optional
parameter "server" defines the mode (server by default)

Signed-off-by: Laurent Vivier 
Reviewed-by: Stefano Brivio 
---
  hmp-commands.hx |   2 +-
  net/clients.h   |   6 +
  net/dgram.c | 630 
  net/hub.c   |   2 +
  net/meson.build |   2 +
  net/net.c   |  19 +-
  net/stream.c| 425 
  qapi/net.json   |  40 ++-
  qemu-options.hx |  12 +
  9 files changed, 1133 insertions(+), 5 deletions(-)
  create mode 100644 net/dgram.c
  create mode 100644 net/stream.c


...

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


Blank line here, please.


Done

...


diff --git a/net/net.c b/net/net.c
index c337d3d753fe..440957b272ee 100644
--- a/net/net.c
+++ b/net/net.c

...

@@ -1612,7 +1617,19 @@ void net_init_clients(void)
   */
  static bool netdev_is_modern(const char *optarg)
  {
-return false;
+QDict *args;
+const char *type;
+bool is_modern;
+
+args = keyval_parse(optarg, "type", NULL, NULL);
+if (!args) {
+return false;
+}
+type = qdict_get_try_str(args, "type");
+is_modern = !g_strcmp0(type, "stream") || !g_strcmp0(type, "dgram");
+qobject_unref(args);
+
+return is_modern;
  }


You could use g_autoptr here:

g_autoptr(QDict) args = NULL;
const char *type;
bool is_modern;

args = keyval_parse(optarg, "type", NULL, NULL);
if (!args) {
return false;
}
type = qdict_get_try_str(args, "type");
return !g_strcmp0(type, "stream") || !g_strcmp0(type, "dgram");

Matter of taste; you decide.


Looks good. We already had some series to convert existing code to g_autoptr(), so it 
seems the way to do.




Now recall how this function is used: it decides whether to parse the
modern way (with qobject_input_visitor_new_str()) or the traditional way
(with qemu_opts_parse_noisily()).

qemu_opts_parse_noisily() parses into a QemuOpts, for later use with the
opts visitor.

qobject_input_visitor_new_str() supports both dotted keys and JSON.  The
former is parsed with keyval_parse(), the latter with
qobject_from_json().  It returns the resulting parse tree wrapped in a
suitable QAPI input visitor.

Issue 1: since we get there only when keyval_parse() succeeds, JSON is
unreachable.  Reproducer:

 $ qemu-system-x86_64 -netdev '{"id":"foo"}'
 upstream-qemu: -netdev {"id":"foo"}: Parameter 'id' is missing

This is parsed with qemu_opts_parse_noisily(), resulting in a QemuOpts
with a single option 'type' with value '{"id":"foo"}'.  The error
message comes from the opts visitor.

To fix this, make netdev_is_modern() return true when optarg[0] == '{'.
This matches how qobject_input_visitor_new_str() recognizes JSON.


OK



Issue 2: when keyval_parse() detects an error, we throw it away and fall
back to QemuOpts.  This is commonly what we want.  But not always.  For
instance:

 $ qemu-system-x86_64 -netdev 
'type=stream,id=foo,addr.type=inet,addr.host=localhost,addr.port=1234,addr.ipv4-off'

Note the typo "ipv4-off" instead of ipv4=off.  The error reporting is crap:

 qemu-system-x86_64: -netdev 
type=stream,id=foo,addr.type=inet,addr.host=localhost,addr.port=1234,addr.ipv4-off:
 warning: short-form boolean option 'addr.ipv4-off' deprecated
 Please use addr.ipv4-off=on instead
 

[PATCH v3 00/51] target/arm: Scalable Matrix Extension

2022-06-20 Thread Richard Henderson
Changes for v3:
  * Rebase on mainline (20 patches upstreamed; new conflicts resolved).
  * Test bit 31 before disas_sme.

The first 21 patches, excepting 17, have been reviewed.


r~


Richard Henderson (51):
  target/arm: Implement TPIDR2_EL0
  target/arm: Add SMEEXC_EL to TB flags
  target/arm: Add syn_smetrap
  target/arm: Add ARM_CP_SME
  target/arm: Add SVCR
  target/arm: Add SMCR_ELx
  target/arm: Add SMIDR_EL1, SMPRI_EL1, SMPRIMAP_EL2
  target/arm: Add PSTATE.{SM,ZA} to TB flags
  target/arm: Add the SME ZA storage to CPUARMState
  target/arm: Implement SMSTART, SMSTOP
  target/arm: Move error for sve%d property to arm_cpu_sve_finalize
  target/arm: Create ARMVQMap
  target/arm: Generalize cpu_arm_{get,set}_vq
  target/arm: Generalize cpu_arm_{get,set}_default_vec_len
  target/arm: Move arm_cpu_*_finalize to internals.h
  target/arm: Unexport aarch64_add_*_properties
  target/arm: Add cpu properties for SME
  target/arm: Introduce sve_vqm1_for_el_sm
  target/arm: Add SVL to TB flags
  target/arm: Move pred_{full,gvec}_reg_{offset,size} to translate-a64.h
  target/arm: Add infrastructure for disas_sme
  target/arm: Trap AdvSIMD usage when Streaming SVE is active
  target/arm: Implement SME RDSVL, ADDSVL, ADDSPL
  target/arm: Implement SME ZERO
  target/arm: Implement SME MOVA
  target/arm: Implement SME LD1, ST1
  target/arm: Export unpredicated ld/st from translate-sve.c
  target/arm: Implement SME LDR, STR
  target/arm: Implement SME ADDHA, ADDVA
  target/arm: Implement FMOPA, FMOPS (non-widening)
  target/arm: Implement BFMOPA, BFMOPS
  target/arm: Implement FMOPA, FMOPS (widening)
  target/arm: Implement SME integer outer product
  target/arm: Implement PSEL
  target/arm: Implement REVD
  target/arm: Implement SCLAMP, UCLAMP
  target/arm: Reset streaming sve state on exception boundaries
  target/arm: Enable SME for -cpu max
  linux-user/aarch64: Clear tpidr2_el0 if CLONE_SETTLS
  linux-user/aarch64: Reset PSTATE.SM on syscalls
  linux-user/aarch64: Add SM bit to SVE signal context
  linux-user/aarch64: Tidy target_restore_sigframe error return
  linux-user/aarch64: Do not allow duplicate or short sve records
  linux-user/aarch64: Verify extra record lock succeeded
  linux-user/aarch64: Move sve record checks into restore
  linux-user/aarch64: Implement SME signal handling
  linux-user: Rename sve prctls
  linux-user/aarch64: Implement PR_SME_GET_VL, PR_SME_SET_VL
  target/arm: Only set ZEN in reset if SVE present
  target/arm: Enable SME for user-only
  linux-user/aarch64: Add SME related hwcap entries

 docs/system/arm/cpu-features.rst  |   56 ++
 docs/system/arm/emulation.rst |4 +
 linux-user/aarch64/target_cpu.h   |5 +-
 linux-user/aarch64/target_prctl.h |   56 +-
 target/arm/cpregs.h   |5 +
 target/arm/cpu.h  |   95 ++-
 target/arm/helper-sme.h   |  146 
 target/arm/helper-sve.h   |4 +
 target/arm/helper.h   |   19 +
 target/arm/internals.h|4 +
 target/arm/syndrome.h |   14 +
 target/arm/translate-a64.h|   53 ++
 target/arm/translate.h|   14 +
 target/arm/sme-fa64.decode|   89 +++
 target/arm/sme.decode |   88 +++
 target/arm/sve.decode |   31 +-
 linux-user/aarch64/cpu_loop.c |9 +
 linux-user/aarch64/signal.c   |  242 +-
 linux-user/elfload.c  |   20 +
 linux-user/syscall.c  |   28 +-
 target/arm/cpu.c  |   34 +-
 target/arm/cpu64.c|  216 --
 target/arm/helper.c   |  276 ++-
 target/arm/kvm64.c|2 +-
 target/arm/machine.c  |   34 +
 target/arm/sme_helper.c   | 1174 +
 target/arm/sve_helper.c   |   28 +
 target/arm/translate-a64.c|  141 +++-
 target/arm/translate-sme.c|  353 +
 target/arm/translate-sve.c|  283 +--
 target/arm/translate-vfp.c|   12 +
 target/arm/translate.c|1 +
 target/arm/vec_helper.c   |   24 +
 target/arm/meson.build|4 +
 34 files changed, 3367 insertions(+), 197 deletions(-)
 create mode 100644 target/arm/helper-sme.h
 create mode 100644 target/arm/sme-fa64.decode
 create mode 100644 target/arm/sme.decode
 create mode 100644 target/arm/sme_helper.c
 create mode 100644 target/arm/translate-sme.c

-- 
2.34.1




[PATCH v3 05/51] target/arm: Add SVCR

2022-06-20 Thread Richard Henderson
This cpreg is used to access two new bits of PSTATE
that are not visible via any other mechanism.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h|  6 ++
 target/arm/helper.c | 13 +
 2 files changed, 19 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e99de18097..bb8cb959d1 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -258,6 +258,7 @@ typedef struct CPUArchState {
  *  nRW (also known as M[4]) is kept, inverted, in env->aarch64
  *  DAIF (exception masks) are kept in env->daif
  *  BTYPE is kept in env->btype
+ *  SM and ZA are kept in env->svcr
  *  all other bits are stored in their correct places in env->pstate
  */
 uint32_t pstate;
@@ -292,6 +293,7 @@ typedef struct CPUArchState {
 uint32_t condexec_bits; /* IT bits.  cpsr[15:10,26:25].  */
 uint32_t btype;  /* BTI branch type.  spsr[11:10].  */
 uint64_t daif; /* exception masks, in the bits they are in PSTATE */
+uint64_t svcr; /* PSTATE.{SM,ZA} in the bits they are in SVCR */
 
 uint64_t elr_el[4]; /* AArch64 exception link regs  */
 uint64_t sp_el[4]; /* AArch64 banked stack pointers */
@@ -1428,6 +1430,10 @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
 #define PSTATE_MODE_EL1t 4
 #define PSTATE_MODE_EL0t 0
 
+/* PSTATE bits that are accessed via SVCR and not stored in SPSR_ELx. */
+FIELD(SVCR, SM, 0, 1)
+FIELD(SVCR, ZA, 1, 1)
+
 /* Write a new value to v7m.exception, thus transitioning into or out
  * of Handler mode; this may result in a change of active stack pointer.
  */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2c080c6cac..3acc1dc378 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6349,11 +6349,24 @@ static CPAccessResult access_tpidr2(CPUARMState *env, 
const ARMCPRegInfo *ri,
 return CP_ACCESS_OK;
 }
 
+static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+   uint64_t value)
+{
+value &= R_SVCR_SM_MASK | R_SVCR_ZA_MASK;
+/* TODO: Side effects. */
+env->svcr = value;
+}
+
 static const ARMCPRegInfo sme_reginfo[] = {
 { .name = "TPIDR2_EL0", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 5,
   .access = PL0_RW, .accessfn = access_tpidr2,
   .fieldoffset = offsetof(CPUARMState, cp15.tpidr2_el0) },
+{ .name = "SVCR", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 2,
+  .access = PL0_RW, .type = ARM_CP_SME,
+  .fieldoffset = offsetof(CPUARMState, svcr),
+  .writefn = svcr_write, .raw_writefn = raw_write },
 };
 #endif /* TARGET_AARCH64 */
 
-- 
2.34.1




[PATCH v3 11/51] target/arm: Move error for sve%d property to arm_cpu_sve_finalize

2022-06-20 Thread Richard Henderson
Keep all of the error messages together.  This does mean that
when setting many sve length properties we'll only generate
one error, but we only really need one.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu64.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 15665c962b..a46e40f4f2 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -487,8 +487,13 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
   "using only sve properties.\n");
 } else {
 error_setg(errp, "cannot enable sve%d", vq * 128);
-error_append_hint(errp, "This CPU does not support "
-  "the vector length %d-bits.\n", vq * 128);
+if (vq_supported) {
+error_append_hint(errp, "This CPU does not support "
+  "the vector length %d-bits.\n", vq * 
128);
+} else {
+error_append_hint(errp, "SVE not supported by KVM "
+  "on this host\n");
+}
 }
 return;
 } else {
@@ -606,12 +611,6 @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, 
const char *name,
 return;
 }
 
-if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
-error_setg(errp, "cannot enable %s", name);
-error_append_hint(errp, "SVE not supported by KVM on this host\n");
-return;
-}
-
 cpu->sve_vq_map = deposit32(cpu->sve_vq_map, vq - 1, 1, value);
 cpu->sve_vq_init |= 1 << (vq - 1);
 }
-- 
2.34.1




[PATCH v3 07/51] target/arm: Add SMIDR_EL1, SMPRI_EL1, SMPRIMAP_EL2

2022-06-20 Thread Richard Henderson
Implement the streaming mode identification register, and the
two streaming priority registers.  For QEMU, they are all RES0.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2072f2a550..bbd04fbd67 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6351,6 +6351,18 @@ static CPAccessResult access_tpidr2(CPUARMState *env, 
const ARMCPRegInfo *ri,
 return CP_ACCESS_OK;
 }
 
+static CPAccessResult access_esm(CPUARMState *env, const ARMCPRegInfo *ri,
+ bool isread)
+{
+/* TODO: FEAT_FGT for SMPRI_EL1 but not SMPRIMAP_EL2 */
+if (arm_current_el(env) < 3
+&& arm_feature(env, ARM_FEATURE_EL3)
+&& !FIELD_EX64(env->cp15.cptr_el[3], CPTR_EL3, ESM)) {
+return CP_ACCESS_TRAP_EL3;
+}
+return CP_ACCESS_OK;
+}
+
 static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
 {
@@ -6408,6 +6420,27 @@ static const ARMCPRegInfo sme_reginfo[] = {
   .access = PL3_RW, .type = ARM_CP_SME,
   .fieldoffset = offsetof(CPUARMState, vfp.smcr_el[3]),
   .writefn = smcr_write, .raw_writefn = raw_write },
+{ .name = "SMIDR_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 6,
+  .access = PL1_R, .accessfn = access_aa64_tid1,
+  /*
+   * IMPLEMENTOR = 0 (software)
+   * REVISION= 0 (implementation defined)
+   * SMPS= 0 (no streaming execution priority in QEMU)
+   * AFFINITY= 0 (streaming sve mode not shared with other PEs)
+   */
+  .type = ARM_CP_CONST, .resetvalue = 0, },
+/*
+ * Because SMIDR_EL1.SMPS is 0, SMPRI_EL1 and SMPRIMAP_EL2 are RES 0.
+ */
+{ .name = "SMPRI_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 4,
+  .access = PL1_RW, .accessfn = access_esm,
+  .type = ARM_CP_CONST, .resetvalue = 0 },
+{ .name = "SMPRIMAP_EL2", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 5,
+  .access = PL2_RW, .accessfn = access_esm,
+  .type = ARM_CP_CONST, .resetvalue = 0 },
 };
 #endif /* TARGET_AARCH64 */
 
-- 
2.34.1




[PATCH v3 19/51] target/arm: Add SVL to TB flags

2022-06-20 Thread Richard Henderson
We need SVL separate from VL for RDSVL et al, as well as
ZA storage loads and stores, which do not require PSTATE.SM.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   | 12 
 target/arm/translate.h |  1 +
 target/arm/helper.c|  8 +++-
 target/arm/translate-a64.c |  1 +
 4 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 244f8428e9..068877323c 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3168,6 +3168,7 @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
 FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
 FIELD(TBFLAG_A64, PSTATE_SM, 22, 1)
 FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
+FIELD(TBFLAG_A64, SVL, 24, 4)
 
 /*
  * Helpers for using the above.
@@ -3213,6 +3214,17 @@ static inline int sve_vq(CPUARMState *env)
 return EX_TBFLAG_A64(env->hflags, VL) + 1;
 }
 
+/**
+ * sme_vq
+ * @env: the cpu context
+ *
+ * Return the SVL cached within env->hflags, in units of quadwords.
+ */
+static inline int sme_vq(CPUARMState *env)
+{
+return EX_TBFLAG_A64(env->hflags, SVL) + 1;
+}
+
 static inline bool bswap_code(bool sctlr_b)
 {
 #ifdef CONFIG_USER_ONLY
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 93766649f7..22fd882368 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -44,6 +44,7 @@ typedef struct DisasContext {
 int sve_excp_el; /* SVE exception EL or 0 if enabled */
 int sme_excp_el; /* SME exception EL or 0 if enabled */
 int vl;  /* current vector length in bytes */
+int svl; /* current streaming vector length in bytes */
 bool vfp_enabled; /* FP enabled via FPSCR.EN */
 int vec_len;
 int vec_stride;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2e4e739969..d2886a123a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11352,7 +11352,13 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState 
*env, int el, int fp_el,
 DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
 }
 if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
-DP_TBFLAG_A64(flags, SMEEXC_EL, sme_exception_el(env, el));
+int sme_el = sme_exception_el(env, el);
+
+DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el);
+if (sme_el == 0) {
+/* Similarly, do not compute SVL if SME is disabled. */
+DP_TBFLAG_A64(flags, SVL, sve_vqm1_for_el_sm(env, el, true));
+}
 if (FIELD_EX64(env->svcr, SVCR, SM)) {
 DP_TBFLAG_A64(flags, PSTATE_SM, 1);
 }
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c050ebe005..c86b97b1d4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14647,6 +14647,7 @@ static void 
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
 dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
 dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
 dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
+dc->svl = (EX_TBFLAG_A64(tb_flags, SVL) + 1) * 16;
 dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
 dc->bt = EX_TBFLAG_A64(tb_flags, BT);
 dc->btype = EX_TBFLAG_A64(tb_flags, BTYPE);
-- 
2.34.1




[PATCH v3 10/51] target/arm: Implement SMSTART, SMSTOP

2022-06-20 Thread Richard Henderson
These two instructions are aliases of MSR (immediate).
Use the two helpers to properly implement svcr_write.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   |  1 +
 target/arm/helper-sme.h| 21 +
 target/arm/helper.h|  1 +
 target/arm/helper.c|  6 ++--
 target/arm/sme_helper.c| 61 ++
 target/arm/translate-a64.c | 24 +++
 target/arm/meson.build |  1 +
 7 files changed, 112 insertions(+), 3 deletions(-)
 create mode 100644 target/arm/helper-sme.h
 create mode 100644 target/arm/sme_helper.c

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index c3c7ec697d..2e049291da 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1106,6 +1106,7 @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
int new_el, bool el0_a64);
 void aarch64_add_sve_properties(Object *obj);
 void aarch64_add_pauth_properties(Object *obj);
+void arm_reset_sve_state(CPUARMState *env);
 
 /*
  * SVE registers are encoded in KVM's memory in an endianness-invariant format.
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
new file mode 100644
index 00..3bd48c235f
--- /dev/null
+++ b/target/arm/helper-sme.h
@@ -0,0 +1,21 @@
+/*
+ *  AArch64 SME specific helper definitions
+ *
+ *  Copyright (c) 2022 Linaro, Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+DEF_HELPER_FLAGS_2(set_pstate_sm, TCG_CALL_NO_RWG, void, env, i32)
+DEF_HELPER_FLAGS_2(set_pstate_za, TCG_CALL_NO_RWG, void, env, i32)
diff --git a/target/arm/helper.h b/target/arm/helper.h
index 07d45faf49..3a8ce42ab0 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -1022,6 +1022,7 @@ DEF_HELPER_FLAGS_6(gvec_bfmlal_idx, TCG_CALL_NO_RWG,
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
 #include "helper-sve.h"
+#include "helper-sme.h"
 #endif
 
 #include "helper-mve.h"
diff --git a/target/arm/helper.c b/target/arm/helper.c
index e06c054c3d..88d96f7991 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6366,9 +6366,9 @@ static CPAccessResult access_esm(CPUARMState *env, const 
ARMCPRegInfo *ri,
 static void svcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
 {
-value &= R_SVCR_SM_MASK | R_SVCR_ZA_MASK;
-/* TODO: Side effects. */
-env->svcr = value;
+helper_set_pstate_sm(env, FIELD_EX64(value, SVCR, SM));
+helper_set_pstate_za(env, FIELD_EX64(value, SVCR, ZA));
+arm_rebuild_hflags(env);
 }
 
 static void smcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
new file mode 100644
index 00..b215725594
--- /dev/null
+++ b/target/arm/sme_helper.c
@@ -0,0 +1,61 @@
+/*
+ * ARM SME Operations
+ *
+ * Copyright (c) 2022 Linaro, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+#include "exec/helper-proto.h"
+
+/* ResetSVEState */
+void arm_reset_sve_state(CPUARMState *env)
+{
+memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs));
+/* Recall that FFR is stored as pregs[16]. */
+memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs));
+vfp_set_fpcr(env, 0x089f);
+}
+
+void helper_set_pstate_sm(CPUARMState *env, uint32_t i)
+{
+if (i == FIELD_EX64(env->svcr, SVCR, SM)) {
+return;
+}
+env->svcr ^= R_SVCR_SM_MASK;
+arm_reset_sve_state(env);
+}
+
+void helper_set_pstate_za(CPUARMState *env, uint32_t i)
+{
+if (i == FIELD_EX64(env->svcr, SVCR, ZA)) {
+return;
+}
+env->svcr ^= R_SVCR_ZA_MASK;
+
+/*
+ * ResetSMEState.
+ *
+ * SetPSTATE_ZA zeros on enable and 

[PATCH v3 27/51] target/arm: Export unpredicated ld/st from translate-sve.c

2022-06-20 Thread Richard Henderson
Add a TCGv_ptr base argument, which will be cpu_env for SVE.
We will reuse this for SME save and restore array insns.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.h |  3 +++
 target/arm/translate-sve.c | 48 --
 2 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index c341c95582..54503745a9 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -165,4 +165,7 @@ void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t 
rn_ofs,
   uint32_t rm_ofs, int64_t shift,
   uint32_t opr_sz, uint32_t max_sz);
 
+void gen_sve_ldr(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int 
imm);
+void gen_sve_str(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int 
imm);
+
 #endif /* TARGET_ARM_TRANSLATE_A64_H */
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 13bdd027a5..adf0cd3e68 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4294,7 +4294,8 @@ TRANS_FEAT(UCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz,
  * The load should begin at the address Rn + IMM.
  */
 
-static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
+void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs,
+ int len, int rn, int imm)
 {
 int len_align = QEMU_ALIGN_DOWN(len, 8);
 int len_remain = len % 8;
@@ -4320,7 +4321,7 @@ static void do_ldr(DisasContext *s, uint32_t vofs, int 
len, int rn, int imm)
 t0 = tcg_temp_new_i64();
 for (i = 0; i < len_align; i += 8) {
 tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEUQ);
-tcg_gen_st_i64(t0, cpu_env, vofs + i);
+tcg_gen_st_i64(t0, base, vofs + i);
 tcg_gen_addi_i64(clean_addr, clean_addr, 8);
 }
 tcg_temp_free_i64(t0);
@@ -4333,6 +4334,12 @@ static void do_ldr(DisasContext *s, uint32_t vofs, int 
len, int rn, int imm)
 clean_addr = new_tmp_a64_local(s);
 tcg_gen_mov_i64(clean_addr, t0);
 
+if (base != cpu_env) {
+TCGv_ptr b = tcg_temp_local_new_ptr();
+tcg_gen_mov_ptr(b, base);
+base = b;
+}
+
 gen_set_label(loop);
 
 t0 = tcg_temp_new_i64();
@@ -4340,7 +4347,7 @@ static void do_ldr(DisasContext *s, uint32_t vofs, int 
len, int rn, int imm)
 tcg_gen_addi_i64(clean_addr, clean_addr, 8);
 
 tp = tcg_temp_new_ptr();
-tcg_gen_add_ptr(tp, cpu_env, i);
+tcg_gen_add_ptr(tp, base, i);
 tcg_gen_addi_ptr(i, i, 8);
 tcg_gen_st_i64(t0, tp, vofs);
 tcg_temp_free_ptr(tp);
@@ -4348,6 +4355,11 @@ static void do_ldr(DisasContext *s, uint32_t vofs, int 
len, int rn, int imm)
 
 tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
 tcg_temp_free_ptr(i);
+
+if (base != cpu_env) {
+tcg_temp_free_ptr(base);
+assert(len_remain == 0);
+}
 }
 
 /*
@@ -4376,13 +4388,14 @@ static void do_ldr(DisasContext *s, uint32_t vofs, int 
len, int rn, int imm)
 default:
 g_assert_not_reached();
 }
-tcg_gen_st_i64(t0, cpu_env, vofs + len_align);
+tcg_gen_st_i64(t0, base, vofs + len_align);
 tcg_temp_free_i64(t0);
 }
 }
 
 /* Similarly for stores.  */
-static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
+void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
+ int len, int rn, int imm)
 {
 int len_align = QEMU_ALIGN_DOWN(len, 8);
 int len_remain = len % 8;
@@ -4408,7 +4421,7 @@ static void do_str(DisasContext *s, uint32_t vofs, int 
len, int rn, int imm)
 
 t0 = tcg_temp_new_i64();
 for (i = 0; i < len_align; i += 8) {
-tcg_gen_ld_i64(t0, cpu_env, vofs + i);
+tcg_gen_ld_i64(t0, base, vofs + i);
 tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ);
 tcg_gen_addi_i64(clean_addr, clean_addr, 8);
 }
@@ -4422,11 +4435,17 @@ static void do_str(DisasContext *s, uint32_t vofs, int 
len, int rn, int imm)
 clean_addr = new_tmp_a64_local(s);
 tcg_gen_mov_i64(clean_addr, t0);
 
+if (base != cpu_env) {
+TCGv_ptr b = tcg_temp_local_new_ptr();
+tcg_gen_mov_ptr(b, base);
+base = b;
+}
+
 gen_set_label(loop);
 
 t0 = tcg_temp_new_i64();
 tp = tcg_temp_new_ptr();
-tcg_gen_add_ptr(tp, cpu_env, i);
+tcg_gen_add_ptr(tp, base, i);
 tcg_gen_ld_i64(t0, tp, vofs);
 tcg_gen_addi_ptr(i, i, 8);
 tcg_temp_free_ptr(tp);
@@ -4437,12 +4456,17 @@ static void do_str(DisasContext *s, uint32_t vofs, int 
len, int rn, int imm)
 
 tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
 tcg_temp_free_ptr(i);
+
+if (base != cpu_env) {
+tcg_temp_free_ptr(base);
+

[PATCH v3 15/51] target/arm: Move arm_cpu_*_finalize to internals.h

2022-06-20 Thread Richard Henderson
Drop the aa32-only inline fallbacks,
and just use a couple of ifdefs.

Reviewed-by: Peter Maydell 
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   | 6 --
 target/arm/internals.h | 3 +++
 target/arm/cpu.c   | 2 ++
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ece720a757..d8ff78d96d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -205,14 +205,8 @@ typedef struct {
 
 #ifdef TARGET_AARCH64
 # define ARM_MAX_VQ16
-void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
-void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
-void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
 #else
 # define ARM_MAX_VQ1
-static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
-static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
-static inline void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) { }
 #endif
 
 typedef struct ARMVectorReg {
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 6f94f3019d..aef568adf7 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1288,6 +1288,9 @@ int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, 
int reg);
 int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg);
 int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
 int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
+void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
+void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
+void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
 #endif
 
 #ifdef CONFIG_USER_ONLY
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1b5d535788..b5276fa944 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1421,6 +1421,7 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
 {
 Error *local_err = NULL;
 
+#ifdef TARGET_AARCH64
 if (arm_feature(>env, ARM_FEATURE_AARCH64)) {
 arm_cpu_sve_finalize(cpu, _err);
 if (local_err != NULL) {
@@ -1440,6 +1441,7 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
 return;
 }
 }
+#endif
 
 if (kvm_enabled()) {
 kvm_arm_steal_time_finalize(cpu, _err);
-- 
2.34.1




[PATCH v3 22/51] target/arm: Trap AdvSIMD usage when Streaming SVE is active

2022-06-20 Thread Richard Henderson
This new behaviour is in the ARM pseudocode function
AArch64.CheckFPAdvSIMDEnabled, which applies to AArch32
via AArch32.CheckAdvSIMDOrFPEnabled when the EL to which
the trap would be delivered is in AArch64 mode.

Given that ARMv9 drops support for AArch32 outside EL0,
the trap EL detection ought to be trivially true, but
the pseudocode still contains a number of conditions,
and QEMU has not yet committed to dropping A32 support
for EL[12] when v9 features are present.

Since the computation of SME_TRAP_SIMD is necessarily
different for the two modes, we might as well preserve
bits within TBFLAG_ANY and allocate separate bits within
TBFLAG_A32 and TBFLAG_A64 instead.

Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   |  6 +++
 target/arm/translate.h |  3 ++
 target/arm/sme-fa64.decode | 89 ++
 target/arm/helper.c| 42 ++
 target/arm/translate-a64.c | 40 -
 target/arm/translate-vfp.c | 12 +
 target/arm/translate.c |  1 +
 target/arm/meson.build |  1 +
 8 files changed, 192 insertions(+), 2 deletions(-)
 create mode 100644 target/arm/sme-fa64.decode

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 068877323c..da1c036fa0 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3132,6 +3132,11 @@ FIELD(TBFLAG_A32, HSTR_ACTIVE, 9, 1)
  * the same thing as the current security state of the processor!
  */
 FIELD(TBFLAG_A32, NS, 10, 1)
+/*
+ * Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not.
+ * This requires an SME trap from AArch32 mode when using NEON.
+ */
+FIELD(TBFLAG_A32, SME_TRAP_SIMD, 11, 1)
 
 /*
  * Bit usage when in AArch32 state, for M-profile only.
@@ -3169,6 +3174,7 @@ FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
 FIELD(TBFLAG_A64, PSTATE_SM, 22, 1)
 FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
 FIELD(TBFLAG_A64, SVL, 24, 4)
+FIELD(TBFLAG_A64, SME_TRAP_SIMD, 28, 1)
 
 /*
  * Helpers for using the above.
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 22fd882368..ef158a75c6 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -102,6 +102,9 @@ typedef struct DisasContext {
 bool pstate_sm;
 /* True if PSTATE.ZA is set. */
 bool pstate_za;
+/* True if AdvSIMD insns should raise an SME Streaming exception. */
+bool sme_trap_simd;
+bool sme_trap_this_insn;
 /* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
 bool mve_no_pred;
 /*
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
new file mode 100644
index 00..4c2569477d
--- /dev/null
+++ b/target/arm/sme-fa64.decode
@@ -0,0 +1,89 @@
+# AArch64 SME allowed instruction decoding
+#
+#  Copyright (c) 2022 Linaro, Ltd
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see .
+
+#
+# This file is processed by scripts/decodetree.py
+#
+
+# These patterns are taken from Appendix E1.1 of DDI0616 A.a,
+# Arm Architecture Reference Manual Supplement,
+# The Scalable Matrix Extension (SME), for Armv9-A
+
+{
+  [
+OK  0-00 1110  0001 0010 11--     # SMOV W|Xd,Vn.B[0]
+OK  0-00 1110  0010 0010 11--     # SMOV W|Xd,Vn.H[0]
+OK  0100 1110  0100 0010 11--     # SMOV Xd,Vn.S[0]
+OK   1110  0001 0011 11--     # UMOV Wd,Vn.B[0]
+OK   1110  0010 0011 11--     # UMOV Wd,Vn.H[0]
+OK   1110  0100 0011 11--     # UMOV Wd,Vn.S[0]
+OK  0100 1110  1000 0011 11--     # UMOV Xd,Vn.D[0]
+  ]
+  FAIL  0--0 111-         # Advanced SIMD vector 
operations
+}
+
+{
+  [
+OK  0101 1110 --1-  11-1 11--     # FMULX/FRECPS/FRSQRTS 
(scalar)
+OK  0101 1110 -10-  00-1 11--     # FMULX/FRECPS/FRSQRTS 
(scalar, FP16)
+OK  01-1 1110 1-10 0001 11-1 10--     # FRECPE/FRSQRTE/FRECPX 
(scalar)
+OK  01-1 1110  1001 11-1 10--     # FRECPE/FRSQRTE/FRECPX 
(scalar, FP16)
+  ]
+  FAIL  01-1 111-         # Advanced SIMD 
single-element operations
+}
+
+FAIL0-00 110-         # Advanced SIMD structure 
load/store
+FAIL1100 1110         # Advanced SIMD cryptography 
extensions
+
+# These are the "avoidance of doubt" final table of Illegal Advanced SIMD 
instructions
+# We don't actually need 

[PATCH v3 28/51] target/arm: Implement SME LDR, STR

2022-06-20 Thread Richard Henderson
We can reuse the SVE functions for LDR and STR, passing in the
base of the ZA vector and a zero offset.

Signed-off-by: Richard Henderson 
---
 target/arm/sme.decode  |  7 +++
 target/arm/translate-sme.c | 23 +++
 2 files changed, 30 insertions(+)

diff --git a/target/arm/sme.decode b/target/arm/sme.decode
index 900e3f2a07..f1ebd857a5 100644
--- a/target/arm/sme.decode
+++ b/target/arm/sme.decode
@@ -46,3 +46,10 @@ LDST1   111 0 esz:2 st:1 rm:5 v:1 .. pg:3 rn:5 0 
za_imm:4  \
  rs=%mova_rs
 LDST1   111 111 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4  \
  esz=4 rs=%mova_rs
+
+  rv rn imm
+@ldstr  ... ... . .. .. ... rn:5 . imm:4 \
+ rv=%mova_rs
+
+LDR 111 100 0 00 .. 000 . 0 @ldstr
+STR 111 100 1 00 .. 000 . 0 @ldstr
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
index 978af74d1d..c3e544d69c 100644
--- a/target/arm/translate-sme.c
+++ b/target/arm/translate-sme.c
@@ -220,3 +220,26 @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
 tcg_temp_free_i64(addr);
 return true;
 }
+
+typedef void GenLdStR(DisasContext *, TCGv_ptr, int, int, int, int);
+
+static bool do_ldst_r(DisasContext *s, arg_ldstr *a, GenLdStR *fn)
+{
+int imm = a->imm;
+TCGv_ptr base;
+
+if (!sme_za_enabled_check(s)) {
+return true;
+}
+
+/* ZA[n] equates to ZA0H.B[n]. */
+base = get_tile_rowcol(s, MO_8, a->rv, imm, false);
+
+fn(s, base, 0, s->svl, a->rn, imm * s->svl);
+
+tcg_temp_free_ptr(base);
+return true;
+}
+
+TRANS_FEAT(LDR, aa64_sme, do_ldst_r, a, gen_sve_ldr)
+TRANS_FEAT(STR, aa64_sme, do_ldst_r, a, gen_sve_str)
-- 
2.34.1




<    1   2   3   4   >