Re: [PATCH 2/3] virtio-net: Only enable userland vq if using tap backend

2021-11-18 Thread Eugenio Perez Martin
On Fri, Nov 19, 2021 at 3:44 AM Jason Wang  wrote:
>
> On Thu, Nov 18, 2021 at 3:57 PM Eugenio Perez Martin
>  wrote:
> >
> > On Thu, Nov 18, 2021 at 6:06 AM Jason Wang  wrote:
> > >
> > > On Thu, Nov 18, 2021 at 3:29 AM Eugenio Pérez  wrote:
> > > >
> > > > Qemu falls back on userland handlers even if vhost-user and vhost-vdpa
> > > > cases. These assumes a tap device can handle the packets.
> > > >
> > > > If a vdpa device fail to start, it can trigger a sigsegv because of
> > > > that. Do not resort on them unless actually possible.
> > >
> > > It would be better to show the calltrace here then we can see the root 
> > > cause.
> > >
> >
> > Sure, I'll paste here and I'll resend to the next version:
> > #1  0x55955f696e92 in nc_sendv_compat (flags=,
> > iovcnt=2, iov=0x7ffe73abe300, nc=0x7fcf22d6d010) at ../net/net.c:756
> > #2  qemu_deliver_packet_iov (sender=,
> > opaque=0x7fcf22d6d010, iovcnt=2, iov=0x7ffe73abe300, flags= > out>) at ../net/net.c:784
> > #3  qemu_deliver_packet_iov (sender=, flags= > out>, iov=0x7ffe73abe300, iovcnt=2, opaque=0x7fcf22d6d010) at
> > ../net/net.c:763
> > #4  0x55955f69a078 in qemu_net_queue_deliver_iov (iovcnt=2,
> > iov=0x7ffe73abe300, flags=0, sender=0x5595631f5ac0,
> > queue=0x559561c7baa0) at ../net/queue.c:179
> > #5  qemu_net_queue_send_iov (queue=0x559561c7baa0,
> > sender=0x5595631f5ac0, flags=flags@entry=0,
> > iov=iov@entry=0x7ffe73abe300,
> > iovcnt=iovcnt@entry=2, sent_cb=sent_cb@entry=0x55955f82ae60
> > ) at ../net/queue.c:246
> > #6  0x55955f697d43 in qemu_sendv_packet_async
> > (sent_cb=0x55955f82ae60 , iovcnt=2,
> > iov=0x7ffe73abe300,
> > sender=) at ../net/net.c:825
> > #7  qemu_sendv_packet_async (sender=,
> > iov=iov@entry=0x7ffe73abe300, iovcnt=iovcnt@entry=1662966768,
> > sent_cb=sent_cb@entry=0x55955f82ae60 ) at
> > ../net/net.c:794
> > #8  0x55955f82aba9 in virtio_net_flush_tx (q=0x0,
> > q@entry=0x5595631edbf0) at ../hw/net/virtio-net.c:2577
> > #9  0x55955f82ade8 in virtio_net_tx_bh (opaque=0x5595631edbf0) at
> > ../hw/net/virtio-net.c:2694
> > #10 0x55955f9e847d in aio_bh_call (bh=0x559561c7e590) at 
> > ../util/async.c:169
> > #11 aio_bh_poll (ctx=ctx@entry=0x559561c81650) at ../util/async.c:169
> > #12 0x55955f9d6912 in aio_dispatch (ctx=0x559561c81650) at
> > ../util/aio-posix.c:381
> > #13 0x55955f9e8322 in aio_ctx_dispatch (source=,
> > callback=, user_data=)
> > at ../util/async.c:311
> > #14 0x7fcf20a5495d in g_main_context_dispatch () from
> > /lib64/libglib-2.0.so.0
> > #15 0x55955f9f2fc0 in glib_pollfds_poll () at ../util/main-loop.c:232
> > #16 os_host_main_loop_wait (timeout=) at 
> > ../util/main-loop.c:255
> > #17 main_loop_wait (nonblocking=nonblocking@entry=0) at 
> > ../util/main-loop.c:531
> > #18 0x55955f7eee49 in qemu_main_loop () at ../softmmu/runstate.c:726
> > #19 0x55955f6235c2 in main (argc=, argv= > out>, envp=) at ../softmmu/main.c:50
> >
> > In nc_sendv_compat, nc->info is net_vhost_vdpa_info, so
> > nc->info->receive is NULL.
> >
> > > >
> > > > Signed-off-by: Eugenio Pérez 
> > > > ---
> > > >  include/hw/virtio/virtio.h |  2 ++
> > > >  hw/net/virtio-net.c|  4 
> > > >  hw/virtio/virtio.c | 21 +
> > > >  3 files changed, 19 insertions(+), 8 deletions(-)
> > > >
> > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > index 8bab9cfb75..1712ba0b4c 100644
> > > > --- a/include/hw/virtio/virtio.h
> > > > +++ b/include/hw/virtio/virtio.h
> > > > @@ -105,6 +105,8 @@ struct VirtIODevice
> > > >  VMChangeStateEntry *vmstate;
> > > >  char *bus_name;
> > > >  uint8_t device_endian;
> > > > +/* backend does not support userspace handler */
> > > > +bool disable_ioeventfd_handler;
> > > >  bool use_guest_notifier_mask;
> > > >  AddressSpace *dma_as;
> > > >  QLIST_HEAD(, VirtQueue) *vector_queues;
> > > > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > > > index 004acf858f..8c5c4e5a9d 100644
> > > > --- a/hw/net/virtio-net.c
> > > > +++ b/hw/net/virtio-net.c
> > > > @@ -3501,6 +3501,10 @@ static void 
> > > > virtio_net_device_realize(DeviceState *dev, Error **errp)
> > > >  nc = qemu_get_queue(n->nic);
> > > >  nc->rxfilter_notify_enabled = 1;
> > > >
> > > > +if (!nc->peer || nc->peer->info->type != NET_CLIENT_DRIVER_TAP) {
> > > > +/* Only tap can use userspace networking */
> > > > +vdev->disable_ioeventfd_handler = true;
> > > > +}
> > > >  if (nc->peer && nc->peer->info->type == 
> > > > NET_CLIENT_DRIVER_VHOST_VDPA) {
> > > >  struct virtio_net_config netcfg = {};
> > > >  memcpy(, >nic_conf.macaddr, ETH_ALEN);
> > > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > > > index ea7c079fb0..1e04db6650 100644
> > > > --- a/hw/virtio/virtio.c
> > > > +++ b/hw/virtio/virtio.c
> > > > @@ -3734,17 +3734,22 @@ static int 
> > > > virtio_device_start_ioeventfd_impl(VirtIODevice *vdev)
> > > 

Re: [PATCH 1/5] hw/core: Remove use of QERR_UNSUPPORTED

2021-11-18 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> QERR_UNSUPPORTED definition is obsolete since 2015 (commit
> 4629ed1e989, "qerror: Finally unused, clean up"). Replace it.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/core/nmi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/core/nmi.c b/hw/core/nmi.c
> index 481c4b3c7e5..b4b4a1ed286 100644
> --- a/hw/core/nmi.c
> +++ b/hw/core/nmi.c
> @@ -70,7 +70,7 @@ void nmi_monitor_handle(int cpu_index, Error **errp)
>  if (ns.handled) {
>  error_propagate(errp, ns.err);
>  } else {
> -error_setg(errp, QERR_UNSUPPORTED);
> +error_setg(errp, "This command is not currently supported");
>  }
>  }

I think this error message doesn't quite fit here.

We error out when the QOM composition tree does not contain an object
providing interface "nmi".  We don't tell the user, though.  This isn't
terrible, because the suitable objects are generally created by board
code, so whether the command works generally depends only on the machine
type.  Still, a bit more detail in the error message wouldn't hurt,
would it?  Say "machine does not support NMIs".




[PATCH v11 23/26] default-configs: Add loongarch linux-user support

2021-11-18 Thread Song Gao
This patch adds loongarch64 linux-user default configs file.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 configs/targets/loongarch64-linux-user.mak | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 configs/targets/loongarch64-linux-user.mak

diff --git a/configs/targets/loongarch64-linux-user.mak 
b/configs/targets/loongarch64-linux-user.mak
new file mode 100644
index 000..5b0acfa
--- /dev/null
+++ b/configs/targets/loongarch64-linux-user.mak
@@ -0,0 +1,3 @@
+# Default configuration for loongson64-linux-user
+TARGET_ARCH=loongarch64
+TARGET_BASE_ARCH=loongarch
-- 
1.8.3.1




[PATCH v11 26/26] scripts: add loongarch64 binfmt config

2021-11-18 Thread Song Gao
Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 scripts/qemu-binfmt-conf.sh | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index 7de996d..da6a937 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -4,7 +4,7 @@
 qemu_target_list="i386 i486 alpha arm armeb sparc sparc32plus sparc64 \
 ppc ppc64 ppc64le m68k mips mipsel mipsn32 mipsn32el mips64 mips64el \
 sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \
-microblaze microblazeel or1k x86_64 hexagon"
+microblaze microblazeel or1k x86_64 hexagon loongarch64"
 
 
i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
 
i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
@@ -140,6 +140,10 @@ 
hexagon_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x
 
hexagon_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
 hexagon_family=hexagon
 
+loongarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01'
+loongarch64_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
+loongarch64_family=loongarch
+
 qemu_get_family() {
 cpu=${HOST_ARCH:-$(uname -m)}
 case "$cpu" in
-- 
1.8.3.1




[PATCH v11 12/26] target/loongarch: Add floating point conversion instruction translation

2021-11-18 Thread Song Gao
This includes:
- FCVT.S.D, FCVT.D.S
- FFINT.{S/D}.{W/L}, FTINT.{W/L}.{S/D}
- FTINT{RM/RP/RZ/RNE}.{W/L}.{S/D}
- FRINT.{S/D}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/fpu_helper.c| 393 +++
 target/loongarch/helper.h|  29 ++
 target/loongarch/insn_trans/trans_fcnv.c.inc |  33 +++
 target/loongarch/insns.decode|  32 +++
 target/loongarch/translate.c |   1 +
 5 files changed, 488 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_fcnv.c.inc

diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
index 807ffd0..4799b47 100644
--- a/target/loongarch/fpu_helper.c
+++ b/target/loongarch/fpu_helper.c
@@ -463,3 +463,396 @@ uint64_t helper_fcmp_s_d(CPULoongArchState *env, uint64_t 
fj,
 FloatRelation cmp = float64_compare(fj, fk, >fp_status);
 return fcmp_common(env, cmp, flags);
 }
+
+/* floating point conversion */
+uint64_t helper_fcvt_s_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = nanbox_s(float64_to_float32(fj, >fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fcvt_d_s(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = float32_to_float64((uint32_t)fj, >fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ffint_s_w(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = nanbox_s(int32_to_float32((int32_t)fj, >fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ffint_s_l(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = nanbox_s(int64_to_float32(fj, >fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ffint_d_w(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = int32_to_float64((int32_t)fj, >fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ffint_d_l(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = int64_to_float64(fj, >fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_frint_s(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = (uint64_t)(float32_round_to_int((uint32_t)fj, >fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_frint_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = float64_round_to_int(fj, >fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrm_l_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(>fp_status);
+
+set_float_rounding_mode(float_round_down, >fp_status);
+fd = float64_to_int64(fj, >fp_status);
+set_float_rounding_mode(old_mode, >fp_status);
+
+if (get_float_exception_flags(>fp_status) &
+(float_flag_invalid | float_flag_overflow)) {
+fd = FLOAT_TO_INT64_OVERFLOW;
+}
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrm_l_s(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(>fp_status);
+
+set_float_rounding_mode(float_round_down, >fp_status);
+fd = float32_to_int64((uint32_t)fj, >fp_status);
+set_float_rounding_mode(old_mode, >fp_status);
+
+if (get_float_exception_flags(>fp_status) &
+(float_flag_invalid | float_flag_overflow)) {
+fd = FLOAT_TO_INT64_OVERFLOW;
+}
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrm_w_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(>fp_status);
+
+set_float_rounding_mode(float_round_down, >fp_status);
+fd = (uint64_t)float64_to_int32(fj, >fp_status);
+set_float_rounding_mode(old_mode, >fp_status);
+
+if (get_float_exception_flags(>fp_status) &
+(float_flag_invalid | float_flag_overflow)) {
+fd = FLOAT_TO_INT32_OVERFLOW;
+}
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrm_w_s(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(>fp_status);
+
+set_float_rounding_mode(float_round_down, >fp_status);
+fd = (uint64_t)float32_to_int32((uint32_t)fj, >fp_status);
+set_float_rounding_mode(old_mode, >fp_status);
+
+if (get_float_exception_flags(>fp_status) &
+(float_flag_invalid | float_flag_overflow)) {
+fd = FLOAT_TO_INT32_OVERFLOW;
+}
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrp_l_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(>fp_status);
+
+set_float_rounding_mode(float_round_up, >fp_status);
+fd = float64_to_int64(fj, >fp_status);
+

Re: [PATCH 4/5] hw/core: Remove uses of QERR_PROPERTY_VALUE_BAD

2021-11-18 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> QERR_PROPERTY_VALUE_BAD definition is obsolete since 2015 (commit
> 4629ed1e989, "qerror: Finally unused, clean up"). Replace the two
> uses and drop the definition.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  include/qapi/qmp/qerror.h | 3 ---
>  hw/core/qdev-properties.c | 2 +-
>  target/i386/cpu.c | 2 +-
>  3 files changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
> index f49ae01cdb0..a3f44fc4a1e 100644
> --- a/include/qapi/qmp/qerror.h
> +++ b/include/qapi/qmp/qerror.h
> @@ -50,9 +50,6 @@
>  #define QERR_PERMISSION_DENIED \
>  "Insufficient permission to perform this operation"
>  
> -#define QERR_PROPERTY_VALUE_BAD \
> -"Property '%s.%s' doesn't take value '%s'"
> -
>  #define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
>  "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", 
> maximum: %" PRId64 ")"
>  
> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> index c34aac6ebc9..dbea4cf8e5e 100644
> --- a/hw/core/qdev-properties.c
> +++ b/hw/core/qdev-properties.c
> @@ -663,7 +663,7 @@ void error_set_from_qdev_prop_error(Error **errp, int 
> ret, Object *obj,
>  break;
>  default:
>  case -EINVAL:
> -error_setg(errp, QERR_PROPERTY_VALUE_BAD,
> +error_setg(errp, "Property '%s.%s' doesn't take value '%s'",
> object_get_typename(obj), name, value);
>  break;
>  case -ENOENT:
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index fc3ed80ef1e..bc63b80e5bd 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -4469,7 +4469,7 @@ static void x86_cpuid_set_vendor(Object *obj, const 
> char *value,
>  int i;
>  
>  if (strlen(value) != CPUID_VENDOR_SZ) {
> -error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
> +error_setg(errp, "Property '.vendor' doesn't take value '%s'", 
> value);
>  return;
>  }

We error out unless the string has exactly CPUID_VENDOR_SZ characters.
We don't tell the user, though[*].  We should!

If this patch was long, I'd separate the long & mechanical from the
error message improvement.  Since it isn't, I suggest to make the error
message improvement the patch's subject, and include the removal of
QERR_PROPERTY_VALUE_BAD "while there".  You choose how to structure
this.


[*] This is a common issue with error systems that make new error
messages harder than reusing some existing message.




[PATCH v11 25/26] target/loongarch: 'make check-tcg' support

2021-11-18 Thread Song Gao
Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
Acked-by: Alex Bennée 
---
 tests/tcg/configure.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
index 9b76f58..49a05ec 100755
--- a/tests/tcg/configure.sh
+++ b/tests/tcg/configure.sh
@@ -51,6 +51,7 @@ fi
 : ${cross_cc_cflags_armeb="-mbig-endian"}
 : ${cross_cc_hexagon="hexagon-unknown-linux-musl-clang"}
 : ${cross_cc_cflags_hexagon="-mv67 -O2 -static"}
+: ${cross_cc_loongarch64="loongarch64-unknown-linux-gnu-gcc"}
 : ${cross_cc_hppa="hppa-linux-gnu-gcc"}
 : ${cross_cc_i386="i686-linux-gnu-gcc"}
 : ${cross_cc_cflags_i386="-m32"}
-- 
1.8.3.1




[PATCH v11 24/26] target/loongarch: Add target build suport

2021-11-18 Thread Song Gao
This patch adds build loongarch-linux-user target support.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 meson.build  |  2 +-
 target/loongarch/meson.build | 19 +++
 target/meson.build   |  1 +
 3 files changed, 21 insertions(+), 1 deletion(-)
 create mode 100644 target/loongarch/meson.build

diff --git a/meson.build b/meson.build
index d03fec6..7ba3aeb 100644
--- a/meson.build
+++ b/meson.build
@@ -56,7 +56,7 @@ python = import('python').find_installation()
 
 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux']
 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
-  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
+  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64', 'loongarch64']
 
 cpu = host_machine.cpu_family()
 
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
new file mode 100644
index 000..bcb076e
--- /dev/null
+++ b/target/loongarch/meson.build
@@ -0,0 +1,19 @@
+gen = decodetree.process('insns.decode')
+
+loongarch_ss = ss.source_set()
+loongarch_ss.add(files(
+  'cpu.c',
+  'disas.c',
+))
+loongarch_tcg_ss = ss.source_set()
+loongarch_tcg_ss.add(gen)
+loongarch_tcg_ss.add(files(
+  'fpu_helper.c',
+  'op_helper.c',
+  'translate.c',
+))
+loongarch_tcg_ss.add(zlib)
+
+loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss])
+
+target_arch += {'loongarch': loongarch_ss}
diff --git a/target/meson.build b/target/meson.build
index 2f69402..a53a604 100644
--- a/target/meson.build
+++ b/target/meson.build
@@ -5,6 +5,7 @@ subdir('cris')
 subdir('hexagon')
 subdir('hppa')
 subdir('i386')
+subdir('loongarch')
 subdir('m68k')
 subdir('microblaze')
 subdir('mips')
-- 
1.8.3.1




[PATCH v11 16/26] target/loongarch: Add disassembler

2021-11-18 Thread Song Gao
This patch adds support for disassembling via option '-d in_asm'.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
---
 include/disas/dis-asm.h  |   2 +
 meson.build  |   1 +
 target/loongarch/disas.c | 625 +++
 3 files changed, 628 insertions(+)
 create mode 100644 target/loongarch/disas.c

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 08e1bee..aeab30f 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -253,6 +253,7 @@ enum bfd_architecture
 #define bfd_mach_rx0x75
 #define bfd_mach_rx_v2 0x76
 #define bfd_mach_rx_v3 0x77
+  bfd_arch_loongarch,
   bfd_arch_last
   };
 #define bfd_mach_s390_31 31
@@ -461,6 +462,7 @@ int print_insn_riscv32  (bfd_vma, 
disassemble_info*);
 int print_insn_riscv64  (bfd_vma, disassemble_info*);
 int print_insn_rx(bfd_vma, disassemble_info *);
 int print_insn_hexagon(bfd_vma, disassemble_info *);
+int print_insn_loongarch(bfd_vma, disassemble_info *);
 
 #ifdef CONFIG_CAPSTONE
 bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size);
diff --git a/meson.build b/meson.build
index e2d38a4..d03fec6 100644
--- a/meson.build
+++ b/meson.build
@@ -1807,6 +1807,7 @@ disassemblers = {
   'sh4' : ['CONFIG_SH4_DIS'],
   'sparc' : ['CONFIG_SPARC_DIS'],
   'xtensa' : ['CONFIG_XTENSA_DIS'],
+  'loongarch' : ['CONFIG_LOONGARCH_DIS'],
 }
 if link_language == 'cpp'
   disassemblers += {
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
new file mode 100644
index 000..4748d0d
--- /dev/null
+++ b/target/loongarch/disas.c
@@ -0,0 +1,625 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch Disassembler
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited.
+ */
+
+#include "qemu/osdep.h"
+#include "disas/dis-asm.h"
+#include "qemu/bitops.h"
+
+typedef struct {
+disassemble_info *info;
+uint64_t pc;
+uint32_t insn;
+} DisasContext;
+
+static inline int plus_1(DisasContext *ctx, int x)
+{
+return x + 1;
+}
+
+static inline int times_4(DisasContext *ctx, int x)
+{
+return x * 4;
+}
+
+#define output(C, INSN, FMT, ...)   \
+{   \
+(C)->info->fprintf_func((C)->info->stream, "%08x   %-9s\t" FMT, \
+(C)->insn, INSN, ##__VA_ARGS__);\
+}
+
+#include "decode-insns.c.inc"
+
+int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info)
+{
+bfd_byte buffer[4];
+uint32_t insn;
+int status;
+
+status = (*info->read_memory_func)(memaddr, buffer, 4, info);
+if (status != 0) {
+(*info->memory_error_func)(status, memaddr, info);
+return -1;
+}
+insn = bfd_getl32(buffer);
+DisasContext ctx = {
+.info = info,
+.pc = memaddr,
+.insn = insn
+};
+
+if (!decode(, insn)) {
+output(, "illegal", "");
+}
+return 4;
+}
+
+static void output_r_i(DisasContext *ctx, arg_r_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, %d", a->rd, a->imm);
+}
+
+static void output_rrr(DisasContext *ctx, arg_rrr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, r%d", a->rd, a->rj, a->rk);
+}
+
+static void output_rr_i(DisasContext *ctx, arg_rr_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->imm);
+}
+
+static void output_rrr_sa(DisasContext *ctx, arg_rrr_sa *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, r%d, %d", a->rd, a->rj, a->rk, a->sa);
+}
+
+static void output_rr(DisasContext *ctx, arg_rr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d", a->rd, a->rj);
+}
+
+static void output_rr_2bw(DisasContext *ctx, arg_rr_2bw *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->msbw, a->lsbw);
+}
+
+static void output_rr_2bd(DisasContext *ctx, arg_rr_2bd *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->msbd, a->lsbd);
+}
+
+static void output_hint_r_i(DisasContext *ctx, arg_hint_r_i *a,
+const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm);
+}
+
+static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "%d", a->imm);
+}
+
+static void output_rr_jk(DisasContext *ctx, arg_rr_jk *a,
+ const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d", a->rj, a->rk);
+}
+
+static void output_ff(DisasContext *ctx, arg_ff *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d", a->fd, a->fj);
+}
+
+static void output_fff(DisasContext *ctx, arg_fff *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d, f%d", a->fd, a->fj, a->fk);
+}
+
+static void 

[PATCH v11 20/26] linux-user: Add LoongArch elf support

2021-11-18 Thread Song Gao
Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
---
 include/elf.h   |  2 ++
 linux-user/elfload.c| 58 +
 linux-user/loongarch64/target_elf.h | 12 
 3 files changed, 72 insertions(+)
 create mode 100644 linux-user/loongarch64/target_elf.h

diff --git a/include/elf.h b/include/elf.h
index 811bf4a..3a4bcb6 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -182,6 +182,8 @@ typedef struct mips_elf_abiflags_v0 {
 
 #define EM_NANOMIPS 249 /* Wave Computing nanoMIPS */
 
+#define EM_LOONGARCH258 /* LoongArch */
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 5da8c02..7827e25 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -914,6 +914,64 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, 
const CPUPPCState *en
 
 #endif
 
+#ifdef TARGET_LOONGARCH64
+
+#define ELF_START_MMAP 0x8000
+
+#define ELF_CLASS   ELFCLASS64
+#define ELF_ARCHEM_LOONGARCH
+
+#define elf_check_arch(x) ((x) == EM_LOONGARCH)
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
+{
+regs->csr_crmd = 2 << 3;
+regs->csr_era = infop->entry;
+regs->regs[3] = infop->start_stack;
+}
+
+/* See linux kernel: arch/loongarch/include/asm/elf.h.  */
+#define ELF_NREG 45
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+/* See linux kernel: arch/loongarch/include/asm/reg.h.  */
+enum {
+TARGET_EF_R0 = 0,
+TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32,
+TARGET_EF_CSR_BADVADDR = TARGET_EF_R0 + 33,
+};
+
+/* See linux kernel: arch/loongarch/kernel/process.c:loongarch_dump_regs64. */
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+   const CPULoongArchState *env)
+{
+int i;
+
+for (i = 0; i < TARGET_EF_R0; i++) {
+(*regs)[i] = 0;
+}
+(*regs)[TARGET_EF_R0] = 0;
+
+for (i = 1; i < ARRAY_SIZE(env->gpr); i++) {
+(*regs)[TARGET_EF_R0 + i] = tswapreg(env->gpr[i]);
+}
+
+(*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->pc);
+(*regs)[TARGET_EF_CSR_BADVADDR] = tswapreg(env->badaddr);
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE4096
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+return 0;
+}
+
+#endif /* TARGET_LOONGARCH64 */
+
 #ifdef TARGET_MIPS
 
 #define ELF_START_MMAP 0x8000
diff --git a/linux-user/loongarch64/target_elf.h 
b/linux-user/loongarch64/target_elf.h
new file mode 100644
index 000..3c690bb
--- /dev/null
+++ b/linux-user/loongarch64/target_elf.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_ELF_H
+#define LOONGARCH_TARGET_ELF_H
+static inline const char *cpu_get_model(uint32_t eflags)
+{
+return "Loongson-3A5000";
+}
+#endif
-- 
1.8.3.1




[PATCH v11 14/26] target/loongarch: Add floating point load/store instruction translation

2021-11-18 Thread Song Gao
This includes:
- FLD.{S/D}, FST.{S/D}
- FLDX.{S/D}, FSTX.{S/D}
- FLD{GT/LE}.{S/D}, FST{GT/LE}.{S/D}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/insn_trans/trans_fmemory.c.inc | 184 
 target/loongarch/insns.decode   |  24 
 target/loongarch/translate.c|   1 +
 3 files changed, 209 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_fmemory.c.inc

diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc 
b/target/loongarch/insn_trans/trans_fmemory.c.inc
new file mode 100644
index 000..a9c66b2
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_fmemory.c.inc
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_fload_imm(DisasContext *ctx, arg_fr_i *a,
+  MemOp mop, bool nanbox)
+{
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv temp = NULL;
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+if (temp) {
+tcg_temp_free(temp);
+}
+return true;
+}
+
+static bool gen_fstore_imm(DisasContext *ctx, arg_fr_i *a,
+   MemOp mop, bool nanbox)
+{
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv temp = NULL;
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+if (temp) {
+tcg_temp_free(temp);
+}
+return true;
+}
+
+static bool gen_fload_tl(DisasContext *ctx, arg_frr *a,
+ MemOp mop, bool nanbox)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_fstore_tl(DisasContext *ctx, arg_frr *a,
+  MemOp mop, bool nanbox)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+tcg_gen_add_tl(addr, src1, src2);
+
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_fload_gt(DisasContext *ctx, arg_frr *a,
+ MemOp mop, bool nanbox)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a,
+  MemOp mop, bool nanbox)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_fload_le(DisasContext *ctx, arg_frr *a,
+ MemOp mop, bool nanbox)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_fstore_le(DisasContext *ctx, arg_frr *a,
+  MemOp mop, bool nanbox)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+

[PATCH v11 22/26] linux-user: Add LoongArch cpu_loop support

2021-11-18 Thread Song Gao
Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
---
 configure   |  5 ++
 linux-user/loongarch64/cpu_loop.c   | 97 +
 linux-user/loongarch64/target_cpu.h | 34 +
 3 files changed, 136 insertions(+)
 create mode 100644 linux-user/loongarch64/cpu_loop.c
 create mode 100644 linux-user/loongarch64/target_cpu.h

diff --git a/configure b/configure
index 48c2177..9df99f6 100755
--- a/configure
+++ b/configure
@@ -581,6 +581,8 @@ elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
   cpu="aarch64"
+elif check_define __loongarch64__ ; then
+  cpu="loongarch64"
 else
   cpu=$(uname -m)
 fi
@@ -612,6 +614,9 @@ case "$cpu" in
   sparc|sun4[cdmuv])
 cpu="sparc"
   ;;
+  loongarch)
+cpu="loongarch"
+  ;;
   *)
 # This will result in either an error or falling back to TCI later
 ARCH=unknown
diff --git a/linux-user/loongarch64/cpu_loop.c 
b/linux-user/loongarch64/cpu_loop.c
new file mode 100644
index 000..f211304
--- /dev/null
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch user cpu_loop.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "qemu-common.h"
+#include "user-internals.h"
+#include "cpu_loop-common.h"
+#include "signal-common.h"
+
+void cpu_loop(CPULoongArchState *env)
+{
+CPUState *cs = env_cpu(env);
+int trapnr, si_code;
+abi_long ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_SYSCALL:
+env->pc += 4;
+ret = do_syscall(env, env->gpr[11],
+ env->gpr[4], env->gpr[5],
+ env->gpr[6], env->gpr[7],
+ env->gpr[8], env->gpr[9],
+ -1, -1);
+if (ret == -TARGET_ERESTARTSYS) {
+env->pc -= 4;
+break;
+}
+if (ret == -TARGET_QEMU_ESIGRETURN) {
+/*
+ * Returning from a successful sigreturn syscall.
+ * Avoid clobbering register state.
+ */
+break;
+}
+env->gpr[4] = ret;
+break;
+case EXCP_ADE:
+force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->badaddr);
+break;
+case EXCP_INE:
+force_sig_fault(TARGET_SIGILL, 0, env->pc);
+break;
+case EXCP_FPE:
+si_code = TARGET_FPE_FLTUNK;
+if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {
+si_code = TARGET_FPE_FLTINV;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_DIV0) {
+si_code = TARGET_FPE_FLTDIV;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_OVERFLOW) {
+si_code = TARGET_FPE_FLTOVF;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_UNDERFLOW) {
+si_code = TARGET_FPE_FLTUND;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_INEXACT) {
+si_code = TARGET_FPE_FLTRES;
+}
+force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
+break;
+case EXCP_DEBUG:
+case EXCP_BREAK:
+force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
+break;
+case EXCP_ATOMIC:
+cpu_exec_step_atomic(cs);
+break;
+default:
+EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n",
+  trapnr);
+exit(EXIT_FAILURE);
+}
+process_pending_signals(env);
+}
+}
+
+void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
+{
+int i;
+
+for (i = 0; i < 32; i++) {
+env->gpr[i] = regs->regs[i];
+}
+env->pc = regs->csr_era;
+
+}
diff --git a/linux-user/loongarch64/target_cpu.h 
b/linux-user/loongarch64/target_cpu.h
new file mode 100644
index 000..a29af66
--- /dev/null
+++ b/linux-user/loongarch64/target_cpu.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_CPU_H
+#define LOONGARCH_TARGET_CPU_H
+
+static inline void cpu_clone_regs_child(CPULoongArchState *env,
+target_ulong newsp, unsigned flags)
+{
+if (newsp) {
+env->gpr[3] = newsp;
+}
+env->gpr[4] = 0;
+}
+
+static inline void cpu_clone_regs_parent(CPULoongArchState *env,
+ unsigned flags)
+{
+}
+
+static 

[PATCH v11 18/26] linux-user: Add LoongArch specific structures

2021-11-18 Thread Song Gao
Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
---
 linux-user/loongarch64/target_structs.h | 48 +
 1 file changed, 48 insertions(+)
 create mode 100644 linux-user/loongarch64/target_structs.h

diff --git a/linux-user/loongarch64/target_structs.h 
b/linux-user/loongarch64/target_structs.h
new file mode 100644
index 000..cc7928a
--- /dev/null
+++ b/linux-user/loongarch64/target_structs.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch specific structures for linux-user
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_STRUCTS_H
+#define LOONGARCH_TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+abi_int __key;  /* Key.  */
+abi_uint uid;   /* Owner's user ID.  */
+abi_uint gid;   /* Owner's group ID.  */
+abi_uint cuid;  /* Creator's user ID.  */
+abi_uint cgid;  /* Creator's group ID.  */
+abi_uint mode;  /* Read/write permission.  */
+abi_ushort __seq;   /* Sequence number.  */
+abi_ushort __pad1;
+abi_ulong __unused1;
+abi_ulong __unused2;
+};
+
+struct target_shmid_ds {
+struct target_ipc_perm shm_perm;/* operation permission struct */
+abi_long shm_segsz; /* size of segment in bytes */
+abi_ulong shm_atime;/* time of last shmat() */
+abi_ulong shm_dtime;/* time of last shmdt() */
+abi_ulong shm_ctime;/* time of last change by shmctl() */
+abi_int shm_cpid;   /* pid of creator */
+abi_int shm_lpid;   /* pid of last shmop */
+abi_ulong shm_nattch;   /* number of current attaches */
+abi_ulong __unused1;
+abi_ulong __unused2;
+};
+
+#define TARGET_SEMID64_DS
+
+struct target_semid64_ds {
+struct target_ipc_perm sem_perm;
+abi_ulong sem_otime;
+abi_ulong sem_ctime;
+abi_ulong sem_nsems;
+abi_ulong __unused1;
+abi_ulong __unused2;
+};
+
+#endif
-- 
1.8.3.1




[PATCH v11 13/26] target/loongarch: Add floating point move instruction translation

2021-11-18 Thread Song Gao
This includes:
- FMOV.{S/D}
- FSEL
- MOVGR2FR.{W/D}, MOVGR2FRH.W
- MOVFR2GR.{S/D}, MOVFRH2GR.S
- MOVGR2FCSR, MOVFCSR2GR
- MOVFR2CF, MOVCF2FR
- MOVGR2CF, MOVCF2GR

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/fpu_helper.c|   6 ++
 target/loongarch/helper.h|   2 +
 target/loongarch/insn_trans/trans_fmov.c.inc | 150 +++
 target/loongarch/insns.decode|  37 +++
 target/loongarch/translate.c |   1 +
 5 files changed, 196 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_fmov.c.inc

diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
index 4799b47..babaa16 100644
--- a/target/loongarch/fpu_helper.c
+++ b/target/loongarch/fpu_helper.c
@@ -856,3 +856,9 @@ uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t 
fj)
 update_fcsr0(env, GETPC());
 return fd;
 }
+
+void helper_set_rounding_mode(CPULoongArchState *env, uint32_t fcsr0)
+{
+set_float_rounding_mode(ieee_rm[(fcsr0 >> FCSR0_RM) & 0x3],
+>fp_status);
+}
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 51bbf25..26ca6d2 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -90,3 +90,5 @@ DEF_HELPER_2(ftint_w_s, i64, env, i64)
 DEF_HELPER_2(ftint_w_d, i64, env, i64)
 DEF_HELPER_2(frint_s, i64, env, i64)
 DEF_HELPER_2(frint_d, i64, env, i64)
+
+DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_RWG, void, env, i32)
diff --git a/target/loongarch/insn_trans/trans_fmov.c.inc 
b/target/loongarch/insn_trans/trans_fmov.c.inc
new file mode 100644
index 000..8acf49e
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_fmov.c.inc
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static const uint32_t fcsr_mask[4] = {
+UINT32_MAX, FCSR0_M1, FCSR0_M2, FCSR0_M3
+};
+
+static bool trans_fsel(DisasContext *ctx, arg_fsel *a)
+{
+TCGv zero = tcg_constant_tl(0);
+TCGv cond = tcg_temp_new();
+
+tcg_gen_ld8u_tl(cond, cpu_env, offsetof(CPULoongArchState, cf[a->ca]));
+tcg_gen_movcond_tl(TCG_COND_EQ, cpu_fpr[a->fd], cond, zero,
+   cpu_fpr[a->fj], cpu_fpr[a->fk]);
+tcg_temp_free(cond);
+return true;
+}
+
+static bool gen_f2f(DisasContext *ctx, arg_ff *a,
+void (*func)(TCGv, TCGv), bool nanbox)
+{
+TCGv dest = cpu_fpr[a->fd];
+TCGv src = cpu_fpr[a->fj];
+
+func(dest, src);
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+return true;
+}
+
+static bool gen_r2f(DisasContext *ctx, arg_fr *a,
+void (*func)(TCGv, TCGv))
+{
+TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
+
+func(cpu_fpr[a->fd], src);
+return true;
+}
+
+static bool gen_f2r(DisasContext *ctx, arg_rf *a,
+void (*func)(TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+func(dest, cpu_fpr[a->fj]);
+return true;
+}
+
+static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a)
+{
+uint32_t mask = fcsr_mask[a->fcsrd];
+TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (mask == UINT32_MAX) {
+tcg_gen_extrl_i64_i32(cpu_fcsr0, Rj);
+} else {
+TCGv_i32 temp = tcg_temp_new_i32();
+
+tcg_gen_extrl_i64_i32(temp, Rj);
+tcg_gen_andi_i32(temp, temp, mask);
+tcg_gen_andi_i32(cpu_fcsr0, cpu_fcsr0, ~mask);
+tcg_gen_or_i32(cpu_fcsr0, cpu_fcsr0, temp);
+tcg_temp_free_i32(temp);
+
+/*
+ * Install the new rounding mode to fpu_status, if changed.
+ * Note that FCSR3 is exactly the rounding mode field.
+ */
+if (mask != FCSR0_M3) {
+return true;
+}
+}
+gen_helper_set_rounding_mode(cpu_env, cpu_fcsr0);
+return true;
+}
+
+static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a)
+{
+TCGv_i32 temp = tcg_temp_new_i32();
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+tcg_gen_andi_i32(temp, cpu_fcsr0, fcsr_mask[a->fcsrs]);
+tcg_gen_ext_i32_i64(dest, temp);
+tcg_temp_free_i32(temp);
+return true;
+}
+
+static void gen_movgr2fr_w(TCGv dest, TCGv src)
+{
+tcg_gen_deposit_i64(dest, dest, src, 0, 32);
+}
+
+static void gen_movgr2frh_w(TCGv dest, TCGv src)
+{
+tcg_gen_deposit_i64(dest, dest, src, 32, 32);
+}
+
+static void gen_movfrh2gr_s(TCGv dest, TCGv src)
+{
+tcg_gen_sextract_tl(dest, src, 32, 32);
+}
+
+static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a)
+{
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_andi_tl(t0, cpu_fpr[a->fj], 0x1);
+tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
+
+tcg_temp_free(t0);
+return true;
+}
+
+static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a)
+{
+tcg_gen_ld8u_tl(cpu_fpr[a->fd], cpu_env,
+   

[PATCH v11 15/26] target/loongarch: Add branch instruction translation

2021-11-18 Thread Song Gao
This includes:
- BEQ, BNE, BLT[U], BGE[U]
- BEQZ, BNEZ
- B
- BL
- JIRL
- BCEQZ, BCNEZ

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/insn_trans/trans_branch.c.inc | 82 ++
 target/loongarch/insns.decode  | 30 ++
 target/loongarch/translate.c   |  6 ++
 3 files changed, 118 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_branch.c.inc

diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
new file mode 100644
index 000..73fd048
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool trans_b(DisasContext *ctx, arg_b *a)
+{
+gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_bl(DisasContext *ctx, arg_bl *a)
+{
+tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4);
+gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+tcg_gen_addi_tl(cpu_pc, src1, a->offs);
+tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
+tcg_gen_lookup_and_goto_ptr();
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static void gen_bc(DisasContext *ctx, TCGv src1, TCGv src2,
+   target_long offs, TCGCond cond)
+{
+TCGLabel *l = gen_new_label();
+tcg_gen_brcond_tl(cond, src1, src2, l);
+gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
+gen_set_label(l);
+gen_goto_tb(ctx, 0, ctx->base.pc_next + offs);
+ctx->base.is_jmp = DISAS_NORETURN;
+}
+
+static bool gen_rr_bc(DisasContext *ctx, arg_rr_offs *a, TCGCond cond)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rd, EXT_NONE);
+
+gen_bc(ctx, src1, src2, a->offs, cond);
+return true;
+}
+
+static bool gen_rz_bc(DisasContext *ctx, arg_r_offs *a, TCGCond cond)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = tcg_constant_tl(0);
+
+gen_bc(ctx, src1, src2, a->offs, cond);
+return true;
+}
+
+static bool gen_cz_bc(DisasContext *ctx, arg_c_offs *a, TCGCond cond)
+{
+TCGv src1 = tcg_temp_new();
+TCGv src2 = tcg_constant_tl(0);
+
+tcg_gen_ld8u_tl(src1, cpu_env,
+offsetof(CPULoongArchState, cf[a->cj & 0x7]));
+gen_bc(ctx, src1, src2, a->offs, cond);
+return true;
+}
+
+TRANS(beq, gen_rr_bc, TCG_COND_EQ)
+TRANS(bne, gen_rr_bc, TCG_COND_NE)
+TRANS(blt, gen_rr_bc, TCG_COND_LT)
+TRANS(bge, gen_rr_bc, TCG_COND_GE)
+TRANS(bltu, gen_rr_bc, TCG_COND_LTU)
+TRANS(bgeu, gen_rr_bc, TCG_COND_GEU)
+TRANS(beqz, gen_rz_bc, TCG_COND_EQ)
+TRANS(bnez, gen_rz_bc, TCG_COND_NE)
+TRANS(bceqz, gen_cz_bc, TCG_COND_EQ)
+TRANS(bcnez, gen_cz_bc, TCG_COND_NE)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 2560c24..5118a1e 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -9,6 +9,9 @@
 # Fields
 #
 %sa2p1 15:2 !function=plus_1
+%offs210:s5 10:16   !function=times_4
+%offs1610:s16   !function=times_4
+%offs260:s10 10:16  !function=times_4
 
 #
 # Argument sets
@@ -38,6 +41,11 @@
rd cj
   fd rj rk
 _i fd rj imm
+_offs   rj offs
+_offs   cj offs
+_dj_offs   rd rj offs
+ offs
+_offs  rj rd offs
 
 #
 # Formats
@@ -74,6 +82,11 @@
 @rc  . . .. cj:3 rd:5
 @frr     . rk:5 rj:5 fd:5
 @fr_i12  .. imm:s12 rj:5 fd:5_i
+@r_offs21  ..  rj:5 ._offs  
offs=%offs21
+@c_offs21   ..  .. cj:3 ._offs  
offs=%offs21
+@rr_dj_offs16   ..  rj:5 rd:5_dj_offs  
offs=%offs16
+@offs26 .. ..
offs=%offs26
+@rr_offs16  ..  rj:5 rd:5_offs 
offs=%offs16
 
 #
 # Fixed point arithmetic operation instruction
@@ -412,3 +425,20 @@ fstgt_s 0011 1111 01100 . . .
@frr
 fstgt_d 0011 1111 01101 . . .@frr
 fstle_s 0011 1111 01110 . . .@frr
 fstle_d 0011 1111 0 . . .@frr
+
+#
+# Branch instructions
+#
+beqz0100 00  . . @r_offs21
+bnez0100 01  . . @r_offs21
+bceqz   0100 10  00 ... .@c_offs21
+bcnez   0100 10  01 ... .@c_offs21
+jirl0100 11  

[PATCH v11 17/26] linux-user: Add LoongArch generic header files

2021-11-18 Thread Song Gao
This includes:
- sockbits.h
- target_errno_defs.h
- target_fcntl.h
- termbits.h

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
---
 linux-user/loongarch64/sockbits.h  | 11 +++
 linux-user/loongarch64/target_errno_defs.h | 12 
 linux-user/loongarch64/target_fcntl.h  | 11 +++
 linux-user/loongarch64/termbits.h  | 11 +++
 4 files changed, 45 insertions(+)
 create mode 100644 linux-user/loongarch64/sockbits.h
 create mode 100644 linux-user/loongarch64/target_errno_defs.h
 create mode 100644 linux-user/loongarch64/target_fcntl.h
 create mode 100644 linux-user/loongarch64/termbits.h

diff --git a/linux-user/loongarch64/sockbits.h 
b/linux-user/loongarch64/sockbits.h
new file mode 100644
index 000..1cffcae
--- /dev/null
+++ b/linux-user/loongarch64/sockbits.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_SOCKBITS_H
+#define LOONGARCH_TARGET_SOCKBITS_H
+
+#include "../generic/sockbits.h"
+
+#endif
diff --git a/linux-user/loongarch64/target_errno_defs.h 
b/linux-user/loongarch64/target_errno_defs.h
new file mode 100644
index 000..c198b8a
--- /dev/null
+++ b/linux-user/loongarch64/target_errno_defs.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_ERRNO_DEFS_H
+#define LOONGARCH_TARGET_ERRNO_DEFS_H
+
+/* Target uses generic errno */
+#include "../generic/target_errno_defs.h"
+
+#endif
diff --git a/linux-user/loongarch64/target_fcntl.h 
b/linux-user/loongarch64/target_fcntl.h
new file mode 100644
index 000..99bf586
--- /dev/null
+++ b/linux-user/loongarch64/target_fcntl.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_FCNTL_H
+#define LOONGARCH_TARGET_FCNTL_H
+
+#include "../generic/fcntl.h"
+
+#endif
diff --git a/linux-user/loongarch64/termbits.h 
b/linux-user/loongarch64/termbits.h
new file mode 100644
index 000..d425db8
--- /dev/null
+++ b/linux-user/loongarch64/termbits.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_TERMBITS_H
+#define LOONGARCH_TARGET_TERMBITS_H
+
+#include "../generic/termbits.h"
+
+#endif
-- 
1.8.3.1




[PATCH v11 01/26] target/loongarch: Add README

2021-11-18 Thread Song Gao
This patch gives an introduction to the LoongArch target.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS |  5 
 target/loongarch/README | 76 +
 2 files changed, 81 insertions(+)
 create mode 100644 target/loongarch/README

diff --git a/MAINTAINERS b/MAINTAINERS
index d3879aa..935bbce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -213,6 +213,11 @@ S: Maintained
 F: target/hppa/
 F: disas/hppa.c
 
+LoongArch TCG CPUS
+M: Song Gao 
+S: Maintained
+F: target/loongarch/
+
 M68K TCG CPUs
 M: Laurent Vivier 
 S: Maintained
diff --git a/target/loongarch/README b/target/loongarch/README
new file mode 100644
index 000..09f809c
--- /dev/null
+++ b/target/loongarch/README
@@ -0,0 +1,76 @@
+- Introduction
+
+  LoongArch is the general processor architecture of Loongson.
+
+  The following versions of the LoongArch core are supported
+core: 3A5000
+
https://github.com/loongson/LoongArch-Documentation/releases/download/2021.08.17/LoongArch-Vol1-v1.00-EN.pdf
+
+  We can get the latest loongarch documents at 
https://github.com/loongson/LoongArch-Documentation/tags.
+
+
+- Linux-user emulation
+
+  We already support Linux user emulation. We can use LoongArch cross-tools to 
build LoongArch executables on X86 machines,
+  and We can also use qemu-loongarch64 to run LoongArch executables.
+
+  1. Install LoongArch cross-tools on X86 machines.
+
+Download cross-tools.
+
+  wget 
https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20210831-cross-tools.tar.xz
+
+  tar -vxf loongarch64-clfs-20210831-cross-tools.tar.xz -C /opt
+
+Config cross-tools env.
+
+  . setenv.sh
+
+  setenv.sh:
+
+  #!/bin/sh
+  set -x
+  CC_PREFIX=/opt/cross-tools
+
+  export PATH=$CC_PREFIX/bin:$PATH
+  export LD_LIBRARY_PATH=$CC_PREFIX/lib:$LD_LIBRARY_PATH
+  export 
LD_LIBRARY_PATH=$CC_PREFIX/loongarch64-unknown-linux-gnu/lib/:$LD_LIBRARY_PATH
+  set +x
+
+  2. Test tests/tcg/multiarch.
+
+./configure --disable-rdma --disable-pvrdma --prefix=/usr  \
+--target-list="loongarch64-linux-user"  \
+--disable-libiscsi --disable-libnfs --disable-libpmem \
+--disable-glusterfs --enable-libusb --enable-usb-redir \
+--disable-opengl --disable-xen --enable-spice --disable-werror \
+--enable-debug --disable-capstone --disable-kvm --enable-profiler
+
+cd  build/
+
+make && make check-tcg
+
+  3. Run LoongArch system basic command with loongarch-clfs-system.
+
+Download clfs-system.
+
+  wget 
https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-system-2021-08-31.tar.bz2
+
+  tar -vxf loongarch64-clfs-system-2021-08-31.tar.bz2 -C /opt/clfs
+
+Config env.
+
+  cp /opt/clfs/lib64/ld-linux-loongarch64.so.1   /lib64
+
+  export LD_LIBRARY_PATH="/opt/clfs/lib64"
+
+Run LoongArch system basic command.
+
+  ./qemu-loongarch64  /opt/clfs/usr/bin/bash
+  ./qemu-loongarch64  /opt/clfs/usr/bin/ls
+  ./qemu-loongarch64  /opt/clfs/usr/bin/pwd
+  ...
+
+
+- Note.
+  We can get the latest LoongArch documents or LoongArch tools at 
https://github.com/loongson/
-- 
1.8.3.1




[PATCH v11 09/26] target/loongarch: Add fixed point extra instruction translation

2021-11-18 Thread Song Gao
This includes:
- CRC[C].W.{B/H/W/D}.W
- SYSCALL
- BREAK
- ASRT{LE/GT}.D
- RDTIME{L/H}.W, RDTIME.D
- CPUCFG

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/helper.h |  4 ++
 target/loongarch/insn_trans/trans_extra.c.inc | 84 +++
 target/loongarch/insns.decode | 22 +++
 target/loongarch/op_helper.c  | 26 +
 target/loongarch/translate.c  |  1 +
 5 files changed, 137 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_extra.c.inc

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 2fe4e63..ec6760d 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -11,3 +11,7 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_3(asrtle_d, void, env, tl, tl)
 DEF_HELPER_3(asrtgt_d, void, env, tl, tl)
+
+DEF_HELPER_3(crc32, tl, tl, tl, tl)
+DEF_HELPER_3(crc32c, tl, tl, tl, tl)
+DEF_HELPER_2(cpucfg, tl, env, tl)
diff --git a/target/loongarch/insn_trans/trans_extra.c.inc 
b/target/loongarch/insn_trans/trans_extra.c.inc
new file mode 100644
index 000..8c2d482
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_extra.c.inc
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool trans_break(DisasContext *ctx, arg_break *a)
+{
+generate_exception(ctx, EXCP_BREAK);
+return true;
+}
+
+static bool trans_syscall(DisasContext *ctx, arg_syscall *a)
+{
+generate_exception(ctx, EXCP_SYSCALL);
+return true;
+}
+
+static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d * a)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+return true;
+}
+
+static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * a)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+return true;
+}
+
+static bool trans_rdtimel_w(DisasContext *ctx, arg_rdtimel_w *a)
+{
+tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
+return true;
+}
+
+static bool trans_rdtimeh_w(DisasContext *ctx, arg_rdtimeh_w *a)
+{
+tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
+return true;
+}
+
+static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a)
+{
+tcg_gen_movi_tl(cpu_gpr[a->rd], 0);
+return true;
+}
+
+static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+gen_helper_cpucfg(dest, cpu_env, src1);
+return true;
+}
+
+static bool gen_crc(DisasContext *ctx, arg_rrr *a,
+void (*func)(TCGv, TCGv, TCGv, TCGv),
+TCGv tsz)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_SIGN);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+func(dest, src2, src1, tsz);
+
+gen_set_gpr(a->rd, dest, EXT_SIGN);
+return true;
+}
+
+TRANS(crc_w_b_w, gen_crc, gen_helper_crc32, tcg_constant_tl(1))
+TRANS(crc_w_h_w, gen_crc, gen_helper_crc32, tcg_constant_tl(2))
+TRANS(crc_w_w_w, gen_crc, gen_helper_crc32, tcg_constant_tl(4))
+TRANS(crc_w_d_w, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
+TRANS(crcc_w_b_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(1))
+TRANS(crcc_w_h_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(2))
+TRANS(crcc_w_w_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(4))
+TRANS(crcc_w_d_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index c222c4a..8dca6f2 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -16,6 +16,7 @@
 imm
 _i  rd imm
rd rj
+_jkrj rk
   rd rj rk
 _i rd rj imm
 _r_i hint rj imm
@@ -28,6 +29,7 @@
 #
 @i15     . imm:15
 @rr     . . rj:5 rd:5
+@rr_jk  . rk:5 rj:5 ._jk
 @rrr     . rk:5 rj:5 rd:5
 @r_i20   ... imm:s20 rd:5_i
 @rr_ui5     . imm:5 rj:5 rd:5_i
@@ -237,3 +239,23 @@ ammax_db_wu 0011 1111 0 . . .
@rrr
 ammax_db_du 0011 1111 1 . . .@rrr
 ammin_db_wu 0011 1111 00010 . . .@rrr
 ammin_db_du 0011 1111 00011 . . .@rrr
+
+#
+# Fixed point extra instruction
+#
+crc_w_b_w    0010 01000 . . .@rrr
+crc_w_h_w    0010 01001 . . .@rrr
+crc_w_w_w    0010 01010 . . .@rrr
+crc_w_d_w    0010 01011 . . .@rrr
+crcc_w_b_w   0010 01100 

[PATCH v11 11/26] target/loongarch: Add floating point comparison instruction translation

2021-11-18 Thread Song Gao
This includes:
- FCMP.cond.{S/D}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/fpu_helper.c| 60 
 target/loongarch/helper.h|  9 +
 target/loongarch/insn_trans/trans_fcmp.c.inc | 56 ++
 target/loongarch/insns.decode|  8 
 target/loongarch/internals.h |  5 +++
 target/loongarch/translate.c |  1 +
 6 files changed, 139 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_fcmp.c.inc

diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
index d0ef675..807ffd0 100644
--- a/target/loongarch/fpu_helper.c
+++ b/target/loongarch/fpu_helper.c
@@ -403,3 +403,63 @@ uint64_t helper_fmuladd_d(CPULoongArchState *env, uint64_t 
fj,
 update_fcsr0(env, GETPC());
 return fd;
 }
+
+static uint64_t fcmp_common(CPULoongArchState *env, FloatRelation cmp,
+uint32_t flags)
+{
+bool ret;
+
+switch (cmp) {
+case float_relation_less:
+ret = (flags & FCMP_LT);
+break;
+case float_relation_equal:
+ret = (flags & FCMP_EQ);
+break;
+case float_relation_greater:
+ret = (flags & FCMP_GT);
+break;
+case float_relation_unordered:
+ret = (flags & FCMP_UN);
+break;
+default:
+g_assert_not_reached();
+}
+update_fcsr0(env, GETPC());
+
+return ret;
+}
+
+/* fcmp_cXXX_s */
+uint64_t helper_fcmp_c_s(CPULoongArchState *env, uint64_t fj,
+ uint64_t fk, uint32_t flags)
+{
+FloatRelation cmp = float32_compare_quiet((uint32_t)fj,
+  (uint32_t)fk, >fp_status);
+return fcmp_common(env, cmp, flags);
+}
+
+/* fcmp_sXXX_s */
+uint64_t helper_fcmp_s_s(CPULoongArchState *env, uint64_t fj,
+ uint64_t fk, uint32_t flags)
+{
+FloatRelation cmp = float32_compare((uint32_t)fj,
+(uint32_t)fk, >fp_status);
+return fcmp_common(env, cmp, flags);
+}
+
+/* fcmp_cXXX_d */
+uint64_t helper_fcmp_c_d(CPULoongArchState *env, uint64_t fj,
+ uint64_t fk, uint32_t flags)
+{
+FloatRelation cmp = float64_compare_quiet(fj, fk, >fp_status);
+return fcmp_common(env, cmp, flags);
+}
+
+/* fcmp_sXXX_d */
+uint64_t helper_fcmp_s_d(CPULoongArchState *env, uint64_t fj,
+ uint64_t fk, uint32_t flags)
+{
+FloatRelation cmp = float64_compare(fj, fk, >fp_status);
+return fcmp_common(env, cmp, flags);
+}
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index d6bb412..30b270a 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -52,3 +52,12 @@ DEF_HELPER_2(frecip_d, i64, env, i64)
 
 DEF_HELPER_FLAGS_2(fclass_s, TCG_CALL_NO_RWG_SE, i64, env, i64)
 DEF_HELPER_FLAGS_2(fclass_d, TCG_CALL_NO_RWG_SE, i64, env, i64)
+
+/* fcmp.cXXX.s */
+DEF_HELPER_4(fcmp_c_s, i64, env, i64, i64, i32)
+/* fcmp.sXXX.s */
+DEF_HELPER_4(fcmp_s_s, i64, env, i64, i64, i32)
+/* fcmp.cXXX.d */
+DEF_HELPER_4(fcmp_c_d, i64, env, i64, i64, i32)
+/* fcmp.sXXX.d */
+DEF_HELPER_4(fcmp_s_d, i64, env, i64, i64, i32)
diff --git a/target/loongarch/insn_trans/trans_fcmp.c.inc 
b/target/loongarch/insn_trans/trans_fcmp.c.inc
new file mode 100644
index 000..ce39c07
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_fcmp.c.inc
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+/* bit0(signaling/quiet) bit1(lt) bit2(eq) bit3(un) bit4(neq) */
+static uint32_t get_fcmp_flags(int cond)
+{
+uint32_t flags = 0;
+
+if (cond & 0x1) {
+flags |= FCMP_LT;
+}
+if (cond & 0x2) {
+flags |= FCMP_EQ;
+}
+if (cond & 0x4) {
+flags |= FCMP_UN;
+}
+if (cond & 0x8) {
+flags |= FCMP_GT | FCMP_LT;
+}
+return flags;
+}
+
+static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
+{
+TCGv var = tcg_temp_new();
+uint32_t flags;
+void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
+
+fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s);
+flags = get_fcmp_flags(a->fcond >> 1);
+
+fn(var, cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk], tcg_constant_i32(flags));
+
+tcg_gen_st8_tl(var, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
+tcg_temp_free(var);
+return true;
+}
+
+static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a)
+{
+TCGv var = tcg_temp_new();
+uint32_t flags;
+void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
+fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d);
+flags = get_fcmp_flags(a->fcond >> 1);
+
+fn(var, cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk], tcg_constant_i32(flags));
+
+tcg_gen_st8_tl(var, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 

[PATCH v11 21/26] linux-user: Add LoongArch syscall support

2021-11-18 Thread Song Gao
We should disable '__BITS_PER_LONG' at [1] before run gensyscalls.sh

 [1] arch/loongarch/include/uapi/asm/bitsperlong.h

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
---
 linux-user/loongarch64/syscall_nr.h | 312 
 linux-user/loongarch64/target_syscall.h |  45 +
 linux-user/syscall_defs.h   |  10 +-
 scripts/gensyscalls.sh  |   1 +
 4 files changed, 364 insertions(+), 4 deletions(-)
 create mode 100644 linux-user/loongarch64/syscall_nr.h
 create mode 100644 linux-user/loongarch64/target_syscall.h

diff --git a/linux-user/loongarch64/syscall_nr.h 
b/linux-user/loongarch64/syscall_nr.h
new file mode 100644
index 000..8fbf287
--- /dev/null
+++ b/linux-user/loongarch64/syscall_nr.h
@@ -0,0 +1,312 @@
+/*
+ * This file contains the system call numbers.
+ * Do not modify.
+ * This file is generated by scripts/gensyscalls.sh
+ */
+#ifndef LINUX_USER_LOONGARCH_SYSCALL_NR_H
+#define LINUX_USER_LOONGARCH_SYSCALL_NR_H
+
+#define TARGET_NR_io_setup 0
+#define TARGET_NR_io_destroy 1
+#define TARGET_NR_io_submit 2
+#define TARGET_NR_io_cancel 3
+#define TARGET_NR_io_getevents 4
+#define TARGET_NR_setxattr 5
+#define TARGET_NR_lsetxattr 6
+#define TARGET_NR_fsetxattr 7
+#define TARGET_NR_getxattr 8
+#define TARGET_NR_lgetxattr 9
+#define TARGET_NR_fgetxattr 10
+#define TARGET_NR_listxattr 11
+#define TARGET_NR_llistxattr 12
+#define TARGET_NR_flistxattr 13
+#define TARGET_NR_removexattr 14
+#define TARGET_NR_lremovexattr 15
+#define TARGET_NR_fremovexattr 16
+#define TARGET_NR_getcwd 17
+#define TARGET_NR_lookup_dcookie 18
+#define TARGET_NR_eventfd2 19
+#define TARGET_NR_epoll_create1 20
+#define TARGET_NR_epoll_ctl 21
+#define TARGET_NR_epoll_pwait 22
+#define TARGET_NR_dup 23
+#define TARGET_NR_dup3 24
+#define TARGET_NR_fcntl 25
+#define TARGET_NR_inotify_init1 26
+#define TARGET_NR_inotify_add_watch 27
+#define TARGET_NR_inotify_rm_watch 28
+#define TARGET_NR_ioctl 29
+#define TARGET_NR_ioprio_set 30
+#define TARGET_NR_ioprio_get 31
+#define TARGET_NR_flock 32
+#define TARGET_NR_mknodat 33
+#define TARGET_NR_mkdirat 34
+#define TARGET_NR_unlinkat 35
+#define TARGET_NR_symlinkat 36
+#define TARGET_NR_linkat 37
+#define TARGET_NR_umount2 39
+#define TARGET_NR_mount 40
+#define TARGET_NR_pivot_root 41
+#define TARGET_NR_nfsservctl 42
+#define TARGET_NR_statfs 43
+#define TARGET_NR_fstatfs 44
+#define TARGET_NR_truncate 45
+#define TARGET_NR_ftruncate 46
+#define TARGET_NR_fallocate 47
+#define TARGET_NR_faccessat 48
+#define TARGET_NR_chdir 49
+#define TARGET_NR_fchdir 50
+#define TARGET_NR_chroot 51
+#define TARGET_NR_fchmod 52
+#define TARGET_NR_fchmodat 53
+#define TARGET_NR_fchownat 54
+#define TARGET_NR_fchown 55
+#define TARGET_NR_openat 56
+#define TARGET_NR_close 57
+#define TARGET_NR_vhangup 58
+#define TARGET_NR_pipe2 59
+#define TARGET_NR_quotactl 60
+#define TARGET_NR_getdents64 61
+#define TARGET_NR_lseek 62
+#define TARGET_NR_read 63
+#define TARGET_NR_write 64
+#define TARGET_NR_readv 65
+#define TARGET_NR_writev 66
+#define TARGET_NR_pread64 67
+#define TARGET_NR_pwrite64 68
+#define TARGET_NR_preadv 69
+#define TARGET_NR_pwritev 70
+#define TARGET_NR_sendfile 71
+#define TARGET_NR_pselect6 72
+#define TARGET_NR_ppoll 73
+#define TARGET_NR_signalfd4 74
+#define TARGET_NR_vmsplice 75
+#define TARGET_NR_splice 76
+#define TARGET_NR_tee 77
+#define TARGET_NR_readlinkat 78
+#define TARGET_NR_newfstatat 79
+#define TARGET_NR_fstat 80
+#define TARGET_NR_sync 81
+#define TARGET_NR_fsync 82
+#define TARGET_NR_fdatasync 83
+#define TARGET_NR_sync_file_range 84
+#define TARGET_NR_timerfd_create 85
+#define TARGET_NR_timerfd_settime 86
+#define TARGET_NR_timerfd_gettime 87
+#define TARGET_NR_utimensat 88
+#define TARGET_NR_acct 89
+#define TARGET_NR_capget 90
+#define TARGET_NR_capset 91
+#define TARGET_NR_personality 92
+#define TARGET_NR_exit 93
+#define TARGET_NR_exit_group 94
+#define TARGET_NR_waitid 95
+#define TARGET_NR_set_tid_address 96
+#define TARGET_NR_unshare 97
+#define TARGET_NR_futex 98
+#define TARGET_NR_set_robust_list 99
+#define TARGET_NR_get_robust_list 100
+#define TARGET_NR_nanosleep 101
+#define TARGET_NR_getitimer 102
+#define TARGET_NR_setitimer 103
+#define TARGET_NR_kexec_load 104
+#define TARGET_NR_init_module 105
+#define TARGET_NR_delete_module 106
+#define TARGET_NR_timer_create 107
+#define TARGET_NR_timer_gettime 108
+#define TARGET_NR_timer_getoverrun 109
+#define TARGET_NR_timer_settime 110
+#define TARGET_NR_timer_delete 111
+#define TARGET_NR_clock_settime 112
+#define TARGET_NR_clock_gettime 113
+#define TARGET_NR_clock_getres 114
+#define TARGET_NR_clock_nanosleep 115
+#define TARGET_NR_syslog 116
+#define TARGET_NR_ptrace 117
+#define TARGET_NR_sched_setparam 118
+#define TARGET_NR_sched_setscheduler 119
+#define TARGET_NR_sched_getscheduler 120
+#define TARGET_NR_sched_getparam 121
+#define TARGET_NR_sched_setaffinity 122
+#define TARGET_NR_sched_getaffinity 123
+#define 

[PATCH v11 03/26] target/loongarch: Add main translation routines

2021-11-18 Thread Song Gao
This patch adds main translation routines and
basic functions for translation.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/helper.h|   6 ++
 target/loongarch/op_helper.c |  21 ++
 target/loongarch/translate.c | 159 +++
 target/loongarch/translate.h |  26 +++
 4 files changed, 212 insertions(+)
 create mode 100644 target/loongarch/helper.h
 create mode 100644 target/loongarch/op_helper.c
 create mode 100644 target/loongarch/translate.c
 create mode 100644 target/loongarch/translate.h

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
new file mode 100644
index 000..eb771c0
--- /dev/null
+++ b/target/loongarch/helper.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+DEF_HELPER_2(raise_exception, noreturn, env, i32)
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
new file mode 100644
index 000..9038109
--- /dev/null
+++ b/target/loongarch/op_helper.c
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation helpers for QEMU.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "cpu.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "internals.h"
+
+/* Exceptions helpers */
+void helper_raise_exception(CPULoongArchState *env, uint32_t exception)
+{
+do_raise_exception(env, exception, GETPC());
+}
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
new file mode 100644
index 000..048c895
--- /dev/null
+++ b/target/loongarch/translate.c
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation for QEMU - main translation routines.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "tcg/tcg-op.h"
+#include "exec/translator.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+
+#include "exec/translator.h"
+#include "exec/log.h"
+#include "qemu/qemu-print.h"
+#include "translate.h"
+#include "internals.h"
+
+/* Global register indices */
+TCGv cpu_gpr[32], cpu_pc;
+static TCGv cpu_lladdr, cpu_llval;
+TCGv_i32 cpu_fcsr0;
+TCGv_i64 cpu_fpr[32];
+
+#define DISAS_STOP   DISAS_TARGET_0
+
+void generate_exception(DisasContext *ctx, int excp)
+{
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
+ctx->base.is_jmp = DISAS_NORETURN;
+}
+
+static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+{
+if (translator_use_goto_tb(>base, dest)) {
+tcg_gen_goto_tb(n);
+tcg_gen_movi_tl(cpu_pc, dest);
+tcg_gen_exit_tb(ctx->base.tb, n);
+} else {
+tcg_gen_movi_tl(cpu_pc, dest);
+tcg_gen_lookup_and_goto_ptr();
+}
+}
+
+static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
+CPUState *cs)
+{
+int64_t bound;
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
+ctx->mem_idx = ctx->base.tb->flags;
+
+/* Bound the number of insns to execute to those left on the page.  */
+bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
+ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
+}
+
+static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
+{
+}
+
+static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+tcg_gen_insn_start(ctx->base.pc_next);
+}
+
+static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+{
+CPULoongArchState *env = cs->env_ptr;
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+
+if (!decode(ctx, ctx->opcode)) {
+qemu_log_mask(LOG_UNIMP, "Error: unkown opcode. 0x%lx: 0x%x\n",
+  ctx->base.pc_next, ctx->opcode);
+generate_exception(ctx, EXCP_INE);
+}
+
+ctx->base.pc_next += 4;
+}
+
+static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+switch (ctx->base.is_jmp) {
+case DISAS_STOP:
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+tcg_gen_lookup_and_goto_ptr();
+break;
+case DISAS_TOO_MANY:
+gen_goto_tb(ctx, 0, ctx->base.pc_next);
+break;
+case DISAS_NORETURN:
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void loongarch_tr_disas_log(const DisasContextBase *dcbase, CPUState 
*cs)
+{
+  

[PATCH v11 08/26] target/loongarch: Add fixed point atomic instruction translation

2021-11-18 Thread Song Gao
This includes:
- LL.{W/D}, SC.{W/D}
- AM{SWAP/ADD/AND/OR/XOR/MAX/MIN}[_DB].{W/D}
- AM{MAX/MIN}[_DB].{WU/DU}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/insn_trans/trans_atomic.c.inc | 130 +
 target/loongarch/insns.decode  |  44 +
 target/loongarch/translate.c   |   1 +
 3 files changed, 175 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_atomic.c.inc

diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
new file mode 100644
index 000..96957bb
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_ll(DisasContext *ctx, arg_rr_i *a,
+   void (*func)(TCGv, TCGv, int))
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_addi_tl(t0, src1, a->imm << 2);
+func(dest, t0, ctx->mem_idx);
+tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
+tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
+tcg_temp_free(t0);
+return true;
+}
+
+static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv t0 = tcg_temp_new();
+TCGv val = tcg_temp_new();
+
+TCGLabel *l1 = gen_new_label();
+TCGLabel *done = gen_new_label();
+
+tcg_gen_addi_tl(t0, src1, a->imm << 2);
+tcg_gen_brcond_tl(TCG_COND_EQ, t0, cpu_lladdr, l1);
+tcg_gen_movi_tl(dest, 0);
+tcg_gen_br(done);
+
+gen_set_label(l1);
+tcg_gen_mov_tl(val, src2);
+/* generate cmpxchg */
+tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval,
+  val, ctx->mem_idx, mop);
+tcg_gen_setcond_tl(TCG_COND_EQ, dest, t0, cpu_llval);
+gen_set_label(done);
+tcg_temp_free(t0);
+tcg_temp_free(val);
+return true;
+}
+
+static bool gen_am(DisasContext *ctx, arg_rrr *a,
+   void (*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
+   MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
+
+if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "Warning: source register overlaps destination register"
+  "in atomic insn at pc=0x" TARGET_FMT_lx "\n",
+  ctx->base.pc_next - 4);
+return false;
+}
+
+func(dest, addr, val, ctx->mem_idx, mop);
+return true;
+}
+
+static bool gen_am_db(DisasContext *ctx, arg_rrr *a,
+  void (*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
+  MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
+
+if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "Warning: source register overlaps destination register"
+  "in atomic insn at pc=0x" TARGET_FMT_lx "\n",
+  ctx->base.pc_next - 4);
+return false;
+}
+
+gen_loongarch_sync(0x10);
+func(dest, addr, val, ctx->mem_idx, mop);
+
+return true;
+}
+
+TRANS(ll_w, gen_ll, tcg_gen_qemu_ld32s)
+TRANS(sc_w, gen_sc, MO_TESL)
+TRANS(ll_d, gen_ll, tcg_gen_qemu_ld64)
+TRANS(sc_d, gen_sc, MO_TEQ)
+TRANS(amswap_w, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
+TRANS(amswap_d, gen_am, tcg_gen_atomic_xchg_tl, MO_TEQ)
+TRANS(amadd_w, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
+TRANS(amadd_d, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEQ)
+TRANS(amand_w, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
+TRANS(amand_d, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEQ)
+TRANS(amor_w, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
+TRANS(amor_d, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEQ)
+TRANS(amxor_w, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
+TRANS(amxor_d, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEQ)
+TRANS(ammax_w, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
+TRANS(ammax_d, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEQ)
+TRANS(ammin_w, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
+TRANS(ammin_d, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEQ)
+TRANS(ammax_wu, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
+TRANS(ammax_du, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEQ)
+TRANS(ammin_wu, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
+TRANS(ammin_du, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEQ)
+TRANS(amswap_db_w, gen_am_db, tcg_gen_atomic_xchg_tl, MO_TESL)

[PATCH v11 19/26] linux-user: Add LoongArch signal support

2021-11-18 Thread Song Gao
Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
---
 linux-user/loongarch64/signal.c| 162 +
 linux-user/loongarch64/target_signal.h |  29 ++
 2 files changed, 191 insertions(+)
 create mode 100644 linux-user/loongarch64/signal.c
 create mode 100644 linux-user/loongarch64/target_signal.h

diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
new file mode 100644
index 000..8fbc827
--- /dev/null
+++ b/linux-user/loongarch64/signal.c
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation of Linux signals
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "signal-common.h"
+#include "user-internals.h"
+#include "linux-user/trace.h"
+
+struct target_sigcontext {
+uint64_t   sc_pc;
+uint64_t   sc_gpr[32];
+uint64_t   sc_fpr[32];
+uint64_t   sc_fcc;
+uint32_t   sc_fcsr;
+uint32_t   sc_flags;
+};
+
+struct target_ucontext {
+target_ulong tuc_flags;
+target_ulong tuc_link;
+target_stack_t tuc_stack;
+target_ulong pad0;
+struct target_sigcontext tuc_mcontext;
+target_sigset_t tuc_sigmask;
+};
+
+struct target_rt_sigframe {
+struct target_siginfo rs_info;
+struct target_ucontext rs_uc;
+};
+
+static inline void setup_sigcontext(CPULoongArchState *env,
+struct target_sigcontext *sc)
+{
+int i;
+
+__put_user(env->pc, >sc_pc);
+
+__put_user(0, >sc_gpr[0]);
+for (i = 1; i < 32; ++i) {
+__put_user(env->gpr[i], >sc_gpr[i]);
+}
+
+for (i = 0; i < 32; ++i) {
+__put_user(env->fpr[i], >sc_fpr[i]);
+}
+}
+
+static inline void
+restore_sigcontext(CPULoongArchState *env, struct target_sigcontext *sc)
+{
+int i;
+
+__get_user(env->pc, >sc_pc);
+
+for (i = 1; i < 32; ++i) {
+__get_user(env->gpr[i], >sc_gpr[i]);
+}
+
+for (i = 0; i < 32; ++i) {
+__get_user(env->fpr[i], >sc_fpr[i]);
+}
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline abi_ulong
+get_sigframe(struct target_sigaction *ka, CPULoongArchState *env,
+ size_t frame_size)
+{
+unsigned long sp;
+
+sp = target_sigsp(get_sp_from_cpustate(env) - 32, ka);
+
+return (sp - frame_size) & ~7;
+}
+
+void setup_rt_frame(int sig, struct target_sigaction *ka,
+target_siginfo_t *info,
+target_sigset_t *set, CPULoongArchState *env)
+{
+struct target_rt_sigframe *frame;
+abi_ulong frame_addr;
+int i;
+
+frame_addr = get_sigframe(ka, env, sizeof(*frame));
+trace_user_setup_rt_frame(env, frame_addr);
+if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+goto give_sigsegv;
+}
+
+tswap_siginfo(>rs_info, info);
+
+__put_user(0, >rs_uc.tuc_flags);
+__put_user(0, >rs_uc.tuc_link);
+target_save_altstack(>rs_uc.tuc_stack, env);
+
+setup_sigcontext(env, >rs_uc.tuc_mcontext);
+
+for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+__put_user(set->sig[i], >rs_uc.tuc_sigmask.sig[i]);
+}
+
+env->gpr[4] = sig;
+env->gpr[5] = frame_addr + offsetof(struct target_rt_sigframe, rs_info);
+env->gpr[6] = frame_addr + offsetof(struct target_rt_sigframe, rs_uc);
+env->gpr[3] = frame_addr;
+env->gpr[1] = default_rt_sigreturn;
+
+env->pc = env->gpr[20] = ka->_sa_handler;
+unlock_user_struct(frame, frame_addr, 1);
+return;
+
+give_sigsegv:
+unlock_user_struct(frame, frame_addr, 1);
+force_sigsegv(sig);
+}
+
+long do_rt_sigreturn(CPULoongArchState *env)
+{
+struct target_rt_sigframe *frame;
+abi_ulong frame_addr;
+sigset_t blocked;
+
+frame_addr = env->gpr[3];
+trace_user_do_rt_sigreturn(env, frame_addr);
+if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
+goto badframe;
+}
+
+target_to_host_sigset(, >rs_uc.tuc_sigmask);
+set_sigmask();
+
+restore_sigcontext(env, >rs_uc.tuc_mcontext);
+target_restore_altstack(>rs_uc.tuc_stack, env);
+
+unlock_user_struct(frame, frame_addr, 0);
+return -TARGET_QEMU_ESIGRETURN;
+
+badframe:
+unlock_user_struct(frame, frame_addr, 0);
+force_sig(TARGET_SIGSEGV);
+return -TARGET_QEMU_ESIGRETURN;
+}
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
+assert(tramp != NULL);
+
+__put_user(0x03822c0b, tramp + 0);  /* ori a7, a7, 0x8b */
+__put_user(0x002b, tramp + 1);  /* syscall 0 */
+
+default_rt_sigreturn = sigtramp_page;
+unlock_user(tramp, sigtramp_page, 8);
+}
diff --git a/linux-user/loongarch64/target_signal.h 
b/linux-user/loongarch64/target_signal.h
new file mode 100644
index 000..c5f467b
--- /dev/null
+++ b/linux-user/loongarch64/target_signal.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson 

[PATCH v11 06/26] target/loongarch: Add fixed point bit instruction translation

2021-11-18 Thread Song Gao
This includes:
- EXT.W.{B/H}
- CL{O/Z}.{W/D}, CT{O/Z}.{W/D}
- BYTEPICK.{W/D}
- REVB.{2H/4H/2W/D}
- REVH.{2W/D}
- BITREV.{4B/8B}, BITREV.{W/D}
- BSTRINS.{W/D}, BSTRPICK.{W/D}
- MASKEQZ, MASKNEZ

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/helper.h   |   4 +
 target/loongarch/insn_trans/trans_bit.c.inc | 252 
 target/loongarch/insns.decode   |  40 +
 target/loongarch/op_helper.c|  22 +++
 target/loongarch/translate.c|   1 +
 5 files changed, 319 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_bit.c.inc

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index eb771c0..04e0245 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -4,3 +4,7 @@
  */
 
 DEF_HELPER_2(raise_exception, noreturn, env, i32)
+
+DEF_HELPER_FLAGS_1(bitrev_w, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_1(bitrev_d, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
diff --git a/target/loongarch/insn_trans/trans_bit.c.inc 
b/target/loongarch/insn_trans/trans_bit.c.inc
new file mode 100644
index 000..5063773
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_bit.c.inc
@@ -0,0 +1,252 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_rr(DisasContext *ctx, arg_rr *a,
+   DisasExtend src_ext, DisasExtend dst_ext,
+   void (*func)(TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src_ext);
+
+func(dest, src1);
+
+if (dst_ext) {
+gen_set_gpr(a->rd, dest, dst_ext);
+}
+return true;
+}
+
+static bool trans_bytepick_w(DisasContext *ctx, arg_bytepick_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+tcg_gen_concat_tl_i64(dest, src1, src2);
+tcg_gen_sextract_i64(dest, dest, (32 - (a->sa) * 8), 32);
+
+return true;
+}
+
+static bool trans_bytepick_d(DisasContext *ctx, arg_bytepick_d *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+tcg_gen_extract2_i64(dest, src1, src2, (64 - (a->sa) * 8));
+return true;
+}
+
+static bool trans_bstrins_w(DisasContext *ctx, arg_bstrins_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (a->lsbw > a->msbw) {
+return false;
+}
+
+tcg_gen_deposit_tl(dest, dest, src1, a->lsbw, a->msbw - a->lsbw + 1);
+tcg_gen_ext32s_tl(dest, dest);
+
+return true;
+}
+
+static bool trans_bstrins_d(DisasContext *ctx, arg_bstrins_d *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (a->lsbd > a->msbd) {
+return false;
+}
+
+tcg_gen_deposit_tl(dest, dest, src1, a->lsbd, a->msbd - a->lsbd + 1);
+return true;
+}
+
+static bool trans_bstrpick_w(DisasContext *ctx, arg_bstrpick_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (a->lsbw > a->msbw) {
+return false;
+}
+
+tcg_gen_extract_tl(dest, src1, a->lsbw, a->msbw - a->lsbw + 1);
+tcg_gen_ext32s_tl(dest, dest);
+return true;
+}
+
+static bool trans_bstrpick_d(DisasContext *ctx, arg_bstrpick_d *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (a->lsbd > a->msbd) {
+return false;
+}
+
+tcg_gen_extract_tl(dest, src1, a->lsbd, a->msbd - a->lsbd + 1);
+return true;
+}
+
+static void gen_clz_w(TCGv dest, TCGv src1)
+{
+tcg_gen_clzi_tl(dest, src1, TARGET_LONG_BITS);
+tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32);
+}
+
+static void gen_clo_w(TCGv dest, TCGv src1)
+{
+tcg_gen_not_tl(dest, src1);
+tcg_gen_ext32u_tl(dest, dest);
+gen_clz_w(dest, dest);
+}
+
+static void gen_ctz_w(TCGv dest, TCGv src1)
+{
+tcg_gen_ori_tl(dest, src1, (target_ulong)MAKE_64BIT_MASK(32, 32));
+tcg_gen_ctzi_tl(dest, dest, 32);
+}
+
+static void gen_cto_w(TCGv dest, TCGv src1)
+{
+tcg_gen_not_tl(dest, src1);
+tcg_gen_ext32u_tl(dest, dest);
+gen_ctz_w(dest, dest);
+}
+
+static void gen_clz_d(TCGv dest, TCGv src1)
+{
+tcg_gen_clzi_i64(dest, src1, TARGET_LONG_BITS);
+}
+
+static void gen_clo_d(TCGv dest, TCGv src1)
+{
+tcg_gen_not_tl(dest, src1);
+gen_clz_d(dest, dest);
+}
+
+static void gen_ctz_d(TCGv dest, TCGv src1)
+{
+tcg_gen_ctzi_tl(dest, src1, TARGET_LONG_BITS);
+}
+
+static void gen_cto_d(TCGv dest, TCGv src1)
+{
+tcg_gen_not_tl(dest, src1);
+gen_ctz_d(dest, dest);
+}
+
+static void gen_revb_2w(TCGv dest, TCGv src1)
+{
+tcg_gen_bswap64_i64(dest, 

[PATCH v11 04/26] target/loongarch: Add fixed point arithmetic instruction translation

2021-11-18 Thread Song Gao
This includes:
- ADD.{W/D}, SUB.{W/D}
- ADDI.{W/D}, ADDU16ID
- ALSL.{W[U]/D}
- LU12I.W, LU32I.D LU52I.D
- SLT[U], SLT[U]I
- PCADDI, PCADDU12I, PCADDU18I, PCALAU12I
- AND, OR, NOR, XOR, ANDN, ORN
- MUL.{W/D}, MULH.{W[U]/D[U]}
- MULW.D.W[U]
- DIV.{W[U]/D[U]}, MOD.{W[U]/D[U]}
- ANDI, ORI, XORI

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/insn_trans/trans_arith.c.inc | 309 ++
 target/loongarch/insns.decode |  79 +++
 target/loongarch/translate.c  |  83 +++
 target/loongarch/translate.h  |  19 ++
 4 files changed, 490 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_arith.c.inc
 create mode 100644 target/loongarch/insns.decode

diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
new file mode 100644
index 000..ae1e113
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -0,0 +1,309 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_rrr(DisasContext *ctx, arg_rrr *a,
+DisasExtend src1_ext, DisasExtend src2_ext,
+DisasExtend dst_ext, void (*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src1_ext);
+TCGv src2 = gpr_src(ctx, a->rk, src2_ext);
+
+func(dest, src1, src2);
+
+/* dst_ext is EXT_NONE and input is dest, We don't run gen_set_gpr. */
+if (dst_ext) {
+gen_set_gpr(a->rd, dest, dst_ext);
+}
+return true;
+}
+
+static bool gen_rr_i(DisasContext *ctx, arg_rr_i *a,
+ DisasExtend src_ext, DisasExtend dst_ext,
+ void (*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src_ext);
+TCGv src2 = tcg_constant_tl(a->imm);
+
+func(dest, src1, src2);
+
+if (dst_ext) {
+gen_set_gpr(a->rd, dest, dst_ext);
+}
+return true;
+}
+
+static bool gen_rrr_sa(DisasContext *ctx, arg_rrr_sa *a,
+  DisasExtend src_ext, DisasExtend dst_ext,
+  void (*func)(TCGv, TCGv, TCGv, TCGv, target_long))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src_ext);
+TCGv src2 = gpr_src(ctx, a->rk, src_ext);
+TCGv temp = tcg_temp_new();
+
+func(dest, src1, src2, temp, a->sa);
+
+if (dst_ext) {
+gen_set_gpr(a->rd, dest, dst_ext);
+}
+tcg_temp_free(temp);
+return true;
+}
+
+static bool trans_lu12i_w(DisasContext *ctx, arg_lu12i_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+tcg_gen_movi_tl(dest, a->imm << 12);
+return true;
+}
+
+static bool gen_pc(DisasContext *ctx, arg_r_i *a,
+   target_ulong (*func)(target_ulong, int))
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+target_ulong addr = func(ctx->base.pc_next, a->imm);
+
+tcg_gen_movi_tl(dest, addr);
+return true;
+}
+
+static void gen_slt(TCGv dest, TCGv src1, TCGv src2)
+{
+tcg_gen_setcond_tl(TCG_COND_LT, dest, src1, src2);
+}
+
+static void gen_sltu(TCGv dest, TCGv src1, TCGv src2)
+{
+tcg_gen_setcond_tl(TCG_COND_LTU, dest, src1, src2);
+}
+
+static void gen_mulh_w(TCGv dest, TCGv src1, TCGv src2)
+{
+tcg_gen_mul_i64(dest, src1, src2);
+tcg_gen_sari_i64(dest, dest, 32);
+}
+
+static void gen_mulh_wu(TCGv dest, TCGv src1, TCGv src2)
+{
+tcg_gen_mul_i64(dest, src1, src2);
+tcg_gen_sari_i64(dest, dest, 32);
+}
+
+static void gen_mulh_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv discard = tcg_temp_new();
+tcg_gen_muls2_tl(discard, dest, src1, src2);
+tcg_temp_free(discard);
+}
+
+static void gen_mulh_du(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv discard = tcg_temp_new();
+tcg_gen_mulu2_tl(discard, dest, src1, src2);
+tcg_temp_free(discard);
+}
+
+static void prep_divisor_d(TCGv ret, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+TCGv t1 = tcg_temp_new();
+TCGv zero = tcg_constant_tl(0);
+
+/*
+ * If min / -1, set the divisor to 1.
+ * This avoids potential host overflow trap and produces min.
+ * If x / 0, set the divisor to 1.
+ * This avoids potential host overflow trap;
+ * the required result is undefined.
+ */
+tcg_gen_setcondi_tl(TCG_COND_EQ, ret, src1, INT64_MIN);
+tcg_gen_setcondi_tl(TCG_COND_EQ, t0, src2, -1);
+tcg_gen_setcondi_tl(TCG_COND_EQ, t1, src2, 0);
+tcg_gen_and_tl(ret, ret, t0);
+tcg_gen_or_tl(ret, ret, t1);
+tcg_gen_movcond_tl(TCG_COND_NE, ret, ret, zero, ret, src2);
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+}
+
+static void prep_divisor_du(TCGv ret, TCGv src2)
+{
+TCGv zero = tcg_constant_tl(0);
+TCGv one = tcg_constant_tl(1);
+
+/*
+ * If x / 0, set the divisor to 1.
+ * This 

[PATCH v11 02/26] target/loongarch: Add core definition

2021-11-18 Thread Song Gao
This patch adds target state header, target definitions
and initialization routines.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu-param.h |  18 +++
 target/loongarch/cpu.c   | 314 +++
 target/loongarch/cpu.h   | 253 ++
 target/loongarch/internals.h |  21 +++
 4 files changed, 606 insertions(+)
 create mode 100644 target/loongarch/cpu-param.h
 create mode 100644 target/loongarch/cpu.c
 create mode 100644 target/loongarch/cpu.h
 create mode 100644 target/loongarch/internals.h

diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
new file mode 100644
index 000..9a769b6
--- /dev/null
+++ b/target/loongarch/cpu-param.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch CPU parameters for QEMU.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_CPU_PARAM_H
+#define LOONGARCH_CPU_PARAM_H
+
+#define TARGET_LONG_BITS 64
+#define TARGET_PHYS_ADDR_SPACE_BITS 48
+#define TARGET_VIRT_ADDR_SPACE_BITS 48
+
+#define TARGET_PAGE_BITS 14
+#define NB_MMU_MODES 4
+
+#endif
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
new file mode 100644
index 000..b3f
--- /dev/null
+++ b/target/loongarch/cpu.c
@@ -0,0 +1,314 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch CPU
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/qemu-print.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "sysemu/qtest.h"
+#include "exec/exec-all.h"
+#include "qapi/qapi-commands-machine-target.h"
+#include "cpu.h"
+#include "internals.h"
+#include "fpu/softfloat-helpers.h"
+
+const char * const regnames[] = {
+"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+};
+
+const char * const fregnames[] = {
+"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+};
+
+static const char * const excp_names[EXCP_LAST + 1] = {
+[EXCP_ADE] = "Address error",
+[EXCP_SYSCALL] = "Syscall",
+[EXCP_BREAK] = "Break",
+[EXCP_INE] = "Instruction Non-existent",
+[EXCP_FPE] = "Floating Point Exception",
+};
+
+const char *loongarch_exception_name(int32_t exception)
+{
+return excp_names[exception];
+}
+
+void QEMU_NORETURN do_raise_exception(CPULoongArchState *env,
+  uint32_t exception,
+  uintptr_t pc)
+{
+CPUState *cs = env_cpu(env);
+
+qemu_log_mask(CPU_LOG_INT, "%s: %d (%s)\n",
+  __func__,
+  exception,
+  loongarch_exception_name(exception));
+cs->exception_index = exception;
+
+cpu_loop_exit_restore(cs, pc);
+}
+
+static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = >env;
+
+env->pc = value;
+}
+
+#ifdef CONFIG_TCG
+static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
+  const TranslationBlock *tb)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = >env;
+
+env->pc = tb->pc;
+}
+#endif /* CONFIG_TCG */
+
+static bool loongarch_cpu_has_work(CPUState *cs)
+{
+return true;
+}
+
+static void loongarch_3a5000_initfn(Object *obj)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+CPULoongArchState *env = >env;
+int i;
+
+for (i = 0; i < 21; i++) {
+env->cpucfg[i] = 0x0;
+}
+
+env->cpucfg[0] = 0x14c010;  /* PRID */
+
+uint32_t data = 0;
+data = FIELD_DP32(data, CPUCFG1, ARCH, 2);
+data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
+data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
+data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f);
+data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f);
+data = FIELD_DP32(data, CPUCFG1, UAL, 1);
+data = FIELD_DP32(data, CPUCFG1, RI, 1);
+data = FIELD_DP32(data, CPUCFG1, EP, 1);
+data = FIELD_DP32(data, CPUCFG1, RPLV, 1);
+data = FIELD_DP32(data, CPUCFG1, HP, 1);
+data = FIELD_DP32(data, CPUCFG1, IOCSR_BRD, 1);
+env->cpucfg[1] = data;
+
+data = 0;
+data = FIELD_DP32(data, CPUCFG2, FP, 1);
+data = FIELD_DP32(data, CPUCFG2, FP_SP, 1);
+data = FIELD_DP32(data, CPUCFG2, FP_DP, 1);
+data = FIELD_DP32(data, CPUCFG2, FP_VER, 1);
+data = FIELD_DP32(data, CPUCFG2, LLFTP, 1);
+data = FIELD_DP32(data, CPUCFG2, LLFTP_VER, 1);
+data = FIELD_DP32(data, CPUCFG2, LSPW, 1);
+data = FIELD_DP32(data, CPUCFG2, LAM, 1);
+

[PATCH v11 10/26] target/loongarch: Add floating point arithmetic instruction translation

2021-11-18 Thread Song Gao
This includes:
- F{ADD/SUB/MUL/DIV}.{S/D}
- F{MADD/MSUB/NMADD/NMSUB}.{S/D}
- F{MAX/MIN}.{S/D}
- F{MAXA/MINA}.{S/D}
- F{ABS/NEG}.{S/D}
- F{SQRT/RECIP/RSQRT}.{S/D}
- F{SCALEB/LOGB/COPYSIGN}.{S/D}
- FCLASS.{S/D}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.c |   1 +
 target/loongarch/fpu_helper.c  | 405 +
 target/loongarch/helper.h  |  37 +++
 target/loongarch/insn_trans/trans_farith.c.inc | 105 +++
 target/loongarch/insns.decode  |  52 
 target/loongarch/internals.h   |   2 +
 target/loongarch/translate.c   |  11 +
 7 files changed, 613 insertions(+)
 create mode 100644 target/loongarch/fpu_helper.c
 create mode 100644 target/loongarch/insn_trans/trans_farith.c.inc

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index b3f..ad11b98 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -185,6 +185,7 @@ static void loongarch_cpu_reset(DeviceState *dev)
 env->fcsr0_mask = 0x1f1f031f;
 env->fcsr0 = 0x0;
 
+restore_fp_status(env);
 cs->exception_index = EXCP_NONE;
 }
 
diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
new file mode 100644
index 000..d0ef675
--- /dev/null
+++ b/target/loongarch/fpu_helper.c
@@ -0,0 +1,405 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch float point emulation helpers for QEMU
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "fpu/softfloat.h"
+#include "internals.h"
+
+#define FLOAT_TO_INT32_OVERFLOW 0x7fff
+#define FLOAT_TO_INT64_OVERFLOW 0x7fffULL
+
+static inline uint64_t nanbox_s(float32 fp)
+{
+return fp | MAKE_64BIT_MASK(32, 32);
+}
+
+/* Convert loongarch rounding mode in fcsr0 to IEEE library */
+static const FloatRoundMode ieee_rm[4] = {
+float_round_nearest_even,
+float_round_to_zero,
+float_round_up,
+float_round_down
+};
+
+void restore_fp_status(CPULoongArchState *env)
+{
+set_float_rounding_mode(ieee_rm[(env->fcsr0 >> FCSR0_RM) & 0x3],
+>fp_status);
+set_flush_to_zero(0, >fp_status);
+}
+
+static int ieee_ex_to_loongarch(int xcpt)
+{
+int ret = 0;
+if (xcpt & float_flag_invalid) {
+ret |= FP_INVALID;
+}
+if (xcpt & float_flag_overflow) {
+ret |= FP_OVERFLOW;
+}
+if (xcpt & float_flag_underflow) {
+ret |= FP_UNDERFLOW;
+}
+if (xcpt & float_flag_divbyzero) {
+ret |= FP_DIV0;
+}
+if (xcpt & float_flag_inexact) {
+ret |= FP_INEXACT;
+}
+return ret;
+}
+
+static void update_fcsr0_mask(CPULoongArchState *env, uintptr_t pc, int mask)
+{
+int flags = get_float_exception_flags(>fp_status);
+
+set_float_exception_flags(0, >fp_status);
+
+if (~mask) {
+flags = flags & (~mask);
+}
+
+if (!flags) {
+SET_FP_CAUSE(env->fcsr0, flags);
+return;
+}
+
+flags = ieee_ex_to_loongarch(flags);
+SET_FP_CAUSE(env->fcsr0, flags);
+
+if (GET_FP_ENABLES(env->fcsr0) & flags) {
+do_raise_exception(env, EXCP_FPE, pc);
+} else {
+UPDATE_FP_FLAGS(env->fcsr0, flags);
+}
+}
+
+static void update_fcsr0(CPULoongArchState *env, uintptr_t pc)
+{
+update_fcsr0_mask(env, pc, 0);
+}
+
+uint64_t helper_fadd_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = nanbox_s(float32_add((uint32_t)fj, (uint32_t)fk, >fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fadd_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = float64_add(fj, fk, >fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fsub_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = nanbox_s(float32_sub((uint32_t)fj, (uint32_t)fk, >fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fsub_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = float64_sub(fj, fk, >fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fmul_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = nanbox_s(float32_mul((uint32_t)fj, (uint32_t)fk, >fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fmul_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = float64_mul(fj, fk, >fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fdiv_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = nanbox_s(float32_div((uint32_t)fj, (uint32_t)fk, >fp_status));
+update_fcsr0(env, 

[PATCH v11 00/26] Add LoongArch linux-user emulation support

2021-11-18 Thread Song Gao
Hi all,

This series only support linux-user emulation.
More about LoongArch at: https://github.com/loongson/

The latest kernel:
  * https://github.com/loongson/linux/tree/loongarch-next

Patches need review:
  * 0016-target-loongarch-Add-disassembler.patch
  * 0017-linux-user-Add-LoongArch-generic-header-files.patch
  * 0018-linux-user-Add-LoongArch-specific-structures.patch
  * 0019-linux-user-Add-LoongArch-signal-support.patch
  * 0020-linux-user-Add-LoongArch-elf-support.patch
  * 0021-linux-user-Add-LoongArch-syscall-support.patch
  * 0022-linux-user-Add-LoongArch-cpu_loop-support.patch

Changes for v11:
  * Clean up insns.decode.  

Changes for v10:
  * Delete format_insn(), use output_XXX.

Changes for v9:
  * Use GPL-2.0+ SPDX license identifier.
  * Move set_loongarch_cpucfg() in loongarch_3a5000_initfn().
  * target/loongarch/insn_trans/trans_xxx.c rename to
target/loongarch/insn_trans/trans_xxx.c.inc.
  * Split host_signal_pc and host_signal_write out of user-exec.c.

Changes for v8:
  * Use the FIELD functions to define cpucfg[i].
  * Re-use the decodetree to disassembler description.
  * Split v7 patch(0017-LoongArch-Linux-User-Emulation.patch).

Changes for v7:
  * scripts/gensyscalls.sh support loongarch64
if we use gensyscalls.sh, we need disable __BITS_PER_LONG at 
arch/loongarch/include/uapi/asm/bitsperlong.h

V10:https://patchew.org/QEMU/1636700049-24381-1-git-send-email-gaos...@loongson.cn/
V9: 
https://patchew.org/QEMU/1636340895-5255-1-git-send-email-gaos...@loongson.cn/
V8: 
https://patchew.org/QEMU/1635760311-20015-1-git-send-email-gaos...@loongson.cn/
V7: 
https://patchew.org/QEMU/1634561247-25499-1-git-send-email-gaos...@loongson.cn/

Please review!

Thanks.


Song Gao (26):
  target/loongarch: Add README
  target/loongarch: Add core definition
  target/loongarch: Add main translation routines
  target/loongarch: Add fixed point arithmetic instruction translation
  target/loongarch: Add fixed point shift instruction translation
  target/loongarch: Add fixed point bit instruction translation
  target/loongarch: Add fixed point load/store instruction translation
  target/loongarch: Add fixed point atomic instruction translation
  target/loongarch: Add fixed point extra instruction translation
  target/loongarch: Add floating point arithmetic instruction
translation
  target/loongarch: Add floating point comparison instruction
translation
  target/loongarch: Add floating point conversion instruction
translation
  target/loongarch: Add floating point move instruction translation
  target/loongarch: Add floating point load/store instruction
translation
  target/loongarch: Add branch instruction translation
  target/loongarch: Add disassembler
  linux-user: Add LoongArch generic header files
  linux-user: Add LoongArch specific structures
  linux-user: Add LoongArch signal support
  linux-user: Add LoongArch elf support
  linux-user: Add LoongArch syscall support
  linux-user: Add LoongArch cpu_loop support
  default-configs: Add loongarch linux-user support
  target/loongarch: Add target build suport
  target/loongarch: 'make check-tcg' support
  scripts: add loongarch64 binfmt config

 MAINTAINERS |   5 +
 configs/targets/loongarch64-linux-user.mak  |   3 +
 configure   |   5 +
 include/disas/dis-asm.h |   2 +
 include/elf.h   |   2 +
 linux-user/elfload.c|  58 ++
 linux-user/loongarch64/cpu_loop.c   |  97 +++
 linux-user/loongarch64/signal.c | 162 +
 linux-user/loongarch64/sockbits.h   |  11 +
 linux-user/loongarch64/syscall_nr.h | 312 +
 linux-user/loongarch64/target_cpu.h |  34 +
 linux-user/loongarch64/target_elf.h |  12 +
 linux-user/loongarch64/target_errno_defs.h  |  12 +
 linux-user/loongarch64/target_fcntl.h   |  11 +
 linux-user/loongarch64/target_signal.h  |  29 +
 linux-user/loongarch64/target_structs.h |  48 ++
 linux-user/loongarch64/target_syscall.h |  45 ++
 linux-user/loongarch64/termbits.h   |  11 +
 linux-user/syscall_defs.h   |  10 +-
 meson.build |   3 +-
 scripts/gensyscalls.sh  |   1 +
 scripts/qemu-binfmt-conf.sh |   6 +-
 target/loongarch/README |  76 +++
 target/loongarch/cpu-param.h|  18 +
 target/loongarch/cpu.c  | 315 +
 target/loongarch/cpu.h  | 253 +++
 target/loongarch/disas.c| 625 +
 target/loongarch/fpu_helper.c   | 864 
 target/loongarch/helper.h   |  94 +++
 target/loongarch/insn_trans/trans_arith.c.inc   | 309 +
 

[PATCH v11 05/26] target/loongarch: Add fixed point shift instruction translation

2021-11-18 Thread Song Gao
This includes:
- SLL.W, SRL.W, SRA.W, ROTR.W
- SLLI.W, SRLI.W, SRAI.W, ROTRI.W
- SLL.D, SRL.D, SRA.D, ROTR.D
- SLLI.D, SRLI.D, SRAI.D, ROTRI.D

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/insn_trans/trans_shift.c.inc | 128 ++
 target/loongarch/insns.decode |  22 +
 target/loongarch/translate.c  |   1 +
 3 files changed, 151 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_shift.c.inc

diff --git a/target/loongarch/insn_trans/trans_shift.c.inc 
b/target/loongarch/insn_trans/trans_shift.c.inc
new file mode 100644
index 000..ea2a612
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_shift.c.inc
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_shift(DisasContext *ctx, arg_rr_i *a,
+  void(*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_SIGN);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO);
+TCGv src2 = tcg_constant_tl(a->imm);
+
+func(dest, src1, src2);
+gen_set_gpr(a->rd, dest, EXT_SIGN);
+
+return true;
+}
+
+static bool gen_shift_i(DisasContext *ctx, arg_rr_i *a,
+void(*func)(TCGv, TCGv, target_long))
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+func(dest, src1, a->imm);
+
+return true;
+}
+
+static void gen_sll_w(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x1f);
+tcg_gen_shl_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_srl_w(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x1f);
+tcg_gen_shr_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_sra_w(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x1f);
+tcg_gen_sar_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_sll_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x3f);
+tcg_gen_shl_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_srl_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x3f);
+tcg_gen_shr_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_sra_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x3f);
+tcg_gen_sar_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_rotr_w(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv_i32 t1 = tcg_temp_new_i32();
+TCGv_i32 t2 = tcg_temp_new_i32();
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_andi_tl(t0, src2, 0x1f);
+
+tcg_gen_trunc_tl_i32(t1, src1);
+tcg_gen_trunc_tl_i32(t2, t0);
+
+tcg_gen_rotr_i32(t1, t1, t2);
+tcg_gen_ext_i32_tl(dest, t1);
+
+tcg_temp_free_i32(t1);
+tcg_temp_free_i32(t2);
+tcg_temp_free(t0);
+}
+
+static void gen_rotr_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x3f);
+tcg_gen_rotr_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO);
+
+tcg_gen_sextract_tl(dest, src1, a->imm, 32 - a->imm);
+return true;
+}
+
+TRANS(sll_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_sll_w)
+TRANS(srl_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_srl_w)
+TRANS(sra_w, gen_rrr, EXT_SIGN, EXT_NONE, EXT_SIGN, gen_sra_w)
+TRANS(sll_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sll_d)
+TRANS(srl_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_srl_d)
+TRANS(sra_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sra_d)
+TRANS(rotr_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_rotr_w)
+TRANS(rotr_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rotr_d)
+TRANS(slli_w, gen_shift, tcg_gen_shl_tl)
+TRANS(slli_d, gen_shift_i, tcg_gen_shli_tl)
+TRANS(srli_w, gen_shift, tcg_gen_shr_tl)
+TRANS(srli_d, gen_shift_i, tcg_gen_shri_tl)
+TRANS(srai_d, gen_shift_i, tcg_gen_sari_tl)
+TRANS(rotri_w, gen_shift, gen_rotr_w)
+TRANS(rotri_d, gen_shift_i, tcg_gen_rotri_tl)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 8579c11..673aee4 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -23,6 +23,8 @@
 #
 @rrr     . rk:5 rj:5 rd:5
 @r_i20   ... imm:s20 rd:5_i
+@rr_ui5     . imm:5 rj:5 rd:5_i
+@rr_ui6   imm:6 rj:5 rd:5_i
 @rr_i12  .. imm:s12 rj:5 rd:5_i
 @rr_ui12  .. imm:12 rj:5 rd:5_i
 @rr_i16  .. imm:s16 rj:5 rd:5  

[PATCH v11 07/26] target/loongarch: Add fixed point load/store instruction translation

2021-11-18 Thread Song Gao
This includes:
- LD.{B[U]/H[U]/W[U]/D}, ST.{B/H/W/D}
- LDX.{B[U]/H[U]/W[U]/D}, STX.{B/H/W/D}
- LDPTR.{W/D}, STPTR.{W/D}
- PRELD
- LD{GT/LE}.{B/H/W/D}, ST{GT/LE}.{B/H/W/D}
- DBAR, IBAR

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/helper.h  |   3 +
 target/loongarch/insn_trans/trans_memory.c.inc | 232 +
 target/loongarch/insns.decode  |  54 ++
 target/loongarch/op_helper.c   |  15 ++
 target/loongarch/translate.c   |  30 
 5 files changed, 334 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_memory.c.inc

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 04e0245..2fe4e63 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -8,3 +8,6 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
 DEF_HELPER_FLAGS_1(bitrev_w, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(bitrev_d, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
+
+DEF_HELPER_3(asrtle_d, void, env, tl, tl)
+DEF_HELPER_3(asrtgt_d, void, env, tl, tl)
diff --git a/target/loongarch/insn_trans/trans_memory.c.inc 
b/target/loongarch/insn_trans/trans_memory.c.inc
new file mode 100644
index 000..1dd7deb
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_memory.c.inc
@@ -0,0 +1,232 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_load(DisasContext *ctx, arg_rr_i *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv temp = NULL;
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
+
+if (temp) {
+tcg_temp_free(temp);
+}
+return true;
+}
+
+static bool gen_store(DisasContext *ctx, arg_rr_i *a, MemOp mop)
+{
+TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv temp = NULL;
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
+
+if (temp) {
+tcg_temp_free(temp);
+}
+return true;
+}
+
+static bool gen_loadx(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_storex(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_load_gt(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_load_le(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_store_gt(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
+
+tcg_temp_free(addr);
+return true;
+}
+
+static bool gen_store_le(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
+
+tcg_temp_free(addr);
+return 

[PATCH V3 2/2] test/qtest/test-filter-mirror.c: Change the default vnet_hdr_support

2021-11-18 Thread Zhang Chen
As net filters changed default vnet_hdr_support=on.
For this e1000 test case need to add vnet_hdr_support=off.

Signed-off-by: Zhang Chen 
---
 tests/qtest/test-filter-mirror.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qtest/test-filter-mirror.c b/tests/qtest/test-filter-mirror.c
index bc0dee64dd..7756f8cfc1 100644
--- a/tests/qtest/test-filter-mirror.c
+++ b/tests/qtest/test-filter-mirror.c
@@ -45,7 +45,7 @@ static void test_mirror(void)
 "-netdev socket,id=qtest-bn0,fd=%d "
 "-device %s,netdev=qtest-bn0,id=qtest-e0 "
 "-chardev socket,id=mirror0,fd=%d "
-"-object 
filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0 "
+"-object 
filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0,vnet_hdr_support=off
 "
 , send_sock[1], devstr, recv_sock[1]);
 
 struct iovec iov[] = {
-- 
2.25.1




[PATCH V3 1/2] net/filter: Enable the vnet_hdr_support by default

2021-11-18 Thread Zhang Chen
This patch make filters and colo-compare module support vnet_hdr by
default. And also support -device non-virtio-net(like e1000.).
Because when enabled the support will make the vnet_hdr_len field
become must-delivery part of filter transfer protocol(even 0 in use
-device e1000). It fully guarantees the compatibility for management
layer like libvirt. But it still can't avoid user manual
configuration error between different filters connected
when enable/disable vnet_hdr_support.

Signed-off-by: Zhang Chen 
---
 net/colo-compare.c| 2 +-
 net/filter-mirror.c   | 4 ++--
 net/filter-rewriter.c | 2 +-
 qemu-options.hx   | 9 +
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index b966e7e514..0232249311 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -1399,7 +1399,7 @@ static void colo_compare_init(Object *obj)
 get_max_queue_size,
 set_max_queue_size, NULL, NULL);
 
-s->vnet_hdr = false;
+s->vnet_hdr = true;
 object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
  compare_set_vnet_hdr);
 }
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index f20240cc9f..adb0c6d89a 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -406,14 +406,14 @@ static void filter_mirror_init(Object *obj)
 {
 MirrorState *s = FILTER_MIRROR(obj);
 
-s->vnet_hdr = false;
+s->vnet_hdr = true;
 }
 
 static void filter_redirector_init(Object *obj)
 {
 MirrorState *s = FILTER_REDIRECTOR(obj);
 
-s->vnet_hdr = false;
+s->vnet_hdr = true;
 }
 
 static void filter_mirror_fini(Object *obj)
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
index bf05023dc3..5698cd39d1 100644
--- a/net/filter-rewriter.c
+++ b/net/filter-rewriter.c
@@ -407,7 +407,7 @@ static void filter_rewriter_init(Object *obj)
 {
 RewriterState *s = FILTER_REWRITER(obj);
 
-s->vnet_hdr = false;
+s->vnet_hdr = true;
 s->failover_mode = FAILOVER_MODE_OFF;
 }
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 7749f59300..c40e385ede 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4967,13 +4967,13 @@ SRST
 ``-object 
filter-mirror,id=id,netdev=netdevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=][,insert=behind|before]``
 filter-mirror on netdev netdevid,mirror net packet to
 chardevchardevid, if it has the vnet\_hdr\_support flag,
-filter-mirror will mirror packet with vnet\_hdr\_len.
+filter-mirror will mirror packet with vnet\_hdr\_len(default: on).
 
 ``-object 
filter-redirector,id=id,netdev=netdevid,indev=chardevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=][,insert=behind|before]``
 filter-redirector on netdev netdevid,redirect filter's net
 packet to chardev chardevid,and redirect indev's packet to
 filter.if it has the vnet\_hdr\_support flag, filter-redirector
-will redirect packet with vnet\_hdr\_len. Create a
+will redirect packet with vnet\_hdr\_len(default: on). Create a
 filter-redirector we need to differ outdev id from indev id, id
 can not be the same. we can just use indev or outdev, but at
 least one of indev or outdev need to be specified.
@@ -4983,7 +4983,8 @@ SRST
 packet to secondary from primary to keep secondary tcp
 connection,and rewrite tcp packet to primary from secondary make
 tcp packet can be handled by client.if it has the
-vnet\_hdr\_support flag, we can parse packet with vnet header.
+vnet\_hdr\_support flag, we can parse packet with vnet
+header(default: on).
 
 usage: colo secondary: -object
 filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0 -object
@@ -5004,7 +5005,7 @@ SRST
 checkpoint and send primary packet to out\_dev. In order to
 improve efficiency, we need to put the task of comparison in
 another iothread. If it has the vnet\_hdr\_support flag,
-colo compare will send/recv packet with vnet\_hdr\_len.
+colo compare will send/recv packet with vnet\_hdr\_len(default: on).
 The compare\_timeout=@var{ms} determines the maximum time of the
 colo-compare hold the packet. The expired\_scan\_cycle=@var{ms}
 is to set the period of scanning expired primary node network packets.
-- 
2.25.1




RE: [PATCH] net/filter: Enable the vnet_hdr_support by default

2021-11-18 Thread Zhang, Chen


> -Original Message-
> From: Jason Wang 
> Sent: Friday, November 19, 2021 11:37 AM
> To: Zhang, Chen 
> Cc: qemu-dev ; Markus Armbruster
> ; Li Zhijian 
> Subject: Re: [PATCH] net/filter: Enable the vnet_hdr_support by default
> 
> On Fri, Nov 19, 2021 at 11:17 AM Jason Wang 
> wrote:
> >
> >
> > 在 2021/11/10 上午10:39, Zhang Chen 写道:
> > > This patch make filters and colo-compare module support vnet_hdr by
> > > default. And also support -device non-virtio-net(like e1000.).
> > > But it can't avoid user manual configuration error between different
> > > filters when enable/disable virtio-net-pci.
> > >
> > > Signed-off-by: Zhang Chen 
> > > ---
> >
> >
> > Applied.
> >
> > Thanks
> 
> Actually not, it breaks filter-mirror test:
> 
> 
> ERROR:../tests/qtest/test-filter-mirror.c:74:test_mirror: assertion failed
> (recv_buf == send_buf): ("" == "Hello! filter-mirror~") ERROR qtest-
> x86_64/test-filter-mirror - Bail out!
> ERROR:../tests/qtest/test-filter-mirror.c:74:test_mirror: assertion failed
> (recv_buf == send_buf): ("" == "Hello! filter-mirror~")
> ^Cmake[1]: *** [Makefile.mtest:784: run-test-96] Interrupt

Oh, This test used default way to send filter data without vnet_hdr_len.
But we changed default filter transfer protocol. I will fix it in another patch.

Thanks
Chen

> 
> Thanks
> 
> >
> >
> > >   net/colo-compare.c| 2 +-
> > >   net/filter-mirror.c   | 4 ++--
> > >   net/filter-rewriter.c | 2 +-
> > >   qemu-options.hx   | 9 +
> > >   4 files changed, 9 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/net/colo-compare.c b/net/colo-compare.c index
> > > b8876d7fd9..82d4d81710 100644
> > > --- a/net/colo-compare.c
> > > +++ b/net/colo-compare.c
> > > @@ -1397,7 +1397,7 @@ static void colo_compare_init(Object *obj)
> > >   get_max_queue_size,
> > >   set_max_queue_size, NULL, NULL);
> > >
> > > -s->vnet_hdr = false;
> > > +s->vnet_hdr = true;
> > >   object_property_add_bool(obj, "vnet_hdr_support",
> compare_get_vnet_hdr,
> > >compare_set_vnet_hdr);
> > >   }
> > > diff --git a/net/filter-mirror.c b/net/filter-mirror.c index
> > > f20240cc9f..adb0c6d89a 100644
> > > --- a/net/filter-mirror.c
> > > +++ b/net/filter-mirror.c
> > > @@ -406,14 +406,14 @@ static void filter_mirror_init(Object *obj)
> > >   {
> > >   MirrorState *s = FILTER_MIRROR(obj);
> > >
> > > -s->vnet_hdr = false;
> > > +s->vnet_hdr = true;
> > >   }
> > >
> > >   static void filter_redirector_init(Object *obj)
> > >   {
> > >   MirrorState *s = FILTER_REDIRECTOR(obj);
> > >
> > > -s->vnet_hdr = false;
> > > +s->vnet_hdr = true;
> > >   }
> > >
> > >   static void filter_mirror_fini(Object *obj) diff --git
> > > a/net/filter-rewriter.c b/net/filter-rewriter.c index
> > > bf05023dc3..5698cd39d1 100644
> > > --- a/net/filter-rewriter.c
> > > +++ b/net/filter-rewriter.c
> > > @@ -407,7 +407,7 @@ static void filter_rewriter_init(Object *obj)
> > >   {
> > >   RewriterState *s = FILTER_REWRITER(obj);
> > >
> > > -s->vnet_hdr = false;
> > > +s->vnet_hdr = true;
> > >   s->failover_mode = FAILOVER_MODE_OFF;
> > >   }
> > >
> > > diff --git a/qemu-options.hx b/qemu-options.hx index
> > > 7749f59300..c40e385ede 100644
> > > --- a/qemu-options.hx
> > > +++ b/qemu-options.hx
> > > @@ -4967,13 +4967,13 @@ SRST
> > >   ``-object filter-
> mirror,id=id,netdev=netdevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr
> _support][,position=head|tail|id=][,insert=behind|before]``
> > >   filter-mirror on netdev netdevid,mirror net packet to
> > >   chardevchardevid, if it has the vnet\_hdr\_support flag,
> > > -filter-mirror will mirror packet with vnet\_hdr\_len.
> > > +filter-mirror will mirror packet with vnet\_hdr\_len(default: 
> > > on).
> > >
> > >   ``-object filter-
> redirector,id=id,netdev=netdevid,indev=chardevid,outdev=chardevid,queu
> e=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=][,insert=behind
> |before]``
> > >   filter-redirector on netdev netdevid,redirect filter's net
> > >   packet to chardev chardevid,and redirect indev's packet to
> > >   filter.if it has the vnet\_hdr\_support flag, filter-redirector
> > > -will redirect packet with vnet\_hdr\_len. Create a
> > > +will redirect packet with vnet\_hdr\_len(default: on).
> > > + Create a
> > >   filter-redirector we need to differ outdev id from indev id, id
> > >   can not be the same. we can just use indev or outdev, but at
> > >   least one of indev or outdev need to be specified.
> > > @@ -4983,7 +4983,8 @@ SRST
> > >   packet to secondary from primary to keep secondary tcp
> > >   connection,and rewrite tcp packet to primary from secondary make
> > >   tcp packet can be handled by client.if it has the
> > > -vnet\_hdr\_support flag, we can parse packet with vnet header.
> > 

Re: [PATCH v4 13/20] target/riscv: Fix RESERVED field length in VTYPE

2021-11-18 Thread Alistair Francis
On Fri, Nov 12, 2021 at 2:06 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 52ce670cbe..b48c7c346c 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -105,7 +105,7 @@ typedef struct CPURISCVState CPURISCVState;
>  FIELD(VTYPE, VLMUL, 0, 2)
>  FIELD(VTYPE, VSEW, 2, 3)
>  FIELD(VTYPE, VEDIV, 5, 2)
> -FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
> +FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 8)
>  FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
>
>  struct CPURISCVState {
> --
> 2.25.1
>
>



Re: [PATCH v4 12/20] target/riscv: Split out the vill from vtype

2021-11-18 Thread Alistair Francis
On Fri, Nov 12, 2021 at 2:03 AM LIU Zhiwei  wrote:
>
> We need not specially process vtype when XLEN changes.
>
> Signed-off-by: LIU Zhiwei 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h   |  1 +
>  target/riscv/cpu_helper.c|  3 +--
>  target/riscv/csr.c   | 13 -
>  target/riscv/machine.c   |  5 +++--
>  target/riscv/vector_helper.c |  3 ++-
>  5 files changed, 19 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 9fba876e08..52ce670cbe 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -119,6 +119,7 @@ struct CPURISCVState {
>  target_ulong vl;
>  target_ulong vstart;
>  target_ulong vtype;
> +bool vill;
>
>  target_ulong pc;
>  target_ulong load_res;
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index a40ed6d748..9b9dc83ab9 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -78,8 +78,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
> *pc,
>  if (riscv_has_ext(env, RVV)) {
>  uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
>  bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
> -flags = FIELD_DP32(flags, TB_FLAGS, VILL,
> -FIELD_EX64(env->vtype, VTYPE, VILL));
> +flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
>  flags = FIELD_DP32(flags, TB_FLAGS, SEW,
>  FIELD_EX64(env->vtype, VTYPE, VSEW));
>  flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 6bb2d09519..8f8f170768 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -286,7 +286,18 @@ static RISCVException write_fcsr(CPURISCVState *env, int 
> csrno,
>  static RISCVException read_vtype(CPURISCVState *env, int csrno,
>   target_ulong *val)
>  {
> -*val = env->vtype;
> +uint64_t vill;
> +switch (cpu_get_xl(env)) {
> +case MXL_RV32:
> +vill = (uint32_t)env->vill << 31;
> +break;
> +case MXL_RV64:
> +vill = (uint64_t)env->vill << 63;
> +break;
> +default:
> +g_assert_not_reached();
> +}
> +*val = (target_ulong)vill | env->vtype;
>  return RISCV_EXCP_NONE;
>  }
>
> diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> index 19e982d3f0..ec7584f256 100644
> --- a/target/riscv/machine.c
> +++ b/target/riscv/machine.c
> @@ -94,8 +94,8 @@ static bool pointermasking_needed(void *opaque)
>
>  static const VMStateDescription vmstate_vector = {
>  .name = "cpu/vector",
> -.version_id = 1,
> -.minimum_version_id = 1,
> +.version_id = 2,
> +.minimum_version_id = 2,
>  .needed = vector_needed,
>  .fields = (VMStateField[]) {
>  VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
> @@ -104,6 +104,7 @@ static const VMStateDescription vmstate_vector = {
>  VMSTATE_UINTTL(env.vl, RISCVCPU),
>  VMSTATE_UINTTL(env.vstart, RISCVCPU),
>  VMSTATE_UINTTL(env.vtype, RISCVCPU),
> +VMSTATE_BOOL(env.vill, RISCVCPU),
>  VMSTATE_END_OF_LIST()
>  }
>  };
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 12c31aa4b4..b02ccefa4d 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -38,7 +38,8 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
> target_ulong s1,
>
>  if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
>  /* only set vill bit. */
> -env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
> +env->vill = 1;
> +env->vtype = 0;
>  env->vl = 0;
>  env->vstart = 0;
>  return 0;
> --
> 2.25.1
>
>



Re: [PATCH v4 11/20] target/riscv: Split pm_enabled into mask and base

2021-11-18 Thread Alistair Francis
On Fri, Nov 12, 2021 at 2:05 AM LIU Zhiwei  wrote:
>
> Use cached cur_pmmask and cur_pmbase to infer the
> current PM mode.
>
> This may decrease the TCG IR by one when pm_enabled
> is true and pm_base_enabled is false.
>
> Signed-off-by: LIU Zhiwei 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h|  3 ++-
>  target/riscv/cpu_helper.c | 25 +++--
>  target/riscv/translate.c  | 12 
>  3 files changed, 17 insertions(+), 23 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index fa5a6ba1c8..9fba876e08 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -411,7 +411,8 @@ FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
>  /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
>  FIELD(TB_FLAGS, XL, 13, 2)
>  /* If PointerMasking should be applied */
> -FIELD(TB_FLAGS, PM_ENABLED, 15, 1)
> +FIELD(TB_FLAGS, PM_MASK_ENABLED, 15, 1)
> +FIELD(TB_FLAGS, PM_BASE_ENABLED, 16, 1)
>
>  #ifdef TARGET_RISCV32
>  #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 8320f56d9f..a40ed6d748 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -108,26 +108,15 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, 
> target_ulong *pc,
>  flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
> get_field(env->mstatus_hs, MSTATUS_FS));
>  }
> -if (riscv_has_ext(env, RVJ)) {
> -int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
> -bool pm_enabled = false;
> -switch (priv) {
> -case PRV_U:
> -pm_enabled = env->mmte & U_PM_ENABLE;
> -break;
> -case PRV_S:
> -pm_enabled = env->mmte & S_PM_ENABLE;
> -break;
> -case PRV_M:
> -pm_enabled = env->mmte & M_PM_ENABLE;
> -break;
> -default:
> -g_assert_not_reached();
> -}
> -flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, pm_enabled);
> -}
>  #endif
>
> +if (env->cur_pmmask < (xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
> +flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
> +}
> +if (env->cur_pmbase != 0) {
> +flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
> +}
> +
>  flags = FIELD_DP32(flags, TB_FLAGS, XL, xl);
>
>  *pflags = flags;
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index fd75f7c4bc..10c16e759d 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -87,7 +87,8 @@ typedef struct DisasContext {
>  /* Space for 3 operands plus 1 extra for address computation. */
>  TCGv temp[4];
>  /* PointerMasking extension */
> -bool pm_enabled;
> +bool pm_mask_enabled;
> +bool pm_base_enabled;
>  } DisasContext;
>
>  static inline bool has_ext(DisasContext *ctx, uint32_t ext)
> @@ -291,12 +292,14 @@ static TCGv get_address(DisasContext *ctx, int rs1, int 
> imm)
>  TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
>
>  tcg_gen_addi_tl(addr, src1, imm);
> -if (ctx->pm_enabled) {
> +if (ctx->pm_mask_enabled) {
>  tcg_gen_and_tl(addr, addr, pm_mask);
> -tcg_gen_or_tl(addr, addr, pm_base);
>  } else if (get_xl(ctx) == MXL_RV32) {
>  tcg_gen_ext32u_tl(addr, addr);
>  }
> +if (ctx->pm_base_enabled) {
> +tcg_gen_or_tl(addr, addr, pm_base);
> +}
>  return addr;
>  }
>
> @@ -643,7 +646,8 @@ static void riscv_tr_init_disas_context(DisasContextBase 
> *dcbase, CPUState *cs)
>  ctx->cs = cs;
>  ctx->ntemp = 0;
>  memset(ctx->temp, 0, sizeof(ctx->temp));
> -ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
> +ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
> +ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
>  ctx->zero = tcg_constant_tl(0);
>  }
>
> --
> 2.25.1
>
>



Re: [PATCH v4 10/20] target/riscv: Calculate address according to XLEN

2021-11-18 Thread Alistair Francis
On Fri, Nov 12, 2021 at 1:59 AM LIU Zhiwei  wrote:
>
> Define one common function to compute a canonical address from a register
> plus offset. Merge gen_pm_adjust_address into this function.
>
> Signed-off-by: LIU Zhiwei 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/insn_trans/trans_rva.c.inc |  9 +++--
>  target/riscv/insn_trans/trans_rvd.c.inc | 19 ++---
>  target/riscv/insn_trans/trans_rvf.c.inc | 19 ++---
>  target/riscv/insn_trans/trans_rvi.c.inc | 18 ++---
>  target/riscv/translate.c| 27 -
>  5 files changed, 22 insertions(+), 70 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rva.c.inc 
> b/target/riscv/insn_trans/trans_rva.c.inc
> index 40fe132b04..1f64b8d332 100644
> --- a/target/riscv/insn_trans/trans_rva.c.inc
> +++ b/target/riscv/insn_trans/trans_rva.c.inc
> @@ -20,12 +20,11 @@
>
>  static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
>  {
> -TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
> +TCGv src1 = get_address(ctx, a->rs1, 0);
>
>  if (a->rl) {
>  tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
>  }
> -src1 = gen_pm_adjust_address(ctx, src1);
>  tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
>  if (a->aq) {
>  tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
> @@ -44,8 +43,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp 
> mop)
>  TCGLabel *l1 = gen_new_label();
>  TCGLabel *l2 = gen_new_label();
>
> -src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
> -src1 = gen_pm_adjust_address(ctx, src1);
> +src1 = get_address(ctx, a->rs1, 0);
>  tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
>
>  /*
> @@ -83,10 +81,9 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
>  MemOp mop)
>  {
>  TCGv dest = dest_gpr(ctx, a->rd);
> -TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
> +TCGv src1 = get_address(ctx, a->rs1, 0);
>  TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
>
> -src1 = gen_pm_adjust_address(ctx, src1);
>  func(dest, src1, src2, ctx->mem_idx, mop);
>
>  gen_set_gpr(ctx, a->rd, dest);
> diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
> b/target/riscv/insn_trans/trans_rvd.c.inc
> index 64fb0046f7..88a491375c 100644
> --- a/target/riscv/insn_trans/trans_rvd.c.inc
> +++ b/target/riscv/insn_trans/trans_rvd.c.inc
> @@ -25,14 +25,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
>  REQUIRE_FPU;
>  REQUIRE_EXT(ctx, RVD);
>
> -addr = get_gpr(ctx, a->rs1, EXT_NONE);
> -if (a->imm) {
> -TCGv temp = temp_new(ctx);
> -tcg_gen_addi_tl(temp, addr, a->imm);
> -addr = temp;
> -}
> -addr = gen_pm_adjust_address(ctx, addr);
> -
> +addr = get_address(ctx, a->rs1, a->imm);
>  tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
>
>  mark_fs_dirty(ctx);
> @@ -46,16 +39,8 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
>  REQUIRE_FPU;
>  REQUIRE_EXT(ctx, RVD);
>
> -addr = get_gpr(ctx, a->rs1, EXT_NONE);
> -if (a->imm) {
> -TCGv temp = temp_new(ctx);
> -tcg_gen_addi_tl(temp, addr, a->imm);
> -addr = temp;
> -}
> -addr = gen_pm_adjust_address(ctx, addr);
> -
> +addr = get_address(ctx, a->rs1, a->imm);
>  tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
> -
>  return true;
>  }
>
> diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
> b/target/riscv/insn_trans/trans_rvf.c.inc
> index b5459249c4..0aac87f7db 100644
> --- a/target/riscv/insn_trans/trans_rvf.c.inc
> +++ b/target/riscv/insn_trans/trans_rvf.c.inc
> @@ -31,14 +31,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
>  REQUIRE_FPU;
>  REQUIRE_EXT(ctx, RVF);
>
> -addr = get_gpr(ctx, a->rs1, EXT_NONE);
> -if (a->imm) {
> -TCGv temp = temp_new(ctx);
> -tcg_gen_addi_tl(temp, addr, a->imm);
> -addr = temp;
> -}
> -addr = gen_pm_adjust_address(ctx, addr);
> -
> +addr = get_address(ctx, a->rs1, a->imm);
>  dest = cpu_fpr[a->rd];
>  tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
>  gen_nanbox_s(dest, dest);
> @@ -54,16 +47,8 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
>  REQUIRE_FPU;
>  REQUIRE_EXT(ctx, RVF);
>
> -addr = get_gpr(ctx, a->rs1, EXT_NONE);
> -if (a->imm) {
> -TCGv temp = tcg_temp_new();
> -tcg_gen_addi_tl(temp, addr, a->imm);
> -addr = temp;
> -}
> -addr = gen_pm_adjust_address(ctx, addr);
> -
> +addr = get_address(ctx, a->rs1, a->imm);
>  tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
> -
>  return true;
>  }
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
> b/target/riscv/insn_trans/trans_rvi.c.inc
> index 40c81421f2..cb73a2f1ee 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ 

Re: [PATCH v4 09/20] target/riscv: Alloc tcg global for cur_pm[mask|base]

2021-11-18 Thread Alistair Francis
On Fri, Nov 12, 2021 at 2:03 AM LIU Zhiwei  wrote:
>
> Replace the array of pm_mask/pm_base with scalar variables.
> Remove the cached array value in DisasContext.
>
> Signed-off-by: LIU Zhiwei 
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/translate.c | 32 
>  1 file changed, 8 insertions(+), 24 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index a6a73ced9e..6cb74c6355 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -37,8 +37,8 @@ static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
>  static TCGv load_res;
>  static TCGv load_val;
>  /* globals for PM CSRs */
> -static TCGv pm_mask[4];
> -static TCGv pm_base[4];
> +static TCGv pm_mask;
> +static TCGv pm_base;
>
>  #include "exec/gen-icount.h"
>
> @@ -88,8 +88,6 @@ typedef struct DisasContext {
>  TCGv temp[4];
>  /* PointerMasking extension */
>  bool pm_enabled;
> -TCGv pm_mask;
> -TCGv pm_base;
>  } DisasContext;
>
>  static inline bool has_ext(DisasContext *ctx, uint32_t ext)
> @@ -297,8 +295,8 @@ static TCGv gen_pm_adjust_address(DisasContext *s, TCGv 
> src)
>  return src;
>  } else {
>  temp = temp_new(s);
> -tcg_gen_andc_tl(temp, src, s->pm_mask);
> -tcg_gen_or_tl(temp, temp, s->pm_base);
> +tcg_gen_andc_tl(temp, src, pm_mask);
> +tcg_gen_or_tl(temp, temp, pm_base);
>  return temp;
>  }
>  }
> @@ -647,10 +645,6 @@ static void riscv_tr_init_disas_context(DisasContextBase 
> *dcbase, CPUState *cs)
>  ctx->ntemp = 0;
>  memset(ctx->temp, 0, sizeof(ctx->temp));
>  ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
> -int priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
> -ctx->pm_mask = pm_mask[priv];
> -ctx->pm_base = pm_base[priv];
> -
>  ctx->zero = tcg_constant_tl(0);
>  }
>
> @@ -763,19 +757,9 @@ void riscv_translate_init(void)
>   "load_res");
>  load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
>   "load_val");
> -#ifndef CONFIG_USER_ONLY
>  /* Assign PM CSRs to tcg globals */
> -pm_mask[PRV_U] =
> -  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmmask), 
> "upmmask");
> -pm_base[PRV_U] =
> -  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmbase), 
> "upmbase");
> -pm_mask[PRV_S] =
> -  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmmask), 
> "spmmask");
> -pm_base[PRV_S] =
> -  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmbase), 
> "spmbase");
> -pm_mask[PRV_M] =
> -  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmmask), 
> "mpmmask");
> -pm_base[PRV_M] =
> -  tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmbase), 
> "mpmbase");
> -#endif
> +pm_mask = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, 
> cur_pmmask),
> + "pmmask");
> +pm_base = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, 
> cur_pmbase),
> + "pmbase");
>  }
> --
> 2.25.1
>
>



Re: [PATCH v4 08/20] target/riscv: Create current pm fields in env

2021-11-18 Thread Alistair Francis
On Fri, Nov 12, 2021 at 2:00 AM LIU Zhiwei  wrote:
>
> Signed-off-by: LIU Zhiwei 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c|  1 +
>  target/riscv/cpu.h|  4 
>  target/riscv/cpu_helper.c | 43 +++
>  target/riscv/csr.c| 19 +
>  target/riscv/machine.c| 10 +
>  5 files changed, 77 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0d2d175fa2..4f01abc989 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -393,6 +393,7 @@ static void riscv_cpu_reset(DeviceState *dev)
>  /* mmte is supposed to have pm.current hardwired to 1 */
>  env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
>  #endif
> +riscv_cpu_update_mask(env);
>  cs->exception_index = RISCV_EXCP_NONE;
>  env->load_res = -1;
>  set_default_nan_mode(1, >fp_status);
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 8befff0166..fa5a6ba1c8 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -250,6 +250,8 @@ struct CPURISCVState {
>  target_ulong upmmask;
>  target_ulong upmbase;
>  #endif
> +target_ulong cur_pmmask;
> +target_ulong cur_pmbase;
>
>  float_status fp_status;
>
> @@ -441,6 +443,8 @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, 
> target_ulong vtype)
>  void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
>target_ulong *cs_base, uint32_t *pflags);
>
> +void riscv_cpu_update_mask(CPURISCVState *env);
> +
>  RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
> target_ulong *ret_value,
> target_ulong new_value, target_ulong write_mask);
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index 79aba9c880..8320f56d9f 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -133,6 +133,48 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, 
> target_ulong *pc,
>  *pflags = flags;
>  }
>
> +void riscv_cpu_update_mask(CPURISCVState *env)
> +{
> +target_ulong mask = -1, base = 0;
> +/*
> + * TODO: Current RVJ spec does not specify
> + * how the extension interacts with XLEN.
> + */
> +#ifndef CONFIG_USER_ONLY
> +if (riscv_has_ext(env, RVJ)) {
> +switch (env->priv) {
> +case PRV_M:
> +if (env->mmte & M_PM_ENABLE) {
> +mask = env->mpmmask;
> +base = env->mpmbase;
> +}
> +break;
> +case PRV_S:
> +if (env->mmte & S_PM_ENABLE) {
> +mask = env->spmmask;
> +base = env->spmbase;
> +}
> +break;
> +case PRV_U:
> +if (env->mmte & U_PM_ENABLE) {
> +mask = env->upmmask;
> +base = env->upmbase;
> +}
> +break;
> +default:
> +g_assert_not_reached();
> +}
> +}
> +#endif
> +if (cpu_get_xl(env) == MXL_RV32) {
> +env->cur_pmmask = mask & UINT32_MAX;
> +env->cur_pmbase = base & UINT32_MAX;
> +} else {
> +env->cur_pmmask = mask;
> +env->cur_pmbase = base;
> +}
> +}
> +
>  #ifndef CONFIG_USER_ONLY
>  static int riscv_cpu_local_irq_pending(CPURISCVState *env)
>  {
> @@ -331,6 +373,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
> newpriv)
>  }
>  /* tlb_flush is unnecessary as mode is contained in mmu_idx */
>  env->priv = newpriv;
> +riscv_cpu_update_mask(env);
>
>  /*
>   * Clear the load reservation - otherwise a reservation placed in one
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 74c0b788fd..6bb2d09519 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1496,6 +1496,7 @@ static RISCVException write_mmte(CPURISCVState *env, 
> int csrno,
>  /* hardwiring pm.instruction bit to 0, since it's not supported yet */
>  wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
>  env->mmte = wpri_val | PM_EXT_DIRTY;
> +riscv_cpu_update_mask(env);
>
>  /* Set XS and SD bits, since PM CSRs are dirty */
>  mstatus = env->mstatus | MSTATUS_XS;
> @@ -1571,6 +1572,9 @@ static RISCVException write_mpmmask(CPURISCVState *env, 
> int csrno,
>  uint64_t mstatus;
>
>  env->mpmmask = val;
> +if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
> +env->cur_pmmask = val;
> +}
>  env->mmte |= PM_EXT_DIRTY;
>
>  /* Set XS and SD bits, since PM CSRs are dirty */
> @@ -1596,6 +1600,9 @@ static RISCVException write_spmmask(CPURISCVState *env, 
> int csrno,
>  return RISCV_EXCP_NONE;
>  }
>  env->spmmask = val;
> +if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
> +env->cur_pmmask = val;
> +}
>  env->mmte |= PM_EXT_DIRTY;
>
>  /* Set XS and SD bits, since PM CSRs are dirty */
> @@ -1621,6 +1628,9 @@ 

[PULL 3/3] net/colo-compare.c: Fix incorrect return when input wrong size

2021-11-18 Thread Jason Wang
From: Zhang Chen 

Signed-off-by: Zhang Chen 
Signed-off-by: Jason Wang 
---
 net/colo-compare.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 1225f40..b966e7e 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -807,7 +807,7 @@ static int compare_chr_send(CompareState *s,
 }
 
 if (!size) {
-return 0;
+return -1;
 }
 
 entry = g_slice_new(SendEntry);
-- 
2.7.4




[PULL 1/3] net: vmxnet3: validate configuration values during activate (CVE-2021-20203)

2021-11-18 Thread Jason Wang
From: Prasad J Pandit 

While activating device in vmxnet3_acticate_device(), it does not
validate guest supplied configuration values against predefined
minimum - maximum limits. This may lead to integer overflow or
OOB access issues. Add checks to avoid it.

Fixes: CVE-2021-20203
Buglink: https://bugs.launchpad.net/qemu/+bug/1913873
Reported-by: Gaoning Pan 
Signed-off-by: Prasad J Pandit 
Signed-off-by: Jason Wang 
---
 hw/net/vmxnet3.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 41f796a..f65af4e 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -1441,6 +1441,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 vmxnet3_setup_rx_filtering(s);
 /* Cache fields from shared memory */
 s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
+assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu < VMXNET3_MAX_MTU);
 VMW_CFPRN("MTU is %u", s->mtu);
 
 s->max_rx_frags =
@@ -1486,6 +1487,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 /* Read rings memory locations for TX queues */
 pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.txRingBasePA);
 size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.txRingSize);
+if (size > VMXNET3_TX_RING_MAX_SIZE) {
+size = VMXNET3_TX_RING_MAX_SIZE;
+}
 
 vmxnet3_ring_init(d, >txq_descr[i].tx_ring, pa, size,
   sizeof(struct Vmxnet3_TxDesc), false);
@@ -1496,6 +1500,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 /* TXC ring */
 pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.compRingBasePA);
 size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.compRingSize);
+if (size > VMXNET3_TC_RING_MAX_SIZE) {
+size = VMXNET3_TC_RING_MAX_SIZE;
+}
 vmxnet3_ring_init(d, >txq_descr[i].comp_ring, pa, size,
   sizeof(struct Vmxnet3_TxCompDesc), true);
 VMXNET3_RING_DUMP(VMW_CFPRN, "TXC", i, >txq_descr[i].comp_ring);
@@ -1537,6 +1544,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 /* RX rings */
 pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.rxRingBasePA[j]);
 size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.rxRingSize[j]);
+if (size > VMXNET3_RX_RING_MAX_SIZE) {
+size = VMXNET3_RX_RING_MAX_SIZE;
+}
 vmxnet3_ring_init(d, >rxq_descr[i].rx_ring[j], pa, size,
   sizeof(struct Vmxnet3_RxDesc), false);
 VMW_CFPRN("RX queue %d:%d: Base: %" PRIx64 ", Size: %d",
@@ -1546,6 +1556,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 /* RXC ring */
 pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.compRingBasePA);
 size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.compRingSize);
+if (size > VMXNET3_RC_RING_MAX_SIZE) {
+size = VMXNET3_RC_RING_MAX_SIZE;
+}
 vmxnet3_ring_init(d, >rxq_descr[i].comp_ring, pa, size,
   sizeof(struct Vmxnet3_RxCompDesc), true);
 VMW_CFPRN("RXC queue %d: Base: %" PRIx64 ", Size: %d", i, pa, size);
-- 
2.7.4




[PULL 0/3] Net patches

2021-11-18 Thread Jason Wang
The following changes since commit 44a3aa0608f01274418487b655d42467c1d8334e:

  Merge tag 'sev-hashes-pull-request' of https://gitlab.com/berrange/qemu into 
staging (2021-11-18 15:06:05 +0100)

are available in the git repository at:

  https://github.com/jasowang/qemu.git tags/net-pull-request

for you to fetch changes up to 0656fbc7ddccdade1709742a9b56ae07dd3c280a:

  net/colo-compare.c: Fix incorrect return when input wrong size (2021-11-19 
11:44:22 +0800)




Prasad J Pandit (1):
  net: vmxnet3: validate configuration values during activate 
(CVE-2021-20203)

Zhang Chen (2):
  net/colo-compare.c: Fix ACK track reverse issue
  net/colo-compare.c: Fix incorrect return when input wrong size

 hw/net/vmxnet3.c   | 13 +
 net/colo-compare.c |  8 +---
 2 files changed, 18 insertions(+), 3 deletions(-)





[PULL 2/3] net/colo-compare.c: Fix ACK track reverse issue

2021-11-18 Thread Jason Wang
From: Zhang Chen 

The TCP protocol ACK maybe bigger than uint32_t MAX.
At this time, the ACK will reverse to 0. This patch
fix the max_ack and min_ack track issue.

Signed-off-by: Zhang Chen 
Signed-off-by: Jason Wang 
---
 net/colo-compare.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index b8876d7..1225f40 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -209,7 +209,8 @@ static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
 
 pkt->tcp_seq = ntohl(tcphd->th_seq);
 pkt->tcp_ack = ntohl(tcphd->th_ack);
-*max_ack = *max_ack > pkt->tcp_ack ? *max_ack : pkt->tcp_ack;
+/* Need to consider ACK will bigger than uint32_t MAX */
+*max_ack = pkt->tcp_ack - *max_ack > 0 ? pkt->tcp_ack : *max_ack;
 pkt->header_size = pkt->transport_header - (uint8_t *)pkt->data
+ (tcphd->th_off << 2);
 pkt->payload_size = pkt->size - pkt->header_size;
@@ -413,7 +414,8 @@ static void colo_compare_tcp(CompareState *s, Connection 
*conn)
  * can ensure that the packet's payload is acknowledged by
  * primary and secondary.
 */
-uint32_t min_ack = conn->pack > conn->sack ? conn->sack : conn->pack;
+uint32_t min_ack = conn->pack - conn->sack > 0 ?
+   conn->sack : conn->pack;
 
 pri:
 if (g_queue_is_empty(>primary_list)) {
-- 
2.7.4




Re: [PATCH] net/filter: Enable the vnet_hdr_support by default

2021-11-18 Thread Jason Wang
On Fri, Nov 19, 2021 at 11:17 AM Jason Wang  wrote:
>
>
> 在 2021/11/10 上午10:39, Zhang Chen 写道:
> > This patch make filters and colo-compare module support vnet_hdr by
> > default. And also support -device non-virtio-net(like e1000.).
> > But it can't avoid user manual configuration error between
> > different filters when enable/disable virtio-net-pci.
> >
> > Signed-off-by: Zhang Chen 
> > ---
>
>
> Applied.
>
> Thanks

Actually not, it breaks filter-mirror test:


ERROR:../tests/qtest/test-filter-mirror.c:74:test_mirror: assertion
failed (recv_buf == send_buf): ("" == "Hello! filter-mirror~")
ERROR qtest-x86_64/test-filter-mirror - Bail out!
ERROR:../tests/qtest/test-filter-mirror.c:74:test_mirror: assertion
failed (recv_buf == send_buf): ("" == "Hello! filter-mirror~")
^Cmake[1]: *** [Makefile.mtest:784: run-test-96] Interrupt

Thanks

>
>
> >   net/colo-compare.c| 2 +-
> >   net/filter-mirror.c   | 4 ++--
> >   net/filter-rewriter.c | 2 +-
> >   qemu-options.hx   | 9 +
> >   4 files changed, 9 insertions(+), 8 deletions(-)
> >
> > diff --git a/net/colo-compare.c b/net/colo-compare.c
> > index b8876d7fd9..82d4d81710 100644
> > --- a/net/colo-compare.c
> > +++ b/net/colo-compare.c
> > @@ -1397,7 +1397,7 @@ static void colo_compare_init(Object *obj)
> >   get_max_queue_size,
> >   set_max_queue_size, NULL, NULL);
> >
> > -s->vnet_hdr = false;
> > +s->vnet_hdr = true;
> >   object_property_add_bool(obj, "vnet_hdr_support", 
> > compare_get_vnet_hdr,
> >compare_set_vnet_hdr);
> >   }
> > diff --git a/net/filter-mirror.c b/net/filter-mirror.c
> > index f20240cc9f..adb0c6d89a 100644
> > --- a/net/filter-mirror.c
> > +++ b/net/filter-mirror.c
> > @@ -406,14 +406,14 @@ static void filter_mirror_init(Object *obj)
> >   {
> >   MirrorState *s = FILTER_MIRROR(obj);
> >
> > -s->vnet_hdr = false;
> > +s->vnet_hdr = true;
> >   }
> >
> >   static void filter_redirector_init(Object *obj)
> >   {
> >   MirrorState *s = FILTER_REDIRECTOR(obj);
> >
> > -s->vnet_hdr = false;
> > +s->vnet_hdr = true;
> >   }
> >
> >   static void filter_mirror_fini(Object *obj)
> > diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
> > index bf05023dc3..5698cd39d1 100644
> > --- a/net/filter-rewriter.c
> > +++ b/net/filter-rewriter.c
> > @@ -407,7 +407,7 @@ static void filter_rewriter_init(Object *obj)
> >   {
> >   RewriterState *s = FILTER_REWRITER(obj);
> >
> > -s->vnet_hdr = false;
> > +s->vnet_hdr = true;
> >   s->failover_mode = FAILOVER_MODE_OFF;
> >   }
> >
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 7749f59300..c40e385ede 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -4967,13 +4967,13 @@ SRST
> >   ``-object 
> > filter-mirror,id=id,netdev=netdevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=][,insert=behind|before]``
> >   filter-mirror on netdev netdevid,mirror net packet to
> >   chardevchardevid, if it has the vnet\_hdr\_support flag,
> > -filter-mirror will mirror packet with vnet\_hdr\_len.
> > +filter-mirror will mirror packet with vnet\_hdr\_len(default: on).
> >
> >   ``-object 
> > filter-redirector,id=id,netdev=netdevid,indev=chardevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=][,insert=behind|before]``
> >   filter-redirector on netdev netdevid,redirect filter's net
> >   packet to chardev chardevid,and redirect indev's packet to
> >   filter.if it has the vnet\_hdr\_support flag, filter-redirector
> > -will redirect packet with vnet\_hdr\_len. Create a
> > +will redirect packet with vnet\_hdr\_len(default: on). Create a
> >   filter-redirector we need to differ outdev id from indev id, id
> >   can not be the same. we can just use indev or outdev, but at
> >   least one of indev or outdev need to be specified.
> > @@ -4983,7 +4983,8 @@ SRST
> >   packet to secondary from primary to keep secondary tcp
> >   connection,and rewrite tcp packet to primary from secondary make
> >   tcp packet can be handled by client.if it has the
> > -vnet\_hdr\_support flag, we can parse packet with vnet header.
> > +vnet\_hdr\_support flag, we can parse packet with vnet
> > +header(default: on).
> >
> >   usage: colo secondary: -object
> >   filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0 -object
> > @@ -5004,7 +5005,7 @@ SRST
> >   checkpoint and send primary packet to out\_dev. In order to
> >   improve efficiency, we need to put the task of comparison in
> >   another iothread. If it has the vnet\_hdr\_support flag,
> > -colo compare will send/recv packet with vnet\_hdr\_len.
> > +colo compare will send/recv packet with vnet\_hdr\_len(default: 
> > on).
> >   The 

Re: [PATCH-for-6.2] net: vmxnet3: validate configuration values during activate (CVE-2021-20203)

2021-11-18 Thread Jason Wang



在 2021/11/18 下午8:32, Philippe Mathieu-Daudé 写道:

ping?



Applied.

Thanks




On 10/18/21 11:09, P J P wrote:

On Monday, 18 October, 2021, 12:20:55 pm IST, Thomas Huth  
wrote:
On 30/01/2021 14.16, P J P wrote:

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index eff299f629..4a910ca971 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -1420,6 +1420,7 @@ static void vmxnet3_activate_device(VMXNET3State *s)
       vmxnet3_setup_rx_filtering(s);
       /* Cache fields from shared memory */
       s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
+    assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu < VMXNET3_MAX_MTU);
       VMW_CFPRN("MTU is %u", s->mtu);
   
       s->max_rx_frags =

@@ -1473,6 +1474,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
           /* Read rings memory locations for TX queues */
           pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.txRingBasePA);
           size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.txRingSize);
+        if (size > VMXNET3_TX_RING_MAX_SIZE) {
+            size = VMXNET3_TX_RING_MAX_SIZE;
+        }
   
           vmxnet3_ring_init(d, >txq_descr[i].tx_ring, pa, size,

                             sizeof(struct Vmxnet3_TxDesc), false);
@@ -1483,6 +1487,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
           /* TXC ring */
           pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, 
conf.compRingBasePA);
           size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, 
conf.compRingSize);
+        if (size > VMXNET3_TC_RING_MAX_SIZE) {
+            size = VMXNET3_TC_RING_MAX_SIZE;
+        }
           vmxnet3_ring_init(d, >txq_descr[i].comp_ring, pa, size,
                             sizeof(struct Vmxnet3_TxCompDesc), true);
           VMXNET3_RING_DUMP(VMW_CFPRN, "TXC", i, >txq_descr[i].comp_ring);
@@ -1524,6 +1531,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
               /* RX rings */
               pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, 
conf.rxRingBasePA[j]);
               size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, 
conf.rxRingSize[j]);
+            if (size > VMXNET3_RX_RING_MAX_SIZE) {
+                size = VMXNET3_RX_RING_MAX_SIZE;
+            }
               vmxnet3_ring_init(d, >rxq_descr[i].rx_ring[j], pa, size,
                                 sizeof(struct Vmxnet3_RxDesc), false);
               VMW_CFPRN("RX queue %d:%d: Base: %" PRIx64 ", Size: %d",
@@ -1533,6 +1543,9 @@ static void vmxnet3_activate_device(VMXNET3State *s)
           /* RXC ring */
           pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.compRingBasePA);
           size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.compRingSize);
+        if (size > VMXNET3_RC_RING_MAX_SIZE) {
+            size = VMXNET3_RC_RING_MAX_SIZE;
+        }
           vmxnet3_ring_init(d, >rxq_descr[i].comp_ring, pa, size,
                             sizeof(struct Vmxnet3_RxCompDesc), true);
           VMW_CFPRN("RXC queue %d: Base: %" PRIx64 ", Size: %d", i, pa, size);



Ping!

According to
https://gitlab.com/qemu-project/qemu/-/issues/308#note_705736713 this is
still an issue...

Patch looks fine to me ... maybe just add some
qemu_log_mask(LOG_GUEST_ERROR, ...) statements before correcting the values?


* Oops! Not sure how I missed it, thought it was pulled upstream.
   Will send a revised patch.


Thank you.
---
   - P J P






Re: Follow-up on the CXL discussion at OFTC

2021-11-18 Thread Ben Widawsky
On 21-11-19 02:29:51, Shreyas Shah wrote:
> Hi Ben
> 
> Are you planning to add the CXL2.0 switch inside QEMU or already added in one 
> of the version? 
>  

>From me, there are no plans for QEMU anything until/unless upstream thinks it
will merge the existing patches, or provide feedback as to what it would take to
get them merged. If upstream doesn't see a point in these patches, then I really
don't see much value in continuing to further them. Once hardware comes out, the
value proposition is certainly less.

Having said that, once I get the port/region patches merged for the Linux
driver, I do intend to go back and try to implement a basic switch so that we
can test those flows.

I admit, I'm curious why you're interested in switches.

> Regards,
> Shreyas
> 
> -Original Message-
> From: Ben Widawsky  
> Sent: Thursday, November 18, 2021 5:48 PM
> To: Shreyas Shah 
> Cc: Saransh Gupta1 ; Jonathan Cameron 
> ; linux-...@vger.kernel.org; 
> qemu-devel@nongnu.org
> Subject: Re: Follow-up on the CXL discussion at OFTC
> 
> On 21-11-18 22:52:56, Shreyas Shah wrote:
> > Hello Folks,
> > 
> > Any plan to add CXL2.0 switch ports in QEMU? 
> 
> What's your definition of plan?
> 
> > 
> > Regards,
> > Shreyas
> 
> [snip]



Re: [PATCH 2/2] net/colo-compare.c: Fix incorrect return when input wrong size

2021-11-18 Thread Jason Wang



在 2021/11/18 上午11:20, Zhang Chen 写道:

Signed-off-by: Zhang Chen 
---



Applied.

Thanks



  net/colo-compare.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 1225f40e41..b966e7e514 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -807,7 +807,7 @@ static int compare_chr_send(CompareState *s,
  }
  
  if (!size) {

-return 0;
+return -1;
  }
  
  entry = g_slice_new(SendEntry);





Re: [PATCH 1/2] net/colo-compare.c: Fix ACK track reverse issue

2021-11-18 Thread Jason Wang



在 2021/11/18 上午11:20, Zhang Chen 写道:

The TCP protocol ACK maybe bigger than uint32_t MAX.
At this time, the ACK will reverse to 0. This patch
fix the max_ack and min_ack track issue.

Signed-off-by: Zhang Chen 
---



Applied.

Thanks



  net/colo-compare.c | 6 --
  1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index b8876d7fd9..1225f40e41 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -209,7 +209,8 @@ static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
  
  pkt->tcp_seq = ntohl(tcphd->th_seq);

  pkt->tcp_ack = ntohl(tcphd->th_ack);
-*max_ack = *max_ack > pkt->tcp_ack ? *max_ack : pkt->tcp_ack;
+/* Need to consider ACK will bigger than uint32_t MAX */
+*max_ack = pkt->tcp_ack - *max_ack > 0 ? pkt->tcp_ack : *max_ack;
  pkt->header_size = pkt->transport_header - (uint8_t *)pkt->data
 + (tcphd->th_off << 2);
  pkt->payload_size = pkt->size - pkt->header_size;
@@ -413,7 +414,8 @@ static void colo_compare_tcp(CompareState *s, Connection 
*conn)
   * can ensure that the packet's payload is acknowledged by
   * primary and secondary.
  */
-uint32_t min_ack = conn->pack > conn->sack ? conn->sack : conn->pack;
+uint32_t min_ack = conn->pack - conn->sack > 0 ?
+   conn->sack : conn->pack;
  
  pri:

  if (g_queue_is_empty(>primary_list)) {





Re: [PATCH] net/filter: Enable the vnet_hdr_support by default

2021-11-18 Thread Jason Wang



在 2021/11/10 上午10:39, Zhang Chen 写道:

This patch make filters and colo-compare module support vnet_hdr by
default. And also support -device non-virtio-net(like e1000.).
But it can't avoid user manual configuration error between
different filters when enable/disable virtio-net-pci.

Signed-off-by: Zhang Chen 
---



Applied.

Thanks



  net/colo-compare.c| 2 +-
  net/filter-mirror.c   | 4 ++--
  net/filter-rewriter.c | 2 +-
  qemu-options.hx   | 9 +
  4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index b8876d7fd9..82d4d81710 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -1397,7 +1397,7 @@ static void colo_compare_init(Object *obj)
  get_max_queue_size,
  set_max_queue_size, NULL, NULL);
  
-s->vnet_hdr = false;

+s->vnet_hdr = true;
  object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
   compare_set_vnet_hdr);
  }
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index f20240cc9f..adb0c6d89a 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -406,14 +406,14 @@ static void filter_mirror_init(Object *obj)
  {
  MirrorState *s = FILTER_MIRROR(obj);
  
-s->vnet_hdr = false;

+s->vnet_hdr = true;
  }
  
  static void filter_redirector_init(Object *obj)

  {
  MirrorState *s = FILTER_REDIRECTOR(obj);
  
-s->vnet_hdr = false;

+s->vnet_hdr = true;
  }
  
  static void filter_mirror_fini(Object *obj)

diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
index bf05023dc3..5698cd39d1 100644
--- a/net/filter-rewriter.c
+++ b/net/filter-rewriter.c
@@ -407,7 +407,7 @@ static void filter_rewriter_init(Object *obj)
  {
  RewriterState *s = FILTER_REWRITER(obj);
  
-s->vnet_hdr = false;

+s->vnet_hdr = true;
  s->failover_mode = FAILOVER_MODE_OFF;
  }
  
diff --git a/qemu-options.hx b/qemu-options.hx

index 7749f59300..c40e385ede 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4967,13 +4967,13 @@ SRST
  ``-object 
filter-mirror,id=id,netdev=netdevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=][,insert=behind|before]``
  filter-mirror on netdev netdevid,mirror net packet to
  chardevchardevid, if it has the vnet\_hdr\_support flag,
-filter-mirror will mirror packet with vnet\_hdr\_len.
+filter-mirror will mirror packet with vnet\_hdr\_len(default: on).
  
  ``-object filter-redirector,id=id,netdev=netdevid,indev=chardevid,outdev=chardevid,queue=all|rx|tx[,vnet_hdr_support][,position=head|tail|id=][,insert=behind|before]``

  filter-redirector on netdev netdevid,redirect filter's net
  packet to chardev chardevid,and redirect indev's packet to
  filter.if it has the vnet\_hdr\_support flag, filter-redirector
-will redirect packet with vnet\_hdr\_len. Create a
+will redirect packet with vnet\_hdr\_len(default: on). Create a
  filter-redirector we need to differ outdev id from indev id, id
  can not be the same. we can just use indev or outdev, but at
  least one of indev or outdev need to be specified.
@@ -4983,7 +4983,8 @@ SRST
  packet to secondary from primary to keep secondary tcp
  connection,and rewrite tcp packet to primary from secondary make
  tcp packet can be handled by client.if it has the
-vnet\_hdr\_support flag, we can parse packet with vnet header.
+vnet\_hdr\_support flag, we can parse packet with vnet
+header(default: on).
  
  usage: colo secondary: -object

  filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0 -object
@@ -5004,7 +5005,7 @@ SRST
  checkpoint and send primary packet to out\_dev. In order to
  improve efficiency, we need to put the task of comparison in
  another iothread. If it has the vnet\_hdr\_support flag,
-colo compare will send/recv packet with vnet\_hdr\_len.
+colo compare will send/recv packet with vnet\_hdr\_len(default: on).
  The compare\_timeout=@var{ms} determines the maximum time of the
  colo-compare hold the packet. The expired\_scan\_cycle=@var{ms}
  is to set the period of scanning expired primary node network packets.





Re: [PATCH v4 00/25] block layer: split block APIs in global state and I/O

2021-11-18 Thread Paolo Bonzini
El jue., 18 nov. 2021 16:31, Hanna Reitz  escribió:

> On 18.11.21 14:50, Paolo Bonzini wrote:
> > On 11/15/21 17:03, Hanna Reitz wrote:
> >>
> >> I only really see four solutions for this:
> >> (1) We somehow make the amend job run in the main context under the
> >> BQL and have it prevent all concurrent I/O access (seems bad)
> >> (2) We can make the permission functions part of the I/O path (seems
> >> wrong and probably impossible?)
> >> (3) We can drop the permissions update and permanently require the
> >> permissions that we need when updating keys (I think this might break
> >> existing use cases)
> >> (4) We can acquire the BQL around the permission update call and
> >> perhaps that works?
> >>
> >> I don’t know how (4) would work but it’s basically the only
> >> reasonable solution I can come up with.  Would this be a way to call
> >> a BQL function from an I/O function?
> >
> > I think that would deadlock:
> >
> > mainI/O thread
> > -
> > start bdrv_co_amend
> > take BQL
> > bdrv_drain
> > ... hangs ...
>
> :/
>
> Is there really nothing we can do?  Forgive me if I’m talking complete
> nonsense here (because frankly I don’t even really know what a bottom
> half is exactly), but can’t we schedule some coroutine in the main
> thread to do the perm notifications and wait for them in the I/O thread?
>

I think you still get a deadlock, just one with a longer chain. You still
have a cycle of things depending on each other, but one of them is now the
I/O thread waiting for the bottom half.

Hmm...  Perhaps.  We would need to undo the permission change when the
> job finishes, though, i.e. in JobDriver.prepare() or JobDriver.clean().
> Doing the change in qmp_x_blockdev_amend() would be asymmetric then, so
> we’d probably want a new JobDriver method that runs in the main thread
> before .run() is invoked. (Unfortunately, “.prepare()” is now taken
> already...)
>

Ok at least it's feasible.

Doesn’t solve the FUSE problem, but there we could try to just take the
> RESIZE permission permanently and if that fails, we just don’t allow
> truncates for that export.  Not nice, but should work for common cases.
>

Yeah definitely not nice. Probably permissions could be protected by their
own mutex, even a global one like the one we have for jobs. For now I
suggest just ignoring the problem and adding a comment, since it's not
really something that didn't exist.

Paolo


Re: [PATCH v5 3/6] net/vmnet: implement shared mode (vmnet-shared)

2021-11-18 Thread Jason Wang
On Fri, Nov 19, 2021 at 1:12 AM Vladislav Yaroshchuk
 wrote:
>
>
>
> пн, 15 нояб. 2021 г. в 07:47, Jason Wang :
>>
>> On Fri, Nov 12, 2021 at 5:14 PM Vladislav Yaroshchuk
>>  wrote:
>> >
>> > Signed-off-by: Phillip Tennen 
>> > Signed-off-by: Vladislav Yaroshchuk 
>> > ---
>>
>> Commit log please.
>>
>>
>
> Sorry, I don't understand what you mean here.
> What is the 'commit log'?

I meant the change log to describe the changes.

>
>>
>> >  net/vmnet-common.m | 305 +
>> >  net/vmnet-shared.c |  75 ++-
>> >  net/vmnet_int.h|  23 
>> >  3 files changed, 399 insertions(+), 4 deletions(-)
>> >
>> > diff --git a/net/vmnet-common.m b/net/vmnet-common.m
>> > index 532d152840..b058e1b846 100644
>> > --- a/net/vmnet-common.m
>> > +++ b/net/vmnet-common.m
>> > @@ -10,6 +10,8 @@
>> >   */
>> >
>> >  #include "qemu/osdep.h"
>> > +#include "qemu/main-loop.h"
>> > +#include "qemu/log.h"
>> >  #include "qapi/qapi-types-net.h"
>> >  #include "vmnet_int.h"
>> >  #include "clients.h"
>> > @@ -17,4 +19,307 @@
>> >  #include "qapi/error.h"
>> >
>> >  #include 
>> > +#include 
>> >
>> > +#ifdef DEBUG
>> > +#define D(x) x
>> > +#define D_LOG(...) qemu_log(__VA_ARGS__)
>> > +#else
>> > +#define D(x) do { } while (0)
>> > +#define D_LOG(...) do { } while (0)
>> > +#endif
>> > +
>> > +typedef struct vmpktdesc vmpktdesc_t;
>> > +typedef struct iovec iovec_t;
>> > +
>> > +static void vmnet_set_send_enabled(VmnetCommonState *s, bool enable)
>> > +{
>> > +s->send_enabled = enable;
>>
>> Is there a way to disable the event when enable is false?
>>
>
> It seems there's no way except setting/unsetting
> the callback via `vmnet_interface_set_event_callback`.
> I decided to drop packages using `s->send_enabled`
> without dealing with the callback.

ok.

>
>> > +}
>> > +
>> > +
>> > +static void vmnet_send_completed(NetClientState *nc, ssize_t len)
>> > +{
>> > +VmnetCommonState *s = DO_UPCAST(VmnetCommonState, nc, nc);
>> > +vmnet_set_send_enabled(s, true);
>> > +}
>> > +
>> > +
>> > +static void vmnet_send(NetClientState *nc,
>> > +   interface_event_t event_id,
>> > +   xpc_object_t event)
>> > +{
>> > +assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
>> > +
>> > +VmnetCommonState *s;
>> > +uint64_t packets_available;
>> > +
>> > +struct iovec *iov;
>> > +struct vmpktdesc *packets;
>> > +int pkt_cnt;
>> > +int i;
>> > +
>> > +vmnet_return_t if_status;
>> > +ssize_t size;
>> > +
>> > +s = DO_UPCAST(VmnetCommonState, nc, nc);
>> > +
>> > +packets_available = xpc_dictionary_get_uint64(
>> > +event,
>> > +vmnet_estimated_packets_available_key
>> > +);
>> > +
>> > +pkt_cnt = (packets_available < VMNET_PACKETS_LIMIT) ?
>> > +  packets_available :
>> > +  VMNET_PACKETS_LIMIT;
>> > +
>> > +
>> > +iov = s->iov_buf;
>> > +packets = s->packets_buf;
>> > +
>> > +for (i = 0; i < pkt_cnt; ++i) {
>> > +packets[i].vm_pkt_size = s->max_packet_size;
>> > +packets[i].vm_pkt_iovcnt = 1;
>> > +packets[i].vm_flags = 0;
>> > +}
>> > +
>> > +if_status = vmnet_read(s->vmnet_if, packets, _cnt);
>> > +if (if_status != VMNET_SUCCESS) {
>> > +error_printf("vmnet: read failed: %s\n",
>> > + vmnet_status_map_str(if_status));
>> > +}
>> > +qemu_mutex_lock_iothread();
>> > +for (i = 0; i < pkt_cnt; ++i) {
>> > +size = qemu_send_packet_async(nc,
>> > +  iov[i].iov_base,
>> > +  packets[i].vm_pkt_size,
>> > +  vmnet_send_completed);
>> > +if (size == 0) {
>> > +vmnet_set_send_enabled(s, false);
>> > +} else if (size < 0) {
>> > +break;
>> > +}
>> > +}
>> > +qemu_mutex_unlock_iothread();
>> > +
>> > +}
>> > +
>> > +
>> > +static void vmnet_register_event_callback(VmnetCommonState *s)
>> > +{
>> > +dispatch_queue_t avail_pkt_q = dispatch_queue_create(
>> > +"org.qemu.vmnet.if_queue",
>> > +DISPATCH_QUEUE_SERIAL
>> > +);
>> > +
>> > +vmnet_interface_set_event_callback(
>> > +s->vmnet_if,
>> > +VMNET_INTERFACE_PACKETS_AVAILABLE,
>> > +avail_pkt_q,
>> > +^(interface_event_t event_id, xpc_object_t event) {
>> > +  if (s->send_enabled) {
>> > +  vmnet_send(>nc, event_id, event);
>> > +  }
>> > +});
>> > +}
>> > +
>> > +
>> > +static void vmnet_bufs_init(VmnetCommonState *s)
>> > +{
>> > +int i;
>> > +struct vmpktdesc *packets;
>> > +struct iovec *iov;
>> > +
>> > +packets = s->packets_buf;
>> > +iov = s->iov_buf;
>> > +
>> > +for (i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
>> > +iov[i].iov_len = s->max_packet_size;
>> > +iov[i].iov_base = g_malloc0(iov[i].iov_len);
>> > +

Re: [PATCH v5 0/6] Add vmnet.framework based network backend

2021-11-18 Thread Jason Wang
On Fri, Nov 19, 2021 at 1:42 AM Vladislav Yaroshchuk
 wrote:
>
>
>
> ср, 17 нояб. 2021 г. в 09:10, Jason Wang :
>>
>> On Tue, Nov 16, 2021 at 11:30 PM Vladislav Yaroshchuk
>>  wrote:
>> >
>> >
>> >
>> > вт, 16 нояб. 2021 г. в 10:23, Jason Wang :
>> >>
>> >> On Mon, Nov 15, 2021 at 6:45 PM Vladislav Yaroshchuk
>> >>  wrote:
>> >> >
>> >> >
>> >> >
>> >> > пн, 15 нояб. 2021 г. в 07:53, Jason Wang :
>> >> >>
>> >> >> On Fri, Nov 12, 2021 at 5:14 PM Vladislav Yaroshchuk
>> >> >>  wrote:
>> >> >> >
>> >> >> > macOS provides networking API for VMs called 'vmnet.framework':
>> >> >> > https://developer.apple.com/documentation/vmnet
>> >> >> >
>> >> >> > We can provide its support as the new QEMU network backends which
>> >> >> > represent three different vmnet.framework interface usage modes:
>> >> >> >
>> >> >> >   * `vmnet-shared`:
>> >> >> > allows the guest to communicate with other guests in shared mode 
>> >> >> > and
>> >> >> > also with external network (Internet) via NAT. Has 
>> >> >> > (macOS-provided)
>> >> >> > DHCP server; subnet mask and IP range can be configured;
>> >> >> >
>> >> >> >   * `vmnet-host`:
>> >> >> > allows the guest to communicate with other guests in host mode.
>> >> >> > By default has enabled DHCP as `vmnet-shared`, but providing
>> >> >> > network unique id (uuid) can make `vmnet-host` interfaces 
>> >> >> > isolated
>> >> >> > from each other and also disables DHCP.
>> >> >> >
>> >> >> >   * `vmnet-bridged`:
>> >> >> > bridges the guest with a physical network interface.
>> >> >> >
>> >> >> > This backends cannot work on macOS Catalina 10.15 cause we use
>> >> >> > vmnet.framework API provided only with macOS 11 and newer. Seems
>> >> >> > that it is not a problem, because QEMU guarantees to work on two most
>> >> >> > recent versions of macOS which now are Big Sur (11) and Monterey 
>> >> >> > (12).
>> >> >> >
>> >> >> > Also, we have one inconvenient restriction: vmnet.framework 
>> >> >> > interfaces
>> >> >> > can create only privileged user:
>> >> >> > `$ sudo qemu-system-x86_64 -nic vmnet-shared`
>> >> >> >
>> >> >> > Attempt of `vmnet-*` netdev creation being unprivileged user fails 
>> >> >> > with
>> >> >> > vmnet's 'general failure'.
>> >> >> >
>> >> >> > This happens because vmnet.framework requires 
>> >> >> > `com.apple.vm.networking`
>> >> >> > entitlement which is: "restricted to developers of virtualization 
>> >> >> > software.
>> >> >> > To request this entitlement, contact your Apple representative." as 
>> >> >> > Apple
>> >> >> > documentation says:
>> >> >> > https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_vm_networking
>> >> >>
>> >> >> Do you know how multipass work? Looks like it uses vmnet without 
>> >> >> privileges.
>> >> >>
>> >> >
>> >> > I've just checked this, and they still need root privileges. They have a
>> >> > `multipassd` daemon which is launched as root by launchd by default.
>> >> >
>> >> > ```
>> >> > bash-5.1$ ps axo ruser,ruid,comm | grep multipass
>> >> > root 0 /Library/Application 
>> >> > Support/com.canonical.multipass/bin/multipassd
>> >> > root 0 /Library/Application 
>> >> > Support/com.canonical.multipass/bin/hyperkit
>> >> > ```
>> >> >
>> >> > That's the reason why it's required to 'enter a password' while 
>> >> > multipass installation:
>> >> > it creates launchd plist (kinda launch rule) and places it to 
>> >> > /Library/LaunchDaemons/,
>> >> > which can be done only with root privileges.
>> >> >
>> >> > ```
>> >> > bash-5.1$ ll /Library/LaunchDaemons | grep multipass
>> >> > -rw-r--r--   1 root  wheel   1.1K 15 Nov 12:47 
>> >> > com.canonical.multipassd.plist
>> >> > ```
>> >> >
>> >> > And after this launchd launches this multipassd daemon as root every 
>> >> > boot.
>> >> >
>> >> > So an unprivileged user can launch a multipass VM instance, but 
>> >> > actually the
>> >> > `hyperkit` process which interacts with vmnet is gonna be launched by 
>> >> > multipassd
>> >> > running as root.
>> >>
>> >> I wonder how it passes the vmnet object to qemu? Nothing obvious from
>> >> the qemu command line that multipass launched:
>> >>
>> >> -nic vmnet-macos,mode=shared,model=virtio-net-pci,mac=52:54:00:52:e8:e4
>> >>
>> >> (But I haven't had time to check their qemu codes).
>> >>
>> >
>> > It seems they just use QEMU with patch by Phillip Tennen:
>> > https://patchew.org/QEMU/20210218134947.1860-1-phillip.en...@gmail.com/
>> >
>> > In that patch he does quite the same as we in this series, the
>> > difference remains in foreground: he creates one new 'vmnet-macos'
>> > netdev, and uses 'mode=shared' property to choose vmnet
>> > operating mode. I decided to create three different netdevs instead
>> > (vmnet-shared, vmnet-host, vmnet-bridged). Also I've added some
>> > features related to isolation and ipv6.
>>
>> Ok.
>>
>> >
>> > > I wonder how it passes the vmnet object to qemu
>> > I hope I clearly described this.
>>
>> A 

Re: [PATCH 2/3] virtio-net: Only enable userland vq if using tap backend

2021-11-18 Thread Jason Wang
On Thu, Nov 18, 2021 at 3:57 PM Eugenio Perez Martin
 wrote:
>
> On Thu, Nov 18, 2021 at 6:06 AM Jason Wang  wrote:
> >
> > On Thu, Nov 18, 2021 at 3:29 AM Eugenio Pérez  wrote:
> > >
> > > Qemu falls back on userland handlers even if vhost-user and vhost-vdpa
> > > cases. These assumes a tap device can handle the packets.
> > >
> > > If a vdpa device fail to start, it can trigger a sigsegv because of
> > > that. Do not resort on them unless actually possible.
> >
> > It would be better to show the calltrace here then we can see the root 
> > cause.
> >
>
> Sure, I'll paste here and I'll resend to the next version:
> #1  0x55955f696e92 in nc_sendv_compat (flags=,
> iovcnt=2, iov=0x7ffe73abe300, nc=0x7fcf22d6d010) at ../net/net.c:756
> #2  qemu_deliver_packet_iov (sender=,
> opaque=0x7fcf22d6d010, iovcnt=2, iov=0x7ffe73abe300, flags= out>) at ../net/net.c:784
> #3  qemu_deliver_packet_iov (sender=, flags= out>, iov=0x7ffe73abe300, iovcnt=2, opaque=0x7fcf22d6d010) at
> ../net/net.c:763
> #4  0x55955f69a078 in qemu_net_queue_deliver_iov (iovcnt=2,
> iov=0x7ffe73abe300, flags=0, sender=0x5595631f5ac0,
> queue=0x559561c7baa0) at ../net/queue.c:179
> #5  qemu_net_queue_send_iov (queue=0x559561c7baa0,
> sender=0x5595631f5ac0, flags=flags@entry=0,
> iov=iov@entry=0x7ffe73abe300,
> iovcnt=iovcnt@entry=2, sent_cb=sent_cb@entry=0x55955f82ae60
> ) at ../net/queue.c:246
> #6  0x55955f697d43 in qemu_sendv_packet_async
> (sent_cb=0x55955f82ae60 , iovcnt=2,
> iov=0x7ffe73abe300,
> sender=) at ../net/net.c:825
> #7  qemu_sendv_packet_async (sender=,
> iov=iov@entry=0x7ffe73abe300, iovcnt=iovcnt@entry=1662966768,
> sent_cb=sent_cb@entry=0x55955f82ae60 ) at
> ../net/net.c:794
> #8  0x55955f82aba9 in virtio_net_flush_tx (q=0x0,
> q@entry=0x5595631edbf0) at ../hw/net/virtio-net.c:2577
> #9  0x55955f82ade8 in virtio_net_tx_bh (opaque=0x5595631edbf0) at
> ../hw/net/virtio-net.c:2694
> #10 0x55955f9e847d in aio_bh_call (bh=0x559561c7e590) at 
> ../util/async.c:169
> #11 aio_bh_poll (ctx=ctx@entry=0x559561c81650) at ../util/async.c:169
> #12 0x55955f9d6912 in aio_dispatch (ctx=0x559561c81650) at
> ../util/aio-posix.c:381
> #13 0x55955f9e8322 in aio_ctx_dispatch (source=,
> callback=, user_data=)
> at ../util/async.c:311
> #14 0x7fcf20a5495d in g_main_context_dispatch () from
> /lib64/libglib-2.0.so.0
> #15 0x55955f9f2fc0 in glib_pollfds_poll () at ../util/main-loop.c:232
> #16 os_host_main_loop_wait (timeout=) at 
> ../util/main-loop.c:255
> #17 main_loop_wait (nonblocking=nonblocking@entry=0) at 
> ../util/main-loop.c:531
> #18 0x55955f7eee49 in qemu_main_loop () at ../softmmu/runstate.c:726
> #19 0x55955f6235c2 in main (argc=, argv= out>, envp=) at ../softmmu/main.c:50
>
> In nc_sendv_compat, nc->info is net_vhost_vdpa_info, so
> nc->info->receive is NULL.
>
> > >
> > > Signed-off-by: Eugenio Pérez 
> > > ---
> > >  include/hw/virtio/virtio.h |  2 ++
> > >  hw/net/virtio-net.c|  4 
> > >  hw/virtio/virtio.c | 21 +
> > >  3 files changed, 19 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > index 8bab9cfb75..1712ba0b4c 100644
> > > --- a/include/hw/virtio/virtio.h
> > > +++ b/include/hw/virtio/virtio.h
> > > @@ -105,6 +105,8 @@ struct VirtIODevice
> > >  VMChangeStateEntry *vmstate;
> > >  char *bus_name;
> > >  uint8_t device_endian;
> > > +/* backend does not support userspace handler */
> > > +bool disable_ioeventfd_handler;
> > >  bool use_guest_notifier_mask;
> > >  AddressSpace *dma_as;
> > >  QLIST_HEAD(, VirtQueue) *vector_queues;
> > > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > > index 004acf858f..8c5c4e5a9d 100644
> > > --- a/hw/net/virtio-net.c
> > > +++ b/hw/net/virtio-net.c
> > > @@ -3501,6 +3501,10 @@ static void virtio_net_device_realize(DeviceState 
> > > *dev, Error **errp)
> > >  nc = qemu_get_queue(n->nic);
> > >  nc->rxfilter_notify_enabled = 1;
> > >
> > > +if (!nc->peer || nc->peer->info->type != NET_CLIENT_DRIVER_TAP) {
> > > +/* Only tap can use userspace networking */
> > > +vdev->disable_ioeventfd_handler = true;
> > > +}
> > >  if (nc->peer && nc->peer->info->type == 
> > > NET_CLIENT_DRIVER_VHOST_VDPA) {
> > >  struct virtio_net_config netcfg = {};
> > >  memcpy(, >nic_conf.macaddr, ETH_ALEN);
> > > diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> > > index ea7c079fb0..1e04db6650 100644
> > > --- a/hw/virtio/virtio.c
> > > +++ b/hw/virtio/virtio.c
> > > @@ -3734,17 +3734,22 @@ static int 
> > > virtio_device_start_ioeventfd_impl(VirtIODevice *vdev)
> > >  err = r;
> > >  goto assign_error;
> > >  }
> > > -event_notifier_set_handler(>host_notifier,
> > > -   virtio_queue_host_notifier_read);
> > > +
> > > +if (!vdev->disable_ioeventfd_handler) {
> 

RE: Follow-up on the CXL discussion at OFTC

2021-11-18 Thread Shreyas Shah via
Hi Ben

Are you planning to add the CXL2.0 switch inside QEMU or already added in one 
of the version? 
 
Regards,
Shreyas

-Original Message-
From: Ben Widawsky  
Sent: Thursday, November 18, 2021 5:48 PM
To: Shreyas Shah 
Cc: Saransh Gupta1 ; Jonathan Cameron 
; linux-...@vger.kernel.org; qemu-devel@nongnu.org
Subject: Re: Follow-up on the CXL discussion at OFTC

On 21-11-18 22:52:56, Shreyas Shah wrote:
> Hello Folks,
> 
> Any plan to add CXL2.0 switch ports in QEMU? 

What's your definition of plan?

> 
> Regards,
> Shreyas

[snip]



Re: Follow-up on the CXL discussion at OFTC

2021-11-18 Thread Ben Widawsky
On 21-11-18 15:20:34, Saransh Gupta1 wrote:
> Hi Ben and Jonathan,
> 
> Thanks for your replies. I'm looking forward to the patches.
> 
> For QEMU, I see hotplug support as an item on the list and would like to 
> start working on it. It would be great if you can provide some pointers 
> about how I should go about it.

It's been a while, so I can't recall what's actually missing. I think it should
mostly behave like a normal PCIe endpoint.

> Also, which version of kernel and QEMU (maybe Jonathan's upcoming version) 
> would be a good starting point for it?

If he rebased and claims it works I have no reason to doubt it :-). I have a
small fix on my v4 branch if you want to use the latest port patches.

> 
> Thanks,
> Saransh
> 
> 
> 
> From:   "Jonathan Cameron" 
> To: "Ben Widawsky" 
> Cc: "Saransh Gupta1" , , 
> 
> Date:   11/17/2021 09:32 AM
> Subject:[EXTERNAL] Re: Follow-up on the CXL discussion at OFTC
> 
> 
> 
> On Wed, 17 Nov 2021 08:57:19 -0800
> Ben Widawsky  wrote:
> 
> > Hi Saransh. Please add the list for these kind of questions. I've 
> converted your
> > HTML mail, but going forward, the list will eat it, so please use text 
> only.
> > 
> > On 21-11-16 00:14:33, Saransh Gupta1 wrote:
> > >Hi Ben,
> > > 
> > >This is Saransh from IBM. Sorry to have (unintentionally) dropped 
> out
> > >of the conversion on OFTC, I'm new to IRC.
> > >Just wanted to follow-up on the discussion there. We discussed 
> about
> > >helping with linux patches reviews. On that front, I have 
> identified
> > >some colleague(s) who can help me with this. Let me know if/how you
> > >want to proceed with that. 
> > 
> > Currently the ball is in my court to re-roll the RFC v2 patches [1] 
> based on
> > feedback from Dan. I've implemented all/most of it, but I'm still 
> debugging some
> > issues with the result.
> > 
> > > 
> > >Maybe not urgently, but my team would also like to get an 
> understanding
> > >of the missing pieces in QEMU. Initially our focus is on type3 
> memory
> > >access and hotplug support. Most of the work that my team does is
> > >open-source, so contributing to the QEMU effort is another possible
> > >line of collaboration. 
> > 
> > If you haven't seen it already, check out my LPC talk [2]. The QEMU 
> patches
> > could use a lot of love. Mostly, I have little/no motivation until 
> upstream
> > shows an interest because I don't have time currently to make sure I 
> don't break
> > vs. upstream. If you want more details here, I can provide them, and I 
> will Cc
> > the qemu-devel mailing list; the end of the LPC talk [2] does have a 
> list.
> Hi Ben, Saransh
> 
> I have a forward port of the series + DOE etc to near current QEMU that is 
> lightly tested,
> and can look to push that out publicly later this week.
> 
> I'd also like to push QEMU support forwards and to start getting this 
> upstream in QEMU
> + fill in some of the missing parts.
> 
> Was aiming to make progress on this a few weeks ago, but as ever other 
> stuff
> got in the way.
> 
> +CC qemu-devel in case anyone else also looking at this.
> 
> Jonathan
> 
> 
> 
> > 
> > > 
> > >Thanks for your help and guidance!
> > > 
> > >Best,
> > >Saransh Gupta
> > >Research Staff Member, IBM Research 
> > 
> > [1]: 
> https://lore.kernel.org/linux-cxl/20211022183709.1199701-1-ben.widaw...@intel.com/T/#t
>  
> 
> > [2]: 
> https://www.youtube.com/watch?v=g89SLjt5Bd4=PLVsQ_xZBEyN3wA8Ej4BUjudXFbXuxhnfc=49
>  
> 
> 
> 
> 
> 
> 



Re: Follow-up on the CXL discussion at OFTC

2021-11-18 Thread Ben Widawsky
On 21-11-18 22:52:56, Shreyas Shah wrote:
> Hello Folks,
> 
> Any plan to add CXL2.0 switch ports in QEMU? 

What's your definition of plan?

> 
> Regards,
> Shreyas

[snip]



RE: Follow-up on the CXL discussion at OFTC

2021-11-18 Thread Shreyas Shah via
Hello Folks,

Any plan to add CXL2.0 switch ports in QEMU? 

Regards,
Shreyas

-Original Message-
From: Saransh Gupta1  
Sent: Thursday, November 18, 2021 2:21 PM
To: Jonathan Cameron ; Ben Widawsky 

Cc: linux-...@vger.kernel.org; qemu-devel@nongnu.org
Subject: RE: Follow-up on the CXL discussion at OFTC

Hi Ben and Jonathan,

Thanks for your replies. I'm looking forward to the patches.

For QEMU, I see hotplug support as an item on the list and would like to start 
working on it. It would be great if you can provide some pointers about how I 
should go about it.
Also, which version of kernel and QEMU (maybe Jonathan's upcoming version) 
would be a good starting point for it?

Thanks,
Saransh



From:   "Jonathan Cameron" 
To: "Ben Widawsky" 
Cc: "Saransh Gupta1" , , 

Date:   11/17/2021 09:32 AM
Subject:[EXTERNAL] Re: Follow-up on the CXL discussion at OFTC



On Wed, 17 Nov 2021 08:57:19 -0800
Ben Widawsky  wrote:

> Hi Saransh. Please add the list for these kind of questions. I've
converted your
> HTML mail, but going forward, the list will eat it, so please use text
only.
> 
> On 21-11-16 00:14:33, Saransh Gupta1 wrote:
> >Hi Ben,
> > 
> >This is Saransh from IBM. Sorry to have (unintentionally) dropped
out
> >of the conversion on OFTC, I'm new to IRC.
> >Just wanted to follow-up on the discussion there. We discussed
about
> >helping with linux patches reviews. On that front, I have
identified
> >some colleague(s) who can help me with this. Let me know if/how you
> >want to proceed with that. 
> 
> Currently the ball is in my court to re-roll the RFC v2 patches [1]
based on
> feedback from Dan. I've implemented all/most of it, but I'm still
debugging some
> issues with the result.
> 
> > 
> >Maybe not urgently, but my team would also like to get an
understanding
> >of the missing pieces in QEMU. Initially our focus is on type3
memory
> >access and hotplug support. Most of the work that my team does is
> >open-source, so contributing to the QEMU effort is another possible
> >line of collaboration. 
> 
> If you haven't seen it already, check out my LPC talk [2]. The QEMU
patches
> could use a lot of love. Mostly, I have little/no motivation until
upstream
> shows an interest because I don't have time currently to make sure I
don't break
> vs. upstream. If you want more details here, I can provide them, and I
will Cc
> the qemu-devel mailing list; the end of the LPC talk [2] does have a
list.
Hi Ben, Saransh

I have a forward port of the series + DOE etc to near current QEMU that is 
lightly tested, and can look to push that out publicly later this week.

I'd also like to push QEMU support forwards and to start getting this upstream 
in QEMU
+ fill in some of the missing parts.

Was aiming to make progress on this a few weeks ago, but as ever other 
stuff
got in the way.

+CC qemu-devel in case anyone else also looking at this.

Jonathan



> 
> > 
> >Thanks for your help and guidance!
> > 
> >Best,
> >Saransh Gupta
> >Research Staff Member, IBM Research 
> 
> [1]: 
https://lore.kernel.org/linux-cxl/20211022183709.1199701-1-ben.widaw...@intel.com/T/#t
 

> [2]: 
https://www.youtube.com/watch?v=g89SLjt5Bd4=PLVsQ_xZBEyN3wA8Ej4BUjudXFbXuxhnfc=49
 









RE: [PATCH] docs/COLO-FT.txt: Drop deprecated 'props' from object-add in COLO docs

2021-11-18 Thread Rao, Lei
OK,all files you mentioned will be modified in the next patch.

Thanks,
Lei.

-Original Message-
From: Markus Armbruster  
Sent: Thursday, November 18, 2021 2:50 PM
To: Rao, Lei 
Cc: Zhang, Chen ; zhang.zhanghaili...@huawei.com; 
quint...@redhat.com; dgilb...@redhat.com; qemu-triv...@nongnu.org; 
qemu-devel@nongnu.org
Subject: Re: [PATCH] docs/COLO-FT.txt: Drop deprecated 'props' from object-add 
in COLO docs

"Rao, Lei"  writes:

> From: "Rao, Lei" 
>
> With the removal of deprecated 'props' from object-add in the commit 
> of "50243407457a9fb0ed17b9a9ba9fc9aee09495b1", we also should update 
> COLO's documents.

We should've done this right when we deprecated it.  Not your fault, and better 
late than never.

Recommend to quote commits like

in commit 5024340745 "qapi/qom: Drop deprecated 'props' from
object-add" (v6.0.0)

I have

[alias]
whatis = "!f() { git --no-pager show -s --pretty=\"tformat:%h 
\"%s\" (`git dc $1 | sed 's/~.*//;s/%/%%/g'`, %cd)\" --date=short $1; }; f"

in my ~/.gitconfig, so I can run

$ git whatis 50243407457a9fb0ed17b9a9ba9fc9aee09495b1
5024340745 qapi/qom: Drop deprecated 'props' from object-add (v6.0.0-rc0, 
2021-03-19)

> Signed-off-by: Lei Rao 

Reviewed-by: Markus Armbruster 

Same issue in docs/system/authz.rst, docs/throttle.txt, and 
docs/tools/qemu-nbd.rst.  Care to fix it there as well?

Also...

> ---
>  docs/COLO-FT.txt | 16 
>  1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt index 
> 8d6d53a..fd5ffcc 100644
> --- a/docs/COLO-FT.txt
> +++ b/docs/COLO-FT.txt
> @@ -289,11 +289,11 @@ Wait until disk is synced, then:
>  {'execute': 'human-monitor-command', 'arguments':{ 'command-line': 
> 'drive_add -n buddy 
> driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,fi
> le.port=,file.export=parent0,node-name=replication0'}}
>  {'execute': 'x-blockdev-change', 'arguments':{ 'parent': 
> 'colo-disk0', 'node': 'replication0' } }
>  

... I'd like us to use double quotes in examples, not single quotes.
QMP supports single quotes as an extension over JSON.  Best to avoid it.
Separate patch, of course.

Same in docs/block-replication.txt.

[...]




RE: Follow-up on the CXL discussion at OFTC

2021-11-18 Thread Saransh Gupta1
Hi Ben and Jonathan,

Thanks for your replies. I'm looking forward to the patches.

For QEMU, I see hotplug support as an item on the list and would like to 
start working on it. It would be great if you can provide some pointers 
about how I should go about it.
Also, which version of kernel and QEMU (maybe Jonathan's upcoming version) 
would be a good starting point for it?

Thanks,
Saransh



From:   "Jonathan Cameron" 
To: "Ben Widawsky" 
Cc: "Saransh Gupta1" , , 

Date:   11/17/2021 09:32 AM
Subject:[EXTERNAL] Re: Follow-up on the CXL discussion at OFTC



On Wed, 17 Nov 2021 08:57:19 -0800
Ben Widawsky  wrote:

> Hi Saransh. Please add the list for these kind of questions. I've 
converted your
> HTML mail, but going forward, the list will eat it, so please use text 
only.
> 
> On 21-11-16 00:14:33, Saransh Gupta1 wrote:
> >Hi Ben,
> > 
> >This is Saransh from IBM. Sorry to have (unintentionally) dropped 
out
> >of the conversion on OFTC, I'm new to IRC.
> >Just wanted to follow-up on the discussion there. We discussed 
about
> >helping with linux patches reviews. On that front, I have 
identified
> >some colleague(s) who can help me with this. Let me know if/how you
> >want to proceed with that. 
> 
> Currently the ball is in my court to re-roll the RFC v2 patches [1] 
based on
> feedback from Dan. I've implemented all/most of it, but I'm still 
debugging some
> issues with the result.
> 
> > 
> >Maybe not urgently, but my team would also like to get an 
understanding
> >of the missing pieces in QEMU. Initially our focus is on type3 
memory
> >access and hotplug support. Most of the work that my team does is
> >open-source, so contributing to the QEMU effort is another possible
> >line of collaboration. 
> 
> If you haven't seen it already, check out my LPC talk [2]. The QEMU 
patches
> could use a lot of love. Mostly, I have little/no motivation until 
upstream
> shows an interest because I don't have time currently to make sure I 
don't break
> vs. upstream. If you want more details here, I can provide them, and I 
will Cc
> the qemu-devel mailing list; the end of the LPC talk [2] does have a 
list.
Hi Ben, Saransh

I have a forward port of the series + DOE etc to near current QEMU that is 
lightly tested,
and can look to push that out publicly later this week.

I'd also like to push QEMU support forwards and to start getting this 
upstream in QEMU
+ fill in some of the missing parts.

Was aiming to make progress on this a few weeks ago, but as ever other 
stuff
got in the way.

+CC qemu-devel in case anyone else also looking at this.

Jonathan



> 
> > 
> >Thanks for your help and guidance!
> > 
> >Best,
> >Saransh Gupta
> >Research Staff Member, IBM Research 
> 
> [1]: 
https://lore.kernel.org/linux-cxl/20211022183709.1199701-1-ben.widaw...@intel.com/T/#t
 

> [2]: 
https://www.youtube.com/watch?v=g89SLjt5Bd4=PLVsQ_xZBEyN3wA8Ej4BUjudXFbXuxhnfc=49
 









Re: [PATCH v2 for-6.2] meson.build: Support ncurses on MacOS and OpenBSD

2021-11-18 Thread Brad Smith

On 11/17/2021 3:53 PM, Stefan Weil wrote:


MacOS provides header files for curses 5.7 with support
for wide characters, but requires _XOPEN_SOURCE_EXTENDED=1
to activate that.

By default those old header files are used even if there
is a newer Homebrew installation of ncurses 6.2 available.

Change also the old macro definition of NCURSES_WIDECHAR
and set it to 1 like it is done in newer versions of
curses.h when _XOPEN_SOURCE_EXTENDED=1 is defined.

OpenBSD has the same version of ncurses and needs the same fix.

Suggested-by: Daniel P. Berrangé 
Signed-off-by: Stefan Weil 
---

v2:
- Only define _XOPEN_SOURCE_EXTENDED when curses.h is used.
- Extended to fix OpenBSD, too (untested!)

  meson.build | 5 -
  ui/curses.c | 4 
  2 files changed, 8 insertions(+), 1 deletion(-)


Tested-by: Brad Smith 



[PATCH] ui/gtk: mon_num parameter to specify target monitor for launching Qemu

2021-11-18 Thread Dongwon Kim
Introducing a new integer parameter to specify the monitor where the
Qemu window is placed upon launching.

Monitor index can start from 0 to (total number of monitors - 1).
Default value for the parameter is -1, which doesn't affect anything.

It can be used together with full-screen=on, which will make the Qemu
window full-screened on the targetted monitor.

Cc: Gerd Hoffmann 
Cc: Vivek Kasireddy 
Cc: sweeaun 
Cc: Khairul Anuar Romli 
Signed-off-by: Dongwon Kim 
---
 qapi/ui.json|  7 ++-
 qemu-options.hx |  2 +-
 ui/gtk.c| 10 ++
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/qapi/ui.json b/qapi/ui.json
index d7567ac866..7552b503b2 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1099,13 +1099,18 @@
 #   assuming the guest will resize the display to match
 #   the window size then.  Otherwise it defaults to "off".
 #   Since 3.1
+# @mon-num: Indicate monitor where Qemu window is lauched. mon-num
+#   could be any number from -1 to (total num of monitors - 1).
+#   (default: -1: use default monitor)
+#   since 6.2
 #
 # Since: 2.12
 #
 ##
 { 'struct'  : 'DisplayGTK',
   'data': { '*grab-on-hover' : 'bool',
-'*zoom-to-fit'   : 'bool'  } }
+'*zoom-to-fit'   : 'bool',
+'*mon-num'   : 'int' } }
 
 ##
 # @DisplayEGLHeadless:
diff --git a/qemu-options.hx b/qemu-options.hx
index 7749f59300..7a888b16b1 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1852,7 +1852,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
 #endif
 #if defined(CONFIG_GTK)
 "-display gtk[,full-screen=on|off][,gl=on|off][,grab-on-hover=on|off]\n"
-"[,show-cursor=on|off][,window-close=on|off]\n"
+"
[,mon-num=][,show-cursor=on|off][,window-close=on|off]\n"
 #endif
 #if defined(CONFIG_VNC)
 "-display vnc=[,]\n"
diff --git a/ui/gtk.c b/ui/gtk.c
index d2892ea6b4..8d8aa55822 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -2314,6 +2314,16 @@ static void gtk_display_init(DisplayState *ds, 
DisplayOptions *opts)
  vc && vc->type == GD_VC_VTE);
 #endif
 
+if (opts->u.gtk.has_mon_num && opts->u.gtk.mon_num &&
+opts->u.gtk.mon_num >= 0) {
+GdkRectangle mon_dest;
+if (opts->u.gtk.mon_num < gdk_display_get_n_monitors(window_display)) {
+gdk_monitor_get_geometry(
+gdk_display_get_monitor(window_display, opts->u.gtk.mon_num),
+_dest);
+gtk_window_move(GTK_WINDOW(s->window), mon_dest.x, mon_dest.y);
+}
+}
 if (opts->has_full_screen &&
 opts->full_screen) {
 gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
-- 
2.30.2




Re: [PULL 02/22] arm: tcg: Adhere to SMCCC 1.3 section 5.2

2021-11-18 Thread Peter Maydell
On Thu, 30 Sept 2021 at 16:12, Peter Maydell  wrote:
>
> From: Alexander Graf 
>
> The SMCCC 1.3 spec section 5.2 says
>
>   The Unknown SMC Function Identifier is a sign-extended value of (-1)
>   that is returned in the R0, W0 or X0 registers. An implementation must
>   return this error code when it receives:
>
> * An SMC or HVC call with an unknown Function Identifier
> * An SMC or HVC call for a removed Function Identifier
> * An SMC64/HVC64 call from AArch32 state
>
> To comply with these statements, let's always return -1 when we encounter
> an unknown HVC or SMC call.

TL/DR: I propose to revert this for 6.2.

This change turns out to cause regressions, for instance on the
imx6ul boards as described here:
https://lore.kernel.org/qemu-devel/c8b89685-7490-328b-51a3-48711c140...@tribudubois.net/

The primary cause of that regression is that the guest code running
at EL3 expects SMCs (not related to PSCI) to do what they would if
our PSCI emulation was not present at all, but after this change
they instead set a value in R0/X0 and continue.

I had a look at fixing this, which involves deferring the "do we
want to enable PSCI emulation?" decision into the hw/arm/boot.c
code (which is the only place we finally figure out whether we're
going to be booting the guest into EL3 or not). I have some
more-or-less working prototype code, but in the course of writing
it I discovered a much harder to fix issue:

The highbank board both:
 (1) wants to enable PSCI emulation
 (2) has a bit of guest code that it wants to run at EL3 and
 to perform SMC calls that trap to the monitor vector table:
 this is the boot stub code that is written to memory by
 arm_write_secure_board_setup_dummy_smc() and which the
 highbank board enables by setting bootinfo->secure_board_setup

We can't satisfy both of those and also have the PSCI emulation
handle all SMC instruction executions regardless of function
identifier value.

There is probably a solution to this, but I'm not sure what it
is right now (it might involve having QEMU manually do the things
that we currently have the arm_write_secure_board_setup_dummy_smc
write guest code to do) and it's going to require digging through
what the highbank board actually is supposed to do here. Given
that we're already in the release cycle for 6.2, I think the
safest and simplest approach is to revert this patch for now,
which just takes us back to the behaviour we've always had
in previous releases. We can then take our time to figure out
how to clean up this mess in 7.0.

thanks
-- PMM



Re: [RFC PATCH v2 5/5] softmmu/physmem: Have flaview API check MemTxAttrs::bus_perm field

2021-11-18 Thread Philippe Mathieu-Daudé
On 8/24/21 16:21, Peter Maydell wrote:
> On Tue, 24 Aug 2021 at 14:50, Philippe Mathieu-Daudé  
> wrote:
>> On 8/24/21 3:15 PM, Stefan Hajnoczi wrote:
>>> On Mon, Aug 23, 2021 at 06:41:57PM +0200, Philippe Mathieu-Daudé wrote:
 Check bus permission in flatview_access_allowed() before
 running any bus transaction.

 There is not change for the default case (MEMTXPERM_UNSPECIFIED).

 The MEMTXPERM_UNRESTRICTED case works as an allow list. Devices
 using it won't be checked by flatview_access_allowed().

 The only deny list equivalent is MEMTXPERM_RAM_DEVICE: devices
 using this flag will reject transactions and set the optional
 MemTxResult to MEMTX_BUS_ERROR.

 Signed-off-by: Philippe Mathieu-Daudé 
 ---
  softmmu/physmem.c | 17 -
  1 file changed, 16 insertions(+), 1 deletion(-)

 diff --git a/softmmu/physmem.c b/softmmu/physmem.c
 index 0d31a2f4199..329542dba75 100644
 --- a/softmmu/physmem.c
 +++ b/softmmu/physmem.c
 @@ -2772,7 +2772,22 @@ static inline bool 
 flatview_access_allowed(MemoryRegion *mr, MemTxAttrs attrs,
 hwaddr addr, hwaddr len,
 MemTxResult *result)
  {
 -return true;
 +if (unlikely(attrs.bus_perm == MEMTXPERM_RAM_DEVICE)) {
 +if (memory_region_is_ram(mr) || memory_region_is_ram_device(mr)) {
 +return true;
 +}
 +qemu_log_mask(LOG_GUEST_ERROR,
 +  "Invalid access to non-RAM device at "
 +  "addr 0x%" HWADDR_PRIX ", size %" HWADDR_PRIu ", "
 +  "region '%s'\n", addr, len, memory_region_name(mr));
 +if (result) {
 +*result |= MEMTX_BUS_ERROR;
>>>
>>> Why bitwise OR?
>>
>> MemTxResult is not an enum but used as a bitfield.
>>
>> See access_with_adjusted_size():
>>
>> MemTxResult r = MEMTX_OK;
>> ...
>> if (memory_region_big_endian(mr)) {
>> for (i = 0; i < size; i += access_size) {
>> r |= access_fn(mr, addr + i, value, access_size,
>> (size - access_size - i) * 8,
>> access_mask, attrs);
>> }
>> } else {
>> for (i = 0; i < size; i += access_size) {
>> r |= access_fn(mr, addr + i, value, access_size, i * 8,
>> access_mask, attrs);
>> }
>> }
>> return r;
>> }
>>
>> and flatview_read_continue() / flatview_write_continue():
>>
>> for (;;) {
>> if (!memory_access_is_direct(mr, true)) {
>> release_lock |= prepare_mmio_access(mr);
>> l = memory_access_size(mr, l, addr1);
>> val = ldn_he_p(buf, l);
>> result |= memory_region_dispatch_write(mr, addr1, val,
>>size_memop(l),
>>attrs);
>> ...
>> return result;
>> }
> 
> In these two examples we OR together the MemTxResults because
> we are looping over multiple accesses and combining all the
> results together; we want to return a "not OK" result if any
> of the individual results failed. Is that the case for
> flatview_access_allowed() ?

You are right, this is not the case here, so we can simplify as
Stefan suggested. Thanks for clarifying the examples.




[PATCH 7/7] python/aqmp: fix send_fd_scm for python 3.6.x

2021-11-18 Thread John Snow
3.6 doesn't play keepaway with the socket object, so we don't need to go
fishing for it on this version. In fact, so long as 'sendmsg' is still
available, it's probably preferable to just use that method and only go
fishing for forbidden details when we absolutely have to.

Reported-by: Thomas Huth 
Signed-off-by: John Snow 
---
 python/qemu/aqmp/qmp_client.py | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/python/qemu/aqmp/qmp_client.py b/python/qemu/aqmp/qmp_client.py
index f987da02eb..8105e29fa8 100644
--- a/python/qemu/aqmp/qmp_client.py
+++ b/python/qemu/aqmp/qmp_client.py
@@ -639,9 +639,12 @@ def send_fd_scm(self, fd: int) -> None:
 if sock.family != socket.AF_UNIX:
 raise AQMPError("Sending file descriptors requires a UNIX socket.")
 
-# Void the warranty sticker.
-# Access to sendmsg in asyncio is scheduled for removal in Python 3.11.
-sock = sock._sock  # pylint: disable=protected-access
+if not hasattr(sock, 'sendmsg'):
+# We need to void the warranty sticker.
+# Access to sendmsg is scheduled for removal in Python 3.11.
+# Find the real backing socket to use it anyway.
+sock = sock._sock  # pylint: disable=protected-access
+
 sock.sendmsg(
 [b' '],
 [(socket.SOL_SOCKET, socket.SCM_RIGHTS, struct.pack('@i', fd))]
-- 
2.31.1




[PATCH 0/7] python: More fixes for 6.2

2021-11-18 Thread John Snow
GitLab: https://gitlab.com/jsnow/qemu/-/pipelines/412040104

Patch 5 fixes a race condition in machine.py exposed by device-crash-test.
Patch 6 fixes a hang in device-crash-test.
Patch 7 fixes send_fd_scm in AQMP under Python 3.6.

Patches 1-3 provide a minor concurrency fix that happened to get fixed
on my way to fixing the above three.
Patch 4 is just a trivial style thing.

With this, device-crash-test should be back to producing only strictly
relevant output.

John Snow (7):
  python/machine: add @sock_dir property
  python/machine: remove _remove_monitor_sockfile property
  python/machine: add instance disambiguator to default nickname
  python/machine: move more variable initializations to _pre_launch
  python/machine: handle "fast" QEMU terminations
  scripts/device-crash-test: Use a QMP timeout
  python/aqmp: fix send_fd_scm for python 3.6.x

 python/qemu/aqmp/qmp_client.py |  9 --
 python/qemu/machine/machine.py | 59 --
 scripts/device-crash-test  |  2 +-
 3 files changed, 42 insertions(+), 28 deletions(-)

-- 
2.31.1





[PATCH 4/7] python/machine: move more variable initializations to _pre_launch

2021-11-18 Thread John Snow
No need to clear them only to set them later.

Signed-off-by: John Snow 
---
 python/qemu/machine/machine.py | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index ad529fd92a..f92e73de40 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -327,6 +327,14 @@ def _pre_launch(self) -> None:
 self._qemu_log_path = os.path.join(self.log_dir, self._name + ".log")
 self._qemu_log_file = open(self._qemu_log_path, 'wb')
 
+self._iolog = None
+self._qemu_full_args = tuple(chain(
+self._wrapper,
+[self._binary],
+self._base_args,
+self._args
+))
+
 def _post_launch(self) -> None:
 if self._qmp_connection:
 self._qmp.accept(self._qmp_timer)
@@ -390,8 +398,6 @@ def launch(self) -> None:
 if self._launched:
 raise QEMUMachineError('VM already launched')
 
-self._iolog = None
-self._qemu_full_args = ()
 try:
 self._launch()
 self._launched = True
@@ -410,12 +416,6 @@ def _launch(self) -> None:
 Launch the VM and establish a QMP connection
 """
 self._pre_launch()
-self._qemu_full_args = tuple(
-chain(self._wrapper,
-  [self._binary],
-  self._base_args,
-  self._args)
-)
 LOG.debug('VM launch command: %r', ' '.join(self._qemu_full_args))
 
 # Cleaning up of this subprocess is guaranteed by _do_shutdown.
-- 
2.31.1




[PATCH 6/7] scripts/device-crash-test: Use a QMP timeout

2021-11-18 Thread John Snow
Despite all the previous fixes, it's still possible for
device-crash-test to wedge itself in the case that QEMU terminates *so
quickly* that it doesn't even begin a connection attempt to our QMP
client. Python will just joyfully wait ad infinitum for a connection
that will now never arrive.

The real fix is to use asyncio to simultaneously poll both the health of
the launched process AND the connection attempt. That's quite a bit more
invasive than just setting a connection timeout, though.

Do the very simplest thing for now.

Signed-off-by: John Snow 
---
 scripts/device-crash-test | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/device-crash-test b/scripts/device-crash-test
index 1c73dac93e..7fbd99158b 100755
--- a/scripts/device-crash-test
+++ b/scripts/device-crash-test
@@ -353,7 +353,7 @@ def checkOneCase(args, testcase):
 '-device', qemuOptsEscape(device)]
 cmdline = ' '.join([binary] + args)
 dbg("will launch QEMU: %s", cmdline)
-vm = QEMUMachine(binary=binary, args=args)
+vm = QEMUMachine(binary=binary, args=args, qmp_timer=15)
 
 exc = None
 exc_traceback = None
-- 
2.31.1




[PATCH 1/7] python/machine: add @sock_dir property

2021-11-18 Thread John Snow
Analogous to temp_dir and log_dir, add a sock_dir property that defaults
to @temp_dir -- instead of base_temp_dir -- when the user hasn't
overridden the sock dir value in the initializer.

This gives us a much more unique directory to put sockfiles in by default.

Signed-off-by: John Snow 
---
 python/qemu/machine/machine.py | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index a487c39745..b1dd77b538 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -134,8 +134,9 @@ def __init__(self,
 self._qmp_timer = qmp_timer
 
 self._name = name or "qemu-%d" % os.getpid()
+self._temp_dir: Optional[str] = None
 self._base_temp_dir = base_temp_dir
-self._sock_dir = sock_dir or self._base_temp_dir
+self._sock_dir = sock_dir
 self._log_dir = log_dir
 
 if monitor_address is not None:
@@ -143,7 +144,7 @@ def __init__(self,
 self._remove_monitor_sockfile = False
 else:
 self._monitor_address = os.path.join(
-self._sock_dir, f"{self._name}-monitor.sock"
+self.sock_dir, f"{self._name}-monitor.sock"
 )
 self._remove_monitor_sockfile = True
 
@@ -163,14 +164,13 @@ def __init__(self,
 self._qmp_set = True   # Enable QMP monitor by default.
 self._qmp_connection: Optional[QEMUMonitorProtocol] = None
 self._qemu_full_args: Tuple[str, ...] = ()
-self._temp_dir: Optional[str] = None
 self._launched = False
 self._machine: Optional[str] = None
 self._console_index = 0
 self._console_set = False
 self._console_device_type: Optional[str] = None
 self._console_address = os.path.join(
-self._sock_dir, f"{self._name}-console.sock"
+self.sock_dir, f"{self._name}-console.sock"
 )
 self._console_socket: Optional[socket.socket] = None
 self._remove_files: List[str] = []
@@ -816,6 +816,15 @@ def temp_dir(self) -> str:
   dir=self._base_temp_dir)
 return self._temp_dir
 
+@property
+def sock_dir(self) -> str:
+"""
+Returns the directory used for sockfiles by this machine.
+"""
+if self._sock_dir:
+return self._sock_dir
+return self.temp_dir
+
 @property
 def log_dir(self) -> str:
 """
-- 
2.31.1




[PATCH 3/7] python/machine: add instance disambiguator to default nickname

2021-11-18 Thread John Snow
If you create two instances of QEMUMachine(), they'll both create the
same nickname by default -- which is not that helpful.

Luckily, they'll both create unique temporary directories ... but due to
user configuration, they may share logging and sockfile directories,
meaning two instances can collide. The Python logging will also be quite
confusing, with no differentiation between the two instances.

Add an instance disambiguator (The memory address of the instance) to
the default nickname to foolproof this in all cases.

Signed-off-by: John Snow 
---
 python/qemu/machine/machine.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index ea9e07805d..ad529fd92a 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -133,7 +133,7 @@ def __init__(self,
 self._wrapper = wrapper
 self._qmp_timer = qmp_timer
 
-self._name = name or "qemu-%d" % os.getpid()
+self._name = name or f"qemu-{os.getpid()}-{id(self):02x}"
 self._temp_dir: Optional[str] = None
 self._base_temp_dir = base_temp_dir
 self._sock_dir = sock_dir
-- 
2.31.1




[PATCH 2/7] python/machine: remove _remove_monitor_sockfile property

2021-11-18 Thread John Snow
It doesn't matter if it was the user or the class itself that specified
where the sockfile should be created; the fact is that if we are using a
sockfile here, we created it and we can clean it up.

Signed-off-by: John Snow 
---
 python/qemu/machine/machine.py | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index b1dd77b538..ea9e07805d 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -141,12 +141,10 @@ def __init__(self,
 
 if monitor_address is not None:
 self._monitor_address = monitor_address
-self._remove_monitor_sockfile = False
 else:
 self._monitor_address = os.path.join(
 self.sock_dir, f"{self._name}-monitor.sock"
 )
-self._remove_monitor_sockfile = True
 
 self._console_log_path = console_log
 if self._console_log_path:
@@ -315,8 +313,7 @@ def _pre_launch(self) -> None:
 self._remove_files.append(self._console_address)
 
 if self._qmp_set:
-if self._remove_monitor_sockfile:
-assert isinstance(self._monitor_address, str)
+if isinstance(self._monitor_address, str):
 self._remove_files.append(self._monitor_address)
 self._qmp_connection = QEMUMonitorProtocol(
 self._monitor_address,
-- 
2.31.1




[PATCH 5/7] python/machine: handle "fast" QEMU terminations

2021-11-18 Thread John Snow
In the case that the QEMU process actually launches -- but then dies so
quickly that we can't establish a QMP connection to it -- QEMUMachine
currently calls _post_shutdown() assuming that it never launched the VM
process.

This isn't true, though: it "merely" may have failed to establish a QMP
connection and the process is in the middle of its own exit path.

If we don't wait for the subprocess, the caller may get a bogus `None`
return for .exitcode(). This behavior was observed from
device-crash-test; after the switch to Async QMP, the timings were
changed such that it was now seemingly possible to witness the failure
of "vm.launch()" *prior* to the exitcode becoming available.

The semantic of the `_launched` property is changed in this
patch. Instead of representing the condition "launch() executed
successfully", it will now represent "has forked a child process
successfully". This way, wait() when called in the exit path won't
become a no-op.
Signed-off-by: John Snow 

Signed-off-by: John Snow 
---
 python/qemu/machine/machine.py | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/python/qemu/machine/machine.py b/python/qemu/machine/machine.py
index f92e73de40..67ab06ca2b 100644
--- a/python/qemu/machine/machine.py
+++ b/python/qemu/machine/machine.py
@@ -349,9 +349,6 @@ def _post_shutdown(self) -> None:
 Called to cleanup the VM instance after the process has exited.
 May also be called after a failed launch.
 """
-# Comprehensive reset for the failed launch case:
-self._early_cleanup()
-
 try:
 self._close_qmp_connection()
 except Exception as err:  # pylint: disable=broad-except
@@ -400,9 +397,16 @@ def launch(self) -> None:
 
 try:
 self._launch()
-self._launched = True
 except:
-self._post_shutdown()
+# We may have launched the process but it may
+# have exited before we could connect via QMP.
+# Assume the VM didn't launch or is exiting.
+# If we don't wait for the process, exitcode() may still be
+# 'None' by the time control is ceded back to the caller.
+if self._launched:
+self.wait()
+else:
+self._post_shutdown()
 
 LOG.debug('Error launching VM')
 if self._qemu_full_args:
@@ -426,6 +430,7 @@ def _launch(self) -> None:
stderr=subprocess.STDOUT,
shell=False,
close_fds=False)
+self._launched = True
 self._post_launch()
 
 def _close_qmp_connection(self) -> None:
@@ -457,8 +462,8 @@ def _early_cleanup(self) -> None:
 """
 Perform any cleanup that needs to happen before the VM exits.
 
-May be invoked by both soft and hard shutdown in failover scenarios.
-Called additionally by _post_shutdown for comprehensive cleanup.
+This method may be called twice upon shutdown, once each by soft
+and hard shutdown in failover scenarios.
 """
 # If we keep the console socket open, we may deadlock waiting
 # for QEMU to exit, while QEMU is waiting for the socket to
-- 
2.31.1




Re: device-crash-test

2021-11-18 Thread John Snow
On Thu, Nov 18, 2021 at 1:31 PM Philippe Mathieu-Daudé 
wrote:

> On 11/18/21 18:55, John Snow wrote:
> > I finally squashed all of the bugs and got a clean run of
> > device-crash-test with a full build of QEMU, over 182,000 individual
> > test cases.
> >
> > Here's all of the legitimate failures I saw:
> >
> > CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=none
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine none,accel=kvm
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x55b1c9dcad90 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=x-remote
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine x-remote,accel=kvm
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x559b43269d40 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=microvm
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine microvm,accel=kvm
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x55760ca941b0 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=none
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine none,accel=tcg
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x557a52333d90 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=x-remote
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine x-remote,accel=tcg
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x55bbcd596d40 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=microvm
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine microvm,accel=tcg
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x55ca35c081b0 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=none
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-i386 -S -machine none,accel=kvm -device
> > sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x55d0e0a03d90 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=x-remote
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-i386 -S -machine x-remote,accel=kvm
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x564648250b30 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=microvm
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-i386 -S -machine microvm,accel=kvm
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x55bef7a235b0 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=none
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-i386 -S -machine none,accel=tcg -device
> > sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x5608b9fecd90 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=x-remote
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-i386 -S -machine x-remote,accel=tcg
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x558306c9cb30 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
> >
> > CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=microvm
> > device=sgx-epc
> > CRITICAL: cmdline: ./qemu-system-i386 -S -machine microvm,accel=tcg
> > -device sgx-epc
> > CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> > Object 0x55e041f465b0 is not an instance of type generic-pc-machine
> > CRITICAL: exit code: -6
>
> Aren't these fixed by
>
> https://lore.kernel.org/qemu-devel/20211109175021.17813-1-pbonz...@redhat.com/
> ?
>

Maybe, dunno. I've been working on fixing up the testing infrastructure and
haven't rebased in a week. It takes a few hours to run the entire battery,
so I can try again 

[PATCH-for-6.2? v2] docs: Render binary names as monospaced text

2021-11-18 Thread Philippe Mathieu-Daudé
Reviewed-by: Darren Kenny 
Signed-off-by: Philippe Mathieu-Daudé 
---
v2: Addressed Eric comments
---
 docs/about/removed-features.rst|  8 
 docs/devel/build-system.rst|  6 +++---
 docs/devel/multi-process.rst   |  6 +++---
 docs/devel/testing.rst |  8 
 docs/image-fuzzer.txt  |  6 +++---
 docs/system/arm/orangepi.rst   |  2 +-
 docs/system/images.rst |  2 +-
 docs/system/qemu-block-drivers.rst.inc |  6 +++---
 docs/system/tls.rst|  2 +-
 docs/tools/qemu-img.rst| 18 +-
 docs/tools/qemu-nbd.rst|  4 ++--
 docs/tools/qemu-storage-daemon.rst |  7 ---
 docs/tools/virtiofsd.rst   |  4 ++--
 13 files changed, 40 insertions(+), 39 deletions(-)

diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
index 9d0d90c90d9..d42c3341dee 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -658,8 +658,8 @@ enforce that any failure to open the backing image 
(including if the
 backing file is missing or an incorrect format was specified) is an
 error when ``-u`` is not used.
 
-qemu-img amend to adjust backing file (removed in 6.1)
-''
+``qemu-img amend`` to adjust backing file (removed in 6.1)
+''
 
 The use of ``qemu-img amend`` to modify the name or format of a qcow2
 backing image was never fully documented or tested, and interferes
@@ -670,8 +670,8 @@ backing chain should be performed with ``qemu-img rebase 
-u`` either
 before or after the remaining changes being performed by amend, as
 appropriate.
 
-qemu-img backing file without format (removed in 6.1)
-'
+``qemu-img`` backing file without format (removed in 6.1)
+'
 
 The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img
 convert`` to create or modify an image that depends on a backing file
diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
index 7a83f5fc0db..431caba7aa0 100644
--- a/docs/devel/build-system.rst
+++ b/docs/devel/build-system.rst
@@ -121,11 +121,11 @@ process for:
 
 1) executables, which include:
 
-   - Tools - qemu-img, qemu-nbd, qga (guest agent), etc
+   - Tools - ``qemu-img``, ``qemu-nbd``, ``qga`` (guest agent), etc
 
-   - System emulators - qemu-system-$ARCH
+   - System emulators - ``qemu-system-$ARCH``
 
-   - Userspace emulators - qemu-$ARCH
+   - Userspace emulators - ``qemu-$ARCH``
 
- Unit tests
 
diff --git a/docs/devel/multi-process.rst b/docs/devel/multi-process.rst
index e5758a79aba..2c5ec977df8 100644
--- a/docs/devel/multi-process.rst
+++ b/docs/devel/multi-process.rst
@@ -187,9 +187,9 @@ desired, in which the emulation application should only be 
allowed to
 access the files or devices the VM it's running on behalf of can access.
  qemu-io model
 
-Qemu-io is a test harness used to test changes to the QEMU block backend
-object code. (e.g., the code that implements disk images for disk driver
-emulation) Qemu-io is not a device emulation application per se, but it
+``qemu-io`` is a test harness used to test changes to the QEMU block backend
+object code (e.g., the code that implements disk images for disk driver
+emulation). ``qemu-io`` is not a device emulation application per se, but it
 does compile the QEMU block objects into a separate binary from the main
 QEMU one. This could be useful for disk device emulation, since its
 emulation applications will need to include the QEMU block objects.
diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index 60c59023e58..755343c7dd0 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -564,11 +564,11 @@ exploiting a QEMU security bug to compromise the host.
 QEMU binaries
 ~
 
-By default, qemu-system-x86_64 is searched in $PATH to run the guest. If there
-isn't one, or if it is older than 2.10, the test won't work. In this case,
+By default, ``qemu-system-x86_64`` is searched in $PATH to run the guest. If
+there isn't one, or if it is older than 2.10, the test won't work. In this 
case,
 provide the QEMU binary in env var: ``QEMU=/path/to/qemu-2.10+``.
 
-Likewise the path to qemu-img can be set in QEMU_IMG environment variable.
+Likewise the path to ``qemu-img`` can be set in QEMU_IMG environment variable.
 
 Make jobs
 ~
@@ -650,7 +650,7 @@ supported. To start the fuzzer, run
 
   tests/image-fuzzer/runner.py -c '[["qemu-img", "info", "$test_img"]]' 
/tmp/test qcow2
 
-Alternatively, some command different from "qemu-img info" can be tested, by
+Alternatively, some command different from ``qemu-img info`` can be tested, by
 changing the ``-c`` option.
 
 Integration tests using the Avocado Framework
diff --git a/docs/image-fuzzer.txt 

Re: [PATCH] audio: Add sndio backend

2021-11-18 Thread Brad Smith

On 11/14/2021 8:18 AM, Christian Schoenebeck wrote:


On Samstag, 13. November 2021 21:40:39 CET Brad Smith wrote:

On 11/8/2021 8:03 AM, Christian Schoenebeck wrote:

On Sonntag, 7. November 2021 06:19:26 CET Brad Smith wrote:

audio: Add sndio backend

Add a sndio backend.

Hi Brad!


sndio is the native API used by OpenBSD, although it has been ported to
other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).

The C code is from Alexandre Ratchov  and the rest of
the bits are from me.

A Signed-off-by: line is mandatory for all QEMU patches:
https://wiki.qemu.org/Contribute/SubmitAPatch

Ah, I was not aware of that. I usually include it but it was an
oversight this time.


Also, it should be clear from the patches who did what exactly, either by
splitting the patches up and assigning the respective authors accordingly,
or by making the person with the most relevant work the patch author and
describing in the commit log additional authors and what they have added/
changed, along with their Signed-off-by: line:

Signed-off-by: Alexandre Ratchov
[Brad Smith: - Added foo

   - Some other change]

Signed-off-by: Brad Smith

I think I'll go with this.


http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/
Documentation/SubmittingPatches?
id=f6f94e2ab1b33f0082ac22d71f66385a60d8157f#n297

Please CC those involved authors.

Will do.

I added Alexandre Ratchov on CC as he seems to be the primary author of this
patch series.


---

   audio/audio.c  |   1 +
   audio/audio_template.h |   2 +
   audio/meson.build  |   1 +
   audio/sndioaudio.c | 555 +
   meson.build|   7 +
   meson_options.txt  |   4 +-
   qapi/audio.json|  25 +-
   qemu-options.hx|   8 +
   tests/vm/freebsd   |   3 +
   9 files changed, 604 insertions(+), 2 deletions(-)

An additional subsection for this backend should be added to MAINTAINERS.

I did not add anything here as I figured it implies a certain level of
obligation. His time
available varies quite a bit (especially at the current time) and I
wasn't sure if it's
appropriate listing him.

Yes, that's an unpleasant but legitimate question: will there be anybody
caring for this sndio backend in QEMU or would it go orphaned right from the
start?


Orphaned from the start makes it sound like we're dumping code and 
walking away.
When I say obligation I mean say responding withing say 3 - 4 days for 
some sort of

an issue vs say maybe taking 1.5 - 2 weeks to respond.


It would be good to have at least somebody familiar with this code to
volunteer as reviewer(s) ("R:" line(s) in MAINTAINERS file). Reviewers are
automatically CCed, so that they can (optionally) give their feedback on
future changes to the sndio backend, i.e. when somebody sends sndio patches to
qemu-devel. This is voluntary and can be revoked at any time, and I do not
expect that you would frequently get emailed for this either.

That sounds reasonable. I'll prod Alexandre further about responding.

As this is a BSD-specific audio backend, it is not likely that an active QEMU
developer would be able to care for it.


I would not say it is BSD-specific. sndio is also packaged and available 
on a good
number of Linux OS's (Alpine, Arch, Gentoo, Magia, Manjaro and some 
others). I

know I have seen some Gentoo users around testing and contributing to sndio
backends. Some use it as their default sound API (Void Linux for 
example). There

are older packages for Debian / Ubuntu that unfortunately don't have the
pkg-config file.


   create mode 100644 audio/sndioaudio.c

diff --git a/audio/audio.c b/audio/audio.c
index 54a153c0ef..bad1ceb69e 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2005,6 +2005,7 @@ void audio_create_pdos(Audiodev *dev)

   CASE(OSS, oss, Oss);
   CASE(PA, pa, Pa);
   CASE(SDL, sdl, Sdl);

+CASE(SNDIO, sndio, );

   CASE(SPICE, spice, );
   CASE(WAV, wav, );

diff --git a/audio/audio_template.h b/audio/audio_template.h
index c6714946aa..ecc5a0bc6d 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -337,6 +337,8 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_,
TYPE)(Audiodev *dev) return
qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE); case

AUDIODEV_DRIVER_SDL:
   return
   qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);

+case AUDIODEV_DRIVER_SNDIO:
+return dev->u.sndio.TYPE;

   case AUDIODEV_DRIVER_SPICE:
   return dev->u.spice.TYPE;
   
   case AUDIODEV_DRIVER_WAV:

diff --git a/audio/meson.build b/audio/meson.build
index 462533bb8c..e24c86e7e6 100644
--- a/audio/meson.build
+++ b/audio/meson.build
@@ -17,6 +17,7 @@ foreach m : [

 ['pa', pulse, files('paaudio.c')],
 ['sdl', sdl, files('sdlaudio.c')],
 ['jack', jack, files('jackaudio.c')],

+  ['sndio', sndio, files('sndioaudio.c')],

 ['spice', spice, 

[PATCH-for-6.2 2/2] hw/display: Do not allow multiple identical VGA devices

2021-11-18 Thread Philippe Mathieu-Daudé
vga_common_init() create a MemoryRegion named "vga.vram",
used as a singleton for the device class. When creating
the same device type multiple times, we get:

  $ qemu-system-mips64 -M pica61 -device isa-cirrus-vga
  RAMBlock "vga.vram" already registered, abort!
  Aborted (core dumped)

Commit 7852a77f598 ("vga: don't abort when adding a duplicate
isa-vga device") added a check for a single device, generalize
it to all VGA devices which call vga_common_init():

  $ qemu-system-mips64 -M pica61 -device isa-cirrus-vga
  qemu-system-mips64: -device isa-cirrus-vga: at most one isa-cirrus-vga device 
is permitted

Reported-by: John Snow 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/44
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/display/vga-isa.c |  9 -
 hw/display/vga.c | 13 +
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
index 2782012196a..b930c8d2667 100644
--- a/hw/display/vga-isa.c
+++ b/hw/display/vga-isa.c
@@ -62,15 +62,6 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
 MemoryRegion *vga_io_memory;
 const MemoryRegionPortio *vga_ports, *vbe_ports;
 
-/*
- * make sure this device is not being added twice, if so
- * exit without crashing qemu
- */
-if (object_resolve_path_type("", TYPE_ISA_VGA, NULL)) {
-error_setg(errp, "at most one %s device is permitted", TYPE_ISA_VGA);
-return;
-}
-
 s->global_vmstate = true;
 if (!vga_common_init(s, OBJECT(dev), errp)) {
 return;
diff --git a/hw/display/vga.c b/hw/display/vga.c
index a6759c7e934..8f0d5cc9019 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -2172,6 +2172,19 @@ bool vga_common_init(VGACommonState *s, Object *obj, 
Error **errp)
 {
 int i, j, v, b;
 
+if (obj) {
+const char *typename = object_get_typename(obj);
+
+/*
+ * make sure this device is not being added twice,
+ * if so exit without crashing qemu
+ */
+if (object_resolve_path_type("", typename, NULL)) {
+error_setg(errp, "at most one %s device is permitted", typename);
+return false;
+}
+}
+
 for(i = 0;i < 256; i++) {
 v = 0;
 for(j = 0; j < 8; j++) {
-- 
2.31.1




[PATCH-for-6.2 1/2] hw/display: Add Error* handle to vga_common_init()

2021-11-18 Thread Philippe Mathieu-Daudé
We want vga_common_init() to fail gracefully,
therefore allow it to take an Error* handle.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/display/vga_int.h| 2 +-
 hw/display/ati.c| 4 +++-
 hw/display/cirrus_vga.c | 4 +++-
 hw/display/cirrus_vga_isa.c | 4 +++-
 hw/display/qxl.c| 4 +++-
 hw/display/vga-isa-mm.c | 3 ++-
 hw/display/vga-isa.c| 4 +++-
 hw/display/vga-pci.c| 8 ++--
 hw/display/vga.c| 4 +++-
 hw/display/virtio-vga.c | 4 +++-
 hw/display/vmware_vga.c | 2 +-
 11 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index 847e784ca6a..305e700014d 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -156,7 +156,7 @@ static inline int c6_to_8(int v)
 return (v << 2) | (b << 1) | b;
 }
 
-void vga_common_init(VGACommonState *s, Object *obj);
+bool vga_common_init(VGACommonState *s, Object *obj, Error **errp);
 void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
   MemoryRegion *address_space_io, bool init_vga_ports);
 MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 31f22754dce..6e38e005022 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -955,7 +955,9 @@ static void ati_vga_realize(PCIDevice *dev, Error **errp)
 }
 
 /* init vga bits */
-vga_common_init(vga, OBJECT(s));
+if (!vga_common_init(vga, OBJECT(s), errp)) {
+return;
+}
 vga_init(vga, OBJECT(s), pci_address_space(dev),
  pci_address_space_io(dev), true);
 vga->con = graphic_console_init(DEVICE(s), 0, s->vga.hw_ops, >vga);
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index fdca6ca659f..5a7ddb84ff0 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -2954,7 +2954,9 @@ static void pci_cirrus_vga_realize(PCIDevice *dev, Error 
**errp)
  return;
  }
  /* setup VGA */
- vga_common_init(>vga, OBJECT(dev));
+if (!vga_common_init(>vga, OBJECT(dev), errp)) {
+return;
+}
  cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev),
 pci_address_space_io(dev));
  s->vga.con = graphic_console_init(DEVICE(dev), 0, s->vga.hw_ops, >vga);
diff --git a/hw/display/cirrus_vga_isa.c b/hw/display/cirrus_vga_isa.c
index 4f6fb1af3bd..96144bd6906 100644
--- a/hw/display/cirrus_vga_isa.c
+++ b/hw/display/cirrus_vga_isa.c
@@ -56,7 +56,9 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error 
**errp)
 return;
 }
 s->global_vmstate = true;
-vga_common_init(s, OBJECT(dev));
+if (!vga_common_init(s, OBJECT(dev), errp)) {
+return;
+}
 cirrus_init_common(>cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0,
isa_address_space(isadev),
isa_address_space_io(isadev));
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 29c80b4289b..16eb98c25d8 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -2198,7 +2198,9 @@ static void qxl_realize_primary(PCIDevice *dev, Error 
**errp)
 qxl_init_ramsize(qxl);
 vga->vbe_size = qxl->vgamem_size;
 vga->vram_size_mb = qxl->vga.vram_size / MiB;
-vga_common_init(vga, OBJECT(dev));
+if (!vga_common_init(vga, OBJECT(dev), errp)) {
+return;
+}
 vga_init(vga, OBJECT(dev),
  pci_address_space(dev), pci_address_space_io(dev), false);
 portio_list_init(>vga_port_list, OBJECT(dev), qxl_vga_portio_list,
diff --git a/hw/display/vga-isa-mm.c b/hw/display/vga-isa-mm.c
index 7321b7a06d5..420da1d7467 100644
--- a/hw/display/vga-isa-mm.c
+++ b/hw/display/vga-isa-mm.c
@@ -25,6 +25,7 @@
 #include "qemu/osdep.h"
 #include "qemu/bitops.h"
 #include "qemu/units.h"
+#include "qapi/error.h"
 #include "migration/vmstate.h"
 #include "hw/display/vga.h"
 #include "vga_int.h"
@@ -101,7 +102,7 @@ int isa_vga_mm_init(hwaddr vram_base,
 
 s->vga.vram_size_mb = VGA_RAM_SIZE / MiB;
 s->vga.global_vmstate = true;
-vga_common_init(>vga, NULL);
+vga_common_init(>vga, NULL, _fatal);
 vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
 
 s->vga.con = graphic_console_init(NULL, 0, s->vga.hw_ops, s);
diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
index 8cea84f2bea..2782012196a 100644
--- a/hw/display/vga-isa.c
+++ b/hw/display/vga-isa.c
@@ -72,7 +72,9 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp)
 }
 
 s->global_vmstate = true;
-vga_common_init(s, OBJECT(dev));
+if (!vga_common_init(s, OBJECT(dev), errp)) {
+return;
+}
 s->legacy_address_space = isa_address_space(isadev);
 vga_io_memory = vga_init_io(s, OBJECT(dev), _ports, _ports);
 isa_register_portio_list(isadev, >portio_vga,
diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index 62fb5c38c1f..3e5bc259f7a 100644
--- a/hw/display/vga-pci.c
+++ 

[PATCH-for-6.2 0/2] hw/display: Do not allow multiple (identical) VGA devices

2021-11-18 Thread Philippe Mathieu-Daudé
Commit 7852a77f598 fixed creating multiple TYPE_ISA_VGA devices,
generalize the fix to all VGA devices.

See https://gitlab.com/qemu-project/qemu/-/issues/44

Philippe Mathieu-Daudé (2):
  hw/display: Add Error* handle to vga_common_init()
  hw/display: Do not allow multiple identical VGA devices

 hw/display/vga_int.h|  2 +-
 hw/display/ati.c|  4 +++-
 hw/display/cirrus_vga.c |  4 +++-
 hw/display/cirrus_vga_isa.c |  4 +++-
 hw/display/qxl.c|  4 +++-
 hw/display/vga-isa-mm.c |  3 ++-
 hw/display/vga-isa.c| 11 ++-
 hw/display/vga-pci.c|  8 ++--
 hw/display/vga.c| 17 -
 hw/display/virtio-vga.c |  4 +++-
 hw/display/vmware_vga.c |  2 +-
 11 files changed, 43 insertions(+), 20 deletions(-)

-- 
2.31.1





Re: device-crash-test

2021-11-18 Thread Philippe Mathieu-Daudé
On 11/18/21 18:55, John Snow wrote:
> I finally squashed all of the bugs and got a clean run of
> device-crash-test with a full build of QEMU, over 182,000 individual
> test cases.
> 
> Here's all of the legitimate failures I saw:
> 
> CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=none
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine none,accel=kvm
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x55b1c9dcad90 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=x-remote
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine x-remote,accel=kvm
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x559b43269d40 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=microvm
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine microvm,accel=kvm
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x55760ca941b0 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=none
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine none,accel=tcg
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x557a52333d90 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=x-remote
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine x-remote,accel=tcg
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x55bbcd596d40 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=microvm
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine microvm,accel=tcg
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x55ca35c081b0 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=none
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-i386 -S -machine none,accel=kvm -device
> sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x55d0e0a03d90 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=x-remote
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-i386 -S -machine x-remote,accel=kvm
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x564648250b30 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=microvm
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-i386 -S -machine microvm,accel=kvm
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x55bef7a235b0 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=none
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-i386 -S -machine none,accel=tcg -device
> sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x5608b9fecd90 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=x-remote
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-i386 -S -machine x-remote,accel=tcg
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x558306c9cb30 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6
> 
> CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=microvm
> device=sgx-epc
> CRITICAL: cmdline: ./qemu-system-i386 -S -machine microvm,accel=tcg
> -device sgx-epc
> CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
> Object 0x55e041f465b0 is not an instance of type generic-pc-machine
> CRITICAL: exit code: -6

Aren't these fixed by
https://lore.kernel.org/qemu-devel/20211109175021.17813-1-pbonz...@redhat.com/
?




Re: [PATCH for-6.2 0/2] escc: fixes for STATUS_TXEMPTY and SPEC_ALLSENT

2021-11-18 Thread Peter Maydell
On Thu, 18 Nov 2021 at 18:18, Mark Cave-Ayland
 wrote:
>
> This is another attempt to fix booting 32-bit QEMU SPARC machines in
> qemu-system-sparc using a real Sun PROM based upon further experiments and
> re-reading of the ESCC datasheet from a previous patch posted at
> https://lists.gnu.org/archive/html/qemu-devel/2021-11/msg00324.html.
>
> It appears that both the Sun PROM and OpenBSD with OpenBIOS fail to send an
> explicit reset command as recommended in the ESCC datasheet, which causes
> hangs during serial port enumeration since the introduction of the recent
> ESCC reset changes.
>
> The first patch always sets STATUS_TXEMPTY in R_STATUS on hardware reset
> which wasn't documented in the "Reset" section(s) but is documented in the
> "Transmit Interrupts and Transmit Buffer Empty Bit" section, whilst the
> second patch updates SPEC_ALLSENT when writing to W_TXCTRL1.
>
> Signed-off-by: Mark Cave-Ayland 

Series
Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH for-6.2 2/2] escc: update the R_SPEC register SPEC_ALLSENT bit when writing to W_TXCTRL1

2021-11-18 Thread Philippe Mathieu-Daudé
On 11/18/21 19:18, Mark Cave-Ayland wrote:
> The ESCC datasheet states that SPEC_ALLSENT is always set in sync mode and set
> in async mode once all characters have cleared the transmitter. Since writes 
> to
> SERIAL_DATA use a synchronous chardev API, the guest can never see the state 
> when
> transmission is in progress so it is possible to set SPEC_ALLSENT in the
> R_SPEC register unconditionally.
> 
> This fixes a hang when using the Sun PROM as it attempts to enumerate the
> onboard serial devices, and a similar hang in OpenBSD SPARC32 where in both 
> cases
> the boot process will not proceed until SPEC_ALLSENT has been set after 
> writing
> to W_TXCTRL1.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/char/escc.c | 14 ++
>  1 file changed, 14 insertions(+)

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH-for-6.2?] docs: Render binary names as monospaced text

2021-11-18 Thread Philippe Mathieu-Daudé
On 11/18/21 16:46, Eric Blake wrote:
> On Thu, Nov 18, 2021 at 03:43:17PM +0100, Philippe Mathieu-Daudé wrote:
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
> 
>> +++ b/docs/about/removed-features.rst
>> @@ -658,8 +658,8 @@ enforce that any failure to open the backing image 
>> (including if the
>>  backing file is missing or an incorrect format was specified) is an
>>  error when ``-u`` is not used.
>>  
>> -qemu-img amend to adjust backing file (removed in 6.1)
>> -''
>> +``qemu-img`` amend to adjust backing file (removed in 6.1)
>> +''
> 
> Why quote just qemu-img here,
> 
>>  
>>  The use of ``qemu-img amend`` to modify the name or format of a qcow2
> 
> when the context is obvious that it is the 'qemu-img amend' subcommand?

Because I was not careful enough :)

>>  backing image was never fully documented or tested, and interferes
>> @@ -670,8 +670,8 @@ backing chain should be performed with ``qemu-img rebase 
>> -u`` either
>>  before or after the remaining changes being performed by amend, as
>>  appropriate.
>>  
>> -qemu-img backing file without format (removed in 6.1)
>> -'
>> +``qemu-img`` backing file without format (removed in 6.1)
>> +'
> 
> This one makes sense, though, as "backing" is not a qemu-img subcommand.
> 
>>  
>>  The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img
>>  convert`` to create or modify an image that depends on a backing file
>> diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
>> index 7a83f5fc0db..431caba7aa0 100644
>> --- a/docs/devel/build-system.rst
>> +++ b/docs/tools/qemu-nbd.rst
>> @@ -38,7 +38,7 @@ driver options if ``--image-opts`` is specified.
>>supported. The common object types that it makes sense to define are the
>>``secret`` object, which is used to supply passwords and/or encryption
>>keys, and the ``tls-creds`` object, which is used to supply TLS
>> -  credentials for the qemu-nbd server or client.
>> +  credentials for the ``qemu-nbd`` server or client.
>>  
>>  .. option:: -p, --port=PORT
>>  
>> @@ -238,7 +238,7 @@ daemon:
>>  Expose the guest-visible contents of a qcow2 file via a block device
>>  /dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for
>>  partitions found within), then disconnect the device when done.
>> -Access to bind qemu-nbd to an /dev/nbd device generally requires root
>> +Access to bind ``qemu-nbd`` to an /dev/nbd device generally requires root
> 
> As long as you're touching this line, s/an/a/.

OK.

>>  privileges, and may also require the execution of ``modprobe nbd``
>>  to enable the kernel NBD client module.  *CAUTION*: Do not use
>>  this method to mount filesystems from an untrusted guest image - a
> 
> Overall looks like a nice changeset.
> 




[PATCH for-6.2 2/2] escc: update the R_SPEC register SPEC_ALLSENT bit when writing to W_TXCTRL1

2021-11-18 Thread Mark Cave-Ayland
The ESCC datasheet states that SPEC_ALLSENT is always set in sync mode and set
in async mode once all characters have cleared the transmitter. Since writes to
SERIAL_DATA use a synchronous chardev API, the guest can never see the state 
when
transmission is in progress so it is possible to set SPEC_ALLSENT in the
R_SPEC register unconditionally.

This fixes a hang when using the Sun PROM as it attempts to enumerate the
onboard serial devices, and a similar hang in OpenBSD SPARC32 where in both 
cases
the boot process will not proceed until SPEC_ALLSENT has been set after writing
to W_TXCTRL1.

Signed-off-by: Mark Cave-Ayland 
---
 hw/char/escc.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/hw/char/escc.c b/hw/char/escc.c
index a7d9050c83..8755d8d34f 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -586,6 +586,20 @@ static void escc_mem_write(void *opaque, hwaddr addr,
 s->wregs[s->reg] = val;
 break;
 case W_TXCTRL1:
+s->wregs[s->reg] = val;
+/*
+ * The ESCC datasheet states that SPEC_ALLSENT is always set in
+ * sync mode, and set in async mode when all characters have
+ * cleared the transmitter. Since writes to SERIAL_DATA use the
+ * blocking qemu_chr_fe_write_all() function to write each
+ * character, the guest can never see the state when async data
+ * is in the process of being transmitted so we can set this bit
+ * unconditionally regardless of the state of the W_TXCTRL1 mode
+ * bits.
+ */
+s->rregs[R_SPEC] |= SPEC_ALLSENT;
+escc_update_parameters(s);
+break;
 case W_TXCTRL2:
 s->wregs[s->reg] = val;
 escc_update_parameters(s);
-- 
2.20.1




[PATCH for-6.2 1/2] escc: always set STATUS_TXEMPTY in R_STATUS on device reset

2021-11-18 Thread Mark Cave-Ayland
The "Transmit Interrupts and Transmit Buffer Empty Bit" section of the ESCC
datasheet states the following about the STATUS_TXEMPTY bit: "After a hardware
reset (including a hardware reset by software), or a channel reset, this bit
is set to 1".

Update escc_reset() to set the STATUS_TXEMPTY bit in the R_STATUS register
on device reset as described which fixes a regression whereby the Sun PROM
checks this bit early on startup and gets stuck in an infinite loop if it is
not set.

Signed-off-by: Mark Cave-Ayland 
---
 hw/char/escc.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/hw/char/escc.c b/hw/char/escc.c
index 0fce4f6324..a7d9050c83 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -354,6 +354,17 @@ static void escc_reset(DeviceState *d)
 cs->rregs[j] = 0;
 cs->wregs[j] = 0;
 }
+
+/*
+ * ...but there is an exception. The "Transmit Interrupts and Transmit
+ * Buffer Empty Bit" section on page 50 of the ESCC datasheet says of
+ * the STATUS_TXEMPTY bit in R_STATUS: "After a hardware reset
+ * (including a hardware reset by software), or a channel reset, this
+ * bit is set to 1". The Sun PROM checks this bit early on startup and
+ * gets stuck in an infinite loop if it is not set.
+ */
+cs->rregs[R_STATUS] |= STATUS_TXEMPTY;
+
 escc_reset_chn(cs);
 }
 }
-- 
2.20.1




[PATCH for-6.2 0/2] escc: fixes for STATUS_TXEMPTY and SPEC_ALLSENT

2021-11-18 Thread Mark Cave-Ayland
This is another attempt to fix booting 32-bit QEMU SPARC machines in
qemu-system-sparc using a real Sun PROM based upon further experiments and
re-reading of the ESCC datasheet from a previous patch posted at
https://lists.gnu.org/archive/html/qemu-devel/2021-11/msg00324.html.

It appears that both the Sun PROM and OpenBSD with OpenBIOS fail to send an
explicit reset command as recommended in the ESCC datasheet, which causes
hangs during serial port enumeration since the introduction of the recent
ESCC reset changes.

The first patch always sets STATUS_TXEMPTY in R_STATUS on hardware reset
which wasn't documented in the "Reset" section(s) but is documented in the
"Transmit Interrupts and Transmit Buffer Empty Bit" section, whilst the
second patch updates SPEC_ALLSENT when writing to W_TXCTRL1.

Signed-off-by: Mark Cave-Ayland 


Mark Cave-Ayland (2):
  escc: always set STATUS_TXEMPTY in R_STATUS on device reset
  escc: update the R_SPEC register SPEC_ALLSENT bit when writing to
W_TXCTRL1

 hw/char/escc.c | 25 +
 1 file changed, 25 insertions(+)

-- 
2.20.1




[PATCH v2 0/3] support dirty restraint on vCPU

2021-11-18 Thread huangy81
From: Hyman Huang(黄勇) 

v2:
- rebase on master
- modify the following points according to the advices given by Juan
  1. rename dirtyrestraint to dirtylimit
  2. implement the full lifecyle function of dirtylimit_calc, include
 dirtylimit_calc and dirtylimit_calc_quit
  3. introduce 'quit' field in dirtylimit_calc_state to implement the
 dirtylimit_calc_quit
  4. remove the ready_cond and ready_mtx since it may not be suitable
  5. put the 'record_dirtypage' function code at the beggining of the 
 file 
  6. remove the unnecesary return;
- other modifications has been made after code review
  1. introduce 'bmap' and 'nr' field in dirtylimit_state to record the
 number of running thread forked by dirtylimit
  2. stop the dirtyrate calculation thread if all the dirtylimit thread
 are stopped
  3. do some renaming works
 dirtyrate calulation thread -> dirtylimit-calc 
 dirtylimit thread -> dirtylimit-{cpu_index}
 function name do_dirtyrestraint -> dirtylimit_check
 qmp command dirty-restraint -> set-drity-limit
 qmp command dirty-restraint-cancel -> cancel-dirty-limit
 header file dirtyrestraint.h -> dirtylimit.h

Please review, thanks !

thanks for the accurate and timely advices given by Juan. we really
appreciate it if corrections and suggetions are proposed !

Best Regards ! 
Hyman

v1:
this patchset introduce a mechanism to impose dirty restraint
on vCPU, aiming to keep the vCPU running in a certain dirtyrate
given by user. dirty restraint on vCPU maybe an alternative
method to implement convergence logic for live migration,
which could improve guest memory performance during migration
compared with traditional method in theory.

For the current live migration implementation, the convergence
logic throttles all vCPUs of the VM, which has some side effects. 
-'read processes' on vCPU will be unnecessarily penalized
- throttle increase percentage step by step, which seems
  struggling to find the optimal throttle percentage when
  dirtyrate is high. 
- hard to predict the remaining time of migration if the
  throttling percentage reachs 99%

to a certain extent, the dirty restraint machnism can fix these
effects by throttling at vCPU granularity during migration.

the implementation is rather straightforward, we calculate
vCPU dirtyrate via the Dirty Ring mechanism periodically
as the commit 0e21bf246 "implement dirty-ring dirtyrate calculation"
does, for vCPU that be specified to impose dirty restraint,
we throttle it periodically as the auto-converge does, once after
throttling, we compare the quota dirtyrate with current dirtyrate,
if current dirtyrate is not under the quota, increase the throttling
percentage until current dirtyrate is under the quota.

this patchset is the basis of implmenting a new auto-converge method
for live migration, we introduce two qmp commands for impose/cancel
the dirty restraint on specified vCPU, so it also can be an independent
api to supply the upper app such as libvirt, which can use it to
implement the convergence logic during live migration, supplemented
with the qmp 'calc-dirty-rate' command or whatever. 

we post this patchset for RFC and any corrections and suggetions about
the implementation, api, throttleing algorithm or whatever are very
appreciated!

Please review, thanks !

Best Regards ! 

Hyman Huang (3):
  migration/dirtyrate: implement vCPU dirtyrate calculation periodically
  cpu-throttle: implement vCPU throttle
  cpus-common: implement dirty limit on vCPU

 cpus-common.c |  41 ++
 include/exec/memory.h |   5 +-
 include/hw/core/cpu.h |   7 +
 include/sysemu/cpu-throttle.h |  23 +++
 include/sysemu/dirtylimit.h   |  44 ++
 migration/dirtyrate.c | 139 --
 migration/dirtyrate.h |   2 +
 qapi/misc.json|  44 ++
 softmmu/cpu-throttle.c| 319 ++
 softmmu/trace-events  |   5 +
 softmmu/vl.c  |   1 +
 11 files changed, 619 insertions(+), 11 deletions(-)
 create mode 100644 include/sysemu/dirtylimit.h

-- 
1.8.3.1




[PATCH v2 1/3] migration/dirtyrate: implement vCPU dirtyrate calculation periodically

2021-11-18 Thread huangy81
From: Hyman Huang(黄勇) 

introduce the third method GLOBAL_DIRTY_RESTRAINT of dirty
tracking for calculate dirtyrate periodly for dirty restraint.

implement thread for calculate dirtyrate periodly, which will
be used for dirty restraint.

add dirtylimit.h to introduce the util function for dirty
limit implementation.

Signed-off-by: Hyman Huang(黄勇) 
---
 include/exec/memory.h   |   5 +-
 include/sysemu/dirtylimit.h |  44 ++
 migration/dirtyrate.c   | 139 
 migration/dirtyrate.h   |   2 +
 4 files changed, 179 insertions(+), 11 deletions(-)
 create mode 100644 include/sysemu/dirtylimit.h

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 20f1b27..606bec8 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -69,7 +69,10 @@ static inline void fuzz_dma_read_cb(size_t addr,
 /* Dirty tracking enabled because measuring dirty rate */
 #define GLOBAL_DIRTY_DIRTY_RATE (1U << 1)
 
-#define GLOBAL_DIRTY_MASK  (0x3)
+/* Dirty tracking enabled because dirty limit */
+#define GLOBAL_DIRTY_LIMIT  (1U << 2)
+
+#define GLOBAL_DIRTY_MASK  (0x7)
 
 extern unsigned int global_dirty_tracking;
 
diff --git a/include/sysemu/dirtylimit.h b/include/sysemu/dirtylimit.h
new file mode 100644
index 000..3a1c74a
--- /dev/null
+++ b/include/sysemu/dirtylimit.h
@@ -0,0 +1,44 @@
+/*
+ * dirty limit helper functions
+ *
+ * Copyright (c) 2021 CHINA TELECOM CO.,LTD.
+ *
+ * Authors:
+ *  Hyman Huang(黄勇) 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_DIRTYRLIMIT_H
+#define QEMU_DIRTYRLIMIT_H
+
+#define DIRTYLIMIT_CALC_PERIOD_TIME_S   15  /* 15s */
+
+/**
+ * dirtylimit_calc_current:
+ *
+ * get current dirty rate of specified vCPU.
+ */
+int64_t dirtylimit_calc_current(int cpu_index);
+
+/**
+ * dirtylimit_calc:
+ *
+ * start dirty rate calculation thread.
+ */
+void dirtylimit_calc(void);
+
+/**
+ * dirtylimit_calc_quit:
+ *
+ * quit dirty rate calculation thread.
+ */
+void dirtylimit_calc_quit(void);
+
+/**
+ * dirtylimit_calc_state_init:
+ *
+ * initialize dirty rate calculation state.
+ */
+void dirtylimit_calc_state_init(int max_cpus);
+#endif
diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c
index d65e744..d370a21 100644
--- a/migration/dirtyrate.c
+++ b/migration/dirtyrate.c
@@ -27,6 +27,7 @@
 #include "qapi/qmp/qdict.h"
 #include "sysemu/kvm.h"
 #include "sysemu/runstate.h"
+#include "sysemu/dirtylimit.h"
 #include "exec/memory.h"
 
 /*
@@ -46,6 +47,134 @@ static struct DirtyRateStat DirtyStat;
 static DirtyRateMeasureMode dirtyrate_mode =
 DIRTY_RATE_MEASURE_MODE_PAGE_SAMPLING;
 
+#define DIRTYLIMIT_CALC_TIME_MS 1000/* 1000ms */
+
+struct {
+DirtyRatesData data;
+int64_t period;
+bool quit;
+} *dirtylimit_calc_state;
+
+static void dirtylimit_global_dirty_log_start(void)
+{
+qemu_mutex_lock_iothread();
+memory_global_dirty_log_start(GLOBAL_DIRTY_LIMIT);
+qemu_mutex_unlock_iothread();
+}
+
+static void dirtylimit_global_dirty_log_stop(void)
+{
+qemu_mutex_lock_iothread();
+memory_global_dirty_log_sync();
+memory_global_dirty_log_stop(GLOBAL_DIRTY_LIMIT);
+qemu_mutex_unlock_iothread();
+}
+
+static inline void record_dirtypages(DirtyPageRecord *dirty_pages,
+ CPUState *cpu, bool start)
+{
+if (start) {
+dirty_pages[cpu->cpu_index].start_pages = cpu->dirty_pages;
+} else {
+dirty_pages[cpu->cpu_index].end_pages = cpu->dirty_pages;
+}
+}
+
+static void dirtylimit_calc_func(void)
+{
+CPUState *cpu;
+DirtyPageRecord *dirty_pages;
+int64_t start_time, end_time, calc_time;
+DirtyRateVcpu rate;
+int i = 0;
+
+dirty_pages = g_malloc0(sizeof(*dirty_pages) *
+dirtylimit_calc_state->data.nvcpu);
+
+dirtylimit_global_dirty_log_start();
+
+CPU_FOREACH(cpu) {
+record_dirtypages(dirty_pages, cpu, true);
+}
+
+start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+g_usleep(DIRTYLIMIT_CALC_TIME_MS * 1000);
+end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+calc_time = end_time - start_time;
+
+dirtylimit_global_dirty_log_stop();
+
+CPU_FOREACH(cpu) {
+record_dirtypages(dirty_pages, cpu, false);
+}
+
+for (i = 0; i < dirtylimit_calc_state->data.nvcpu; i++) {
+uint64_t increased_dirty_pages =
+dirty_pages[i].end_pages - dirty_pages[i].start_pages;
+uint64_t memory_size_MB =
+(increased_dirty_pages * TARGET_PAGE_SIZE) >> 20;
+int64_t dirtyrate = (memory_size_MB * 1000) / calc_time;
+
+rate.id = i;
+rate.dirty_rate  = dirtyrate;
+dirtylimit_calc_state->data.rates[i] = rate;
+
+trace_dirtyrate_do_calculate_vcpu(i,
+dirtylimit_calc_state->data.rates[i].dirty_rate);
+}
+}
+
+static void *dirtylimit_calc_thread(void 

[PATCH v2 3/3] cpus-common: implement dirty limit on vCPU

2021-11-18 Thread huangy81
From: Hyman Huang(黄勇) 

implement dirtyrate calculation periodically basing on
dirty-ring and throttle vCPU until it reachs the quota
dirtyrate given by user.

introduce qmp commands set-dirty-limit/cancel-dirty-limit to
set/cancel dirty limit on vCPU.

Signed-off-by: Hyman Huang(黄勇) 
---
 cpus-common.c | 41 +
 include/hw/core/cpu.h |  7 +++
 qapi/misc.json| 44 
 softmmu/vl.c  |  1 +
 4 files changed, 93 insertions(+)

diff --git a/cpus-common.c b/cpus-common.c
index 6e73d3e..e32612b 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -23,6 +23,11 @@
 #include "hw/core/cpu.h"
 #include "sysemu/cpus.h"
 #include "qemu/lockable.h"
+#include "sysemu/dirtylimit.h"
+#include "sysemu/cpu-throttle.h"
+#include "sysemu/kvm.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-misc.h"
 
 static QemuMutex qemu_cpu_list_lock;
 static QemuCond exclusive_cond;
@@ -352,3 +357,39 @@ void process_queued_cpu_work(CPUState *cpu)
 qemu_mutex_unlock(>work_mutex);
 qemu_cond_broadcast(_work_cond);
 }
+
+void qmp_set_dirty_limit(int64_t idx,
+ uint64_t dirtyrate,
+ Error **errp)
+{
+if (!kvm_dirty_ring_enabled()) {
+error_setg(errp, "dirty ring not enable, needed by dirty restraint!");
+return;
+}
+
+dirtylimit_calc();
+dirtylimit_vcpu(idx, dirtyrate);
+}
+
+void qmp_cancel_dirty_limit(int64_t idx,
+Error **errp)
+{
+if (!kvm_dirty_ring_enabled()) {
+error_setg(errp, "dirty ring not enable, needed by dirty restraint!");
+return;
+}
+
+if (unlikely(!dirtylimit_cancel_vcpu(idx))) {
+dirtylimit_calc_quit();
+}
+}
+
+void dirtylimit_setup(int max_cpus)
+{
+if (!kvm_dirty_ring_enabled()) {
+return;
+}
+
+dirtylimit_calc_state_init(max_cpus);
+dirtylimit_state_init(max_cpus);
+}
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index e948e81..dd65e9e 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -881,6 +881,13 @@ void end_exclusive(void);
  */
 void qemu_init_vcpu(CPUState *cpu);
 
+/**
+ * dirtylimit_setup:
+ *
+ * dirtylimit setup.
+ */
+void dirtylimit_setup(int max_cpus);
+
 #define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */
 #define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */
 #define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */
diff --git a/qapi/misc.json b/qapi/misc.json
index 358548a..7f6da34 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -527,3 +527,47 @@
  'data': { '*option': 'str' },
  'returns': ['CommandLineOptionInfo'],
  'allow-preconfig': true }
+
+##
+# @DirtyRateQuotaVcpu:
+#
+# Dirty rate of vcpu.
+#
+# @idx: vcpu index.
+#
+# @dirtyrate: dirty rate.
+#
+# Since: 6.3
+#
+##
+{ 'struct': 'DirtyRateQuotaVcpu',
+  'data': { 'idx': 'int', 'dirtyrate': 'uint64' } }
+
+##
+# @set-dirty-limit:
+#
+# Since: 6.3
+#
+# Example:
+#   {"execute": "set-dirty-limit"}
+#"arguments": { "idx": "cpu-index",
+#   "dirtyrate": "quota-dirtyrate" } }
+#
+##
+{ 'command': 'set-dirty-limit',
+  'data': 'DirtyRateQuotaVcpu' }
+
+##
+# @cancel-dirty-limit:
+#
+# @idx: index of vCPU to be canceled
+#
+# Since: 6.3
+#
+# Example:
+#   {"execute": "cancel-dirty-limit"}
+#"arguments": { "idx": "cpu-index" } }
+#
+##
+{ 'command': 'cancel-dirty-limit',
+  'data': { 'idx': 'int' } }
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 1159a64..170ee23 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -3776,5 +3776,6 @@ void qemu_init(int argc, char **argv, char **envp)
 qemu_init_displays();
 accel_setup_post(current_machine);
 os_setup_post();
+dirtylimit_setup(current_machine->smp.max_cpus);
 resume_mux_open();
 }
-- 
1.8.3.1




[PATCH v2 2/3] cpu-throttle: implement vCPU throttle

2021-11-18 Thread huangy81
From: Hyman Huang(黄勇) 

impose dirty restraint on vCPU by kicking it and sleep
as the auto-converge does during migration, but just
kick the specified vCPU instead, not all vCPUs of vm.

start a thread to track the dirtylimit status and adjust
the throttle pencentage dynamically depend on current
and quota dirtyrate.

introduce the util function in the header for dirtylimit
implementation.

Signed-off-by: Hyman Huang(黄勇) 
---
 include/sysemu/cpu-throttle.h |  23 +++
 softmmu/cpu-throttle.c| 319 ++
 softmmu/trace-events  |   5 +
 3 files changed, 347 insertions(+)

diff --git a/include/sysemu/cpu-throttle.h b/include/sysemu/cpu-throttle.h
index d65bdef..726c1ce 100644
--- a/include/sysemu/cpu-throttle.h
+++ b/include/sysemu/cpu-throttle.h
@@ -65,4 +65,27 @@ bool cpu_throttle_active(void);
  */
 int cpu_throttle_get_percentage(void);
 
+/**
+ * dirtylimit_state_init:
+ *
+ * initialize golobal state for dirtylimit
+ */
+void dirtylimit_state_init(int max_cpus);
+
+/**
+ * dirtylimit_vcpu:
+ *
+ * impose dirtylimit on vcpu util reaching the quota dirtyrate
+ */
+void dirtylimit_vcpu(int cpu_index,
+ uint64_t quota);
+/**
+ * dirtylimit_cancel_vcpu:
+ *
+ * cancel dirtylimit for the specified vcpu
+ *
+ * Returns: the number of running threads for dirtylimit
+ */
+int dirtylimit_cancel_vcpu(int cpu_index);
+
 #endif /* SYSEMU_CPU_THROTTLE_H */
diff --git a/softmmu/cpu-throttle.c b/softmmu/cpu-throttle.c
index 8c2144a..a5e67c9 100644
--- a/softmmu/cpu-throttle.c
+++ b/softmmu/cpu-throttle.c
@@ -29,6 +29,8 @@
 #include "qemu/main-loop.h"
 #include "sysemu/cpus.h"
 #include "sysemu/cpu-throttle.h"
+#include "sysemu/dirtylimit.h"
+#include "trace.h"
 
 /* vcpu throttling controls */
 static QEMUTimer *throttle_timer;
@@ -38,6 +40,323 @@ static unsigned int throttle_percentage;
 #define CPU_THROTTLE_PCT_MAX 99
 #define CPU_THROTTLE_TIMESLICE_NS 1000
 
+#define DIRTYLIMIT_TOLERANCE_RANGE  15  /* 15MB/s */
+
+#define DIRTYLIMIT_THROTTLE_HEAVY_WATERMARK 75
+#define DIRTYLIMIT_THROTTLE_SLIGHT_WATERMARK90
+
+#define DIRTYLIMIT_THROTTLE_HEAVY_STEP_SIZE 5
+#define DIRTYLIMIT_THROTTLE_SLIGHT_STEP_SIZE2
+
+typedef enum {
+RESTRAIN_KEEP,
+RESTRAIN_RATIO,
+RESTRAIN_HEAVY,
+RESTRAIN_SLIGHT,
+} RestrainPolicy;
+
+typedef struct DirtyLimitState {
+int cpu_index;
+bool enabled;
+uint64_t quota; /* quota dirtyrate MB/s */
+QemuThread thread;
+char *name; /* thread name */
+} DirtyLimitState;
+
+struct {
+DirtyLimitState *states;
+int max_cpus;
+unsigned long *bmap; /* running thread bitmap */
+unsigned long nr;
+} *dirtylimit_state;
+
+static inline bool dirtylimit_enabled(int cpu_index)
+{
+return qatomic_read(_state->states[cpu_index].enabled);
+}
+
+static inline void dirtylimit_set_quota(int cpu_index, uint64_t quota)
+{
+qatomic_set(_state->states[cpu_index].quota, quota);
+}
+
+static inline uint64_t dirtylimit_quota(int cpu_index)
+{
+return qatomic_read(_state->states[cpu_index].quota);
+}
+
+static int64_t dirtylimit_current(int cpu_index)
+{
+return dirtylimit_calc_current(cpu_index);
+}
+
+static void dirtylimit_vcpu_thread(CPUState *cpu, run_on_cpu_data data)
+{
+double pct;
+double throttle_ratio;
+int64_t sleeptime_ns, endtime_ns;
+int *percentage = (int *)data.host_ptr;
+
+pct = (double)(*percentage) / 100;
+throttle_ratio = pct / (1 - pct);
+/* Add 1ns to fix double's rounding error (like 0.999...) */
+sleeptime_ns = (int64_t)(throttle_ratio * CPU_THROTTLE_TIMESLICE_NS + 1);
+endtime_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + sleeptime_ns;
+while (sleeptime_ns > 0 && !cpu->stop) {
+if (sleeptime_ns > SCALE_MS) {
+qemu_cond_timedwait_iothread(cpu->halt_cond,
+ sleeptime_ns / SCALE_MS);
+} else {
+qemu_mutex_unlock_iothread();
+g_usleep(sleeptime_ns / SCALE_US);
+qemu_mutex_lock_iothread();
+}
+sleeptime_ns = endtime_ns - qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+}
+qatomic_set(>throttle_thread_scheduled, 0);
+
+free(percentage);
+}
+
+static void dirtylimit_check(int cpu_index,
+ int percentage)
+{
+CPUState *cpu;
+int64_t sleeptime_ns, starttime_ms, currenttime_ms;
+int *pct_parameter;
+double pct;
+
+pct = (double) percentage / 100;
+
+starttime_ms = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+
+while (true) {
+CPU_FOREACH(cpu) {
+if ((cpu_index == cpu->cpu_index) &&
+(!qatomic_xchg(>throttle_thread_scheduled, 1))) {
+pct_parameter = malloc(sizeof(*pct_parameter));
+*pct_parameter = percentage;
+async_run_on_cpu(cpu, dirtylimit_vcpu_thread,
+ RUN_ON_CPU_HOST_PTR(pct_parameter));
+

Re: [qemu-web PATCH] remove deployment phase from CI

2021-11-18 Thread Willian Rampazzo
On Thu, Nov 18, 2021 at 4:50 AM Paolo Bonzini  wrote:
>
> qemu.org is now served via a reverse proxy from qemu-project.gitlab.io; it 
> does
> not need anymore the rsync step to the QEMU project's shell server.
> Remove it from the CI.
>
> Signed-off-by: Paolo Bonzini 
> ---
>  .gitlab-ci.yml | 24 
>  1 file changed, 24 deletions(-)
>

Reviewed-by: Willian Rampazzo 




device-crash-test

2021-11-18 Thread John Snow
I finally squashed all of the bugs and got a clean run of device-crash-test
with a full build of QEMU, over 182,000 individual test cases.

Here's all of the legitimate failures I saw:

CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=none
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine none,accel=kvm -device
sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x55b1c9dcad90 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=x-remote
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine x-remote,accel=kvm
-device sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x559b43269d40 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-x86_64 accel=kvm machine=microvm
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine microvm,accel=kvm
-device sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x55760ca941b0 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=none
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine none,accel=tcg -device
sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x557a52333d90 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=x-remote
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine x-remote,accel=tcg
-device sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x55bbcd596d40 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-x86_64 accel=tcg machine=microvm
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-x86_64 -S -machine microvm,accel=tcg
-device sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x55ca35c081b0 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-mips64el accel=tcg machine=pica61
device=isa-cirrus-vga
CRITICAL: cmdline: ./qemu-system-mips64el -S -machine pica61,accel=tcg
-device isa-cirrus-vga
CRITICAL: log: RAMBlock "vga.vram" already registered, abort!
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=none
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-i386 -S -machine none,accel=kvm -device
sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x55d0e0a03d90 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=x-remote
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-i386 -S -machine x-remote,accel=kvm
-device sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x564648250b30 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-i386 accel=kvm machine=microvm
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-i386 -S -machine microvm,accel=kvm -device
sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x55bef7a235b0 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=none
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-i386 -S -machine none,accel=tcg -device
sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x5608b9fecd90 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=x-remote
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-i386 -S -machine x-remote,accel=tcg
-device sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x558306c9cb30 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-i386 accel=tcg machine=microvm
device=sgx-epc
CRITICAL: cmdline: ./qemu-system-i386 -S -machine microvm,accel=tcg -device
sgx-epc
CRITICAL: log: /home/jsnow/src/qemu/include/hw/i386/pc.h:128:PC_MACHINE:
Object 0x55e041f465b0 is not an instance of type generic-pc-machine
CRITICAL: exit code: -6

CRITICAL: failed: binary=./qemu-system-mips64 accel=tcg machine=pica61
device=isa-cirrus-vga
CRITICAL: cmdline: ./qemu-system-mips64 -S -machine pica61,accel=tcg
-device isa-cirrus-vga
CRITICAL: log: RAMBlock "vga.vram" already registered, abort!
CRITICAL: exit code: -6


--js


Re: [PATCH v5 0/6] Add vmnet.framework based network backend

2021-11-18 Thread Vladislav Yaroshchuk
ср, 17 нояб. 2021 г. в 09:10, Jason Wang :

> On Tue, Nov 16, 2021 at 11:30 PM Vladislav Yaroshchuk
>  wrote:
> >
> >
> >
> > вт, 16 нояб. 2021 г. в 10:23, Jason Wang :
> >>
> >> On Mon, Nov 15, 2021 at 6:45 PM Vladislav Yaroshchuk
> >>  wrote:
> >> >
> >> >
> >> >
> >> > пн, 15 нояб. 2021 г. в 07:53, Jason Wang :
> >> >>
> >> >> On Fri, Nov 12, 2021 at 5:14 PM Vladislav Yaroshchuk
> >> >>  wrote:
> >> >> >
> >> >> > macOS provides networking API for VMs called 'vmnet.framework':
> >> >> > https://developer.apple.com/documentation/vmnet
> >> >> >
> >> >> > We can provide its support as the new QEMU network backends which
> >> >> > represent three different vmnet.framework interface usage modes:
> >> >> >
> >> >> >   * `vmnet-shared`:
> >> >> > allows the guest to communicate with other guests in shared
> mode and
> >> >> > also with external network (Internet) via NAT. Has
> (macOS-provided)
> >> >> > DHCP server; subnet mask and IP range can be configured;
> >> >> >
> >> >> >   * `vmnet-host`:
> >> >> > allows the guest to communicate with other guests in host mode.
> >> >> > By default has enabled DHCP as `vmnet-shared`, but providing
> >> >> > network unique id (uuid) can make `vmnet-host` interfaces
> isolated
> >> >> > from each other and also disables DHCP.
> >> >> >
> >> >> >   * `vmnet-bridged`:
> >> >> > bridges the guest with a physical network interface.
> >> >> >
> >> >> > This backends cannot work on macOS Catalina 10.15 cause we use
> >> >> > vmnet.framework API provided only with macOS 11 and newer. Seems
> >> >> > that it is not a problem, because QEMU guarantees to work on two
> most
> >> >> > recent versions of macOS which now are Big Sur (11) and Monterey
> (12).
> >> >> >
> >> >> > Also, we have one inconvenient restriction: vmnet.framework
> interfaces
> >> >> > can create only privileged user:
> >> >> > `$ sudo qemu-system-x86_64 -nic vmnet-shared`
> >> >> >
> >> >> > Attempt of `vmnet-*` netdev creation being unprivileged user fails
> with
> >> >> > vmnet's 'general failure'.
> >> >> >
> >> >> > This happens because vmnet.framework requires
> `com.apple.vm.networking`
> >> >> > entitlement which is: "restricted to developers of virtualization
> software.
> >> >> > To request this entitlement, contact your Apple representative."
> as Apple
> >> >> > documentation says:
> >> >> >
> https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_vm_networking
> >> >>
> >> >> Do you know how multipass work? Looks like it uses vmnet without
> privileges.
> >> >>
> >> >
> >> > I've just checked this, and they still need root privileges. They
> have a
> >> > `multipassd` daemon which is launched as root by launchd by default.
> >> >
> >> > ```
> >> > bash-5.1$ ps axo ruser,ruid,comm | grep multipass
> >> > root 0 /Library/Application
> Support/com.canonical.multipass/bin/multipassd
> >> > root 0 /Library/Application
> Support/com.canonical.multipass/bin/hyperkit
> >> > ```
> >> >
> >> > That's the reason why it's required to 'enter a password' while
> multipass installation:
> >> > it creates launchd plist (kinda launch rule) and places it to
> /Library/LaunchDaemons/,
> >> > which can be done only with root privileges.
> >> >
> >> > ```
> >> > bash-5.1$ ll /Library/LaunchDaemons | grep multipass
> >> > -rw-r--r--   1 root  wheel   1.1K 15 Nov 12:47
> com.canonical.multipassd.plist
> >> > ```
> >> >
> >> > And after this launchd launches this multipassd daemon as root every
> boot.
> >> >
> >> > So an unprivileged user can launch a multipass VM instance, but
> actually the
> >> > `hyperkit` process which interacts with vmnet is gonna be launched by
> multipassd
> >> > running as root.
> >>
> >> I wonder how it passes the vmnet object to qemu? Nothing obvious from
> >> the qemu command line that multipass launched:
> >>
> >> -nic vmnet-macos,mode=shared,model=virtio-net-pci,mac=52:54:00:52:e8:e4
> >>
> >> (But I haven't had time to check their qemu codes).
> >>
> >
> > It seems they just use QEMU with patch by Phillip Tennen:
> > https://patchew.org/QEMU/20210218134947.1860-1-phillip.en...@gmail.com/
> >
> > In that patch he does quite the same as we in this series, the
> > difference remains in foreground: he creates one new 'vmnet-macos'
> > netdev, and uses 'mode=shared' property to choose vmnet
> > operating mode. I decided to create three different netdevs instead
> > (vmnet-shared, vmnet-host, vmnet-bridged). Also I've added some
> > features related to isolation and ipv6.
>
> Ok.
>
> >
> > > I wonder how it passes the vmnet object to qemu
> > I hope I clearly described this.
>
> A silly question, how did the 'hyperkit' process pass the vmnet object to
> qemu?
>
> I think I didn't describe it very well in the previous mail.
The 'hyperkit' and QEMU are two multipass 'drivers'.

hyperkit is an independent hypervisor based on xhyve (bhyve):
https://github.com/moby/hyperkit

So there are many ways to launch 

Re: [PATCH] hw/i2c: add pca9543 support to mux

2021-11-18 Thread Patrick Venture
On Mon, Nov 8, 2021 at 1:58 PM Patrick Venture  wrote:

> Adds support for the 2 channel pca9543 i2c switch.
>
> Signed-off-by: Patrick Venture 
> ---
>  hw/i2c/i2c_mux_pca954x.c | 12 
>  include/hw/i2c/i2c_mux_pca954x.h |  1 +
>  2 files changed, 13 insertions(+)
>
> diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
> index 847c59921c..36a5c8cb31 100644
> --- a/hw/i2c/i2c_mux_pca954x.c
> +++ b/hw/i2c/i2c_mux_pca954x.c
> @@ -29,6 +29,7 @@
>
>  #define PCA9548_CHANNEL_COUNT 8
>  #define PCA9546_CHANNEL_COUNT 4
> +#define PCA9543_CHANNEL_COUNT 2
>
>  /*
>   * struct Pca954xChannel - The i2c mux device will have N of these states
> @@ -203,6 +204,12 @@ static void pca954x_channel_class_init(ObjectClass
> *klass, void *data)
>  dc->desc = "Pca954x Channel";
>  }
>
> +static void pca9543_class_init(ObjectClass *klass, void *data)
> +{
> +Pca954xClass *s = PCA954X_CLASS(klass);
> +s->nchans = PCA9543_CHANNEL_COUNT;
> +}
> +
>  static void pca9546_class_init(ObjectClass *klass, void *data)
>  {
>  Pca954xClass *s = PCA954X_CLASS(klass);
> @@ -268,6 +275,11 @@ static const TypeInfo pca954x_info[] = {
>  .class_init= pca954x_class_init,
>  .abstract  = true,
>  },
> +{
> +.name  = TYPE_PCA9543,
> +.parent= TYPE_PCA954X,
> +.class_init= pca9543_class_init,
> +},
>  {
>  .name  = TYPE_PCA9546,
>  .parent= TYPE_PCA954X,
> diff --git a/include/hw/i2c/i2c_mux_pca954x.h
> b/include/hw/i2c/i2c_mux_pca954x.h
> index 8aaf9bbc39..91e2ffd0a2 100644
> --- a/include/hw/i2c/i2c_mux_pca954x.h
> +++ b/include/hw/i2c/i2c_mux_pca954x.h
> @@ -3,6 +3,7 @@
>
>  #include "hw/i2c/i2c.h"
>
> +#define TYPE_PCA9543 "pca9543"
>  #define TYPE_PCA9546 "pca9546"
>  #define TYPE_PCA9548 "pca9548"
>
> --
> 2.34.0.rc0.344.g81b53c2807-goog
>
> Friendly ping. The patch itself is trivial, but let me know if I've
submitted it incorrectly since I also maintain this device.

-Patrick


Re: [PATCH v5 3/6] net/vmnet: implement shared mode (vmnet-shared)

2021-11-18 Thread Vladislav Yaroshchuk
пн, 15 нояб. 2021 г. в 07:47, Jason Wang :

> On Fri, Nov 12, 2021 at 5:14 PM Vladislav Yaroshchuk
>  wrote:
> >
> > Signed-off-by: Phillip Tennen 
> > Signed-off-by: Vladislav Yaroshchuk 
> > ---
>
> Commit log please.
>
>
>
Sorry, I don't understand what you mean here.
What is the 'commit log'?


> >  net/vmnet-common.m | 305 +
> >  net/vmnet-shared.c |  75 ++-
> >  net/vmnet_int.h|  23 
> >  3 files changed, 399 insertions(+), 4 deletions(-)
> >
> > diff --git a/net/vmnet-common.m b/net/vmnet-common.m
> > index 532d152840..b058e1b846 100644
> > --- a/net/vmnet-common.m
> > +++ b/net/vmnet-common.m
> > @@ -10,6 +10,8 @@
> >   */
> >
> >  #include "qemu/osdep.h"
> > +#include "qemu/main-loop.h"
> > +#include "qemu/log.h"
> >  #include "qapi/qapi-types-net.h"
> >  #include "vmnet_int.h"
> >  #include "clients.h"
> > @@ -17,4 +19,307 @@
> >  #include "qapi/error.h"
> >
> >  #include 
> > +#include 
> >
> > +#ifdef DEBUG
> > +#define D(x) x
> > +#define D_LOG(...) qemu_log(__VA_ARGS__)
> > +#else
> > +#define D(x) do { } while (0)
> > +#define D_LOG(...) do { } while (0)
> > +#endif
> > +
> > +typedef struct vmpktdesc vmpktdesc_t;
> > +typedef struct iovec iovec_t;
> > +
> > +static void vmnet_set_send_enabled(VmnetCommonState *s, bool enable)
> > +{
> > +s->send_enabled = enable;
>
> Is there a way to disable the event when enable is false?
>
>
It seems there's no way except setting/unsetting
the callback via `vmnet_interface_set_event_callback`.
I decided to drop packages using `s->send_enabled`
without dealing with the callback.

> +}
> > +
> > +
> > +static void vmnet_send_completed(NetClientState *nc, ssize_t len)
> > +{
> > +VmnetCommonState *s = DO_UPCAST(VmnetCommonState, nc, nc);
> > +vmnet_set_send_enabled(s, true);
> > +}
> > +
> > +
> > +static void vmnet_send(NetClientState *nc,
> > +   interface_event_t event_id,
> > +   xpc_object_t event)
> > +{
> > +assert(event_id == VMNET_INTERFACE_PACKETS_AVAILABLE);
> > +
> > +VmnetCommonState *s;
> > +uint64_t packets_available;
> > +
> > +struct iovec *iov;
> > +struct vmpktdesc *packets;
> > +int pkt_cnt;
> > +int i;
> > +
> > +vmnet_return_t if_status;
> > +ssize_t size;
> > +
> > +s = DO_UPCAST(VmnetCommonState, nc, nc);
> > +
> > +packets_available = xpc_dictionary_get_uint64(
> > +event,
> > +vmnet_estimated_packets_available_key
> > +);
> > +
> > +pkt_cnt = (packets_available < VMNET_PACKETS_LIMIT) ?
> > +  packets_available :
> > +  VMNET_PACKETS_LIMIT;
> > +
> > +
> > +iov = s->iov_buf;
> > +packets = s->packets_buf;
> > +
> > +for (i = 0; i < pkt_cnt; ++i) {
> > +packets[i].vm_pkt_size = s->max_packet_size;
> > +packets[i].vm_pkt_iovcnt = 1;
> > +packets[i].vm_flags = 0;
> > +}
> > +
> > +if_status = vmnet_read(s->vmnet_if, packets, _cnt);
> > +if (if_status != VMNET_SUCCESS) {
> > +error_printf("vmnet: read failed: %s\n",
> > + vmnet_status_map_str(if_status));
> > +}
> > +qemu_mutex_lock_iothread();
> > +for (i = 0; i < pkt_cnt; ++i) {
> > +size = qemu_send_packet_async(nc,
> > +  iov[i].iov_base,
> > +  packets[i].vm_pkt_size,
> > +  vmnet_send_completed);
> > +if (size == 0) {
> > +vmnet_set_send_enabled(s, false);
> > +} else if (size < 0) {
> > +break;
> > +}
> > +}
> > +qemu_mutex_unlock_iothread();
> > +
> > +}
> > +
> > +
> > +static void vmnet_register_event_callback(VmnetCommonState *s)
> > +{
> > +dispatch_queue_t avail_pkt_q = dispatch_queue_create(
> > +"org.qemu.vmnet.if_queue",
> > +DISPATCH_QUEUE_SERIAL
> > +);
> > +
> > +vmnet_interface_set_event_callback(
> > +s->vmnet_if,
> > +VMNET_INTERFACE_PACKETS_AVAILABLE,
> > +avail_pkt_q,
> > +^(interface_event_t event_id, xpc_object_t event) {
> > +  if (s->send_enabled) {
> > +  vmnet_send(>nc, event_id, event);
> > +  }
> > +});
> > +}
> > +
> > +
> > +static void vmnet_bufs_init(VmnetCommonState *s)
> > +{
> > +int i;
> > +struct vmpktdesc *packets;
> > +struct iovec *iov;
> > +
> > +packets = s->packets_buf;
> > +iov = s->iov_buf;
> > +
> > +for (i = 0; i < VMNET_PACKETS_LIMIT; ++i) {
> > +iov[i].iov_len = s->max_packet_size;
> > +iov[i].iov_base = g_malloc0(iov[i].iov_len);
> > +packets[i].vm_pkt_iov = iov + i;
> > +}
> > +}
> > +
> > +
> > +const char *vmnet_status_map_str(vmnet_return_t status)
> > +{
> > +switch (status) {
> > +case VMNET_SUCCESS:
> > +return "success";
> > +case VMNET_FAILURE:
> > +return "general failure";
> > +case 

[qemu-web PATCH] Update URLs of "SubmitAPatch" wiki doc

2021-11-18 Thread Kashyap Chamarthy
We've recently converted[1] the "SubmitAPatch" page from Wiki to in-tree
docs.  So update the website to reflect this.

[1] https://gitlab.com/qemu-project/qemu/-/commit/9f73de8df03 --
9f73de8df0 (docs: rSTify the "SubmitAPatch" wiki, 2021-11-10)

Signed-off-by: Kashyap Chamarthy 
---
 CONTRIBUTING.md| 2 +-
 contribute.md  | 2 +-
 contribute/report-a-bug.md | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d5cbf07..b6fc0bd 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -12,7 +12,7 @@ You should also CC the website maintainers:
 
 For further guidance on sending patches consult:
 
-https://wiki.qemu.org/Contribute/SubmitAPatch
+https://qemu-project.gitlab.io/qemu/devel/submitting-a-patch.html
 
 It is expected that contributors check the rendered website before submitting
 patches. This is possible by either running jekyll locally, or by using the
diff --git a/contribute.md b/contribute.md
index 4802452..77cd5f4 100644
--- a/contribute.md
+++ b/contribute.md
@@ -17,6 +17,6 @@ permalink: /contribute/
   [Contributor FAQ](https://wiki.qemu.org/Contribute/FAQ),
   [Improve the 
website](https://www.qemu.org/2017/02/04/the-new-qemu-website-is-up/)
 
-Please do not submit merge requests on GitLab; patches are sent to the mailing 
list according to QEMU's [patch submissions 
guidelines](https://wiki.qemu.org/Contribute/SubmitAPatch).
+Please do not submit merge requests on GitLab; patches are sent to the mailing 
list according to QEMU's [patch submissions 
guidelines](https://qemu-project.gitlab.io/qemu/devel/submitting-a-patch.html).
 
 Contributing to QEMU is subject to the [QEMU Code of 
Conduct](https://qemu.org/docs/master/devel/code-of-conduct.html).
diff --git a/contribute/report-a-bug.md b/contribute/report-a-bug.md
index 96b60d8..b24c759 100644
--- a/contribute/report-a-bug.md
+++ b/contribute/report-a-bug.md
@@ -18,7 +18,7 @@ When submitting a bug report, please try to do the following:
 
 * Include information about the host and guest (operating system, version, 
32/64-bit).
 
-QEMU does not use GitLab merge requests; patches are sent to the mailing list 
according to QEMU's [patch submissions 
guidelines](https://wiki.qemu.org/Contribute/SubmitAPatch).
+QEMU does not use GitLab merge requests; patches are sent to the mailing list 
according to QEMU's [patch submissions 
guidelines](https://qemu-project.gitlab.io/qemu/devel/submitting-a-patch.html).
 
 Do NOT report security issues (or other bugs, too) as "confidential" bugs in 
the
 bug tracker.  QEMU has a [security process](../security-process) for issues
-- 
2.31.1




Re: [PULL 0/6 for-6.2] AMD SEV patches

2021-11-18 Thread Richard Henderson

On 11/18/21 2:35 PM, Daniel P. Berrangé wrote:

The following changes since commit 0055ecca84cb948c935224b4f7ca1ceb26209790:

   Merge tag 'vfio-fixes-2027.0' of git://github.com/awilliam/qemu-vfio 
into staging (2021-11-18 09:39:47 +0100)

are available in the Git repository at:

   https://gitlab.com/berrange/qemu tags/sev-hashes-pull-request

for you to fetch changes up to 58603ba2680fa35eade630e4b040e96953a11021:

   target/i386/sev: Replace qemu_map_ram_ptr with address_space_map (2021-11-18 
13:28:32 +)


Add property for requesting AMD SEV measured kernel launch

  - The 'sev-guest' object gains a boolean 'kernel-hashes' property
which must be enabled to request a measured kernel launch.



Dov Murik (6):
   qapi/qom,target/i386: sev-guest: Introduce kernel-hashes=on|off option
   target/i386/sev: Add kernel hashes only if sev-guest.kernel-hashes=on
   target/i386/sev: Rephrase error message when no hashes table in guest
 firmware
   target/i386/sev: Fail when invalid hashes table area detected
   target/i386/sev: Perform padding calculations at compile-time
   target/i386/sev: Replace qemu_map_ram_ptr with address_space_map

  qapi/qom.json |  7 -
  qemu-options.hx   |  6 +++-
  target/i386/sev.c | 79 +++
  3 files changed, 77 insertions(+), 15 deletions(-)


Applied, thanks.


r~




Re: [PATCH] nvmm: Fix support for stable version

2021-11-18 Thread nia
Ping? It would be very nice if this could make it into 6.2
so we don't have to continue patching around this.

On Tue, Nov 02, 2021 at 10:12:28AM +0100, Kamil Rytarowski wrote:
> Reviewed-by: Kamil Rytarowski 
> 
> Paolo, could you please merge it?
> 
> On 13.10.2021 15:54, nia wrote:
> > NVMM user version 1 is the version being shipped with netbsd-9,
> > which is the most recent stable branch of NetBSD. This makes it
> > possible to use the NVMM accelerator on the most recent NetBSD
> > release, 9.2, which lacks nvmm_cpu_stop.
> > 
> > (CC'ing maintainers)
> > 
> > Signed-off-by: Nia Alarie 
> > ---
> >  meson.build |  4 +---
> >  target/i386/nvmm/nvmm-all.c | 10 ++
> >  2 files changed, 11 insertions(+), 3 deletions(-)
> > 
> > diff --git a/meson.build b/meson.build
> > index 15ef4d3c41..6e4d9b919a 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -244,9 +244,7 @@ if not get_option('hax').disabled()
> >endif
> >  endif
> >  if targetos == 'netbsd'
> > -  if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: 
> > get_option('nvmm'))
> > -nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
> > -  endif
> > +  nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
> >if nvmm.found()
> >  accelerators += 'CONFIG_NVMM'
> >endif
> > diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c
> > index a488b00e90..4a10412427 100644
> > --- a/target/i386/nvmm/nvmm-all.c
> > +++ b/target/i386/nvmm/nvmm-all.c
> > @@ -750,7 +750,11 @@ nvmm_vcpu_loop(CPUState *cpu)
> >  nvmm_vcpu_pre_run(cpu);
> >  
> >  if (qatomic_read(>exit_request)) {
> > +#if NVMM_USER_VERSION >= 2
> >  nvmm_vcpu_stop(vcpu);
> > +#else
> > +qemu_cpu_kick_self();
> > +#endif
> >  }
> >  
> >  /* Read exit_request before the kernel reads the immediate exit 
> > flag */
> > @@ -767,6 +771,7 @@ nvmm_vcpu_loop(CPUState *cpu)
> >  switch (exit->reason) {
> >  case NVMM_VCPU_EXIT_NONE:
> >  break;
> > +#if NVMM_USER_VERSION >= 2
> >  case NVMM_VCPU_EXIT_STOPPED:
> >  /*
> >   * The kernel cleared the immediate exit flag; 
> > cpu->exit_request
> > @@ -775,6 +780,7 @@ nvmm_vcpu_loop(CPUState *cpu)
> >  smp_wmb();
> >  qcpu->stop = true;
> >  break;
> > +#endif
> >  case NVMM_VCPU_EXIT_MEMORY:
> >  ret = nvmm_handle_mem(mach, vcpu);
> >  break;
> > @@ -888,8 +894,12 @@ nvmm_ipi_signal(int sigcpu)
> >  {
> >  if (current_cpu) {
> >  struct qemu_vcpu *qcpu = get_qemu_vcpu(current_cpu);
> > +#if NVMM_USER_VERSION >= 2
> >  struct nvmm_vcpu *vcpu = >vcpu;
> >  nvmm_vcpu_stop(vcpu);
> > +#else
> > +qcpu->stop = true;
> > +#endif
> >  }
> >  }
> >  
> > 
> 



Re: [PATCH v2 2/2] iotests/149: Skip on unsupported ciphers

2021-11-18 Thread Hanna Reitz

On 17.11.21 16:46, Daniel P. Berrangé wrote:

On Wed, Nov 17, 2021 at 04:17:07PM +0100, Hanna Reitz wrote:

Whenever qemu-img or qemu-io report that some cipher is unsupported,
skip the whole test, because that is probably because qemu has been
configured with the gnutls crypto backend.

We could taylor the algorithm list to what gnutls supports, but this is
a test that is run rather rarely anyway (because it requires
password-less sudo), and so it seems better and easier to skip it.  When
this test is intentionally run to check LUKS compatibility, it seems
better not to limit the algorithms but keep the list extensive.

I'd really like to figure out a way to be able to partially run
this test. When I have hit problems in the past, I needed to
run specific tests, but then the expected output always contains
everything.  I've thought of a few options

  - Split it into many stanadlone tests - eg
  tests/qemu-iotests/tests/luks-host-$ALG


I wouldn’t hate it, though we should have some common file where common 
code can be sourced from.



  - Split only the expected output eg
  
  149-$SUBTEST


   and have a way to indicate which of expected output files
   we need to concatenate for the set of subtests that we
   run.


I’d prefer it if the test could verify its own output so that the 
reference output is basically just the usual unittest output of dots, 
“Ran XX tests” and “OK”.


(Two reasons: You can then easily disable some tests with the reference 
output changing only slightly; and it makes reviewing a test much easier 
because then I don’t need to verify the reference output...)



  - Introduce some template syntax in expected output
tha can be used to munge the output.

  - Stop comparing expected output entirely and just
then this into a normal python unit test.


That’s something that might indeed be useful for unittest-style iotests.

Then again, we already allow them to skip any test case and it will be 
counted as success, is that not sufficient?



  - Insert your idea here ?


I personally most prefer unittest-style tests, because with them you can 
just %s/def test_/def xtest_/, then reverse this change for all the 
cases you want to run, and then adjust the reference output to match the 
number of tests run.


So I suppose the best idea I have is to convert this test into unittest 
style, and then it should be more modular when it comes to what subtests 
it wants to run.


I mean, it doesn’t have to truly be an iotests.QMPTestCase.  It would be 
sufficient if the test itself verified the output of every command it 
invokes (instead of leaving that to a separate reference output file) 
and then printed something like “OK” afterwards.  Then we could 
trivially skip some cases just by printing “OK” even if they weren’t run.


Hanna




Re: [PULL 0/5] Python patches

2021-11-18 Thread John Snow
On Thu, Nov 18, 2021 at 1:46 AM Gerd Hoffmann  wrote:

>   Hi,
>
> > - Split python/qemu/qmp out into its own repository and begin uploading
> it
> > to PyPI, as a test. (Do not delete python/qemu/qmp yet at this phase.)
>
> I think you can do that as two separate steps.
>
> pip can install from vcs too, i.e. when splitted to a separate repo but
> not yet uploaded to pypi you can simply drop something like ...
>
> git+https://gitlab.com/qemu/qemu-python.git@master
>
> ... into pip-requirements.txt.  That way you can easily test things
> before actually uploading to pypi.
>
>
Indeed - a limitation here however is that pip will not install from this
source unless explicitly asked to, so you couldn't use this package as a
requirement for another one, for example -- but it works as a testing step.
but that's the rough outline of where I am headed and what I think needs to
be done to get there. It's just taking me a while to get everything put in
order exactly the right way to be able to flip the switch. Hopefully soon,
though.

I realized when re-reading my mails last night that I said I wouldn't be
able to do it until "next release" but what I really meant was "until the
next development window".

--js


Re: [PATCH-for-6.2?] docs: Render binary names as monospaced text

2021-11-18 Thread Eric Blake
On Thu, Nov 18, 2021 at 03:43:17PM +0100, Philippe Mathieu-Daudé wrote:
> Signed-off-by: Philippe Mathieu-Daudé 
> ---

> +++ b/docs/about/removed-features.rst
> @@ -658,8 +658,8 @@ enforce that any failure to open the backing image 
> (including if the
>  backing file is missing or an incorrect format was specified) is an
>  error when ``-u`` is not used.
>  
> -qemu-img amend to adjust backing file (removed in 6.1)
> -''
> +``qemu-img`` amend to adjust backing file (removed in 6.1)
> +''

Why quote just qemu-img here,

>  
>  The use of ``qemu-img amend`` to modify the name or format of a qcow2

when the context is obvious that it is the 'qemu-img amend' subcommand?

>  backing image was never fully documented or tested, and interferes
> @@ -670,8 +670,8 @@ backing chain should be performed with ``qemu-img rebase 
> -u`` either
>  before or after the remaining changes being performed by amend, as
>  appropriate.
>  
> -qemu-img backing file without format (removed in 6.1)
> -'
> +``qemu-img`` backing file without format (removed in 6.1)
> +'

This one makes sense, though, as "backing" is not a qemu-img subcommand.

>  
>  The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img
>  convert`` to create or modify an image that depends on a backing file
> diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
> index 7a83f5fc0db..431caba7aa0 100644
> --- a/docs/devel/build-system.rst
> +++ b/docs/tools/qemu-nbd.rst
> @@ -38,7 +38,7 @@ driver options if ``--image-opts`` is specified.
>supported. The common object types that it makes sense to define are the
>``secret`` object, which is used to supply passwords and/or encryption
>keys, and the ``tls-creds`` object, which is used to supply TLS
> -  credentials for the qemu-nbd server or client.
> +  credentials for the ``qemu-nbd`` server or client.
>  
>  .. option:: -p, --port=PORT
>  
> @@ -238,7 +238,7 @@ daemon:
>  Expose the guest-visible contents of a qcow2 file via a block device
>  /dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for
>  partitions found within), then disconnect the device when done.
> -Access to bind qemu-nbd to an /dev/nbd device generally requires root
> +Access to bind ``qemu-nbd`` to an /dev/nbd device generally requires root

As long as you're touching this line, s/an/a/.

>  privileges, and may also require the execution of ``modprobe nbd``
>  to enable the kernel NBD client module.  *CAUTION*: Do not use
>  this method to mount filesystems from an untrusted guest image - a

Overall looks like a nice changeset.

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




Re: [PATCH-for-6.2?] docs: Spell QEMU all caps

2021-11-18 Thread Markus Armbruster
Philippe Mathieu-Daudé  writes:

> Replace Qemu -> QEMU.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Markus Armbruster 




  1   2   3   >