Re: [PATCH 2/3] virtio-net: Only enable userland vq if using tap backend
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
> -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
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
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
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
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]
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
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
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)
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
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
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
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 下午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
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 上午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 上午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/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
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
ср, 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
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)
пн, 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
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
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
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
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
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
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
Philippe Mathieu-Daudé writes: > Replace Qemu -> QEMU. > > Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Markus Armbruster