diff --git a/9pfs-prevent-opening-special-files-CVE-2023-2861.patch b/9pfs-prevent-opening-special-files-CVE-2023-2861.patch deleted file mode 100644 index f19e039e8c56f05a20cd7f1287a8bf843d67b332..0000000000000000000000000000000000000000 --- a/9pfs-prevent-opening-special-files-CVE-2023-2861.patch +++ /dev/null @@ -1,172 +0,0 @@ -From beed3295acf786cec520a8a0aec5efcd2ca12b23 Mon Sep 17 00:00:00 2001 -From: liuxiangdong -Date: Fri, 14 Jul 2023 05:11:57 +0800 -Subject: [PATCH] 9pfs: prevent opening special files (CVE-2023-2861) The 9p - protocol does not specifically define how server shall behave when client - tries to open a special file, however from security POV it does make sense - for 9p server to prohibit opening any special file on host side in general. A - sane Linux 9p client for instance would never attempt to open a special file - on host side, it would always handle those exclusively on its guest side. A - malicious client however could potentially escape from the exported 9p tree - by creating and opening a device file on host side. - -With QEMU this could only be exploited in the following unsafe setups: - - - Running QEMU binary as root AND 9p 'local' fs driver AND 'passthrough' - security model. - -or - - - Using 9p 'proxy' fs driver (which is running its helper daemon as - root). - -These setups were already discouraged for safety reasons before, -however for obvious reasons we are now tightening behaviour on this. - -Fixes: CVE-2023-2861 -Reported-by: Yanwu Shen -Reported-by: Jietao Xiao -Reported-by: Jinku Li -Reported-by: Wenbo Shen -Signed-off-by: Christian Schoenebeck -Reviewed-by: Greg Kurz -Reviewed-by: Michael Tokarev -Message-Id: ---- - fsdev/virtfs-proxy-helper.c | 27 +++++++++++++++++++++++-- - hw/9pfs/9p-util.h | 40 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 65 insertions(+), 2 deletions(-) - -diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c -index 15c0e79b06..f9e4669a5b 100644 ---- a/fsdev/virtfs-proxy-helper.c -+++ b/fsdev/virtfs-proxy-helper.c -@@ -26,6 +26,7 @@ - #include "qemu/xattr.h" - #include "9p-iov-marshal.h" - #include "hw/9pfs/9p-proxy.h" -+#include "hw/9pfs/9p-util.h" - #include "fsdev/9p-iov-marshal.h" - - #define PROGNAME "virtfs-proxy-helper" -@@ -338,6 +339,28 @@ static void resetugid(int suid, int sgid) - } - } - -+/* -+ * Open regular file or directory. Attempts to open any special file are -+ * rejected. -+ * -+ * returns file descriptor or -1 on error -+ */ -+static int open_regular(const char *pathname, int flags, mode_t mode) -+{ -+ int fd; -+ -+ fd = open(pathname, flags, mode); -+ if (fd < 0) { -+ return fd; -+ } -+ -+ if (close_if_special_file(fd) < 0) { -+ return -1; -+ } -+ -+ return fd; -+} -+ - /* - * send response in two parts - * 1) ProxyHeader -@@ -682,7 +705,7 @@ static int do_create(struct iovec *iovec) - if (ret < 0) { - goto unmarshal_err_out; - } -- ret = open(path.data, flags, mode); -+ ret = open_regular(path.data, flags, mode); - if (ret < 0) { - ret = -errno; - } -@@ -707,7 +730,7 @@ static int do_open(struct iovec *iovec) - if (ret < 0) { - goto err_out; - } -- ret = open(path.data, flags); -+ ret = open_regular(path.data, flags, 0); - if (ret < 0) { - ret = -errno; - } -diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h -index 546f46dc7d..23000e917f 100644 ---- a/hw/9pfs/9p-util.h -+++ b/hw/9pfs/9p-util.h -@@ -13,12 +13,16 @@ - #ifndef QEMU_9P_UTIL_H - #define QEMU_9P_UTIL_H - -+#include "qemu/error-report.h" -+ - #ifdef O_PATH - #define O_PATH_9P_UTIL O_PATH - #else - #define O_PATH_9P_UTIL 0 - #endif - -+#define qemu_fstat fstat -+ - static inline void close_preserve_errno(int fd) - { - int serrno = errno; -@@ -26,6 +30,38 @@ static inline void close_preserve_errno(int fd) - errno = serrno; - } - -+/** -+ * close_if_special_file() - Close @fd if neither regular file nor directory. -+ * -+ * @fd: file descriptor of open file -+ * Return: 0 on regular file or directory, -1 otherwise -+ * -+ * CVE-2023-2861: Prohibit opening any special file directly on host -+ * (especially device files), as a compromised client could potentially gain -+ * access outside exported tree under certain, unsafe setups. We expect -+ * client to handle I/O on special files exclusively on guest side. -+ */ -+static inline int close_if_special_file(int fd) -+{ -+ struct stat stbuf; -+ -+ if (qemu_fstat(fd, &stbuf) < 0) { -+ close_preserve_errno(fd); -+ return -1; -+ } -+ if (!S_ISREG(stbuf.st_mode) && !S_ISDIR(stbuf.st_mode)) { -+ error_report_once( -+ "9p: broken or compromised client detected; attempt to open " -+ "special file (i.e. neither regular file, nor directory)" -+ ); -+ close(fd); -+ errno = ENXIO; -+ return -1; -+ } -+ -+ return 0; -+} -+ - static inline int openat_dir(int dirfd, const char *name) - { - return openat(dirfd, name, -@@ -56,6 +92,10 @@ again: - return -1; - } - -+ if (close_if_special_file(fd) < 0) { -+ return -1; -+ } -+ - serrno = errno; - /* O_NONBLOCK was only needed to open the file. Let's drop it. We don't - * do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat() --- -2.41.0.windows.1 - diff --git a/AVX512-support-for-xbzrle_encode_buffer.patch b/AVX512-support-for-xbzrle_encode_buffer.patch deleted file mode 100644 index 63484267376bcc25149765f2908a58970d3432f5..0000000000000000000000000000000000000000 --- a/AVX512-support-for-xbzrle_encode_buffer.patch +++ /dev/null @@ -1,310 +0,0 @@ -From 4d572573175449f48fc12c9f9524fc09f219cdbd Mon Sep 17 00:00:00 2001 -From: ling xu -Date: Wed, 16 Nov 2022 23:29:22 +0800 -Subject: [PATCH] AVX512 support for xbzrle_encode_buffer - -mainline inclusion -from mainline-v8.0.0-rc0 -commit 04ffce137b6d85ab4e7687e54e4dffcef0a9ab99 -category: feature -feature: AVX512 support for xbzrle_encode_buffer -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6Z50P - -Intel-SIG: commit 04ffce137b6d ("AVX512 support for xbzrle_encode_buffer") - -------------------------------------- - -AVX512 support for xbzrle_encode_buffer - -This commit is the same with [PATCH v6 1/2], and provides avx512 support for xbzrle_encode_buffer -function to accelerate xbzrle encoding speed. Runtime check of avx512 -support and benchmark for this feature are added. Compared with C -version of xbzrle_encode_buffer function, avx512 version can achieve -50%-70% performance improvement on benchmarking. In addition, if dirty -data is randomly located in 4K page, the avx512 version can achieve -almost 140% performance gain. - -Signed-off-by: ling xu -Co-authored-by: Zhou Zhao -Co-authored-by: Jun Jin -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -Signed-off-by: Aichun Shi ---- - meson.build | 17 +++++ - meson_options.txt | 2 + - migration/ram.c | 34 +++++++++- - migration/xbzrle.c | 124 ++++++++++++++++++++++++++++++++++ - migration/xbzrle.h | 4 ++ - scripts/meson-buildoptions.sh | 3 + - 6 files changed, 181 insertions(+), 3 deletions(-) - -diff --git a/meson.build b/meson.build -index 9f77254861..45bc69bf0c 100644 ---- a/meson.build -+++ b/meson.build -@@ -1816,6 +1816,22 @@ config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + ''' - return -1; - }''')) - -+config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \ -+ .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \ -+ .require(cc.links(''' -+ #pragma GCC push_options -+ #pragma GCC target("avx512bw") -+ #include -+ #include -+ static int bar(void *a) { -+ -+ __m512i *x = a; -+ __m512i res= _mm512_abs_epi8(*x); -+ return res[1]; -+ } -+ int main(int argc, char *argv[]) { return bar(argv[0]); } -+ '''), error_message: 'AVX512BW not available').allowed()) -+ - ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target - 'HAVE_GDB_BIN'] - arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST'] -@@ -3318,6 +3334,7 @@ summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_US - summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')} - summary_info += {'memory allocator': get_option('malloc')} - summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} -+summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} - summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')} - summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')} - summary_info += {'gcov': get_option('b_coverage')} -diff --git a/meson_options.txt b/meson_options.txt -index e9cbe48cb9..ec9c3c0a05 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -70,6 +70,8 @@ option('avx2', type: 'feature', value: 'auto', - description: 'AVX2 optimizations') - option('avx512f', type: 'feature', value: 'disabled', - description: 'AVX512F optimizations') -+option('avx512bw', type: 'feature', value: 'auto', -+ description: 'AVX512BW optimizations') - - option('attr', type : 'feature', value : 'auto', - description: 'attr/xattr support') -diff --git a/migration/ram.c b/migration/ram.c -index c3484ee1a9..a4383954b4 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -91,6 +91,34 @@ static inline bool is_zero_range(uint8_t *p, uint64_t size) - return buffer_is_zero(p, size); - } - -+int (*xbzrle_encode_buffer_func)(uint8_t *, uint8_t *, int, -+ uint8_t *, int) = xbzrle_encode_buffer; -+#if defined(CONFIG_AVX512BW_OPT) -+#include "qemu/cpuid.h" -+static void __attribute__((constructor)) init_cpu_flag(void) -+{ -+ unsigned max = __get_cpuid_max(0, NULL); -+ int a, b, c, d; -+ if (max >= 1) { -+ __cpuid(1, a, b, c, d); -+ /* We must check that AVX is not just available, but usable. */ -+ if ((c & bit_OSXSAVE) && (c & bit_AVX) && max >= 7) { -+ int bv; -+ __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0)); -+ __cpuid_count(7, 0, a, b, c, d); -+ /* 0xe6: -+ * XCR0[7:5] = 111b (OPMASK state, upper 256-bit of ZMM0-ZMM15 -+ * and ZMM16-ZMM31 state are enabled by OS) -+ * XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS) -+ */ -+ if ((bv & 0xe6) == 0xe6 && (b & bit_AVX512BW)) { -+ xbzrle_encode_buffer_func = xbzrle_encode_buffer_avx512; -+ } -+ } -+ } -+} -+#endif -+ - XBZRLECacheStats xbzrle_counters; - - /* struct contains XBZRLE cache and a static page -@@ -1031,9 +1059,9 @@ static int save_xbzrle_page(RAMState *rs, uint8_t **current_data, - memcpy(XBZRLE.current_buf, *current_data, TARGET_PAGE_SIZE); - - /* XBZRLE encoding (if there is no overflow) */ -- encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf, -- TARGET_PAGE_SIZE, XBZRLE.encoded_buf, -- TARGET_PAGE_SIZE); -+ encoded_len = xbzrle_encode_buffer_func(prev_cached_page, XBZRLE.current_buf, -+ TARGET_PAGE_SIZE, XBZRLE.encoded_buf, -+ TARGET_PAGE_SIZE); - - /* - * Update the cache contents, so that it corresponds to the data -diff --git a/migration/xbzrle.c b/migration/xbzrle.c -index 1ba482ded9..05366e86c0 100644 ---- a/migration/xbzrle.c -+++ b/migration/xbzrle.c -@@ -174,3 +174,127 @@ int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen) - - return d; - } -+ -+#if defined(CONFIG_AVX512BW_OPT) -+#pragma GCC push_options -+#pragma GCC target("avx512bw") -+#include -+int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen, -+ uint8_t *dst, int dlen) -+{ -+ uint32_t zrun_len = 0, nzrun_len = 0; -+ int d = 0, i = 0, num = 0; -+ uint8_t *nzrun_start = NULL; -+ /* add 1 to include residual part in main loop */ -+ uint32_t count512s = (slen >> 6) + 1; -+ /* countResidual is tail of data, i.e., countResidual = slen % 64 */ -+ uint32_t count_residual = slen & 0b111111; -+ bool never_same = true; -+ uint64_t mask_residual = 1; -+ mask_residual <<= count_residual; -+ mask_residual -= 1; -+ __m512i r = _mm512_set1_epi32(0); -+ -+ while (count512s) { -+ if (d + 2 > dlen) { -+ return -1; -+ } -+ -+ int bytes_to_check = 64; -+ uint64_t mask = 0xffffffffffffffff; -+ if (count512s == 1) { -+ bytes_to_check = count_residual; -+ mask = mask_residual; -+ } -+ __m512i old_data = _mm512_mask_loadu_epi8(r, -+ mask, old_buf + i); -+ __m512i new_data = _mm512_mask_loadu_epi8(r, -+ mask, new_buf + i); -+ uint64_t comp = _mm512_cmpeq_epi8_mask(old_data, new_data); -+ count512s--; -+ -+ bool is_same = (comp & 0x1); -+ while (bytes_to_check) { -+ if (is_same) { -+ if (nzrun_len) { -+ d += uleb128_encode_small(dst + d, nzrun_len); -+ if (d + nzrun_len > dlen) { -+ return -1; -+ } -+ nzrun_start = new_buf + i - nzrun_len; -+ memcpy(dst + d, nzrun_start, nzrun_len); -+ d += nzrun_len; -+ nzrun_len = 0; -+ } -+ /* 64 data at a time for speed */ -+ if (count512s && (comp == 0xffffffffffffffff)) { -+ i += 64; -+ zrun_len += 64; -+ break; -+ } -+ never_same = false; -+ num = __builtin_ctzll(~comp); -+ num = (num < bytes_to_check) ? num : bytes_to_check; -+ zrun_len += num; -+ bytes_to_check -= num; -+ comp >>= num; -+ i += num; -+ if (bytes_to_check) { -+ /* still has different data after same data */ -+ d += uleb128_encode_small(dst + d, zrun_len); -+ zrun_len = 0; -+ } else { -+ break; -+ } -+ } -+ if (never_same || zrun_len) { -+ /* -+ * never_same only acts if -+ * data begins with diff in first count512s -+ */ -+ d += uleb128_encode_small(dst + d, zrun_len); -+ zrun_len = 0; -+ never_same = false; -+ } -+ /* has diff, 64 data at a time for speed */ -+ if ((bytes_to_check == 64) && (comp == 0x0)) { -+ i += 64; -+ nzrun_len += 64; -+ break; -+ } -+ num = __builtin_ctzll(comp); -+ num = (num < bytes_to_check) ? num : bytes_to_check; -+ nzrun_len += num; -+ bytes_to_check -= num; -+ comp >>= num; -+ i += num; -+ if (bytes_to_check) { -+ /* mask like 111000 */ -+ d += uleb128_encode_small(dst + d, nzrun_len); -+ /* overflow */ -+ if (d + nzrun_len > dlen) { -+ return -1; -+ } -+ nzrun_start = new_buf + i - nzrun_len; -+ memcpy(dst + d, nzrun_start, nzrun_len); -+ d += nzrun_len; -+ nzrun_len = 0; -+ is_same = true; -+ } -+ } -+ } -+ -+ if (nzrun_len != 0) { -+ d += uleb128_encode_small(dst + d, nzrun_len); -+ /* overflow */ -+ if (d + nzrun_len > dlen) { -+ return -1; -+ } -+ nzrun_start = new_buf + i - nzrun_len; -+ memcpy(dst + d, nzrun_start, nzrun_len); -+ d += nzrun_len; -+ } -+ return d; -+} -+#pragma GCC pop_options -+#endif -diff --git a/migration/xbzrle.h b/migration/xbzrle.h -index a0db507b9c..6feb49160a 100644 ---- a/migration/xbzrle.h -+++ b/migration/xbzrle.h -@@ -18,4 +18,8 @@ int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen, - uint8_t *dst, int dlen); - - int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen); -+#if defined(CONFIG_AVX512BW_OPT) -+int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen, -+ uint8_t *dst, int dlen); -+#endif - #endif -diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh -index b994bf16f0..8c00cce411 100644 ---- a/scripts/meson-buildoptions.sh -+++ b/scripts/meson-buildoptions.sh -@@ -26,6 +26,7 @@ meson_options_help() { - printf "%s\n" ' attr attr/xattr support' - printf "%s\n" ' auth-pam PAM access control' - printf "%s\n" ' avx2 AVX2 optimizations' -+ printf "%s\n" ' avx512bw AVX512BW optimizations' - printf "%s\n" ' avx512f AVX512F optimizations' - printf "%s\n" ' bpf eBPF support' - printf "%s\n" ' brlapi brlapi character device driver' -@@ -111,6 +112,8 @@ _meson_option_parse() { - --disable-auth-pam) printf "%s" -Dauth_pam=disabled ;; - --enable-avx2) printf "%s" -Davx2=enabled ;; - --disable-avx2) printf "%s" -Davx2=disabled ;; -+ --enable-avx512bw) printf "%s" -Davx512bw=enabled ;; -+ --disable-avx512bw) printf "%s" -Davx512bw=disabled ;; - --enable-avx512f) printf "%s" -Davx512f=enabled ;; - --disable-avx512f) printf "%s" -Davx512f=disabled ;; - --enable-bpf) printf "%s" -Dbpf=enabled ;; --- -2.27.0 - diff --git a/Add-PowerManager-support.patch b/Add-PowerManager-support.patch deleted file mode 100644 index 0ed7b2bea9e83e33ee3b4dc3851c8ca7a567fe4f..0000000000000000000000000000000000000000 --- a/Add-PowerManager-support.patch +++ /dev/null @@ -1,758 +0,0 @@ -From 1fc8fa6cd621c17988b043c1b3abe9ccb189a1d7 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 06:34:32 -0500 -Subject: [PATCH] Add PowerManager support. - -Add Loongarch ACPI power management device simulation. - -Signed-off-by: lixianglai ---- - hw/acpi/Kconfig | 8 + - hw/acpi/larch_7a.c | 616 +++++++++++++++++++++++++++++++++++++++++ - hw/acpi/meson.build | 1 + - include/hw/acpi/ls7a.h | 79 ++++++ - 4 files changed, 704 insertions(+) - create mode 100644 hw/acpi/larch_7a.c - create mode 100644 include/hw/acpi/ls7a.h - -diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig -index 622b0b50b7..245c5554df 100644 ---- a/hw/acpi/Kconfig -+++ b/hw/acpi/Kconfig -@@ -15,6 +15,14 @@ config ACPI_X86_ICH - bool - select ACPI_X86 - -+config ACPI_LOONGARCH -+ bool -+ select ACPI -+ select ACPI_CPU_HOTPLUG -+ select ACPI_MEMORY_HOTPLUG -+ select ACPI_PIIX4 -+ select ACPI_PCIHP -+ - config ACPI_CPU_HOTPLUG - bool - -diff --git a/hw/acpi/larch_7a.c b/hw/acpi/larch_7a.c -new file mode 100644 -index 0000000000..59b43170ff ---- /dev/null -+++ b/hw/acpi/larch_7a.c -@@ -0,0 +1,616 @@ -+/* -+ * Loongarch acpi emulation -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ */ -+ -+#include "qemu/osdep.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/runstate.h" -+#include "sysemu/reset.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/ls7a.h" -+#include "hw/nvram/fw_cfg.h" -+#include "qemu/config-file.h" -+#include "qapi/opts-visitor.h" -+#include "qapi/qapi-events-run-state.h" -+#include "qapi/error.h" -+#include "hw/loongarch/ls7a.h" -+#include "hw/mem/pc-dimm.h" -+#include "hw/mem/nvdimm.h" -+#include "migration/vmstate.h" -+ -+static void ls7a_pm_update_sci_fn(ACPIREGS *regs) -+{ -+ LS7APCIPMRegs *pm = container_of(regs, LS7APCIPMRegs, acpi_regs); -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static uint64_t ls7a_gpe_readb(void *opaque, hwaddr addr, unsigned width) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ return acpi_gpe_ioport_readb(&pm->acpi_regs, addr); -+} -+ -+static void ls7a_gpe_writeb(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static const MemoryRegionOps ls7a_gpe_ops = { -+ .read = ls7a_gpe_readb, -+ .write = ls7a_gpe_writeb, -+ .valid.min_access_size = 1, -+ .valid.max_access_size = 8, -+ .impl.min_access_size = 1, -+ .impl.max_access_size = 1, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+#define VMSTATE_GPE_ARRAY(_field, _state) \ -+{ \ -+ .name = (stringify(_field)), .version_id = 0, .num = ACPI_GPE0_LEN, \ -+ .info = &vmstate_info_uint8, .size = sizeof(uint8_t), \ -+ .flags = VMS_ARRAY | VMS_POINTER, \ -+ .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ -+} -+ -+static uint64_t ls7a_reset_readw(void *opaque, hwaddr addr, unsigned width) -+{ -+ return 0; -+} -+ -+static void ls7a_reset_writew(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ if (val & 1) { -+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); -+ } -+} -+ -+static const MemoryRegionOps ls7a_reset_ops = { -+ .read = ls7a_reset_readw, -+ .write = ls7a_reset_writew, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static bool vmstate_test_use_memhp(void *opaque) -+{ -+ LS7APCIPMRegs *s = opaque; -+ return s->acpi_memory_hotplug.is_enabled; -+} -+ -+static const VMStateDescription vmstate_memhp_state = { -+ .name = "ls7a_pm/memhp", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .minimum_version_id_old = 1, -+ .needed = vmstate_test_use_memhp, -+ .fields = (VMStateField[]){ VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, -+ LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static const VMStateDescription vmstate_cpuhp_state = { -+ .name = "ls7a_pm/cpuhp", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .minimum_version_id_old = 1, -+ .fields = -+ (VMStateField[]){ VMSTATE_CPU_HOTPLUG(cpuhp_state, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+const VMStateDescription vmstate_ls7a_pm = { -+ .name = "ls7a_pm", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = -+ (VMStateField[]){ -+ VMSTATE_UINT16(acpi_regs.pm1.evt.sts, LS7APCIPMRegs), -+ VMSTATE_UINT16(acpi_regs.pm1.evt.en, LS7APCIPMRegs), -+ VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, LS7APCIPMRegs), -+ VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, LS7APCIPMRegs), -+ VMSTATE_INT64(acpi_regs.tmr.overflow_time, LS7APCIPMRegs), -+ VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, LS7APCIPMRegs), -+ VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() }, -+ .subsections = (const VMStateDescription *[]){ &vmstate_memhp_state, -+ &vmstate_cpuhp_state, NULL } -+}; -+ -+static inline int64_t acpi_pm_tmr_get_clock(void) -+{ -+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, -+ NANOSECONDS_PER_SECOND); -+} -+ -+static uint32_t acpi_pm_tmr_get(ACPIREGS *ar) -+{ -+ uint32_t d = acpi_pm_tmr_get_clock(); -+ return d & 0xffffff; -+} -+ -+static void acpi_pm_tmr_timer(void *opaque) -+{ -+ ACPIREGS *ar = opaque; -+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_PMTIMER, NULL); -+ ar->tmr.update_sci(ar); -+} -+ -+static uint64_t acpi_pm_tmr_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ return acpi_pm_tmr_get(opaque); -+} -+ -+static void acpi_pm_tmr_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ /* nothing */ -+} -+ -+static const MemoryRegionOps acpi_pm_tmr_ops = { -+ .read = acpi_pm_tmr_read, -+ .write = acpi_pm_tmr_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void ls7a_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, -+ MemoryRegion *parent, uint64_t offset) -+{ -+ ar->tmr.update_sci = update_sci; -+ ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar); -+ memory_region_init_io(&ar->tmr.io, memory_region_owner(parent), -+ &acpi_pm_tmr_ops, ar, "acpi-tmr", 4); -+ memory_region_add_subregion(parent, offset, &ar->tmr.io); -+} -+ -+static void acpi_pm1_evt_write_sts(ACPIREGS *ar, uint16_t val) -+{ -+ uint16_t pm1_sts = acpi_pm1_evt_get_sts(ar); -+ if (pm1_sts & val & ACPI_BITMASK_TIMER_STATUS) { -+ /* if TMRSTS is reset, then compute the new overflow time */ -+ acpi_pm_tmr_calc_overflow_time(ar); -+ } -+ ar->pm1.evt.sts &= ~val; -+} -+ -+static uint64_t acpi_pm_evt_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ switch (addr) { -+ case 0: -+ return acpi_pm1_evt_get_sts(ar); -+ case 4: -+ return ar->pm1.evt.en; -+ default: -+ return 0; -+ } -+} -+ -+static void acpi_pm1_evt_write_en(ACPIREGS *ar, uint16_t val) -+{ -+ ar->pm1.evt.en = val; -+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_RTC, -+ val & ACPI_BITMASK_RT_CLOCK_ENABLE); -+ qemu_system_wakeup_enable(QEMU_WAKEUP_REASON_PMTIMER, -+ val & ACPI_BITMASK_TIMER_ENABLE); -+} -+ -+static void acpi_pm_evt_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ switch (addr) { -+ case 0: -+ acpi_pm1_evt_write_sts(ar, val); -+ ar->pm1.evt.update_sci(ar); -+ break; -+ case 4: -+ acpi_pm1_evt_write_en(ar, val); -+ ar->pm1.evt.update_sci(ar); -+ break; -+ default: -+ break; -+ } -+} -+ -+static const MemoryRegionOps acpi_pm_evt_ops = { -+ .read = acpi_pm_evt_read, -+ .write = acpi_pm_evt_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void ls7a_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci, -+ MemoryRegion *parent, uint64_t offset) -+{ -+ ar->pm1.evt.update_sci = update_sci; -+ memory_region_init_io(&ar->pm1.evt.io, memory_region_owner(parent), -+ &acpi_pm_evt_ops, ar, "acpi-evt", 8); -+ memory_region_add_subregion(parent, offset, &ar->pm1.evt.io); -+} -+ -+static uint64_t acpi_pm_cnt_read(void *opaque, hwaddr addr, unsigned width) -+{ -+ ACPIREGS *ar = opaque; -+ return ar->pm1.cnt.cnt; -+} -+ -+/* ACPI PM1aCNT */ -+static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) -+{ -+ ar->pm1.cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); -+ if (val & ACPI_BITMASK_SLEEP_ENABLE) { -+ /* change suspend type */ -+ uint16_t sus_typ = (val >> 10) & 7; -+ switch (sus_typ) { -+ /* s3,s4 not support */ -+ case 5: -+ case 6: -+ warn_report("acpi s3,s4 state not support"); -+ break; -+ /* s5: soft off */ -+ case 7: -+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); -+ break; -+ default: -+ break; -+ } -+ } -+} -+ -+static void acpi_pm_cnt_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned width) -+{ -+ acpi_pm1_cnt_write(opaque, val); -+} -+ -+static const MemoryRegionOps acpi_pm_cnt_ops = { -+ .read = acpi_pm_cnt_read, -+ .write = acpi_pm_cnt_write, -+ .valid.min_access_size = 4, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void acpi_notify_wakeup(Notifier *notifier, void *data) -+{ -+ ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); -+ WakeupReason *reason = data; -+ -+ switch (*reason) { -+ case QEMU_WAKEUP_REASON_RTC: -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_RT_CLOCK_STATUS); -+ break; -+ case QEMU_WAKEUP_REASON_PMTIMER: -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_TIMER_STATUS); -+ break; -+ case QEMU_WAKEUP_REASON_OTHER: -+ /* -+ * ACPI_BITMASK_WAKE_STATUS should be set on resume. -+ * Pretend that resume was caused by power button -+ */ -+ ar->pm1.evt.sts |= -+ (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void ls7a_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, -+ bool disable_s3, bool disable_s4, uint8_t s4_val, -+ uint64_t offset) -+{ -+ FWCfgState *fw_cfg; -+ -+ ar->pm1.cnt.s4_val = s4_val; -+ ar->wakeup.notify = acpi_notify_wakeup; -+ qemu_register_wakeup_notifier(&ar->wakeup); -+ memory_region_init_io(&ar->pm1.cnt.io, memory_region_owner(parent), -+ &acpi_pm_cnt_ops, ar, "acpi-cnt", 4); -+ memory_region_add_subregion(parent, offset, &ar->pm1.cnt.io); -+ -+ fw_cfg = fw_cfg_find(); -+ if (fw_cfg) { -+ uint8_t suspend[6] = { 128, 0, 0, 129, 128, 128 }; -+ suspend[3] = 1 | ((!disable_s3) << 7); -+ suspend[4] = s4_val | ((!disable_s4) << 7); -+ fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6); -+ } -+} -+ -+static void ls7a_pm_reset(void *opaque) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ -+ acpi_pm1_evt_reset(&pm->acpi_regs); -+ acpi_pm1_cnt_reset(&pm->acpi_regs); -+ acpi_pm_tmr_reset(&pm->acpi_regs); -+ acpi_gpe_reset(&pm->acpi_regs); -+ -+ acpi_update_sci(&pm->acpi_regs, pm->irq); -+} -+ -+static void pm_powerdown_req(Notifier *n, void *opaque) -+{ -+ LS7APCIPMRegs *pm = container_of(n, LS7APCIPMRegs, powerdown_notifier); -+ -+ acpi_pm1_evt_power_down(&pm->acpi_regs); -+} -+ -+void ls7a_pm_init(LS7APCIPMRegs *pm, qemu_irq *pic) -+{ -+ unsigned long base, gpe_len, acpi_aci_irq; -+ -+ /* -+ * ls7a board acpi hardware info, including -+ * acpi system io base address -+ * acpi gpe length -+ * acpi sci irq number -+ */ -+ base = ACPI_IO_BASE; -+ gpe_len = ACPI_GPE0_LEN; -+ acpi_aci_irq = ACPI_SCI_IRQ; -+ -+ pm->irq = pic[acpi_aci_irq - 64]; -+ memory_region_init(&pm->iomem, NULL, "ls7a_pm", ACPI_IO_SIZE); -+ memory_region_add_subregion(get_system_memory(), base, &pm->iomem); -+ -+ cpu_hotplug_hw_init(get_system_memory(), NULL, &pm->cpuhp_state, -+ CPU_HOTPLUG_BASE); -+ -+ ls7a_pm_tmr_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, -+ LS7A_PM_TMR_BLK); -+ ls7a_pm1_evt_init(&pm->acpi_regs, ls7a_pm_update_sci_fn, &pm->iomem, -+ LS7A_PM_EVT_BLK); -+ ls7a_pm1_cnt_init(&pm->acpi_regs, &pm->iomem, false, false, 2, -+ LS7A_PM_CNT_BLK); -+ -+ acpi_gpe_init(&pm->acpi_regs, gpe_len); -+ memory_region_init_io(&pm->iomem_gpe, NULL, &ls7a_gpe_ops, pm, "acpi-gpe0", -+ gpe_len); -+ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_STS_REG, &pm->iomem_gpe); -+ -+ memory_region_init_io(&pm->iomem_reset, NULL, &ls7a_reset_ops, pm, -+ "acpi-reset", 4); -+ memory_region_add_subregion(&pm->iomem, LS7A_GPE0_RESET_REG, -+ &pm->iomem_reset); -+ -+ qemu_register_reset(ls7a_pm_reset, pm); -+ -+ pm->powerdown_notifier.notify = pm_powerdown_req; -+ qemu_register_powerdown_notifier(&pm->powerdown_notifier); -+ -+ if (pm->acpi_memory_hotplug.is_enabled) { -+ acpi_memory_hotplug_init(get_system_memory(), NULL, -+ &pm->acpi_memory_hotplug, -+ MEMORY_HOTPLUG_BASE); -+ } -+} -+ -+static void ls7a_pm_get_gpe0_blk(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ uint64_t value = ACPI_IO_BASE + LS7A_GPE0_STS_REG; -+ -+ visit_type_uint64(v, name, &value, errp); -+} -+ -+static bool ls7a_pm_get_memory_hotplug_support(Object *obj, Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(obj); -+ -+ return ls7a->pm.acpi_memory_hotplug.is_enabled; -+} -+ -+static void ls7a_pm_set_memory_hotplug_support(Object *obj, bool value, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(obj); -+ -+ ls7a->pm.acpi_memory_hotplug.is_enabled = value; -+} -+ -+static void ls7a_pm_get_disable_s3(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->disable_s3; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_disable_s3(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->disable_s3 = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void ls7a_pm_get_disable_s4(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->disable_s4; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_disable_s4(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->disable_s4 = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void ls7a_pm_get_s4_val(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ uint8_t value = pm->s4_val; -+ -+ visit_type_uint8(v, name, &value, errp); -+} -+ -+static void ls7a_pm_set_s4_val(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LS7APCIPMRegs *pm = opaque; -+ Error *local_err = NULL; -+ uint8_t value; -+ -+ visit_type_uint8(v, name, &value, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ pm->s4_val = value; -+out: -+ error_propagate(errp, local_err); -+} -+ -+void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp) -+{ -+ static const uint32_t gpe0_len = ACPI_GPE0_LEN; -+ pm->acpi_memory_hotplug.is_enabled = true; -+ pm->disable_s3 = 0; -+ pm->disable_s4 = 0; -+ pm->s4_val = 2; -+ -+ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, -+ &pm->pm_io_base, OBJ_PROP_FLAG_READ); -+ object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32", -+ ls7a_pm_get_gpe0_blk, NULL, NULL, pm); -+ object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, &gpe0_len, -+ OBJ_PROP_FLAG_READ); -+ object_property_add_bool(obj, "memory-hotplug-support", -+ ls7a_pm_get_memory_hotplug_support, -+ ls7a_pm_set_memory_hotplug_support); -+ object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", -+ ls7a_pm_get_disable_s3, ls7a_pm_set_disable_s3, NULL, -+ pm); -+ object_property_add(obj, ACPI_PM_PROP_S4_DISABLED, "uint8", -+ ls7a_pm_get_disable_s4, ls7a_pm_set_disable_s4, NULL, -+ pm); -+ object_property_add(obj, ACPI_PM_PROP_S4_VAL, "uint8", ls7a_pm_get_s4_val, -+ ls7a_pm_set_s4_val, NULL, pm); -+} -+ -+void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { -+ nvdimm_acpi_plug_cb(hotplug_dev, dev); -+ } else { -+ acpi_memory_plug_cb(hotplug_dev, &ls7a->pm.acpi_memory_hotplug, -+ dev, errp); -+ } -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_plug_cb(hotplug_dev, &ls7a->pm.cpuhp_state, dev, errp); -+ } else { -+ error_setg(errp, -+ "acpi: device plug request for not supported device" -+ " type: %s", -+ object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ acpi_memory_unplug_request_cb( -+ hotplug_dev, &ls7a->pm.acpi_memory_hotplug, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_unplug_request_cb(hotplug_dev, &ls7a->pm.cpuhp_state, dev, -+ errp); -+ } else { -+ error_setg(errp, -+ "acpi: device unplug request for not supported device" -+ " type: %s", -+ object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(hotplug_dev)); -+ -+ if (ls7a->pm.acpi_memory_hotplug.is_enabled && -+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ acpi_memory_unplug_cb(&ls7a->pm.acpi_memory_hotplug, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_unplug_cb(&ls7a->pm.cpuhp_state, dev, errp); -+ } else { -+ error_setg(errp, -+ "acpi: device unplug for not supported device" -+ " type: %s", -+ object_get_typename(OBJECT(dev))); -+ } -+} -+ -+void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); -+ -+ acpi_memory_ospm_status(&ls7a->pm.acpi_memory_hotplug, list); -+ acpi_cpu_ospm_status(&ls7a->pm.cpuhp_state, list); -+} -+ -+void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(OBJECT(adev)); -+ -+ acpi_send_gpe_event(&ls7a->pm.acpi_regs, ls7a->pm.irq, ev); -+} -diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build -index 448ea6afb4..4718d143fc 100644 ---- a/hw/acpi/meson.build -+++ b/hw/acpi/meson.build -@@ -6,6 +6,7 @@ acpi_ss.add(files( - 'core.c', - 'utils.c', - )) -+acpi_ss.add(when: 'CONFIG_ACPI_LOONGARCH', if_true: files('larch_7a.c')) - acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu.c', 'cpu_hotplug.c')) - acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_false: files('acpi-cpu-hotplug-stub.c')) - acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_true: files('memory_hotplug.c')) -diff --git a/include/hw/acpi/ls7a.h b/include/hw/acpi/ls7a.h -new file mode 100644 -index 0000000000..295baa4b5a ---- /dev/null -+++ b/include/hw/acpi/ls7a.h -@@ -0,0 +1,79 @@ -+/* -+ * QEMU GMCH/LS7A PCI PM Emulation -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef HW_ACPI_LS7A_H -+#define HW_ACPI_LS7A_H -+ -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/cpu_hotplug.h" -+#include "hw/acpi/cpu.h" -+#include "hw/acpi/memory_hotplug.h" -+#include "hw/acpi/acpi_dev_interface.h" -+#include "hw/acpi/tco.h" -+ -+#define CPU_HOTPLUG_BASE 0x1e000000 -+#define MEMORY_HOTPLUG_BASE 0x1e00000c -+ -+typedef struct LS7APCIPMRegs { -+ /* -+ * In ls7a spec says that pm1_cnt register is 32bit width and -+ * that the upper 16bits are reserved and unused. -+ * PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t. -+ */ -+ ACPIREGS acpi_regs; -+ -+ MemoryRegion iomem; -+ MemoryRegion iomem_gpe; -+ MemoryRegion iomem_smi; -+ MemoryRegion iomem_reset; -+ -+ qemu_irq irq; /* SCI */ -+ -+ uint32_t pm_io_base; -+ Notifier powerdown_notifier; -+ -+ bool cpu_hotplug_legacy; -+ AcpiCpuHotplug gpe_cpu; -+ CPUHotplugState cpuhp_state; -+ -+ MemHotplugState acpi_memory_hotplug; -+ -+ uint8_t disable_s3; -+ uint8_t disable_s4; -+ uint8_t s4_val; -+} LS7APCIPMRegs; -+ -+void ls7a_pm_init(LS7APCIPMRegs *ls7a, qemu_irq *sci_irq); -+ -+void ls7a_pm_iospace_update(LS7APCIPMRegs *pm, uint32_t pm_io_base); -+extern const VMStateDescription vmstate_ls7a_pm; -+ -+void ls7a_pm_add_properties(Object *obj, LS7APCIPMRegs *pm, Error **errp); -+ -+void ls7a_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp); -+void ls7a_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+void ls7a_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp); -+ -+void ls7a_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); -+ -+void ls7a_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev); -+#endif /* HW_ACPI_LS7A_H */ --- -2.27.0 - diff --git a/Add-RTC-support.patch b/Add-RTC-support.patch deleted file mode 100644 index 06e50c07e157702de6b96097257813f5191fe2af..0000000000000000000000000000000000000000 --- a/Add-RTC-support.patch +++ /dev/null @@ -1,402 +0,0 @@ -From 1b831c95e652d185c20efe74457927f5d7e35153 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 06:35:16 -0500 -Subject: [PATCH] Add RTC support. - -Add Loongarch real-time clock device simulation. - -Signed-off-by: lixianglai ---- - hw/meson.build | 1 + - hw/timer/Kconfig | 2 + - hw/timer/ls7a_rtc.c | 343 +++++++++++++++++++++++++++++++++++++++++++ - hw/timer/meson.build | 1 + - 4 files changed, 347 insertions(+) - create mode 100644 hw/timer/ls7a_rtc.c - -diff --git a/hw/meson.build b/hw/meson.build -index f39c1f7e70..a9a078ec33 100644 ---- a/hw/meson.build -+++ b/hw/meson.build -@@ -17,6 +17,7 @@ subdir('intc') - subdir('ipack') - subdir('ipmi') - subdir('isa') -+subdir('loongarch') - subdir('mem') - subdir('misc') - subdir('net') -diff --git a/hw/timer/Kconfig b/hw/timer/Kconfig -index 010be7ed1f..b395c72d7d 100644 ---- a/hw/timer/Kconfig -+++ b/hw/timer/Kconfig -@@ -60,3 +60,5 @@ config STELLARIS_GPTM - - config AVR_TIMER16 - bool -+config LS7A_RTC -+ bool -diff --git a/hw/timer/ls7a_rtc.c b/hw/timer/ls7a_rtc.c -new file mode 100644 -index 0000000000..56c2695654 ---- /dev/null -+++ b/hw/timer/ls7a_rtc.c -@@ -0,0 +1,343 @@ -+/* -+ * Loongarch rtc emulation -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "hw/sysbus.h" -+#include "hw/irq.h" -+#include "include/hw/register.h" -+#include "qemu/timer.h" -+#include "sysemu/sysemu.h" -+#include "qemu/cutils.h" -+#include "qemu/log.h" -+#include "qemu-common.h" -+#include "migration/vmstate.h" -+ -+#ifdef DEBUG_LS7A_RTC -+#define DPRINTF \ -+ (fmt, ...) do \ -+ { \ -+ printf("ls7a_rtc: " fmt, ##__VA_ARGS__); \ -+ } \ -+ while (0) -+#else -+#define DPRINTF \ -+ (fmt, ...) do \ -+ { \ -+ } \ -+ while (0) -+#endif -+ -+#define SYS_TOYTRIM 0x20 -+#define SYS_TOYWRITE0 0x24 -+#define SYS_TOYWRITE1 0x28 -+#define SYS_TOYREAD0 0x2C -+#define SYS_TOYREAD1 0x30 -+#define SYS_TOYMATCH0 0x34 -+#define SYS_TOYMATCH1 0x38 -+#define SYS_TOYMATCH2 0x3C -+#define SYS_RTCCTRL 0x40 -+#define SYS_RTCTRIM 0x60 -+#define SYS_RTCWRTIE0 0x64 -+#define SYS_RTCREAD0 0x68 -+#define SYS_RTCMATCH0 0x6C -+#define SYS_RTCMATCH1 0x70 -+#define SYS_RTCMATCH2 0x74 -+ -+/** -+ ** shift bits and filed mask -+ **/ -+#define TOY_MON_MASK 0x3f -+#define TOY_DAY_MASK 0x1f -+#define TOY_HOUR_MASK 0x1f -+#define TOY_MIN_MASK 0x3f -+#define TOY_SEC_MASK 0x3f -+#define TOY_MSEC_MASK 0xf -+ -+#define TOY_MON_SHIFT 26 -+#define TOY_DAY_SHIFT 21 -+#define TOY_HOUR_SHIFT 16 -+#define TOY_MIN_SHIFT 10 -+#define TOY_SEC_SHIFT 4 -+#define TOY_MSEC_SHIFT 0 -+ -+#define TOY_MATCH_YEAR_MASK 0x3f -+#define TOY_MATCH_MON_MASK 0xf -+#define TOY_MATCH_DAY_MASK 0x1f -+#define TOY_MATCH_HOUR_MASK 0x1f -+#define TOY_MATCH_MIN_MASK 0x3f -+#define TOY_MATCH_SEC_MASK 0x3f -+ -+#define TOY_MATCH_YEAR_SHIFT 26 -+#define TOY_MATCH_MON_SHIFT 22 -+#define TOY_MATCH_DAY_SHIFT 17 -+#define TOY_MATCH_HOUR_SHIFT 12 -+#define TOY_MATCH_MIN_SHIFT 6 -+#define TOY_MATCH_SEC_SHIFT 0 -+ -+#define TOY_ENABLE_BIT (1U << 11) -+ -+#define TYPE_LS7A_RTC "ls7a_rtc" -+#define LS7A_RTC(obj) OBJECT_CHECK(LS7A_RTCState, (obj), TYPE_LS7A_RTC) -+ -+typedef struct LS7A_RTCState { -+ SysBusDevice parent_obj; -+ -+ MemoryRegion iomem; -+ QEMUTimer *timer; -+ /* -+ * Needed to preserve the tick_count across migration, even if the -+ * absolute value of the rtc_clock is different on the source and -+ * destination. -+ */ -+ int64_t offset; -+ int64_t data; -+ int64_t save_alarm_offset; -+ int tidx; -+ uint32_t toymatch[3]; -+ uint32_t toytrim; -+ uint32_t cntrctl; -+ uint32_t rtctrim; -+ uint32_t rtccount; -+ uint32_t rtcmatch[3]; -+ qemu_irq toy_irq; -+} LS7A_RTCState; -+ -+enum { -+ TOYEN = 1UL << 11, -+ RTCEN = 1UL << 13, -+}; -+ -+static uint64_t ls7a_rtc_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ struct tm tm; -+ unsigned int val = 0; -+ -+ switch (addr) { -+ case SYS_TOYREAD0: -+ qemu_get_timedate(&tm, s->offset); -+ val = (((tm.tm_mon + 1) & TOY_MON_MASK) << TOY_MON_SHIFT) | -+ (((tm.tm_mday) & TOY_DAY_MASK) << TOY_DAY_SHIFT) | -+ (((tm.tm_hour) & TOY_HOUR_MASK) << TOY_HOUR_SHIFT) | -+ (((tm.tm_min) & TOY_MIN_MASK) << TOY_MIN_SHIFT) | -+ (((tm.tm_sec) & TOY_SEC_MASK) << TOY_SEC_SHIFT) | 0x0; -+ break; -+ case SYS_TOYREAD1: -+ qemu_get_timedate(&tm, s->offset); -+ val = tm.tm_year; -+ break; -+ case SYS_TOYMATCH0: -+ val = s->toymatch[0]; -+ break; -+ case SYS_TOYMATCH1: -+ val = s->toymatch[1]; -+ break; -+ case SYS_TOYMATCH2: -+ val = s->toymatch[2]; -+ break; -+ case SYS_RTCCTRL: -+ val = s->cntrctl; -+ break; -+ case SYS_RTCREAD0: -+ val = s->rtccount; -+ break; -+ case SYS_RTCMATCH0: -+ val = s->rtcmatch[0]; -+ break; -+ case SYS_RTCMATCH1: -+ val = s->rtcmatch[1]; -+ break; -+ case SYS_RTCMATCH2: -+ val = s->rtcmatch[2]; -+ break; -+ default: -+ break; -+ } -+ return val; -+} -+ -+static void ls7a_rtc_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ struct tm tm; -+ int64_t alarm_offset, year_diff, expire_time; -+ -+ switch (addr) { -+ case SYS_TOYWRITE0: -+ qemu_get_timedate(&tm, s->offset); -+ tm.tm_sec = (val >> TOY_SEC_SHIFT) & TOY_SEC_MASK; -+ tm.tm_min = (val >> TOY_MIN_SHIFT) & TOY_MIN_MASK; -+ tm.tm_hour = (val >> TOY_HOUR_SHIFT) & TOY_HOUR_MASK; -+ tm.tm_mday = ((val >> TOY_DAY_SHIFT) & TOY_DAY_MASK); -+ tm.tm_mon = ((val >> TOY_MON_SHIFT) & TOY_MON_MASK) - 1; -+ s->offset = qemu_timedate_diff(&tm); -+ break; -+ case SYS_TOYWRITE1: -+ qemu_get_timedate(&tm, s->offset); -+ tm.tm_year = val; -+ s->offset = qemu_timedate_diff(&tm); -+ break; -+ case SYS_TOYMATCH0: -+ s->toymatch[0] = val; -+ qemu_get_timedate(&tm, s->offset); -+ tm.tm_sec = (val >> TOY_MATCH_SEC_SHIFT) & TOY_MATCH_SEC_MASK; -+ tm.tm_min = (val >> TOY_MATCH_MIN_SHIFT) & TOY_MATCH_MIN_MASK; -+ tm.tm_hour = ((val >> TOY_MATCH_HOUR_SHIFT) & TOY_MATCH_HOUR_MASK); -+ tm.tm_mday = ((val >> TOY_MATCH_DAY_SHIFT) & TOY_MATCH_DAY_MASK); -+ tm.tm_mon = ((val >> TOY_MATCH_MON_SHIFT) & TOY_MATCH_MON_MASK) - 1; -+ year_diff = ((val >> TOY_MATCH_YEAR_SHIFT) & TOY_MATCH_YEAR_MASK); -+ year_diff = year_diff - (tm.tm_year & TOY_MATCH_YEAR_MASK); -+ tm.tm_year = tm.tm_year + year_diff; -+ alarm_offset = qemu_timedate_diff(&tm) - s->offset; -+ if ((alarm_offset < 0) && (alarm_offset > -5)) { -+ alarm_offset = 0; -+ } -+ expire_time = qemu_clock_get_ms(rtc_clock); -+ expire_time += ((alarm_offset * 1000) + 100); -+ timer_mod(s->timer, expire_time); -+ break; -+ case SYS_TOYMATCH1: -+ s->toymatch[1] = val; -+ break; -+ case SYS_TOYMATCH2: -+ s->toymatch[2] = val; -+ break; -+ case SYS_RTCCTRL: -+ s->cntrctl = val; -+ break; -+ case SYS_RTCWRTIE0: -+ s->rtccount = val; -+ break; -+ case SYS_RTCMATCH0: -+ s->rtcmatch[0] = val; -+ break; -+ case SYS_RTCMATCH1: -+ val = s->rtcmatch[1]; -+ break; -+ case SYS_RTCMATCH2: -+ val = s->rtcmatch[2]; -+ break; -+ default: -+ break; -+ } -+} -+ -+static const MemoryRegionOps ls7a_rtc_ops = { -+ .read = ls7a_rtc_read, -+ .write = ls7a_rtc_write, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+ .valid = { -+ .min_access_size = 4, -+ .max_access_size = 4, -+ }, -+ -+}; -+ -+static void toy_timer(void *opaque) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ -+ if (s->cntrctl & TOY_ENABLE_BIT) { -+ qemu_irq_pulse(s->toy_irq); -+ } -+} -+ -+static void ls7a_rtc_realize(DeviceState *dev, Error **errp) -+{ -+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev); -+ LS7A_RTCState *d = LS7A_RTC(sbd); -+ memory_region_init_io(&d->iomem, NULL, &ls7a_rtc_ops, (void *)d, -+ "ls7a_rtc", 0x100); -+ -+ sysbus_init_irq(sbd, &d->toy_irq); -+ -+ sysbus_init_mmio(sbd, &d->iomem); -+ d->timer = timer_new_ms(rtc_clock, toy_timer, d); -+ timer_mod(d->timer, qemu_clock_get_ms(rtc_clock) + 100); -+ d->offset = 0; -+} -+ -+static int ls7a_rtc_pre_save(void *opaque) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ struct tm tm; -+ int64_t year_diff, value; -+ -+ value = s->toymatch[0]; -+ qemu_get_timedate(&tm, s->offset); -+ tm.tm_sec = (value >> TOY_MATCH_SEC_SHIFT) & TOY_MATCH_SEC_MASK; -+ tm.tm_min = (value >> TOY_MATCH_MIN_SHIFT) & TOY_MATCH_MIN_MASK; -+ tm.tm_hour = ((value >> TOY_MATCH_HOUR_SHIFT) & TOY_MATCH_HOUR_MASK); -+ tm.tm_mday = ((value >> TOY_MATCH_DAY_SHIFT) & TOY_MATCH_DAY_MASK); -+ tm.tm_mon = ((value >> TOY_MATCH_MON_SHIFT) & TOY_MATCH_MON_MASK) - 1; -+ year_diff = ((value >> TOY_MATCH_YEAR_SHIFT) & TOY_MATCH_YEAR_MASK); -+ year_diff = year_diff - (tm.tm_year & TOY_MATCH_YEAR_MASK); -+ tm.tm_year = tm.tm_year + year_diff; -+ s->save_alarm_offset = qemu_timedate_diff(&tm) - s->offset; -+ -+ return 0; -+} -+ -+static int ls7a_rtc_post_load(void *opaque, int version_id) -+{ -+ LS7A_RTCState *s = (LS7A_RTCState *)opaque; -+ int64_t expire_time; -+ -+ expire_time = qemu_clock_get_ms(rtc_clock) + (s->save_alarm_offset * 1000); -+ timer_mod(s->timer, expire_time); -+ -+ return 0; -+} -+ -+static const VMStateDescription vmstate_ls7a_rtc = { -+ .name = "ls7a_rtc", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = ls7a_rtc_pre_save, -+ .post_load = ls7a_rtc_post_load, -+ .fields = -+ (VMStateField[]){ VMSTATE_INT64(offset, LS7A_RTCState), -+ VMSTATE_INT64(save_alarm_offset, LS7A_RTCState), -+ VMSTATE_UINT32(toymatch[0], LS7A_RTCState), -+ VMSTATE_UINT32(cntrctl, LS7A_RTCState), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static void ls7a_rtc_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ dc->vmsd = &vmstate_ls7a_rtc; -+ dc->realize = ls7a_rtc_realize; -+ dc->desc = "ls7a rtc"; -+} -+ -+static const TypeInfo ls7a_rtc_info = { -+ .name = TYPE_LS7A_RTC, -+ .parent = TYPE_SYS_BUS_DEVICE, -+ .instance_size = sizeof(LS7A_RTCState), -+ .class_init = ls7a_rtc_class_init, -+}; -+ -+static void ls7a_rtc_register_types(void) -+{ -+ type_register_static(&ls7a_rtc_info); -+} -+ -+type_init(ls7a_rtc_register_types) -diff --git a/hw/timer/meson.build b/hw/timer/meson.build -index 03092e2ceb..e841a2f6ee 100644 ---- a/hw/timer/meson.build -+++ b/hw/timer/meson.build -@@ -16,6 +16,7 @@ softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_mct.c')) - softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_pwm.c')) - softmmu_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_gptimer.c')) - softmmu_ss.add(when: 'CONFIG_HPET', if_true: files('hpet.c')) -+softmmu_ss.add(when: 'CONFIG_LS7A_RTC', if_true: files('ls7a_rtc.c')) - softmmu_ss.add(when: 'CONFIG_I8254', if_true: files('i8254_common.c', 'i8254.c')) - softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_epit.c')) - softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpt.c')) --- -2.27.0 - diff --git a/Add-bios.patch b/Add-bios.patch deleted file mode 100644 index 00647298f0b946ca4cf8134c0e2554eafb787f13..0000000000000000000000000000000000000000 --- a/Add-bios.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6921fc74a9a58445e453eeb3c2ee74cead690ee4 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 07:22:18 -0500 -Subject: [PATCH] Add bios. - -Add loongarch bios. - -Signed-off-by: lixianglai ---- - pc-bios/meson.build | 2 ++ - 1 files changed, 2 insertions(+) - -diff --git a/pc-bios/meson.build b/pc-bios/meson.build -index 05e9065ad6..f2a1d111a1 100644 ---- a/pc-bios/meson.build -+++ b/pc-bios/meson.build -@@ -86,6 +86,8 @@ blobs = files( - 'opensbi-riscv32-generic-fw_dynamic.elf', - 'opensbi-riscv64-generic-fw_dynamic.elf', - 'npcm7xx_bootrom.bin', -+ 'loongarch_bios.bin', -+ 'loongarch_vars.bin', - ) - - if get_option('install_blobs') --- -2.27.0 - diff --git a/Add-command-line.patch b/Add-command-line.patch deleted file mode 100644 index ee9af2d36e49764d799f1f62afc2323f54f52220..0000000000000000000000000000000000000000 --- a/Add-command-line.patch +++ /dev/null @@ -1,104 +0,0 @@ -From a88f2d12afb6a6b5b3d97983cea95d6088f0bf04 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 07:21:17 -0500 -Subject: [PATCH] Add command line. - -Add loongarch command support. - -Signed-off-by: lixianglai ---- - include/sysemu/arch_init.h | 1 + - qapi/machine-target.json | 6 ++++-- - qapi/machine.json | 2 +- - qapi/misc-target.json | 1 + - qemu-options.hx | 2 +- - softmmu/qdev-monitor.c | 2 +- - 6 files changed, 9 insertions(+), 5 deletions(-) - -diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h -index 1cf27baa7c..0907b92cd1 100644 ---- a/include/sysemu/arch_init.h -+++ b/include/sysemu/arch_init.h -@@ -25,6 +25,7 @@ enum { - QEMU_ARCH_AVR = (1 << 21), - QEMU_ARCH_HEXAGON = (1 << 22), - QEMU_ARCH_SW64 = (1 << 23), -+ QEMU_ARCH_LOONGARCH64 = (1 << 24), - }; - - extern const uint32_t arch_type; -diff --git a/qapi/machine-target.json b/qapi/machine-target.json -index f5ec4bc172..682dc86b42 100644 ---- a/qapi/machine-target.json -+++ b/qapi/machine-target.json -@@ -324,7 +324,8 @@ - 'TARGET_ARM', - 'TARGET_I386', - 'TARGET_S390X', -- 'TARGET_MIPS' ] } } -+ 'TARGET_MIPS', -+ 'TARGET_LOONGARCH64' ] } } - - ## - # @query-cpu-definitions: -@@ -340,4 +341,5 @@ - 'TARGET_ARM', - 'TARGET_I386', - 'TARGET_S390X', -- 'TARGET_MIPS' ] } } -+ 'TARGET_MIPS', -+ 'TARGET_LOONGARCH64' ] } } -diff --git a/qapi/machine.json b/qapi/machine.json -index 03cfb268a4..31b0350b99 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -34,7 +34,7 @@ - 'mips64el', 'mipsel', 'nios2', 'or1k', 'ppc', - 'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4', - 'sh4eb', 'sparc', 'sparc64', 'tricore', -- 'x86_64', 'xtensa', 'xtensaeb' ] } -+ 'x86_64', 'xtensa', 'xtensaeb', 'loongarch64' ] } - - ## - # @CpuS390State: -diff --git a/qapi/misc-target.json b/qapi/misc-target.json -index 4bc45d2474..63cebef573 100644 ---- a/qapi/misc-target.json -+++ b/qapi/misc-target.json -@@ -33,6 +33,7 @@ - 'TARGET_PPC64', - 'TARGET_S390X', - 'TARGET_SH4', -+ 'TARGET_LOONGARCH64', - 'TARGET_SPARC' ] } } - - ## -diff --git a/qemu-options.hx b/qemu-options.hx -index 047d28a357..e62bb6bebd 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -2533,7 +2533,7 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios, - " specify SMBIOS type 17 fields\n" - "-smbios type=41[,designation=str][,kind=str][,instance=%d][,pcidev=str]\n" - " specify SMBIOS type 41 fields\n", -- QEMU_ARCH_I386 | QEMU_ARCH_ARM) -+ QEMU_ARCH_I386 | QEMU_ARCH_ARM | QEMU_ARCH_LOONGARCH64) - SRST - ``-smbios file=binary`` - Load SMBIOS entry from binary file. -diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c -index 142352b24e..4ca4e92ce2 100644 ---- a/softmmu/qdev-monitor.c -+++ b/softmmu/qdev-monitor.c -@@ -62,7 +62,7 @@ typedef struct QDevAlias - QEMU_ARCH_MIPS | QEMU_ARCH_PPC | \ - QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \ - QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA | \ -- QEMU_ARCH_SW64) -+ QEMU_ARCH_SW64 | QEMU_ARCH_LOONGARCH64) - #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X) - #define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K) - --- -2.27.0 - diff --git a/Add-compile-script.patch b/Add-compile-script.patch deleted file mode 100644 index f897aa74f3114675447d57328f40c06949bf2a95..0000000000000000000000000000000000000000 --- a/Add-compile-script.patch +++ /dev/null @@ -1,255 +0,0 @@ -From 6668690dee884342e29103b5df1ab751bb236bba Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 07:22:58 -0500 -Subject: [PATCH] Add compile script. - -Modify the compile script for loongarch. - -Signed-off-by: lixianglai ---- - .../devices/loongarch64-softmmu/default.mak | 158 ++++++++++++++++++ - configs/targets/loongarch64-softmmu.mak | 3 + - configure | 5 + - meson.build | 7 +- - 4 files changed, 172 insertions(+), 1 deletion(-) - create mode 100644 configs/devices/loongarch64-softmmu/default.mak - create mode 100644 configs/targets/loongarch64-softmmu.mak - -diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak -new file mode 100644 -index 0000000000..c4cc246833 ---- /dev/null -+++ b/configs/devices/loongarch64-softmmu/default.mak -@@ -0,0 +1,158 @@ -+# Default configuration for loongarch-softmmu -+ -+CONFIG_PCI=y -+CONFIG_ACPI_PCI=y -+# For now, CONFIG_IDE_CORE requires ISA, so we enable it here -+CONFIG_ISA_BUS=y -+CONFIG_VIRTIO_PCI=y -+ -+CONFIG_VGA_PCI=y -+CONFIG_ACPI_SMBUS=y -+CONFIG_VHOST_USER_SCSI=y -+CONFIG_VHOST_USER_BLK=y -+CONFIG_VIRTIO=y -+CONFIG_VIRTIO_BALLOON=y -+CONFIG_VIRTIO_BLK=y -+CONFIG_VIRTIO_CRYPTO=y -+CONFIG_VIRTIO_GPU=y -+CONFIG_VIRTIO_INPUT=y -+CONFIG_VIRTIO_NET=y -+CONFIG_VIRTIO_RNG=y -+CONFIG_SCSI=y -+CONFIG_VIRTIO_SCSI=y -+CONFIG_VIRTIO_SERIAL=y -+ -+CONFIG_USB_UHCI=y -+CONFIG_USB_OHCI=y -+CONFIG_USB_OHCI_PCI=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_NEC=y -+CONFIG_NE2000_PCI=y -+CONFIG_EEPRO100_PCI=y -+CONFIG_PCNET_PCI=y -+CONFIG_PCNET_COMMON=y -+CONFIG_AC97=y -+CONFIG_HDA=y -+CONFIG_ES1370=y -+CONFIG_SCSI=y -+CONFIG_LSI_SCSI_PCI=y -+CONFIG_VMW_PVSCSI_SCSI_PCI=y -+CONFIG_MEGASAS_SCSI_PCI=y -+CONFIG_MPTSAS_SCSI_PCI=y -+CONFIG_RTL8139_PCI=y -+CONFIG_E1000_PCI=y -+CONFIG_IDE_CORE=y -+CONFIG_IDE_QDEV=y -+CONFIG_IDE_PCI=y -+CONFIG_AHCI=y -+CONFIG_AHCI_ICH9=y -+CONFIG_ESP=y -+CONFIG_ESP_PCI=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_SERIAL_PCI=y -+CONFIG_CAN_BUS=y -+CONFIG_CAN_SJA1000=y -+CONFIG_CAN_PCI=y -+CONFIG_USB_UHCI=y -+CONFIG_USB_OHCI=y -+CONFIG_USB_XHCI=y -+CONFIG_USB_XHCI_NEC=y -+CONFIG_NE2000_PCI=y -+CONFIG_EEPRO100_PCI=y -+CONFIG_PCNET_PCI=y -+CONFIG_PCNET_COMMON=y -+CONFIG_AC97=y -+CONFIG_HDA=y -+CONFIG_ES1370=y -+CONFIG_SCSI=y -+CONFIG_LSI_SCSI_PCI=y -+CONFIG_VMW_PVSCSI_SCSI_PCI=y -+CONFIG_MEGASAS_SCSI_PCI=y -+CONFIG_MPTSAS_SCSI_PCI=y -+CONFIG_RTL8139_PCI=y -+CONFIG_E1000_PCI=y -+CONFIG_IDE_CORE=y -+CONFIG_IDE_QDEV=y -+CONFIG_IDE_PCI=y -+CONFIG_AHCI=y -+CONFIG_ESP=y -+CONFIG_ESP_PCI=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_SERIAL_PCI=y -+CONFIG_CAN_BUS=y -+CONFIG_CAN_SJA1000=y -+CONFIG_CAN_PCI=y -+ -+CONFIG_SPICE=y -+CONFIG_QXL=y -+CONFIG_ESP=y -+CONFIG_SCSI=y -+CONFIG_VGA_ISA=y -+CONFIG_VGA_ISA_MM=y -+CONFIG_VGA_CIRRUS=y -+CONFIG_VMWARE_VGA=y -+CONFIG_VIRTIO_VGA=y -+CONFIG_SERIAL=y -+CONFIG_SERIAL_ISA=y -+CONFIG_PARALLEL=y -+CONFIG_I8254=y -+CONFIG_PCSPK=y -+CONFIG_PCKBD=y -+CONFIG_FDC=y -+CONFIG_ACPI=y -+CONFIG_ACPI_MEMORY_HOTPLUG=y -+CONFIG_ACPI_NVDIMM=y -+CONFIG_ACPI_CPU_HOTPLUG=y -+CONFIG_APM=y -+CONFIG_I8257=y -+CONFIG_PIIX4=y -+CONFIG_IDE_ISA=y -+CONFIG_IDE_PIIX=y -+CONFIG_MIPSNET=y -+CONFIG_PFLASH_CFI01=y -+CONFIG_I8259=y -+CONFIG_MC146818RTC=y -+CONFIG_ISA_TESTDEV=y -+CONFIG_EMPTY_SLOT=y -+CONFIG_I2C=y -+CONFIG_DIMM=y -+CONFIG_MEM_DEVICE=y -+ -+# Arch Specified CONFIG defines -+CONFIG_IDE_VIA=y -+CONFIG_VT82C686=y -+CONFIG_RC4030=y -+CONFIG_DP8393X=y -+CONFIG_DS1225Y=y -+CONFIG_FITLOADER=y -+CONFIG_SMBIOS=y -+ -+CONFIG_PCIE_PORT=y -+CONFIG_I82801B11=y -+CONFIG_XIO3130=y -+CONFIG_PCI_EXPRESS=y -+CONFIG_MSI_NONBROKEN=y -+CONFIG_IOH3420=y -+CONFIG_SD=y -+CONFIG_SDHCI=y -+CONFIG_VIRTFS=y -+CONFIG_VIRTIO_9P=y -+CONFIG_USB_EHCI=y -+CONFIG_USB_EHCI_PCI=y -+CONFIG_USB_EHCI_SYSBUS=y -+CONFIG_USB_STORAGE_BOT=y -+CONFIG_TPM_EMULATOR=y -+CONFIG_TPM_TIS=y -+CONFIG_PLATFORM_BUS=y -+CONFIG_TPM_TIS_SYSBUS=y -+CONFIG_ACPI_LOONGARCH=y -+CONFIG_LS7A_RTC=y -+ -+#vfio config -+CONFIG_VFIO=y -+CONFIG_VFIO_PCI=y -+CONFIG_VFIO_PLATFORM=y -+CONFIG_VFIO_XGMAC=y -+CONFIG_VFIO_AMD_XGBE=y -diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak -new file mode 100644 -index 0000000000..c42dfbbd9c ---- /dev/null -+++ b/configs/targets/loongarch64-softmmu.mak -@@ -0,0 +1,3 @@ -+TARGET_ARCH=loongarch64 -+TARGET_SUPPORTS_MTTCG=y -+TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml -diff --git a/configure b/configure -index 2576d1c693..a84dc891cc 100755 ---- a/configure -+++ b/configure -@@ -579,6 +579,8 @@ elif check_define __arm__ ; then - cpu="arm" - elif check_define __aarch64__ ; then - cpu="aarch64" -+elif check_define __loongarch__ ; then -+ cpu="loongarch64" - else - cpu=$(uname -m) - fi -@@ -604,6 +606,9 @@ case "$cpu" in - aarch64) - cpu="aarch64" - ;; -+ loongarch64) -+ cpu="loongarch64" -+ ;; - mips*) - cpu="mips" - ;; -diff --git a/meson.build b/meson.build -index d0bbceffe1..d80426b3e8 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', 'sw64'] -+ 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64', 'sw64', 'loongarch64'] - - cpu = host_machine.cpu_family() - -@@ -83,6 +83,8 @@ elif cpu in ['mips', 'mips64'] - kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] - elif cpu == 'sw64' - kvm_targets = ['sw64-softmmu'] -+elif cpu == 'loongarch64' -+ kvm_targets = ['loongarch64-softmmu'] - else - kvm_targets = [] - endif -@@ -367,6 +369,8 @@ if not get_option('tcg').disabled() - tcg_arch = 'ppc' - elif config_host['ARCH'] in ['sw64'] - tcg_arch = 'sw64' -+ elif config_host['ARCH'] == 'loongarch64' -+ tcg_arch = 'loongarch64' - endif - add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, - language: ['c', 'cpp', 'objc']) -@@ -1822,6 +1826,7 @@ disassemblers = { - 'sh4' : ['CONFIG_SH4_DIS'], - 'sparc' : ['CONFIG_SPARC_DIS'], - 'xtensa' : ['CONFIG_XTENSA_DIS'], -+ 'loongarch64' : ['CONFIG_LOONGARCH_DIS'], - 'sw64' : ['CONFIG_SW64_DIS'], - } - if link_language == 'cpp' --- -2.27.0 - diff --git a/Add-disas-gdb.patch b/Add-disas-gdb.patch deleted file mode 100644 index 3ccf9076a564145033a61d031a7dd9db2c51b55b..0000000000000000000000000000000000000000 --- a/Add-disas-gdb.patch +++ /dev/null @@ -1,2882 +0,0 @@ -From e66da47c4fc44bf2e861fbe58a84e08b11fd3f3b Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 07:17:12 -0500 -Subject: [PATCH] Add disas gdb. - -Add disas gdb xml. - -Signed-off-by: lixianglai ---- - disas/loongarch.c | 2736 ++++++++++++++++++++++++++++++++++ - disas/meson.build | 1 + - gdb-xml/loongarch-base64.xml | 45 + - gdb-xml/loongarch-fpu.xml | 50 + - 4 files changed, 2832 insertions(+) - create mode 100644 disas/loongarch.c - create mode 100644 gdb-xml/loongarch-base64.xml - create mode 100644 gdb-xml/loongarch-fpu.xml - -diff --git a/disas/loongarch.c b/disas/loongarch.c -new file mode 100644 -index 0000000000..b3f38e99ab ---- /dev/null -+++ b/disas/loongarch.c -@@ -0,0 +1,2736 @@ -+/* -+ * QEMU Loongarch Disassembler -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ */ -+ -+#include "qemu/osdep.h" -+#include "disas/dis-asm.h" -+ -+#define INSNLEN 4 -+ -+/* types */ -+typedef uint16_t la_opcode; -+ -+/* enums */ -+typedef enum { -+ la_op_illegal = 0, -+ la_op_gr2scr = 1, -+ la_op_scr2gr = 2, -+ la_op_clo_w = 3, -+ la_op_clz_w = 4, -+ la_op_cto_w = 5, -+ la_op_ctz_w = 6, -+ la_op_clo_d = 7, -+ la_op_clz_d = 8, -+ la_op_cto_d = 9, -+ la_op_ctz_d = 10, -+ la_op_revb_2h = 11, -+ la_op_revb_4h = 12, -+ la_op_revb_2w = 13, -+ la_op_revb_d = 14, -+ la_op_revh_2w = 15, -+ la_op_revh_d = 16, -+ la_op_bitrev_4b = 17, -+ la_op_bitrev_8b = 18, -+ la_op_bitrev_w = 19, -+ la_op_bitrev_d = 20, -+ la_op_ext_w_h = 21, -+ la_op_ext_w_b = 22, -+ la_op_rdtime_d = 23, -+ la_op_cpucfg = 24, -+ la_op_asrtle_d = 25, -+ la_op_asrtgt_d = 26, -+ la_op_alsl_w = 27, -+ la_op_alsl_wu = 28, -+ la_op_bytepick_w = 29, -+ la_op_bytepick_d = 30, -+ la_op_add_w = 31, -+ la_op_add_d = 32, -+ la_op_sub_w = 33, -+ la_op_sub_d = 34, -+ la_op_slt = 35, -+ la_op_sltu = 36, -+ la_op_maskeqz = 37, -+ la_op_masknez = 38, -+ la_op_nor = 39, -+ la_op_and = 40, -+ la_op_or = 41, -+ la_op_xor = 42, -+ la_op_orn = 43, -+ la_op_andn = 44, -+ la_op_sll_w = 45, -+ la_op_srl_w = 46, -+ la_op_sra_w = 47, -+ la_op_sll_d = 48, -+ la_op_srl_d = 49, -+ la_op_sra_d = 50, -+ la_op_rotr_w = 51, -+ la_op_rotr_d = 52, -+ la_op_mul_w = 53, -+ la_op_mulh_w = 54, -+ la_op_mulh_wu = 55, -+ la_op_mul_d = 56, -+ la_op_mulh_d = 57, -+ la_op_mulh_du = 58, -+ la_op_mulw_d_w = 59, -+ la_op_mulw_d_wu = 60, -+ la_op_div_w = 61, -+ la_op_mod_w = 62, -+ la_op_div_wu = 63, -+ la_op_mod_wu = 64, -+ la_op_div_d = 65, -+ la_op_mod_d = 66, -+ la_op_div_du = 67, -+ la_op_mod_du = 68, -+ la_op_crc_w_b_w = 69, -+ la_op_crc_w_h_w = 70, -+ la_op_crc_w_w_w = 71, -+ la_op_crc_w_d_w = 72, -+ la_op_crcc_w_b_w = 73, -+ la_op_crcc_w_h_w = 74, -+ la_op_crcc_w_w_w = 75, -+ la_op_crcc_w_d_w = 76, -+ la_op_break = 77, -+ la_op_dbcl = 78, -+ la_op_syscall = 79, -+ la_op_alsl_d = 80, -+ la_op_slli_w = 81, -+ la_op_slli_d = 82, -+ la_op_srli_w = 83, -+ la_op_srli_d = 84, -+ la_op_srai_w = 85, -+ la_op_srai_d = 86, -+ la_op_rotri_w = 87, -+ la_op_rotri_d = 88, -+ la_op_bstrins_w = 89, -+ la_op_bstrpick_w = 90, -+ la_op_bstrins_d = 91, -+ la_op_bstrpick_d = 92, -+ la_op_fadd_s = 93, -+ la_op_fadd_d = 94, -+ la_op_fsub_s = 95, -+ la_op_fsub_d = 96, -+ la_op_fmul_s = 97, -+ la_op_fmul_d = 98, -+ la_op_fdiv_s = 99, -+ la_op_fdiv_d = 100, -+ la_op_fmax_s = 101, -+ la_op_fmax_d = 102, -+ la_op_fmin_s = 103, -+ la_op_fmin_d = 104, -+ la_op_fmaxa_s = 105, -+ la_op_fmaxa_d = 106, -+ la_op_fmina_s = 107, -+ la_op_fmina_d = 108, -+ la_op_fscaleb_s = 109, -+ la_op_fscaleb_d = 110, -+ la_op_fcopysign_s = 111, -+ la_op_fcopysign_d = 112, -+ la_op_fabs_s = 113, -+ la_op_fabs_d = 114, -+ la_op_fneg_s = 115, -+ la_op_fneg_d = 116, -+ la_op_flogb_s = 117, -+ la_op_flogb_d = 118, -+ la_op_fclass_s = 119, -+ la_op_fclass_d = 120, -+ la_op_fsqrt_s = 121, -+ la_op_fsqrt_d = 122, -+ la_op_frecip_s = 123, -+ la_op_frecip_d = 124, -+ la_op_frsqrt_s = 125, -+ la_op_frsqrt_d = 126, -+ la_op_fmov_s = 127, -+ la_op_fmov_d = 128, -+ la_op_movgr2fr_w = 129, -+ la_op_movgr2fr_d = 130, -+ la_op_movgr2frh_w = 131, -+ la_op_movfr2gr_s = 132, -+ la_op_movfr2gr_d = 133, -+ la_op_movfrh2gr_s = 134, -+ la_op_movgr2fcsr = 135, -+ la_op_movfcsr2gr = 136, -+ la_op_movfr2cf = 137, -+ la_op_movcf2fr = 138, -+ la_op_movgr2cf = 139, -+ la_op_movcf2gr = 140, -+ la_op_fcvt_s_d = 141, -+ la_op_fcvt_d_s = 142, -+ -+ la_op_ftintrm_w_s = 143, -+ la_op_ftintrm_w_d = 144, -+ la_op_ftintrm_l_s = 145, -+ la_op_ftintrm_l_d = 146, -+ la_op_ftintrp_w_s = 147, -+ la_op_ftintrp_w_d = 148, -+ la_op_ftintrp_l_s = 149, -+ la_op_ftintrp_l_d = 150, -+ la_op_ftintrz_w_s = 151, -+ la_op_ftintrz_w_d = 152, -+ la_op_ftintrz_l_s = 153, -+ la_op_ftintrz_l_d = 154, -+ la_op_ftintrne_w_s = 155, -+ la_op_ftintrne_w_d = 156, -+ la_op_ftintrne_l_s = 157, -+ la_op_ftintrne_l_d = 158, -+ la_op_ftint_w_s = 159, -+ la_op_ftint_w_d = 160, -+ la_op_ftint_l_s = 161, -+ la_op_ftint_l_d = 162, -+ la_op_ffint_s_w = 163, -+ la_op_ffint_s_l = 164, -+ la_op_ffint_d_w = 165, -+ la_op_ffint_d_l = 166, -+ la_op_frint_s = 167, -+ la_op_frint_d = 168, -+ -+ la_op_slti = 169, -+ la_op_sltui = 170, -+ la_op_addi_w = 171, -+ la_op_addi_d = 172, -+ la_op_lu52i_d = 173, -+ la_op_addi = 174, -+ la_op_ori = 175, -+ la_op_xori = 176, -+ -+ la_op_csrxchg = 177, -+ la_op_cacop = 178, -+ la_op_lddir = 179, -+ la_op_ldpte = 180, -+ la_op_iocsrrd_b = 181, -+ la_op_iocsrrd_h = 182, -+ la_op_iocsrrd_w = 183, -+ la_op_iocsrrd_d = 184, -+ la_op_iocsrwr_b = 185, -+ la_op_iocsrwr_h = 186, -+ la_op_iocsrwr_w = 187, -+ la_op_iocsrwr_d = 188, -+ la_op_tlbclr = 189, -+ la_op_tlbflush = 190, -+ la_op_tlbsrch = 191, -+ la_op_tlbrd = 192, -+ la_op_tlbwr = 193, -+ la_op_tlbfill = 194, -+ la_op_ertn = 195, -+ la_op_idle = 196, -+ la_op_invtlb = 197, -+ -+ la_op_fmadd_s = 198, -+ la_op_fmadd_d = 199, -+ la_op_fmsub_s = 200, -+ la_op_fmsub_d = 201, -+ la_op_fnmadd_s = 202, -+ la_op_fnmadd_d = 203, -+ la_op_fnmsub_s = 204, -+ la_op_fnmsub_d = 205, -+ la_op_fcmp_cond_s = 206, -+ la_op_fcmp_cond_d = 207, -+ la_op_fsel = 208, -+ la_op_addu16i_d = 209, -+ la_op_lu12i_w = 210, -+ la_op_lu32i_d = 211, -+ la_op_pcaddi = 212, -+ la_op_pcalau12i = 213, -+ la_op_pcaddu12i = 214, -+ la_op_pcaddu18i = 215, -+ -+ la_op_ll_w = 216, -+ la_op_sc_w = 217, -+ la_op_ll_d = 218, -+ la_op_sc_d = 219, -+ la_op_ldptr_w = 220, -+ la_op_stptr_w = 221, -+ la_op_ldptr_d = 222, -+ la_op_stptr_d = 223, -+ la_op_ld_b = 224, -+ la_op_ld_h = 225, -+ la_op_ld_w = 226, -+ la_op_ld_d = 227, -+ la_op_st_b = 228, -+ la_op_st_h = 229, -+ la_op_st_w = 230, -+ la_op_st_d = 231, -+ la_op_ld_bu = 232, -+ la_op_ld_hu = 233, -+ la_op_ld_wu = 234, -+ la_op_preld = 235, -+ la_op_fld_s = 236, -+ la_op_fst_s = 237, -+ la_op_fld_d = 238, -+ la_op_fst_d = 239, -+ la_op_ldl_w = 240, -+ la_op_ldr_w = 241, -+ la_op_ldl_d = 242, -+ la_op_ldr_d = 243, -+ la_op_stl_d = 244, -+ la_op_str_d = 245, -+ la_op_ldx_b = 246, -+ la_op_ldx_h = 247, -+ la_op_ldx_w = 248, -+ la_op_ldx_d = 249, -+ la_op_stx_b = 250, -+ la_op_stx_h = 251, -+ la_op_stx_w = 252, -+ la_op_stx_d = 253, -+ la_op_ldx_bu = 254, -+ la_op_ldx_hu = 255, -+ la_op_ldx_wu = 256, -+ la_op_fldx_s = 257, -+ la_op_fldx_d = 258, -+ la_op_fstx_s = 259, -+ la_op_fstx_d = 260, -+ -+ la_op_amswap_w = 261, -+ la_op_amswap_d = 262, -+ la_op_amadd_w = 263, -+ la_op_amadd_d = 264, -+ la_op_amand_w = 265, -+ la_op_amand_d = 266, -+ la_op_amor_w = 267, -+ la_op_amor_d = 268, -+ la_op_amxor_w = 269, -+ la_op_amxor_d = 270, -+ la_op_ammax_w = 271, -+ la_op_ammax_d = 272, -+ la_op_ammin_w = 273, -+ la_op_ammin_d = 274, -+ la_op_ammax_wu = 275, -+ la_op_ammax_du = 276, -+ la_op_ammin_wu = 277, -+ la_op_ammin_du = 278, -+ la_op_amswap_db_w = 279, -+ la_op_amswap_db_d = 280, -+ la_op_amadd_db_w = 281, -+ la_op_amadd_db_d = 282, -+ la_op_amand_db_w = 283, -+ la_op_amand_db_d = 284, -+ la_op_amor_db_w = 285, -+ la_op_amor_db_d = 286, -+ la_op_amxor_db_w = 287, -+ la_op_amxor_db_d = 288, -+ la_op_ammax_db_w = 289, -+ la_op_ammax_db_d = 290, -+ la_op_ammin_db_w = 291, -+ la_op_ammin_db_d = 292, -+ la_op_ammax_db_wu = 293, -+ la_op_ammax_db_du = 294, -+ la_op_ammin_db_wu = 295, -+ la_op_ammin_db_du = 296, -+ la_op_dbar = 297, -+ la_op_ibar = 298, -+ la_op_fldgt_s = 299, -+ la_op_fldgt_d = 300, -+ la_op_fldle_s = 301, -+ la_op_fldle_d = 302, -+ la_op_fstgt_s = 303, -+ la_op_fstgt_d = 304, -+ ls_op_fstle_s = 305, -+ la_op_fstle_d = 306, -+ la_op_ldgt_b = 307, -+ la_op_ldgt_h = 308, -+ la_op_ldgt_w = 309, -+ la_op_ldgt_d = 310, -+ la_op_ldle_b = 311, -+ la_op_ldle_h = 312, -+ la_op_ldle_w = 313, -+ la_op_ldle_d = 314, -+ la_op_stgt_b = 315, -+ la_op_stgt_h = 316, -+ la_op_stgt_w = 317, -+ la_op_stgt_d = 318, -+ la_op_stle_b = 319, -+ la_op_stle_h = 320, -+ la_op_stle_w = 321, -+ la_op_stle_d = 322, -+ la_op_beqz = 323, -+ la_op_bnez = 324, -+ la_op_bceqz = 325, -+ la_op_bcnez = 326, -+ la_op_jirl = 327, -+ la_op_b = 328, -+ la_op_bl = 329, -+ la_op_beq = 330, -+ la_op_bne = 331, -+ la_op_blt = 332, -+ la_op_bge = 333, -+ la_op_bltu = 334, -+ la_op_bgeu = 335, -+ -+ /* vz insn */ -+ la_op_hvcl = 336, -+ -+} la_op; -+ -+typedef enum { -+ la_codec_illegal, -+ la_codec_empty, -+ la_codec_2r, -+ la_codec_2r_u5, -+ la_codec_2r_u6, -+ la_codec_2r_2bw, -+ la_codec_2r_2bd, -+ la_codec_3r, -+ la_codec_3r_rd0, -+ la_codec_3r_sa2, -+ la_codec_3r_sa3, -+ la_codec_4r, -+ la_codec_r_im20, -+ la_codec_2r_im16, -+ la_codec_2r_im14, -+ la_codec_2r_im12, -+ la_codec_im5_r_im12, -+ la_codec_2r_im8, -+ la_codec_r_sd, -+ la_codec_r_sj, -+ la_codec_r_cd, -+ la_codec_r_cj, -+ la_codec_r_seq, -+ la_codec_code, -+ la_codec_whint, -+ la_codec_invtlb, -+ la_codec_r_ofs21, -+ la_codec_cj_ofs21, -+ la_codec_ofs26, -+ la_codec_cond, -+ la_codec_sel, -+ -+} la_codec; -+ -+#define la_fmt_illegal "nte" -+#define la_fmt_empty "nt" -+#define la_fmt_sd_rj "ntA,1" -+#define la_fmt_rd_sj "nt0,B" -+#define la_fmt_rd_rj "nt0,1" -+#define la_fmt_rj_rk "nt1,2" -+#define la_fmt_rj_seq "nt1,x" -+#define la_fmt_rd_si20 "nt0,i(x)" -+#define la_fmt_rd_rj_ui5 "nt0,1,C" -+#define la_fmt_rd_rj_ui6 "nt0,1.C" -+#define la_fmt_rd_rj_level "nt0,1,x" -+#define la_fmt_rd_rj_msbw_lsbw "nt0,1,C,D" -+#define la_fmt_rd_rj_msbd_lsbd "nt0,1,C,D" -+#define la_fmt_rd_rj_si12 "nt0,1,i(x)" -+#define la_fmt_hint_rj_si12 "ntE,1,i(x)" -+#define la_fmt_rd_rj_csr "nt0,1,x" -+#define la_fmt_rd_rj_si14 "nt0,1,i(x)" -+#define la_fmt_rd_rj_si16 "nt0,1,i(x)" -+#define la_fmt_rd_rj_rk "nt0,1,2" -+#define la_fmt_fd_rj_rk "nt3,1,2" -+#define la_fmt_rd_rj_rk_sa2 "nt0,1,2,D" -+#define la_fmt_rd_rj_rk_sa3 "nt0,1,2,D" -+#define la_fmt_fd_rj "nt3,1" -+#define la_fmt_rd_fj "nt0,4" -+#define la_fmt_fd_fj "nt3,4" -+#define la_fmt_fd_fj_si12 "nt3,4,i(x)" -+#define la_fmt_fcsrd_rj "ntF,1" -+#define la_fmt_rd_fcsrs "nt0,G" -+#define la_fmt_cd_fj "ntH,4" -+#define la_fmt_fd_cj "nt3,I" -+#define la_fmt_fd_fj_fk "nt3,4,5" -+#define la_fmt_code "ntJ" -+#define la_fmt_whint "ntx" -+#define la_fmt_invtlb "ntx,1,2" /* op,rj,rk */ -+#define la_fmt_offs26 "nto(X)p" -+#define la_fmt_rj_offs21 "nt1,o(X)p" -+#define la_fmt_cj_offs21 "ntQ,o(X)p" -+#define la_fmt_rd_rj_offs16 "nt0,1,o(X)" -+#define la_fmt_rj_rd_offs16 "nt1,0,o(X)p" -+#define la_fmt_s_cd_fj_fk "K.stH,4,5" -+#define la_fmt_d_cd_fj_fk "K.dtH,4,5" -+#define la_fmt_fd_fj_fk_fa "nt3,4,5,6" -+#define la_fmt_fd_fj_fk_ca "nt3,4,5,L" -+#define la_fmt_cop_rj_si12 "ntM,1,i(x)" -+ -+/* structures */ -+ -+typedef struct { -+ uint32_t pc; -+ uint32_t insn; -+ int32_t imm; -+ int32_t imm2; -+ uint16_t op; -+ uint16_t code; -+ uint8_t codec; -+ uint8_t r1; -+ uint8_t r2; -+ uint8_t r3; -+ uint8_t r4; -+ uint8_t bit; -+} la_decode; -+ -+typedef struct { -+ const char *const name; -+ const la_codec codec; -+ const char *const format; -+} la_opcode_data; -+ -+/* reg names */ -+const char *const loongarch_r_normal_name[32] = { -+ "$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 loongarch_f_normal_name[32] = { -+ "$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", -+}; -+ -+const char *const loongarch_cr_normal_name[4] = { -+ "$scr0", -+ "$scr1", -+ "$scr2", -+ "$scr3", -+}; -+ -+const char *const loongarch_c_normal_name[8] = { -+ "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7", -+}; -+ -+/* instruction data */ -+const la_opcode_data opcode_la[] = { -+ { "illegal", la_codec_illegal, la_fmt_illegal }, -+ { "gr2scr", la_codec_r_sd, la_fmt_sd_rj }, -+ { "scr2gr", la_codec_r_sj, la_fmt_rd_sj }, -+ { "clo.w", la_codec_2r, la_fmt_rd_rj }, -+ { "clz.w", la_codec_2r, la_fmt_rd_rj }, -+ { "cto.w", la_codec_2r, la_fmt_rd_rj }, -+ { "ctz.w", la_codec_2r, la_fmt_rd_rj }, -+ { "clo.d", la_codec_2r, la_fmt_rd_rj }, -+ { "clz.d", la_codec_2r, la_fmt_rd_rj }, -+ { "cto.d", la_codec_2r, la_fmt_rd_rj }, -+ { "ctz_d", la_codec_2r, la_fmt_rd_rj }, -+ { "revb.2h", la_codec_2r, la_fmt_rd_rj }, -+ { "revb.4h", la_codec_2r, la_fmt_rd_rj }, -+ { "revb.2w", la_codec_2r, la_fmt_rd_rj }, -+ { "revb.d", la_codec_2r, la_fmt_rd_rj }, -+ { "revh.2w", la_codec_2r, la_fmt_rd_rj }, -+ { "revh.d", la_codec_2r, la_fmt_rd_rj }, -+ { "bitrev.4b", la_codec_2r, la_fmt_rd_rj }, -+ { "bitrev.8b", la_codec_2r, la_fmt_rd_rj }, -+ { "bitrev.w", la_codec_2r, la_fmt_rd_rj }, -+ { "bitrev.d", la_codec_2r, la_fmt_rd_rj }, -+ { "ext.w.h", la_codec_2r, la_fmt_rd_rj }, -+ { "ext.w.b", la_codec_2r, la_fmt_rd_rj }, -+ { "rdtime.d", la_codec_2r, la_fmt_rd_rj }, -+ { "cpucfg", la_codec_2r, la_fmt_rd_rj }, -+ { "asrtle.d", la_codec_3r_rd0, la_fmt_rj_rk }, -+ { "asrtgt.d", la_codec_3r_rd0, la_fmt_rj_rk }, -+ { "alsl.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, -+ { "alsl.wu", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, -+ { "bytepick.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, -+ { "bytepick.d", la_codec_3r_sa3, la_fmt_rd_rj_rk_sa3 }, -+ { "add.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "add.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sub.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sub.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "slt", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sltu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "maskeqz", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "masknez", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "nor", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "and", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "or", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "xor", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "orn", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "andn", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sll.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "srl.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sra.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sll.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "srl.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "sra.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "rotr.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "rotr.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mul.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulh.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulh.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mul.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulh.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulh.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulw.d.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mulw.d.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "div.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mod.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "div.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mod.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "div.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mod.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "div.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "mod.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crcc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crcc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crcc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "crcc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "break", la_codec_code, la_fmt_code }, -+ { "dbcl", la_codec_code, la_fmt_code }, -+ { "syscall", la_codec_code, la_fmt_code }, -+ { "alsl.d", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, -+ { "slli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, -+ { "slli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, -+ { "srli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, -+ { "srli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, -+ { "srai.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, -+ { "srai.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, -+ { "rotri.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, -+ { "rotri.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, -+ { "bstrins.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, -+ { "bstrpick.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, -+ { "bstrins.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, -+ { "bstrpick.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, -+ { "fadd.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fadd.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fsub.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fsub.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmul.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmul.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fdiv.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fdiv.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmax.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmax.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmin.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmin.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmaxa.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmaxa.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmina.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fmina.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fscaleb.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fscaleb.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fcopysign.s", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fcopysign.d", la_codec_3r, la_fmt_fd_fj_fk }, -+ { "fabs.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fabs.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fneg.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fneg.d", la_codec_2r, la_fmt_fd_fj }, -+ { "flogb.s", la_codec_2r, la_fmt_fd_fj }, -+ { "flogb.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fclass.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fclass.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fsqrt.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fsqrt.d", la_codec_2r, la_fmt_fd_fj }, -+ { "frecip.s", la_codec_2r, la_fmt_fd_fj }, -+ { "frecip.d", la_codec_2r, la_fmt_fd_fj }, -+ { "frsqrt.s", la_codec_2r, la_fmt_fd_fj }, -+ { "frsqrt.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fmov.s", la_codec_2r, la_fmt_fd_fj }, -+ { "fmov.d", la_codec_2r, la_fmt_fd_fj }, -+ { "movgr2fr.w", la_codec_2r, la_fmt_fd_rj }, -+ { "movgr2fr.d", la_codec_2r, la_fmt_fd_rj }, -+ { "movgr2frh.w", la_codec_2r, la_fmt_fd_rj }, -+ { "movfr2gr.s", la_codec_2r, la_fmt_rd_fj }, -+ { "movfr2gr.d", la_codec_2r, la_fmt_rd_fj }, -+ { "movfrh2gr.s", la_codec_2r, la_fmt_rd_fj }, -+ { "movgr2fcsr", la_codec_2r, la_fmt_fcsrd_rj }, -+ { "movfcsr2gr", la_codec_2r, la_fmt_rd_fcsrs }, -+ { "movfr2cf", la_codec_r_cd, la_fmt_cd_fj }, -+ { "movcf2fr", la_codec_r_cj, la_fmt_fd_cj }, -+ { "movgr2cf", la_codec_r_cd, la_fmt_cd_fj }, -+ { "movcf2gr", la_codec_r_cj, la_fmt_fd_cj }, -+ { "fcvt.s.d", la_codec_2r, la_fmt_fd_fj }, -+ { "fcvt.d.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrm.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrm.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrm.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrm.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrp.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrp.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrp.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrp.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrz.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrz.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrz.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrz.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrne.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrne.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrne.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftintrne.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftint.w.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftint.w.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ftint.l.s", la_codec_2r, la_fmt_fd_fj }, -+ { "ftint.l.d", la_codec_2r, la_fmt_fd_fj }, -+ { "ffint.s.w", la_codec_2r, la_fmt_fd_fj }, -+ { "ffint.s.l", la_codec_2r, la_fmt_fd_fj }, -+ { "ffint.d.w", la_codec_2r, la_fmt_fd_fj }, -+ { "ffint.d.l", la_codec_2r, la_fmt_fd_fj }, -+ { "frint.s", la_codec_2r, la_fmt_fd_fj }, -+ { "frint.d", la_codec_2r, la_fmt_fd_fj }, -+ { "slti", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "sltui", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "addi.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "addi.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "lu52i.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "addi", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "xori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "csrxchg", la_codec_2r_im14, la_fmt_rd_rj_csr }, -+ { "cacop", la_codec_im5_r_im12, la_fmt_cop_rj_si12 }, -+ { "lddir", la_codec_2r_im8, la_fmt_rd_rj_level }, -+ { "ldpte", la_codec_r_seq, la_fmt_rj_seq }, -+ { "iocsrrd.b", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrrd.h", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrrd.w", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrrd.d", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrwr.b", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrwr.h", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrwr.w", la_codec_2r, la_fmt_rd_rj }, -+ { "iocsrwr.d", la_codec_2r, la_fmt_rd_rj }, -+ { "tlbclr", la_codec_empty, la_fmt_empty }, -+ { "tlbflush", la_codec_empty, la_fmt_empty }, -+ { "tlbsrch", la_codec_empty, la_fmt_empty }, -+ { "tlbrd", la_codec_empty, la_fmt_empty }, -+ { "tlbwr", la_codec_empty, la_fmt_empty }, -+ { "tlbfill", la_codec_empty, la_fmt_empty }, -+ { "ertn", la_codec_empty, la_fmt_empty }, -+ { "idle", la_codec_whint, la_fmt_whint }, -+ { "invtlb", la_codec_invtlb, la_fmt_invtlb }, -+ { "fmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fnmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fnmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fnmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fnmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, -+ { "fcmp.cond.s", la_codec_cond, la_fmt_s_cd_fj_fk }, -+ { "fcmp.cond.d", la_codec_cond, la_fmt_d_cd_fj_fk }, -+ { "fsel", la_codec_sel, la_fmt_fd_fj_fk_ca }, -+ { "addu16i.d", la_codec_2r_im16, la_fmt_rd_rj_si16 }, -+ { "lu12i.w", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "lu32i.d", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "pcaddi", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "pcalau12i", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "pcaddu12i", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "pcaddu18i", la_codec_r_im20, la_fmt_rd_si20 }, -+ { "ll.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "sc.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "ll.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "sc.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "ldptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "stptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "ldptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "stptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, -+ { "ld.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "st.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "st.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "st.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "st.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.bu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.hu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ld.wu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "preld", la_codec_2r_im12, la_fmt_hint_rj_si12 }, -+ { "fld.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, -+ { "fst.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, -+ { "fld.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, -+ { "fst.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, -+ { "ldl.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ldr.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ldl.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ldr.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "stl.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "str.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, -+ { "ldx.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stx.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stx.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stx.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stx.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.bu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.hu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldx.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "fldx.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fldx.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstx.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstx.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "amswap.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amswap.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amadd.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amadd.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amand.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amand.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amor.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amor.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amxor.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amxor.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amswap.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amswap.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amadd.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amadd.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amand.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amand.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amxor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "amxor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.db.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.db.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammax.db.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ammin.db.du", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "dbar", la_codec_whint, la_fmt_whint }, -+ { "ibar", la_codec_whint, la_fmt_whint }, -+ { "fldgt.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fldgt.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fldle.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fldle.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstgt.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstgt.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstle.s", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "fstle.d", la_codec_3r, la_fmt_fd_rj_rk }, -+ { "ldgt.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldgt.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldgt.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldgt.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldle.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldle.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldle.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "ldle.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stgt.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stgt.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stgt.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stgt.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stle.b", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stle.h", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stle.w", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "stle.d", la_codec_3r, la_fmt_rd_rj_rk }, -+ { "beqz", la_codec_r_ofs21, la_fmt_rj_offs21 }, -+ { "bnez", la_codec_r_ofs21, la_fmt_rj_offs21 }, -+ { "bceqz", la_codec_cj_ofs21, la_fmt_cj_offs21 }, -+ { "bcnez", la_codec_cj_ofs21, la_fmt_cj_offs21 }, -+ { "jirl", la_codec_2r_im16, la_fmt_rd_rj_offs16 }, -+ { "b", la_codec_ofs26, la_fmt_offs26 }, -+ { "bl", la_codec_ofs26, la_fmt_offs26 }, -+ { "beq", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "bne", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "blt", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "bge", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "bltu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ { "bgeu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, -+ -+ /* vz insn */ -+ { "hvcl", la_codec_code, la_fmt_code }, -+ -+}; -+ -+/* decode opcode */ -+static void decode_insn_opcode(la_decode *dec) -+{ -+ uint32_t insn = dec->insn; -+ uint16_t op = la_op_illegal; -+ switch ((insn >> 26) & 0x3f) { -+ case 0x0: -+ switch ((insn >> 22) & 0xf) { -+ case 0x0: -+ switch ((insn >> 18) & 0xf) { -+ case 0x0: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x2: -+ switch ((insn >> 2) & 0x7) { -+ case 0x0: -+ op = la_op_gr2scr; -+ break; -+ } -+ break; -+ case 0x3: -+ switch ((insn >> 7) & 0x7) { -+ case 0x0: -+ op = la_op_scr2gr; -+ break; -+ } -+ break; -+ case 0x4: -+ op = la_op_clo_w; -+ break; -+ case 0x5: -+ op = la_op_clz_w; -+ break; -+ case 0x6: -+ op = la_op_cto_w; -+ break; -+ case 0x7: -+ op = la_op_ctz_w; -+ break; -+ case 0x8: -+ op = la_op_clo_d; -+ break; -+ case 0x9: -+ op = la_op_clz_d; -+ break; -+ case 0xa: -+ op = la_op_cto_d; -+ break; -+ case 0xb: -+ op = la_op_ctz_d; -+ break; -+ case 0xc: -+ op = la_op_revb_2h; -+ break; -+ case 0xd: -+ op = la_op_revb_4h; -+ break; -+ case 0xe: -+ op = la_op_revb_2w; -+ break; -+ case 0xf: -+ op = la_op_revb_d; -+ break; -+ case 0x10: -+ op = la_op_revh_2w; -+ break; -+ case 0x11: -+ op = la_op_revh_d; -+ break; -+ case 0x12: -+ op = la_op_bitrev_4b; -+ break; -+ case 0x13: -+ op = la_op_bitrev_8b; -+ break; -+ case 0x14: -+ op = la_op_bitrev_w; -+ break; -+ case 0x15: -+ op = la_op_bitrev_d; -+ break; -+ case 0x16: -+ op = la_op_ext_w_h; -+ break; -+ case 0x17: -+ op = la_op_ext_w_b; -+ break; -+ case 0x1a: -+ op = la_op_rdtime_d; -+ break; -+ case 0x1b: -+ op = la_op_cpucfg; -+ break; -+ } -+ break; -+ case 0x2: -+ switch (insn & 0x0000001f) { -+ case 0x00000000: -+ op = la_op_asrtle_d; -+ break; -+ } -+ break; -+ case 0x3: -+ switch (insn & 0x0000001f) { -+ case 0x00000000: -+ op = la_op_asrtgt_d; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x1: -+ switch ((insn >> 17) & 0x1) { -+ case 0x0: -+ op = la_op_alsl_w; -+ break; -+ case 0x1: -+ op = la_op_alsl_wu; -+ break; -+ } -+ break; -+ case 0x2: -+ switch ((insn >> 17) & 0x1) { -+ case 0x0: -+ op = la_op_bytepick_w; -+ break; -+ } -+ break; -+ case 0x3: -+ op = la_op_bytepick_d; -+ break; -+ case 0x4: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_add_w; -+ break; -+ case 0x1: -+ op = la_op_add_d; -+ break; -+ case 0x2: -+ op = la_op_sub_w; -+ break; -+ case 0x3: -+ op = la_op_sub_d; -+ break; -+ case 0x4: -+ op = la_op_slt; -+ break; -+ case 0x5: -+ op = la_op_sltu; -+ break; -+ case 0x6: -+ op = la_op_maskeqz; -+ break; -+ case 0x7: -+ op = la_op_masknez; -+ break; -+ } -+ break; -+ case 0x5: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_nor; -+ break; -+ case 0x1: -+ op = la_op_and; -+ break; -+ case 0x2: -+ op = la_op_or; -+ break; -+ case 0x3: -+ op = la_op_xor; -+ break; -+ case 0x4: -+ op = la_op_orn; -+ break; -+ case 0x5: -+ op = la_op_andn; -+ break; -+ case 0x6: -+ op = la_op_sll_w; -+ break; -+ case 0x7: -+ op = la_op_srl_w; -+ break; -+ } -+ break; -+ case 0x6: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_sra_w; -+ break; -+ case 0x1: -+ op = la_op_sll_d; -+ break; -+ case 0x2: -+ op = la_op_srl_d; -+ break; -+ case 0x3: -+ op = la_op_sra_d; -+ break; -+ case 0x6: -+ op = la_op_rotr_w; -+ break; -+ case 0x7: -+ op = la_op_rotr_d; -+ break; -+ } -+ break; -+ case 0x7: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_mul_w; -+ break; -+ case 0x1: -+ op = la_op_mulh_w; -+ break; -+ case 0x2: -+ op = la_op_mulh_wu; -+ break; -+ case 0x3: -+ op = la_op_mul_d; -+ break; -+ case 0x4: -+ op = la_op_mulh_d; -+ break; -+ case 0x5: -+ op = la_op_mulh_du; -+ break; -+ case 0x6: -+ op = la_op_mulw_d_w; -+ break; -+ case 0x7: -+ op = la_op_mulw_d_wu; -+ break; -+ } -+ break; -+ case 0x8: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_div_w; -+ break; -+ case 0x1: -+ op = la_op_mod_w; -+ break; -+ case 0x2: -+ op = la_op_div_wu; -+ break; -+ case 0x3: -+ op = la_op_mod_wu; -+ break; -+ case 0x4: -+ op = la_op_div_d; -+ break; -+ case 0x5: -+ op = la_op_mod_d; -+ break; -+ case 0x6: -+ op = la_op_div_du; -+ break; -+ case 0x7: -+ op = la_op_mod_du; -+ break; -+ } -+ break; -+ case 0x9: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ op = la_op_crc_w_b_w; -+ break; -+ case 0x1: -+ op = la_op_crc_w_h_w; -+ break; -+ case 0x2: -+ op = la_op_crc_w_w_w; -+ break; -+ case 0x3: -+ op = la_op_crc_w_d_w; -+ break; -+ case 0x4: -+ op = la_op_crcc_w_b_w; -+ break; -+ case 0x5: -+ op = la_op_crcc_w_h_w; -+ break; -+ case 0x6: -+ op = la_op_crcc_w_w_w; -+ break; -+ case 0x7: -+ op = la_op_crcc_w_d_w; -+ break; -+ } -+ break; -+ case 0xa: -+ switch ((insn >> 15) & 0x7) { -+ case 0x4: -+ op = la_op_break; -+ break; -+ case 0x5: -+ op = la_op_dbcl; -+ break; -+ case 0x6: -+ op = la_op_syscall; -+ break; -+ case 0x7: -+ op = la_op_hvcl; -+ break; -+ } -+ break; -+ case 0xb: -+ switch ((insn >> 17) & 0x1) { -+ case 0x0: -+ op = la_op_alsl_d; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x1: -+ switch ((insn >> 21) & 0x1) { -+ case 0x0: -+ switch ((insn >> 16) & 0x1f) { -+ case 0x0: -+ switch ((insn >> 15) & 0x1) { -+ case 0x1: -+ op = la_op_slli_w; -+ break; -+ } -+ break; -+ case 0x1: -+ op = la_op_slli_d; -+ break; -+ case 0x4: -+ switch ((insn >> 15) & 0x1) { -+ case 0x1: -+ op = la_op_srli_w; -+ break; -+ } -+ break; -+ case 0x5: -+ op = la_op_srli_d; -+ break; -+ case 0x8: -+ switch ((insn >> 15) & 0x1) { -+ case 0x1: -+ op = la_op_srai_w; -+ break; -+ } -+ break; -+ case 0x9: -+ op = la_op_srai_d; -+ break; -+ case 0xc: -+ switch ((insn >> 15) & 0x1) { -+ case 0x1: -+ op = la_op_rotri_w; -+ break; -+ } -+ break; -+ case 0xd: -+ op = la_op_rotri_d; -+ break; -+ } -+ break; -+ case 0x1: -+ switch ((insn >> 15) & 0x1) { -+ case 0x0: -+ op = la_op_bstrins_w; -+ break; -+ case 0x1: -+ op = la_op_bstrpick_w; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x2: -+ op = la_op_bstrins_d; -+ break; -+ case 0x3: -+ op = la_op_bstrpick_d; -+ break; -+ case 0x4: -+ switch ((insn >> 15) & 0x7f) { -+ case 0x1: -+ op = la_op_fadd_s; -+ break; -+ case 0x2: -+ op = la_op_fadd_d; -+ break; -+ case 0x5: -+ op = la_op_fsub_s; -+ break; -+ case 0x6: -+ op = la_op_fsub_d; -+ break; -+ case 0x9: -+ op = la_op_fmul_s; -+ break; -+ case 0xa: -+ op = la_op_fmul_d; -+ break; -+ case 0xd: -+ op = la_op_fdiv_s; -+ break; -+ case 0xe: -+ op = la_op_fdiv_d; -+ break; -+ case 0x11: -+ op = la_op_fmax_s; -+ break; -+ case 0x12: -+ op = la_op_fmax_d; -+ break; -+ case 0x15: -+ op = la_op_fmin_s; -+ break; -+ case 0x16: -+ op = la_op_fmin_d; -+ break; -+ case 0x19: -+ op = la_op_fmaxa_s; -+ break; -+ case 0x1a: -+ op = la_op_fmaxa_d; -+ break; -+ case 0x1d: -+ op = la_op_fmina_s; -+ break; -+ case 0x1e: -+ op = la_op_fmina_d; -+ break; -+ case 0x21: -+ op = la_op_fscaleb_s; -+ break; -+ case 0x22: -+ op = la_op_fscaleb_d; -+ break; -+ case 0x25: -+ op = la_op_fcopysign_s; -+ break; -+ case 0x26: -+ op = la_op_fcopysign_d; -+ break; -+ case 0x28: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x1: -+ op = la_op_fabs_s; -+ break; -+ case 0x2: -+ op = la_op_fabs_d; -+ break; -+ case 0x5: -+ op = la_op_fneg_s; -+ break; -+ case 0x6: -+ op = la_op_fneg_d; -+ break; -+ case 0x9: -+ op = la_op_flogb_s; -+ break; -+ case 0xa: -+ op = la_op_flogb_d; -+ break; -+ case 0xd: -+ op = la_op_fclass_s; -+ break; -+ case 0xe: -+ op = la_op_fclass_d; -+ break; -+ case 0x11: -+ op = la_op_fsqrt_s; -+ break; -+ case 0x12: -+ op = la_op_fsqrt_d; -+ break; -+ case 0x15: -+ op = la_op_frecip_s; -+ break; -+ case 0x16: -+ op = la_op_frecip_d; -+ break; -+ case 0x19: -+ op = la_op_frsqrt_s; -+ break; -+ case 0x1a: -+ op = la_op_frsqrt_d; -+ break; -+ } -+ break; -+ case 0x29: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x5: -+ op = la_op_fmov_s; -+ break; -+ case 0x6: -+ op = la_op_fmov_d; -+ break; -+ case 0x9: -+ op = la_op_movgr2fr_w; -+ break; -+ case 0xa: -+ op = la_op_movgr2fr_d; -+ break; -+ case 0xb: -+ op = la_op_movgr2frh_w; -+ break; -+ case 0xd: -+ op = la_op_movfr2gr_s; -+ break; -+ case 0xe: -+ op = la_op_movfr2gr_d; -+ break; -+ case 0xf: -+ op = la_op_movfrh2gr_s; -+ break; -+ case 0x10: -+ op = la_op_movgr2fcsr; -+ break; -+ case 0x12: -+ op = la_op_movfcsr2gr; -+ break; -+ case 0x14: -+ switch ((insn >> 3) & 0x3) { -+ case 0x0: -+ op = la_op_movfr2cf; -+ break; -+ } -+ break; -+ case 0x15: -+ switch ((insn >> 8) & 0x3) { -+ case 0x0: -+ op = la_op_movcf2fr; -+ break; -+ } -+ break; -+ case 0x16: -+ switch ((insn >> 3) & 0x3) { -+ case 0x0: -+ op = la_op_movgr2cf; -+ break; -+ } -+ break; -+ case 0x17: -+ switch ((insn >> 8) & 0x3) { -+ case 0x0: -+ op = la_op_movcf2gr; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x32: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x6: -+ op = la_op_fcvt_s_d; -+ break; -+ case 0x9: -+ op = la_op_fcvt_d_s; -+ break; -+ } -+ break; -+ case 0x34: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x1: -+ op = la_op_ftintrm_w_s; -+ break; -+ case 0x2: -+ op = la_op_ftintrm_w_d; -+ break; -+ case 0x9: -+ op = la_op_ftintrm_l_s; -+ break; -+ case 0xa: -+ op = la_op_ftintrm_l_d; -+ break; -+ case 0x11: -+ op = la_op_ftintrp_w_s; -+ break; -+ case 0x12: -+ op = la_op_ftintrp_w_d; -+ break; -+ case 0x19: -+ op = la_op_ftintrp_l_s; -+ break; -+ case 0x1a: -+ op = la_op_ftintrp_l_d; -+ break; -+ } -+ break; -+ case 0x35: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x1: -+ op = la_op_ftintrz_w_s; -+ break; -+ case 0x2: -+ op = la_op_ftintrz_w_d; -+ break; -+ case 0x9: -+ op = la_op_ftintrz_l_s; -+ break; -+ case 0xa: -+ op = la_op_ftintrz_l_d; -+ break; -+ case 0x11: -+ op = la_op_ftintrne_w_s; -+ break; -+ case 0x12: -+ op = la_op_ftintrne_w_d; -+ break; -+ case 0x19: -+ op = la_op_ftintrne_l_s; -+ break; -+ case 0x1a: -+ op = la_op_ftintrne_l_d; -+ break; -+ } -+ break; -+ case 0x36: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x1: -+ op = la_op_ftint_w_s; -+ break; -+ case 0x2: -+ op = la_op_ftint_w_d; -+ break; -+ case 0x9: -+ op = la_op_ftint_l_s; -+ break; -+ case 0xa: -+ op = la_op_ftint_l_d; -+ break; -+ } -+ break; -+ case 0x3a: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x4: -+ op = la_op_ffint_s_w; -+ break; -+ case 0x6: -+ op = la_op_ffint_s_l; -+ break; -+ case 0x8: -+ op = la_op_ffint_d_w; -+ break; -+ case 0xa: -+ op = la_op_ffint_d_l; -+ break; -+ } -+ break; -+ case 0x3c: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x11: -+ op = la_op_frint_s; -+ break; -+ case 0x12: -+ op = la_op_frint_d; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x8: -+ op = la_op_slti; -+ break; -+ case 0x9: -+ op = la_op_sltui; -+ break; -+ case 0xa: -+ op = la_op_addi_w; -+ break; -+ case 0xb: -+ op = la_op_addi_d; -+ break; -+ case 0xc: -+ op = la_op_lu52i_d; -+ break; -+ case 0xd: -+ op = la_op_addi; -+ break; -+ case 0xe: -+ op = la_op_ori; -+ break; -+ case 0xf: -+ op = la_op_xori; -+ break; -+ } -+ break; -+ case 0x1: -+ switch ((insn >> 24) & 0x3) { -+ case 0x0: -+ op = la_op_csrxchg; -+ break; -+ case 0x2: -+ switch ((insn >> 22) & 0x3) { -+ case 0x0: -+ op = la_op_cacop; -+ break; -+ case 0x1: -+ switch ((insn >> 18) & 0xf) { -+ case 0x0: -+ op = la_op_lddir; -+ break; -+ case 0x1: -+ switch (insn & 0x0000001f) { -+ case 0x00000000: -+ op = la_op_ldpte; -+ break; -+ } -+ break; -+ case 0x2: -+ switch ((insn >> 15) & 0x7) { -+ case 0x0: -+ switch ((insn >> 10) & 0x1f) { -+ case 0x0: -+ op = la_op_iocsrrd_b; -+ break; -+ case 0x1: -+ op = la_op_iocsrrd_h; -+ break; -+ case 0x2: -+ op = la_op_iocsrrd_w; -+ break; -+ case 0x3: -+ op = la_op_iocsrrd_d; -+ break; -+ case 0x4: -+ op = la_op_iocsrwr_b; -+ break; -+ case 0x5: -+ op = la_op_iocsrwr_h; -+ break; -+ case 0x6: -+ op = la_op_iocsrwr_w; -+ break; -+ case 0x7: -+ op = la_op_iocsrwr_d; -+ break; -+ case 0x8: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbclr; -+ break; -+ } -+ break; -+ case 0x9: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbflush; -+ break; -+ } -+ break; -+ case 0xa: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbsrch; -+ break; -+ } -+ break; -+ case 0xb: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbrd; -+ break; -+ } -+ break; -+ case 0xc: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbwr; -+ break; -+ } -+ break; -+ case 0xd: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_tlbfill; -+ break; -+ } -+ break; -+ case 0xe: -+ switch (insn & 0x000003ff) { -+ case 0x00000000: -+ op = la_op_ertn; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x1: -+ op = la_op_idle; -+ break; -+ case 0x3: -+ op = la_op_invtlb; -+ break; -+ } -+ break; -+ } -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x2: -+ switch ((insn >> 20) & 0x3f) { -+ case 0x1: -+ op = la_op_fmadd_s; -+ break; -+ case 0x2: -+ op = la_op_fmadd_d; -+ break; -+ case 0x5: -+ op = la_op_fmsub_s; -+ break; -+ case 0x6: -+ op = la_op_fmsub_d; -+ break; -+ case 0x9: -+ op = la_op_fnmadd_s; -+ break; -+ case 0xa: -+ op = la_op_fnmadd_d; -+ break; -+ case 0xd: -+ op = la_op_fnmsub_s; -+ break; -+ case 0xe: -+ op = la_op_fnmsub_d; -+ break; -+ } -+ break; -+ case 0x3: -+ switch ((insn >> 20) & 0x3f) { -+ case 0x1: -+ switch ((insn >> 3) & 0x3) { -+ case 0x0: -+ op = la_op_fcmp_cond_s; -+ break; -+ } -+ break; -+ case 0x2: -+ switch ((insn >> 3) & 0x3) { -+ case 0x0: -+ op = la_op_fcmp_cond_d; -+ break; -+ } -+ break; -+ case 0x10: -+ switch ((insn >> 18) & 0x3) { -+ case 0x0: -+ op = la_op_fsel; -+ break; -+ } -+ break; -+ } -+ break; -+ case 0x4: -+ op = la_op_addu16i_d; -+ break; -+ case 0x5: -+ switch ((insn >> 25) & 0x1) { -+ case 0x0: -+ op = la_op_lu12i_w; -+ break; -+ case 0x1: -+ op = la_op_lu32i_d; -+ break; -+ } -+ break; -+ case 0x6: -+ switch ((insn >> 25) & 0x1) { -+ case 0x0: -+ op = la_op_pcaddi; -+ break; -+ case 0x1: -+ op = la_op_pcalau12i; -+ break; -+ } -+ break; -+ case 0x7: -+ switch ((insn >> 25) & 0x1) { -+ case 0x0: -+ op = la_op_pcaddu12i; -+ break; -+ case 0x1: -+ op = la_op_pcaddu18i; -+ break; -+ } -+ break; -+ case 0x8: -+ switch ((insn >> 24) & 0x3) { -+ case 0x0: -+ op = la_op_ll_w; -+ break; -+ case 0x1: -+ op = la_op_sc_w; -+ break; -+ case 0x2: -+ op = la_op_ll_d; -+ break; -+ case 0x3: -+ op = la_op_sc_d; -+ break; -+ } -+ break; -+ case 0x9: -+ switch ((insn >> 24) & 0x3) { -+ case 0x0: -+ op = la_op_ldptr_w; -+ break; -+ case 0x1: -+ op = la_op_stptr_w; -+ break; -+ case 0x2: -+ op = la_op_ldptr_d; -+ break; -+ case 0x3: -+ op = la_op_stptr_d; -+ break; -+ } -+ break; -+ case 0xa: -+ switch ((insn >> 22) & 0xf) { -+ case 0x0: -+ op = la_op_ld_b; -+ break; -+ case 0x1: -+ op = la_op_ld_h; -+ break; -+ case 0x2: -+ op = la_op_ld_w; -+ break; -+ case 0x3: -+ op = la_op_ld_d; -+ break; -+ case 0x4: -+ op = la_op_st_b; -+ break; -+ case 0x5: -+ op = la_op_st_h; -+ break; -+ case 0x6: -+ op = la_op_st_w; -+ break; -+ case 0x7: -+ op = la_op_st_d; -+ break; -+ case 0x8: -+ op = la_op_ld_bu; -+ break; -+ case 0x9: -+ op = la_op_ld_hu; -+ break; -+ case 0xa: -+ op = la_op_ld_wu; -+ break; -+ case 0xb: -+ op = la_op_preld; -+ break; -+ case 0xc: -+ op = la_op_fld_s; -+ break; -+ case 0xd: -+ op = la_op_fst_s; -+ break; -+ case 0xe: -+ op = la_op_fld_d; -+ break; -+ case 0xf: -+ op = la_op_fst_d; -+ break; -+ } -+ break; -+ case 0xb: -+ switch ((insn >> 22) & 0xf) { -+ case 0x8: -+ op = la_op_ldl_w; -+ break; -+ case 0x9: -+ op = la_op_ldr_w; -+ break; -+ case 0xa: -+ op = la_op_ldl_d; -+ break; -+ case 0xb: -+ op = la_op_ldr_d; -+ break; -+ case 0xe: -+ op = la_op_stl_d; -+ break; -+ case 0xf: -+ op = la_op_str_d; -+ break; -+ } -+ break; -+ case 0xe: -+ switch ((insn >> 15) & 0x7ff) { -+ case 0x0: -+ op = la_op_ldx_b; -+ break; -+ case 0x8: -+ op = la_op_ldx_h; -+ break; -+ case 0x10: -+ op = la_op_ldx_w; -+ break; -+ case 0x18: -+ op = la_op_ldx_d; -+ break; -+ case 0x20: -+ op = la_op_stx_b; -+ break; -+ case 0x28: -+ op = la_op_stx_h; -+ break; -+ case 0x30: -+ op = la_op_stx_w; -+ break; -+ case 0x38: -+ op = la_op_stx_d; -+ break; -+ case 0x40: -+ op = la_op_ldx_bu; -+ break; -+ case 0x48: -+ op = la_op_ldx_hu; -+ break; -+ case 0x50: -+ op = la_op_ldx_wu; -+ break; -+ case 0x60: -+ op = la_op_fldx_s; -+ break; -+ case 0x68: -+ op = la_op_fldx_d; -+ break; -+ case 0x70: -+ op = la_op_fstx_s; -+ break; -+ case 0x78: -+ op = la_op_fstx_d; -+ break; -+ case 0xc0: -+ op = la_op_amswap_w; -+ break; -+ case 0xc1: -+ op = la_op_amswap_d; -+ break; -+ case 0xc2: -+ op = la_op_amadd_w; -+ break; -+ case 0xc3: -+ op = la_op_amadd_d; -+ break; -+ case 0xc4: -+ op = la_op_amand_w; -+ break; -+ case 0xc5: -+ op = la_op_amand_d; -+ break; -+ case 0xc6: -+ op = la_op_amor_w; -+ break; -+ case 0xc7: -+ op = la_op_amor_d; -+ break; -+ case 0xc8: -+ op = la_op_amxor_w; -+ break; -+ case 0xc9: -+ op = la_op_amxor_d; -+ break; -+ case 0xca: -+ op = la_op_ammax_w; -+ break; -+ case 0xcb: -+ op = la_op_ammax_d; -+ break; -+ case 0xcc: -+ op = la_op_ammin_w; -+ break; -+ case 0xcd: -+ op = la_op_ammin_d; -+ break; -+ case 0xce: -+ op = la_op_ammax_wu; -+ break; -+ case 0xcf: -+ op = la_op_ammax_du; -+ break; -+ case 0xd0: -+ op = la_op_ammin_wu; -+ break; -+ case 0xd1: -+ op = la_op_ammin_du; -+ break; -+ case 0xd2: -+ op = la_op_amswap_db_w; -+ break; -+ case 0xd3: -+ op = la_op_amswap_db_d; -+ break; -+ case 0xd4: -+ op = la_op_amadd_db_w; -+ break; -+ case 0xd5: -+ op = la_op_amadd_db_d; -+ break; -+ case 0xd6: -+ op = la_op_amand_db_w; -+ break; -+ case 0xd7: -+ op = la_op_amand_db_d; -+ break; -+ case 0xd8: -+ op = la_op_amor_db_w; -+ break; -+ case 0xd9: -+ op = la_op_amor_db_d; -+ break; -+ case 0xda: -+ op = la_op_amxor_db_w; -+ break; -+ case 0xdb: -+ op = la_op_amxor_db_d; -+ break; -+ case 0xdc: -+ op = la_op_ammax_db_w; -+ break; -+ case 0xdd: -+ op = la_op_ammax_db_d; -+ break; -+ case 0xde: -+ op = la_op_ammin_db_w; -+ break; -+ case 0xdf: -+ op = la_op_ammin_db_d; -+ break; -+ case 0xe0: -+ op = la_op_ammax_db_wu; -+ break; -+ case 0xe1: -+ op = la_op_ammax_db_du; -+ break; -+ case 0xe2: -+ op = la_op_ammin_db_wu; -+ break; -+ case 0xe3: -+ op = la_op_ammin_db_du; -+ break; -+ case 0xe4: -+ op = la_op_dbar; -+ break; -+ case 0xe5: -+ op = la_op_ibar; -+ break; -+ case 0xe8: -+ op = la_op_fldgt_s; -+ break; -+ case 0xe9: -+ op = la_op_fldgt_d; -+ break; -+ case 0xea: -+ op = la_op_fldle_s; -+ break; -+ case 0xeb: -+ op = la_op_fldle_d; -+ break; -+ case 0xec: -+ op = la_op_fstgt_s; -+ break; -+ case 0xed: -+ op = la_op_fstgt_d; -+ break; -+ case 0xee: -+ op = ls_op_fstle_s; -+ break; -+ case 0xef: -+ op = la_op_fstle_d; -+ break; -+ case 0xf0: -+ op = la_op_ldgt_b; -+ break; -+ case 0xf1: -+ op = la_op_ldgt_h; -+ break; -+ case 0xf2: -+ op = la_op_ldgt_w; -+ break; -+ case 0xf3: -+ op = la_op_ldgt_d; -+ break; -+ case 0xf4: -+ op = la_op_ldle_b; -+ break; -+ case 0xf5: -+ op = la_op_ldle_h; -+ break; -+ case 0xf6: -+ op = la_op_ldle_w; -+ break; -+ case 0xf7: -+ op = la_op_ldle_d; -+ break; -+ case 0xf8: -+ op = la_op_stgt_b; -+ break; -+ case 0xf9: -+ op = la_op_stgt_h; -+ break; -+ case 0xfa: -+ op = la_op_stgt_w; -+ break; -+ case 0xfb: -+ op = la_op_stgt_d; -+ break; -+ case 0xfc: -+ op = la_op_stle_b; -+ break; -+ case 0xfd: -+ op = la_op_stle_h; -+ break; -+ case 0xfe: -+ op = la_op_stle_w; -+ break; -+ case 0xff: -+ op = la_op_stle_d; -+ break; -+ } -+ break; -+ case 0x10: -+ op = la_op_beqz; -+ break; -+ case 0x11: -+ op = la_op_bnez; -+ break; -+ case 0x12: -+ switch ((insn >> 8) & 0x3) { -+ case 0x0: -+ op = la_op_bceqz; -+ break; -+ case 0x1: -+ op = la_op_bcnez; -+ break; -+ } -+ break; -+ case 0x13: -+ op = la_op_jirl; -+ break; -+ case 0x14: -+ op = la_op_b; -+ break; -+ case 0x15: -+ op = la_op_bl; -+ break; -+ case 0x16: -+ op = la_op_beq; -+ break; -+ case 0x17: -+ op = la_op_bne; -+ break; -+ case 0x18: -+ op = la_op_blt; -+ break; -+ case 0x19: -+ op = la_op_bge; -+ break; -+ case 0x1a: -+ op = la_op_bltu; -+ break; -+ case 0x1b: -+ op = la_op_bgeu; -+ break; -+ default: -+ op = la_op_illegal; -+ break; -+ } -+ dec->op = op; -+} -+ -+/* operand extractors */ -+#define IM_5 5 -+#define IM_8 8 -+#define IM_12 12 -+#define IM_14 14 -+#define IM_15 15 -+#define IM_16 16 -+#define IM_20 20 -+#define IM_21 21 -+#define IM_26 26 -+ -+static uint32_t operand_r1(uint32_t insn) -+{ -+ return insn & 0x1f; -+} -+ -+static uint32_t operand_r2(uint32_t insn) -+{ -+ return (insn >> 5) & 0x1f; -+} -+ -+static uint32_t operand_r3(uint32_t insn) -+{ -+ return (insn >> 10) & 0x1f; -+} -+ -+static uint32_t operand_r4(uint32_t insn) -+{ -+ return (insn >> 15) & 0x1f; -+} -+ -+static uint32_t operand_u6(uint32_t insn) -+{ -+ return (insn >> 10) & 0x3f; -+} -+ -+static uint32_t operand_bw1(uint32_t insn) -+{ -+ return (insn >> 10) & 0x1f; -+} -+ -+static uint32_t operand_bw2(uint32_t insn) -+{ -+ return (insn >> 16) & 0x1f; -+} -+ -+static uint32_t operand_bd1(uint32_t insn) -+{ -+ return (insn >> 10) & 0x3f; -+} -+ -+static uint32_t operand_bd2(uint32_t insn) -+{ -+ return (insn >> 16) & 0x3f; -+} -+ -+static uint32_t operand_sa2(uint32_t insn) -+{ -+ return (insn >> 15) & 0x3; -+} -+ -+static uint32_t operand_sa3(uint32_t insn) -+{ -+ return (insn >> 15) & 0x3; -+} -+ -+static int32_t operand_im20(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 5) & 0xfffff); -+ return imm > (1 << 19) ? imm - (1 << 20) : imm; -+} -+ -+static int32_t operand_im16(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 10) & 0xffff); -+ return imm > (1 << 15) ? imm - (1 << 16) : imm; -+} -+ -+static int32_t operand_im14(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 10) & 0x3fff); -+ return imm > (1 << 13) ? imm - (1 << 14) : imm; -+} -+ -+static int32_t operand_im12(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 10) & 0xfff); -+ return imm > (1 << 11) ? imm - (1 << 12) : imm; -+} -+ -+static int32_t operand_im8(uint32_t insn) -+{ -+ int32_t imm = (int32_t)((insn >> 10) & 0xff); -+ return imm > (1 << 7) ? imm - (1 << 8) : imm; -+} -+ -+static uint32_t operand_sd(uint32_t insn) -+{ -+ return insn & 0x3; -+} -+ -+static uint32_t operand_sj(uint32_t insn) -+{ -+ return (insn >> 5) & 0x3; -+} -+ -+static uint32_t operand_cd(uint32_t insn) -+{ -+ return insn & 0x7; -+} -+ -+static uint32_t operand_cj(uint32_t insn) -+{ -+ return (insn >> 5) & 0x7; -+} -+ -+static uint32_t operand_code(uint32_t insn) -+{ -+ return insn & 0x7fff; -+} -+ -+static int32_t operand_whint(uint32_t insn) -+{ -+ int32_t imm = (int32_t)(insn & 0x7fff); -+ return imm > (1 << 14) ? imm - (1 << 15) : imm; -+} -+ -+static int32_t operand_invop(uint32_t insn) -+{ -+ int32_t imm = (int32_t)(insn & 0x1f); -+ return imm > (1 << 4) ? imm - (1 << 5) : imm; -+} -+ -+static int32_t operand_ofs21(uint32_t insn) -+{ -+ int32_t imm = (((int32_t)insn & 0x1f) << 16) | ((insn >> 10) & 0xffff); -+ return imm > (1 << 20) ? imm - (1 << 21) : imm; -+} -+ -+static int32_t operand_ofs26(uint32_t insn) -+{ -+ int32_t imm = (((int32_t)insn & 0x3ff) << 16) | ((insn >> 10) & 0xffff); -+ return imm > (1 << 25) ? imm - (1 << 26) : imm; -+} -+ -+static uint32_t operand_fcond(uint32_t insn) -+{ -+ return (insn >> 15) & 0x1f; -+} -+ -+static uint32_t operand_sel(uint32_t insn) -+{ -+ return (insn >> 15) & 0x7; -+} -+ -+/* decode operands */ -+static void decode_insn_operands(la_decode *dec) -+{ -+ uint32_t insn = dec->insn; -+ dec->codec = opcode_la[dec->op].codec; -+ switch (dec->codec) { -+ case la_codec_illegal: -+ case la_codec_empty: -+ break; -+ case la_codec_2r: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ break; -+ case la_codec_2r_u5: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ break; -+ case la_codec_2r_u6: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_u6(insn); -+ break; -+ case la_codec_2r_2bw: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_bw1(insn); -+ dec->r4 = operand_bw2(insn); -+ break; -+ case la_codec_2r_2bd: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_bd1(insn); -+ dec->r4 = operand_bd2(insn); -+ break; -+ case la_codec_3r: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ break; -+ case la_codec_3r_rd0: -+ dec->r1 = 0; -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ break; -+ case la_codec_3r_sa2: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_sa2(insn); -+ break; -+ case la_codec_3r_sa3: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_sa3(insn); -+ break; -+ case la_codec_4r: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_r4(insn); -+ break; -+ case la_codec_r_im20: -+ dec->r1 = operand_r1(insn); -+ dec->imm = operand_im20(insn); -+ dec->bit = IM_20; -+ break; -+ case la_codec_2r_im16: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im16(insn); -+ dec->bit = IM_16; -+ break; -+ case la_codec_2r_im14: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im14(insn); -+ dec->bit = IM_14; -+ break; -+ case la_codec_im5_r_im12: -+ dec->imm2 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im12(insn); -+ dec->bit = IM_12; -+ break; -+ case la_codec_2r_im12: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im12(insn); -+ dec->bit = IM_12; -+ break; -+ case la_codec_2r_im8: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->imm = operand_im8(insn); -+ dec->bit = IM_8; -+ break; -+ case la_codec_r_sd: -+ dec->r1 = operand_sd(insn); -+ dec->r2 = operand_r2(insn); -+ break; -+ case la_codec_r_sj: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_sj(insn); -+ break; -+ case la_codec_r_cd: -+ dec->r1 = operand_cd(insn); -+ dec->r2 = operand_r2(insn); -+ break; -+ case la_codec_r_cj: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_cj(insn); -+ break; -+ case la_codec_r_seq: -+ dec->r1 = 0; -+ dec->r2 = operand_r1(insn); -+ dec->imm = operand_im8(insn); -+ dec->bit = IM_8; -+ break; -+ case la_codec_code: -+ dec->code = operand_code(insn); -+ break; -+ case la_codec_whint: -+ dec->imm = operand_whint(insn); -+ dec->bit = IM_15; -+ break; -+ case la_codec_invtlb: -+ dec->imm = operand_invop(insn); -+ dec->bit = IM_5; -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ break; -+ case la_codec_r_ofs21: -+ dec->imm = operand_ofs21(insn); -+ dec->bit = IM_21; -+ dec->r2 = operand_r2(insn); -+ break; -+ case la_codec_cj_ofs21: -+ dec->imm = operand_ofs21(insn); -+ dec->bit = IM_21; -+ dec->r2 = operand_cj(insn); -+ break; -+ case la_codec_ofs26: -+ dec->imm = operand_ofs26(insn); -+ dec->bit = IM_26; -+ break; -+ case la_codec_cond: -+ dec->r1 = operand_cd(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_fcond(insn); -+ break; -+ case la_codec_sel: -+ dec->r1 = operand_r1(insn); -+ dec->r2 = operand_r2(insn); -+ dec->r3 = operand_r3(insn); -+ dec->r4 = operand_sel(insn); -+ break; -+ } -+} -+ -+/* format instruction */ -+ -+static void append(char *s1, const char *s2, size_t n) -+{ -+ size_t l1 = strlen(s1); -+ if (n - l1 - 1 > 0) { -+ strncat(s1, s2, n - l1); -+ } -+} -+ -+static void format_insn(char *buf, size_t buflen, size_t tab, la_decode *dec) -+{ -+ char tmp[16]; -+ const char *fmt; -+ -+ fmt = opcode_la[dec->op].format; -+ while (*fmt) { -+ switch (*fmt) { -+ case 'n': /* name */ -+ append(buf, opcode_la[dec->op].name, buflen); -+ break; -+ case 's': -+ append(buf, "s", buflen); -+ break; -+ case 'd': -+ append(buf, "d", buflen); -+ break; -+ case 'e': /* illegal */ -+ snprintf(tmp, sizeof(tmp), "%x", dec->insn); -+ append(buf, tmp, buflen); -+ break; -+ case 't': -+ while (strlen(buf) < tab) { -+ append(buf, " ", buflen); -+ } -+ break; -+ case '(': -+ append(buf, "(", buflen); -+ break; -+ case ',': -+ append(buf, ",", buflen); -+ break; -+ case '.': -+ append(buf, ".", buflen); -+ break; -+ case ')': -+ append(buf, ")", buflen); -+ break; -+ case '0': /* rd */ -+ append(buf, loongarch_r_normal_name[dec->r1], buflen); -+ break; -+ case '1': /* rj */ -+ append(buf, loongarch_r_normal_name[dec->r2], buflen); -+ break; -+ case '2': /* rk */ -+ append(buf, loongarch_r_normal_name[dec->r3], buflen); -+ break; -+ case '3': /* fd */ -+ append(buf, loongarch_f_normal_name[dec->r1], buflen); -+ break; -+ case '4': /* fj */ -+ append(buf, loongarch_f_normal_name[dec->r2], buflen); -+ break; -+ case '5': /* fk */ -+ append(buf, loongarch_f_normal_name[dec->r3], buflen); -+ break; -+ case '6': /* fa */ -+ append(buf, loongarch_f_normal_name[dec->r4], buflen); -+ break; -+ case 'A': /* sd */ -+ append(buf, loongarch_cr_normal_name[dec->r1], buflen); -+ break; -+ case 'B': /* sj */ -+ append(buf, loongarch_cr_normal_name[dec->r2], buflen); -+ break; -+ case 'C': /* r3 */ -+ snprintf(tmp, sizeof(tmp), "%x", dec->r3); -+ append(buf, tmp, buflen); -+ break; -+ case 'D': /* r4 */ -+ snprintf(tmp, sizeof(tmp), "%x", dec->r4); -+ append(buf, tmp, buflen); -+ break; -+ case 'E': /* r1 */ -+ snprintf(tmp, sizeof(tmp), "%x", dec->r1); -+ append(buf, tmp, buflen); -+ break; -+ case 'F': /* fcsrd */ -+ append(buf, loongarch_r_normal_name[dec->r1], buflen); -+ break; -+ case 'G': /* fcsrs */ -+ append(buf, loongarch_r_normal_name[dec->r2], buflen); -+ break; -+ case 'H': /* cd */ -+ append(buf, loongarch_c_normal_name[dec->r1], buflen); -+ break; -+ case 'I': /* cj */ -+ append(buf, loongarch_c_normal_name[dec->r2], buflen); -+ break; -+ case 'J': /* code */ -+ snprintf(tmp, sizeof(tmp), "0x%x", dec->code); -+ append(buf, tmp, buflen); -+ break; -+ case 'K': /* cond */ -+ switch (dec->r4) { -+ case 0x0: -+ append(buf, "caf", buflen); -+ break; -+ case 0x1: -+ append(buf, "saf", buflen); -+ break; -+ case 0x2: -+ append(buf, "clt", buflen); -+ break; -+ case 0x3: -+ append(buf, "slt", buflen); -+ break; -+ case 0x4: -+ append(buf, "ceq", buflen); -+ break; -+ case 0x5: -+ append(buf, "seq", buflen); -+ break; -+ case 0x6: -+ append(buf, "cle", buflen); -+ break; -+ case 0x7: -+ append(buf, "sle", buflen); -+ break; -+ case 0x8: -+ append(buf, "cun", buflen); -+ break; -+ case 0x9: -+ append(buf, "sun", buflen); -+ break; -+ case 0xA: -+ append(buf, "cult", buflen); -+ break; -+ case 0xB: -+ append(buf, "sult", buflen); -+ break; -+ case 0xC: -+ append(buf, "cueq", buflen); -+ break; -+ case 0xD: -+ append(buf, "sueq", buflen); -+ break; -+ case 0xE: -+ append(buf, "cule", buflen); -+ break; -+ case 0xF: -+ append(buf, "sule", buflen); -+ break; -+ case 0x10: -+ append(buf, "cne", buflen); -+ break; -+ case 0x11: -+ append(buf, "sne", buflen); -+ break; -+ case 0x14: -+ append(buf, "cor", buflen); -+ break; -+ case 0x15: -+ append(buf, "sor", buflen); -+ break; -+ case 0x18: -+ append(buf, "cune", buflen); -+ break; -+ case 0x19: -+ append(buf, "sune", buflen); -+ break; -+ } -+ break; -+ case 'L': /* ca */ -+ append(buf, loongarch_c_normal_name[dec->r4], buflen); -+ break; -+ case 'M': /* cop */ -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm2) & 0x1f); -+ append(buf, tmp, buflen); -+ break; -+ case 'i': /* sixx d */ -+ snprintf(tmp, sizeof(tmp), "%d", dec->imm); -+ append(buf, tmp, buflen); -+ break; -+ case 'o': /* offset */ -+ snprintf(tmp, sizeof(tmp), "%d", (dec->imm) << 2); -+ append(buf, tmp, buflen); -+ break; -+ case 'x': /* sixx x */ -+ switch (dec->bit) { -+ case IM_5: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x1f); -+ append(buf, tmp, buflen); -+ break; -+ case IM_8: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_12: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_14: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x3fff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_15: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x7fff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_16: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xffff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_20: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfffff); -+ append(buf, tmp, buflen); -+ break; -+ default: -+ snprintf(tmp, sizeof(tmp), "0x%x", dec->imm); -+ append(buf, tmp, buflen); -+ break; -+ } -+ break; -+ case 'X': /* offset x*/ -+ switch (dec->bit) { -+ case IM_16: -+ snprintf(tmp, sizeof(tmp), "0x%x", ((dec->imm) << 2) & 0xffff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_21: -+ snprintf(tmp, sizeof(tmp), "0x%x", -+ ((dec->imm) << 2) & 0x1fffff); -+ append(buf, tmp, buflen); -+ break; -+ case IM_26: -+ snprintf(tmp, sizeof(tmp), "0x%x", -+ ((dec->imm) << 2) & 0x3ffffff); -+ append(buf, tmp, buflen); -+ break; -+ default: -+ snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) << 2); -+ append(buf, tmp, buflen); -+ break; -+ } -+ break; -+ case 'p': /* pc */ -+ snprintf(tmp, sizeof(tmp), " # 0x%" PRIx32 "", -+ dec->pc + ((dec->imm) << 2)); -+ append(buf, tmp, buflen); -+ break; -+ default: -+ break; -+ } -+ fmt++; -+ } -+} -+ -+/* disassemble instruction */ -+static void disasm_insn(char *buf, size_t buflen, bfd_vma pc, -+ unsigned long int insn) -+{ -+ la_decode dec = { 0 }; -+ dec.pc = pc; -+ dec.insn = insn; -+ decode_insn_opcode(&dec); -+ decode_insn_operands(&dec); -+ format_insn(buf, buflen, 16, &dec); -+} -+ -+int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info) -+{ -+ char buf[128] = { 0 }; -+ bfd_byte buffer[INSNLEN]; -+ unsigned long insn; -+ int status; -+ -+ status = (*info->read_memory_func)(memaddr, buffer, INSNLEN, info); -+ if (status == 0) { -+ insn = (uint32_t)bfd_getl32(buffer); -+ (*info->fprintf_func)(info->stream, "%08" PRIx64 " ", insn); -+ } else { -+ (*info->memory_error_func)(status, memaddr, info); -+ return -1; -+ } -+ disasm_insn(buf, sizeof(buf), memaddr, insn); -+ (*info->fprintf_func)(info->stream, "\t%s", buf); -+ return INSNLEN; -+} -diff --git a/disas/meson.build b/disas/meson.build -index 5c5daa69a7..c337369cb1 100644 ---- a/disas/meson.build -+++ b/disas/meson.build -@@ -12,6 +12,7 @@ common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.c')) - common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c')) - common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c')) - common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c')) -+common_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: files('loongarch.c')) - common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.cpp')) - common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c')) - common_ss.add(when: 'CONFIG_PPC_DIS', if_true: files('ppc.c')) -diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml -new file mode 100644 -index 0000000000..2e515e0e36 ---- /dev/null -+++ b/gdb-xml/loongarch-base64.xml -@@ -0,0 +1,45 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/gdb-xml/loongarch-fpu.xml b/gdb-xml/loongarch-fpu.xml -new file mode 100644 -index 0000000000..d398fe3650 ---- /dev/null -+++ b/gdb-xml/loongarch-fpu.xml -@@ -0,0 +1,50 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ --- -2.27.0 - diff --git a/Add-dummy-Aspeed-AST2600-Display-Port-MCU-DPMCU.patch b/Add-dummy-Aspeed-AST2600-Display-Port-MCU-DPMCU.patch deleted file mode 100644 index 2887ce74c7a7df78e48c21cae92767e2a70d481f..0000000000000000000000000000000000000000 --- a/Add-dummy-Aspeed-AST2600-Display-Port-MCU-DPMCU.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 48f112e0b8e65fccc3bf66510fafb6e9a8d58e90 Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Mon, 4 Dec 2023 10:50:04 +0800 -Subject: [PATCH] Add dummy Aspeed AST2600 Display Port MCU (DPMCU) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit d9e9cd59df4bc92e4cf7ad1bfa6e2a8429ff31b4 - -AST2600 Display Port MCU introduces 0x18000000~0x1803FFFF as it's memory -and io address. If guest machine try to access DPMCU memory, it will -cause a fatal error. - -Signed-off-by: Troy Lee -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Cédric Le Goater -Message-id: 20211210083034.726610-1-troy_lee@aspeedtech.com -Signed-off-by: Peter Maydell -Signed-off-by: Luo Yifan ---- - hw/arm/aspeed_ast2600.c | 8 ++++++++ - include/hw/arm/aspeed_soc.h | 2 ++ - 2 files changed, 10 insertions(+) - -diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c -index 0384357a95..e33483fb5d 100644 ---- a/hw/arm/aspeed_ast2600.c -+++ b/hw/arm/aspeed_ast2600.c -@@ -19,9 +19,11 @@ - #include "sysemu/sysemu.h" - - #define ASPEED_SOC_IOMEM_SIZE 0x00200000 -+#define ASPEED_SOC_DPMCU_SIZE 0x00040000 - - static const hwaddr aspeed_soc_ast2600_memmap[] = { - [ASPEED_DEV_SRAM] = 0x10000000, -+ [ASPEED_DEV_DPMCU] = 0x18000000, - /* 0x16000000 0x17FFFFFF : AHB BUS do LPC Bus bridge */ - [ASPEED_DEV_IOMEM] = 0x1E600000, - [ASPEED_DEV_PWM] = 0x1E610000, -@@ -44,6 +46,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = { - [ASPEED_DEV_SCU] = 0x1E6E2000, - [ASPEED_DEV_XDMA] = 0x1E6E7000, - [ASPEED_DEV_ADC] = 0x1E6E9000, -+ [ASPEED_DEV_DP] = 0x1E6EB000, - [ASPEED_DEV_VIDEO] = 0x1E700000, - [ASPEED_DEV_SDHCI] = 0x1E740000, - [ASPEED_DEV_EMMC] = 0x1E750000, -@@ -104,6 +107,7 @@ static const int aspeed_soc_ast2600_irqmap[] = { - [ASPEED_DEV_ETH3] = 32, - [ASPEED_DEV_ETH4] = 33, - [ASPEED_DEV_KCS] = 138, /* 138 -> 142 */ -+ [ASPEED_DEV_DP] = 62, - }; - - static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl) -@@ -298,6 +302,10 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) - memory_region_add_subregion(get_system_memory(), - sc->memmap[ASPEED_DEV_SRAM], &s->sram); - -+ /* DPMCU */ -+ create_unimplemented_device("aspeed.dpmcu", sc->memmap[ASPEED_DEV_DPMCU], -+ ASPEED_SOC_DPMCU_SIZE); -+ - /* SCU */ - if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { - return; -diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h -index 8139358549..18fb7eed46 100644 ---- a/include/hw/arm/aspeed_soc.h -+++ b/include/hw/arm/aspeed_soc.h -@@ -139,6 +139,8 @@ enum { - ASPEED_DEV_EMMC, - ASPEED_DEV_KCS, - ASPEED_DEV_HACE, -+ ASPEED_DEV_DPMCU, -+ ASPEED_DEV_DP, - }; - - #endif /* ASPEED_SOC_H */ --- -2.27.0 - diff --git a/Add-flex-bison-to-debian-hexagon-cross.patch b/Add-flex-bison-to-debian-hexagon-cross.patch deleted file mode 100644 index 1307956d7e0875f7889017d4927e67c873273303..0000000000000000000000000000000000000000 --- a/Add-flex-bison-to-debian-hexagon-cross.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 96df1be5fee763f54db9f50466f4ccf433c48ea1 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Wed, 30 Nov 2022 14:33:12 +0800 -Subject: [PATCH 03/17] Add flex/bison to `debian-hexagon-cross` - -debian-hexagon-cross contains two images, one to build the toolchain -used for building the Hexagon tests themselves, and one image to build -QEMU and run the tests. -This commit adds flex/bison to the final image that builds QEMU so that -it can also build idef-parser. -Note: This container is not built by the CI and needs to be rebuilt and -updated manually. - -Signed-off-by: Anton Johansson -Signed-off-by: jianchunfu ---- - tests/docker/dockerfiles/debian-hexagon-cross.docker | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker b/tests/docker/dockerfiles/debian-hexagon-cross.docker -index d5dc299dc1..a64e950f07 100644 ---- a/tests/docker/dockerfiles/debian-hexagon-cross.docker -+++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker -@@ -38,7 +38,7 @@ RUN cat /etc/apt/sources.list | sed "s/^deb\ /deb-src /" >> /etc/apt/sources.lis - # Install QEMU build deps for use in CI - RUN apt update && \ - DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \ -- DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy git ninja-build && \ -+ DEBIAN_FRONTEND=noninteractive eatmydata apt install -yy bison flex git ninja-build && \ - DEBIAN_FRONTEND=noninteractive eatmydata \ - apt build-dep -yy --arch-only qemu - COPY --from=0 /usr/local /usr/local --- -2.27.0 - diff --git a/Add-lbt-support-for-kvm.patch b/Add-lbt-support-for-kvm.patch deleted file mode 100644 index 76cfd18165a25d9d636bc9ffca2de3c5847189f7..0000000000000000000000000000000000000000 --- a/Add-lbt-support-for-kvm.patch +++ /dev/null @@ -1,160 +0,0 @@ -From c174f8c60cd372301200cdecaaae345b079cf589 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Wed, 24 May 2023 23:28:41 -0400 -Subject: [PATCH] Add lbt support for kvm. - -Add lbt registers get and put function. - -Signed-off-by: lixianglai ---- - hw/loongarch/larch_3a.c | 3 ++- - linux-headers/asm-loongarch64/kvm.h | 15 +++++++++++++ - target/loongarch64/cpu.h | 10 +++++++++ - target/loongarch64/kvm.c | 35 +++++++++++++++++++++++++++++ - 4 files changed, 62 insertions(+), 1 deletion(-) - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index cef1a6f3d2..95bb224664 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -356,7 +356,8 @@ struct kvm_cpucfg ls3a5k_cpucfgs = { - .cpucfg[LOONGARCH_CPUCFG2] = - CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | CPUCFG2_FPVERS | - CPUCFG2_LSX | CPUCFG2_LASX | CPUCFG2_COMPLEX | CPUCFG2_CRYPTO | -- CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_LSPW | CPUCFG2_LAM, -+ CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_X86BT | CPUCFG2_ARMBT | -+ CPUCFG2_MIPSBT | CPUCFG2_LSPW | CPUCFG2_LAM, - .cpucfg[LOONGARCH_CPUCFG3] = - CPUCFG3_CCDMA | CPUCFG3_SFB | CPUCFG3_UCACC | CPUCFG3_LLEXC | - CPUCFG3_SCDLY | CPUCFG3_LLDBAR | CPUCFG3_ITLBT | CPUCFG3_ICACHET | -diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h -index a473916d50..a036ea57cd 100644 ---- a/linux-headers/asm-loongarch64/kvm.h -+++ b/linux-headers/asm-loongarch64/kvm.h -@@ -82,6 +82,7 @@ struct kvm_fpu { - * Register set = 2: KVM specific registers (see definitions below). - * - * Register set = 3: FPU / MSA registers (see definitions below). -+ * Register set = 4: LBT registers (see definitions below). - * - * Other sets registers may be added in the future. Each set would - * have its own identifier in bits[31..16]. -@@ -91,6 +92,7 @@ struct kvm_fpu { - #define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x0000000000010000ULL) - #define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x0000000000020000ULL) - #define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x0000000000030000ULL) -+#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x0000000000040000ULL) - - /* - * KVM_REG_LOONGARCH_GP - General purpose registers from kvm_regs. -@@ -174,6 +176,19 @@ struct kvm_fpu { - #define KVM_REG_LOONGARCH_VCPU_RESET \ - (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4) - -+#define KVM_REG_LBT_SCR0 \ -+ (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1) -+#define KVM_REG_LBT_SCR1 \ -+ (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2) -+#define KVM_REG_LBT_SCR2 \ -+ (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3) -+#define KVM_REG_LBT_SCR3 \ -+ (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4) -+#define KVM_REG_LBT_FLAGS \ -+ (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5) -+#define KVM_REG_LBT_FTOP \ -+ (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6) -+ - struct kvm_iocsr_entry { - __u32 addr; - __u32 pad; -diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h -index bf5b36d404..8a29a507b1 100644 ---- a/target/loongarch64/cpu.h -+++ b/target/loongarch64/cpu.h -@@ -75,6 +75,7 @@ typedef struct CPULOONGARCHFPUContext { - uint32_t fcsr0; - uint32_t fcsr0_rw_bitmask; - uint32_t vcsr16; -+ uint64_t ftop; - } CPULOONGARCHFPUContext; - - /* fp control and status register definition */ -@@ -196,6 +197,15 @@ struct CPULOONGARCHState { - struct { - uint64_t guest_addr; - } st; -+ struct { -+ /* scratch registers */ -+ unsigned long scr0; -+ unsigned long scr1; -+ unsigned long scr2; -+ unsigned long scr3; -+ /* loongarch eflag */ -+ unsigned long eflag; -+ } lbt; - }; - - /* -diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c -index 21f6d5695f..0a4dc86421 100644 ---- a/target/loongarch64/kvm.c -+++ b/target/loongarch64/kvm.c -@@ -1277,6 +1277,39 @@ int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu) - return 0; - } - -+ -+static int kvm_loongarch_put_lbt_registers(CPUState *cs) -+{ -+ int ret = 0; -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR0, &env->lbt.scr0); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR1, &env->lbt.scr1); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR2, &env->lbt.scr2); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_SCR3, &env->lbt.scr3); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_FLAGS, &env->lbt.eflag); -+ ret |= kvm_larch_putq(cs, KVM_REG_LBT_FTOP, &env->active_fpu.ftop); -+ -+ return ret; -+} -+ -+static int kvm_loongarch_get_lbt_registers(CPUState *cs) -+{ -+ int ret = 0; -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR0, &env->lbt.scr0); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR1, &env->lbt.scr1); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR2, &env->lbt.scr2); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_SCR3, &env->lbt.scr3); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_FLAGS, &env->lbt.eflag); -+ ret |= kvm_larch_getq(cs, KVM_REG_LBT_FTOP, &env->active_fpu.ftop); -+ -+ return ret; -+} -+ - int kvm_arch_put_registers(CPUState *cs, int level) - { - LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -@@ -1308,6 +1341,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) - return ret; - } - -+ kvm_loongarch_put_lbt_registers(cs); - return ret; - } - -@@ -1334,6 +1368,7 @@ int kvm_arch_get_registers(CPUState *cs) - - kvm_loongarch_get_csr_registers(cs); - kvm_loongarch_get_fpu_registers(cs); -+ kvm_loongarch_get_lbt_registers(cs); - - return ret; - } --- -2.41.0.windows.1 - diff --git a/Add-linux-headers-and-linux-user.patch b/Add-linux-headers-and-linux-user.patch deleted file mode 100644 index 795206c0da934a48c9c98fee361eb69c5039aab2..0000000000000000000000000000000000000000 --- a/Add-linux-headers-and-linux-user.patch +++ /dev/null @@ -1,1999 +0,0 @@ -From 5930ad6d2fa6071dbec9a790724ac2ec364fb28f Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 07:16:26 -0500 -Subject: [PATCH] Add linux-headers and linux-user. - -Add linux-headers and linux-user files. - -Signed-off-by: lixianglai ---- - linux-headers/asm-loongarch64/bitsperlong.h | 25 ++ - linux-headers/asm-loongarch64/kvm.h | 351 ++++++++++++++++++++ - linux-headers/asm-loongarch64/sgidefs.h | 31 ++ - linux-headers/asm-loongarch64/unistd.h | 22 ++ - linux-headers/linux/kvm.h | 25 ++ - linux-user/elfload.c | 64 ++++ - linux-user/loongarch64/cpu_loop.c | 179 ++++++++++ - linux-user/loongarch64/meson.build | 6 + - linux-user/loongarch64/signal.c | 218 ++++++++++++ - linux-user/loongarch64/sockbits.h | 18 + - linux-user/loongarch64/syscall_nr.h | 304 +++++++++++++++++ - linux-user/loongarch64/target_cpu.h | 47 +++ - linux-user/loongarch64/target_elf.h | 24 ++ - linux-user/loongarch64/target_fcntl.h | 23 ++ - linux-user/loongarch64/target_signal.h | 40 +++ - linux-user/loongarch64/target_structs.h | 63 ++++ - linux-user/loongarch64/target_syscall.h | 63 ++++ - linux-user/loongarch64/termbits.h | 241 ++++++++++++++ - linux-user/meson.build | 1 + - linux-user/qemu.h | 2 +- - linux-user/syscall.c | 3 + - linux-user/syscall_defs.h | 10 +- - 22 files changed, 1755 insertions(+), 5 deletions(-) - create mode 100644 linux-headers/asm-loongarch64/bitsperlong.h - create mode 100644 linux-headers/asm-loongarch64/kvm.h - create mode 100644 linux-headers/asm-loongarch64/sgidefs.h - create mode 100644 linux-headers/asm-loongarch64/unistd.h - create mode 100644 linux-user/loongarch64/cpu_loop.c - create mode 100644 linux-user/loongarch64/meson.build - create mode 100644 linux-user/loongarch64/signal.c - create mode 100644 linux-user/loongarch64/sockbits.h - create mode 100644 linux-user/loongarch64/syscall_nr.h - create mode 100644 linux-user/loongarch64/target_cpu.h - create mode 100644 linux-user/loongarch64/target_elf.h - create mode 100644 linux-user/loongarch64/target_fcntl.h - create mode 100644 linux-user/loongarch64/target_signal.h - create mode 100644 linux-user/loongarch64/target_structs.h - create mode 100644 linux-user/loongarch64/target_syscall.h - create mode 100644 linux-user/loongarch64/termbits.h - -diff --git a/linux-headers/asm-loongarch64/bitsperlong.h b/linux-headers/asm-loongarch64/bitsperlong.h -new file mode 100644 -index 0000000000..a7981540d2 ---- /dev/null -+++ b/linux-headers/asm-loongarch64/bitsperlong.h -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef __ASM_LOONGARCH_BITSPERLONG_H -+#define __ASM_LOONGARCH_BITSPERLONG_H -+ -+#define __BITS_PER_LONG _LOONGARCH_SZLONG -+ -+#include -+ -+#endif /* __ASM_LOONGARCH_BITSPERLONG_H */ -diff --git a/linux-headers/asm-loongarch64/kvm.h b/linux-headers/asm-loongarch64/kvm.h -new file mode 100644 -index 0000000000..a473916d50 ---- /dev/null -+++ b/linux-headers/asm-loongarch64/kvm.h -@@ -0,0 +1,351 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef __LINUX_KVM_LOONGARCH_H -+#define __LINUX_KVM_LOONGARCH_H -+ -+#include -+ -+#define __KVM_HAVE_GUEST_DEBUG -+#define KVM_GUESTDBG_USE_SW_BP 0x00010000 -+#define KVM_GUESTDBG_USE_HW_BP 0x00020000 -+#define KVM_DATA_HW_BREAKPOINT_NUM 8 -+#define KVM_INST_HW_BREAKPOINT_NUM 8 -+ -+/* -+ * KVM Loongarch specific structures and definitions. -+ * -+ * Some parts derived from the x86 version of this file. -+ */ -+ -+#define __KVM_HAVE_READONLY_MEM -+ -+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 -+#define KVM_LARCH_VCPU_PVTIME_CTRL 2 -+#define KVM_LARCH_VCPU_PVTIME_IPA 0 -+ -+/* -+ * for KVM_GET_REGS and KVM_SET_REGS -+ */ -+struct kvm_regs { -+ /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ -+ __u64 gpr[32]; -+ __u64 pc; -+}; -+ -+/* -+ * for KVM_GET_CPUCFG -+ */ -+struct kvm_cpucfg { -+ /* out (KVM_GET_CPUCFG) */ -+ __u32 cpucfg[64]; -+}; -+ -+/* -+ * for KVM_GET_FPU and KVM_SET_FPU -+ */ -+struct kvm_fpu { -+ __u32 fcsr; -+ __u32 vcsr; -+ __u64 fcc; /* 8x8 */ -+ struct kvm_fpureg { -+ __u64 val64[4]; // support max 256 bits -+ } fpr[32]; -+}; -+ -+/* -+ * For LOONGARCH, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various -+ * registers. The id field is broken down as follows: -+ * -+ * bits[63..52] - As per linux/kvm.h -+ * bits[51..32] - Must be zero. -+ * bits[31..16] - Register set. -+ * -+ * Register set = 0: GP registers from kvm_regs (see definitions below). -+ * -+ * Register set = 1: CSR registers. -+ * -+ * Register set = 2: KVM specific registers (see definitions below). -+ * -+ * Register set = 3: FPU / MSA registers (see definitions below). -+ * -+ * Other sets registers may be added in the future. Each set would -+ * have its own identifier in bits[31..16]. -+ */ -+ -+#define KVM_REG_LOONGARCH_GP (KVM_REG_LOONGARCH | 0x0000000000000000ULL) -+#define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x0000000000010000ULL) -+#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x0000000000020000ULL) -+#define KVM_REG_LOONGARCH_FPU (KVM_REG_LOONGARCH | 0x0000000000030000ULL) -+ -+/* -+ * KVM_REG_LOONGARCH_GP - General purpose registers from kvm_regs. -+ */ -+ -+#define KVM_REG_LOONGARCH_R0 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 0) -+#define KVM_REG_LOONGARCH_R1 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 1) -+#define KVM_REG_LOONGARCH_R2 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 2) -+#define KVM_REG_LOONGARCH_R3 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 3) -+#define KVM_REG_LOONGARCH_R4 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 4) -+#define KVM_REG_LOONGARCH_R5 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 5) -+#define KVM_REG_LOONGARCH_R6 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 6) -+#define KVM_REG_LOONGARCH_R7 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 7) -+#define KVM_REG_LOONGARCH_R8 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 8) -+#define KVM_REG_LOONGARCH_R9 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 9) -+#define KVM_REG_LOONGARCH_R10 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 10) -+#define KVM_REG_LOONGARCH_R11 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 11) -+#define KVM_REG_LOONGARCH_R12 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 12) -+#define KVM_REG_LOONGARCH_R13 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 13) -+#define KVM_REG_LOONGARCH_R14 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 14) -+#define KVM_REG_LOONGARCH_R15 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 15) -+#define KVM_REG_LOONGARCH_R16 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 16) -+#define KVM_REG_LOONGARCH_R17 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 17) -+#define KVM_REG_LOONGARCH_R18 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 18) -+#define KVM_REG_LOONGARCH_R19 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 19) -+#define KVM_REG_LOONGARCH_R20 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 20) -+#define KVM_REG_LOONGARCH_R21 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 21) -+#define KVM_REG_LOONGARCH_R22 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 22) -+#define KVM_REG_LOONGARCH_R23 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 23) -+#define KVM_REG_LOONGARCH_R24 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 24) -+#define KVM_REG_LOONGARCH_R25 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 25) -+#define KVM_REG_LOONGARCH_R26 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 26) -+#define KVM_REG_LOONGARCH_R27 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 27) -+#define KVM_REG_LOONGARCH_R28 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 28) -+#define KVM_REG_LOONGARCH_R29 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 29) -+#define KVM_REG_LOONGARCH_R30 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 30) -+#define KVM_REG_LOONGARCH_R31 (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 31) -+ -+#define KVM_REG_LOONGARCH_HI (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 32) -+#define KVM_REG_LOONGARCH_LO (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 33) -+#define KVM_REG_LOONGARCH_PC (KVM_REG_LOONGARCH_GP | KVM_REG_SIZE_U64 | 34) -+ -+/* -+ * KVM_REG_LOONGARCH_KVM - KVM specific control registers. -+ */ -+ -+/* -+ * CP0_Count control -+ * DC: Set 0: Master disable CP0_Count and set COUNT_RESUME to now -+ * Set 1: Master re-enable CP0_Count with unchanged bias, handling timer -+ * interrupts since COUNT_RESUME -+ * This can be used to freeze the timer to get a consistent snapshot of -+ * the CP0_Count and timer interrupt pending state, while also resuming -+ * safely without losing time or guest timer interrupts. -+ * Other: Reserved, do not change. -+ */ -+#define KVM_REG_LOONGARCH_COUNT_CTL \ -+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 0) -+#define KVM_REG_LOONGARCH_COUNT_CTL_DC 0x00000001 -+ -+/* -+ * CP0_Count resume monotonic nanoseconds -+ * The monotonic nanosecond time of the last set of COUNT_CTL.DC (master -+ * disable). Any reads and writes of Count related registers while -+ * COUNT_CTL.DC=1 will appear to occur at this time. When COUNT_CTL.DC is -+ * cleared again (master enable) any timer interrupts since this time will be -+ * emulated. -+ * Modifications to times in the future are rejected. -+ */ -+#define KVM_REG_LOONGARCH_COUNT_RESUME \ -+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1) -+/* -+ * CP0_Count rate in Hz -+ * Specifies the rate of the CP0_Count timer in Hz. Modifications occur without -+ * discontinuities in CP0_Count. -+ */ -+#define KVM_REG_LOONGARCH_COUNT_HZ \ -+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2) -+#define KVM_REG_LOONGARCH_COUNTER \ -+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3) -+#define KVM_REG_LOONGARCH_VCPU_RESET \ -+ (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 4) -+ -+struct kvm_iocsr_entry { -+ __u32 addr; -+ __u32 pad; -+ __u64 data; -+}; -+ -+struct kvm_csr_entry { -+ __u32 index; -+ __u32 reserved; -+ __u64 data; -+}; -+ -+/* for KVM_GET_MSRS and KVM_SET_MSRS */ -+struct kvm_msrs { -+ __u32 ncsrs; /* number of msrs in entries */ -+ __u32 pad; -+ struct kvm_csr_entry entries[0]; -+}; -+ -+#define __KVM_HAVE_IRQ_LINE -+ -+struct kvm_debug_exit_arch { -+ __u64 epc; -+ __u32 fwps; -+ __u32 mwps; -+ __u32 exception; -+}; -+ -+/* for KVM_SET_GUEST_DEBUG */ -+struct hw_breakpoint { -+ __u64 addr; -+ __u64 mask; -+ __u32 asid; -+ __u32 ctrl; -+}; -+ -+struct kvm_guest_debug_arch { -+ struct hw_breakpoint data_breakpoint[KVM_DATA_HW_BREAKPOINT_NUM]; -+ struct hw_breakpoint inst_breakpoint[KVM_INST_HW_BREAKPOINT_NUM]; -+ int inst_bp_nums, data_bp_nums; -+}; -+ -+/* definition of registers in kvm_run */ -+struct kvm_sync_regs { -+}; -+ -+/* dummy definition */ -+struct kvm_sregs { -+}; -+ -+struct kvm_loongarch_interrupt { -+ /* in */ -+ __u32 cpu; -+ __u32 irq; -+}; -+ -+#define KVM_IRQCHIP_LS7A_IOAPIC 0x0 -+#define KVM_IRQCHIP_LS3A_GIPI 0x1 -+#define KVM_IRQCHIP_LS3A_HT_IRQ 0x2 -+#define KVM_IRQCHIP_LS3A_ROUTE 0x3 -+#define KVM_IRQCHIP_LS3A_EXTIRQ 0x4 -+#define KVM_IRQCHIP_LS3A_IPMASK 0x5 -+#define KVM_NR_IRQCHIPS 1 -+#define KVM_IRQCHIP_NUM_PINS 64 -+ -+#define KVM_MAX_CORES 256 -+#define KVM_EXTIOI_IRQS (256) -+#define KVM_EXTIOI_IRQS_BITMAP_SIZE (KVM_EXTIOI_IRQS / 8) -+/* map to ipnum per 32 irqs */ -+#define KVM_EXTIOI_IRQS_IPMAP_SIZE (KVM_EXTIOI_IRQS / 32) -+#define KVM_EXTIOI_IRQS_PER_GROUP 32 -+#define KVM_EXTIOI_IRQS_COREMAP_SIZE (KVM_EXTIOI_IRQS) -+#define KVM_EXTIOI_IRQS_NODETYPE_SIZE 16 -+ -+struct ls7a_ioapic_state { -+ __u64 int_id; -+ /* 0x020 interrupt mask register */ -+ __u64 int_mask; -+ /* 0x040 1=msi */ -+ __u64 htmsi_en; -+ /* 0x060 edge=1 level =0 */ -+ __u64 intedge; -+ /* 0x080 for clean edge int,set 1 clean,set 0 is noused */ -+ __u64 intclr; -+ /* 0x0c0 */ -+ __u64 auto_crtl0; -+ /* 0x0e0 */ -+ __u64 auto_crtl1; -+ /* 0x100 - 0x140 */ -+ __u8 route_entry[64]; -+ /* 0x200 - 0x240 */ -+ __u8 htmsi_vector[64]; -+ /* 0x300 */ -+ __u64 intisr_chip0; -+ /* 0x320 */ -+ __u64 intisr_chip1; -+ /* edge detection */ -+ __u64 last_intirr; -+ /* 0x380 interrupt request register */ -+ __u64 intirr; -+ /* 0x3a0 interrupt service register */ -+ __u64 intisr; -+ /* 0x3e0 interrupt level polarity selection register, -+ * 0 for high level tirgger -+ */ -+ __u64 int_polarity; -+}; -+ -+struct loongarch_gipi_single { -+ __u32 status; -+ __u32 en; -+ __u32 set; -+ __u32 clear; -+ __u64 buf[4]; -+}; -+ -+struct loongarch_gipiState { -+ struct loongarch_gipi_single core[KVM_MAX_CORES]; -+}; -+ -+struct kvm_loongarch_ls3a_extirq_state { -+ union ext_en_r -+ { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; -+ } ext_en_r; -+ union bounce_r -+ { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; -+ } bounce_r; -+ union ext_isr_r -+ { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_BITMAP_SIZE]; -+ } ext_isr_r; -+ union ext_core_isr_r -+ { -+ uint64_t reg_u64[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_MAX_CORES][KVM_EXTIOI_IRQS_BITMAP_SIZE]; -+ } ext_core_isr_r; -+ union ip_map_r -+ { -+ uint64_t reg_u64; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_IPMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_IPMAP_SIZE]; -+ } ip_map_r; -+ union core_map_r -+ { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_COREMAP_SIZE / 8]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_COREMAP_SIZE / 4]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_COREMAP_SIZE]; -+ } core_map_r; -+ union node_type_r -+ { -+ uint64_t reg_u64[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 4]; -+ uint32_t reg_u32[KVM_EXTIOI_IRQS_NODETYPE_SIZE / 2]; -+ uint16_t reg_u16[KVM_EXTIOI_IRQS_NODETYPE_SIZE]; -+ uint8_t reg_u8[KVM_EXTIOI_IRQS_NODETYPE_SIZE * 2]; -+ } node_type_r; -+}; -+ -+struct loongarch_kvm_irqchip { -+ __u16 chip_id; -+ __u16 len; -+ __u16 vcpu_id; -+ __u16 reserved; -+ char data[0]; -+}; -+ -+#endif /* __LINUX_KVM_LOONGARCH_H */ -diff --git a/linux-headers/asm-loongarch64/sgidefs.h b/linux-headers/asm-loongarch64/sgidefs.h -new file mode 100644 -index 0000000000..89e8be582e ---- /dev/null -+++ b/linux-headers/asm-loongarch64/sgidefs.h -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef __ASM_SGIDEFS_H -+#define __ASM_SGIDEFS_H -+ -+#define _LOONGARCH_ISA_LOONGARCH32 6 -+#define _LOONGARCH_ISA_LOONGARCH64 7 -+ -+/* -+ * Subprogram calling convention -+ */ -+#define _LOONGARCH_SIM_ABILP32 1 -+#define _LOONGARCH_SIM_ABILPX32 2 -+#define _LOONGARCH_SIM_ABILP64 3 -+ -+#endif /* __ASM_SGIDEFS_H */ -diff --git a/linux-headers/asm-loongarch64/unistd.h b/linux-headers/asm-loongarch64/unistd.h -new file mode 100644 -index 0000000000..ef710673a3 ---- /dev/null -+++ b/linux-headers/asm-loongarch64/unistd.h -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifdef __LP64__ -+#define __ARCH_WANT_NEW_STAT -+#endif /* __LP64__ */ -+ -+#include -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 7870cd0280..c9986c1966 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -2008,6 +2008,31 @@ struct kvm_stats_desc { - char name[]; - }; - -+#ifdef __loongarch__ -+struct kvm_loongarch_vcpu_state { -+ __u8 online_vcpus; -+ __u8 is_migrate; -+ __u32 cpu_freq; -+ __u32 count_ctl; -+ __u64 pending_exceptions; -+ __u64 pending_exceptions_clr; -+ __u64 core_ext_ioisr[4]; -+}; -+ -+#define KVM_CAP_LOONGARCH_FPU 800 -+#define KVM_CAP_LOONGARCH_LSX 801 -+#define KVM_CAP_LOONGARCH_VZ 802 -+#define KVM_REG_LOONGARCH 0x9000000000000000ULL -+#define KVM_LARCH_GET_VCPU_STATE \ -+ _IOR(KVMIO, 0xc0, struct kvm_loongarch_vcpu_state) -+#define KVM_LARCH_SET_VCPU_STATE \ -+ _IOW(KVMIO, 0xc1, struct kvm_loongarch_vcpu_state) -+#define KVM_LARCH_GET_CPUCFG _IOR(KVMIO, 0xc2, struct kvm_cpucfg) -+#define KVM_LOONGARCH_GET_IOCSR _IOR(KVMIO, 0xc3, struct kvm_iocsr_entry) -+#define KVM_LOONGARCH_SET_IOCSR _IOW(KVMIO, 0xc4, struct kvm_iocsr_entry) -+#define KVM_LARCH_SET_CPUCFG _IOR(KVMIO, 0xc5, struct kvm_cpucfg) -+#endif -+ - #define KVM_GET_STATS_FD _IO(KVMIO, 0xce) - - /* Available with KVM_CAP_XSAVE2 */ -diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 767f54c76d..2625af99dd 100644 ---- a/linux-user/elfload.c -+++ b/linux-user/elfload.c -@@ -1041,6 +1041,70 @@ static uint32_t get_elf_hwcap(void) - - #endif /* TARGET_MIPS */ - -+#ifdef TARGET_LOONGARCH64 -+ -+#define ELF_START_MMAP 0x80000000 -+ -+#define ELF_CLASS ELFCLASS64 -+#define ELF_ARCH EM_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/mips/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/uapi/asm/reg.h */ -+enum { -+ TARGET_EF_R0 = 0, -+ TARGET_EF_R26 = TARGET_EF_R0 + 26, -+ TARGET_EF_R27 = TARGET_EF_R0 + 27, -+ TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32, -+ TARGET_EF_CSR_BADV = TARGET_EF_R0 + 33, -+ TARGET_EF_CSR_CRMD = TARGET_EF_R0 + 34, -+ TARGET_EF_CSR_ESTAT = TARGET_EF_R0 + 38 -+}; -+ -+/* See linux kernel: arch/loongarch/kernel/process.c:elf_dump_regs. */ -+static void elf_core_copy_regs(target_elf_gregset_t *regs, -+ const CPULOONGARCHState *env) -+{ -+ int i; -+ -+ (*regs)[TARGET_EF_R0] = 0; -+ -+ for (i = 1; i < ARRAY_SIZE(env->active_tc.gpr); i++) { -+ (*regs)[TARGET_EF_R0 + i] = tswapreg(env->active_tc.gpr[i]); -+ } -+ -+ (*regs)[TARGET_EF_R26] = 0; -+ (*regs)[TARGET_EF_R27] = 0; -+ (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->active_tc.PC); -+ (*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->CSR_BADV); -+ (*regs)[TARGET_EF_CSR_CRMD] = tswapreg(env->CSR_CRMD); -+ (*regs)[TARGET_EF_CSR_ESTAT] = tswapreg(env->CSR_ESTAT); -+} -+ -+#define USE_ELF_CORE_DUMP -+#define ELF_EXEC_PAGESIZE 4096 -+ -+#define ELF_HWCAP get_elf_hwcap() -+ -+static uint32_t get_elf_hwcap(void) -+{ -+ return 0; -+} -+ -+#endif /* TARGET_LOONGARCH64 */ -+ - #ifdef TARGET_MICROBLAZE - - #define ELF_START_MMAP 0x80000000 -diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c -new file mode 100644 -index 0000000000..eb455465ab ---- /dev/null -+++ b/linux-user/loongarch64/cpu_loop.c -@@ -0,0 +1,179 @@ -+/* -+ * qemu user cpu loop -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu.h" -+#include "cpu_loop-common.h" -+#include "elf.h" -+ -+/* Break codes */ -+enum { BRK_OVERFLOW = 6, BRK_DIVZERO = 7 }; -+ -+void force_sig_fault(CPULOONGARCHState *env, target_siginfo_t *info, -+ unsigned int code) -+{ -+ -+ switch (code) { -+ case BRK_OVERFLOW: -+ case BRK_DIVZERO: -+ info->si_signo = TARGET_SIGFPE; -+ info->si_errno = 0; -+ info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV; -+ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info); -+ ret = 0; -+ break; -+ default: -+ info->si_signo = TARGET_SIGTRAP; -+ info->si_errno = 0; -+ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info); -+ ret = 0; -+ break; -+ } -+} -+ -+void cpu_loop(CPULOONGARCHState *env) -+{ -+ CPUState *cs = CPU(loongarch_env_get_cpu(env)); -+ target_siginfo_t info; -+ int trapnr; -+ 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_SYSCALL: -+ env->active_tc.PC += 4; -+ ret = -+ do_syscall(env, env->active_tc.gpr[11], env->active_tc.gpr[4], -+ env->active_tc.gpr[5], env->active_tc.gpr[6], -+ env->active_tc.gpr[7], env->active_tc.gpr[8], -+ env->active_tc.gpr[9], -1, -1); -+ if (ret == -TARGET_ERESTARTSYS) { -+ env->active_tc.PC -= 4; -+ break; -+ } -+ if (ret == -TARGET_QEMU_ESIGRETURN) { -+ /* -+ * Returning from a successful sigreturn syscall. -+ * Avoid clobbering register state. -+ */ -+ break; -+ } -+ env->active_tc.gpr[4] = ret; -+ break; -+ case EXCP_TLBL: -+ case EXCP_TLBS: -+ case EXCP_AdEL: -+ case EXCP_AdES: -+ info.si_signo = TARGET_SIGSEGV; -+ info.si_errno = 0; -+ /* XXX: check env->error_code */ -+ info.si_code = TARGET_SEGV_MAPERR; -+ info._sifields._sigfault._addr = env->CSR_BADV; -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_FPDIS: -+ case EXCP_LSXDIS: -+ case EXCP_LASXDIS: -+ case EXCP_RI: -+ info.si_signo = TARGET_SIGILL; -+ info.si_errno = 0; -+ info.si_code = 0; -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_INTERRUPT: -+ /* just indicate that signals should be handled asap */ -+ break; -+ case EXCP_DEBUG: -+ info.si_signo = TARGET_SIGTRAP; -+ info.si_errno = 0; -+ info.si_code = TARGET_TRAP_BRKPT; -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_FPE: -+ info.si_signo = TARGET_SIGFPE; -+ info.si_errno = 0; -+ info.si_code = TARGET_FPE_FLTUNK; -+ if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INVALID) { -+ info.si_code = TARGET_FPE_FLTINV; -+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_DIV0) { -+ info.si_code = TARGET_FPE_FLTDIV; -+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_OVERFLOW) { -+ info.si_code = TARGET_FPE_FLTOVF; -+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_UNDERFLOW) { -+ info.si_code = TARGET_FPE_FLTUND; -+ } else if (GET_FP_CAUSE(env->active_fpu.fcsr0) & FP_INEXACT) { -+ info.si_code = TARGET_FPE_FLTRES; -+ } -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_BREAK: { -+ abi_ulong trap_instr; -+ unsigned int code; -+ -+ ret = get_user_u32(trap_instr, env->active_tc.PC); -+ if (ret != 0) { -+ goto error; -+ } -+ -+ code = trap_instr & 0x7fff; -+ force_sig_fault(env, &info, code); -+ } break; -+ case EXCP_TRAP: { -+ abi_ulong trap_instr; -+ unsigned int code = 0; -+ -+ ret = get_user_u32(trap_instr, env->active_tc.PC); -+ -+ if (ret != 0) { -+ goto error; -+ } -+ -+ /* The immediate versions don't provide a code. */ -+ if (!(trap_instr & 0xFC000000)) { -+ code = ((trap_instr >> 6) & ((1 << 10) - 1)); -+ } -+ force_sig_fault(env, &info, code); -+ } break; -+ case EXCP_ATOMIC: -+ cpu_exec_step_atomic(cs); -+ break; -+ default: -+ error: -+ EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", -+ trapnr); -+ abort(); -+ } -+ 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->active_tc.gpr[i] = regs->regs[i]; -+ } -+ env->active_tc.PC = regs->csr_era & ~(target_ulong)1; -+} -diff --git a/linux-user/loongarch64/meson.build b/linux-user/loongarch64/meson.build -new file mode 100644 -index 0000000000..c4c0b4d701 ---- /dev/null -+++ b/linux-user/loongarch64/meson.build -@@ -0,0 +1,6 @@ -+syscall_nr_generators += { -+ 'loongarch64': generator(sh, -+ arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@', -+ '', 'TARGET_SYSCALL_OFFSET' ], -+ output: '@BASENAME@_nr.h') -+} -diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c -new file mode 100644 -index 0000000000..2f336035c9 ---- /dev/null -+++ b/linux-user/loongarch64/signal.c -@@ -0,0 +1,218 @@ -+/* -+ * Emulation of Linux signals -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu.h" -+#include "signal-common.h" -+#include "linux-user/trace.h" -+ -+#define FPU_REG_WIDTH 256 -+union fpureg -+{ -+ uint32_t val32[FPU_REG_WIDTH / 32]; -+ uint64_t val64[FPU_REG_WIDTH / 64]; -+}; -+ -+struct target_sigcontext { -+ uint64_t sc_pc; -+ uint64_t sc_regs[32]; -+ uint32_t sc_flags; -+ -+ uint32_t sc_fcsr; -+ uint32_t sc_vcsr; -+ uint64_t sc_fcc; -+ union fpureg sc_fpregs[32] __attribute__((aligned(32))); -+ -+ uint32_t sc_reserved; -+}; -+ -+struct sigframe { -+ uint32_t sf_ass[4]; /* argument save space for o32 */ -+ uint32_t sf_code[2]; /* signal trampoline */ -+ struct target_sigcontext sf_sc; -+ target_sigset_t sf_mask; -+}; -+ -+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 { -+ uint32_t rs_ass[4]; /* argument save space for o32 */ -+ uint32_t rs_code[2]; /* signal trampoline */ -+ struct target_siginfo rs_info; -+ struct target_ucontext rs_uc; -+}; -+ -+static inline void setup_sigcontext(CPULOONGARCHState *regs, -+ struct target_sigcontext *sc) -+{ -+ int i; -+ -+ __put_user(exception_resume_pc(regs), &sc->sc_pc); -+ regs->hflags &= ~LARCH_HFLAG_BMASK; -+ -+ __put_user(0, &sc->sc_regs[0]); -+ for (i = 1; i < 32; ++i) { -+ __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); -+ } -+ -+ for (i = 0; i < 32; ++i) { -+ __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]); -+ } -+} -+ -+static inline void restore_sigcontext(CPULOONGARCHState *regs, -+ struct target_sigcontext *sc) -+{ -+ int i; -+ -+ __get_user(regs->CSR_ERA, &sc->sc_pc); -+ -+ for (i = 1; i < 32; ++i) { -+ __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); -+ } -+ -+ for (i = 0; i < 32; ++i) { -+ __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i].val64[0]); -+ } -+} -+ -+/* -+ * Determine which stack to use.. -+ */ -+static inline abi_ulong get_sigframe(struct target_sigaction *ka, -+ CPULOONGARCHState *regs, -+ size_t frame_size) -+{ -+ unsigned long sp; -+ -+ /* -+ * FPU emulator may have its own trampoline active just -+ * above the user stack, 16-bytes before the next lowest -+ * 16 byte boundary. Try to avoid trashing it. -+ */ -+ sp = target_sigsp(get_sp_from_cpustate(regs) - 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; -+ } -+ -+ /* ori a7, $r0, TARGET_NR_rt_sigreturn */ -+ /* syscall 0 */ -+ __put_user(0x0380000b + (TARGET_NR_rt_sigreturn << 10), -+ &frame->rs_code[0]); -+ __put_user(0x002b0000, &frame->rs_code[1]); -+ -+ tswap_siginfo(&frame->rs_info, info); -+ -+ __put_user(0, &frame->rs_uc.tuc_flags); -+ __put_user(0, &frame->rs_uc.tuc_link); -+ target_save_altstack(&frame->rs_uc.tuc_stack, env); -+ -+ setup_sigcontext(env, &frame->rs_uc.tuc_mcontext); -+ -+ for (i = 0; i < TARGET_NSIG_WORDS; i++) { -+ __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]); -+ } -+ -+ /* -+ * Arguments to signal handler: -+ * -+ * a0 = signal number -+ * a1 = pointer to siginfo_t -+ * a2 = pointer to ucontext_t -+ * -+ * $25 and PC point to the signal handler, $29 points to the -+ * struct sigframe. -+ */ -+ env->active_tc.gpr[4] = sig; -+ env->active_tc.gpr[5] = -+ frame_addr + offsetof(struct target_rt_sigframe, rs_info); -+ env->active_tc.gpr[6] = -+ frame_addr + offsetof(struct target_rt_sigframe, rs_uc); -+ env->active_tc.gpr[3] = frame_addr; -+ env->active_tc.gpr[1] = -+ frame_addr + offsetof(struct target_rt_sigframe, rs_code); -+ /* -+ * The original kernel code sets CP0_ERA to the handler -+ * since it returns to userland using ertn -+ * we cannot do this here, and we must set PC directly -+ */ -+ env->active_tc.PC = env->active_tc.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->active_tc.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(&blocked, &frame->rs_uc.tuc_sigmask); -+ set_sigmask(&blocked); -+ -+ restore_sigcontext(env, &frame->rs_uc.tuc_mcontext); -+ -+ if (do_sigaltstack( -+ frame_addr + offsetof(struct target_rt_sigframe, rs_uc.tuc_stack), -+ 0, get_sp_from_cpustate(env)) == -EFAULT) -+ goto badframe; -+ -+ env->active_tc.PC = env->CSR_ERA; -+ /* -+ * I am not sure this is right, but it seems to work -+ * maybe a problem with nested signals ? -+ */ -+ env->CSR_ERA = 0; -+ return -TARGET_QEMU_ESIGRETURN; -+ -+badframe: -+ force_sig(TARGET_SIGSEGV); -+ return -TARGET_QEMU_ESIGRETURN; -+} -diff --git a/linux-user/loongarch64/sockbits.h b/linux-user/loongarch64/sockbits.h -new file mode 100644 -index 0000000000..8bcbfcb060 ---- /dev/null -+++ b/linux-user/loongarch64/sockbits.h -@@ -0,0 +1,18 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "../generic/sockbits.h" -diff --git a/linux-user/loongarch64/syscall_nr.h b/linux-user/loongarch64/syscall_nr.h -new file mode 100644 -index 0000000000..0217ad77f9 ---- /dev/null -+++ b/linux-user/loongarch64/syscall_nr.h -@@ -0,0 +1,304 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#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_renameat 38 -+#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 TARGET_NR_sched_yield 124 -+#define TARGET_NR_sched_get_priority_max 125 -+#define TARGET_NR_sched_get_priority_min 126 -+#define TARGET_NR_sched_rr_get_interval 127 -+#define TARGET_NR_restart_syscall 128 -+#define TARGET_NR_kill 129 -+#define TARGET_NR_tkill 130 -+#define TARGET_NR_tgkill 131 -+#define TARGET_NR_sigaltstack 132 -+#define TARGET_NR_rt_sigsuspend 133 -+#define TARGET_NR_rt_sigaction 134 -+#define TARGET_NR_rt_sigprocmask 135 -+#define TARGET_NR_rt_sigpending 136 -+#define TARGET_NR_rt_sigtimedwait 137 -+#define TARGET_NR_rt_sigqueueinfo 138 -+#define TARGET_NR_rt_sigreturn 139 -+#define TARGET_NR_setpriority 140 -+#define TARGET_NR_getpriority 141 -+#define TARGET_NR_reboot 142 -+#define TARGET_NR_setregid 143 -+#define TARGET_NR_setgid 144 -+#define TARGET_NR_setreuid 145 -+#define TARGET_NR_setuid 146 -+#define TARGET_NR_setresuid 147 -+#define TARGET_NR_getresuid 148 -+#define TARGET_NR_setresgid 149 -+#define TARGET_NR_getresgid 150 -+#define TARGET_NR_setfsuid 151 -+#define TARGET_NR_setfsgid 152 -+#define TARGET_NR_times 153 -+#define TARGET_NR_setpgid 154 -+#define TARGET_NR_getpgid 155 -+#define TARGET_NR_getsid 156 -+#define TARGET_NR_setsid 157 -+#define TARGET_NR_getgroups 158 -+#define TARGET_NR_setgroups 159 -+#define TARGET_NR_uname 160 -+#define TARGET_NR_sethostname 161 -+#define TARGET_NR_setdomainname 162 -+#define TARGET_NR_getrlimit 163 -+#define TARGET_NR_setrlimit 164 -+#define TARGET_NR_getrusage 165 -+#define TARGET_NR_umask 166 -+#define TARGET_NR_prctl 167 -+#define TARGET_NR_getcpu 168 -+#define TARGET_NR_gettimeofday 169 -+#define TARGET_NR_settimeofday 170 -+#define TARGET_NR_adjtimex 171 -+#define TARGET_NR_getpid 172 -+#define TARGET_NR_getppid 173 -+#define TARGET_NR_getuid 174 -+#define TARGET_NR_geteuid 175 -+#define TARGET_NR_getgid 176 -+#define TARGET_NR_getegid 177 -+#define TARGET_NR_gettid 178 -+#define TARGET_NR_sysinfo 179 -+#define TARGET_NR_mq_open 180 -+#define TARGET_NR_mq_unlink 181 -+#define TARGET_NR_mq_timedsend 182 -+#define TARGET_NR_mq_timedreceive 183 -+#define TARGET_NR_mq_notify 184 -+#define TARGET_NR_mq_getsetattr 185 -+#define TARGET_NR_msgget 186 -+#define TARGET_NR_msgctl 187 -+#define TARGET_NR_msgrcv 188 -+#define TARGET_NR_msgsnd 189 -+#define TARGET_NR_semget 190 -+#define TARGET_NR_semctl 191 -+#define TARGET_NR_semtimedop 192 -+#define TARGET_NR_semop 193 -+#define TARGET_NR_shmget 194 -+#define TARGET_NR_shmctl 195 -+#define TARGET_NR_shmat 196 -+#define TARGET_NR_shmdt 197 -+#define TARGET_NR_socket 198 -+#define TARGET_NR_socketpair 199 -+#define TARGET_NR_bind 200 -+#define TARGET_NR_listen 201 -+#define TARGET_NR_accept 202 -+#define TARGET_NR_connect 203 -+#define TARGET_NR_getsockname 204 -+#define TARGET_NR_getpeername 205 -+#define TARGET_NR_sendto 206 -+#define TARGET_NR_recvfrom 207 -+#define TARGET_NR_setsockopt 208 -+#define TARGET_NR_getsockopt 209 -+#define TARGET_NR_shutdown 210 -+#define TARGET_NR_sendmsg 211 -+#define TARGET_NR_recvmsg 212 -+#define TARGET_NR_readahead 213 -+#define TARGET_NR_brk 214 -+#define TARGET_NR_munmap 215 -+#define TARGET_NR_mremap 216 -+#define TARGET_NR_add_key 217 -+#define TARGET_NR_request_key 218 -+#define TARGET_NR_keyctl 219 -+#define TARGET_NR_clone 220 -+#define TARGET_NR_execve 221 -+#define TARGET_NR_mmap 222 -+#define TARGET_NR_fadvise64 223 -+#define TARGET_NR_swapon 224 -+#define TARGET_NR_swapoff 225 -+#define TARGET_NR_mprotect 226 -+#define TARGET_NR_msync 227 -+#define TARGET_NR_mlock 228 -+#define TARGET_NR_munlock 229 -+#define TARGET_NR_mlockall 230 -+#define TARGET_NR_munlockall 231 -+#define TARGET_NR_mincore 232 -+#define TARGET_NR_madvise 233 -+#define TARGET_NR_remap_file_pages 234 -+#define TARGET_NR_mbind 235 -+#define TARGET_NR_get_mempolicy 236 -+#define TARGET_NR_set_mempolicy 237 -+#define TARGET_NR_migrate_pages 238 -+#define TARGET_NR_move_pages 239 -+#define TARGET_NR_rt_tgsigqueueinfo 240 -+#define TARGET_NR_perf_event_open 241 -+#define TARGET_NR_accept4 242 -+#define TARGET_NR_recvmmsg 243 -+#define TARGET_NR_arch_specific_syscall 244 -+#define TARGET_NR_wait4 260 -+#define TARGET_NR_prlimit64 261 -+#define TARGET_NR_fanotify_init 262 -+#define TARGET_NR_fanotify_mark 263 -+#define TARGET_NR_name_to_handle_at 264 -+#define TARGET_NR_open_by_handle_at 265 -+#define TARGET_NR_clock_adjtime 266 -+#define TARGET_NR_syncfs 267 -+#define TARGET_NR_setns 268 -+#define TARGET_NR_sendmmsg 269 -+#define TARGET_NR_process_vm_readv 270 -+#define TARGET_NR_process_vm_writev 271 -+#define TARGET_NR_kcmp 272 -+#define TARGET_NR_finit_module 273 -+#define TARGET_NR_sched_setattr 274 -+#define TARGET_NR_sched_getattr 275 -+#define TARGET_NR_renameat2 276 -+#define TARGET_NR_seccomp 277 -+#define TARGET_NR_getrandom 278 -+#define TARGET_NR_memfd_create 279 -+#define TARGET_NR_bpf 280 -+#define TARGET_NR_execveat 281 -+#define TARGET_NR_userfaultfd 282 -+#define TARGET_NR_membarrier 283 -+#define TARGET_NR_mlock2 284 -+#define TARGET_NR_copy_file_range 285 -+#define TARGET_NR_preadv2 286 -+#define TARGET_NR_pwritev2 287 -+#define TARGET_NR_pkey_mprotect 288 -+#define TARGET_NR_pkey_alloc 289 -+#define TARGET_NR_pkey_free 290 -+#define TARGET_NR_statx 291 -+#define TARGET_NR_io_pgetevents 292 -+#define TARGET_NR_rseq 293 -+#define TARGET_NR_kexec_file_load 294 -+ -+#define TARGET_NR_syscalls (TARGET_NR_kexec_file_load + 1) -+ -+#endif -diff --git a/linux-user/loongarch64/target_cpu.h b/linux-user/loongarch64/target_cpu.h -new file mode 100644 -index 0000000000..c4bdb4648b ---- /dev/null -+++ b/linux-user/loongarch64/target_cpu.h -@@ -0,0 +1,47 @@ -+/* -+ * loongarch specific CPU ABI and functions for linux-user -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#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->active_tc.gpr[3] = newsp; -+ } -+ env->active_tc.gpr[7] = 0; -+ env->active_tc.gpr[4] = 0; -+} -+ -+static inline void cpu_clone_regs_parent(CPULOONGARCHState *env, -+ unsigned flags) -+{ -+} -+ -+static inline void cpu_set_tls(CPULOONGARCHState *env, target_ulong newtls) -+{ -+ env->active_tc.gpr[2] = newtls; -+} -+ -+static inline abi_ulong get_sp_from_cpustate(CPULOONGARCHState *state) -+{ -+ return state->active_tc.gpr[3]; -+} -+#endif -diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h -new file mode 100644 -index 0000000000..2290a9a6d1 ---- /dev/null -+++ b/linux-user/loongarch64/target_elf.h -@@ -0,0 +1,24 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LOONGARCH_TARGET_ELF_H -+#define LOONGARCH_TARGET_ELF_H -+static inline const char *cpu_get_model(uint32_t eflags) -+{ -+ return "Loongson-3A5000"; -+} -+#endif -diff --git a/linux-user/loongarch64/target_fcntl.h b/linux-user/loongarch64/target_fcntl.h -new file mode 100644 -index 0000000000..9a2bc1cef5 ---- /dev/null -+++ b/linux-user/loongarch64/target_fcntl.h -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LOONGARCH_TARGET_FCNTL_H -+#define LOONGARCH_TARGET_FCNTL_H -+ -+#include "../generic/fcntl.h" -+ -+#endif /* LOONGARCH_TARGET_FCNTL_H */ -diff --git a/linux-user/loongarch64/target_signal.h b/linux-user/loongarch64/target_signal.h -new file mode 100644 -index 0000000000..be98151723 ---- /dev/null -+++ b/linux-user/loongarch64/target_signal.h -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LOONGARCH_TARGET_SIGNAL_H -+#define LOONGARCH_TARGET_SIGNAL_H -+ -+/* this struct defines a stack used during syscall handling */ -+ -+typedef struct target_sigaltstack { -+ abi_long ss_sp; -+ abi_int ss_flags; -+ abi_ulong ss_size; -+} target_stack_t; -+ -+/* -+ * sigaltstack controls -+ */ -+#define TARGET_SS_ONSTACK 1 -+#define TARGET_SS_DISABLE 2 -+ -+#define TARGET_MINSIGSTKSZ 2048 -+#define TARGET_SIGSTKSZ 8192 -+ -+#include "../generic/signal.h" -+ -+#endif /* LOONGARCH_TARGET_SIGNAL_H */ -diff --git a/linux-user/loongarch64/target_structs.h b/linux-user/loongarch64/target_structs.h -new file mode 100644 -index 0000000000..53e7b3e0e2 ---- /dev/null -+++ b/linux-user/loongarch64/target_structs.h -@@ -0,0 +1,63 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#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 -+ -+/* -+ * The semid64_ds structure for the MIPS architecture. -+ * Note extra padding because this structure is passed back and forth -+ * between kernel and user space. -+ */ -+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 -diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h -new file mode 100644 -index 0000000000..6acc015b85 ---- /dev/null -+++ b/linux-user/loongarch64/target_syscall.h -@@ -0,0 +1,63 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LOONGARCH_TARGET_SYSCALL_H -+#define LOONGARCH_TARGET_SYSCALL_H -+ -+/* -+ * this struct defines the way the registers are stored on the -+ * stack during a system call. -+ */ -+ -+struct target_pt_regs { -+ /* Saved main processor registers. */ -+ target_ulong regs[32]; -+ -+ /* Saved special registers. */ -+ /* Saved special registers. */ -+ target_ulong csr_crmd; -+ target_ulong csr_prmd; -+ target_ulong csr_euen; -+ target_ulong csr_ecfg; -+ target_ulong csr_estat; -+ target_ulong csr_era; -+ target_ulong csr_badvaddr; -+ target_ulong orig_a0; -+ target_ulong __last[0]; -+}; -+ -+#define UNAME_MACHINE "loongarch" -+#define UNAME_MINIMUM_RELEASE "2.6.32" -+ -+#define TARGET_CLONE_BACKWARDS -+#define TARGET_MINSIGSTKSZ 2048 -+#define TARGET_MLOCKALL_MCL_CURRENT 1 -+#define TARGET_MLOCKALL_MCL_FUTURE 2 -+ -+#define TARGET_FORCE_SHMLBA -+ -+static inline abi_ulong target_shmlba(CPULOONGARCHState *env) -+{ -+ return 0x40000; -+} -+ -+#define TARGET_PR_SET_FP_MODE 45 -+#define TARGET_PR_GET_FP_MODE 46 -+#define TARGET_PR_FP_MODE_FR (1 << 0) -+#define TARGET_PR_FP_MODE_FRE (1 << 1) -+ -+#endif /* LOONGARCH_TARGET_SYSCALL_H */ -diff --git a/linux-user/loongarch64/termbits.h b/linux-user/loongarch64/termbits.h -new file mode 100644 -index 0000000000..dd251e14b3 ---- /dev/null -+++ b/linux-user/loongarch64/termbits.h -@@ -0,0 +1,241 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LINUX_USER_LOONGARCH_TERMBITS_H -+#define LINUX_USER_LOONGARCH_TERMBITS_H -+ -+#define TARGET_NCCS 19 -+ -+struct target_termios { -+ unsigned int c_iflag; /* input mode flags */ -+ unsigned int c_oflag; /* output mode flags */ -+ unsigned int c_cflag; /* control mode flags */ -+ unsigned int c_lflag; /* local mode flags */ -+ unsigned char c_line; /* line discipline */ -+ unsigned char c_cc[TARGET_NCCS]; /* control characters */ -+}; -+ -+/* c_iflag bits */ -+#define TARGET_IGNBRK 0000001 -+#define TARGET_BRKINT 0000002 -+#define TARGET_IGNPAR 0000004 -+#define TARGET_PARMRK 0000010 -+#define TARGET_INPCK 0000020 -+#define TARGET_ISTRIP 0000040 -+#define TARGET_INLCR 0000100 -+#define TARGET_IGNCR 0000200 -+#define TARGET_ICRNL 0000400 -+#define TARGET_IUCLC 0001000 -+#define TARGET_IXON 0002000 -+#define TARGET_IXANY 0004000 -+#define TARGET_IXOFF 0010000 -+#define TARGET_IMAXBEL 0020000 -+#define TARGET_IUTF8 0040000 -+ -+/* c_oflag bits */ -+#define TARGET_OPOST 0000001 -+#define TARGET_OLCUC 0000002 -+#define TARGET_ONLCR 0000004 -+#define TARGET_OCRNL 0000010 -+#define TARGET_ONOCR 0000020 -+#define TARGET_ONLRET 0000040 -+#define TARGET_OFILL 0000100 -+#define TARGET_OFDEL 0000200 -+#define TARGET_NLDLY 0000400 -+#define TARGET_NL0 0000000 -+#define TARGET_NL1 0000400 -+#define TARGET_CRDLY 0003000 -+#define TARGET_CR0 0000000 -+#define TARGET_CR1 0001000 -+#define TARGET_CR2 0002000 -+#define TARGET_CR3 0003000 -+#define TARGET_TABDLY 0014000 -+#define TARGET_TAB0 0000000 -+#define TARGET_TAB1 0004000 -+#define TARGET_TAB2 0010000 -+#define TARGET_TAB3 0014000 -+#define TARGET_XTABS 0014000 -+#define TARGET_BSDLY 0020000 -+#define TARGET_BS0 0000000 -+#define TARGET_BS1 0020000 -+#define TARGET_VTDLY 0040000 -+#define TARGET_VT0 0000000 -+#define TARGET_VT1 0040000 -+#define TARGET_FFDLY 0100000 -+#define TARGET_FF0 0000000 -+#define TARGET_FF1 0100000 -+ -+/* c_cflag bit meaning */ -+#define TARGET_CBAUD 0010017 -+#define TARGET_B0 0000000 /* hang up */ -+#define TARGET_B50 0000001 -+#define TARGET_B75 0000002 -+#define TARGET_B110 0000003 -+#define TARGET_B134 0000004 -+#define TARGET_B150 0000005 -+#define TARGET_B200 0000006 -+#define TARGET_B300 0000007 -+#define TARGET_B600 0000010 -+#define TARGET_B1200 0000011 -+#define TARGET_B1800 0000012 -+#define TARGET_B2400 0000013 -+#define TARGET_B4800 0000014 -+#define TARGET_B9600 0000015 -+#define TARGET_B19200 0000016 -+#define TARGET_B38400 0000017 -+#define TARGET_EXTA B19200 -+#define TARGET_EXTB B38400 -+#define TARGET_CSIZE 0000060 -+#define TARGET_CS5 0000000 -+#define TARGET_CS6 0000020 -+#define TARGET_CS7 0000040 -+#define TARGET_CS8 0000060 -+#define TARGET_CSTOPB 0000100 -+#define TARGET_CREAD 0000200 -+#define TARGET_PARENB 0000400 -+#define TARGET_PARODD 0001000 -+#define TARGET_HUPCL 0002000 -+#define TARGET_CLOCAL 0004000 -+#define TARGET_CBAUDEX 0010000 -+#define TARGET_B57600 0010001 -+#define TARGET_B115200 0010002 -+#define TARGET_B230400 0010003 -+#define TARGET_B460800 0010004 -+#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ -+#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ -+#define TARGET_CRTSCTS 020000000000 /* flow control */ -+ -+/* c_lflag bits */ -+#define TARGET_ISIG 0000001 -+#define TARGET_ICANON 0000002 -+#define TARGET_XCASE 0000004 -+#define TARGET_ECHO 0000010 -+#define TARGET_ECHOE 0000020 -+#define TARGET_ECHOK 0000040 -+#define TARGET_ECHONL 0000100 -+#define TARGET_NOFLSH 0000200 -+#define TARGET_TOSTOP 0000400 -+#define TARGET_ECHOCTL 0001000 -+#define TARGET_ECHOPRT 0002000 -+#define TARGET_ECHOKE 0004000 -+#define TARGET_FLUSHO 0010000 -+#define TARGET_PENDIN 0040000 -+#define TARGET_IEXTEN 0100000 -+ -+/* c_cc character offsets */ -+#define TARGET_VINTR 0 -+#define TARGET_VQUIT 1 -+#define TARGET_VERASE 2 -+#define TARGET_VKILL 3 -+#define TARGET_VEOF 4 -+#define TARGET_VTIME 5 -+#define TARGET_VMIN 6 -+#define TARGET_VSWTC 7 -+#define TARGET_VSTART 8 -+#define TARGET_VSTOP 9 -+#define TARGET_VSUSP 10 -+#define TARGET_VEOL 11 -+#define TARGET_VREPRINT 12 -+#define TARGET_VDISCARD 13 -+#define TARGET_VWERASE 14 -+#define TARGET_VLNEXT 15 -+#define TARGET_VEOL2 16 -+ -+/* ioctls */ -+ -+#define TARGET_TCGETS 0x5401 -+#define TARGET_TCSETS 0x5402 -+#define TARGET_TCSETSW 0x5403 -+#define TARGET_TCSETSF 0x5404 -+#define TARGET_TCGETA 0x5405 -+#define TARGET_TCSETA 0x5406 -+#define TARGET_TCSETAW 0x5407 -+#define TARGET_TCSETAF 0x5408 -+#define TARGET_TCSBRK 0x5409 -+#define TARGET_TCXONC 0x540A -+#define TARGET_TCFLSH 0x540B -+ -+#define TARGET_TIOCEXCL 0x540C -+#define TARGET_TIOCNXCL 0x540D -+#define TARGET_TIOCSCTTY 0x540E -+#define TARGET_TIOCGPGRP 0x540F -+#define TARGET_TIOCSPGRP 0x5410 -+#define TARGET_TIOCOUTQ 0x5411 -+#define TARGET_TIOCSTI 0x5412 -+#define TARGET_TIOCGWINSZ 0x5413 -+#define TARGET_TIOCSWINSZ 0x5414 -+#define TARGET_TIOCMGET 0x5415 -+#define TARGET_TIOCMBIS 0x5416 -+#define TARGET_TIOCMBIC 0x5417 -+#define TARGET_TIOCMSET 0x5418 -+#define TARGET_TIOCGSOFTCAR 0x5419 -+#define TARGET_TIOCSSOFTCAR 0x541A -+#define TARGET_FIONREAD 0x541B -+#define TARGET_TIOCINQ TARGET_FIONREAD -+#define TARGET_TIOCLINUX 0x541C -+#define TARGET_TIOCCONS 0x541D -+#define TARGET_TIOCGSERIAL 0x541E -+#define TARGET_TIOCSSERIAL 0x541F -+#define TARGET_TIOCPKT 0x5420 -+#define TARGET_FIONBIO 0x5421 -+#define TARGET_TIOCNOTTY 0x5422 -+#define TARGET_TIOCSETD 0x5423 -+#define TARGET_TIOCGETD 0x5424 -+#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -+#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */ -+#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ -+#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ -+#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ -+/* Get Pty Number (of pty-mux device) */ -+#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int) -+/* Lock/unlock Pty */ -+#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int) -+/* Safely open the slave */ -+#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) -+ -+#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ -+#define TARGET_FIOCLEX 0x5451 -+#define TARGET_FIOASYNC 0x5452 -+#define TARGET_TIOCSERCONFIG 0x5453 -+#define TARGET_TIOCSERGWILD 0x5454 -+#define TARGET_TIOCSERSWILD 0x5455 -+#define TARGET_TIOCGLCKTRMIOS 0x5456 -+#define TARGET_TIOCSLCKTRMIOS 0x5457 -+#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ -+#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ -+#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ -+#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ -+ -+/* wait for a change on serial input line(s) */ -+#define TARGET_TIOCMIWAIT 0x545C -+/* read serial port inline interrupt counts */ -+#define TARGET_TIOCGICOUNT 0x545D -+#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ -+#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ -+ -+/* Used for packet mode */ -+#define TARGET_TIOCPKT_DATA 0 -+#define TARGET_TIOCPKT_FLUSHREAD 1 -+#define TARGET_TIOCPKT_FLUSHWRITE 2 -+#define TARGET_TIOCPKT_STOP 4 -+#define TARGET_TIOCPKT_START 8 -+#define TARGET_TIOCPKT_NOSTOP 16 -+#define TARGET_TIOCPKT_DOSTOP 32 -+ -+#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -+ -+#endif -diff --git a/linux-user/meson.build b/linux-user/meson.build -index 4f4196ed13..8b8edefa6e 100644 ---- a/linux-user/meson.build -+++ b/linux-user/meson.build -@@ -40,3 +40,4 @@ subdir('sparc') - subdir('sw64') - subdir('x86_64') - subdir('xtensa') -+subdir('loongarch64') -diff --git a/linux-user/qemu.h b/linux-user/qemu.h -index 5c713fa8ab..66ddb25d1c 100644 ---- a/linux-user/qemu.h -+++ b/linux-user/qemu.h -@@ -61,7 +61,7 @@ struct image_info { - /* For target-specific processing of NT_GNU_PROPERTY_TYPE_0. */ - uint32_t note_flags; - --#ifdef TARGET_MIPS -+#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64) - int fp_abi; - int interp_fp_abi; - #endif -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index fce2c03259..a544d04524 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -1614,6 +1614,9 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes, - #elif defined(TARGET_MIPS) - ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1]; - return host_pipe[0]; -+#elif defined(TARGET_LOONGARCH64) -+ ((CPULOONGARCHState *)cpu_env)->active_tc.gpr[5] = host_pipe[1]; -+ return host_pipe[0]; - #elif defined(TARGET_SH4) - ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; - return host_pipe[0]; -diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h -index 0b13975937..04ca5fe7a0 100644 ---- a/linux-user/syscall_defs.h -+++ b/linux-user/syscall_defs.h -@@ -74,7 +74,7 @@ - || defined(TARGET_M68K) || defined(TARGET_CRIS) \ - || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \ - || defined(TARGET_NIOS2) || defined(TARGET_RISCV) \ -- || defined(TARGET_XTENSA) -+ || defined(TARGET_XTENSA) || defined(TARGET_LOONGARCH64) - - #define TARGET_IOC_SIZEBITS 14 - #define TARGET_IOC_DIRBITS 2 -@@ -450,7 +450,7 @@ struct target_dirent64 { - #define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */ - #define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */ - --#ifdef TARGET_MIPS -+#if defined(TARGET_MIPS) || defined(TARGET_LOONGARCH64) - #define TARGET_NSIG 128 - #else - #define TARGET_NSIG 64 -@@ -2133,7 +2133,8 @@ struct target_stat64 { - abi_ulong __unused5; - }; - --#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV) -+#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || \ -+ defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64) - - /* These are the asm-generic versions of the stat and stat64 structures */ - -@@ -2161,7 +2162,7 @@ struct target_stat { - unsigned int __unused5; - }; - --#if !defined(TARGET_RISCV64) -+#if !(defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)) - #define TARGET_HAS_STRUCT_STAT64 - struct target_stat64 { - uint64_t st_dev; -@@ -2331,6 +2332,7 @@ struct target_statfs64 { - }; - #elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \ - defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \ -+ defined(TARGET_LOONGARCH64) || \ - defined(TARGET_RISCV)) && !defined(TARGET_ABI32) - struct target_statfs { - abi_long f_type; --- -2.27.0 - diff --git a/Add-loongarch-machine.patch b/Add-loongarch-machine.patch deleted file mode 100644 index 10380b7c8e52482d8f17d7bcffb6a59adbeda492..0000000000000000000000000000000000000000 --- a/Add-loongarch-machine.patch +++ /dev/null @@ -1,6181 +0,0 @@ -From 810369434538d64a4118c3ec70d4c3daf479bd52 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 07:14:21 -0500 -Subject: [PATCH] Add loongarch machine. - -1.Add loongarch ACPI table support. -2.Add loongarch apic support. -3.Add loongarch ipi support. -4.Add loongarch hotplug support. -5.Add loongarch board simulation. -6.Add loongarch interrupt support. -7.Add loongarch north bridge simulation. -8.Add loongarch iocsr device simulation. -9.Add loongarch system bus support. - -Signed-off-by: lixianglai ---- - hw/loongarch/Kconfig | 17 + - hw/loongarch/acpi-build.c | 827 ++++++++++++ - hw/loongarch/acpi-build.h | 32 + - hw/loongarch/apic.c | 689 ++++++++++ - hw/loongarch/ioapic.c | 419 ++++++ - hw/loongarch/iocsr.c | 227 ++++ - hw/loongarch/ipi.c | 284 ++++ - hw/loongarch/larch_3a.c | 2063 +++++++++++++++++++++++++++++ - hw/loongarch/larch_hotplug.c | 377 ++++++ - hw/loongarch/larch_int.c | 87 ++ - hw/loongarch/ls7a_nb.c | 289 ++++ - hw/loongarch/meson.build | 15 + - hw/loongarch/sysbus-fdt.c | 178 +++ - include/disas/dis-asm.h | 3 +- - include/elf.h | 2 + - include/hw/loongarch/bios.h | 24 + - include/hw/loongarch/cpudevs.h | 71 + - include/hw/loongarch/larch.h | 164 +++ - include/hw/loongarch/ls7a.h | 167 +++ - include/hw/loongarch/sysbus-fdt.h | 33 + - include/qemu/osdep.h | 4 + - 21 files changed, 5971 insertions(+), 1 deletion(-) - create mode 100644 hw/loongarch/Kconfig - create mode 100644 hw/loongarch/acpi-build.c - create mode 100644 hw/loongarch/acpi-build.h - create mode 100644 hw/loongarch/apic.c - create mode 100644 hw/loongarch/ioapic.c - create mode 100644 hw/loongarch/iocsr.c - create mode 100644 hw/loongarch/ipi.c - create mode 100644 hw/loongarch/larch_3a.c - create mode 100644 hw/loongarch/larch_hotplug.c - create mode 100644 hw/loongarch/larch_int.c - create mode 100644 hw/loongarch/ls7a_nb.c - create mode 100644 hw/loongarch/meson.build - create mode 100644 hw/loongarch/sysbus-fdt.c - create mode 100644 include/hw/loongarch/bios.h - create mode 100644 include/hw/loongarch/cpudevs.h - create mode 100644 include/hw/loongarch/larch.h - create mode 100644 include/hw/loongarch/ls7a.h - create mode 100644 include/hw/loongarch/sysbus-fdt.h - -diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig -new file mode 100644 -index 0000000000..3fe2677fda ---- /dev/null -+++ b/hw/loongarch/Kconfig -@@ -0,0 +1,17 @@ -+config LS7A_APIC -+ bool -+ -+config LS7A_RTC -+ bool -+ -+config LOONGSON3A -+ bool -+ -+config MEM_HOTPLUG -+ bool -+ -+config ACPI_LOONGARCH -+ bool -+ -+config E1000E_PCI -+ bool -diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c -new file mode 100644 -index 0000000000..4dd128a05e ---- /dev/null -+++ b/hw/loongarch/acpi-build.c -@@ -0,0 +1,827 @@ -+/* -+ * Support for generating ACPI tables and passing them to Guests -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qapi/qmp/qnum.h" -+#include "acpi-build.h" -+#include "qemu-common.h" -+#include "qemu/bitmap.h" -+#include "qemu/error-report.h" -+#include "hw/pci/pci.h" -+#include "hw/boards.h" -+#include "hw/core/cpu.h" -+#include "target/loongarch64/cpu.h" -+#include "hw/misc/pvpanic.h" -+#include "hw/timer/hpet.h" -+#include "hw/acpi/acpi-defs.h" -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/cpu.h" -+#include "hw/nvram/fw_cfg.h" -+#include "hw/acpi/bios-linker-loader.h" -+#include "hw/loader.h" -+#include "hw/isa/isa.h" -+#include "hw/block/fdc.h" -+#include "hw/acpi/memory_hotplug.h" -+#include "sysemu/tpm.h" -+#include "hw/acpi/tpm.h" -+#include "hw/acpi/vmgenid.h" -+#include "sysemu/tpm_backend.h" -+#include "hw/rtc/mc146818rtc_regs.h" -+#include "sysemu/numa.h" -+#include "sysemu/runstate.h" -+#include "sysemu/reset.h" -+#include "migration/vmstate.h" -+#include "hw/mem/memory-device.h" -+#include "hw/acpi/utils.h" -+#include "hw/acpi/pci.h" -+/* Supported chipsets: */ -+#include "hw/acpi/aml-build.h" -+#include "hw/loongarch/larch.h" -+#include "hw/loongarch/ls7a.h" -+#include "hw/platform-bus.h" -+ -+#include "hw/acpi/ipmi.h" -+#include "hw/acpi/ls7a.h" -+ -+/* -+ * These are used to size the ACPI tables for -M pc-i440fx-1.7 and -+ * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows -+ * a little bit, there should be plenty of free space since the DSDT -+ * shrunk by ~1.5k between QEMU 2.0 and QEMU 2.1. -+ */ -+#define ACPI_BUILD_ALIGN_SIZE 0x1000 -+#define ACPI_BUILD_TABLE_SIZE 0x20000 -+ -+/* #define DEBUG_ACPI_BUILD */ -+#ifdef DEBUG_ACPI_BUILD -+#define ACPI_BUILD_DPRINTF(fmt, ...) \ -+ do { \ -+ printf("ACPI_BUILD: " fmt, ##__VA_ARGS__); \ -+ } while (0) -+#else -+#define ACPI_BUILD_DPRINTF(fmt, ...) -+#endif -+ -+/* Default IOAPIC ID */ -+#define ACPI_BUILD_IOAPIC_ID 0x0 -+ -+/* PCI fw r3.0 MCFG table. */ -+/* Subtable */ -+ -+typedef struct AcpiMiscInfo { -+ bool is_piix4; -+ bool has_hpet; -+ TPMVersion tpm_version; -+ const unsigned char *dsdt_code; -+ unsigned dsdt_size; -+ uint16_t pvpanic_port; -+ uint16_t applesmc_io_base; -+} AcpiMiscInfo; -+ -+typedef struct AcpiBuildPciBusHotplugState { -+ GArray *device_table; -+ GArray *notify_table; -+ struct AcpiBuildPciBusHotplugState *parent; -+ bool pcihp_bridge_en; -+} AcpiBuildPciBusHotplugState; -+ -+static void init_common_fadt_data(AcpiFadtData *data) -+{ -+ AmlAddressSpace as = AML_AS_SYSTEM_MEMORY; -+ uint64_t base = LS7A_ACPI_REG_BASE; -+ AcpiFadtData fadt = { -+ .rev = 3, -+ .flags = (1 << ACPI_FADT_F_WBINVD) | (1 << ACPI_FADT_F_PROC_C1) | -+ (1 << ACPI_FADT_F_SLP_BUTTON) | -+ (1 << ACPI_FADT_F_TMR_VAL_EXT) | -+ (1 << ACPI_FADT_F_RESET_REG_SUP), -+ /* C2 state not supported */ -+ .plvl2_lat = 0xfff, -+ /* C3 state not supported */ -+ .plvl3_lat = 0xfff, -+ .smi_cmd = 0x00, -+ .sci_int = ACPI_SCI_IRQ, -+ .acpi_enable_cmd = 0x00, -+ .acpi_disable_cmd = 0x00, -+ .pm1a_evt = { .space_id = as, -+ .bit_width = 8 * 8, -+ .address = base + LS7A_PM_EVT_BLK }, -+ .pm1a_cnt = { .space_id = as, -+ .bit_width = 4 * 8, -+ .address = base + LS7A_PM_CNT_BLK }, -+ .pm_tmr = { .space_id = as, -+ .bit_width = 4 * 8, -+ .address = base + LS7A_PM_TMR_BLK }, -+ .gpe0_blk = { .space_id = as, -+ .bit_width = 8 * 8, -+ .address = base + LS7A_GPE0_STS_REG }, -+ .reset_reg = { .space_id = as, -+ .bit_width = 4 * 8, -+ .address = base + LS7A_GPE0_RESET_REG }, -+ .reset_val = 0x1, -+ }; -+ *data = fadt; -+} -+ -+static void acpi_align_size(GArray *blob, unsigned align) -+{ -+ /* -+ * Align size to multiple of given size. This reduces the chance -+ * we need to change size in the future (breaking cross version migration). -+ */ -+ g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align)); -+} -+ -+/* FACS */ -+static void build_facs(GArray *table_data) -+{ -+ const char *sig = "FACS"; -+ const uint8_t reserved[40] = {}; -+ -+ g_array_append_vals(table_data, sig, 4); /* Signature */ -+ build_append_int_noprefix(table_data, 64, 4); /* Length */ -+ build_append_int_noprefix(table_data, 0, 4); /* Hardware Signature */ -+ build_append_int_noprefix(table_data, 0, 4); /* Firmware Waking Vector */ -+ build_append_int_noprefix(table_data, 0, 4); /* Global Lock */ -+ build_append_int_noprefix(table_data, 0, 4); /* Flags */ -+ g_array_append_vals(table_data, reserved, 40); /* Reserved */ -+} -+ -+void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, -+ const CPUArchIdList *apic_ids, GArray *entry, -+ bool force_enabled) -+{ -+ uint32_t apic_id = apic_ids->cpus[uid].arch_id; -+ /* Flags – Local APIC Flags */ -+ uint32_t flags = apic_ids->cpus[uid].cpu != NULL || force_enabled ? 1 : 0; -+ -+ /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */ -+ build_append_int_noprefix(entry, 0, 1); /* Type */ -+ build_append_int_noprefix(entry, 8, 1); /* Length */ -+ build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */ -+ build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */ -+ build_append_int_noprefix(entry, flags, 4); /* Flags */ -+} -+ -+static void build_ioapic(GArray *entry, uint8_t id, uint32_t addr, -+ uint32_t irq) -+{ -+ /* Rev 1.0b, 5.2.8.2 IO APIC */ -+ build_append_int_noprefix(entry, 1, 1); /* Type */ -+ build_append_int_noprefix(entry, 12, 1); /* Length */ -+ build_append_int_noprefix(entry, id, 1); /* IO APIC ID */ -+ build_append_int_noprefix(entry, 0, 1); /* Reserved */ -+ build_append_int_noprefix(entry, addr, 4); /* IO APIC Address */ -+ build_append_int_noprefix(entry, irq, 4); /* System Vector Base */ -+} -+ -+static void build_madt(GArray *table_data, BIOSLinker *linker, -+ LoongarchMachineState *lsms) -+{ -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ MachineClass *mc = MACHINE_GET_CLASS(lsms); -+ const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(lsms)); -+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(lsms->acpi_dev); -+ AcpiDeviceIf *adev = ACPI_DEVICE_IF(lsms->acpi_dev); -+ int i; -+ AcpiTable table = { .sig = "APIC", -+ .rev = 1, -+ .oem_id = lsms->oem_id, -+ .oem_table_id = lsms->oem_table_id }; -+ -+ acpi_table_begin(&table, table_data); -+ -+ /* Local APIC Address */ -+ build_append_int_noprefix(table_data, 0, 4); -+ build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */ -+ -+ for (i = 0; i < apic_ids->len; i++) { -+ adevc->madt_cpu(adev, i, apic_ids, table_data, false); -+ } -+ -+ build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID, lsmc->ls7a_ioapic_reg_base, -+ LOONGARCH_PCH_IRQ_BASE); -+ -+ /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */ -+ build_append_int_noprefix(table_data, 3, 1); /* Type */ -+ build_append_int_noprefix(table_data, 6, 1); /* Length */ -+ /* ACPI Processor ID */ -+ build_append_int_noprefix(table_data, 0xFF, 1); /* all processors */ -+ build_append_int_noprefix(table_data, 0, 2); /* Flags */ -+ /* Local APIC INTI# */ -+ build_append_int_noprefix(table_data, 1, 1); /* ACPI_LINT1 */ -+ -+ /* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */ -+ build_append_int_noprefix(table_data, 4, 1); /* Type */ -+ build_append_int_noprefix(table_data, 6, 1); /* Length */ -+ /* ACPI Processor ID */ -+ build_append_int_noprefix(table_data, 0xFF, 1); /* all processors */ -+ build_append_int_noprefix(table_data, 0, 2); /* Flags */ -+ /* Local APIC INTI# */ -+ build_append_int_noprefix(table_data, 1, 1); /* ACPI_LINT1 */ -+ -+ acpi_table_end(linker, &table); -+} -+ -+static void build_srat(GArray *table_data, BIOSLinker *linker, -+ MachineState *machine) -+{ -+ uint64_t i, mem_len, mem_base; -+ MachineClass *mc = MACHINE_GET_CLASS(machine); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); -+ int nb_numa_nodes = machine->numa_state->num_nodes; -+ NodeInfo *numa_info = machine->numa_state->nodes; -+ AcpiTable table = { .sig = "SRAT", -+ .rev = 1, -+ .oem_id = lsms->oem_id, -+ .oem_table_id = lsms->oem_table_id }; -+ -+ acpi_table_begin(&table, table_data); -+ build_append_int_noprefix(table_data, 1, 4); /* Reserved */ -+ build_append_int_noprefix(table_data, 0, 8); /* Reserved */ -+ -+ for (i = 0; i < apic_ids->len; ++i) { -+ /* 5.2.15.1 Processor Local APIC/SAPIC Affinity Structure */ -+ build_append_int_noprefix(table_data, 0, 1); /* Type */ -+ build_append_int_noprefix(table_data, 16, 1); /* Length */ -+ /* Proximity Domain [7:0] */ -+ build_append_int_noprefix(table_data, apic_ids->cpus[i].props.node_id, -+ 1); -+ build_append_int_noprefix(table_data, apic_ids->cpus[i].arch_id, -+ 1); /* APIC ID */ -+ /* Flags, Table 5-36 */ -+ build_append_int_noprefix(table_data, 1, 4); -+ build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */ -+ /* Proximity Domain [31:8] */ -+ build_append_int_noprefix(table_data, 0, 3); -+ build_append_int_noprefix(table_data, 0, 4); /* Reserved */ -+ } -+ -+ /* node0 */ -+ mem_base = (uint64_t)0; -+ mem_len = 0x10000000; -+ build_srat_memory(table_data, mem_base, mem_len, 0, MEM_AFFINITY_ENABLED); -+ mem_base = 0x90000000; -+ if (!nb_numa_nodes) { -+ mem_len = machine->ram_size - 0x10000000; -+ } else { -+ mem_len = numa_info[0].node_mem - 0x10000000; -+ } -+ -+ build_srat_memory(table_data, mem_base, mem_len, 0, MEM_AFFINITY_ENABLED); -+ mem_base += mem_len; -+ -+ /* node1 ~ nodemax */ -+ for (i = 1; i < nb_numa_nodes; ++i) { -+ mem_len = numa_info[i].node_mem; -+ build_srat_memory(table_data, mem_base, mem_len, i, -+ MEM_AFFINITY_ENABLED); -+ mem_base += mem_len; -+ } -+ -+ if (lsms->hotplug_memory_size) { -+ build_srat_memory(table_data, machine->device_memory->base, -+ lsms->hotplug_memory_size, 0, -+ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); -+ } -+ -+ acpi_table_end(linker, &table); -+} -+ -+typedef struct AcpiBuildState { -+ /* Copy of table in RAM (for patching). */ -+ MemoryRegion *table_mr; -+ /* Is table patched? */ -+ uint8_t patched; -+ void *rsdp; -+ MemoryRegion *rsdp_mr; -+ MemoryRegion *linker_mr; -+} AcpiBuildState; -+ -+static void build_ls7a_pci0_int(Aml *table) -+{ -+ Aml *sb_scope = aml_scope("_SB"); -+ Aml *pci0_scope = aml_scope("PCI0"); -+ Aml *prt_pkg = aml_varpackage(128); -+ int slot, pin; -+ -+ for (slot = 0; slot < PCI_SLOT_MAX; slot++) { -+ for (pin = 0; pin < PCI_NUM_PINS; pin++) { -+ Aml *pkg = aml_package(4); -+ aml_append(pkg, aml_int((slot << 16) | 0xFFFF)); -+ aml_append(pkg, aml_int(pin)); -+ aml_append(pkg, aml_int(0)); -+ aml_append(pkg, aml_int(LOONGARCH_PCH_IRQ_BASE + 16 + -+ (slot * 4 + pin) % 16)); -+ aml_append(prt_pkg, pkg); -+ } -+ } -+ aml_append(pci0_scope, aml_name_decl("_PRT", prt_pkg)); -+ -+ aml_append(sb_scope, pci0_scope); -+ -+ aml_append(table, sb_scope); -+} -+ -+static void build_dbg_aml(Aml *table) -+{ -+ Aml *field; -+ Aml *method; -+ Aml *while_ctx; -+ Aml *scope = aml_scope("\\"); -+ Aml *buf = aml_local(0); -+ Aml *len = aml_local(1); -+ Aml *idx = aml_local(2); -+ -+ aml_append(scope, aml_operation_region("DBG", AML_SYSTEM_IO, -+ aml_int(0x0402), 0x01)); -+ field = aml_field("DBG", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); -+ aml_append(field, aml_named_field("DBGB", 8)); -+ aml_append(scope, field); -+ -+ method = aml_method("DBUG", 1, AML_NOTSERIALIZED); -+ -+ aml_append(method, aml_to_hexstring(aml_arg(0), buf)); -+ aml_append(method, aml_to_buffer(buf, buf)); -+ aml_append(method, aml_subtract(aml_sizeof(buf), aml_int(1), len)); -+ aml_append(method, aml_store(aml_int(0), idx)); -+ -+ while_ctx = aml_while(aml_lless(idx, len)); -+ aml_append(while_ctx, -+ aml_store(aml_derefof(aml_index(buf, idx)), aml_name("DBGB"))); -+ aml_append(while_ctx, aml_increment(idx)); -+ aml_append(method, while_ctx); -+ -+ aml_append(method, aml_store(aml_int(0x0A), aml_name("DBGB"))); -+ aml_append(scope, method); -+ -+ aml_append(table, scope); -+} -+ -+static Aml *build_ls7a_osc_method(void) -+{ -+ Aml *if_ctx; -+ Aml *if_ctx2; -+ Aml *else_ctx; -+ Aml *method; -+ Aml *a_cwd1 = aml_name("CDW1"); -+ Aml *a_ctrl = aml_local(0); -+ -+ method = aml_method("_OSC", 4, AML_NOTSERIALIZED); -+ aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); -+ -+ if_ctx = aml_if(aml_equal( -+ aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766"))); -+ aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); -+ aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); -+ -+ aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl)); -+ -+ /* -+ * Always allow native PME, AER (no dependencies) -+ * Allow SHPC (PCI bridges can have SHPC controller) -+ */ -+ aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl)); -+ -+ if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1)))); -+ /* Unknown revision */ -+ aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1)); -+ aml_append(if_ctx, if_ctx2); -+ -+ if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl))); -+ /* Capabilities bits were masked */ -+ aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1)); -+ aml_append(if_ctx, if_ctx2); -+ -+ /* Update DWORD3 in the buffer */ -+ aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3"))); -+ aml_append(method, if_ctx); -+ -+ else_ctx = aml_else(); -+ /* Unrecognized UUID */ -+ aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1)); -+ aml_append(method, else_ctx); -+ -+ aml_append(method, aml_return(aml_arg(3))); -+ return method; -+} -+ -+static void build_ls7a_rtc_device_aml(Aml *table) -+{ -+ Aml *dev; -+ Aml *crs; -+ uint32_t rtc_irq = LS7A_RTC_IRQ; -+ -+ Aml *scope = aml_scope("_SB"); -+ dev = aml_device("RTC"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("LOON0001"))); -+ crs = aml_resource_template(); -+ aml_append(crs, aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, -+ AML_MAX_FIXED, AML_NON_CACHEABLE, -+ AML_READ_WRITE, 0, LS7A_RTC_REG_BASE, -+ LS7A_RTC_REG_BASE + LS7A_RTC_LEN - 1, 0, -+ LS7A_RTC_LEN)); -+ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, -+ AML_EXCLUSIVE, &rtc_irq, 1)); -+ -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ aml_append(scope, dev); -+ aml_append(table, scope); -+} -+ -+static void build_ls7a_uart_device_aml(Aml *table) -+{ -+ Aml *dev; -+ Aml *crs; -+ Aml *pkg0, *pkg1, *pkg2; -+ uint32_t uart_irq = LS7A_UART_IRQ; -+ -+ Aml *scope = aml_scope("_SB"); -+ dev = aml_device("COMA"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501"))); -+ aml_append(dev, aml_name_decl("_UID", aml_int(0))); -+ aml_append(dev, aml_name_decl("_CCA", aml_int(1))); -+ crs = aml_resource_template(); -+ aml_append(crs, aml_qword_memory( -+ AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, -+ AML_NON_CACHEABLE, AML_READ_WRITE, 0, LS7A_UART_BASE, -+ LS7A_UART_BASE + LS7A_UART_LEN - 1, 0, 0x8)); -+ aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, -+ AML_EXCLUSIVE, &uart_irq, 1)); -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ pkg0 = aml_package(0x2); -+ aml_append(pkg0, aml_int(0x01F78A40)); -+ aml_append(pkg0, aml_string("clock-frenquency")); -+ pkg1 = aml_package(0x1); -+ aml_append(pkg1, pkg0); -+ pkg2 = aml_package(0x2); -+ aml_append(pkg2, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); -+ aml_append(pkg2, pkg1); -+ -+ aml_append(dev, aml_name_decl("_DSD", pkg2)); -+ -+ aml_append(scope, dev); -+ aml_append(table, scope); -+} -+ -+#ifdef CONFIG_TPM -+static void acpi_dsdt_add_tpm(Aml *scope, LoongarchMachineState *vms) -+{ -+ PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); -+ hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS; -+ SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find()); -+ MemoryRegion *sbdev_mr; -+ hwaddr tpm_base; -+ -+ if (!sbdev) { -+ return; -+ } -+ -+ tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); -+ assert(tpm_base != -1); -+ -+ tpm_base += pbus_base; -+ -+ sbdev_mr = sysbus_mmio_get_region(sbdev, 0); -+ -+ Aml *dev = aml_device("TPM0"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101"))); -+ aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device"))); -+ aml_append(dev, aml_name_decl("_UID", aml_int(0))); -+ -+ Aml *crs = aml_resource_template(); -+ aml_append(crs, aml_memory32_fixed(tpm_base, -+ (uint32_t)memory_region_size(sbdev_mr), -+ AML_READ_WRITE)); -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ aml_append(scope, dev); -+} -+#endif -+ -+static void build_dsdt(GArray *table_data, BIOSLinker *linker, -+ MachineState *machine) -+{ -+ Aml *dsdt, *sb_scope, *scope, *dev, *crs, *pkg; -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ uint32_t nr_mem = machine->ram_slots; -+ uint64_t base = LS7A_ACPI_REG_BASE; -+ int root_bus_limit = PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1); -+ AcpiTable table = { .sig = "DSDT", -+ .rev = 1, -+ .oem_id = lsms->oem_id, -+ .oem_table_id = lsms->oem_table_id }; -+ -+ acpi_table_begin(&table, table_data); -+ dsdt = init_aml_allocator(); -+ -+ build_dbg_aml(dsdt); -+ -+ sb_scope = aml_scope("_SB"); -+ dev = aml_device("PCI0"); -+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); -+ aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); -+ aml_append(dev, aml_name_decl("_ADR", aml_int(0))); -+ aml_append(dev, aml_name_decl("_BBN", aml_int(0))); -+ aml_append(dev, aml_name_decl("_UID", aml_int(1))); -+ aml_append(dev, build_ls7a_osc_method()); -+ aml_append(sb_scope, dev); -+ -+#ifdef CONFIG_TPM -+ acpi_dsdt_add_tpm(sb_scope, lsms); -+#endif -+ aml_append(dsdt, sb_scope); -+ -+ build_ls7a_pci0_int(dsdt); -+ build_ls7a_rtc_device_aml(dsdt); -+ build_ls7a_uart_device_aml(dsdt); -+ -+ if (lsms->acpi_dev) { -+ CPUHotplugFeatures opts = { .acpi_1_compatible = true, -+ .has_legacy_cphp = false }; -+ build_cpus_aml(dsdt, machine, opts, CPU_HOTPLUG_BASE, "\\_SB.PCI0", -+ "\\_GPE._E02", AML_SYSTEM_MEMORY); -+ -+ build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", "\\_GPE._E03", -+ AML_SYSTEM_MEMORY, MEMORY_HOTPLUG_BASE); -+ } -+ -+ scope = aml_scope("_GPE"); -+ { -+ aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); -+ } -+ aml_append(dsdt, scope); -+ -+ scope = aml_scope("\\_SB.PCI0"); -+ /* build PCI0._CRS */ -+ crs = aml_resource_template(); -+ aml_append(crs, aml_word_bus_number( -+ AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, 0x0000, -+ 0x0, root_bus_limit, 0x0000, root_bus_limit + 1)); -+ aml_append(crs, aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, -+ AML_ENTIRE_RANGE, 0x0000, 0x4000, 0xFFFF, -+ 0x0000, 0xC000)); -+ aml_append(crs, -+ aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, -+ AML_CACHEABLE, AML_READ_WRITE, 0, 0x40000000, -+ 0x7FFFFFFF, 0, 0x40000000)); -+ aml_append(scope, aml_name_decl("_CRS", crs)); -+ -+ /* reserve GPE0 block resources */ -+ dev = aml_device("GPE0"); -+ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06"))); -+ aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources"))); -+ /* device present, functioning, decoding, not shown in UI */ -+ aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); -+ crs = aml_resource_template(); -+ aml_append(crs, -+ aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, -+ AML_CACHEABLE, AML_READ_WRITE, 0, -+ base + LS7A_GPE0_STS_REG, -+ base + LS7A_GPE0_STS_REG + 0x3, 0, 0x4)); -+ aml_append(dev, aml_name_decl("_CRS", crs)); -+ aml_append(scope, dev); -+ aml_append(dsdt, scope); -+ -+ scope = aml_scope("\\"); -+ pkg = aml_package(4); -+ aml_append(pkg, aml_int(7)); /* PM1a_CNT.SLP_TYP */ -+ aml_append(pkg, aml_int(7)); /* PM1b_CNT.SLP_TYP not impl. */ -+ aml_append(pkg, aml_int(0)); /* reserved */ -+ aml_append(pkg, aml_int(0)); /* reserved */ -+ aml_append(scope, aml_name_decl("_S5", pkg)); -+ aml_append(dsdt, scope); -+ -+ /* copy AML table into ACPI tables blob and patch header there */ -+ g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); -+ acpi_table_end(linker, &table); -+ free_aml_allocator(); -+} -+ -+static void acpi_build(AcpiBuildTables *tables, MachineState *machine) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ GArray *table_offsets; -+ AcpiFadtData fadt_data; -+ unsigned facs, rsdt, fadt, dsdt; -+ uint8_t *u; -+ size_t aml_len = 0; -+ GArray *tables_blob = tables->table_data; -+ -+ init_common_fadt_data(&fadt_data); -+ -+ table_offsets = g_array_new(false, true, sizeof(uint32_t)); /* clear */ -+ ACPI_BUILD_DPRINTF("init ACPI tables\n"); -+ -+ bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE, -+ tables_blob, 64, false /* high memory */); -+ -+ /* -+ * FACS is pointed to by FADT. -+ * We place it first since it's the only table that has alignment -+ * requirements. -+ */ -+ facs = tables_blob->len; -+ build_facs(tables_blob); -+ -+ /* DSDT is pointed to by FADT */ -+ dsdt = tables_blob->len; -+ build_dsdt(tables_blob, tables->linker, MACHINE(qdev_get_machine())); -+ -+ /* -+ * Count the size of the DSDT and SSDT, we will need it for legacy -+ * sizing of ACPI tables. -+ */ -+ aml_len += tables_blob->len - dsdt; -+ -+ /* ACPI tables pointed to by RSDT */ -+ fadt = tables_blob->len; -+ acpi_add_table(table_offsets, tables_blob); -+ fadt_data.facs_tbl_offset = &facs; -+ fadt_data.dsdt_tbl_offset = &dsdt; -+ fadt_data.xdsdt_tbl_offset = &dsdt; -+ build_fadt(tables_blob, tables->linker, &fadt_data, "LOONGS", "TP-R00"); -+ aml_len += tables_blob->len - fadt; -+ -+ acpi_add_table(table_offsets, tables_blob); -+ build_madt(tables_blob, tables->linker, lsms); -+ -+ acpi_add_table(table_offsets, tables_blob); -+ build_srat(tables_blob, tables->linker, machine); -+ if (machine->numa_state->have_numa_distance) { -+ acpi_add_table(table_offsets, tables_blob); -+ build_slit(tables_blob, tables->linker, machine, lsms->oem_id, -+ lsms->oem_table_id); -+ } -+ -+ if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { -+ acpi_add_table(table_offsets, tables_blob); -+ build_tpm2(tables_blob, tables->linker, tables->tcpalog, lsms->oem_id, -+ lsms->oem_table_id); -+ } -+ -+ /* Build mcfg */ -+ acpi_add_table(table_offsets, tables_blob); -+ { -+ AcpiMcfgInfo mcfg = { -+ .base = LS_PCIECFG_BASE, -+ .size = LS_PCIECFG_SIZE, -+ }; -+ build_mcfg(tables_blob, tables->linker, &mcfg, lsms->oem_id, -+ lsms->oem_table_id); -+ } -+ -+ /* Add tables supplied by user (if any) */ -+ for (u = acpi_table_first(); u; u = acpi_table_next(u)) { -+ unsigned len = acpi_table_len(u); -+ -+ acpi_add_table(table_offsets, tables_blob); -+ g_array_append_vals(tables_blob, u, len); -+ } -+ -+ /* RSDT is pointed to by RSDP */ -+ rsdt = tables_blob->len; -+ build_rsdt(tables_blob, tables->linker, table_offsets, "LOONGS", "TP-R00"); -+ -+ /* RSDP is in FSEG memory, so allocate it separately */ -+ { -+ AcpiRsdpData rsdp_data = { -+ .revision = 0, -+ .oem_id = lsms->oem_id, -+ .xsdt_tbl_offset = NULL, -+ .rsdt_tbl_offset = &rsdt, -+ }; -+ build_rsdp(tables->rsdp, tables->linker, &rsdp_data); -+ } -+ acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE); -+ -+ /* Cleanup memory that's no longer used. */ -+ g_array_free(table_offsets, true); -+} -+ -+static void acpi_ram_update(MemoryRegion *mr, GArray *data) -+{ -+ uint32_t size = acpi_data_len(data); -+ -+ /* -+ * Make sure RAM size is correct - -+ * in case it got changed e.g. by migration -+ */ -+ memory_region_ram_resize(mr, size, &error_abort); -+ -+ memcpy(memory_region_get_ram_ptr(mr), data->data, size); -+ memory_region_set_dirty(mr, 0, size); -+} -+ -+static void acpi_build_update(void *build_opaque) -+{ -+ AcpiBuildState *build_state = build_opaque; -+ AcpiBuildTables tables; -+ -+ /* No state to update or already patched? Nothing to do. */ -+ if (!build_state || build_state->patched) { -+ return; -+ } -+ build_state->patched = 1; -+ -+ acpi_build_tables_init(&tables); -+ -+ acpi_build(&tables, MACHINE(qdev_get_machine())); -+ -+ acpi_ram_update(build_state->table_mr, tables.table_data); -+ -+ if (build_state->rsdp) { -+ memcpy(build_state->rsdp, tables.rsdp->data, -+ acpi_data_len(tables.rsdp)); -+ } else { -+ acpi_ram_update(build_state->rsdp_mr, tables.rsdp); -+ } -+ -+ acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); -+ acpi_build_tables_cleanup(&tables, true); -+} -+ -+static void acpi_build_reset(void *build_opaque) -+{ -+ AcpiBuildState *build_state = build_opaque; -+ build_state->patched = 0; -+} -+ -+static const VMStateDescription vmstate_acpi_build = { -+ .name = "acpi_build", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField[]){ VMSTATE_UINT8(patched, AcpiBuildState), -+ VMSTATE_END_OF_LIST() }, -+}; -+ -+void loongarch_acpi_setup(void) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ AcpiBuildTables tables; -+ AcpiBuildState *build_state; -+ -+ if (!lsms->fw_cfg) { -+ ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n"); -+ return; -+ } -+ -+ if (!lsms->acpi_build_enabled) { -+ ACPI_BUILD_DPRINTF("ACPI build disabled. Bailing out.\n"); -+ return; -+ } -+ -+ if (!loongarch_is_acpi_enabled(lsms)) { -+ ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n"); -+ return; -+ } -+ -+ build_state = g_malloc0(sizeof *build_state); -+ -+ acpi_build_tables_init(&tables); -+ acpi_build(&tables, MACHINE(lsms)); -+ -+ /* Now expose it all to Guest */ -+ build_state->table_mr = -+ acpi_add_rom_blob(acpi_build_update, build_state, tables.table_data, -+ ACPI_BUILD_TABLE_FILE); -+ assert(build_state->table_mr != NULL); -+ -+ build_state->linker_mr = -+ acpi_add_rom_blob(acpi_build_update, build_state, -+ tables.linker->cmd_blob, "etc/table-loader"); -+ -+ fw_cfg_add_file(lsms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, -+ acpi_data_len(tables.tcpalog)); -+ -+ build_state->rsdp = NULL; -+ build_state->rsdp_mr = acpi_add_rom_blob( -+ acpi_build_update, build_state, tables.rsdp, ACPI_BUILD_RSDP_FILE); -+ -+ qemu_register_reset(acpi_build_reset, build_state); -+ acpi_build_reset(build_state); -+ vmstate_register(NULL, 0, &vmstate_acpi_build, build_state); -+ -+ /* -+ * Cleanup tables but don't free the memory: we track it -+ * in build_state. -+ */ -+ acpi_build_tables_cleanup(&tables, false); -+} -diff --git a/hw/loongarch/acpi-build.h b/hw/loongarch/acpi-build.h -new file mode 100644 -index 0000000000..97d53a9258 ---- /dev/null -+++ b/hw/loongarch/acpi-build.h -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef HW_LARCH_ACPI_BUILD_H -+#define HW_LARCH_ACPI_BUILD_H -+ -+#define EFI_ACPI_OEM_ID "LARCH" -+#define EFI_ACPI_OEM_TABLE_ID "LARCH" /* OEM table id 8 bytes long */ -+#define EFI_ACPI_OEM_REVISION 0x00000002 -+#define EFI_ACPI_CREATOR_ID "LINUX" -+#define EFI_ACPI_CREATOR_REVISION 0x01000013 -+ -+#define ACPI_COMPATIBLE_1_0 0 -+#define ACPI_COMPATIBLE_2_0 1 -+ -+void loongarch_acpi_setup(void); -+ -+#endif -diff --git a/hw/loongarch/apic.c b/hw/loongarch/apic.c -new file mode 100644 -index 0000000000..9e762cf0fe ---- /dev/null -+++ b/hw/loongarch/apic.c -@@ -0,0 +1,689 @@ -+/* -+ * Loongarch 3A5000 interrupt controller emulation -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "hw/boards.h" -+#include "hw/irq.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/sysbus.h" -+#include "qemu/host-utils.h" -+#include "qemu/error-report.h" -+#include "sysemu/kvm.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "target/loongarch64/cpu.h" -+#include "exec/address-spaces.h" -+#include "hw/loongarch/larch.h" -+#include "migration/vmstate.h" -+ -+#define DEBUG_APIC 0 -+ -+#define DPRINTF(fmt, ...) \ -+ do { \ -+ if (DEBUG_APIC) { \ -+ fprintf(stderr, "APIC: " fmt, ##__VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+#define APIC_OFFSET 0x400 -+#define APIC_BASE (0x1f010000ULL) -+#define EXTIOI_NODETYPE_START (0x4a0 - APIC_OFFSET) -+#define EXTIOI_NODETYPE_END (0x4c0 - APIC_OFFSET) -+#define EXTIOI_IPMAP_START (0x4c0 - APIC_OFFSET) -+#define EXTIOI_IPMAP_END (0x4c8 - APIC_OFFSET) -+#define EXTIOI_ENABLE_START (0x600 - APIC_OFFSET) -+#define EXTIOI_ENABLE_END (0x620 - APIC_OFFSET) -+#define EXTIOI_BOUNCE_START (0x680 - APIC_OFFSET) -+#define EXTIOI_BOUNCE_END (0x6a0 - APIC_OFFSET) -+#define EXTIOI_ISR_START (0x700 - APIC_OFFSET) -+#define EXTIOI_ISR_END (0x720 - APIC_OFFSET) -+#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) -+#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) -+#define EXTIOI_COREISR_START (0x10000) -+#define EXTIOI_COREISR_END (EXTIOI_COREISR_START + 0x10000) -+ -+static int ext_irq_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ apicState *apic = opaque; -+ struct loongarch_kvm_irqchip *chip; -+ struct kvm_loongarch_ls3a_extirq_state *kstate; -+ int ret, length, i, vcpuid; -+#endif -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { -+ return 0; -+ } -+#ifdef CONFIG_KVM -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct kvm_loongarch_ls3a_extirq_state); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS3A_EXTIRQ; -+ chip->len = length; -+ -+ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ -+ kstate = (struct kvm_loongarch_ls3a_extirq_state *)chip->data; -+ for (i = 0; i < EXTIOI_IRQS_BITMAP_SIZE; i++) { -+ apic->ext_en[i] = kstate->ext_en_r.reg_u8[i]; -+ apic->ext_bounce[i] = kstate->bounce_r.reg_u8[i]; -+ apic->ext_isr[i] = kstate->ext_isr_r.reg_u8[i]; -+ for (vcpuid = 0; vcpuid < MAX_CORES; vcpuid++) { -+ apic->ext_coreisr[vcpuid][i] = -+ kstate->ext_core_isr_r.reg_u8[vcpuid][i]; -+ } -+ } -+ for (i = 0; i < EXTIOI_IRQS_IPMAP_SIZE; i++) { -+ apic->ext_ipmap[i] = kstate->ip_map_r.reg_u8[i]; -+ } -+ for (i = 0; i < EXTIOI_IRQS; i++) { -+ apic->ext_coremap[i] = kstate->core_map_r.reg_u8[i]; -+ } -+ for (i = 0; i < 16; i++) { -+ apic->ext_nodetype[i] = kstate->node_type_r.reg_u16[i]; -+ } -+ g_free(chip); -+#endif -+ return 0; -+} -+ -+static int ext_irq_post_load(void *opaque, int version) -+{ -+#ifdef CONFIG_KVM -+ apicState *apic = opaque; -+ struct loongarch_kvm_irqchip *chip; -+ struct kvm_loongarch_ls3a_extirq_state *kstate; -+ int ret, length, i, vcpuid; -+#endif -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { -+ return 0; -+ } -+#ifdef CONFIG_KVM -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct kvm_loongarch_ls3a_extirq_state); -+ chip = g_malloc0(length); -+ -+ chip->chip_id = KVM_IRQCHIP_LS3A_EXTIRQ; -+ chip->len = length; -+ -+ kstate = (struct kvm_loongarch_ls3a_extirq_state *)chip->data; -+ for (i = 0; i < EXTIOI_IRQS_BITMAP_SIZE; i++) { -+ kstate->ext_en_r.reg_u8[i] = apic->ext_en[i]; -+ kstate->bounce_r.reg_u8[i] = apic->ext_bounce[i]; -+ kstate->ext_isr_r.reg_u8[i] = apic->ext_isr[i]; -+ for (vcpuid = 0; vcpuid < MAX_CORES; vcpuid++) { -+ kstate->ext_core_isr_r.reg_u8[vcpuid][i] = -+ apic->ext_coreisr[vcpuid][i]; -+ } -+ } -+ for (i = 0; i < EXTIOI_IRQS_IPMAP_SIZE; i++) { -+ kstate->ip_map_r.reg_u8[i] = apic->ext_ipmap[i]; -+ } -+ for (i = 0; i < EXTIOI_IRQS; i++) { -+ kstate->core_map_r.reg_u8[i] = apic->ext_coremap[i]; -+ } -+ for (i = 0; i < 16; i++) { -+ kstate->node_type_r.reg_u16[i] = apic->ext_nodetype[i]; -+ } -+ -+ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_SET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ g_free(chip); -+#endif -+ return 0; -+} -+ -+typedef struct nodeApicState { -+ unsigned long addr; -+ int nodeid; -+ apicState *apic; -+} nodeApicState; -+ -+static void ioapic_update_irq(void *opaque, int irq, int level) -+{ -+ apicState *s = opaque; -+ uint8_t ipnum, cpu, cpu_ipnum; -+ unsigned long found1, found2; -+ uint8_t reg_count, reg_bit; -+ -+ reg_count = irq / 32; -+ reg_bit = irq % 32; -+ -+ ipnum = s->ext_sw_ipmap[irq]; -+ cpu = s->ext_sw_coremap[irq]; -+ cpu_ipnum = cpu * LS3A_INTC_IP + ipnum; -+ if (level == 1) { -+ if (test_bit(reg_bit, ((void *)s->ext_en + 0x4 * reg_count)) == -+ false) { -+ return; -+ } -+ -+ if (test_bit(reg_bit, ((void *)s->ext_isr + 0x4 * reg_count)) == -+ false) { -+ return; -+ } -+ bitmap_set(((void *)s->ext_coreisr[cpu] + 0x4 * reg_count), reg_bit, -+ 1); -+ found1 = -+ find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), -+ EXTIOI_IRQS, 0); -+ bitmap_set(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), -+ reg_bit, 1); -+ if (found1 >= EXTIOI_IRQS) { -+ qemu_set_irq(s->parent_irq[cpu][ipnum], level); -+ } -+ } else { -+ bitmap_clear(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); -+ bitmap_clear(((void *)s->ext_coreisr[cpu] + 0x4 * reg_count), reg_bit, -+ 1); -+ found1 = -+ find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), -+ EXTIOI_IRQS, 0); -+ found1 += reg_count * 32; -+ bitmap_clear(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), -+ reg_bit, 1); -+ found2 = -+ find_next_bit(((void *)s->ext_ipisr[cpu_ipnum] + 0x4 * reg_count), -+ EXTIOI_IRQS, 0); -+ if ((found1 < EXTIOI_IRQS) && (found2 >= EXTIOI_IRQS)) { -+ qemu_set_irq(s->parent_irq[cpu][ipnum], level); -+ } -+ } -+} -+ -+static void ioapic_setirq(void *opaque, int irq, int level) -+{ -+ apicState *s = opaque; -+ uint8_t reg_count, reg_bit; -+ -+ reg_count = irq / 32; -+ reg_bit = irq % 32; -+ -+ if (level) { -+ bitmap_set(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); -+ } else { -+ bitmap_clear(((void *)s->ext_isr + 0x4 * reg_count), reg_bit, 1); -+ } -+ -+ ioapic_update_irq(s, irq, level); -+} -+ -+static uint32_t apic_readb(void *opaque, hwaddr addr) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint8_t ret; -+ int cpu; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ ret = 0; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ ret = *(uint8_t *)((void *)state->ext_en + off); -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ ret = *(uint8_t *)((void *)state->ext_bounce + off); -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ ret = *(uint8_t *)((void *)state->ext_isr + off); -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ ret = *(uint8_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ off -= EXTIOI_IPMAP_START; -+ ret = *(uint8_t *)((void *)state->ext_ipmap + off); -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ off -= EXTIOI_COREMAP_START; -+ ret = *(uint8_t *)((void *)state->ext_coremap + off); -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ ret = *(uint8_t *)((void *)state->ext_nodetype + off); -+ } -+ -+ DPRINTF("readb reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); -+ return ret; -+} -+ -+static uint32_t apic_readw(void *opaque, hwaddr addr) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint16_t ret; -+ int cpu; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ ret = 0; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ ret = *(uint16_t *)((void *)state->ext_en + off); -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ ret = *(uint16_t *)((void *)state->ext_bounce + off); -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ ret = *(uint16_t *)((void *)state->ext_isr + off); -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ ret = *(uint16_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ off -= EXTIOI_IPMAP_START; -+ ret = *(uint16_t *)((void *)state->ext_ipmap + off); -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ off -= EXTIOI_COREMAP_START; -+ ret = *(uint16_t *)((void *)state->ext_coremap + off); -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ ret = *(uint16_t *)((void *)state->ext_nodetype + off); -+ } -+ -+ DPRINTF("readw reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); -+ return ret; -+} -+ -+static uint32_t apic_readl(void *opaque, hwaddr addr) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint32_t ret; -+ int cpu; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ ret = 0; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ ret = *(uint32_t *)((void *)state->ext_en + off); -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ ret = *(uint32_t *)((void *)state->ext_bounce + off); -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ ret = *(uint32_t *)((void *)state->ext_isr + off); -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ ret = *(uint32_t *)((void *)state->ext_coreisr[cpu] + (off & 0x1f)); -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ off -= EXTIOI_IPMAP_START; -+ ret = *(uint32_t *)((void *)state->ext_ipmap + off); -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ off -= EXTIOI_COREMAP_START; -+ ret = *(uint32_t *)((void *)state->ext_coremap + off); -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ ret = *(uint32_t *)((void *)state->ext_nodetype + off); -+ } -+ -+ DPRINTF("readl reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, ret); -+ return ret; -+} -+ -+static void apic_writeb(void *opaque, hwaddr addr, uint32_t val) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint8_t old; -+ int cpu, i, ipnum, level, mask; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ old = *(uint8_t *)((void *)state->ext_en + off); -+ if (old != val) { -+ *(uint8_t *)((void *)state->ext_en + off) = val; -+ old = old ^ val; -+ mask = 0x1; -+ for (i = 0; i < 8; i++) { -+ if (old & mask) { -+ level = !!(val & (0x1 << i)); -+ ioapic_update_irq(state, i + off * 8, level); -+ } -+ mask = mask << 1; -+ } -+ } -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ *(uint8_t *)((void *)state->ext_bounce + off) = val; -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ old = *(uint8_t *)((void *)state->ext_isr + off); -+ *(uint8_t *)((void *)state->ext_isr + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 8; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ off = off & 0x1f; -+ old = *(uint8_t *)((void *)state->ext_coreisr[cpu] + off); -+ *(uint8_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 8; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ off -= EXTIOI_IPMAP_START; -+ val = val & 0xf; -+ *(uint8_t *)((void *)state->ext_ipmap + off) = val; -+ ipnum = 0; -+ for (i = 0; i < 4; i++) { -+ if (val & (0x1 << i)) { -+ ipnum = i; -+ break; -+ } -+ } -+ if (val) { -+ for (i = 0; i < 32; i++) { -+ cpu = off * 32 + i; -+ state->ext_sw_ipmap[cpu] = ipnum; -+ } -+ } -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ off -= EXTIOI_COREMAP_START; -+ val = val & 0xff; -+ *(uint8_t *)((void *)state->ext_coremap + off) = val; -+ state->ext_sw_coremap[off] = val; -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ *(uint8_t *)((void *)state->ext_nodetype + off) = val; -+ } -+ -+ DPRINTF("writeb reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); -+} -+ -+static void apic_writew(void *opaque, hwaddr addr, uint32_t val) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint16_t old; -+ int cpu, i, level, mask; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ old = *(uint16_t *)((void *)state->ext_en + off); -+ if (old != val) { -+ *(uint16_t *)((void *)state->ext_en + off) = val; -+ old = old ^ val; -+ mask = 0x1; -+ for (i = 0; i < 16; i++) { -+ if (old & mask) { -+ level = !!(val & (0x1 << i)); -+ ioapic_update_irq(state, i + off * 8, level); -+ } -+ mask = mask << 1; -+ } -+ } -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ *(uint16_t *)((void *)state->ext_bounce + off) = val; -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ old = *(uint16_t *)((void *)state->ext_isr + off); -+ *(uint16_t *)((void *)state->ext_isr + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 16; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ off = off & 0x1f; -+ old = *(uint16_t *)((void *)state->ext_coreisr[cpu] + off); -+ *(uint16_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 16; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ apic_writeb(opaque, addr, val & 0xff); -+ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); -+ -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ apic_writeb(opaque, addr, val & 0xff); -+ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); -+ -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ *(uint16_t *)((void *)state->ext_nodetype + off) = val; -+ } -+ -+ DPRINTF("writew reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); -+} -+ -+static void apic_writel(void *opaque, hwaddr addr, uint32_t val) -+{ -+ nodeApicState *node; -+ apicState *state; -+ unsigned long off; -+ uint32_t old; -+ int cpu, i, level, mask; -+ -+ node = (nodeApicState *)opaque; -+ state = node->apic; -+ off = addr & 0xfffff; -+ if ((off >= EXTIOI_ENABLE_START) && (off < EXTIOI_ENABLE_END)) { -+ off -= EXTIOI_ENABLE_START; -+ old = *(uint32_t *)((void *)state->ext_en + off); -+ if (old != val) { -+ *(uint32_t *)((void *)state->ext_en + off) = val; -+ old = old ^ val; -+ mask = 0x1; -+ for (i = 0; i < 32; i++) { -+ if (old & mask) { -+ level = !!(val & (0x1 << i)); -+ ioapic_update_irq(state, i + off * 8, level); -+ } -+ mask = mask << 1; -+ } -+ } -+ } else if ((off >= EXTIOI_BOUNCE_START) && (off < EXTIOI_BOUNCE_END)) { -+ off -= EXTIOI_BOUNCE_START; -+ *(uint32_t *)((void *)state->ext_bounce + off) = val; -+ } else if ((off >= EXTIOI_ISR_START) && (off < EXTIOI_ISR_END)) { -+ off -= EXTIOI_ISR_START; -+ old = *(uint32_t *)((void *)state->ext_isr + off); -+ *(uint32_t *)((void *)state->ext_isr + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 32; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_COREISR_START) && (off < EXTIOI_COREISR_END)) { -+ off -= EXTIOI_COREISR_START; -+ cpu = (off >> 8) & 0xff; -+ off = off & 0x1f; -+ old = *(uint32_t *)((void *)state->ext_coreisr[cpu] + off); -+ *(uint32_t *)((void *)state->ext_coreisr[cpu] + off) = old & ~val; -+ mask = 0x1; -+ for (i = 0; i < 32; i++) { -+ if ((old & mask) && (val & mask)) { -+ ioapic_update_irq(state, i + off * 8, 0); -+ } -+ mask = mask << 1; -+ } -+ } else if ((off >= EXTIOI_IPMAP_START) && (off < EXTIOI_IPMAP_END)) { -+ apic_writeb(opaque, addr, val & 0xff); -+ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); -+ apic_writeb(opaque, addr + 2, (val >> 16) & 0xff); -+ apic_writeb(opaque, addr + 3, (val >> 24) & 0xff); -+ -+ } else if ((off >= EXTIOI_COREMAP_START) && (off < EXTIOI_COREMAP_END)) { -+ apic_writeb(opaque, addr, val & 0xff); -+ apic_writeb(opaque, addr + 1, (val >> 8) & 0xff); -+ apic_writeb(opaque, addr + 2, (val >> 16) & 0xff); -+ apic_writeb(opaque, addr + 3, (val >> 24) & 0xff); -+ -+ } else if ((off >= EXTIOI_NODETYPE_START) && (off < EXTIOI_NODETYPE_END)) { -+ off -= EXTIOI_NODETYPE_START; -+ *(uint32_t *)((void *)state->ext_nodetype + off) = val; -+ } -+ -+ DPRINTF("writel reg 0x" TARGET_FMT_plx " = %x\n", node->addr + addr, val); -+} -+ -+static uint64_t apic_readfn(void *opaque, hwaddr addr, unsigned size) -+{ -+ switch (size) { -+ case 1: -+ return apic_readb(opaque, addr); -+ case 2: -+ return apic_readw(opaque, addr); -+ case 4: -+ return apic_readl(opaque, addr); -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void apic_writefn(void *opaque, hwaddr addr, uint64_t value, -+ unsigned size) -+{ -+ switch (size) { -+ case 1: -+ apic_writeb(opaque, addr, value); -+ break; -+ case 2: -+ apic_writew(opaque, addr, value); -+ break; -+ case 4: -+ apic_writel(opaque, addr, value); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static const VMStateDescription vmstate_apic = { -+ .name = "apic", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = ext_irq_pre_save, -+ .post_load = ext_irq_post_load, -+ .fields = -+ (VMStateField[]){ -+ VMSTATE_UINT8_ARRAY(ext_en, apicState, EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_UINT8_ARRAY(ext_bounce, apicState, -+ EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_UINT8_ARRAY(ext_isr, apicState, EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_UINT8_2DARRAY(ext_coreisr, apicState, MAX_CORES, -+ EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_UINT8_ARRAY(ext_ipmap, apicState, EXTIOI_IRQS_IPMAP_SIZE), -+ VMSTATE_UINT8_ARRAY(ext_coremap, apicState, EXTIOI_IRQS), -+ VMSTATE_UINT16_ARRAY(ext_nodetype, apicState, 16), -+ VMSTATE_UINT64(ext_control, apicState), -+ VMSTATE_UINT8_ARRAY(ext_sw_ipmap, apicState, EXTIOI_IRQS), -+ VMSTATE_UINT8_ARRAY(ext_sw_coremap, apicState, EXTIOI_IRQS), -+ VMSTATE_UINT8_2DARRAY(ext_ipisr, apicState, -+ MAX_CORES *LS3A_INTC_IP, -+ EXTIOI_IRQS_BITMAP_SIZE), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static const MemoryRegionOps apic_ops = { -+ .read = apic_readfn, -+ .write = apic_writefn, -+ .impl.min_access_size = 1, -+ .impl.max_access_size = 4, -+ .valid.min_access_size = 1, -+ .valid.max_access_size = 4, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+int cpu_init_apic(LoongarchMachineState *ms, CPULOONGARCHState *env, int cpu) -+{ -+ apicState *apic; -+ nodeApicState *node; -+ MemoryRegion *iomem; -+ unsigned long base; -+ int pin; -+ char str[32]; -+ -+ if (ms->apic == NULL) { -+ apic = g_malloc0(sizeof(apicState)); -+ vmstate_register(NULL, 0, &vmstate_apic, apic); -+ apic->irq = qemu_allocate_irqs(ioapic_setirq, apic, EXTIOI_IRQS); -+ -+ for (pin = 0; pin < LS3A_INTC_IP; pin++) { -+ /* cpu_pin[9:2] <= intc_pin[7:0] */ -+ apic->parent_irq[cpu][pin] = env->irq[pin + 2]; -+ } -+ ms->apic = apic; -+ -+ if (cpu == 0) { -+ base = APIC_BASE; -+ node = g_malloc0(sizeof(nodeApicState)); -+ node->apic = ms->apic; -+ node->addr = base; -+ -+ iomem = g_new(MemoryRegion, 1); -+ sprintf(str, "apic%d", cpu); -+ /* extioi addr 0x1f010000~0x1f02ffff */ -+ memory_region_init_io(iomem, NULL, &apic_ops, node, str, 0x20000); -+ memory_region_add_subregion(get_system_memory(), base, iomem); -+ } -+ -+ } else { -+ if (cpu != 0) { -+ for (pin = 0; pin < LS3A_INTC_IP; pin++) { -+ ms->apic->parent_irq[cpu][pin] = env->irq[pin + 2]; -+ } -+ } -+ } -+ return 0; -+} -diff --git a/hw/loongarch/ioapic.c b/hw/loongarch/ioapic.c -new file mode 100644 -index 0000000000..102102781f ---- /dev/null -+++ b/hw/loongarch/ioapic.c -@@ -0,0 +1,419 @@ -+/* -+ * LS7A1000 Northbridge IOAPIC support -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "hw/sysbus.h" -+#include "hw/irq.h" -+#include "qemu/log.h" -+#include "sysemu/kvm.h" -+#include "linux/kvm.h" -+#include "migration/vmstate.h" -+ -+#define DEBUG_LS7A_APIC 0 -+ -+#define DPRINTF(fmt, ...) \ -+ do { \ -+ if (DEBUG_LS7A_APIC) { \ -+ fprintf(stderr, "IOAPIC: " fmt, ##__VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+#define TYPE_LS7A_APIC "ioapic" -+#define LS7A_APIC(obj) OBJECT_CHECK(LS7AApicState, (obj), TYPE_LS7A_APIC) -+ -+#define LS7A_IOAPIC_ROUTE_ENTRY_OFFSET 0x100 -+#define LS7A_IOAPIC_INT_ID_OFFSET 0x00 -+#define LS7A_INT_ID_VAL 0x7000000UL -+#define LS7A_INT_ID_VER 0x1f0001UL -+#define LS7A_IOAPIC_INT_MASK_OFFSET 0x20 -+#define LS7A_IOAPIC_INT_EDGE_OFFSET 0x60 -+#define LS7A_IOAPIC_INT_CLEAR_OFFSET 0x80 -+#define LS7A_IOAPIC_INT_STATUS_OFFSET 0x3a0 -+#define LS7A_IOAPIC_INT_POL_OFFSET 0x3e0 -+#define LS7A_IOAPIC_HTMSI_EN_OFFSET 0x40 -+#define LS7A_IOAPIC_HTMSI_VEC_OFFSET 0x200 -+#define LS7A_AUTO_CTRL0_OFFSET 0xc0 -+#define LS7A_AUTO_CTRL1_OFFSET 0xe0 -+ -+typedef struct LS7AApicState { -+ SysBusDevice parent_obj; -+ qemu_irq parent_irq[257]; -+ uint64_t int_id; -+ uint64_t int_mask; /*0x020 interrupt mask register*/ -+ uint64_t htmsi_en; /*0x040 1=msi*/ -+ uint64_t intedge; /*0x060 edge=1 level =0*/ -+ uint64_t intclr; /*0x080 for clean edge int,set 1 clean,set 0 is noused*/ -+ uint64_t auto_crtl0; /*0x0c0*/ -+ uint64_t auto_crtl1; /*0x0e0*/ -+ uint8_t route_entry[64]; /*0x100 - 0x140*/ -+ uint8_t htmsi_vector[64]; /*0x200 - 0x240*/ -+ uint64_t intisr_chip0; /*0x300*/ -+ uint64_t intisr_chip1; /*0x320*/ -+ uint64_t last_intirr; /* edge detection */ -+ uint64_t intirr; /* 0x380 interrupt request register */ -+ uint64_t intisr; /* 0x3a0 interrupt service register */ -+ /* -+ * 0x3e0 interrupt level polarity -+ * selection register 0 for high level tirgger -+ */ -+ uint64_t int_polarity; -+ MemoryRegion iomem; -+} LS7AApicState; -+ -+static void update_irq(LS7AApicState *s) -+{ -+ int i; -+ if ((s->intirr & (~s->int_mask)) & (~s->htmsi_en)) { -+ DPRINTF("7a update irqline up\n"); -+ s->intisr = (s->intirr & (~s->int_mask) & (~s->htmsi_en)); -+ qemu_set_irq(s->parent_irq[256], 1); -+ } else { -+ DPRINTF("7a update irqline down\n"); -+ s->intisr &= (~s->htmsi_en); -+ qemu_set_irq(s->parent_irq[256], 0); -+ } -+ if (s->htmsi_en) { -+ for (i = 0; i < 64; i++) { -+ if ((((~s->intisr) & s->intirr) & s->htmsi_en) & (1ULL << i)) { -+ s->intisr |= 1ULL << i; -+ qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 1); -+ } else if (((~(s->intisr | s->intirr)) & s->htmsi_en) & -+ (1ULL << i)) { -+ qemu_set_irq(s->parent_irq[s->htmsi_vector[i]], 0); -+ } -+ } -+ } -+} -+ -+static void irq_handler(void *opaque, int irq, int level) -+{ -+ LS7AApicState *s = opaque; -+ -+ assert(irq < 64); -+ uint64_t mask = 1ULL << irq; -+ DPRINTF("------ %s irq %d %d\n", __func__, irq, level); -+ -+ if (s->intedge & mask) { -+ /* edge triggered */ -+ /*TODO*/ -+ } else { -+ /* level triggered */ -+ if (level) { -+ s->intirr |= mask; -+ } else { -+ s->intirr &= ~mask; -+ } -+ } -+ update_irq(s); -+} -+ -+static uint64_t ls7a_apic_reg_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ LS7AApicState *a = opaque; -+ uint64_t val = 0; -+ uint64_t offset; -+ int64_t offset_tmp; -+ offset = addr & 0xfff; -+ if (8 == size) { -+ switch (offset) { -+ case LS7A_IOAPIC_INT_ID_OFFSET: -+ val = LS7A_INT_ID_VER; -+ val = (val << 32) + LS7A_INT_ID_VAL; -+ break; -+ case LS7A_IOAPIC_INT_MASK_OFFSET: -+ val = a->int_mask; -+ break; -+ case LS7A_IOAPIC_INT_STATUS_OFFSET: -+ val = a->intisr & (~a->int_mask); -+ break; -+ case LS7A_IOAPIC_INT_EDGE_OFFSET: -+ val = a->intedge; -+ break; -+ case LS7A_IOAPIC_INT_POL_OFFSET: -+ val = a->int_polarity; -+ break; -+ case LS7A_IOAPIC_HTMSI_EN_OFFSET: -+ val = a->htmsi_en; -+ break; -+ case LS7A_AUTO_CTRL0_OFFSET: -+ case LS7A_AUTO_CTRL1_OFFSET: -+ break; -+ default: -+ break; -+ } -+ } else if (1 == size) { -+ if (offset >= LS7A_IOAPIC_HTMSI_VEC_OFFSET) { -+ offset_tmp = offset - LS7A_IOAPIC_HTMSI_VEC_OFFSET; -+ if (offset_tmp >= 0 && offset_tmp < 64) { -+ val = a->htmsi_vector[offset_tmp]; -+ } -+ } else if (offset >= LS7A_IOAPIC_ROUTE_ENTRY_OFFSET) { -+ offset_tmp = offset - LS7A_IOAPIC_ROUTE_ENTRY_OFFSET; -+ if (offset_tmp >= 0 && offset_tmp < 64) { -+ val = a->route_entry[offset_tmp]; -+ DPRINTF("addr %lx val %lx\n", addr, val); -+ } -+ } -+ } -+ DPRINTF(TARGET_FMT_plx " val %lx\n", addr, val); -+ return val; -+} -+ -+static void ls7a_apic_reg_write(void *opaque, hwaddr addr, uint64_t data, -+ unsigned size) -+{ -+ LS7AApicState *a = opaque; -+ int64_t offset_tmp; -+ uint64_t offset; -+ offset = addr & 0xfff; -+ DPRINTF(TARGET_FMT_plx " size %d val %lx\n", addr, size, data); -+ if (8 == size) { -+ switch (offset) { -+ case LS7A_IOAPIC_INT_MASK_OFFSET: -+ a->int_mask = data; -+ update_irq(a); -+ break; -+ case LS7A_IOAPIC_INT_STATUS_OFFSET: -+ a->intisr = data; -+ break; -+ case LS7A_IOAPIC_INT_EDGE_OFFSET: -+ a->intedge = data; -+ break; -+ case LS7A_IOAPIC_INT_CLEAR_OFFSET: -+ a->intisr &= (~data); -+ update_irq(a); -+ break; -+ case LS7A_IOAPIC_INT_POL_OFFSET: -+ a->int_polarity = data; -+ break; -+ case LS7A_IOAPIC_HTMSI_EN_OFFSET: -+ a->htmsi_en = data; -+ break; -+ case LS7A_AUTO_CTRL0_OFFSET: -+ case LS7A_AUTO_CTRL1_OFFSET: -+ break; -+ default: -+ break; -+ } -+ } else if (1 == size) { -+ if (offset >= LS7A_IOAPIC_HTMSI_VEC_OFFSET) { -+ offset_tmp = offset - LS7A_IOAPIC_HTMSI_VEC_OFFSET; -+ if (offset_tmp >= 0 && offset_tmp < 64) { -+ a->htmsi_vector[offset_tmp] = (uint8_t)(data & 0xff); -+ } -+ } else if (offset >= LS7A_IOAPIC_ROUTE_ENTRY_OFFSET) { -+ offset_tmp = offset - LS7A_IOAPIC_ROUTE_ENTRY_OFFSET; -+ if (offset_tmp >= 0 && offset_tmp < 64) { -+ a->route_entry[offset_tmp] = (uint8_t)(data & 0xff); -+ } -+ } -+ } -+} -+ -+static const MemoryRegionOps ls7a_apic_ops = { -+ .read = ls7a_apic_reg_read, -+ .write = ls7a_apic_reg_write, -+ .valid = { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+static int kvm_ls7a_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ LS7AApicState *s = opaque; -+ struct loongarch_kvm_irqchip *chip; -+ struct ls7a_ioapic_state *state; -+ int ret, i, length; -+ -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { -+ return 0; -+ } -+ -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct ls7a_ioapic_state); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; -+ chip->len = length; -+ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ state = (struct ls7a_ioapic_state *)chip->data; -+ s->int_id = state->int_id; -+ s->int_mask = state->int_mask; -+ s->htmsi_en = state->htmsi_en; -+ s->intedge = state->intedge; -+ s->intclr = state->intclr; -+ s->auto_crtl0 = state->auto_crtl0; -+ s->auto_crtl1 = state->auto_crtl1; -+ for (i = 0; i < 64; i++) { -+ s->route_entry[i] = state->route_entry[i]; -+ s->htmsi_vector[i] = state->htmsi_vector[i]; -+ } -+ s->intisr_chip0 = state->intisr_chip0; -+ s->intisr_chip1 = state->intisr_chip1; -+ s->intirr = state->intirr; -+ s->intisr = state->intisr; -+ s->int_polarity = state->int_polarity; -+ g_free(chip); -+#endif -+ return 0; -+} -+ -+static int kvm_ls7a_post_load(void *opaque, int version) -+{ -+#ifdef CONFIG_KVM -+ LS7AApicState *s = opaque; -+ struct loongarch_kvm_irqchip *chip; -+ struct ls7a_ioapic_state *state; -+ int ret, i, length; -+ -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { -+ return 0; -+ } -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct ls7a_ioapic_state); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; -+ chip->len = length; -+ -+ state = (struct ls7a_ioapic_state *)chip->data; -+ state->int_id = s->int_id; -+ state->int_mask = s->int_mask; -+ state->htmsi_en = s->htmsi_en; -+ state->intedge = s->intedge; -+ state->intclr = s->intclr; -+ state->auto_crtl0 = s->auto_crtl0; -+ state->auto_crtl1 = s->auto_crtl1; -+ for (i = 0; i < 64; i++) { -+ state->route_entry[i] = s->route_entry[i]; -+ state->htmsi_vector[i] = s->htmsi_vector[i]; -+ } -+ state->intisr_chip0 = s->intisr_chip0; -+ state->intisr_chip1 = s->intisr_chip1; -+ state->last_intirr = 0; -+ state->intirr = s->intirr; -+ state->intisr = s->intisr; -+ state->int_polarity = s->int_polarity; -+ -+ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ g_free(chip); -+#endif -+ return 0; -+} -+ -+static void ls7a_apic_reset(DeviceState *d) -+{ -+ LS7AApicState *s = LS7A_APIC(d); -+ int i; -+ -+ s->int_id = 0x001f000107000000; -+ s->int_mask = 0xffffffffffffffff; -+ s->htmsi_en = 0x0; -+ s->intedge = 0x0; -+ s->intclr = 0x0; -+ s->auto_crtl0 = 0x0; -+ s->auto_crtl1 = 0x0; -+ for (i = 0; i < 64; i++) { -+ s->route_entry[i] = 0x1; -+ s->htmsi_vector[i] = 0x0; -+ } -+ s->intisr_chip0 = 0x0; -+ s->intisr_chip1 = 0x0; -+ s->intirr = 0x0; -+ s->intisr = 0x0; -+ s->int_polarity = 0x0; -+ kvm_ls7a_post_load(s, 0); -+} -+ -+static void ls7a_apic_init(Object *obj) -+{ -+ DeviceState *dev = DEVICE(obj); -+ LS7AApicState *s = LS7A_APIC(obj); -+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj); -+ int tmp; -+ memory_region_init_io(&s->iomem, obj, &ls7a_apic_ops, s, TYPE_LS7A_APIC, -+ 0x1000); -+ sysbus_init_mmio(sbd, &s->iomem); -+ for (tmp = 0; tmp < 257; tmp++) { -+ sysbus_init_irq(sbd, &s->parent_irq[tmp]); -+ } -+ qdev_init_gpio_in(dev, irq_handler, 64); -+} -+ -+static const VMStateDescription vmstate_ls7a_apic = { -+ .name = TYPE_LS7A_APIC, -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = kvm_ls7a_pre_save, -+ .post_load = kvm_ls7a_post_load, -+ .fields = -+ (VMStateField[]){ VMSTATE_UINT64(int_mask, LS7AApicState), -+ VMSTATE_UINT64(htmsi_en, LS7AApicState), -+ VMSTATE_UINT64(intedge, LS7AApicState), -+ VMSTATE_UINT64(intclr, LS7AApicState), -+ VMSTATE_UINT64(auto_crtl0, LS7AApicState), -+ VMSTATE_UINT64(auto_crtl1, LS7AApicState), -+ VMSTATE_UINT8_ARRAY(route_entry, LS7AApicState, 64), -+ VMSTATE_UINT8_ARRAY(htmsi_vector, LS7AApicState, 64), -+ VMSTATE_UINT64(intisr_chip0, LS7AApicState), -+ VMSTATE_UINT64(intisr_chip1, LS7AApicState), -+ VMSTATE_UINT64(last_intirr, LS7AApicState), -+ VMSTATE_UINT64(intirr, LS7AApicState), -+ VMSTATE_UINT64(intisr, LS7AApicState), -+ VMSTATE_UINT64(int_polarity, LS7AApicState), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static void ls7a_apic_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ -+ dc->reset = ls7a_apic_reset; -+ dc->vmsd = &vmstate_ls7a_apic; -+} -+ -+static const TypeInfo ls7a_apic_info = { -+ .name = TYPE_LS7A_APIC, -+ .parent = TYPE_SYS_BUS_DEVICE, -+ .instance_size = sizeof(LS7AApicState), -+ .instance_init = ls7a_apic_init, -+ .class_init = ls7a_apic_class_init, -+}; -+ -+static void ls7a_apic_register_types(void) -+{ -+ type_register_static(&ls7a_apic_info); -+} -+ -+type_init(ls7a_apic_register_types) -diff --git a/hw/loongarch/iocsr.c b/hw/loongarch/iocsr.c -new file mode 100644 -index 0000000000..a1eb54bdd2 ---- /dev/null -+++ b/hw/loongarch/iocsr.c -@@ -0,0 +1,227 @@ -+/* -+ * LOONGARCH IOCSR support -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "hw/sysbus.h" -+#include "qemu/log.h" -+#include "sysemu/kvm.h" -+#include "linux/kvm.h" -+#include "migration/vmstate.h" -+#include "hw/boards.h" -+#include "hw/loongarch/larch.h" -+ -+#define BIT_ULL(nr) (1ULL << (nr)) -+#define LOONGARCH_IOCSR_FEATURES 0x8 -+#define IOCSRF_TEMP BIT_ULL(0) -+#define IOCSRF_NODECNT BIT_ULL(1) -+#define IOCSRF_MSI BIT_ULL(2) -+#define IOCSRF_EXTIOI BIT_ULL(3) -+#define IOCSRF_CSRIPI BIT_ULL(4) -+#define IOCSRF_FREQCSR BIT_ULL(5) -+#define IOCSRF_FREQSCALE BIT_ULL(6) -+#define IOCSRF_DVFSV1 BIT_ULL(7) -+#define IOCSRF_GMOD BIT_ULL(9) -+#define IOCSRF_VM BIT_ULL(11) -+#define LOONGARCH_IOCSR_VENDOR 0x10 -+#define LOONGARCH_IOCSR_CPUNAME 0x20 -+#define LOONGARCH_IOCSR_NODECNT 0x408 -+#define LOONGARCH_IOCSR_MISC_FUNC 0x420 -+#define IOCSR_MISC_FUNC_TIMER_RESET BIT_ULL(21) -+#define IOCSR_MISC_FUNC_EXT_IOI_EN BIT_ULL(48) -+ -+enum { -+ IOCSR_FEATURES, -+ IOCSR_VENDOR, -+ IOCSR_CPUNAME, -+ IOCSR_NODECNT, -+ IOCSR_MISC_FUNC, -+ IOCSR_MAX -+}; -+ -+#ifdef CONFIG_KVM -+static uint32_t iocsr_array[IOCSR_MAX] = { -+ [IOCSR_FEATURES] = LOONGARCH_IOCSR_FEATURES, -+ [IOCSR_VENDOR] = LOONGARCH_IOCSR_VENDOR, -+ [IOCSR_CPUNAME] = LOONGARCH_IOCSR_CPUNAME, -+ [IOCSR_NODECNT] = LOONGARCH_IOCSR_NODECNT, -+ [IOCSR_MISC_FUNC] = LOONGARCH_IOCSR_MISC_FUNC, -+}; -+#endif -+ -+#define TYPE_IOCSR "iocsr" -+#define IOCSR(obj) OBJECT_CHECK(IOCSRState, (obj), TYPE_IOCSR) -+ -+typedef struct IOCSRState { -+ SysBusDevice parent_obj; -+ uint64_t iocsr_val[IOCSR_MAX]; -+} IOCSRState; -+ -+IOCSRState iocsr_init = { .iocsr_val = { -+ IOCSRF_NODECNT | IOCSRF_MSI | IOCSRF_EXTIOI | -+ IOCSRF_CSRIPI | IOCSRF_GMOD | IOCSRF_VM, -+ 0x6e6f73676e6f6f4c, /* Loongson */ -+ 0x303030354133, /*3A5000*/ -+ 0x4, -+ 0x0, -+ } }; -+ -+static int kvm_iocsr_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ IOCSRState *s = opaque; -+ struct kvm_iocsr_entry entry; -+ int i = 0; -+ -+ if ((!kvm_enabled())) { -+ return 0; -+ } -+ -+ for (i = 0; i < IOCSR_MAX; i++) { -+ entry.addr = iocsr_array[i]; -+ kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_GET_IOCSR, &entry); -+ s->iocsr_val[i] = entry.data; -+ } -+#endif -+ return 0; -+} -+ -+static int kvm_iocsr_post_load(void *opaque, int version) -+{ -+#ifdef CONFIG_KVM -+ IOCSRState *s = opaque; -+ struct kvm_iocsr_entry entry; -+ int i = 0; -+ -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ -+ for (i = 0; i < IOCSR_MAX; i++) { -+ entry.addr = iocsr_array[i]; -+ entry.data = s->iocsr_val[i]; -+ kvm_vm_ioctl(kvm_state, KVM_LOONGARCH_SET_IOCSR, &entry); -+ } -+#endif -+ return 0; -+} -+ -+static void iocsr_reset(DeviceState *d) -+{ -+ IOCSRState *s = IOCSR(d); -+ int i; -+ -+ for (i = 0; i < IOCSR_MAX; i++) { -+ s->iocsr_val[i] = iocsr_init.iocsr_val[i]; -+ } -+ kvm_iocsr_post_load(s, 0); -+} -+ -+static void init_vendor_cpuname(uint64_t *vendor, uint64_t *cpu_name, -+ char *cpuname) -+{ -+ int i = 0, len = 0; -+ char *index = NULL, *index_end = NULL; -+ char *vendor_c = (char *)vendor; -+ char *cpu_name_c = (char *)cpu_name; -+ -+ index = strstr(cpuname, "-"); -+ len = strlen(cpuname); -+ if ((index == NULL) || (len <= 0)) { -+ return; -+ } -+ -+ *vendor = 0; -+ *cpu_name = 0; -+ index_end = cpuname + len; -+ -+ while (((cpuname + i) < index) && (i < sizeof(uint64_t))) { -+ vendor_c[i] = cpuname[i]; -+ i++; -+ } -+ -+ index += 1; -+ i = 0; -+ -+ while (((index + i) < index_end) && (i < sizeof(uint64_t))) { -+ cpu_name_c[i] = index[i]; -+ i++; -+ } -+ -+ return; -+} -+ -+static void iocsr_instance_init(Object *obj) -+{ -+ IOCSRState *s = IOCSR(obj); -+ int i; -+ LoongarchMachineState *lsms; -+ LoongarchMachineClass *lsmc; -+ Object *machine = qdev_get_machine(); -+ ObjectClass *mc = object_get_class(machine); -+ -+ /* 'lams' should be initialized */ -+ if (!strcmp(MACHINE_CLASS(mc)->name, "none")) { -+ return; -+ } -+ -+ lsms = LoongarchMACHINE(machine); -+ lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ -+ init_vendor_cpuname((uint64_t *)&iocsr_init.iocsr_val[IOCSR_VENDOR], -+ (uint64_t *)&iocsr_init.iocsr_val[IOCSR_CPUNAME], -+ lsmc->cpu_name); -+ -+ for (i = 0; i < IOCSR_MAX; i++) { -+ s->iocsr_val[i] = iocsr_init.iocsr_val[i]; -+ } -+} -+ -+static const VMStateDescription vmstate_iocsr = { -+ .name = TYPE_IOCSR, -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .pre_save = kvm_iocsr_pre_save, -+ .post_load = kvm_iocsr_post_load, -+ .fields = (VMStateField[]){ VMSTATE_UINT64_ARRAY(iocsr_val, IOCSRState, -+ IOCSR_MAX), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static void iocsr_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ -+ dc->reset = iocsr_reset; -+ dc->vmsd = &vmstate_iocsr; -+} -+ -+static const TypeInfo iocsr_info = { -+ .name = TYPE_IOCSR, -+ .parent = TYPE_SYS_BUS_DEVICE, -+ .instance_size = sizeof(IOCSRState), -+ .instance_init = iocsr_instance_init, -+ .class_init = iocsr_class_init, -+}; -+ -+static void iocsr_register_types(void) -+{ -+ type_register_static(&iocsr_info); -+} -+ -+type_init(iocsr_register_types) -diff --git a/hw/loongarch/ipi.c b/hw/loongarch/ipi.c -new file mode 100644 -index 0000000000..affa97392e ---- /dev/null -+++ b/hw/loongarch/ipi.c -@@ -0,0 +1,284 @@ -+/* -+ * LOONGARCH IPI support -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/units.h" -+#include "qapi/error.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/loongarch/cpudevs.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/cpus.h" -+#include "sysemu/kvm.h" -+#include "hw/core/cpu.h" -+#include "qemu/log.h" -+#include "hw/loongarch/bios.h" -+#include "elf.h" -+#include "linux/kvm.h" -+#include "hw/loongarch/larch.h" -+#include "hw/loongarch/ls7a.h" -+#include "migration/vmstate.h" -+ -+static int gipi_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ gipiState *state = opaque; -+ struct loongarch_gipiState *kstate; -+ struct loongarch_kvm_irqchip *chip; -+ int ret, i, j, length; -+#endif -+ -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { -+ return 0; -+ } -+ -+#ifdef CONFIG_KVM -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct loongarch_gipiState); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; -+ chip->len = length; -+ ret = kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ -+ kstate = (struct loongarch_gipiState *)chip->data; -+ -+ for (i = 0; i < MAX_GIPI_CORE_NUM; i++) { -+ state->core[i].status = kstate->core[i].status; -+ state->core[i].en = kstate->core[i].en; -+ state->core[i].set = kstate->core[i].set; -+ state->core[i].clear = kstate->core[i].clear; -+ for (j = 0; j < MAX_GIPI_MBX_NUM; j++) { -+ state->core[i].buf[j] = kstate->core[i].buf[j]; -+ } -+ } -+ g_free(chip); -+#endif -+ -+ return 0; -+} -+ -+static int gipi_post_load(void *opaque, int version) -+{ -+#ifdef CONFIG_KVM -+ gipiState *state = opaque; -+ struct loongarch_gipiState *kstate; -+ struct loongarch_kvm_irqchip *chip; -+ int ret, i, j, length; -+#endif -+ -+ if ((!kvm_enabled()) || (!kvm_irqchip_in_kernel())) { -+ return 0; -+ } -+ -+#ifdef CONFIG_KVM -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct loongarch_gipiState); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; -+ chip->len = length; -+ kstate = (struct loongarch_gipiState *)chip->data; -+ -+ for (i = 0; i < MAX_GIPI_CORE_NUM; i++) { -+ kstate->core[i].status = state->core[i].status; -+ kstate->core[i].en = state->core[i].en; -+ kstate->core[i].set = state->core[i].set; -+ kstate->core[i].clear = state->core[i].clear; -+ for (j = 0; j < MAX_GIPI_MBX_NUM; j++) { -+ kstate->core[i].buf[j] = state->core[i].buf[j]; -+ } -+ } -+ -+ ret = kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ if (ret < 0) { -+ fprintf(stderr, "KVM_GET_IRQCHIP failed: %s\n", strerror(ret)); -+ abort(); -+ } -+ g_free(chip); -+#endif -+ return 0; -+} -+ -+static const VMStateDescription vmstate_gipi_core = { -+ .name = "gipi-single", -+ .version_id = 0, -+ .minimum_version_id = 0, -+ .fields = -+ (VMStateField[]){ -+ VMSTATE_UINT32(status, gipi_core), VMSTATE_UINT32(en, gipi_core), -+ VMSTATE_UINT32(set, gipi_core), VMSTATE_UINT32(clear, gipi_core), -+ VMSTATE_UINT64_ARRAY(buf, gipi_core, MAX_GIPI_MBX_NUM), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static const VMStateDescription vmstate_gipi = { -+ .name = "gipi", -+ .pre_save = gipi_pre_save, -+ .post_load = gipi_post_load, -+ .version_id = 0, -+ .minimum_version_id = 0, -+ .fields = (VMStateField[]){ VMSTATE_STRUCT_ARRAY( -+ core, gipiState, MAX_GIPI_CORE_NUM, 0, -+ vmstate_gipi_core, gipi_core), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static void gipi_writel(void *opaque, hwaddr addr, uint64_t val, unsigned size) -+{ -+ gipi_core *s = opaque; -+ gipi_core *ss; -+ void *pbuf; -+ uint32_t cpu, action_data, mailaddr; -+ LoongarchMachineState *ms = LoongarchMACHINE(qdev_get_machine()); -+ -+ if ((size != 4) && (size != 8)) { -+ hw_error("size not 4 and not 8"); -+ } -+ addr &= 0xff; -+ switch (addr) { -+ case CORE0_STATUS_OFF: -+ hw_error("CORE0_STATUS_OFF Can't be write\n"); -+ break; -+ case CORE0_EN_OFF: -+ s->en = val; -+ break; -+ case CORE0_IPI_SEND: -+ cpu = (val >> 16) & 0x3ff; -+ action_data = 1UL << (val & 0x1f); -+ ss = &ms->gipi->core[cpu]; -+ ss->status |= action_data; -+ if (ss->status != 0) { -+ qemu_irq_raise(ss->irq); -+ } -+ break; -+ case CORE0_MAIL_SEND: -+ cpu = (val >> 16) & 0x3ff; -+ mailaddr = (val >> 2) & 0x7; -+ ss = &ms->gipi->core[cpu]; -+ pbuf = (void *)ss->buf + mailaddr * 4; -+ *(unsigned int *)pbuf = (val >> 32); -+ break; -+ case CORE0_SET_OFF: -+ hw_error("CORE0_SET_OFF Can't be write\n"); -+ break; -+ case CORE0_CLEAR_OFF: -+ s->status ^= val; -+ if (s->status == 0) { -+ qemu_irq_lower(s->irq); -+ } -+ break; -+ case 0x20 ... 0x3c: -+ pbuf = (void *)s->buf + (addr - 0x20); -+ if (size == 1) { -+ *(unsigned char *)pbuf = (unsigned char)val; -+ } else if (size == 2) { -+ *(unsigned short *)pbuf = (unsigned short)val; -+ } else if (size == 4) { -+ *(unsigned int *)pbuf = (unsigned int)val; -+ } else if (size == 8) { -+ *(unsigned long *)pbuf = (unsigned long)val; -+ } -+ break; -+ default: -+ break; -+ } -+} -+ -+static uint64_t gipi_readl(void *opaque, hwaddr addr, unsigned size) -+{ -+ gipi_core *s = opaque; -+ uint64_t ret = 0; -+ void *pbuf; -+ -+ addr &= 0xff; -+ if ((size != 4) && (size != 8)) { -+ hw_error("size not 4 and not 8 size:%d\n", size); -+ } -+ switch (addr) { -+ case CORE0_STATUS_OFF: -+ ret = s->status; -+ break; -+ case CORE0_EN_OFF: -+ ret = s->en; -+ break; -+ case CORE0_SET_OFF: -+ ret = 0; -+ break; -+ case CORE0_CLEAR_OFF: -+ ret = 0; -+ break; -+ case 0x20 ... 0x3c: -+ pbuf = (void *)s->buf + (addr - 0x20); -+ if (size == 1) { -+ ret = *(unsigned char *)pbuf; -+ } else if (size == 2) { -+ ret = *(unsigned short *)pbuf; -+ } else if (size == 4) { -+ ret = *(unsigned int *)pbuf; -+ } else if (size == 8) { -+ ret = *(unsigned long *)pbuf; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+static const MemoryRegionOps gipi_ops = { -+ .read = gipi_readl, -+ .write = gipi_writel, -+ .valid = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+int cpu_init_ipi(LoongarchMachineState *ms, qemu_irq parent, int cpu) -+{ -+ hwaddr addr; -+ MemoryRegion *region; -+ char str[32]; -+ -+ if (ms->gipi == NULL) { -+ ms->gipi = g_malloc0(sizeof(gipiState)); -+ vmstate_register(NULL, 0, &vmstate_gipi, ms->gipi); -+ } -+ -+ ms->gipi->core[cpu].irq = parent; -+ -+ addr = SMP_GIPI_MAILBOX | (cpu << 8); -+ region = g_new(MemoryRegion, 1); -+ sprintf(str, "gipi%d", cpu); -+ memory_region_init_io(region, NULL, &gipi_ops, &ms->gipi->core[cpu], str, -+ 0x100); -+ memory_region_add_subregion(get_system_memory(), addr, region); -+ return 0; -+} -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -new file mode 100644 -index 0000000000..fe786008ac ---- /dev/null -+++ b/hw/loongarch/larch_3a.c -@@ -0,0 +1,2063 @@ -+/* -+ * QEMU loongarch 3a develop board emulation -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/units.h" -+#include "qapi/error.h" -+#include "qemu/datadir.h" -+#include "hw/hw.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/i386/pc.h" -+#include "hw/char/serial.h" -+#include "hw/isa/isa.h" -+#include "hw/qdev-core.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/runstate.h" -+#include "sysemu/reset.h" -+#include "migration/vmstate.h" -+#include "sysemu/cpus.h" -+#include "hw/boards.h" -+#include "qemu/log.h" -+#include "hw/loongarch/bios.h" -+#include "hw/loader.h" -+#include "elf.h" -+#include "exec/address-spaces.h" -+#include "hw/ide.h" -+#include "hw/pci/pci_host.h" -+#include "hw/pci/msi.h" -+#include "linux/kvm.h" -+#include "sysemu/kvm.h" -+#include "sysemu/numa.h" -+#include "hw/rtc/mc146818rtc.h" -+#include "hw/irq.h" -+#include "net/net.h" -+#include "hw/platform-bus.h" -+#include "hw/timer/i8254.h" -+#include "hw/loongarch/larch.h" -+#include "hw/loongarch/ls7a.h" -+#include "hw/nvram/fw_cfg.h" -+#include "hw/firmware/smbios.h" -+#include "acpi-build.h" -+#include -+#include -+#include "sysemu/block-backend.h" -+#include "hw/block/flash.h" -+#include "sysemu/device_tree.h" -+#include "qapi/visitor.h" -+#include "qapi/qapi-visit-common.h" -+#include "sysemu/tpm.h" -+#include "hw/loongarch/sysbus-fdt.h" -+ -+#include -+ -+#define DMA64_SUPPORTED 0x2 -+#define MAX_IDE_BUS 2 -+ -+#define BOOTPARAM_PHYADDR 0x0ff00000ULL -+#define BOOTPARAM_ADDR (0x9000000000000000ULL + BOOTPARAM_PHYADDR) -+#define SMBIOS_PHYSICAL_ADDRESS 0x0fe00000 -+#define SMBIOS_SIZE_LIMIT 0x200000 -+#define RESERVED_SIZE_LIMIT 0x1100000 -+#define COMMAND_LINE_SIZE 4096 -+#define FW_CONF_ADDR 0x0fff0000 -+ -+#define PHYS_TO_VIRT(x) ((x) | 0x9000000000000000ULL) -+ -+#define TARGET_REALPAGE_MASK (TARGET_PAGE_MASK << 2) -+ -+#ifdef CONFIG_KVM -+#define LS_ISA_IO_SIZE 0x02000000 -+#else -+#define LS_ISA_IO_SIZE 0x00010000 -+#endif -+ -+#ifdef CONFIG_KVM -+#define align(x) (((x) + 63) & ~63) -+#else -+#define align(x) (((x) + 15) & ~15) -+#endif -+ -+#define DEBUG_LOONGARCH3A 0 -+#define FLASH_SECTOR_SIZE 4096 -+ -+#define DPRINTF(fmt, ...) \ -+ do { \ -+ if (DEBUG_LOONGARCH3A) { \ -+ fprintf(stderr, fmt, ##__VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+#define DEFINE_LS3A5K_MACHINE(suffix, name, optionfn) \ -+ static void ls3a5k_init_##suffix(MachineState *machine) \ -+ { \ -+ ls3a5k_init(machine); \ -+ } \ -+ DEFINE_LOONGARCH_MACHINE(suffix, name, ls3a5k_init_##suffix, optionfn) -+ -+struct efi_memory_map_loongarch { -+ uint16_t vers; /* version of efi_memory_map */ -+ uint32_t nr_map; /* number of memory_maps */ -+ uint32_t mem_freq; /* memory frequence */ -+ struct mem_map { -+ uint32_t node_id; /* node_id which memory attached to */ -+ uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ -+ uint64_t mem_start; /* memory map start address */ -+ uint32_t mem_size; /* each memory_map size, not the total size */ -+ } map[128]; -+} __attribute__((packed)); -+ -+enum loongarch_cpu_type { Loongson3 = 0x1, Loongson3_comp = 0x2 }; -+ -+struct GlobalProperty loongarch_compat[] = { -+ { -+ .driver = "rtl8139", -+ .property = "romfile", -+ .value = "", -+ }, -+ { -+ .driver = "e1000", -+ .property = "romfile", -+ .value = "", -+ }, -+ { -+ .driver = "virtio-net-pci", -+ .property = "romfile", -+ .value = "", -+ }, -+ { -+ .driver = "qxl-vga", -+ .property = "romfile", -+ .value = "", -+ }, -+ { -+ .driver = "VGA", -+ .property = "romfile", -+ .value = "", -+ }, -+ { -+ .driver = "cirrus-vga", -+ .property = "romfile", -+ .value = "", -+ }, -+ { -+ .driver = "virtio-vga", -+ .property = "romfile", -+ .value = "", -+ }, -+ { -+ .driver = "vmware-svga", -+ .property = "romfile", -+ .value = "", -+ }, -+}; -+const size_t loongarch_compat_len = G_N_ELEMENTS(loongarch_compat); -+ -+/* -+ * Capability and feature descriptor structure for LOONGARCH CPU -+ */ -+struct efi_cpuinfo_loongarch { -+ uint16_t vers; /* version of efi_cpuinfo_loongarch */ -+ uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ -+ enum loongarch_cpu_type cputype; /* 3A, 3B, etc. */ -+ uint32_t total_node; /* num of total numa nodes */ -+ uint16_t cpu_startup_core_id; /* Core id */ -+ uint16_t reserved_cores_mask; -+ uint32_t cpu_clock_freq; /* cpu_clock */ -+ uint32_t nr_cpus; -+} __attribute__((packed)); -+ -+#define MAX_UARTS 64 -+struct uart_device { -+ uint32_t iotype; /* see include/linux/serial_core.h */ -+ uint32_t uartclk; -+ uint32_t int_offset; -+ uint64_t uart_base; -+} __attribute__((packed)); -+ -+#define MAX_SENSORS 64 -+#define SENSOR_TEMPER 0x00000001 -+#define SENSOR_VOLTAGE 0x00000002 -+#define SENSOR_FAN 0x00000004 -+struct sensor_device { -+ char name[32]; /* a formal name */ -+ char label[64]; /* a flexible description */ -+ uint32_t type; /* SENSOR_* */ -+ uint32_t id; /* instance id of a sensor-class */ -+ /* -+ * see arch/loongarch/include/ -+ * asm/mach-loongarch/loongarch_hwmon.h -+ */ -+ uint32_t fan_policy; -+ uint32_t fan_percent; /* only for constant speed policy */ -+ uint64_t base_addr; /* base address of device registers */ -+} __attribute__((packed)); -+ -+struct system_loongarch { -+ uint16_t vers; /* version of system_loongarch */ -+ uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ -+ uint32_t sing_double_channel; /* 1:single; 2:double */ -+ uint32_t nr_uarts; -+ struct uart_device uarts[MAX_UARTS]; -+ uint32_t nr_sensors; -+ struct sensor_device sensors[MAX_SENSORS]; -+ char has_ec; -+ char ec_name[32]; -+ uint64_t ec_base_addr; -+ char has_tcm; -+ char tcm_name[32]; -+ uint64_t tcm_base_addr; -+ uint64_t workarounds; /* see workarounds.h */ -+} __attribute__((packed)); -+ -+struct irq_source_routing_table { -+ uint16_t vers; -+ uint16_t size; -+ uint16_t rtr_bus; -+ uint16_t rtr_devfn; -+ uint32_t vendor; -+ uint32_t device; -+ uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ -+ uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ -+ uint64_t ht_enable; /* irqs used in this PIC */ -+ uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ -+ uint64_t pci_mem_start_addr; -+ uint64_t pci_mem_end_addr; -+ uint64_t pci_io_start_addr; -+ uint64_t pci_io_end_addr; -+ uint64_t pci_config_addr; -+ uint32_t dma_mask_bits; -+ uint16_t dma_noncoherent; -+} __attribute__((packed)); -+ -+struct interface_info { -+ uint16_t vers; /* version of the specificition */ -+ uint16_t size; -+ uint8_t flag; -+ char description[64]; -+} __attribute__((packed)); -+ -+#define MAX_RESOURCE_NUMBER 128 -+struct resource_loongarch { -+ uint64_t start; /* resource start address */ -+ uint64_t end; /* resource end address */ -+ char name[64]; -+ uint32_t flags; -+}; -+ -+struct archdev_data { -+}; /* arch specific additions */ -+ -+struct board_devices { -+ char name[64]; /* hold the device name */ -+ uint32_t num_resources; /* number of device_resource */ -+ /* for each device's resource */ -+ struct resource_loongarch resource[MAX_RESOURCE_NUMBER]; -+ /* arch specific additions */ -+ struct archdev_data archdata; -+}; -+ -+struct loongarch_special_attribute { -+ uint16_t vers; /* version of this special */ -+ char special_name[64]; /* special_atribute_name */ -+ uint32_t loongarch_special_type; /* type of special device */ -+ /* for each device's resource */ -+ struct resource_loongarch resource[MAX_RESOURCE_NUMBER]; -+}; -+ -+struct loongarch_params { -+ uint64_t memory_offset; /* efi_memory_map_loongarch struct offset */ -+ uint64_t cpu_offset; /* efi_cpuinfo_loongarch struct offset */ -+ uint64_t system_offset; /* system_loongarch struct offset */ -+ uint64_t irq_offset; /* irq_source_routing_table struct offset */ -+ uint64_t interface_offset; /* interface_info struct offset */ -+ uint64_t special_offset; /* loongarch_special_attribute struct offset */ -+ uint64_t boarddev_table_offset; /* board_devices offset */ -+}; -+ -+struct smbios_tables { -+ uint16_t vers; /* version of smbios */ -+ uint64_t vga_bios; /* vga_bios address */ -+ struct loongarch_params lp; -+}; -+ -+struct efi_reset_system_t { -+ uint64_t ResetCold; -+ uint64_t ResetWarm; -+ uint64_t ResetType; -+ uint64_t Shutdown; -+ uint64_t DoSuspend; /* NULL if not support */ -+}; -+ -+struct efi_loongarch { -+ uint64_t mps; /* MPS table */ -+ uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ -+ uint64_t acpi20; /* ACPI table (ACPI 2.0) */ -+ struct smbios_tables smbios; /* SM BIOS table */ -+ uint64_t sal_systab; /* SAL system table */ -+ uint64_t boot_info; /* boot info table */ -+}; -+ -+struct boot_params { -+ struct efi_loongarch efi; -+ struct efi_reset_system_t reset_system; -+}; -+ -+static struct _loaderparams { -+ unsigned long ram_size; -+ const char *kernel_filename; -+ const char *kernel_cmdline; -+ const char *initrd_filename; -+ unsigned long a0, a1, a2; -+} loaderparams; -+ -+static struct _firmware_config { -+ unsigned long ram_size; -+ unsigned int mem_freq; -+ unsigned int cpu_nr; -+ unsigned int cpu_clock_freq; -+} fw_config; -+ -+struct la_memmap_entry { -+ uint64_t address; -+ uint64_t length; -+ uint32_t type; -+ uint32_t reserved; -+}; -+ -+static void *boot_params_buf; -+static void *boot_params_p; -+static struct la_memmap_entry *la_memmap_table; -+static unsigned la_memmap_entries; -+ -+CPULOONGARCHState *cpu_states[LOONGARCH_MAX_VCPUS]; -+ -+struct kvm_cpucfg ls3a5k_cpucfgs = { -+ .cpucfg[LOONGARCH_CPUCFG0] = CPUCFG0_3A5000_PRID, -+ .cpucfg[LOONGARCH_CPUCFG1] = -+ CPUCFG1_ISGR64 | CPUCFG1_PAGING | CPUCFG1_IOCSR | CPUCFG1_PABITS | -+ CPUCFG1_VABITS | CPUCFG1_UAL | CPUCFG1_RI | CPUCFG1_XI | CPUCFG1_RPLV | -+ CPUCFG1_HUGEPG | CPUCFG1_IOCSRBRD, -+ .cpucfg[LOONGARCH_CPUCFG2] = -+ CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | CPUCFG2_FPVERS | -+ CPUCFG2_LSX | CPUCFG2_LASX | CPUCFG2_COMPLEX | CPUCFG2_CRYPTO | -+ CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | CPUCFG2_LSPW | CPUCFG2_LAM, -+ .cpucfg[LOONGARCH_CPUCFG3] = -+ CPUCFG3_CCDMA | CPUCFG3_SFB | CPUCFG3_UCACC | CPUCFG3_LLEXC | -+ CPUCFG3_SCDLY | CPUCFG3_LLDBAR | CPUCFG3_ITLBT | CPUCFG3_ICACHET | -+ CPUCFG3_SPW_LVL | CPUCFG3_SPW_HG_HF | CPUCFG3_RVA | CPUCFG3_RVAMAX, -+ .cpucfg[LOONGARCH_CPUCFG4] = CCFREQ_100M, -+ .cpucfg[LOONGARCH_CPUCFG5] = CPUCFG5_CCMUL | CPUCFG5_CCDIV, -+ .cpucfg[LOONGARCH_CPUCFG6] = CPUCFG6_PMP | CPUCFG6_PAMVER | CPUCFG6_PMNUM | -+ CPUCFG6_PMBITS | CPUCFG6_UPM, -+ .cpucfg[LOONGARCH_CPUCFG16] = CPUCFG16_L1_IUPRE | CPUCFG16_L1_DPRE | -+ CPUCFG16_L2_IUPRE | CPUCFG16_L2_IUUNIFY | -+ CPUCFG16_L2_IUPRIV | CPUCFG16_L3_IUPRE | -+ CPUCFG16_L3_IUUNIFY | CPUCFG16_L3_IUINCL, -+ .cpucfg[LOONGARCH_CPUCFG17] = -+ CPUCFG17_L1I_WAYS_M | CPUCFG17_L1I_SETS_M | CPUCFG17_L1I_SIZE_M, -+ .cpucfg[LOONGARCH_CPUCFG18] = -+ CPUCFG18_L1D_WAYS_M | CPUCFG18_L1D_SETS_M | CPUCFG18_L1D_SIZE_M, -+ .cpucfg[LOONGARCH_CPUCFG19] = -+ CPUCFG19_L2_WAYS_M | CPUCFG19_L2_SETS_M | CPUCFG19_L2_SIZE_M, -+ .cpucfg[LOONGARCH_CPUCFG20] = -+ CPUCFG20_L3_WAYS_M | CPUCFG20_L3_SETS_M | CPUCFG20_L3_SIZE_M, -+}; -+ -+bool loongarch_is_acpi_enabled(LoongarchMachineState *vms) -+{ -+ if (vms->acpi == ON_OFF_AUTO_OFF) { -+ return false; -+ } -+ return true; -+} -+ -+static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(obj); -+ OnOffAuto acpi = lsms->acpi; -+ -+ visit_type_OnOffAuto(v, name, &acpi, errp); -+} -+ -+static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(obj); -+ -+ visit_type_OnOffAuto(v, name, &lsms->acpi, errp); -+} -+ -+int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) -+{ -+ int i; -+ -+ for (i = 0; i < la_memmap_entries; i++) { -+ if (la_memmap_table[i].address == address) { -+ fprintf(stderr, "%s address:0x%lx length:0x%lx already exists\n", -+ __func__, address, length); -+ return 0; -+ } -+ } -+ -+ la_memmap_table = g_renew(struct la_memmap_entry, la_memmap_table, -+ la_memmap_entries + 1); -+ la_memmap_table[la_memmap_entries].address = cpu_to_le64(address); -+ la_memmap_table[la_memmap_entries].length = cpu_to_le64(length); -+ la_memmap_table[la_memmap_entries].type = cpu_to_le32(type); -+ la_memmap_entries++; -+ -+ return la_memmap_entries; -+} -+ -+static ram_addr_t get_hotplug_membase(ram_addr_t ram_size) -+{ -+ ram_addr_t sstart; -+ -+ if (ram_size <= 0x10000000) { -+ sstart = 0x90000000; -+ } else { -+ sstart = 0x90000000 + ROUND_UP((ram_size - 0x10000000), -+ LOONGARCH_HOTPLUG_MEM_ALIGN); -+ } -+ return sstart; -+} -+ -+static struct efi_memory_map_loongarch *init_memory_map(void *g_map) -+{ -+ struct efi_memory_map_loongarch *emap = g_map; -+ -+ emap->nr_map = 4; -+ emap->mem_freq = 266000000; -+ -+ emap->map[0].node_id = 0; -+ emap->map[0].mem_type = 1; -+ emap->map[0].mem_start = 0x0; -+#ifdef CONFIG_KVM -+ emap->map[0].mem_size = -+ (loaderparams.ram_size > 0x10000000 ? 256 -+ : (loaderparams.ram_size >> 20)) - -+ 18; -+#else -+ emap->map[0].mem_size = atoi(getenv("memsize")); -+#endif -+ -+ emap->map[1].node_id = 0; -+ emap->map[1].mem_type = 2; -+ emap->map[1].mem_start = 0x90000000; -+#ifdef CONFIG_KVM -+ emap->map[1].mem_size = (loaderparams.ram_size > 0x10000000 -+ ? (loaderparams.ram_size >> 20) - 256 -+ : 0); -+#else -+ emap->map[1].mem_size = atoi(getenv("highmemsize")); -+#endif -+ -+ /* support for smbios */ -+ emap->map[2].node_id = 0; -+ emap->map[2].mem_type = 10; -+ emap->map[2].mem_start = SMBIOS_PHYSICAL_ADDRESS; -+ emap->map[2].mem_size = SMBIOS_SIZE_LIMIT >> 20; -+ -+ emap->map[3].node_id = 0; -+ emap->map[3].mem_type = 3; -+ emap->map[3].mem_start = 0xee00000; -+ emap->map[3].mem_size = RESERVED_SIZE_LIMIT >> 20; -+ -+ return emap; -+} -+ -+static uint64_t get_host_cpu_freq(void) -+{ -+ int fd = 0; -+ char buf[1024]; -+ uint64_t freq = 0, size = 0; -+ char *buf_p; -+ -+ fd = open("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", -+ O_RDONLY); -+ if (fd == -1) { -+ fprintf(stderr, "/sys/devices/system/cpu/cpu0/cpufreq/ \ -+ cpuinfo_max_freq not exist!\n"); -+ fprintf(stderr, "Trying /proc/cpuinfo...\n"); -+ } else { -+ size = read(fd, buf, 16); -+ if (size == -1) { -+ fprintf(stderr, "read err...\n"); -+ } -+ close(fd); -+ freq = (uint64_t)atoi(buf); -+ return freq * 1000; -+ } -+ -+ fd = open("/proc/cpuinfo", O_RDONLY); -+ if (fd == -1) { -+ fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); -+ return 0; -+ } -+ -+ size = read(fd, buf, 1024); -+ if (size == -1) { -+ fprintf(stderr, "read err...\n"); -+ } -+ close(fd); -+ -+ buf_p = strstr(buf, "MHz"); -+ if (buf_p) { -+ while (*buf_p != ':') { -+ buf_p++; -+ } -+ buf_p += 2; -+ } else { -+ buf_p = strstr(buf, "name"); -+ while (*buf_p != '@') { -+ buf_p++; -+ } -+ buf_p += 2; -+ } -+ -+ memcpy(buf, buf_p, 12); -+ buf_p = buf; -+ while ((*buf_p >= '0') && (*buf_p <= '9')) { -+ buf_p++; -+ } -+ *buf_p = '\0'; -+ -+ freq = (uint64_t)atoi(buf); -+ return freq * 1000 * 1000; -+} -+ -+static char *get_host_cpu_model_name(void) -+{ -+ int fd = 0; -+ int size = 0; -+ static char buf[1024]; -+ char *buf_p; -+ -+ fd = open("/proc/cpuinfo", O_RDONLY); -+ if (fd == -1) { -+ fprintf(stderr, "Failed to open /proc/cpuinfo!\n"); -+ return 0; -+ } -+ -+ size = read(fd, buf, 1024); -+ if (size == -1) { -+ fprintf(stderr, "read err...\n"); -+ } -+ close(fd); -+ buf_p = strstr(buf, "Name"); -+ if (!buf_p) { -+ buf_p = strstr(buf, "name"); -+ } -+ if (!buf_p) { -+ fprintf(stderr, "Can't find cpu name\n"); -+ return 0; -+ } -+ -+ while (*buf_p != ':') { -+ buf_p++; -+ } -+ buf_p = buf_p + 2; -+ memcpy(buf, buf_p, 40); -+ buf_p = buf; -+ while (*buf_p != '\n') { -+ buf_p++; -+ } -+ -+ *(buf_p) = '\0'; -+ -+ return buf; -+} -+ -+static void fw_conf_init(unsigned long ramsize) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ int smp_cpus = ms->smp.cpus; -+ fw_config.ram_size = ramsize; -+ fw_config.mem_freq = 266000000; -+ fw_config.cpu_nr = smp_cpus; -+ fw_config.cpu_clock_freq = get_host_cpu_freq(); -+} -+ -+static struct efi_cpuinfo_loongarch *init_cpu_info(void *g_cpuinfo_loongarch) -+{ -+ struct efi_cpuinfo_loongarch *c = g_cpuinfo_loongarch; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ int smp_cpus = ms->smp.cpus; -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ -+ if (strstr(lsmc->cpu_name, "5000")) { -+ c->processor_id = 0x14c010; -+ } -+ c->cputype = Loongson3_comp; -+ c->cpu_clock_freq = get_host_cpu_freq(); -+ if (!c->cpu_clock_freq) { -+ c->cpu_clock_freq = 200000000; -+ } -+ c->total_node = 1; -+ c->nr_cpus = smp_cpus; -+ c->cpu_startup_core_id = 0; -+ c->reserved_cores_mask = 0xffff & (0xffff << smp_cpus); -+ -+ return c; -+} -+ -+static struct system_loongarch *init_system_loongarch(void *g_sysitem) -+{ -+ struct system_loongarch *s = g_sysitem; -+ -+ s->ccnuma_smp = 1; -+ s->ccnuma_smp = 0; -+ s->sing_double_channel = 1; -+ -+ return s; -+} -+ -+enum loongarch_irq_source_enum { HT, I8259, UNKNOWN }; -+ -+static struct irq_source_routing_table *init_irq_source(void *g_irq_source) -+{ -+ struct irq_source_routing_table *irq_info = g_irq_source; -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ -+ irq_info->PIC_type = HT; -+ irq_info->ht_int_bit = 1 << 24; -+ irq_info->ht_enable = 0x0000d17b; -+ irq_info->node_id = 0; -+ -+ irq_info->pci_mem_start_addr = PCIE_MEMORY_BASE; -+ irq_info->pci_mem_end_addr = -+ irq_info->pci_mem_start_addr + PCIE_MEMORY_SIZE - 1; -+ -+ if (strstr(lsmc->cpu_name, "5000")) { -+ irq_info->pci_io_start_addr = LS3A5K_ISA_IO_BASE; -+ } -+ irq_info->dma_noncoherent = 1; -+ return irq_info; -+} -+ -+static struct interface_info *init_interface_info(void *g_interface) -+{ -+ struct interface_info *inter = g_interface; -+ int flashsize = 0x80000; -+ -+ inter->vers = 0x0001; -+ inter->size = flashsize / 0x400; -+ inter->flag = 1; -+ -+ strcpy(inter->description, "PMON_Version_v2.1"); -+ -+ return inter; -+} -+ -+static struct board_devices *board_devices_info(void *g_board) -+{ -+ struct board_devices *bd = g_board; -+ LoongarchMachineState *lsms = LoongarchMACHINE(qdev_get_machine()); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ -+ if (!strcmp(lsmc->bridge_name, "ls7a")) { -+ strcpy(bd->name, "Loongarch-3A-7A-1w-V1.03-demo"); -+ } -+ bd->num_resources = 10; -+ -+ return bd; -+} -+ -+static struct loongarch_special_attribute *init_special_info(void *g_special) -+{ -+ struct loongarch_special_attribute *special = g_special; -+ char update[11] = "2013-01-01"; -+ int VRAM_SIZE = 0x20000; -+ -+ strcpy(special->special_name, update); -+ special->resource[0].flags = 0; -+ special->resource[0].start = 0; -+ special->resource[0].end = VRAM_SIZE; -+ strcpy(special->resource[0].name, "SPMODULE"); -+ special->resource[0].flags |= DMA64_SUPPORTED; -+ -+ return special; -+} -+ -+static void init_loongarch_params(struct loongarch_params *lp) -+{ -+ void *p = boot_params_p; -+ -+ lp->memory_offset = -+ (unsigned long long)init_memory_map(p) - (unsigned long long)lp; -+ p += align(sizeof(struct efi_memory_map_loongarch)); -+ -+ lp->cpu_offset = -+ (unsigned long long)init_cpu_info(p) - (unsigned long long)lp; -+ p += align(sizeof(struct efi_cpuinfo_loongarch)); -+ -+ lp->system_offset = -+ (unsigned long long)init_system_loongarch(p) - (unsigned long long)lp; -+ p += align(sizeof(struct system_loongarch)); -+ -+ lp->irq_offset = -+ (unsigned long long)init_irq_source(p) - (unsigned long long)lp; -+ p += align(sizeof(struct irq_source_routing_table)); -+ -+ lp->interface_offset = -+ (unsigned long long)init_interface_info(p) - (unsigned long long)lp; -+ p += align(sizeof(struct interface_info)); -+ -+ lp->boarddev_table_offset = -+ (unsigned long long)board_devices_info(p) - (unsigned long long)lp; -+ p += align(sizeof(struct board_devices)); -+ -+ lp->special_offset = -+ (unsigned long long)init_special_info(p) - (unsigned long long)lp; -+ p += align(sizeof(struct loongarch_special_attribute)); -+ -+ boot_params_p = p; -+} -+ -+static void init_smbios(struct smbios_tables *smbios) -+{ -+ smbios->vers = 1; -+ smbios->vga_bios = 1; -+ init_loongarch_params(&(smbios->lp)); -+} -+ -+static void init_efi(struct efi_loongarch *efi) -+{ -+ init_smbios(&(efi->smbios)); -+} -+ -+static int init_boot_param(struct boot_params *bp) -+{ -+ init_efi(&(bp->efi)); -+ -+ return 0; -+} -+ -+static unsigned int ls3a5k_aui_boot_code[] = { -+ 0x0380200d, /* ori $r13,$r0,0x8 */ -+ 0x0400002d, /* csrwr $r13,0x0 */ -+ 0x0401000e, /* csrrd $r14,0x40 */ -+ 0x0343fdce, /* andi $r14,$r14,0xff */ -+ 0x143fc02c, /* lu12i.w $r12,261889(0x1fe01) */ -+ 0x1600000c, /* lu32i.d $r12,0 */ -+ 0x0320018c, /* lu52i.d $r12,$r12,-1792(0x800) */ -+ 0x03400dcf, /* andi $r15,$r14,0x3 */ -+ 0x004121ef, /* slli.d $r15,$r15,0x8 */ -+ 0x00153d8c, /* or $r12,$r12,$r15 */ -+ 0x034031d0, /* andi $r16,$r14,0xc */ -+ 0x0041aa10, /* slli.d $r16,$r16,0x2a */ -+ 0x0015418c, /* or $r12,$r12,$r16 */ -+ 0x28808184, /* ld.w $r4,$r12,32(0x20) */ -+ 0x43fffc9f, /* beqz $r4,0 -4 */ -+ 0x28c08184, /* ld.d $r4,$r12,32(0x20) */ -+ 0x28c0a183, /* ld.d $r3,$r12,40(0x28) */ -+ 0x28c0c182, /* ld.d $r2,$r12,48(0x30) */ -+ 0x28c0e185, /* ld.d $r5,$r12,56(0x38) */ -+ 0x4c000080, /* jirl $r0,$r4,0 */ -+}; -+ -+static int set_bootparam_uefi(ram_addr_t initrd_offset, long initrd_size) -+{ -+ long params_size; -+ char memenv[32]; -+ char highmemenv[32]; -+ void *params_buf; -+ unsigned long *parg_env; -+ int ret = 0; -+ -+ /* Allocate params_buf for command line. */ -+ params_size = 0x100000; -+ params_buf = g_malloc0(params_size); -+ -+ /* -+ * Layout of params_buf looks like this: -+ * argv[0], argv[1], 0, env[0], env[1], ...env[i], 0, -+ * argv[0]'s data, argv[1]'s data, env[0]'data, ..., env[i]'s data, 0 -+ */ -+ parg_env = (void *)params_buf; -+ -+ ret = (3 + 1) * sizeof(target_ulong); -+ *parg_env++ = (BOOTPARAM_ADDR + ret); -+ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, "g")); -+ -+ /* argv1 */ -+ *parg_env++ = BOOTPARAM_ADDR + ret; -+ if (initrd_size > 0) -+ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, -+ "rd_start=0x%llx rd_size=%li %s", -+ PHYS_TO_VIRT((uint32_t)initrd_offset), -+ initrd_size, loaderparams.kernel_cmdline)); -+ else -+ ret += (1 + snprintf(params_buf + ret, COMMAND_LINE_SIZE - ret, "%s", -+ loaderparams.kernel_cmdline)); -+ -+ /* argv2 */ -+ *parg_env++ = 0; -+ -+ /* env */ -+ sprintf(memenv, "%lu", -+ loaderparams.ram_size > 0x10000000 -+ ? 256 -+ : (loaderparams.ram_size >> 20)); -+ sprintf(highmemenv, "%lu", -+ loaderparams.ram_size > 0x10000000 -+ ? (loaderparams.ram_size >> 20) - 256 -+ : 0); -+ -+ setenv("memsize", memenv, 1); -+ setenv("highmemsize", highmemenv, 1); -+ -+ ret = ((ret + 32) & ~31); -+ -+ boot_params_buf = (void *)(params_buf + ret); -+ boot_params_p = boot_params_buf + align(sizeof(struct boot_params)); -+ init_boot_param(boot_params_buf); -+ rom_add_blob_fixed("params", params_buf, params_size, BOOTPARAM_PHYADDR); -+ loaderparams.a0 = 2; -+ loaderparams.a1 = BOOTPARAM_ADDR; -+ loaderparams.a2 = BOOTPARAM_ADDR + ret; -+ -+ return 0; -+} -+ -+static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) -+{ -+ return addr & 0x1fffffffll; -+} -+ -+static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg, uint64_t highram_size, -+ uint64_t phyAddr_initrd) -+{ -+ int64_t entry, kernel_low, kernel_high; -+ long initrd_size = 0; -+ uint64_t initrd_offset = 0; -+ void *cmdline_buf; -+ int ret = 0; -+ -+ ret = load_elf(loaderparams.kernel_filename, NULL, -+ cpu_loongarch_virt_to_phys, NULL, (uint64_t *)&entry, -+ (uint64_t *)&kernel_low, (uint64_t *)&kernel_high, NULL, 0, -+ EM_LOONGARCH, 1, 0); -+ -+ if (0 > ret) { -+ error_report("kernel image load error"); -+ exit(1); -+ } -+ -+ fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ENTRY, entry); -+ -+ if (loaderparams.initrd_filename) { -+ initrd_size = get_image_size(loaderparams.initrd_filename); -+ if (0 < initrd_size) { -+ if (initrd_size > highram_size) { -+ error_report("initrd size is too big, should below %ld MB", -+ highram_size / MiB); -+ /*prevent write io memory address space*/ -+ exit(1); -+ } -+ initrd_offset = -+ (phyAddr_initrd - initrd_size) & TARGET_REALPAGE_MASK; -+ initrd_size = load_image_targphys( -+ loaderparams.initrd_filename, initrd_offset, -+ loaderparams.ram_size - initrd_offset); -+ fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_offset); -+ fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); -+ } else { -+ error_report("initrd image size is error"); -+ } -+ } -+ -+ cmdline_buf = g_malloc0(COMMAND_LINE_SIZE); -+ if (initrd_size > 0) -+ ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, -+ "rd_start=0x%llx rd_size=%li %s", -+ PHYS_TO_VIRT(initrd_offset), initrd_size, -+ loaderparams.kernel_cmdline)); -+ else -+ ret = (1 + snprintf(cmdline_buf, COMMAND_LINE_SIZE, "%s", -+ loaderparams.kernel_cmdline)); -+ -+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, ret); -+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, (const char *)cmdline_buf); -+ -+ return; -+} -+ -+static int64_t load_kernel(void) -+{ -+ int64_t entry, kernel_low, kernel_high; -+ long initrd_size = 0; -+ ram_addr_t initrd_offset = 0; -+ -+ load_elf(loaderparams.kernel_filename, NULL, cpu_loongarch_virt_to_phys, -+ NULL, (uint64_t *)&entry, (uint64_t *)&kernel_low, -+ (uint64_t *)&kernel_high, NULL, 0, EM_LOONGARCH, 1, 0); -+ -+ if (loaderparams.initrd_filename) { -+ initrd_size = get_image_size(loaderparams.initrd_filename); -+ -+ if (initrd_size > 0) { -+ initrd_offset = (kernel_high * 4 + ~TARGET_REALPAGE_MASK) & -+ TARGET_REALPAGE_MASK; -+ initrd_size = load_image_targphys( -+ loaderparams.initrd_filename, initrd_offset, -+ loaderparams.ram_size - initrd_offset); -+ } -+ } -+ set_bootparam_uefi(initrd_offset, initrd_size); -+ -+ return entry; -+} -+ -+static void main_cpu_reset(void *opaque) -+{ -+ ResetData *s = (ResetData *)opaque; -+ CPULOONGARCHState *env = &s->cpu->env; -+ -+ cpu_reset(CPU(s->cpu)); -+ env->active_tc.PC = s->vector; -+ env->active_tc.gpr[4] = loaderparams.a0; -+ env->active_tc.gpr[5] = loaderparams.a1; -+ env->active_tc.gpr[6] = loaderparams.a2; -+} -+ -+void slave_cpu_reset(void *opaque) -+{ -+ ResetData *s = (ResetData *)opaque; -+ -+ cpu_reset(CPU(s->cpu)); -+} -+ -+/* KVM_IRQ_LINE irq field index values */ -+#define KVM_LOONGARCH_IRQ_TYPE_SHIFT 24 -+#define KVM_LOONGARCH_IRQ_TYPE_MASK 0xff -+#define KVM_LOONGARCH_IRQ_VCPU_SHIFT 16 -+#define KVM_LOONGARCH_IRQ_VCPU_MASK 0xff -+#define KVM_LOONGARCH_IRQ_NUM_SHIFT 0 -+#define KVM_LOONGARCH_IRQ_NUM_MASK 0xffff -+ -+/* irq_type field */ -+#define KVM_LOONGARCH_IRQ_TYPE_CPU_IP 0 -+#define KVM_LOONGARCH_IRQ_TYPE_CPU_IO 1 -+#define KVM_LOONGARCH_IRQ_TYPE_HT 2 -+#define KVM_LOONGARCH_IRQ_TYPE_MSI 3 -+#define KVM_LOONGARCH_IRQ_TYPE_IOAPIC 4 -+ -+static void legacy_set_irq(void *opaque, int irq, int level) -+{ -+ qemu_irq *pic = opaque; -+ -+ qemu_set_irq(pic[irq], level); -+} -+ -+typedef struct ls3a_intctlstate { -+ uint8_t nodecounter_reg[0x100]; -+ uint8_t pm_reg[0x100]; -+ uint8_t msi_reg[0x8]; -+ CPULOONGARCHState **env; -+ DeviceState *apicdev; -+ qemu_irq *ioapic_irq; -+#ifdef CONFIG_KVM -+ struct loongarch_kvm_irqchip chip; -+#endif -+} ls3a_intctlstate; -+ -+typedef struct ls3a_func_args { -+ ls3a_intctlstate *state; -+ uint64_t base; -+ uint32_t mask; -+ uint8_t *mem; -+} ls3a_func_args; -+ -+static uint64_t ls3a_msi_mem_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ return 0; -+} -+ -+static void ls3a_msi_mem_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size) -+{ -+ struct kvm_msi msi; -+ apicState *apic; -+ -+ apic = (apicState *)opaque; -+ msi.address_lo = 0; -+ msi.address_hi = 0; -+ msi.data = val & 0xff; -+ msi.flags = 0; -+ memset(msi.pad, 0, sizeof(msi.pad)); -+ -+ if (kvm_irqchip_in_kernel()) { -+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi); -+ } else { -+ qemu_set_irq(apic->irq[msi.data], 1); -+ } -+} -+ -+static const MemoryRegionOps ls3a_msi_ops = { -+ .read = ls3a_msi_mem_read, -+ .write = ls3a_msi_mem_write, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+static const VMStateDescription vmstate_ls3a_msi = { -+ .name = "ls3a-msi", -+ .version_id = 0, -+ .minimum_version_id = 0, -+ .fields = -+ (VMStateField[]){ VMSTATE_UINT8_ARRAY(msi_reg, ls3a_intctlstate, 0x8), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static void ioapic_handler(void *opaque, int irq, int level) -+{ -+ apicState *apic; -+ int kvm_irq; -+ -+ apic = (apicState *)opaque; -+ -+ if (kvm_irqchip_in_kernel()) { -+ kvm_irq = -+ (KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT) | -+ (0 << KVM_LOONGARCH_IRQ_VCPU_SHIFT) | irq; -+ kvm_set_irq(kvm_state, kvm_irq, !!level); -+ } else { -+ qemu_set_irq(apic->irq[irq], level); -+ } -+} -+ -+static void *ls3a_intctl_init(MachineState *machine, CPULOONGARCHState *env[]) -+{ -+ qemu_irq *irqhandler; -+ ls3a_intctlstate *s; -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LoongarchMachineClass *mc = LoongarchMACHINE_GET_CLASS(lsms); -+ DeviceState *dev; -+ SysBusDevice *busdev; -+ MemoryRegion *address_space_mem = get_system_memory(); -+ MemoryRegion *iomem = NULL; -+#ifdef CONFIG_KVM -+ int i; -+#endif -+ -+ s = g_malloc0(sizeof(ls3a_intctlstate)); -+ -+ if (!s) { -+ return NULL; -+ } -+ -+ /*Add MSI mmio memory*/ -+ iomem = g_new(MemoryRegion, 1); -+ memory_region_init_io(iomem, NULL, &ls3a_msi_ops, lsms->apic, "ls3a_msi", -+ 0x8); -+ memory_region_add_subregion(address_space_mem, MSI_ADDR_LOW, iomem); -+ vmstate_register(NULL, 0, &vmstate_ls3a_msi, s); -+ -+ s->env = env; -+ -+ if (!strcmp(mc->bridge_name, "ls7a")) { -+ if (lsms->apic_xrupt_override) { -+ DPRINTF("irqchip in kernel %d\n", kvm_irqchip_in_kernel()); -+#ifdef CONFIG_KVM -+ if (kvm_has_gsi_routing()) { -+ for (i = 0; i < 32; ++i) { -+ kvm_irqchip_add_irq_route(kvm_state, i, 0, i); -+ } -+ kvm_gsi_routing_allowed = true; -+ } -+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); -+#endif -+ } -+ -+ irqhandler = qemu_allocate_irqs(ioapic_handler, lsms->apic, 64); -+ dev = qdev_new("ioapic"); -+ busdev = SYS_BUS_DEVICE(dev); -+ sysbus_realize_and_unref(busdev, &error_fatal); -+ sysbus_mmio_map(busdev, 0, mc->ls7a_ioapic_reg_base); -+ s->ioapic_irq = irqhandler; -+ s->apicdev = dev; -+ return s->ioapic_irq; -+ } -+ return NULL; -+} -+ -+/* Network support */ -+static void network_init(PCIBus *pci_bus) -+{ -+ int i; -+ -+ for (i = 0; i < nb_nics; i++) { -+ NICInfo *nd = &nd_table[i]; -+ -+ if (!nd->model) { -+ nd->model = g_strdup("virtio-net-pci"); -+ } -+ -+ pci_nic_init_nofail(nd, pci_bus, nd->model, NULL); -+ } -+} -+ -+void loongarch_cpu_destroy(MachineState *machine, LOONGARCHCPU *cpu) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ unsigned int id; -+ int smp_cpus = machine->smp.cpus; -+ id = cpu->id; -+ qemu_unregister_reset(slave_cpu_reset, lsms->reset_info[id]); -+ g_free(lsms->reset_info[id]); -+ lsms->reset_info[id] = NULL; -+ -+ smp_cpus -= 1; -+ if (lsms->fw_cfg) { -+ fw_cfg_modify_i16(lsms->fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); -+ } -+ -+ qemu_del_vm_change_state_handler(cpu->cpuStateEntry); -+} -+ -+LOONGARCHCPU *loongarch_cpu_create(MachineState *machine, LOONGARCHCPU *cpu, -+ Error **errp) -+{ -+ CPULOONGARCHState *env; -+ unsigned int id; -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ int smp_cpus = machine->smp.cpus; -+ id = cpu->id; -+ env = &cpu->env; -+ cpu_states[id] = env; -+ env->CSR_TMID |= id; -+ -+ lsms = LoongarchMACHINE(machine); -+ lsms->reset_info[id] = g_malloc0(sizeof(ResetData)); -+ lsms->reset_info[id]->cpu = cpu; -+ lsms->reset_info[id]->vector = env->active_tc.PC; -+ qemu_register_reset(slave_cpu_reset, lsms->reset_info[id]); -+ -+ /* Init CPU internal devices */ -+ cpu_init_irq(cpu); -+ cpu_loongarch_clock_init(cpu); -+ -+ smp_cpus += 1; -+ if (lsms->fw_cfg) { -+ fw_cfg_modify_i16(lsms->fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); -+ } -+ cpu_init_ipi(lsms, env->irq[12], id); -+ cpu_init_apic(lsms, env, id); -+ -+ return cpu; -+} -+ -+static void fw_cfg_boot_set(void *opaque, const char *boot_device, -+ Error **errp) -+{ -+ fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); -+} -+ -+static FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, -+ LoongarchMachineState *lsms) -+{ -+ FWCfgState *fw_cfg; -+ uint64_t *numa_fw_cfg; -+ int i; -+ const CPUArchIdList *cpus; -+ MachineClass *mc = MACHINE_GET_CLASS(lsms); -+ MachineState *ms = MACHINE(OBJECT(lsms)); -+ int max_cpus = ms->smp.max_cpus; -+ int smp_cpus = ms->smp.cpus; -+ int nb_numa_nodes = ms->numa_state->num_nodes; -+ NodeInfo *numa_info = ms->numa_state->nodes; -+ -+ fw_cfg = fw_cfg_init_mem_wide(FW_CFG_ADDR + 8, FW_CFG_ADDR, 8, 0, NULL); -+ fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); -+ fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); -+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); -+ -+ /* -+ * allocate memory for the NUMA channel: one (64bit) word for the number -+ * of nodes, one word for each VCPU->node and one word for each node to -+ * hold the amount of memory. -+ */ -+ numa_fw_cfg = g_new0(uint64_t, 1 + max_cpus + nb_numa_nodes); -+ numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); -+ cpus = mc->possible_cpu_arch_ids(MACHINE(lsms)); -+ for (i = 0; i < cpus->len; i++) { -+ unsigned int apic_id = cpus->cpus[i].arch_id; -+ assert(apic_id < max_cpus); -+ numa_fw_cfg[apic_id + 1] = cpu_to_le64(cpus->cpus[i].props.node_id); -+ } -+ for (i = 0; i < nb_numa_nodes; i++) { -+ numa_fw_cfg[max_cpus + 1 + i] = cpu_to_le64(numa_info[i].node_mem); -+ } -+ fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg, -+ (1 + max_cpus + nb_numa_nodes) * sizeof(*numa_fw_cfg)); -+ -+ qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); -+ return fw_cfg; -+} -+ -+static void loongarch_build_smbios(LoongarchMachineState *lsms) -+{ -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ MachineState *ms = MACHINE(OBJECT(lsms)); -+ uint8_t *smbios_tables, *smbios_anchor; -+ size_t smbios_tables_len, smbios_anchor_len; -+ const char *product = "QEMU Virtual Machine"; -+ ms->smp.cores = 4; -+ -+ if (!lsms->fw_cfg) { -+ return; -+ } -+ -+ if (kvm_enabled()) { -+ if (strstr(lsmc->cpu_name, "5000")) { -+ product = "KVM"; -+ } -+ } else { -+ product = "Loongarch-3A5K-7A1000-TCG"; -+ } -+ -+ smbios_set_defaults("Loongson", product, lsmc->cpu_name, false, true, -+ SMBIOS_ENTRY_POINT_30); -+ -+ smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len, -+ &smbios_anchor, &smbios_anchor_len, &error_fatal); -+ -+ if (smbios_anchor) { -+ fw_cfg_add_file(lsms->fw_cfg, "etc/smbios/smbios-tables", -+ smbios_tables, smbios_tables_len); -+ fw_cfg_add_file(lsms->fw_cfg, "etc/smbios/smbios-anchor", -+ smbios_anchor, smbios_anchor_len); -+ } -+} -+ -+static void loongarch_machine_done(Notifier *notifier, void *data) -+{ -+ LoongarchMachineState *lsms = -+ container_of(notifier, LoongarchMachineState, machine_done); -+ -+ platform_bus_add_all_fdt_nodes( -+ lsms->fdt, NULL, VIRT_PLATFORM_BUS_BASEADDRESS, VIRT_PLATFORM_BUS_SIZE, -+ VIRT_PLATFORM_BUS_IRQ); -+ -+ qemu_fdt_dumpdtb(lsms->fdt, lsms->fdt_size); -+ /* load fdt */ -+ MemoryRegion *fdt_rom = g_new(MemoryRegion, 1); -+ memory_region_init_rom(fdt_rom, NULL, "fdt", LS_FDT_SIZE, &error_fatal); -+ memory_region_add_subregion(get_system_memory(), LS_FDT_BASE, fdt_rom); -+ rom_add_blob_fixed("fdt", lsms->fdt, lsms->fdt_size, LS_FDT_BASE); -+ -+ loongarch_acpi_setup(); -+ loongarch_build_smbios(lsms); -+} -+ -+#ifdef CONFIG_TCG -+#define FEATURE_REG 0x1fe00008 -+#define VENDOR_REG 0x1fe00010 -+#define CPUNAME_REG 0x1fe00020 -+#define OTHER_FUNC_REG 0x1fe00420 -+#define _str(x) #x -+#define str(x) _str(x) -+#define SIMPLE_OPS(ADDR, SIZE) \ -+ ({ \ -+ MemoryRegion *iomem = g_new(MemoryRegion, 1); \ -+ memory_region_init_io(iomem, NULL, &loongarch_qemu_ops, (void *)ADDR, \ -+ str(ADDR), SIZE); \ -+ memory_region_add_subregion_overlap(address_space_mem, ADDR, iomem, \ -+ 1); \ -+ }) -+ -+static int reg180; -+ -+static void loongarch_qemu_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size) -+{ -+ addr = ((hwaddr)(long)opaque) + addr; -+ addr = addr & 0xffffffff; -+ switch (addr) { -+ case 0x1fe00180: -+ reg180 = val; -+ break; -+ } -+} -+ -+static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ uint64_t feature = 0UL; -+ addr = ((hwaddr)(long)opaque) + addr; -+ addr = addr & 0xffffffff; -+ switch (addr) { -+ case 0x1fe00180: -+ return reg180; -+ case 0x1001041c: -+ return 0xa800; -+ case FEATURE_REG: -+ feature |= 1UL << 2 | 1UL << 3 | 1UL << 4 | 1UL << 11; -+ return feature; -+ case VENDOR_REG: -+ return *(uint64_t *)"Loongson-3A5000"; -+ case CPUNAME_REG: -+ return *(uint64_t *)"3A5000"; -+ case 0x10013ffc: -+ return 0x80; -+ } -+ return 0; -+} -+ -+static const MemoryRegionOps loongarch_qemu_ops = { -+ .read = loongarch_qemu_read, -+ .write = loongarch_qemu_write, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+ .valid = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 4, -+ .max_access_size = 8, -+ }, -+}; -+#endif -+ -+static void loongarch_system_flash_cleanup_unused(LoongarchMachineState *lsms) -+{ -+ char *prop_name; -+ int i; -+ Object *dev_obj; -+ -+ for (i = 0; i < ARRAY_SIZE(lsms->flash); i++) { -+ dev_obj = OBJECT(lsms->flash[i]); -+ if (!object_property_get_bool(dev_obj, "realized", &error_abort)) { -+ prop_name = g_strdup_printf("pflash%d", i); -+ object_property_del(OBJECT(lsms), prop_name); -+ g_free(prop_name); -+ object_unparent(dev_obj); -+ lsms->flash[i] = NULL; -+ } -+ } -+} -+ -+static bool loongarch_system_flash_init(LoongarchMachineState *lsms) -+{ -+ int i = 0; -+ int64_t size = 0; -+ PFlashCFI01 *pflash = NULL; -+ BlockBackend *pflash_blk; -+ -+ for (i = 0; i < ARRAY_SIZE(lsms->flash); i++) { -+ pflash_blk = NULL; -+ pflash = NULL; -+ -+ pflash = lsms->flash[i]; -+ pflash_cfi01_legacy_drive(pflash, drive_get(IF_PFLASH, 0, i)); -+ -+ pflash_blk = pflash_cfi01_get_blk(pflash); -+ /*The pflash0 must be exist, or not support boot by pflash*/ -+ if (pflash_blk == NULL) { -+ if (i == 0) { -+ return false; -+ } else { -+ break; -+ } -+ } -+ -+ size = blk_getlength(pflash_blk); -+ if (size == 0 || size % FLASH_SECTOR_SIZE != 0) { -+ error_report("system firmware block device %s has invalid size " -+ "%" PRId64, -+ blk_name(pflash_blk), size); -+ error_report("its size must be a non-zero multiple of 0x%x", -+ FLASH_SECTOR_SIZE); -+ exit(1); -+ } -+ qdev_prop_set_uint32(DEVICE(pflash), "num-blocks", -+ size / FLASH_SECTOR_SIZE); -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(pflash), &error_fatal); -+ if (i == 0) { -+ sysbus_mmio_map(SYS_BUS_DEVICE(pflash), 0, LS_BIOS_BASE); -+ } else { -+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(pflash), 0, -+ LS_BIOS_VAR_BASE, 1); -+ } -+ } -+ -+ return true; -+} -+ -+static void ls3a5k_bios_init(LoongarchMachineState *lsms, ram_addr_t ram_size, -+ uint64_t highram_size, uint64_t phyAddr_initrd, -+ const char *kernel_filename, -+ const char *kernel_cmdline, -+ const char *initrd_filename) -+{ -+ MemoryRegion *bios; -+ bool fw_cfg_used = false; -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ char *filename; -+ int bios_size; -+ const char *bios_name; -+ -+ bios_name = MACHINE(lsms)->firmware; -+ if (kernel_filename) { -+ loaderparams.ram_size = ram_size; -+ loaderparams.kernel_filename = kernel_filename; -+ loaderparams.kernel_cmdline = kernel_cmdline; -+ loaderparams.initrd_filename = initrd_filename; -+ } -+ -+ if (loongarch_system_flash_init(lsms)) { -+ fw_cfg_used = true; -+ } else { -+ bios = g_new(MemoryRegion, 1); -+ memory_region_init_ram(bios, NULL, "loongarch.bios", LS_BIOS_SIZE, -+ &error_fatal); -+ memory_region_set_readonly(bios, true); -+ memory_region_add_subregion(get_system_memory(), LS_BIOS_BASE, bios); -+ -+ /* BIOS load */ -+ if (bios_name) { -+ if (access(bios_name, R_OK) == 0) { -+ load_image_targphys(bios_name, LS_BIOS_BASE, LS_BIOS_SIZE); -+ } else { -+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); -+ load_image_targphys(filename, LS_BIOS_BASE, LS_BIOS_SIZE); -+ g_free(filename); -+ } -+ fw_cfg_used = true; -+ } else { -+ if (strstr(lsmc->cpu_name, "5000")) { -+ bios_size = sizeof(ls3a5k_aui_boot_code); -+ rom_add_blob_fixed("bios", ls3a5k_aui_boot_code, bios_size, -+ LS_BIOS_BASE); -+ } -+ -+ if (kernel_filename) { -+ lsms->reset_info[0]->vector = load_kernel(); -+ } -+ } -+ } -+ -+ loongarch_system_flash_cleanup_unused(lsms); -+ -+ if (fw_cfg_used) { -+ lsms->fw_cfg = loongarch_fw_cfg_init(ram_size, lsms); -+ rom_set_fw(lsms->fw_cfg); -+ fw_conf_init(ram_size); -+ rom_add_blob_fixed("fw_conf", (void *)&fw_config, sizeof(fw_config), -+ FW_CONF_ADDR); -+ -+ if (kernel_filename) { -+ fw_cfg_add_kernel_info(lsms->fw_cfg, highram_size, phyAddr_initrd); -+ } -+ } -+ -+ if (lsms->fw_cfg != NULL) { -+ fw_cfg_add_file(lsms->fw_cfg, "etc/memmap", la_memmap_table, -+ sizeof(struct la_memmap_entry) * (la_memmap_entries)); -+ } -+ -+ return; -+} -+ -+static void create_fdt(LoongarchMachineState *lsms) -+{ -+ lsms->fdt = create_device_tree(&lsms->fdt_size); -+ if (!lsms->fdt) { -+ error_report("create_device_tree() failed"); -+ exit(1); -+ } -+ -+ /* Header */ -+ qemu_fdt_setprop_string(lsms->fdt, "/", "compatible", -+ "linux,dummy-loongson3"); -+ qemu_fdt_setprop_cell(lsms->fdt, "/", "#address-cells", 0x2); -+ qemu_fdt_setprop_cell(lsms->fdt, "/", "#size-cells", 0x2); -+} -+ -+static void fdt_add_cpu_nodes(const LoongarchMachineState *lsms) -+{ -+ int num; -+ const MachineState *ms = MACHINE(lsms); -+ int smp_cpus = ms->smp.cpus; -+ -+ qemu_fdt_add_subnode(lsms->fdt, "/cpus"); -+ qemu_fdt_setprop_cell(lsms->fdt, "/cpus", "#address-cells", 0x1); -+ qemu_fdt_setprop_cell(lsms->fdt, "/cpus", "#size-cells", 0x0); -+ -+ /* cpu nodes */ -+ for (num = smp_cpus - 1; num >= 0; num--) { -+ char *nodename = g_strdup_printf("/cpus/cpu@%d", num); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num)); -+ -+ qemu_fdt_add_subnode(lsms->fdt, nodename); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, "device_type", "cpu"); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, "compatible", -+ cpu->dtb_compatible); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "reg", num); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "phandle", -+ qemu_fdt_alloc_phandle(lsms->fdt)); -+ g_free(nodename); -+ } -+ -+ /*cpu map */ -+ qemu_fdt_add_subnode(lsms->fdt, "/cpus/cpu-map"); -+ -+ for (num = smp_cpus - 1; num >= 0; num--) { -+ char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num); -+ char *map_path; -+ -+ if (ms->smp.threads > 1) { -+ map_path = -+ g_strdup_printf("/cpus/cpu-map/socket%d/core%d/thread%d", -+ num / (ms->smp.cores * ms->smp.threads), -+ (num / ms->smp.threads) % ms->smp.cores, -+ num % ms->smp.threads); -+ } else { -+ map_path = -+ g_strdup_printf("/cpus/cpu-map/socket%d/core%d", -+ num / ms->smp.cores, num % ms->smp.cores); -+ } -+ qemu_fdt_add_path(lsms->fdt, map_path); -+ qemu_fdt_setprop_phandle(lsms->fdt, map_path, "cpu", cpu_path); -+ -+ g_free(map_path); -+ g_free(cpu_path); -+ } -+} -+ -+static void fdt_add_fw_cfg_node(const LoongarchMachineState *lsms) -+{ -+ char *nodename; -+ hwaddr base = FW_CFG_ADDR; -+ -+ nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base); -+ qemu_fdt_add_subnode(lsms->fdt, nodename); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, "compatible", -+ "qemu,fw-cfg-mmio"); -+ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "reg", 2, base, 2, 0x8); -+ qemu_fdt_setprop(lsms->fdt, nodename, "dma-coherent", NULL, 0); -+ g_free(nodename); -+} -+ -+static void fdt_add_pcie_node(const LoongarchMachineState *lsms) -+{ -+ char *nodename; -+ hwaddr base_mmio = PCIE_MEMORY_BASE; -+ hwaddr size_mmio = PCIE_MEMORY_SIZE; -+ hwaddr base_pio = LS3A5K_ISA_IO_BASE; -+ hwaddr size_pio = LS_ISA_IO_SIZE; -+ hwaddr base_pcie = LS_PCIECFG_BASE; -+ hwaddr size_pcie = LS_PCIECFG_SIZE; -+ hwaddr base = base_pcie; -+ -+ nodename = g_strdup_printf("/pcie@%" PRIx64, base); -+ qemu_fdt_add_subnode(lsms->fdt, nodename); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, "compatible", -+ "pci-host-ecam-generic"); -+ qemu_fdt_setprop_string(lsms->fdt, nodename, "device_type", "pci"); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "#address-cells", 3); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "#size-cells", 2); -+ qemu_fdt_setprop_cell(lsms->fdt, nodename, "linux,pci-domain", 0); -+ qemu_fdt_setprop_cells(lsms->fdt, nodename, "bus-range", 0, -+ PCIE_MMCFG_BUS(LS_PCIECFG_SIZE - 1)); -+ qemu_fdt_setprop(lsms->fdt, nodename, "dma-coherent", NULL, 0); -+ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "reg", 2, base_pcie, 2, -+ size_pcie); -+ qemu_fdt_setprop_sized_cells(lsms->fdt, nodename, "ranges", 1, -+ FDT_PCI_RANGE_IOPORT, 2, 0, 2, base_pio, 2, -+ size_pio, 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, -+ 2, base_mmio, 2, size_mmio); -+ g_free(nodename); -+} -+ -+static void create_platform_bus(LoongarchMachineState *s, qemu_irq *pic) -+{ -+ DeviceState *dev; -+ SysBusDevice *sysbus; -+ int i; -+ MemoryRegion *sysmem = get_system_memory(); -+ -+ dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE); -+ dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE); -+ qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS); -+ qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE); -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); -+ s->platform_bus_dev = dev; -+ -+ sysbus = SYS_BUS_DEVICE(dev); -+ for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) { -+ int irq = VIRT_PLATFORM_BUS_IRQ + i; -+ sysbus_connect_irq(sysbus, i, pic[irq - LOONGARCH_PCH_IRQ_BASE]); -+ } -+ -+ memory_region_add_subregion(sysmem, VIRT_PLATFORM_BUS_BASEADDRESS, -+ sysbus_mmio_get_region(sysbus, 0)); -+} -+ -+static void ls3a5k_init(MachineState *args) -+{ -+ int i; -+ const char *cpu_model = args->cpu_type; -+ const char *kernel_filename = args->kernel_filename; -+ const char *kernel_cmdline = args->kernel_cmdline; -+ const char *initrd_filename = args->initrd_filename; -+ -+ ram_addr_t ram_size = args->ram_size; -+ MemoryRegion *address_space_mem = get_system_memory(); -+ ram_addr_t offset = 0; -+ MemoryRegion *isa_io = g_new(MemoryRegion, 1); -+ MemoryRegion *isa_mem = g_new(MemoryRegion, 1); -+ MachineState *machine = args; -+ MachineClass *mc = MACHINE_GET_CLASS(machine); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ int smp_cpus = machine->smp.cpus; -+ int nb_numa_nodes = machine->numa_state->num_nodes; -+ NodeInfo *numa_info = machine->numa_state->nodes; -+ LOONGARCHCPU *cpu; -+ CPULOONGARCHState *env; -+ qemu_irq *ls7a_apic = NULL; -+ qemu_irq *pirq = NULL; -+ PCIBus *pci_bus = NULL; -+ char *ramName = NULL; -+ uint64_t lowram_size = 0, highram_size = 0, phyAddr = 0, memmap_size = 0, -+ highram_end_addr = 0; -+ -+ CPUArchIdList *possible_cpus; -+ if (strstr(lsmc->cpu_name, "5000")) { -+ if (strcmp(cpu_model, LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000")) && -+ strcmp(cpu_model, LOONGARCH_CPU_TYPE_NAME("host"))) { -+ error_report("machine type %s does not match cpu type %s", -+ lsmc->cpu_name, cpu_model); -+ exit(1); -+ } -+ if (kvm_enabled()) { -+ kvm_vm_ioctl(kvm_state, KVM_LARCH_SET_CPUCFG, ls3a5k_cpucfgs); -+ } -+ } -+ -+ create_fdt(lsms); -+ -+ DPRINTF("isa 0x%lx\n", lsmc->isa_io_base); -+ DPRINTF("cpu_name %s bridge_name %s\n", lsmc->cpu_name, lsmc->bridge_name); -+ -+ /* init CPUs */ -+ mc->possible_cpu_arch_ids(machine); -+ possible_cpus = machine->possible_cpus; -+ -+ for (i = 0; i < smp_cpus; i++) { -+ Object *obj = NULL; -+ Error *local_err = NULL; -+ -+ obj = object_new(possible_cpus->cpus[i].type); -+ -+ object_property_set_uint(obj, "id", possible_cpus->cpus[i].arch_id, -+ &local_err); -+ object_property_set_bool(obj, "realized", true, &local_err); -+ -+ object_unref(obj); -+ error_propagate(&error_fatal, local_err); -+ -+ cpu = LOONGARCH_CPU(CPU(obj)); -+ if (cpu == NULL) { -+ fprintf(stderr, "Unable to find CPU definition\n"); -+ exit(1); -+ } -+ -+ env = &cpu->env; -+ cpu_states[i] = env; -+ env->CSR_TMID |= i; -+ -+ lsms->reset_info[i] = g_malloc0(sizeof(ResetData)); -+ lsms->reset_info[i]->cpu = cpu; -+ lsms->reset_info[i]->vector = env->active_tc.PC; -+ if (i == 0) { -+ qemu_register_reset(main_cpu_reset, lsms->reset_info[i]); -+ } else { -+ qemu_register_reset(slave_cpu_reset, lsms->reset_info[i]); -+ } -+ -+ /* Init CPU internal devices */ -+ cpu_init_irq(cpu); -+ cpu_loongarch_clock_init(cpu); -+ cpu_init_ipi(lsms, env->irq[12], i); -+ cpu_init_apic(lsms, env, i); -+ } -+ -+ lsms->hotpluged_cpu_num = 0; -+ fdt_add_cpu_nodes(lsms); -+ env = cpu_states[0]; -+ -+ /* node0 mem*/ -+ phyAddr = (uint64_t)0; -+ MemoryRegion *lowmem = g_new(MemoryRegion, 1); -+ ramName = g_strdup_printf("loongarch_ls3a.node%d.lowram", 0); -+ -+ lowram_size = MIN(ram_size, 256 * 0x100000); -+ memory_region_init_alias(lowmem, NULL, ramName, machine->ram, 0, -+ lowram_size); -+ memory_region_add_subregion(address_space_mem, phyAddr, lowmem); -+ -+ offset += lowram_size; -+ if (nb_numa_nodes > 0) { -+ highram_size = numa_info[0].node_mem - 256 * MiB; -+ if (numa_info[0].node_mem > GiB) { -+ memmap_size = numa_info[0].node_mem - GiB; -+ la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); -+ } -+ } else { -+ highram_size = ram_size - 256 * MiB; -+ if (ram_size > GiB) { -+ memmap_size = ram_size - GiB; -+ la_memmap_add_entry(0xc0000000ULL, memmap_size, SYSTEM_RAM); -+ } -+ } -+ -+ phyAddr = (uint64_t)0x90000000; -+ MemoryRegion *highmem = g_new(MemoryRegion, 1); -+ ramName = g_strdup_printf("loongarch_ls3a.node%d.highram", 0); -+ memory_region_init_alias(highmem, NULL, ramName, machine->ram, offset, -+ highram_size); -+ memory_region_add_subregion(address_space_mem, phyAddr, highmem); -+ offset += highram_size; -+ phyAddr += highram_size; -+ -+ /* initrd address use high mem from high to low */ -+ highram_end_addr = phyAddr; -+ /* node1~ nodemax */ -+ for (i = 1; i < nb_numa_nodes; i++) { -+ MemoryRegion *nodemem = g_new(MemoryRegion, 1); -+ ramName = g_strdup_printf("loongarch_ls3a.node%d.ram", i); -+ memory_region_init_alias(nodemem, NULL, ramName, machine->ram, offset, -+ numa_info[i].node_mem); -+ memory_region_add_subregion(address_space_mem, phyAddr, nodemem); -+ la_memmap_add_entry(phyAddr, numa_info[i].node_mem, SYSTEM_RAM); -+ offset += numa_info[i].node_mem; -+ phyAddr += numa_info[i].node_mem; -+ } -+ -+ fdt_add_fw_cfg_node(lsms); -+ ls3a5k_bios_init(lsms, ram_size, highram_size, highram_end_addr, -+ kernel_filename, kernel_cmdline, initrd_filename); -+ -+ lsms->machine_done.notify = loongarch_machine_done; -+ qemu_add_machine_init_done_notifier(&lsms->machine_done); -+ /*vmstate_register_ram_global(bios);*/ -+ -+ /* initialize hotplug memory address space */ -+ lsms->hotplug_memory_size = 0; -+ -+ /* always allocate the device memory information */ -+ machine->device_memory = g_malloc0(sizeof(*machine->device_memory)); -+ if (machine->ram_size < machine->maxram_size) { -+ int max_memslots; -+ -+ lsms->hotplug_memory_size = machine->maxram_size - machine->ram_size; -+ /* -+ * Limit the number of hotpluggable memory slots to half the number -+ * slots that KVM supports, leaving the other half for PCI and other -+ * devices. However ensure that number of slots doesn't drop below 32. -+ */ -+ max_memslots = LOONGARCH_MAX_RAM_SLOTS; -+ if (kvm_enabled()) { -+ max_memslots = kvm_get_max_memslots() / 2; -+ } -+ -+ if (machine->ram_slots == 0) -+ machine->ram_slots = -+ lsms->hotplug_memory_size / LOONGARCH_HOTPLUG_MEM_ALIGN; -+ -+ if (machine->ram_slots > max_memslots) { -+ error_report("Specified number of memory slots %" PRIu64 -+ " exceeds max supported %d", -+ machine->ram_slots, max_memslots); -+ exit(1); -+ } -+ -+ lsms->ram_slots = machine->ram_slots; -+ -+ machine->device_memory->base = get_hotplug_membase(machine->ram_size); -+ memory_region_init(&machine->device_memory->mr, OBJECT(lsms), -+ "device-memory", lsms->hotplug_memory_size); -+ memory_region_add_subregion(get_system_memory(), -+ machine->device_memory->base, -+ &machine->device_memory->mr); -+ } -+ -+ memory_region_init_alias(isa_io, NULL, "isa-io", get_system_io(), 0, -+ LS_ISA_IO_SIZE); -+ memory_region_init(isa_mem, NULL, "isa-mem", PCIE_MEMORY_SIZE); -+ memory_region_add_subregion(get_system_memory(), lsmc->isa_io_base, -+ isa_io); -+ memory_region_add_subregion(get_system_memory(), PCIE_MEMORY_BASE, -+ isa_mem); -+ -+ if (!strcmp(lsmc->bridge_name, "ls7a")) { -+ /*Initialize the 7A IO interrupt subsystem*/ -+ DeviceState *ls7a_dev; -+ lsms->apic_xrupt_override = kvm_irqchip_in_kernel(); -+ ls7a_apic = ls3a_intctl_init(machine, cpu_states); -+ if (!ls7a_apic) { -+ perror("Init 7A APIC failed\n"); -+ exit(1); -+ } -+ pci_bus = ls7a_init(machine, ls7a_apic, &ls7a_dev); -+ -+ object_property_add_link( -+ OBJECT(machine), LOONGARCH_MACHINE_ACPI_DEVICE_PROP, -+ TYPE_HOTPLUG_HANDLER, (Object **)&lsms->acpi_dev, -+ object_property_allow_set_link, OBJ_PROP_LINK_STRONG); -+ object_property_set_link(OBJECT(machine), -+ LOONGARCH_MACHINE_ACPI_DEVICE_PROP, -+ OBJECT(ls7a_dev), &error_abort); -+ -+ create_platform_bus(lsms, ls7a_apic); -+ -+#ifdef CONFIG_KVM -+ if (kvm_enabled()) { -+ kvm_direct_msi_allowed = -+ (kvm_check_extension(kvm_state, KVM_CAP_SIGNAL_MSI) > 0); -+ } else { -+ kvm_direct_msi_allowed = 0; -+ } -+ msi_nonbroken = kvm_direct_msi_allowed; -+#else -+ msi_nonbroken = true; -+#endif -+ sysbus_create_simple("ls7a_rtc", LS7A_RTC_REG_BASE, -+ ls7a_apic[LS7A_RTC_IRQ - LOONGARCH_PCH_IRQ_BASE]); -+ } -+ -+ /*Initialize the CPU serial device*/ -+ -+ if (serial_hd(0)) { -+ pirq = qemu_allocate_irqs( -+ legacy_set_irq, -+ ls7a_apic + (LS7A_UART_IRQ - LOONGARCH_PCH_IRQ_BASE), 1); -+ serial_mm_init(address_space_mem, LS7A_UART_BASE, 0, pirq[0], 115200, -+ serial_hd(0), DEVICE_NATIVE_ENDIAN); -+ } -+ -+ /*network card*/ -+ network_init(pci_bus); -+ /* VGA setup. Don't bother loading the bios. */ -+ pci_vga_init(pci_bus); -+ -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(qdev_new("iocsr")), &error_fatal); -+ -+#ifdef CONFIG_TCG -+ int nb_nodes = (smp_cpus - 1) / 4; -+ for (i = 0; i <= nb_nodes; i++) { -+ uint64_t off = (uint64_t)i << 44; -+ SIMPLE_OPS(((hwaddr)0x1fe00180 | off), 0x8); -+ SIMPLE_OPS(((hwaddr)0x1fe0019c | off), 0x8); -+ SIMPLE_OPS(((hwaddr)0x1fe001d0 | off), 0x8); -+ SIMPLE_OPS(((hwaddr)FEATURE_REG | off), 0x8); -+ SIMPLE_OPS(((hwaddr)VENDOR_REG | off), 0x8); -+ SIMPLE_OPS(((hwaddr)CPUNAME_REG | off), 0x8); -+ SIMPLE_OPS(((hwaddr)OTHER_FUNC_REG | off), 0x8); -+ } -+ -+ SIMPLE_OPS(0x1001041c, 0x4); -+ SIMPLE_OPS(0x10002000, 0x14); -+ SIMPLE_OPS(0x10013ffc, 0x4); -+#endif -+ -+ fdt_add_pcie_node(lsms); -+} -+ -+static const CPUArchIdList *loongarch_possible_cpu_arch_ids(MachineState *ms) -+{ -+ int i; -+ int max_cpus = ms->smp.max_cpus; -+ -+ if (ms->possible_cpus) { -+ /* -+ * make sure that max_cpus hasn't changed since the first use, i.e. -+ * -smp hasn't been parsed after it -+ */ -+ assert(ms->possible_cpus->len == max_cpus); -+ return ms->possible_cpus; -+ } -+ -+ ms->possible_cpus = -+ g_malloc0(sizeof(CPUArchIdList) + sizeof(CPUArchId) * max_cpus); -+ ms->possible_cpus->len = max_cpus; -+ for (i = 0; i < ms->possible_cpus->len; i++) { -+ ms->possible_cpus->cpus[i].type = ms->cpu_type; -+ ms->possible_cpus->cpus[i].vcpus_count = 1; -+ ms->possible_cpus->cpus[i].props.has_core_id = true; -+ ms->possible_cpus->cpus[i].props.core_id = i; -+ ms->possible_cpus->cpus[i].arch_id = i; -+ } -+ return ms->possible_cpus; -+} -+ -+static PFlashCFI01 *loongarch_pflash_create(LoongarchMachineState *lsms, -+ const char *name, -+ const char *alias_prop_name) -+{ -+ DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01); -+ -+ qdev_prop_set_uint64(dev, "sector-length", FLASH_SECTOR_SIZE); -+ qdev_prop_set_uint8(dev, "width", 1); -+ qdev_prop_set_string(dev, "name", name); -+ object_property_add_child(OBJECT(lsms), name, OBJECT(dev)); -+ object_property_add_alias(OBJECT(lsms), alias_prop_name, OBJECT(dev), -+ "drive"); -+ return PFLASH_CFI01(dev); -+} -+ -+static void loongarch_system_flash_create(LoongarchMachineState *lsms) -+{ -+ lsms->flash[0] = loongarch_pflash_create(lsms, "system.flash0", "pflash0"); -+ lsms->flash[1] = loongarch_pflash_create(lsms, "system.flash1", "pflash1"); -+} -+ -+static void loongarch_machine_initfn(Object *obj) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(obj); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ lsms->acpi_build_enabled = lsmc->has_acpi_build; -+ loongarch_system_flash_create(lsms); -+ lsms->oem_id = g_strndup(EFI_ACPI_OEM_ID, 6); -+ lsms->oem_table_id = g_strndup(EFI_ACPI_OEM_TABLE_ID, 6); -+} -+ -+static void ls3a5k_ls7a_machine_options(MachineClass *m) -+{ -+ char *cpu_name = get_host_cpu_model_name(); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_CLASS(m); -+ m->desc = "Loongarch3a5k LS7A1000 machine"; -+ m->max_cpus = LOONGARCH_MAX_VCPUS; -+ m->alias = "loongson7a"; -+ m->is_default = 1; -+ lsmc->isa_io_base = LS3A5K_ISA_IO_BASE; -+ lsmc->pciecfg_base = LS_PCIECFG_BASE; -+ lsmc->ls7a_ioapic_reg_base = LS3A5K_LS7A_IOAPIC_REG_BASE; -+ lsmc->node_shift = 44; -+ strncpy(lsmc->cpu_name, cpu_name, sizeof(lsmc->cpu_name) - 1); -+ lsmc->cpu_name[sizeof(lsmc->cpu_name) - 1] = 0; -+ strncpy(lsmc->bridge_name, "ls7a", sizeof(lsmc->bridge_name) - 1); -+ lsmc->bridge_name[sizeof(lsmc->bridge_name) - 1] = 0; -+ compat_props_add(m->compat_props, loongarch_compat, loongarch_compat_len); -+} -+ -+static void ls3a_board_reset(MachineState *ms) -+{ -+ qemu_devices_reset(); -+#ifdef CONFIG_KVM -+ struct loongarch_kvm_irqchip *chip; -+ int length; -+ -+ if (!kvm_enabled()) { -+ return; -+ } -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct loongarch_gipiState); -+ chip = g_malloc0(length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS3A_GIPI; -+ chip->len = length; -+ kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ -+ length = sizeof(struct loongarch_kvm_irqchip) + -+ sizeof(struct ls7a_ioapic_state); -+ chip = g_realloc(chip, length); -+ memset(chip, 0, length); -+ chip->chip_id = KVM_IRQCHIP_LS7A_IOAPIC; -+ chip->len = length; -+ kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); -+ -+ g_free(chip); -+#endif -+} -+ -+static CpuInstanceProperties ls3a_cpu_index_to_props(MachineState *ms, -+ unsigned cpu_index) -+{ -+ MachineClass *mc = MACHINE_GET_CLASS(ms); -+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); -+ -+ assert(cpu_index < possible_cpus->len); -+ return possible_cpus->cpus[cpu_index].props; -+} -+ -+static int64_t ls3a_get_default_cpu_node_id(const MachineState *ms, int idx) -+{ -+ int nb_numa_nodes = ms->numa_state->num_nodes; -+ int smp_cores = ms->smp.cores; -+ return idx / smp_cores % nb_numa_nodes; -+} -+ -+static void loongarch_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_CLASS(oc); -+ -+ lsmc->get_hotplug_handler = mc->get_hotplug_handler; -+ lsmc->has_acpi_build = true; -+ mc->get_hotplug_handler = loongarch_get_hotpug_handler; -+ mc->has_hotpluggable_cpus = true; -+ mc->cpu_index_to_instance_props = ls3a_cpu_index_to_props; -+ mc->possible_cpu_arch_ids = loongarch_possible_cpu_arch_ids; -+ mc->get_default_cpu_node_id = ls3a_get_default_cpu_node_id; -+ mc->default_ram_size = 1 * GiB; -+ mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("Loongson-3A5000"); -+ mc->default_ram_id = "loongarch_ls3a.ram"; -+ -+#ifdef CONFIG_TPM -+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); -+#endif -+ -+ mc->reset = ls3a_board_reset; -+ mc->max_cpus = LOONGARCH_MAX_VCPUS; -+ hc->pre_plug = loongarch_machine_device_pre_plug; -+ hc->plug = loongarch_machine_device_plug; -+ hc->unplug = longson_machine_device_unplug; -+ hc->unplug_request = loongarch_machine_device_unplug_request; -+ -+ object_class_property_add(oc, "acpi", "OnOffAuto", loongarch_get_acpi, -+ loongarch_set_acpi, NULL, NULL); -+ object_class_property_set_description(oc, "acpi", "Enable ACPI"); -+} -+ -+static const TypeInfo loongarch_info = { -+ .name = TYPE_LOONGARCH_MACHINE, -+ .parent = TYPE_MACHINE, -+ .abstract = true, -+ .instance_size = sizeof(LoongarchMachineState), -+ .instance_init = loongarch_machine_initfn, -+ .class_size = sizeof(LoongarchMachineClass), -+ .class_init = loongarch_class_init, -+ .interfaces = (InterfaceInfo[]){ { TYPE_HOTPLUG_HANDLER }, {} }, -+}; -+ -+static void loongarch_machine_register_types(void) -+{ -+ type_register_static(&loongarch_info); -+} -+ -+type_init(loongarch_machine_register_types) -+ -+ DEFINE_LS3A5K_MACHINE(loongson7a_v1_0, "loongson7a_v1.0", -+ ls3a5k_ls7a_machine_options); -diff --git a/hw/loongarch/larch_hotplug.c b/hw/loongarch/larch_hotplug.c -new file mode 100644 -index 0000000000..52f13af7b3 ---- /dev/null -+++ b/hw/loongarch/larch_hotplug.c -@@ -0,0 +1,377 @@ -+/* -+ * Hotplug emulation on Loongarch system. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qemu-common.h" -+#include "qemu/queue.h" -+#include "qemu/units.h" -+#include "qemu/cutils.h" -+#include "qemu/bcd.h" -+#include "hw/hotplug.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/mem/memory-device.h" -+#include "sysemu/numa.h" -+#include "sysemu/cpus.h" -+#include "hw/loongarch/larch.h" -+#include "hw/cpu/core.h" -+#include "hw/nvram/fw_cfg.h" -+#include "hw/platform-bus.h" -+ -+/* find cpu slot in machine->possible_cpus by core_id */ -+static CPUArchId *loongarch_find_cpu_slot(MachineState *ms, uint32_t id, -+ int *idx) -+{ -+ int index = id; -+ -+ if (index >= ms->possible_cpus->len) { -+ return NULL; -+ } -+ if (idx) { -+ *idx = index; -+ } -+ return &ms->possible_cpus->cpus[index]; -+} -+ -+static void loongarch_memory_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ Error *local_err = NULL; -+ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); -+ HotplugHandlerClass *hhc; -+ uint64_t size; -+ -+ size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort); -+ if (size % LOONGARCH_HOTPLUG_MEM_ALIGN) { -+ error_setg(&local_err, -+ "Hotplugged memory size must be a multiple of " -+ "%lld MB", -+ LOONGARCH_HOTPLUG_MEM_ALIGN / MiB); -+ goto out; -+ } -+ -+ pc_dimm_plug(PC_DIMM(dev), MACHINE(lsms)); -+ -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->plug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &error_abort); -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_memory_unplug_request(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ Error *local_err = NULL; -+ HotplugHandlerClass *hhc; -+ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); -+ -+ if (!lsms->acpi_dev || !loongarch_is_acpi_enabled(lsms)) { -+ error_setg( -+ &local_err, -+ "memory hotplug is not enabled: missing acpi device or acpi disabled"); -+ goto out; -+ } -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_cpu_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ CPUArchId *found_cpu; -+ HotplugHandlerClass *hhc; -+ Error *local_err = NULL; -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ -+ if (local_err) { -+ goto out; -+ } -+ -+ loongarch_cpu_destroy(machine, cpu); -+ -+ found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, NULL); -+ found_cpu->cpu = NULL; -+ object_unparent(OBJECT(dev)); -+ lsms->hotpluged_cpu_num -= 1; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_memory_unplug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ Error *local_err = NULL; -+ HotplugHandlerClass *hhc; -+ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); -+ -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->unplug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ -+ if (local_err) { -+ goto out; -+ } -+ -+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev)); -+ object_unparent(OBJECT(dev)); -+ -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_cpu_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ MachineState *ms = MACHINE(OBJECT(hotplug_dev)); -+ MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev); -+ LoongarchMachineState *lsms = LoongarchMACHINE(ms); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ CPUArchId *cpu_slot; -+ Error *local_err = NULL; -+ int index; -+ int free_index = lsms->hotpluged_cpu_num + ms->smp.cpus; -+ int max_cpus = ms->smp.max_cpus; -+ -+ if (dev->hotplugged && !mc->has_hotpluggable_cpus) { -+ error_setg(&local_err, "CPU hotplug not supported for this machine"); -+ goto out; -+ } -+ -+ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { -+ error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", -+ ms->cpu_type); -+ return; -+ } -+ -+ /* if ID is not set, set it based on core properties */ -+ if (cpu->id == UNASSIGNED_CPU_ID) { -+ if ((cpu->core_id) > (max_cpus - 1)) { -+ error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u", -+ cpu->core_id, max_cpus - 1); -+ return; -+ } -+ -+ if (free_index > (max_cpus - 1)) { -+ error_setg(errp, "The maximum number of CPUs cannot exceed %u.", -+ max_cpus); -+ return; -+ } -+ -+ if (cpu->core_id != free_index) { -+ error_setg(errp, "Invalid CPU core-id: %u must be :%u", -+ cpu->core_id, free_index); -+ return; -+ } -+ -+ cpu->id = cpu->core_id; -+ } -+ -+ cpu_slot = loongarch_find_cpu_slot(MACHINE(hotplug_dev), cpu->id, &index); -+ if (!cpu_slot) { -+ error_setg(&local_err, "core id %d out of range", cpu->id); -+ goto out; -+ } -+ -+ if (cpu_slot->cpu) { -+ error_setg(&local_err, "core %d already populated", cpu->id); -+ goto out; -+ } -+ -+ numa_cpu_pre_plug(cpu_slot, dev, &local_err); -+ -+ return; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_memory_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ PCDIMMDevice *dimm = PC_DIMM(dev); -+ Error *local_err = NULL; -+ uint64_t size; -+ -+ if (!lsms->acpi_dev || !loongarch_is_acpi_enabled(lsms)) { -+ error_setg( -+ errp, -+ "memory hotplug is not enabled: missing acpi device or acpi disabled"); -+ return; -+ } -+ -+ size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return; -+ } -+ -+ if (size % LOONGARCH_HOTPLUG_MEM_ALIGN) { -+ error_setg(errp, -+ "Hotplugged memory size must be a multiple of " -+ "%lld MB", -+ LOONGARCH_HOTPLUG_MEM_ALIGN / MiB); -+ return; -+ } -+ -+ pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp); -+} -+ -+static void loongarch_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, -+ Error **errp) -+{ -+ CPUArchId *found_cpu; -+ HotplugHandlerClass *hhc; -+ Error *local_err = NULL; -+ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ -+ if (lsms->acpi_dev) { -+ loongarch_cpu_create(machine, cpu, errp); -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->plug(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ } -+ -+ found_cpu = loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, NULL); -+ found_cpu->cpu = OBJECT(dev); -+ lsms->hotpluged_cpu_num += 1; -+out: -+ error_propagate(errp, local_err); -+} -+ -+static void loongarch_cpu_unplug_request(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ MachineState *machine = MACHINE(OBJECT(hotplug_dev)); -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ Error *local_err = NULL; -+ HotplugHandlerClass *hhc; -+ int idx = -1; -+ -+ if (!lsms->acpi_dev) { -+ error_setg(&local_err, "CPU hot unplug not supported without ACPI"); -+ goto out; -+ } -+ -+ loongarch_find_cpu_slot(MACHINE(lsms), cpu->id, &idx); -+ assert(idx != -1); -+ if (idx == 0) { -+ error_setg(&local_err, "Boot CPU is unpluggable"); -+ goto out; -+ } -+ -+ hhc = HOTPLUG_HANDLER_GET_CLASS(lsms->acpi_dev); -+ hhc->unplug_request(HOTPLUG_HANDLER(lsms->acpi_dev), dev, &local_err); -+ -+ if (local_err) { -+ goto out; -+ } -+ -+out: -+ error_propagate(errp, local_err); -+} -+ -+void longson_machine_device_unplug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); -+ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ loongarch_memory_unplug(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ if (!mc->has_hotpluggable_cpus) { -+ error_setg(errp, "CPU hot unplug not supported on this machine"); -+ return; -+ } -+ loongarch_cpu_unplug(hotplug_dev, dev, errp); -+ } else { -+ error_setg(errp, -+ "acpi: device unplug for not supported device" -+ " type: %s", -+ object_get_typename(OBJECT(dev))); -+ } -+ -+ return; -+} -+ -+void loongarch_machine_device_unplug_request(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ loongarch_memory_unplug_request(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ loongarch_cpu_unplug_request(hotplug_dev, dev, errp); -+ } -+} -+ -+HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, -+ DeviceState *dev) -+{ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || -+ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) || -+ object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) { -+ return HOTPLUG_HANDLER(machine); -+ } -+ return NULL; -+} -+ -+void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ loongarch_memory_pre_plug(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ loongarch_cpu_pre_plug(hotplug_dev, dev, errp); -+ } -+} -+ -+void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(hotplug_dev); -+ -+ if (lsms->platform_bus_dev) { -+ MachineClass *mc = MACHINE_GET_CLASS(lsms); -+ -+ if (device_is_dynamic_sysbus(mc, dev)) { -+ platform_bus_link_device( -+ PLATFORM_BUS_DEVICE(lsms->platform_bus_dev), -+ SYS_BUS_DEVICE(dev)); -+ } -+ } -+ -+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { -+ loongarch_memory_plug(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) { -+ loongarch_cpu_plug(hotplug_dev, dev, errp); -+ } -+} -diff --git a/hw/loongarch/larch_int.c b/hw/loongarch/larch_int.c -new file mode 100644 -index 0000000000..ff3750e982 ---- /dev/null -+++ b/hw/loongarch/larch_int.c -@@ -0,0 +1,87 @@ -+/* -+ * QEMU LOONGARCH interrupt support -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/main-loop.h" -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/loongarch/cpudevs.h" -+#include "cpu.h" -+#include "sysemu/kvm.h" -+#include "kvm_larch.h" -+#ifdef CONFIG_KVM -+#include -+#endif -+ -+static void cpu_irq_request(void *opaque, int irq, int level) -+{ -+ LOONGARCHCPU *cpu = opaque; -+ CPULOONGARCHState *env = &cpu->env; -+ CPUState *cs = CPU(cpu); -+ bool locked = false; -+ -+ if (irq < 0 || irq > 13) { -+ return; -+ } -+ -+ /* Make sure locking works even if BQL is already held by the caller */ -+ if (!qemu_mutex_iothread_locked()) { -+ locked = true; -+ qemu_mutex_lock_iothread(); -+ } -+ -+ if (level) { -+ env->CSR_ESTAT |= 1 << irq; -+ } else { -+ env->CSR_ESTAT &= ~(1 << irq); -+ } -+ -+ if (kvm_enabled()) { -+ if (irq == 2) { -+ kvm_loongarch_set_interrupt(cpu, irq, level); -+ } else if (irq == 3) { -+ kvm_loongarch_set_interrupt(cpu, irq, level); -+ } else if (irq == 12) { -+ kvm_loongarch_set_ipi_interrupt(cpu, irq, level); -+ } -+ } -+ -+ if (env->CSR_ESTAT & CSR_ESTAT_IPMASK) { -+ cpu_interrupt(cs, CPU_INTERRUPT_HARD); -+ } else { -+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); -+ } -+ -+ if (locked) { -+ qemu_mutex_unlock_iothread(); -+ } -+} -+ -+void cpu_init_irq(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ qemu_irq *qi; -+ int i; -+ -+ qi = qemu_allocate_irqs(cpu_irq_request, loongarch_env_get_cpu(env), -+ N_IRQS); -+ for (i = 0; i < N_IRQS; i++) { -+ env->irq[i] = qi[i]; -+ } -+} -diff --git a/hw/loongarch/ls7a_nb.c b/hw/loongarch/ls7a_nb.c -new file mode 100644 -index 0000000000..933b3f2869 ---- /dev/null -+++ b/hw/loongarch/ls7a_nb.c -@@ -0,0 +1,289 @@ -+/* -+ * Loongarch 7A1000 north bridge support -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+ -+#include "hw/hw.h" -+#include "hw/irq.h" -+#include "hw/sysbus.h" -+#include "hw/pci/pci.h" -+#include "hw/i386/pc.h" -+#include "hw/pci/pci_host.h" -+#include "hw/pci/pcie_host.h" -+#include "sysemu/sysemu.h" -+#include "exec/address-spaces.h" -+#include "qapi/error.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/acpi/ls7a.h" -+#include "hw/i386/pc.h" -+#include "hw/isa/isa.h" -+#include "hw/boards.h" -+#include "qemu/log.h" -+#include "hw/loongarch/bios.h" -+#include "hw/loader.h" -+#include "elf.h" -+#include "exec/address-spaces.h" -+#include "exec/memory.h" -+#include "hw/pci/pci_bridge.h" -+#include "hw/pci/pci_bus.h" -+#include "linux/kvm.h" -+#include "sysemu/kvm.h" -+#include "sysemu/runstate.h" -+#include "sysemu/reset.h" -+#include "migration/vmstate.h" -+#include "hw/loongarch/larch.h" -+#include "hw/loongarch/ls7a.h" -+ -+#undef DEBUG_LS7A -+ -+#ifdef DEBUG_LS7A -+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) -+#else -+#define DPRINTF(fmt, ...) -+#endif -+ -+static void ls7a_reset(void *opaque) -+{ -+ uint64_t wmask; -+ wmask = ~(-1); -+ -+ PCIDevice *dev = opaque; -+ pci_set_word(dev->config + PCI_VENDOR_ID, 0x0014); -+ pci_set_word(dev->wmask + PCI_VENDOR_ID, wmask & 0xffff); -+ pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff); -+ pci_set_word(dev->config + PCI_DEVICE_ID, 0x7a00); -+ pci_set_word(dev->wmask + PCI_DEVICE_ID, wmask & 0xffff); -+ pci_set_word(dev->cmask + PCI_DEVICE_ID, 0xffff); -+ pci_set_word(dev->config + 0x4, 0x0000); -+ pci_set_word(dev->config + PCI_STATUS, 0x0010); -+ pci_set_word(dev->wmask + PCI_STATUS, wmask & 0xffff); -+ pci_set_word(dev->cmask + PCI_STATUS, 0xffff); -+ pci_set_byte(dev->config + PCI_REVISION_ID, 0x0); -+ pci_set_byte(dev->wmask + PCI_REVISION_ID, wmask & 0xff); -+ pci_set_byte(dev->cmask + PCI_REVISION_ID, 0xff); -+ pci_set_byte(dev->config + 0x9, 0x00); -+ pci_set_byte(dev->wmask + 0x9, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0x9, 0xff); -+ pci_set_byte(dev->config + 0xa, 0x00); -+ pci_set_byte(dev->wmask + 0xa, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0xa, 0xff); -+ pci_set_byte(dev->config + 0xb, 0x06); -+ pci_set_byte(dev->wmask + 0xb, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0xb, 0xff); -+ pci_set_byte(dev->config + 0xc, 0x00); -+ pci_set_byte(dev->wmask + 0xc, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0xc, 0xff); -+ pci_set_byte(dev->config + 0xe, 0x80); -+ pci_set_byte(dev->wmask + 0xe, wmask & 0xff); -+ pci_set_byte(dev->cmask + 0xe, 0xff); -+} -+ -+static const VMStateDescription vmstate_ls7a_pcie = { -+ .name = "LS7A_PCIE", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField[]){ VMSTATE_PCI_DEVICE(dev, LS7APCIState), -+ VMSTATE_STRUCT(pm, LS7APCIState, 0, -+ vmstate_ls7a_pm, LS7APCIPMRegs), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+static PCIINTxRoute ls7a_route_intx_pin_to_irq(void *opaque, int pin) -+{ -+ PCIINTxRoute route; -+ -+ route.irq = pin; -+ route.mode = PCI_INTX_ENABLED; -+ return route; -+} -+ -+static int pci_ls7a_map_irq(PCIDevice *d, int irq_num) -+{ -+ int irq; -+ -+ irq = 16 + ((PCI_SLOT(d->devfn) * 4 + irq_num) & 0xf); -+ return irq; -+} -+ -+static void pci_ls7a_set_irq(void *opaque, int irq_num, int level) -+{ -+ qemu_irq *pic = opaque; -+ DPRINTF("------ %s irq %d %d\n", __func__, irq_num, level); -+ qemu_set_irq(pic[irq_num], level); -+} -+ -+static void ls7a_pcie_realize(PCIDevice *dev, Error **errp) -+{ -+ LS7APCIState *s = PCIE_LS7A(dev); -+ /* Ls7a North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */ -+ pci_config_set_prog_interface(dev->config, 0x00); -+ -+ /* set the default value of north bridge pci config */ -+ qemu_register_reset(ls7a_reset, s); -+} -+ -+static AddressSpace *ls7a_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) -+{ -+ return &address_space_memory; -+} -+ -+static PCIBus *pci_ls7a_init(MachineState *machine, DeviceState *dev, -+ qemu_irq *pic) -+{ -+ LoongarchMachineState *lsms = LoongarchMACHINE(machine); -+ LoongarchMachineClass *lsmc = LoongarchMACHINE_GET_CLASS(lsms); -+ PCIExpressHost *e; -+ PCIHostState *phb; -+ -+ e = PCIE_HOST_BRIDGE(dev); -+ phb = PCI_HOST_BRIDGE(e); -+ phb->bus = pci_register_root_bus( -+ dev, "pcie.0", pci_ls7a_set_irq, pci_ls7a_map_irq, pic, -+ get_system_memory(), get_system_io(), (1 << 3), 128, TYPE_PCIE_BUS); -+ pcie_host_mmcfg_update(e, true, lsmc->pciecfg_base, LS_PCIECFG_SIZE); -+ DPRINTF("------ %d\n", __LINE__); -+ -+ pci_bus_set_route_irq_fn(phb->bus, ls7a_route_intx_pin_to_irq); -+ -+ return phb->bus; -+} -+ -+PCIBus *ls7a_init(MachineState *machine, qemu_irq *pic, DeviceState **ls7a_dev) -+{ -+ DeviceState *dev; -+ PCIHostState *phb; -+ LS7APCIState *pbs; -+ PCIDevice *pcid; -+ PCIBus *pci_bus; -+ PCIExpressHost *e; -+ -+ /*1. init the HT PCI CFG*/ -+ DPRINTF("------ %d\n", __LINE__); -+ dev = qdev_new(TYPE_LS7A_PCIE_HOST_BRIDGE); -+ e = PCIE_HOST_BRIDGE(dev); -+ phb = PCI_HOST_BRIDGE(e); -+ -+ DPRINTF("------ %d\n", __LINE__); -+ pci_bus = pci_ls7a_init(machine, dev, pic); -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); -+ phb->bus = pci_bus; -+ /* set the pcihost pointer after rs780_pcihost_initfn is called */ -+ DPRINTF("------ %d\n", __LINE__); -+ pcid = pci_new(PCI_DEVFN(0, 0), TYPE_PCIE_LS7A); -+ pbs = PCIE_LS7A(pcid); -+ pbs->pciehost = LS7A_PCIE_HOST_BRIDGE(dev); -+ pbs->pciehost->pci_dev = pbs; -+ -+ if (ls7a_dev) { -+ *ls7a_dev = DEVICE(pcid); -+ } -+ -+ pci_realize_and_unref(pcid, phb->bus, &error_fatal); -+ -+ /* IOMMU */ -+ pci_setup_iommu(phb->bus, ls7a_pci_dma_iommu, NULL); -+ -+ ls7a_pm_init(&pbs->pm, pic); -+ DPRINTF("------ %d\n", __LINE__); -+ /*3. init the north bridge VGA,not do now*/ -+ return pci_bus; -+} -+ -+LS7APCIState *get_ls7a_type(Object *obj) -+{ -+ LS7APCIState *pbs; -+ -+ pbs = PCIE_LS7A(obj); -+ return pbs; -+} -+ -+static void ls7a_pcie_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); -+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); -+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass); -+ -+ k->realize = ls7a_pcie_realize; -+ k->vendor_id = 0x0014; -+ k->device_id = 0x7a00; -+ k->revision = 0x00; -+ k->class_id = PCI_CLASS_BRIDGE_HOST; -+ dc->desc = "LS7A1000 PCIE Host bridge"; -+ dc->vmsd = &vmstate_ls7a_pcie; -+ /* -+ * PCI-facing part of the host bridge, not usable without the -+ * host-facing part, which can't be device_add'ed, yet. -+ */ -+ dc->user_creatable = false; -+ hc->plug = ls7a_pm_device_plug_cb; -+ hc->unplug_request = ls7a_pm_device_unplug_request_cb; -+ hc->unplug = ls7a_pm_device_unplug_cb; -+ adevc->ospm_status = ls7a_pm_ospm_status; -+ adevc->send_event = ls7a_send_gpe; -+ adevc->madt_cpu = ls7a_madt_cpu_entry; -+} -+ -+static void ls7a_pci_add_properties(LS7APCIState *ls7a) -+{ -+ ls7a_pm_add_properties(OBJECT(ls7a), &ls7a->pm, NULL); -+} -+ -+static void ls7a_pci_initfn(Object *obj) -+{ -+ LS7APCIState *ls7a = get_ls7a_type(obj); -+ -+ ls7a_pci_add_properties(ls7a); -+} -+ -+static const TypeInfo ls7a_pcie_device_info = { -+ .name = TYPE_PCIE_LS7A, -+ .parent = TYPE_PCI_DEVICE, -+ .instance_size = sizeof(LS7APCIState), -+ .class_init = ls7a_pcie_class_init, -+ .instance_init = ls7a_pci_initfn, -+ .interfaces = -+ (InterfaceInfo[]){ -+ { TYPE_HOTPLUG_HANDLER }, -+ { TYPE_ACPI_DEVICE_IF }, -+ { INTERFACE_CONVENTIONAL_PCI_DEVICE }, -+ {}, -+ }, -+}; -+ -+static void ls7a_pciehost_class_init(ObjectClass *klass, void *data) -+{ -+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); -+ k->parent_class.fw_name = "pci"; -+} -+ -+static const TypeInfo ls7a_pciehost_info = { -+ .name = TYPE_LS7A_PCIE_HOST_BRIDGE, -+ .parent = TYPE_PCIE_HOST_BRIDGE, -+ .instance_size = sizeof(LS7APCIEHost), -+ .class_init = ls7a_pciehost_class_init, -+}; -+ -+static void ls7a_register_types(void) -+{ -+ type_register_static(&ls7a_pciehost_info); -+ type_register_static(&ls7a_pcie_device_info); -+} -+ -+type_init(ls7a_register_types) -diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build -new file mode 100644 -index 0000000000..ca4d5567b5 ---- /dev/null -+++ b/hw/loongarch/meson.build -@@ -0,0 +1,15 @@ -+loongarch_ss = ss.source_set() -+loongarch_ss.add(files('larch_3a.c'), fdt) -+loongarch_ss.add(files( -+ 'larch_int.c', -+ 'larch_hotplug.c', -+ 'ls7a_nb.c', -+ 'ioapic.c', -+ 'acpi-build.c', -+ 'ipi.c', -+ 'apic.c', -+ 'iocsr.c', -+ 'sysbus-fdt.c', -+)) -+ -+hw_arch += {'loongarch64': loongarch_ss} -diff --git a/hw/loongarch/sysbus-fdt.c b/hw/loongarch/sysbus-fdt.c -new file mode 100644 -index 0000000000..05b4dda33a ---- /dev/null -+++ b/hw/loongarch/sysbus-fdt.c -@@ -0,0 +1,178 @@ -+/* -+ * Loongarch Platform Bus device tree generation helpers -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include -+#include "qemu/error-report.h" -+#include "sysemu/device_tree.h" -+#include "hw/platform-bus.h" -+#include "hw/display/ramfb.h" -+#include "hw/loongarch/sysbus-fdt.h" -+#include "sysemu/tpm.h" -+ -+/* -+ * internal struct that contains the information to create dynamic -+ * sysbus device node -+ */ -+typedef struct PlatformBusFDTData { -+ void *fdt; /* device tree handle */ -+ int irq_start; /* index of the first IRQ usable by platform bus devices */ -+ const char *pbus_node_name; /* name of the platform bus node */ -+ PlatformBusDevice *pbus; -+} PlatformBusFDTData; -+ -+/* struct that allows to match a device and create its FDT node */ -+typedef struct BindingEntry { -+ const char *typename; -+ const char *compat; -+ int (*add_fn)(SysBusDevice *sbdev, void *opaque); -+ bool (*match_fn)(SysBusDevice *sbdev, const struct BindingEntry *combo); -+} BindingEntry; -+ -+static int no_fdt_node(SysBusDevice *sbdev, void *opaque) -+{ -+ return 0; -+} -+ -+/* Device type based matching */ -+static bool type_match(SysBusDevice *sbdev, const BindingEntry *entry) -+{ -+ return !strcmp(object_get_typename(OBJECT(sbdev)), entry->typename); -+} -+ -+#define TYPE_BINDING(type, add_fn) \ -+ { \ -+ (type), NULL, (add_fn), NULL \ -+ } -+ -+#ifdef CONFIG_TPM -+/* -+ * add_tpm_tis_fdt_node: Create a DT node for TPM TIS -+ * -+ * See kernel documentation: -+ * Documentation/devicetree/bindings/security/tpm/tpm_tis_mmio.txt -+ * Optional interrupt for command completion is not exposed -+ */ -+static int add_tpm_tis_fdt_node(SysBusDevice *sbdev, void *opaque) -+{ -+ PlatformBusFDTData *data = opaque; -+ PlatformBusDevice *pbus = data->pbus; -+ void *fdt = data->fdt; -+ const char *parent_node = data->pbus_node_name; -+ char *nodename; -+ uint32_t reg_attr[2]; -+ uint64_t mmio_base; -+ -+ mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); -+ nodename = g_strdup_printf("%s/tpm_tis@%" PRIx64, parent_node, mmio_base); -+ qemu_fdt_add_subnode(fdt, nodename); -+ -+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "tcg,tpm-tis-mmio"); -+ -+ reg_attr[0] = cpu_to_be32(mmio_base); -+ reg_attr[1] = cpu_to_be32(0x5000); -+ qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 2 * sizeof(uint32_t)); -+ -+ g_free(nodename); -+ -+ return 0; -+} -+#endif -+ -+/* list of supported dynamic sysbus bindings */ -+static const BindingEntry bindings[] = { -+#ifdef CONFIG_TPM -+ TYPE_BINDING(TYPE_TPM_TIS_SYSBUS, add_tpm_tis_fdt_node), -+#endif -+ TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node), -+ TYPE_BINDING("", NULL), /* last element */ -+}; -+ -+/** -+ * add_fdt_node - add the device tree node of a dynamic sysbus device -+ * -+ * @sbdev: handle to the sysbus device -+ * @opaque: handle to the PlatformBusFDTData -+ * -+ * Checks the sysbus type belongs to the list of device types that -+ * are dynamically instantiable and if so call the node creation -+ * function. -+ */ -+static void add_fdt_node(SysBusDevice *sbdev, void *opaque) -+{ -+ int i, ret; -+ -+ for (i = 0; i < ARRAY_SIZE(bindings); i++) { -+ const BindingEntry *iter = &bindings[i]; -+ -+ if (type_match(sbdev, iter)) { -+ if (!iter->match_fn || iter->match_fn(sbdev, iter)) { -+ ret = iter->add_fn(sbdev, opaque); -+ assert(!ret); -+ return; -+ } -+ } -+ } -+ error_report("Device %s can not be dynamically instantiated", -+ qdev_fw_name(DEVICE(sbdev))); -+ exit(1); -+} -+ -+void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, -+ hwaddr bus_size, int irq_start) -+{ -+ const char platcomp[] = "qemu,platform\0simple-bus"; -+ PlatformBusDevice *pbus; -+ DeviceState *dev; -+ gchar *node; -+ -+ assert(fdt); -+ -+ node = g_strdup_printf("/platform@%" PRIx64, addr); -+ -+ /* Create a /platform node that we can put all devices into */ -+ qemu_fdt_add_subnode(fdt, node); -+ qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp)); -+ -+ /* -+ * Our platform bus region is less than 32bits, so 1 cell is enough for -+ * address and size -+ */ -+ qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1); -+ qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1); -+ qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, bus_size); -+ if (intc != NULL) { -+ qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", intc); -+ } -+ dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE); -+ pbus = PLATFORM_BUS_DEVICE(dev); -+ -+ PlatformBusFDTData data = { -+ .fdt = fdt, -+ .irq_start = irq_start, -+ .pbus_node_name = node, -+ .pbus = pbus, -+ }; -+ -+ /* Loop through all dynamic sysbus devices and create their node */ -+ foreach_dynamic_sysbus_device(add_fdt_node, &data); -+ -+ g_free(node); -+} -diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h -index 4590bcc968..b165453fa1 100644 ---- a/include/disas/dis-asm.h -+++ b/include/disas/dis-asm.h -@@ -336,7 +336,7 @@ typedef struct disassemble_info { - Returns an errno value or 0 for success. */ - int (*read_memory_func) - (bfd_vma memaddr, bfd_byte *myaddr, int length, -- struct disassemble_info *info); -+ struct disassemble_info *info); - - /* Function which should be called if we get an error that we can't - recover from. STATUS is the errno value from read_memory_func and -@@ -465,6 +465,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/include/elf.h b/include/elf.h -index 79c188b62f..cd7808f37a 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_LOONGARCH 258 /* Loongarch */ -+ - /* - * This is an interim value that we will use until the committee comes - * up with a final number. -diff --git a/include/hw/loongarch/bios.h b/include/hw/loongarch/bios.h -new file mode 100644 -index 0000000000..8e0f6c7d64 ---- /dev/null -+++ b/include/hw/loongarch/bios.h -@@ -0,0 +1,24 @@ -+/* -+ * bios on Loongarch system. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/units.h" -+#include "cpu.h" -+ -+#define BIOS_SIZE (4 * MiB) -+#define BIOS_FILENAME "loongarch_bios.bin" -diff --git a/include/hw/loongarch/cpudevs.h b/include/hw/loongarch/cpudevs.h -new file mode 100644 -index 0000000000..ea4007f8fa ---- /dev/null -+++ b/include/hw/loongarch/cpudevs.h -@@ -0,0 +1,71 @@ -+/* -+ * cpu device emulation on Loongarch system. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef HW_LOONGARCH_CPUDEVS_H -+#define HW_LOONGARCH_CPUDEVS_H -+ -+#include "target/loongarch64/cpu-qom.h" -+ -+/* Definitions for LOONGARCH CPU internal devices. */ -+#define MAX_GIPI_CORE_NUM 256 -+#define MAX_GIPI_MBX_NUM 4 -+ -+#define LS3A_INTC_IP 8 -+#define MAX_CORES 256 -+#define EXTIOI_IRQS (256) -+#define EXTIOI_IRQS_BITMAP_SIZE (256 / 8) -+/* map to ipnum per 32 irqs */ -+#define EXTIOI_IRQS_IPMAP_SIZE (256 / 32) -+ -+typedef struct gipi_core { -+ uint32_t status; -+ uint32_t en; -+ uint32_t set; -+ uint32_t clear; -+ uint64_t buf[MAX_GIPI_MBX_NUM]; -+ qemu_irq irq; -+} gipi_core; -+ -+typedef struct gipiState { -+ gipi_core core[MAX_GIPI_CORE_NUM]; -+} gipiState; -+ -+typedef struct apicState { -+ /* hardware state */ -+ uint8_t ext_en[EXTIOI_IRQS_BITMAP_SIZE]; -+ uint8_t ext_bounce[EXTIOI_IRQS_BITMAP_SIZE]; -+ uint8_t ext_isr[EXTIOI_IRQS_BITMAP_SIZE]; -+ uint8_t ext_coreisr[MAX_CORES][EXTIOI_IRQS_BITMAP_SIZE]; -+ uint8_t ext_ipmap[EXTIOI_IRQS_IPMAP_SIZE]; -+ uint8_t ext_coremap[EXTIOI_IRQS]; -+ uint16_t ext_nodetype[16]; -+ uint64_t ext_control; -+ -+ /* software state */ -+ uint8_t ext_sw_ipmap[EXTIOI_IRQS]; -+ uint8_t ext_sw_coremap[EXTIOI_IRQS]; -+ uint8_t ext_ipisr[MAX_CORES * LS3A_INTC_IP][EXTIOI_IRQS_BITMAP_SIZE]; -+ -+ qemu_irq parent_irq[MAX_CORES][LS3A_INTC_IP]; -+ qemu_irq *irq; -+} apicState; -+ -+void cpu_init_irq(LOONGARCHCPU *cpu); -+void cpu_loongarch_clock_init(LOONGARCHCPU *cpu); -+#endif -diff --git a/include/hw/loongarch/larch.h b/include/hw/loongarch/larch.h -new file mode 100644 -index 0000000000..a9f8dea9f5 ---- /dev/null -+++ b/include/hw/loongarch/larch.h -@@ -0,0 +1,164 @@ -+/* -+ * Hotplug emulation on Loongarch system. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef HW_LOONGARCH_H -+#define HW_LOONGARCH_H -+ -+#include "target/loongarch64/cpu.h" -+#include "qemu-common.h" -+#include "exec/memory.h" -+#include "hw/mem/pc-dimm.h" -+#include "hw/hotplug.h" -+#include "hw/boards.h" -+#include "hw/acpi/acpi.h" -+#include "qemu/notify.h" -+#include "qemu/error-report.h" -+#include "qemu/queue.h" -+#include "hw/acpi/memory_hotplug.h" -+#include "hw/loongarch/cpudevs.h" -+#include "hw/block/flash.h" -+ -+#define LOONGARCH_MAX_VCPUS 256 -+#define LOONGARCH_MAX_PFLASH 2 -+/* 256MB alignment for hotplug memory region */ -+#define LOONGARCH_HOTPLUG_MEM_ALIGN (1ULL << 28) -+#define LOONGARCH_MAX_RAM_SLOTS 10 -+ -+/* Memory types: */ -+#define SYSTEM_RAM 1 -+#define SYSTEM_RAM_RESERVED 2 -+#define ACPI_TABLE 3 -+#define ACPI_NVS 4 -+#define SYSTEM_PMEM 5 -+ -+#define MAX_MEM_MAP 128 -+ -+typedef struct LoongarchMachineClass { -+ /*< private >*/ -+ MachineClass parent_class; -+ -+ /* Methods: */ -+ HotplugHandler *(*get_hotplug_handler)(MachineState *machine, -+ DeviceState *dev); -+ -+ bool has_acpi_build; -+ -+ /* save different cpu address*/ -+ uint64_t isa_io_base; -+ uint64_t ht_control_regs_base; -+ uint64_t hpet_mmio_addr; -+ uint64_t smbus_cfg_base; -+ uint64_t pciecfg_base; -+ uint64_t ls7a_ioapic_reg_base; -+ uint32_t node_shift; -+ char cpu_name[40]; -+ char bridge_name[16]; -+ -+} LoongarchMachineClass; -+ -+typedef struct ResetData { -+ LOONGARCHCPU *cpu; -+ uint64_t vector; -+} ResetData; -+ -+typedef struct LoongarchMachineState { -+ /*< private >*/ -+ MachineState parent_obj; -+ -+ /* */ -+ ram_addr_t hotplug_memory_size; -+ -+ /* State for other subsystems/APIs: */ -+ Notifier machine_done; -+ /* Pointers to devices and objects: */ -+ HotplugHandler *acpi_dev; -+ int ram_slots; -+ ResetData *reset_info[LOONGARCH_MAX_VCPUS]; -+ DeviceState *rtc; -+ gipiState *gipi; -+ apicState *apic; -+ -+ FWCfgState *fw_cfg; -+ bool acpi_build_enabled; -+ bool apic_xrupt_override; -+ CPUArchIdList *possible_cpus; -+ PFlashCFI01 *flash[LOONGARCH_MAX_PFLASH]; -+ void *fdt; -+ int fdt_size; -+ unsigned int hotpluged_cpu_num; -+ DeviceState *platform_bus_dev; -+ OnOffAuto acpi; -+ char *oem_id; -+ char *oem_table_id; -+} LoongarchMachineState; -+ -+#define LOONGARCH_MACHINE_ACPI_DEVICE_PROP "loongarch-acpi-device" -+#define TYPE_LOONGARCH_MACHINE "loongarch-machine" -+ -+#define LoongarchMACHINE(obj) \ -+ OBJECT_CHECK(LoongarchMachineState, (obj), TYPE_LOONGARCH_MACHINE) -+#define LoongarchMACHINE_GET_CLASS(obj) \ -+ OBJECT_GET_CLASS(LoongarchMachineClass, (obj), TYPE_LOONGARCH_MACHINE) -+#define LoongarchMACHINE_CLASS(klass) \ -+ OBJECT_CLASS_CHECK(LoongarchMachineClass, (klass), TYPE_LOONGARCH_MACHINE) -+ -+#define DEFINE_LOONGARCH_MACHINE(suffix, namestr, initfn, optsfn) \ -+ static void loongarch_machine_##suffix##_class_init(ObjectClass *oc, \ -+ void *data) \ -+ { \ -+ MachineClass *mc = MACHINE_CLASS(oc); \ -+ optsfn(mc); \ -+ mc->init = initfn; \ -+ } \ -+ static const TypeInfo loongarch_machine_type_##suffix = { \ -+ .name = namestr TYPE_MACHINE_SUFFIX, \ -+ .parent = TYPE_LOONGARCH_MACHINE, \ -+ .class_init = loongarch_machine_##suffix##_class_init, \ -+ }; \ -+ static void loongarch_machine_init_##suffix(void) \ -+ { \ -+ type_register(&loongarch_machine_type_##suffix); \ -+ } \ -+ type_init(loongarch_machine_init_##suffix) -+ -+void loongarch_machine_device_unplug_request(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+void longson_machine_device_unplug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+HotplugHandler *loongarch_get_hotpug_handler(MachineState *machine, -+ DeviceState *dev); -+void loongarch_machine_device_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+void loongarch_machine_device_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp); -+ -+LOONGARCHCPU *loongarch_cpu_create(MachineState *machine, LOONGARCHCPU *cpu, -+ Error **errp); -+void loongarch_cpu_destroy(MachineState *machine, LOONGARCHCPU *cpu); -+int cpu_init_ipi(LoongarchMachineState *ms, qemu_irq parent, int cpu); -+int cpu_init_apic(LoongarchMachineState *ms, CPULOONGARCHState *env, int cpu); -+int la_memmap_add_entry(uint64_t address, uint64_t length, uint32_t type); -+bool loongarch_is_acpi_enabled(LoongarchMachineState *vms); -+ -+/* acpi-build.c */ -+void ls7a_madt_cpu_entry(AcpiDeviceIf *adev, int uid, -+ const CPUArchIdList *apic_ids, GArray *entry, -+ bool force_enabled); -+void slave_cpu_reset(void *opaque); -+#endif -diff --git a/include/hw/loongarch/ls7a.h b/include/hw/loongarch/ls7a.h -new file mode 100644 -index 0000000000..e1f3c8d032 ---- /dev/null -+++ b/include/hw/loongarch/ls7a.h -@@ -0,0 +1,167 @@ -+/* -+ * Acpi emulation on Loongarch system. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef HW_LS7A_H -+#define HW_LS7A_H -+ -+#include "hw/hw.h" -+#include "hw/isa/isa.h" -+#include "hw/sysbus.h" -+#include "hw/isa/apm.h" -+#include "hw/pci/pci.h" -+#include "hw/pci/pcie_host.h" -+#include "hw/pci/pci_bridge.h" -+#include "hw/acpi/acpi.h" -+#include "hw/acpi/ls7a.h" -+#include "hw/pci/pci_bus.h" -+ -+/* LS7A PCH Registers (Misc, Confreg) */ -+#define LS7A_PCH_REG_BASE 0x10000000UL -+#define LS3A5K_LS7A_IOAPIC_REG_BASE (LS7A_PCH_REG_BASE) -+#define LS7A_MISC_REG_BASE (LS7A_PCH_REG_BASE + 0x00080000) -+#define LS7A_ACPI_REG_BASE (LS7A_MISC_REG_BASE + 0x00050000) -+ -+#define LOONGARCH_PCH_IRQ_BASE 64 -+#define LS7A_UART_IRQ (LOONGARCH_PCH_IRQ_BASE + 2) -+#define LS7A_RTC_IRQ (LOONGARCH_PCH_IRQ_BASE + 3) -+#define LS7A_SCI_IRQ (LOONGARCH_PCH_IRQ_BASE + 4) -+#define LS7A_ACPI_IO_BASE 0x800 -+#define LS7A_ACPI_IO_SIZE 0x100 -+#define LS7A_PM_EVT_BLK (0x0C) /* 4 bytes */ -+#define LS7A_PM_CNT_BLK (0x14) /* 2 bytes */ -+#define LS7A_GPE0_STS_REG (0x28) /* 4 bytes */ -+#define LS7A_GPE0_ENA_REG (0x2C) /* 4 bytes */ -+#define LS7A_GPE0_RESET_REG (0x30) /* 4 bytes */ -+#define LS7A_PM_TMR_BLK (0x18) /* 4 bytes */ -+#define LS7A_GPE0_LEN (8) -+#define LS7A_RTC_REG_BASE (LS7A_MISC_REG_BASE + 0x00050100) -+#define LS7A_RTC_LEN (0x100) -+ -+#define ACPI_IO_BASE (LS7A_ACPI_REG_BASE) -+#define ACPI_GPE0_LEN (LS7A_GPE0_LEN) -+#define ACPI_IO_SIZE (LS7A_ACPI_IO_SIZE) -+#define ACPI_SCI_IRQ (LS7A_SCI_IRQ) -+ -+#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 -+#define VIRT_PLATFORM_BUS_SIZE 0x02000000 -+#define VIRT_PLATFORM_BUS_NUM_IRQS 2 -+#define VIRT_PLATFORM_BUS_IRQ (LOONGARCH_PCH_IRQ_BASE + 5) -+ -+#define LS3A5K_ISA_IO_BASE 0x18000000UL -+#define LS_BIOS_BASE 0x1c000000 -+#define LS_BIOS_VAR_BASE 0x1c3a0000 -+#define LS_BIOS_SIZE (4 * 1024 * 1024) -+#define LS_FDT_BASE 0x1c400000 -+#define LS_FDT_SIZE 0x00100000 -+ -+#define FW_CFG_ADDR 0x1e020000 -+#define LS7A_REG_BASE 0x1FE00000 -+#define LS7A_UART_BASE 0x1fe001e0 -+#define LS7A_UART_LEN 0x8 -+#define SMP_GIPI_MAILBOX 0x1f000000ULL -+#define CORE0_STATUS_OFF 0x000 -+#define CORE0_EN_OFF 0x004 -+#define CORE0_SET_OFF 0x008 -+#define CORE0_CLEAR_OFF 0x00c -+#define CORE0_BUF_20 0x020 -+#define CORE0_BUF_28 0x028 -+#define CORE0_BUF_30 0x030 -+#define CORE0_BUF_38 0x038 -+#define CORE0_IPI_SEND 0x040 -+#define CORE0_MAIL_SEND 0x048 -+#define INT_ROUTER_REGS_BASE 0x1fe01400UL -+#define INT_ROUTER_REGS_SIZE 0x100 -+#define INT_ROUTER_REGS_SYS_INT0 0x00 -+#define INT_ROUTER_REGS_SYS_INT1 0x01 -+#define INT_ROUTER_REGS_SYS_INT2 0x02 -+#define INT_ROUTER_REGS_SYS_INT3 0x03 -+#define INT_ROUTER_REGS_PCI_INT0 0x04 -+#define INT_ROUTER_REGS_PCI_INT1 0x05 -+#define INT_ROUTER_REGS_PCI_INT2 0x06 -+#define INT_ROUTER_REGS_PCI_INT3 0x07 -+#define INT_ROUTER_REGS_MATRIX_INT0 0x08 -+#define INT_ROUTER_REGS_MATRIX_INT1 0x09 -+#define INT_ROUTER_REGS_LPC_INT 0x0a -+#define INT_ROUTER_REGS_MC0 0x0b -+#define INT_ROUTER_REGS_MC1 0x0c -+#define INT_ROUTER_REGS_BARRIER 0x0d -+#define INT_ROUTER_REGS_THSENS_INT 0x0e -+#define INT_ROUTER_REGS_PCI_PERR 0x0f -+#define INT_ROUTER_REGS_HT0_INT0 0x10 -+#define INT_ROUTER_REGS_HT0_INT1 0x11 -+#define INT_ROUTER_REGS_HT0_INT2 0x12 -+#define INT_ROUTER_REGS_HT0_INT3 0x13 -+#define INT_ROUTER_REGS_HT0_INT4 0x14 -+#define INT_ROUTER_REGS_HT0_INT5 0x15 -+#define INT_ROUTER_REGS_HT0_INT6 0x16 -+#define INT_ROUTER_REGS_HT0_INT7 0x17 -+#define INT_ROUTER_REGS_HT1_INT0 0x18 -+#define INT_ROUTER_REGS_HT1_INT1 0x19 -+#define INT_ROUTER_REGS_HT1_INT2 0x1a -+#define INT_ROUTER_REGS_HT1_INT3 0x1b -+#define INT_ROUTER_REGS_HT1_INT4 0x1c -+#define INT_ROUTER_REGS_HT1_INT5 0x1d -+#define INT_ROUTER_REGS_HT1_INT6 0x1e -+#define INT_ROUTER_REGS_HT1_INT7 0x1f -+#define INT_ROUTER_REGS_ISR 0x20 -+#define INT_ROUTER_REGS_EN 0x24 -+#define INT_ROUTER_REGS_EN_SET 0x28 -+#define INT_ROUTER_REGS_EN_CLR 0x2c -+#define INT_ROUTER_REGS_EDGE 0x38 -+#define INT_ROUTER_REGS_CORE0_INTISR 0x40 -+#define INT_ROUTER_REGS_CORE1_INTISR 0x48 -+#define INT_ROUTER_REGS_CORE2_INTISR 0x50 -+#define INT_ROUTER_REGS_CORE3_INTISR 0x58 -+ -+#define LS_PCIECFG_BASE 0x20000000 -+#define LS_PCIECFG_SIZE 0x08000000 -+#define MSI_ADDR_LOW 0x2FF00000 -+#define MSI_ADDR_HI 0x0 -+ -+#define PCIE_MEMORY_BASE 0x40000000 -+#define PCIE_MEMORY_SIZE 0x40000000 -+ -+typedef struct LS7APCIState LS7APCIState; -+typedef struct LS7APCIEHost { -+ PCIExpressHost parent_obj; -+ LS7APCIState *pci_dev; -+} LS7APCIEHost; -+ -+struct LS7APCIState { -+ PCIDevice dev; -+ -+ LS7APCIEHost *pciehost; -+ -+ /* LS7A registers */ -+ MemoryRegion iomem; -+ LS7APCIPMRegs pm; -+}; -+ -+#define TYPE_LS7A_PCIE_HOST_BRIDGE "ls7a1000-pciehost" -+#define LS7A_PCIE_HOST_BRIDGE(obj) \ -+ OBJECT_CHECK(LS7APCIEHost, (obj), TYPE_LS7A_PCIE_HOST_BRIDGE) -+ -+#define TYPE_PCIE_LS7A "ls7a1000_pcie" -+#define PCIE_LS7A(obj) OBJECT_CHECK(LS7APCIState, (obj), TYPE_PCIE_LS7A) -+ -+PCIBus *ls7a_init(MachineState *machine, qemu_irq *irq, -+ DeviceState **ls7a_dev); -+LS7APCIState *get_ls7a_type(Object *obj); -+ -+#endif /* HW_LS7A_H */ -diff --git a/include/hw/loongarch/sysbus-fdt.h b/include/hw/loongarch/sysbus-fdt.h -new file mode 100644 -index 0000000000..6bf53097e1 ---- /dev/null -+++ b/include/hw/loongarch/sysbus-fdt.h -@@ -0,0 +1,33 @@ -+/* -+ * Dynamic sysbus device tree node generation API -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef HW_ARM_SYSBUS_FDT_H -+#define HW_ARM_SYSBUS_FDT_H -+ -+#include "exec/hwaddr.h" -+ -+/** -+ * platform_bus_add_all_fdt_nodes - create all the platform bus nodes -+ * -+ * builds the parent platform bus node and all the nodes of dynamic -+ * sysbus devices attached to it. -+ */ -+void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr, -+ hwaddr bus_size, int irq_start); -+#endif -diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h -index 60718fc342..fd9e53f623 100644 ---- a/include/qemu/osdep.h -+++ b/include/qemu/osdep.h -@@ -533,6 +533,10 @@ static inline void qemu_cleanup_generic_vfree(void *p) - Valgrind does not support alignments larger than 1 MiB, - therefore we need special code which handles running on Valgrind. */ - # define QEMU_VMALLOC_ALIGN (512 * 4096) -+#elif defined(__linux__) && defined(__loongarch__) -+ /* Use 32 MiB alignment so transparent hugepages can be used by KVM. */ -+#define QEMU_VMALLOC_ALIGN (qemu_real_host_page_size * \ -+ qemu_real_host_page_size / 8) - #elif defined(__linux__) && defined(__s390x__) - /* Use 1 MiB (segment size) alignment so gmap can be used by KVM. */ - # define QEMU_VMALLOC_ALIGN (256 * 4096) --- -2.27.0 - diff --git a/Add-target-loongarch64.patch b/Add-target-loongarch64.patch deleted file mode 100644 index 4d6324c6acb305a1661b580e4a052e18dfdf51ab..0000000000000000000000000000000000000000 --- a/Add-target-loongarch64.patch +++ /dev/null @@ -1,15466 +0,0 @@ -From 9aefc417ef8c705503b51b844b489598448656d0 Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 07:15:39 -0500 -Subject: [PATCH] Add target/loongarch64. - -1.Add loongarch cpu simulation. -2.Add loongarch csr simulation. -3.Add loongarch fpu support. -4.Add loongarch gdb support. -5.Add loongarhch kvm support. -6.Add loongarch stable timer. -7.Add loongarch tcg related support. - -Signed-off-by: lixianglai ---- - target/Kconfig | 1 + - target/loongarch64/Kconfig | 2 + - target/loongarch64/arch_dump.c | 179 ++ - target/loongarch64/cpu-csr.h | 880 ++++++++ - target/loongarch64/cpu-param.h | 46 + - target/loongarch64/cpu-qom.h | 54 + - target/loongarch64/cpu.c | 575 +++++ - target/loongarch64/cpu.h | 359 +++ - target/loongarch64/csr_helper.c | 697 ++++++ - target/loongarch64/fpu.c | 25 + - target/loongarch64/fpu_helper.c | 891 ++++++++ - target/loongarch64/fpu_helper.h | 127 ++ - target/loongarch64/gdbstub.c | 164 ++ - target/loongarch64/helper.c | 726 +++++++ - target/loongarch64/helper.h | 178 ++ - target/loongarch64/insn.decode | 532 +++++ - target/loongarch64/instmap.h | 217 ++ - target/loongarch64/internal.h | 207 ++ - target/loongarch64/kvm.c | 1366 ++++++++++++ - target/loongarch64/kvm_larch.h | 49 + - target/loongarch64/larch-defs.h | 42 + - target/loongarch64/machine.c | 423 ++++ - target/loongarch64/meson.build | 35 + - target/loongarch64/op_helper.c | 485 +++++ - target/loongarch64/stabletimer.c | 117 + - target/loongarch64/tlb_helper.c | 641 ++++++ - target/loongarch64/trans.inc.c | 3482 ++++++++++++++++++++++++++++++ - target/loongarch64/translate.c | 2705 +++++++++++++++++++++++ - target/meson.build | 1 + - 29 files changed, 15206 insertions(+) - create mode 100644 target/loongarch64/Kconfig - create mode 100644 target/loongarch64/arch_dump.c - create mode 100644 target/loongarch64/cpu-csr.h - create mode 100644 target/loongarch64/cpu-param.h - create mode 100644 target/loongarch64/cpu-qom.h - create mode 100644 target/loongarch64/cpu.c - create mode 100644 target/loongarch64/cpu.h - create mode 100644 target/loongarch64/csr_helper.c - create mode 100644 target/loongarch64/fpu.c - create mode 100644 target/loongarch64/fpu_helper.c - create mode 100644 target/loongarch64/fpu_helper.h - create mode 100644 target/loongarch64/gdbstub.c - create mode 100644 target/loongarch64/helper.c - create mode 100644 target/loongarch64/helper.h - create mode 100644 target/loongarch64/insn.decode - create mode 100644 target/loongarch64/instmap.h - create mode 100644 target/loongarch64/internal.h - create mode 100644 target/loongarch64/kvm.c - create mode 100644 target/loongarch64/kvm_larch.h - create mode 100644 target/loongarch64/larch-defs.h - create mode 100644 target/loongarch64/machine.c - create mode 100644 target/loongarch64/meson.build - create mode 100644 target/loongarch64/op_helper.c - create mode 100644 target/loongarch64/stabletimer.c - create mode 100644 target/loongarch64/tlb_helper.c - create mode 100644 target/loongarch64/trans.inc.c - create mode 100644 target/loongarch64/translate.c - -diff --git a/target/Kconfig b/target/Kconfig -index a8d6cb1e97..b2abc7b60b 100644 ---- a/target/Kconfig -+++ b/target/Kconfig -@@ -4,6 +4,7 @@ source avr/Kconfig - source cris/Kconfig - source hppa/Kconfig - source i386/Kconfig -+source loongarch64/Kconfig - source m68k/Kconfig - source microblaze/Kconfig - source mips/Kconfig -diff --git a/target/loongarch64/Kconfig b/target/loongarch64/Kconfig -new file mode 100644 -index 0000000000..46b26b1a85 ---- /dev/null -+++ b/target/loongarch64/Kconfig -@@ -0,0 +1,2 @@ -+config LOONGARCH64 -+ bool -diff --git a/target/loongarch64/arch_dump.c b/target/loongarch64/arch_dump.c -new file mode 100644 -index 0000000000..adce817d54 ---- /dev/null -+++ b/target/loongarch64/arch_dump.c -@@ -0,0 +1,179 @@ -+/* -+ * Support for writing ELF notes for RM architectures -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "elf.h" -+#include "sysemu/dump.h" -+#include "internal.h" -+ -+/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */ -+struct loongarch_user_regs { -+ uint64_t gpr[32]; -+ uint64_t lo; -+ uint64_t hi; -+ uint64_t csr_era; -+ uint64_t csr_badvaddr; -+ uint64_t csr_crmd; -+ uint64_t csr_ecfg; -+ uint64_t pad[7]; -+} QEMU_PACKED; -+ -+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_user_regs) != 360); -+ -+/* struct elf_prstatus from include/uapi/linux/elfcore.h */ -+struct loongarch_elf_prstatus { -+ char pad1[32]; /* 32 == offsetof(struct elf_prstatus, pr_pid) */ -+ uint32_t pr_pid; -+ /* -+ * 76 == offsetof(struct elf_prstatus, pr_reg) - -+ * offsetof(struct elf_prstatus, pr_ppid) -+ */ -+ char pad2[76]; -+ struct loongarch_user_regs pr_reg; -+ uint32_t pr_fpvalid; -+ char pad3[4]; -+} QEMU_PACKED; -+ -+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_elf_prstatus) != 480); -+ -+/* -+ * struct user_fpsimd_state from arch/arm64/include/uapi/asm/ptrace.h -+ * -+ * While the vregs member of user_fpsimd_state is of type __uint128_t, -+ * QEMU uses an array of uint64_t, where the high half of the 128-bit -+ * value is always in the 2n+1'th index. Thus we also break the 128- -+ * bit values into two halves in this reproduction of user_fpsimd_state. -+ */ -+ -+struct loongarch_fpu_struct { -+ uint64_t fpr[32]; -+ unsigned int fir; -+ unsigned int fcsr; -+} QEMU_PACKED; -+ -+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_fpu_struct) != 264); -+ -+struct loongarch_note { -+ Elf64_Nhdr hdr; -+ char name[8]; /* align_up(sizeof("CORE"), 4) */ -+ union -+ { -+ struct loongarch_elf_prstatus prstatus; -+ struct loongarch_fpu_struct fpu; -+ }; -+} QEMU_PACKED; -+ -+#define LOONGARCH_NOTE_HEADER_SIZE offsetof(struct loongarch_note, prstatus) -+#define LOONGARCH_PRSTATUS_NOTE_SIZE \ -+ (LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_elf_prstatus)) -+#define LOONGARCH_PRFPREG_NOTE_SIZE \ -+ (LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_fpu_struct)) -+ -+static void loongarch_note_init(struct loongarch_note *note, DumpState *s, -+ const char *name, Elf64_Word namesz, -+ Elf64_Word type, Elf64_Word descsz) -+{ -+ memset(note, 0, sizeof(*note)); -+ -+ note->hdr.n_namesz = cpu_to_dump32(s, namesz); -+ note->hdr.n_descsz = cpu_to_dump32(s, descsz); -+ note->hdr.n_type = cpu_to_dump32(s, type); -+ -+ memcpy(note->name, name, namesz); -+} -+ -+static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f, -+ CPULOONGARCHState *env, int cpuid, -+ DumpState *s) -+{ -+ struct loongarch_note note; -+ int ret, i; -+ -+ loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu)); -+ -+ note.fpu.fcsr = cpu_to_dump64(s, env->active_fpu.fcsr0); -+ -+ for (i = 0; i < 32; ++i) { -+ note.fpu.fpr[i] = cpu_to_dump64(s, env->active_fpu.fpr[i].fd); -+ } -+ -+ ret = f(¬e, LOONGARCH_PRFPREG_NOTE_SIZE, s); -+ if (ret < 0) { -+ return -1; -+ } -+ -+ return 0; -+} -+ -+int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, -+ int cpuid, void *opaque) -+{ -+ struct loongarch_note note; -+ CPULOONGARCHState *env = &LOONGARCH_CPU(cs)->env; -+ DumpState *s = opaque; -+ int ret, i; -+ -+ loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS, -+ sizeof(note.prstatus)); -+ -+ note.prstatus.pr_pid = cpu_to_dump32(s, cpuid); -+ note.prstatus.pr_fpvalid = cpu_to_dump32(s, 1); -+ -+ for (i = 0; i < 32; ++i) { -+ note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->active_tc.gpr[i]); -+ } -+ note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA); -+ note.prstatus.pr_reg.csr_badvaddr = cpu_to_dump64(s, env->CSR_BADV); -+ note.prstatus.pr_reg.csr_crmd = cpu_to_dump64(s, env->CSR_CRMD); -+ note.prstatus.pr_reg.csr_ecfg = cpu_to_dump64(s, env->CSR_ECFG); -+ -+ ret = f(¬e, LOONGARCH_PRSTATUS_NOTE_SIZE, s); -+ if (ret < 0) { -+ return -1; -+ } -+ -+ ret = loongarch_write_elf64_fprpreg(f, env, cpuid, s); -+ if (ret < 0) { -+ return -1; -+ } -+ -+ return ret; -+} -+ -+int cpu_get_dump_info(ArchDumpInfo *info, -+ const GuestPhysBlockList *guest_phys_blocks) -+{ -+ info->d_machine = EM_LOONGARCH; -+ info->d_endian = ELFDATA2LSB; -+ info->d_class = ELFCLASS64; -+ -+ return 0; -+} -+ -+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) -+{ -+ size_t note_size = 0; -+ -+ if (class == ELFCLASS64) { -+ note_size = LOONGARCH_PRSTATUS_NOTE_SIZE + LOONGARCH_PRFPREG_NOTE_SIZE; -+ } -+ -+ return note_size * nr_cpus; -+} -diff --git a/target/loongarch64/cpu-csr.h b/target/loongarch64/cpu-csr.h -new file mode 100644 -index 0000000000..278a66c395 ---- /dev/null -+++ b/target/loongarch64/cpu-csr.h -@@ -0,0 +1,880 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef _CPU_CSR_H_ -+#define _CPU_CSR_H_ -+ -+/* basic CSR register */ -+#define LOONGARCH_CSR_CRMD 0x0 /* 32 current mode info */ -+#define CSR_CRMD_DACM_SHIFT 7 -+#define CSR_CRMD_DACM_WIDTH 2 -+#define CSR_CRMD_DACM (0x3UL << CSR_CRMD_DACM_SHIFT) -+#define CSR_CRMD_DACF_SHIFT 5 -+#define CSR_CRMD_DACF_WIDTH 2 -+#define CSR_CRMD_DACF (0x3UL << CSR_CRMD_DACF_SHIFT) -+#define CSR_CRMD_PG_SHIFT 4 -+#define CSR_CRMD_PG (0x1UL << CSR_CRMD_PG_SHIFT) -+#define CSR_CRMD_DA_SHIFT 3 -+#define CSR_CRMD_DA (0x1UL << CSR_CRMD_DA_SHIFT) -+#define CSR_CRMD_IE_SHIFT 2 -+#define CSR_CRMD_IE (0x1UL << CSR_CRMD_IE_SHIFT) -+#define CSR_CRMD_PLV_SHIFT 0 -+#define CSR_CRMD_PLV_WIDTH 2 -+#define CSR_CRMD_PLV (0x3UL << CSR_CRMD_PLV_SHIFT) -+ -+#define PLV_USER 3 -+#define PLV_KERN 0 -+#define PLV_MASK 0x3 -+ -+#define LOONGARCH_CSR_PRMD 0x1 /* 32 prev-exception mode info */ -+#define CSR_PRMD_PIE_SHIFT 2 -+#define CSR_PRMD_PIE (0x1UL << CSR_PRMD_PIE_SHIFT) -+#define CSR_PRMD_PPLV_SHIFT 0 -+#define CSR_PRMD_PPLV_WIDTH 2 -+#define CSR_PRMD_PPLV (0x3UL << CSR_PRMD_PPLV_SHIFT) -+ -+#define LOONGARCH_CSR_EUEN 0x2 /* 32 coprocessor enable */ -+#define CSR_EUEN_LBTEN_SHIFT 3 -+#define CSR_EUEN_LBTEN (0x1UL << CSR_EUEN_LBTEN_SHIFT) -+#define CSR_EUEN_LASXEN_SHIFT 2 -+#define CSR_EUEN_LASXEN (0x1UL << CSR_EUEN_LASXEN_SHIFT) -+#define CSR_EUEN_LSXEN_SHIFT 1 -+#define CSR_EUEN_LSXEN (0x1UL << CSR_EUEN_LSXEN_SHIFT) -+#define CSR_EUEN_FPEN_SHIFT 0 -+#define CSR_EUEN_FPEN (0x1UL << CSR_EUEN_FPEN_SHIFT) -+ -+#define LOONGARCH_CSR_MISC 0x3 /* 32 misc config */ -+ -+#define LOONGARCH_CSR_ECFG 0x4 /* 32 exception config */ -+#define CSR_ECFG_VS_SHIFT 16 -+#define CSR_ECFG_VS_WIDTH 3 -+#define CSR_ECFG_VS (0x7UL << CSR_ECFG_VS_SHIFT) -+#define CSR_ECFG_IM_SHIFT 0 -+#define CSR_ECFG_IM_WIDTH 13 -+#define CSR_ECFG_IM (0x1fffUL << CSR_ECFG_IM_SHIFT) -+ -+#define CSR_ECFG_IPMASK 0x00001fff -+ -+#define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */ -+#define CSR_ESTAT_ESUBCODE_SHIFT 22 -+#define CSR_ESTAT_ESUBCODE_WIDTH 9 -+#define CSR_ESTAT_ESUBCODE (0x1ffULL << CSR_ESTAT_ESUBCODE_SHIFT) -+#define CSR_ESTAT_EXC_SH 16 -+#define CSR_ESTAT_EXC_WIDTH 5 -+#define CSR_ESTAT_EXC (0x1fULL << CSR_ESTAT_EXC_SH) -+#define CSR_ESTAT_IS_SHIFT 0 -+#define CSR_ESTAT_IS_WIDTH 15 -+#define CSR_ESTAT_IS (0x7fffULL << CSR_ESTAT_IS_SHIFT) -+ -+#define CSR_ESTAT_IPMASK 0x00001fff -+ -+#define EXCODE_IP 64 -+#define EXCCODE_RSV 0 -+#define EXCCODE_TLBL 1 -+#define EXCCODE_TLBS 2 -+#define EXCCODE_TLBI 3 -+#define EXCCODE_MOD 4 -+#define EXCCODE_TLBRI 5 -+#define EXCCODE_TLBXI 6 -+#define EXCCODE_TLBPE 7 -+#define EXCCODE_ADE 8 -+#define EXCCODE_UNALIGN 9 -+#define EXCCODE_OOB 10 -+#define EXCCODE_SYS 11 -+#define EXCCODE_BP 12 -+#define EXCCODE_RI 13 -+#define EXCCODE_IPE 14 -+#define EXCCODE_FPDIS 15 -+#define EXCCODE_LSXDIS 16 -+#define EXCCODE_LASXDIS 17 -+#define EXCCODE_FPE 18 -+#define EXCCODE_WATCH 19 -+#define EXCCODE_BTDIS 20 -+#define EXCCODE_BTE 21 -+#define EXCCODE_PSI 22 -+#define EXCCODE_HYP 23 -+#define EXCCODE_FC 24 -+#define EXCCODE_SE 25 -+ -+#define LOONGARCH_CSR_ERA 0x6 /* 64 error PC */ -+#define LOONGARCH_CSR_BADV 0x7 /* 64 bad virtual address */ -+#define LOONGARCH_CSR_BADI 0x8 /* 32 bad instruction */ -+#define LOONGARCH_CSR_EEPN 0xc /* 64 exception enter base address */ -+#define LOONGARCH_EEPN_CPUID (0x3ffULL << 0) -+ -+#define CU_FPE 1 -+#define CU_LSXE (1 << 1) -+#define CU_LASXE (1 << 2) -+#define CU_LBTE (1 << 3) -+ -+/* TLB related CSR register : start with TLB if no pagewalk */ -+/* 32 TLB Index, EHINV, PageSize, is_gtlb */ -+#define LOONGARCH_CSR_TLBIDX 0x10 -+#define CSR_TLBIDX_EHINV_SHIFT 31 -+#define CSR_TLBIDX_EHINV (0x1ULL << CSR_TLBIDX_EHINV_SHIFT) -+#define CSR_TLBIDX_PS_SHIFT 24 -+#define CSR_TLBIDX_PS_WIDTH 6 -+#define CSR_TLBIDX_PS (0x3fULL << CSR_TLBIDX_PS_SHIFT) -+#define CSR_TLBIDX_IDX_SHIFT 0 -+#define CSR_TLBIDX_IDX_WIDTH 12 -+#define CSR_TLBIDX_IDX (0xfffULL << CSR_TLBIDX_IDX_SHIFT) -+#define CSR_TLBIDX_SIZEM 0x3f000000 -+#define CSR_TLBIDX_SIZE CSR_TLBIDX_PS_SHIFT -+#define CSR_TLBIDX_IDXM 0xfff -+ -+#define LOONGARCH_CSR_TLBEHI 0x11 /* 64 TLB EntryHi without ASID */ -+#define LOONGARCH_CSR_TLBELO0 0x12 /* 64 TLB EntryLo0 */ -+#define CSR_TLBLO0_RPLV_SHIFT 63 -+#define CSR_TLBLO0_RPLV (0x1ULL << CSR_TLBLO0_RPLV_SHIFT) -+#define CSR_TLBLO0_XI_SHIFT 62 -+#define CSR_TLBLO0_XI (0x1ULL << CSR_TLBLO0_XI_SHIFT) -+#define CSR_TLBLO0_RI_SHIFT 61 -+#define CSR_TLBLO0_RI (0x1ULL << CSR_TLBLO0_RI_SHIFT) -+#define CSR_TLBLO0_PPN_SHIFT 12 -+#define CSR_TLBLO0_PPN_WIDTH 36 /* ignore lower 12bits */ -+#define CSR_TLBLO0_PPN (0xfffffffffULL << CSR_TLBLO0_PPN_SHIFT) -+#define CSR_TLBLO0_GLOBAL_SHIFT 6 -+#define CSR_TLBLO0_GLOBAL (0x1ULL << CSR_TLBLO0_GLOBAL_SHIFT) -+#define CSR_TLBLO0_CCA_SHIFT 4 -+#define CSR_TLBLO0_CCA_WIDTH 2 -+#define CSR_TLBLO0_CCA (0x3ULL << CSR_TLBLO0_CCA_SHIFT) -+#define CSR_TLBLO0_PLV_SHIFT 2 -+#define CSR_TLBLO0_PLV_WIDTH 2 -+#define CSR_TLBLO0_PLV (0x3ULL << CSR_TLBLO0_PLV_SHIFT) -+#define CSR_TLBLO0_WE_SHIFT 1 -+#define CSR_TLBLO0_WE (0x1ULL << CSR_TLBLO0_WE_SHIFT) -+#define CSR_TLBLO0_V_SHIFT 0 -+#define CSR_TLBLO0_V (0x1ULL << CSR_TLBLO0_V_SHIFT) -+ -+#define LOONGARCH_CSR_TLBELO1 0x13 /* 64 TLB EntryLo1 */ -+#define CSR_TLBLO1_RPLV_SHIFT 63 -+#define CSR_TLBLO1_RPLV (0x1ULL << CSR_TLBLO1_RPLV_SHIFT) -+#define CSR_TLBLO1_XI_SHIFT 62 -+#define CSR_TLBLO1_XI (0x1ULL << CSR_TLBLO1_XI_SHIFT) -+#define CSR_TLBLO1_RI_SHIFT 61 -+#define CSR_TLBLO1_RI (0x1ULL << CSR_TLBLO1_RI_SHIFT) -+#define CSR_TLBLO1_PPN_SHIFT 12 -+#define CSR_TLBLO1_PPN_WIDTH 36 /* ignore lower 12bits */ -+#define CSR_TLBLO1_PPN (0xfffffffffULL << CSR_TLBLO1_PPN_SHIFT) -+#define CSR_TLBLO1_GLOBAL_SHIFT 6 -+#define CSR_TLBLO1_GLOBAL (0x1ULL << CSR_TLBLO1_GLOBAL_SHIFT) -+#define CSR_TLBLO1_CCA_SHIFT 4 -+#define CSR_TLBLO1_CCA_WIDTH 2 -+#define CSR_TLBLO1_CCA (0x3ULL << CSR_TLBLO1_CCA_SHIFT) -+#define CSR_TLBLO1_PLV_SHIFT 2 -+#define CSR_TLBLO1_PLV_WIDTH 2 -+#define CSR_TLBLO1_PLV (0x3ULL << CSR_TLBLO1_PLV_SHIFT) -+#define CSR_TLBLO1_WE_SHIFT 1 -+#define CSR_TLBLO1_WE (0x1ULL << CSR_TLBLO1_WE_SHIFT) -+#define CSR_TLBLO1_V_SHIFT 0 -+#define CSR_TLBLO1_V (0x1ULL << CSR_TLBLO1_V_SHIFT) -+ -+#define LOONGARCH_ENTRYLO_RI (1ULL << 61) -+#define LOONGARCH_ENTRYLO_XI (1ULL << 62) -+ -+#define LOONGARCH_CSR_TLBWIRED 0x14 /* 32 TLB wired */ -+#define LOONGARCH_CSR_GTLBC 0x15 /* guest-related TLB */ -+#define CSR_GTLBC_RID_SHIFT 16 -+#define CSR_GTLBC_RID_WIDTH 8 -+#define CSR_GTLBC_RID (0xffULL << CSR_GTLBC_RID_SHIFT) -+#define CSR_GTLBC_TOTI_SHIFT 13 -+#define CSR_GTLBC_TOTI (0x1ULL << CSR_GTLBC_TOTI_SHIFT) -+#define CSR_GTLBC_USERID_SHIFT 12 -+#define CSR_GTLBC_USERID (0x1ULL << CSR_GTLBC_USERID_SHIFT) -+#define CSR_GTLBC_GMTLBSZ_SHIFT 0 -+#define CSR_GTLBC_GMTLBSZ_WIDTH 6 -+#define CSR_GTLBC_GMTLBSZ (0x3fULL << CSR_GTLBC_GVTLBSZ_SHIFT) -+ -+#define LOONGARCH_CSR_TRGP 0x16 /* guest-related TLB */ -+#define CSR_TRGP_RID_SHIFT 16 -+#define CSR_TRGP_RID_WIDTH 8 -+#define CSR_TRGP_RID (0xffULL << CSR_TRGP_RID_SHIFT) -+#define CSR_TRGP_GTLB_SHIFT 0 -+#define CSR_TRGP_GTLB (1 << CSR_TRGP_GTLB_SHIFT) -+ -+#define LOONGARCH_CSR_ASID 0x18 /* 64 ASID */ -+#define CSR_ASID_BIT_SHIFT 16 /* ASIDBits */ -+#define CSR_ASID_BIT_WIDTH 8 -+#define CSR_ASID_BIT (0xffULL << CSR_ASID_BIT_SHIFT) -+#define CSR_ASID_ASID_SHIFT 0 -+#define CSR_ASID_ASID_WIDTH 10 -+#define CSR_ASID_ASID (0x3ffULL << CSR_ASID_ASID_SHIFT) -+ -+/* 64 page table base address when badv[47] = 0 */ -+#define LOONGARCH_CSR_PGDL 0x19 -+/* 64 page table base address when badv[47] = 1 */ -+#define LOONGARCH_CSR_PGDH 0x1a -+#define LOONGARCH_CSR_PGD 0x1b /* 64 page table base */ -+#define LOONGARCH_CSR_PWCTL0 0x1c /* 64 PWCtl0 */ -+#define CSR_PWCTL0_PTEW_SHIFT 30 -+#define CSR_PWCTL0_PTEW_WIDTH 2 -+#define CSR_PWCTL0_PTEW (0x3ULL << CSR_PWCTL0_PTEW_SHIFT) -+#define CSR_PWCTL0_DIR1WIDTH_SHIFT 25 -+#define CSR_PWCTL0_DIR1WIDTH_WIDTH 5 -+#define CSR_PWCTL0_DIR1WIDTH (0x1fULL << CSR_PWCTL0_DIR1WIDTH_SHIFT) -+#define CSR_PWCTL0_DIR1BASE_SHIFT 20 -+#define CSR_PWCTL0_DIR1BASE_WIDTH 5 -+#define CSR_PWCTL0_DIR1BASE (0x1fULL << CSR_PWCTL0_DIR1BASE_SHIFT) -+#define CSR_PWCTL0_DIR0WIDTH_SHIFT 15 -+#define CSR_PWCTL0_DIR0WIDTH_WIDTH 5 -+#define CSR_PWCTL0_DIR0WIDTH (0x1fULL << CSR_PWCTL0_DIR0WIDTH_SHIFT) -+#define CSR_PWCTL0_DIR0BASE_SHIFT 10 -+#define CSR_PWCTL0_DIR0BASE_WIDTH 5 -+#define CSR_PWCTL0_DIR0BASE (0x1fULL << CSR_PWCTL0_DIR0BASE_SHIFT) -+#define CSR_PWCTL0_PTWIDTH_SHIFT 5 -+#define CSR_PWCTL0_PTWIDTH_WIDTH 5 -+#define CSR_PWCTL0_PTWIDTH (0x1fULL << CSR_PWCTL0_PTWIDTH_SHIFT) -+#define CSR_PWCTL0_PTBASE_SHIFT 0 -+#define CSR_PWCTL0_PTBASE_WIDTH 5 -+#define CSR_PWCTL0_PTBASE (0x1fULL << CSR_PWCTL0_PTBASE_SHIFT) -+ -+#define LOONGARCH_CSR_PWCTL1 0x1d /* 64 PWCtl1 */ -+#define CSR_PWCTL1_DIR3WIDTH_SHIFT 18 -+#define CSR_PWCTL1_DIR3WIDTH_WIDTH 5 -+#define CSR_PWCTL1_DIR3WIDTH (0x1fULL << CSR_PWCTL1_DIR3WIDTH_SHIFT) -+#define CSR_PWCTL1_DIR3BASE_SHIFT 12 -+#define CSR_PWCTL1_DIR3BASE_WIDTH 5 -+#define CSR_PWCTL1_DIR3BASE (0x1fULL << CSR_PWCTL0_DIR3BASE_SHIFT) -+#define CSR_PWCTL1_DIR2WIDTH_SHIFT 6 -+#define CSR_PWCTL1_DIR2WIDTH_WIDTH 5 -+#define CSR_PWCTL1_DIR2WIDTH (0x1fULL << CSR_PWCTL1_DIR2WIDTH_SHIFT) -+#define CSR_PWCTL1_DIR2BASE_SHIFT 0 -+#define CSR_PWCTL1_DIR2BASE_WIDTH 5 -+#define CSR_PWCTL1_DIR2BASE (0x1fULL << CSR_PWCTL0_DIR2BASE_SHIFT) -+ -+#define LOONGARCH_CSR_STLBPGSIZE 0x1e /* 64 */ -+#define CSR_STLBPGSIZE_PS_WIDTH 6 -+#define CSR_STLBPGSIZE_PS (0x3f) -+ -+#define LOONGARCH_CSR_RVACFG 0x1f -+#define CSR_RVACFG_RDVA_WIDTH 4 -+#define CSR_RVACFG_RDVA (0xf) -+ -+/* read only CSR register : start with CPU */ -+#define LOONGARCH_CSR_CPUID 0x20 /* 32 CPU core number */ -+#define CSR_CPUID_CID_WIDTH 9 -+#define CSR_CPUID_CID (0x1ff) -+ -+#define LOONGARCH_CSR_PRCFG1 0x21 /* 32 CPU info */ -+#define CSR_CONF1_VSMAX_SHIFT 12 -+#define CSR_CONF1_VSMAX_WIDTH 3 -+#define CSR_CONF1_VSMAX (7ULL << CSR_CONF1_VSMAX_SHIFT) -+/* stable timer bits - 1, 0x2f = 47*/ -+#define CSR_CONF1_TMRBITS_SHIFT 4 -+#define CSR_CONF1_TMRBITS_WIDTH 8 -+#define CSR_CONF1_TMRBITS (0xffULL << CSR_CONF1_TMRBITS_SHIFT) -+#define CSR_CONF1_KSNUM_SHIFT 0 -+#define CSR_CONF1_KSNUM_WIDTH 4 -+#define CSR_CONF1_KSNUM (0x8) -+ -+#define LOONGARCH_CSR_PRCFG2 0x22 -+#define CSR_CONF2_PGMASK_SUPP 0x3ffff000 -+ -+#define LOONGARCH_CSR_PRCFG3 0x23 -+#define CSR_CONF3_STLBIDX_SHIFT 20 -+#define CSR_CONF3_STLBIDX_WIDTH 6 -+#define CSR_CONF3_STLBIDX (0x3fULL << CSR_CONF3_STLBIDX_SHIFT) -+#define CSR_STLB_SETS 256 -+#define CSR_CONF3_STLBWAYS_SHIFT 12 -+#define CSR_CONF3_STLBWAYS_WIDTH 8 -+#define CSR_CONF3_STLBWAYS (0xffULL << CSR_CONF3_STLBWAYS_SHIFT) -+#define CSR_STLBWAYS_SIZE 8 -+#define CSR_CONF3_MTLBSIZE_SHIFT 4 -+#define CSR_CONF3_MTLBSIZE_WIDTH 8 -+#define CSR_CONF3_MTLBSIZE (0xffULL << CSR_CONF3_MTLBSIZE_SHIFT) -+/* mean VTLB 64 index */ -+#define CSR_MTLB_SIZE 64 -+#define CSR_CONF3_TLBORG_SHIFT 0 -+#define CSR_CONF3_TLBORG_WIDTH 4 -+#define CSR_CONF3_TLBORG (0xfULL << CSR_CONF3_TLBORG_SHIFT) -+/* mean use MTLB+STLB */ -+#define TLB_ORG 2 -+ -+/* Kscratch : start with KS */ -+#define LOONGARCH_CSR_KS0 0x30 /* 64 */ -+#define LOONGARCH_CSR_KS1 0x31 /* 64 */ -+#define LOONGARCH_CSR_KS2 0x32 /* 64 */ -+#define LOONGARCH_CSR_KS3 0x33 /* 64 */ -+#define LOONGARCH_CSR_KS4 0x34 /* 64 */ -+#define LOONGARCH_CSR_KS5 0x35 /* 64 */ -+#define LOONGARCH_CSR_KS6 0x36 /* 64 */ -+#define LOONGARCH_CSR_KS7 0x37 /* 64 */ -+#define LOONGARCH_CSR_KS8 0x38 /* 64 */ -+ -+/* timer : start with TM */ -+#define LOONGARCH_CSR_TMID 0x40 /* 32 timer ID */ -+ -+#define LOONGARCH_CSR_TCFG 0x41 /* 64 timer config */ -+#define CSR_TCFG_VAL_SHIFT 2 -+#define CSR_TCFG_VAL_WIDTH 48 -+#define CSR_TCFG_VAL (0x3fffffffffffULL << CSR_TCFG_VAL_SHIFT) -+#define CSR_TCFG_PERIOD_SHIFT 1 -+#define CSR_TCFG_PERIOD (0x1ULL << CSR_TCFG_PERIOD_SHIFT) -+#define CSR_TCFG_EN (0x1) -+ -+#define LOONGARCH_CSR_TVAL 0x42 /* 64 timer ticks remain */ -+ -+#define LOONGARCH_CSR_CNTC 0x43 /* 64 timer offset */ -+ -+#define LOONGARCH_CSR_TINTCLR 0x44 /* 64 timer interrupt clear */ -+#define CSR_TINTCLR_TI_SHIFT 0 -+#define CSR_TINTCLR_TI (1 << CSR_TINTCLR_TI_SHIFT) -+ -+/* guest : start with GST */ -+#define LOONGARCH_CSR_GSTAT 0x50 /* 32 basic guest info */ -+#define CSR_GSTAT_GID_SHIFT 16 -+#define CSR_GSTAT_GID_WIDTH 8 -+#define CSR_GSTAT_GID (0xffULL << CSR_GSTAT_GID_SHIFT) -+#define CSR_GSTAT_GIDBIT_SHIFT 4 -+#define CSR_GSTAT_GIDBIT_WIDTH 6 -+#define CSR_GSTAT_GIDBIT (0x3fULL << CSR_GSTAT_GIDBIT_SHIFT) -+#define CSR_GSTAT_PVM_SHIFT 1 -+#define CSR_GSTAT_PVM (0x1ULL << CSR_GSTAT_PVM_SHIFT) -+#define CSR_GSTAT_VM_SHIFT 0 -+#define CSR_GSTAT_VM (0x1ULL << CSR_GSTAT_VM_SHIFT) -+ -+#define LOONGARCH_CSR_GCFG 0x51 /* 32 guest config */ -+#define CSR_GCFG_GPERF_SHIFT 24 -+#define CSR_GCFG_GPERF_WIDTH 3 -+#define CSR_GCFG_GPERF (0x7ULL << CSR_GCFG_GPERF_SHIFT) -+#define CSR_GCFG_GCI_SHIFT 20 -+#define CSR_GCFG_GCI_WIDTH 2 -+#define CSR_GCFG_GCI (0x3ULL << CSR_GCFG_GCI_SHIFT) -+#define CSR_GCFG_GCI_ALL (0x0ULL << CSR_GCFG_GCI_SHIFT) -+#define CSR_GCFG_GCI_HIT (0x1ULL << CSR_GCFG_GCI_SHIFT) -+#define CSR_GCFG_GCI_SECURE (0x2ULL << CSR_GCFG_GCI_SHIFT) -+#define CSR_GCFG_GCIP_SHIFT 16 -+#define CSR_GCFG_GCIP (0xfULL << CSR_GCFG_GCIP_SHIFT) -+#define CSR_GCFG_GCIP_ALL (0x1ULL << CSR_GCFG_GCIP_SHIFT) -+#define CSR_GCFG_GCIP_HIT (0x1ULL << (CSR_GCFG_GCIP_SHIFT + 1)) -+#define CSR_GCFG_GCIP_SECURE (0x1ULL << (CSR_GCFG_GCIP_SHIFT + 2)) -+#define CSR_GCFG_TORU_SHIFT 15 -+#define CSR_GCFG_TORU (0x1ULL << CSR_GCFG_TORU_SHIFT) -+#define CSR_GCFG_TORUP_SHIFT 14 -+#define CSR_GCFG_TORUP (0x1ULL << CSR_GCFG_TORUP_SHIFT) -+#define CSR_GCFG_TOP_SHIFT 13 -+#define CSR_GCFG_TOP (0x1ULL << CSR_GCFG_TOP_SHIFT) -+#define CSR_GCFG_TOPP_SHIFT 12 -+#define CSR_GCFG_TOPP (0x1ULL << CSR_GCFG_TOPP_SHIFT) -+#define CSR_GCFG_TOE_SHIFT 11 -+#define CSR_GCFG_TOE (0x1ULL << CSR_GCFG_TOE_SHIFT) -+#define CSR_GCFG_TOEP_SHIFT 10 -+#define CSR_GCFG_TOEP (0x1ULL << CSR_GCFG_TOEP_SHIFT) -+#define CSR_GCFG_TIT_SHIFT 9 -+#define CSR_GCFG_TIT (0x1ULL << CSR_GCFG_TIT_SHIFT) -+#define CSR_GCFG_TITP_SHIFT 8 -+#define CSR_GCFG_TITP (0x1ULL << CSR_GCFG_TITP_SHIFT) -+#define CSR_GCFG_SIT_SHIFT 7 -+#define CSR_GCFG_SIT (0x1ULL << CSR_GCFG_SIT_SHIFT) -+#define CSR_GCFG_SITP_SHIFT 6 -+#define CSR_GCFG_SITP (0x1ULL << CSR_GCFG_SITP_SHIFT) -+#define CSR_GCFG_CACTRL_SHIFT 4 -+#define CSR_GCFG_CACTRL_WIDTH 2 -+#define CSR_GCFG_CACTRL (0x3ULL << CSR_GCFG_CACTRL_SHIFT) -+#define CSR_GCFG_CACTRL_GUEST (0x0ULL << CSR_GCFG_CACTRL_SHIFT) -+#define CSR_GCFG_CACTRL_ROOT (0x1ULL << CSR_GCFG_CACTRL_SHIFT) -+#define CSR_GCFG_CACTRL_NEST (0x2ULL << CSR_GCFG_CACTRL_SHIFT) -+#define CSR_GCFG_CCCP_WIDTH 4 -+#define CSR_GCFG_CCCP (0xf) -+#define CSR_GCFG_CCCP_GUEST (0x1ULL << 0) -+#define CSR_GCFG_CCCP_ROOT (0x1ULL << 1) -+#define CSR_GCFG_CCCP_NEST (0x1ULL << 2) -+ -+#define LOONGARCH_CSR_GINTC 0x52 /* 64 guest exception control */ -+#define CSR_GINTC_HC_SHIFT 16 -+#define CSR_GINTC_HC_WIDTH 8 -+#define CSR_GINTC_HC (0xffULL << CSR_GINTC_HC_SHIFT) -+#define CSR_GINTC_PIP_SHIFT 8 -+#define CSR_GINTC_PIP_WIDTH 8 -+#define CSR_GINTC_PIP (0xffULL << CSR_GINTC_PIP_SHIFT) -+#define CSR_GINTC_VIP_SHIFT 0 -+#define CSR_GINTC_VIP_WIDTH 8 -+#define CSR_GINTC_VIP (0xff) -+ -+#define LOONGARCH_CSR_GCNTC 0x53 /* 64 guest timer offset */ -+ -+/* LLBCTL */ -+#define LOONGARCH_CSR_LLBCTL 0x60 /* 32 csr number to be changed */ -+#define CSR_LLBCTL_ROLLB_SHIFT 0 -+#define CSR_LLBCTL_ROLLB (1ULL << CSR_LLBCTL_ROLLB_SHIFT) -+#define CSR_LLBCTL_WCLLB_SHIFT 1 -+#define CSR_LLBCTL_WCLLB (1ULL << CSR_LLBCTL_WCLLB_SHIFT) -+#define CSR_LLBCTL_KLO_SHIFT 2 -+#define CSR_LLBCTL_KLO (1ULL << CSR_LLBCTL_KLO_SHIFT) -+ -+/* implement dependent */ -+#define LOONGARCH_CSR_IMPCTL1 0x80 /* 32 loongarch config */ -+#define CSR_MISPEC_SHIFT 20 -+#define CSR_MISPEC_WIDTH 8 -+#define CSR_MISPEC (0xffULL << CSR_MISPEC_SHIFT) -+#define CSR_SSEN_SHIFT 18 -+#define CSR_SSEN (1ULL << CSR_SSEN_SHIFT) -+#define CSR_SCRAND_SHIFT 17 -+#define CSR_SCRAND (1ULL << CSR_SCRAND_SHIFT) -+#define CSR_LLEXCL_SHIFT 16 -+#define CSR_LLEXCL (1ULL << CSR_LLEXCL_SHIFT) -+#define CSR_DISVC_SHIFT 15 -+#define CSR_DISVC (1ULL << CSR_DISVC_SHIFT) -+#define CSR_VCLRU_SHIFT 14 -+#define CSR_VCLRU (1ULL << CSR_VCLRU_SHIFT) -+#define CSR_DCLRU_SHIFT 13 -+#define CSR_DCLRU (1ULL << CSR_DCLRU_SHIFT) -+#define CSR_FASTLDQ_SHIFT 12 -+#define CSR_FASTLDQ (1ULL << CSR_FASTLDQ_SHIFT) -+#define CSR_USERCAC_SHIFT 11 -+#define CSR_USERCAC (1ULL << CSR_USERCAC_SHIFT) -+#define CSR_ANTI_MISPEC_SHIFT 10 -+#define CSR_ANTI_MISPEC (1ULL << CSR_ANTI_MISPEC_SHIFT) -+#define CSR_ANTI_FLUSHSFB_SHIFT 9 -+#define CSR_ANTI_FLUSHSFB (1ULL << CSR_ANTI_FLUSHSFB_SHIFT) -+#define CSR_STFILL_SHIFT 8 -+#define CSR_STFILL (1ULL << CSR_STFILL_SHIFT) -+#define CSR_LIFEP_SHIFT 7 -+#define CSR_LIFEP (1ULL << CSR_LIFEP_SHIFT) -+#define CSR_LLSYNC_SHIFT 6 -+#define CSR_LLSYNC (1ULL << CSR_LLSYNC_SHIFT) -+#define CSR_BRBTDIS_SHIFT 5 -+#define CSR_BRBTDIS (1ULL << CSR_BRBTDIS_SHIFT) -+#define CSR_RASDIS_SHIFT 4 -+#define CSR_RASDIS (1ULL << CSR_RASDIS_SHIFT) -+#define CSR_STPRE_SHIFT 2 -+#define CSR_STPRE_WIDTH 2 -+#define CSR_STPRE (3ULL << CSR_STPRE_SHIFT) -+#define CSR_INSTPRE_SHIFT 1 -+#define CSR_INSTPRE (1ULL << CSR_INSTPRE_SHIFT) -+#define CSR_DATAPRE_SHIFT 0 -+#define CSR_DATAPRE (1ULL << CSR_DATAPRE_SHIFT) -+ -+#define LOONGARCH_CSR_IMPCTL2 0x81 /* 32 Flush */ -+#define CSR_IMPCTL2_MTLB_SHIFT 0 -+#define CSR_IMPCTL2_MTLB (1ULL << CSR_IMPCTL2_MTLB_SHIFT) -+#define CSR_IMPCTL2_STLB_SHIFT 1 -+#define CSR_IMPCTL2_STLB (1ULL << CSR_IMPCTL2_STLB_SHIFT) -+#define CSR_IMPCTL2_DTLB_SHIFT 2 -+#define CSR_IMPCTL2_DTLB (1ULL << CSR_IMPCTL2_DTLB_SHIFT) -+#define CSR_IMPCTL2_ITLB_SHIFT 3 -+#define CSR_IMPCTL2_ITLB (1ULL << CSR_IMPCTL2_ITLB_SHIFT) -+#define CSR_IMPCTL2_BTAC_SHIFT 4 -+#define CSR_IMPCTL2_BTAC (1ULL << CSR_IMPCTL2_BTAC_SHIFT) -+ -+#define LOONGARCH_FLUSH_VTLB 1 -+#define LOONGARCH_FLUSH_FTLB (1 << 1) -+#define LOONGARCH_FLUSH_DTLB (1 << 2) -+#define LOONGARCH_FLUSH_ITLB (1 << 3) -+#define LOONGARCH_FLUSH_BTAC (1 << 4) -+ -+#define LOONGARCH_CSR_GNMI 0x82 -+ -+/* TLB Refill Only */ -+#define LOONGARCH_CSR_TLBRENT 0x88 /* 64 TLB refill exception address */ -+#define LOONGARCH_CSR_TLBRBADV 0x89 /* 64 TLB refill badvaddr */ -+#define LOONGARCH_CSR_TLBRERA 0x8a /* 64 TLB refill ERA */ -+#define LOONGARCH_CSR_TLBRSAVE 0x8b /* 64 KScratch for TLB refill */ -+#define LOONGARCH_CSR_TLBRELO0 0x8c /* 64 TLB refill entrylo0 */ -+#define LOONGARCH_CSR_TLBRELO1 0x8d /* 64 TLB refill entrylo1 */ -+#define LOONGARCH_CSR_TLBREHI 0x8e /* 64 TLB refill entryhi */ -+#define LOONGARCH_CSR_TLBRPRMD 0x8f /* 64 TLB refill mode info */ -+ -+/* error related */ -+#define LOONGARCH_CSR_ERRCTL 0x90 /* 32 ERRCTL */ -+#define LOONGARCH_CSR_ERRINFO 0x91 -+#define LOONGARCH_CSR_ERRINFO1 0x92 -+#define LOONGARCH_CSR_ERRENT 0x93 /* 64 error exception base */ -+#define LOONGARCH_CSR_ERRERA 0x94 /* 64 error exception PC */ -+#define LOONGARCH_CSR_ERRSAVE 0x95 /* 64 KScratch for error exception */ -+ -+#define LOONGARCH_CSR_CTAG 0x98 /* 64 TagLo + TagHi */ -+ -+/* direct map windows */ -+#define LOONGARCH_CSR_DMWIN0 0x180 /* 64 direct map win0: MEM & IF */ -+#define LOONGARCH_CSR_DMWIN1 0x181 /* 64 direct map win1: MEM & IF */ -+#define LOONGARCH_CSR_DMWIN2 0x182 /* 64 direct map win2: MEM */ -+#define LOONGARCH_CSR_DMWIN3 0x183 /* 64 direct map win3: MEM */ -+#define CSR_DMW_PLV0 0x1 -+#define CSR_DMW_PLV1 0x2 -+#define CSR_DMW_PLV2 0x4 -+#define CSR_DMW_PLV3 0x8 -+#define CSR_DMW_BASE_SH 48 -+#define dmwin_va2pa(va) (va & (((unsigned long)1 << CSR_DMW_BASE_SH) - 1)) -+ -+/* performance counter */ -+#define LOONGARCH_CSR_PERFCTRL0 0x200 /* 32 perf event 0 config */ -+#define LOONGARCH_CSR_PERFCNTR0 0x201 /* 64 perf event 0 count value */ -+#define LOONGARCH_CSR_PERFCTRL1 0x202 /* 32 perf event 1 config */ -+#define LOONGARCH_CSR_PERFCNTR1 0x203 /* 64 perf event 1 count value */ -+#define LOONGARCH_CSR_PERFCTRL2 0x204 /* 32 perf event 2 config */ -+#define LOONGARCH_CSR_PERFCNTR2 0x205 /* 64 perf event 2 count value */ -+#define LOONGARCH_CSR_PERFCTRL3 0x206 /* 32 perf event 3 config */ -+#define LOONGARCH_CSR_PERFCNTR3 0x207 /* 64 perf event 3 count value */ -+#define CSR_PERFCTRL_PLV0 (1ULL << 16) -+#define CSR_PERFCTRL_PLV1 (1ULL << 17) -+#define CSR_PERFCTRL_PLV2 (1ULL << 18) -+#define CSR_PERFCTRL_PLV3 (1ULL << 19) -+#define CSR_PERFCTRL_IE (1ULL << 20) -+#define CSR_PERFCTRL_EVENT 0x3ff -+ -+/* debug */ -+#define LOONGARCH_CSR_MWPC 0x300 /* data breakpoint config */ -+#define LOONGARCH_CSR_MWPS 0x301 /* data breakpoint status */ -+ -+#define LOONGARCH_CSR_DB0ADDR 0x310 /* data breakpoint 0 address */ -+#define LOONGARCH_CSR_DB0MASK 0x311 /* data breakpoint 0 mask */ -+#define LOONGARCH_CSR_DB0CTL 0x312 /* data breakpoint 0 control */ -+#define LOONGARCH_CSR_DB0ASID 0x313 /* data breakpoint 0 asid */ -+ -+#define LOONGARCH_CSR_DB1ADDR 0x318 /* data breakpoint 1 address */ -+#define LOONGARCH_CSR_DB1MASK 0x319 /* data breakpoint 1 mask */ -+#define LOONGARCH_CSR_DB1CTL 0x31a /* data breakpoint 1 control */ -+#define LOONGARCH_CSR_DB1ASID 0x31b /* data breakpoint 1 asid */ -+ -+#define LOONGARCH_CSR_DB2ADDR 0x320 /* data breakpoint 2 address */ -+#define LOONGARCH_CSR_DB2MASK 0x321 /* data breakpoint 2 mask */ -+#define LOONGARCH_CSR_DB2CTL 0x322 /* data breakpoint 2 control */ -+#define LOONGARCH_CSR_DB2ASID 0x323 /* data breakpoint 2 asid */ -+ -+#define LOONGARCH_CSR_DB3ADDR 0x328 /* data breakpoint 3 address */ -+#define LOONGARCH_CSR_DB3MASK 0x329 /* data breakpoint 3 mask */ -+#define LOONGARCH_CSR_DB3CTL 0x32a /* data breakpoint 3 control */ -+#define LOONGARCH_CSR_DB3ASID 0x32b /* data breakpoint 3 asid */ -+ -+#define LOONGARCH_CSR_FWPC 0x380 /* instruction breakpoint config */ -+#define LOONGARCH_CSR_FWPS 0x381 /* instruction breakpoint status */ -+ -+#define LOONGARCH_CSR_IB0ADDR 0x390 /* inst breakpoint 0 address */ -+#define LOONGARCH_CSR_IB0MASK 0x391 /* inst breakpoint 0 mask */ -+#define LOONGARCH_CSR_IB0CTL 0x392 /* inst breakpoint 0 control */ -+#define LOONGARCH_CSR_IB0ASID 0x393 /* inst breakpoint 0 asid */ -+#define LOONGARCH_CSR_IB1ADDR 0x398 /* inst breakpoint 1 address */ -+#define LOONGARCH_CSR_IB1MASK 0x399 /* inst breakpoint 1 mask */ -+#define LOONGARCH_CSR_IB1CTL 0x39a /* inst breakpoint 1 control */ -+#define LOONGARCH_CSR_IB1ASID 0x39b /* inst breakpoint 1 asid */ -+ -+#define LOONGARCH_CSR_IB2ADDR 0x3a0 /* inst breakpoint 2 address */ -+#define LOONGARCH_CSR_IB2MASK 0x3a1 /* inst breakpoint 2 mask */ -+#define LOONGARCH_CSR_IB2CTL 0x3a2 /* inst breakpoint 2 control */ -+#define LOONGARCH_CSR_IB2ASID 0x3a3 /* inst breakpoint 2 asid */ -+ -+#define LOONGARCH_CSR_IB3ADDR 0x3a8 /* inst breakpoint 3 address */ -+#define LOONGARCH_CSR_IB3MASK 0x3a9 /* inst breakpoint 3 mask */ -+#define LOONGARCH_CSR_IB3CTL 0x3aa /* inst breakpoint 3 control */ -+#define LOONGARCH_CSR_IB3ASID 0x3ab /* inst breakpoint 3 asid */ -+ -+#define LOONGARCH_CSR_IB4ADDR 0x3b0 /* inst breakpoint 4 address */ -+#define LOONGARCH_CSR_IB4MASK 0x3b1 /* inst breakpoint 4 mask */ -+#define LOONGARCH_CSR_IB4CTL 0x3b2 /* inst breakpoint 4 control */ -+#define LOONGARCH_CSR_IB4ASID 0x3b3 /* inst breakpoint 4 asid */ -+ -+#define LOONGARCH_CSR_IB5ADDR 0x3b8 /* inst breakpoint 5 address */ -+#define LOONGARCH_CSR_IB5MASK 0x3b9 /* inst breakpoint 5 mask */ -+#define LOONGARCH_CSR_IB5CTL 0x3ba /* inst breakpoint 5 control */ -+#define LOONGARCH_CSR_IB5ASID 0x3bb /* inst breakpoint 5 asid */ -+ -+#define LOONGARCH_CSR_IB6ADDR 0x3c0 /* inst breakpoint 6 address */ -+#define LOONGARCH_CSR_IB6MASK 0x3c1 /* inst breakpoint 6 mask */ -+#define LOONGARCH_CSR_IB6CTL 0x3c2 /* inst breakpoint 6 control */ -+#define LOONGARCH_CSR_IB6ASID 0x3c3 /* inst breakpoint 6 asid */ -+ -+#define LOONGARCH_CSR_IB7ADDR 0x3c8 /* inst breakpoint 7 address */ -+#define LOONGARCH_CSR_IB7MASK 0x3c9 /* inst breakpoint 7 mask */ -+#define LOONGARCH_CSR_IB7CTL 0x3ca /* inst breakpoint 7 control */ -+#define LOONGARCH_CSR_IB7ASID 0x3cb /* inst breakpoint 7 asid */ -+ -+#define LOONGARCH_CSR_DEBUG 0x500 /* debug config */ -+#define CSR_DEBUG_DM 0 -+#define CSR_DEBUG_DMVER 1 -+#define CSR_DEBUG_DINT 8 -+#define CSR_DEBUG_DBP 9 -+#define CSR_DEBUG_DIB 10 -+#define CSR_DEBUG_DDB 11 -+ -+#define LOONGARCH_CSR_DERA 0x501 /* debug era */ -+#define LOONGARCH_CSR_DESAVE 0x502 /* debug save */ -+ -+#define LOONGARCH_CSR_PRID 0xc0 /* 32 LOONGARCH CP0 PRID */ -+ -+#define LOONGARCH_CPUCFG0 0x0 -+#define CPUCFG0_3A5000_PRID 0x0014c010 -+ -+#define LOONGARCH_CPUCFG1 0x1 -+#define CPUCFG1_ISGR32 BIT(0) -+#define CPUCFG1_ISGR64 BIT(1) -+#define CPUCFG1_PAGING BIT(2) -+#define CPUCFG1_IOCSR BIT(3) -+#define CPUCFG1_PABITS (47 << 4) -+#define CPUCFG1_VABITS (47 << 12) -+#define CPUCFG1_UAL BIT(20) -+#define CPUCFG1_RI BIT(21) -+#define CPUCFG1_XI BIT(22) -+#define CPUCFG1_RPLV BIT(23) -+#define CPUCFG1_HUGEPG BIT(24) -+#define CPUCFG1_IOCSRBRD BIT(25) -+#define CPUCFG1_MSGINT BIT(26) -+ -+#define LOONGARCH_CPUCFG2 0x2 -+#define CPUCFG2_FP BIT(0) -+#define CPUCFG2_FPSP BIT(1) -+#define CPUCFG2_FPDP BIT(2) -+#define CPUCFG2_FPVERS (0 << 3) -+#define CPUCFG2_LSX BIT(6) -+#define CPUCFG2_LASX BIT(7) -+#define CPUCFG2_COMPLEX BIT(8) -+#define CPUCFG2_CRYPTO BIT(9) -+#define CPUCFG2_LVZP BIT(10) -+#define CPUCFG2_LVZVER (0 << 11) -+#define CPUCFG2_LLFTP BIT(14) -+#define CPUCFG2_LLFTPREV (1 << 15) -+#define CPUCFG2_X86BT BIT(18) -+#define CPUCFG2_ARMBT BIT(19) -+#define CPUCFG2_MIPSBT BIT(20) -+#define CPUCFG2_LSPW BIT(21) -+#define CPUCFG2_LAM BIT(22) -+ -+#define LOONGARCH_CPUCFG3 0x3 -+#define CPUCFG3_CCDMA BIT(0) -+#define CPUCFG3_SFB BIT(1) -+#define CPUCFG3_UCACC BIT(2) -+#define CPUCFG3_LLEXC BIT(3) -+#define CPUCFG3_SCDLY BIT(4) -+#define CPUCFG3_LLDBAR BIT(5) -+#define CPUCFG3_ITLBT BIT(6) -+#define CPUCFG3_ICACHET BIT(7) -+#define CPUCFG3_SPW_LVL (4 << 8) -+#define CPUCFG3_SPW_HG_HF BIT(11) -+#define CPUCFG3_RVA BIT(12) -+#define CPUCFG3_RVAMAX (7 << 13) -+ -+#define LOONGARCH_CPUCFG4 0x4 -+#define CCFREQ_100M 100000000 /* 100M */ -+ -+#define LOONGARCH_CPUCFG5 0x5 -+#define CPUCFG5_CCMUL 1 -+#define CPUCFG5_CCDIV (1 << 16) -+ -+#define LOONGARCH_CPUCFG6 0x6 -+#define CPUCFG6_PMP BIT(0) -+#define CPUCFG6_PAMVER (1 << 1) -+#define CPUCFG6_PMNUM (3 << 4) -+#define CPUCFG6_PMBITS (63 << 8) -+#define CPUCFG6_UPM BIT(14) -+ -+#define LOONGARCH_CPUCFG16 0x10 -+#define CPUCFG16_L1_IUPRE BIT(0) -+#define CPUCFG16_L1_UNIFY BIT(1) -+#define CPUCFG16_L1_DPRE BIT(2) -+#define CPUCFG16_L2_IUPRE BIT(3) -+#define CPUCFG16_L2_IUUNIFY BIT(4) -+#define CPUCFG16_L2_IUPRIV BIT(5) -+#define CPUCFG16_L2_IUINCL BIT(6) -+#define CPUCFG16_L2_DPRE BIT(7) -+#define CPUCFG16_L2_DPRIV BIT(8) -+#define CPUCFG16_L2_DINCL BIT(9) -+#define CPUCFG16_L3_IUPRE BIT(10) -+#define CPUCFG16_L3_IUUNIFY BIT(11) -+#define CPUCFG16_L3_IUPRIV BIT(12) -+#define CPUCFG16_L3_IUINCL BIT(13) -+#define CPUCFG16_L3_DPRE BIT(14) -+#define CPUCFG16_L3_DPRIV BIT(15) -+#define CPUCFG16_L3_DINCL BIT(16) -+ -+#define LOONGARCH_CPUCFG17 0x11 -+#define CPUCFG17_L1I_WAYS_M (3 << 0) -+#define CPUCFG17_L1I_SETS_M (8 << 16) -+#define CPUCFG17_L1I_SIZE_M (6 << 24) -+ -+#define LOONGARCH_CPUCFG18 0x12 -+#define CPUCFG18_L1D_WAYS_M (3 << 0) -+#define CPUCFG18_L1D_SETS_M (8 << 16) -+#define CPUCFG18_L1D_SIZE_M (6 << 24) -+ -+#define LOONGARCH_CPUCFG19 0x13 -+#define CPUCFG19_L2_WAYS_M (0xf << 0) -+#define CPUCFG19_L2_SETS_M (8 << 16) -+#define CPUCFG19_L2_SIZE_M (6 << 24) -+ -+#define LOONGARCH_CPUCFG20 0x14 -+#define CPUCFG20_L3_WAYS_M (0xf << 0) -+#define CPUCFG20_L3_SETS_M (0xe << 16) -+#define CPUCFG20_L3_SIZE_M (0x6 << 24) -+ -+#define LOONGARCH_PAGE_HUGE 0x40 -+#define LOONGARCH_HUGE_GLOBAL 0x1000 -+#define LOONGARCH_HUGE_GLOBAL_SH 12 -+ -+/* -+ * All CSR register -+ * -+ * default value in target/loongarch/cpu.c -+ * reset function in target/loongarch/translate.c:cpu_state_reset() -+ * -+ * This macro will be used only twice. -+ * > In target/loongarch/cpu.h:CPULOONGARCHState -+ * > In target/loongarch/internal.h:loongarch_def_t -+ * -+ * helper_function to rd/wr: -+ * > declare in target/loongarch/helper.h -+ * > realize in target/loongarch/op_helper.c -+ * -+ * during translate: -+ * > gen_csr_rdl() -+ * > gen_csr_wrl() -+ * > gen_csr_rdq() -+ * > gen_csr_wrq() -+ */ -+#define CPU_LOONGARCH_CSR \ -+ uint64_t CSR_CRMD; \ -+ uint64_t CSR_PRMD; \ -+ uint64_t CSR_EUEN; \ -+ uint64_t CSR_MISC; \ -+ uint64_t CSR_ECFG; \ -+ uint64_t CSR_ESTAT; \ -+ uint64_t CSR_ERA; \ -+ uint64_t CSR_BADV; \ -+ uint64_t CSR_BADI; \ -+ uint64_t CSR_EEPN; \ -+ uint64_t CSR_TLBIDX; \ -+ uint64_t CSR_TLBEHI; \ -+ uint64_t CSR_TLBELO0; \ -+ uint64_t CSR_TLBELO1; \ -+ uint64_t CSR_TLBWIRED; \ -+ uint64_t CSR_GTLBC; \ -+ uint64_t CSR_TRGP; \ -+ uint64_t CSR_ASID; \ -+ uint64_t CSR_PGDL; \ -+ uint64_t CSR_PGDH; \ -+ uint64_t CSR_PGD; \ -+ uint64_t CSR_PWCTL0; \ -+ uint64_t CSR_PWCTL1; \ -+ uint64_t CSR_STLBPGSIZE; \ -+ uint64_t CSR_RVACFG; \ -+ uint64_t CSR_CPUID; \ -+ uint64_t CSR_PRCFG1; \ -+ uint64_t CSR_PRCFG2; \ -+ uint64_t CSR_PRCFG3; \ -+ uint64_t CSR_KS0; \ -+ uint64_t CSR_KS1; \ -+ uint64_t CSR_KS2; \ -+ uint64_t CSR_KS3; \ -+ uint64_t CSR_KS4; \ -+ uint64_t CSR_KS5; \ -+ uint64_t CSR_KS6; \ -+ uint64_t CSR_KS7; \ -+ uint64_t CSR_KS8; \ -+ uint64_t CSR_TMID; \ -+ uint64_t CSR_TCFG; \ -+ uint64_t CSR_TVAL; \ -+ uint64_t CSR_CNTC; \ -+ uint64_t CSR_TINTCLR; \ -+ uint64_t CSR_GSTAT; \ -+ uint64_t CSR_GCFG; \ -+ uint64_t CSR_GINTC; \ -+ uint64_t CSR_GCNTC; \ -+ uint64_t CSR_LLBCTL; \ -+ uint64_t CSR_IMPCTL1; \ -+ uint64_t CSR_IMPCTL2; \ -+ uint64_t CSR_GNMI; \ -+ uint64_t CSR_TLBRENT; \ -+ uint64_t CSR_TLBRBADV; \ -+ uint64_t CSR_TLBRERA; \ -+ uint64_t CSR_TLBRSAVE; \ -+ uint64_t CSR_TLBRELO0; \ -+ uint64_t CSR_TLBRELO1; \ -+ uint64_t CSR_TLBREHI; \ -+ uint64_t CSR_TLBRPRMD; \ -+ uint64_t CSR_ERRCTL; \ -+ uint64_t CSR_ERRINFO; \ -+ uint64_t CSR_ERRINFO1; \ -+ uint64_t CSR_ERRENT; \ -+ uint64_t CSR_ERRERA; \ -+ uint64_t CSR_ERRSAVE; \ -+ uint64_t CSR_CTAG; \ -+ uint64_t CSR_DMWIN0; \ -+ uint64_t CSR_DMWIN1; \ -+ uint64_t CSR_DMWIN2; \ -+ uint64_t CSR_DMWIN3; \ -+ uint64_t CSR_PERFCTRL0; \ -+ uint64_t CSR_PERFCNTR0; \ -+ uint64_t CSR_PERFCTRL1; \ -+ uint64_t CSR_PERFCNTR1; \ -+ uint64_t CSR_PERFCTRL2; \ -+ uint64_t CSR_PERFCNTR2; \ -+ uint64_t CSR_PERFCTRL3; \ -+ uint64_t CSR_PERFCNTR3; \ -+ uint64_t CSR_MWPC; \ -+ uint64_t CSR_MWPS; \ -+ uint64_t CSR_DB0ADDR; \ -+ uint64_t CSR_DB0MASK; \ -+ uint64_t CSR_DB0CTL; \ -+ uint64_t CSR_DB0ASID; \ -+ uint64_t CSR_DB1ADDR; \ -+ uint64_t CSR_DB1MASK; \ -+ uint64_t CSR_DB1CTL; \ -+ uint64_t CSR_DB1ASID; \ -+ uint64_t CSR_DB2ADDR; \ -+ uint64_t CSR_DB2MASK; \ -+ uint64_t CSR_DB2CTL; \ -+ uint64_t CSR_DB2ASID; \ -+ uint64_t CSR_DB3ADDR; \ -+ uint64_t CSR_DB3MASK; \ -+ uint64_t CSR_DB3CTL; \ -+ uint64_t CSR_DB3ASID; \ -+ uint64_t CSR_FWPC; \ -+ uint64_t CSR_FWPS; \ -+ uint64_t CSR_IB0ADDR; \ -+ uint64_t CSR_IB0MASK; \ -+ uint64_t CSR_IB0CTL; \ -+ uint64_t CSR_IB0ASID; \ -+ uint64_t CSR_IB1ADDR; \ -+ uint64_t CSR_IB1MASK; \ -+ uint64_t CSR_IB1CTL; \ -+ uint64_t CSR_IB1ASID; \ -+ uint64_t CSR_IB2ADDR; \ -+ uint64_t CSR_IB2MASK; \ -+ uint64_t CSR_IB2CTL; \ -+ uint64_t CSR_IB2ASID; \ -+ uint64_t CSR_IB3ADDR; \ -+ uint64_t CSR_IB3MASK; \ -+ uint64_t CSR_IB3CTL; \ -+ uint64_t CSR_IB3ASID; \ -+ uint64_t CSR_IB4ADDR; \ -+ uint64_t CSR_IB4MASK; \ -+ uint64_t CSR_IB4CTL; \ -+ uint64_t CSR_IB4ASID; \ -+ uint64_t CSR_IB5ADDR; \ -+ uint64_t CSR_IB5MASK; \ -+ uint64_t CSR_IB5CTL; \ -+ uint64_t CSR_IB5ASID; \ -+ uint64_t CSR_IB6ADDR; \ -+ uint64_t CSR_IB6MASK; \ -+ uint64_t CSR_IB6CTL; \ -+ uint64_t CSR_IB6ASID; \ -+ uint64_t CSR_IB7ADDR; \ -+ uint64_t CSR_IB7MASK; \ -+ uint64_t CSR_IB7CTL; \ -+ uint64_t CSR_IB7ASID; \ -+ uint64_t CSR_DEBUG; \ -+ uint64_t CSR_DERA; \ -+ uint64_t CSR_DESAVE; -+ -+#define LOONGARCH_CSR_32(_R, _S) \ -+ (KVM_REG_LOONGARCH_CSR | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) -+ -+#define LOONGARCH_CSR_64(_R, _S) \ -+ (KVM_REG_LOONGARCH_CSR | KVM_REG_SIZE_U64 | (8 * (_R) + (_S))) -+ -+#define KVM_IOC_CSRID(id) LOONGARCH_CSR_64(id, 0) -+ -+#endif -diff --git a/target/loongarch64/cpu-param.h b/target/loongarch64/cpu-param.h -new file mode 100644 -index 0000000000..b5acb6b91e ---- /dev/null -+++ b/target/loongarch64/cpu-param.h -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef CPU_PARAM_H -+#define CPU_PARAM_H -+ -+/* If we want to use host float regs... */ -+/* #define USE_HOST_FLOAT_REGS */ -+ -+/* Real pages are variable size... */ -+#define TARGET_PAGE_BITS 14 -+ -+#define LOONGARCH_TLB_MAX 2112 -+ -+#define TARGET_LONG_BITS 64 -+#define TARGET_PHYS_ADDR_SPACE_BITS 48 -+#define TARGET_VIRT_ADDR_SPACE_BITS 48 -+ -+/* -+ * bit definitions for insn_flags (ISAs/ASEs flags) -+ * ------------------------------------------------ -+ */ -+#define ISA_LARCH32 0x00000001ULL -+#define ISA_LARCH64 0x00000002ULL -+#define INSN_LOONGARCH 0x00010000ULL -+ -+#define CPU_LARCH32 (ISA_LARCH32) -+#define CPU_LARCH64 (ISA_LARCH32 | ISA_LARCH64) -+ -+#define NB_MMU_MODES 4 -+ -+#endif /* QEMU_LOONGARCH_DEFS_H */ -diff --git a/target/loongarch64/cpu-qom.h b/target/loongarch64/cpu-qom.h -new file mode 100644 -index 0000000000..43541c34e5 ---- /dev/null -+++ b/target/loongarch64/cpu-qom.h -@@ -0,0 +1,54 @@ -+/* -+ * QEMU LOONGARCH CPU -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef QEMU_LOONGARCH_CPU_QOM_H -+#define QEMU_LOONGARCH_CPU_QOM_H -+ -+#include "hw/core/cpu.h" -+ -+#define TYPE_LOONGARCH_CPU "loongarch-cpu" -+ -+#define LOONGARCH_CPU_CLASS(klass) \ -+ OBJECT_CLASS_CHECK(LOONGARCHCPUClass, (klass), TYPE_LOONGARCH_CPU) -+#define LOONGARCH_CPU(obj) \ -+ OBJECT_CHECK(LOONGARCHCPU, (obj), TYPE_LOONGARCH_CPU) -+#define LOONGARCH_CPU_GET_CLASS(obj) \ -+ OBJECT_GET_CLASS(LOONGARCHCPUClass, (obj), TYPE_LOONGARCH_CPU) -+ -+/** -+ * LOONGARCHCPUClass: -+ * @parent_realize: The parent class' realize handler. -+ * @parent_reset: The parent class' reset handler. -+ * -+ * A LOONGARCH CPU model. -+ */ -+typedef struct LOONGARCHCPUClass { -+ /*< private >*/ -+ CPUClass parent_class; -+ /*< public >*/ -+ -+ DeviceRealize parent_realize; -+ DeviceUnrealize parent_unrealize; -+ DeviceReset parent_reset; -+ const struct loongarch_def_t *cpu_def; -+} LOONGARCHCPUClass; -+ -+typedef struct LOONGARCHCPU LOONGARCHCPU; -+ -+#endif -diff --git a/target/loongarch64/cpu.c b/target/loongarch64/cpu.c -new file mode 100644 -index 0000000000..ce04d8064f ---- /dev/null -+++ b/target/loongarch64/cpu.c -@@ -0,0 +1,575 @@ -+/* -+ * QEMU LOONGARCH CPU -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qapi/visitor.h" -+#include "cpu.h" -+#include "internal.h" -+#include "kvm_larch.h" -+#include "qemu-common.h" -+#include "hw/qdev-properties.h" -+#include "sysemu/kvm.h" -+#include "exec/exec-all.h" -+#include "sysemu/arch_init.h" -+#include "cpu-csr.h" -+#include "qemu/qemu-print.h" -+#include "qapi/qapi-commands-machine-target.h" -+#ifdef CONFIG_TCG -+#include "hw/core/tcg-cpu-ops.h" -+#endif /* CONFIG_TCG */ -+ -+#define LOONGARCH_CONFIG1 \ -+ ((0x8 << CSR_CONF1_KSNUM_SHIFT) | (0x2f << CSR_CONF1_TMRBITS_SHIFT) | \ -+ (0x7 << CSR_CONF1_VSMAX_SHIFT)) -+ -+#define LOONGARCH_CONFIG3 \ -+ ((0x2 << CSR_CONF3_TLBORG_SHIFT) | (0x3f << CSR_CONF3_MTLBSIZE_SHIFT) | \ -+ (0x7 << CSR_CONF3_STLBWAYS_SHIFT) | (0x8 << CSR_CONF3_STLBIDX_SHIFT)) -+ -+/* LOONGARCH CPU definitions */ -+const loongarch_def_t loongarch_defs[] = { -+ { -+ .name = "Loongson-3A5000", -+ -+ /* for LoongISA CSR */ -+ .CSR_PRCFG1 = LOONGARCH_CONFIG1, -+ .CSR_PRCFG2 = 0x3ffff000, -+ .CSR_PRCFG3 = LOONGARCH_CONFIG3, -+ .CSR_CRMD = (0 << CSR_CRMD_PLV_SHIFT) | (0 << CSR_CRMD_IE_SHIFT) | -+ (1 << CSR_CRMD_DA_SHIFT) | (0 << CSR_CRMD_PG_SHIFT) | -+ (1 << CSR_CRMD_DACF_SHIFT) | (1 << CSR_CRMD_DACM_SHIFT), -+ .CSR_ECFG = 0x7 << 16, -+ .CSR_STLBPGSIZE = 0xe, -+ .CSR_RVACFG = 0x0, -+ .CSR_ASID = 0xa0000, -+ .FCSR0 = 0x0, -+ .FCSR0_rw_bitmask = 0x1f1f03df, -+ .PABITS = 48, -+ .insn_flags = CPU_LARCH64 | INSN_LOONGARCH, -+ .mmu_type = MMU_TYPE_LS3A5K, -+ }, -+ { -+ .name = "host", -+ -+ /* for LoongISA CSR */ -+ .CSR_PRCFG1 = LOONGARCH_CONFIG1, -+ .CSR_PRCFG2 = 0x3ffff000, -+ .CSR_PRCFG3 = LOONGARCH_CONFIG3, -+ .CSR_CRMD = (0 << CSR_CRMD_PLV_SHIFT) | (0 << CSR_CRMD_IE_SHIFT) | -+ (1 << CSR_CRMD_DA_SHIFT) | (0 << CSR_CRMD_PG_SHIFT) | -+ (1 << CSR_CRMD_DACF_SHIFT) | (1 << CSR_CRMD_DACM_SHIFT), -+ .CSR_ECFG = 0x7 << 16, -+ .CSR_STLBPGSIZE = 0xe, -+ .CSR_RVACFG = 0x0, -+ .FCSR0 = 0x0, -+ .FCSR0_rw_bitmask = 0x1f1f03df, -+ .PABITS = 48, -+ .insn_flags = CPU_LARCH64 | INSN_LOONGARCH, -+ .mmu_type = MMU_TYPE_LS3A5K, -+ }, -+}; -+const int loongarch_defs_number = ARRAY_SIZE(loongarch_defs); -+ -+void loongarch_cpu_list(void) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(loongarch_defs); i++) { -+ qemu_printf("LOONGARCH '%s'\n", loongarch_defs[i].name); -+ } -+} -+ -+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) -+{ -+ CpuDefinitionInfoList *cpu_list = NULL; -+ const loongarch_def_t *def; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(loongarch_defs); i++) { -+ CpuDefinitionInfoList *entry; -+ CpuDefinitionInfo *info; -+ -+ def = &loongarch_defs[i]; -+ info = g_malloc0(sizeof(*info)); -+ info->name = g_strdup(def->name); -+ -+ entry = g_malloc0(sizeof(*entry)); -+ entry->value = info; -+ entry->next = cpu_list; -+ cpu_list = entry; -+ } -+ -+ return cpu_list; -+} -+ -+static void loongarch_cpu_set_pc(CPUState *cs, vaddr value) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ env->active_tc.PC = value & ~(target_ulong)1; -+} -+ -+static bool loongarch_cpu_has_work(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ bool has_work = false; -+ -+ /* -+ * It is implementation dependent if non-enabled -+ * interrupts wake-up the CPU, however most of the implementations only -+ * check for interrupts that can be taken. -+ */ -+ if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && -+ cpu_loongarch_hw_interrupts_pending(env)) { -+ has_work = true; -+ } -+ -+ return has_work; -+} -+ -+const char *const regnames[] = { -+ "r0", "ra", "tp", "sp", "a0", "a1", "a2", "a3", "a4", "a5", "a6", -+ "a7", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "x0", -+ "fp", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", -+}; -+ -+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 void fpu_dump_state(CPULOONGARCHState *env, FILE *f, -+ fprintf_function fpu_fprintf, int flags) -+{ -+ int i; -+ int is_fpu64 = 1; -+ -+#define printfpr(fp) \ -+ do { \ -+ if (is_fpu64) \ -+ fpu_fprintf( \ -+ f, "w:%08x d:%016" PRIx64 " fd:%13g fs:%13g psu: %13g\n", \ -+ (fp)->w[FP_ENDIAN_IDX], (fp)->d, (double)(fp)->fd, \ -+ (double)(fp)->fs[FP_ENDIAN_IDX], \ -+ (double)(fp)->fs[!FP_ENDIAN_IDX]); \ -+ else { \ -+ fpr_t tmp; \ -+ tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \ -+ tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \ -+ fpu_fprintf(f, \ -+ "w:%08x d:%016" PRIx64 " fd:%13g fs:%13g psu:%13g\n", \ -+ tmp.w[FP_ENDIAN_IDX], tmp.d, (double)tmp.fd, \ -+ (double)tmp.fs[FP_ENDIAN_IDX], \ -+ (double)tmp.fs[!FP_ENDIAN_IDX]); \ -+ } \ -+ } while (0) -+ -+ fpu_fprintf(f, "FCSR0 0x%08x SR.FR %d fp_status 0x%02x\n", -+ env->active_fpu.fcsr0, is_fpu64, -+ get_float_exception_flags(&env->active_fpu.fp_status)); -+ for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { -+ fpu_fprintf(f, "%3s: ", fregnames[i]); -+ printfpr(&env->active_fpu.fpr[i]); -+ } -+ -+#undef printfpr -+} -+ -+void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int i; -+ -+ qemu_fprintf(f, "pc:\t %lx\n", env->active_tc.PC); -+ for (i = 0; i < 32; i++) { -+ if ((i & 3) == 0) { -+ qemu_fprintf(f, "GPR%02d:", i); -+ } -+ qemu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], -+ env->active_tc.gpr[i]); -+ if ((i & 3) == 3) { -+ qemu_fprintf(f, "\n"); -+ } -+ } -+ qemu_fprintf(f, "EUEN 0x%lx\n", env->CSR_EUEN); -+ qemu_fprintf(f, "ESTAT 0x%lx\n", env->CSR_ESTAT); -+ qemu_fprintf(f, "ERA 0x%lx\n", env->CSR_ERA); -+ qemu_fprintf(f, "CRMD 0x%lx\n", env->CSR_CRMD); -+ qemu_fprintf(f, "PRMD 0x%lx\n", env->CSR_PRMD); -+ qemu_fprintf(f, "BadVAddr 0x%lx\n", env->CSR_BADV); -+ qemu_fprintf(f, "TLB refill ERA 0x%lx\n", env->CSR_TLBRERA); -+ qemu_fprintf(f, "TLB refill BadV 0x%lx\n", env->CSR_TLBRBADV); -+ qemu_fprintf(f, "EEPN 0x%lx\n", env->CSR_EEPN); -+ qemu_fprintf(f, "BadInstr 0x%lx\n", env->CSR_BADI); -+ qemu_fprintf(f, "PRCFG1 0x%lx\nPRCFG2 0x%lx\nPRCFG3 0x%lx\n", -+ env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3); -+ if ((flags & CPU_DUMP_FPU) && (env->hflags & LARCH_HFLAG_FPU)) { -+ fpu_dump_state(env, f, qemu_fprintf, flags); -+ } -+} -+ -+void cpu_state_reset(CPULOONGARCHState *env) -+{ -+ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); -+ CPUState *cs = CPU(cpu); -+ -+ /* Reset registers to their default values */ -+ env->CSR_PRCFG1 = env->cpu_model->CSR_PRCFG1; -+ env->CSR_PRCFG2 = env->cpu_model->CSR_PRCFG2; -+ env->CSR_PRCFG3 = env->cpu_model->CSR_PRCFG3; -+ env->CSR_CRMD = env->cpu_model->CSR_CRMD; -+ env->CSR_ECFG = env->cpu_model->CSR_ECFG; -+ env->CSR_STLBPGSIZE = env->cpu_model->CSR_STLBPGSIZE; -+ env->CSR_RVACFG = env->cpu_model->CSR_RVACFG; -+ env->CSR_ASID = env->cpu_model->CSR_ASID; -+ -+ env->current_tc = 0; -+ env->active_fpu.fcsr0_rw_bitmask = env->cpu_model->FCSR0_rw_bitmask; -+ env->active_fpu.fcsr0 = env->cpu_model->FCSR0; -+ env->insn_flags = env->cpu_model->insn_flags; -+ -+#if !defined(CONFIG_USER_ONLY) -+ env->CSR_ERA = env->active_tc.PC; -+ env->active_tc.PC = env->exception_base; -+#ifdef CONFIG_TCG -+ env->tlb->tlb_in_use = env->tlb->nb_tlb; -+#endif -+ env->CSR_TLBWIRED = 0; -+ env->CSR_TMID = cs->cpu_index; -+ env->CSR_CPUID = (cs->cpu_index & 0x1ff); -+ env->CSR_EEPN |= (uint64_t)0x80000000; -+ env->CSR_TLBRENT |= (uint64_t)0x80000000; -+#endif -+ -+ /* Count register increments in debug mode, EJTAG version 1 */ -+ env->CSR_DEBUG = (1 << CSR_DEBUG_DINT) | (0x1 << CSR_DEBUG_DMVER); -+ -+ compute_hflags(env); -+ restore_fp_status(env); -+ cs->exception_index = EXCP_NONE; -+} -+ -+/* CPUClass::reset() */ -+static void loongarch_cpu_reset(DeviceState *dev) -+{ -+ CPUState *s = CPU(dev); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(s); -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(cpu); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ mcc->parent_reset(dev); -+ -+ memset(env, 0, offsetof(CPULOONGARCHState, end_reset_fields)); -+ -+ cpu_state_reset(env); -+ -+#ifndef CONFIG_USER_ONLY -+ if (kvm_enabled()) { -+ kvm_loongarch_reset_vcpu(cpu); -+ } -+#endif -+} -+ -+static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info) -+{ -+ info->print_insn = print_insn_loongarch; -+} -+ -+static void fpu_init(CPULOONGARCHState *env, const loongarch_def_t *def) -+{ -+ memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); -+} -+ -+void cpu_loongarch_realize_env(CPULOONGARCHState *env) -+{ -+ env->exception_base = 0x1C000000; -+ -+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) -+ mmu_init(env, env->cpu_model); -+#endif -+ fpu_init(env, env->cpu_model); -+} -+ -+static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) -+{ -+ CPUState *cs = CPU(dev); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(dev); -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(dev); -+ Error *local_err = NULL; -+ -+ cpu_exec_realizefn(cs, &local_err); -+ if (local_err != NULL) { -+ error_propagate(errp, local_err); -+ return; -+ } -+ -+ cpu_loongarch_realize_env(&cpu->env); -+ -+ loongarch_cpu_register_gdb_regs_for_features(cs); -+ -+ cpu_reset(cs); -+ qemu_init_vcpu(cs); -+ -+ mcc->parent_realize(dev, errp); -+ cpu->hotplugged = 1; -+} -+ -+static void loongarch_cpu_unrealizefn(DeviceState *dev) -+{ -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(dev); -+ -+#ifndef CONFIG_USER_ONLY -+ cpu_remove_sync(CPU(dev)); -+#endif -+ -+ mcc->parent_unrealize(dev); -+} -+ -+static void loongarch_cpu_initfn(Object *obj) -+{ -+ CPUState *cs = CPU(obj); -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(obj); -+ CPULOONGARCHState *env = &cpu->env; -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(obj); -+ cpu_set_cpustate_pointers(cpu); -+ cs->env_ptr = env; -+ env->cpu_model = mcc->cpu_def; -+ cs->halted = 1; -+ cpu->dtb_compatible = "loongarch,Loongson-3A5000"; -+} -+ -+static char *loongarch_cpu_type_name(const char *cpu_model) -+{ -+ return g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model); -+} -+ -+static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model) -+{ -+ ObjectClass *oc; -+ char *typename; -+ -+ typename = loongarch_cpu_type_name(cpu_model); -+ oc = object_class_by_name(typename); -+ g_free(typename); -+ return oc; -+} -+ -+static int64_t loongarch_cpu_get_arch_id(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ -+ return cpu->id; -+} -+ -+static Property loongarch_cpu_properties[] = { -+ DEFINE_PROP_INT32("core-id", LOONGARCHCPU, core_id, -1), -+ DEFINE_PROP_INT32("id", LOONGARCHCPU, id, UNASSIGNED_CPU_ID), -+ DEFINE_PROP_INT32("node-id", LOONGARCHCPU, node_id, -+ CPU_UNSET_NUMA_NODE_ID), -+ -+ DEFINE_PROP_END_OF_LIST() -+}; -+ -+#ifdef CONFIG_TCG -+static void loongarch_cpu_synchronize_from_tb(CPUState *cs, -+ const TranslationBlock *tb) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ env->active_tc.PC = tb->pc; -+ env->hflags &= ~LARCH_HFLAG_BMASK; -+ env->hflags |= tb->flags & LARCH_HFLAG_BMASK; -+} -+ -+static const struct TCGCPUOps loongarch_tcg_ops = { -+ .initialize = loongarch_tcg_init, -+ .synchronize_from_tb = loongarch_cpu_synchronize_from_tb, -+ -+ .tlb_fill = loongarch_cpu_tlb_fill, -+ .cpu_exec_interrupt = loongarch_cpu_exec_interrupt, -+ .do_interrupt = loongarch_cpu_do_interrupt, -+ -+#ifndef CONFIG_USER_ONLY -+ .do_unaligned_access = loongarch_cpu_do_unaligned_access, -+#endif /* !CONFIG_USER_ONLY */ -+}; -+#endif /* CONFIG_TCG */ -+ -+#if !defined(CONFIG_USER_ONLY) -+static int get_physical_address(CPULOONGARCHState *env, hwaddr *physical, -+ int *prot, target_ulong real_address, int rw, -+ int access_type, int mmu_idx) -+{ -+ int user_mode = mmu_idx == LARCH_HFLAG_UM; -+ int kernel_mode = !user_mode; -+ unsigned plv, base_c, base_v, tmp; -+ -+ /* effective address (modified for KVM T&E kernel segments) */ -+ target_ulong address = real_address; -+ -+ /* Check PG */ -+ if (!(env->CSR_CRMD & CSR_CRMD_PG)) { -+ /* DA mode */ -+ *physical = address & 0xffffffffffffUL; -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ -+ plv = kernel_mode | (user_mode << 3); -+ base_v = address >> CSR_DMW_BASE_SH; -+ /* Check direct map window 0 */ -+ base_c = env->CSR_DMWIN0 >> CSR_DMW_BASE_SH; -+ if ((plv & env->CSR_DMWIN0) && (base_c == base_v)) { -+ *physical = dmwin_va2pa(address); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ /* Check direct map window 1 */ -+ base_c = env->CSR_DMWIN1 >> CSR_DMW_BASE_SH; -+ if ((plv & env->CSR_DMWIN1) && (base_c == base_v)) { -+ *physical = dmwin_va2pa(address); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ /* Check valid extension */ -+ tmp = address >> 47; -+ if (!(tmp == 0 || tmp == 0x1ffff)) { -+ return TLBRET_BADADDR; -+ } -+ /* mapped address */ -+ return env->tlb->map_address(env, physical, prot, real_address, rw, -+ access_type); -+} -+ -+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ hwaddr phys_addr; -+ int prot; -+ -+ if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT, -+ cpu_mmu_index(env, false)) != 0) { -+ return -1; -+ } -+ return phys_addr; -+} -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+#include "hw/core/sysemu-cpu-ops.h" -+ -+static const struct SysemuCPUOps loongarch_sysemu_ops = { -+ .write_elf64_note = loongarch_cpu_write_elf64_note, -+ .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, -+ .legacy_vmsd = &vmstate_loongarch_cpu, -+}; -+#endif -+ -+static gchar *loongarch_gdb_arch_name(CPUState *cs) -+{ -+ return g_strdup("loongarch64"); -+} -+ -+static void loongarch_cpu_class_init(ObjectClass *c, void *data) -+{ -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_CLASS(c); -+ CPUClass *cc = CPU_CLASS(c); -+ DeviceClass *dc = DEVICE_CLASS(c); -+ -+ device_class_set_props(dc, loongarch_cpu_properties); -+ device_class_set_parent_realize(dc, loongarch_cpu_realizefn, -+ &mcc->parent_realize); -+ -+ device_class_set_parent_unrealize(dc, loongarch_cpu_unrealizefn, -+ &mcc->parent_unrealize); -+ -+ device_class_set_parent_reset(dc, loongarch_cpu_reset, &mcc->parent_reset); -+ cc->get_arch_id = loongarch_cpu_get_arch_id; -+ -+ cc->class_by_name = loongarch_cpu_class_by_name; -+ cc->has_work = loongarch_cpu_has_work; -+ cc->dump_state = loongarch_cpu_dump_state; -+ cc->set_pc = loongarch_cpu_set_pc; -+ cc->gdb_read_register = loongarch_cpu_gdb_read_register; -+ cc->gdb_write_register = loongarch_cpu_gdb_write_register; -+ cc->disas_set_info = loongarch_cpu_disas_set_info; -+ cc->gdb_arch_name = loongarch_gdb_arch_name; -+#ifndef CONFIG_USER_ONLY -+ cc->sysemu_ops = &loongarch_sysemu_ops; -+#endif /* !CONFIG_USER_ONLY */ -+ -+ cc->gdb_num_core_regs = 35; -+ cc->gdb_core_xml_file = "loongarch-base64.xml"; -+ cc->gdb_stop_before_watchpoint = true; -+ -+ dc->user_creatable = true; -+#ifdef CONFIG_TCG -+ cc->tcg_ops = &loongarch_tcg_ops; -+#endif /* CONFIG_TCG */ -+} -+ -+static const TypeInfo loongarch_cpu_type_info = { -+ .name = TYPE_LOONGARCH_CPU, -+ .parent = TYPE_CPU, -+ .instance_size = sizeof(LOONGARCHCPU), -+ .instance_init = loongarch_cpu_initfn, -+ .abstract = true, -+ .class_size = sizeof(LOONGARCHCPUClass), -+ .class_init = loongarch_cpu_class_init, -+}; -+ -+static void loongarch_cpu_cpudef_class_init(ObjectClass *oc, void *data) -+{ -+ LOONGARCHCPUClass *mcc = LOONGARCH_CPU_CLASS(oc); -+ mcc->cpu_def = data; -+} -+ -+static void loongarch_register_cpudef_type(const struct loongarch_def_t *def) -+{ -+ char *typename = loongarch_cpu_type_name(def->name); -+ TypeInfo ti = { -+ .name = typename, -+ .parent = TYPE_LOONGARCH_CPU, -+ .class_init = loongarch_cpu_cpudef_class_init, -+ .class_data = (void *)def, -+ }; -+ -+ type_register(&ti); -+ g_free(typename); -+} -+ -+static void loongarch_cpu_register_types(void) -+{ -+ int i; -+ -+ type_register_static(&loongarch_cpu_type_info); -+ for (i = 0; i < loongarch_defs_number; i++) { -+ loongarch_register_cpudef_type(&loongarch_defs[i]); -+ } -+} -+ -+type_init(loongarch_cpu_register_types) -diff --git a/target/loongarch64/cpu.h b/target/loongarch64/cpu.h -new file mode 100644 -index 0000000000..bf5b36d404 ---- /dev/null -+++ b/target/loongarch64/cpu.h -@@ -0,0 +1,359 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LOONGARCH_CPU_H -+#define LOONGARCH_CPU_H -+ -+#define CPUArchState struct CPULOONGARCHState -+ -+#include "qemu-common.h" -+#include "cpu-qom.h" -+#include "larch-defs.h" -+#include "exec/cpu-defs.h" -+#include "fpu/softfloat.h" -+#include "sysemu/sysemu.h" -+#include "cpu-csr.h" -+ -+#define TCG_GUEST_DEFAULT_MO (0) -+ -+struct CPULOONGARCHState; -+typedef LOONGARCHCPU ArchCPU; -+typedef struct CPULOONGARCHTLBContext CPULOONGARCHTLBContext; -+ -+#define LASX_REG_WIDTH (256) -+typedef union lasx_reg_t lasx_reg_t; -+union lasx_reg_t -+{ -+ int64_t val64[LASX_REG_WIDTH / 64]; -+}; -+ -+typedef union fpr_t fpr_t; -+union fpr_t -+{ -+ float64 fd; /* ieee double precision */ -+ float32 fs[2]; /* ieee single precision */ -+ uint64_t d; /* binary double fixed-point */ -+ uint32_t w[2]; /* binary single fixed-point */ -+ /* FPU/LASX register mapping is not tested on big-endian hosts. */ -+ lasx_reg_t lasx; /* vector data */ -+}; -+/* -+ * define FP_ENDIAN_IDX to access the same location -+ * in the fpr_t union regardless of the host endianness -+ */ -+#if defined(HOST_WORDS_BIGENDIAN) -+#define FP_ENDIAN_IDX 1 -+#else -+#define FP_ENDIAN_IDX 0 -+#endif -+ -+typedef struct CPULOONGARCHFPUContext { -+ /* Floating point registers */ -+ fpr_t fpr[32]; -+ float_status fp_status; -+ -+ bool cf[8]; -+ /* -+ * fcsr0 -+ * 31:29 |28:24 |23:21 |20:16 |15:10 |9:8 |7 |6 |5 |4:0 -+ * Cause Flags RM DAE TM Enables -+ */ -+ uint32_t fcsr0; -+ uint32_t fcsr0_rw_bitmask; -+ uint32_t vcsr16; -+} CPULOONGARCHFPUContext; -+ -+/* fp control and status register definition */ -+#define FCSR0_M1 0xdf /* DAE, TM and Enables */ -+#define FCSR0_M2 0x1f1f0000 /* Cause and Flags */ -+#define FCSR0_M3 0x300 /* Round Mode */ -+#define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */ -+#define GET_FP_CAUSE(reg) (((reg) >> 24) & 0x1f) -+#define GET_FP_ENABLE(reg) (((reg) >> 0) & 0x1f) -+#define GET_FP_FLAGS(reg) (((reg) >> 16) & 0x1f) -+#define SET_FP_CAUSE(reg, v) \ -+ do { \ -+ (reg) = ((reg) & ~(0x1f << 24)) | ((v & 0x1f) << 24); \ -+ } while (0) -+#define SET_FP_ENABLE(reg, v) \ -+ do { \ -+ (reg) = ((reg) & ~(0x1f << 0)) | ((v & 0x1f) << 0); \ -+ } while (0) -+#define SET_FP_FLAGS(reg, v) \ -+ do { \ -+ (reg) = ((reg) & ~(0x1f << 16)) | ((v & 0x1f) << 16); \ -+ } while (0) -+#define UPDATE_FP_FLAGS(reg, v) \ -+ do { \ -+ (reg) |= ((v & 0x1f) << 16); \ -+ } while (0) -+#define FP_INEXACT 1 -+#define FP_UNDERFLOW 2 -+#define FP_OVERFLOW 4 -+#define FP_DIV0 8 -+#define FP_INVALID 16 -+ -+#define TARGET_INSN_START_EXTRA_WORDS 2 -+ -+typedef struct loongarch_def_t loongarch_def_t; -+ -+#define LOONGARCH_FPU_MAX 1 -+#define LOONGARCH_KSCRATCH_NUM 8 -+ -+typedef struct TCState TCState; -+struct TCState { -+ target_ulong gpr[32]; -+ target_ulong PC; -+}; -+ -+#define N_IRQS 14 -+#define IRQ_TIMER 11 -+#define IRQ_IPI 12 -+#define IRQ_UART 2 -+ -+typedef struct CPULOONGARCHState CPULOONGARCHState; -+struct CPULOONGARCHState { -+ TCState active_tc; -+ CPULOONGARCHFPUContext active_fpu; -+ -+ uint32_t current_tc; -+ uint64_t scr[4]; -+ uint32_t PABITS; -+ -+ /* LoongISA CSR register */ -+ CPU_LOONGARCH_CSR -+ uint64_t lladdr; -+ target_ulong llval; -+ uint64_t llval_wp; -+ uint32_t llnewval_wp; -+ -+ CPULOONGARCHFPUContext fpus[LOONGARCH_FPU_MAX]; -+ /* QEMU */ -+ int error_code; -+#define EXCP_TLB_NOMATCH 0x1 -+#define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */ -+ uint32_t hflags; /* CPU State */ -+ /* TMASK defines different execution modes */ -+#define LARCH_HFLAG_TMASK 0x5F5807FF -+ /* -+ * The KSU flags must be the lowest bits in hflags. The flag order -+ * must be the same as defined for CP0 Status. This allows to use -+ * the bits as the value of mmu_idx. -+ */ -+#define LARCH_HFLAG_KSU 0x00003 /* kernel/user mode mask */ -+#define LARCH_HFLAG_UM 0x00003 /* user mode flag */ -+#define LARCH_HFLAG_KM 0x00000 /* kernel mode flag */ -+#define LARCH_HFLAG_64 0x00008 /* 64-bit instructions enabled */ -+#define LARCH_HFLAG_FPU 0x00020 /* FPU enabled */ -+#define LARCH_HFLAG_AWRAP 0x00200 /* 32-bit compatibility address wrapping */ -+ /* -+ * If translation is interrupted between the branch instruction and -+ * the delay slot, record what type of branch it is so that we can -+ * resume translation properly. It might be possible to reduce -+ * this from three bits to two. -+ */ -+#define LARCH_HFLAG_BMASK 0x03800 -+#define LARCH_HFLAG_B 0x00800 /* Unconditional branch */ -+#define LARCH_HFLAG_BC 0x01000 /* Conditional branch */ -+#define LARCH_HFLAG_BR 0x02000 /* branch to register (can't link TB) */ -+#define LARCH_HFLAG_LSX 0x1000000 -+#define LARCH_HFLAG_LASX 0x2000000 -+#define LARCH_HFLAG_LBT 0x40000000 -+ target_ulong btarget; /* Jump / branch target */ -+ target_ulong bcond; /* Branch condition (if needed) */ -+ -+ uint64_t insn_flags; /* Supported instruction set */ -+ int cpu_cfg[64]; -+ -+ /* Fields up to this point are cleared by a CPU reset */ -+ struct { -+ } end_reset_fields; -+ -+ /* Fields from here on are preserved across CPU reset. */ -+#if !defined(CONFIG_USER_ONLY) -+ CPULOONGARCHTLBContext *tlb; -+#endif -+ -+ const loongarch_def_t *cpu_model; -+ void *irq[N_IRQS]; -+ QEMUTimer *timer; /* Internal timer */ -+ MemoryRegion *itc_tag; /* ITC Configuration Tags */ -+ target_ulong exception_base; /* ExceptionBase input to the core */ -+ struct { -+ uint64_t guest_addr; -+ } st; -+}; -+ -+/* -+ * CPU can't have 0xFFFFFFFF APIC ID, use that value to distinguish -+ * that ID hasn't been set yet -+ */ -+#define UNASSIGNED_CPU_ID 0xFFFFFFFF -+ -+/** -+ * LOONGARCHCPU: -+ * @env: #CPULOONGARCHState -+ * -+ * A LOONGARCH CPU. -+ */ -+struct LOONGARCHCPU { -+ /*< private >*/ -+ CPUState parent_obj; -+ /*< public >*/ -+ CPUNegativeOffsetState neg; -+ CPULOONGARCHState env; -+ int32_t id; -+ int hotplugged; -+ uint8_t online_vcpus; -+ uint8_t is_migrate; -+ uint64_t counter_value; -+ uint32_t cpu_freq; -+ uint32_t count_ctl; -+ uint64_t pending_exceptions; -+ uint64_t pending_exceptions_clr; -+ uint64_t core_ext_ioisr[4]; -+ VMChangeStateEntry *cpuStateEntry; -+ int32_t node_id; /* NUMA node this CPU belongs to */ -+ int32_t core_id; -+ struct kvm_msrs *kvm_csr_buf; -+ /* 'compatible' string for this CPU for Linux device trees */ -+ const char *dtb_compatible; -+}; -+ -+static inline LOONGARCHCPU *loongarch_env_get_cpu(CPULOONGARCHState *env) -+{ -+ return container_of(env, LOONGARCHCPU, env); -+} -+ -+#define ENV_GET_CPU(e) CPU(loongarch_env_get_cpu(e)) -+ -+#define ENV_OFFSET offsetof(LOONGARCHCPU, env) -+ -+void loongarch_cpu_list(void); -+ -+#define cpu_signal_handler cpu_loongarch_signal_handler -+#define cpu_list loongarch_cpu_list -+ -+/* -+ * MMU modes definitions. We carefully match the indices with our -+ * hflags layout. -+ */ -+#define MMU_MODE0_SUFFIX _kernel -+#define MMU_MODE1_SUFFIX _super -+#define MMU_MODE2_SUFFIX _user -+#define MMU_MODE3_SUFFIX _error -+#define MMU_USER_IDX 3 -+ -+static inline int hflags_mmu_index(uint32_t hflags) -+{ -+ return hflags & LARCH_HFLAG_KSU; -+} -+ -+static inline int cpu_mmu_index(CPULOONGARCHState *env, bool ifetch) -+{ -+ return hflags_mmu_index(env->hflags); -+} -+ -+#include "exec/cpu-all.h" -+ -+/* -+ * Memory access type : -+ * may be needed for precise access rights control and precise exceptions. -+ */ -+enum { -+ /* 1 bit to define user level / supervisor access */ -+ ACCESS_USER = 0x00, -+ ACCESS_SUPER = 0x01, -+ /* 1 bit to indicate direction */ -+ ACCESS_STORE = 0x02, -+ /* Type of instruction that generated the access */ -+ ACCESS_CODE = 0x10, /* Code fetch access */ -+ ACCESS_INT = 0x20, /* Integer load/store access */ -+ ACCESS_FLOAT = 0x30, /* floating point load/store access */ -+}; -+ -+/* Exceptions */ -+enum { -+ EXCP_NONE = -1, -+ EXCP_RESET = 0, -+ EXCP_SRESET, -+ EXCP_DINT, -+ EXCP_NMI, -+ EXCP_EXT_INTERRUPT, -+ EXCP_AdEL, -+ EXCP_AdES, -+ EXCP_TLBF, -+ EXCP_IBE, -+ EXCP_SYSCALL, -+ EXCP_BREAK, -+ EXCP_FPDIS, -+ EXCP_LSXDIS, -+ EXCP_LASXDIS, -+ EXCP_RI, -+ EXCP_OVERFLOW, -+ EXCP_TRAP, -+ EXCP_FPE, -+ EXCP_LTLBL, -+ EXCP_TLBL, -+ EXCP_TLBS, -+ EXCP_DBE, -+ EXCP_TLBXI, -+ EXCP_TLBRI, -+ EXCP_TLBPE, -+ EXCP_BTDIS, -+ -+ EXCP_LAST = EXCP_BTDIS, -+}; -+ -+/* -+ * This is an internally generated WAKE request line. -+ * It is driven by the CPU itself. Raised when the MT -+ * block wants to wake a VPE from an inactive state and -+ * cleared when VPE goes from active to inactive. -+ */ -+#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 -+ -+int cpu_loongarch_signal_handler(int host_signum, void *pinfo, void *puc); -+ -+#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU -+#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX -+#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU -+ -+/* helper.c */ -+target_ulong exception_resume_pc(CPULOONGARCHState *env); -+ -+/* gdbstub.c */ -+void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs); -+void mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def); -+ -+static inline void cpu_get_tb_cpu_state(CPULOONGARCHState *env, -+ target_ulong *pc, -+ target_ulong *cs_base, uint32_t *flags) -+{ -+ *pc = env->active_tc.PC; -+ *cs_base = 0; -+ *flags = env->hflags & (LARCH_HFLAG_TMASK | LARCH_HFLAG_BMASK); -+} -+ -+static inline bool cpu_refill_state(CPULOONGARCHState *env) -+{ -+ return env->CSR_TLBRERA & 0x1; -+} -+ -+extern const char *const regnames[]; -+extern const char *const fregnames[]; -+#endif /* LOONGARCH_CPU_H */ -diff --git a/target/loongarch64/csr_helper.c b/target/loongarch64/csr_helper.c -new file mode 100644 -index 0000000000..093e7e54d8 ---- /dev/null -+++ b/target/loongarch64/csr_helper.c -@@ -0,0 +1,697 @@ -+/* -+ * loongarch tlb emulation helpers for qemu. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/main-loop.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/host-utils.h" -+#include "exec/helper-proto.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+#include "sysemu/kvm.h" -+#include "hw/irq.h" -+#include "cpu-csr.h" -+#include "instmap.h" -+ -+#ifndef CONFIG_USER_ONLY -+target_ulong helper_csr_rdq(CPULOONGARCHState *env, uint64_t csr) -+{ -+ int64_t v; -+ -+#define CASE_CSR_RDQ(csr) \ -+ case LOONGARCH_CSR_##csr: { \ -+ v = env->CSR_##csr; \ -+ break; \ -+ }; -+ -+ switch (csr) { -+ CASE_CSR_RDQ(CRMD) -+ CASE_CSR_RDQ(PRMD) -+ CASE_CSR_RDQ(EUEN) -+ CASE_CSR_RDQ(MISC) -+ CASE_CSR_RDQ(ECFG) -+ CASE_CSR_RDQ(ESTAT) -+ CASE_CSR_RDQ(ERA) -+ CASE_CSR_RDQ(BADV) -+ CASE_CSR_RDQ(BADI) -+ CASE_CSR_RDQ(EEPN) -+ CASE_CSR_RDQ(TLBIDX) -+ CASE_CSR_RDQ(TLBEHI) -+ CASE_CSR_RDQ(TLBELO0) -+ CASE_CSR_RDQ(TLBELO1) -+ CASE_CSR_RDQ(TLBWIRED) -+ CASE_CSR_RDQ(GTLBC) -+ CASE_CSR_RDQ(TRGP) -+ CASE_CSR_RDQ(ASID) -+ CASE_CSR_RDQ(PGDL) -+ CASE_CSR_RDQ(PGDH) -+ CASE_CSR_RDQ(PGD) -+ CASE_CSR_RDQ(PWCTL0) -+ CASE_CSR_RDQ(PWCTL1) -+ CASE_CSR_RDQ(STLBPGSIZE) -+ CASE_CSR_RDQ(RVACFG) -+ CASE_CSR_RDQ(CPUID) -+ CASE_CSR_RDQ(PRCFG1) -+ CASE_CSR_RDQ(PRCFG2) -+ CASE_CSR_RDQ(PRCFG3) -+ CASE_CSR_RDQ(KS0) -+ CASE_CSR_RDQ(KS1) -+ CASE_CSR_RDQ(KS2) -+ CASE_CSR_RDQ(KS3) -+ CASE_CSR_RDQ(KS4) -+ CASE_CSR_RDQ(KS5) -+ CASE_CSR_RDQ(KS6) -+ CASE_CSR_RDQ(KS7) -+ CASE_CSR_RDQ(KS8) -+ CASE_CSR_RDQ(TMID) -+ CASE_CSR_RDQ(TCFG) -+ case LOONGARCH_CSR_TVAL: -+ v = cpu_loongarch_get_stable_timer_ticks(env); -+ break; -+ CASE_CSR_RDQ(CNTC) -+ CASE_CSR_RDQ(TINTCLR) -+ CASE_CSR_RDQ(GSTAT) -+ CASE_CSR_RDQ(GCFG) -+ CASE_CSR_RDQ(GINTC) -+ CASE_CSR_RDQ(GCNTC) -+ CASE_CSR_RDQ(LLBCTL) -+ CASE_CSR_RDQ(IMPCTL1) -+ CASE_CSR_RDQ(IMPCTL2) -+ CASE_CSR_RDQ(GNMI) -+ CASE_CSR_RDQ(TLBRENT) -+ CASE_CSR_RDQ(TLBRBADV) -+ CASE_CSR_RDQ(TLBRERA) -+ CASE_CSR_RDQ(TLBRSAVE) -+ CASE_CSR_RDQ(TLBRELO0) -+ CASE_CSR_RDQ(TLBRELO1) -+ CASE_CSR_RDQ(TLBREHI) -+ CASE_CSR_RDQ(TLBRPRMD) -+ CASE_CSR_RDQ(ERRCTL) -+ CASE_CSR_RDQ(ERRINFO) -+ CASE_CSR_RDQ(ERRINFO1) -+ CASE_CSR_RDQ(ERRENT) -+ CASE_CSR_RDQ(ERRERA) -+ CASE_CSR_RDQ(ERRSAVE) -+ CASE_CSR_RDQ(CTAG) -+ CASE_CSR_RDQ(DMWIN0) -+ CASE_CSR_RDQ(DMWIN1) -+ CASE_CSR_RDQ(DMWIN2) -+ CASE_CSR_RDQ(DMWIN3) -+ CASE_CSR_RDQ(PERFCTRL0) -+ CASE_CSR_RDQ(PERFCNTR0) -+ CASE_CSR_RDQ(PERFCTRL1) -+ CASE_CSR_RDQ(PERFCNTR1) -+ CASE_CSR_RDQ(PERFCTRL2) -+ CASE_CSR_RDQ(PERFCNTR2) -+ CASE_CSR_RDQ(PERFCTRL3) -+ CASE_CSR_RDQ(PERFCNTR3) -+ /* debug */ -+ CASE_CSR_RDQ(MWPC) -+ CASE_CSR_RDQ(MWPS) -+ CASE_CSR_RDQ(DB0ADDR) -+ CASE_CSR_RDQ(DB0MASK) -+ CASE_CSR_RDQ(DB0CTL) -+ CASE_CSR_RDQ(DB0ASID) -+ CASE_CSR_RDQ(DB1ADDR) -+ CASE_CSR_RDQ(DB1MASK) -+ CASE_CSR_RDQ(DB1CTL) -+ CASE_CSR_RDQ(DB1ASID) -+ CASE_CSR_RDQ(DB2ADDR) -+ CASE_CSR_RDQ(DB2MASK) -+ CASE_CSR_RDQ(DB2CTL) -+ CASE_CSR_RDQ(DB2ASID) -+ CASE_CSR_RDQ(DB3ADDR) -+ CASE_CSR_RDQ(DB3MASK) -+ CASE_CSR_RDQ(DB3CTL) -+ CASE_CSR_RDQ(DB3ASID) -+ CASE_CSR_RDQ(FWPC) -+ CASE_CSR_RDQ(FWPS) -+ CASE_CSR_RDQ(IB0ADDR) -+ CASE_CSR_RDQ(IB0MASK) -+ CASE_CSR_RDQ(IB0CTL) -+ CASE_CSR_RDQ(IB0ASID) -+ CASE_CSR_RDQ(IB1ADDR) -+ CASE_CSR_RDQ(IB1MASK) -+ CASE_CSR_RDQ(IB1CTL) -+ CASE_CSR_RDQ(IB1ASID) -+ CASE_CSR_RDQ(IB2ADDR) -+ CASE_CSR_RDQ(IB2MASK) -+ CASE_CSR_RDQ(IB2CTL) -+ CASE_CSR_RDQ(IB2ASID) -+ CASE_CSR_RDQ(IB3ADDR) -+ CASE_CSR_RDQ(IB3MASK) -+ CASE_CSR_RDQ(IB3CTL) -+ CASE_CSR_RDQ(IB3ASID) -+ CASE_CSR_RDQ(IB4ADDR) -+ CASE_CSR_RDQ(IB4MASK) -+ CASE_CSR_RDQ(IB4CTL) -+ CASE_CSR_RDQ(IB4ASID) -+ CASE_CSR_RDQ(IB5ADDR) -+ CASE_CSR_RDQ(IB5MASK) -+ CASE_CSR_RDQ(IB5CTL) -+ CASE_CSR_RDQ(IB5ASID) -+ CASE_CSR_RDQ(IB6ADDR) -+ CASE_CSR_RDQ(IB6MASK) -+ CASE_CSR_RDQ(IB6CTL) -+ CASE_CSR_RDQ(IB6ASID) -+ CASE_CSR_RDQ(IB7ADDR) -+ CASE_CSR_RDQ(IB7MASK) -+ CASE_CSR_RDQ(IB7CTL) -+ CASE_CSR_RDQ(IB7ASID) -+ CASE_CSR_RDQ(DEBUG) -+ CASE_CSR_RDQ(DERA) -+ CASE_CSR_RDQ(DESAVE) -+ default : -+ assert(0); -+ } -+ -+#undef CASE_CSR_RDQ -+ compute_hflags(env); -+ return v; -+} -+ -+target_ulong helper_csr_wrq(CPULOONGARCHState *env, target_ulong val, -+ uint64_t csr) -+{ -+ int64_t old_v, v; -+ old_v = -1; -+ v = val; -+ -+#define CASE_CSR_WRQ(csr) \ -+ case LOONGARCH_CSR_##csr: { \ -+ old_v = env->CSR_##csr; \ -+ env->CSR_##csr = v; \ -+ break; \ -+ }; -+ -+ switch (csr) { -+ CASE_CSR_WRQ(CRMD) -+ CASE_CSR_WRQ(PRMD) -+ CASE_CSR_WRQ(EUEN) -+ CASE_CSR_WRQ(MISC) -+ CASE_CSR_WRQ(ECFG) -+ CASE_CSR_WRQ(ESTAT) -+ CASE_CSR_WRQ(ERA) -+ CASE_CSR_WRQ(BADV) -+ CASE_CSR_WRQ(BADI) -+ CASE_CSR_WRQ(EEPN) -+ CASE_CSR_WRQ(TLBIDX) -+ CASE_CSR_WRQ(TLBEHI) -+ CASE_CSR_WRQ(TLBELO0) -+ CASE_CSR_WRQ(TLBELO1) -+ CASE_CSR_WRQ(TLBWIRED) -+ CASE_CSR_WRQ(GTLBC) -+ CASE_CSR_WRQ(TRGP) -+ CASE_CSR_WRQ(ASID) -+ CASE_CSR_WRQ(PGDL) -+ CASE_CSR_WRQ(PGDH) -+ CASE_CSR_WRQ(PGD) -+ CASE_CSR_WRQ(PWCTL0) -+ CASE_CSR_WRQ(PWCTL1) -+ CASE_CSR_WRQ(STLBPGSIZE) -+ CASE_CSR_WRQ(RVACFG) -+ CASE_CSR_WRQ(CPUID) -+ CASE_CSR_WRQ(PRCFG1) -+ CASE_CSR_WRQ(PRCFG2) -+ CASE_CSR_WRQ(PRCFG3) -+ CASE_CSR_WRQ(KS0) -+ CASE_CSR_WRQ(KS1) -+ CASE_CSR_WRQ(KS2) -+ CASE_CSR_WRQ(KS3) -+ CASE_CSR_WRQ(KS4) -+ CASE_CSR_WRQ(KS5) -+ CASE_CSR_WRQ(KS6) -+ CASE_CSR_WRQ(KS7) -+ CASE_CSR_WRQ(KS8) -+ CASE_CSR_WRQ(TMID) -+ case LOONGARCH_CSR_TCFG: -+ old_v = env->CSR_TCFG; -+ cpu_loongarch_store_stable_timer_config(env, v); -+ break; -+ CASE_CSR_WRQ(TVAL) -+ CASE_CSR_WRQ(CNTC) -+ case LOONGARCH_CSR_TINTCLR: -+ old_v = 0; -+ qemu_irq_lower(env->irq[IRQ_TIMER]); -+ break; -+ CASE_CSR_WRQ(GSTAT) -+ CASE_CSR_WRQ(GCFG) -+ CASE_CSR_WRQ(GINTC) -+ CASE_CSR_WRQ(GCNTC) -+ CASE_CSR_WRQ(LLBCTL) -+ CASE_CSR_WRQ(IMPCTL1) -+ case LOONGARCH_CSR_IMPCTL2: -+ if (v & CSR_IMPCTL2_MTLB) { -+ ls3a5k_flush_vtlb(env); -+ } -+ if (v & CSR_IMPCTL2_STLB) { -+ ls3a5k_flush_ftlb(env); -+ } -+ break; -+ CASE_CSR_WRQ(GNMI) -+ CASE_CSR_WRQ(TLBRENT) -+ CASE_CSR_WRQ(TLBRBADV) -+ CASE_CSR_WRQ(TLBRERA) -+ CASE_CSR_WRQ(TLBRSAVE) -+ CASE_CSR_WRQ(TLBRELO0) -+ CASE_CSR_WRQ(TLBRELO1) -+ CASE_CSR_WRQ(TLBREHI) -+ CASE_CSR_WRQ(TLBRPRMD) -+ CASE_CSR_WRQ(ERRCTL) -+ CASE_CSR_WRQ(ERRINFO) -+ CASE_CSR_WRQ(ERRINFO1) -+ CASE_CSR_WRQ(ERRENT) -+ CASE_CSR_WRQ(ERRERA) -+ CASE_CSR_WRQ(ERRSAVE) -+ CASE_CSR_WRQ(CTAG) -+ CASE_CSR_WRQ(DMWIN0) -+ CASE_CSR_WRQ(DMWIN1) -+ CASE_CSR_WRQ(DMWIN2) -+ CASE_CSR_WRQ(DMWIN3) -+ CASE_CSR_WRQ(PERFCTRL0) -+ CASE_CSR_WRQ(PERFCNTR0) -+ CASE_CSR_WRQ(PERFCTRL1) -+ CASE_CSR_WRQ(PERFCNTR1) -+ CASE_CSR_WRQ(PERFCTRL2) -+ CASE_CSR_WRQ(PERFCNTR2) -+ CASE_CSR_WRQ(PERFCTRL3) -+ CASE_CSR_WRQ(PERFCNTR3) -+ /* debug */ -+ CASE_CSR_WRQ(MWPC) -+ CASE_CSR_WRQ(MWPS) -+ CASE_CSR_WRQ(DB0ADDR) -+ CASE_CSR_WRQ(DB0MASK) -+ CASE_CSR_WRQ(DB0CTL) -+ CASE_CSR_WRQ(DB0ASID) -+ CASE_CSR_WRQ(DB1ADDR) -+ CASE_CSR_WRQ(DB1MASK) -+ CASE_CSR_WRQ(DB1CTL) -+ CASE_CSR_WRQ(DB1ASID) -+ CASE_CSR_WRQ(DB2ADDR) -+ CASE_CSR_WRQ(DB2MASK) -+ CASE_CSR_WRQ(DB2CTL) -+ CASE_CSR_WRQ(DB2ASID) -+ CASE_CSR_WRQ(DB3ADDR) -+ CASE_CSR_WRQ(DB3MASK) -+ CASE_CSR_WRQ(DB3CTL) -+ CASE_CSR_WRQ(DB3ASID) -+ CASE_CSR_WRQ(FWPC) -+ CASE_CSR_WRQ(FWPS) -+ CASE_CSR_WRQ(IB0ADDR) -+ CASE_CSR_WRQ(IB0MASK) -+ CASE_CSR_WRQ(IB0CTL) -+ CASE_CSR_WRQ(IB0ASID) -+ CASE_CSR_WRQ(IB1ADDR) -+ CASE_CSR_WRQ(IB1MASK) -+ CASE_CSR_WRQ(IB1CTL) -+ CASE_CSR_WRQ(IB1ASID) -+ CASE_CSR_WRQ(IB2ADDR) -+ CASE_CSR_WRQ(IB2MASK) -+ CASE_CSR_WRQ(IB2CTL) -+ CASE_CSR_WRQ(IB2ASID) -+ CASE_CSR_WRQ(IB3ADDR) -+ CASE_CSR_WRQ(IB3MASK) -+ CASE_CSR_WRQ(IB3CTL) -+ CASE_CSR_WRQ(IB3ASID) -+ CASE_CSR_WRQ(IB4ADDR) -+ CASE_CSR_WRQ(IB4MASK) -+ CASE_CSR_WRQ(IB4CTL) -+ CASE_CSR_WRQ(IB4ASID) -+ CASE_CSR_WRQ(IB5ADDR) -+ CASE_CSR_WRQ(IB5MASK) -+ CASE_CSR_WRQ(IB5CTL) -+ CASE_CSR_WRQ(IB5ASID) -+ CASE_CSR_WRQ(IB6ADDR) -+ CASE_CSR_WRQ(IB6MASK) -+ CASE_CSR_WRQ(IB6CTL) -+ CASE_CSR_WRQ(IB6ASID) -+ CASE_CSR_WRQ(IB7ADDR) -+ CASE_CSR_WRQ(IB7MASK) -+ CASE_CSR_WRQ(IB7CTL) -+ CASE_CSR_WRQ(IB7ASID) -+ CASE_CSR_WRQ(DEBUG) -+ CASE_CSR_WRQ(DERA) -+ CASE_CSR_WRQ(DESAVE) -+ default : -+ assert(0); -+ } -+ -+ if (csr == LOONGARCH_CSR_ASID) { -+ if (old_v != v) { -+ tlb_flush(CPU(loongarch_env_get_cpu(env))); -+ } -+ } -+ -+#undef CASE_CSR_WRQ -+ compute_hflags(env); -+ return old_v; -+} -+ -+target_ulong helper_csr_xchgq(CPULOONGARCHState *env, target_ulong val, -+ target_ulong mask, uint64_t csr) -+{ -+ target_ulong v, tmp; -+ v = val & mask; -+ -+#define CASE_CSR_XCHGQ(csr) \ -+ case LOONGARCH_CSR_##csr: { \ -+ val = env->CSR_##csr; \ -+ env->CSR_##csr = (env->CSR_##csr) & (~mask); \ -+ env->CSR_##csr = (env->CSR_##csr) | v; \ -+ break; \ -+ }; -+ -+ switch (csr) { -+ CASE_CSR_XCHGQ(CRMD) -+ CASE_CSR_XCHGQ(PRMD) -+ CASE_CSR_XCHGQ(EUEN) -+ CASE_CSR_XCHGQ(MISC) -+ CASE_CSR_XCHGQ(ECFG) -+ case LOONGARCH_CSR_ESTAT: -+ val = env->CSR_ESTAT; -+ qatomic_and(&env->CSR_ESTAT, ~mask); -+ qatomic_or(&env->CSR_ESTAT, v); -+ break; -+ CASE_CSR_XCHGQ(ERA) -+ CASE_CSR_XCHGQ(BADV) -+ CASE_CSR_XCHGQ(BADI) -+ CASE_CSR_XCHGQ(EEPN) -+ CASE_CSR_XCHGQ(TLBIDX) -+ CASE_CSR_XCHGQ(TLBEHI) -+ CASE_CSR_XCHGQ(TLBELO0) -+ CASE_CSR_XCHGQ(TLBELO1) -+ CASE_CSR_XCHGQ(TLBWIRED) -+ CASE_CSR_XCHGQ(GTLBC) -+ CASE_CSR_XCHGQ(TRGP) -+ CASE_CSR_XCHGQ(ASID) -+ CASE_CSR_XCHGQ(PGDL) -+ CASE_CSR_XCHGQ(PGDH) -+ CASE_CSR_XCHGQ(PGD) -+ CASE_CSR_XCHGQ(PWCTL0) -+ CASE_CSR_XCHGQ(PWCTL1) -+ CASE_CSR_XCHGQ(STLBPGSIZE) -+ CASE_CSR_XCHGQ(RVACFG) -+ CASE_CSR_XCHGQ(CPUID) -+ CASE_CSR_XCHGQ(PRCFG1) -+ CASE_CSR_XCHGQ(PRCFG2) -+ CASE_CSR_XCHGQ(PRCFG3) -+ CASE_CSR_XCHGQ(KS0) -+ CASE_CSR_XCHGQ(KS1) -+ CASE_CSR_XCHGQ(KS2) -+ CASE_CSR_XCHGQ(KS3) -+ CASE_CSR_XCHGQ(KS4) -+ CASE_CSR_XCHGQ(KS5) -+ CASE_CSR_XCHGQ(KS6) -+ CASE_CSR_XCHGQ(KS7) -+ CASE_CSR_XCHGQ(KS8) -+ CASE_CSR_XCHGQ(TMID) -+ case LOONGARCH_CSR_TCFG: -+ val = env->CSR_TCFG; -+ tmp = val & ~mask; -+ tmp |= v; -+ cpu_loongarch_store_stable_timer_config(env, tmp); -+ break; -+ CASE_CSR_XCHGQ(TVAL) -+ CASE_CSR_XCHGQ(CNTC) -+ CASE_CSR_XCHGQ(TINTCLR) -+ CASE_CSR_XCHGQ(GSTAT) -+ CASE_CSR_XCHGQ(GCFG) -+ CASE_CSR_XCHGQ(GINTC) -+ CASE_CSR_XCHGQ(GCNTC) -+ CASE_CSR_XCHGQ(LLBCTL) -+ CASE_CSR_XCHGQ(IMPCTL1) -+ CASE_CSR_XCHGQ(IMPCTL2) -+ CASE_CSR_XCHGQ(GNMI) -+ CASE_CSR_XCHGQ(TLBRENT) -+ CASE_CSR_XCHGQ(TLBRBADV) -+ CASE_CSR_XCHGQ(TLBRERA) -+ CASE_CSR_XCHGQ(TLBRSAVE) -+ CASE_CSR_XCHGQ(TLBRELO0) -+ CASE_CSR_XCHGQ(TLBRELO1) -+ CASE_CSR_XCHGQ(TLBREHI) -+ CASE_CSR_XCHGQ(TLBRPRMD) -+ CASE_CSR_XCHGQ(ERRCTL) -+ CASE_CSR_XCHGQ(ERRINFO) -+ CASE_CSR_XCHGQ(ERRINFO1) -+ CASE_CSR_XCHGQ(ERRENT) -+ CASE_CSR_XCHGQ(ERRERA) -+ CASE_CSR_XCHGQ(ERRSAVE) -+ CASE_CSR_XCHGQ(CTAG) -+ CASE_CSR_XCHGQ(DMWIN0) -+ CASE_CSR_XCHGQ(DMWIN1) -+ CASE_CSR_XCHGQ(DMWIN2) -+ CASE_CSR_XCHGQ(DMWIN3) -+ CASE_CSR_XCHGQ(PERFCTRL0) -+ CASE_CSR_XCHGQ(PERFCNTR0) -+ CASE_CSR_XCHGQ(PERFCTRL1) -+ CASE_CSR_XCHGQ(PERFCNTR1) -+ CASE_CSR_XCHGQ(PERFCTRL2) -+ CASE_CSR_XCHGQ(PERFCNTR2) -+ CASE_CSR_XCHGQ(PERFCTRL3) -+ CASE_CSR_XCHGQ(PERFCNTR3) -+ /* debug */ -+ CASE_CSR_XCHGQ(MWPC) -+ CASE_CSR_XCHGQ(MWPS) -+ CASE_CSR_XCHGQ(DB0ADDR) -+ CASE_CSR_XCHGQ(DB0MASK) -+ CASE_CSR_XCHGQ(DB0CTL) -+ CASE_CSR_XCHGQ(DB0ASID) -+ CASE_CSR_XCHGQ(DB1ADDR) -+ CASE_CSR_XCHGQ(DB1MASK) -+ CASE_CSR_XCHGQ(DB1CTL) -+ CASE_CSR_XCHGQ(DB1ASID) -+ CASE_CSR_XCHGQ(DB2ADDR) -+ CASE_CSR_XCHGQ(DB2MASK) -+ CASE_CSR_XCHGQ(DB2CTL) -+ CASE_CSR_XCHGQ(DB2ASID) -+ CASE_CSR_XCHGQ(DB3ADDR) -+ CASE_CSR_XCHGQ(DB3MASK) -+ CASE_CSR_XCHGQ(DB3CTL) -+ CASE_CSR_XCHGQ(DB3ASID) -+ CASE_CSR_XCHGQ(FWPC) -+ CASE_CSR_XCHGQ(FWPS) -+ CASE_CSR_XCHGQ(IB0ADDR) -+ CASE_CSR_XCHGQ(IB0MASK) -+ CASE_CSR_XCHGQ(IB0CTL) -+ CASE_CSR_XCHGQ(IB0ASID) -+ CASE_CSR_XCHGQ(IB1ADDR) -+ CASE_CSR_XCHGQ(IB1MASK) -+ CASE_CSR_XCHGQ(IB1CTL) -+ CASE_CSR_XCHGQ(IB1ASID) -+ CASE_CSR_XCHGQ(IB2ADDR) -+ CASE_CSR_XCHGQ(IB2MASK) -+ CASE_CSR_XCHGQ(IB2CTL) -+ CASE_CSR_XCHGQ(IB2ASID) -+ CASE_CSR_XCHGQ(IB3ADDR) -+ CASE_CSR_XCHGQ(IB3MASK) -+ CASE_CSR_XCHGQ(IB3CTL) -+ CASE_CSR_XCHGQ(IB3ASID) -+ CASE_CSR_XCHGQ(IB4ADDR) -+ CASE_CSR_XCHGQ(IB4MASK) -+ CASE_CSR_XCHGQ(IB4CTL) -+ CASE_CSR_XCHGQ(IB4ASID) -+ CASE_CSR_XCHGQ(IB5ADDR) -+ CASE_CSR_XCHGQ(IB5MASK) -+ CASE_CSR_XCHGQ(IB5CTL) -+ CASE_CSR_XCHGQ(IB5ASID) -+ CASE_CSR_XCHGQ(IB6ADDR) -+ CASE_CSR_XCHGQ(IB6MASK) -+ CASE_CSR_XCHGQ(IB6CTL) -+ CASE_CSR_XCHGQ(IB6ASID) -+ CASE_CSR_XCHGQ(IB7ADDR) -+ CASE_CSR_XCHGQ(IB7MASK) -+ CASE_CSR_XCHGQ(IB7CTL) -+ CASE_CSR_XCHGQ(IB7ASID) -+ CASE_CSR_XCHGQ(DEBUG) -+ CASE_CSR_XCHGQ(DERA) -+ CASE_CSR_XCHGQ(DESAVE) -+ default : -+ assert(0); -+ } -+ -+#undef CASE_CSR_XCHGQ -+ compute_hflags(env); -+ return val; -+} -+ -+static target_ulong confbus_addr(CPULOONGARCHState *env, int cpuid, -+ target_ulong csr_addr) -+{ -+ target_ulong addr; -+ target_ulong node_addr; -+ int cores_per_node = ((0x60018 >> 3) & 0xff) + 1; -+ -+ switch (cores_per_node) { -+ case 4: -+ assert(cpuid < 64); -+ node_addr = ((target_ulong)(cpuid & 0x3c) << 42); -+ break; -+ case 8: -+ assert(cpuid < 128); -+ node_addr = ((target_ulong)(cpuid & 0x78) << 41) + -+ ((target_ulong)(cpuid & 0x4) << 14); -+ break; -+ case 16: -+ assert(cpuid < 256); -+ node_addr = ((target_ulong)(cpuid & 0xf0) << 40) + -+ ((target_ulong)(cpuid & 0xc) << 14); -+ break; -+ default: -+ assert(0); -+ break; -+ } -+ -+ /* -+ * per core address -+ *0x10xx => ipi -+ * 0x18xx => extioi isr -+ */ -+ if (((csr_addr & 0xff00) == 0x1000)) { -+ addr = (csr_addr & 0xff) + (target_ulong)(cpuid << 8); -+ addr = 0x800000001f000000UL + addr; -+ return addr; -+ } else if ((csr_addr & 0xff00) == 0x1800) { -+ addr = (csr_addr & 0xff) + ((target_ulong)(cpuid << 8)); -+ addr = 0x800000001f020000UL + addr; -+ return addr; -+ } else if ((csr_addr & 0xff00) >= 0x1400 && (csr_addr & 0xff00) < 0x1d00) { -+ addr = 0x800000001f010000UL + ((csr_addr & 0xfff) - 0x400); -+ return addr; -+ } else if (csr_addr == 0x408) { -+ addr = csr_addr; -+ } else { -+ addr = csr_addr + node_addr; -+ } -+ -+ addr = 0x800000001fe00000UL + addr; -+ return addr; -+} -+ -+void helper_iocsr(CPULOONGARCHState *env, target_ulong r_addr, -+ target_ulong r_val, uint32_t op) -+{ -+ target_ulong addr; -+ target_ulong val = env->active_tc.gpr[r_val]; -+ int mask; -+ -+ addr = confbus_addr(env, CPU(loongarch_env_get_cpu(env))->cpu_index, -+ env->active_tc.gpr[r_addr]); -+ -+ switch (env->active_tc.gpr[r_addr]) { -+ /* IPI send */ -+ case 0x1040: -+ if (op != OPC_LARCH_ST_W) { -+ return; -+ } -+ op = OPC_LARCH_ST_W; -+ break; -+ -+ /* Mail send */ -+ case 0x1048: -+ if (op != OPC_LARCH_ST_D) { -+ return; -+ } -+ op = OPC_LARCH_ST_D; -+ break; -+ -+ /* ANY send */ -+ case 0x1158: -+ if (op != OPC_LARCH_ST_D) { -+ return; -+ } -+ addr = confbus_addr(env, (val >> 16) & 0x3ff, val & 0xffff); -+ mask = (val >> 27) & 0xf; -+ val = (val >> 32); -+ switch (mask) { -+ case 0: -+ op = OPC_LARCH_ST_W; -+ break; -+ case 0x7: -+ op = OPC_LARCH_ST_B; -+ addr += 3; -+ val >>= 24; -+ break; -+ case 0xb: -+ op = OPC_LARCH_ST_B; -+ addr += 2; -+ val >>= 16; -+ break; -+ case 0xd: -+ op = OPC_LARCH_ST_B; -+ addr += 1; -+ val >>= 8; -+ break; -+ case 0xe: -+ op = OPC_LARCH_ST_B; -+ break; -+ case 0xc: -+ op = OPC_LARCH_ST_H; -+ break; -+ case 0x3: -+ op = OPC_LARCH_ST_H; -+ addr += 2; -+ val >>= 16; -+ break; -+ default: -+ qemu_log("Unsupported any_send mask0x%x\n", mask); -+ break; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ switch (op) { -+ case OPC_LARCH_LD_D: -+ env->active_tc.gpr[r_val] = cpu_ldq_data_ra(env, addr, GETPC()); -+ break; -+ case OPC_LARCH_LD_W: -+ env->active_tc.gpr[r_val] = cpu_ldl_data_ra(env, addr, GETPC()); -+ break; -+ case OPC_LARCH_LD_H: -+ assert(0); -+ break; -+ case OPC_LARCH_LD_B: -+ assert(0); -+ break; -+ case OPC_LARCH_ST_D: -+ cpu_stq_data_ra(env, addr, val, GETPC()); -+ break; -+ case OPC_LARCH_ST_W: -+ cpu_stl_data_ra(env, addr, val, GETPC()); -+ break; -+ case OPC_LARCH_ST_H: -+ cpu_stb_data_ra(env, addr, val, GETPC()); -+ break; -+ case OPC_LARCH_ST_B: -+ cpu_stb_data_ra(env, addr, val, GETPC()); -+ break; -+ default: -+ qemu_log("Unknown op 0x%x", op); -+ assert(0); -+ } -+} -+#endif -+ -+target_ulong helper_cpucfg(CPULOONGARCHState *env, target_ulong rj) -+{ -+ return 0; -+} -diff --git a/target/loongarch64/fpu.c b/target/loongarch64/fpu.c -new file mode 100644 -index 0000000000..f063c8bae0 ---- /dev/null -+++ b/target/loongarch64/fpu.c -@@ -0,0 +1,25 @@ -+/* -+ * loongarch float point emulation helpers for qemu. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "fpu/softfloat.h" -+ -+/* convert loongarch rounding mode in fcsr0 to IEEE library */ -+unsigned int ieee_rm[] = { float_round_nearest_even, float_round_to_zero, -+ float_round_up, float_round_down }; -diff --git a/target/loongarch64/fpu_helper.c b/target/loongarch64/fpu_helper.c -new file mode 100644 -index 0000000000..033bf0de84 ---- /dev/null -+++ b/target/loongarch64/fpu_helper.c -@@ -0,0 +1,891 @@ -+/* -+ * loongarch float point emulation helpers for qemu. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/host-utils.h" -+#include "exec/helper-proto.h" -+#include "exec/exec-all.h" -+#include "fpu/softfloat.h" -+ -+#define FP_TO_INT32_OVERFLOW 0x7fffffff -+#define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL -+ -+#define FLOAT_CLASS_SIGNALING_NAN 0x001 -+#define FLOAT_CLASS_QUIET_NAN 0x002 -+#define FLOAT_CLASS_NEGATIVE_INFINITY 0x004 -+#define FLOAT_CLASS_NEGATIVE_NORMAL 0x008 -+#define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010 -+#define FLOAT_CLASS_NEGATIVE_ZERO 0x020 -+#define FLOAT_CLASS_POSITIVE_INFINITY 0x040 -+#define FLOAT_CLASS_POSITIVE_NORMAL 0x080 -+#define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100 -+#define FLOAT_CLASS_POSITIVE_ZERO 0x200 -+ -+target_ulong helper_movfcsr2gr(CPULOONGARCHState *env, uint32_t reg) -+{ -+ target_ulong r = 0; -+ -+ switch (reg) { -+ case 0: -+ r = (uint32_t)env->active_fpu.fcsr0; -+ break; -+ case 1: -+ r = (env->active_fpu.fcsr0 & FCSR0_M1); -+ break; -+ case 2: -+ r = (env->active_fpu.fcsr0 & FCSR0_M2); -+ break; -+ case 3: -+ r = (env->active_fpu.fcsr0 & FCSR0_M3); -+ break; -+ case 16: -+ r = (uint32_t)env->active_fpu.vcsr16; -+ break; -+ default: -+ printf("%s: warning, fcsr '%d' not supported\n", __func__, reg); -+ assert(0); -+ break; -+ } -+ -+ return r; -+} -+ -+void helper_movgr2fcsr(CPULOONGARCHState *env, target_ulong arg1, -+ uint32_t fcsr, uint32_t rj) -+{ -+ switch (fcsr) { -+ case 0: -+ env->active_fpu.fcsr0 = arg1; -+ break; -+ case 1: -+ env->active_fpu.fcsr0 = -+ (arg1 & FCSR0_M1) | (env->active_fpu.fcsr0 & ~FCSR0_M1); -+ break; -+ case 2: -+ env->active_fpu.fcsr0 = -+ (arg1 & FCSR0_M2) | (env->active_fpu.fcsr0 & ~FCSR0_M2); -+ break; -+ case 3: -+ env->active_fpu.fcsr0 = -+ (arg1 & FCSR0_M3) | (env->active_fpu.fcsr0 & ~FCSR0_M3); -+ break; -+ case 16: -+ env->active_fpu.vcsr16 = arg1; -+ break; -+ default: -+ printf("%s: warning, fcsr '%d' not supported\n", __func__, fcsr); -+ assert(0); -+ break; -+ } -+ restore_fp_status(env); -+ set_float_exception_flags(0, &env->active_fpu.fp_status); -+} -+ -+void helper_movreg2cf(CPULOONGARCHState *env, uint32_t cd, target_ulong src) -+{ -+ env->active_fpu.cf[cd & 0x7] = src & 0x1; -+} -+ -+void helper_movreg2cf_i32(CPULOONGARCHState *env, uint32_t cd, uint32_t src) -+{ -+ env->active_fpu.cf[cd & 0x7] = src & 0x1; -+} -+ -+void helper_movreg2cf_i64(CPULOONGARCHState *env, uint32_t cd, uint64_t src) -+{ -+ env->active_fpu.cf[cd & 0x7] = src & 0x1; -+} -+ -+target_ulong helper_movcf2reg(CPULOONGARCHState *env, uint32_t cj) -+{ -+ return (target_ulong)env->active_fpu.cf[cj & 0x7]; -+} -+ -+int ieee_ex_to_loongarch(int xcpt) -+{ -+ int ret = 0; -+ if (xcpt) { -+ 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 inline void update_fcsr0(CPULOONGARCHState *env, uintptr_t pc) -+{ -+ int tmp = ieee_ex_to_loongarch( -+ get_float_exception_flags(&env->active_fpu.fp_status)); -+ -+ SET_FP_CAUSE(env->active_fpu.fcsr0, tmp); -+ if (tmp) { -+ set_float_exception_flags(0, &env->active_fpu.fp_status); -+ -+ if (GET_FP_ENABLE(env->active_fpu.fcsr0) & tmp) { -+ do_raise_exception(env, EXCP_FPE, pc); -+ } else { -+ UPDATE_FP_FLAGS(env->active_fpu.fcsr0, tmp); -+ } -+ } -+} -+ -+/* unary operations, modifying fp status */ -+uint64_t helper_float_sqrt_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt0; -+} -+ -+uint32_t helper_float_sqrt_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst0; -+} -+ -+uint64_t helper_float_cvtd_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint64_t helper_float_cvtd_w(CPULOONGARCHState *env, uint32_t wt0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint64_t helper_float_cvtd_l(CPULOONGARCHState *env, uint64_t dt0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint64_t helper_float_cvt_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_cvt_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_cvts_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t fst2; -+ -+ fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint32_t helper_float_cvts_w(CPULOONGARCHState *env, uint32_t wt0) -+{ -+ uint32_t fst2; -+ -+ fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint32_t helper_float_cvts_l(CPULOONGARCHState *env, uint64_t dt0) -+{ -+ uint32_t fst2; -+ -+ fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint32_t helper_float_cvt_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_cvt_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_round_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_nearest_even, -+ &env->active_fpu.fp_status); -+ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_round_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_nearest_even, -+ &env->active_fpu.fp_status); -+ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_round_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_nearest_even, -+ &env->active_fpu.fp_status); -+ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_round_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_nearest_even, -+ &env->active_fpu.fp_status); -+ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_trunc_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_trunc_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_trunc_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_trunc_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_ceil_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); -+ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_ceil_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); -+ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_ceil_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); -+ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_ceil_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); -+ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_floor_l_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); -+ dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint64_t helper_float_floor_l_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint64_t dt2; -+ -+ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); -+ dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ dt2 = FP_TO_INT64_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_floor_w_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); -+ wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint32_t helper_float_floor_w_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); -+ wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); -+ restore_rounding_mode(env); -+ if (get_float_exception_flags(&env->active_fpu.fp_status) & -+ (float_flag_invalid | float_flag_overflow)) { -+ wt2 = FP_TO_INT32_OVERFLOW; -+ } -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+/* unary operations, not modifying fp status */ -+#define FLOAT_UNOP(name) \ -+ uint64_t helper_float_##name##_d(uint64_t fdt0) \ -+ { \ -+ return float64_##name(fdt0); \ -+ } \ -+ uint32_t helper_float_##name##_s(uint32_t fst0) \ -+ { \ -+ return float32_##name(fst0); \ -+ } -+ -+FLOAT_UNOP(abs) -+FLOAT_UNOP(chs) -+#undef FLOAT_UNOP -+ -+uint64_t helper_float_recip_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint32_t helper_float_recip_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t fst2; -+ -+ fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint64_t helper_float_rsqrt_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t fdt2; -+ -+ fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status); -+ fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdt2; -+} -+ -+uint32_t helper_float_rsqrt_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t fst2; -+ -+ fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status); -+ fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fst2; -+} -+ -+uint32_t helper_float_rint_s(CPULOONGARCHState *env, uint32_t fs) -+{ -+ uint32_t fdret; -+ -+ fdret = float32_round_to_int(fs, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdret; -+} -+ -+uint64_t helper_float_rint_d(CPULOONGARCHState *env, uint64_t fs) -+{ -+ uint64_t fdret; -+ -+ fdret = float64_round_to_int(fs, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return fdret; -+} -+ -+#define FLOAT_CLASS(name, bits) \ -+ uint##bits##_t float_##name(uint##bits##_t arg, float_status *status) \ -+ { \ -+ if (float##bits##_is_signaling_nan(arg, status)) { \ -+ return FLOAT_CLASS_SIGNALING_NAN; \ -+ } else if (float##bits##_is_quiet_nan(arg, status)) { \ -+ return FLOAT_CLASS_QUIET_NAN; \ -+ } else if (float##bits##_is_neg(arg)) { \ -+ if (float##bits##_is_infinity(arg)) { \ -+ return FLOAT_CLASS_NEGATIVE_INFINITY; \ -+ } else if (float##bits##_is_zero(arg)) { \ -+ return FLOAT_CLASS_NEGATIVE_ZERO; \ -+ } else if (float##bits##_is_zero_or_denormal(arg)) { \ -+ return FLOAT_CLASS_NEGATIVE_SUBNORMAL; \ -+ } else { \ -+ return FLOAT_CLASS_NEGATIVE_NORMAL; \ -+ } \ -+ } else { \ -+ if (float##bits##_is_infinity(arg)) { \ -+ return FLOAT_CLASS_POSITIVE_INFINITY; \ -+ } else if (float##bits##_is_zero(arg)) { \ -+ return FLOAT_CLASS_POSITIVE_ZERO; \ -+ } else if (float##bits##_is_zero_or_denormal(arg)) { \ -+ return FLOAT_CLASS_POSITIVE_SUBNORMAL; \ -+ } else { \ -+ return FLOAT_CLASS_POSITIVE_NORMAL; \ -+ } \ -+ } \ -+ } \ -+ \ -+ uint##bits##_t helper_float_##name(CPULOONGARCHState *env, \ -+ uint##bits##_t arg) \ -+ { \ -+ return float_##name(arg, &env->active_fpu.fp_status); \ -+ } -+ -+FLOAT_CLASS(class_s, 32) -+FLOAT_CLASS(class_d, 64) -+#undef FLOAT_CLASS -+ -+/* binary operations */ -+#define FLOAT_BINOP(name) \ -+ uint64_t helper_float_##name##_d(CPULOONGARCHState *env, uint64_t fdt0, \ -+ uint64_t fdt1) \ -+ { \ -+ uint64_t dt2; \ -+ \ -+ dt2 = float64_##name(fdt0, fdt1, &env->active_fpu.fp_status); \ -+ update_fcsr0(env, GETPC()); \ -+ return dt2; \ -+ } \ -+ \ -+ uint32_t helper_float_##name##_s(CPULOONGARCHState *env, uint32_t fst0, \ -+ uint32_t fst1) \ -+ { \ -+ uint32_t wt2; \ -+ \ -+ wt2 = float32_##name(fst0, fst1, &env->active_fpu.fp_status); \ -+ update_fcsr0(env, GETPC()); \ -+ return wt2; \ -+ } -+ -+FLOAT_BINOP(add) -+FLOAT_BINOP(sub) -+FLOAT_BINOP(mul) -+FLOAT_BINOP(div) -+#undef FLOAT_BINOP -+ -+uint64_t helper_float_exp2_d(CPULOONGARCHState *env, uint64_t fdt0, -+ uint64_t fdt1) -+{ -+ uint64_t dt2; -+ int64_t n = (int64_t)fdt1; -+ -+ dt2 = float64_scalbn(fdt0, n > 0x1000 ? 0x1000 : n < -0x1000 ? -0x1000 : n, -+ &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+uint32_t helper_float_exp2_s(CPULOONGARCHState *env, uint32_t fst0, -+ uint32_t fst1) -+{ -+ uint32_t wt2; -+ int32_t n = (int32_t)fst1; -+ -+ wt2 = float32_scalbn(fst0, n > 0x200 ? 0x200 : n < -0x200 ? -0x200 : n, -+ &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+#define FLOAT_MINMAX(name, bits, minmaxfunc) \ -+ uint##bits##_t helper_float_##name(CPULOONGARCHState *env, \ -+ uint##bits##_t fs, uint##bits##_t ft) \ -+ { \ -+ uint##bits##_t fdret; \ -+ \ -+ fdret = \ -+ float##bits##_##minmaxfunc(fs, ft, &env->active_fpu.fp_status); \ -+ update_fcsr0(env, GETPC()); \ -+ return fdret; \ -+ } -+ -+FLOAT_MINMAX(max_s, 32, maxnum) -+FLOAT_MINMAX(max_d, 64, maxnum) -+FLOAT_MINMAX(maxa_s, 32, maxnummag) -+FLOAT_MINMAX(maxa_d, 64, maxnummag) -+ -+FLOAT_MINMAX(min_s, 32, minnum) -+FLOAT_MINMAX(min_d, 64, minnum) -+FLOAT_MINMAX(mina_s, 32, minnummag) -+FLOAT_MINMAX(mina_d, 64, minnummag) -+#undef FLOAT_MINMAX -+ -+#define FLOAT_FMADDSUB(name, bits, muladd_arg) \ -+ uint##bits##_t helper_float_##name(CPULOONGARCHState *env, \ -+ uint##bits##_t fs, uint##bits##_t ft, \ -+ uint##bits##_t fd) \ -+ { \ -+ uint##bits##_t fdret; \ -+ \ -+ fdret = float##bits##_muladd(fs, ft, fd, muladd_arg, \ -+ &env->active_fpu.fp_status); \ -+ update_fcsr0(env, GETPC()); \ -+ return fdret; \ -+ } -+ -+FLOAT_FMADDSUB(maddf_s, 32, 0) -+FLOAT_FMADDSUB(maddf_d, 64, 0) -+FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_c) -+FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_c) -+FLOAT_FMADDSUB(nmaddf_s, 32, float_muladd_negate_result) -+FLOAT_FMADDSUB(nmaddf_d, 64, float_muladd_negate_result) -+FLOAT_FMADDSUB(nmsubf_s, 32, -+ float_muladd_negate_result | float_muladd_negate_c) -+FLOAT_FMADDSUB(nmsubf_d, 64, -+ float_muladd_negate_result | float_muladd_negate_c) -+#undef FLOAT_FMADDSUB -+ -+/* compare operations */ -+#define FOP_CONDN_D(op, cond) \ -+ uint64_t helper_cmp_d_##op(CPULOONGARCHState *env, uint64_t fdt0, \ -+ uint64_t fdt1) \ -+ { \ -+ uint64_t c; \ -+ c = cond; \ -+ update_fcsr0(env, GETPC()); \ -+ if (c) { \ -+ return -1; \ -+ } else { \ -+ return 0; \ -+ } \ -+ } -+ -+/* -+ * NOTE: the comma operator will make "cond" to eval to false, -+ * but float64_unordered_quiet() is still called. -+ */ -+FOP_CONDN_D(af, -+ (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status), -+ 0)) -+FOP_CONDN_D(un, -+ (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status))) -+FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(ueq, -+ (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_eq_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(ult, -+ (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(ule, -+ (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+/* -+ * NOTE: the comma operator will make "cond" to eval to false, -+ * but float64_unordered() is still called. -+ */ -+FOP_CONDN_D(saf, -+ (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status), 0)) -+FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status))) -+FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(sle, (float64_le(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_le(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_le_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(une, -+ (float64_unordered_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_lt_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_lt_quiet(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(sor, (float64_le(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_le(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_lt(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))) -+FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0, &env->active_fpu.fp_status) || -+ float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))) -+ -+#define FOP_CONDN_S(op, cond) \ -+ uint32_t helper_cmp_s_##op(CPULOONGARCHState *env, uint32_t fst0, \ -+ uint32_t fst1) \ -+ { \ -+ uint64_t c; \ -+ c = cond; \ -+ update_fcsr0(env, GETPC()); \ -+ if (c) { \ -+ return -1; \ -+ } else { \ -+ return 0; \ -+ } \ -+ } -+ -+/* -+ * NOTE: the comma operator will make "cond" to eval to false, -+ * but float32_unordered_quiet() is still called. -+ */ -+FOP_CONDN_S(af, -+ (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status), -+ 0)) -+FOP_CONDN_S(un, -+ (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status))) -+FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(ueq, -+ (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_eq_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(ult, -+ (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(ule, -+ (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+/* -+ * NOTE: the comma operator will make "cond" to eval to false, -+ * but float32_unordered() is still called. -+ */ -+FOP_CONDN_S(saf, -+ (float32_unordered(fst1, fst0, &env->active_fpu.fp_status), 0)) -+FOP_CONDN_S(sun, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status))) -+FOP_CONDN_S(seq, (float32_eq(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_eq(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(slt, (float32_lt(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(sult, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_lt(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(sle, (float32_le(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(sule, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_le(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_le_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(une, -+ (float32_unordered_quiet(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_lt_quiet(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_lt_quiet(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(sor, (float32_le(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_le(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_lt(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_lt(fst0, fst1, &env->active_fpu.fp_status))) -+FOP_CONDN_S(sne, (float32_lt(fst1, fst0, &env->active_fpu.fp_status) || -+ float32_lt(fst0, fst1, &env->active_fpu.fp_status))) -+ -+uint32_t helper_float_logb_s(CPULOONGARCHState *env, uint32_t fst0) -+{ -+ uint32_t wt2; -+ -+ wt2 = float32_log2(fst0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return wt2; -+} -+ -+uint64_t helper_float_logb_d(CPULOONGARCHState *env, uint64_t fdt0) -+{ -+ uint64_t dt2; -+ -+ dt2 = float64_log2(fdt0, &env->active_fpu.fp_status); -+ update_fcsr0(env, GETPC()); -+ return dt2; -+} -+ -+target_ulong helper_fsel(CPULOONGARCHState *env, target_ulong fj, -+ target_ulong fk, uint32_t ca) -+{ -+ if (env->active_fpu.cf[ca & 0x7]) { -+ return fk; -+ } else { -+ return fj; -+ } -+} -diff --git a/target/loongarch64/fpu_helper.h b/target/loongarch64/fpu_helper.h -new file mode 100644 -index 0000000000..9efa7e30ca ---- /dev/null -+++ b/target/loongarch64/fpu_helper.h -@@ -0,0 +1,127 @@ -+/* -+ * loongarch internal definitions and helpers -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LOONGARCH_FPU_H -+#define LOONGARCH_FPU_H -+ -+#include "cpu-csr.h" -+ -+extern const struct loongarch_def_t loongarch_defs[]; -+extern const int loongarch_defs_number; -+ -+enum CPULSXDataFormat { DF_BYTE = 0, DF_HALF, DF_WORD, DF_DOUBLE, DF_QUAD }; -+ -+void loongarch_cpu_do_interrupt(CPUState *cpu); -+bool loongarch_cpu_exec_interrupt(CPUState *cpu, int int_req); -+void loongarch_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, -+ MMUAccessType access_type, int mmu_idx, -+ uintptr_t retaddr) QEMU_NORETURN; -+ -+#if !defined(CONFIG_USER_ONLY) -+ -+typedef struct r4k_tlb_t r4k_tlb_t; -+struct r4k_tlb_t { -+ target_ulong VPN; -+ uint32_t PageMask; -+ uint16_t ASID; -+ unsigned int G:1; -+ unsigned int C0:3; -+ unsigned int C1:3; -+ unsigned int V0:1; -+ unsigned int V1:1; -+ unsigned int D0:1; -+ unsigned int D1:1; -+ unsigned int XI0:1; -+ unsigned int XI1:1; -+ unsigned int RI0:1; -+ unsigned int RI1:1; -+ unsigned int EHINV:1; -+ uint64_t PPN[2]; -+}; -+ -+int no_mmu_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type); -+int fixed_mmu_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type); -+int r4k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type); -+ -+/* loongarch 3a5000 tlb helper function : lisa csr */ -+int ls3a5k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type); -+void ls3a5k_helper_tlbwr(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbfill(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbsrch(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbrd(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbclr(CPULOONGARCHState *env); -+void ls3a5k_helper_tlbflush(CPULOONGARCHState *env); -+void ls3a5k_invalidate_tlb(CPULOONGARCHState *env, int idx); -+void ls3a5k_helper_invtlb(CPULOONGARCHState *env, target_ulong addr, -+ target_ulong info, int op); -+void ls3a5k_flush_vtlb(CPULOONGARCHState *env); -+void ls3a5k_flush_ftlb(CPULOONGARCHState *env); -+hwaddr cpu_loongarch_translate_address(CPULOONGARCHState *env, -+ target_ulong address, int rw); -+#endif -+ -+#define cpu_signal_handler cpu_loongarch_signal_handler -+ -+static inline bool cpu_loongarch_hw_interrupts_enabled(CPULOONGARCHState *env) -+{ -+ bool ret = 0; -+ -+ ret = env->CSR_CRMD & (1 << CSR_CRMD_IE_SHIFT); -+ -+ return ret; -+} -+ -+void loongarch_tcg_init(void); -+ -+/* helper.c */ -+bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, -+ MMUAccessType access_type, int mmu_idx, bool probe, -+ uintptr_t retaddr); -+ -+/* op_helper.c */ -+uint32_t float_class_s(uint32_t arg, float_status *fst); -+uint64_t float_class_d(uint64_t arg, float_status *fst); -+ -+int ieee_ex_to_loongarch(int xcpt); -+void update_pagemask(CPULOONGARCHState *env, target_ulong arg1, -+ int32_t *pagemask); -+ -+void cpu_loongarch_tlb_flush(CPULOONGARCHState *env); -+void sync_c0_status(CPULOONGARCHState *env, CPULOONGARCHState *cpu, int tc); -+ -+void QEMU_NORETURN do_raise_exception_err(CPULOONGARCHState *env, -+ uint32_t exception, int error_code, -+ uintptr_t pc); -+int loongarch_read_qxfer(CPUState *cs, const char *annex, uint8_t *read_buf, -+ unsigned long offset, unsigned long len); -+int loongarch_write_qxfer(CPUState *cs, const char *annex, -+ const uint8_t *write_buf, unsigned long offset, -+ unsigned long len); -+ -+static inline void QEMU_NORETURN do_raise_exception(CPULOONGARCHState *env, -+ uint32_t exception, -+ uintptr_t pc) -+{ -+ do_raise_exception_err(env, exception, 0, pc); -+} -+#endif -diff --git a/target/loongarch64/gdbstub.c b/target/loongarch64/gdbstub.c -new file mode 100644 -index 0000000000..5ee91dc930 ---- /dev/null -+++ b/target/loongarch64/gdbstub.c -@@ -0,0 +1,164 @@ -+/* -+ * LOONGARCH gdb server stub -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu-common.h" -+#include "cpu.h" -+#include "internal.h" -+#include "exec/gdbstub.h" -+#ifdef CONFIG_TCG -+#include "exec/helper-proto.h" -+#endif -+ -+uint64_t read_fcc(CPULOONGARCHState *env) -+{ -+ uint64_t ret = 0; -+ -+ for (int i = 0; i < 8; ++i) { -+ ret |= (uint64_t)env->active_fpu.cf[i] << (i * 8); -+ } -+ -+ return ret; -+} -+ -+void write_fcc(CPULOONGARCHState *env, uint64_t val) -+{ -+ for (int i = 0; i < 8; ++i) { -+ env->active_fpu.cf[i] = (val >> (i * 8)) & 1; -+ } -+} -+ -+int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int size = 0; -+ -+ if (0 <= n && n < 32) { -+ return gdb_get_regl(mem_buf, env->active_tc.gpr[n]); -+ } -+ -+ switch (n) { -+ case 32: -+ size = gdb_get_regl(mem_buf, 0); -+ break; -+ case 33: -+ size = gdb_get_regl(mem_buf, env->active_tc.PC); -+ break; -+ case 34: -+ size = gdb_get_regl(mem_buf, env->CSR_BADV); -+ break; -+ default: -+ break; -+ } -+ -+ return size; -+} -+ -+int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ target_ulong tmp = ldtul_p(mem_buf); -+ int size = 0; -+ -+ if (0 <= n && n < 32) { -+ return env->active_tc.gpr[n] = tmp, sizeof(target_ulong); -+ } -+ -+ size = sizeof(target_ulong); -+ -+ switch (n) { -+ case 33: -+ env->active_tc.PC = tmp; -+ break; -+ case 32: -+ case 34: -+ default: -+ size = 0; -+ break; -+ } -+ -+ return size; -+} -+ -+static int loongarch_gdb_get_fpu(CPULOONGARCHState *env, GByteArray *mem_buf, -+ int n) -+{ -+ if (0 <= n && n < 32) { -+ return gdb_get_reg64(mem_buf, env->active_fpu.fpr[n].d); -+ } else if (n == 32) { -+ uint64_t val = read_fcc(env); -+ return gdb_get_reg64(mem_buf, val); -+ } else if (n == 33) { -+ return gdb_get_reg32(mem_buf, env->active_fpu.fcsr0); -+ } -+ return 0; -+} -+ -+static int loongarch_gdb_set_fpu(CPULOONGARCHState *env, uint8_t *mem_buf, -+ int n) -+{ -+ int length = 0; -+ -+ if (0 <= n && n < 32) { -+ env->active_fpu.fpr[n].d = ldq_p(mem_buf); -+ length = 8; -+ } else if (n == 32) { -+ uint64_t val = ldq_p(mem_buf); -+ write_fcc(env, val); -+ length = 8; -+ } else if (n == 33) { -+ env->active_fpu.fcsr0 = ldl_p(mem_buf); -+ length = 4; -+ } -+ return length; -+} -+ -+void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) -+{ -+ gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, -+ 34, "loongarch-fpu.xml", 0); -+} -+ -+#ifdef CONFIG_TCG -+int loongarch_read_qxfer(CPUState *cs, const char *annex, uint8_t *read_buf, -+ unsigned long offset, unsigned long len) -+{ -+ if (strncmp(annex, "cpucfg", sizeof("cpucfg") - 1) == 0) { -+ if (offset % 4 != 0 || len % 4 != 0) { -+ return 0; -+ } -+ -+ size_t i; -+ for (i = offset; i < offset + len; i += 4) -+ ((uint32_t *)read_buf)[(i - offset) / 4] = -+ helper_cpucfg(&(LOONGARCH_CPU(cs)->env), i / 4); -+ return 32 * 4; -+ } -+ return 0; -+} -+ -+int loongarch_write_qxfer(CPUState *cs, const char *annex, -+ const uint8_t *write_buf, unsigned long offset, -+ unsigned long len) -+{ -+ return 0; -+} -+#endif -diff --git a/target/loongarch64/helper.c b/target/loongarch64/helper.c -new file mode 100644 -index 0000000000..ec25803c1c ---- /dev/null -+++ b/target/loongarch64/helper.c -@@ -0,0 +1,726 @@ -+/* -+ * LOONGARCH emulation helpers for qemu. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "internal.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+#include "exec/log.h" -+#include "hw/loongarch/cpudevs.h" -+ -+#if !defined(CONFIG_USER_ONLY) -+ -+static int ls3a5k_map_address_tlb_entry(CPULOONGARCHState *env, -+ hwaddr *physical, int *prot, -+ target_ulong address, int rw, -+ int access_type, ls3a5k_tlb_t *tlb) -+{ -+ uint64_t mask = tlb->PageMask; -+ int n = !!(address & mask & ~(mask >> 1)); -+ uint32_t plv = env->CSR_CRMD & CSR_CRMD_PLV; -+ -+ /* Check access rights */ -+ if (!(n ? tlb->V1 : tlb->V0)) { -+ return TLBRET_INVALID; -+ } -+ -+ if (rw == MMU_INST_FETCH && (n ? tlb->XI1 : tlb->XI0)) { -+ return TLBRET_XI; -+ } -+ -+ if (rw == MMU_DATA_LOAD && (n ? tlb->RI1 : tlb->RI0)) { -+ return TLBRET_RI; -+ } -+ -+ if (plv > (n ? tlb->PLV1 : tlb->PLV0)) { -+ return TLBRET_PE; -+ } -+ -+ if (rw != MMU_DATA_STORE || (n ? tlb->WE1 : tlb->WE0)) { -+ /* -+ * PPN address -+ * 4 KB: [47:13] [12;0] -+ * 16 KB: [47:15] [14:0] -+ */ -+ if (n) { -+ *physical = tlb->PPN1 | (address & (mask >> 1)); -+ } else { -+ *physical = tlb->PPN0 | (address & (mask >> 1)); -+ } -+ *prot = PAGE_READ; -+ if (n ? tlb->WE1 : tlb->WE0) { -+ *prot |= PAGE_WRITE; -+ } -+ if (!(n ? tlb->XI1 : tlb->XI0)) { -+ *prot |= PAGE_EXEC; -+ } -+ return TLBRET_MATCH; -+ } -+ -+ return TLBRET_DIRTY; -+} -+ -+/* Loongarch 3A5K -style MMU emulation */ -+int ls3a5k_map_address(CPULOONGARCHState *env, hwaddr *physical, int *prot, -+ target_ulong address, int rw, int access_type) -+{ -+ uint16_t asid = env->CSR_ASID & 0x3ff; -+ int i; -+ ls3a5k_tlb_t *tlb; -+ -+ int ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ int vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; -+ -+ int ftlb_idx; -+ -+ uint64_t mask; -+ uint64_t vpn; /* address to map */ -+ uint64_t tag; /* address in TLB entry */ -+ -+ /* search VTLB */ -+ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ mask = tlb->PageMask; -+ -+ vpn = address & 0xffffffffe000 & ~mask; -+ tag = tlb->VPN & ~mask; -+ -+ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && -+ tlb->EHINV != 1) { -+ return ls3a5k_map_address_tlb_entry(env, physical, prot, address, -+ rw, access_type, tlb); -+ } -+ } -+ -+ if (ftlb_size == 0) { -+ return TLBRET_NOMATCH; -+ } -+ -+ /* search FTLB */ -+ mask = env->tlb->mmu.ls3a5k.ftlb_mask; -+ vpn = address & 0xffffffffe000 & ~mask; -+ -+ ftlb_idx = (address & 0xffffffffc000) >> 15; /* 16 KB */ -+ ftlb_idx = ftlb_idx & 0xff; /* [0,255] */ -+ -+ for (i = 0; i < 8; ++i) { -+ /* -+ * ---------- set 0 1 2 ... 7 -+ * ftlb_idx ----------------------------------- -+ * 0 | 0 1 2 ... 7 -+ * 1 | 8 9 10 ... 15 -+ * 2 | 16 17 18 ... 23 -+ * ... | -+ * 255 | 2040 2041 2042 ... 2047 -+ */ -+ tlb = &env->tlb->mmu.ls3a5k.tlb[ftlb_idx * 8 + i]; -+ tag = tlb->VPN & ~mask; -+ -+ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && -+ tlb->EHINV != 1) { -+ return ls3a5k_map_address_tlb_entry(env, physical, prot, address, -+ rw, access_type, tlb); -+ } -+ } -+ -+ return TLBRET_NOMATCH; -+} -+ -+static int get_physical_address(CPULOONGARCHState *env, hwaddr *physical, -+ int *prot, target_ulong real_address, int rw, -+ int access_type, int mmu_idx) -+{ -+ int user_mode = mmu_idx == LARCH_HFLAG_UM; -+ int kernel_mode = !user_mode; -+ unsigned plv, base_c, base_v, tmp; -+ -+ /* effective address (modified for KVM T&E kernel segments) */ -+ target_ulong address = real_address; -+ -+ /* Check PG */ -+ if (!(env->CSR_CRMD & CSR_CRMD_PG)) { -+ /* DA mode */ -+ *physical = address & 0xffffffffffffUL; -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ -+ plv = kernel_mode | (user_mode << 3); -+ base_v = address >> CSR_DMW_BASE_SH; -+ /* Check direct map window 0 */ -+ base_c = env->CSR_DMWIN0 >> CSR_DMW_BASE_SH; -+ if ((plv & env->CSR_DMWIN0) && (base_c == base_v)) { -+ *physical = dmwin_va2pa(address); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ /* Check direct map window 1 */ -+ base_c = env->CSR_DMWIN1 >> CSR_DMW_BASE_SH; -+ if ((plv & env->CSR_DMWIN1) && (base_c == base_v)) { -+ *physical = dmwin_va2pa(address); -+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ return TLBRET_MATCH; -+ } -+ /* Check valid extension */ -+ tmp = address >> 47; -+ if (!(tmp == 0 || tmp == 0x1ffff)) { -+ return TLBRET_BADADDR; -+ } -+ /* mapped address */ -+ return env->tlb->map_address(env, physical, prot, real_address, rw, -+ access_type); -+} -+ -+void cpu_loongarch_tlb_flush(CPULOONGARCHState *env) -+{ -+ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); -+ -+ /* Flush qemu's TLB and discard all shadowed entries. */ -+ tlb_flush(CPU(cpu)); -+ env->tlb->tlb_in_use = env->tlb->nb_tlb; -+} -+#endif -+ -+static void raise_mmu_exception(CPULOONGARCHState *env, target_ulong address, -+ int rw, int tlb_error) -+{ -+ CPUState *cs = CPU(loongarch_env_get_cpu(env)); -+ int exception = 0, error_code = 0; -+ -+ if (rw == MMU_INST_FETCH) { -+ error_code |= EXCP_INST_NOTAVAIL; -+ } -+ -+ switch (tlb_error) { -+ default: -+ case TLBRET_BADADDR: -+ /* Reference to kernel address from user mode or supervisor mode */ -+ /* Reference to supervisor address from user mode */ -+ if (rw == MMU_DATA_STORE) { -+ exception = EXCP_AdES; -+ } else { -+ exception = EXCP_AdEL; -+ } -+ break; -+ case TLBRET_NOMATCH: -+ /* No TLB match for a mapped address */ -+ if (rw == MMU_DATA_STORE) { -+ exception = EXCP_TLBS; -+ } else { -+ exception = EXCP_TLBL; -+ } -+ error_code |= EXCP_TLB_NOMATCH; -+ break; -+ case TLBRET_INVALID: -+ /* TLB match with no valid bit */ -+ if (rw == MMU_DATA_STORE) { -+ exception = EXCP_TLBS; -+ } else { -+ exception = EXCP_TLBL; -+ } -+ break; -+ case TLBRET_DIRTY: -+ /* TLB match but 'D' bit is cleared */ -+ exception = EXCP_LTLBL; -+ break; -+ case TLBRET_XI: -+ /* Execute-Inhibit Exception */ -+ exception = EXCP_TLBXI; -+ break; -+ case TLBRET_RI: -+ /* Read-Inhibit Exception */ -+ exception = EXCP_TLBRI; -+ break; -+ case TLBRET_PE: -+ /* Privileged Exception */ -+ exception = EXCP_TLBPE; -+ break; -+ } -+ -+ if (env->insn_flags & INSN_LOONGARCH) { -+ if (tlb_error == TLBRET_NOMATCH) { -+ env->CSR_TLBRBADV = address; -+ env->CSR_TLBREHI = address & (TARGET_PAGE_MASK << 1); -+ cs->exception_index = exception; -+ env->error_code = error_code; -+ return; -+ } -+ } -+ -+ /* Raise exception */ -+ env->CSR_BADV = address; -+ cs->exception_index = exception; -+ env->error_code = error_code; -+ -+ if (env->insn_flags & INSN_LOONGARCH) { -+ env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); -+ } -+} -+ -+bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, -+ MMUAccessType access_type, int mmu_idx, bool probe, -+ uintptr_t retaddr) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+#if !defined(CONFIG_USER_ONLY) -+ hwaddr physical; -+ int prot; -+ int loongarch_access_type; -+#endif -+ int ret = TLBRET_BADADDR; -+ -+ qemu_log_mask(CPU_LOG_MMU, -+ "%s pc " TARGET_FMT_lx " ad %" VADDR_PRIx " mmu_idx %d\n", -+ __func__, env->active_tc.PC, address, mmu_idx); -+ -+ /* data access */ -+#if !defined(CONFIG_USER_ONLY) -+ /* XXX: put correct access by using cpu_restore_state() correctly */ -+ loongarch_access_type = ACCESS_INT; -+ ret = get_physical_address(env, &physical, &prot, address, access_type, -+ loongarch_access_type, mmu_idx); -+ switch (ret) { -+ case TLBRET_MATCH: -+ qemu_log_mask(CPU_LOG_MMU, -+ "%s address=%" VADDR_PRIx " physical " TARGET_FMT_plx -+ " prot %d asid %ld pc 0x%lx\n", -+ __func__, address, physical, prot, env->CSR_ASID, -+ env->active_tc.PC); -+ break; -+ default: -+ qemu_log_mask(CPU_LOG_MMU, -+ "%s address=%" VADDR_PRIx " ret %d asid %ld pc 0x%lx\n", -+ __func__, address, ret, env->CSR_ASID, -+ env->active_tc.PC); -+ break; -+ } -+ if (ret == TLBRET_MATCH) { -+ tlb_set_page(cs, address & TARGET_PAGE_MASK, -+ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC, mmu_idx, -+ TARGET_PAGE_SIZE); -+ ret = true; -+ } -+ if (probe) { -+ return false; -+ } -+#endif -+ -+ raise_mmu_exception(env, address, access_type, ret); -+ do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr); -+} -+ -+#if !defined(CONFIG_USER_ONLY) -+hwaddr cpu_loongarch_translate_address(CPULOONGARCHState *env, -+ target_ulong address, int rw) -+{ -+ hwaddr physical; -+ int prot; -+ int access_type; -+ int ret = 0; -+ -+ /* data access */ -+ access_type = ACCESS_INT; -+ ret = get_physical_address(env, &physical, &prot, address, rw, access_type, -+ cpu_mmu_index(env, false)); -+ if (ret != TLBRET_MATCH) { -+ raise_mmu_exception(env, address, rw, ret); -+ return -1LL; -+ } else { -+ return physical; -+ } -+} -+ -+static const char *const excp_names[EXCP_LAST + 1] = { -+ [EXCP_RESET] = "reset", -+ [EXCP_SRESET] = "soft reset", -+ [EXCP_NMI] = "non-maskable interrupt", -+ [EXCP_EXT_INTERRUPT] = "interrupt", -+ [EXCP_AdEL] = "address error load", -+ [EXCP_AdES] = "address error store", -+ [EXCP_TLBF] = "TLB refill", -+ [EXCP_IBE] = "instruction bus error", -+ [EXCP_SYSCALL] = "syscall", -+ [EXCP_BREAK] = "break", -+ [EXCP_FPDIS] = "float unit unusable", -+ [EXCP_LSXDIS] = "vector128 unusable", -+ [EXCP_LASXDIS] = "vector256 unusable", -+ [EXCP_RI] = "reserved instruction", -+ [EXCP_OVERFLOW] = "arithmetic overflow", -+ [EXCP_TRAP] = "trap", -+ [EXCP_FPE] = "floating point", -+ [EXCP_LTLBL] = "TLB modify", -+ [EXCP_TLBL] = "TLB load", -+ [EXCP_TLBS] = "TLB store", -+ [EXCP_DBE] = "data bus error", -+ [EXCP_TLBXI] = "TLB execute-inhibit", -+ [EXCP_TLBRI] = "TLB read-inhibit", -+ [EXCP_TLBPE] = "TLB priviledged error", -+}; -+#endif -+ -+target_ulong exception_resume_pc(CPULOONGARCHState *env) -+{ -+ target_ulong bad_pc; -+ -+ bad_pc = env->active_tc.PC; -+ if (env->hflags & LARCH_HFLAG_BMASK) { -+ /* -+ * If the exception was raised from a delay slot, come back to -+ * the jump. -+ */ -+ bad_pc -= 4; -+ } -+ -+ return bad_pc; -+} -+ -+#if !defined(CONFIG_USER_ONLY) -+static void set_hflags_for_handler(CPULOONGARCHState *env) -+{ -+ /* Exception handlers are entered in 32-bit mode. */ -+} -+ -+static inline void set_badinstr_registers(CPULOONGARCHState *env) -+{ -+ if ((env->insn_flags & INSN_LOONGARCH)) { -+ env->CSR_BADI = cpu_ldl_code(env, env->active_tc.PC); -+ return; -+ } -+} -+#endif -+ -+static inline unsigned int get_vint_size(CPULOONGARCHState *env) -+{ -+ unsigned int size = 0; -+ -+ switch ((env->CSR_ECFG >> 16) & 0x7) { -+ case 0: -+ break; -+ case 1: -+ size = 2 * 4; /* #Insts * inst_size */ -+ break; -+ case 2: -+ size = 4 * 4; -+ break; -+ case 3: -+ size = 8 * 4; -+ break; -+ case 4: -+ size = 16 * 4; -+ break; -+ case 5: -+ size = 32 * 4; -+ break; -+ case 6: -+ size = 64 * 4; -+ break; -+ case 7: -+ size = 128 * 4; -+ break; -+ default: -+ printf("%s: unexpected value", __func__); -+ assert(0); -+ } -+ -+ return size; -+} -+ -+#define is_refill(cs, env) \ -+ (((cs->exception_index == EXCP_TLBL) || \ -+ (cs->exception_index == EXCP_TLBS)) && \ -+ (env->error_code & EXCP_TLB_NOMATCH)) -+ -+void loongarch_cpu_do_interrupt(CPUState *cs) -+{ -+#if !defined(CONFIG_USER_ONLY) -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ bool update_badinstr = 0; -+ int cause = -1; -+ const char *name; -+ -+ if (qemu_loglevel_mask(CPU_LOG_INT) && -+ cs->exception_index != EXCP_EXT_INTERRUPT) { -+ if (cs->exception_index < 0 || cs->exception_index > EXCP_LAST) { -+ name = "unknown"; -+ } else { -+ name = excp_names[cs->exception_index]; -+ } -+ -+ qemu_log("%s enter: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx -+ " TLBRERA 0x%016lx" -+ " %s exception\n", -+ __func__, env->active_tc.PC, env->CSR_ERA, env->CSR_TLBRERA, -+ name); -+ } -+ -+ switch (cs->exception_index) { -+ case EXCP_RESET: -+ cpu_reset(CPU(cpu)); -+ break; -+ case EXCP_NMI: -+ env->CSR_ERRERA = exception_resume_pc(env); -+ env->hflags &= ~LARCH_HFLAG_BMASK; -+ env->hflags |= LARCH_HFLAG_64; -+ env->hflags &= ~LARCH_HFLAG_AWRAP; -+ env->hflags &= ~(LARCH_HFLAG_KSU); -+ env->active_tc.PC = env->exception_base; -+ set_hflags_for_handler(env); -+ break; -+ case EXCP_EXT_INTERRUPT: -+ cause = 0; -+ goto set_ERA; -+ case EXCP_LTLBL: -+ cause = 1; -+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); -+ goto set_ERA; -+ case EXCP_TLBL: -+ cause = 2; -+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); -+ goto set_ERA; -+ case EXCP_TLBS: -+ cause = 3; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_AdEL: -+ cause = 4; -+ update_badinstr = !(env->error_code & EXCP_INST_NOTAVAIL); -+ goto set_ERA; -+ case EXCP_AdES: -+ cause = 5; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_IBE: -+ cause = 6; -+ goto set_ERA; -+ case EXCP_DBE: -+ cause = 7; -+ goto set_ERA; -+ case EXCP_SYSCALL: -+ cause = 8; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_BREAK: -+ cause = 9; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_RI: -+ cause = 10; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_FPDIS: -+ case EXCP_LSXDIS: -+ case EXCP_LASXDIS: -+ cause = 11; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_OVERFLOW: -+ cause = 12; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_TRAP: -+ cause = 13; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_FPE: -+ cause = 15; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_TLBRI: -+ cause = 19; -+ update_badinstr = 1; -+ goto set_ERA; -+ case EXCP_TLBXI: -+ case EXCP_TLBPE: -+ cause = 20; -+ goto set_ERA; -+ set_ERA: -+ if (is_refill(cs, env)) { -+ env->CSR_TLBRERA = exception_resume_pc(env); -+ env->CSR_TLBRERA |= 1; -+ } else { -+ env->CSR_ERA = exception_resume_pc(env); -+ } -+ -+ if (update_badinstr) { -+ set_badinstr_registers(env); -+ } -+ env->hflags &= ~(LARCH_HFLAG_KSU); -+ -+ env->hflags &= ~LARCH_HFLAG_BMASK; -+ if (env->insn_flags & INSN_LOONGARCH) { -+ /* save PLV and IE */ -+ if (is_refill(cs, env)) { -+ env->CSR_TLBRPRMD &= (~0x7); -+ env->CSR_TLBRPRMD |= (env->CSR_CRMD & 0x7); -+ } else { -+ env->CSR_PRMD &= (~0x7); -+ env->CSR_PRMD |= (env->CSR_CRMD & 0x7); -+ } -+ -+ env->CSR_CRMD &= ~(0x7); -+ -+ switch (cs->exception_index) { -+ case EXCP_EXT_INTERRUPT: -+ break; -+ case EXCP_TLBL: -+ if (env->error_code & EXCP_INST_NOTAVAIL) { -+ cause = EXCCODE_TLBI; -+ } else { -+ cause = EXCCODE_TLBL; -+ } -+ break; -+ case EXCP_TLBS: -+ cause = EXCCODE_TLBS; -+ break; -+ case EXCP_LTLBL: -+ cause = EXCCODE_MOD; -+ break; -+ case EXCP_TLBRI: -+ cause = EXCCODE_TLBRI; -+ break; -+ case EXCP_TLBXI: -+ cause = EXCCODE_TLBXI; -+ break; -+ case EXCP_TLBPE: -+ cause = EXCCODE_TLBPE; -+ break; -+ case EXCP_AdEL: -+ case EXCP_AdES: -+ case EXCP_IBE: -+ case EXCP_DBE: -+ cause = EXCCODE_ADE; -+ break; -+ case EXCP_SYSCALL: -+ cause = EXCCODE_SYS; -+ break; -+ case EXCP_BREAK: -+ cause = EXCCODE_BP; -+ break; -+ case EXCP_RI: -+ cause = EXCCODE_RI; -+ break; -+ case EXCP_FPDIS: -+ cause = EXCCODE_FPDIS; -+ break; -+ case EXCP_LSXDIS: -+ cause = EXCCODE_LSXDIS; -+ break; -+ case EXCP_LASXDIS: -+ cause = EXCCODE_LASXDIS; -+ break; -+ case EXCP_FPE: -+ cause = EXCCODE_FPE; -+ break; -+ default: -+ printf("Error: exception(%d) '%s' has not been supported\n", -+ cs->exception_index, excp_names[cs->exception_index]); -+ abort(); -+ } -+ -+ uint32_t vec_size = get_vint_size(env); -+ env->active_tc.PC = env->CSR_EEPN; -+ env->active_tc.PC += cause * vec_size; -+ if (is_refill(cs, env)) { -+ /* TLB Refill */ -+ env->active_tc.PC = env->CSR_TLBRENT; -+ break; /* Do not modify excode */ -+ } -+ if (cs->exception_index == EXCP_EXT_INTERRUPT) { -+ /* Interrupt */ -+ uint32_t vector = 0; -+ uint32_t pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK; -+ pending &= env->CSR_ECFG & CSR_ECFG_IPMASK; -+ -+ /* Find the highest-priority interrupt. */ -+ while (pending >>= 1) { -+ vector++; -+ } -+ env->active_tc.PC = -+ env->CSR_EEPN + (EXCODE_IP + vector) * vec_size; -+ if (qemu_loglevel_mask(CPU_LOG_INT)) { -+ qemu_log("%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx -+ " cause %d\n" -+ " A " TARGET_FMT_lx " D " TARGET_FMT_lx -+ " vector = %d ExC %08lx ExS %08lx\n", -+ __func__, env->active_tc.PC, env->CSR_ERA, cause, -+ env->CSR_BADV, env->CSR_DERA, vector, -+ env->CSR_ECFG, env->CSR_ESTAT); -+ } -+ } -+ /* Excode */ -+ env->CSR_ESTAT = (env->CSR_ESTAT & ~(0x1f << CSR_ESTAT_EXC_SH)) | -+ (cause << CSR_ESTAT_EXC_SH); -+ } -+ set_hflags_for_handler(env); -+ break; -+ default: -+ abort(); -+ } -+ if (qemu_loglevel_mask(CPU_LOG_INT) && -+ cs->exception_index != EXCP_EXT_INTERRUPT) { -+ qemu_log("%s: PC " TARGET_FMT_lx " ERA 0x%08lx" -+ " cause %d%s\n" -+ " ESTAT %08lx EXCFG 0x%08lx BADVA 0x%08lx BADI 0x%08lx \ -+ SYS_NUM %lu cpu %d asid 0x%lx" -+ "\n", -+ __func__, env->active_tc.PC, -+ is_refill(cs, env) ? env->CSR_TLBRERA : env->CSR_ERA, cause, -+ is_refill(cs, env) ? "(refill)" : "", env->CSR_ESTAT, -+ env->CSR_ECFG, -+ is_refill(cs, env) ? env->CSR_TLBRBADV : env->CSR_BADV, -+ env->CSR_BADI, env->active_tc.gpr[11], cs->cpu_index, -+ env->CSR_ASID); -+ } -+#endif -+ cs->exception_index = EXCP_NONE; -+} -+ -+bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request) -+{ -+ if (interrupt_request & CPU_INTERRUPT_HARD) { -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ -+ if (cpu_loongarch_hw_interrupts_enabled(env) && -+ cpu_loongarch_hw_interrupts_pending(env)) { -+ /* Raise it */ -+ cs->exception_index = EXCP_EXT_INTERRUPT; -+ env->error_code = 0; -+ loongarch_cpu_do_interrupt(cs); -+ return true; -+ } -+ } -+ return false; -+} -+ -+void QEMU_NORETURN do_raise_exception_err(CPULOONGARCHState *env, -+ uint32_t exception, int error_code, -+ uintptr_t pc) -+{ -+ CPUState *cs = CPU(loongarch_env_get_cpu(env)); -+ -+ qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", __func__, exception, error_code); -+ cs->exception_index = exception; -+ env->error_code = error_code; -+ -+ cpu_loop_exit_restore(cs, pc); -+} -diff --git a/target/loongarch64/helper.h b/target/loongarch64/helper.h -new file mode 100644 -index 0000000000..868b16da1e ---- /dev/null -+++ b/target/loongarch64/helper.h -@@ -0,0 +1,178 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int) -+DEF_HELPER_2(raise_exception, noreturn, env, i32) -+DEF_HELPER_1(raise_exception_debug, noreturn, env) -+ -+DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) -+DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) -+ -+DEF_HELPER_3(crc32, tl, tl, tl, i32) -+DEF_HELPER_3(crc32c, tl, tl, tl, i32) -+ -+#ifndef CONFIG_USER_ONLY -+/* LoongISA CSR register */ -+DEF_HELPER_2(csr_rdq, tl, env, i64) -+DEF_HELPER_3(csr_wrq, tl, env, tl, i64) -+DEF_HELPER_4(csr_xchgq, tl, env, tl, tl, i64) -+ -+#endif /* !CONFIG_USER_ONLY */ -+ -+/* CP1 functions */ -+DEF_HELPER_2(movfcsr2gr, tl, env, i32) -+DEF_HELPER_4(movgr2fcsr, void, env, tl, i32, i32) -+ -+DEF_HELPER_2(float_cvtd_s, i64, env, i32) -+DEF_HELPER_2(float_cvtd_w, i64, env, i32) -+DEF_HELPER_2(float_cvtd_l, i64, env, i64) -+DEF_HELPER_2(float_cvts_d, i32, env, i64) -+DEF_HELPER_2(float_cvts_w, i32, env, i32) -+DEF_HELPER_2(float_cvts_l, i32, env, i64) -+ -+DEF_HELPER_FLAGS_2(float_class_s, TCG_CALL_NO_RWG_SE, i32, env, i32) -+DEF_HELPER_FLAGS_2(float_class_d, TCG_CALL_NO_RWG_SE, i64, env, i64) -+ -+#define FOP_PROTO(op) \ -+ DEF_HELPER_4(float_##op##_s, i32, env, i32, i32, i32) \ -+ DEF_HELPER_4(float_##op##_d, i64, env, i64, i64, i64) -+FOP_PROTO(maddf) -+FOP_PROTO(msubf) -+FOP_PROTO(nmaddf) -+FOP_PROTO(nmsubf) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+ DEF_HELPER_3(float_##op##_s, i32, env, i32, i32) \ -+ DEF_HELPER_3(float_##op##_d, i64, env, i64, i64) -+FOP_PROTO(max) -+FOP_PROTO(maxa) -+FOP_PROTO(min) -+FOP_PROTO(mina) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+ DEF_HELPER_2(float_##op##_l_s, i64, env, i32) \ -+ DEF_HELPER_2(float_##op##_l_d, i64, env, i64) \ -+ DEF_HELPER_2(float_##op##_w_s, i32, env, i32) \ -+ DEF_HELPER_2(float_##op##_w_d, i32, env, i64) -+FOP_PROTO(cvt) -+FOP_PROTO(round) -+FOP_PROTO(trunc) -+FOP_PROTO(ceil) -+FOP_PROTO(floor) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+ DEF_HELPER_2(float_##op##_s, i32, env, i32) \ -+ DEF_HELPER_2(float_##op##_d, i64, env, i64) -+FOP_PROTO(sqrt) -+FOP_PROTO(rsqrt) -+FOP_PROTO(recip) -+FOP_PROTO(rint) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+ DEF_HELPER_1(float_##op##_s, i32, i32) \ -+ DEF_HELPER_1(float_##op##_d, i64, i64) -+FOP_PROTO(abs) -+FOP_PROTO(chs) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+ DEF_HELPER_3(float_##op##_s, i32, env, i32, i32) \ -+ DEF_HELPER_3(float_##op##_d, i64, env, i64, i64) -+FOP_PROTO(add) -+FOP_PROTO(sub) -+FOP_PROTO(mul) -+FOP_PROTO(div) -+#undef FOP_PROTO -+ -+#define FOP_PROTO(op) \ -+ DEF_HELPER_3(cmp_d_##op, i64, env, i64, i64) \ -+ DEF_HELPER_3(cmp_s_##op, i32, env, i32, i32) -+FOP_PROTO(af) -+FOP_PROTO(un) -+FOP_PROTO(eq) -+FOP_PROTO(ueq) -+FOP_PROTO(lt) -+FOP_PROTO(ult) -+FOP_PROTO(le) -+FOP_PROTO(ule) -+FOP_PROTO(saf) -+FOP_PROTO(sun) -+FOP_PROTO(seq) -+FOP_PROTO(sueq) -+FOP_PROTO(slt) -+FOP_PROTO(sult) -+FOP_PROTO(sle) -+FOP_PROTO(sule) -+FOP_PROTO(or) -+FOP_PROTO(une) -+FOP_PROTO(ne) -+FOP_PROTO(sor) -+FOP_PROTO(sune) -+FOP_PROTO(sne) -+#undef FOP_PROTO -+ -+/* Special functions */ -+#ifndef CONFIG_USER_ONLY -+DEF_HELPER_1(tlbwr, void, env) -+DEF_HELPER_1(tlbfill, void, env) -+DEF_HELPER_1(tlbsrch, void, env) -+DEF_HELPER_1(tlbrd, void, env) -+DEF_HELPER_1(tlbclr, void, env) -+DEF_HELPER_1(tlbflush, void, env) -+DEF_HELPER_4(invtlb, void, env, tl, tl, tl) -+DEF_HELPER_1(ertn, void, env) -+DEF_HELPER_5(lddir, void, env, tl, tl, tl, i32) -+DEF_HELPER_4(ldpte, void, env, tl, tl, i32) -+DEF_HELPER_3(drdtime, void, env, tl, tl) -+DEF_HELPER_1(read_pgd, tl, env) -+#endif /* !CONFIG_USER_ONLY */ -+DEF_HELPER_2(cpucfg, tl, env, tl) -+DEF_HELPER_1(idle, void, env) -+ -+DEF_HELPER_3(float_exp2_s, i32, env, i32, i32) -+DEF_HELPER_3(float_exp2_d, i64, env, i64, i64) -+DEF_HELPER_2(float_logb_s, i32, env, i32) -+DEF_HELPER_2(float_logb_d, i64, env, i64) -+DEF_HELPER_3(movreg2cf, void, env, i32, tl) -+DEF_HELPER_2(movcf2reg, tl, env, i32) -+DEF_HELPER_3(movreg2cf_i32, void, env, i32, i32) -+DEF_HELPER_3(movreg2cf_i64, void, env, i32, i64) -+ -+DEF_HELPER_2(cto_w, tl, env, tl) -+DEF_HELPER_2(ctz_w, tl, env, tl) -+DEF_HELPER_2(cto_d, tl, env, tl) -+DEF_HELPER_2(ctz_d, tl, env, tl) -+DEF_HELPER_2(bitrev_w, tl, env, tl) -+DEF_HELPER_2(bitrev_d, tl, env, tl) -+ -+DEF_HELPER_2(load_scr, i64, env, i32) -+DEF_HELPER_3(store_scr, void, env, i32, i64) -+ -+DEF_HELPER_3(asrtle_d, void, env, tl, tl) -+DEF_HELPER_3(asrtgt_d, void, env, tl, tl) -+ -+DEF_HELPER_4(fsel, i64, env, i64, i64, i32) -+ -+#ifndef CONFIG_USER_ONLY -+DEF_HELPER_4(iocsr, void, env, tl, tl, i32) -+#endif -+DEF_HELPER_3(memtrace_addr, void, env, tl, i32) -+DEF_HELPER_2(memtrace_val, void, env, tl) -diff --git a/target/loongarch64/insn.decode b/target/loongarch64/insn.decode -new file mode 100644 -index 0000000000..2f82441ea7 ---- /dev/null -+++ b/target/loongarch64/insn.decode -@@ -0,0 +1,532 @@ -+# -+# loongarch ISA decode for 64-bit prefixed insns -+# -+# Copyright (c) 2023 Loongarch Technology -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms and conditions of the GNU General Public License, -+# version 2 or later, as published by the Free Software Foundation. -+# -+# This program is distributed in the hope it will be useful, but WITHOUT -+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+# more details. -+# -+# You should have received a copy of the GNU General Public License along with -+# this program. If not, see . -+# -+ -+# Fields -+%sd 0:2 -+%rj 5:5 -+%rd 0:5 -+%sj 5:2 -+%ptr 5:3 -+%rk 10:5 -+%sa2 15:2 -+%sa3 15:3 -+%si5 10:s5 -+%code 0:15 -+%cond 10:4 -+%cond2 0:4 -+%ui5 10:5 -+%ui6 10:6 -+%ui3 10:3 -+%ui4 10:4 -+%op 5:5 -+%ui8 10:8 -+%msbw 16:5 -+%lsbw 10:5 -+%msbd 16:6 -+%lsbd 10:6 -+%fd 0:5 -+%fj 5:5 -+%fk 10:5 -+%fcsrd 0:5 -+%fcsrs 5:5 -+%cd 0:3 -+%cj 5:3 -+%si12 10:s12 -+%ui12 10:12 -+%csr 10:14 -+%cop 0:5 -+%level 10:8 -+%seq 10:8 -+%whint 0:15 -+%addr 10:5 -+%info 5:5 -+%invop 0:5 -+%fa 15:5 -+%vd 0:5 -+%vj 5:5 -+%vk 10:5 -+%va 15:5 -+%xd 0:5 -+%xj 5:5 -+%xk 10:5 -+%xa 15:5 -+%fcond 15:5 -+%ca 15:3 -+%vui5 15:5 -+%si16 10:s16 -+%si20 5:s20 -+%si14 10:s14 -+%hint 0:5 -+%si9 10:s9 -+%si10 10:s10 -+%si11 10:s11 -+%si8 10:s8 -+%idx1 18:1 -+%idx2 18:2 -+%idx3 18:3 -+%idx4 18:4 -+%idx 18:5 -+%offs21 0:s5 10:16 -+%offs16 10:s16 -+%offs 0:s10 10:16 -+%mode 5:5 -+%ui2 10:2 -+%ui1 10:1 -+%ui7 10:7 -+%i13 5:13 -+ -+# Argument sets -+&fmt_sdrj sd rj -+&fmt_rdsj rd sj -+&fmt_rdrj rd rj -+&fmt_empty -+&fmt_rjrk rj rk -+&fmt_rdrjrksa2 rd rj rk sa2 -+&fmt_rdrjrksa3 rd rj rk sa3 -+&fmt_rdrjrk rd rj rk -+&fmt_code code -+&fmt_rdrjui5 rd rj ui5 -+&fmt_rdrjui6 rd rj ui6 -+&fmt_rdrjmsbwlsbw rd rj msbw lsbw -+&fmt_rdrjmsbdlsbd rd rj msbd lsbd -+&fmt_fdfjfk fd fj fk -+&fmt_fdfj fd fj -+&fmt_fdrj fd rj -+&fmt_rdfj rd fj -+&fmt_fcsrdrj fcsrd rj -+&fmt_rdfcsrs rd fcsrs -+&fmt_cdfj cd fj -+&fmt_fdcj fd cj -+&fmt_cdrj cd rj -+&fmt_rdcj rd cj -+&fmt_rdrjsi12 rd rj si12 -+&fmt_rdrjui12 rd rj ui12 -+&fmt_rdrjcsr rd rj csr -+&fmt_coprjsi12 cop rj si12 -+&fmt_rdrjlevel rd rj level -+&fmt_rjseq rj seq -+&fmt_whint whint -+&fmt_invtlb addr info invop -+&fmt_fdfjfkfa fd fj fk fa -+&fmt_cdfjfkfcond cd fj fk fcond -+&fmt_fdfjfkca fd fj fk ca -+&fmt_rdrjsi16 rd rj si16 -+&fmt_rdsi20 rd si20 -+&fmt_rdrjsi14 rd rj si14 -+&fmt_hintrjsi12 hint rj si12 -+&fmt_fdrjsi12 fd rj si12 -+&fmt_fdrjrk fd rj rk -+&fmt_rjoffs21 rj offs21 -+&fmt_cjoffs21 cj offs21 -+&fmt_rdrjoffs16 rd rj offs16 -+&fmt_offs offs -+&fmt_rjrdoffs16 rj rd offs16 -+ -+# Formats -+@fmt_sdrj .... ........ ..... ..... ..... ... .. &fmt_sdrj %sd %rj -+@fmt_rdsj .... ........ ..... ..... ... .. ..... &fmt_rdsj %rd %sj -+@fmt_rdrj .... ........ ..... ..... ..... ..... &fmt_rdrj %rd %rj -+@fmt_empty .... ........ ..... ..... ..... ..... &fmt_empty -+@fmt_rjrk .... ........ ..... ..... ..... ..... &fmt_rjrk %rj %rk -+@fmt_rdrjrksa2 .... ........ ... .. ..... ..... ..... &fmt_rdrjrksa2 %rd %rj %rk %sa2 -+@fmt_rdrjrksa3 .... ........ .. ... ..... ..... ..... &fmt_rdrjrksa3 %rd %rj %rk %sa3 -+@fmt_rdrjrk .... ........ ..... ..... ..... ..... &fmt_rdrjrk %rd %rj %rk -+@fmt_code .... ........ ..... ............... &fmt_code %code -+@fmt_rdrjui5 .... ........ ..... ..... ..... ..... &fmt_rdrjui5 %rd %rj %ui5 -+@fmt_rdrjui6 .... ........ .... ...... ..... ..... &fmt_rdrjui6 %rd %rj %ui6 -+@fmt_rdrjmsbwlsbw .... ....... ..... . ..... ..... ..... &fmt_rdrjmsbwlsbw %rd %rj %msbw %lsbw -+@fmt_rdrjmsbdlsbd .... ...... ...... ...... ..... ..... &fmt_rdrjmsbdlsbd %rd %rj %msbd %lsbd -+@fmt_fdfjfk .... ........ ..... ..... ..... ..... &fmt_fdfjfk %fd %fj %fk -+@fmt_fdfj .... ........ ..... ..... ..... ..... &fmt_fdfj %fd %fj -+@fmt_fdrj .... ........ ..... ..... ..... ..... &fmt_fdrj %fd %rj -+@fmt_rdfj .... ........ ..... ..... ..... ..... &fmt_rdfj %rd %fj -+@fmt_fcsrdrj .... ........ ..... ..... ..... ..... &fmt_fcsrdrj %fcsrd %rj -+@fmt_rdfcsrs .... ........ ..... ..... ..... ..... &fmt_rdfcsrs %rd %fcsrs -+@fmt_cdfj .... ........ ..... ..... ..... .. ... &fmt_cdfj %cd %fj -+@fmt_fdcj .... ........ ..... ..... .. ... ..... &fmt_fdcj %fd %cj -+@fmt_cdrj .... ........ ..... ..... ..... .. ... &fmt_cdrj %cd %rj -+@fmt_rdcj .... ........ ..... ..... .. ... ..... &fmt_rdcj %rd %cj -+@fmt_rdrjsi12 .... ...... ............ ..... ..... &fmt_rdrjsi12 %rd %rj %si12 -+@fmt_rdrjui12 .... ...... ............ ..... ..... &fmt_rdrjui12 %rd %rj %ui12 -+@fmt_rdrjcsr .... .... .............. ..... ..... &fmt_rdrjcsr %rd %rj %csr -+@fmt_coprjsi12 .... ...... ............ ..... ..... &fmt_coprjsi12 %cop %rj %si12 -+@fmt_rdrjlevel .... ........ .. ........ ..... ..... &fmt_rdrjlevel %rd %rj %level -+@fmt_rjseq .... ........ .. ........ ..... ..... &fmt_rjseq %rj %seq -+@fmt_whint .... ........ ..... ............... &fmt_whint %whint -+@fmt_invtlb ...... ...... ..... ..... ..... ..... &fmt_invtlb %addr %info %invop -+@fmt_fdfjfkfa .... ........ ..... ..... ..... ..... &fmt_fdfjfkfa %fd %fj %fk %fa -+@fmt_cdfjfkfcond .... ........ ..... ..... ..... .. ... &fmt_cdfjfkfcond %cd %fj %fk %fcond -+@fmt_fdfjfkca .... ........ .. ... ..... ..... ..... &fmt_fdfjfkca %fd %fj %fk %ca -+@fmt_rdrjsi16 .... .. ................ ..... ..... &fmt_rdrjsi16 %rd %rj %si16 -+@fmt_rdsi20 .... ... .................... ..... &fmt_rdsi20 %rd %si20 -+@fmt_rdrjsi14 .... .... .............. ..... ..... &fmt_rdrjsi14 %rd %rj %si14 -+@fmt_hintrjsi12 .... ...... ............ ..... ..... &fmt_hintrjsi12 %hint %rj %si12 -+@fmt_fdrjsi12 .... ...... ............ ..... ..... &fmt_fdrjsi12 %fd %rj %si12 -+@fmt_fdrjrk .... ........ ..... ..... ..... ..... &fmt_fdrjrk %fd %rj %rk -+@fmt_rjoffs21 .... .. ................ ..... ..... &fmt_rjoffs21 %rj %offs21 -+@fmt_cjoffs21 .... .. ................ .. ... ..... &fmt_cjoffs21 %cj %offs21 -+@fmt_rdrjoffs16 .... .. ................ ..... ..... &fmt_rdrjoffs16 %rd %rj %offs16 -+@fmt_offs .... .. .......................... &fmt_offs %offs -+@fmt_rjrdoffs16 .... .. ................ ..... ..... &fmt_rjrdoffs16 %rj %rd %offs16 -+ -+# Instructions -+ -+# Fiexd point arithmetic Instructions -+gr2scr 0000 00000000 00000 00010 ..... 000 .. @fmt_sdrj -+scr2gr 0000 00000000 00000 00011 000 .. ..... @fmt_rdsj -+clo_w 0000 00000000 00000 00100 ..... ..... @fmt_rdrj -+clz_w 0000 00000000 00000 00101 ..... ..... @fmt_rdrj -+cto_w 0000 00000000 00000 00110 ..... ..... @fmt_rdrj -+ctz_w 0000 00000000 00000 00111 ..... ..... @fmt_rdrj -+clo_d 0000 00000000 00000 01000 ..... ..... @fmt_rdrj -+clz_d 0000 00000000 00000 01001 ..... ..... @fmt_rdrj -+cto_d 0000 00000000 00000 01010 ..... ..... @fmt_rdrj -+ctz_d 0000 00000000 00000 01011 ..... ..... @fmt_rdrj -+revb_2h 0000 00000000 00000 01100 ..... ..... @fmt_rdrj -+revb_4h 0000 00000000 00000 01101 ..... ..... @fmt_rdrj -+revb_2w 0000 00000000 00000 01110 ..... ..... @fmt_rdrj -+revb_d 0000 00000000 00000 01111 ..... ..... @fmt_rdrj -+revh_2w 0000 00000000 00000 10000 ..... ..... @fmt_rdrj -+revh_d 0000 00000000 00000 10001 ..... ..... @fmt_rdrj -+bitrev_4b 0000 00000000 00000 10010 ..... ..... @fmt_rdrj -+bitrev_8b 0000 00000000 00000 10011 ..... ..... @fmt_rdrj -+bitrev_w 0000 00000000 00000 10100 ..... ..... @fmt_rdrj -+bitrev_d 0000 00000000 00000 10101 ..... ..... @fmt_rdrj -+ext_w_h 0000 00000000 00000 10110 ..... ..... @fmt_rdrj -+ext_w_b 0000 00000000 00000 10111 ..... ..... @fmt_rdrj -+rdtime_d 0000 00000000 00000 11010 ..... ..... @fmt_rdrj -+cpucfg 0000 00000000 00000 11011 ..... ..... @fmt_rdrj -+asrtle_d 0000 00000000 00010 ..... ..... 00000 @fmt_rjrk -+asrtgt_d 0000 00000000 00011 ..... ..... 00000 @fmt_rjrk -+alsl_w 0000 00000000 010 .. ..... ..... ..... @fmt_rdrjrksa2 -+alsl_wu 0000 00000000 011 .. ..... ..... ..... @fmt_rdrjrksa2 -+bytepick_w 0000 00000000 100 .. ..... ..... ..... @fmt_rdrjrksa2 -+bytepick_d 0000 00000000 11 ... ..... ..... ..... @fmt_rdrjrksa3 -+add_w 0000 00000001 00000 ..... ..... ..... @fmt_rdrjrk -+add_d 0000 00000001 00001 ..... ..... ..... @fmt_rdrjrk -+sub_w 0000 00000001 00010 ..... ..... ..... @fmt_rdrjrk -+sub_d 0000 00000001 00011 ..... ..... ..... @fmt_rdrjrk -+slt 0000 00000001 00100 ..... ..... ..... @fmt_rdrjrk -+sltu 0000 00000001 00101 ..... ..... ..... @fmt_rdrjrk -+maskeqz 0000 00000001 00110 ..... ..... ..... @fmt_rdrjrk -+masknez 0000 00000001 00111 ..... ..... ..... @fmt_rdrjrk -+nor 0000 00000001 01000 ..... ..... ..... @fmt_rdrjrk -+and 0000 00000001 01001 ..... ..... ..... @fmt_rdrjrk -+or 0000 00000001 01010 ..... ..... ..... @fmt_rdrjrk -+xor 0000 00000001 01011 ..... ..... ..... @fmt_rdrjrk -+orn 0000 00000001 01100 ..... ..... ..... @fmt_rdrjrk -+andn 0000 00000001 01101 ..... ..... ..... @fmt_rdrjrk -+sll_w 0000 00000001 01110 ..... ..... ..... @fmt_rdrjrk -+srl_w 0000 00000001 01111 ..... ..... ..... @fmt_rdrjrk -+sra_w 0000 00000001 10000 ..... ..... ..... @fmt_rdrjrk -+sll_d 0000 00000001 10001 ..... ..... ..... @fmt_rdrjrk -+srl_d 0000 00000001 10010 ..... ..... ..... @fmt_rdrjrk -+sra_d 0000 00000001 10011 ..... ..... ..... @fmt_rdrjrk -+rotr_w 0000 00000001 10110 ..... ..... ..... @fmt_rdrjrk -+rotr_d 0000 00000001 10111 ..... ..... ..... @fmt_rdrjrk -+mul_w 0000 00000001 11000 ..... ..... ..... @fmt_rdrjrk -+mulh_w 0000 00000001 11001 ..... ..... ..... @fmt_rdrjrk -+mulh_wu 0000 00000001 11010 ..... ..... ..... @fmt_rdrjrk -+mul_d 0000 00000001 11011 ..... ..... ..... @fmt_rdrjrk -+mulh_d 0000 00000001 11100 ..... ..... ..... @fmt_rdrjrk -+mulh_du 0000 00000001 11101 ..... ..... ..... @fmt_rdrjrk -+mulw_d_w 0000 00000001 11110 ..... ..... ..... @fmt_rdrjrk -+mulw_d_wu 0000 00000001 11111 ..... ..... ..... @fmt_rdrjrk -+div_w 0000 00000010 00000 ..... ..... ..... @fmt_rdrjrk -+mod_w 0000 00000010 00001 ..... ..... ..... @fmt_rdrjrk -+div_wu 0000 00000010 00010 ..... ..... ..... @fmt_rdrjrk -+mod_wu 0000 00000010 00011 ..... ..... ..... @fmt_rdrjrk -+div_d 0000 00000010 00100 ..... ..... ..... @fmt_rdrjrk -+mod_d 0000 00000010 00101 ..... ..... ..... @fmt_rdrjrk -+div_du 0000 00000010 00110 ..... ..... ..... @fmt_rdrjrk -+mod_du 0000 00000010 00111 ..... ..... ..... @fmt_rdrjrk -+crc_w_b_w 0000 00000010 01000 ..... ..... ..... @fmt_rdrjrk -+crc_w_h_w 0000 00000010 01001 ..... ..... ..... @fmt_rdrjrk -+crc_w_w_w 0000 00000010 01010 ..... ..... ..... @fmt_rdrjrk -+crc_w_d_w 0000 00000010 01011 ..... ..... ..... @fmt_rdrjrk -+crcc_w_b_w 0000 00000010 01100 ..... ..... ..... @fmt_rdrjrk -+crcc_w_h_w 0000 00000010 01101 ..... ..... ..... @fmt_rdrjrk -+crcc_w_w_w 0000 00000010 01110 ..... ..... ..... @fmt_rdrjrk -+crcc_w_d_w 0000 00000010 01111 ..... ..... ..... @fmt_rdrjrk -+break 0000 00000010 10100 ............... @fmt_code -+dbcl 0000 00000010 10101 ............... @fmt_code -+syscall 0000 00000010 10110 ............... @fmt_code -+alsl_d 0000 00000010 110 .. ..... ..... ..... @fmt_rdrjrksa2 -+slli_w 0000 00000100 00001 ..... ..... ..... @fmt_rdrjui5 -+slli_d 0000 00000100 0001 ...... ..... ..... @fmt_rdrjui6 -+srli_w 0000 00000100 01001 ..... ..... ..... @fmt_rdrjui5 -+srli_d 0000 00000100 0101 ...... ..... ..... @fmt_rdrjui6 -+srai_w 0000 00000100 10001 ..... ..... ..... @fmt_rdrjui5 -+srai_d 0000 00000100 1001 ...... ..... ..... @fmt_rdrjui6 -+rotri_w 0000 00000100 11001 ..... ..... ..... @fmt_rdrjui5 -+rotri_d 0000 00000100 1101 ...... ..... ..... @fmt_rdrjui6 -+bstrins_w 0000 0000011 ..... 0 ..... ..... ..... @fmt_rdrjmsbwlsbw -+bstrpick_w 0000 0000011 ..... 1 ..... ..... ..... @fmt_rdrjmsbwlsbw -+bstrins_d 0000 000010 ...... ...... ..... ..... @fmt_rdrjmsbdlsbd -+bstrpick_d 0000 000011 ...... ...... ..... ..... @fmt_rdrjmsbdlsbd -+ -+# float Instructions -+fadd_s 0000 00010000 00001 ..... ..... ..... @fmt_fdfjfk -+fadd_d 0000 00010000 00010 ..... ..... ..... @fmt_fdfjfk -+fsub_s 0000 00010000 00101 ..... ..... ..... @fmt_fdfjfk -+fsub_d 0000 00010000 00110 ..... ..... ..... @fmt_fdfjfk -+fmul_s 0000 00010000 01001 ..... ..... ..... @fmt_fdfjfk -+fmul_d 0000 00010000 01010 ..... ..... ..... @fmt_fdfjfk -+fdiv_s 0000 00010000 01101 ..... ..... ..... @fmt_fdfjfk -+fdiv_d 0000 00010000 01110 ..... ..... ..... @fmt_fdfjfk -+fmax_s 0000 00010000 10001 ..... ..... ..... @fmt_fdfjfk -+fmax_d 0000 00010000 10010 ..... ..... ..... @fmt_fdfjfk -+fmin_s 0000 00010000 10101 ..... ..... ..... @fmt_fdfjfk -+fmin_d 0000 00010000 10110 ..... ..... ..... @fmt_fdfjfk -+fmaxa_s 0000 00010000 11001 ..... ..... ..... @fmt_fdfjfk -+fmaxa_d 0000 00010000 11010 ..... ..... ..... @fmt_fdfjfk -+fmina_s 0000 00010000 11101 ..... ..... ..... @fmt_fdfjfk -+fmina_d 0000 00010000 11110 ..... ..... ..... @fmt_fdfjfk -+fscaleb_s 0000 00010001 00001 ..... ..... ..... @fmt_fdfjfk -+fscaleb_d 0000 00010001 00010 ..... ..... ..... @fmt_fdfjfk -+fcopysign_s 0000 00010001 00101 ..... ..... ..... @fmt_fdfjfk -+fcopysign_d 0000 00010001 00110 ..... ..... ..... @fmt_fdfjfk -+fabs_s 0000 00010001 01000 00001 ..... ..... @fmt_fdfj -+fabs_d 0000 00010001 01000 00010 ..... ..... @fmt_fdfj -+fneg_s 0000 00010001 01000 00101 ..... ..... @fmt_fdfj -+fneg_d 0000 00010001 01000 00110 ..... ..... @fmt_fdfj -+flogb_s 0000 00010001 01000 01001 ..... ..... @fmt_fdfj -+flogb_d 0000 00010001 01000 01010 ..... ..... @fmt_fdfj -+fclass_s 0000 00010001 01000 01101 ..... ..... @fmt_fdfj -+fclass_d 0000 00010001 01000 01110 ..... ..... @fmt_fdfj -+fsqrt_s 0000 00010001 01000 10001 ..... ..... @fmt_fdfj -+fsqrt_d 0000 00010001 01000 10010 ..... ..... @fmt_fdfj -+frecip_s 0000 00010001 01000 10101 ..... ..... @fmt_fdfj -+frecip_d 0000 00010001 01000 10110 ..... ..... @fmt_fdfj -+frsqrt_s 0000 00010001 01000 11001 ..... ..... @fmt_fdfj -+frsqrt_d 0000 00010001 01000 11010 ..... ..... @fmt_fdfj -+fmov_s 0000 00010001 01001 00101 ..... ..... @fmt_fdfj -+fmov_d 0000 00010001 01001 00110 ..... ..... @fmt_fdfj -+movgr2fr_w 0000 00010001 01001 01001 ..... ..... @fmt_fdrj -+movgr2fr_d 0000 00010001 01001 01010 ..... ..... @fmt_fdrj -+movgr2frh_w 0000 00010001 01001 01011 ..... ..... @fmt_fdrj -+movfr2gr_s 0000 00010001 01001 01101 ..... ..... @fmt_rdfj -+movfr2gr_d 0000 00010001 01001 01110 ..... ..... @fmt_rdfj -+movfrh2gr_s 0000 00010001 01001 01111 ..... ..... @fmt_rdfj -+movgr2fcsr 0000 00010001 01001 10000 ..... ..... @fmt_fcsrdrj -+movfcsr2gr 0000 00010001 01001 10010 ..... ..... @fmt_rdfcsrs -+movfr2cf 0000 00010001 01001 10100 ..... 00 ... @fmt_cdfj -+movcf2fr 0000 00010001 01001 10101 00 ... ..... @fmt_fdcj -+movgr2cf 0000 00010001 01001 10110 ..... 00 ... @fmt_cdrj -+movcf2gr 0000 00010001 01001 10111 00 ... ..... @fmt_rdcj -+fcvt_s_d 0000 00010001 10010 00110 ..... ..... @fmt_fdfj -+fcvt_d_s 0000 00010001 10010 01001 ..... ..... @fmt_fdfj -+ftintrm_w_s 0000 00010001 10100 00001 ..... ..... @fmt_fdfj -+ftintrm_w_d 0000 00010001 10100 00010 ..... ..... @fmt_fdfj -+ftintrm_l_s 0000 00010001 10100 01001 ..... ..... @fmt_fdfj -+ftintrm_l_d 0000 00010001 10100 01010 ..... ..... @fmt_fdfj -+ftintrp_w_s 0000 00010001 10100 10001 ..... ..... @fmt_fdfj -+ftintrp_w_d 0000 00010001 10100 10010 ..... ..... @fmt_fdfj -+ftintrp_l_s 0000 00010001 10100 11001 ..... ..... @fmt_fdfj -+ftintrp_l_d 0000 00010001 10100 11010 ..... ..... @fmt_fdfj -+ftintrz_w_s 0000 00010001 10101 00001 ..... ..... @fmt_fdfj -+ftintrz_w_d 0000 00010001 10101 00010 ..... ..... @fmt_fdfj -+ftintrz_l_s 0000 00010001 10101 01001 ..... ..... @fmt_fdfj -+ftintrz_l_d 0000 00010001 10101 01010 ..... ..... @fmt_fdfj -+ftintrne_w_s 0000 00010001 10101 10001 ..... ..... @fmt_fdfj -+ftintrne_w_d 0000 00010001 10101 10010 ..... ..... @fmt_fdfj -+ftintrne_l_s 0000 00010001 10101 11001 ..... ..... @fmt_fdfj -+ftintrne_l_d 0000 00010001 10101 11010 ..... ..... @fmt_fdfj -+ftint_w_s 0000 00010001 10110 00001 ..... ..... @fmt_fdfj -+ftint_w_d 0000 00010001 10110 00010 ..... ..... @fmt_fdfj -+ftint_l_s 0000 00010001 10110 01001 ..... ..... @fmt_fdfj -+ftint_l_d 0000 00010001 10110 01010 ..... ..... @fmt_fdfj -+ffint_s_w 0000 00010001 11010 00100 ..... ..... @fmt_fdfj -+ffint_s_l 0000 00010001 11010 00110 ..... ..... @fmt_fdfj -+ffint_d_w 0000 00010001 11010 01000 ..... ..... @fmt_fdfj -+ffint_d_l 0000 00010001 11010 01010 ..... ..... @fmt_fdfj -+frint_s 0000 00010001 11100 10001 ..... ..... @fmt_fdfj -+frint_d 0000 00010001 11100 10010 ..... ..... @fmt_fdfj -+ -+# 12 bit immediate Instructions -+slti 0000 001000 ............ ..... ..... @fmt_rdrjsi12 -+sltui 0000 001001 ............ ..... ..... @fmt_rdrjsi12 -+addi_w 0000 001010 ............ ..... ..... @fmt_rdrjsi12 -+addi_d 0000 001011 ............ ..... ..... @fmt_rdrjsi12 -+lu52i_d 0000 001100 ............ ..... ..... @fmt_rdrjsi12 -+andi 0000 001101 ............ ..... ..... @fmt_rdrjui12 -+ori 0000 001110 ............ ..... ..... @fmt_rdrjui12 -+xori 0000 001111 ............ ..... ..... @fmt_rdrjui12 -+ -+# core Instructions -+csrxchg 0000 0100 .............. ..... ..... @fmt_rdrjcsr -+cacop 0000 011000 ............ ..... ..... @fmt_coprjsi12 -+lddir 0000 01100100 00 ........ ..... ..... @fmt_rdrjlevel -+ldpte 0000 01100100 01 ........ ..... 00000 @fmt_rjseq -+iocsrrd_b 0000 01100100 10000 00000 ..... ..... @fmt_rdrj -+iocsrrd_h 0000 01100100 10000 00001 ..... ..... @fmt_rdrj -+iocsrrd_w 0000 01100100 10000 00010 ..... ..... @fmt_rdrj -+iocsrrd_d 0000 01100100 10000 00011 ..... ..... @fmt_rdrj -+iocsrwr_b 0000 01100100 10000 00100 ..... ..... @fmt_rdrj -+iocsrwr_h 0000 01100100 10000 00101 ..... ..... @fmt_rdrj -+iocsrwr_w 0000 01100100 10000 00110 ..... ..... @fmt_rdrj -+iocsrwr_d 0000 01100100 10000 00111 ..... ..... @fmt_rdrj -+tlbclr 0000 01100100 10000 01000 00000 00000 @fmt_empty -+tlbflush 0000 01100100 10000 01001 00000 00000 @fmt_empty -+tlbsrch 0000 01100100 10000 01010 00000 00000 @fmt_empty -+tlbrd 0000 01100100 10000 01011 00000 00000 @fmt_empty -+tlbwr 0000 01100100 10000 01100 00000 00000 @fmt_empty -+tlbfill 0000 01100100 10000 01101 00000 00000 @fmt_empty -+ertn 0000 01100100 10000 01110 00000 00000 @fmt_empty -+idle 0000 01100100 10001 ............... @fmt_whint -+invtlb 0000 01100100 10011 ..... ..... ..... @fmt_invtlb -+ -+# foure Op Instructions -+fmadd_s 0000 10000001 ..... ..... ..... ..... @fmt_fdfjfkfa -+fmadd_d 0000 10000010 ..... ..... ..... ..... @fmt_fdfjfkfa -+fmsub_s 0000 10000101 ..... ..... ..... ..... @fmt_fdfjfkfa -+fmsub_d 0000 10000110 ..... ..... ..... ..... @fmt_fdfjfkfa -+fnmadd_s 0000 10001001 ..... ..... ..... ..... @fmt_fdfjfkfa -+fnmadd_d 0000 10001010 ..... ..... ..... ..... @fmt_fdfjfkfa -+fnmsub_s 0000 10001101 ..... ..... ..... ..... @fmt_fdfjfkfa -+fnmsub_d 0000 10001110 ..... ..... ..... ..... @fmt_fdfjfkfa -+fcmp_cond_s 0000 11000001 ..... ..... ..... 00 ... @fmt_cdfjfkfcond -+fcmp_cond_d 0000 11000010 ..... ..... ..... 00 ... @fmt_cdfjfkfcond -+fsel 0000 11010000 00 ... ..... ..... ..... @fmt_fdfjfkca -+ -+# loog immediate Instructions -+addu16i_d 0001 00 ................ ..... ..... @fmt_rdrjsi16 -+lu12i_w 0001 010 .................... ..... @fmt_rdsi20 -+lu32i_d 0001 011 .................... ..... @fmt_rdsi20 -+pcaddi 0001 100 .................... ..... @fmt_rdsi20 -+pcalau12i 0001 101 .................... ..... @fmt_rdsi20 -+pcaddu12i 0001 110 .................... ..... @fmt_rdsi20 -+pcaddu18i 0001 111 .................... ..... @fmt_rdsi20 -+ -+# load/store Instructions -+ll_w 0010 0000 .............. ..... ..... @fmt_rdrjsi14 -+sc_w 0010 0001 .............. ..... ..... @fmt_rdrjsi14 -+ll_d 0010 0010 .............. ..... ..... @fmt_rdrjsi14 -+sc_d 0010 0011 .............. ..... ..... @fmt_rdrjsi14 -+ldptr_w 0010 0100 .............. ..... ..... @fmt_rdrjsi14 -+stptr_w 0010 0101 .............. ..... ..... @fmt_rdrjsi14 -+ldptr_d 0010 0110 .............. ..... ..... @fmt_rdrjsi14 -+stptr_d 0010 0111 .............. ..... ..... @fmt_rdrjsi14 -+ld_b 0010 100000 ............ ..... ..... @fmt_rdrjsi12 -+ld_h 0010 100001 ............ ..... ..... @fmt_rdrjsi12 -+ld_w 0010 100010 ............ ..... ..... @fmt_rdrjsi12 -+ld_d 0010 100011 ............ ..... ..... @fmt_rdrjsi12 -+st_b 0010 100100 ............ ..... ..... @fmt_rdrjsi12 -+st_h 0010 100101 ............ ..... ..... @fmt_rdrjsi12 -+st_w 0010 100110 ............ ..... ..... @fmt_rdrjsi12 -+st_d 0010 100111 ............ ..... ..... @fmt_rdrjsi12 -+ld_bu 0010 101000 ............ ..... ..... @fmt_rdrjsi12 -+ld_hu 0010 101001 ............ ..... ..... @fmt_rdrjsi12 -+ld_wu 0010 101010 ............ ..... ..... @fmt_rdrjsi12 -+preld 0010 101011 ............ ..... ..... @fmt_hintrjsi12 -+fld_s 0010 101100 ............ ..... ..... @fmt_fdrjsi12 -+fst_s 0010 101101 ............ ..... ..... @fmt_fdrjsi12 -+fld_d 0010 101110 ............ ..... ..... @fmt_fdrjsi12 -+fst_d 0010 101111 ............ ..... ..... @fmt_fdrjsi12 -+ldx_b 0011 10000000 00000 ..... ..... ..... @fmt_rdrjrk -+ldx_h 0011 10000000 01000 ..... ..... ..... @fmt_rdrjrk -+ldx_w 0011 10000000 10000 ..... ..... ..... @fmt_rdrjrk -+ldx_d 0011 10000000 11000 ..... ..... ..... @fmt_rdrjrk -+stx_b 0011 10000001 00000 ..... ..... ..... @fmt_rdrjrk -+stx_h 0011 10000001 01000 ..... ..... ..... @fmt_rdrjrk -+stx_w 0011 10000001 10000 ..... ..... ..... @fmt_rdrjrk -+stx_d 0011 10000001 11000 ..... ..... ..... @fmt_rdrjrk -+ldx_bu 0011 10000010 00000 ..... ..... ..... @fmt_rdrjrk -+ldx_hu 0011 10000010 01000 ..... ..... ..... @fmt_rdrjrk -+ldx_wu 0011 10000010 10000 ..... ..... ..... @fmt_rdrjrk -+fldx_s 0011 10000011 00000 ..... ..... ..... @fmt_fdrjrk -+fldx_d 0011 10000011 01000 ..... ..... ..... @fmt_fdrjrk -+fstx_s 0011 10000011 10000 ..... ..... ..... @fmt_fdrjrk -+fstx_d 0011 10000011 11000 ..... ..... ..... @fmt_fdrjrk -+amswap_w 0011 10000110 00000 ..... ..... ..... @fmt_rdrjrk -+amswap_d 0011 10000110 00001 ..... ..... ..... @fmt_rdrjrk -+amadd_w 0011 10000110 00010 ..... ..... ..... @fmt_rdrjrk -+amadd_d 0011 10000110 00011 ..... ..... ..... @fmt_rdrjrk -+amand_w 0011 10000110 00100 ..... ..... ..... @fmt_rdrjrk -+amand_d 0011 10000110 00101 ..... ..... ..... @fmt_rdrjrk -+amor_w 0011 10000110 00110 ..... ..... ..... @fmt_rdrjrk -+amor_d 0011 10000110 00111 ..... ..... ..... @fmt_rdrjrk -+amxor_w 0011 10000110 01000 ..... ..... ..... @fmt_rdrjrk -+amxor_d 0011 10000110 01001 ..... ..... ..... @fmt_rdrjrk -+ammax_w 0011 10000110 01010 ..... ..... ..... @fmt_rdrjrk -+ammax_d 0011 10000110 01011 ..... ..... ..... @fmt_rdrjrk -+ammin_w 0011 10000110 01100 ..... ..... ..... @fmt_rdrjrk -+ammin_d 0011 10000110 01101 ..... ..... ..... @fmt_rdrjrk -+ammax_wu 0011 10000110 01110 ..... ..... ..... @fmt_rdrjrk -+ammax_du 0011 10000110 01111 ..... ..... ..... @fmt_rdrjrk -+ammin_wu 0011 10000110 10000 ..... ..... ..... @fmt_rdrjrk -+ammin_du 0011 10000110 10001 ..... ..... ..... @fmt_rdrjrk -+amswap_db_w 0011 10000110 10010 ..... ..... ..... @fmt_rdrjrk -+amswap_db_d 0011 10000110 10011 ..... ..... ..... @fmt_rdrjrk -+amadd_db_w 0011 10000110 10100 ..... ..... ..... @fmt_rdrjrk -+amadd_db_d 0011 10000110 10101 ..... ..... ..... @fmt_rdrjrk -+amand_db_w 0011 10000110 10110 ..... ..... ..... @fmt_rdrjrk -+amand_db_d 0011 10000110 10111 ..... ..... ..... @fmt_rdrjrk -+amor_db_w 0011 10000110 11000 ..... ..... ..... @fmt_rdrjrk -+amor_db_d 0011 10000110 11001 ..... ..... ..... @fmt_rdrjrk -+amxor_db_w 0011 10000110 11010 ..... ..... ..... @fmt_rdrjrk -+amxor_db_d 0011 10000110 11011 ..... ..... ..... @fmt_rdrjrk -+ammax_db_w 0011 10000110 11100 ..... ..... ..... @fmt_rdrjrk -+ammax_db_d 0011 10000110 11101 ..... ..... ..... @fmt_rdrjrk -+ammin_db_w 0011 10000110 11110 ..... ..... ..... @fmt_rdrjrk -+ammin_db_d 0011 10000110 11111 ..... ..... ..... @fmt_rdrjrk -+ammax_db_wu 0011 10000111 00000 ..... ..... ..... @fmt_rdrjrk -+ammax_db_du 0011 10000111 00001 ..... ..... ..... @fmt_rdrjrk -+ammin_db_wu 0011 10000111 00010 ..... ..... ..... @fmt_rdrjrk -+ammin_db_du 0011 10000111 00011 ..... ..... ..... @fmt_rdrjrk -+dbar 0011 10000111 00100 ............... @fmt_whint -+ibar 0011 10000111 00101 ............... @fmt_whint -+fldgt_s 0011 10000111 01000 ..... ..... ..... @fmt_fdrjrk -+fldgt_d 0011 10000111 01001 ..... ..... ..... @fmt_fdrjrk -+fldle_s 0011 10000111 01010 ..... ..... ..... @fmt_fdrjrk -+fldle_d 0011 10000111 01011 ..... ..... ..... @fmt_fdrjrk -+fstgt_s 0011 10000111 01100 ..... ..... ..... @fmt_fdrjrk -+fstgt_d 0011 10000111 01101 ..... ..... ..... @fmt_fdrjrk -+fstle_s 0011 10000111 01110 ..... ..... ..... @fmt_fdrjrk -+fstle_d 0011 10000111 01111 ..... ..... ..... @fmt_fdrjrk -+ldgt_b 0011 10000111 10000 ..... ..... ..... @fmt_rdrjrk -+ldgt_h 0011 10000111 10001 ..... ..... ..... @fmt_rdrjrk -+ldgt_w 0011 10000111 10010 ..... ..... ..... @fmt_rdrjrk -+ldgt_d 0011 10000111 10011 ..... ..... ..... @fmt_rdrjrk -+ldle_b 0011 10000111 10100 ..... ..... ..... @fmt_rdrjrk -+ldle_h 0011 10000111 10101 ..... ..... ..... @fmt_rdrjrk -+ldle_w 0011 10000111 10110 ..... ..... ..... @fmt_rdrjrk -+ldle_d 0011 10000111 10111 ..... ..... ..... @fmt_rdrjrk -+stgt_b 0011 10000111 11000 ..... ..... ..... @fmt_rdrjrk -+stgt_h 0011 10000111 11001 ..... ..... ..... @fmt_rdrjrk -+stgt_w 0011 10000111 11010 ..... ..... ..... @fmt_rdrjrk -+stgt_d 0011 10000111 11011 ..... ..... ..... @fmt_rdrjrk -+stle_b 0011 10000111 11100 ..... ..... ..... @fmt_rdrjrk -+stle_h 0011 10000111 11101 ..... ..... ..... @fmt_rdrjrk -+stle_w 0011 10000111 11110 ..... ..... ..... @fmt_rdrjrk -+stle_d 0011 10000111 11111 ..... ..... ..... @fmt_rdrjrk -+ -+# jump Instructions -+beqz 0100 00 ................ ..... ..... @fmt_rjoffs21 -+bnez 0100 01 ................ ..... ..... @fmt_rjoffs21 -+bceqz 0100 10 ................ 00 ... ..... @fmt_cjoffs21 -+bcnez 0100 10 ................ 01 ... ..... @fmt_cjoffs21 -+jirl 0100 11 ................ ..... ..... @fmt_rdrjoffs16 -+b 0101 00 .......................... @fmt_offs -+bl 0101 01 .......................... @fmt_offs -+beq 0101 10 ................ ..... ..... @fmt_rjrdoffs16 -+bne 0101 11 ................ ..... ..... @fmt_rjrdoffs16 -+blt 0110 00 ................ ..... ..... @fmt_rjrdoffs16 -+bge 0110 01 ................ ..... ..... @fmt_rjrdoffs16 -+bltu 0110 10 ................ ..... ..... @fmt_rjrdoffs16 -+bgeu 0110 11 ................ ..... ..... @fmt_rjrdoffs16 -diff --git a/target/loongarch64/instmap.h b/target/loongarch64/instmap.h -new file mode 100644 -index 0000000000..5fbb8b5d29 ---- /dev/null -+++ b/target/loongarch64/instmap.h -@@ -0,0 +1,217 @@ -+/* -+ * Loongarch emulation for qemu: instruction opcode -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef TARGET_LARCH_INSTMAP_H -+#define TARGET_LARCH_INSTMAP_H -+ -+enum { -+ /* fix opcodes */ -+ OPC_LARCH_CLO_W = (0x000004 << 10), -+ OPC_LARCH_CLZ_W = (0x000005 << 10), -+ OPC_LARCH_CLO_D = (0x000008 << 10), -+ OPC_LARCH_CLZ_D = (0x000009 << 10), -+ OPC_LARCH_REVB_2H = (0x00000C << 10), -+ OPC_LARCH_REVB_4H = (0x00000D << 10), -+ OPC_LARCH_REVH_D = (0x000011 << 10), -+ OPC_LARCH_BREV_4B = (0x000012 << 10), -+ OPC_LARCH_BREV_8B = (0x000013 << 10), -+ OPC_LARCH_EXT_WH = (0x000016 << 10), -+ OPC_LARCH_EXT_WB = (0x000017 << 10), -+ -+ OPC_LARCH_ADD_W = (0x00020 << 15), -+ OPC_LARCH_ADD_D = (0x00021 << 15), -+ OPC_LARCH_SUB_W = (0x00022 << 15), -+ OPC_LARCH_SUB_D = (0x00023 << 15), -+ OPC_LARCH_SLT = (0x00024 << 15), -+ OPC_LARCH_SLTU = (0x00025 << 15), -+ OPC_LARCH_MASKEQZ = (0x00026 << 15), -+ OPC_LARCH_MASKNEZ = (0x00027 << 15), -+ OPC_LARCH_NOR = (0x00028 << 15), -+ OPC_LARCH_AND = (0x00029 << 15), -+ OPC_LARCH_OR = (0x0002A << 15), -+ OPC_LARCH_XOR = (0x0002B << 15), -+ OPC_LARCH_SLL_W = (0x0002E << 15), -+ OPC_LARCH_SRL_W = (0x0002F << 15), -+ OPC_LARCH_SRA_W = (0x00030 << 15), -+ OPC_LARCH_SLL_D = (0x00031 << 15), -+ OPC_LARCH_SRL_D = (0x00032 << 15), -+ OPC_LARCH_SRA_D = (0x00033 << 15), -+ OPC_LARCH_ROTR_W = (0x00036 << 15), -+ OPC_LARCH_ROTR_D = (0x00037 << 15), -+ OPC_LARCH_MUL_W = (0x00038 << 15), -+ OPC_LARCH_MULH_W = (0x00039 << 15), -+ OPC_LARCH_MULH_WU = (0x0003A << 15), -+ OPC_LARCH_MUL_D = (0x0003B << 15), -+ OPC_LARCH_MULH_D = (0x0003C << 15), -+ OPC_LARCH_MULH_DU = (0x0003D << 15), -+ OPC_LARCH_DIV_W = (0x00040 << 15), -+ OPC_LARCH_MOD_W = (0x00041 << 15), -+ OPC_LARCH_DIV_WU = (0x00042 << 15), -+ OPC_LARCH_MOD_WU = (0x00043 << 15), -+ OPC_LARCH_DIV_D = (0x00044 << 15), -+ OPC_LARCH_MOD_D = (0x00045 << 15), -+ OPC_LARCH_DIV_DU = (0x00046 << 15), -+ OPC_LARCH_MOD_DU = (0x00047 << 15), -+ OPC_LARCH_SRLI_W = (0x00089 << 15), -+ OPC_LARCH_SRAI_W = (0x00091 << 15), -+ OPC_LARCH_ROTRI_W = (0x00099 << 15), -+ -+ OPC_LARCH_ALSL_W = (0x0002 << 17), -+ OPC_LARCH_ALSL_D = (0x0016 << 17), -+ -+ OPC_LARCH_TRINS_W = (0x003 << 21) | (0x0 << 15), -+ OPC_LARCH_TRPICK_W = (0x003 << 21) | (0x1 << 15), -+}; -+ -+enum { -+ /* float opcodes */ -+ OPC_LARCH_FABS_S = (0x004501 << 10), -+ OPC_LARCH_FABS_D = (0x004502 << 10), -+ OPC_LARCH_FNEG_S = (0x004505 << 10), -+ OPC_LARCH_FNEG_D = (0x004506 << 10), -+ OPC_LARCH_FCLASS_S = (0x00450D << 10), -+ OPC_LARCH_FCLASS_D = (0x00450E << 10), -+ OPC_LARCH_FSQRT_S = (0x004511 << 10), -+ OPC_LARCH_FSQRT_D = (0x004512 << 10), -+ OPC_LARCH_FRECIP_S = (0x004515 << 10), -+ OPC_LARCH_FRECIP_D = (0x004516 << 10), -+ OPC_LARCH_FRSQRT_S = (0x004519 << 10), -+ OPC_LARCH_FRSQRT_D = (0x00451A << 10), -+ OPC_LARCH_FMOV_S = (0x004525 << 10), -+ OPC_LARCH_FMOV_D = (0x004526 << 10), -+ OPC_LARCH_GR2FR_W = (0x004529 << 10), -+ OPC_LARCH_GR2FR_D = (0x00452A << 10), -+ OPC_LARCH_GR2FRH_W = (0x00452B << 10), -+ OPC_LARCH_FR2GR_S = (0x00452D << 10), -+ OPC_LARCH_FR2GR_D = (0x00452E << 10), -+ OPC_LARCH_FRH2GR_S = (0x00452F << 10), -+ -+ OPC_LARCH_FCVT_S_D = (0x004646 << 10), -+ OPC_LARCH_FCVT_D_S = (0x004649 << 10), -+ OPC_LARCH_FTINTRM_W_S = (0x004681 << 10), -+ OPC_LARCH_FTINTRM_W_D = (0x004682 << 10), -+ OPC_LARCH_FTINTRM_L_S = (0x004689 << 10), -+ OPC_LARCH_FTINTRM_L_D = (0x00468A << 10), -+ OPC_LARCH_FTINTRP_W_S = (0x004691 << 10), -+ OPC_LARCH_FTINTRP_W_D = (0x004692 << 10), -+ OPC_LARCH_FTINTRP_L_S = (0x004699 << 10), -+ OPC_LARCH_FTINTRP_L_D = (0x00469A << 10), -+ OPC_LARCH_FTINTRZ_W_S = (0x0046A1 << 10), -+ OPC_LARCH_FTINTRZ_W_D = (0x0046A2 << 10), -+ OPC_LARCH_FTINTRZ_L_S = (0x0046A9 << 10), -+ OPC_LARCH_FTINTRZ_L_D = (0x0046AA << 10), -+ OPC_LARCH_FTINTRNE_W_S = (0x0046B1 << 10), -+ OPC_LARCH_FTINTRNE_W_D = (0x0046B2 << 10), -+ OPC_LARCH_FTINTRNE_L_S = (0x0046B9 << 10), -+ OPC_LARCH_FTINTRNE_L_D = (0x0046BA << 10), -+ OPC_LARCH_FTINT_W_S = (0x0046C1 << 10), -+ OPC_LARCH_FTINT_W_D = (0x0046C2 << 10), -+ OPC_LARCH_FTINT_L_S = (0x0046C9 << 10), -+ OPC_LARCH_FTINT_L_D = (0x0046CA << 10), -+ OPC_LARCH_FFINT_S_W = (0x004744 << 10), -+ OPC_LARCH_FFINT_S_L = (0x004746 << 10), -+ OPC_LARCH_FFINT_D_W = (0x004748 << 10), -+ OPC_LARCH_FFINT_D_L = (0x00474A << 10), -+ OPC_LARCH_FRINT_S = (0x004791 << 10), -+ OPC_LARCH_FRINT_D = (0x004792 << 10), -+ -+ OPC_LARCH_FADD_S = (0x00201 << 15), -+ OPC_LARCH_FADD_D = (0x00202 << 15), -+ OPC_LARCH_FSUB_S = (0x00205 << 15), -+ OPC_LARCH_FSUB_D = (0x00206 << 15), -+ OPC_LARCH_FMUL_S = (0x00209 << 15), -+ OPC_LARCH_FMUL_D = (0x0020A << 15), -+ OPC_LARCH_FDIV_S = (0x0020D << 15), -+ OPC_LARCH_FDIV_D = (0x0020E << 15), -+ OPC_LARCH_FMAX_S = (0x00211 << 15), -+ OPC_LARCH_FMAX_D = (0x00212 << 15), -+ OPC_LARCH_FMIN_S = (0x00215 << 15), -+ OPC_LARCH_FMIN_D = (0x00216 << 15), -+ OPC_LARCH_FMAXA_S = (0x00219 << 15), -+ OPC_LARCH_FMAXA_D = (0x0021A << 15), -+ OPC_LARCH_FMINA_S = (0x0021D << 15), -+ OPC_LARCH_FMINA_D = (0x0021E << 15), -+}; -+ -+enum { -+ /* 12 bit immediate opcodes */ -+ OPC_LARCH_SLTI = (0x008 << 22), -+ OPC_LARCH_SLTIU = (0x009 << 22), -+ OPC_LARCH_ADDI_W = (0x00A << 22), -+ OPC_LARCH_ADDI_D = (0x00B << 22), -+ OPC_LARCH_ANDI = (0x00D << 22), -+ OPC_LARCH_ORI = (0x00E << 22), -+ OPC_LARCH_XORI = (0x00F << 22), -+}; -+ -+enum { -+ /* load/store opcodes */ -+ OPC_LARCH_FLDX_S = (0x07060 << 15), -+ OPC_LARCH_FLDX_D = (0x07068 << 15), -+ OPC_LARCH_FSTX_S = (0x07070 << 15), -+ OPC_LARCH_FSTX_D = (0x07078 << 15), -+ OPC_LARCH_FLDGT_S = (0x070E8 << 15), -+ OPC_LARCH_FLDGT_D = (0x070E9 << 15), -+ OPC_LARCH_FLDLE_S = (0x070EA << 15), -+ OPC_LARCH_FLDLE_D = (0x070EB << 15), -+ OPC_LARCH_FSTGT_S = (0x070EC << 15), -+ OPC_LARCH_FSTGT_D = (0x070ED << 15), -+ OPC_LARCH_FSTLE_S = (0x070EE << 15), -+ OPC_LARCH_FSTLE_D = (0x070EF << 15), -+ -+ OPC_LARCH_LD_B = (0x0A0 << 22), -+ OPC_LARCH_LD_H = (0x0A1 << 22), -+ OPC_LARCH_LD_W = (0x0A2 << 22), -+ OPC_LARCH_LD_D = (0x0A3 << 22), -+ OPC_LARCH_ST_B = (0x0A4 << 22), -+ OPC_LARCH_ST_H = (0x0A5 << 22), -+ OPC_LARCH_ST_W = (0x0A6 << 22), -+ OPC_LARCH_ST_D = (0x0A7 << 22), -+ OPC_LARCH_LD_BU = (0x0A8 << 22), -+ OPC_LARCH_LD_HU = (0x0A9 << 22), -+ OPC_LARCH_LD_WU = (0x0AA << 22), -+ OPC_LARCH_FLD_S = (0x0AC << 22), -+ OPC_LARCH_FST_S = (0x0AD << 22), -+ OPC_LARCH_FLD_D = (0x0AE << 22), -+ OPC_LARCH_FST_D = (0x0AF << 22), -+ -+ OPC_LARCH_LL_W = (0x20 << 24), -+ OPC_LARCH_SC_W = (0x21 << 24), -+ OPC_LARCH_LL_D = (0x22 << 24), -+ OPC_LARCH_SC_D = (0x23 << 24), -+ OPC_LARCH_LDPTR_W = (0x24 << 24), -+ OPC_LARCH_STPTR_W = (0x25 << 24), -+ OPC_LARCH_LDPTR_D = (0x26 << 24), -+ OPC_LARCH_STPTR_D = (0x27 << 24), -+}; -+ -+enum { -+ /* jump opcodes */ -+ OPC_LARCH_BEQZ = (0x10 << 26), -+ OPC_LARCH_BNEZ = (0x11 << 26), -+ OPC_LARCH_B = (0x14 << 26), -+ OPC_LARCH_BEQ = (0x16 << 26), -+ OPC_LARCH_BNE = (0x17 << 26), -+ OPC_LARCH_BLT = (0x18 << 26), -+ OPC_LARCH_BGE = (0x19 << 26), -+ OPC_LARCH_BLTU = (0x1A << 26), -+ OPC_LARCH_BGEU = (0x1B << 26), -+}; -+ -+#endif -diff --git a/target/loongarch64/internal.h b/target/loongarch64/internal.h -new file mode 100644 -index 0000000000..a51b7e6f56 ---- /dev/null -+++ b/target/loongarch64/internal.h -@@ -0,0 +1,207 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LOONGARCH_INTERNAL_H -+#define LOONGARCH_INTERNAL_H -+ -+#include "cpu-csr.h" -+ -+/* -+ * MMU types, the first four entries have the same layout as the -+ * CP0C0_MT field. -+ */ -+enum loongarch_mmu_types { -+ MMU_TYPE_NONE, -+ MMU_TYPE_LS3A5K, /* LISA CSR */ -+}; -+ -+struct loongarch_def_t { -+ const char *name; -+ int32_t CSR_PRid; -+ int32_t FCSR0; -+ int32_t FCSR0_rw_bitmask; -+ int32_t PABITS; -+ CPU_LOONGARCH_CSR -+ uint64_t insn_flags; -+ enum loongarch_mmu_types mmu_type; -+ int cpu_cfg[64]; -+}; -+ -+/* loongarch 3a5000 TLB entry */ -+struct ls3a5k_tlb_t { -+ target_ulong VPN; -+ uint64_t PageMask; /* CSR_TLBIDX[29:24] */ -+ uint32_t PageSize; -+ uint16_t ASID; -+ unsigned int G:1; /* CSR_TLBLO[6] */ -+ -+ unsigned int C0:3; /* CSR_TLBLO[5:4] */ -+ unsigned int C1:3; -+ -+ unsigned int V0:1; /* CSR_TLBLO[0] */ -+ unsigned int V1:1; -+ -+ unsigned int WE0:1; /* CSR_TLBLO[1] */ -+ unsigned int WE1:1; -+ -+ unsigned int XI0:1; /* CSR_TLBLO[62] */ -+ unsigned int XI1:1; -+ -+ unsigned int RI0:1; /* CSR_TLBLO[61] */ -+ unsigned int RI1:1; -+ -+ unsigned int EHINV:1;/* CSR_TLBIDX[31] */ -+ -+ unsigned int PLV0:2; /* CSR_TLBLO[3:2] */ -+ unsigned int PLV1:2; -+ -+ unsigned int RPLV0:1; -+ unsigned int RPLV1:1; /* CSR_TLBLO[63] */ -+ -+ uint64_t PPN0; /* CSR_TLBLO[47:12] */ -+ uint64_t PPN1; /* CSR_TLBLO[47:12] */ -+}; -+typedef struct ls3a5k_tlb_t ls3a5k_tlb_t; -+ -+struct CPULOONGARCHTLBContext { -+ uint32_t nb_tlb; -+ uint32_t tlb_in_use; -+ int (*map_address)(struct CPULOONGARCHState *env, hwaddr *physical, -+ int *prot, target_ulong address, int rw, -+ int access_type); -+ void (*helper_tlbwr)(struct CPULOONGARCHState *env); -+ void (*helper_tlbfill)(struct CPULOONGARCHState *env); -+ void (*helper_tlbsrch)(struct CPULOONGARCHState *env); -+ void (*helper_tlbrd)(struct CPULOONGARCHState *env); -+ void (*helper_tlbclr)(struct CPULOONGARCHState *env); -+ void (*helper_tlbflush)(struct CPULOONGARCHState *env); -+ void (*helper_invtlb)(struct CPULOONGARCHState *env, target_ulong addr, -+ target_ulong info, int op); -+ union -+ { -+ struct { -+ uint64_t ftlb_mask; -+ uint32_t ftlb_size; /* at most : 8 * 256 = 2048 */ -+ uint32_t vtlb_size; /* at most : 64 */ -+ ls3a5k_tlb_t tlb[2048 + 64]; /* at most : 2048 FTLB + 64 VTLB */ -+ } ls3a5k; -+ } mmu; -+}; -+ -+enum { -+ TLBRET_PE = -7, -+ TLBRET_XI = -6, -+ TLBRET_RI = -5, -+ TLBRET_DIRTY = -4, -+ TLBRET_INVALID = -3, -+ TLBRET_NOMATCH = -2, -+ TLBRET_BADADDR = -1, -+ TLBRET_MATCH = 0 -+}; -+ -+extern unsigned int ieee_rm[]; -+ -+static inline void restore_rounding_mode(CPULOONGARCHState *env) -+{ -+ set_float_rounding_mode(ieee_rm[(env->active_fpu.fcsr0 >> FCSR0_RM) & 0x3], -+ &env->active_fpu.fp_status); -+} -+ -+static inline void restore_flush_mode(CPULOONGARCHState *env) -+{ -+ set_flush_to_zero(0, &env->active_fpu.fp_status); -+} -+ -+static inline void restore_fp_status(CPULOONGARCHState *env) -+{ -+ restore_rounding_mode(env); -+ restore_flush_mode(env); -+} -+ -+static inline void compute_hflags(CPULOONGARCHState *env) -+{ -+ env->hflags &= ~(LARCH_HFLAG_64 | LARCH_HFLAG_FPU | LARCH_HFLAG_KSU | -+ LARCH_HFLAG_AWRAP | LARCH_HFLAG_LSX | LARCH_HFLAG_LASX); -+ -+ env->hflags |= (env->CSR_CRMD & CSR_CRMD_PLV); -+ env->hflags |= LARCH_HFLAG_64; -+ -+ if (env->CSR_EUEN & CSR_EUEN_FPEN) { -+ env->hflags |= LARCH_HFLAG_FPU; -+ } -+ if (env->CSR_EUEN & CSR_EUEN_LSXEN) { -+ env->hflags |= LARCH_HFLAG_LSX; -+ } -+ if (env->CSR_EUEN & CSR_EUEN_LASXEN) { -+ env->hflags |= LARCH_HFLAG_LASX; -+ } -+ if (env->CSR_EUEN & CSR_EUEN_LBTEN) { -+ env->hflags |= LARCH_HFLAG_LBT; -+ } -+} -+ -+/* Check if there is pending and not masked out interrupt */ -+static inline bool cpu_loongarch_hw_interrupts_pending(CPULOONGARCHState *env) -+{ -+ int32_t pending; -+ int32_t status; -+ bool r; -+ -+ pending = env->CSR_ESTAT & CSR_ESTAT_IPMASK; -+ status = env->CSR_ECFG & CSR_ECFG_IPMASK; -+ -+ /* -+ * Configured with compatibility or VInt (Vectored Interrupts) -+ * treats the pending lines as individual interrupt lines, the status -+ * lines are individual masks. -+ */ -+ r = (pending & status) != 0; -+ -+ return r; -+} -+ -+/* stabletimer.c */ -+uint32_t cpu_loongarch_get_random_ls3a5k_tlb(uint32_t low, uint32_t high); -+uint64_t cpu_loongarch_get_stable_counter(CPULOONGARCHState *env); -+uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env); -+void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, -+ uint64_t value); -+int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, -+ int cpuid, void *opaque); -+ -+void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); -+ -+/* TODO QOM'ify CPU reset and remove */ -+void cpu_state_reset(CPULOONGARCHState *s); -+void cpu_loongarch_realize_env(CPULOONGARCHState *env); -+ -+uint64_t read_fcc(CPULOONGARCHState *env); -+void write_fcc(CPULOONGARCHState *env, uint64_t val); -+ -+int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n); -+int loongarch_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); -+ -+#ifdef CONFIG_TCG -+#include "fpu_helper.h" -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+extern const struct VMStateDescription vmstate_loongarch_cpu; -+hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); -+#endif -+ -+#endif -diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c -new file mode 100644 -index 0000000000..2b0159bb32 ---- /dev/null -+++ b/target/loongarch64/kvm.c -@@ -0,0 +1,1366 @@ -+/* -+ * KVM/LOONGARCH: LOONGARCH specific KVM APIs -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include -+ -+#include -+ -+#include "qemu-common.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/error-report.h" -+#include "qemu/timer.h" -+#include "qemu/main-loop.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/kvm.h" -+#include "sysemu/runstate.h" -+#include "sysemu/cpus.h" -+#include "kvm_larch.h" -+#include "exec/memattrs.h" -+#include "exec/gdbstub.h" -+ -+#define DEBUG_KVM 0 -+/* -+ * A 16384-byte buffer can hold the 8-byte kvm_msrs header, plus -+ * 2047 kvm_msr_entry structs -+ */ -+#define CSR_BUF_SIZE 16384 -+ -+#define DPRINTF(fmt, ...) \ -+ do { \ -+ if (DEBUG_KVM) { \ -+ fprintf(stderr, fmt, ##__VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+/* -+ * Define loongarch kvm version. -+ * Add version number when -+ * qemu/kvm interface changed -+ */ -+#define KVM_LOONGARCH_VERSION 1 -+ -+static struct { -+ target_ulong addr; -+ int len; -+ int type; -+} inst_breakpoint[8], data_breakpoint[8]; -+ -+int nb_data_breakpoint = 0, nb_inst_breakpoint = 0; -+static int kvm_loongarch_version_cap; -+ -+/* -+ * Hardware breakpoint control register -+ * 4:1 plv0-plv3 enable -+ * 6:5 config virtualization mode -+ * 9:8 load store -+ */ -+static const int type_code[] = { [GDB_BREAKPOINT_HW] = 0x5e, -+ [GDB_WATCHPOINT_READ] = (0x5e | 1 << 8), -+ [GDB_WATCHPOINT_WRITE] = (0x5e | 1 << 9), -+ [GDB_WATCHPOINT_ACCESS] = -+ (0x5e | 1 << 8 | 1 << 9) }; -+ -+const KVMCapabilityInfo kvm_arch_required_capabilities[] = { -+ KVM_CAP_LAST_INFO -+}; -+ -+static void kvm_loongarch_update_state(void *opaque, bool running, -+ RunState state); -+static inline int kvm_larch_putq(CPUState *cs, uint64_t reg_id, -+ uint64_t *addr); -+ -+unsigned long kvm_arch_vcpu_id(CPUState *cs) -+{ -+ return cs->cpu_index; -+} -+ -+int kvm_arch_init(MachineState *ms, KVMState *s) -+{ -+ /* LOONGARCH has 128 signals */ -+ kvm_set_sigmask_len(s, 16); -+ -+ kvm_loongarch_version_cap = kvm_check_extension(s, KVM_CAP_LOONGARCH_VZ); -+ -+ if (kvm_loongarch_version_cap != KVM_LOONGARCH_VERSION) { -+ warn_report("QEMU/KVM version not match, qemu_la_version: lvz-%d,\ -+ kvm_la_version: lvz-%d \n", -+ KVM_LOONGARCH_VERSION, kvm_loongarch_version_cap); -+ } -+ return 0; -+} -+ -+int kvm_arch_irqchip_create(KVMState *s) -+{ -+ return 0; -+} -+ -+static void kvm_csr_set_addr(uint64_t **addr, uint32_t index, uint64_t *p) -+{ -+ addr[index] = p; -+} -+ -+int kvm_arch_init_vcpu(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ uint64_t **addr; -+ CPULOONGARCHState *env = &cpu->env; -+ int ret = 0; -+ -+ kvm_vcpu_enable_cap(cs, KVM_CAP_LOONGARCH_FPU, 0, 0); -+ kvm_vcpu_enable_cap(cs, KVM_CAP_LOONGARCH_LSX, 0, 0); -+ -+ cpu->cpuStateEntry = -+ qemu_add_vm_change_state_handler(kvm_loongarch_update_state, cs); -+ cpu->kvm_csr_buf = g_malloc0(CSR_BUF_SIZE + CSR_BUF_SIZE); -+ -+ addr = (void *)cpu->kvm_csr_buf + CSR_BUF_SIZE; -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_CRMD, &env->CSR_CRMD); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRMD, &env->CSR_PRMD); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_EUEN, &env->CSR_EUEN); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_MISC, &env->CSR_MISC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ECFG, &env->CSR_ECFG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ESTAT, &env->CSR_ESTAT); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERA, &env->CSR_ERA); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_BADV, &env->CSR_BADV); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_BADI, &env->CSR_BADI); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_EEPN, &env->CSR_EEPN); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBIDX, &env->CSR_TLBIDX); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBEHI, &env->CSR_TLBEHI); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBELO0, &env->CSR_TLBELO0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBELO1, &env->CSR_TLBELO1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GTLBC, &env->CSR_GTLBC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TRGP, &env->CSR_TRGP); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ASID, &env->CSR_ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGDL, &env->CSR_PGDL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGDH, &env->CSR_PGDH); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PGD, &env->CSR_PGD); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PWCTL0, &env->CSR_PWCTL0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PWCTL1, &env->CSR_PWCTL1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_STLBPGSIZE, &env->CSR_STLBPGSIZE); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_RVACFG, &env->CSR_RVACFG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_CPUID, &env->CSR_CPUID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG1, &env->CSR_PRCFG1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG2, &env->CSR_PRCFG2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PRCFG3, &env->CSR_PRCFG3); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS0, &env->CSR_KS0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS1, &env->CSR_KS1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS2, &env->CSR_KS2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS3, &env->CSR_KS3); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS4, &env->CSR_KS4); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS5, &env->CSR_KS5); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS6, &env->CSR_KS6); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_KS7, &env->CSR_KS7); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TMID, &env->CSR_TMID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_CNTC, &env->CSR_CNTC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TINTCLR, &env->CSR_TINTCLR); -+ -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GSTAT, &env->CSR_GSTAT); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GCFG, &env->CSR_GCFG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GINTC, &env->CSR_GINTC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GCNTC, &env->CSR_GCNTC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_LLBCTL, &env->CSR_LLBCTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IMPCTL1, &env->CSR_IMPCTL1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IMPCTL2, &env->CSR_IMPCTL2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_GNMI, &env->CSR_GNMI); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRENT, &env->CSR_TLBRENT); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRBADV, &env->CSR_TLBRBADV); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRERA, &env->CSR_TLBRERA); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRSAVE, &env->CSR_TLBRSAVE); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRELO0, &env->CSR_TLBRELO0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRELO1, &env->CSR_TLBRELO1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBREHI, &env->CSR_TLBREHI); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_TLBRPRMD, &env->CSR_TLBRPRMD); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRCTL, &env->CSR_ERRCTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRINFO, &env->CSR_ERRINFO); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRINFO1, &env->CSR_ERRINFO1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRENT, &env->CSR_ERRENT); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRERA, &env->CSR_ERRERA); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_ERRSAVE, &env->CSR_ERRSAVE); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_CTAG, &env->CSR_CTAG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN0, &env->CSR_DMWIN0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN1, &env->CSR_DMWIN1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN2, &env->CSR_DMWIN2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DMWIN3, &env->CSR_DMWIN3); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL0, &env->CSR_PERFCTRL0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR0, &env->CSR_PERFCNTR0); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL1, &env->CSR_PERFCTRL1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR1, &env->CSR_PERFCNTR1); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL2, &env->CSR_PERFCTRL2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR2, &env->CSR_PERFCNTR2); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCTRL3, &env->CSR_PERFCTRL3); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_PERFCNTR3, &env->CSR_PERFCNTR3); -+ -+ /* debug */ -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_MWPC, &env->CSR_MWPC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_MWPS, &env->CSR_MWPS); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0ADDR, &env->CSR_DB0ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0MASK, &env->CSR_DB0MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0CTL, &env->CSR_DB0CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB0ASID, &env->CSR_DB0ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1ADDR, &env->CSR_DB1ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1MASK, &env->CSR_DB1MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1CTL, &env->CSR_DB1CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB1ASID, &env->CSR_DB1ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2ADDR, &env->CSR_DB2ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2MASK, &env->CSR_DB2MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2CTL, &env->CSR_DB2CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB2ASID, &env->CSR_DB2ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3ADDR, &env->CSR_DB3ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3MASK, &env->CSR_DB3MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3CTL, &env->CSR_DB3CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DB3ASID, &env->CSR_DB3ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_FWPC, &env->CSR_FWPC); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_FWPS, &env->CSR_FWPS); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0ADDR, &env->CSR_IB0ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0MASK, &env->CSR_IB0MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0CTL, &env->CSR_IB0CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB0ASID, &env->CSR_IB0ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1ADDR, &env->CSR_IB1ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1MASK, &env->CSR_IB1MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1CTL, &env->CSR_IB1CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB1ASID, &env->CSR_IB1ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2ADDR, &env->CSR_IB2ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2MASK, &env->CSR_IB2MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2CTL, &env->CSR_IB2CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB2ASID, &env->CSR_IB2ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3ADDR, &env->CSR_IB3ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3MASK, &env->CSR_IB3MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3CTL, &env->CSR_IB3CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB3ASID, &env->CSR_IB3ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4ADDR, &env->CSR_IB4ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4MASK, &env->CSR_IB4MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4CTL, &env->CSR_IB4CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB4ASID, &env->CSR_IB4ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5ADDR, &env->CSR_IB5ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5MASK, &env->CSR_IB5MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5CTL, &env->CSR_IB5CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB5ASID, &env->CSR_IB5ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6ADDR, &env->CSR_IB6ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6MASK, &env->CSR_IB6MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6CTL, &env->CSR_IB6CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB6ASID, &env->CSR_IB6ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7ADDR, &env->CSR_IB7ADDR); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7MASK, &env->CSR_IB7MASK); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7CTL, &env->CSR_IB7CTL); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_IB7ASID, &env->CSR_IB7ASID); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DEBUG, &env->CSR_DEBUG); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DERA, &env->CSR_DERA); -+ kvm_csr_set_addr(addr, LOONGARCH_CSR_DESAVE, &env->CSR_DESAVE); -+ -+ DPRINTF("%s\n", __func__); -+ return ret; -+} -+ -+int kvm_arch_destroy_vcpu(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ -+ g_free(cpu->kvm_csr_buf); -+ cpu->kvm_csr_buf = NULL; -+ return 0; -+} -+ -+static void kvm_csr_buf_reset(LOONGARCHCPU *cpu) -+{ -+ memset(cpu->kvm_csr_buf, 0, CSR_BUF_SIZE); -+} -+ -+static void kvm_csr_entry_add(LOONGARCHCPU *cpu, uint32_t index, -+ uint64_t value) -+{ -+ struct kvm_msrs *msrs = cpu->kvm_csr_buf; -+ void *limit = ((void *)msrs) + CSR_BUF_SIZE; -+ struct kvm_csr_entry *entry = &msrs->entries[msrs->ncsrs]; -+ -+ assert((void *)(entry + 1) <= limit); -+ -+ entry->index = index; -+ entry->reserved = 0; -+ entry->data = value; -+ msrs->ncsrs++; -+} -+ -+void kvm_loongarch_reset_vcpu(LOONGARCHCPU *cpu) -+{ -+ int ret = 0; -+ uint64_t reset = 1; -+ -+ if (CPU(cpu)->kvm_fd > 0) { -+ ret = kvm_larch_putq(CPU(cpu), KVM_REG_LOONGARCH_VCPU_RESET, &reset); -+ if (ret < 0) { -+ error_report("%s reset vcpu failed:%d", __func__, ret); -+ } -+ } -+ -+ DPRINTF("%s\n", __func__); -+} -+ -+void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) -+{ -+ int n; -+ if (kvm_sw_breakpoints_active(cpu)) { -+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; -+ } -+ if (nb_data_breakpoint > 0) { -+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; -+ for (n = 0; n < nb_data_breakpoint; n++) { -+ dbg->arch.data_breakpoint[n].addr = data_breakpoint[n].addr; -+ dbg->arch.data_breakpoint[n].mask = 0; -+ dbg->arch.data_breakpoint[n].asid = 0; -+ dbg->arch.data_breakpoint[n].ctrl = -+ type_code[data_breakpoint[n].type]; -+ } -+ dbg->arch.data_bp_nums = nb_data_breakpoint; -+ } else { -+ dbg->arch.data_bp_nums = 0; -+ } -+ if (nb_inst_breakpoint > 0) { -+ dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP; -+ for (n = 0; n < nb_inst_breakpoint; n++) { -+ dbg->arch.inst_breakpoint[n].addr = inst_breakpoint[n].addr; -+ dbg->arch.inst_breakpoint[n].mask = 0; -+ dbg->arch.inst_breakpoint[n].asid = 0; -+ dbg->arch.inst_breakpoint[n].ctrl = -+ type_code[inst_breakpoint[n].type]; -+ } -+ dbg->arch.inst_bp_nums = nb_inst_breakpoint; -+ } else { -+ dbg->arch.inst_bp_nums = 0; -+ } -+} -+ -+static const unsigned int brk_insn = 0x002b8005; -+ -+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) -+{ -+ DPRINTF("%s\n", __func__); -+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || -+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { -+ error_report("%s failed", __func__); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) -+{ -+ static uint32_t brk; -+ -+ DPRINTF("%s\n", __func__); -+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || -+ brk != brk_insn || -+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { -+ error_report("%s failed", __func__); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int find_hw_breakpoint(uint64_t addr, int len, int type) -+{ -+ int n; -+ switch (type) { -+ case GDB_BREAKPOINT_HW: -+ if (nb_inst_breakpoint == 0) { -+ return -1; -+ } -+ for (n = 0; n < nb_inst_breakpoint; n++) { -+ if (inst_breakpoint[n].addr == addr && -+ inst_breakpoint[n].type == type) { -+ return n; -+ } -+ } -+ break; -+ case GDB_WATCHPOINT_WRITE: -+ case GDB_WATCHPOINT_READ: -+ case GDB_WATCHPOINT_ACCESS: -+ if (nb_data_breakpoint == 0) { -+ return -1; -+ } -+ for (n = 0; n < nb_data_breakpoint; n++) { -+ if (data_breakpoint[n].addr == addr && -+ data_breakpoint[n].type == type && -+ data_breakpoint[n].len == len) { -+ return n; -+ } -+ } -+ break; -+ default: -+ return -1; -+ } -+ return -1; -+} -+ -+int kvm_arch_insert_hw_breakpoint(target_ulong addr, target_ulong len, -+ int type) -+{ -+ switch (type) { -+ case GDB_BREAKPOINT_HW: -+ len = 1; -+ if (nb_inst_breakpoint == 8) { -+ return -ENOBUFS; -+ } -+ if (find_hw_breakpoint(addr, len, type) >= 0) { -+ return -EEXIST; -+ } -+ inst_breakpoint[nb_inst_breakpoint].addr = addr; -+ inst_breakpoint[nb_inst_breakpoint].len = len; -+ inst_breakpoint[nb_inst_breakpoint].type = type; -+ nb_inst_breakpoint++; -+ break; -+ case GDB_WATCHPOINT_WRITE: -+ case GDB_WATCHPOINT_READ: -+ case GDB_WATCHPOINT_ACCESS: -+ switch (len) { -+ case 1: -+ case 2: -+ case 4: -+ case 8: -+ if (addr & (len - 1)) { -+ return -EINVAL; -+ } -+ if (nb_data_breakpoint == 8) { -+ return -ENOBUFS; -+ } -+ if (find_hw_breakpoint(addr, len, type) >= 0) { -+ return -EEXIST; -+ } -+ data_breakpoint[nb_data_breakpoint].addr = addr; -+ data_breakpoint[nb_data_breakpoint].len = len; -+ data_breakpoint[nb_data_breakpoint].type = type; -+ nb_data_breakpoint++; -+ break; -+ default: -+ return -EINVAL; -+ } -+ break; -+ default: -+ return -ENOSYS; -+ } -+ return 0; -+} -+ -+int kvm_arch_remove_hw_breakpoint(target_ulong addr, target_ulong len, -+ int type) -+{ -+ int n; -+ n = find_hw_breakpoint(addr, (type == GDB_BREAKPOINT_HW) ? 1 : len, type); -+ if (n < 0) { -+ printf("err not find remove target\n"); -+ return -ENOENT; -+ } -+ switch (type) { -+ case GDB_BREAKPOINT_HW: -+ nb_inst_breakpoint--; -+ inst_breakpoint[n] = inst_breakpoint[nb_inst_breakpoint]; -+ break; -+ case GDB_WATCHPOINT_WRITE: -+ case GDB_WATCHPOINT_READ: -+ case GDB_WATCHPOINT_ACCESS: -+ nb_data_breakpoint--; -+ data_breakpoint[n] = data_breakpoint[nb_data_breakpoint]; -+ break; -+ default: -+ return -1; -+ } -+ return 0; -+} -+ -+void kvm_arch_remove_all_hw_breakpoints(void) -+{ -+ DPRINTF("%s\n", __func__); -+ nb_data_breakpoint = 0; -+ nb_inst_breakpoint = 0; -+} -+ -+static inline int cpu_loongarch_io_interrupts_pending(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ -+ return env->CSR_ESTAT & (0x1 << 2); -+} -+ -+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ int r; -+ struct kvm_loongarch_interrupt intr; -+ -+ qemu_mutex_lock_iothread(); -+ -+ if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && -+ cpu_loongarch_io_interrupts_pending(cpu)) { -+ intr.cpu = -1; -+ intr.irq = 2; -+ r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); -+ if (r < 0) { -+ error_report("%s: cpu %d: failed to inject IRQ %x", __func__, -+ cs->cpu_index, intr.irq); -+ } -+ } -+ -+ qemu_mutex_unlock_iothread(); -+} -+ -+MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) -+{ -+ return MEMTXATTRS_UNSPECIFIED; -+} -+ -+int kvm_arch_process_async_events(CPUState *cs) -+{ -+ return cs->halted; -+} -+ -+static CPUWatchpoint hw_watchpoint; -+ -+static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int i; -+ bool ret = false; -+ kvm_cpu_synchronize_state(cs); -+ if (cs->singlestep_enabled) { -+ return true; -+ } -+ if (kvm_find_sw_breakpoint(cs, env->active_tc.PC)) { -+ return true; -+ } -+ /* hw breakpoint */ -+ if (run->debug.arch.exception == EXCCODE_WATCH) { -+ for (i = 0; i < 8; i++) { -+ if (run->debug.arch.fwps & (1 << i)) { -+ ret = true; -+ break; -+ } -+ } -+ for (i = 0; i < 8; i++) { -+ if (run->debug.arch.mwps & (1 << i)) { -+ cs->watchpoint_hit = &hw_watchpoint; -+ hw_watchpoint.vaddr = data_breakpoint[i].addr; -+ switch (data_breakpoint[i].type) { -+ case GDB_WATCHPOINT_READ: -+ ret = true; -+ hw_watchpoint.flags = BP_MEM_READ; -+ break; -+ case GDB_WATCHPOINT_WRITE: -+ ret = true; -+ hw_watchpoint.flags = BP_MEM_WRITE; -+ break; -+ case GDB_WATCHPOINT_ACCESS: -+ ret = true; -+ hw_watchpoint.flags = BP_MEM_ACCESS; -+ break; -+ } -+ } -+ } -+ run->debug.arch.exception = 0; -+ run->debug.arch.fwps = 0; -+ run->debug.arch.mwps = 0; -+ } -+ return ret; -+} -+ -+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) -+{ -+ int ret; -+ -+ DPRINTF("%s\n", __func__); -+ switch (run->exit_reason) { -+ case KVM_EXIT_HYPERCALL: -+ DPRINTF("handle LOONGARCH hypercall\n"); -+ ret = 0; -+ run->hypercall.ret = ret; -+ break; -+ -+ case KVM_EXIT_DEBUG: -+ ret = 0; -+ if (kvm_loongarch_handle_debug(cs, run)) { -+ ret = EXCP_DEBUG; -+ } -+ break; -+ default: -+ error_report("%s: unknown exit reason %d", __func__, run->exit_reason); -+ ret = -1; -+ break; -+ } -+ -+ return ret; -+} -+ -+bool kvm_arch_stop_on_emulation_error(CPUState *cs) -+{ -+ DPRINTF("%s\n", __func__); -+ return true; -+} -+ -+void kvm_arch_init_irq_routing(KVMState *s) -+{ -+} -+ -+int kvm_loongarch_set_interrupt(LOONGARCHCPU *cpu, int irq, int level) -+{ -+ CPUState *cs = CPU(cpu); -+ struct kvm_loongarch_interrupt intr; -+ -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ -+ intr.cpu = -1; -+ -+ if (level) { -+ intr.irq = irq; -+ } else { -+ intr.irq = -irq; -+ } -+ -+ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); -+ -+ return 0; -+} -+ -+int kvm_loongarch_set_ipi_interrupt(LOONGARCHCPU *cpu, int irq, int level) -+{ -+ CPUState *cs = current_cpu; -+ CPUState *dest_cs = CPU(cpu); -+ struct kvm_loongarch_interrupt intr; -+ -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ -+ intr.cpu = dest_cs->cpu_index; -+ -+ if (level) { -+ intr.irq = irq; -+ } else { -+ intr.irq = -irq; -+ } -+ -+ DPRINTF("%s: IRQ: %d\n", __func__, intr.irq); -+ if (!current_cpu) { -+ cs = dest_cs; -+ } -+ kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); -+ -+ return 0; -+} -+ -+static inline int kvm_loongarch_put_one_reg(CPUState *cs, uint64_t reg_id, -+ int32_t *addr) -+{ -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)addr }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_put_one_ureg(CPUState *cs, uint64_t reg_id, -+ uint32_t *addr) -+{ -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)addr }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_put_one_ulreg(CPUState *cs, uint64_t reg_id, -+ target_ulong *addr) -+{ -+ uint64_t val64 = *addr; -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)&val64 }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_put_one_reg64(CPUState *cs, int64_t reg_id, -+ int64_t *addr) -+{ -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)addr }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_larch_putq(CPUState *cs, uint64_t reg_id, uint64_t *addr) -+{ -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)addr }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_get_one_reg(CPUState *cs, uint64_t reg_id, -+ int32_t *addr) -+{ -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)addr }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_get_one_ureg(CPUState *cs, uint64_t reg_id, -+ uint32_t *addr) -+{ -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)addr }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_get_one_ulreg(CPUState *cs, uint64_t reg_id, -+ target_ulong *addr) -+{ -+ int ret; -+ uint64_t val64 = 0; -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)&val64 }; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+ if (ret >= 0) { -+ *addr = val64; -+ } -+ return ret; -+} -+ -+static inline int kvm_loongarch_get_one_reg64(CPUState *cs, int64_t reg_id, -+ int64_t *addr) -+{ -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)addr }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_larch_getq(CPUState *cs, uint64_t reg_id, uint64_t *addr) -+{ -+ struct kvm_one_reg csrreg = { .id = reg_id, .addr = (uintptr_t)addr }; -+ -+ return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &csrreg); -+} -+ -+static inline int kvm_loongarch_change_one_reg(CPUState *cs, uint64_t reg_id, -+ int32_t *addr, int32_t mask) -+{ -+ int err; -+ int32_t tmp, change; -+ -+ err = kvm_loongarch_get_one_reg(cs, reg_id, &tmp); -+ if (err < 0) { -+ return err; -+ } -+ -+ /* only change bits in mask */ -+ change = (*addr ^ tmp) & mask; -+ if (!change) { -+ return 0; -+ } -+ -+ tmp = tmp ^ change; -+ return kvm_loongarch_put_one_reg(cs, reg_id, &tmp); -+} -+ -+static inline int kvm_loongarch_change_one_reg64(CPUState *cs, uint64_t reg_id, -+ int64_t *addr, int64_t mask) -+{ -+ int err; -+ int64_t tmp, change; -+ -+ err = kvm_loongarch_get_one_reg64(cs, reg_id, &tmp); -+ if (err < 0) { -+ DPRINTF("%s: Failed to get CSR_CONFIG7 (%d)\n", __func__, err); -+ return err; -+ } -+ -+ /* only change bits in mask */ -+ change = (*addr ^ tmp) & mask; -+ if (!change) { -+ return 0; -+ } -+ -+ tmp = tmp ^ change; -+ return kvm_loongarch_put_one_reg64(cs, reg_id, &tmp); -+} -+/* -+ * Handle the VM clock being started or stopped -+ */ -+static void kvm_loongarch_update_state(void *opaque, bool running, -+ RunState state) -+{ -+ CPUState *cs = opaque; -+ int ret; -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ -+ /* -+ * If state is already dirty (synced to QEMU) then the KVM timer state is -+ * already saved and can be restored when it is synced back to KVM. -+ */ -+ if (!running) { -+ ret = -+ kvm_larch_getq(cs, KVM_REG_LOONGARCH_COUNTER, &cpu->counter_value); -+ if (ret < 0) { -+ printf("%s: Failed to get counter_value (%d)\n", __func__, ret); -+ } -+ -+ } else { -+ ret = kvm_larch_putq(cs, KVM_REG_LOONGARCH_COUNTER, -+ &(LOONGARCH_CPU(cs))->counter_value); -+ if (ret < 0) { -+ printf("%s: Failed to put counter_value (%d)\n", __func__, ret); -+ } -+ } -+} -+ -+static int kvm_loongarch_put_fpu_registers(CPUState *cs, int level) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int err, ret = 0; -+ unsigned int i; -+ struct kvm_fpu fpu; -+ -+ fpu.fcsr = env->active_fpu.fcsr0; -+ for (i = 0; i < 32; i++) { -+ memcpy(&fpu.fpr[i], &env->active_fpu.fpr[i], -+ sizeof(struct kvm_fpureg)); -+ } -+ for (i = 0; i < 8; i++) { -+ ((char *)&fpu.fcc)[i] = env->active_fpu.cf[i]; -+ } -+ fpu.vcsr = env->active_fpu.vcsr16; -+ -+ err = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu); -+ if (err < 0) { -+ DPRINTF("%s: Failed to get FPU (%d)\n", __func__, err); -+ ret = err; -+ } -+ -+ return ret; -+} -+ -+static int kvm_loongarch_get_fpu_registers(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int err, ret = 0; -+ unsigned int i; -+ struct kvm_fpu fpu; -+ -+ err = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu); -+ if (err < 0) { -+ DPRINTF("%s: Failed to get FPU (%d)\n", __func__, err); -+ ret = err; -+ } else { -+ env->active_fpu.fcsr0 = fpu.fcsr; -+ for (i = 0; i < 32; i++) { -+ memcpy(&env->active_fpu.fpr[i], &fpu.fpr[i], -+ sizeof(struct kvm_fpureg)); -+ } -+ for (i = 0; i < 8; i++) { -+ env->active_fpu.cf[i] = ((char *)&fpu.fcc)[i]; -+ } -+ env->active_fpu.vcsr16 = fpu.vcsr; -+ } -+ -+ return ret; -+} -+ -+#define KVM_PUT_ONE_UREG64(cs, regidx, addr) \ -+ ({ \ -+ int err; \ -+ uint64_t csrid = 0; \ -+ csrid = (KVM_IOC_CSRID(regidx)); \ -+ err = kvm_larch_putq(cs, csrid, addr); \ -+ if (err < 0) { \ -+ DPRINTF("%s: Failed to put regidx 0x%x err:%d\n", __func__, \ -+ regidx, err); \ -+ } \ -+ err; \ -+ }) -+ -+static int kvm_loongarch_put_csr_registers(CPUState *cs, int level) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int ret = 0; -+ -+ (void)level; -+ -+ kvm_csr_buf_reset(cpu); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CRMD, env->CSR_CRMD); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRMD, env->CSR_PRMD); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EUEN, env->CSR_EUEN); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MISC, env->CSR_MISC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ECFG, env->CSR_ECFG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ESTAT, env->CSR_ESTAT); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERA, env->CSR_ERA); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADV, env->CSR_BADV); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADI, env->CSR_BADI); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EEPN, env->CSR_EEPN); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, env->CSR_TLBIDX); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, env->CSR_TLBEHI); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, env->CSR_TLBELO0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, env->CSR_TLBELO1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GTLBC, env->CSR_GTLBC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TRGP, env->CSR_TRGP); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ASID, env->CSR_ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDL, env->CSR_PGDL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDH, env->CSR_PGDH); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGD, env->CSR_PGD); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, env->CSR_PWCTL0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, env->CSR_PWCTL1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, env->CSR_STLBPGSIZE); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_RVACFG, env->CSR_RVACFG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CPUID, env->CSR_CPUID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, env->CSR_PRCFG1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, env->CSR_PRCFG2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, env->CSR_PRCFG3); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS0, env->CSR_KS0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS1, env->CSR_KS1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS2, env->CSR_KS2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS3, env->CSR_KS3); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS4, env->CSR_KS4); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS5, env->CSR_KS5); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS6, env->CSR_KS6); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS7, env->CSR_KS7); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TMID, env->CSR_TMID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CNTC, env->CSR_CNTC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, env->CSR_TINTCLR); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GSTAT, env->CSR_GSTAT); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCFG, env->CSR_GCFG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GINTC, env->CSR_GINTC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCNTC, env->CSR_GCNTC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, env->CSR_LLBCTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, env->CSR_IMPCTL1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, env->CSR_IMPCTL2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GNMI, env->CSR_GNMI); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, env->CSR_TLBRENT); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, env->CSR_TLBRBADV); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, env->CSR_TLBRERA); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, env->CSR_TLBRSAVE); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, env->CSR_TLBRELO0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, env->CSR_TLBRELO1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, env->CSR_TLBREHI); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, env->CSR_TLBRPRMD); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, env->CSR_ERRCTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, env->CSR_ERRINFO); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, env->CSR_ERRINFO1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRENT, env->CSR_ERRENT); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRERA, env->CSR_ERRERA); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, env->CSR_ERRSAVE); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CTAG, env->CSR_CTAG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, env->CSR_DMWIN0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, env->CSR_DMWIN1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, env->CSR_DMWIN2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, env->CSR_DMWIN3); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, env->CSR_PERFCTRL0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, env->CSR_PERFCNTR0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, env->CSR_PERFCTRL1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, env->CSR_PERFCNTR1); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, env->CSR_PERFCTRL2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, env->CSR_PERFCNTR2); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, env->CSR_PERFCTRL3); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, env->CSR_PERFCNTR3); -+ -+ /* debug */ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPC, env->CSR_MWPC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPS, env->CSR_MWPS); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, env->CSR_DB0ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, env->CSR_DB0MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, env->CSR_DB0CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, env->CSR_DB0ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, env->CSR_DB1ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, env->CSR_DB1MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, env->CSR_DB1CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, env->CSR_DB1ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, env->CSR_DB2ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, env->CSR_DB2MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, env->CSR_DB2CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, env->CSR_DB2ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, env->CSR_DB3ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, env->CSR_DB3MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, env->CSR_DB3CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, env->CSR_DB3ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPC, env->CSR_FWPC); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPS, env->CSR_FWPS); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, env->CSR_IB0ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, env->CSR_IB0MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, env->CSR_IB0CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, env->CSR_IB0ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, env->CSR_IB1ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, env->CSR_IB1MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, env->CSR_IB1CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, env->CSR_IB1ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, env->CSR_IB2ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, env->CSR_IB2MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, env->CSR_IB2CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, env->CSR_IB2ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, env->CSR_IB3ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, env->CSR_IB3MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, env->CSR_IB3CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, env->CSR_IB3ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, env->CSR_IB4ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, env->CSR_IB4MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, env->CSR_IB4CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, env->CSR_IB4ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, env->CSR_IB5ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, env->CSR_IB5MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, env->CSR_IB5CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, env->CSR_IB5ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, env->CSR_IB6ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, env->CSR_IB6MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, env->CSR_IB6CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, env->CSR_IB6ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, env->CSR_IB7ADDR); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, env->CSR_IB7MASK); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, env->CSR_IB7CTL); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, env->CSR_IB7ASID); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DEBUG, env->CSR_DEBUG); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DERA, env->CSR_DERA); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DESAVE, env->CSR_DESAVE); -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_MSRS, cpu->kvm_csr_buf); -+ if (ret < cpu->kvm_csr_buf->ncsrs) { -+ struct kvm_csr_entry *e = &cpu->kvm_csr_buf->entries[ret]; -+ printf("error: failed to set CSR 0x%" PRIx32 " to 0x%" PRIx64 "\n", -+ (uint32_t)e->index, (uint64_t)e->data); -+ } -+ -+ /* -+ * timer cfg must be put at last since it is used to enable -+ * guest timer -+ */ -+ ret |= KVM_PUT_ONE_UREG64(cs, LOONGARCH_CSR_TVAL, &env->CSR_TVAL); -+ ret |= KVM_PUT_ONE_UREG64(cs, LOONGARCH_CSR_TCFG, &env->CSR_TCFG); -+ return ret; -+} -+ -+#define KVM_GET_ONE_UREG64(cs, regidx, addr) \ -+ ({ \ -+ int err; \ -+ uint64_t csrid = 0; \ -+ csrid = (KVM_IOC_CSRID(regidx)); \ -+ err = kvm_larch_getq(cs, csrid, addr); \ -+ if (err < 0) { \ -+ DPRINTF("%s: Failed to put regidx 0x%x err:%d\n", __func__, \ -+ regidx, err); \ -+ } \ -+ err; \ -+ }) -+ -+static int kvm_loongarch_get_csr_registers(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int ret = 0, i; -+ struct kvm_csr_entry *csrs = cpu->kvm_csr_buf->entries; -+ uint64_t **addr; -+ -+ kvm_csr_buf_reset(cpu); -+ addr = (void *)cpu->kvm_csr_buf + CSR_BUF_SIZE; -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CRMD, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRMD, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EUEN, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MISC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ECFG, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ESTAT, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERA, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADV, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_BADI, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_EEPN, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBIDX, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBEHI, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBELO1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GTLBC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TRGP, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGDH, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PGD, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PWCTL1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_STLBPGSIZE, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_RVACFG, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CPUID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PRCFG3, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS3, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS4, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS5, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS6, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_KS7, 0); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TMID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CNTC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TINTCLR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GSTAT, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCFG, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GINTC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GCNTC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_LLBCTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IMPCTL2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_GNMI, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRENT, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRBADV, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRERA, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRSAVE, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRELO1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBREHI, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_TLBRPRMD, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRCTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRINFO1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRENT, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRERA, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_ERRSAVE, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_CTAG, 0); -+ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DMWIN3, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR0, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR1, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR2, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCTRL3, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_PERFCNTR3, 0); -+ -+ /* debug */ -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_MWPS, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB0ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB1ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB2ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DB3ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPC, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_FWPS, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB0ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB1ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB2ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB3ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB4ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB5ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB6ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ADDR, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7MASK, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7CTL, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_IB7ASID, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DEBUG, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DERA, 0); -+ kvm_csr_entry_add(cpu, LOONGARCH_CSR_DESAVE, 0); -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_MSRS, cpu->kvm_csr_buf); -+ if (ret < cpu->kvm_csr_buf->ncsrs) { -+ struct kvm_csr_entry *e = &cpu->kvm_csr_buf->entries[ret]; -+ printf("error: failed to get CSR 0x%" PRIx32 "\n", (uint32_t)e->index); -+ } -+ -+ for (i = 0; i < ret; i++) { -+ uint32_t index = csrs[i].index; -+ if (addr[index]) { -+ *addr[index] = csrs[i].data; -+ } else { -+ printf("Failed to get addr CSR 0x%" PRIx32 "\n", i); -+ } -+ } -+ -+ ret |= KVM_GET_ONE_UREG64(cs, LOONGARCH_CSR_TVAL, &env->CSR_TVAL); -+ ret |= KVM_GET_ONE_UREG64(cs, LOONGARCH_CSR_TCFG, &env->CSR_TCFG); -+ return ret; -+} -+ -+int kvm_loongarch_put_pvtime(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ int err; -+ struct kvm_device_attr attr = { -+ .group = KVM_LARCH_VCPU_PVTIME_CTRL, -+ .attr = KVM_LARCH_VCPU_PVTIME_IPA, -+ .addr = (uint64_t)&env->st.guest_addr, -+ }; -+ -+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr); -+ if (err != 0) { -+ /* It's ok even though kvm has not such attr */ -+ return 0; -+ } -+ -+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_DEVICE_ATTR, attr); -+ if (err != 0) { -+ error_report("PVTIME IPA: KVM_SET_DEVICE_ATTR: %s", strerror(-err)); -+ return err; -+ } -+ -+ return 0; -+} -+ -+int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ int err; -+ struct kvm_device_attr attr = { -+ .group = KVM_LARCH_VCPU_PVTIME_CTRL, -+ .attr = KVM_LARCH_VCPU_PVTIME_IPA, -+ .addr = (uint64_t)&env->st.guest_addr, -+ }; -+ -+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr); -+ if (err != 0) { -+ /* It's ok even though kvm has not such attr */ -+ return 0; -+ } -+ -+ err = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_DEVICE_ATTR, attr); -+ if (err != 0) { -+ error_report("PVTIME IPA: KVM_GET_DEVICE_ATTR: %s", strerror(-err)); -+ return err; -+ } -+ -+ return 0; -+} -+ -+int kvm_arch_put_registers(CPUState *cs, int level) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ struct kvm_regs regs; -+ int ret; -+ int i; -+ -+ /* Set the registers based on QEMU's view of things */ -+ for (i = 0; i < 32; i++) { -+ regs.gpr[i] = (int64_t)(target_long)env->active_tc.gpr[i]; -+ } -+ -+ regs.pc = (int64_t)(target_long)env->active_tc.PC; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); -+ -+ if (ret < 0) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_put_csr_registers(cs, level); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ ret = kvm_loongarch_put_fpu_registers(cs, level); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ return ret; -+} -+ -+int kvm_arch_get_registers(CPUState *cs) -+{ -+ LOONGARCHCPU *cpu = LOONGARCH_CPU(cs); -+ CPULOONGARCHState *env = &cpu->env; -+ int ret = 0; -+ struct kvm_regs regs; -+ int i; -+ -+ /* Get the current register set as KVM seems it */ -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s); -+ -+ if (ret < 0) { -+ return ret; -+ } -+ -+ for (i = 0; i < 32; i++) { -+ env->active_tc.gpr[i] = regs.gpr[i]; -+ } -+ -+ env->active_tc.PC = regs.pc; -+ -+ kvm_loongarch_get_csr_registers(cs); -+ kvm_loongarch_get_fpu_registers(cs); -+ -+ return ret; -+} -+ -+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, -+ uint64_t address, uint32_t data, PCIDevice *dev) -+{ -+ return 0; -+} -+ -+int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, -+ int vector, PCIDevice *dev) -+{ -+ return 0; -+} -+ -+bool kvm_arch_cpu_check_are_resettable(void) -+{ -+ return true; -+} -+ -+int kvm_arch_release_virq_post(int virq) -+{ -+ return 0; -+} -+ -+int kvm_arch_msi_data_to_gsi(uint32_t data) -+{ -+ abort(); -+} -diff --git a/target/loongarch64/kvm_larch.h b/target/loongarch64/kvm_larch.h -new file mode 100644 -index 0000000000..637dec8106 ---- /dev/null -+++ b/target/loongarch64/kvm_larch.h -@@ -0,0 +1,49 @@ -+/* -+ * KVM/LOONGARCH: LOONGARCH specific KVM APIs -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef KVM_LOONGARCH_H -+#define KVM_LOONGARCH_H -+ -+/** -+ * kvm_loongarch_reset_vcpu: -+ * @cpu: LOONGARCHCPU -+ * -+ * Called at reset time to set kernel registers to their initial values. -+ */ -+void kvm_loongarch_reset_vcpu(LOONGARCHCPU *cpu); -+ -+int kvm_loongarch_set_interrupt(LOONGARCHCPU *cpu, int irq, int level); -+int kvm_loongarch_set_ipi_interrupt(LOONGARCHCPU *cpu, int irq, int level); -+ -+int kvm_loongarch_put_pvtime(LOONGARCHCPU *cpu); -+int kvm_loongarch_get_pvtime(LOONGARCHCPU *cpu); -+ -+#ifndef KVM_INTERRUPT_SET -+#define KVM_INTERRUPT_SET -1 -+#endif -+ -+#ifndef KVM_INTERRUPT_UNSET -+#define KVM_INTERRUPT_UNSET -2 -+#endif -+ -+#ifndef KVM_INTERRUPT_SET_LEVEL -+#define KVM_INTERRUPT_SET_LEVEL -3 -+#endif -+ -+#endif /* KVM_LOONGARCH_H */ -diff --git a/target/loongarch64/larch-defs.h b/target/loongarch64/larch-defs.h -new file mode 100644 -index 0000000000..e22a0dc652 ---- /dev/null -+++ b/target/loongarch64/larch-defs.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef QEMU_LOONGARCH_DEFS_H -+#define QEMU_LOONGARCH_DEFS_H -+ -+/* If we want to use host float regs... */ -+/* #define USE_HOST_FLOAT_REGS */ -+ -+/* Real pages are variable size... */ -+#define TARGET_PAGE_BITS 14 -+#define LOONGARCH_TLB_MAX 2112 -+#define TARGET_LONG_BITS 64 -+#define TARGET_PHYS_ADDR_SPACE_BITS 48 -+#define TARGET_VIRT_ADDR_SPACE_BITS 48 -+ -+/* -+ * bit definitions for insn_flags (ISAs/ASEs flags) -+ * ------------------------------------------------ -+ */ -+#define ISA_LARCH32 0x00000001ULL -+#define ISA_LARCH64 0x00000002ULL -+#define INSN_LOONGARCH 0x00010000ULL -+ -+#define CPU_LARCH32 (ISA_LARCH32) -+#define CPU_LARCH64 (ISA_LARCH32 | ISA_LARCH64) -+ -+#endif /* QEMU_LOONGARCH_DEFS_H */ -diff --git a/target/loongarch64/machine.c b/target/loongarch64/machine.c -new file mode 100644 -index 0000000000..d91c858383 ---- /dev/null -+++ b/target/loongarch64/machine.c -@@ -0,0 +1,423 @@ -+/* -+ * Loongarch 3A5000 machine emulation -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu-common.h" -+#include "cpu.h" -+#include "internal.h" -+#include "hw/hw.h" -+#include "kvm_larch.h" -+#include "migration/cpu.h" -+#include "linux/kvm.h" -+#include "sysemu/kvm.h" -+#include "qemu/error-report.h" -+ -+static int cpu_post_load(void *opaque, int version_id) -+{ -+ LOONGARCHCPU *cpu = opaque; -+ CPULOONGARCHState *env = &cpu->env; -+ int r = 0; -+ -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ -+#ifdef CONFIG_KVM -+ struct kvm_loongarch_vcpu_state vcpu_state; -+ int i; -+ -+ vcpu_state.online_vcpus = cpu->online_vcpus; -+ vcpu_state.is_migrate = cpu->is_migrate; -+ vcpu_state.cpu_freq = cpu->cpu_freq; -+ vcpu_state.count_ctl = cpu->count_ctl; -+ vcpu_state.pending_exceptions = cpu->pending_exceptions; -+ vcpu_state.pending_exceptions_clr = cpu->pending_exceptions_clr; -+ for (i = 0; i < 4; i++) { -+ vcpu_state.core_ext_ioisr[i] = cpu->core_ext_ioisr[i]; -+ } -+ r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_SET_VCPU_STATE, &vcpu_state); -+ if (r) { -+ error_report("set vcpu state failed %d", r); -+ } -+ -+ kvm_loongarch_put_pvtime(cpu); -+#endif -+ -+ restore_fp_status(env); -+ compute_hflags(env); -+ -+ return r; -+} -+ -+static int cpu_pre_save(void *opaque) -+{ -+#ifdef CONFIG_KVM -+ LOONGARCHCPU *cpu = opaque; -+ struct kvm_loongarch_vcpu_state vcpu_state; -+ int i, r = 0; -+ if (!kvm_enabled()) { -+ return 0; -+ } -+ -+ r = kvm_vcpu_ioctl(CPU(cpu), KVM_LARCH_GET_VCPU_STATE, &vcpu_state); -+ if (r < 0) { -+ error_report("get vcpu state failed %d", r); -+ return r; -+ } -+ -+ cpu->online_vcpus = vcpu_state.online_vcpus; -+ cpu->is_migrate = vcpu_state.is_migrate; -+ cpu->cpu_freq = vcpu_state.cpu_freq; -+ cpu->count_ctl = vcpu_state.count_ctl; -+ cpu->pending_exceptions = vcpu_state.pending_exceptions; -+ cpu->pending_exceptions_clr = vcpu_state.pending_exceptions_clr; -+ for (i = 0; i < 4; i++) { -+ cpu->core_ext_ioisr[i] = vcpu_state.core_ext_ioisr[i]; -+ } -+ -+ kvm_loongarch_get_pvtime(cpu); -+#endif -+ return 0; -+} -+ -+/* FPU state */ -+ -+static int get_fpr(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field) -+{ -+ fpr_t *v = pv; -+ qemu_get_be64s(f, &v->d); -+ return 0; -+} -+ -+static int put_fpr(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field, JSONWriter *vmdesc) -+{ -+ fpr_t *v = pv; -+ qemu_put_be64s(f, &v->d); -+ return 0; -+} -+ -+const VMStateInfo vmstate_info_fpr = { -+ .name = "fpr", -+ .get = get_fpr, -+ .put = put_fpr, -+}; -+ -+#define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v) \ -+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_fpr, fpr_t) -+ -+#define VMSTATE_FPR_ARRAY(_f, _s, _n) VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0) -+ -+static VMStateField vmstate_fpu_fields[] = { -+ VMSTATE_FPR_ARRAY(fpr, CPULOONGARCHFPUContext, 32), -+ VMSTATE_UINT32(fcsr0, CPULOONGARCHFPUContext), VMSTATE_END_OF_LIST() -+}; -+ -+const VMStateDescription vmstate_fpu = { .name = "cpu/fpu", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = vmstate_fpu_fields }; -+ -+const VMStateDescription vmstate_inactive_fpu = { .name = "cpu/inactive_fpu", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = -+ vmstate_fpu_fields }; -+ -+/* TC state */ -+ -+static VMStateField vmstate_tc_fields[] = { -+ VMSTATE_UINTTL_ARRAY(gpr, TCState, 32), VMSTATE_UINTTL(PC, TCState), -+ VMSTATE_END_OF_LIST() -+}; -+ -+const VMStateDescription vmstate_tc = { .name = "cpu/tc", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = vmstate_tc_fields }; -+ -+const VMStateDescription vmstate_inactive_tc = { .name = "cpu/inactive_tc", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = vmstate_tc_fields }; -+ -+/* TLB state */ -+ -+static int get_tlb(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field) -+{ -+ ls3a5k_tlb_t *v = pv; -+ uint32_t flags; -+ -+ qemu_get_betls(f, &v->VPN); -+ qemu_get_be64s(f, &v->PageMask); -+ qemu_get_be32s(f, &v->PageSize); -+ qemu_get_be16s(f, &v->ASID); -+ qemu_get_be32s(f, &flags); -+ v->RPLV1 = (flags >> 21) & 1; -+ v->RPLV0 = (flags >> 20) & 1; -+ v->PLV1 = (flags >> 18) & 3; -+ v->PLV0 = (flags >> 16) & 3; -+ v->EHINV = (flags >> 15) & 1; -+ v->RI1 = (flags >> 14) & 1; -+ v->RI0 = (flags >> 13) & 1; -+ v->XI1 = (flags >> 12) & 1; -+ v->XI0 = (flags >> 11) & 1; -+ v->WE1 = (flags >> 10) & 1; -+ v->WE0 = (flags >> 9) & 1; -+ v->V1 = (flags >> 8) & 1; -+ v->V0 = (flags >> 7) & 1; -+ v->C1 = (flags >> 4) & 7; -+ v->C0 = (flags >> 1) & 7; -+ v->G = (flags >> 0) & 1; -+ qemu_get_be64s(f, &v->PPN0); -+ qemu_get_be64s(f, &v->PPN1); -+ -+ return 0; -+} -+ -+static int put_tlb(QEMUFile *f, void *pv, size_t size, -+ const VMStateField *field, JSONWriter *vmdesc) -+{ -+ ls3a5k_tlb_t *v = pv; -+ -+ uint16_t asid = v->ASID; -+ uint32_t flags = -+ ((v->RPLV1 << 21) | (v->RPLV0 << 20) | (v->PLV1 << 18) | -+ (v->PLV0 << 16) | (v->EHINV << 15) | (v->RI1 << 14) | (v->RI0 << 13) | -+ (v->XI1 << 12) | (v->XI0 << 11) | (v->WE1 << 10) | (v->WE0 << 9) | -+ (v->V1 << 8) | (v->V0 << 7) | (v->C1 << 4) | (v->C0 << 1) | -+ (v->G << 0)); -+ -+ qemu_put_betls(f, &v->VPN); -+ qemu_put_be64s(f, &v->PageMask); -+ qemu_put_be32s(f, &v->PageSize); -+ qemu_put_be16s(f, &asid); -+ qemu_put_be32s(f, &flags); -+ qemu_put_be64s(f, &v->PPN0); -+ qemu_put_be64s(f, &v->PPN1); -+ -+ return 0; -+} -+ -+const VMStateInfo vmstate_info_tlb = { -+ .name = "tlb_entry", -+ .get = get_tlb, -+ .put = put_tlb, -+}; -+ -+#define VMSTATE_TLB_ARRAY_V(_f, _s, _n, _v) \ -+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_tlb, ls3a5k_tlb_t) -+ -+#define VMSTATE_TLB_ARRAY(_f, _s, _n) VMSTATE_TLB_ARRAY_V(_f, _s, _n, 0) -+ -+const VMStateDescription vmstate_tlb = { -+ .name = "cpu/tlb", -+ .version_id = 2, -+ .minimum_version_id = 2, -+ .fields = -+ (VMStateField[]){ VMSTATE_UINT32(nb_tlb, CPULOONGARCHTLBContext), -+ VMSTATE_UINT32(tlb_in_use, CPULOONGARCHTLBContext), -+ VMSTATE_TLB_ARRAY(mmu.ls3a5k.tlb, -+ CPULOONGARCHTLBContext, -+ LOONGARCH_TLB_MAX), -+ VMSTATE_END_OF_LIST() } -+}; -+ -+/* LOONGARCH CPU state */ -+ -+const VMStateDescription vmstate_loongarch_cpu = { -+ .name = "cpu", -+ .version_id = 15, -+ .minimum_version_id = 15, -+ .post_load = cpu_post_load, -+ .pre_save = cpu_pre_save, -+ .fields = -+ (VMStateField[]){ -+ /* Active TC */ -+ VMSTATE_STRUCT(env.active_tc, LOONGARCHCPU, 1, vmstate_tc, -+ TCState), -+ -+ /* Active FPU */ -+ VMSTATE_STRUCT(env.active_fpu, LOONGARCHCPU, 1, vmstate_fpu, -+ CPULOONGARCHFPUContext), -+ -+ /* TLB */ -+ VMSTATE_STRUCT_POINTER(env.tlb, LOONGARCHCPU, vmstate_tlb, -+ CPULOONGARCHTLBContext), -+ /* CPU metastate */ -+ VMSTATE_UINT32(env.current_tc, LOONGARCHCPU), -+ VMSTATE_INT32(env.error_code, LOONGARCHCPU), -+ VMSTATE_UINTTL(env.btarget, LOONGARCHCPU), -+ VMSTATE_UINTTL(env.bcond, LOONGARCHCPU), -+ -+ VMSTATE_UINT64(env.lladdr, LOONGARCHCPU), -+ -+ /* PV time */ -+ VMSTATE_UINT64(env.st.guest_addr, LOONGARCHCPU), -+ -+ /* Remaining CSR registers */ -+ VMSTATE_UINT64(env.CSR_CRMD, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PRMD, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_EUEN, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_MISC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ECFG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ESTAT, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERA, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_BADV, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_BADI, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_EEPN, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBIDX, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBEHI, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBELO0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBELO1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBWIRED, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GTLBC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TRGP, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PGDL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PGDH, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PGD, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PWCTL0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PWCTL1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_STLBPGSIZE, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_RVACFG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_CPUID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PRCFG1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PRCFG2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PRCFG3, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS3, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS4, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS5, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS6, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_KS7, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TMID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TCFG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TVAL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_CNTC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TINTCLR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GSTAT, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GCFG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GINTC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GCNTC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_LLBCTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IMPCTL1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IMPCTL2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_GNMI, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBRENT, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBRBADV, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBRERA, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBRSAVE, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBRELO0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBRELO1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBREHI, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_TLBRPRMD, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRCTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRINFO, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRINFO1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRENT, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRERA, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_ERRSAVE, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_CTAG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DMWIN0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DMWIN1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DMWIN2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DMWIN3, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCTRL0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCNTR0, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCTRL1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCNTR1, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCTRL2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCNTR2, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCTRL3, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_PERFCNTR3, LOONGARCHCPU), -+ /* debug */ -+ VMSTATE_UINT64(env.CSR_MWPC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_MWPS, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB0ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB0MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB0CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB0ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB1ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB1MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB1CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB1ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB2ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB2MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB2CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB2ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB3ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB3MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB3CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DB3ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_FWPC, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_FWPS, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB0ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB0MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB0CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB0ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB1ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB1MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB1CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB1ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB2ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB2MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB2CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB2ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB3ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB3MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB3CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB3ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB4ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB4MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB4CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB4ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB5ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB5MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB5CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB5ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB6ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB6MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB6CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB6ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB7ADDR, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB7MASK, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB7CTL, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_IB7ASID, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DEBUG, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DERA, LOONGARCHCPU), -+ VMSTATE_UINT64(env.CSR_DESAVE, LOONGARCHCPU), -+ -+ VMSTATE_STRUCT_ARRAY(env.fpus, LOONGARCHCPU, LOONGARCH_FPU_MAX, 1, -+ vmstate_inactive_fpu, CPULOONGARCHFPUContext), -+ VMSTATE_UINT8(online_vcpus, LOONGARCHCPU), -+ VMSTATE_UINT8(is_migrate, LOONGARCHCPU), -+ VMSTATE_UINT64(counter_value, LOONGARCHCPU), -+ VMSTATE_UINT32(cpu_freq, LOONGARCHCPU), -+ VMSTATE_UINT32(count_ctl, LOONGARCHCPU), -+ VMSTATE_UINT64(pending_exceptions, LOONGARCHCPU), -+ VMSTATE_UINT64(pending_exceptions_clr, LOONGARCHCPU), -+ VMSTATE_UINT64_ARRAY(core_ext_ioisr, LOONGARCHCPU, 4), -+ -+ VMSTATE_END_OF_LIST() }, -+}; -diff --git a/target/loongarch64/meson.build b/target/loongarch64/meson.build -new file mode 100644 -index 0000000000..6badf4484e ---- /dev/null -+++ b/target/loongarch64/meson.build -@@ -0,0 +1,35 @@ -+loongarch_user_ss = ss.source_set() -+loongarch_softmmu_ss = ss.source_set() -+loongarch_ss = ss.source_set() -+loongarch_ss.add(files( -+ 'cpu.c', -+ 'fpu.c', -+ 'gdbstub.c', -+)) -+ -+gen = [ -+ decodetree.process('insn.decode', extra_args: [ '--decode', 'decode_insn', -+ '--insnwidth', '32' ]) -+] -+ -+loongarch_ss.add(gen) -+loongarch_ss.add(when: 'CONFIG_TCG', if_true: files( -+ 'helper.c', -+ 'translate.c', -+ 'op_helper.c', -+ 'fpu_helper.c', -+ 'tlb_helper.c', -+ 'csr_helper.c', -+)) -+ -+loongarch_softmmu_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( -+ 'machine.c', -+ 'stabletimer.c', -+ 'arch_dump.c', -+)) -+ -+loongarch_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) -+ -+target_arch += {'loongarch64': loongarch_ss} -+target_softmmu_arch += {'loongarch64': loongarch_softmmu_ss} -+target_user_arch += {'loongarch64': loongarch_user_ss} -diff --git a/target/loongarch64/op_helper.c b/target/loongarch64/op_helper.c -new file mode 100644 -index 0000000000..7257e59479 ---- /dev/null -+++ b/target/loongarch64/op_helper.c -@@ -0,0 +1,485 @@ -+/* -+ * LOONGARCH emulation helpers for qemu. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/main-loop.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/host-utils.h" -+#include "exec/helper-proto.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+#include "sysemu/kvm.h" -+#include "qemu/crc32c.h" -+#include -+#include "hw/irq.h" -+#include "hw/core/cpu.h" -+#include "instmap.h" -+ -+/* Exceptions processing helpers */ -+ -+void helper_raise_exception_err(CPULOONGARCHState *env, uint32_t exception, -+ int error_code) -+{ -+ do_raise_exception_err(env, exception, error_code, 0); -+} -+ -+void helper_raise_exception(CPULOONGARCHState *env, uint32_t exception) -+{ -+ do_raise_exception(env, exception, GETPC()); -+} -+ -+void helper_raise_exception_debug(CPULOONGARCHState *env) -+{ -+ do_raise_exception(env, EXCP_DEBUG, 0); -+} -+ -+static void raise_exception(CPULOONGARCHState *env, uint32_t exception) -+{ -+ do_raise_exception(env, exception, 0); -+} -+ -+#if defined(CONFIG_USER_ONLY) -+#define HELPER_LD(name, insn, type) \ -+ static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ int mem_idx, uintptr_t retaddr) \ -+ { \ -+ return (type)cpu_##insn##_data_ra(env, addr, retaddr); \ -+ } -+#else -+ -+#define HF_SMAP_SHIFT 23 /* CR4.SMAP */ -+#define HF_SMAP_MASK (1 << HF_SMAP_SHIFT) -+#define MMU_KNOSMAP_IDX 2 -+#define HF_CPL_SHIFT 0 -+#define HF_CPL_MASK (3 << HF_CPL_SHIFT) -+#define AC_MASK 0x00040000 -+#define MMU_KSMAP_IDX 0 -+static inline int cpu_mmu_index_kernel(CPULOONGARCHState *env) -+{ -+ return !(env->hflags & HF_SMAP_MASK) -+ ? MMU_KNOSMAP_IDX -+ : ((env->hflags & HF_CPL_MASK) < 3 && (env->hflags & AC_MASK)) -+ ? MMU_KNOSMAP_IDX -+ : MMU_KSMAP_IDX; -+} -+ -+#define cpu_ldl_kernel_ra(e, p, r) \ -+ cpu_ldl_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) -+ -+#define HELPER_LD(name, insn, type) \ -+ static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ int mem_idx, uintptr_t retaddr) \ -+ { \ -+ } -+#endif -+ -+#if defined(CONFIG_USER_ONLY) -+#define HELPER_ST(name, insn, type) \ -+ static inline void do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ type val, int mem_idx, uintptr_t retaddr) \ -+ { \ -+ } -+#else -+#define HELPER_ST(name, insn, type) \ -+ static inline void do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ type val, int mem_idx, uintptr_t retaddr) \ -+ { \ -+ } -+#endif -+ -+static inline target_ulong bitswap(target_ulong v) -+{ -+ v = ((v >> 1) & (target_ulong)0x5555555555555555ULL) | -+ ((v & (target_ulong)0x5555555555555555ULL) << 1); -+ v = ((v >> 2) & (target_ulong)0x3333333333333333ULL) | -+ ((v & (target_ulong)0x3333333333333333ULL) << 2); -+ v = ((v >> 4) & (target_ulong)0x0F0F0F0F0F0F0F0FULL) | -+ ((v & (target_ulong)0x0F0F0F0F0F0F0F0FULL) << 4); -+ return v; -+} -+ -+target_ulong helper_dbitswap(target_ulong rt) -+{ -+ return bitswap(rt); -+} -+ -+target_ulong helper_bitswap(target_ulong rt) -+{ -+ return (int32_t)bitswap(rt); -+} -+ -+/* these crc32 functions are based on target/arm/helper-a64.c */ -+target_ulong helper_crc32(target_ulong val, target_ulong m, uint32_t sz) -+{ -+ uint8_t buf[8]; -+ target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); -+ -+ m &= mask; -+ stq_le_p(buf, m); -+ return (int32_t)(crc32(val ^ 0xffffffff, buf, sz) ^ 0xffffffff); -+} -+ -+target_ulong helper_crc32c(target_ulong val, target_ulong m, uint32_t sz) -+{ -+ uint8_t buf[8]; -+ target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); -+ m &= mask; -+ stq_le_p(buf, m); -+ return (int32_t)(crc32c(val, buf, sz) ^ 0xffffffff); -+} -+ -+#ifndef CONFIG_USER_ONLY -+ -+#define HELPER_LD_ATOMIC(name, insn, almask) \ -+ target_ulong helper_##name(CPULOONGARCHState *env, target_ulong arg, \ -+ int mem_idx) \ -+ { \ -+ } -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+void helper_drdtime(CPULOONGARCHState *env, target_ulong rd, target_ulong rs) -+{ -+ env->active_tc.gpr[rd] = cpu_loongarch_get_stable_counter(env); -+ env->active_tc.gpr[rs] = env->CSR_TMID; -+} -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+static void debug_pre_ertn(CPULOONGARCHState *env) -+{ -+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) { -+ qemu_log("ERTN: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx, -+ env->active_tc.PC, env->CSR_ERA); -+ qemu_log("\n"); -+ } -+} -+ -+static void debug_post_ertn(CPULOONGARCHState *env) -+{ -+ if (qemu_loglevel_mask(CPU_LOG_EXEC)) { -+ qemu_log("ERTN: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx, -+ env->active_tc.PC, env->CSR_ERA); -+ } -+} -+ -+static void set_pc(CPULOONGARCHState *env, target_ulong error_pc) -+{ -+ env->active_tc.PC = error_pc & ~(target_ulong)1; -+} -+ -+static inline void exception_return(CPULOONGARCHState *env) -+{ -+ debug_pre_ertn(env); -+ -+ if (cpu_refill_state(env)) { -+ env->CSR_CRMD &= (~0x7); -+ env->CSR_CRMD |= (env->CSR_TLBRPRMD & 0x7); -+ /* Clear Refill flag and set pc */ -+ env->CSR_TLBRERA &= (~0x1); -+ set_pc(env, env->CSR_TLBRERA); -+ if (qemu_loglevel_mask(CPU_LOG_INT)) { -+ qemu_log("%s: TLBRERA 0x%lx\n", __func__, env->CSR_TLBRERA); -+ } -+ } else { -+ env->CSR_CRMD &= (~0x7); -+ env->CSR_CRMD |= (env->CSR_PRMD & 0x7); -+ /* Clear Refill flag and set pc*/ -+ set_pc(env, env->CSR_ERA); -+ if (qemu_loglevel_mask(CPU_LOG_INT)) { -+ qemu_log("%s: ERA 0x%lx\n", __func__, env->CSR_ERA); -+ } -+ } -+ -+ compute_hflags(env); -+ debug_post_ertn(env); -+} -+ -+void helper_ertn(CPULOONGARCHState *env) -+{ -+ exception_return(env); -+ env->lladdr = 1; -+} -+ -+#endif /* !CONFIG_USER_ONLY */ -+ -+void helper_idle(CPULOONGARCHState *env) -+{ -+ CPUState *cs = CPU(loongarch_env_get_cpu(env)); -+ -+ cs->halted = 1; -+ cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); -+ /* -+ * Last instruction in the block, PC was updated before -+ * - no need to recover PC and icount -+ */ -+ raise_exception(env, EXCP_HLT); -+} -+ -+#if !defined(CONFIG_USER_ONLY) -+ -+void loongarch_cpu_do_unaligned_access(CPUState *cs, vaddr addr, -+ MMUAccessType access_type, int mmu_idx, -+ uintptr_t retaddr) -+{ -+ while (1) { -+ } -+} -+ -+#endif /* !CONFIG_USER_ONLY */ -+ -+void helper_store_scr(CPULOONGARCHState *env, uint32_t n, target_ulong val) -+{ -+ env->scr[n & 0x3] = val; -+} -+ -+target_ulong helper_load_scr(CPULOONGARCHState *env, uint32_t n) -+{ -+ return env->scr[n & 0x3]; -+} -+ -+/* loongarch assert op */ -+void helper_asrtle_d(CPULOONGARCHState *env, target_ulong rs, target_ulong rt) -+{ -+ if (rs > rt) { -+ do_raise_exception(env, EXCP_AdEL, GETPC()); -+ } -+} -+ -+void helper_asrtgt_d(CPULOONGARCHState *env, target_ulong rs, target_ulong rt) -+{ -+ if (rs <= rt) { -+ do_raise_exception(env, EXCP_AdEL, GETPC()); -+ } -+} -+ -+target_ulong helper_cto_w(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint32_t v = (uint32_t)a0; -+ int temp = 0; -+ -+ while ((v & 0x1) == 1) { -+ temp++; -+ v = v >> 1; -+ } -+ -+ return (target_ulong)temp; -+} -+ -+target_ulong helper_ctz_w(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint32_t v = (uint32_t)a0; -+ -+ if (v == 0) { -+ return 32; -+ } -+ -+ int temp = 0; -+ while ((v & 0x1) == 0) { -+ temp++; -+ v = v >> 1; -+ } -+ -+ return (target_ulong)temp; -+} -+ -+target_ulong helper_cto_d(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint64_t v = a0; -+ int temp = 0; -+ -+ while ((v & 0x1) == 1) { -+ temp++; -+ v = v >> 1; -+ } -+ -+ return (target_ulong)temp; -+} -+ -+target_ulong helper_ctz_d(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint64_t v = a0; -+ -+ if (v == 0) { -+ return 64; -+ } -+ -+ int temp = 0; -+ while ((v & 0x1) == 0) { -+ temp++; -+ v = v >> 1; -+ } -+ -+ return (target_ulong)temp; -+} -+ -+target_ulong helper_bitrev_w(CPULOONGARCHState *env, target_ulong a0) -+{ -+ int32_t v = (int32_t)a0; -+ const int SIZE = 32; -+ uint8_t bytes[SIZE]; -+ -+ int i; -+ for (i = 0; i < SIZE; i++) { -+ bytes[i] = v & 0x1; -+ v = v >> 1; -+ } -+ /* v == 0 */ -+ for (i = 0; i < SIZE; i++) { -+ v = v | ((uint32_t)bytes[i] << (SIZE - 1 - i)); -+ } -+ -+ return (target_ulong)(int32_t)v; -+} -+ -+target_ulong helper_bitrev_d(CPULOONGARCHState *env, target_ulong a0) -+{ -+ uint64_t v = a0; -+ const int SIZE = 64; -+ uint8_t bytes[SIZE]; -+ -+ int i; -+ for (i = 0; i < SIZE; i++) { -+ bytes[i] = v & 0x1; -+ v = v >> 1; -+ } -+ /* v == 0 */ -+ for (i = 0; i < SIZE; i++) { -+ v = v | ((uint64_t)bytes[i] << (SIZE - 1 - i)); -+ } -+ -+ return (target_ulong)v; -+} -+ -+void helper_memtrace_addr(CPULOONGARCHState *env, target_ulong address, -+ uint32_t op) -+{ -+ qemu_log("[cpu %d asid 0x%lx pc 0x%lx] addr 0x%lx op", -+ CPU(loongarch_env_get_cpu(env))->cpu_index, env->CSR_ASID, -+ env->active_tc.PC, address); -+ switch (op) { -+ case OPC_LARCH_LDPTR_D: -+ qemu_log("OPC_LARCH_LDPTR_D"); -+ break; -+ case OPC_LARCH_LD_D: -+ qemu_log("OPC_LARCH_LD_D"); -+ break; -+ case OPC_LARCH_LDPTR_W: -+ qemu_log("OPC_LARCH_LDPTR_W"); -+ break; -+ case OPC_LARCH_LD_W: -+ qemu_log("OPC_LARCH_LD_W"); -+ break; -+ case OPC_LARCH_LD_H: -+ qemu_log("OPC_LARCH_LD_H"); -+ break; -+ case OPC_LARCH_LD_B: -+ qemu_log("OPC_LARCH_LD_B"); -+ break; -+ case OPC_LARCH_LD_WU: -+ qemu_log("OPC_LARCH_LD_WU"); -+ break; -+ case OPC_LARCH_LD_HU: -+ qemu_log("OPC_LARCH_LD_HU"); -+ break; -+ case OPC_LARCH_LD_BU: -+ qemu_log("OPC_LARCH_LD_BU"); -+ break; -+ case OPC_LARCH_STPTR_D: -+ qemu_log("OPC_LARCH_STPTR_D"); -+ break; -+ case OPC_LARCH_ST_D: -+ qemu_log("OPC_LARCH_ST_D"); -+ break; -+ case OPC_LARCH_STPTR_W: -+ qemu_log("OPC_LARCH_STPTR_W"); -+ break; -+ case OPC_LARCH_ST_W: -+ qemu_log("OPC_LARCH_ST_W"); -+ break; -+ case OPC_LARCH_ST_H: -+ qemu_log("OPC_LARCH_ST_H"); -+ break; -+ case OPC_LARCH_ST_B: -+ qemu_log("OPC_LARCH_ST_B"); -+ break; -+ case OPC_LARCH_FLD_S: -+ qemu_log("OPC_LARCH_FLD_S"); -+ break; -+ case OPC_LARCH_FLD_D: -+ qemu_log("OPC_LARCH_FLD_D"); -+ break; -+ case OPC_LARCH_FST_S: -+ qemu_log("OPC_LARCH_FST_S"); -+ break; -+ case OPC_LARCH_FST_D: -+ qemu_log("OPC_LARCH_FST_D"); -+ break; -+ case OPC_LARCH_FLDX_S: -+ qemu_log("OPC_LARCH_FLDX_S"); -+ break; -+ case OPC_LARCH_FLDGT_S: -+ qemu_log("OPC_LARCH_FLDGT_S"); -+ break; -+ case OPC_LARCH_FLDLE_S: -+ qemu_log("OPC_LARCH_FLDLE_S"); -+ break; -+ case OPC_LARCH_FSTX_S: -+ qemu_log("OPC_LARCH_FSTX_S"); -+ break; -+ case OPC_LARCH_FSTGT_S: -+ qemu_log("OPC_LARCH_FSTGT_S"); -+ break; -+ case OPC_LARCH_FSTLE_S: -+ qemu_log("OPC_LARCH_FSTLE_S"); -+ break; -+ case OPC_LARCH_FLDX_D: -+ qemu_log("OPC_LARCH_FLDX_D"); -+ break; -+ case OPC_LARCH_FLDGT_D: -+ qemu_log("OPC_LARCH_FLDGT_D"); -+ break; -+ case OPC_LARCH_FLDLE_D: -+ qemu_log("OPC_LARCH_FLDLE_D"); -+ break; -+ case OPC_LARCH_FSTX_D: -+ qemu_log("OPC_LARCH_FSTX_D"); -+ break; -+ case OPC_LARCH_FSTGT_D: -+ qemu_log("OPC_LARCH_FSTGT_D"); -+ break; -+ case OPC_LARCH_FSTLE_D: -+ qemu_log("OPC_LARCH_FSTLE_D"); -+ break; -+ case OPC_LARCH_LL_W: -+ qemu_log("OPC_LARCH_LL_W"); -+ break; -+ case OPC_LARCH_LL_D: -+ qemu_log("OPC_LARCH_LL_D"); -+ break; -+ default: -+ qemu_log("0x%x", op); -+ } -+} -+ -+void helper_memtrace_val(CPULOONGARCHState *env, target_ulong val) -+{ -+ qemu_log("val 0x%lx\n", val); -+} -diff --git a/target/loongarch64/stabletimer.c b/target/loongarch64/stabletimer.c -new file mode 100644 -index 0000000000..4f4ccc5d89 ---- /dev/null -+++ b/target/loongarch64/stabletimer.c -@@ -0,0 +1,117 @@ -+/* -+ * QEMU LOONGARCH timer support -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "hw/loongarch/cpudevs.h" -+#include "qemu/timer.h" -+#include "sysemu/kvm.h" -+#include "internal.h" -+#include "hw/irq.h" -+ -+#ifdef DEBUG_TIMER -+#define debug_timer(fmt, args...) \ -+ printf("%s(%d)-%s -> " #fmt "\n", __FILE__, __LINE__, __func__, ##args); -+#else -+#define debug_timer(fmt, args...) -+#endif -+ -+#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */ -+#define STABLETIMER_TICK_MASK 0xfffffffffffcUL -+#define STABLETIMER_ENABLE 0x1UL -+#define STABLETIMER_PERIOD 0x2UL -+ -+/* return random value in [low, high] */ -+uint32_t cpu_loongarch_get_random_ls3a5k_tlb(uint32_t low, uint32_t high) -+{ -+ static uint32_t seed = 5; -+ static uint32_t prev_idx; -+ uint32_t idx; -+ uint32_t nb_rand_tlb = high - low + 1; -+ -+ do { -+ seed = 1103515245 * seed + 12345; -+ idx = (seed >> 16) % nb_rand_tlb + low; -+ } while (idx == prev_idx); -+ prev_idx = idx; -+ -+ return idx; -+} -+ -+/* LOONGARCH timer */ -+uint64_t cpu_loongarch_get_stable_counter(CPULOONGARCHState *env) -+{ -+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD; -+} -+ -+uint64_t cpu_loongarch_get_stable_timer_ticks(CPULOONGARCHState *env) -+{ -+ uint64_t now, expire; -+ -+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); -+ expire = timer_expire_time_ns(env->timer); -+ -+ return (expire - now) / TIMER_PERIOD; -+} -+ -+void cpu_loongarch_store_stable_timer_config(CPULOONGARCHState *env, -+ uint64_t value) -+{ -+ uint64_t now, next; -+ -+ env->CSR_TCFG = value; -+ if (value & STABLETIMER_ENABLE) { -+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); -+ next = now + (value & STABLETIMER_TICK_MASK) * TIMER_PERIOD; -+ timer_mod(env->timer, next); -+ } -+ debug_timer("0x%lx 0x%lx now 0x%lx, next 0x%lx", value, env->CSR_TCFG, now, -+ next); -+} -+ -+static void loongarch_stable_timer_cb(void *opaque) -+{ -+ CPULOONGARCHState *env; -+ uint64_t now, next; -+ -+ env = opaque; -+ debug_timer(); -+ if (env->CSR_TCFG & STABLETIMER_PERIOD) { -+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); -+ next = now + (env->CSR_TCFG & STABLETIMER_TICK_MASK) * TIMER_PERIOD; -+ timer_mod(env->timer, next); -+ } else { -+ env->CSR_TCFG &= ~STABLETIMER_ENABLE; -+ } -+ -+ qemu_irq_raise(env->irq[IRQ_TIMER]); -+} -+ -+void cpu_loongarch_clock_init(LOONGARCHCPU *cpu) -+{ -+ CPULOONGARCHState *env = &cpu->env; -+ -+ /* -+ * If we're in KVM mode, don't create the periodic timer, that is handled -+ * in kernel. -+ */ -+ if (!kvm_enabled()) { -+ env->timer = -+ timer_new_ns(QEMU_CLOCK_VIRTUAL, &loongarch_stable_timer_cb, env); -+ } -+} -diff --git a/target/loongarch64/tlb_helper.c b/target/loongarch64/tlb_helper.c -new file mode 100644 -index 0000000000..b6e924fbec ---- /dev/null -+++ b/target/loongarch64/tlb_helper.c -@@ -0,0 +1,641 @@ -+/* -+ * loongarch tlb emulation helpers for qemu. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/main-loop.h" -+#include "cpu.h" -+#include "internal.h" -+#include "qemu/host-utils.h" -+#include "exec/helper-proto.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+ -+#ifndef CONFIG_USER_ONLY -+ -+#define HELPER_LD(name, insn, type) \ -+ static inline type do_##name(CPULOONGARCHState *env, target_ulong addr, \ -+ int mem_idx, uintptr_t retaddr) \ -+ { \ -+ } -+ -+void helper_lddir(CPULOONGARCHState *env, target_ulong base, target_ulong rt, -+ target_ulong level, uint32_t mem_idx) -+{ -+} -+ -+void helper_ldpte(CPULOONGARCHState *env, target_ulong base, target_ulong odd, -+ uint32_t mem_idx) -+{ -+} -+ -+target_ulong helper_read_pgd(CPULOONGARCHState *env) -+{ -+ uint64_t badv; -+ -+ assert(env->CSR_TLBRERA & 0x1); -+ -+ if (env->CSR_TLBRERA & 0x1) { -+ badv = env->CSR_TLBRBADV; -+ } else { -+ badv = env->CSR_BADV; -+ } -+ -+ if ((badv >> 63) & 0x1) { -+ return env->CSR_PGDH; -+ } else { -+ return env->CSR_PGDL; -+ } -+} -+ -+/* TLB management */ -+static uint64_t ls3a5k_pagesize_to_mask(int pagesize) -+{ -+ /* 4KB - 1GB */ -+ if (pagesize < 12 && pagesize > 30) { -+ printf("[ERROR] unsupported page size %d\n", pagesize); -+ exit(-1); -+ } -+ -+ return (1 << (pagesize + 1)) - 1; -+} -+ -+static void ls3a5k_fill_tlb_entry(CPULOONGARCHState *env, ls3a5k_tlb_t *tlb, -+ int is_ftlb) -+{ -+ uint64_t page_mask; /* 0000...00001111...1111 */ -+ uint32_t page_size; -+ uint64_t entryhi; -+ uint64_t lo0, lo1; -+ -+ if (env->CSR_TLBRERA & 0x1) { -+ page_size = env->CSR_TLBREHI & 0x3f; -+ entryhi = env->CSR_TLBREHI; -+ lo0 = env->CSR_TLBRELO0; -+ lo1 = env->CSR_TLBRELO1; -+ } else { -+ page_size = (env->CSR_TLBIDX >> CSR_TLBIDX_PS_SHIFT) & 0x3f; -+ entryhi = env->CSR_TLBEHI; -+ lo0 = env->CSR_TLBELO0; -+ lo1 = env->CSR_TLBELO1; -+ } -+ -+ if (page_size == 0) { -+ printf("Warning: page_size is 0\n"); -+ } -+ -+ /* -+ * 15-12 11-8 7-4 3-0 -+ * 4KB: 0001 1111 1111 1111 // double 4KB mask [12:0] -+ * 16KB: 0111 1111 1111 1111 // double 16KB mask [14:0] -+ */ -+ if (is_ftlb) { -+ page_mask = env->tlb->mmu.ls3a5k.ftlb_mask; -+ } else { -+ page_mask = ls3a5k_pagesize_to_mask(page_size); -+ } -+ -+ tlb->VPN = entryhi & 0xffffffffe000 & ~page_mask; -+ -+ tlb->ASID = env->CSR_ASID & 0x3ff; /* CSR_ASID[9:0] */ -+ tlb->EHINV = 0; -+ tlb->G = (lo0 >> CSR_TLBLO0_GLOBAL_SHIFT) & /* CSR_TLBLO[6] */ -+ (lo1 >> CSR_TLBLO1_GLOBAL_SHIFT) & 1; -+ -+ tlb->PageMask = page_mask; -+ tlb->PageSize = page_size; -+ -+ tlb->V0 = (lo0 >> CSR_TLBLO0_V_SHIFT) & 0x1; /* [0] */ -+ tlb->WE0 = (lo0 >> CSR_TLBLO0_WE_SHIFT) & 0x1; /* [1] */ -+ tlb->PLV0 = (lo0 >> CSR_TLBLO0_PLV_SHIFT) & 0x3; /* [3:2] */ -+ tlb->C0 = (lo0 >> CSR_TLBLO0_CCA_SHIFT) & 0x3; /* [5:4] */ -+ tlb->PPN0 = (lo0 & 0xfffffffff000 & ~(page_mask >> 1)); -+ tlb->RI0 = (lo0 >> CSR_TLBLO0_RI_SHIFT) & 0x1; /* [61] */ -+ tlb->XI0 = (lo0 >> CSR_TLBLO0_XI_SHIFT) & 0x1; /* [62] */ -+ tlb->RPLV0 = (lo0 >> CSR_TLBLO0_RPLV_SHIFT) & 0x1; /* [63] */ -+ -+ tlb->V1 = (lo1 >> CSR_TLBLO1_V_SHIFT) & 0x1; /* [0] */ -+ tlb->WE1 = (lo1 >> CSR_TLBLO1_WE_SHIFT) & 0x1; /* [1] */ -+ tlb->PLV1 = (lo1 >> CSR_TLBLO1_PLV_SHIFT) & 0x3; /* [3:2] */ -+ tlb->C1 = (lo1 >> CSR_TLBLO1_CCA_SHIFT) & 0x3; /* [5:4] */ -+ tlb->PPN1 = (lo1 & 0xfffffffff000 & ~(page_mask >> 1)); -+ tlb->RI1 = (lo1 >> CSR_TLBLO1_RI_SHIFT) & 0x1; /* [61] */ -+ tlb->XI1 = (lo1 >> CSR_TLBLO1_XI_SHIFT) & 0x1; /* [62] */ -+ tlb->RPLV1 = (lo1 >> CSR_TLBLO1_RPLV_SHIFT) & 0x1; /* [63] */ -+} -+ -+static void ls3a5k_fill_tlb(CPULOONGARCHState *env, int idx, bool tlbwr) -+{ -+ ls3a5k_tlb_t *tlb; -+ -+ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; -+ if (tlbwr) { -+ if ((env->CSR_TLBIDX >> CSR_TLBIDX_EHINV_SHIFT) & 0x1) { -+ tlb->EHINV = 1; -+ return; -+ } -+ } -+ -+ if (idx < 2048) { -+ ls3a5k_fill_tlb_entry(env, tlb, 1); -+ } else { -+ ls3a5k_fill_tlb_entry(env, tlb, 0); -+ } -+} -+ -+void ls3a5k_flush_vtlb(CPULOONGARCHState *env) -+{ -+ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ uint32_t vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; -+ int i; -+ -+ ls3a5k_tlb_t *tlb; -+ -+ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ tlb->EHINV = 1; -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+void ls3a5k_flush_ftlb(CPULOONGARCHState *env) -+{ -+ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ int i; -+ -+ ls3a5k_tlb_t *tlb; -+ -+ for (i = 0; i < ftlb_size; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ tlb->EHINV = 1; -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+void ls3a5k_helper_tlbclr(CPULOONGARCHState *env) -+{ -+ int i; -+ uint16_t asid; -+ int vsize, fsize, index; -+ int start = 0, end = -1; -+ -+ asid = env->CSR_ASID & 0x3ff; -+ vsize = env->tlb->mmu.ls3a5k.vtlb_size; -+ fsize = env->tlb->mmu.ls3a5k.ftlb_size; -+ index = env->CSR_TLBIDX & CSR_TLBIDX_IDX; -+ -+ if (index < fsize) { -+ /* FTLB. One line per operation */ -+ int set = index % 256; -+ start = set * 8; -+ end = start + 7; -+ } else if (index < (fsize + vsize)) { -+ /* VTLB. All entries */ -+ start = fsize; -+ end = fsize + vsize - 1; -+ } else { -+ /* Ignore */ -+ } -+ -+ for (i = start; i <= end; i++) { -+ ls3a5k_tlb_t *tlb; -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ if (!tlb->G && tlb->ASID == asid) { -+ tlb->EHINV = 1; -+ } -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+void ls3a5k_helper_tlbflush(CPULOONGARCHState *env) -+{ -+ int i; -+ int vsize, fsize, index; -+ int start = 0, end = -1; -+ -+ vsize = env->tlb->mmu.ls3a5k.vtlb_size; -+ fsize = env->tlb->mmu.ls3a5k.ftlb_size; -+ index = env->CSR_TLBIDX & CSR_TLBIDX_IDX; -+ -+ if (index < fsize) { -+ /* FTLB. One line per operation */ -+ int set = index % 256; -+ start = set * 8; -+ end = start + 7; -+ } else if (index < (fsize + vsize)) { -+ /* VTLB. All entries */ -+ start = fsize; -+ end = fsize + vsize - 1; -+ } else { -+ /* Ignore */ -+ } -+ -+ for (i = start; i <= end; i++) { -+ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+void ls3a5k_helper_invtlb(CPULOONGARCHState *env, target_ulong addr, -+ target_ulong info, int op) -+{ -+ uint32_t asid = info & 0x3ff; -+ int i; -+ -+ switch (op) { -+ case 0: -+ case 1: -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; -+ } -+ break; -+ case 4: { -+ int i; -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ -+ if (!tlb->G && tlb->ASID == asid) { -+ tlb->EHINV = 1; -+ } -+ } -+ break; -+ } -+ -+ case 5: { -+ int i; -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ uint64_t vpn = addr & 0xffffffffe000 & ~tlb->PageMask; -+ -+ if (!tlb->G && tlb->ASID == asid && vpn == tlb->VPN) { -+ tlb->EHINV = 1; -+ } -+ } -+ break; -+ } -+ case 6: { -+ int i; -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ struct ls3a5k_tlb_t *tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ uint64_t vpn = addr & 0xffffffffe000 & ~tlb->PageMask; -+ -+ if ((tlb->G || tlb->ASID == asid) && vpn == tlb->VPN) { -+ tlb->EHINV = 1; -+ } -+ } -+ break; -+ } -+ default: -+ helper_raise_exception(env, EXCP_RI); -+ } -+ -+ cpu_loongarch_tlb_flush(env); -+} -+ -+static void ls3a5k_invalidate_tlb_entry(CPULOONGARCHState *env, -+ ls3a5k_tlb_t *tlb) -+{ -+ LOONGARCHCPU *cpu = loongarch_env_get_cpu(env); -+ CPUState *cs = CPU(cpu); -+ target_ulong addr; -+ target_ulong end; -+ target_ulong mask; -+ -+ mask = tlb->PageMask; /* 000...000111...111 */ -+ -+ if (tlb->V0) { -+ addr = tlb->VPN & ~mask; /* xxx...xxx[0]000..0000 */ -+ end = addr | (mask >> 1); /* xxx...xxx[0]111..1111 */ -+ while (addr < end) { -+ tlb_flush_page(cs, addr); -+ addr += TARGET_PAGE_SIZE; -+ } -+ } -+ -+ if (tlb->V1) { -+ /* xxx...xxx[1]000..0000 */ -+ addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1); -+ end = addr | mask; /* xxx...xxx[1]111..1111 */ -+ while (addr - 1 < end) { -+ tlb_flush_page(cs, addr); -+ addr += TARGET_PAGE_SIZE; -+ } -+ } -+} -+ -+void ls3a5k_invalidate_tlb(CPULOONGARCHState *env, int idx) -+{ -+ ls3a5k_tlb_t *tlb; -+ int asid = env->CSR_ASID & 0x3ff; -+ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; -+ if (tlb->G == 0 && tlb->ASID != asid) { -+ return; -+ } -+ ls3a5k_invalidate_tlb_entry(env, tlb); -+} -+ -+void ls3a5k_helper_tlbwr(CPULOONGARCHState *env) -+{ -+ int idx = env->CSR_TLBIDX & CSR_TLBIDX_IDX; /* [11:0] */ -+ -+ /* Convert idx if in FTLB */ -+ if (idx < env->tlb->mmu.ls3a5k.ftlb_size) { -+ /* -+ * 0 3 6 0 1 2 -+ * 1 4 7 => 3 4 5 -+ * 2 5 8 6 7 8 -+ */ -+ int set = idx % 256; -+ int way = idx / 256; -+ idx = set * 8 + way; -+ } -+ ls3a5k_invalidate_tlb(env, idx); -+ ls3a5k_fill_tlb(env, idx, true); -+} -+ -+void ls3a5k_helper_tlbfill(CPULOONGARCHState *env) -+{ -+ uint64_t mask; -+ uint64_t address; -+ int idx; -+ int set, ftlb_idx; -+ -+ uint64_t entryhi; -+ uint32_t pagesize; -+ -+ if (env->CSR_TLBRERA & 0x1) { -+ entryhi = env->CSR_TLBREHI & ~0x3f; -+ pagesize = env->CSR_TLBREHI & 0x3f; -+ } else { -+ entryhi = env->CSR_TLBEHI; -+ pagesize = (env->CSR_TLBIDX >> CSR_TLBIDX_PS_SHIFT) & 0x3f; -+ } -+ -+ uint32_t ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ uint32_t vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; -+ -+ mask = ls3a5k_pagesize_to_mask(pagesize); -+ -+ if (mask == env->tlb->mmu.ls3a5k.ftlb_mask && -+ env->tlb->mmu.ls3a5k.ftlb_size > 0) { -+ /* only write into FTLB */ -+ address = entryhi & 0xffffffffe000; /* [47:13] */ -+ -+ /* choose one set ramdomly */ -+ set = cpu_loongarch_get_random_ls3a5k_tlb(0, 7); -+ -+ /* index in one set */ -+ ftlb_idx = (address >> 15) & 0xff; /* [0,255] */ -+ -+ /* final idx */ -+ idx = ftlb_idx * 8 + set; /* max is 7 + 8 * 255 = 2047 */ -+ } else { -+ /* only write into VTLB */ -+ int wired_nr = env->CSR_TLBWIRED & 0x3f; -+ idx = cpu_loongarch_get_random_ls3a5k_tlb(ftlb_size + wired_nr, -+ ftlb_size + vtlb_size - 1); -+ } -+ -+ ls3a5k_invalidate_tlb(env, idx); -+ ls3a5k_fill_tlb(env, idx, false); -+} -+ -+void ls3a5k_helper_tlbsrch(CPULOONGARCHState *env) -+{ -+ uint64_t mask; -+ uint64_t vpn; -+ uint64_t tag; -+ uint16_t asid; -+ -+ int ftlb_size = env->tlb->mmu.ls3a5k.ftlb_size; -+ int vtlb_size = env->tlb->mmu.ls3a5k.vtlb_size; -+ int i; -+ int ftlb_idx; /* [0,255] 2^8 0xff */ -+ -+ ls3a5k_tlb_t *tlb; -+ -+ asid = env->CSR_ASID & 0x3ff; -+ -+ /* search VTLB */ -+ for (i = ftlb_size; i < ftlb_size + vtlb_size; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[i]; -+ mask = tlb->PageMask; -+ -+ vpn = env->CSR_TLBEHI & 0xffffffffe000 & ~mask; -+ tag = tlb->VPN & ~mask; -+ -+ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && -+ tlb->EHINV != 1) { -+ env->CSR_TLBIDX = -+ (i & 0xfff) | ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); -+ goto _MATCH_OUT_; -+ } -+ } -+ -+ if (ftlb_size == 0) { -+ goto _NO_MATCH_OUT_; -+ } -+ -+ /* search FTLB */ -+ mask = env->tlb->mmu.ls3a5k.ftlb_mask; -+ vpn = env->CSR_TLBEHI & 0xffffffffe000 & ~mask; -+ -+ ftlb_idx = (env->CSR_TLBEHI & 0xffffffffe000) >> 15; /* 16 KB */ -+ ftlb_idx = ftlb_idx & 0xff; /* [0,255] */ -+ -+ for (i = 0; i < 8; ++i) { -+ tlb = &env->tlb->mmu.ls3a5k.tlb[ftlb_idx * 8 + i]; -+ tag = tlb->VPN & ~mask; -+ -+ if ((tlb->G == 1 || tlb->ASID == asid) && vpn == tag && -+ tlb->EHINV != 1) { -+ env->CSR_TLBIDX = ((i * 256 + ftlb_idx) & 0xfff) | -+ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); -+ goto _MATCH_OUT_; -+ } -+ } -+ -+_NO_MATCH_OUT_: -+ env->CSR_TLBIDX = 1 << CSR_TLBIDX_EHINV_SHIFT; -+_MATCH_OUT_: -+ return; -+} -+ -+void ls3a5k_helper_tlbrd(CPULOONGARCHState *env) -+{ -+ ls3a5k_tlb_t *tlb; -+ int idx; -+ uint16_t asid; -+ -+ idx = env->CSR_TLBIDX & CSR_TLBIDX_IDX; -+ if (idx < env->tlb->mmu.ls3a5k.ftlb_size) { -+ int set = idx % 256; -+ int way = idx / 256; -+ idx = set * 8 + way; -+ } -+ -+ tlb = &env->tlb->mmu.ls3a5k.tlb[idx]; -+ -+ asid = env->CSR_ASID & 0x3ff; -+ -+ if (asid != tlb->ASID) { -+ cpu_loongarch_tlb_flush(env); -+ } -+ -+ if (tlb->EHINV) { -+ /* invalid TLB entry */ -+ env->CSR_TLBIDX = 1 << CSR_TLBIDX_EHINV_SHIFT; -+ env->CSR_TLBEHI = 0; -+ env->CSR_TLBELO0 = 0; -+ env->CSR_TLBELO1 = 0; -+ } else { -+ /* valid TLB entry */ -+ env->CSR_TLBIDX = (env->CSR_TLBIDX & 0xfff) | -+ ((tlb->PageSize & 0x3f) << CSR_TLBIDX_PS_SHIFT); -+ env->CSR_TLBEHI = tlb->VPN; -+ env->CSR_TLBELO0 = (tlb->V0 << CSR_TLBLO0_V_SHIFT) | -+ (tlb->WE0 << CSR_TLBLO0_WE_SHIFT) | -+ (tlb->PLV0 << CSR_TLBLO0_PLV_SHIFT) | -+ (tlb->C0 << CSR_TLBLO0_CCA_SHIFT) | -+ (tlb->G << CSR_TLBLO0_GLOBAL_SHIFT) | -+ (tlb->PPN0 & 0xfffffffff000) | -+ ((uint64_t)tlb->RI0 << CSR_TLBLO0_RI_SHIFT) | -+ ((uint64_t)tlb->XI0 << CSR_TLBLO0_XI_SHIFT) | -+ ((uint64_t)tlb->RPLV0 << CSR_TLBLO0_RPLV_SHIFT); -+ env->CSR_TLBELO1 = (tlb->V1 << CSR_TLBLO1_V_SHIFT) | -+ (tlb->WE1 << CSR_TLBLO1_WE_SHIFT) | -+ (tlb->PLV1 << CSR_TLBLO1_PLV_SHIFT) | -+ (tlb->C1 << CSR_TLBLO1_CCA_SHIFT) | -+ (tlb->G << CSR_TLBLO0_GLOBAL_SHIFT) | -+ (tlb->PPN1 & 0xfffffffff000) | -+ ((uint64_t)tlb->RI1 << CSR_TLBLO1_RI_SHIFT) | -+ ((uint64_t)tlb->XI1 << CSR_TLBLO1_XI_SHIFT) | -+ ((uint64_t)tlb->RPLV1 << CSR_TLBLO1_RPLV_SHIFT); -+ env->CSR_ASID = -+ (tlb->ASID << CSR_ASID_ASID_SHIFT) | (env->CSR_ASID & 0xff0000); -+ } -+} -+ -+void helper_tlbwr(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbwr(env); -+} -+ -+void helper_tlbfill(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbfill(env); -+} -+ -+void helper_tlbsrch(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbsrch(env); -+} -+ -+void helper_tlbrd(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbrd(env); -+} -+ -+void helper_tlbclr(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbclr(env); -+} -+ -+void helper_tlbflush(CPULOONGARCHState *env) -+{ -+ env->tlb->helper_tlbflush(env); -+} -+ -+void helper_invtlb(CPULOONGARCHState *env, target_ulong addr, -+ target_ulong info, target_ulong op) -+{ -+ env->tlb->helper_invtlb(env, addr, info, op); -+} -+ -+static void ls3a5k_mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def) -+{ -+ /* number of VTLB */ -+ env->tlb->nb_tlb = 64; -+ env->tlb->mmu.ls3a5k.vtlb_size = 64; -+ -+ /* number of FTLB */ -+ env->tlb->nb_tlb += 2048; -+ env->tlb->mmu.ls3a5k.ftlb_size = 2048; -+ env->tlb->mmu.ls3a5k.ftlb_mask = (1 << 15) - 1; /* 16 KB */ -+ /* -+ * page_size | ftlb_mask | party field -+ * ---------------------------------------------------------------- -+ * 4 KB = 12 | ( 1 << 13 ) - 1 = [12:0] | [12] -+ * 16 KB = 14 | ( 1 << 15 ) - 1 = [14:0] | [14] -+ * 64 KB = 16 | ( 1 << 17 ) - 1 = [16:0] | [16] -+ * 256 KB = 18 | ( 1 << 19 ) - 1 = [18:0] | [18] -+ * 1 MB = 20 | ( 1 << 21 ) - 1 = [20:0] | [20] -+ * 4 MB = 22 | ( 1 << 23 ) - 1 = [22:0] | [22] -+ * 16 MB = 24 | ( 1 << 25 ) - 1 = [24:0] | [24] -+ * 64 MB = 26 | ( 1 << 27 ) - 1 = [26:0] | [26] -+ * 256 MB = 28 | ( 1 << 29 ) - 1 = [28:0] | [28] -+ * 1 GB = 30 | ( 1 << 31 ) - 1 = [30:0] | [30] -+ * ---------------------------------------------------------------- -+ * take party field index as @n. eg. For 16 KB, n = 14 -+ * ---------------------------------------------------------------- -+ * tlb->VPN = TLBEHI & 0xffffffffe000[47:13] & ~mask = [47:n+1] -+ * tlb->PPN = TLBLO0 & 0xffffffffe000[47:13] & ~mask = [47:n+1] -+ * tlb->PPN = TLBLO1 & 0xffffffffe000[47:13] & ~mask = [47:n+1] -+ * ---------------------------------------------------------------- -+ * On mapping : -+ * > vpn = address & 0xffffffffe000[47:13] & ~mask = [47:n+1] -+ * > tag = tlb->VPN & ~mask = [47:n+1] -+ * ---------------------------------------------------------------- -+ * physical address = [47:n+1] | [n:0] -+ * physical address = tlb->PPN0 | (address & mask) -+ * physical address = tlb->PPN1 | (address & mask) -+ */ -+ -+ int i; -+ for (i = 0; i < env->tlb->nb_tlb; i++) { -+ env->tlb->mmu.ls3a5k.tlb[i].EHINV = 1; -+ } -+ -+ /* TLB's helper functions */ -+ env->tlb->map_address = &ls3a5k_map_address; -+ env->tlb->helper_tlbwr = ls3a5k_helper_tlbwr; -+ env->tlb->helper_tlbfill = ls3a5k_helper_tlbfill; -+ env->tlb->helper_tlbsrch = ls3a5k_helper_tlbsrch; -+ env->tlb->helper_tlbrd = ls3a5k_helper_tlbrd; -+ env->tlb->helper_tlbclr = ls3a5k_helper_tlbclr; -+ env->tlb->helper_tlbflush = ls3a5k_helper_tlbflush; -+ env->tlb->helper_invtlb = ls3a5k_helper_invtlb; -+} -+ -+void mmu_init(CPULOONGARCHState *env, const loongarch_def_t *def) -+{ -+ env->tlb = g_malloc0(sizeof(CPULOONGARCHTLBContext)); -+ -+ switch (def->mmu_type) { -+ case MMU_TYPE_LS3A5K: -+ ls3a5k_mmu_init(env, def); -+ break; -+ default: -+ cpu_abort(CPU(loongarch_env_get_cpu(env)), "MMU type not supported\n"); -+ } -+} -+#endif /* !CONFIG_USER_ONLY */ -diff --git a/target/loongarch64/trans.inc.c b/target/loongarch64/trans.inc.c -new file mode 100644 -index 0000000000..07bb0bb6e0 ---- /dev/null -+++ b/target/loongarch64/trans.inc.c -@@ -0,0 +1,3482 @@ -+/* -+ * LOONGARCH emulation for QEMU - main translation routines Extension -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+static bool trans_syscall(DisasContext *ctx, arg_syscall *a) -+{ -+ generate_exception_end(ctx, EXCP_SYSCALL); -+ return true; -+} -+ -+static bool trans_break(DisasContext *ctx, arg_break *a) -+{ -+ generate_exception_end(ctx, EXCP_BREAK); -+ return true; -+} -+ -+static bool trans_dbcl(DisasContext *ctx, arg_dbcl *a) -+{ -+ /* -+ * dbcl instruction is not support in tcg -+ */ -+ generate_exception_end(ctx, EXCP_RI); -+ return true; -+} -+ -+static bool trans_addi_w(DisasContext *ctx, arg_addi_w *a) -+{ -+ gen_arith_imm(ctx, OPC_LARCH_ADDI_W, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_addi_d(DisasContext *ctx, arg_addi_d *a) -+{ -+ gen_arith_imm(ctx, OPC_LARCH_ADDI_D, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_slli_d(DisasContext *ctx, arg_slli_d *a) -+{ -+ if (a->rd == 0) { -+ /* Nop */ -+ return true; -+ } -+ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_shli_tl(cpu_gpr[a->rd], t0, a->ui6); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_andi(DisasContext *ctx, arg_andi *a) -+{ -+ gen_logic_imm(ctx, OPC_LARCH_ANDI, a->rd, a->rj, a->ui12); -+ return true; -+} -+ -+static bool trans_srli_d(DisasContext *ctx, arg_srli_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_shri_tl(cpu_gpr[a->rd], t0, a->ui6); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_slli_w(DisasContext *ctx, arg_slli_w *a) -+{ -+ if (a->rd == 0) { -+ /* Nop */ -+ return true; -+ } -+ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_shli_tl(t0, t0, a->ui5); -+ tcg_gen_ext32s_tl(cpu_gpr[a->rd], t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_addu16i_d(DisasContext *ctx, arg_addu16i_d *a) -+{ -+ if (a->rj != 0) { -+ tcg_gen_addi_tl(cpu_gpr[a->rd], cpu_gpr[a->rj], a->si16 << 16); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[a->rd], a->si16 << 16); -+ } -+ return true; -+} -+ -+static bool trans_lu12i_w(DisasContext *ctx, arg_lu12i_w *a) -+{ -+ tcg_gen_movi_tl(cpu_gpr[a->rd], a->si20 << 12); -+ return true; -+} -+ -+static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d *a) -+{ -+ TCGv_i64 t0, t1; -+ t0 = tcg_temp_new_i64(); -+ t1 = tcg_temp_new_i64(); -+ -+ tcg_gen_movi_tl(t0, a->si20); -+ tcg_gen_concat_tl_i64(t1, cpu_gpr[a->rd], t0); -+ gen_store_gpr(t1, a->rd); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_pcaddi(DisasContext *ctx, arg_pcaddi *a) -+{ -+ target_ulong pc = ctx->base.pc_next; -+ target_ulong addr = pc + (a->si20 << 2); -+ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); -+ return true; -+} -+ -+static bool trans_pcalau12i(DisasContext *ctx, arg_pcalau12i *a) -+{ -+ target_ulong pc = ctx->base.pc_next; -+ target_ulong addr = (pc + (a->si20 << 12)) & ~0xfff; -+ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); -+ return true; -+} -+ -+static bool trans_pcaddu12i(DisasContext *ctx, arg_pcaddu12i *a) -+{ -+ target_ulong pc = ctx->base.pc_next; -+ target_ulong addr = pc + (a->si20 << 12); -+ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); -+ return true; -+} -+ -+static bool trans_pcaddu18i(DisasContext *ctx, arg_pcaddu18i *a) -+{ -+ target_ulong pc = ctx->base.pc_next; -+ target_ulong addr = pc + ((target_ulong)(a->si20) << 18); -+ tcg_gen_movi_tl(cpu_gpr[a->rd], addr); -+ return true; -+} -+ -+static bool trans_slti(DisasContext *ctx, arg_slti *a) -+{ -+ gen_slt_imm(ctx, OPC_LARCH_SLTI, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_sltui(DisasContext *ctx, arg_sltui *a) -+{ -+ gen_slt_imm(ctx, OPC_LARCH_SLTIU, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_lu52i_d(DisasContext *ctx, arg_lu52i_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ gen_load_gpr(t1, a->rj); -+ -+ tcg_gen_movi_tl(t0, a->si12); -+ tcg_gen_shli_tl(t0, t0, 52); -+ tcg_gen_andi_tl(t1, t1, 0xfffffffffffffU); -+ tcg_gen_or_tl(cpu_gpr[a->rd], t0, t1); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ori(DisasContext *ctx, arg_ori *a) -+{ -+ gen_logic_imm(ctx, OPC_LARCH_ORI, a->rd, a->rj, a->ui12); -+ return true; -+} -+ -+static bool trans_xori(DisasContext *ctx, arg_xori *a) -+{ -+ gen_logic_imm(ctx, OPC_LARCH_XORI, a->rd, a->rj, a->ui12); -+ return true; -+} -+ -+static bool trans_bstrins_d(DisasContext *ctx, arg_bstrins_d *a) -+{ -+ int lsb = a->lsbd; -+ int msb = a->msbd; -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ if (lsb > msb) { -+ return false; -+ } -+ -+ gen_load_gpr(t1, a->rj); -+ gen_load_gpr(t0, a->rd); -+ tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); -+ gen_store_gpr(t0, a->rd); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_bstrpick_d(DisasContext *ctx, arg_bstrpick_d *a) -+{ -+ int lsb = a->lsbd; -+ int msb = a->msbd; -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ if (lsb > msb) { -+ return false; -+ } -+ -+ gen_load_gpr(t1, a->rj); -+ gen_load_gpr(t0, a->rd); -+ tcg_gen_extract_tl(t0, t1, lsb, msb - lsb + 1); -+ gen_store_gpr(t0, a->rd); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_bstrins_w(DisasContext *ctx, arg_bstrins_w *a) -+{ -+ gen_bitops(ctx, OPC_LARCH_TRINS_W, a->rd, a->rj, a->lsbw, a->msbw); -+ return true; -+} -+ -+static bool trans_bstrpick_w(DisasContext *ctx, arg_bstrpick_w *a) -+{ -+ if (a->lsbw > a->msbw) { -+ return false; -+ } -+ gen_bitops(ctx, OPC_LARCH_TRPICK_W, a->rd, a->rj, a->lsbw, -+ a->msbw - a->lsbw); -+ return true; -+} -+ -+static bool trans_ldptr_w(DisasContext *ctx, arg_ldptr_w *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LDPTR_W, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_stptr_w(DisasContext *ctx, arg_stptr_w *a) -+{ -+ gen_st(ctx, OPC_LARCH_STPTR_W, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_ldptr_d(DisasContext *ctx, arg_ldptr_d *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LDPTR_D, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_stptr_d(DisasContext *ctx, arg_stptr_d *a) -+{ -+ gen_st(ctx, OPC_LARCH_STPTR_D, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_ld_b(DisasContext *ctx, arg_ld_b *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_B, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_h(DisasContext *ctx, arg_ld_h *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_H, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_w(DisasContext *ctx, arg_ld_w *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_W, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_d(DisasContext *ctx, arg_ld_d *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_D, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_st_b(DisasContext *ctx, arg_st_b *a) -+{ -+ gen_st(ctx, OPC_LARCH_ST_B, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_st_h(DisasContext *ctx, arg_st_h *a) -+{ -+ gen_st(ctx, OPC_LARCH_ST_H, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_st_w(DisasContext *ctx, arg_st_w *a) -+{ -+ gen_st(ctx, OPC_LARCH_ST_W, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_st_d(DisasContext *ctx, arg_st_d *a) -+{ -+ gen_st(ctx, OPC_LARCH_ST_D, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_bu(DisasContext *ctx, arg_ld_bu *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_BU, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_hu(DisasContext *ctx, arg_ld_hu *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_HU, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ld_wu(DisasContext *ctx, arg_ld_wu *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LD_WU, a->rd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_preld(DisasContext *ctx, arg_preld *a) -+{ -+ /* Treat as NOP. */ -+ return true; -+} -+ -+static bool trans_ll_w(DisasContext *ctx, arg_ll_w *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LL_W, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a) -+{ -+ gen_st_cond(ctx, a->rd, a->rj, a->si14 << 2, MO_TESL, false); -+ return true; -+} -+ -+static bool trans_ll_d(DisasContext *ctx, arg_ll_d *a) -+{ -+ gen_ld(ctx, OPC_LARCH_LL_D, a->rd, a->rj, a->si14 << 2); -+ return true; -+} -+ -+static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a) -+{ -+ gen_st_cond(ctx, a->rd, a->rj, a->si14 << 2, MO_TEQ, false); -+ return true; -+} -+ -+static bool trans_fld_s(DisasContext *ctx, arg_fld_s *a) -+{ -+ gen_fp_ldst(ctx, OPC_LARCH_FLD_S, a->fd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_fst_s(DisasContext *ctx, arg_fst_s *a) -+{ -+ gen_fp_ldst(ctx, OPC_LARCH_FST_S, a->fd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_fld_d(DisasContext *ctx, arg_fld_d *a) -+{ -+ gen_fp_ldst(ctx, OPC_LARCH_FLD_D, a->fd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_fst_d(DisasContext *ctx, arg_fst_d *a) -+{ -+ gen_fp_ldst(ctx, OPC_LARCH_FST_D, a->fd, a->rj, a->si12); -+ return true; -+} -+ -+static bool trans_ldx_b(DisasContext *ctx, arg_ldx_b *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_SB); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_h(DisasContext *ctx, arg_ldx_h *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TESW | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_w(DisasContext *ctx, arg_ldx_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TESL | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_ldx_d(DisasContext *ctx, arg_ldx_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEQ | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_stx_b(DisasContext *ctx, arg_stx_b *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ gen_load_gpr(t1, a->rd); -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_stx_h(DisasContext *ctx, arg_stx_h *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ gen_load_gpr(t1, a->rd); -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW | ctx->default_tcg_memop_mask); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_stx_w(DisasContext *ctx, arg_stx_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ gen_load_gpr(t1, a->rd); -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL | ctx->default_tcg_memop_mask); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_stx_d(DisasContext *ctx, arg_stx_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ gen_load_gpr(t1, a->rd); -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ | ctx->default_tcg_memop_mask); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_bu(DisasContext *ctx, arg_ldx_bu *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_hu(DisasContext *ctx, arg_ldx_hu *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEUW | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_ldx_wu(DisasContext *ctx, arg_ldx_wu *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_op_addr_add(ctx, t0, cpu_gpr[a->rj], cpu_gpr[a->rk]); -+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_TEUL | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t1, a->rd); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_fldx_s(DisasContext *ctx, arg_fldx_s *a) -+{ -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDX_S, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fldx_d(DisasContext *ctx, arg_fldx_d *a) -+{ -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDX_D, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstx_s(DisasContext *ctx, arg_fstx_s *a) -+{ -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTX_S, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstx_d(DisasContext *ctx, arg_fstx_d *a) -+{ -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTX_D, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+#define TRANS_AM_W(name, op) \ -+ static bool trans_##name(DisasContext *ctx, arg_##name *a) \ -+ { \ -+ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ -+ printf("%s: warning, register equal\n", __func__); \ -+ return false; \ -+ } \ -+ int mem_idx = ctx->mem_idx; \ -+ TCGv addr = tcg_temp_new(); \ -+ TCGv val = tcg_temp_new(); \ -+ TCGv ret = tcg_temp_new(); \ -+ \ -+ gen_load_gpr(addr, a->rj); \ -+ gen_load_gpr(val, a->rk); \ -+ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, \ -+ MO_TESL | ctx->default_tcg_memop_mask); \ -+ gen_store_gpr(ret, a->rd); \ -+ \ -+ tcg_temp_free(addr); \ -+ tcg_temp_free(val); \ -+ tcg_temp_free(ret); \ -+ return true; \ -+ } -+#define TRANS_AM_D(name, op) \ -+ static bool trans_##name(DisasContext *ctx, arg_##name *a) \ -+ { \ -+ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ -+ printf("%s: warning, register equal\n", __func__); \ -+ return false; \ -+ } \ -+ int mem_idx = ctx->mem_idx; \ -+ TCGv addr = tcg_temp_new(); \ -+ TCGv val = tcg_temp_new(); \ -+ TCGv ret = tcg_temp_new(); \ -+ \ -+ gen_load_gpr(addr, a->rj); \ -+ gen_load_gpr(val, a->rk); \ -+ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, \ -+ MO_TEQ | ctx->default_tcg_memop_mask); \ -+ gen_store_gpr(ret, a->rd); \ -+ \ -+ tcg_temp_free(addr); \ -+ tcg_temp_free(val); \ -+ tcg_temp_free(ret); \ -+ return true; \ -+ } -+#define TRANS_AM(name, op) \ -+ TRANS_AM_W(name##_w, op) \ -+ TRANS_AM_D(name##_d, op) -+TRANS_AM(amswap, xchg) /* trans_amswap_w, trans_amswap_d */ -+TRANS_AM(amadd, fetch_add) /* trans_amadd_w, trans_amadd_d */ -+TRANS_AM(amand, fetch_and) /* trans_amand_w, trans_amand_d */ -+TRANS_AM(amor, fetch_or) /* trans_amor_w, trans_amor_d */ -+TRANS_AM(amxor, fetch_xor) /* trans_amxor_w, trans_amxor_d */ -+TRANS_AM(ammax, fetch_smax) /* trans_ammax_w, trans_ammax_d */ -+TRANS_AM(ammin, fetch_smin) /* trans_ammin_w, trans_ammin_d */ -+TRANS_AM_W(ammax_wu, fetch_umax) /* trans_ammax_wu */ -+TRANS_AM_D(ammax_du, fetch_umax) /* trans_ammax_du */ -+TRANS_AM_W(ammin_wu, fetch_umin) /* trans_ammin_wu */ -+TRANS_AM_D(ammin_du, fetch_umin) /* trans_ammin_du */ -+#undef TRANS_AM -+#undef TRANS_AM_W -+#undef TRANS_AM_D -+ -+#define TRANS_AM_DB_W(name, op) \ -+ static bool trans_##name(DisasContext *ctx, arg_##name *a) \ -+ { \ -+ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ -+ printf("%s: warning, register equal\n", __func__); \ -+ return false; \ -+ } \ -+ int mem_idx = ctx->mem_idx; \ -+ TCGv addr = tcg_temp_new(); \ -+ TCGv val = tcg_temp_new(); \ -+ TCGv ret = tcg_temp_new(); \ -+ \ -+ gen_sync(0x10); \ -+ gen_load_gpr(addr, a->rj); \ -+ gen_load_gpr(val, a->rk); \ -+ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, \ -+ MO_TESL | ctx->default_tcg_memop_mask); \ -+ gen_store_gpr(ret, a->rd); \ -+ \ -+ tcg_temp_free(addr); \ -+ tcg_temp_free(val); \ -+ tcg_temp_free(ret); \ -+ return true; \ -+ } -+#define TRANS_AM_DB_D(name, op) \ -+ static bool trans_##name(DisasContext *ctx, arg_##name *a) \ -+ { \ -+ if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { \ -+ printf("%s: warning, register equal\n", __func__); \ -+ return false; \ -+ } \ -+ int mem_idx = ctx->mem_idx; \ -+ TCGv addr = tcg_temp_new(); \ -+ TCGv val = tcg_temp_new(); \ -+ TCGv ret = tcg_temp_new(); \ -+ \ -+ gen_sync(0x10); \ -+ gen_load_gpr(addr, a->rj); \ -+ gen_load_gpr(val, a->rk); \ -+ tcg_gen_atomic_##op##_tl(ret, addr, val, mem_idx, \ -+ MO_TEQ | ctx->default_tcg_memop_mask); \ -+ gen_store_gpr(ret, a->rd); \ -+ \ -+ tcg_temp_free(addr); \ -+ tcg_temp_free(val); \ -+ tcg_temp_free(ret); \ -+ return true; \ -+ } -+#define TRANS_AM_DB(name, op) \ -+ TRANS_AM_DB_W(name##_db_w, op) \ -+ TRANS_AM_DB_D(name##_db_d, op) -+TRANS_AM_DB(amswap, xchg) /* trans_amswap_db_w, trans_amswap_db_d */ -+TRANS_AM_DB(amadd, fetch_add) /* trans_amadd_db_w, trans_amadd_db_d */ -+TRANS_AM_DB(amand, fetch_and) /* trans_amand_db_w, trans_amand_db_d */ -+TRANS_AM_DB(amor, fetch_or) /* trans_amor_db_w, trans_amor_db_d */ -+TRANS_AM_DB(amxor, fetch_xor) /* trans_amxor_db_w, trans_amxor_db_d */ -+TRANS_AM_DB(ammax, fetch_smax) /* trans_ammax_db_w, trans_ammax_db_d */ -+TRANS_AM_DB(ammin, fetch_smin) /* trans_ammin_db_w, trans_ammin_db_d */ -+TRANS_AM_DB_W(ammax_db_wu, fetch_umax) /* trans_ammax_db_wu */ -+TRANS_AM_DB_D(ammax_db_du, fetch_umax) /* trans_ammax_db_du */ -+TRANS_AM_DB_W(ammin_db_wu, fetch_umin) /* trans_ammin_db_wu */ -+TRANS_AM_DB_D(ammin_db_du, fetch_umin) /* trans_ammin_db_du */ -+#undef TRANS_AM_DB -+#undef TRANS_AM_DB_W -+#undef TRANS_AM_DB_D -+ -+static bool trans_dbar(DisasContext *ctx, arg_dbar *a) -+{ -+ gen_sync(a->whint); -+ return true; -+} -+ -+static bool trans_ibar(DisasContext *ctx, arg_ibar *a) -+{ -+ /* -+ * FENCE_I is a no-op in QEMU, -+ * however we need to end the translation block -+ */ -+ ctx->base.is_jmp = DISAS_STOP; -+ return true; -+} -+ -+#define ASRTGT \ -+ do { \ -+ TCGv t1 = tcg_temp_new(); \ -+ TCGv t2 = tcg_temp_new(); \ -+ gen_load_gpr(t1, a->rj); \ -+ gen_load_gpr(t2, a->rk); \ -+ gen_helper_asrtgt_d(cpu_env, t1, t2); \ -+ tcg_temp_free(t1); \ -+ tcg_temp_free(t2); \ -+ } while (0) -+ -+#define ASRTLE \ -+ do { \ -+ TCGv t1 = tcg_temp_new(); \ -+ TCGv t2 = tcg_temp_new(); \ -+ gen_load_gpr(t1, a->rj); \ -+ gen_load_gpr(t2, a->rk); \ -+ gen_helper_asrtle_d(cpu_env, t1, t2); \ -+ tcg_temp_free(t1); \ -+ tcg_temp_free(t2); \ -+ } while (0) -+ -+static bool trans_fldgt_s(DisasContext *ctx, arg_fldgt_s *a) -+{ -+ ASRTGT; -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDGT_S, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fldgt_d(DisasContext *ctx, arg_fldgt_d *a) -+{ -+ ASRTGT; -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDGT_D, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fldle_s(DisasContext *ctx, arg_fldle_s *a) -+{ -+ ASRTLE; -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDLE_S, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fldle_d(DisasContext *ctx, arg_fldle_d *a) -+{ -+ ASRTLE; -+ gen_flt3_ldst(ctx, OPC_LARCH_FLDLE_D, a->fd, 0, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstgt_s(DisasContext *ctx, arg_fstgt_s *a) -+{ -+ ASRTGT; -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTGT_S, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstgt_d(DisasContext *ctx, arg_fstgt_d *a) -+{ -+ ASRTGT; -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTGT_D, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstle_s(DisasContext *ctx, arg_fstle_s *a) -+{ -+ ASRTLE; -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTLE_S, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_fstle_d(DisasContext *ctx, arg_fstle_d *a) -+{ -+ ASRTLE; -+ gen_flt3_ldst(ctx, OPC_LARCH_FSTLE_D, 0, a->fd, a->rj, a->rk); -+ return true; -+} -+ -+#define DECL_ARG(name) \ -+ arg_##name arg = { \ -+ .rd = a->rd, \ -+ .rj = a->rj, \ -+ .rk = a->rk, \ -+ }; -+ -+static bool trans_ldgt_b(DisasContext *ctx, arg_ldgt_b *a) -+{ -+ ASRTGT; -+ DECL_ARG(ldx_b) -+ trans_ldx_b(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldgt_h(DisasContext *ctx, arg_ldgt_h *a) -+{ -+ ASRTGT; -+ DECL_ARG(ldx_h) -+ trans_ldx_h(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldgt_w(DisasContext *ctx, arg_ldgt_w *a) -+{ -+ ASRTGT; -+ DECL_ARG(ldx_w) -+ trans_ldx_w(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldgt_d(DisasContext *ctx, arg_ldgt_d *a) -+{ -+ ASRTGT; -+ DECL_ARG(ldx_d) -+ trans_ldx_d(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldle_b(DisasContext *ctx, arg_ldle_b *a) -+{ -+ ASRTLE; -+ DECL_ARG(ldx_b) -+ trans_ldx_b(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldle_h(DisasContext *ctx, arg_ldle_h *a) -+{ -+ ASRTLE; -+ DECL_ARG(ldx_h) -+ trans_ldx_h(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldle_w(DisasContext *ctx, arg_ldle_w *a) -+{ -+ ASRTLE; -+ DECL_ARG(ldx_w) -+ trans_ldx_w(ctx, &arg); -+ return true; -+} -+ -+static bool trans_ldle_d(DisasContext *ctx, arg_ldle_d *a) -+{ -+ ASRTLE; -+ DECL_ARG(ldx_d) -+ trans_ldx_d(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stgt_b(DisasContext *ctx, arg_stgt_b *a) -+{ -+ ASRTGT; -+ DECL_ARG(stx_b) -+ trans_stx_b(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stgt_h(DisasContext *ctx, arg_stgt_h *a) -+{ -+ ASRTGT; -+ DECL_ARG(stx_h) -+ trans_stx_h(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stgt_w(DisasContext *ctx, arg_stgt_w *a) -+{ -+ ASRTGT; -+ DECL_ARG(stx_w) -+ trans_stx_w(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stgt_d(DisasContext *ctx, arg_stgt_d *a) -+{ -+ ASRTGT; -+ DECL_ARG(stx_d) -+ trans_stx_d(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stle_b(DisasContext *ctx, arg_stle_b *a) -+{ -+ ASRTLE; -+ DECL_ARG(stx_b) -+ trans_stx_b(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stle_h(DisasContext *ctx, arg_stle_h *a) -+{ -+ ASRTLE; -+ DECL_ARG(stx_h) -+ trans_stx_h(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stle_w(DisasContext *ctx, arg_stle_w *a) -+{ -+ ASRTLE; -+ DECL_ARG(stx_w) -+ trans_stx_w(ctx, &arg); -+ return true; -+} -+ -+static bool trans_stle_d(DisasContext *ctx, arg_stle_d *a) -+{ -+ ASRTLE; -+ DECL_ARG(stx_d) -+ trans_stx_d(ctx, &arg); -+ return true; -+} -+ -+#undef ASRTGT -+#undef ASRTLE -+#undef DECL_ARG -+ -+static bool trans_beqz(DisasContext *ctx, arg_beqz *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BEQZ, 4, a->rj, 0, a->offs21 << 2); -+ return true; -+} -+ -+static bool trans_bnez(DisasContext *ctx, arg_bnez *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BNEZ, 4, a->rj, 0, a->offs21 << 2); -+ return true; -+} -+ -+static bool trans_bceqz(DisasContext *ctx, arg_bceqz *a) -+{ -+ TCGv_i32 cj = tcg_const_i32(a->cj); -+ TCGv v0 = tcg_temp_new(); -+ TCGv v1 = tcg_const_i64(0); -+ -+ gen_helper_movcf2reg(v0, cpu_env, cj); -+ tcg_gen_setcond_tl(TCG_COND_EQ, bcond, v0, v1); -+ ctx->hflags |= LARCH_HFLAG_BC; -+ ctx->btarget = ctx->base.pc_next + (a->offs21 << 2); -+ -+ tcg_temp_free_i32(cj); -+ tcg_temp_free(v0); -+ tcg_temp_free(v1); -+ return true; -+} -+ -+static bool trans_bcnez(DisasContext *ctx, arg_bcnez *a) -+{ -+ TCGv_i32 cj = tcg_const_i32(a->cj); -+ TCGv v0 = tcg_temp_new(); -+ TCGv v1 = tcg_const_i64(0); -+ -+ gen_helper_movcf2reg(v0, cpu_env, cj); -+ tcg_gen_setcond_tl(TCG_COND_NE, bcond, v0, v1); -+ ctx->hflags |= LARCH_HFLAG_BC; -+ ctx->btarget = ctx->base.pc_next + (a->offs21 << 2); -+ -+ tcg_temp_free_i32(cj); -+ tcg_temp_free(v0); -+ tcg_temp_free(v1); -+ return true; -+} -+ -+static bool trans_b(DisasContext *ctx, arg_b *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_B, 4, 0, 0, a->offs << 2); -+ return true; -+} -+ -+static bool trans_bl(DisasContext *ctx, arg_bl *a) -+{ -+ ctx->btarget = ctx->base.pc_next + (a->offs << 2); -+ tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4); -+ ctx->hflags |= LARCH_HFLAG_B; -+ gen_branch(ctx, 4); -+ return true; -+} -+ -+static bool trans_blt(DisasContext *ctx, arg_blt *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BLT, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_bge(DisasContext *ctx, arg_bge *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BGE, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_bltu(DisasContext *ctx, arg_bltu *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BLTU, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BGEU, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_beq(DisasContext *ctx, arg_beq *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BEQ, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_bne(DisasContext *ctx, arg_bne *a) -+{ -+ gen_compute_branch(ctx, OPC_LARCH_BNE, 4, a->rj, a->rd, a->offs16 << 2); -+ return true; -+} -+ -+static bool trans_jirl(DisasContext *ctx, arg_jirl *a) -+{ -+ gen_base_offset_addr(ctx, btarget, a->rj, a->offs16 << 2); -+ if (a->rd != 0) { -+ tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->base.pc_next + 4); -+ } -+ ctx->hflags |= LARCH_HFLAG_BR; -+ gen_branch(ctx, 4); -+ -+ return true; -+} -+ -+#define TRANS_F4FR(name, fmt, op, bits) \ -+ static bool trans_##name##_##fmt(DisasContext *ctx, \ -+ arg_##name##_##fmt *a) \ -+ { \ -+ check_cp1_enabled(ctx); \ -+ TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ -+ TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ -+ TCGv_i##bits fp2 = tcg_temp_new_i##bits(); \ -+ TCGv_i##bits fp3 = tcg_temp_new_i##bits(); \ -+ check_cp1_enabled(ctx); \ -+ gen_load_fpr##bits(ctx, fp0, a->fj); \ -+ gen_load_fpr##bits(ctx, fp1, a->fk); \ -+ gen_load_fpr##bits(ctx, fp2, a->fa); \ -+ gen_helper_float_##op##_##fmt(fp3, cpu_env, fp0, fp1, fp2); \ -+ gen_store_fpr##bits(ctx, fp3, a->fd); \ -+ tcg_temp_free_i##bits(fp3); \ -+ tcg_temp_free_i##bits(fp2); \ -+ tcg_temp_free_i##bits(fp1); \ -+ tcg_temp_free_i##bits(fp0); \ -+ return true; \ -+ } -+ -+TRANS_F4FR(fmadd, s, maddf, 32) /* trans_fmadd_s */ -+TRANS_F4FR(fmadd, d, maddf, 64) /* trans_fmadd_d */ -+TRANS_F4FR(fmsub, s, msubf, 32) /* trans_fmsub_s */ -+TRANS_F4FR(fmsub, d, msubf, 64) /* trans_fmsub_d */ -+TRANS_F4FR(fnmadd, s, nmaddf, 32) /* trans_fnmadd_s */ -+TRANS_F4FR(fnmadd, d, nmaddf, 64) /* trans_fnmadd_d */ -+TRANS_F4FR(fnmsub, s, nmsubf, 32) /* trans_fnmsub_s */ -+TRANS_F4FR(fnmsub, d, nmsubf, 64) /* trans_fnmsub_d */ -+#undef TRANS_F4FR -+ -+static bool trans_fadd_s(DisasContext *ctx, arg_fadd_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FADD_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FADD_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fsub_s(DisasContext *ctx, arg_fsub_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FSUB_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FSUB_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmul_s(DisasContext *ctx, arg_fmul_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMUL_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMUL_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fdiv_s(DisasContext *ctx, arg_fdiv_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FDIV_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FDIV_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmax_s(DisasContext *ctx, arg_fmax_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMAX_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMAX_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmin_s(DisasContext *ctx, arg_fmin_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMIN_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMIN_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmaxa_s(DisasContext *ctx, arg_fmaxa_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMAXA_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmaxa_d(DisasContext *ctx, arg_fmaxa_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMAXA_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmina_s(DisasContext *ctx, arg_fmina_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMINA_S, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmina_d(DisasContext *ctx, arg_fmina_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMINA_D, a->fk, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fscaleb_s(DisasContext *ctx, arg_fscaleb_s *a) -+{ -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr32(ctx, fp0, a->fj); -+ gen_load_fpr32(ctx, fp1, a->fk); -+ gen_helper_float_exp2_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, a->fd); -+ tcg_temp_free_i32(fp0); -+ return true; -+} -+ -+static bool trans_fscaleb_d(DisasContext *ctx, arg_fscaleb_d *a) -+{ -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fp0, a->fj); -+ gen_load_fpr64(ctx, fp1, a->fk); -+ gen_helper_float_exp2_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, a->fd); -+ tcg_temp_free_i64(fp0); -+ return true; -+} -+ -+static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a) -+{ -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ TCGv_i32 fp2 = tcg_temp_new_i32(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr32(ctx, fp0, a->fj); -+ gen_load_fpr32(ctx, fp1, a->fk); -+ tcg_gen_deposit_i32(fp2, fp1, fp0, 0, 31); -+ gen_store_fpr32(ctx, fp2, a->fd); -+ -+ tcg_temp_free_i32(fp2); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ return true; -+} -+ -+static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a) -+{ -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ TCGv_i64 fp2 = tcg_temp_new_i64(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fp0, a->fj); -+ gen_load_fpr64(ctx, fp1, a->fk); -+ tcg_gen_deposit_i64(fp2, fp1, fp0, 0, 63); -+ gen_store_fpr64(ctx, fp2, a->fd); -+ -+ tcg_temp_free_i64(fp2); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ return true; -+} -+ -+static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FABS_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FABS_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FNEG_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FNEG_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_flogb_s(DisasContext *ctx, arg_flogb_s *a) -+{ -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr32(ctx, fp0, a->fj); -+ gen_helper_float_logb_s(fp1, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp1, a->fd); -+ -+ tcg_temp_free_i32(fp0); -+ tcg_temp_free_i32(fp1); -+ return true; -+} -+ -+static bool trans_flogb_d(DisasContext *ctx, arg_flogb_d *a) -+{ -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fp0, a->fj); -+ gen_helper_float_logb_d(fp1, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp1, a->fd); -+ -+ tcg_temp_free_i64(fp0); -+ tcg_temp_free_i64(fp1); -+ return true; -+} -+ -+static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FCLASS_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FCLASS_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fsqrt_s(DisasContext *ctx, arg_fsqrt_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FSQRT_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FSQRT_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frecip_s(DisasContext *ctx, arg_frecip_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRECIP_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frecip_d(DisasContext *ctx, arg_frecip_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRECIP_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frsqrt_s(DisasContext *ctx, arg_frsqrt_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRSQRT_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frsqrt_d(DisasContext *ctx, arg_frsqrt_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRSQRT_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmov_s(DisasContext *ctx, arg_fmov_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMOV_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fmov_d(DisasContext *ctx, arg_fmov_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FMOV_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_movgr2fr_w(DisasContext *ctx, arg_movgr2fr_w *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_GR2FR_W, a->rj, a->fd); -+ return true; -+} -+ -+static bool trans_movgr2fr_d(DisasContext *ctx, arg_movgr2fr_d *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_GR2FR_D, a->rj, a->fd); -+ return true; -+} -+ -+static bool trans_movgr2frh_w(DisasContext *ctx, arg_movgr2frh_w *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_GR2FRH_W, a->rj, a->fd); -+ return true; -+} -+ -+static bool trans_movfr2gr_s(DisasContext *ctx, arg_movfr2gr_s *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_FR2GR_S, a->rd, a->fj); -+ return true; -+} -+ -+static bool trans_movfr2gr_d(DisasContext *ctx, arg_movfr2gr_d *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_FR2GR_D, a->rd, a->fj); -+ return true; -+} -+ -+static bool trans_movfrh2gr_s(DisasContext *ctx, arg_movfrh2gr_s *a) -+{ -+ gen_cp1(ctx, OPC_LARCH_FRH2GR_S, a->rd, a->fj); -+ return true; -+} -+ -+static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ check_cp1_enabled(ctx); -+ gen_load_gpr(t0, a->rj); -+ save_cpu_state(ctx, 0); -+ { -+ TCGv_i32 fs_tmp = tcg_const_i32(a->fcsrd); -+ gen_helper_0e2i(movgr2fcsr, t0, fs_tmp, a->rj); -+ tcg_temp_free_i32(fs_tmp); -+ } -+ /* Stop translation as we may have changed hflags */ -+ ctx->base.is_jmp = DISAS_STOP; -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_helper_1e0i(movfcsr2gr, t0, a->fcsrs); -+ gen_store_gpr(t0, a->rd); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) -+{ -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i32 cd = tcg_const_i32(a->cd); -+ -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fp0, a->fj); -+ gen_helper_movreg2cf(cpu_env, cd, fp0); -+ -+ tcg_temp_free_i64(fp0); -+ tcg_temp_free_i32(cd); -+ return true; -+} -+ -+static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv_i32 cj = tcg_const_i32(a->cj); -+ -+ check_cp1_enabled(ctx); -+ gen_helper_movcf2reg(t0, cpu_env, cj); -+ gen_store_fpr64(ctx, t0, a->fd); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv_i32 cd = tcg_const_i32(a->cd); -+ -+ check_cp1_enabled(ctx); -+ gen_load_gpr(t0, a->rj); -+ gen_helper_movreg2cf(cpu_env, cd, t0); -+ -+ tcg_temp_free(t0); -+ tcg_temp_free_i32(cd); -+ return true; -+} -+ -+static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a) -+{ -+ TCGv_i32 cj = tcg_const_i32(a->cj); -+ -+ check_cp1_enabled(ctx); -+ gen_helper_movcf2reg(cpu_gpr[a->rd], cpu_env, cj); -+ -+ tcg_temp_free_i32(cj); -+ return true; -+} -+ -+static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FCVT_S_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FCVT_D_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrm_w_s(DisasContext *ctx, arg_ftintrm_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRM_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrm_w_d(DisasContext *ctx, arg_ftintrm_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRM_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrm_l_s(DisasContext *ctx, arg_ftintrm_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRM_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrm_l_d(DisasContext *ctx, arg_ftintrm_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRM_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrp_w_s(DisasContext *ctx, arg_ftintrp_w_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRP_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrp_w_d(DisasContext *ctx, arg_ftintrp_w_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRP_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrp_l_s(DisasContext *ctx, arg_ftintrp_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRP_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrp_l_d(DisasContext *ctx, arg_ftintrp_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRP_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrz_w_s(DisasContext *ctx, arg_ftintrz_w_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRZ_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrz_w_d(DisasContext *ctx, arg_ftintrz_w_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRZ_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrz_l_s(DisasContext *ctx, arg_ftintrz_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRZ_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrz_l_d(DisasContext *ctx, arg_ftintrz_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRZ_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrne_w_s(DisasContext *ctx, arg_ftintrne_w_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRNE_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrne_w_d(DisasContext *ctx, arg_ftintrne_w_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRNE_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrne_l_s(DisasContext *ctx, arg_ftintrne_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRNE_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftintrne_l_d(DisasContext *ctx, arg_ftintrne_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINTRNE_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftint_w_s(DisasContext *ctx, arg_ftint_w_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINT_W_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftint_w_d(DisasContext *ctx, arg_ftint_w_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINT_W_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftint_l_s(DisasContext *ctx, arg_ftint_l_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINT_L_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ftint_l_d(DisasContext *ctx, arg_ftint_l_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FTINT_L_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ffint_s_w(DisasContext *ctx, arg_ffint_s_w *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FFINT_S_W, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ffint_s_l(DisasContext *ctx, arg_ffint_s_l *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FFINT_S_L, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ffint_d_w(DisasContext *ctx, arg_ffint_d_w *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FFINT_D_W, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_ffint_d_l(DisasContext *ctx, arg_ffint_d_l *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FFINT_D_L, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frint_s(DisasContext *ctx, arg_frint_s *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRINT_S, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_frint_d(DisasContext *ctx, arg_frint_d *a) -+{ -+ gen_farith(ctx, OPC_LARCH_FRINT_D, 0, a->fj, a->fd, 0); -+ return true; -+} -+ -+static bool trans_alsl_w(DisasContext *ctx, arg_alsl_w *a) -+{ -+ gen_lsa(ctx, OPC_LARCH_ALSL_W, a->rd, a->rj, a->rk, a->sa2); -+ return true; -+} -+ -+static bool trans_alsl_wu(DisasContext *ctx, arg_alsl_wu *a) -+{ -+ TCGv t0, t1; -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ gen_load_gpr(t1, a->rk); -+ tcg_gen_shli_tl(t0, t0, a->sa2 + 1); -+ tcg_gen_add_tl(t0, t0, t1); -+ tcg_gen_ext32u_tl(cpu_gpr[a->rd], t0); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ -+ return true; -+} -+ -+static bool trans_alsl_d(DisasContext *ctx, arg_alsl_d *a) -+{ -+ check_larch_64(ctx); -+ gen_lsa(ctx, OPC_LARCH_ALSL_D, a->rd, a->rj, a->rk, a->sa2); -+ return true; -+} -+ -+static bool trans_bytepick_w(DisasContext *ctx, arg_bytepick_w *a) -+{ -+ gen_align(ctx, 32, a->rd, a->rj, a->rk, a->sa2); -+ return true; -+} -+ -+static bool trans_bytepick_d(DisasContext *ctx, arg_bytepick_d *a) -+{ -+ check_larch_64(ctx); -+ gen_align(ctx, 64, a->rd, a->rj, a->rk, a->sa3); -+ return true; -+} -+ -+static bool trans_add_w(DisasContext *ctx, arg_add_w *a) -+{ -+ gen_arith(ctx, OPC_LARCH_ADD_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_sub_w(DisasContext *ctx, arg_sub_w *a) -+{ -+ gen_arith(ctx, OPC_LARCH_SUB_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_add_d(DisasContext *ctx, arg_add_d *a) -+{ -+ gen_arith(ctx, OPC_LARCH_ADD_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_sub_d(DisasContext *ctx, arg_sub_d *a) -+{ -+ check_larch_64(ctx); -+ gen_arith(ctx, OPC_LARCH_SUB_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_slt(DisasContext *ctx, arg_slt *a) -+{ -+ gen_slt(ctx, OPC_LARCH_SLT, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_sltu(DisasContext *ctx, arg_sltu *a) -+{ -+ gen_slt(ctx, OPC_LARCH_SLTU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_maskeqz(DisasContext *ctx, arg_maskeqz *a) -+{ -+ gen_cond_move(ctx, OPC_LARCH_MASKEQZ, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_masknez(DisasContext *ctx, arg_masknez *a) -+{ -+ gen_cond_move(ctx, OPC_LARCH_MASKNEZ, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_nor(DisasContext *ctx, arg_nor *a) -+{ -+ gen_logic(ctx, OPC_LARCH_NOR, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_and(DisasContext *ctx, arg_and *a) -+{ -+ gen_logic(ctx, OPC_LARCH_AND, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_or(DisasContext *ctx, arg_or *a) -+{ -+ gen_logic(ctx, OPC_LARCH_OR, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_xor(DisasContext *ctx, arg_xor *a) -+{ -+ gen_logic(ctx, OPC_LARCH_XOR, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_orn(DisasContext *ctx, arg_orn *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rk); -+ tcg_gen_not_tl(t0, t0); -+ tcg_gen_or_tl(cpu_gpr[a->rd], cpu_gpr[a->rj], t0); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_andn(DisasContext *ctx, arg_andn *a) -+{ -+ TCGv t0, t1; -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rk); -+ gen_load_gpr(t1, a->rj); -+ tcg_gen_not_tl(t0, t0); -+ tcg_gen_and_tl(cpu_gpr[a->rd], t1, t0); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+static bool trans_sll_w(DisasContext *ctx, arg_sll_w *a) -+{ -+ gen_shift(ctx, OPC_LARCH_SLL_W, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_srl_w(DisasContext *ctx, arg_srl_w *a) -+{ -+ gen_shift(ctx, OPC_LARCH_SRL_W, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_sra_w(DisasContext *ctx, arg_sra_w *a) -+{ -+ gen_shift(ctx, OPC_LARCH_SRA_W, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_sll_d(DisasContext *ctx, arg_sll_d *a) -+{ -+ check_larch_64(ctx); -+ gen_shift(ctx, OPC_LARCH_SLL_D, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_srl_d(DisasContext *ctx, arg_srl_d *a) -+{ -+ check_larch_64(ctx); -+ gen_shift(ctx, OPC_LARCH_SRL_D, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_sra_d(DisasContext *ctx, arg_sra_d *a) -+{ -+ check_larch_64(ctx); -+ gen_shift(ctx, OPC_LARCH_SRA_D, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_rotr_w(DisasContext *ctx, arg_rotr_w *a) -+{ -+ gen_shift(ctx, OPC_LARCH_ROTR_W, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_rotr_d(DisasContext *ctx, arg_rotr_d *a) -+{ -+ check_larch_64(ctx); -+ gen_shift(ctx, OPC_LARCH_ROTR_D, a->rd, a->rk, a->rj); -+ return true; -+} -+ -+static bool trans_crc_w_b_w(DisasContext *ctx, arg_crc_w_b_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 1, 0); -+ return true; -+} -+ -+static bool trans_crc_w_h_w(DisasContext *ctx, arg_crc_w_h_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 2, 0); -+ return true; -+} -+ -+static bool trans_crc_w_w_w(DisasContext *ctx, arg_crc_w_w_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 4, 0); -+ return true; -+} -+ -+static bool trans_crc_w_d_w(DisasContext *ctx, arg_crc_w_d_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 8, 0); -+ return true; -+} -+ -+static bool trans_crcc_w_b_w(DisasContext *ctx, arg_crcc_w_b_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 1, 1); -+ return true; -+} -+ -+static bool trans_crcc_w_h_w(DisasContext *ctx, arg_crcc_w_h_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 2, 1); -+ return true; -+} -+ -+static bool trans_crcc_w_w_w(DisasContext *ctx, arg_crcc_w_w_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 4, 1); -+ return true; -+} -+ -+static bool trans_crcc_w_d_w(DisasContext *ctx, arg_crcc_w_d_w *a) -+{ -+ gen_crc32(ctx, a->rd, a->rj, a->rk, 8, 1); -+ return true; -+} -+ -+static bool trans_mul_w(DisasContext *ctx, arg_mul_w *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MUL_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulh_w(DisasContext *ctx, arg_mulh_w *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MULH_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulh_wu(DisasContext *ctx, arg_mulh_wu *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MULH_WU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mul_d(DisasContext *ctx, arg_mul_d *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MUL_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulh_d(DisasContext *ctx, arg_mulh_d *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MULH_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulh_du(DisasContext *ctx, arg_mulh_du *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MULH_DU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mulw_d_w(DisasContext *ctx, arg_mulw_d_w *a) -+{ -+ TCGv_i64 t0 = tcg_temp_new_i64(); -+ TCGv_i64 t1 = tcg_temp_new_i64(); -+ TCGv_i64 t2 = tcg_temp_new_i64(); -+ gen_load_gpr(t0, a->rj); -+ gen_load_gpr(t1, a->rk); -+ tcg_gen_ext32s_i64(t0, t0); -+ tcg_gen_ext32s_i64(t1, t1); -+ tcg_gen_mul_i64(t2, t0, t1); -+ gen_store_gpr(t2, a->rd); -+ tcg_temp_free_i64(t0); -+ tcg_temp_free_i64(t1); -+ tcg_temp_free_i64(t2); -+ return true; -+} -+ -+static bool trans_mulw_d_wu(DisasContext *ctx, arg_mulw_d_wu *a) -+{ -+ TCGv_i64 t0 = tcg_temp_new_i64(); -+ TCGv_i64 t1 = tcg_temp_new_i64(); -+ TCGv_i64 t2 = tcg_temp_new_i64(); -+ gen_load_gpr(t0, a->rj); -+ gen_load_gpr(t1, a->rk); -+ tcg_gen_ext32u_i64(t0, t0); -+ tcg_gen_ext32u_i64(t1, t1); -+ tcg_gen_mul_i64(t2, t0, t1); -+ gen_store_gpr(t2, a->rd); -+ tcg_temp_free_i64(t0); -+ tcg_temp_free_i64(t1); -+ tcg_temp_free_i64(t2); -+ return true; -+} -+ -+static bool trans_div_w(DisasContext *ctx, arg_div_w *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_DIV_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mod_w(DisasContext *ctx, arg_mod_w *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MOD_W, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_div_wu(DisasContext *ctx, arg_div_wu *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_DIV_WU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mod_wu(DisasContext *ctx, arg_mod_wu *a) -+{ -+ gen_r6_muldiv(ctx, OPC_LARCH_MOD_WU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_div_d(DisasContext *ctx, arg_div_d *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_DIV_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mod_d(DisasContext *ctx, arg_mod_d *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MOD_D, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_div_du(DisasContext *ctx, arg_div_du *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_DIV_DU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+static bool trans_mod_du(DisasContext *ctx, arg_mod_du *a) -+{ -+ check_larch_64(ctx); -+ gen_r6_muldiv(ctx, OPC_LARCH_MOD_DU, a->rd, a->rj, a->rk); -+ return true; -+} -+ -+/* do not update CP0.BadVaddr */ -+static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d *a) -+{ -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_temp_new(); -+ gen_load_gpr(t1, a->rj); -+ gen_load_gpr(t2, a->rk); -+ gen_helper_asrtle_d(cpu_env, t1, t2); -+ tcg_temp_free(t1); -+ tcg_temp_free(t2); -+ return true; -+} -+ -+/* do not update CP0.BadVaddr */ -+static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d *a) -+{ -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_temp_new(); -+ gen_load_gpr(t1, a->rj); -+ gen_load_gpr(t2, a->rk); -+ gen_helper_asrtgt_d(cpu_env, t1, t2); -+ tcg_temp_free(t1); -+ tcg_temp_free(t2); -+ return true; -+} -+ -+#ifdef CONFIG_USER_ONLY -+static bool trans_gr2scr(DisasContext *ctx, arg_gr2scr *a) -+{ -+ return false; -+} -+ -+static bool trans_scr2gr(DisasContext *ctx, arg_scr2gr *a) -+{ -+ return false; -+} -+#else -+static bool trans_gr2scr(DisasContext *ctx, arg_gr2scr *a) -+{ -+ TCGv_i32 sd = tcg_const_i32(a->sd); -+ TCGv val = tcg_temp_new(); -+ check_lbt_enabled(ctx); -+ gen_load_gpr(val, a->rj); -+ gen_helper_store_scr(cpu_env, sd, val); -+ tcg_temp_free_i32(sd); -+ tcg_temp_free(val); -+ return true; -+} -+ -+static bool trans_scr2gr(DisasContext *ctx, arg_scr2gr *a) -+{ -+ if (a->rd == 0) { -+ /* Nop */ -+ return true; -+ } -+ -+ TCGv_i32 tsj = tcg_const_i32(a->sj); -+ check_lbt_enabled(ctx); -+ gen_helper_load_scr(cpu_gpr[a->rd], cpu_env, tsj); -+ tcg_temp_free_i32(tsj); -+ return true; -+} -+#endif -+ -+static bool trans_clo_w(DisasContext *ctx, arg_clo_w *a) -+{ -+ gen_cl(ctx, OPC_LARCH_CLO_W, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_clz_w(DisasContext *ctx, arg_clz_w *a) -+{ -+ gen_cl(ctx, OPC_LARCH_CLZ_W, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_cto_w(DisasContext *ctx, arg_cto_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ gen_helper_cto_w(cpu_gpr[a->rd], cpu_env, t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_ctz_w(DisasContext *ctx, arg_ctz_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ gen_helper_ctz_w(cpu_gpr[a->rd], cpu_env, t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_clo_d(DisasContext *ctx, arg_clo_d *a) -+{ -+ check_larch_64(ctx); -+ gen_cl(ctx, OPC_LARCH_CLO_D, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_clz_d(DisasContext *ctx, arg_clz_d *a) -+{ -+ check_larch_64(ctx); -+ gen_cl(ctx, OPC_LARCH_CLZ_D, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_cto_d(DisasContext *ctx, arg_cto_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ gen_helper_cto_d(cpu_gpr[a->rd], cpu_env, t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_ctz_d(DisasContext *ctx, arg_ctz_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, a->rj); -+ gen_helper_ctz_d(cpu_gpr[a->rd], cpu_env, t0); -+ -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_revb_2h(DisasContext *ctx, arg_revb_2h *a) -+{ -+ gen_bshfl(ctx, OPC_LARCH_REVB_2H, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revb_4h(DisasContext *ctx, arg_revb_4h *a) -+{ -+ check_larch_64(ctx); -+ gen_bshfl(ctx, OPC_LARCH_REVB_4H, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revb_2w(DisasContext *ctx, arg_revb_2w *a) -+{ -+ handle_rev32(ctx, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revb_d(DisasContext *ctx, arg_revb_d *a) -+{ -+ handle_rev64(ctx, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revh_2w(DisasContext *ctx, arg_revh_2w *a) -+{ -+ handle_rev16(ctx, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_revh_d(DisasContext *ctx, arg_revh_d *a) -+{ -+ check_larch_64(ctx); -+ gen_bshfl(ctx, OPC_LARCH_REVH_D, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_bitrev_4b(DisasContext *ctx, arg_bitrev_4b *a) -+{ -+ gen_bitswap(ctx, OPC_LARCH_BREV_4B, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_bitrev_8b(DisasContext *ctx, arg_bitrev_8b *a) -+{ -+ check_larch_64(ctx); -+ gen_bitswap(ctx, OPC_LARCH_BREV_8B, a->rd, a->rj); -+ return true; -+} -+ -+static bool trans_bitrev_w(DisasContext *ctx, arg_bitrev_w *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ gen_helper_bitrev_w(cpu_gpr[a->rd], cpu_env, t0); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_bitrev_d(DisasContext *ctx, arg_bitrev_d *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ gen_helper_bitrev_d(cpu_gpr[a->rd], cpu_env, t0); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_ext_w_h(DisasContext *ctx, arg_ext_w_h *a) -+{ -+ gen_bshfl(ctx, OPC_LARCH_EXT_WH, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_ext_w_b(DisasContext *ctx, arg_ext_w_b *a) -+{ -+ gen_bshfl(ctx, OPC_LARCH_EXT_WB, a->rj, a->rd); -+ return true; -+} -+ -+static bool trans_srli_w(DisasContext *ctx, arg_srli_w *a) -+{ -+ gen_shift_imm(ctx, OPC_LARCH_SRLI_W, a->rd, a->rj, a->ui5); -+ return true; -+} -+ -+static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a) -+{ -+ gen_shift_imm(ctx, OPC_LARCH_SRAI_W, a->rd, a->rj, a->ui5); -+ return true; -+} -+ -+static bool trans_srai_d(DisasContext *ctx, arg_srai_d *a) -+{ -+ TCGv t0; -+ check_larch_64(ctx); -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_sari_tl(cpu_gpr[a->rd], t0, a->ui6); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_rotri_w(DisasContext *ctx, arg_rotri_w *a) -+{ -+ gen_shift_imm(ctx, OPC_LARCH_ROTRI_W, a->rd, a->rj, a->ui5); -+ return true; -+} -+ -+static bool trans_rotri_d(DisasContext *ctx, arg_rotri_d *a) -+{ -+ TCGv t0; -+ check_larch_64(ctx); -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ tcg_gen_rotri_tl(cpu_gpr[a->rd], t0, a->ui6); -+ tcg_temp_free(t0); -+ return true; -+} -+ -+static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) -+{ -+ check_cp1_enabled(ctx); -+ gen_fcmp_s(ctx, a->fcond, a->fk, a->fj, a->cd); -+ return true; -+} -+ -+static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a) -+{ -+ check_cp1_enabled(ctx); -+ gen_fcmp_d(ctx, a->fcond, a->fk, a->fj, a->cd); -+ return true; -+} -+ -+static bool trans_fsel(DisasContext *ctx, arg_fsel *a) -+{ -+ TCGv_i64 fj = tcg_temp_new_i64(); -+ TCGv_i64 fk = tcg_temp_new_i64(); -+ TCGv_i64 fd = tcg_temp_new_i64(); -+ TCGv_i32 ca = tcg_const_i32(a->ca); -+ check_cp1_enabled(ctx); -+ gen_load_fpr64(ctx, fj, a->fj); -+ gen_load_fpr64(ctx, fk, a->fk); -+ gen_helper_fsel(fd, cpu_env, fj, fk, ca); -+ gen_store_fpr64(ctx, fd, a->fd); -+ tcg_temp_free_i64(fj); -+ tcg_temp_free_i64(fk); -+ tcg_temp_free_i64(fd); -+ tcg_temp_free_i32(ca); -+ return true; -+} -+ -+#include "cpu-csr.h" -+ -+#ifdef CONFIG_USER_ONLY -+ -+static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) -+{ -+ return false; -+} -+ -+#else -+ -+#define GEN_CSRRQ_CASE(name) \ -+ do { \ -+ case LOONGARCH_CSR_##name: \ -+ gen_csr_rdq(ctx, cpu_gpr[rd], LOONGARCH_CSR_##name); \ -+ } while (0) -+ -+static bool trans_csrrd(DisasContext *ctx, unsigned rd, unsigned csr) -+{ -+ switch (csr) { -+ GEN_CSRRQ_CASE(CRMD); -+ break; -+ GEN_CSRRQ_CASE(PRMD); -+ break; -+ GEN_CSRRQ_CASE(EUEN); -+ break; -+ GEN_CSRRQ_CASE(MISC); -+ break; -+ GEN_CSRRQ_CASE(ECFG); -+ break; -+ GEN_CSRRQ_CASE(ESTAT); -+ break; -+ GEN_CSRRQ_CASE(ERA); -+ break; -+ GEN_CSRRQ_CASE(BADV); -+ break; -+ GEN_CSRRQ_CASE(BADI); -+ break; -+ GEN_CSRRQ_CASE(EEPN); -+ break; -+ GEN_CSRRQ_CASE(TLBIDX); -+ break; -+ GEN_CSRRQ_CASE(TLBEHI); -+ break; -+ GEN_CSRRQ_CASE(TLBELO0); -+ break; -+ GEN_CSRRQ_CASE(TLBELO1); -+ break; -+ GEN_CSRRQ_CASE(TLBWIRED); -+ break; -+ GEN_CSRRQ_CASE(GTLBC); -+ break; -+ GEN_CSRRQ_CASE(TRGP); -+ break; -+ GEN_CSRRQ_CASE(ASID); -+ break; -+ GEN_CSRRQ_CASE(PGDL); -+ break; -+ GEN_CSRRQ_CASE(PGDH); -+ break; -+ case LOONGARCH_CSR_PGD: -+ gen_helper_read_pgd(cpu_gpr[rd], cpu_env); -+ break; -+ GEN_CSRRQ_CASE(PWCTL0); -+ break; -+ GEN_CSRRQ_CASE(PWCTL1); -+ break; -+ GEN_CSRRQ_CASE(STLBPGSIZE); -+ break; -+ GEN_CSRRQ_CASE(RVACFG); -+ break; -+ GEN_CSRRQ_CASE(CPUID); -+ break; -+ GEN_CSRRQ_CASE(PRCFG1); -+ break; -+ GEN_CSRRQ_CASE(PRCFG2); -+ break; -+ GEN_CSRRQ_CASE(PRCFG3); -+ break; -+ GEN_CSRRQ_CASE(KS0); -+ break; -+ GEN_CSRRQ_CASE(KS1); -+ break; -+ GEN_CSRRQ_CASE(KS2); -+ break; -+ GEN_CSRRQ_CASE(KS3); -+ break; -+ GEN_CSRRQ_CASE(KS4); -+ break; -+ GEN_CSRRQ_CASE(KS5); -+ break; -+ GEN_CSRRQ_CASE(KS6); -+ break; -+ GEN_CSRRQ_CASE(KS7); -+ break; -+ GEN_CSRRQ_CASE(KS8); -+ break; -+ GEN_CSRRQ_CASE(TMID); -+ break; -+ GEN_CSRRQ_CASE(TCFG); -+ break; -+ GEN_CSRRQ_CASE(TVAL); -+ break; -+ GEN_CSRRQ_CASE(CNTC); -+ break; -+ GEN_CSRRQ_CASE(TINTCLR); -+ break; -+ GEN_CSRRQ_CASE(GSTAT); -+ break; -+ GEN_CSRRQ_CASE(GCFG); -+ break; -+ GEN_CSRRQ_CASE(GINTC); -+ break; -+ GEN_CSRRQ_CASE(GCNTC); -+ break; -+ GEN_CSRRQ_CASE(LLBCTL); -+ break; -+ GEN_CSRRQ_CASE(IMPCTL1); -+ break; -+ GEN_CSRRQ_CASE(IMPCTL2); -+ break; -+ GEN_CSRRQ_CASE(GNMI); -+ break; -+ GEN_CSRRQ_CASE(TLBRENT); -+ break; -+ GEN_CSRRQ_CASE(TLBRBADV); -+ break; -+ GEN_CSRRQ_CASE(TLBRERA); -+ break; -+ GEN_CSRRQ_CASE(TLBRSAVE); -+ break; -+ GEN_CSRRQ_CASE(TLBRELO0); -+ break; -+ GEN_CSRRQ_CASE(TLBRELO1); -+ break; -+ GEN_CSRRQ_CASE(TLBREHI); -+ break; -+ GEN_CSRRQ_CASE(TLBRPRMD); -+ break; -+ GEN_CSRRQ_CASE(ERRCTL); -+ break; -+ GEN_CSRRQ_CASE(ERRINFO); -+ break; -+ GEN_CSRRQ_CASE(ERRINFO1); -+ break; -+ GEN_CSRRQ_CASE(ERRENT); -+ break; -+ GEN_CSRRQ_CASE(ERRERA); -+ break; -+ GEN_CSRRQ_CASE(ERRSAVE); -+ break; -+ GEN_CSRRQ_CASE(CTAG); -+ break; -+ GEN_CSRRQ_CASE(DMWIN0); -+ break; -+ GEN_CSRRQ_CASE(DMWIN1); -+ break; -+ GEN_CSRRQ_CASE(DMWIN2); -+ break; -+ GEN_CSRRQ_CASE(DMWIN3); -+ break; -+ GEN_CSRRQ_CASE(PERFCTRL0); -+ break; -+ GEN_CSRRQ_CASE(PERFCNTR0); -+ break; -+ GEN_CSRRQ_CASE(PERFCTRL1); -+ break; -+ GEN_CSRRQ_CASE(PERFCNTR1); -+ break; -+ GEN_CSRRQ_CASE(PERFCTRL2); -+ break; -+ GEN_CSRRQ_CASE(PERFCNTR2); -+ break; -+ GEN_CSRRQ_CASE(PERFCTRL3); -+ break; -+ GEN_CSRRQ_CASE(PERFCNTR3); -+ break; -+ /* debug */ -+ GEN_CSRRQ_CASE(MWPC); -+ break; -+ GEN_CSRRQ_CASE(MWPS); -+ break; -+ GEN_CSRRQ_CASE(DB0ADDR); -+ break; -+ GEN_CSRRQ_CASE(DB0MASK); -+ break; -+ GEN_CSRRQ_CASE(DB0CTL); -+ break; -+ GEN_CSRRQ_CASE(DB0ASID); -+ break; -+ GEN_CSRRQ_CASE(DB1ADDR); -+ break; -+ GEN_CSRRQ_CASE(DB1MASK); -+ break; -+ GEN_CSRRQ_CASE(DB1CTL); -+ break; -+ GEN_CSRRQ_CASE(DB1ASID); -+ break; -+ GEN_CSRRQ_CASE(DB2ADDR); -+ break; -+ GEN_CSRRQ_CASE(DB2MASK); -+ break; -+ GEN_CSRRQ_CASE(DB2CTL); -+ break; -+ GEN_CSRRQ_CASE(DB2ASID); -+ break; -+ GEN_CSRRQ_CASE(DB3ADDR); -+ break; -+ GEN_CSRRQ_CASE(DB3MASK); -+ break; -+ GEN_CSRRQ_CASE(DB3CTL); -+ break; -+ GEN_CSRRQ_CASE(DB3ASID); -+ break; -+ GEN_CSRRQ_CASE(FWPC); -+ break; -+ GEN_CSRRQ_CASE(FWPS); -+ break; -+ GEN_CSRRQ_CASE(IB0ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB0MASK); -+ break; -+ GEN_CSRRQ_CASE(IB0CTL); -+ break; -+ GEN_CSRRQ_CASE(IB0ASID); -+ break; -+ GEN_CSRRQ_CASE(IB1ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB1MASK); -+ break; -+ GEN_CSRRQ_CASE(IB1CTL); -+ break; -+ GEN_CSRRQ_CASE(IB1ASID); -+ break; -+ GEN_CSRRQ_CASE(IB2ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB2MASK); -+ break; -+ GEN_CSRRQ_CASE(IB2CTL); -+ break; -+ GEN_CSRRQ_CASE(IB2ASID); -+ break; -+ GEN_CSRRQ_CASE(IB3ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB3MASK); -+ break; -+ GEN_CSRRQ_CASE(IB3CTL); -+ break; -+ GEN_CSRRQ_CASE(IB3ASID); -+ break; -+ GEN_CSRRQ_CASE(IB4ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB4MASK); -+ break; -+ GEN_CSRRQ_CASE(IB4CTL); -+ break; -+ GEN_CSRRQ_CASE(IB4ASID); -+ break; -+ GEN_CSRRQ_CASE(IB5ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB5MASK); -+ break; -+ GEN_CSRRQ_CASE(IB5CTL); -+ break; -+ GEN_CSRRQ_CASE(IB5ASID); -+ break; -+ GEN_CSRRQ_CASE(IB6ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB6MASK); -+ break; -+ GEN_CSRRQ_CASE(IB6CTL); -+ break; -+ GEN_CSRRQ_CASE(IB6ASID); -+ break; -+ GEN_CSRRQ_CASE(IB7ADDR); -+ break; -+ GEN_CSRRQ_CASE(IB7MASK); -+ break; -+ GEN_CSRRQ_CASE(IB7CTL); -+ break; -+ GEN_CSRRQ_CASE(IB7ASID); -+ break; -+ GEN_CSRRQ_CASE(DEBUG); -+ break; -+ GEN_CSRRQ_CASE(DERA); -+ break; -+ GEN_CSRRQ_CASE(DESAVE); -+ break; -+ default: -+ return false; -+ } -+ -+#undef GEN_CSRRQ_CASE -+ -+ return true; -+} -+ -+#define GEN_CSRWQ_CASE(name) \ -+ do { \ -+ case LOONGARCH_CSR_##name: \ -+ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_##name); \ -+ } while (0) -+ -+static bool trans_csrwr(DisasContext *ctx, unsigned rd, unsigned csr) -+{ -+ -+ switch (csr) { -+ case LOONGARCH_CSR_CRMD: -+ save_cpu_state(ctx, 1); -+ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_CRMD); -+ gen_save_pc(ctx->base.pc_next + 4); -+ ctx->base.is_jmp = DISAS_EXIT; -+ break; -+ GEN_CSRWQ_CASE(PRMD); -+ break; -+ case LOONGARCH_CSR_EUEN: -+ gen_csr_wrq(ctx, cpu_gpr[rd], LOONGARCH_CSR_EUEN); -+ /* Stop translation */ -+ gen_save_pc(ctx->base.pc_next + 4); -+ ctx->base.is_jmp = DISAS_EXIT; -+ break; -+ GEN_CSRWQ_CASE(MISC); -+ break; -+ GEN_CSRWQ_CASE(ECFG); -+ break; -+ GEN_CSRWQ_CASE(ESTAT); -+ break; -+ GEN_CSRWQ_CASE(ERA); -+ break; -+ GEN_CSRWQ_CASE(BADV); -+ break; -+ GEN_CSRWQ_CASE(BADI); -+ break; -+ GEN_CSRWQ_CASE(EEPN); -+ break; -+ GEN_CSRWQ_CASE(TLBIDX); -+ break; -+ GEN_CSRWQ_CASE(TLBEHI); -+ break; -+ GEN_CSRWQ_CASE(TLBELO0); -+ break; -+ GEN_CSRWQ_CASE(TLBELO1); -+ break; -+ GEN_CSRWQ_CASE(TLBWIRED); -+ break; -+ GEN_CSRWQ_CASE(GTLBC); -+ break; -+ GEN_CSRWQ_CASE(TRGP); -+ break; -+ GEN_CSRWQ_CASE(ASID); -+ break; -+ GEN_CSRWQ_CASE(PGDL); -+ break; -+ GEN_CSRWQ_CASE(PGDH); -+ break; -+ GEN_CSRWQ_CASE(PGD); -+ break; -+ GEN_CSRWQ_CASE(PWCTL0); -+ break; -+ GEN_CSRWQ_CASE(PWCTL1); -+ break; -+ GEN_CSRWQ_CASE(STLBPGSIZE); -+ break; -+ GEN_CSRWQ_CASE(RVACFG); -+ break; -+ GEN_CSRWQ_CASE(CPUID); -+ break; -+ GEN_CSRWQ_CASE(PRCFG1); -+ break; -+ GEN_CSRWQ_CASE(PRCFG2); -+ break; -+ GEN_CSRWQ_CASE(PRCFG3); -+ break; -+ GEN_CSRWQ_CASE(KS0); -+ break; -+ GEN_CSRWQ_CASE(KS1); -+ break; -+ GEN_CSRWQ_CASE(KS2); -+ break; -+ GEN_CSRWQ_CASE(KS3); -+ break; -+ GEN_CSRWQ_CASE(KS4); -+ break; -+ GEN_CSRWQ_CASE(KS5); -+ break; -+ GEN_CSRWQ_CASE(KS6); -+ break; -+ GEN_CSRWQ_CASE(KS7); -+ break; -+ GEN_CSRWQ_CASE(KS8); -+ break; -+ GEN_CSRWQ_CASE(TMID); -+ break; -+ GEN_CSRWQ_CASE(TCFG); -+ break; -+ GEN_CSRWQ_CASE(TVAL); -+ break; -+ GEN_CSRWQ_CASE(CNTC); -+ break; -+ GEN_CSRWQ_CASE(TINTCLR); -+ break; -+ GEN_CSRWQ_CASE(GSTAT); -+ break; -+ GEN_CSRWQ_CASE(GCFG); -+ break; -+ GEN_CSRWQ_CASE(GINTC); -+ break; -+ GEN_CSRWQ_CASE(GCNTC); -+ break; -+ GEN_CSRWQ_CASE(LLBCTL); -+ break; -+ GEN_CSRWQ_CASE(IMPCTL1); -+ break; -+ GEN_CSRWQ_CASE(IMPCTL2); -+ break; -+ GEN_CSRWQ_CASE(GNMI); -+ break; -+ GEN_CSRWQ_CASE(TLBRENT); -+ break; -+ GEN_CSRWQ_CASE(TLBRBADV); -+ break; -+ GEN_CSRWQ_CASE(TLBRERA); -+ break; -+ GEN_CSRWQ_CASE(TLBRSAVE); -+ break; -+ GEN_CSRWQ_CASE(TLBRELO0); -+ break; -+ GEN_CSRWQ_CASE(TLBRELO1); -+ break; -+ GEN_CSRWQ_CASE(TLBREHI); -+ break; -+ GEN_CSRWQ_CASE(TLBRPRMD); -+ break; -+ GEN_CSRWQ_CASE(ERRCTL); -+ break; -+ GEN_CSRWQ_CASE(ERRINFO); -+ break; -+ GEN_CSRWQ_CASE(ERRINFO1); -+ break; -+ GEN_CSRWQ_CASE(ERRENT); -+ break; -+ GEN_CSRWQ_CASE(ERRERA); -+ break; -+ GEN_CSRWQ_CASE(ERRSAVE); -+ break; -+ GEN_CSRWQ_CASE(CTAG); -+ break; -+ GEN_CSRWQ_CASE(DMWIN0); -+ break; -+ GEN_CSRWQ_CASE(DMWIN1); -+ break; -+ GEN_CSRWQ_CASE(DMWIN2); -+ break; -+ GEN_CSRWQ_CASE(DMWIN3); -+ break; -+ GEN_CSRWQ_CASE(PERFCTRL0); -+ break; -+ GEN_CSRWQ_CASE(PERFCNTR0); -+ break; -+ GEN_CSRWQ_CASE(PERFCTRL1); -+ break; -+ GEN_CSRWQ_CASE(PERFCNTR1); -+ break; -+ GEN_CSRWQ_CASE(PERFCTRL2); -+ break; -+ GEN_CSRWQ_CASE(PERFCNTR2); -+ break; -+ GEN_CSRWQ_CASE(PERFCTRL3); -+ break; -+ GEN_CSRWQ_CASE(PERFCNTR3); -+ break; -+ /* debug */ -+ GEN_CSRWQ_CASE(MWPC); -+ break; -+ GEN_CSRWQ_CASE(MWPS); -+ break; -+ GEN_CSRWQ_CASE(DB0ADDR); -+ break; -+ GEN_CSRWQ_CASE(DB0MASK); -+ break; -+ GEN_CSRWQ_CASE(DB0CTL); -+ break; -+ GEN_CSRWQ_CASE(DB0ASID); -+ break; -+ GEN_CSRWQ_CASE(DB1ADDR); -+ break; -+ GEN_CSRWQ_CASE(DB1MASK); -+ break; -+ GEN_CSRWQ_CASE(DB1CTL); -+ break; -+ GEN_CSRWQ_CASE(DB1ASID); -+ break; -+ GEN_CSRWQ_CASE(DB2ADDR); -+ break; -+ GEN_CSRWQ_CASE(DB2MASK); -+ break; -+ GEN_CSRWQ_CASE(DB2CTL); -+ break; -+ GEN_CSRWQ_CASE(DB2ASID); -+ break; -+ GEN_CSRWQ_CASE(DB3ADDR); -+ break; -+ GEN_CSRWQ_CASE(DB3MASK); -+ break; -+ GEN_CSRWQ_CASE(DB3CTL); -+ break; -+ GEN_CSRWQ_CASE(DB3ASID); -+ break; -+ GEN_CSRWQ_CASE(FWPC); -+ break; -+ GEN_CSRWQ_CASE(FWPS); -+ break; -+ GEN_CSRWQ_CASE(IB0ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB0MASK); -+ break; -+ GEN_CSRWQ_CASE(IB0CTL); -+ break; -+ GEN_CSRWQ_CASE(IB0ASID); -+ break; -+ GEN_CSRWQ_CASE(IB1ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB1MASK); -+ break; -+ GEN_CSRWQ_CASE(IB1CTL); -+ break; -+ GEN_CSRWQ_CASE(IB1ASID); -+ break; -+ GEN_CSRWQ_CASE(IB2ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB2MASK); -+ break; -+ GEN_CSRWQ_CASE(IB2CTL); -+ break; -+ GEN_CSRWQ_CASE(IB2ASID); -+ break; -+ GEN_CSRWQ_CASE(IB3ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB3MASK); -+ break; -+ GEN_CSRWQ_CASE(IB3CTL); -+ break; -+ GEN_CSRWQ_CASE(IB3ASID); -+ break; -+ GEN_CSRWQ_CASE(IB4ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB4MASK); -+ break; -+ GEN_CSRWQ_CASE(IB4CTL); -+ break; -+ GEN_CSRWQ_CASE(IB4ASID); -+ break; -+ GEN_CSRWQ_CASE(IB5ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB5MASK); -+ break; -+ GEN_CSRWQ_CASE(IB5CTL); -+ break; -+ GEN_CSRWQ_CASE(IB5ASID); -+ break; -+ GEN_CSRWQ_CASE(IB6ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB6MASK); -+ break; -+ GEN_CSRWQ_CASE(IB6CTL); -+ break; -+ GEN_CSRWQ_CASE(IB6ASID); -+ break; -+ GEN_CSRWQ_CASE(IB7ADDR); -+ break; -+ GEN_CSRWQ_CASE(IB7MASK); -+ break; -+ GEN_CSRWQ_CASE(IB7CTL); -+ break; -+ GEN_CSRWQ_CASE(IB7ASID); -+ break; -+ GEN_CSRWQ_CASE(DEBUG); -+ break; -+ GEN_CSRWQ_CASE(DERA); -+ break; -+ GEN_CSRWQ_CASE(DESAVE); -+ break; -+ default: -+ return false; -+ } -+ -+#undef GEN_CSRWQ_CASE -+ -+ return true; -+} -+ -+#define GEN_CSRXQ_CASE(name) \ -+ do { \ -+ case LOONGARCH_CSR_##name: \ -+ if (rd == 0) { \ -+ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_##name); \ -+ } else { \ -+ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], \ -+ LOONGARCH_CSR_##name); \ -+ } \ -+ } while (0) -+ -+static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) -+{ -+ unsigned rd, rj, csr; -+ TCGv zero = tcg_const_tl(0); -+ rd = a->rd; -+ rj = a->rj; -+ csr = a->csr; -+ -+ if (rj == 0) { -+ return trans_csrrd(ctx, rd, csr); -+ } else if (rj == 1) { -+ return trans_csrwr(ctx, rd, csr); -+ } -+ -+ switch (csr) { -+ case LOONGARCH_CSR_CRMD: -+ save_cpu_state(ctx, 1); -+ if (rd == 0) { -+ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_CRMD); -+ } else { -+ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], LOONGARCH_CSR_CRMD); -+ } -+ gen_save_pc(ctx->base.pc_next + 4); -+ ctx->base.is_jmp = DISAS_EXIT; -+ break; -+ -+ GEN_CSRXQ_CASE(PRMD); -+ break; -+ case LOONGARCH_CSR_EUEN: -+ if (rd == 0) { -+ gen_csr_xchgq(ctx, zero, cpu_gpr[rj], LOONGARCH_CSR_EUEN); -+ } else { -+ gen_csr_xchgq(ctx, cpu_gpr[rd], cpu_gpr[rj], LOONGARCH_CSR_EUEN); -+ } -+ /* Stop translation */ -+ gen_save_pc(ctx->base.pc_next + 4); -+ ctx->base.is_jmp = DISAS_EXIT; -+ break; -+ GEN_CSRXQ_CASE(MISC); -+ break; -+ GEN_CSRXQ_CASE(ECFG); -+ break; -+ GEN_CSRXQ_CASE(ESTAT); -+ break; -+ GEN_CSRXQ_CASE(ERA); -+ break; -+ GEN_CSRXQ_CASE(BADV); -+ break; -+ GEN_CSRXQ_CASE(BADI); -+ break; -+ GEN_CSRXQ_CASE(EEPN); -+ break; -+ GEN_CSRXQ_CASE(TLBIDX); -+ break; -+ GEN_CSRXQ_CASE(TLBEHI); -+ break; -+ GEN_CSRXQ_CASE(TLBELO0); -+ break; -+ GEN_CSRXQ_CASE(TLBELO1); -+ break; -+ GEN_CSRXQ_CASE(TLBWIRED); -+ break; -+ GEN_CSRXQ_CASE(GTLBC); -+ break; -+ GEN_CSRXQ_CASE(TRGP); -+ break; -+ GEN_CSRXQ_CASE(ASID); -+ break; -+ GEN_CSRXQ_CASE(PGDL); -+ break; -+ GEN_CSRXQ_CASE(PGDH); -+ break; -+ GEN_CSRXQ_CASE(PGD); -+ break; -+ GEN_CSRXQ_CASE(PWCTL0); -+ break; -+ GEN_CSRXQ_CASE(PWCTL1); -+ break; -+ GEN_CSRXQ_CASE(STLBPGSIZE); -+ break; -+ GEN_CSRXQ_CASE(RVACFG); -+ break; -+ GEN_CSRXQ_CASE(CPUID); -+ break; -+ GEN_CSRXQ_CASE(PRCFG1); -+ break; -+ GEN_CSRXQ_CASE(PRCFG2); -+ break; -+ GEN_CSRXQ_CASE(PRCFG3); -+ break; -+ GEN_CSRXQ_CASE(KS0); -+ break; -+ GEN_CSRXQ_CASE(KS1); -+ break; -+ GEN_CSRXQ_CASE(KS2); -+ break; -+ GEN_CSRXQ_CASE(KS3); -+ break; -+ GEN_CSRXQ_CASE(KS4); -+ break; -+ GEN_CSRXQ_CASE(KS5); -+ break; -+ GEN_CSRXQ_CASE(KS6); -+ break; -+ GEN_CSRXQ_CASE(KS7); -+ break; -+ GEN_CSRXQ_CASE(KS8); -+ break; -+ GEN_CSRXQ_CASE(TMID); -+ break; -+ GEN_CSRXQ_CASE(TCFG); -+ break; -+ GEN_CSRXQ_CASE(TVAL); -+ break; -+ GEN_CSRXQ_CASE(CNTC); -+ break; -+ GEN_CSRXQ_CASE(TINTCLR); -+ break; -+ GEN_CSRXQ_CASE(GSTAT); -+ break; -+ GEN_CSRXQ_CASE(GCFG); -+ break; -+ GEN_CSRXQ_CASE(GINTC); -+ break; -+ GEN_CSRXQ_CASE(GCNTC); -+ break; -+ GEN_CSRXQ_CASE(LLBCTL); -+ break; -+ GEN_CSRXQ_CASE(IMPCTL1); -+ break; -+ GEN_CSRXQ_CASE(IMPCTL2); -+ break; -+ GEN_CSRXQ_CASE(GNMI); -+ break; -+ GEN_CSRXQ_CASE(TLBRENT); -+ break; -+ GEN_CSRXQ_CASE(TLBRBADV); -+ break; -+ GEN_CSRXQ_CASE(TLBRERA); -+ break; -+ GEN_CSRXQ_CASE(TLBRSAVE); -+ break; -+ GEN_CSRXQ_CASE(TLBRELO0); -+ break; -+ GEN_CSRXQ_CASE(TLBRELO1); -+ break; -+ GEN_CSRXQ_CASE(TLBREHI); -+ break; -+ GEN_CSRXQ_CASE(TLBRPRMD); -+ break; -+ GEN_CSRXQ_CASE(ERRCTL); -+ break; -+ GEN_CSRXQ_CASE(ERRINFO); -+ break; -+ GEN_CSRXQ_CASE(ERRINFO1); -+ break; -+ GEN_CSRXQ_CASE(ERRENT); -+ break; -+ GEN_CSRXQ_CASE(ERRERA); -+ break; -+ GEN_CSRXQ_CASE(ERRSAVE); -+ break; -+ GEN_CSRXQ_CASE(CTAG); -+ break; -+ GEN_CSRXQ_CASE(DMWIN0); -+ break; -+ GEN_CSRXQ_CASE(DMWIN1); -+ break; -+ GEN_CSRXQ_CASE(DMWIN2); -+ break; -+ GEN_CSRXQ_CASE(DMWIN3); -+ break; -+ GEN_CSRXQ_CASE(PERFCTRL0); -+ break; -+ GEN_CSRXQ_CASE(PERFCNTR0); -+ break; -+ GEN_CSRXQ_CASE(PERFCTRL1); -+ break; -+ GEN_CSRXQ_CASE(PERFCNTR1); -+ break; -+ GEN_CSRXQ_CASE(PERFCTRL2); -+ break; -+ GEN_CSRXQ_CASE(PERFCNTR2); -+ break; -+ GEN_CSRXQ_CASE(PERFCTRL3); -+ break; -+ GEN_CSRXQ_CASE(PERFCNTR3); -+ break; -+ /* debug */ -+ GEN_CSRXQ_CASE(MWPC); -+ break; -+ GEN_CSRXQ_CASE(MWPS); -+ break; -+ GEN_CSRXQ_CASE(DB0ADDR); -+ break; -+ GEN_CSRXQ_CASE(DB0MASK); -+ break; -+ GEN_CSRXQ_CASE(DB0CTL); -+ break; -+ GEN_CSRXQ_CASE(DB0ASID); -+ break; -+ GEN_CSRXQ_CASE(DB1ADDR); -+ break; -+ GEN_CSRXQ_CASE(DB1MASK); -+ break; -+ GEN_CSRXQ_CASE(DB1CTL); -+ break; -+ GEN_CSRXQ_CASE(DB1ASID); -+ break; -+ GEN_CSRXQ_CASE(DB2ADDR); -+ break; -+ GEN_CSRXQ_CASE(DB2MASK); -+ break; -+ GEN_CSRXQ_CASE(DB2CTL); -+ break; -+ GEN_CSRXQ_CASE(DB2ASID); -+ break; -+ GEN_CSRXQ_CASE(DB3ADDR); -+ break; -+ GEN_CSRXQ_CASE(DB3MASK); -+ break; -+ GEN_CSRXQ_CASE(DB3CTL); -+ break; -+ GEN_CSRXQ_CASE(DB3ASID); -+ break; -+ GEN_CSRXQ_CASE(FWPC); -+ break; -+ GEN_CSRXQ_CASE(FWPS); -+ break; -+ GEN_CSRXQ_CASE(IB0ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB0MASK); -+ break; -+ GEN_CSRXQ_CASE(IB0CTL); -+ break; -+ GEN_CSRXQ_CASE(IB0ASID); -+ break; -+ GEN_CSRXQ_CASE(IB1ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB1MASK); -+ break; -+ GEN_CSRXQ_CASE(IB1CTL); -+ break; -+ GEN_CSRXQ_CASE(IB1ASID); -+ break; -+ GEN_CSRXQ_CASE(IB2ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB2MASK); -+ break; -+ GEN_CSRXQ_CASE(IB2CTL); -+ break; -+ GEN_CSRXQ_CASE(IB2ASID); -+ break; -+ GEN_CSRXQ_CASE(IB3ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB3MASK); -+ break; -+ GEN_CSRXQ_CASE(IB3CTL); -+ break; -+ GEN_CSRXQ_CASE(IB3ASID); -+ break; -+ GEN_CSRXQ_CASE(IB4ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB4MASK); -+ break; -+ GEN_CSRXQ_CASE(IB4CTL); -+ break; -+ GEN_CSRXQ_CASE(IB4ASID); -+ break; -+ GEN_CSRXQ_CASE(IB5ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB5MASK); -+ break; -+ GEN_CSRXQ_CASE(IB5CTL); -+ break; -+ GEN_CSRXQ_CASE(IB5ASID); -+ break; -+ GEN_CSRXQ_CASE(IB6ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB6MASK); -+ break; -+ GEN_CSRXQ_CASE(IB6CTL); -+ break; -+ GEN_CSRXQ_CASE(IB6ASID); -+ break; -+ GEN_CSRXQ_CASE(IB7ADDR); -+ break; -+ GEN_CSRXQ_CASE(IB7MASK); -+ break; -+ GEN_CSRXQ_CASE(IB7CTL); -+ break; -+ GEN_CSRXQ_CASE(IB7ASID); -+ break; -+ GEN_CSRXQ_CASE(DEBUG); -+ break; -+ GEN_CSRXQ_CASE(DERA); -+ break; -+ GEN_CSRXQ_CASE(DESAVE); -+ break; -+ default: -+ return false; -+ } -+ -+#undef GEN_CSRXQ_CASE -+ tcg_temp_free(zero); -+ return true; -+} -+ -+#endif -+ -+static bool trans_cacop(DisasContext *ctx, arg_cacop *a) -+{ -+ /* Treat as NOP. */ -+ return true; -+} -+ -+#ifdef CONFIG_USER_ONLY -+ -+static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a) -+{ -+ return false; -+} -+ -+static bool trans_lddir(DisasContext *ctx, arg_lddir *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_b(DisasContext *ctx, arg_iocsrwr_b *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_h(DisasContext *ctx, arg_iocsrwr_h *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_w(DisasContext *ctx, arg_iocsrwr_w *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a) -+{ -+ return false; -+} -+#else -+ -+static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a) -+{ -+ TCGv t0, t1; -+ TCGv_i32 t2; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->seq); -+ t2 = tcg_const_i32(ctx->mem_idx); -+ gen_helper_ldpte(cpu_env, t0, t1, t2); -+ -+ return true; -+} -+ -+static bool trans_lddir(DisasContext *ctx, arg_lddir *a) -+{ -+ TCGv t0, t1, t2; -+ TCGv_i32 t3; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ t2 = tcg_const_tl(a->level); -+ t3 = tcg_const_i32(ctx->mem_idx); -+ gen_helper_lddir(cpu_env, t0, t1, t2, t3); -+ -+ return true; -+} -+ -+static bool trans_iocsrrd_b(DisasContext *ctx, arg_iocsrrd_b *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_h(DisasContext *ctx, arg_iocsrrd_h *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrrd_w(DisasContext *ctx, arg_iocsrrd_w *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_LD_W); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+ -+static bool trans_iocsrrd_d(DisasContext *ctx, arg_iocsrrd_d *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_LD_D); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+ -+static bool trans_iocsrwr_b(DisasContext *ctx, arg_iocsrwr_b *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_B); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+ -+static bool trans_iocsrwr_h(DisasContext *ctx, arg_iocsrwr_h *a) -+{ -+ return false; -+} -+ -+static bool trans_iocsrwr_w(DisasContext *ctx, arg_iocsrwr_w *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_W); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+ -+static bool trans_iocsrwr_d(DisasContext *ctx, arg_iocsrwr_d *a) -+{ -+ TCGv_i32 iocsr_op = tcg_const_i32(OPC_LARCH_ST_D); -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rj); -+ t1 = tcg_const_tl(a->rd); -+ gen_helper_iocsr(cpu_env, t0, t1, iocsr_op); -+ return true; -+} -+#endif /* !CONFIG_USER_ONLY */ -+ -+#ifdef CONFIG_USER_ONLY -+ -+#define GEN_FALSE_TRANS(name) \ -+ static bool trans_##name(DisasContext *ctx, arg_##name *a) \ -+ { \ -+ return false; \ -+ } -+ -+GEN_FALSE_TRANS(tlbclr) -+GEN_FALSE_TRANS(invtlb) -+GEN_FALSE_TRANS(tlbflush) -+GEN_FALSE_TRANS(tlbsrch) -+GEN_FALSE_TRANS(tlbrd) -+GEN_FALSE_TRANS(tlbwr) -+GEN_FALSE_TRANS(tlbfill) -+GEN_FALSE_TRANS(ertn) -+ -+#else -+ -+static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a) -+{ -+ gen_helper_tlbclr(cpu_env); -+ return true; -+} -+ -+static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a) -+{ -+ gen_helper_tlbflush(cpu_env); -+ return true; -+} -+ -+static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a) -+{ -+ TCGv addr = tcg_temp_new(); -+ TCGv info = tcg_temp_new(); -+ TCGv op = tcg_const_tl(a->invop); -+ -+ gen_load_gpr(addr, a->addr); -+ gen_load_gpr(info, a->info); -+ gen_helper_invtlb(cpu_env, addr, info, op); -+ -+ tcg_temp_free(addr); -+ tcg_temp_free(info); -+ tcg_temp_free(op); -+ return true; -+} -+ -+static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a) -+{ -+ gen_helper_tlbsrch(cpu_env); -+ return true; -+} -+ -+static bool trans_tlbrd(DisasContext *ctx, arg_tlbrd *a) -+{ -+ gen_helper_tlbrd(cpu_env); -+ return true; -+} -+ -+static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a) -+{ -+ gen_helper_tlbwr(cpu_env); -+ return true; -+} -+ -+static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a) -+{ -+ gen_helper_tlbfill(cpu_env); -+ return true; -+} -+ -+static bool trans_ertn(DisasContext *ctx, arg_ertn *a) -+{ -+ gen_helper_ertn(cpu_env); -+ ctx->base.is_jmp = DISAS_EXIT; -+ return true; -+} -+ -+#endif /* CONFIG_USER_ONLY */ -+ -+static bool trans_idle(DisasContext *ctx, arg_idle *a) -+{ -+ ctx->base.pc_next += 4; -+ save_cpu_state(ctx, 1); -+ ctx->base.pc_next -= 4; -+ gen_helper_idle(cpu_env); -+ ctx->base.is_jmp = DISAS_NORETURN; -+ return true; -+} -+ -+#ifdef CONFIG_USER_ONLY -+ -+static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) -+{ -+ /* Nop */ -+ return true; -+} -+ -+#else -+ -+static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) -+{ -+ TCGv t0, t1; -+ t0 = tcg_const_tl(a->rd); -+ t1 = tcg_const_tl(a->rj); -+ gen_helper_drdtime(cpu_env, t0, t1); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return true; -+} -+ -+#endif -+ -+static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a) -+{ -+ TCGv t0 = tcg_temp_new(); -+ gen_load_gpr(t0, a->rj); -+ gen_helper_cpucfg(cpu_gpr[a->rd], cpu_env, t0); -+ tcg_temp_free(t0); -+ return true; -+} -diff --git a/target/loongarch64/translate.c b/target/loongarch64/translate.c -new file mode 100644 -index 0000000000..2c65e4826a ---- /dev/null -+++ b/target/loongarch64/translate.c -@@ -0,0 +1,2705 @@ -+/* -+ * LOONGARCH emulation for QEMU - main translation routines -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "internal.h" -+#include "disas/disas.h" -+#include "exec/exec-all.h" -+#include "tcg/tcg-op.h" -+#include "exec/cpu_ldst.h" -+#include "hw/loongarch/cpudevs.h" -+ -+#include "exec/helper-proto.h" -+#include "exec/helper-gen.h" -+#include "semihosting/semihost.h" -+ -+#include "trace-tcg.h" -+#include "exec/translator.h" -+#include "exec/log.h" -+ -+#include "instmap.h" -+ -+#define LARCH_DEBUG_DISAS 0 -+ -+/* Values for the fmt field in FP instructions */ -+enum { -+ /* 0 - 15 are reserved */ -+ FMT_S = 16, /* single fp */ -+ FMT_D = 17, /* double fp */ -+}; -+ -+/* global register indices */ -+static TCGv cpu_gpr[32], cpu_PC; -+static TCGv btarget, bcond; -+static TCGv cpu_lladdr, cpu_llval; -+static TCGv_i32 hflags; -+static TCGv_i32 fpu_fcsr0; -+static TCGv_i64 fpu_f64[32]; -+ -+#include "exec/gen-icount.h" -+ -+#define gen_helper_0e0i(name, arg) \ -+ do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg); \ -+ gen_helper_##name(cpu_env, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_0e1i(name, arg1, arg2) \ -+ do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ -+ gen_helper_##name(cpu_env, arg1, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_1e0i(name, ret, arg1) \ -+ do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg1); \ -+ gen_helper_##name(ret, cpu_env, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_1e1i(name, ret, arg1, arg2) \ -+ do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg2); \ -+ gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_0e2i(name, arg1, arg2, arg3) \ -+ do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ -+ gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) \ -+ do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg3); \ -+ gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) \ -+ do { \ -+ TCGv_i32 helper_tmp = tcg_const_i32(arg4); \ -+ gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \ -+ tcg_temp_free_i32(helper_tmp); \ -+ } while (0) -+ -+typedef struct DisasContext { -+ DisasContextBase base; -+ target_ulong saved_pc; -+ target_ulong page_start; -+ uint32_t opcode; -+ uint64_t insn_flags; -+ /* Routine used to access memory */ -+ int mem_idx; -+ MemOp default_tcg_memop_mask; -+ uint32_t hflags, saved_hflags; -+ target_ulong btarget; -+} DisasContext; -+ -+#define DISAS_STOP DISAS_TARGET_0 -+#define DISAS_EXIT DISAS_TARGET_1 -+ -+#define LOG_DISAS(...) \ -+ do { \ -+ if (LARCH_DEBUG_DISAS) { \ -+ qemu_log_mask(CPU_LOG_TB_IN_ASM, ##__VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+#define LARCH_INVAL(op) \ -+ do { \ -+ if (LARCH_DEBUG_DISAS) { \ -+ qemu_log_mask(CPU_LOG_TB_IN_ASM, \ -+ TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \ -+ ctx->base.pc_next, ctx->opcode, op, \ -+ ctx->opcode >> 26, ctx->opcode & 0x3F, \ -+ ((ctx->opcode >> 16) & 0x1F)); \ -+ } \ -+ } while (0) -+ -+/* General purpose registers moves. */ -+static inline void gen_load_gpr(TCGv t, int reg) -+{ -+ if (reg == 0) { -+ tcg_gen_movi_tl(t, 0); -+ } else { -+ tcg_gen_mov_tl(t, cpu_gpr[reg]); -+ } -+} -+ -+static inline void gen_store_gpr(TCGv t, int reg) -+{ -+ if (reg != 0) { -+ tcg_gen_mov_tl(cpu_gpr[reg], t); -+ } -+} -+ -+/* Moves to/from shadow registers. */ -+/* Tests */ -+static inline void gen_save_pc(target_ulong pc) -+{ -+ tcg_gen_movi_tl(cpu_PC, pc); -+} -+ -+static inline void save_cpu_state(DisasContext *ctx, int do_save_pc) -+{ -+ LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags); -+ if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) { -+ gen_save_pc(ctx->base.pc_next); -+ ctx->saved_pc = ctx->base.pc_next; -+ } -+ if (ctx->hflags != ctx->saved_hflags) { -+ tcg_gen_movi_i32(hflags, ctx->hflags); -+ ctx->saved_hflags = ctx->hflags; -+ switch (ctx->hflags & LARCH_HFLAG_BMASK) { -+ case LARCH_HFLAG_BR: -+ break; -+ case LARCH_HFLAG_BC: -+ case LARCH_HFLAG_B: -+ tcg_gen_movi_tl(btarget, ctx->btarget); -+ break; -+ } -+ } -+} -+ -+static inline void restore_cpu_state(CPULOONGARCHState *env, DisasContext *ctx) -+{ -+ ctx->saved_hflags = ctx->hflags; -+ switch (ctx->hflags & LARCH_HFLAG_BMASK) { -+ case LARCH_HFLAG_BR: -+ break; -+ case LARCH_HFLAG_BC: -+ case LARCH_HFLAG_B: -+ ctx->btarget = env->btarget; -+ break; -+ } -+} -+ -+static inline void generate_exception_err(DisasContext *ctx, int excp, int err) -+{ -+ TCGv_i32 texcp = tcg_const_i32(excp); -+ TCGv_i32 terr = tcg_const_i32(err); -+ save_cpu_state(ctx, 1); -+ gen_helper_raise_exception_err(cpu_env, texcp, terr); -+ tcg_temp_free_i32(terr); -+ tcg_temp_free_i32(texcp); -+ ctx->base.is_jmp = DISAS_NORETURN; -+} -+ -+static inline void generate_exception_end(DisasContext *ctx, int excp) -+{ -+ generate_exception_err(ctx, excp, 0); -+} -+ -+/* Floating point register moves. */ -+static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) -+{ -+ tcg_gen_extrl_i64_i32(t, fpu_f64[reg]); -+} -+ -+static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg) -+{ -+ TCGv_i64 t64; -+ t64 = tcg_temp_new_i64(); -+ tcg_gen_extu_i32_i64(t64, t); -+ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32); -+ tcg_temp_free_i64(t64); -+} -+ -+static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) -+{ -+ tcg_gen_extrh_i64_i32(t, fpu_f64[reg]); -+} -+ -+static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg) -+{ -+ TCGv_i64 t64 = tcg_temp_new_i64(); -+ tcg_gen_extu_i32_i64(t64, t); -+ tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32); -+ tcg_temp_free_i64(t64); -+} -+ -+static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) -+{ -+ tcg_gen_mov_i64(t, fpu_f64[reg]); -+} -+ -+static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg) -+{ -+ tcg_gen_mov_i64(fpu_f64[reg], t); -+} -+ -+static inline int get_fp_bit(int cc) -+{ -+ if (cc) { -+ return 24 + cc; -+ } else { -+ return 23; -+ } -+} -+ -+/* Addresses computation */ -+static inline void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, -+ TCGv arg1) -+{ -+ tcg_gen_add_tl(ret, arg0, arg1); -+ -+ if (ctx->hflags & LARCH_HFLAG_AWRAP) { -+ tcg_gen_ext32s_i64(ret, ret); -+ } -+} -+ -+static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, -+ target_long ofs) -+{ -+ tcg_gen_addi_tl(ret, base, ofs); -+ -+ if (ctx->hflags & LARCH_HFLAG_AWRAP) { -+ tcg_gen_ext32s_i64(ret, ret); -+ } -+} -+ -+/* Sign-extract the low 32-bits to a target_long. */ -+static inline void gen_move_low32(TCGv ret, TCGv_i64 arg) -+{ -+ tcg_gen_ext32s_i64(ret, arg); -+} -+ -+/* Sign-extract the high 32-bits to a target_long. */ -+static inline void gen_move_high32(TCGv ret, TCGv_i64 arg) -+{ -+ tcg_gen_sari_i64(ret, arg, 32); -+} -+ -+static inline void check_cp1_enabled(DisasContext *ctx) -+{ -+#ifndef CONFIG_USER_ONLY -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_FPU))) { -+ generate_exception_err(ctx, EXCP_FPDIS, 1); -+ } -+#endif -+} -+ -+static inline void check_lsx_enabled(DisasContext *ctx) -+{ -+#ifndef CONFIG_USER_ONLY -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LSX))) { -+ generate_exception_err(ctx, EXCP_LSXDIS, 1); -+ } -+#endif -+} -+ -+static inline void check_lasx_enabled(DisasContext *ctx) -+{ -+#ifndef CONFIG_USER_ONLY -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LASX))) { -+ generate_exception_err(ctx, EXCP_LASXDIS, 1); -+ } -+#endif -+} -+ -+static inline void check_lbt_enabled(DisasContext *ctx) -+{ -+#ifndef CONFIG_USER_ONLY -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_LBT))) { -+ generate_exception_err(ctx, EXCP_BTDIS, 1); -+ } -+#endif -+} -+ -+/* -+ * This code generates a "reserved instruction" exception if the -+ * CPU does not support the instruction set corresponding to flags. -+ */ -+static inline void check_insn(DisasContext *ctx, uint64_t flags) -+{ -+ if (unlikely(!(ctx->insn_flags & flags))) { -+ generate_exception_end(ctx, EXCP_RI); -+ } -+} -+ -+/* -+ * This code generates a "reserved instruction" exception if the -+ * CPU has corresponding flag set which indicates that the instruction -+ * has been removed. -+ */ -+static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) -+{ -+ if (unlikely(ctx->insn_flags & flags)) { -+ generate_exception_end(ctx, EXCP_RI); -+ } -+} -+ -+/* -+ * The Linux kernel traps certain reserved instruction exceptions to -+ * emulate the corresponding instructions. QEMU is the kernel in user -+ * mode, so those traps are emulated by accepting the instructions. -+ * -+ * A reserved instruction exception is generated for flagged CPUs if -+ * QEMU runs in system mode. -+ */ -+static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) -+{ -+#ifndef CONFIG_USER_ONLY -+ check_insn_opc_removed(ctx, flags); -+#endif -+} -+ -+/* -+ * This code generates a "reserved instruction" exception if 64-bit -+ * instructions are not enabled. -+ */ -+static inline void check_larch_64(DisasContext *ctx) -+{ -+ if (unlikely(!(ctx->hflags & LARCH_HFLAG_64))) { -+ generate_exception_end(ctx, EXCP_RI); -+ } -+} -+ -+/* -+ * Define small wrappers for gen_load_fpr* so that we have a uniform -+ * calling interface for 32 and 64-bit FPRs. No sense in changing -+ * all callers for gen_load_fpr32 when we need the CTX parameter for -+ * this one use. -+ */ -+#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y) -+#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y) -+#define FCOP_CONDNS(fmt, ifmt, bits, STORE) \ -+ static inline void gen_fcmp_##fmt(DisasContext *ctx, int n, int ft, \ -+ int fs, int cd) \ -+ { \ -+ TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \ -+ TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \ -+ TCGv_i32 fcc = tcg_const_i32(cd); \ -+ check_cp1_enabled(ctx); \ -+ gen_ldcmp_fpr##bits(ctx, fp0, fs); \ -+ gen_ldcmp_fpr##bits(ctx, fp1, ft); \ -+ switch (n) { \ -+ case 0: \ -+ gen_helper_cmp_##fmt##_af(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 1: \ -+ gen_helper_cmp_##fmt##_saf(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 2: \ -+ gen_helper_cmp_##fmt##_lt(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 3: \ -+ gen_helper_cmp_##fmt##_slt(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 4: \ -+ gen_helper_cmp_##fmt##_eq(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 5: \ -+ gen_helper_cmp_##fmt##_seq(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 6: \ -+ gen_helper_cmp_##fmt##_le(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 7: \ -+ gen_helper_cmp_##fmt##_sle(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 8: \ -+ gen_helper_cmp_##fmt##_un(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 9: \ -+ gen_helper_cmp_##fmt##_sun(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 10: \ -+ gen_helper_cmp_##fmt##_ult(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 11: \ -+ gen_helper_cmp_##fmt##_sult(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 12: \ -+ gen_helper_cmp_##fmt##_ueq(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 13: \ -+ gen_helper_cmp_##fmt##_sueq(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 14: \ -+ gen_helper_cmp_##fmt##_ule(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 15: \ -+ gen_helper_cmp_##fmt##_sule(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 16: \ -+ gen_helper_cmp_##fmt##_ne(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 17: \ -+ gen_helper_cmp_##fmt##_sne(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 20: \ -+ gen_helper_cmp_##fmt##_or(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 21: \ -+ gen_helper_cmp_##fmt##_sor(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 24: \ -+ gen_helper_cmp_##fmt##_une(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ case 25: \ -+ gen_helper_cmp_##fmt##_sune(fp0, cpu_env, fp0, fp1); \ -+ break; \ -+ default: \ -+ abort(); \ -+ } \ -+ STORE; \ -+ tcg_temp_free_i##bits(fp0); \ -+ tcg_temp_free_i##bits(fp1); \ -+ tcg_temp_free_i32(fcc); \ -+ } -+ -+FCOP_CONDNS(d, FMT_D, 64, gen_helper_movreg2cf_i64(cpu_env, fcc, fp0)) -+FCOP_CONDNS(s, FMT_S, 32, gen_helper_movreg2cf_i32(cpu_env, fcc, fp0)) -+#undef FCOP_CONDNS -+#undef gen_ldcmp_fpr32 -+#undef gen_ldcmp_fpr64 -+ -+/* load/store instructions. */ -+#ifdef CONFIG_USER_ONLY -+#define OP_LD_ATOMIC(insn, fname) \ -+ static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ -+ DisasContext *ctx) \ -+ { \ -+ TCGv t0 = tcg_temp_new(); \ -+ tcg_gen_mov_tl(t0, arg1); \ -+ tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \ -+ tcg_gen_st_tl(t0, cpu_env, offsetof(CPULOONGARCHState, lladdr)); \ -+ tcg_gen_st_tl(ret, cpu_env, offsetof(CPULOONGARCHState, llval)); \ -+ tcg_temp_free(t0); \ -+ } -+#else -+#define OP_LD_ATOMIC(insn, fname) \ -+ static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \ -+ DisasContext *ctx) \ -+ { \ -+ gen_helper_1e1i(insn, ret, arg1, mem_idx); \ -+ } -+#endif -+ -+static void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, -+ int offset) -+{ -+ if (base == 0) { -+ tcg_gen_movi_tl(addr, offset); -+ } else if (offset == 0) { -+ gen_load_gpr(addr, base); -+ } else { -+ tcg_gen_movi_tl(addr, offset); -+ gen_op_addr_add(ctx, addr, cpu_gpr[base], addr); -+ } -+} -+ -+/* Load */ -+static void gen_ld(DisasContext *ctx, uint32_t opc, int rt, int base, -+ int offset) -+{ -+ TCGv t0; -+ int mem_idx = ctx->mem_idx; -+ -+ t0 = tcg_temp_new(); -+ gen_base_offset_addr(ctx, t0, base, offset); -+ -+ switch (opc) { -+ case OPC_LARCH_LD_WU: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, -+ MO_TEUL | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LDPTR_D: -+ case OPC_LARCH_LD_D: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, -+ MO_TEQ | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LL_D: -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LDPTR_W: -+ case OPC_LARCH_LD_W: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, -+ MO_TESL | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LD_H: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, -+ MO_TESW | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LD_HU: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, -+ MO_TEUW | ctx->default_tcg_memop_mask); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LD_B: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LD_BU: -+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_LL_W: -+ gen_store_gpr(t0, rt); -+ break; -+ } -+ -+ tcg_temp_free(t0); -+} -+ -+/* Store */ -+static void gen_st(DisasContext *ctx, uint32_t opc, int rt, int base, -+ int offset) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ int mem_idx = ctx->mem_idx; -+ -+ gen_base_offset_addr(ctx, t0, base, offset); -+ gen_load_gpr(t1, rt); -+ -+ switch (opc) { -+ case OPC_LARCH_STPTR_D: -+ case OPC_LARCH_ST_D: -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, -+ MO_TEQ | ctx->default_tcg_memop_mask); -+ break; -+ case OPC_LARCH_STPTR_W: -+ case OPC_LARCH_ST_W: -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, -+ MO_TEUL | ctx->default_tcg_memop_mask); -+ break; -+ case OPC_LARCH_ST_H: -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, -+ MO_TEUW | ctx->default_tcg_memop_mask); -+ break; -+ case OPC_LARCH_ST_B: -+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8); -+ break; -+ } -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+/* Store conditional */ -+static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, -+ MemOp tcg_mo, bool eva) -+{ -+ TCGv addr, t0, val; -+ TCGLabel *l1 = gen_new_label(); -+ TCGLabel *done = gen_new_label(); -+ -+ t0 = tcg_temp_new(); -+ addr = tcg_temp_new(); -+ /* compare the address against that of the preceeding LL */ -+ gen_base_offset_addr(ctx, addr, base, offset); -+ tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); -+ tcg_temp_free(addr); -+ tcg_gen_movi_tl(t0, 0); -+ gen_store_gpr(t0, rt); -+ tcg_gen_br(done); -+ -+ gen_set_label(l1); -+ /* generate cmpxchg */ -+ val = tcg_temp_new(); -+ gen_load_gpr(val, rt); -+ tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, -+ eva ? LARCH_HFLAG_UM : ctx->mem_idx, tcg_mo); -+ tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); -+ gen_store_gpr(t0, rt); -+ tcg_temp_free(val); -+ -+ gen_set_label(done); -+ tcg_temp_free(t0); -+} -+ -+/* Load and store */ -+static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft, TCGv t0) -+{ -+ /* -+ * Don't do NOP if destination is zero: we must perform the actual -+ * memory access. -+ */ -+ switch (opc) { -+ case OPC_LARCH_FLD_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, -+ MO_TESL | ctx->default_tcg_memop_mask); -+ gen_store_fpr32(ctx, fp0, ft); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FST_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, ft); -+ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, -+ MO_TEUL | ctx->default_tcg_memop_mask); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FLD_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, -+ MO_TEQ | ctx->default_tcg_memop_mask); -+ gen_store_fpr64(ctx, fp0, ft); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FST_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, ft); -+ tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, -+ MO_TEQ | ctx->default_tcg_memop_mask); -+ tcg_temp_free_i64(fp0); -+ } break; -+ default: -+ LARCH_INVAL("flt_ldst"); -+ generate_exception_end(ctx, EXCP_RI); -+ break; -+ } -+} -+ -+static void gen_fp_ldst(DisasContext *ctx, uint32_t op, int rt, int rs, -+ int16_t imm) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ check_cp1_enabled(ctx); -+ gen_base_offset_addr(ctx, t0, rs, imm); -+ gen_flt_ldst(ctx, op, rt, t0); -+ tcg_temp_free(t0); -+} -+ -+/* Arithmetic with immediate operand */ -+static void gen_arith_imm(DisasContext *ctx, uint32_t opc, int rt, int rs, -+ int imm) -+{ -+ target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ -+ -+ if (rt == 0) { -+ /* -+ * If no destination, treat it as a NOP. -+ * For addi, we must generate the overflow exception when needed. -+ */ -+ return; -+ } -+ switch (opc) { -+ case OPC_LARCH_ADDI_W: -+ if (rs != 0) { -+ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], uimm); -+ } -+ break; -+ case OPC_LARCH_ADDI_D: -+ if (rs != 0) { -+ tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], uimm); -+ } -+ break; -+ } -+} -+ -+/* Logic with immediate operand */ -+static void gen_logic_imm(DisasContext *ctx, uint32_t opc, int rt, int rs, -+ int16_t imm) -+{ -+ target_ulong uimm; -+ -+ if (rt == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ uimm = (uint16_t)imm; -+ switch (opc) { -+ case OPC_LARCH_ANDI: -+ if (likely(rs != 0)) { -+ tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], 0); -+ } -+ break; -+ case OPC_LARCH_ORI: -+ if (rs != 0) { -+ tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], uimm); -+ } -+ break; -+ case OPC_LARCH_XORI: -+ if (likely(rs != 0)) { -+ tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rt], uimm); -+ } -+ break; -+ default: -+ break; -+ } -+} -+ -+/* Set on less than with immediate operand */ -+static void gen_slt_imm(DisasContext *ctx, uint32_t opc, int rt, int rs, -+ int16_t imm) -+{ -+ target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */ -+ TCGv t0; -+ -+ if (rt == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ switch (opc) { -+ case OPC_LARCH_SLTI: -+ tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm); -+ break; -+ case OPC_LARCH_SLTIU: -+ tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm); -+ break; -+ } -+ tcg_temp_free(t0); -+} -+ -+/* Shifts with immediate operand */ -+static void gen_shift_imm(DisasContext *ctx, uint32_t opc, int rt, int rs, -+ int16_t imm) -+{ -+ target_ulong uimm = ((uint16_t)imm) & 0x1f; -+ TCGv t0; -+ -+ if (rt == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ switch (opc) { -+ case OPC_LARCH_SRAI_W: -+ tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm); -+ break; -+ case OPC_LARCH_SRLI_W: -+ if (uimm != 0) { -+ tcg_gen_ext32u_tl(t0, t0); -+ tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm); -+ } else { -+ tcg_gen_ext32s_tl(cpu_gpr[rt], t0); -+ } -+ break; -+ case OPC_LARCH_ROTRI_W: -+ if (uimm != 0) { -+ TCGv_i32 t1 = tcg_temp_new_i32(); -+ -+ tcg_gen_trunc_tl_i32(t1, t0); -+ tcg_gen_rotri_i32(t1, t1, uimm); -+ tcg_gen_ext_i32_tl(cpu_gpr[rt], t1); -+ tcg_temp_free_i32(t1); -+ } else { -+ tcg_gen_ext32s_tl(cpu_gpr[rt], t0); -+ } -+ break; -+ } -+ tcg_temp_free(t0); -+} -+ -+/* Arithmetic */ -+static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) -+{ -+ if (rd == 0) { -+ /* -+ * If no destination, treat it as a NOP. -+ * For add & sub, we must generate the -+ * overflow exception when needed. -+ */ -+ return; -+ } -+ -+ switch (opc) { -+ case OPC_LARCH_ADD_W: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_SUB_W: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_ADD_D: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_SUB_D: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ } -+} -+ -+/* Conditional move */ -+static void gen_cond_move(DisasContext *ctx, uint32_t opc, int rd, int rs, -+ int rt) -+{ -+ TCGv t0, t1, t2; -+ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rt); -+ t1 = tcg_const_tl(0); -+ t2 = tcg_temp_new(); -+ gen_load_gpr(t2, rs); -+ switch (opc) { -+ case OPC_LARCH_MASKEQZ: -+ tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); -+ break; -+ case OPC_LARCH_MASKNEZ: -+ tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); -+ break; -+ } -+ tcg_temp_free(t2); -+ tcg_temp_free(t1); -+ tcg_temp_free(t0); -+} -+ -+/* Logic */ -+static void gen_logic(DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) -+{ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ switch (opc) { -+ case OPC_LARCH_AND: -+ if (likely(rs != 0 && rt != 0)) { -+ tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_NOR: -+ if (rs != 0 && rt != 0) { -+ tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0)); -+ } -+ break; -+ case OPC_LARCH_OR: -+ if (likely(rs != 0 && rt != 0)) { -+ tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ case OPC_LARCH_XOR: -+ if (likely(rs != 0 && rt != 0)) { -+ tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]); -+ } else if (rs == 0 && rt != 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]); -+ } else if (rs != 0 && rt == 0) { -+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); -+ } else { -+ tcg_gen_movi_tl(cpu_gpr[rd], 0); -+ } -+ break; -+ } -+} -+ -+/* Set on lower than */ -+static void gen_slt(DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) -+{ -+ TCGv t0, t1; -+ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ switch (opc) { -+ case OPC_LARCH_SLT: -+ tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1); -+ break; -+ case OPC_LARCH_SLTU: -+ tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1); -+ break; -+ } -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+/* Shifts */ -+static void gen_shift(DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) -+{ -+ TCGv t0, t1; -+ -+ if (rd == 0) { -+ /* -+ * If no destination, treat it as a NOP. -+ * For add & sub, we must generate the -+ * overflow exception when needed. -+ */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ switch (opc) { -+ case OPC_LARCH_SLL_W: -+ tcg_gen_andi_tl(t0, t0, 0x1f); -+ tcg_gen_shl_tl(t0, t1, t0); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_SRA_W: -+ tcg_gen_andi_tl(t0, t0, 0x1f); -+ tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); -+ break; -+ case OPC_LARCH_SRL_W: -+ tcg_gen_ext32u_tl(t1, t1); -+ tcg_gen_andi_tl(t0, t0, 0x1f); -+ tcg_gen_shr_tl(t0, t1, t0); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_ROTR_W: { -+ TCGv_i32 t2 = tcg_temp_new_i32(); -+ TCGv_i32 t3 = tcg_temp_new_i32(); -+ -+ tcg_gen_trunc_tl_i32(t2, t0); -+ tcg_gen_trunc_tl_i32(t3, t1); -+ tcg_gen_andi_i32(t2, t2, 0x1f); -+ tcg_gen_rotr_i32(t2, t3, t2); -+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); -+ tcg_temp_free_i32(t2); -+ tcg_temp_free_i32(t3); -+ } break; -+ case OPC_LARCH_SLL_D: -+ tcg_gen_andi_tl(t0, t0, 0x3f); -+ tcg_gen_shl_tl(cpu_gpr[rd], t1, t0); -+ break; -+ case OPC_LARCH_SRA_D: -+ tcg_gen_andi_tl(t0, t0, 0x3f); -+ tcg_gen_sar_tl(cpu_gpr[rd], t1, t0); -+ break; -+ case OPC_LARCH_SRL_D: -+ tcg_gen_andi_tl(t0, t0, 0x3f); -+ tcg_gen_shr_tl(cpu_gpr[rd], t1, t0); -+ break; -+ case OPC_LARCH_ROTR_D: -+ tcg_gen_andi_tl(t0, t0, 0x3f); -+ tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0); -+ break; -+ } -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+static inline void gen_r6_ld(target_long addr, int reg, int memidx, -+ MemOp memop) -+{ -+ TCGv t0 = tcg_const_tl(addr); -+ tcg_gen_qemu_ld_tl(t0, t0, memidx, memop); -+ gen_store_gpr(t0, reg); -+ tcg_temp_free(t0); -+} -+ -+static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) -+{ -+ TCGv t0, t1; -+ -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ -+ switch (opc) { -+ case OPC_LARCH_DIV_W: { -+ TCGv t2 = tcg_temp_new(); -+ TCGv t3 = tcg_temp_new(); -+ tcg_gen_ext32s_tl(t0, t0); -+ tcg_gen_ext32s_tl(t1, t1); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); -+ tcg_gen_and_tl(t2, t2, t3); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); -+ tcg_gen_or_tl(t2, t2, t3); -+ tcg_gen_movi_tl(t3, 0); -+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); -+ tcg_gen_div_tl(cpu_gpr[rd], t0, t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_MOD_W: { -+ TCGv t2 = tcg_temp_new(); -+ TCGv t3 = tcg_temp_new(); -+ tcg_gen_ext32s_tl(t0, t0); -+ tcg_gen_ext32s_tl(t1, t1); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); -+ tcg_gen_and_tl(t2, t2, t3); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); -+ tcg_gen_or_tl(t2, t2, t3); -+ tcg_gen_movi_tl(t3, 0); -+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); -+ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_DIV_WU: { -+ TCGv t2 = tcg_const_tl(0); -+ TCGv t3 = tcg_const_tl(1); -+ tcg_gen_ext32u_tl(t0, t0); -+ tcg_gen_ext32u_tl(t1, t1); -+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); -+ tcg_gen_divu_tl(cpu_gpr[rd], t0, t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_MOD_WU: { -+ TCGv t2 = tcg_const_tl(0); -+ TCGv t3 = tcg_const_tl(1); -+ tcg_gen_ext32u_tl(t0, t0); -+ tcg_gen_ext32u_tl(t1, t1); -+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); -+ tcg_gen_remu_tl(cpu_gpr[rd], t0, t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_MUL_W: { -+ TCGv_i32 t2 = tcg_temp_new_i32(); -+ TCGv_i32 t3 = tcg_temp_new_i32(); -+ tcg_gen_trunc_tl_i32(t2, t0); -+ tcg_gen_trunc_tl_i32(t3, t1); -+ tcg_gen_mul_i32(t2, t2, t3); -+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2); -+ tcg_temp_free_i32(t2); -+ tcg_temp_free_i32(t3); -+ } break; -+ case OPC_LARCH_MULH_W: { -+ TCGv_i32 t2 = tcg_temp_new_i32(); -+ TCGv_i32 t3 = tcg_temp_new_i32(); -+ tcg_gen_trunc_tl_i32(t2, t0); -+ tcg_gen_trunc_tl_i32(t3, t1); -+ tcg_gen_muls2_i32(t2, t3, t2, t3); -+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); -+ tcg_temp_free_i32(t2); -+ tcg_temp_free_i32(t3); -+ } break; -+ case OPC_LARCH_MULH_WU: { -+ TCGv_i32 t2 = tcg_temp_new_i32(); -+ TCGv_i32 t3 = tcg_temp_new_i32(); -+ tcg_gen_trunc_tl_i32(t2, t0); -+ tcg_gen_trunc_tl_i32(t3, t1); -+ tcg_gen_mulu2_i32(t2, t3, t2, t3); -+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t3); -+ tcg_temp_free_i32(t2); -+ tcg_temp_free_i32(t3); -+ } break; -+ case OPC_LARCH_DIV_D: { -+ TCGv t2 = tcg_temp_new(); -+ TCGv t3 = tcg_temp_new(); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); -+ tcg_gen_and_tl(t2, t2, t3); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); -+ tcg_gen_or_tl(t2, t2, t3); -+ tcg_gen_movi_tl(t3, 0); -+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); -+ tcg_gen_div_tl(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_MOD_D: { -+ TCGv t2 = tcg_temp_new(); -+ TCGv t3 = tcg_temp_new(); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL); -+ tcg_gen_and_tl(t2, t2, t3); -+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); -+ tcg_gen_or_tl(t2, t2, t3); -+ tcg_gen_movi_tl(t3, 0); -+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); -+ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_DIV_DU: { -+ TCGv t2 = tcg_const_tl(0); -+ TCGv t3 = tcg_const_tl(1); -+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); -+ tcg_gen_divu_i64(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_MOD_DU: { -+ TCGv t2 = tcg_const_tl(0); -+ TCGv t3 = tcg_const_tl(1); -+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1); -+ tcg_gen_remu_i64(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t3); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_MUL_D: -+ tcg_gen_mul_i64(cpu_gpr[rd], t0, t1); -+ break; -+ case OPC_LARCH_MULH_D: { -+ TCGv t2 = tcg_temp_new(); -+ tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t2); -+ } break; -+ case OPC_LARCH_MULH_DU: { -+ TCGv t2 = tcg_temp_new(); -+ tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t2); -+ } break; -+ default: -+ LARCH_INVAL("r6 mul/div"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+out: -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+static void gen_cl(DisasContext *ctx, uint32_t opc, int rd, int rs) -+{ -+ TCGv t0; -+ -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = cpu_gpr[rd]; -+ gen_load_gpr(t0, rs); -+ -+ switch (opc) { -+ case OPC_LARCH_CLO_W: -+ case OPC_LARCH_CLO_D: -+ tcg_gen_not_tl(t0, t0); -+ break; -+ } -+ -+ switch (opc) { -+ case OPC_LARCH_CLO_W: -+ case OPC_LARCH_CLZ_W: -+ tcg_gen_ext32u_tl(t0, t0); -+ tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS); -+ tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32); -+ break; -+ case OPC_LARCH_CLO_D: -+ case OPC_LARCH_CLZ_D: -+ tcg_gen_clzi_i64(t0, t0, 64); -+ break; -+ } -+} -+ -+static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) -+{ -+ if (unlikely(ctx->base.singlestep_enabled)) { -+ return false; -+ } -+ -+#ifndef CONFIG_USER_ONLY -+ return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -+#else -+ return true; -+#endif -+} -+ -+static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) -+{ -+ if (use_goto_tb(ctx, dest)) { -+ tcg_gen_goto_tb(n); -+ gen_save_pc(dest); -+ tcg_gen_exit_tb(ctx->base.tb, n); -+ } else { -+ gen_save_pc(dest); -+ if (ctx->base.singlestep_enabled) { -+ save_cpu_state(ctx, 0); -+ gen_helper_raise_exception_debug(cpu_env); -+ } -+ tcg_gen_lookup_and_goto_ptr(); -+ } -+} -+ -+/* Branches */ -+static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int insn_bytes, -+ int rs, int rt, int32_t offset) -+{ -+ target_ulong btgt = -1; -+ int bcond_compute = 0; -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ if (ctx->hflags & LARCH_HFLAG_BMASK) { -+#ifdef LARCH_DEBUG_DISAS -+ LOG_DISAS("Branch at PC 0x" TARGET_FMT_lx "\n", ctx->base.pc_next); -+#endif -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ -+ /* Load needed operands */ -+ switch (opc) { -+ case OPC_LARCH_BLT: -+ case OPC_LARCH_BGE: -+ case OPC_LARCH_BLTU: -+ case OPC_LARCH_BGEU: -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ bcond_compute = 1; -+ btgt = ctx->base.pc_next + offset; -+ break; -+ case OPC_LARCH_BEQZ: -+ case OPC_LARCH_B: -+ case OPC_LARCH_BEQ: -+ case OPC_LARCH_BNEZ: -+ case OPC_LARCH_BNE: -+ /* Compare two registers */ -+ if (rs != rt) { -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ bcond_compute = 1; -+ } -+ btgt = ctx->base.pc_next + offset; -+ break; -+ default: -+ LARCH_INVAL("branch/jump"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ if (bcond_compute == 0) { -+ /* No condition to be computed */ -+ switch (opc) { -+ case OPC_LARCH_BEQZ: /* rx == rx */ -+ case OPC_LARCH_B: -+ case OPC_LARCH_BEQ: -+ /* Always take */ -+ ctx->hflags |= LARCH_HFLAG_B; -+ break; -+ case OPC_LARCH_BNEZ: -+ case OPC_LARCH_BNE: -+ /* Treat as NOP. */ -+ goto out; -+ default: -+ LARCH_INVAL("branch/jump"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ } else { -+ switch (opc) { -+ case OPC_LARCH_BLT: -+ tcg_gen_setcond_tl(TCG_COND_LT, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BGE: -+ tcg_gen_setcond_tl(TCG_COND_GE, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BLTU: -+ tcg_gen_setcond_tl(TCG_COND_LTU, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BGEU: -+ tcg_gen_setcond_tl(TCG_COND_GEU, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BEQZ: -+ case OPC_LARCH_B: -+ case OPC_LARCH_BEQ: -+ tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); -+ goto not_likely; -+ case OPC_LARCH_BNEZ: -+ case OPC_LARCH_BNE: -+ tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); -+ goto not_likely; -+ not_likely: -+ ctx->hflags |= LARCH_HFLAG_BC; -+ break; -+ default: -+ LARCH_INVAL("conditional branch/jump"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ } -+ -+ ctx->btarget = btgt; -+ -+out: -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+/* special3 bitfield operations */ -+static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt, int rs, -+ int lsb, int msb) -+{ -+ TCGv t0 = tcg_temp_new(); -+ TCGv t1 = tcg_temp_new(); -+ -+ gen_load_gpr(t1, rs); -+ switch (opc) { -+ case OPC_LARCH_TRPICK_W: -+ if (lsb + msb > 31) { -+ goto fail; -+ } -+ if (msb != 31) { -+ tcg_gen_extract_tl(t0, t1, lsb, msb + 1); -+ } else { -+ /* -+ * The two checks together imply that lsb == 0, -+ * so this is a simple sign-extension. -+ */ -+ tcg_gen_ext32s_tl(t0, t1); -+ } -+ break; -+ case OPC_LARCH_TRINS_W: -+ if (lsb > msb) { -+ goto fail; -+ } -+ gen_load_gpr(t0, rt); -+ tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); -+ tcg_gen_ext32s_tl(t0, t0); -+ break; -+ default: -+ fail: -+ LARCH_INVAL("bitops"); -+ generate_exception_end(ctx, EXCP_RI); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ return; -+ } -+ gen_store_gpr(t0, rt); -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+} -+ -+static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd) -+{ -+ TCGv t0; -+ -+ if (rd == 0) { -+ /* If no destination, treat it as a NOP. */ -+ return; -+ } -+ -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rt); -+ switch (op2) { -+ case OPC_LARCH_REVB_2H: { -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_const_tl(0x00FF00FF); -+ -+ tcg_gen_shri_tl(t1, t0, 8); -+ tcg_gen_and_tl(t1, t1, t2); -+ tcg_gen_and_tl(t0, t0, t2); -+ tcg_gen_shli_tl(t0, t0, 8); -+ tcg_gen_or_tl(t0, t0, t1); -+ tcg_temp_free(t2); -+ tcg_temp_free(t1); -+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); -+ } break; -+ case OPC_LARCH_EXT_WB: -+ tcg_gen_ext8s_tl(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_EXT_WH: -+ tcg_gen_ext16s_tl(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_REVB_4H: { -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL); -+ -+ tcg_gen_shri_tl(t1, t0, 8); -+ tcg_gen_and_tl(t1, t1, t2); -+ tcg_gen_and_tl(t0, t0, t2); -+ tcg_gen_shli_tl(t0, t0, 8); -+ tcg_gen_or_tl(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t2); -+ tcg_temp_free(t1); -+ } break; -+ case OPC_LARCH_REVH_D: { -+ TCGv t1 = tcg_temp_new(); -+ TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL); -+ -+ tcg_gen_shri_tl(t1, t0, 16); -+ tcg_gen_and_tl(t1, t1, t2); -+ tcg_gen_and_tl(t0, t0, t2); -+ tcg_gen_shli_tl(t0, t0, 16); -+ tcg_gen_or_tl(t0, t0, t1); -+ tcg_gen_shri_tl(t1, t0, 32); -+ tcg_gen_shli_tl(t0, t0, 32); -+ tcg_gen_or_tl(cpu_gpr[rd], t0, t1); -+ tcg_temp_free(t2); -+ tcg_temp_free(t1); -+ } break; -+ default: -+ LARCH_INVAL("bsfhl"); -+ generate_exception_end(ctx, EXCP_RI); -+ tcg_temp_free(t0); -+ return; -+ } -+ tcg_temp_free(t0); -+} -+ -+/* REV with sf==1, opcode==3 ("REV64") */ -+static void handle_rev64(DisasContext *ctx, unsigned int rn, unsigned int rd) -+{ -+ tcg_gen_bswap64_i64(cpu_gpr[rd], cpu_gpr[rn]); -+} -+ -+/* -+ * REV with sf==0, opcode==2 -+ * REV32 (sf==1, opcode==2) -+ */ -+static void handle_rev32(DisasContext *ctx, unsigned int rn, unsigned int rd) -+{ -+ TCGv_i64 tcg_rd = tcg_temp_new_i64(); -+ gen_load_gpr(tcg_rd, rd); -+ -+ TCGv_i64 tcg_tmp = tcg_temp_new_i64(); -+ TCGv_i64 tcg_rn = tcg_temp_new_i64(); -+ gen_load_gpr(tcg_rn, rn); -+ -+ /* bswap32_i64 requires zero high word */ -+ tcg_gen_ext32u_i64(tcg_tmp, tcg_rn); -+ tcg_gen_bswap32_i64(tcg_rd, tcg_tmp, TCG_BSWAP_OZ); -+ tcg_gen_shri_i64(tcg_tmp, tcg_rn, 32); -+ tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp, TCG_BSWAP_OZ); -+ tcg_gen_concat32_i64(cpu_gpr[rd], tcg_rd, tcg_tmp); -+ -+ tcg_temp_free_i64(tcg_tmp); -+ tcg_temp_free_i64(tcg_rd); -+ tcg_temp_free_i64(tcg_rn); -+} -+ -+/* REV16 */ -+static void handle_rev16(DisasContext *ctx, unsigned int rn, unsigned int rd) -+{ -+ TCGv_i64 tcg_rd = tcg_temp_new_i64(); -+ TCGv_i64 tcg_rn = tcg_temp_new_i64(); -+ gen_load_gpr(tcg_rd, rd); -+ gen_load_gpr(tcg_rn, rn); -+ TCGv_i64 tcg_tmp = tcg_temp_new_i64(); -+ TCGv_i64 mask = tcg_const_i64(0x0000ffff0000ffffull); -+ -+ tcg_gen_shri_i64(tcg_tmp, tcg_rn, 16); -+ tcg_gen_and_i64(tcg_rd, tcg_rn, mask); -+ tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask); -+ tcg_gen_shli_i64(tcg_rd, tcg_rd, 16); -+ tcg_gen_or_i64(cpu_gpr[rd], tcg_rd, tcg_tmp); -+ -+ tcg_temp_free_i64(mask); -+ tcg_temp_free_i64(tcg_tmp); -+ tcg_temp_free_i64(tcg_rd); -+ tcg_temp_free_i64(tcg_rn); -+} -+ -+static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt, -+ int imm2) -+{ -+ TCGv t0; -+ TCGv t1; -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ gen_load_gpr(t0, rs); -+ gen_load_gpr(t1, rt); -+ tcg_gen_shli_tl(t0, t0, imm2 + 1); -+ tcg_gen_add_tl(cpu_gpr[rd], t0, t1); -+ if (opc == OPC_LARCH_ALSL_W) { -+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); -+ } -+ -+ tcg_temp_free(t1); -+ tcg_temp_free(t0); -+ -+ return; -+} -+ -+static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs, -+ int rt, int bits) -+{ -+ TCGv t0; -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ if (bits == 0 || bits == wordsz) { -+ if (bits == 0) { -+ gen_load_gpr(t0, rt); -+ } else { -+ gen_load_gpr(t0, rs); -+ } -+ switch (wordsz) { -+ case 32: -+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0); -+ break; -+ case 64: -+ tcg_gen_mov_tl(cpu_gpr[rd], t0); -+ break; -+ } -+ } else { -+ TCGv t1 = tcg_temp_new(); -+ gen_load_gpr(t0, rt); -+ gen_load_gpr(t1, rs); -+ switch (wordsz) { -+ case 32: { -+ TCGv_i64 t2 = tcg_temp_new_i64(); -+ tcg_gen_concat_tl_i64(t2, t1, t0); -+ tcg_gen_shri_i64(t2, t2, 32 - bits); -+ gen_move_low32(cpu_gpr[rd], t2); -+ tcg_temp_free_i64(t2); -+ } break; -+ case 64: -+ tcg_gen_shli_tl(t0, t0, bits); -+ tcg_gen_shri_tl(t1, t1, 64 - bits); -+ tcg_gen_or_tl(cpu_gpr[rd], t1, t0); -+ break; -+ } -+ tcg_temp_free(t1); -+ } -+ -+ tcg_temp_free(t0); -+} -+ -+static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, -+ int bp) -+{ -+ gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8); -+} -+ -+static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt) -+{ -+ TCGv t0; -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ gen_load_gpr(t0, rt); -+ switch (opc) { -+ case OPC_LARCH_BREV_4B: -+ gen_helper_bitswap(cpu_gpr[rd], t0); -+ break; -+ case OPC_LARCH_BREV_8B: -+ gen_helper_dbitswap(cpu_gpr[rd], t0); -+ break; -+ } -+ tcg_temp_free(t0); -+} -+ -+static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs) -+{ -+ TCGv t0 = tcg_temp_new(); -+ check_cp1_enabled(ctx); -+ -+ switch (opc) { -+ case OPC_LARCH_FR2GR_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ tcg_gen_ext_i32_tl(t0, fp0); -+ tcg_temp_free_i32(fp0); -+ } -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_GR2FR_W: -+ gen_load_gpr(t0, rt); -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ tcg_gen_trunc_tl_i32(fp0, t0); -+ gen_store_fpr32(ctx, fp0, fs); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ case OPC_LARCH_FR2GR_D: -+ gen_load_fpr64(ctx, t0, fs); -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_GR2FR_D: -+ gen_load_gpr(t0, rt); -+ gen_store_fpr64(ctx, t0, fs); -+ break; -+ case OPC_LARCH_FRH2GR_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32h(ctx, fp0, fs); -+ tcg_gen_ext_i32_tl(t0, fp0); -+ tcg_temp_free_i32(fp0); -+ } -+ gen_store_gpr(t0, rt); -+ break; -+ case OPC_LARCH_GR2FRH_W: -+ gen_load_gpr(t0, rt); -+ { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ tcg_gen_trunc_tl_i32(fp0, t0); -+ gen_store_fpr32h(ctx, fp0, fs); -+ tcg_temp_free_i32(fp0); -+ } -+ break; -+ default: -+ LARCH_INVAL("cp1 move"); -+ generate_exception_end(ctx, EXCP_RI); -+ goto out; -+ } -+ -+out: -+ tcg_temp_free(t0); -+} -+ -+static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd, int cc, -+ int tf) -+{ -+ int cond; -+ TCGv_i32 t0 = tcg_temp_new_i32(); -+ TCGLabel *l1 = gen_new_label(); -+ TCGLabel *l2 = gen_new_label(); -+ -+ if (tf) { -+ cond = TCG_COND_EQ; -+ } else { -+ cond = TCG_COND_NE; -+ } -+ -+ tcg_gen_andi_i32(t0, fpu_fcsr0, 1 << get_fp_bit(cc)); -+ tcg_gen_brcondi_i32(cond, t0, 0, l1); -+ gen_load_fpr32(ctx, t0, fs); -+ gen_store_fpr32(ctx, t0, fd); -+ gen_set_label(l1); -+ -+ tcg_gen_andi_i32(t0, fpu_fcsr0, 1 << get_fp_bit(cc + 1)); -+ tcg_gen_brcondi_i32(cond, t0, 0, l2); -+ gen_load_fpr32h(ctx, t0, fs); -+ gen_store_fpr32h(ctx, t0, fd); -+ tcg_temp_free_i32(t0); -+ gen_set_label(l2); -+} -+ -+static void gen_farith(DisasContext *ctx, uint32_t opc, int ft, int fs, int fd, -+ int cc) -+{ -+ check_cp1_enabled(ctx); -+ switch (opc) { -+ case OPC_LARCH_FADD_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_add_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FSUB_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FMUL_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FDIV_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_div_s(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i32(fp1); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FSQRT_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_sqrt_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FABS_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_abs_s(fp0, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FMOV_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FNEG_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_chs_s(fp0, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FTINTRNE_L_S: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_round_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } break; -+ case OPC_LARCH_FTINTRZ_L_S: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_trunc_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } break; -+ case OPC_LARCH_FTINTRP_L_S: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_ceil_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } break; -+ case OPC_LARCH_FTINTRM_L_S: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_floor_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } break; -+ case OPC_LARCH_FTINTRNE_W_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_round_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FTINTRZ_W_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_trunc_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FTINTRP_W_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_ceil_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FTINTRM_W_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_floor_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FRECIP_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_recip_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FRSQRT_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_rsqrt_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FRINT_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_rint_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FCLASS_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_class_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FMIN_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ TCGv_i32 fp2 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_min_s(fp2, cpu_env, fp0, fp1); -+ gen_store_fpr32(ctx, fp2, fd); -+ tcg_temp_free_i32(fp2); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FMINA_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ TCGv_i32 fp2 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1); -+ gen_store_fpr32(ctx, fp2, fd); -+ tcg_temp_free_i32(fp2); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FMAX_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_max_s(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr32(ctx, fp1, fd); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FMAXA_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ TCGv_i32 fp1 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_load_fpr32(ctx, fp1, ft); -+ gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr32(ctx, fp1, fd); -+ tcg_temp_free_i32(fp1); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FCVT_D_S: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_cvtd_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } break; -+ case OPC_LARCH_FTINT_W_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_cvt_w_s(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FTINT_L_S: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_cvt_l_s(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } break; -+ case OPC_LARCH_FADD_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_add_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FSUB_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FMUL_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FDIV_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_div_d(fp0, cpu_env, fp0, fp1); -+ tcg_temp_free_i64(fp1); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FSQRT_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_sqrt_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FABS_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_abs_d(fp0, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FMOV_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FNEG_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_chs_d(fp0, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FTINTRNE_L_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_round_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FTINTRZ_L_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_trunc_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FTINTRP_L_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_ceil_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FTINTRM_L_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_floor_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FTINTRNE_W_D: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_round_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } break; -+ case OPC_LARCH_FTINTRZ_W_D: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_trunc_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } break; -+ case OPC_LARCH_FTINTRP_W_D: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_ceil_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } break; -+ case OPC_LARCH_FTINTRM_W_D: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_floor_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } break; -+ case OPC_LARCH_FRECIP_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_recip_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FRSQRT_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_rsqrt_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FRINT_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_rint_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FCLASS_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_class_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FMIN_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_min_d(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr64(ctx, fp1, fd); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FMINA_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr64(ctx, fp1, fd); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FMAX_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_max_d(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr64(ctx, fp1, fd); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FMAXA_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ TCGv_i64 fp1 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_load_fpr64(ctx, fp1, ft); -+ gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1); -+ gen_store_fpr64(ctx, fp1, fd); -+ tcg_temp_free_i64(fp1); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FCVT_S_D: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_cvts_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } break; -+ case OPC_LARCH_FTINT_W_D: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_cvt_w_d(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } break; -+ case OPC_LARCH_FTINT_L_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_cvt_l_d(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FFINT_S_W: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ gen_load_fpr32(ctx, fp0, fs); -+ gen_helper_float_cvts_w(fp0, cpu_env, fp0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FFINT_D_W: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr32(ctx, fp32, fs); -+ gen_helper_float_cvtd_w(fp64, cpu_env, fp32); -+ tcg_temp_free_i32(fp32); -+ gen_store_fpr64(ctx, fp64, fd); -+ tcg_temp_free_i64(fp64); -+ } break; -+ case OPC_LARCH_FFINT_S_L: { -+ TCGv_i32 fp32 = tcg_temp_new_i32(); -+ TCGv_i64 fp64 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp64, fs); -+ gen_helper_float_cvts_l(fp32, cpu_env, fp64); -+ tcg_temp_free_i64(fp64); -+ gen_store_fpr32(ctx, fp32, fd); -+ tcg_temp_free_i32(fp32); -+ } break; -+ case OPC_LARCH_FFINT_D_L: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ -+ gen_load_fpr64(ctx, fp0, fs); -+ gen_helper_float_cvtd_l(fp0, cpu_env, fp0); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ default: -+ LARCH_INVAL("farith"); -+ generate_exception_end(ctx, EXCP_RI); -+ return; -+ } -+} -+ -+/* Coprocessor 3 (FPU) */ -+static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc, int fd, int fs, -+ int base, int index) -+{ -+ TCGv t0 = tcg_temp_new(); -+ -+ check_cp1_enabled(ctx); -+ if (base == 0) { -+ gen_load_gpr(t0, index); -+ } else if (index == 0) { -+ gen_load_gpr(t0, base); -+ } else { -+ gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]); -+ } -+ -+ /* -+ * Don't do NOP if destination is zero: we must perform the actual -+ * memory access. -+ */ -+ switch (opc) { -+ case OPC_LARCH_FLDX_S: -+ case OPC_LARCH_FLDGT_S: -+ case OPC_LARCH_FLDLE_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ -+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL); -+ tcg_gen_trunc_tl_i32(fp0, t0); -+ gen_store_fpr32(ctx, fp0, fd); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FLDX_D: -+ case OPC_LARCH_FLDGT_D: -+ case OPC_LARCH_FLDLE_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ); -+ gen_store_fpr64(ctx, fp0, fd); -+ tcg_temp_free_i64(fp0); -+ } break; -+ case OPC_LARCH_FSTX_S: -+ case OPC_LARCH_FSTGT_S: -+ case OPC_LARCH_FSTLE_S: { -+ TCGv_i32 fp0 = tcg_temp_new_i32(); -+ gen_load_fpr32(ctx, fp0, fs); -+ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL); -+ tcg_temp_free_i32(fp0); -+ } break; -+ case OPC_LARCH_FSTX_D: -+ case OPC_LARCH_FSTGT_D: -+ case OPC_LARCH_FSTLE_D: { -+ TCGv_i64 fp0 = tcg_temp_new_i64(); -+ gen_load_fpr64(ctx, fp0, fs); -+ tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ); -+ tcg_temp_free_i64(fp0); -+ } break; -+ } -+ tcg_temp_free(t0); -+} -+ -+static inline void clear_branch_hflags(DisasContext *ctx) -+{ -+ ctx->hflags &= ~LARCH_HFLAG_BMASK; -+ if (ctx->base.is_jmp == DISAS_NEXT) { -+ save_cpu_state(ctx, 0); -+ } else { -+ /* -+ * It is not safe to save ctx->hflags as hflags may be changed -+ * in execution time. -+ */ -+ tcg_gen_andi_i32(hflags, hflags, ~LARCH_HFLAG_BMASK); -+ } -+} -+ -+static void gen_branch(DisasContext *ctx, int insn_bytes) -+{ -+ if (ctx->hflags & LARCH_HFLAG_BMASK) { -+ int proc_hflags = ctx->hflags & LARCH_HFLAG_BMASK; -+ /* Branches completion */ -+ clear_branch_hflags(ctx); -+ ctx->base.is_jmp = DISAS_NORETURN; -+ /* FIXME: Need to clear can_do_io. */ -+ switch (proc_hflags & LARCH_HFLAG_BMASK) { -+ case LARCH_HFLAG_B: -+ /* unconditional branch */ -+ gen_goto_tb(ctx, 0, ctx->btarget); -+ break; -+ case LARCH_HFLAG_BC: -+ /* Conditional branch */ -+ { -+ TCGLabel *l1 = gen_new_label(); -+ -+ tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); -+ gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes); -+ gen_set_label(l1); -+ gen_goto_tb(ctx, 0, ctx->btarget); -+ } -+ break; -+ case LARCH_HFLAG_BR: -+ /* unconditional branch to register */ -+ tcg_gen_mov_tl(cpu_PC, btarget); -+ if (ctx->base.singlestep_enabled) { -+ save_cpu_state(ctx, 0); -+ gen_helper_raise_exception_debug(cpu_env); -+ } -+ tcg_gen_lookup_and_goto_ptr(); -+ break; -+ default: -+ fprintf(stderr, "unknown branch 0x%x\n", proc_hflags); -+ abort(); -+ } -+ } -+} -+ -+/* Signed immediate */ -+#define SIMM(op, start, width) \ -+ ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) << (32 - width)) >> \ -+ (32 - width)) -+/* Zero-extended immediate */ -+#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width))) -+ -+static void gen_sync(int stype) -+{ -+ TCGBar tcg_mo = TCG_BAR_SC; -+ -+ switch (stype) { -+ case 0x4: /* SYNC_WMB */ -+ tcg_mo |= TCG_MO_ST_ST; -+ break; -+ case 0x10: /* SYNC_MB */ -+ tcg_mo |= TCG_MO_ALL; -+ break; -+ case 0x11: /* SYNC_ACQUIRE */ -+ tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; -+ break; -+ case 0x12: /* SYNC_RELEASE */ -+ tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; -+ break; -+ case 0x13: /* SYNC_RMB */ -+ tcg_mo |= TCG_MO_LD_LD; -+ break; -+ default: -+ tcg_mo |= TCG_MO_ALL; -+ break; -+ } -+ -+ tcg_gen_mb(tcg_mo); -+} -+ -+static void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz, -+ int crc32c) -+{ -+ TCGv t0; -+ TCGv t1; -+ TCGv_i32 tsz = tcg_const_i32(1 << sz); -+ if (rd == 0) { -+ /* Treat as NOP. */ -+ return; -+ } -+ t0 = tcg_temp_new(); -+ t1 = tcg_temp_new(); -+ -+ gen_load_gpr(t0, rt); -+ gen_load_gpr(t1, rs); -+ -+ if (crc32c) { -+ gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz); -+ } else { -+ gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz); -+ } -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(t1); -+ tcg_temp_free_i32(tsz); -+} -+ -+#include "cpu-csr.h" -+ -+#ifndef CONFIG_USER_ONLY -+ -+/* -+ * 64-bit CSR read -+ * -+ * @arg : GPR to store the value of CSR register -+ * @csr : CSR register number -+ */ -+static void gen_csr_rdq(DisasContext *ctx, TCGv rd, int64_t a1) -+{ -+ TCGv_i64 csr = tcg_const_i64(a1); -+ gen_helper_csr_rdq(rd, cpu_env, csr); -+} -+ -+/* -+ * 64-bit CSR write -+ * -+ * @arg : GPR that stores the new value of CSR register -+ * @csr : CSR register number -+ */ -+static void gen_csr_wrq(DisasContext *ctx, TCGv val, int64_t a1) -+{ -+ TCGv_i64 csr = tcg_const_i64(a1); -+ gen_helper_csr_wrq(val, cpu_env, val, csr); -+} -+ -+/* -+ * 64-bit CSR exchange -+ * -+ * @arg : GPR that stores the new value of CSR register -+ * @csr : CSR register number -+ */ -+static void gen_csr_xchgq(DisasContext *ctx, TCGv val, TCGv mask, int64_t a1) -+{ -+ TCGv_i64 csr = tcg_const_i64(a1); -+ gen_helper_csr_xchgq(val, cpu_env, val, mask, csr); -+} -+#endif /* !CONFIG_USER_ONLY */ -+ -+static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, -+ CPUState *cs) -+{ -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ CPULOONGARCHState *env = cs->env_ptr; -+ -+ ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; -+ ctx->saved_pc = -1; -+ ctx->insn_flags = env->insn_flags; -+ ctx->btarget = 0; -+ /* Restore state from the tb context. */ -+ ctx->hflags = -+ (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */ -+ restore_cpu_state(env, ctx); -+#ifdef CONFIG_USER_ONLY -+ ctx->mem_idx = LARCH_HFLAG_UM; -+#else -+ ctx->mem_idx = hflags_mmu_index(ctx->hflags); -+#endif -+ ctx->default_tcg_memop_mask = MO_ALIGN; -+ -+ LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx, -+ ctx->hflags); -+} -+ -+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, ctx->hflags & LARCH_HFLAG_BMASK, -+ ctx->btarget); -+} -+ -+/* 128 and 256 lsx vector instructions are not supported yet */ -+static bool decode_vector_lsx(uint32_t opcode) -+{ -+ uint32_t value = (opcode & 0xff000000); -+ -+ if ((opcode & 0xf0000000) == 0x70000000) { -+ return true; -+ } else if ((opcode & 0xfff00000) == 0x38400000) { -+ return true; -+ } else { -+ switch (value) { -+ case 0x09000000: -+ case 0x0a000000: -+ case 0x0e000000: -+ case 0x0f000000: -+ case 0x2c000000: -+ case 0x30000000: -+ case 0x31000000: -+ case 0x32000000: -+ case 0x33000000: -+ return true; -+ } -+ } -+ return false; -+} -+ -+static bool decode_insn(DisasContext *ctx, uint32_t insn); -+#include "decode-insn.c.inc" -+#include "trans.inc.c" -+ -+static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) -+{ -+ CPULOONGARCHState *env = cs->env_ptr; -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ int insn_bytes = 4; -+ -+ ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); -+ -+ if (!decode_insn(ctx, ctx->opcode)) { -+ if (decode_vector_lsx(ctx->opcode)) { -+ generate_exception_end(ctx, EXCP_RI); -+ } else { -+ fprintf(stderr, "Error: unkown opcode. 0x%lx: 0x%x\n", -+ ctx->base.pc_next, ctx->opcode); -+ generate_exception_end(ctx, EXCP_RI); -+ } -+ } -+ -+ if (ctx->hflags & LARCH_HFLAG_BMASK) { -+ gen_branch(ctx, insn_bytes); -+ } -+ ctx->base.pc_next += insn_bytes; -+} -+ -+static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) -+{ -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ -+ if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) { -+ save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT); -+ gen_helper_raise_exception_debug(cpu_env); -+ } else { -+ switch (ctx->base.is_jmp) { -+ case DISAS_STOP: -+ gen_save_pc(ctx->base.pc_next); -+ tcg_gen_lookup_and_goto_ptr(); -+ break; -+ case DISAS_NEXT: -+ case DISAS_TOO_MANY: -+ save_cpu_state(ctx, 0); -+ gen_goto_tb(ctx, 0, ctx->base.pc_next); -+ break; -+ case DISAS_EXIT: -+ tcg_gen_exit_tb(NULL, 0); -+ break; -+ case DISAS_NORETURN: -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+ } -+} -+ -+static void loongarch_tr_disas_log(const DisasContextBase *dcbase, -+ CPUState *cs) -+{ -+ qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); -+ log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); -+} -+ -+static const TranslatorOps loongarch_tr_ops = { -+ .init_disas_context = loongarch_tr_init_disas_context, -+ .tb_start = loongarch_tr_tb_start, -+ .insn_start = loongarch_tr_insn_start, -+ .translate_insn = loongarch_tr_translate_insn, -+ .tb_stop = loongarch_tr_tb_stop, -+ .disas_log = loongarch_tr_disas_log, -+}; -+ -+void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb, -+ int max_insns) -+{ -+ DisasContext ctx; -+ -+ translator_loop(&loongarch_tr_ops, &ctx.base, cs, tb, max_insns); -+} -+ -+void loongarch_tcg_init(void) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) -+ cpu_gpr[i] = tcg_global_mem_new( -+ cpu_env, offsetof(CPULOONGARCHState, active_tc.gpr[i]), -+ regnames[i]); -+ -+ for (i = 0; i < 32; i++) { -+ int off = offsetof(CPULOONGARCHState, active_fpu.fpr[i].d); -+ fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); -+ } -+ -+ cpu_PC = tcg_global_mem_new( -+ cpu_env, offsetof(CPULOONGARCHState, active_tc.PC), "PC"); -+ bcond = tcg_global_mem_new(cpu_env, offsetof(CPULOONGARCHState, bcond), -+ "bcond"); -+ btarget = tcg_global_mem_new(cpu_env, offsetof(CPULOONGARCHState, btarget), -+ "btarget"); -+ hflags = tcg_global_mem_new_i32( -+ cpu_env, offsetof(CPULOONGARCHState, hflags), "hflags"); -+ fpu_fcsr0 = tcg_global_mem_new_i32( -+ cpu_env, offsetof(CPULOONGARCHState, active_fpu.fcsr0), "fcsr0"); -+ cpu_lladdr = tcg_global_mem_new( -+ cpu_env, offsetof(CPULOONGARCHState, lladdr), "lladdr"); -+ cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPULOONGARCHState, llval), -+ "llval"); -+} -+ -+void restore_state_to_opc(CPULOONGARCHState *env, TranslationBlock *tb, -+ target_ulong *data) -+{ -+ env->active_tc.PC = data[0]; -+ env->hflags &= ~LARCH_HFLAG_BMASK; -+ env->hflags |= data[1]; -+ switch (env->hflags & LARCH_HFLAG_BMASK) { -+ case LARCH_HFLAG_BR: -+ break; -+ case LARCH_HFLAG_BC: -+ case LARCH_HFLAG_B: -+ env->btarget = data[2]; -+ break; -+ } -+} -diff --git a/target/meson.build b/target/meson.build -index ec6bc97331..a824a390f9 100644 ---- a/target/meson.build -+++ b/target/meson.build -@@ -5,6 +5,7 @@ subdir('cris') - subdir('hexagon') - subdir('hppa') - subdir('i386') -+subdir('loongarch64') - subdir('m68k') - subdir('microblaze') - subdir('mips') --- -2.27.0 - diff --git a/Add-tcg.patch b/Add-tcg.patch deleted file mode 100644 index b12f7b5320498de5459356ff9ad2d50cb3668d53..0000000000000000000000000000000000000000 --- a/Add-tcg.patch +++ /dev/null @@ -1,3009 +0,0 @@ -From 39d543dea10ff4995370e731be08017b6d3af76f Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Tue, 7 Feb 2023 07:21:51 -0500 -Subject: [PATCH] Add tcg. - -Add loongarch tcg related. - -Signed-off-by: lixianglai ---- - tcg/loongarch64/tcg-insn-defs.c.inc | 985 +++++++++++++++ - tcg/loongarch64/tcg-target-con-set.h | 39 + - tcg/loongarch64/tcg-target-con-str.h | 36 + - tcg/loongarch64/tcg-target.c.inc | 1727 ++++++++++++++++++++++++++ - tcg/loongarch64/tcg-target.h | 168 +++ - 5 files changed, 2955 insertions(+) - create mode 100644 tcg/loongarch64/tcg-insn-defs.c.inc - create mode 100644 tcg/loongarch64/tcg-target-con-set.h - create mode 100644 tcg/loongarch64/tcg-target-con-str.h - create mode 100644 tcg/loongarch64/tcg-target.c.inc - create mode 100644 tcg/loongarch64/tcg-target.h - -diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc b/tcg/loongarch64/tcg-insn-defs.c.inc -new file mode 100644 -index 0000000000..2a8fdad626 ---- /dev/null -+++ b/tcg/loongarch64/tcg-insn-defs.c.inc -@@ -0,0 +1,985 @@ -+/* -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ -+ */ -+ -+typedef enum { -+ OPC_CLZ_W = 0x00001400, -+ OPC_CTZ_W = 0x00001c00, -+ OPC_CLZ_D = 0x00002400, -+ OPC_CTZ_D = 0x00002c00, -+ OPC_REVB_2H = 0x00003000, -+ OPC_REVB_2W = 0x00003800, -+ OPC_REVB_D = 0x00003c00, -+ OPC_SEXT_H = 0x00005800, -+ OPC_SEXT_B = 0x00005c00, -+ OPC_ADD_W = 0x00100000, -+ OPC_ADD_D = 0x00108000, -+ OPC_SUB_W = 0x00110000, -+ OPC_SUB_D = 0x00118000, -+ OPC_SLT = 0x00120000, -+ OPC_SLTU = 0x00128000, -+ OPC_MASKEQZ = 0x00130000, -+ OPC_MASKNEZ = 0x00138000, -+ OPC_NOR = 0x00140000, -+ OPC_AND = 0x00148000, -+ OPC_OR = 0x00150000, -+ OPC_XOR = 0x00158000, -+ OPC_ORN = 0x00160000, -+ OPC_ANDN = 0x00168000, -+ OPC_SLL_W = 0x00170000, -+ OPC_SRL_W = 0x00178000, -+ OPC_SRA_W = 0x00180000, -+ OPC_SLL_D = 0x00188000, -+ OPC_SRL_D = 0x00190000, -+ OPC_SRA_D = 0x00198000, -+ OPC_ROTR_W = 0x001b0000, -+ OPC_ROTR_D = 0x001b8000, -+ OPC_MUL_W = 0x001c0000, -+ OPC_MULH_W = 0x001c8000, -+ OPC_MULH_WU = 0x001d0000, -+ OPC_MUL_D = 0x001d8000, -+ OPC_MULH_D = 0x001e0000, -+ OPC_MULH_DU = 0x001e8000, -+ OPC_DIV_W = 0x00200000, -+ OPC_MOD_W = 0x00208000, -+ OPC_DIV_WU = 0x00210000, -+ OPC_MOD_WU = 0x00218000, -+ OPC_DIV_D = 0x00220000, -+ OPC_MOD_D = 0x00228000, -+ OPC_DIV_DU = 0x00230000, -+ OPC_MOD_DU = 0x00238000, -+ OPC_SLLI_W = 0x00408000, -+ OPC_SLLI_D = 0x00410000, -+ OPC_SRLI_W = 0x00448000, -+ OPC_SRLI_D = 0x00450000, -+ OPC_SRAI_W = 0x00488000, -+ OPC_SRAI_D = 0x00490000, -+ OPC_ROTRI_W = 0x004c8000, -+ OPC_ROTRI_D = 0x004d0000, -+ OPC_BSTRINS_W = 0x00600000, -+ OPC_BSTRPICK_W = 0x00608000, -+ OPC_BSTRINS_D = 0x00800000, -+ OPC_BSTRPICK_D = 0x00c00000, -+ OPC_SLTI = 0x02000000, -+ OPC_SLTUI = 0x02400000, -+ OPC_ADDI_W = 0x02800000, -+ OPC_ADDI_D = 0x02c00000, -+ OPC_CU52I_D = 0x03000000, -+ OPC_ANDI = 0x03400000, -+ OPC_ORI = 0x03800000, -+ OPC_XORI = 0x03c00000, -+ OPC_LU12I_W = 0x14000000, -+ OPC_CU32I_D = 0x16000000, -+ OPC_PCADDU2I = 0x18000000, -+ OPC_PCALAU12I = 0x1a000000, -+ OPC_PCADDU12I = 0x1c000000, -+ OPC_PCADDU18I = 0x1e000000, -+ OPC_LD_B = 0x28000000, -+ OPC_LD_H = 0x28400000, -+ OPC_LD_W = 0x28800000, -+ OPC_LD_D = 0x28c00000, -+ OPC_ST_B = 0x29000000, -+ OPC_ST_H = 0x29400000, -+ OPC_ST_W = 0x29800000, -+ OPC_ST_D = 0x29c00000, -+ OPC_LD_BU = 0x2a000000, -+ OPC_LD_HU = 0x2a400000, -+ OPC_LD_WU = 0x2a800000, -+ OPC_LDX_B = 0x38000000, -+ OPC_LDX_H = 0x38040000, -+ OPC_LDX_W = 0x38080000, -+ OPC_LDX_D = 0x380c0000, -+ OPC_STX_B = 0x38100000, -+ OPC_STX_H = 0x38140000, -+ OPC_STX_W = 0x38180000, -+ OPC_STX_D = 0x381c0000, -+ OPC_LDX_BU = 0x38200000, -+ OPC_LDX_HU = 0x38240000, -+ OPC_LDX_WU = 0x38280000, -+ OPC_DBAR = 0x38720000, -+ OPC_JIRL = 0x4c000000, -+ OPC_B = 0x50000000, -+ OPC_BL = 0x54000000, -+ OPC_BEQ = 0x58000000, -+ OPC_BNE = 0x5c000000, -+ OPC_BGT = 0x60000000, -+ OPC_BLE = 0x64000000, -+ OPC_BGTU = 0x68000000, -+ OPC_BLEU = 0x6c000000, -+} LoongArchInsn; -+ -+static int32_t __attribute__((unused)) -+encode_d_slot(LoongArchInsn opc, uint32_t d) -+{ -+ return opc | d; -+} -+ -+static int32_t __attribute__((unused)) -+encode_dj_slots(LoongArchInsn opc, uint32_t d, uint32_t j) -+{ -+ return opc | d | j << 5; -+} -+ -+static int32_t __attribute__((unused)) -+encode_djk_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k) -+{ -+ return opc | d | j << 5 | k << 10; -+} -+ -+static int32_t __attribute__((unused)) -+encode_djkm_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k, -+ uint32_t m) -+{ -+ return opc | d | j << 5 | k << 10 | m << 16; -+} -+ -+static int32_t __attribute__((unused)) -+encode_dk_slots(LoongArchInsn opc, uint32_t d, uint32_t k) -+{ -+ return opc | d | k << 10; -+} -+ -+static int32_t __attribute__((unused)) -+encode_dj_insn(LoongArchInsn opc, TCGReg d, TCGReg j) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ return encode_dj_slots(opc, d, j); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djk_insn(LoongArchInsn opc, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(k >= 0 && k <= 0x1f); -+ return encode_djk_slots(opc, d, j, k); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djsk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(sk12 >= -0x800 && sk12 <= 0x7ff); -+ return encode_djk_slots(opc, d, j, sk12 & 0xfff); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djsk16_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(sk16 >= -0x8000 && sk16 <= 0x7fff); -+ return encode_djk_slots(opc, d, j, sk16 & 0xffff); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk12) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk12 <= 0xfff); -+ return encode_djk_slots(opc, d, j, uk12); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk5_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk5 <= 0x1f); -+ return encode_djk_slots(opc, d, j, uk5); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk5um5_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk5, -+ uint32_t um5) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk5 <= 0x1f); -+ tcg_debug_assert(um5 <= 0x1f); -+ return encode_djkm_slots(opc, d, j, uk5, um5); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk6_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk6 <= 0x3f); -+ return encode_djk_slots(opc, d, j, uk6); -+} -+ -+static int32_t __attribute__((unused)) -+encode_djuk6um6_insn(LoongArchInsn opc, TCGReg d, TCGReg j, uint32_t uk6, -+ uint32_t um6) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(j >= 0 && j <= 0x1f); -+ tcg_debug_assert(uk6 <= 0x3f); -+ tcg_debug_assert(um6 <= 0x3f); -+ return encode_djkm_slots(opc, d, j, uk6, um6); -+} -+ -+static int32_t __attribute__((unused)) -+encode_dsj20_insn(LoongArchInsn opc, TCGReg d, int32_t sj20) -+{ -+ tcg_debug_assert(d >= 0 && d <= 0x1f); -+ tcg_debug_assert(sj20 >= -0x80000 && sj20 <= 0x7ffff); -+ return encode_dj_slots(opc, d, sj20 & 0xfffff); -+} -+ -+static int32_t __attribute__((unused)) -+encode_sd10k16_insn(LoongArchInsn opc, int32_t sd10k16) -+{ -+ tcg_debug_assert(sd10k16 >= -0x2000000 && sd10k16 <= 0x1ffffff); -+ return encode_dk_slots(opc, (sd10k16 >> 16) & 0x3ff, sd10k16 & 0xffff); -+} -+ -+static int32_t __attribute__((unused)) -+encode_ud15_insn(LoongArchInsn opc, uint32_t ud15) -+{ -+ tcg_debug_assert(ud15 <= 0x7fff); -+ return encode_d_slot(opc, ud15); -+} -+ -+/* Emits the `clz.w d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_clz_w(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_CLZ_W, d, j)); -+} -+ -+/* Emits the `ctz.w d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ctz_w(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_CTZ_W, d, j)); -+} -+ -+/* Emits the `clz.d d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_clz_d(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_CLZ_D, d, j)); -+} -+ -+/* Emits the `ctz.d d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ctz_d(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_CTZ_D, d, j)); -+} -+ -+/* Emits the `revb.2h d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_revb_2h(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_REVB_2H, d, j)); -+} -+ -+/* Emits the `revb.2w d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_revb_2w(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_REVB_2W, d, j)); -+} -+ -+/* Emits the `revb.d d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_revb_d(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_REVB_D, d, j)); -+} -+ -+/* Emits the `sext.h d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sext_h(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_SEXT_H, d, j)); -+} -+ -+/* Emits the `sext.b d, j` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sext_b(TCGContext *s, TCGReg d, TCGReg j) -+{ -+ tcg_out32(s, encode_dj_insn(OPC_SEXT_B, d, j)); -+} -+ -+/* Emits the `add.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_add_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ADD_W, d, j, k)); -+} -+ -+/* Emits the `add.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_add_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ADD_D, d, j, k)); -+} -+ -+/* Emits the `sub.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sub_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SUB_W, d, j, k)); -+} -+ -+/* Emits the `sub.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sub_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SUB_D, d, j, k)); -+} -+ -+/* Emits the `slt d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_slt(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SLT, d, j, k)); -+} -+ -+/* Emits the `sltu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sltu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SLTU, d, j, k)); -+} -+ -+/* Emits the `maskeqz d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_maskeqz(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MASKEQZ, d, j, k)); -+} -+ -+/* Emits the `masknez d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_masknez(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MASKNEZ, d, j, k)); -+} -+ -+/* Emits the `nor d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_nor(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_NOR, d, j, k)); -+} -+ -+/* Emits the `and d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_and(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_AND, d, j, k)); -+} -+ -+/* Emits the `or d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_or(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_OR, d, j, k)); -+} -+ -+/* Emits the `xor d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_xor(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_XOR, d, j, k)); -+} -+ -+/* Emits the `orn d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_orn(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ORN, d, j, k)); -+} -+ -+/* Emits the `andn d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_andn(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ANDN, d, j, k)); -+} -+ -+/* Emits the `sll.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sll_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SLL_W, d, j, k)); -+} -+ -+/* Emits the `srl.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srl_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SRL_W, d, j, k)); -+} -+ -+/* Emits the `sra.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sra_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SRA_W, d, j, k)); -+} -+ -+/* Emits the `sll.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sll_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SLL_D, d, j, k)); -+} -+ -+/* Emits the `srl.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srl_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SRL_D, d, j, k)); -+} -+ -+/* Emits the `sra.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sra_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_SRA_D, d, j, k)); -+} -+ -+/* Emits the `rotr.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_rotr_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ROTR_W, d, j, k)); -+} -+ -+/* Emits the `rotr.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_rotr_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_ROTR_D, d, j, k)); -+} -+ -+/* Emits the `mul.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mul_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MUL_W, d, j, k)); -+} -+ -+/* Emits the `mulh.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mulh_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MULH_W, d, j, k)); -+} -+ -+/* Emits the `mulh.wu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mulh_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MULH_WU, d, j, k)); -+} -+ -+/* Emits the `mul.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mul_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MUL_D, d, j, k)); -+} -+ -+/* Emits the `mulh.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mulh_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MULH_D, d, j, k)); -+} -+ -+/* Emits the `mulh.du d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mulh_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MULH_DU, d, j, k)); -+} -+ -+/* Emits the `div.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_div_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_DIV_W, d, j, k)); -+} -+ -+/* Emits the `mod.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mod_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MOD_W, d, j, k)); -+} -+ -+/* Emits the `div.wu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_div_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_DIV_WU, d, j, k)); -+} -+ -+/* Emits the `mod.wu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mod_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MOD_WU, d, j, k)); -+} -+ -+/* Emits the `div.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_div_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_DIV_D, d, j, k)); -+} -+ -+/* Emits the `mod.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mod_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MOD_D, d, j, k)); -+} -+ -+/* Emits the `div.du d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_div_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_DIV_DU, d, j, k)); -+} -+ -+/* Emits the `mod.du d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_mod_du(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_MOD_DU, d, j, k)); -+} -+ -+/* Emits the `slli.w d, j, uk5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_slli_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_out32(s, encode_djuk5_insn(OPC_SLLI_W, d, j, uk5)); -+} -+ -+/* Emits the `slli.d d, j, uk6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_slli_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_out32(s, encode_djuk6_insn(OPC_SLLI_D, d, j, uk6)); -+} -+ -+/* Emits the `srli.w d, j, uk5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srli_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_out32(s, encode_djuk5_insn(OPC_SRLI_W, d, j, uk5)); -+} -+ -+/* Emits the `srli.d d, j, uk6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srli_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_out32(s, encode_djuk6_insn(OPC_SRLI_D, d, j, uk6)); -+} -+ -+/* Emits the `srai.w d, j, uk5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srai_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_out32(s, encode_djuk5_insn(OPC_SRAI_W, d, j, uk5)); -+} -+ -+/* Emits the `srai.d d, j, uk6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_srai_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_out32(s, encode_djuk6_insn(OPC_SRAI_D, d, j, uk6)); -+} -+ -+/* Emits the `rotri.w d, j, uk5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_rotri_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5) -+{ -+ tcg_out32(s, encode_djuk5_insn(OPC_ROTRI_W, d, j, uk5)); -+} -+ -+/* Emits the `rotri.d d, j, uk6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_rotri_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6) -+{ -+ tcg_out32(s, encode_djuk6_insn(OPC_ROTRI_D, d, j, uk6)); -+} -+ -+/* Emits the `bstrins.w d, j, uk5, um5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bstrins_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5, -+ uint32_t um5) -+{ -+ tcg_out32(s, encode_djuk5um5_insn(OPC_BSTRINS_W, d, j, uk5, um5)); -+} -+ -+/* Emits the `bstrpick.w d, j, uk5, um5` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bstrpick_w(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk5, -+ uint32_t um5) -+{ -+ tcg_out32(s, encode_djuk5um5_insn(OPC_BSTRPICK_W, d, j, uk5, um5)); -+} -+ -+/* Emits the `bstrins.d d, j, uk6, um6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bstrins_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6, -+ uint32_t um6) -+{ -+ tcg_out32(s, encode_djuk6um6_insn(OPC_BSTRINS_D, d, j, uk6, um6)); -+} -+ -+/* Emits the `bstrpick.d d, j, uk6, um6` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bstrpick_d(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk6, -+ uint32_t um6) -+{ -+ tcg_out32(s, encode_djuk6um6_insn(OPC_BSTRPICK_D, d, j, uk6, um6)); -+} -+ -+/* Emits the `slti d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_slti(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_SLTI, d, j, sk12)); -+} -+ -+/* Emits the `sltui d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_sltui(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_SLTUI, d, j, sk12)); -+} -+ -+/* Emits the `addi.w d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_addi_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ADDI_W, d, j, sk12)); -+} -+ -+/* Emits the `addi.d d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_addi_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ADDI_D, d, j, sk12)); -+} -+ -+/* Emits the `cu52i.d d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_cu52i_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_CU52I_D, d, j, sk12)); -+} -+ -+/* Emits the `andi d, j, uk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_andi(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) -+{ -+ tcg_out32(s, encode_djuk12_insn(OPC_ANDI, d, j, uk12)); -+} -+ -+/* Emits the `ori d, j, uk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) -+{ -+ tcg_out32(s, encode_djuk12_insn(OPC_ORI, d, j, uk12)); -+} -+ -+/* Emits the `xori d, j, uk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_xori(TCGContext *s, TCGReg d, TCGReg j, uint32_t uk12) -+{ -+ tcg_out32(s, encode_djuk12_insn(OPC_XORI, d, j, uk12)); -+} -+ -+/* Emits the `lu12i.w d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_lu12i_w(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_LU12I_W, d, sj20)); -+} -+ -+/* Emits the `cu32i.d d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_cu32i_d(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_CU32I_D, d, sj20)); -+} -+ -+/* Emits the `pcaddu2i d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_pcaddu2i(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU2I, d, sj20)); -+} -+ -+/* Emits the `pcalau12i d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_pcalau12i(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_PCALAU12I, d, sj20)); -+} -+ -+/* Emits the `pcaddu12i d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_pcaddu12i(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU12I, d, sj20)); -+} -+ -+/* Emits the `pcaddu18i d, sj20` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_pcaddu18i(TCGContext *s, TCGReg d, int32_t sj20) -+{ -+ tcg_out32(s, encode_dsj20_insn(OPC_PCADDU18I, d, sj20)); -+} -+ -+/* Emits the `ld.b d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_b(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_B, d, j, sk12)); -+} -+ -+/* Emits the `ld.h d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_h(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_H, d, j, sk12)); -+} -+ -+/* Emits the `ld.w d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_W, d, j, sk12)); -+} -+ -+/* Emits the `ld.d d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_D, d, j, sk12)); -+} -+ -+/* Emits the `st.b d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_st_b(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ST_B, d, j, sk12)); -+} -+ -+/* Emits the `st.h d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_st_h(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ST_H, d, j, sk12)); -+} -+ -+/* Emits the `st.w d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_st_w(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ST_W, d, j, sk12)); -+} -+ -+/* Emits the `st.d d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_st_d(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_ST_D, d, j, sk12)); -+} -+ -+/* Emits the `ld.bu d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_bu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_BU, d, j, sk12)); -+} -+ -+/* Emits the `ld.hu d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_hu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_HU, d, j, sk12)); -+} -+ -+/* Emits the `ld.wu d, j, sk12` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ld_wu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk12) -+{ -+ tcg_out32(s, encode_djsk12_insn(OPC_LD_WU, d, j, sk12)); -+} -+ -+/* Emits the `ldx.b d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_b(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_B, d, j, k)); -+} -+ -+/* Emits the `ldx.h d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_h(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_H, d, j, k)); -+} -+ -+/* Emits the `ldx.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_W, d, j, k)); -+} -+ -+/* Emits the `ldx.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_D, d, j, k)); -+} -+ -+/* Emits the `stx.b d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_stx_b(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_STX_B, d, j, k)); -+} -+ -+/* Emits the `stx.h d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_stx_h(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_STX_H, d, j, k)); -+} -+ -+/* Emits the `stx.w d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_stx_w(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_STX_W, d, j, k)); -+} -+ -+/* Emits the `stx.d d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_stx_d(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_STX_D, d, j, k)); -+} -+ -+/* Emits the `ldx.bu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_bu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_BU, d, j, k)); -+} -+ -+/* Emits the `ldx.hu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_hu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_HU, d, j, k)); -+} -+ -+/* Emits the `ldx.wu d, j, k` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ldx_wu(TCGContext *s, TCGReg d, TCGReg j, TCGReg k) -+{ -+ tcg_out32(s, encode_djk_insn(OPC_LDX_WU, d, j, k)); -+} -+ -+/* Emits the `dbar ud15` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_dbar(TCGContext *s, uint32_t ud15) -+{ -+ tcg_out32(s, encode_ud15_insn(OPC_DBAR, ud15)); -+} -+ -+/* Emits the `jirl d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_jirl(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_JIRL, d, j, sk16)); -+} -+ -+/* Emits the `b sd10k16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_b(TCGContext *s, int32_t sd10k16) -+{ -+ tcg_out32(s, encode_sd10k16_insn(OPC_B, sd10k16)); -+} -+ -+/* Emits the `bl sd10k16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bl(TCGContext *s, int32_t sd10k16) -+{ -+ tcg_out32(s, encode_sd10k16_insn(OPC_BL, sd10k16)); -+} -+ -+/* Emits the `beq d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_beq(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BEQ, d, j, sk16)); -+} -+ -+/* Emits the `bne d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bne(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BNE, d, j, sk16)); -+} -+ -+/* Emits the `bgt d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bgt(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BGT, d, j, sk16)); -+} -+ -+/* Emits the `ble d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_ble(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BLE, d, j, sk16)); -+} -+ -+/* Emits the `bgtu d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bgtu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BGTU, d, j, sk16)); -+} -+ -+/* Emits the `bleu d, j, sk16` instruction. */ -+static void __attribute__((unused)) -+tcg_out_opc_bleu(TCGContext *s, TCGReg d, TCGReg j, int32_t sk16) -+{ -+ tcg_out32(s, encode_djsk16_insn(OPC_BLEU, d, j, sk16)); -+} -+/* End of generated code. */ -diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h -new file mode 100644 -index 0000000000..7b0297034f ---- /dev/null -+++ b/tcg/loongarch64/tcg-target-con-set.h -@@ -0,0 +1,39 @@ -+/* -+ * Define LoongArch target-specific constraint sets. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+/* -+ * C_On_Im(...) defines a constraint set with outputs and inputs. -+ * Each operand should be a sequence of constraint letters as defined by -+ * tcg-target-con-str.h; the constraint combination is inclusive or. -+ */ -+C_O0_I1(r) -+C_O0_I2(rZ, r) -+C_O0_I2(rZ, rZ) -+C_O0_I2(LZ, L) -+C_O1_I1(r, r) -+C_O1_I1(r, L) -+C_O1_I2(r, r, rC) -+C_O1_I2(r, r, ri) -+C_O1_I2(r, r, rI) -+C_O1_I2(r, r, rU) -+C_O1_I2(r, r, rW) -+C_O1_I2(r, r, rZ) -+C_O1_I2(r, 0, rZ) -+C_O1_I2(r, rZ, rN) -+C_O1_I2(r, rZ, rZ) -diff --git a/tcg/loongarch64/tcg-target-con-str.h b/tcg/loongarch64/tcg-target-con-str.h -new file mode 100644 -index 0000000000..b105f5ebd8 ---- /dev/null -+++ b/tcg/loongarch64/tcg-target-con-str.h -@@ -0,0 +1,36 @@ -+/* -+ * Define LoongArch target-specific operand constraints. -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+/* -+ * Define constraint letters for register sets: -+ * REGS(letter, register_mask) -+ */ -+REGS('r', ALL_GENERAL_REGS) -+REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS) -+ -+/* -+ * Define constraint letters for constants: -+ * CONST(letter, TCG_CT_CONST_* bit set) -+ */ -+CONST('I', TCG_CT_CONST_S12) -+CONST('N', TCG_CT_CONST_N12) -+CONST('U', TCG_CT_CONST_U12) -+CONST('Z', TCG_CT_CONST_ZERO) -+CONST('C', TCG_CT_CONST_C12) -+CONST('W', TCG_CT_CONST_WSZ) -diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc -new file mode 100644 -index 0000000000..0b28b30002 ---- /dev/null -+++ b/tcg/loongarch64/tcg-target.c.inc -@@ -0,0 +1,1727 @@ -+/* -+ * Tiny Code Generator for QEMU -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#include "../tcg-ldst.c.inc" -+ -+#ifdef CONFIG_DEBUG_TCG -+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { -+ "zero", -+ "ra", -+ "tp", -+ "sp", -+ "a0", -+ "a1", -+ "a2", -+ "a3", -+ "a4", -+ "a5", -+ "a6", -+ "a7", -+ "t0", -+ "t1", -+ "t2", -+ "t3", -+ "t4", -+ "t5", -+ "t6", -+ "t7", -+ "t8", -+ "r21", /* reserved in the LP64* ABI, hence no ABI name */ -+ "s9", -+ "s0", -+ "s1", -+ "s2", -+ "s3", -+ "s4", -+ "s5", -+ "s6", -+ "s7", -+ "s8" -+}; -+#endif -+ -+static const int tcg_target_reg_alloc_order[] = { -+ /* Registers preserved across calls */ -+ /* TCG_REG_S0 reserved for TCG_AREG0 */ -+ TCG_REG_S1, -+ TCG_REG_S2, -+ TCG_REG_S3, -+ TCG_REG_S4, -+ TCG_REG_S5, -+ TCG_REG_S6, -+ TCG_REG_S7, -+ TCG_REG_S8, -+ TCG_REG_S9, -+ -+ /* Registers (potentially) clobbered across calls */ -+ TCG_REG_T0, -+ TCG_REG_T1, -+ TCG_REG_T2, -+ TCG_REG_T3, -+ TCG_REG_T4, -+ TCG_REG_T5, -+ TCG_REG_T6, -+ TCG_REG_T7, -+ TCG_REG_T8, -+ -+ /* Argument registers, opposite order of allocation. */ -+ TCG_REG_A7, -+ TCG_REG_A6, -+ TCG_REG_A5, -+ TCG_REG_A4, -+ TCG_REG_A3, -+ TCG_REG_A2, -+ TCG_REG_A1, -+ TCG_REG_A0, -+}; -+ -+static const int tcg_target_call_iarg_regs[] = { -+ TCG_REG_A0, -+ TCG_REG_A1, -+ TCG_REG_A2, -+ TCG_REG_A3, -+ TCG_REG_A4, -+ TCG_REG_A5, -+ TCG_REG_A6, -+ TCG_REG_A7, -+}; -+ -+static const int tcg_target_call_oarg_regs[] = { -+ TCG_REG_A0, -+ TCG_REG_A1, -+}; -+ -+#ifndef CONFIG_SOFTMMU -+#define USE_GUEST_BASE (guest_base != 0) -+#define TCG_GUEST_BASE_REG TCG_REG_S1 -+#endif -+ -+#define TCG_CT_CONST_ZERO 0x100 -+#define TCG_CT_CONST_S12 0x200 -+#define TCG_CT_CONST_N12 0x400 -+#define TCG_CT_CONST_U12 0x800 -+#define TCG_CT_CONST_C12 0x1000 -+#define TCG_CT_CONST_WSZ 0x2000 -+ -+#define ALL_GENERAL_REGS MAKE_64BIT_MASK(0, 32) -+/* -+ * For softmmu, we need to avoid conflicts with the first 5 -+ * argument registers to call the helper. Some of these are -+ * also used for the tlb lookup. -+ */ -+#ifdef CONFIG_SOFTMMU -+#define SOFTMMU_RESERVE_REGS MAKE_64BIT_MASK(TCG_REG_A0, 5) -+#else -+#define SOFTMMU_RESERVE_REGS 0 -+#endif -+ -+static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len) -+{ -+ return sextract64(val, pos, len); -+} -+ -+/* test if a constant matches the constraint */ -+static bool tcg_target_const_match(int64_t val, TCGType type, int ct) -+{ -+ if (ct & TCG_CT_CONST) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_ZERO) && val == 0) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_C12) && ~val >= 0 && ~val <= 0xfff) { -+ return true; -+ } -+ if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) { -+ return true; -+ } -+ return false; -+} -+ -+/* -+ * Relocations -+ */ -+ -+/* -+ * Relocation records defined in LoongArch ELF psABI v1.00 is way too -+ * complicated; a whopping stack machine is needed to stuff the fields, at -+ * the very least one SOP_PUSH and one SOP_POP (of the correct format) are -+ * needed. -+ * -+ * Hence, define our own simpler relocation types. Numbers are chosen as to -+ * not collide with potential future additions to the true ELF relocation -+ * type enum. -+ */ -+ -+/* Field Sk16, shifted right by 2; suitable for conditional jumps */ -+#define R_LOONGARCH_BR_SK16 256 -+/* Field Sd10k16, shifted right by 2; suitable for B and BL */ -+#define R_LOONGARCH_BR_SD10K16 257 -+ -+static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit *target) -+{ -+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); -+ intptr_t offset = (intptr_t)target - (intptr_t)src_rx; -+ -+ tcg_debug_assert((offset & 3) == 0); -+ offset >>= 2; -+ if (offset == sextreg(offset, 0, 16)) { -+ *src_rw = deposit64(*src_rw, 10, 16, offset); -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool reloc_br_sd10k16(tcg_insn_unit *src_rw, -+ const tcg_insn_unit *target) -+{ -+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); -+ intptr_t offset = (intptr_t)target - (intptr_t)src_rx; -+ -+ tcg_debug_assert((offset & 3) == 0); -+ offset >>= 2; -+ if (offset == sextreg(offset, 0, 26)) { -+ *src_rw = deposit64(*src_rw, 0, 10, offset >> 16); /* slot d10 */ -+ *src_rw = deposit64(*src_rw, 10, 16, offset); /* slot k16 */ -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool patch_reloc(tcg_insn_unit *code_ptr, int type, intptr_t value, -+ intptr_t addend) -+{ -+ tcg_debug_assert(addend == 0); -+ switch (type) { -+ case R_LOONGARCH_BR_SK16: -+ return reloc_br_sk16(code_ptr, (tcg_insn_unit *)value); -+ case R_LOONGARCH_BR_SD10K16: -+ return reloc_br_sd10k16(code_ptr, (tcg_insn_unit *)value); -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+#include "tcg-insn-defs.c.inc" -+ -+/* -+ * TCG intrinsics -+ */ -+ -+static void tcg_out_mb(TCGContext *s, TCGArg a0) -+{ -+ /* Baseline LoongArch only has the full barrier, unfortunately. */ -+ tcg_out_opc_dbar(s, 0); -+} -+ -+static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) -+{ -+ if (ret == arg) { -+ return true; -+ } -+ switch (type) { -+ case TCG_TYPE_I32: -+ case TCG_TYPE_I64: -+ /* -+ * Conventional register-register move used in LoongArch is -+ * `or dst, src, zero`. -+ */ -+ tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+ return true; -+} -+ -+static bool imm_part_needs_loading(bool high_bits_are_ones, -+ tcg_target_long part) -+{ -+ if (high_bits_are_ones) { -+ return part != -1; -+ } else { -+ return part != 0; -+ } -+} -+ -+/* Loads a 32-bit immediate into rd, sign-extended. */ -+static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val) -+{ -+ tcg_target_long lo = sextreg(val, 0, 12); -+ tcg_target_long hi12 = sextreg(val, 12, 20); -+ -+ /* Single-instruction cases. */ -+ if (lo == val) { -+ /* val fits in simm12: addi.w rd, zero, val */ -+ tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val); -+ return; -+ } -+ if (0x800 <= val && val <= 0xfff) { -+ /* val fits in uimm12: ori rd, zero, val */ -+ tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val); -+ return; -+ } -+ -+ /* High bits must be set; load with lu12i.w + optional ori. */ -+ tcg_out_opc_lu12i_w(s, rd, hi12); -+ if (lo != 0) { -+ tcg_out_opc_ori(s, rd, rd, lo & 0xfff); -+ } -+} -+ -+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, -+ tcg_target_long val) -+{ -+ /* -+ * LoongArch conventionally loads 64-bit immediates in at most 4 steps, -+ * with dedicated instructions for filling the respective bitfields -+ * below: -+ * -+ * 6 5 4 3 -+ * 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 -+ * +-----------------------+---------------------------------------+... -+ * | hi52 | hi32 | -+ * +-----------------------+---------------------------------------+... -+ * 3 2 1 -+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -+ * ...+-------------------------------------+-------------------------+ -+ * | hi12 | lo | -+ * ...+-------------------------------------+-------------------------+ -+ * -+ * Check if val belong to one of the several fast cases, before falling -+ * back to the slow path. -+ */ -+ -+ intptr_t pc_offset; -+ tcg_target_long val_lo, val_hi, pc_hi, offset_hi; -+ tcg_target_long hi32, hi52; -+ bool rd_high_bits_are_ones; -+ -+ /* Value fits in signed i32. */ -+ if (type == TCG_TYPE_I32 || val == (int32_t)val) { -+ tcg_out_movi_i32(s, rd, val); -+ return; -+ } -+ -+ /* PC-relative cases. */ -+ pc_offset = tcg_pcrel_diff(s, (void *)val); -+ if (pc_offset == sextreg(pc_offset, 0, 22) && (pc_offset & 3) == 0) { -+ /* Single pcaddu2i. */ -+ tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2); -+ return; -+ } -+ -+ if (pc_offset == (int32_t)pc_offset) { -+ /* Offset within 32 bits; load with pcalau12i + ori. */ -+ val_lo = sextreg(val, 0, 12); -+ val_hi = val >> 12; -+ pc_hi = (val - pc_offset) >> 12; -+ offset_hi = val_hi - pc_hi; -+ -+ tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20)); -+ tcg_out_opc_pcalau12i(s, rd, offset_hi); -+ if (val_lo != 0) { -+ tcg_out_opc_ori(s, rd, rd, val_lo & 0xfff); -+ } -+ return; -+ } -+ -+ hi32 = sextreg(val, 32, 20); -+ hi52 = sextreg(val, 52, 12); -+ -+ /* Single cu52i.d case. */ -+ if (ctz64(val) >= 52) { -+ tcg_out_opc_cu52i_d(s, rd, TCG_REG_ZERO, hi52); -+ return; -+ } -+ -+ /* Slow path. Initialize the low 32 bits, then concat high bits. */ -+ tcg_out_movi_i32(s, rd, val); -+ rd_high_bits_are_ones = (int32_t)val < 0; -+ -+ if (imm_part_needs_loading(rd_high_bits_are_ones, hi32)) { -+ tcg_out_opc_cu32i_d(s, rd, hi32); -+ rd_high_bits_are_ones = hi32 < 0; -+ } -+ -+ if (imm_part_needs_loading(rd_high_bits_are_ones, hi52)) { -+ tcg_out_opc_cu52i_d(s, rd, rd, hi52); -+ } -+} -+ -+static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_andi(s, ret, arg, 0xff); -+} -+ -+static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_bstrpick_w(s, ret, arg, 0, 15); -+} -+ -+static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31); -+} -+ -+static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_sext_b(s, ret, arg); -+} -+ -+static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_sext_h(s, ret, arg); -+} -+ -+static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg) -+{ -+ tcg_out_opc_addi_w(s, ret, arg, 0); -+} -+ -+static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc, TCGReg a0, -+ TCGReg a1, TCGReg a2, bool c2, bool is_32bit) -+{ -+ if (c2) { -+ /* -+ * Fast path: semantics already satisfied due to constraint and -+ * insn behavior, single instruction is enough. -+ */ -+ tcg_debug_assert(a2 == (is_32bit ? 32 : 64)); -+ /* all clz/ctz insns belong to DJ-format */ -+ tcg_out32(s, encode_dj_insn(opc, a0, a1)); -+ return; -+ } -+ -+ tcg_out32(s, encode_dj_insn(opc, TCG_REG_TMP0, a1)); -+ /* a0 = a1 ? REG_TMP0 : a2 */ -+ tcg_out_opc_maskeqz(s, TCG_REG_TMP0, TCG_REG_TMP0, a1); -+ tcg_out_opc_masknez(s, a0, a2, a1); -+ tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0); -+} -+ -+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, -+ TCGReg arg1, TCGReg arg2, bool c2) -+{ -+ TCGReg tmp; -+ -+ if (c2) { -+ tcg_debug_assert(arg2 == 0); -+ } -+ -+ switch (cond) { -+ case TCG_COND_EQ: -+ if (c2) { -+ tmp = arg1; -+ } else { -+ tcg_out_opc_sub_d(s, ret, arg1, arg2); -+ tmp = ret; -+ } -+ tcg_out_opc_sltui(s, ret, tmp, 1); -+ break; -+ case TCG_COND_NE: -+ if (c2) { -+ tmp = arg1; -+ } else { -+ tcg_out_opc_sub_d(s, ret, arg1, arg2); -+ tmp = ret; -+ } -+ tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp); -+ break; -+ case TCG_COND_LT: -+ tcg_out_opc_slt(s, ret, arg1, arg2); -+ break; -+ case TCG_COND_GE: -+ tcg_out_opc_slt(s, ret, arg1, arg2); -+ tcg_out_opc_xori(s, ret, ret, 1); -+ break; -+ case TCG_COND_LE: -+ tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, false); -+ break; -+ case TCG_COND_GT: -+ tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, false); -+ break; -+ case TCG_COND_LTU: -+ tcg_out_opc_sltu(s, ret, arg1, arg2); -+ break; -+ case TCG_COND_GEU: -+ tcg_out_opc_sltu(s, ret, arg1, arg2); -+ tcg_out_opc_xori(s, ret, ret, 1); -+ break; -+ case TCG_COND_LEU: -+ tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, false); -+ break; -+ case TCG_COND_GTU: -+ tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, false); -+ break; -+ default: -+ g_assert_not_reached(); -+ break; -+ } -+} -+ -+/* -+ * Branch helpers -+ */ -+ -+static const struct { -+ LoongArchInsn op; -+ bool swap; -+} tcg_brcond_to_loongarch[] = { -+ [TCG_COND_EQ] = { OPC_BEQ, false }, [TCG_COND_NE] = { OPC_BNE, false }, -+ [TCG_COND_LT] = { OPC_BGT, true }, [TCG_COND_GE] = { OPC_BLE, true }, -+ [TCG_COND_LE] = { OPC_BLE, false }, [TCG_COND_GT] = { OPC_BGT, false }, -+ [TCG_COND_LTU] = { OPC_BGTU, true }, [TCG_COND_GEU] = { OPC_BLEU, true }, -+ [TCG_COND_LEU] = { OPC_BLEU, false }, [TCG_COND_GTU] = { OPC_BGTU, false } -+}; -+ -+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1, -+ TCGReg arg2, TCGLabel *l) -+{ -+ LoongArchInsn op = tcg_brcond_to_loongarch[cond].op; -+ -+ tcg_debug_assert(op != 0); -+ -+ if (tcg_brcond_to_loongarch[cond].swap) { -+ TCGReg t = arg1; -+ arg1 = arg2; -+ arg2 = t; -+ } -+ -+ /* all conditional branch insns belong to DJSk16-format */ -+ tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SK16, l, 0); -+ tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0)); -+} -+ -+static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, -+ bool tail) -+{ -+ TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA; -+ ptrdiff_t offset = tcg_pcrel_diff(s, arg); -+ -+ tcg_debug_assert((offset & 3) == 0); -+ if (offset == sextreg(offset, 0, 28)) { -+ /* short jump: +/- 256MiB */ -+ if (tail) { -+ tcg_out_opc_b(s, offset >> 2); -+ } else { -+ tcg_out_opc_bl(s, offset >> 2); -+ } -+ } else if (offset == sextreg(offset, 0, 38)) { -+ /* long jump: +/- 256GiB */ -+ tcg_target_long lo = sextreg(offset, 0, 18); -+ tcg_target_long hi = offset - lo; -+ tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, hi >> 18); -+ tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2); -+ } else { -+ /* far jump: 64-bit */ -+ tcg_target_long lo = sextreg((tcg_target_long)arg, 0, 18); -+ tcg_target_long hi = (tcg_target_long)arg - lo; -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, hi); -+ tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2); -+ } -+} -+ -+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg) -+{ -+ tcg_out_call_int(s, arg, false); -+} -+ -+/* -+ * Load/store helpers -+ */ -+ -+static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data, -+ TCGReg addr, intptr_t offset) -+{ -+ intptr_t imm12 = sextreg(offset, 0, 12); -+ -+ if (offset != imm12) { -+ intptr_t diff = offset - (uintptr_t)s->code_ptr; -+ -+ if (addr == TCG_REG_ZERO && diff == (int32_t)diff) { -+ imm12 = sextreg(diff, 0, 12); -+ tcg_out_opc_pcaddu12i(s, TCG_REG_TMP2, (diff - imm12) >> 12); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12); -+ if (addr != TCG_REG_ZERO) { -+ tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, addr); -+ } -+ } -+ addr = TCG_REG_TMP2; -+ } -+ -+ switch (opc) { -+ case OPC_LD_B: -+ case OPC_LD_BU: -+ case OPC_LD_H: -+ case OPC_LD_HU: -+ case OPC_LD_W: -+ case OPC_LD_WU: -+ case OPC_LD_D: -+ case OPC_ST_B: -+ case OPC_ST_H: -+ case OPC_ST_W: -+ case OPC_ST_D: -+ tcg_out32(s, encode_djsk12_insn(opc, data, addr, imm12)); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, -+ intptr_t arg2) -+{ -+ bool is_32bit = type == TCG_TYPE_I32; -+ tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2); -+} -+ -+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1, -+ intptr_t arg2) -+{ -+ bool is_32bit = type == TCG_TYPE_I32; -+ tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2); -+} -+ -+static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, TCGReg base, -+ intptr_t ofs) -+{ -+ if (val == 0) { -+ tcg_out_st(s, type, TCG_REG_ZERO, base, ofs); -+ return true; -+ } -+ return false; -+} -+ -+/* -+ * Load/store helpers for SoftMMU, and qemu_ld/st implementations -+ */ -+ -+#if defined(CONFIG_SOFTMMU) -+/* -+ * helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, -+ * MemOpIdx oi, uintptr_t ra) -+ */ -+static void *const qemu_ld_helpers[4] = { -+ [MO_8] = helper_ret_ldub_mmu, -+ [MO_16] = helper_le_lduw_mmu, -+ [MO_32] = helper_le_ldul_mmu, -+ [MO_64] = helper_le_ldq_mmu, -+}; -+ -+/* -+ * helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr, -+ * uintxx_t val, MemOpIdx oi, -+ * uintptr_t ra) -+ */ -+static void *const qemu_st_helpers[4] = { -+ [MO_8] = helper_ret_stb_mmu, -+ [MO_16] = helper_le_stw_mmu, -+ [MO_32] = helper_le_stl_mmu, -+ [MO_64] = helper_le_stq_mmu, -+}; -+ -+/* We expect to use a 12-bit negative offset from ENV. */ -+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); -+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11)); -+ -+static bool tcg_out_goto(TCGContext *s, const tcg_insn_unit *target) -+{ -+ tcg_out_opc_b(s, 0); -+ return reloc_br_sd10k16(s->code_ptr - 1, target); -+} -+ -+/* -+ * Emits common code for TLB addend lookup, that eventually loads the -+ * addend in TCG_REG_TMP2. -+ */ -+static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, MemOpIdx oi, -+ tcg_insn_unit **label_ptr, bool is_load) -+{ -+ MemOp opc = get_memop(oi); -+ unsigned s_bits = opc & MO_SIZE; -+ unsigned a_bits = get_alignment_bits(opc); -+ tcg_target_long compare_mask; -+ int mem_index = get_mmuidx(oi); -+ int fast_ofs = TLB_MASK_TABLE_OFS(mem_index); -+ int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask); -+ int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table); -+ -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs); -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs); -+ -+ tcg_out_opc_srli_d(s, TCG_REG_TMP2, addrl, -+ TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); -+ tcg_out_opc_and(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP0); -+ tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1); -+ -+ /* Load the tlb comparator and the addend. */ -+ tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2, -+ is_load ? offsetof(CPUTLBEntry, addr_read) -+ : offsetof(CPUTLBEntry, addr_write)); -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2, -+ offsetof(CPUTLBEntry, addend)); -+ -+ /* We don't support unaligned accesses. */ -+ if (a_bits < s_bits) { -+ a_bits = s_bits; -+ } -+ /* Clear the non-page, non-alignment bits from the address. */ -+ compare_mask = (tcg_target_long)TARGET_PAGE_MASK | ((1 << a_bits) - 1); -+ tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask); -+ tcg_out_opc_and(s, TCG_REG_TMP1, TCG_REG_TMP1, addrl); -+ -+ /* Compare masked address with the TLB entry. */ -+ label_ptr[0] = s->code_ptr; -+ tcg_out_opc_bne(s, TCG_REG_TMP0, TCG_REG_TMP1, 0); -+ -+ /* TLB Hit - addend in TCG_REG_TMP2, ready for use. */ -+} -+ -+static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi, -+ TCGType type, TCGReg datalo, TCGReg addrlo, -+ void *raddr, tcg_insn_unit **label_ptr) -+{ -+ TCGLabelQemuLdst *label = new_ldst_label(s); -+ -+ label->is_ld = is_ld; -+ label->oi = oi; -+ label->type = type; -+ label->datalo_reg = datalo; -+ label->datahi_reg = 0; /* unused */ -+ label->addrlo_reg = addrlo; -+ label->addrhi_reg = 0; /* unused */ -+ label->raddr = tcg_splitwx_to_rx(raddr); -+ label->label_ptr[0] = label_ptr[0]; -+} -+ -+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ MemOpIdx oi = l->oi; -+ MemOp opc = get_memop(oi); -+ MemOp size = opc & MO_SIZE; -+ TCGType type = l->type; -+ -+ /* resolve label address */ -+ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { -+ return false; -+ } -+ -+ /* call load helper */ -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A2, oi); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, (tcg_target_long)l->raddr); -+ -+ tcg_out_call(s, qemu_ld_helpers[size]); -+ -+ switch (opc & MO_SSIZE) { -+ case MO_SB: -+ tcg_out_ext8s(s, l->datalo_reg, TCG_REG_A0); -+ break; -+ case MO_SW: -+ tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0); -+ break; -+ case MO_SL: -+ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); -+ break; -+ case MO_UL: -+ if (type == TCG_TYPE_I32) { -+ /* MO_UL loads of i32 should be sign-extended too */ -+ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); -+ break; -+ } -+ /* fallthrough */ -+ default: -+ tcg_out_mov(s, type, l->datalo_reg, TCG_REG_A0); -+ break; -+ } -+ -+ return tcg_out_goto(s, l->raddr); -+} -+ -+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ MemOpIdx oi = l->oi; -+ MemOp opc = get_memop(oi); -+ MemOp size = opc & MO_SIZE; -+ -+ /* resolve label address */ -+ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { -+ return false; -+ } -+ -+ /* call store helper */ -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); -+ switch (size) { -+ case MO_8: -+ tcg_out_ext8u(s, TCG_REG_A2, l->datalo_reg); -+ break; -+ case MO_16: -+ tcg_out_ext16u(s, TCG_REG_A2, l->datalo_reg); -+ break; -+ case MO_32: -+ tcg_out_ext32u(s, TCG_REG_A2, l->datalo_reg); -+ break; -+ case MO_64: -+ tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_A2, l->datalo_reg); -+ break; -+ default: -+ g_assert_not_reached(); -+ break; -+ } -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, oi); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A4, (tcg_target_long)l->raddr); -+ -+ tcg_out_call(s, qemu_st_helpers[size]); -+ -+ return tcg_out_goto(s, l->raddr); -+} -+#else -+ -+/* -+ * Alignment helpers for user-mode emulation -+ */ -+ -+static void tcg_out_test_alignment(TCGContext *s, bool is_ld, TCGReg addr_reg, -+ unsigned a_bits) -+{ -+ TCGLabelQemuLdst *l = new_ldst_label(s); -+ -+ l->is_ld = is_ld; -+ l->addrlo_reg = addr_reg; -+ -+ /* -+ * Without micro-architecture details, we don't know which of bstrpick or -+ * andi is faster, so use bstrpick as it's not constrained by imm field -+ * width. (Not to say alignments >= 2^12 are going to happen any time -+ * soon, though) -+ */ -+ tcg_out_opc_bstrpick_d(s, TCG_REG_TMP1, addr_reg, 0, a_bits - 1); -+ -+ l->label_ptr[0] = s->code_ptr; -+ tcg_out_opc_bne(s, TCG_REG_TMP1, TCG_REG_ZERO, 0); -+ -+ l->raddr = tcg_splitwx_to_rx(s->code_ptr); -+} -+ -+static bool tcg_out_fail_alignment(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ /* resolve label address */ -+ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { -+ return false; -+ } -+ -+ tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_A1, l->addrlo_reg); -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); -+ -+ /* tail call, with the return address back inline. */ -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (uintptr_t)l->raddr); -+ tcg_out_call_int( -+ s, -+ (const void *)(l->is_ld ? helper_unaligned_ld : helper_unaligned_st), -+ true); -+ return true; -+} -+ -+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ return tcg_out_fail_alignment(s, l); -+} -+ -+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) -+{ -+ return tcg_out_fail_alignment(s, l); -+} -+ -+#endif /* CONFIG_SOFTMMU */ -+ -+/* -+ * `ext32u` the address register into the temp register given, -+ * if target is 32-bit, no-op otherwise. -+ * -+ * Returns the address register ready for use with TLB addend. -+ */ -+static TCGReg tcg_out_zext_addr_if_32_bit(TCGContext *s, TCGReg addr, -+ TCGReg tmp) -+{ -+ if (TARGET_LONG_BITS == 32) { -+ tcg_out_ext32u(s, tmp, addr); -+ return tmp; -+ } -+ return addr; -+} -+ -+static void tcg_out_qemu_ld_indexed(TCGContext *s, TCGReg rd, TCGReg rj, -+ TCGReg rk, MemOp opc, TCGType type) -+{ -+ /* Byte swapping is left to middle-end expansion. */ -+ tcg_debug_assert((opc & MO_BSWAP) == 0); -+ -+ switch (opc & MO_SSIZE) { -+ case MO_UB: -+ tcg_out_opc_ldx_bu(s, rd, rj, rk); -+ break; -+ case MO_SB: -+ tcg_out_opc_ldx_b(s, rd, rj, rk); -+ break; -+ case MO_UW: -+ tcg_out_opc_ldx_hu(s, rd, rj, rk); -+ break; -+ case MO_SW: -+ tcg_out_opc_ldx_h(s, rd, rj, rk); -+ break; -+ case MO_UL: -+ if (type == TCG_TYPE_I64) { -+ tcg_out_opc_ldx_wu(s, rd, rj, rk); -+ break; -+ } -+ /* fallthrough */ -+ case MO_SL: -+ tcg_out_opc_ldx_w(s, rd, rj, rk); -+ break; -+ case MO_Q: -+ tcg_out_opc_ldx_d(s, rd, rj, rk); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGType type) -+{ -+ TCGReg addr_regl; -+ TCGReg data_regl; -+ MemOpIdx oi; -+ MemOp opc; -+#if defined(CONFIG_SOFTMMU) -+ tcg_insn_unit *label_ptr[1]; -+#else -+ unsigned a_bits; -+#endif -+ TCGReg base; -+ -+ data_regl = *args++; -+ addr_regl = *args++; -+ oi = *args++; -+ opc = get_memop(oi); -+ -+#if defined(CONFIG_SOFTMMU) -+ tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 1); -+ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); -+ tcg_out_qemu_ld_indexed(s, data_regl, base, TCG_REG_TMP2, opc, type); -+ add_qemu_ldst_label(s, 1, oi, type, data_regl, addr_regl, s->code_ptr, -+ label_ptr); -+#else -+ a_bits = get_alignment_bits(opc); -+ if (a_bits) { -+ tcg_out_test_alignment(s, true, addr_regl, a_bits); -+ } -+ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); -+ TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO; -+ tcg_out_qemu_ld_indexed(s, data_regl, base, guest_base_reg, opc, type); -+#endif -+} -+ -+static void tcg_out_qemu_st_indexed(TCGContext *s, TCGReg data, TCGReg rj, -+ TCGReg rk, MemOp opc) -+{ -+ /* Byte swapping is left to middle-end expansion. */ -+ tcg_debug_assert((opc & MO_BSWAP) == 0); -+ -+ switch (opc & MO_SIZE) { -+ case MO_8: -+ tcg_out_opc_stx_b(s, data, rj, rk); -+ break; -+ case MO_16: -+ tcg_out_opc_stx_h(s, data, rj, rk); -+ break; -+ case MO_32: -+ tcg_out_opc_stx_w(s, data, rj, rk); -+ break; -+ case MO_64: -+ tcg_out_opc_stx_d(s, data, rj, rk); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) -+{ -+ TCGReg addr_regl; -+ TCGReg data_regl; -+ MemOpIdx oi; -+ MemOp opc; -+#if defined(CONFIG_SOFTMMU) -+ tcg_insn_unit *label_ptr[1]; -+#else -+ unsigned a_bits; -+#endif -+ TCGReg base; -+ -+ data_regl = *args++; -+ addr_regl = *args++; -+ oi = *args++; -+ opc = get_memop(oi); -+ -+#if defined(CONFIG_SOFTMMU) -+ tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 0); -+ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); -+ tcg_out_qemu_st_indexed(s, data_regl, base, TCG_REG_TMP2, opc); -+ add_qemu_ldst_label(s, 0, oi, 0, /* type param is unused for stores */ -+ data_regl, addr_regl, s->code_ptr, label_ptr); -+#else -+ a_bits = get_alignment_bits(opc); -+ if (a_bits) { -+ tcg_out_test_alignment(s, false, addr_regl, a_bits); -+ } -+ base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); -+ TCGReg guest_base_reg = USE_GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_ZERO; -+ tcg_out_qemu_st_indexed(s, data_regl, base, guest_base_reg, opc); -+#endif -+} -+ -+/* -+ * Entry-points -+ */ -+ -+static const tcg_insn_unit *tb_ret_addr; -+ -+static void tcg_out_op(TCGContext *s, TCGOpcode opc, -+ const TCGArg args[TCG_MAX_OP_ARGS], -+ const int const_args[TCG_MAX_OP_ARGS]) -+{ -+ TCGArg a0 = args[0]; -+ TCGArg a1 = args[1]; -+ TCGArg a2 = args[2]; -+ int c2 = const_args[2]; -+ -+ switch (opc) { -+ case INDEX_op_exit_tb: -+ /* Reuse the zeroing that exists for goto_ptr. */ -+ if (a0 == 0) { -+ tcg_out_call_int(s, tcg_code_gen_epilogue, true); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0); -+ tcg_out_call_int(s, tb_ret_addr, true); -+ } -+ break; -+ -+ case INDEX_op_goto_tb: -+ assert(s->tb_jmp_insn_offset == 0); -+ /* indirect jump method */ -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO, -+ (uintptr_t)(s->tb_jmp_target_addr + a0)); -+ tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0); -+ set_jmp_reset_offset(s, a0); -+ break; -+ -+ case INDEX_op_mb: -+ tcg_out_mb(s, a0); -+ break; -+ -+ case INDEX_op_goto_ptr: -+ tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0); -+ break; -+ -+ case INDEX_op_br: -+ tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SD10K16, arg_label(a0), -+ 0); -+ tcg_out_opc_b(s, 0); -+ break; -+ -+ case INDEX_op_brcond_i32: -+ case INDEX_op_brcond_i64: -+ tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); -+ break; -+ -+ case INDEX_op_ext8s_i32: -+ case INDEX_op_ext8s_i64: -+ tcg_out_ext8s(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext8u_i32: -+ case INDEX_op_ext8u_i64: -+ tcg_out_ext8u(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext16s_i32: -+ case INDEX_op_ext16s_i64: -+ tcg_out_ext16s(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext16u_i32: -+ case INDEX_op_ext16u_i64: -+ tcg_out_ext16u(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext32u_i64: -+ case INDEX_op_extu_i32_i64: -+ tcg_out_ext32u(s, a0, a1); -+ break; -+ -+ case INDEX_op_ext32s_i64: -+ case INDEX_op_extrl_i64_i32: -+ case INDEX_op_ext_i32_i64: -+ tcg_out_ext32s(s, a0, a1); -+ break; -+ -+ case INDEX_op_extrh_i64_i32: -+ tcg_out_opc_srai_d(s, a0, a1, 32); -+ break; -+ -+ case INDEX_op_not_i32: -+ case INDEX_op_not_i64: -+ tcg_out_opc_nor(s, a0, a1, TCG_REG_ZERO); -+ break; -+ -+ case INDEX_op_nor_i32: -+ case INDEX_op_nor_i64: -+ if (c2) { -+ tcg_out_opc_ori(s, a0, a1, a2); -+ tcg_out_opc_nor(s, a0, a0, TCG_REG_ZERO); -+ } else { -+ tcg_out_opc_nor(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_andc_i32: -+ case INDEX_op_andc_i64: -+ if (c2) { -+ /* guaranteed to fit due to constraint */ -+ tcg_out_opc_andi(s, a0, a1, ~a2); -+ } else { -+ tcg_out_opc_andn(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_orc_i32: -+ case INDEX_op_orc_i64: -+ if (c2) { -+ /* guaranteed to fit due to constraint */ -+ tcg_out_opc_ori(s, a0, a1, ~a2); -+ } else { -+ tcg_out_opc_orn(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_and_i32: -+ case INDEX_op_and_i64: -+ if (c2) { -+ tcg_out_opc_andi(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_and(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_or_i32: -+ case INDEX_op_or_i64: -+ if (c2) { -+ tcg_out_opc_ori(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_or(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_xor_i32: -+ case INDEX_op_xor_i64: -+ if (c2) { -+ tcg_out_opc_xori(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_xor(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_extract_i32: -+ tcg_out_opc_bstrpick_w(s, a0, a1, a2, a2 + args[3] - 1); -+ break; -+ case INDEX_op_extract_i64: -+ tcg_out_opc_bstrpick_d(s, a0, a1, a2, a2 + args[3] - 1); -+ break; -+ -+ case INDEX_op_deposit_i32: -+ tcg_out_opc_bstrins_w(s, a0, a2, args[3], args[3] + args[4] - 1); -+ break; -+ case INDEX_op_deposit_i64: -+ tcg_out_opc_bstrins_d(s, a0, a2, args[3], args[3] + args[4] - 1); -+ break; -+ -+ case INDEX_op_bswap16_i32: -+ case INDEX_op_bswap16_i64: -+ tcg_out_opc_revb_2h(s, a0, a1); -+ if (a2 & TCG_BSWAP_OS) { -+ tcg_out_ext16s(s, a0, a0); -+ } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { -+ tcg_out_ext16u(s, a0, a0); -+ } -+ break; -+ -+ case INDEX_op_bswap32_i32: -+ /* All 32-bit values are computed sign-extended in the register. */ -+ a2 = TCG_BSWAP_OS; -+ /* fallthrough */ -+ case INDEX_op_bswap32_i64: -+ tcg_out_opc_revb_2w(s, a0, a1); -+ if (a2 & TCG_BSWAP_OS) { -+ tcg_out_ext32s(s, a0, a0); -+ } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { -+ tcg_out_ext32u(s, a0, a0); -+ } -+ break; -+ -+ case INDEX_op_bswap64_i64: -+ tcg_out_opc_revb_d(s, a0, a1); -+ break; -+ -+ case INDEX_op_clz_i32: -+ tcg_out_clzctz(s, OPC_CLZ_W, a0, a1, a2, c2, true); -+ break; -+ case INDEX_op_clz_i64: -+ tcg_out_clzctz(s, OPC_CLZ_D, a0, a1, a2, c2, false); -+ break; -+ -+ case INDEX_op_ctz_i32: -+ tcg_out_clzctz(s, OPC_CTZ_W, a0, a1, a2, c2, true); -+ break; -+ case INDEX_op_ctz_i64: -+ tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false); -+ break; -+ -+ case INDEX_op_shl_i32: -+ if (c2) { -+ tcg_out_opc_slli_w(s, a0, a1, a2 & 0x1f); -+ } else { -+ tcg_out_opc_sll_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_shl_i64: -+ if (c2) { -+ tcg_out_opc_slli_d(s, a0, a1, a2 & 0x3f); -+ } else { -+ tcg_out_opc_sll_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_shr_i32: -+ if (c2) { -+ tcg_out_opc_srli_w(s, a0, a1, a2 & 0x1f); -+ } else { -+ tcg_out_opc_srl_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_shr_i64: -+ if (c2) { -+ tcg_out_opc_srli_d(s, a0, a1, a2 & 0x3f); -+ } else { -+ tcg_out_opc_srl_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_sar_i32: -+ if (c2) { -+ tcg_out_opc_srai_w(s, a0, a1, a2 & 0x1f); -+ } else { -+ tcg_out_opc_sra_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_sar_i64: -+ if (c2) { -+ tcg_out_opc_srai_d(s, a0, a1, a2 & 0x3f); -+ } else { -+ tcg_out_opc_sra_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_rotl_i32: -+ /* transform into equivalent rotr/rotri */ -+ if (c2) { -+ tcg_out_opc_rotri_w(s, a0, a1, (32 - a2) & 0x1f); -+ } else { -+ tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2); -+ tcg_out_opc_rotr_w(s, a0, a1, TCG_REG_TMP0); -+ } -+ break; -+ case INDEX_op_rotl_i64: -+ /* transform into equivalent rotr/rotri */ -+ if (c2) { -+ tcg_out_opc_rotri_d(s, a0, a1, (64 - a2) & 0x3f); -+ } else { -+ tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2); -+ tcg_out_opc_rotr_d(s, a0, a1, TCG_REG_TMP0); -+ } -+ break; -+ -+ case INDEX_op_rotr_i32: -+ if (c2) { -+ tcg_out_opc_rotri_w(s, a0, a1, a2 & 0x1f); -+ } else { -+ tcg_out_opc_rotr_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_rotr_i64: -+ if (c2) { -+ tcg_out_opc_rotri_d(s, a0, a1, a2 & 0x3f); -+ } else { -+ tcg_out_opc_rotr_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_add_i32: -+ if (c2) { -+ tcg_out_opc_addi_w(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_add_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_add_i64: -+ if (c2) { -+ tcg_out_opc_addi_d(s, a0, a1, a2); -+ } else { -+ tcg_out_opc_add_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_sub_i32: -+ if (c2) { -+ tcg_out_opc_addi_w(s, a0, a1, -a2); -+ } else { -+ tcg_out_opc_sub_w(s, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_sub_i64: -+ if (c2) { -+ tcg_out_opc_addi_d(s, a0, a1, -a2); -+ } else { -+ tcg_out_opc_sub_d(s, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_mul_i32: -+ tcg_out_opc_mul_w(s, a0, a1, a2); -+ break; -+ case INDEX_op_mul_i64: -+ tcg_out_opc_mul_d(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_mulsh_i32: -+ tcg_out_opc_mulh_w(s, a0, a1, a2); -+ break; -+ case INDEX_op_mulsh_i64: -+ tcg_out_opc_mulh_d(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_muluh_i32: -+ tcg_out_opc_mulh_wu(s, a0, a1, a2); -+ break; -+ case INDEX_op_muluh_i64: -+ tcg_out_opc_mulh_du(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_div_i32: -+ tcg_out_opc_div_w(s, a0, a1, a2); -+ break; -+ case INDEX_op_div_i64: -+ tcg_out_opc_div_d(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_divu_i32: -+ tcg_out_opc_div_wu(s, a0, a1, a2); -+ break; -+ case INDEX_op_divu_i64: -+ tcg_out_opc_div_du(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_rem_i32: -+ tcg_out_opc_mod_w(s, a0, a1, a2); -+ break; -+ case INDEX_op_rem_i64: -+ tcg_out_opc_mod_d(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_remu_i32: -+ tcg_out_opc_mod_wu(s, a0, a1, a2); -+ break; -+ case INDEX_op_remu_i64: -+ tcg_out_opc_mod_du(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_setcond_i32: -+ case INDEX_op_setcond_i64: -+ tcg_out_setcond(s, args[3], a0, a1, a2, c2); -+ break; -+ -+ case INDEX_op_ld8s_i32: -+ case INDEX_op_ld8s_i64: -+ tcg_out_ldst(s, OPC_LD_B, a0, a1, a2); -+ break; -+ case INDEX_op_ld8u_i32: -+ case INDEX_op_ld8u_i64: -+ tcg_out_ldst(s, OPC_LD_BU, a0, a1, a2); -+ break; -+ case INDEX_op_ld16s_i32: -+ case INDEX_op_ld16s_i64: -+ tcg_out_ldst(s, OPC_LD_H, a0, a1, a2); -+ break; -+ case INDEX_op_ld16u_i32: -+ case INDEX_op_ld16u_i64: -+ tcg_out_ldst(s, OPC_LD_HU, a0, a1, a2); -+ break; -+ case INDEX_op_ld_i32: -+ case INDEX_op_ld32s_i64: -+ tcg_out_ldst(s, OPC_LD_W, a0, a1, a2); -+ break; -+ case INDEX_op_ld32u_i64: -+ tcg_out_ldst(s, OPC_LD_WU, a0, a1, a2); -+ break; -+ case INDEX_op_ld_i64: -+ tcg_out_ldst(s, OPC_LD_D, a0, a1, a2); -+ break; -+ -+ case INDEX_op_st8_i32: -+ case INDEX_op_st8_i64: -+ tcg_out_ldst(s, OPC_ST_B, a0, a1, a2); -+ break; -+ case INDEX_op_st16_i32: -+ case INDEX_op_st16_i64: -+ tcg_out_ldst(s, OPC_ST_H, a0, a1, a2); -+ break; -+ case INDEX_op_st_i32: -+ case INDEX_op_st32_i64: -+ tcg_out_ldst(s, OPC_ST_W, a0, a1, a2); -+ break; -+ case INDEX_op_st_i64: -+ tcg_out_ldst(s, OPC_ST_D, a0, a1, a2); -+ break; -+ -+ case INDEX_op_qemu_ld_i32: -+ tcg_out_qemu_ld(s, args, TCG_TYPE_I32); -+ break; -+ case INDEX_op_qemu_ld_i64: -+ tcg_out_qemu_ld(s, args, TCG_TYPE_I64); -+ break; -+ case INDEX_op_qemu_st_i32: -+ tcg_out_qemu_st(s, args); -+ break; -+ case INDEX_op_qemu_st_i64: -+ tcg_out_qemu_st(s, args); -+ break; -+ -+ case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ -+ case INDEX_op_mov_i64: -+ case INDEX_op_call: /* Always emitted via tcg_out_call. */ -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) -+{ -+ switch (op) { -+ case INDEX_op_goto_ptr: -+ return C_O0_I1(r); -+ -+ case INDEX_op_st8_i32: -+ case INDEX_op_st8_i64: -+ case INDEX_op_st16_i32: -+ case INDEX_op_st16_i64: -+ case INDEX_op_st32_i64: -+ case INDEX_op_st_i32: -+ case INDEX_op_st_i64: -+ return C_O0_I2(rZ, r); -+ -+ case INDEX_op_brcond_i32: -+ case INDEX_op_brcond_i64: -+ return C_O0_I2(rZ, rZ); -+ -+ case INDEX_op_qemu_st_i32: -+ case INDEX_op_qemu_st_i64: -+ return C_O0_I2(LZ, L); -+ -+ case INDEX_op_ext8s_i32: -+ case INDEX_op_ext8s_i64: -+ case INDEX_op_ext8u_i32: -+ case INDEX_op_ext8u_i64: -+ case INDEX_op_ext16s_i32: -+ case INDEX_op_ext16s_i64: -+ case INDEX_op_ext16u_i32: -+ case INDEX_op_ext16u_i64: -+ case INDEX_op_ext32s_i64: -+ case INDEX_op_ext32u_i64: -+ case INDEX_op_extu_i32_i64: -+ case INDEX_op_extrl_i64_i32: -+ case INDEX_op_extrh_i64_i32: -+ case INDEX_op_ext_i32_i64: -+ case INDEX_op_not_i32: -+ case INDEX_op_not_i64: -+ case INDEX_op_extract_i32: -+ case INDEX_op_extract_i64: -+ case INDEX_op_bswap16_i32: -+ case INDEX_op_bswap16_i64: -+ case INDEX_op_bswap32_i32: -+ case INDEX_op_bswap32_i64: -+ case INDEX_op_bswap64_i64: -+ case INDEX_op_ld8s_i32: -+ case INDEX_op_ld8s_i64: -+ case INDEX_op_ld8u_i32: -+ case INDEX_op_ld8u_i64: -+ case INDEX_op_ld16s_i32: -+ case INDEX_op_ld16s_i64: -+ case INDEX_op_ld16u_i32: -+ case INDEX_op_ld16u_i64: -+ case INDEX_op_ld32s_i64: -+ case INDEX_op_ld32u_i64: -+ case INDEX_op_ld_i32: -+ case INDEX_op_ld_i64: -+ return C_O1_I1(r, r); -+ -+ case INDEX_op_qemu_ld_i32: -+ case INDEX_op_qemu_ld_i64: -+ return C_O1_I1(r, L); -+ -+ case INDEX_op_andc_i32: -+ case INDEX_op_andc_i64: -+ case INDEX_op_orc_i32: -+ case INDEX_op_orc_i64: -+ /* -+ * LoongArch insns for these ops don't have reg-imm forms, but we -+ * can express using andi/ori if ~constant satisfies -+ * TCG_CT_CONST_U12. -+ */ -+ return C_O1_I2(r, r, rC); -+ -+ case INDEX_op_shl_i32: -+ case INDEX_op_shl_i64: -+ case INDEX_op_shr_i32: -+ case INDEX_op_shr_i64: -+ case INDEX_op_sar_i32: -+ case INDEX_op_sar_i64: -+ case INDEX_op_rotl_i32: -+ case INDEX_op_rotl_i64: -+ case INDEX_op_rotr_i32: -+ case INDEX_op_rotr_i64: -+ return C_O1_I2(r, r, ri); -+ -+ case INDEX_op_add_i32: -+ case INDEX_op_add_i64: -+ return C_O1_I2(r, r, rI); -+ -+ case INDEX_op_and_i32: -+ case INDEX_op_and_i64: -+ case INDEX_op_nor_i32: -+ case INDEX_op_nor_i64: -+ case INDEX_op_or_i32: -+ case INDEX_op_or_i64: -+ case INDEX_op_xor_i32: -+ case INDEX_op_xor_i64: -+ /* LoongArch reg-imm bitops have their imms ZERO-extended */ -+ return C_O1_I2(r, r, rU); -+ -+ case INDEX_op_clz_i32: -+ case INDEX_op_clz_i64: -+ case INDEX_op_ctz_i32: -+ case INDEX_op_ctz_i64: -+ return C_O1_I2(r, r, rW); -+ -+ case INDEX_op_setcond_i32: -+ case INDEX_op_setcond_i64: -+ return C_O1_I2(r, r, rZ); -+ -+ case INDEX_op_deposit_i32: -+ case INDEX_op_deposit_i64: -+ /* Must deposit into the same register as input */ -+ return C_O1_I2(r, 0, rZ); -+ -+ case INDEX_op_sub_i32: -+ case INDEX_op_sub_i64: -+ return C_O1_I2(r, rZ, rN); -+ -+ case INDEX_op_mul_i32: -+ case INDEX_op_mul_i64: -+ case INDEX_op_mulsh_i32: -+ case INDEX_op_mulsh_i64: -+ case INDEX_op_muluh_i32: -+ case INDEX_op_muluh_i64: -+ case INDEX_op_div_i32: -+ case INDEX_op_div_i64: -+ case INDEX_op_divu_i32: -+ case INDEX_op_divu_i64: -+ case INDEX_op_rem_i32: -+ case INDEX_op_rem_i64: -+ case INDEX_op_remu_i32: -+ case INDEX_op_remu_i64: -+ return C_O1_I2(r, rZ, rZ); -+ -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static const int tcg_target_callee_save_regs[] = { -+ TCG_REG_S0, /* used for the global env (TCG_AREG0) */ -+ TCG_REG_S1, -+ TCG_REG_S2, -+ TCG_REG_S3, -+ TCG_REG_S4, -+ TCG_REG_S5, -+ TCG_REG_S6, -+ TCG_REG_S7, -+ TCG_REG_S8, -+ TCG_REG_S9, -+ TCG_REG_RA, /* should be last for ABI compliance */ -+}; -+ -+/* Stack frame parameters. */ -+#define REG_SIZE (TCG_TARGET_REG_BITS / 8) -+#define SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE) -+#define TEMP_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long)) -+#define FRAME_SIZE \ -+ ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE + \ -+ TCG_TARGET_STACK_ALIGN - 1) & \ -+ -TCG_TARGET_STACK_ALIGN) -+#define SAVE_OFS (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE) -+ -+/* We're expecting to be able to use an immediate for frame allocation. */ -+QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff); -+ -+/* Generate global QEMU prologue and epilogue code */ -+static void tcg_target_qemu_prologue(TCGContext *s) -+{ -+ int i; -+ -+ tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE); -+ -+ /* TB prologue */ -+ tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE); -+ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { -+ tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], TCG_REG_SP, -+ SAVE_OFS + i * REG_SIZE); -+ } -+ -+#if !defined(CONFIG_SOFTMMU) -+ if (USE_GUEST_BASE) { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base); -+ tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); -+ } -+#endif -+ -+ /* Call generated code */ -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); -+ tcg_out_opc_jirl(s, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0); -+ -+ /* Return path for goto_ptr. Set return value to 0 */ -+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); -+ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO); -+ -+ /* TB epilogue */ -+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr); -+ for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { -+ tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i], TCG_REG_SP, -+ SAVE_OFS + i * REG_SIZE); -+ } -+ -+ tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE); -+ tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0); -+} -+ -+static void tcg_target_init(TCGContext *s) -+{ -+ tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS; -+ tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS; -+ -+ tcg_target_call_clobber_regs = ALL_GENERAL_REGS; -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9); -+ -+ s->reserved_regs = 0; -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED); -+} -+ -+typedef struct { -+ DebugFrameHeader h; -+ uint8_t fde_def_cfa[4]; -+ uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2]; -+} DebugFrame; -+ -+#define ELF_HOST_MACHINE EM_LOONGARCH -+ -+static const DebugFrame -+ debug_frame = { .h.cie.len = sizeof(DebugFrameCIE) - -+ 4, /* length after .len member */ -+ .h.cie.id = -1, -+ .h.cie.version = 1, -+ .h.cie.code_align = 1, -+ .h.cie.data_align = -+ -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */ -+ .h.cie.return_column = TCG_REG_RA, -+ -+ /* Total FDE size does not include the "len" member. */ -+ .h.fde.len = sizeof(DebugFrame) - -+ offsetof(DebugFrame, h.fde.cie_offset), -+ -+ .fde_def_cfa = { 12, -+ TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */ -+ (FRAME_SIZE & 0x7f) | -+ 0x80, /* ... uleb128 FRAME_SIZE */ -+ (FRAME_SIZE >> 7) }, -+ .fde_reg_ofs = { -+ 0x80 + 23, 11, /* DW_CFA_offset, s0, -88 */ -+ 0x80 + 24, 10, /* DW_CFA_offset, s1, -80 */ -+ 0x80 + 25, 9, /* DW_CFA_offset, s2, -72 */ -+ 0x80 + 26, 8, /* DW_CFA_offset, s3, -64 */ -+ 0x80 + 27, 7, /* DW_CFA_offset, s4, -56 */ -+ 0x80 + 28, 6, /* DW_CFA_offset, s5, -48 */ -+ 0x80 + 29, 5, /* DW_CFA_offset, s6, -40 */ -+ 0x80 + 30, 4, /* DW_CFA_offset, s7, -32 */ -+ 0x80 + 31, 3, /* DW_CFA_offset, s8, -24 */ -+ 0x80 + 22, 2, /* DW_CFA_offset, s9, -16 */ -+ 0x80 + 1, 1, /* DW_CFA_offset, ra, -8 */ -+ } }; -+ -+void tcg_register_jit(const void *buf, size_t buf_size) -+{ -+ tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); -+} -diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h -new file mode 100644 -index 0000000000..20f77b707d ---- /dev/null -+++ b/tcg/loongarch64/tcg-target.h -@@ -0,0 +1,168 @@ -+/* -+ * Tiny Code Generator for QEMU -+ * -+ * Copyright (c) 2023 Loongarch Technology -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2 or later, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ * -+ */ -+ -+#ifndef LOONGARCH_TCG_TARGET_H -+#define LOONGARCH_TCG_TARGET_H -+ -+/* -+ * Loongson removed the (incomplete) 32-bit support from kernel and toolchain -+ * for the initial upstreaming of this architecture, so don't bother and just -+ * support the LP64* ABI for now. -+ */ -+ -+#if defined(__loongarch64) -+#define TCG_TARGET_REG_BITS 64 -+#else -+#error unsupported LoongArch register size -+#endif -+ -+#define TCG_TARGET_INSN_UNIT_SIZE 4 -+#define TCG_TARGET_NB_REGS 32 -+#define MAX_CODE_GEN_BUFFER_SIZE SIZE_MAX -+ -+typedef enum { -+ TCG_REG_ZERO, -+ TCG_REG_RA, -+ TCG_REG_TP, -+ TCG_REG_SP, -+ TCG_REG_A0, -+ TCG_REG_A1, -+ TCG_REG_A2, -+ TCG_REG_A3, -+ TCG_REG_A4, -+ TCG_REG_A5, -+ TCG_REG_A6, -+ TCG_REG_A7, -+ TCG_REG_T0, -+ TCG_REG_T1, -+ TCG_REG_T2, -+ TCG_REG_T3, -+ TCG_REG_T4, -+ TCG_REG_T5, -+ TCG_REG_T6, -+ TCG_REG_T7, -+ TCG_REG_T8, -+ TCG_REG_RESERVED, -+ TCG_REG_S9, -+ TCG_REG_S0, -+ TCG_REG_S1, -+ TCG_REG_S2, -+ TCG_REG_S3, -+ TCG_REG_S4, -+ TCG_REG_S5, -+ TCG_REG_S6, -+ TCG_REG_S7, -+ TCG_REG_S8, -+ -+ /* aliases */ -+ TCG_AREG0 = TCG_REG_S0, -+ TCG_REG_TMP0 = TCG_REG_T8, -+ TCG_REG_TMP1 = TCG_REG_T7, -+ TCG_REG_TMP2 = TCG_REG_T6, -+} TCGReg; -+ -+/* used for function call generation */ -+#define TCG_REG_CALL_STACK TCG_REG_SP -+#define TCG_TARGET_STACK_ALIGN 16 -+#define TCG_TARGET_CALL_ALIGN_ARGS 1 -+#define TCG_TARGET_CALL_STACK_OFFSET 0 -+ -+/* optional instructions */ -+#define TCG_TARGET_HAS_movcond_i32 0 -+#define TCG_TARGET_HAS_div_i32 1 -+#define TCG_TARGET_HAS_rem_i32 1 -+#define TCG_TARGET_HAS_div2_i32 0 -+#define TCG_TARGET_HAS_rot_i32 1 -+#define TCG_TARGET_HAS_deposit_i32 1 -+#define TCG_TARGET_HAS_extract_i32 1 -+#define TCG_TARGET_HAS_sextract_i32 0 -+#define TCG_TARGET_HAS_extract2_i32 0 -+#define TCG_TARGET_HAS_add2_i32 0 -+#define TCG_TARGET_HAS_sub2_i32 0 -+#define TCG_TARGET_HAS_mulu2_i32 0 -+#define TCG_TARGET_HAS_muls2_i32 0 -+#define TCG_TARGET_HAS_muluh_i32 1 -+#define TCG_TARGET_HAS_mulsh_i32 1 -+#define TCG_TARGET_HAS_ext8s_i32 1 -+#define TCG_TARGET_HAS_ext16s_i32 1 -+#define TCG_TARGET_HAS_ext8u_i32 1 -+#define TCG_TARGET_HAS_ext16u_i32 1 -+#define TCG_TARGET_HAS_bswap16_i32 1 -+#define TCG_TARGET_HAS_bswap32_i32 1 -+#define TCG_TARGET_HAS_not_i32 1 -+#define TCG_TARGET_HAS_neg_i32 0 -+#define TCG_TARGET_HAS_andc_i32 1 -+#define TCG_TARGET_HAS_orc_i32 1 -+#define TCG_TARGET_HAS_eqv_i32 0 -+#define TCG_TARGET_HAS_nand_i32 0 -+#define TCG_TARGET_HAS_nor_i32 1 -+#define TCG_TARGET_HAS_clz_i32 1 -+#define TCG_TARGET_HAS_ctz_i32 1 -+#define TCG_TARGET_HAS_ctpop_i32 0 -+#define TCG_TARGET_HAS_direct_jump 0 -+#define TCG_TARGET_HAS_brcond2 0 -+#define TCG_TARGET_HAS_setcond2 0 -+#define TCG_TARGET_HAS_qemu_st8_i32 0 -+ -+/* 64-bit operations */ -+#define TCG_TARGET_HAS_movcond_i64 0 -+#define TCG_TARGET_HAS_div_i64 1 -+#define TCG_TARGET_HAS_rem_i64 1 -+#define TCG_TARGET_HAS_div2_i64 0 -+#define TCG_TARGET_HAS_rot_i64 1 -+#define TCG_TARGET_HAS_deposit_i64 1 -+#define TCG_TARGET_HAS_extract_i64 1 -+#define TCG_TARGET_HAS_sextract_i64 0 -+#define TCG_TARGET_HAS_extract2_i64 0 -+#define TCG_TARGET_HAS_extrl_i64_i32 1 -+#define TCG_TARGET_HAS_extrh_i64_i32 1 -+#define TCG_TARGET_HAS_ext8s_i64 1 -+#define TCG_TARGET_HAS_ext16s_i64 1 -+#define TCG_TARGET_HAS_ext32s_i64 1 -+#define TCG_TARGET_HAS_ext8u_i64 1 -+#define TCG_TARGET_HAS_ext16u_i64 1 -+#define TCG_TARGET_HAS_ext32u_i64 1 -+#define TCG_TARGET_HAS_bswap16_i64 1 -+#define TCG_TARGET_HAS_bswap32_i64 1 -+#define TCG_TARGET_HAS_bswap64_i64 1 -+#define TCG_TARGET_HAS_not_i64 1 -+#define TCG_TARGET_HAS_neg_i64 0 -+#define TCG_TARGET_HAS_andc_i64 1 -+#define TCG_TARGET_HAS_orc_i64 1 -+#define TCG_TARGET_HAS_eqv_i64 0 -+#define TCG_TARGET_HAS_nand_i64 0 -+#define TCG_TARGET_HAS_nor_i64 1 -+#define TCG_TARGET_HAS_clz_i64 1 -+#define TCG_TARGET_HAS_ctz_i64 1 -+#define TCG_TARGET_HAS_ctpop_i64 0 -+#define TCG_TARGET_HAS_add2_i64 0 -+#define TCG_TARGET_HAS_sub2_i64 0 -+#define TCG_TARGET_HAS_mulu2_i64 0 -+#define TCG_TARGET_HAS_muls2_i64 0 -+#define TCG_TARGET_HAS_muluh_i64 1 -+#define TCG_TARGET_HAS_mulsh_i64 1 -+ -+/* not defined -- call should be eliminated at compile time */ -+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t); -+ -+#define TCG_TARGET_DEFAULT_MO (0) -+#define TCG_TARGET_HAS_MEMORY_BSWAP 0 -+#define TCG_TARGET_NEED_LDST_LABELS -+ -+#endif /* LOONGARCH_TCG_TARGET_H */ --- -2.27.0 - diff --git a/Allow-setting-up-to-8-bytes-with-the-generic-loader.patch b/Allow-setting-up-to-8-bytes-with-the-generic-loader.patch deleted file mode 100644 index a33522abcba10a94f2fc6dd70a5023e4ab8cb56f..0000000000000000000000000000000000000000 --- a/Allow-setting-up-to-8-bytes-with-the-generic-loader.patch +++ /dev/null @@ -1,48 +0,0 @@ -From baf464ea0c35f9b235e8385b0771392ce362a6ec Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 21 Jul 2023 06:14:37 +0000 -Subject: [PATCH] Allow setting up to 8 bytes with the generic loader mainline - inclusion commit f42483d776bce29a9925ed61cc10eb27a5b2446c category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -The documentation for the generic loader says that "the maximum size of -the data is 8 bytes". However, attempts to set data-len=8 trigger the -following assertion failure: - -../hw/core/generic-loader.c:59: generic_loader_reset: Assertion `s->data_len < sizeof(s->data)' failed. - -The type of s->data is uint64_t (i.e. 8 bytes long), so I believe this -assert should use <= instead of <. - -Fixes: e481a1f63c93 ("generic-loader: Add a generic loader") -Signed-off-by: Petr Tesarik -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Alistair Francis -Message-id: 20220120092715.7805-1-ptesarik@suse.com -Signed-off-by: Alistair Francis - -Signed-off-by: tangbinzy ---- - hw/core/generic-loader.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c -index 9a24ffb880..504ed7ca72 100644 ---- a/hw/core/generic-loader.c -+++ b/hw/core/generic-loader.c -@@ -56,7 +56,7 @@ static void generic_loader_reset(void *opaque) - } - - if (s->data_len) { -- assert(s->data_len < sizeof(s->data)); -+ assert(s->data_len <= sizeof(s->data)); - dma_memory_write(s->cpu->as, s->addr, &s->data, s->data_len, - MEMTXATTRS_UNSPECIFIED); - } --- -2.41.0.windows.1 - diff --git a/BinDir.tar.gz b/BinDir.tar.gz index 6ed70f867ea227e3db214cdc9ed06d36cdcf2553..0a73a153b39c915f5629cea943239196bdb049fe 100644 Binary files a/BinDir.tar.gz and b/BinDir.tar.gz differ diff --git a/Check-and-report-for-incomplete-global-option-format.patch b/Check-and-report-for-incomplete-global-option-format.patch deleted file mode 100644 index 2ca33d727e550e0f71feab9f47c7c5abc9b66cb1..0000000000000000000000000000000000000000 --- a/Check-and-report-for-incomplete-global-option-format.patch +++ /dev/null @@ -1,49 +0,0 @@ -From c24b649580f7eeb656124fabe255760829d01408 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 26 Jul 2023 13:37:41 +0000 -Subject: [PATCH] Check and report for incomplete 'global' option format - mainline inclusion commit 818e1636080768749dc826acd4825e71828ec7e6 category: - bugfix - ---------------------------------------------------------------- - -Qemu might crash when provided incomplete '-global' option. -For example: - qemu-system-x86_64 -global driver=isa-fdc - qemu-system-x86_64: ../../devel/qemu/qapi/string-input-visitor.c:394: - string_input_visitor_new: Assertion `str' failed. - Aborted (core dumped) - -Fixes: 3751d7c43f795b ("vl: allow full-blown QemuOpts syntax for -global") -Signed-off-by: Rohit Kumar -Reviewed-by: Markus Armbruster -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/604 -Message-Id: <20220216071508.412974-1-rohit.kumar3@nutanix.com> -Signed-off-by: Thomas Huth - -Signed-off-by: tangbinzy ---- - softmmu/qdev-monitor.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c -index 4ca4e92ce2..14efb37014 100644 ---- a/softmmu/qdev-monitor.c -+++ b/softmmu/qdev-monitor.c -@@ -1041,6 +1041,13 @@ int qemu_global_option(const char *str) - if (!opts) { - return -1; - } -+ if (!qemu_opt_get(opts, "driver") -+ || !qemu_opt_get(opts, "property") -+ || !qemu_opt_get(opts, "value")) { -+ error_report("options 'driver', 'property', and 'value'" -+ " are required"); -+ return -1; -+ } - - return 0; - } --- -2.41.0.windows.1 - diff --git a/Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch b/Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch deleted file mode 100644 index b0071b50932b38fd7736dad548a083f356980f7f..0000000000000000000000000000000000000000 --- a/Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9e2158495059b485f2c28bb649c8b4a87fb3105c Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Wed, 9 Feb 2022 11:24:32 +0800 -Subject: [PATCH 12/15] Currently, while kvm and qemu can not handle some kvm - exit, qemu will do vm_stop, which will make vm in pause state. This action - make vm unrecoverable, so send guest panic to libvirt instead. - ---- - accel/kvm/kvm-all.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index eecd8031cf..b128d311c2 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2970,7 +2970,7 @@ int kvm_cpu_exec(CPUState *cpu) - - if (ret < 0) { - cpu_dump_state(cpu, stderr, CPU_DUMP_CODE); -- vm_stop(RUN_STATE_INTERNAL_ERROR); -+ qemu_system_guest_panicked(cpu_get_crash_info(cpu)); - } - - qatomic_set(&cpu->exit_request, 0); --- -2.27.0 - diff --git a/Fix-STM32F2XX-USART-data-register-readout.patch b/Fix-STM32F2XX-USART-data-register-readout.patch deleted file mode 100644 index 3244c318eea71f252674abbb455bf16e563412b0..0000000000000000000000000000000000000000 --- a/Fix-STM32F2XX-USART-data-register-readout.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 8733b8a26407177b867d3293283c257efeb784a0 Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Fri, 1 Dec 2023 12:51:56 +0800 -Subject: [PATCH] Fix STM32F2XX USART data register readout -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit ab08c3467605365b44fab1b66bb6254db86814f6 - -Fix issue where the data register may be overwritten by next character -reception before being read and returned. - -Signed-off-by: Olivier Hériveaux -Reviewed-by: Peter Maydell -Reviewed-by: Alistair Francis -Message-id: 20211128120723.4053-1-olivier.heriveaux@ledger.fr -Signed-off-by: Peter Maydell -Signed-off-by: Luo Yifan ---- - hw/char/stm32f2xx_usart.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c -index 8df0832424..fde67f4f03 100644 ---- a/hw/char/stm32f2xx_usart.c -+++ b/hw/char/stm32f2xx_usart.c -@@ -103,10 +103,11 @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr, - return retvalue; - case USART_DR: - DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr); -+ retvalue = s->usart_dr & 0x3FF; - s->usart_sr &= ~USART_SR_RXNE; - qemu_chr_fe_accept_input(&s->chr); - qemu_set_irq(s->irq, 0); -- return s->usart_dr & 0x3FF; -+ return retvalue; - case USART_BRR: - return s->usart_brr; - case USART_CR1: --- -2.27.0 - diff --git a/Fix-several-typos-in-documentation-found-by-codespel.patch b/Fix-several-typos-in-documentation-found-by-codespel.patch deleted file mode 100644 index 4140f2d601e7264925cbbec248e839fae9de1284..0000000000000000000000000000000000000000 --- a/Fix-several-typos-in-documentation-found-by-codespel.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 961450f0cf1e2e3a092dd723d7c63a310a881e93 Mon Sep 17 00:00:00 2001 -From: wangjinlei -Date: Wed, 23 Nov 2022 14:37:06 +0800 -Subject: [PATCH 10/29] Fix several typos in documentation (found by codespell) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Those typos are in files which are used to generate the QEMU manual. - -Signed-off-by: Stefan Weil -Message-Id: <20221110190825.879620-1-sw@weilnetz.de> -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Ani Sinha -Reviewed-by: Peter Maydell -Acked-by: Michael S. Tsirkin -[thuth: update sentence in can.rst as suggested by Peter] -Signed-off-by: Thomas Huth -Signed-off-by: wangjinlei ---- - hw/scsi/esp.c | 6 +++--- - include/exec/memory.h | 6 +++--- - qemu-options.hx | 4 ++-- - tests/qtest/libqos/qgraph.h | 2 +- - tests/qtest/libqos/virtio-9p.c | 2 +- - 5 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c -index 58d0edbd56..f38231f8cd 100644 ---- a/hw/scsi/esp.c -+++ b/hw/scsi/esp.c -@@ -510,7 +510,7 @@ static void do_dma_pdma_cb(ESPState *s) - } else { - /* - * Extra message out bytes received: update cmdfifo_cdb_offset -- * and then switch to commmand phase -+ * and then switch to command phase - */ - s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo); - s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; -@@ -622,7 +622,7 @@ static void esp_do_dma(ESPState *s) - } else { - /* - * Extra message out bytes received: update cmdfifo_cdb_offset -- * and then switch to commmand phase -+ * and then switch to command phase - */ - s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo); - s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; -@@ -733,7 +733,7 @@ static void esp_do_nodma(ESPState *s) - } else { - /* - * Extra message out bytes received: update cmdfifo_cdb_offset -- * and then switch to commmand phase -+ * and then switch to command phase - */ - s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo); - s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 4b5b431e45..abb838f194 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -561,7 +561,7 @@ typedef void (*ReplayRamDiscard)(MemoryRegionSection *section, void *opaque); - * A #RamDiscardManager coordinates which parts of specific RAM #MemoryRegion - * regions are currently populated to be used/accessed by the VM, notifying - * after parts were discarded (freeing up memory) and before parts will be -- * populated (consuming memory), to be used/acessed by the VM. -+ * populated (consuming memory), to be used/accessed by the VM. - * - * A #RamDiscardManager can only be set for a RAM #MemoryRegion while the - * #MemoryRegion isn't mapped yet; it cannot change while the #MemoryRegion is -@@ -585,7 +585,7 @@ typedef void (*ReplayRamDiscard)(MemoryRegionSection *section, void *opaque); - * Listeners are called in multiples of the minimum granularity (unless it - * would exceed the registered range) and changes are aligned to the minimum - * granularity within the #MemoryRegion. Listeners have to prepare for memory -- * becomming discarded in a different granularity than it was populated and the -+ * becoming discarded in a different granularity than it was populated and the - * other way around. - */ - struct RamDiscardManagerClass { -@@ -1242,7 +1242,7 @@ void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr, - Error **errp); - - /** -- * memory_region_init_resizeable_ram: Initialize memory region with resizeable -+ * memory_region_init_resizeable_ram: Initialize memory region with resizable - * RAM. Accesses into the region will - * modify memory directly. Only an initial - * portion of this RAM is actually used. -diff --git a/qemu-options.hx b/qemu-options.hx -index 1aaf38c613..047d28a357 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -318,7 +318,7 @@ SRST - \ - ``-numa cpu,node-id=node[,socket-id=x][,core-id=y][,thread-id=z]`` - \ --``-numa hmat-lb,initiator=node,target=node,hierarchy=hierarchy,data-type=tpye[,latency=lat][,bandwidth=bw]`` -+``-numa hmat-lb,initiator=node,target=node,hierarchy=hierarchy,data-type=type[,latency=lat][,bandwidth=bw]`` - \ - ``-numa hmat-cache,node-id=node,size=size,level=level[,associativity=str][,policy=str][,line=size]`` - Define a NUMA node and assign RAM and VCPUs to it. Set the NUMA -@@ -1717,7 +1717,7 @@ SRST - directory on host is made directly accessible by guest as a pass-through - file system by using the 9P network protocol for communication between - host and guests, if desired even accessible, shared by several guests -- simultaniously. -+ simultaneously. - - Note that ``-virtfs`` is actually just a convenience shortcut for its - generalized form ``-fsdev -device virtio-9p-pci``. -diff --git a/tests/qtest/libqos/qgraph.h b/tests/qtest/libqos/qgraph.h -index 871740c0dc..33d609a06a 100644 ---- a/tests/qtest/libqos/qgraph.h -+++ b/tests/qtest/libqos/qgraph.h -@@ -381,7 +381,7 @@ QOSGraphObject *qos_driver_new(QOSGraphNode *node, QOSGraphObject *parent, - * mind: only tests with a path down from the actual test case node (leaf) up - * to the graph's root node are actually executed by the qtest framework. And - * the qtest framework uses QMP to automatically check which QEMU drivers are -- * actually currently available, and accordingly qos marks certain pathes as -+ * actually currently available, and accordingly qos marks certain paths as - * 'unavailable' in such cases (e.g. when QEMU was compiled without support for - * a certain feature). - */ -diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c -index b4e1143288..2941d3cdc6 100644 ---- a/tests/qtest/libqos/virtio-9p.c -+++ b/tests/qtest/libqos/virtio-9p.c -@@ -31,7 +31,7 @@ - static QGuestAllocator *alloc; - static char *local_test_path; - --/* Concatenates the passed 2 pathes. Returned result must be freed. */ -+/* Concatenates the passed 2 paths. Returned result must be freed. */ - static char *concat_path(const char* a, const char* b) - { - return g_build_filename(a, b, NULL); --- -2.27.0 - diff --git a/Fix-several-typos-in-documentation.patch b/Fix-several-typos-in-documentation.patch deleted file mode 100644 index 7fb38afd8a5ca19a0d0efae71c6d8c48bdc42b7b..0000000000000000000000000000000000000000 --- a/Fix-several-typos-in-documentation.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4dd2cdf016e40c88b57480d9c296d6c7c2cb6600 Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Thu, 1 Dec 2022 20:24:53 +0800 -Subject: [PATCH 06/17] Fix several typos in documentation - -Signed-off-by: tangzhongrui tangzhongrui@cmss.chinamobile.com ---- - docs/can.txt | 2 +- - hw/virtio/virtio-mem.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/docs/can.txt b/docs/can.txt -index 0d310237df..873c95a35d 100644 ---- a/docs/can.txt -+++ b/docs/can.txt -@@ -166,7 +166,7 @@ and with bitrate switch - - cangen can0 -b - --The test can be run viceversa, generate messages in the guest system and capture them -+The test can be run vice-versa, generate messages in the guest system and capture them - in the host one and much more combinations. - - Links to other resources -diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c -index 341c3fa2c1..becac0d93b 100644 ---- a/hw/virtio/virtio-mem.c -+++ b/hw/virtio/virtio-mem.c -@@ -877,7 +877,7 @@ static int virtio_mem_mig_sanity_checks_post_load(void *opaque, int version_id) - return -EINVAL; - } - /* -- * Note: Preparation for resizeable memory regions. The maximum size -+ * Note: Preparation for resizable memory regions. The maximum size - * of the memory region must not change during migration. - */ - if (tmp->region_size != new_region_size) { --- -2.27.0 - diff --git a/Fix-smp.cores-value-and-Fix-divide-0-error.patch b/Fix-smp.cores-value-and-Fix-divide-0-error.patch deleted file mode 100644 index 1d8dd6efa79ea22f78e78e27f0fb957c54e0909f..0000000000000000000000000000000000000000 --- a/Fix-smp.cores-value-and-Fix-divide-0-error.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 08d0374d80ef321a421d4d9716c05006b469c78f Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Wed, 24 May 2023 23:06:51 -0400 -Subject: [PATCH] Fix smp.cores value and Fix divide 0 error - -The smp.cores should use the default value passed from -qemu start command, and the argument is cores_per_socket. - -The variable nb_numa_nodes may be 0, and a division by 0 -error will occur later, and special treatment is done for -nb_numa_nodes here. - -Signed-off-by: lixianglai ---- - hw/loongarch/larch_3a.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/hw/loongarch/larch_3a.c b/hw/loongarch/larch_3a.c -index fe786008ac..cef1a6f3d2 100644 ---- a/hw/loongarch/larch_3a.c -+++ b/hw/loongarch/larch_3a.c -@@ -1221,7 +1221,6 @@ static void loongarch_build_smbios(LoongarchMachineState *lsms) - uint8_t *smbios_tables, *smbios_anchor; - size_t smbios_tables_len, smbios_anchor_len; - const char *product = "QEMU Virtual Machine"; -- ms->smp.cores = 4; - - if (!lsms->fw_cfg) { - return; -@@ -2005,6 +2004,10 @@ static int64_t ls3a_get_default_cpu_node_id(const MachineState *ms, int idx) - { - int nb_numa_nodes = ms->numa_state->num_nodes; - int smp_cores = ms->smp.cores; -+ -+ if (nb_numa_nodes == 0) { -+ nb_numa_nodes = 1; -+ } - return idx / smp_cores % nb_numa_nodes; - } - --- -2.41.0.windows.1 - diff --git a/Fixed-a-QEMU-hang-when-guest-poweroff-in-COLO-mode.patch b/Fixed-a-QEMU-hang-when-guest-poweroff-in-COLO-mode.patch deleted file mode 100644 index 10e21c23b6636fdda91ab26b467c0c3f781722b2..0000000000000000000000000000000000000000 --- a/Fixed-a-QEMU-hang-when-guest-poweroff-in-COLO-mode.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 6de250962994520ba8daca709cd4b3b54d5e3afb Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Fri, 1 Dec 2023 10:47:48 +0800 -Subject: [PATCH] Fixed a QEMU hang when guest poweroff in COLO mode - -cherry picked from commit 795969ab1fe6d5a0f524be92e2e1ecd13f1873eb - -When the PVM guest poweroff, the COLO thread may wait a semaphore -in colo_process_checkpoint().So, we should wake up the COLO thread -before migration shutdown. - -Signed-off-by: Lei Rao -Reviewed-by: Zhang Chen -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -Signed-off-by: Luo Yifan ---- - include/migration/colo.h | 1 + - migration/colo.c | 20 ++++++++++++++++++++ - migration/migration.c | 6 ++++++ - 3 files changed, 27 insertions(+) - -diff --git a/include/migration/colo.h b/include/migration/colo.h -index 768e1f04c3..5fbe1a6d5d 100644 ---- a/include/migration/colo.h -+++ b/include/migration/colo.h -@@ -37,4 +37,5 @@ COLOMode get_colo_mode(void); - void colo_do_failover(void); - - void colo_checkpoint_notify(void *opaque); -+void colo_shutdown(void); - #endif -diff --git a/migration/colo.c b/migration/colo.c -index 2415325262..0d3d98f707 100644 ---- a/migration/colo.c -+++ b/migration/colo.c -@@ -820,6 +820,26 @@ static void colo_wait_handle_message(MigrationIncomingState *mis, - } - } - -+void colo_shutdown(void) -+{ -+ MigrationIncomingState *mis = NULL; -+ MigrationState *s = NULL; -+ -+ switch (get_colo_mode()) { -+ case COLO_MODE_PRIMARY: -+ s = migrate_get_current(); -+ qemu_event_set(&s->colo_checkpoint_event); -+ qemu_sem_post(&s->colo_exit_sem); -+ break; -+ case COLO_MODE_SECONDARY: -+ mis = migration_incoming_get_current(); -+ qemu_sem_post(&mis->colo_incoming_sem); -+ break; -+ default: -+ break; -+ } -+} -+ - void *colo_process_incoming_thread(void *opaque) - { - MigrationIncomingState *mis = opaque; -diff --git a/migration/migration.c b/migration/migration.c -index 2ec116f901..cceaacc7f7 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -226,6 +226,12 @@ void migration_cancel(const Error *error) - - void migration_shutdown(void) - { -+ /* -+ * When the QEMU main thread exit, the COLO thread -+ * may wait a semaphore. So, we should wakeup the -+ * COLO thread before migration shutdown. -+ */ -+ colo_shutdown(); - /* - * Cancel the current migration - that will (eventually) - * stop the migration using this structure --- -2.27.0 - diff --git a/IPv6-add-support-for-IPv6-protocol.patch b/IPv6-add-support-for-IPv6-protocol.patch deleted file mode 100644 index 23ed9a27cb5c99375ccadda8c94cefa17496fd72..0000000000000000000000000000000000000000 --- a/IPv6-add-support-for-IPv6-protocol.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 039e70e84d966ee28267f3fe76c8558ef65619f9 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Sat, 12 Feb 2022 14:31:00 +0800 -Subject: [PATCH] IPv6: add support for IPv6 protocol - -Add support for IPv6 protocol. - -Signed-off-by: Yan Wang ---- - roms/ipxe/src/config/general.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/roms/ipxe/src/config/general.h b/roms/ipxe/src/config/general.h -index 3c14a2c..e7ce2b9 100644 ---- a/roms/ipxe/src/config/general.h -+++ b/roms/ipxe/src/config/general.h -@@ -35,7 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - */ - - #define NET_PROTO_IPV4 /* IPv4 protocol */ --#undef NET_PROTO_IPV6 /* IPv6 protocol */ -+#define NET_PROTO_IPV6 /* IPv6 protocol */ - #undef NET_PROTO_FCOE /* Fibre Channel over Ethernet protocol */ - #define NET_PROTO_STP /* Spanning Tree protocol */ - #define NET_PROTO_LACP /* Link Aggregation control protocol */ --- -1.9.1 - diff --git a/KVM-x86-workaround-invalid-CPUID-0xD-9-info-on-some-.patch b/KVM-x86-workaround-invalid-CPUID-0xD-9-info-on-some-.patch deleted file mode 100644 index bf01f17d663941e229ab4ecbe08cab3c30e7d522..0000000000000000000000000000000000000000 --- a/KVM-x86-workaround-invalid-CPUID-0xD-9-info-on-some-.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 49cb3c9f3cc3a567ce2e6159bf27328c64b6601d Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Wed, 23 Mar 2022 12:33:25 +0100 -Subject: [PATCH 10/10] KVM: x86: workaround invalid CPUID[0xD,9] info on some - AMD processors -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -from mainline-v7.0.0-rc2 -commit 58f7db26f21c690cf9a669c314cfd7371506084a -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit 58f7db26f21c ("KVM: x86: workaround invalid CPUID[0xD,9] info -on some AMD processors") - ----------------------------------------------------------------- - -KVM: x86: workaround invalid CPUID[0xD,9] info on some AMD processors - -Some AMD processors expose the PKRU extended save state even if they do not have -the related PKU feature in CPUID. Worse, when they do they report a size of -64, whereas the expected size of the PKRU extended save state is 8, therefore -the esa->size == eax assertion does not hold. - -The state is already ignored by KVM_GET_SUPPORTED_CPUID because it -was not enabled in the host XCR0. However, QEMU kvm_cpu_xsave_init() -runs before QEMU invokes arch_prctl() to enable dynamically-enabled -save states such as XTILEDATA, and KVM_GET_SUPPORTED_CPUID hides save -states that have yet to be enabled. Therefore, kvm_cpu_xsave_init() -needs to consult the host CPUID instead of KVM_GET_SUPPORTED_CPUID, -and dies with an assertion failure. - -When setting up the ExtSaveArea array to match the host, ignore features that -KVM does not report as supported. This will cause QEMU to skip the incorrect -CPUID leaf instead of tripping the assertion. - -Closes: https://gitlab.com/qemu-project/qemu/-/issues/916 -Reported-by: Daniel P. Berrangé -Analyzed-by: Yang Zhong -Reported-by: Peter Krempa -Tested-by: Daniel P. Berrangé -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 4 ++-- - target/i386/cpu.h | 2 ++ - target/i386/kvm/kvm-cpu.c | 19 ++++++++++++------- - 3 files changed, 16 insertions(+), 9 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 1bc03d3eef..551b47ab1e 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -4973,8 +4973,8 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) - return cpu_list; - } - --static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, -- bool migratable_only) -+uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, -+ bool migratable_only) - { - FeatureWordInfo *wi = &feature_word_info[w]; - uint64_t r = 0; -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index eaa99c302f..290f1beaea 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -605,6 +605,8 @@ typedef enum FeatureWord { - } FeatureWord; - - typedef uint64_t FeatureWordArray[FEATURE_WORDS]; -+uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, -+ bool migratable_only); - - /* cpuid_features bits */ - #define CPUID_FP87 (1U << 0) -diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c -index a35a1bf9fe..5eb955ce9a 100644 ---- a/target/i386/kvm/kvm-cpu.c -+++ b/target/i386/kvm/kvm-cpu.c -@@ -99,13 +99,18 @@ static void kvm_cpu_xsave_init(void) - for (i = XSTATE_SSE_BIT + 1; i < XSAVE_STATE_AREA_COUNT; i++) { - ExtSaveArea *esa = &x86_ext_save_areas[i]; - -- if (esa->size) { -- host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx); -- if (eax != 0) { -- assert(esa->size == eax); -- esa->offset = ebx; -- esa->ecx = ecx; -- } -+ if (!esa->size) { -+ continue; -+ } -+ if ((x86_cpu_get_supported_feature_word(esa->feature, false) & esa->bits) -+ != esa->bits) { -+ continue; -+ } -+ host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx); -+ if (eax != 0) { -+ assert(esa->size == eax); -+ esa->offset = ebx; -+ esa->ecx = ecx; - } - } - } --- -2.27.0 - diff --git a/QGA-VSS-Add-wrapper-to-send-log-to-debugger-and-stde.patch b/QGA-VSS-Add-wrapper-to-send-log-to-debugger-and-stde.patch deleted file mode 100644 index 38aecce8b19120acdd95fd6baeaca3af0158fe50..0000000000000000000000000000000000000000 --- a/QGA-VSS-Add-wrapper-to-send-log-to-debugger-and-stde.patch +++ /dev/null @@ -1,110 +0,0 @@ -From a7d32227e6a7b3eff114135f68f980ac686f6b80 Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Sun, 30 Jul 2023 23:14:18 -0700 -Subject: [PATCH] QGA VSS: Add wrapper to send log to debugger and stderr - mainline inclusion commit 925d05d38a2bc76b5a49359370650a820bc891da category: - bugfix - -Reviewed-by: Thomas Huth -Signed-off-by: Konstantin Kostiuk -Signed-off-by: zhujun2 ---- - qga/vss-win32/meson.build | 2 +- - qga/vss-win32/vss-debug.cpp | 39 +++++++++++++++++++++++++++++++++++++ - qga/vss-win32/vss-debug.h | 25 ++++++++++++++++++++++++ - 3 files changed, 65 insertions(+), 1 deletion(-) - create mode 100644 qga/vss-win32/vss-debug.cpp - create mode 100644 qga/vss-win32/vss-debug.h - -diff --git a/qga/vss-win32/meson.build b/qga/vss-win32/meson.build -index 90825edef3..290796556c 100644 ---- a/qga/vss-win32/meson.build -+++ b/qga/vss-win32/meson.build -@@ -3,7 +3,7 @@ if add_languages('cpp', required: false) - link_args = cc.get_supported_link_arguments(['-fstack-protector-all', '-fstack-protector-strong', - '-Wl,--add-stdcall-alias', '-Wl,--enable-stdcall-fixup']) - -- qga_vss = shared_module('qga-vss', ['requester.cpp', 'provider.cpp', 'install.cpp'], -+ qga_vss = shared_module('qga-vss', ['requester.cpp', 'provider.cpp', 'install.cpp', 'vss-debug.cpp'], - name_prefix: '', - cpp_args: ['-Wno-unknown-pragmas', '-Wno-delete-non-virtual-dtor', '-Wno-non-virtual-dtor'], - link_args: link_args, -diff --git a/qga/vss-win32/vss-debug.cpp b/qga/vss-win32/vss-debug.cpp -new file mode 100644 -index 0000000000..820b1c6667 ---- /dev/null -+++ b/qga/vss-win32/vss-debug.cpp -@@ -0,0 +1,39 @@ -+/* -+ * QEMU Guest Agent VSS debug declarations -+ * -+ * Copyright (C) 2023 Red Hat Inc -+ * -+ * Authors: -+ * Konstantin Kostiuk -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ */ -+ -+#include "qemu/osdep.h" -+#include "vss-debug.h" -+#include "vss-common.h" -+ -+void qga_debug_internal(const char *funcname, const char *fmt, ...) -+{ -+ char user_string[512] = {0}; -+ char full_string[640] = {0}; -+ -+ va_list args; -+ va_start(args, fmt); -+ if (vsnprintf(user_string, _countof(user_string), fmt, args) <= 0) { -+ va_end(args); -+ return; -+ } -+ -+ va_end(args); -+ -+ if (snprintf(full_string, _countof(full_string), -+ QGA_PROVIDER_NAME "[%lu]: %s %s\n", -+ GetCurrentThreadId(), funcname, user_string) <= 0) { -+ return; -+ } -+ -+ OutputDebugString(full_string); -+ fputs(full_string, stderr); -+} -diff --git a/qga/vss-win32/vss-debug.h b/qga/vss-win32/vss-debug.h -new file mode 100644 -index 0000000000..7800457392 ---- /dev/null -+++ b/qga/vss-win32/vss-debug.h -@@ -0,0 +1,25 @@ -+/* -+ * QEMU Guest Agent VSS debug declarations -+ * -+ * Copyright (C) 2023 Red Hat Inc -+ * -+ * Authors: -+ * Konstantin Kostiuk -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ */ -+ -+#include "qemu/osdep.h" -+#include -+ -+#ifndef VSS_DEBUG_H -+#define VSS_DEBUG_H -+ -+void qga_debug_internal(const char *funcname, const char *fmt, ...) G_GNUC_PRINTF(2, 3); -+ -+#define qga_debug(fmt, ...) qga_debug_internal(__func__, fmt, ## __VA_ARGS__) -+#define qga_debug_begin qga_debug("begin") -+#define qga_debug_end qga_debug("end") -+ -+#endif --- -2.41.0.windows.1 - diff --git a/Remove-the-unused-local-variable-records.patch b/Remove-the-unused-local-variable-records.patch deleted file mode 100644 index d41ab54c9765dac7d5a8055e5b3a6fcf1e9f400d..0000000000000000000000000000000000000000 --- a/Remove-the-unused-local-variable-records.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 7b859a86cbdde8bf17619c43a6d4ae687a20f003 Mon Sep 17 00:00:00 2001 -From: dinglimin -Date: Wed, 29 Jun 2022 16:26:17 +0800 -Subject: [PATCH] Remove the unused local variable "records". - -Signed-off-by: dinglimin ---- - tests/migration/guestperf/engine.py | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/tests/migration/guestperf/engine.py b/tests/migration/guestperf/engine.py -index 87a6ab2009..59fca2c70b 100644 ---- a/tests/migration/guestperf/engine.py -+++ b/tests/migration/guestperf/engine.py -@@ -65,7 +65,6 @@ def _vcpu_timing(self, pid, tid_list): - return records - - def _cpu_timing(self, pid): -- records = [] - now = time.time() - - jiffies_per_sec = os.sysconf(os.sysconf_names['SC_CLK_TCK']) --- -2.27.0 - diff --git a/Remove-this-redundant-return.patch b/Remove-this-redundant-return.patch deleted file mode 100644 index 4d028bde780249cedd3ea87289cb69286247fcf7..0000000000000000000000000000000000000000 --- a/Remove-this-redundant-return.patch +++ /dev/null @@ -1,25 +0,0 @@ -From e7ef56975af8553690afb16f32fe74d62762b853 Mon Sep 17 00:00:00 2001 -From: dinglimin -Date: Wed, 29 Jun 2022 14:02:59 +0800 -Subject: [PATCH] Remove this redundant return. - -Signed-off-by: dinglimin ---- - scripts/vmstate-static-checker.py | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py -index 539ead62b4..6838bf7e7c 100755 ---- a/scripts/vmstate-static-checker.py -+++ b/scripts/vmstate-static-checker.py -@@ -367,7 +367,6 @@ def check_machine_type(s, d): - if s["Name"] != d["Name"]: - print("Warning: checking incompatible machine types:", end=' ') - print("\"" + s["Name"] + "\", \"" + d["Name"] + "\"") -- return - - - def main(): --- -2.27.0 - diff --git a/Revert-cpu-add-Cortex-A72-processor-kvm-target-suppo.patch b/Revert-cpu-add-Cortex-A72-processor-kvm-target-suppo.patch deleted file mode 100644 index 684893c93f9c04880af0d0177503b8b0afaf9ffd..0000000000000000000000000000000000000000 --- a/Revert-cpu-add-Cortex-A72-processor-kvm-target-suppo.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 7474971c6fd6c6f77e66ded125e5f2521c7e12a2 Mon Sep 17 00:00:00 2001 -From: Mingwang Li -Date: Wed, 9 Feb 2022 17:35:52 +0800 -Subject: [PATCH 2/3] Revert "cpu: add Cortex-A72 processor kvm target support" - -This reverts commit f0da7fa5230b5f771570b2c12288e4a56a20dd97. - -Signed-off-by: Mingwang Li ---- - target/arm/cpu64.c | 1 - - target/arm/kvm-consts.h | 3 --- - 2 files changed, 4 deletions(-) - -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index bd8e5b5676..26419fe994 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -202,7 +202,6 @@ static void aarch64_a72_initfn(Object *obj) - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,cortex-a72"; -- cpu->kvm_target = QEMU_KVM_ARM_TARGET_GENERIC_V8; - set_feature(&cpu->env, ARM_FEATURE_V8); - set_feature(&cpu->env, ARM_FEATURE_NEON); - set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); -diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h -index 5f1311ade7..580f1c1fee 100644 ---- a/target/arm/kvm-consts.h -+++ b/target/arm/kvm-consts.h -@@ -130,8 +130,6 @@ MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED); - #define QEMU_KVM_ARM_TARGET_CORTEX_A57 2 - #define QEMU_KVM_ARM_TARGET_XGENE_POTENZA 3 - #define QEMU_KVM_ARM_TARGET_CORTEX_A53 4 --/* Generic ARM v8 target */ --#define QEMU_KVM_ARM_TARGET_GENERIC_V8 5 - - /* There's no kernel define for this: sentinel value which - * matches no KVM target value for either 64 or 32 bit -@@ -143,7 +141,6 @@ MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53); --MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_GENERIC_V8, KVM_ARM_TARGET_GENERIC_V8); - - #define CP_REG_ARM64 0x6000000000000000ULL - #define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000 --- -2.27.0 - diff --git a/Revert-cpu-parse-feature-to-avoid-failure.patch b/Revert-cpu-parse-feature-to-avoid-failure.patch deleted file mode 100644 index 038edb892f46cd97b3a0b59dd6f6f1436a7e5442..0000000000000000000000000000000000000000 --- a/Revert-cpu-parse-feature-to-avoid-failure.patch +++ /dev/null @@ -1,67 +0,0 @@ -From cae52ca5b1dd4a295eaabc9649481f3d6a684f06 Mon Sep 17 00:00:00 2001 -From: Mingwang Li -Date: Wed, 9 Feb 2022 17:33:26 +0800 -Subject: [PATCH 1/3] Revert "cpu: parse +/- feature to avoid failure" - -This reverts commit ef83cde8dd2c9b404527354489b14d2bd238733d. - -Signed-off-by: Mingwang Li ---- - target/arm/cpu64.c | 37 ------------------------------------- - 1 file changed, 37 deletions(-) - -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 08d886de7b..bd8e5b5676 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -983,47 +983,10 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs) - return g_strdup("aarch64"); - } - --/* Parse "+feature,-feature,feature=foo" CPU feature string -- */ --static void arm_cpu_parse_featurestr(const char *typename, char *features, -- Error **errp ) --{ -- char *featurestr; -- char *val; -- static bool cpu_globals_initialized; -- -- if (cpu_globals_initialized) { -- return; -- } -- cpu_globals_initialized = true; -- -- featurestr = features ? strtok(features, ",") : NULL; -- while (featurestr) { -- val = strchr(featurestr, '='); -- if (val) { -- GlobalProperty *prop = g_new0(typeof(*prop), 1); -- *val = 0; -- val++; -- prop->driver = typename; -- prop->property = g_strdup(featurestr); -- prop->value = g_strdup(val); -- qdev_prop_register_global(prop); -- } else if (featurestr[0] == '+' || featurestr[0] == '-') { -- warn_report("Ignore %s feature\n", featurestr); -- } else { -- error_setg(errp, "Expected key=value format, found %s.", -- featurestr); -- return; -- } -- featurestr = strtok(NULL, ","); -- } --} -- - static void aarch64_cpu_class_init(ObjectClass *oc, void *data) - { - CPUClass *cc = CPU_CLASS(oc); - -- cc->parse_features = arm_cpu_parse_featurestr; - cc->gdb_read_register = aarch64_cpu_gdb_read_register; - cc->gdb_write_register = aarch64_cpu_gdb_write_register; - cc->gdb_num_core_regs = 34; --- -2.27.0 - diff --git a/Revert-hw-arm-smmu-common-Allow-domain-invalidation-.patch b/Revert-hw-arm-smmu-common-Allow-domain-invalidation-.patch deleted file mode 100644 index 3029daa2cff8522c7c970a86d8ff95750ef9905b..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmu-common-Allow-domain-invalidation-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c57d05a6ba11075b6998b98a204017c44f81759f Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:55 +0800 -Subject: [PATCH 32/36] Revert "hw/arm/smmu-common: Allow domain invalidation - for NH_ALL/NSNH_ALL" - -This reverts commit 876d18c962f0ead31d8458cd7ac19178be78455c. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmu-common.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c -index f253a27e1a..730dd20db1 100644 ---- a/hw/arm/smmu-common.c -+++ b/hw/arm/smmu-common.c -@@ -478,7 +478,6 @@ static void smmu_unmap_notifier_range(IOMMUNotifier *n) - event.entry.iova = n->start; - event.entry.perm = IOMMU_NONE; - event.entry.addr_mask = n->end - n->start; -- event.entry.granularity = IOMMU_INV_GRAN_DOMAIN; - - memory_region_notify_iommu_one(n, &event); - } --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Advertise-MSI_TRANSLATE-attribu.patch b/Revert-hw-arm-smmuv3-Advertise-MSI_TRANSLATE-attribu.patch deleted file mode 100644 index 3a8ffa8598b1aaa8c4e91a87cd7c290b75bf8f0b..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Advertise-MSI_TRANSLATE-attribu.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 6ce1e1161c833d59b659a9f50062439a24ce6995 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:36 +0800 -Subject: [PATCH 17/36] Revert "hw/arm/smmuv3: Advertise MSI_TRANSLATE - attribute" - -This reverts commit 5a759ab19d508361053e388694546216705d173b. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 275f1db430..5a092506d3 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -1600,9 +1600,6 @@ static int smmuv3_get_attr(IOMMUMemoryRegion *iommu, - if (attr == IOMMU_ATTR_VFIO_NESTED) { - *(bool *) data = true; - return 0; -- } else if (attr == IOMMU_ATTR_MSI_TRANSLATE) { -- *(bool *) data = true; -- return 0; - } - return -EINVAL; - } --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Allow-MAP-notifiers.patch b/Revert-hw-arm-smmuv3-Allow-MAP-notifiers.patch deleted file mode 100644 index def7e72f24922400bd460cacf4a59f59f9564b47..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Allow-MAP-notifiers.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 27fb5c981f920fe6ee1345d35d5c3b6cff1b1ce6 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:29 +0800 -Subject: [PATCH 11/36] Revert "hw/arm/smmuv3: Allow MAP notifiers" - -This reverts commit dc126664134989975ce9ab9e7d5d2c8916628bf6. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 55e78db65d..ed932d3340 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -1632,6 +1632,14 @@ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu, - return -EINVAL; - } - -+ if (new & IOMMU_NOTIFIER_MAP) { -+ error_setg(errp, -+ "device %02x.%02x.%x requires iommu MAP notifier which is " -+ "not currently supported", pci_bus_num(sdev->bus), -+ PCI_SLOT(sdev->devfn), PCI_FUNC(sdev->devfn)); -+ return -EINVAL; -+ } -+ - if (old == IOMMU_NOTIFIER_NONE) { - trace_smmuv3_notify_flag_add(iommu->parent_obj.name); - QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next); --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Fill-the-IOTLBEntry-arch_id-on-.patch b/Revert-hw-arm-smmuv3-Fill-the-IOTLBEntry-arch_id-on-.patch deleted file mode 100644 index 3f6885fe5049e4bbc1d9508f2bf947a271017da2..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Fill-the-IOTLBEntry-arch_id-on-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 868d85814a59b1b710b3edf34a0916f6849b72c0 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:33 +0800 -Subject: [PATCH 15/36] Revert "hw/arm/smmuv3: Fill the IOTLBEntry arch_id on - NH_VA invalidation" - -This reverts commit dcda615b3d9b1acffee3d31d57974cc9e4bd0dee. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 3751fb3ea8..e09e54a9aa 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -837,8 +837,6 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - event.entry.iova = iova; - event.entry.addr_mask = num_pages * (1 << granule) - 1; - event.entry.perm = IOMMU_NONE; -- event.entry.flags = IOMMU_INV_FLAGS_ARCHID; -- event.entry.arch_id = asid; - - memory_region_notify_iommu_one(n, &event); - } --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Fill-the-IOTLBEntry-leaf-field-.patch b/Revert-hw-arm-smmuv3-Fill-the-IOTLBEntry-leaf-field-.patch deleted file mode 100644 index 9137bbe328b540f9da509c83cc606f8b0abbd589..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Fill-the-IOTLBEntry-leaf-field-.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 62e581d9c6adfa3aebcefa8c5270aa6fc38ed541 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:32 +0800 -Subject: [PATCH 14/36] Revert "hw/arm/smmuv3: Fill the IOTLBEntry leaf field - on NH_VA invalidation" - -This reverts commit c219274b7b6a472d7340a4f72a052ba33ed19659. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index cceb3794d4..3751fb3ea8 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -804,7 +804,7 @@ epilogue: - static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - IOMMUNotifier *n, - int asid, dma_addr_t iova, -- uint8_t tg, uint64_t num_pages, bool leaf) -+ uint8_t tg, uint64_t num_pages) - { - SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu); - IOMMUTLBEvent event = {}; -@@ -839,7 +839,6 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - event.entry.perm = IOMMU_NONE; - event.entry.flags = IOMMU_INV_FLAGS_ARCHID; - event.entry.arch_id = asid; -- event.entry.leaf = leaf; - - memory_region_notify_iommu_one(n, &event); - } -@@ -871,7 +870,7 @@ static void smmuv3_notify_asid(IOMMUMemoryRegion *mr, - - /* invalidate an asid/iova range tuple in all mr's */ - static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova, -- uint8_t tg, uint64_t num_pages, bool leaf) -+ uint8_t tg, uint64_t num_pages) - { - SMMUDevice *sdev; - -@@ -883,7 +882,7 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova, - tg, num_pages); - - IOMMU_NOTIFIER_FOREACH(n, mr) { -- smmuv3_notify_iova(mr, n, asid, iova, tg, num_pages, leaf); -+ smmuv3_notify_iova(mr, n, asid, iova, tg, num_pages); - } - } - } -@@ -908,7 +907,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd) - - if (!tg) { - trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, 1, ttl, leaf); -- smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1, leaf); -+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1); - smmu_iotlb_inv_iova(s, asid, addr, tg, 1, ttl); - return; - } -@@ -926,7 +925,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd) - - num_pages = (mask + 1) >> granule; - trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf); -- smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages, leaf); -+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages); - smmu_iotlb_inv_iova(s, asid, addr, tg, num_pages, ttl); - addr += mask + 1; - } --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Implement-fault-injection.patch b/Revert-hw-arm-smmuv3-Implement-fault-injection.patch deleted file mode 100644 index a335500f6b067a4bc9368bc687bf1944ca81408f..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Implement-fault-injection.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 822386d862324be3c334faff790c1f6a64c5455a Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:30 +0800 -Subject: [PATCH 12/36] Revert "hw/arm/smmuv3: Implement fault injection" - -This reverts commit d31c754470b4b651d0e19c66738fbcc8fc6abf3c. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 71 ------------------------------------------------- - 1 file changed, 71 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index ed932d3340..514ce9d57d 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -1664,76 +1664,6 @@ static int smmuv3_get_attr(IOMMUMemoryRegion *iommu, - return -EINVAL; - } - --struct iommu_fault; -- --static inline int --smmuv3_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, -- struct iommu_fault *buf) --{ --#ifdef __linux__ -- SMMUDevice *sdev = container_of(iommu_mr, SMMUDevice, iommu); -- SMMUv3State *s3 = sdev->smmu; -- uint32_t sid = smmu_get_sid(sdev); -- int i; -- -- for (i = 0; i < count; i++) { -- SMMUEventInfo info = {}; -- struct iommu_fault_unrecoverable *record; -- -- if (buf[i].type != IOMMU_FAULT_DMA_UNRECOV) { -- continue; -- } -- -- info.sid = sid; -- record = &buf[i].event; -- -- switch (record->reason) { -- case IOMMU_FAULT_REASON_PASID_INVALID: -- info.type = SMMU_EVT_C_BAD_SUBSTREAMID; -- /* TODO further fill info.u.c_bad_substream */ -- break; -- case IOMMU_FAULT_REASON_PASID_FETCH: -- info.type = SMMU_EVT_F_CD_FETCH; -- break; -- case IOMMU_FAULT_REASON_BAD_PASID_ENTRY: -- info.type = SMMU_EVT_C_BAD_CD; -- /* TODO further fill info.u.c_bad_cd */ -- break; -- case IOMMU_FAULT_REASON_WALK_EABT: -- info.type = SMMU_EVT_F_WALK_EABT; -- info.u.f_walk_eabt.addr = record->addr; -- info.u.f_walk_eabt.addr2 = record->fetch_addr; -- break; -- case IOMMU_FAULT_REASON_PTE_FETCH: -- info.type = SMMU_EVT_F_TRANSLATION; -- info.u.f_translation.addr = record->addr; -- break; -- case IOMMU_FAULT_REASON_OOR_ADDRESS: -- info.type = SMMU_EVT_F_ADDR_SIZE; -- info.u.f_addr_size.addr = record->addr; -- break; -- case IOMMU_FAULT_REASON_ACCESS: -- info.type = SMMU_EVT_F_ACCESS; -- info.u.f_access.addr = record->addr; -- break; -- case IOMMU_FAULT_REASON_PERMISSION: -- info.type = SMMU_EVT_F_PERMISSION; -- info.u.f_permission.addr = record->addr; -- break; -- default: -- warn_report("%s Unexpected fault reason received from host: %d", -- __func__, record->reason); -- continue; -- } -- -- smmuv3_record_event(s3, &info); -- } -- return 0; --#else -- return -1; --#endif --} -- - static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - void *data) - { -@@ -1742,7 +1672,6 @@ static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - imrc->translate = smmuv3_translate; - imrc->notify_flag_changed = smmuv3_notify_flag_changed; - imrc->get_attr = smmuv3_get_attr; -- imrc->inject_faults = smmuv3_inject_faults; - } - - static const TypeInfo smmuv3_type_info = { --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Improve-stage1-ASID-invalidatio.patch b/Revert-hw-arm-smmuv3-Improve-stage1-ASID-invalidatio.patch deleted file mode 100644 index 3f812bb509ec6f554ceca61efbbc01cd85a476dd..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Improve-stage1-ASID-invalidatio.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 98ca0862f34c891a0e381bd382306398b88ac5bc Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:56 +0800 -Subject: [PATCH 33/36] Revert "hw/arm/smmuv3: Improve stage1 ASID - invalidation" - -This reverts commit de53feaa37a267a21ed30a642e1e64c5fcfbc4a4. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 44 ++------------------------------------------ - hw/arm/trace-events | 1 - - 2 files changed, 2 insertions(+), 43 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index f4de66827d..0e8fe646aa 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -840,31 +840,6 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - memory_region_notify_iommu_one(n, &event); - } - --/** -- * smmuv3_notify_asid - call the notifier @n for a given asid -- * -- * @mr: IOMMU mr region handle -- * @n: notifier to be called -- * @asid: address space ID or negative value if we don't care -- */ --static void smmuv3_notify_asid(IOMMUMemoryRegion *mr, -- IOMMUNotifier *n, int asid) --{ -- IOMMUTLBEvent event = {}; -- -- event.type = IOMMU_NOTIFIER_UNMAP; -- event.entry.target_as = &address_space_memory; -- event.entry.perm = IOMMU_NONE; -- event.entry.granularity = IOMMU_INV_GRAN_PASID; -- event.entry.flags = IOMMU_INV_FLAGS_ARCHID; -- event.entry.arch_id = asid; -- event.entry.iova = n->start; -- event.entry.addr_mask = n->end - n->start; -- -- memory_region_notify_iommu_one(n, &event); --} -- -- - /* invalidate an asid/iova range tuple in all mr's */ - static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova, - uint8_t tg, uint64_t num_pages) -@@ -942,22 +917,6 @@ smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) - return true; - } - --static void smmuv3_s1_asid_inval(SMMUState *s, uint16_t asid) --{ -- SMMUDevice *sdev; -- -- trace_smmuv3_s1_asid_inval(asid); -- QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) { -- IOMMUMemoryRegion *mr = &sdev->iommu; -- IOMMUNotifier *n; -- -- IOMMU_NOTIFIER_FOREACH(n, mr) { -- smmuv3_notify_asid(mr, n, asid); -- } -- } -- smmu_iotlb_inv_asid(s, asid); --} -- - static int smmuv3_cmdq_consume(SMMUv3State *s) - { - SMMUState *bs = ARM_SMMU(s); -@@ -1072,7 +1031,8 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) - uint16_t asid = CMD_ASID(&cmd); - - trace_smmuv3_cmdq_tlbi_nh_asid(asid); -- smmuv3_s1_asid_inval(bs, asid); -+ smmu_inv_notifiers_all(&s->smmu_state); -+ smmu_iotlb_inv_asid(bs, asid); - break; - } - case SMMU_CMD_TLBI_NH_ALL: -diff --git a/hw/arm/trace-events b/hw/arm/trace-events -index 1447ad5a90..2dee296c8f 100644 ---- a/hw/arm/trace-events -+++ b/hw/arm/trace-events -@@ -46,7 +46,6 @@ smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=0x%x" - smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid=0x%x (hits=%d, misses=%d, hit rate=%d)" - smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid=0x%x (hits=%d, misses=%d, hit rate=%d)" - smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid=%d asid=%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d" --smmuv3_s1_asid_inval(int asid) "asid=%d" - smmuv3_cmdq_tlbi_nh(void) "" - smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d" - smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x" --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Pass-stage-1-configurations-to-.patch b/Revert-hw-arm-smmuv3-Pass-stage-1-configurations-to-.patch deleted file mode 100644 index 158b3d55c01799edf01d67fd2f82efbc42f0c516..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Pass-stage-1-configurations-to-.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 9682b8cd2454c00fbb4c4f7eb3e959187d9e6f1c Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:31 +0800 -Subject: [PATCH 13/36] Revert "hw/arm/smmuv3: Pass stage 1 configurations to - the host" - -This reverts commit 2e5929ec2a35a7a227dc7ba70a557a84993a366d. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmu-internal.h | 1 - - hw/arm/smmuv3.c | 71 ++++++------------------------------------ - hw/arm/trace-events | 1 - - 3 files changed, 9 insertions(+), 64 deletions(-) - -diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h -index 5ef8c598c6..2d75b31953 100644 ---- a/hw/arm/smmu-internal.h -+++ b/hw/arm/smmu-internal.h -@@ -105,7 +105,6 @@ typedef struct SMMUIOTLBPageInvInfo { - } SMMUIOTLBPageInvInfo; - - typedef struct SMMUSIDRange { -- SMMUState *state; - uint32_t start; - uint32_t end; - } SMMUSIDRange; -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 514ce9d57d..cceb3794d4 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -16,10 +16,6 @@ - * with this program; if not, see . - */ - --#ifdef __linux__ --#include "linux/iommu.h" --#endif -- - #include "qemu/osdep.h" - #include "qemu/bitops.h" - #include "hw/irq.h" -@@ -936,61 +932,6 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd) - } - } - --static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) --{ --#ifdef __linux__ -- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid); -- SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid, -- .inval_ste_allowed = true}; -- IOMMUConfig iommu_config = {}; -- SMMUTransCfg *cfg; -- SMMUDevice *sdev; -- -- if (!mr) { -- return; -- } -- -- sdev = container_of(mr, SMMUDevice, iommu); -- -- /* flush QEMU config cache */ -- smmuv3_flush_config(sdev); -- -- if (!pci_device_is_pasid_ops_set(sdev->bus, sdev->devfn)) { -- return; -- } -- -- cfg = smmuv3_get_config(sdev, &event); -- -- if (!cfg) { -- return; -- } -- -- iommu_config.pasid_cfg.argsz = sizeof(struct iommu_pasid_table_config); -- iommu_config.pasid_cfg.version = PASID_TABLE_CFG_VERSION_1; -- iommu_config.pasid_cfg.format = IOMMU_PASID_FORMAT_SMMUV3; -- iommu_config.pasid_cfg.base_ptr = cfg->s1ctxptr; -- iommu_config.pasid_cfg.pasid_bits = 0; -- iommu_config.pasid_cfg.vendor_data.smmuv3.version = PASID_TABLE_SMMUV3_CFG_VERSION_1; -- -- if (cfg->disabled || cfg->bypassed) { -- iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_BYPASS; -- } else if (cfg->aborted) { -- iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_ABORT; -- } else { -- iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_TRANSLATE; -- } -- -- trace_smmuv3_notify_config_change(mr->parent_obj.name, -- iommu_config.pasid_cfg.config, -- iommu_config.pasid_cfg.base_ptr); -- -- if (pci_device_set_pasid_table(sdev->bus, sdev->devfn, &iommu_config)) { -- error_report("Failed to pass PASID table to host for iommu mr %s (%m)", -- mr->parent_obj.name); -- } --#endif --} -- - static gboolean - smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) - { -@@ -1001,7 +942,6 @@ smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) - if (sid < sid_range->start || sid > sid_range->end) { - return false; - } -- smmuv3_notify_config_change(sid_range->state, sid); - trace_smmuv3_config_cache_inv(sid); - return true; - } -@@ -1072,14 +1012,22 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) - case SMMU_CMD_CFGI_STE: - { - uint32_t sid = CMD_SID(&cmd); -+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid); -+ SMMUDevice *sdev; - - if (CMD_SSEC(&cmd)) { - cmd_error = SMMU_CERROR_ILL; - break; - } - -+ if (!mr) { -+ break; -+ } -+ - trace_smmuv3_cmdq_cfgi_ste(sid); -- smmuv3_notify_config_change(bs, sid); -+ sdev = container_of(mr, SMMUDevice, iommu); -+ smmuv3_flush_config(sdev); -+ - break; - } - case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */ -@@ -1094,7 +1042,6 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) - } - - mask = (1ULL << (range + 1)) - 1; -- sid_range.state = bs; - sid_range.start = sid & ~mask; - sid_range.end = sid_range.start + mask; - -diff --git a/hw/arm/trace-events b/hw/arm/trace-events -index d9851d663e..1447ad5a90 100644 ---- a/hw/arm/trace-events -+++ b/hw/arm/trace-events -@@ -53,5 +53,4 @@ smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x" - smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s" - smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s" - smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64 --smmuv3_notify_config_change(const char *name, uint8_t config, uint64_t s1ctxptr) "iommu mr=%s config=%d s1ctxptr=0x%"PRIx64 - --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Post-load-stage-1-configuration.patch b/Revert-hw-arm-smmuv3-Post-load-stage-1-configuration.patch deleted file mode 100644 index e10ded8e3f5f2010f7bf14c62a8abb6f9a62b67f..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Post-load-stage-1-configuration.patch +++ /dev/null @@ -1,105 +0,0 @@ -From c3dab32ec9b111e036b7de9cb8cb5a987b1764f3 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:16 +0800 -Subject: [PATCH 03/36] Revert "hw/arm/smmuv3: Post-load stage 1 configurations - to the host" - -This reverts commit 1b95c995f032c21bf6607dda8ede0f5856bb190a. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 33 +++++---------------------------- - 1 file changed, 5 insertions(+), 28 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 2bd9f22055..55e78db65d 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -936,7 +936,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd) - } - } - --static int smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) -+static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) - { - #ifdef __linux__ - IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid); -@@ -945,10 +945,9 @@ static int smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) - IOMMUConfig iommu_config = {}; - SMMUTransCfg *cfg; - SMMUDevice *sdev; -- int ret; - - if (!mr) { -- return 0; -+ return; - } - - sdev = container_of(mr, SMMUDevice, iommu); -@@ -957,13 +956,13 @@ static int smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) - smmuv3_flush_config(sdev); - - if (!pci_device_is_pasid_ops_set(sdev->bus, sdev->devfn)) { -- return 0; -+ return; - } - - cfg = smmuv3_get_config(sdev, &event); - - if (!cfg) { -- return 0; -+ return; - } - - iommu_config.pasid_cfg.argsz = sizeof(struct iommu_pasid_table_config); -@@ -985,13 +984,10 @@ static int smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) - iommu_config.pasid_cfg.config, - iommu_config.pasid_cfg.base_ptr); - -- ret = pci_device_set_pasid_table(sdev->bus, sdev->devfn, &iommu_config); -- if (ret) { -+ if (pci_device_set_pasid_table(sdev->bus, sdev->devfn, &iommu_config)) { - error_report("Failed to pass PASID table to host for iommu mr %s (%m)", - mr->parent_obj.name); - } -- -- return ret; - #endif - } - -@@ -1561,24 +1557,6 @@ static void smmu_realize(DeviceState *d, Error **errp) - smmu_init_irq(s, dev); - } - --static int smmuv3_post_load(void *opaque, int version_id) --{ -- SMMUv3State *s3 = opaque; -- SMMUState *s = &(s3->smmu_state); -- SMMUDevice *sdev; -- int ret = 0; -- -- QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) { -- uint32_t sid = smmu_get_sid(sdev); -- ret = smmuv3_notify_config_change(s, sid); -- if (ret) { -- break; -- } -- } -- -- return ret; --} -- - static const VMStateDescription vmstate_smmuv3_queue = { - .name = "smmuv3_queue", - .version_id = 1, -@@ -1597,7 +1575,6 @@ static const VMStateDescription vmstate_smmuv3 = { - .version_id = 1, - .minimum_version_id = 1, - .priority = MIG_PRI_IOMMU, -- .post_load = smmuv3_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT32(features, SMMUv3State), - VMSTATE_UINT8(sid_size, SMMUv3State), --- -2.27.0 - diff --git a/Revert-hw-arm-smmuv3-Store-the-PASID-table-GPA-in-th.patch b/Revert-hw-arm-smmuv3-Store-the-PASID-table-GPA-in-th.patch deleted file mode 100644 index 22661e79007c06155d97cdfe15c80fe67eb2e4cb..0000000000000000000000000000000000000000 --- a/Revert-hw-arm-smmuv3-Store-the-PASID-table-GPA-in-th.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7d0023ef0c909bc569477e7676bc4c43734783a3 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:35 +0800 -Subject: [PATCH 16/36] Revert "hw/arm/smmuv3: Store the PASID table GPA in the - translation config" - -This reverts commit f937ce4124d57eea27d516957a2efa0e7fbdf198. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 1 - - include/hw/arm/smmu-common.h | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index e09e54a9aa..275f1db430 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -362,7 +362,6 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg, - "SMMUv3 S1 stalling fault model not allowed yet\n"); - goto bad_ste; - } -- cfg->s1ctxptr = STE_CTXPTR(ste); - return 0; - - bad_ste: -diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h -index d578339935..706be3c6d0 100644 ---- a/include/hw/arm/smmu-common.h -+++ b/include/hw/arm/smmu-common.h -@@ -76,7 +76,6 @@ typedef struct SMMUTransCfg { - uint8_t tbi; /* Top Byte Ignore */ - uint16_t asid; - SMMUTransTableInfo tt[2]; -- dma_addr_t s1ctxptr; - uint32_t iotlb_hits; /* counts IOTLB hits for this asid */ - uint32_t iotlb_misses; /* counts IOTLB misses for this asid */ - } SMMUTransCfg; --- -2.27.0 - diff --git a/Revert-hw-virtio-virtio-iommu-pci-Enforce-the-device.patch b/Revert-hw-virtio-virtio-iommu-pci-Enforce-the-device.patch deleted file mode 100644 index b3017089f753ded5c1573abdfd16c620ebde3988..0000000000000000000000000000000000000000 --- a/Revert-hw-virtio-virtio-iommu-pci-Enforce-the-device.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f66f64cf3ca968db2ca7f45bfd125ec7d85624e5 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Mon, 4 Dec 2023 17:30:02 +0800 -Subject: [PATCH] Revert "hw/virtio/virtio-iommu-pci: Enforce the device is - plugged on the root bus" - -This reverts commit a2323aa79da71c92e818306f1e18184619309a35. - -Signed-off-by: jiangdongxu ---- - hw/virtio/virtio-iommu-pci.c | 13 +++---------- - 1 file changed, 3 insertions(+), 10 deletions(-) - -diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c -index 37eb2fb979..a160ae6b41 100644 ---- a/hw/virtio/virtio-iommu-pci.c -+++ b/hw/virtio/virtio-iommu-pci.c -@@ -44,7 +44,6 @@ static Property virtio_iommu_pci_properties[] = { - static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) - { - VirtIOIOMMUPCI *dev = VIRTIO_IOMMU_PCI(vpci_dev); -- PCIBus *pbus = pci_get_bus(&vpci_dev->pci_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - VirtIOIOMMU *s = VIRTIO_IOMMU(vdev); - -@@ -66,17 +65,11 @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) - s->reserved_regions[i].type != VIRTIO_IOMMU_RESV_MEM_T_MSI) { - error_setg(errp, "reserved region %d has an invalid type", i); - error_append_hint(errp, "Valid values are 0 and 1\n"); -- return; -- } -+ } - } -- if (!pci_bus_is_root(pbus)) { -- error_setg(errp, "virtio-iommu-pci must be plugged on the root bus"); -- return; -- } -- - object_property_set_link(OBJECT(dev), "primary-bus", -- OBJECT(pbus), &error_abort); -- -+ OBJECT(pci_get_bus(&vpci_dev->pci_dev)), -+ &error_abort); - virtio_pci_force_virtio_1(vpci_dev); - qdev_realize(vdev, BUS(&vpci_dev->bus), errp); - } --- -2.27.0 - diff --git a/Revert-iommu-Introduce-generic-header.patch b/Revert-iommu-Introduce-generic-header.patch deleted file mode 100644 index edea25ab3a5a539b85fee1baea1d886ee93ec2f5..0000000000000000000000000000000000000000 --- a/Revert-iommu-Introduce-generic-header.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 2916e0465befa35df9cce14b761177be55ccce4d Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:50 +0800 -Subject: [PATCH 28/36] Revert "iommu: Introduce generic header" - -This reverts commit 5e312f7b41ec48dc7dc9805af9f52aa8ed393bf9. - -Signed-off-by: Kunkun Jiang ---- - include/hw/iommu/iommu.h | 28 ---------------------------- - 1 file changed, 28 deletions(-) - delete mode 100644 include/hw/iommu/iommu.h - -diff --git a/include/hw/iommu/iommu.h b/include/hw/iommu/iommu.h -deleted file mode 100644 -index 12092bda7b..0000000000 ---- a/include/hw/iommu/iommu.h -+++ /dev/null -@@ -1,28 +0,0 @@ --/* -- * common header for iommu devices -- * -- * Copyright Red Hat, Inc. 2019 -- * -- * Authors: -- * Eric Auger -- * -- * This work is licensed under the terms of the GNU GPL, version 2. See -- * the COPYING file in the top-level directory. -- */ -- --#ifndef QEMU_HW_IOMMU_IOMMU_H --#define QEMU_HW_IOMMU_IOMMU_H --#ifdef __linux__ --#include --#endif -- --typedef struct IOMMUConfig { -- union { --#ifdef __linux__ -- struct iommu_pasid_table_config pasid_cfg; --#endif -- }; --} IOMMUConfig; -- -- --#endif /* QEMU_HW_IOMMU_IOMMU_H */ --- -2.27.0 - diff --git a/Revert-memory-Add-IOMMU_ATTR_MSI_TRANSLATE-IOMMU-mem.patch b/Revert-memory-Add-IOMMU_ATTR_MSI_TRANSLATE-IOMMU-mem.patch deleted file mode 100644 index 5e140e502aab55bad30816f733738a9db2475d0d..0000000000000000000000000000000000000000 --- a/Revert-memory-Add-IOMMU_ATTR_MSI_TRANSLATE-IOMMU-mem.patch +++ /dev/null @@ -1,28 +0,0 @@ -From eb4958875239ccfabc03f28738d520c75db638d5 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:52 +0800 -Subject: [PATCH 30/36] Revert "memory: Add IOMMU_ATTR_MSI_TRANSLATE IOMMU - memory region attribute" - -This reverts commit 062923fd4e6d11e1b724f2dd059f8b0c6e65bf7a. - -Signed-off-by: Kunkun Jiang ---- - include/exec/memory.h | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 67d9061766..229c9cf85b 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -326,7 +326,6 @@ typedef struct MemoryRegionClass { - enum IOMMUMemoryRegionAttr { - IOMMU_ATTR_SPAPR_TCE_FD, - IOMMU_ATTR_VFIO_NESTED, -- IOMMU_ATTR_MSI_TRANSLATE, - }; - - /* --- -2.27.0 - diff --git a/Revert-memory-Add-IOMMU_ATTR_VFIO_NESTED-IOMMU-memor.patch b/Revert-memory-Add-IOMMU_ATTR_VFIO_NESTED-IOMMU-memor.patch deleted file mode 100644 index 642ba03d1a79fab4ae42c68f90b6442db2cd2b00..0000000000000000000000000000000000000000 --- a/Revert-memory-Add-IOMMU_ATTR_VFIO_NESTED-IOMMU-memor.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 4c9e81175e15ca78c7ba7090ec20ea10c9e12751 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:53 +0800 -Subject: [PATCH 31/36] Revert "memory: Add IOMMU_ATTR_VFIO_NESTED IOMMU memory - region attribute" - -This reverts commit b380e3e0c30fb68dbbfb1397f3c374adfff77ac4. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 12 ------------ - include/exec/memory.h | 3 +-- - 2 files changed, 1 insertion(+), 14 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 5a092506d3..f4de66827d 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -1593,17 +1593,6 @@ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu, - return 0; - } - --static int smmuv3_get_attr(IOMMUMemoryRegion *iommu, -- enum IOMMUMemoryRegionAttr attr, -- void *data) --{ -- if (attr == IOMMU_ATTR_VFIO_NESTED) { -- *(bool *) data = true; -- return 0; -- } -- return -EINVAL; --} -- - static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - void *data) - { -@@ -1611,7 +1600,6 @@ static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - - imrc->translate = smmuv3_translate; - imrc->notify_flag_changed = smmuv3_notify_flag_changed; -- imrc->get_attr = smmuv3_get_attr; - } - - static const TypeInfo smmuv3_type_info = { -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 229c9cf85b..273f7f45d3 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -324,8 +324,7 @@ typedef struct MemoryRegionClass { - - - enum IOMMUMemoryRegionAttr { -- IOMMU_ATTR_SPAPR_TCE_FD, -- IOMMU_ATTR_VFIO_NESTED, -+ IOMMU_ATTR_SPAPR_TCE_FD - }; - - /* --- -2.27.0 - diff --git a/Revert-memory-Add-new-fields-in-IOTLBEntry.patch b/Revert-memory-Add-new-fields-in-IOTLBEntry.patch deleted file mode 100644 index c5bbe0c8c874982e574d7f900f85afbb522b04f3..0000000000000000000000000000000000000000 --- a/Revert-memory-Add-new-fields-in-IOTLBEntry.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 8cc370faf56aeaa060e1b4d9a307075bae982563 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:57 +0800 -Subject: [PATCH 34/36] Revert "memory: Add new fields in IOTLBEntry" - -This reverts commit da97cef20d4ee5a8f3942953836b35e7f7dd974f. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmu-common.c | 2 +- - hw/arm/smmuv3.c | 2 +- - hw/i386/intel_iommu.c | 6 +++--- - hw/ppc/spapr_iommu.c | 2 +- - hw/virtio/virtio-iommu.c | 4 ++-- - include/exec/memory.h | 36 +----------------------------------- - 6 files changed, 9 insertions(+), 43 deletions(-) - -diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c -index 730dd20db1..e09b9c13b7 100644 ---- a/hw/arm/smmu-common.c -+++ b/hw/arm/smmu-common.c -@@ -471,7 +471,7 @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid) - /* Unmap the whole notifier's range */ - static void smmu_unmap_notifier_range(IOMMUNotifier *n) - { -- IOMMUTLBEvent event = {}; -+ IOMMUTLBEvent event; - - event.type = IOMMU_NOTIFIER_UNMAP; - event.entry.target_as = &address_space_memory; -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 0e8fe646aa..3b43368be0 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -806,7 +806,7 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - uint8_t tg, uint64_t num_pages) - { - SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu); -- IOMMUTLBEvent event = {}; -+ IOMMUTLBEvent event; - uint8_t granule; - - if (!tg) { -diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c -index 6501d93f7e..5b865ac08c 100644 ---- a/hw/i386/intel_iommu.c -+++ b/hw/i386/intel_iommu.c -@@ -1197,7 +1197,7 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start, - uint32_t offset; - uint64_t slpte; - uint64_t subpage_size, subpage_mask; -- IOMMUTLBEvent event = {}; -+ IOMMUTLBEvent event; - uint64_t iova = start; - uint64_t iova_next; - int ret = 0; -@@ -2431,7 +2431,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s, - VTDInvDesc *inv_desc) - { - VTDAddressSpace *vtd_dev_as; -- IOMMUTLBEvent event = {}; -+ IOMMUTLBEvent event; - struct VTDBus *vtd_bus; - hwaddr addr; - uint64_t sz; -@@ -3487,7 +3487,7 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n) - size = remain = end - start + 1; - - while (remain >= VTD_PAGE_SIZE) { -- IOMMUTLBEvent event = {}; -+ IOMMUTLBEvent event; - uint64_t mask = dma_aligned_pow2_mask(start, end, s->aw_bits); - uint64_t size = mask + 1; - -diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c -index 454df25d44..db01071858 100644 ---- a/hw/ppc/spapr_iommu.c -+++ b/hw/ppc/spapr_iommu.c -@@ -449,7 +449,7 @@ static void spapr_tce_reset(DeviceState *dev) - static target_ulong put_tce_emu(SpaprTceTable *tcet, target_ulong ioba, - target_ulong tce) - { -- IOMMUTLBEvent event = {}; -+ IOMMUTLBEvent event; - hwaddr page_mask = IOMMU_PAGE_MASK(tcet->page_shift); - unsigned long index = (ioba - tcet->bus_offset) >> tcet->page_shift; - -diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c -index 83ed2b82e6..1b23e8e18c 100644 ---- a/hw/virtio/virtio-iommu.c -+++ b/hw/virtio/virtio-iommu.c -@@ -129,7 +129,7 @@ static void virtio_iommu_notify_map(IOMMUMemoryRegion *mr, hwaddr virt_start, - hwaddr virt_end, hwaddr paddr, - uint32_t flags) - { -- IOMMUTLBEvent event = {}; -+ IOMMUTLBEvent event; - IOMMUAccessFlags perm = IOMMU_ACCESS_FLAG(flags & VIRTIO_IOMMU_MAP_F_READ, - flags & VIRTIO_IOMMU_MAP_F_WRITE); - -@@ -154,7 +154,7 @@ static void virtio_iommu_notify_map(IOMMUMemoryRegion *mr, hwaddr virt_start, - static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start, - hwaddr virt_end) - { -- IOMMUTLBEvent event = {}; -+ IOMMUTLBEvent event; - uint64_t delta = virt_end - virt_start; - - if (!(mr->iommu_notify_flags & IOMMU_NOTIFIER_UNMAP)) { -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 273f7f45d3..4b5b431e45 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -116,48 +116,14 @@ typedef enum { - IOMMU_RW = 3, - } IOMMUAccessFlags; - --/* Granularity of the cache invalidation */ --typedef enum { -- IOMMU_INV_GRAN_ADDR = 0, -- IOMMU_INV_GRAN_PASID, -- IOMMU_INV_GRAN_DOMAIN, --} IOMMUInvGranularity; -- - #define IOMMU_ACCESS_FLAG(r, w) (((r) ? IOMMU_RO : 0) | ((w) ? IOMMU_WO : 0)) - --/** -- * struct IOMMUTLBEntry - IOMMU TLB entry -- * -- * Structure used when performing a translation or when notifying MAP or -- * UNMAP (invalidation) events -- * -- * @target_as: target address space -- * @iova: IO virtual address (input) -- * @translated_addr: translated address (output) -- * @addr_mask: address mask (0xfff means 4K binding), must be multiple of 2 -- * @perm: permission flag of the mapping (NONE encodes no mapping or -- * invalidation notification) -- * @granularity: granularity of the invalidation -- * @flags: informs whether the following fields are set -- * @arch_id: architecture specific ID tagging the TLB -- * @pasid: PASID tagging the TLB -- * @leaf: when @perm is NONE, indicates whether only caches for the last -- * level of translation need to be invalidated. -- */ - struct IOMMUTLBEntry { - AddressSpace *target_as; - hwaddr iova; - hwaddr translated_addr; -- hwaddr addr_mask; -+ hwaddr addr_mask; /* 0xfff = 4k translation */ - IOMMUAccessFlags perm; -- IOMMUInvGranularity granularity; --#define IOMMU_INV_FLAGS_PASID (1 << 0) --#define IOMMU_INV_FLAGS_ARCHID (1 << 1) --#define IOMMU_INV_FLAGS_LEAF (1 << 2) -- uint32_t flags; -- uint32_t arch_id; -- uint32_t pasid; -- bool leaf; - }; - - /* --- -2.27.0 - diff --git a/Revert-memory-Introduce-IOMMU-Memory-Region-inject_f.patch b/Revert-memory-Introduce-IOMMU-Memory-Region-inject_f.patch deleted file mode 100644 index 8efb12280f25a98ca616ba0daa200b3a6569c8bd..0000000000000000000000000000000000000000 --- a/Revert-memory-Introduce-IOMMU-Memory-Region-inject_f.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 3ab99dc1bf580607791aa402ad330720ce993ae2 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:51 +0800 -Subject: [PATCH 29/36] Revert "memory: Introduce IOMMU Memory Region - inject_faults API" - -This reverts commit d2dce19165f133935ff72e209f19bc43ab4d1421. - -Signed-off-by: Kunkun Jiang ---- - include/exec/memory.h | 24 ------------------------ - softmmu/memory.c | 10 ---------- - 2 files changed, 34 deletions(-) - -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 7c3fe69d52..67d9061766 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -106,8 +106,6 @@ struct MemoryRegionSection { - bool nonvolatile; - }; - --struct iommu_fault; -- - typedef struct IOMMUTLBEntry IOMMUTLBEntry; - - /* See address_space_translate: bit 0 is read, bit 1 is write. */ -@@ -528,19 +526,6 @@ struct IOMMUMemoryRegionClass { - int (*iommu_set_page_size_mask)(IOMMUMemoryRegion *iommu, - uint64_t page_size_mask, - Error **errp); -- -- /* -- * Inject @count faults into the IOMMU memory region -- * -- * Optional method: if this method is not provided, then -- * memory_region_injection_faults() will return -ENOENT -- * -- * @iommu: the IOMMU memory region to inject the faults in -- * @count: number of faults to inject -- * @buf: fault buffer -- */ -- int (*inject_faults)(IOMMUMemoryRegion *iommu, int count, -- struct iommu_fault *buf); - }; - - typedef struct RamDiscardListener RamDiscardListener; -@@ -1837,15 +1822,6 @@ int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr); - int memory_region_iommu_set_page_size_mask(IOMMUMemoryRegion *iommu_mr, - uint64_t page_size_mask, - Error **errp); --/** -- * memory_region_inject_faults : inject @count faults stored in @buf -- * -- * @iommu_mr: the IOMMU memory region -- * @count: number of faults to be injected -- * @buf: buffer containing the faults -- */ --int memory_region_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, -- struct iommu_fault *buf); - - /** - * memory_region_name: get a memory region's name -diff --git a/softmmu/memory.c b/softmmu/memory.c -index 9f98209ab2..7340e19ff5 100644 ---- a/softmmu/memory.c -+++ b/softmmu/memory.c -@@ -2111,16 +2111,6 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, - rdmc->unregister_listener(rdm, rdl); - } - --int memory_region_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, -- struct iommu_fault *buf) --{ -- IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr); -- if (!imrc->inject_faults) { -- return -ENOENT; -- } -- return imrc->inject_faults(iommu_mr, count, buf); --} -- - void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) - { - uint8_t mask = 1 << client; --- -2.27.0 - diff --git a/Revert-monitor-limit-io-error-qmp-event-to-at-most-o.patch b/Revert-monitor-limit-io-error-qmp-event-to-at-most-o.patch deleted file mode 100644 index 112161f6733b0f45f07bfb738342eefa9d12ad35..0000000000000000000000000000000000000000 --- a/Revert-monitor-limit-io-error-qmp-event-to-at-most-o.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e42b57adeac96c7d39b1c032ab3b66b7eff18cc8 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Tue, 29 Mar 2022 15:18:56 +0800 -Subject: [PATCH 2/2] Revert "monitor: limit io error qmp event to at most once - per 60s" - -This reverts commit 44f45b5c163efed5387dac40e229e0a50bf5921a. - -The commit 44f45b5c will reduse the IO-hang related log, which -is useful to solve the problem. - -Signed-off-by: Yan Wang ---- - monitor/monitor.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/monitor/monitor.c b/monitor/monitor.c -index 28206bedc4..257ef4ee54 100644 ---- a/monitor/monitor.c -+++ b/monitor/monitor.c -@@ -301,7 +301,6 @@ static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = { - [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS }, - [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS }, - [QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS }, -- [QAPI_EVENT_BLOCK_IO_ERROR] = { 60L * 1000 * SCALE_MS }, - }; - - /* --- -2.27.0 - diff --git a/Revert-pci-Add-return_page_response-pci-ops.patch b/Revert-pci-Add-return_page_response-pci-ops.patch deleted file mode 100644 index cafc0a41c70770bfd59f2d6bf80c1ed3f0ec981c..0000000000000000000000000000000000000000 --- a/Revert-pci-Add-return_page_response-pci-ops.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 9f843b181db3d73e86df140a41975a7645adc071 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:27 +0800 -Subject: [PATCH 10/36] Revert "pci: Add return_page_response pci ops" - -This reverts commit 228345cfa59c764e725e2d3680a4bc3ecb237609. - -Signed-off-by: Kunkun Jiang ---- - hw/pci/pci.c | 16 ---------------- - include/hw/iommu/iommu.h | 8 -------- - include/hw/pci/pci.h | 4 ---- - 3 files changed, 28 deletions(-) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 0743dc7c42..71076fff48 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -2797,22 +2797,6 @@ int pci_device_set_pasid_table(PCIBus *bus, int32_t devfn, - return -ENOENT; - } - --int pci_device_return_page_response(PCIBus *bus, int32_t devfn, -- IOMMUPageResponse *resp) --{ -- PCIDevice *dev; -- -- if (!bus) { -- return -EINVAL; -- } -- -- dev = bus->devices[devfn]; -- if (dev && dev->pasid_ops && dev->pasid_ops->return_page_response) { -- return dev->pasid_ops->return_page_response(bus, devfn, resp); -- } -- return -ENOENT; --} -- - static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque) - { - Range *range = opaque; -diff --git a/include/hw/iommu/iommu.h b/include/hw/iommu/iommu.h -index 5890f095b1..12092bda7b 100644 ---- a/include/hw/iommu/iommu.h -+++ b/include/hw/iommu/iommu.h -@@ -24,13 +24,5 @@ typedef struct IOMMUConfig { - }; - } IOMMUConfig; - --typedef struct IOMMUPageResponse { -- union { --#ifdef __linux__ -- struct iommu_page_response resp; --#endif -- }; --} IOMMUPageResponse; -- - - #endif /* QEMU_HW_IOMMU_IOMMU_H */ -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index bfe3a6bca7..4cf3dc6b43 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -268,8 +268,6 @@ typedef struct PCIReqIDCache PCIReqIDCache; - - struct PCIPASIDOps { - int (*set_pasid_table)(PCIBus *bus, int32_t devfn, IOMMUConfig *config); -- int (*return_page_response)(PCIBus *bus, int32_t devfn, -- IOMMUPageResponse *resp); - }; - typedef struct PCIPASIDOps PCIPASIDOps; - -@@ -510,8 +508,6 @@ void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque); - void pci_setup_pasid_ops(PCIDevice *dev, PCIPASIDOps *ops); - bool pci_device_is_pasid_ops_set(PCIBus *bus, int32_t devfn); - int pci_device_set_pasid_table(PCIBus *bus, int32_t devfn, IOMMUConfig *config); --int pci_device_return_page_response(PCIBus *bus, int32_t devfn, -- IOMMUPageResponse *resp); - - static inline void - pci_set_byte(uint8_t *config, uint8_t val) --- -2.27.0 - diff --git a/Revert-pci-introduce-PCIPASIDOps-to-PCIDevice.patch b/Revert-pci-introduce-PCIPASIDOps-to-PCIDevice.patch deleted file mode 100644 index 65862e9989e51e47e5e9d0c42985a77c2724e67f..0000000000000000000000000000000000000000 --- a/Revert-pci-introduce-PCIPASIDOps-to-PCIDevice.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 87a125d3a175fd65f921dc7089450e13ce2ac457 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:49 +0800 -Subject: [PATCH 27/36] Revert "pci: introduce PCIPASIDOps to PCIDevice" - -This reverts commit c71485494970e7aa986be2b05bf7e2847017e264. - -Signed-off-by: Kunkun Jiang ---- - hw/pci/pci.c | 34 ---------------------------------- - include/hw/pci/pci.h | 11 ----------- - 2 files changed, 45 deletions(-) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 71076fff48..40e2516d99 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -2763,40 +2763,6 @@ void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque) - bus->iommu_opaque = opaque; - } - --void pci_setup_pasid_ops(PCIDevice *dev, PCIPASIDOps *ops) --{ -- assert(ops && !dev->pasid_ops); -- dev->pasid_ops = ops; --} -- --bool pci_device_is_pasid_ops_set(PCIBus *bus, int32_t devfn) --{ -- PCIDevice *dev; -- -- if (!bus) { -- return false; -- } -- -- dev = bus->devices[devfn]; -- return !!(dev && dev->pasid_ops); --} -- --int pci_device_set_pasid_table(PCIBus *bus, int32_t devfn, -- IOMMUConfig *config) --{ -- PCIDevice *dev; -- -- if (!bus) { -- return -EINVAL; -- } -- -- dev = bus->devices[devfn]; -- if (dev && dev->pasid_ops && dev->pasid_ops->set_pasid_table) { -- return dev->pasid_ops->set_pasid_table(bus, devfn, config); -- } -- return -ENOENT; --} -- - static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque) - { - Range *range = opaque; -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index 4cf3dc6b43..5b36334a28 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -9,7 +9,6 @@ - - #include "hw/pci/pcie.h" - #include "qom/object.h" --#include "hw/iommu/iommu.h" - - extern bool pci_available; - -@@ -266,11 +265,6 @@ struct PCIReqIDCache { - }; - typedef struct PCIReqIDCache PCIReqIDCache; - --struct PCIPASIDOps { -- int (*set_pasid_table)(PCIBus *bus, int32_t devfn, IOMMUConfig *config); --}; --typedef struct PCIPASIDOps PCIPASIDOps; -- - struct PCIDevice { - DeviceState qdev; - bool partially_hotplugged; -@@ -367,7 +361,6 @@ struct PCIDevice { - /* ID of standby device in net_failover pair */ - char *failover_pair_id; - uint32_t acpi_index; -- PCIPASIDOps *pasid_ops; - }; - - void pci_register_bar(PCIDevice *pci_dev, int region_num, -@@ -505,10 +498,6 @@ typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int); - AddressSpace *pci_device_iommu_address_space(PCIDevice *dev); - void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque); - --void pci_setup_pasid_ops(PCIDevice *dev, PCIPASIDOps *ops); --bool pci_device_is_pasid_ops_set(PCIBus *bus, int32_t devfn); --int pci_device_set_pasid_table(PCIBus *bus, int32_t devfn, IOMMUConfig *config); -- - static inline void - pci_set_byte(uint8_t *config, uint8_t val) - { --- -2.27.0 - diff --git a/Revert-qmp-add-command-to-query-used-memslots-of-vho.patch b/Revert-qmp-add-command-to-query-used-memslots-of-vho.patch deleted file mode 100644 index 02f8797078723c92d08fabe7243a9cc1dbdfd5a5..0000000000000000000000000000000000000000 --- a/Revert-qmp-add-command-to-query-used-memslots-of-vho.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 92e9fb334c38cd21652ce8adde9ec01ab4412426 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Tue, 15 Feb 2022 15:18:17 +0800 -Subject: [PATCH] Revert "qmp: add command to query used memslots of vhost-net - and vhost-user" - -This reverts commit 1545a60a8b78490c7dc8909b7012bca63dba63cd. - -Signed-off-by: Jinhua Cao ---- - hw/virtio/vhost-backend.c | 2 +- - hw/virtio/vhost-user.c | 2 +- - include/hw/virtio/vhost-backend.h | 2 -- - monitor/qmp-cmds.c | 12 ------------ - qapi/net.json | 18 ------------------ - qapi/pragma.json | 4 +--- - 6 files changed, 3 insertions(+), 37 deletions(-) - -diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c -index d8e1710758..2acfb750fd 100644 ---- a/hw/virtio/vhost-backend.c -+++ b/hw/virtio/vhost-backend.c -@@ -300,7 +300,7 @@ static void vhost_kernel_set_used_memslots(struct vhost_dev *dev) - vhost_kernel_used_memslots = dev->mem->nregions; - } - --unsigned int vhost_kernel_get_used_memslots(void) -+static unsigned int vhost_kernel_get_used_memslots(void) - { - return vhost_kernel_used_memslots; - } -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index 8f69a3b850..176cae9244 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -2544,7 +2544,7 @@ static void vhost_user_set_used_memslots(struct vhost_dev *dev) - vhost_user_used_memslots = counter; - } - --unsigned int vhost_user_get_used_memslots(void) -+static unsigned int vhost_user_get_used_memslots(void) - { - return vhost_user_used_memslots; - } -diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h -index 7bbc658161..a64708f456 100644 ---- a/include/hw/virtio/vhost-backend.h -+++ b/include/hw/virtio/vhost-backend.h -@@ -190,6 +190,4 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev, - - int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd); - --unsigned int vhost_kernel_get_used_memslots(void); --unsigned int vhost_user_get_used_memslots(void); - #endif /* VHOST_BACKEND_H */ -diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c -index a138e7dd4b..d71beace6a 100644 ---- a/monitor/qmp-cmds.c -+++ b/monitor/qmp-cmds.c -@@ -37,7 +37,6 @@ - #include "qapi/qapi-commands-machine.h" - #include "qapi/qapi-commands-misc.h" - #include "qapi/qapi-commands-ui.h" --#include "qapi/qapi-commands-net.h" - #include "qapi/type-helpers.h" - #include "qapi/qmp/qerror.h" - #include "exec/ramlist.h" -@@ -45,7 +44,6 @@ - #include "hw/acpi/acpi_dev_interface.h" - #include "hw/intc/intc.h" - #include "hw/rdma/rdma.h" --#include "hw/virtio/vhost-backend.h" - - NameInfo *qmp_query_name(Error **errp) - { -@@ -476,13 +474,3 @@ int64_t qmp_query_rtc_date_diff(Error **errp) - { - return get_rtc_date_diff(); - } -- --uint32_t qmp_query_vhost_kernel_used_memslots(Error **errp) --{ -- return vhost_kernel_get_used_memslots(); --} -- --uint32_t qmp_query_vhost_user_used_memslots(Error **errp) --{ -- return vhost_user_get_used_memslots(); --} -diff --git a/qapi/net.json b/qapi/net.json -index c9ff849eed..7fab2e7cd8 100644 ---- a/qapi/net.json -+++ b/qapi/net.json -@@ -696,21 +696,3 @@ - ## - { 'event': 'FAILOVER_NEGOTIATED', - 'data': {'device-id': 'str'} } -- --## --# @query-vhost-kernel-used-memslots: --# --# Get vhost-kernel nic used memslots --# --# Since: 4.1 --## --{ 'command': 'query-vhost-kernel-used-memslots', 'returns': 'uint32' } -- --## --# @query-vhost-user-used-memslots: --# --# Get vhost-user nic used memslots --# --# Since: 4.1 --## --{ 'command': 'query-vhost-user-used-memslots', 'returns': 'uint32' } -diff --git a/qapi/pragma.json b/qapi/pragma.json -index d35c897acb..b37f6de445 100644 ---- a/qapi/pragma.json -+++ b/qapi/pragma.json -@@ -27,9 +27,7 @@ - 'query-tpm-models', - 'query-tpm-types', - 'ringbuf-read', -- 'query-rtc-date-diff', -- 'query-vhost-user-used-memslots', -- 'query-vhost-kernel-used-memslots' ], -+ 'query-rtc-date-diff' ], - # Externally visible types whose member names may use uppercase - 'member-name-exceptions': [ # visible in: - 'ACPISlotType', # query-acpi-ospm-status --- -2.27.0 - diff --git a/Revert-update-linux-headers-Import-iommu.h.patch b/Revert-update-linux-headers-Import-iommu.h.patch deleted file mode 100644 index 8346a9bd39f8503913983b1ec165bf62529ad64c..0000000000000000000000000000000000000000 --- a/Revert-update-linux-headers-Import-iommu.h.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 00e2515716eda5426bd999f812add9ff70204fc6 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:23:00 +0800 -Subject: [PATCH 36/36] Revert "update-linux-headers: Import iommu.h" - -This reverts commit 694acf3c321908d26ce508842b7bd076664ffbc6. - -Signed-off-by: Kunkun Jiang ---- - scripts/update-linux-headers.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index acde610733..fea4d6eb65 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -144,7 +144,7 @@ done - - rm -rf "$output/linux-headers/linux" - mkdir -p "$output/linux-headers/linux" --for header in kvm.h vfio.h vfio_ccw.h vfio_zdev.h vhost.h iommu.h \ -+for header in kvm.h vfio.h vfio_ccw.h vfio_zdev.h vhost.h \ - psci.h psp-sev.h userfaultfd.h mman.h; do - cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux" - done --- -2.27.0 - diff --git a/Revert-vfio-Add-vfio_prereg_listener_global_log_star.patch b/Revert-vfio-Add-vfio_prereg_listener_global_log_star.patch deleted file mode 100644 index 8b8f9670337759aad16489898f56edbc68948791..0000000000000000000000000000000000000000 --- a/Revert-vfio-Add-vfio_prereg_listener_global_log_star.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 92c1c6d689d9f501a3f242b085cbbcb22ee931b4 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:18 +0800 -Subject: [PATCH 04/36] Revert "vfio: Add - vfio_prereg_listener_global_log_start/stop in nested stage" - -This reverts commit 287c63ab540533f1f9642e753c091caa7e6e2511. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 24 ------------------------ - 1 file changed, 24 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 65f3979492..20c820aa74 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1501,17 +1501,6 @@ static void vfio_listener_log_global_start(MemoryListener *listener) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); - -- /* For nested mode, vfio_prereg_listener is used to start dirty tracking */ -- if (container->iommu_type != VFIO_TYPE1_NESTING_IOMMU) { -- vfio_set_dirty_page_tracking(container, true); -- } --} -- --static void vfio_prereg_listener_log_global_start(MemoryListener *listener) --{ -- VFIOContainer *container = -- container_of(listener, VFIOContainer, prereg_listener); -- - vfio_set_dirty_page_tracking(container, true); - } - -@@ -1519,17 +1508,6 @@ static void vfio_listener_log_global_stop(MemoryListener *listener) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); - -- /* For nested mode, vfio_prereg_listener is used to stop dirty tracking */ -- if (container->iommu_type != VFIO_TYPE1_NESTING_IOMMU) { -- vfio_set_dirty_page_tracking(container, false); -- } --} -- --static void vfio_prereg_listener_log_global_stop(MemoryListener *listener) --{ -- VFIOContainer *container = -- container_of(listener, VFIOContainer, prereg_listener); -- - vfio_set_dirty_page_tracking(container, false); - } - -@@ -1944,8 +1922,6 @@ static const MemoryListener vfio_memory_listener = { - static MemoryListener vfio_memory_prereg_listener = { - .region_add = vfio_prereg_listener_region_add, - .region_del = vfio_prereg_listener_region_del, -- .log_global_start = vfio_prereg_listener_log_global_start, -- .log_global_stop = vfio_prereg_listener_log_global_stop, - .log_sync = vfio_prereg_listener_log_sync, - .log_clear = vfio_prereg_listener_log_clear, - }; --- -2.27.0 - diff --git a/Revert-vfio-Add-vfio_prereg_listener_log_clear-to-re.patch b/Revert-vfio-Add-vfio_prereg_listener_log_clear-to-re.patch deleted file mode 100644 index 99a3a716230e9e48f7814b7b2b47198f33c25eaa..0000000000000000000000000000000000000000 --- a/Revert-vfio-Add-vfio_prereg_listener_log_clear-to-re.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 609b216873bfa9377f624dabcf709930e1722ca7 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:20 +0800 -Subject: [PATCH 05/36] Revert "vfio: Add vfio_prereg_listener_log_clear to - re-enable mark dirty pages" - -This reverts commit 7086df6d90cd698a3e20cf4cf6e9a834f168cd8f. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 40 +--------------------------------------- - 1 file changed, 1 insertion(+), 39 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 20c820aa74..2506cd57ee 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1857,43 +1857,6 @@ static int vfio_physical_log_clear(VFIOContainer *container, - return ret; - } - --static void vfio_prereg_listener_log_clear(MemoryListener *listener, -- MemoryRegionSection *section) --{ -- VFIOContainer *container = -- container_of(listener, VFIOContainer, prereg_listener); -- -- if (!memory_region_is_ram(section->mr)) { -- return; -- } -- -- vfio_physical_log_clear(container, section); --} -- --static int vfio_clear_dirty_bitmap(VFIOContainer *container, -- MemoryRegionSection *section) --{ -- if (memory_region_is_iommu(section->mr)) { -- /* -- * In nested mode, stage 2 (gpa->hpa) and stage 1 (giova->gpa) are -- * set up separately. It is inappropriate to pass 'giova' to kernel -- * to get dirty pages. We only need to focus on stage 2 mapping when -- * marking dirty pages. -- */ -- if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -- return 0; -- } -- -- /* -- * TODO: x86. With the log_clear() interface added, x86 may inplement -- * its own method. -- */ -- } -- -- /* Here we assume that memory_region_is_ram(section->mr) == true */ -- return vfio_physical_log_clear(container, section); --} -- - static void vfio_listener_log_clear(MemoryListener *listener, - MemoryRegionSection *section) - { -@@ -1905,7 +1868,7 @@ static void vfio_listener_log_clear(MemoryListener *listener, - } - - if (vfio_devices_all_dirty_tracking(container)) { -- vfio_clear_dirty_bitmap(container, section); -+ vfio_physical_log_clear(container, section); - } - } - -@@ -1923,7 +1886,6 @@ static MemoryListener vfio_memory_prereg_listener = { - .region_add = vfio_prereg_listener_region_add, - .region_del = vfio_prereg_listener_region_del, - .log_sync = vfio_prereg_listener_log_sync, -- .log_clear = vfio_prereg_listener_log_clear, - }; - - static void vfio_listener_release(VFIOContainer *container) --- -2.27.0 - diff --git a/Revert-vfio-Add-vfio_prereg_listener_log_sync-in-nes.patch b/Revert-vfio-Add-vfio_prereg_listener_log_sync-in-nes.patch deleted file mode 100644 index f2def5f968e0bc667decc5ddd1b92e3a9bd63478..0000000000000000000000000000000000000000 --- a/Revert-vfio-Add-vfio_prereg_listener_log_sync-in-nes.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 13253899d93b287a7e8d78bdff48978f633eb279 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:22 +0800 -Subject: [PATCH 06/36] Revert "vfio: Add vfio_prereg_listener_log_sync in - nested stage" - -This reverts commit f4523389bf57593484308124e06d67855bb79315. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 27 --------------------------- - 1 file changed, 27 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 2506cd57ee..6136b1ef61 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1579,22 +1579,6 @@ static int vfio_dma_sync_ram_section_dirty_bitmap(VFIOContainer *container, - int128_get64(section->size), ram_addr); - } - --static void vfio_prereg_listener_log_sync(MemoryListener *listener, -- MemoryRegionSection *section) --{ -- VFIOContainer *container = -- container_of(listener, VFIOContainer, prereg_listener); -- -- if (!memory_region_is_ram(section->mr) || -- !container->dirty_pages_supported) { -- return; -- } -- -- if (vfio_devices_all_dirty_tracking(container)) { -- vfio_dma_sync_ram_section_dirty_bitmap(container, section); -- } --} -- - typedef struct { - IOMMUNotifier n; - VFIOGuestIOMMU *giommu; -@@ -1682,16 +1666,6 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container, - if (memory_region_is_iommu(section->mr)) { - VFIOGuestIOMMU *giommu; - -- /* -- * In nested mode, stage 2 (gpa->hpa) and stage 1 (giova->gpa) are -- * set up separately. It is inappropriate to pass 'giova' to kernel -- * to get dirty pages. We only need to focus on stage 2 mapping when -- * marking dirty pages. -- */ -- if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -- return 0; -- } -- - QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) { - if (MEMORY_REGION(giommu->iommu) == section->mr && - giommu->n.start == section->offset_within_region) { -@@ -1885,7 +1859,6 @@ static const MemoryListener vfio_memory_listener = { - static MemoryListener vfio_memory_prereg_listener = { - .region_add = vfio_prereg_listener_region_add, - .region_del = vfio_prereg_listener_region_del, -- .log_sync = vfio_prereg_listener_log_sync, - }; - - static void vfio_listener_release(VFIOContainer *container) --- -2.27.0 - diff --git a/Revert-vfio-Force-nested-if-iommu-requires-it.patch b/Revert-vfio-Force-nested-if-iommu-requires-it.patch deleted file mode 100644 index 9f85d5fd14e303301cb8e4e6d1f9f7b5d6a4bb25..0000000000000000000000000000000000000000 --- a/Revert-vfio-Force-nested-if-iommu-requires-it.patch +++ /dev/null @@ -1,97 +0,0 @@ -From bac64f79264fd95b349004dd20b4ef7e9944fcb7 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:47 +0800 -Subject: [PATCH 26/36] Revert "vfio: Force nested if iommu requires it" - -This reverts commit e7eef5af743a53f0415267ebe9bba2e5f0e05816. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 36 ++++++++---------------------------- - 1 file changed, 8 insertions(+), 28 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index d7533637c9..6cb91e7ffd 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -2045,38 +2045,27 @@ static void vfio_put_address_space(VFIOAddressSpace *space) - * vfio_get_iommu_type - selects the richest iommu_type (v2 first) - */ - static int vfio_get_iommu_type(VFIOContainer *container, -- bool want_nested, - Error **errp) - { -- int iommu_types[] = { VFIO_TYPE1_NESTING_IOMMU, -- VFIO_TYPE1v2_IOMMU, VFIO_TYPE1_IOMMU, -+ int iommu_types[] = { VFIO_TYPE1v2_IOMMU, VFIO_TYPE1_IOMMU, - VFIO_SPAPR_TCE_v2_IOMMU, VFIO_SPAPR_TCE_IOMMU }; -- int i, ret = -EINVAL; -+ int i; - - for (i = 0; i < ARRAY_SIZE(iommu_types); i++) { - if (ioctl(container->fd, VFIO_CHECK_EXTENSION, iommu_types[i])) { -- if (iommu_types[i] == VFIO_TYPE1_NESTING_IOMMU && !want_nested) { -- continue; -- } -- ret = iommu_types[i]; -- break; -+ return iommu_types[i]; - } - } -- if (ret < 0) { -- error_setg(errp, "No available IOMMU models"); -- } else if (want_nested && ret != VFIO_TYPE1_NESTING_IOMMU) { -- error_setg(errp, "Nested mode requested but not supported"); -- ret = -EINVAL; -- } -- return ret; -+ error_setg(errp, "No available IOMMU models"); -+ return -EINVAL; - } - - static int vfio_init_container(VFIOContainer *container, int group_fd, -- bool want_nested, Error **errp) -+ Error **errp) - { - int iommu_type, dirty_log_manual_clear, ret; - -- iommu_type = vfio_get_iommu_type(container, want_nested, errp); -+ iommu_type = vfio_get_iommu_type(container, errp); - if (iommu_type < 0) { - return iommu_type; - } -@@ -2188,14 +2177,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - VFIOContainer *container; - int ret, fd; - VFIOAddressSpace *space; -- IOMMUMemoryRegion *iommu_mr; -- bool nested = false; -- -- if (memory_region_is_iommu(as->root)) { -- iommu_mr = IOMMU_MEMORY_REGION(as->root); -- memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_VFIO_NESTED, -- (void *)&nested); -- } - - space = vfio_get_address_space(as); - -@@ -2276,7 +2257,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - QLIST_INIT(&container->vrdl_list); - QLIST_INIT(&container->dma_list); - -- ret = vfio_init_container(container, group->fd, nested, errp); -+ ret = vfio_init_container(container, group->fd, errp); - if (ret) { - goto free_container_exit; - } -@@ -2288,7 +2269,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - } - - switch (container->iommu_type) { -- case VFIO_TYPE1_NESTING_IOMMU: - case VFIO_TYPE1v2_IOMMU: - case VFIO_TYPE1_IOMMU: - { --- -2.27.0 - diff --git a/Revert-vfio-Helper-to-get-IRQ-info-including-capabil.patch b/Revert-vfio-Helper-to-get-IRQ-info-including-capabil.patch deleted file mode 100644 index 0f4cf227d52058122034ebc878d4c3c69e2c8afe..0000000000000000000000000000000000000000 --- a/Revert-vfio-Helper-to-get-IRQ-info-including-capabil.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 1ab4bff7e5d82a16a0d004fd964819d092325776 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:41 +0800 -Subject: [PATCH 21/36] Revert "vfio: Helper to get IRQ info including - capabilities" - -This reverts commit a4336765c99a876743c0ead89997ad6f97d7b442. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 97 ----------------------------------- - hw/vfio/trace-events | 1 - - include/hw/vfio/vfio-common.h | 7 --- - 3 files changed, 105 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index d05a485808..1f78af121d 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1919,25 +1919,6 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, - return true; - } - --struct vfio_info_cap_header * --vfio_get_irq_info_cap(struct vfio_irq_info *info, uint16_t id) --{ -- struct vfio_info_cap_header *hdr; -- void *ptr = info; -- -- if (!(info->flags & VFIO_IRQ_INFO_FLAG_CAPS)) { -- return NULL; -- } -- -- for (hdr = ptr + info->cap_offset; hdr != ptr; hdr = ptr + hdr->next) { -- if (hdr->id == id) { -- return hdr; -- } -- } -- -- return NULL; --} -- - static int vfio_setup_region_sparse_mmaps(VFIORegion *region, - struct vfio_region_info *info) - { -@@ -2906,33 +2887,6 @@ retry: - return 0; - } - --int vfio_get_irq_info(VFIODevice *vbasedev, int index, -- struct vfio_irq_info **info) --{ -- size_t argsz = sizeof(struct vfio_irq_info); -- -- *info = g_malloc0(argsz); -- -- (*info)->index = index; --retry: -- (*info)->argsz = argsz; -- -- if (ioctl(vbasedev->fd, VFIO_DEVICE_GET_IRQ_INFO, *info)) { -- g_free(*info); -- *info = NULL; -- return -errno; -- } -- -- if ((*info)->argsz > argsz) { -- argsz = (*info)->argsz; -- *info = g_realloc(*info, argsz); -- -- goto retry; -- } -- -- return 0; --} -- - int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, - uint32_t subtype, struct vfio_region_info **info) - { -@@ -2968,42 +2922,6 @@ int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, - return -ENODEV; - } - --int vfio_get_dev_irq_info(VFIODevice *vbasedev, uint32_t type, -- uint32_t subtype, struct vfio_irq_info **info) --{ -- int i; -- -- for (i = 0; i < vbasedev->num_irqs; i++) { -- struct vfio_info_cap_header *hdr; -- struct vfio_irq_info_cap_type *cap_type; -- -- if (vfio_get_irq_info(vbasedev, i, info)) { -- continue; -- } -- -- hdr = vfio_get_irq_info_cap(*info, VFIO_IRQ_INFO_CAP_TYPE); -- if (!hdr) { -- g_free(*info); -- continue; -- } -- -- cap_type = container_of(hdr, struct vfio_irq_info_cap_type, header); -- -- trace_vfio_get_dev_irq(vbasedev->name, i, -- cap_type->type, cap_type->subtype); -- -- if (cap_type->type == type && cap_type->subtype == subtype) { -- return 0; -- } -- -- g_free(*info); -- } -- -- *info = NULL; -- return -ENODEV; --} -- -- - bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) - { - struct vfio_region_info *info = NULL; -@@ -3019,21 +2937,6 @@ bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) - return ret; - } - --bool vfio_has_irq_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) --{ -- struct vfio_region_info *info = NULL; -- bool ret = false; -- -- if (!vfio_get_region_info(vbasedev, region, &info)) { -- if (vfio_get_region_info_cap(info, cap_type)) { -- ret = true; -- } -- g_free(info); -- } -- -- return ret; --} -- - /* - * Interfaces for IBM EEH (Enhanced Error Handling) - */ -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index f5fe201ab5..35bd415d6d 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -117,7 +117,6 @@ vfio_region_unmap(const char *name, unsigned long offset, unsigned long end) "Re - vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Device %s region %d: %d sparse mmap entries" - vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]" - vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8" --vfio_get_dev_irq(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8" - vfio_dma_unmap_overflow_workaround(void) "" - vfio_iommu_addr_inv_iotlb(int asid, uint64_t addr, uint64_t size, uint64_t nb_granules, bool leaf) "nested IOTLB invalidate asid=%d, addr=0x%"PRIx64" granule_size=0x%"PRIx64" nb_granules=0x%"PRIx64" leaf=%d" - vfio_iommu_asid_inv_iotlb(int asid) "nested IOTLB invalidate asid=%d" -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 7fdca26fa0..a838a939e4 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -254,13 +254,6 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, - unsigned int *avail); - struct vfio_info_cap_header * - vfio_get_device_info_cap(struct vfio_device_info *info, uint16_t id); --int vfio_get_irq_info(VFIODevice *vbasedev, int index, -- struct vfio_irq_info **info); --int vfio_get_dev_irq_info(VFIODevice *vbasedev, uint32_t type, -- uint32_t subtype, struct vfio_irq_info **info); --bool vfio_has_irq_cap(VFIODevice *vbasedev, int irq, uint16_t cap_type); --struct vfio_info_cap_header * --vfio_get_irq_info_cap(struct vfio_irq_info *info, uint16_t id); - #endif - extern const MemoryListener vfio_prereg_listener; - --- -2.27.0 - diff --git a/Revert-vfio-Introduce-helpers-to-DMA-map-unmap-a-RAM.patch b/Revert-vfio-Introduce-helpers-to-DMA-map-unmap-a-RAM.patch deleted file mode 100644 index 0a8be2846c4d1781ddde062dbec0580fd45e6c37..0000000000000000000000000000000000000000 --- a/Revert-vfio-Introduce-helpers-to-DMA-map-unmap-a-RAM.patch +++ /dev/null @@ -1,277 +0,0 @@ -From e73a30ce20cf0686e7a08e061f8afa5c8c385361 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:45 +0800 -Subject: [PATCH 24/36] Revert "vfio: Introduce helpers to DMA map/unmap a RAM - section" - -This reverts commit dab969657d8ff8b175856f91b035b74849cf69ba. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 206 ++++++++++++++++++------------------------- - hw/vfio/trace-events | 4 +- - 2 files changed, 87 insertions(+), 123 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index b3dc090840..d358789f19 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -922,130 +922,13 @@ hostwin_from_range(VFIOContainer *container, hwaddr iova, hwaddr end) - return NULL; - } - --static int vfio_dma_map_ram_section(VFIOContainer *container, -- MemoryRegionSection *section, Error **err) --{ -- VFIOHostDMAWindow *hostwin; -- Int128 llend, llsize; -- hwaddr iova, end; -- void *vaddr; -- int ret; -- -- assert(memory_region_is_ram(section->mr)); -- -- iova = TARGET_PAGE_ALIGN(section->offset_within_address_space); -- llend = int128_make64(section->offset_within_address_space); -- llend = int128_add(llend, section->size); -- llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK)); -- end = int128_get64(int128_sub(llend, int128_one())); -- -- vaddr = memory_region_get_ram_ptr(section->mr) + -- section->offset_within_region + -- (iova - section->offset_within_address_space); -- -- hostwin = hostwin_from_range(container, iova, end); -- if (!hostwin) { -- error_setg(err, "Container %p can't map guest IOVA region" -- " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, container, iova, end); -- return -EFAULT; -- } -- -- trace_vfio_dma_map_ram(iova, end, vaddr); -- -- llsize = int128_sub(llend, int128_make64(iova)); -- -- if (memory_region_is_ram_device(section->mr)) { -- hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; -- -- if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) { -- trace_vfio_listener_region_add_no_dma_map( -- memory_region_name(section->mr), -- section->offset_within_address_space, -- int128_getlo(section->size), -- pgmask + 1); -- return 0; -- } -- } -- -- ret = vfio_dma_map(container, iova, int128_get64(llsize), -- vaddr, section->readonly); -- if (ret) { -- error_setg(err, "vfio_dma_map(%p, 0x%"HWADDR_PRIx", " -- "0x%"HWADDR_PRIx", %p) = %d (%m)", -- container, iova, int128_get64(llsize), vaddr, ret); -- if (memory_region_is_ram_device(section->mr)) { -- /* Allow unexpected mappings not to be fatal for RAM devices */ -- error_report_err(*err); -- return 0; -- } -- return ret; -- } -- return 0; --} -- --static void vfio_dma_unmap_ram_section(VFIOContainer *container, -- MemoryRegionSection *section) --{ -- Int128 llend, llsize; -- hwaddr iova, end; -- bool try_unmap = true; -- int ret; -- -- iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -- llend = int128_make64(section->offset_within_address_space); -- llend = int128_add(llend, section->size); -- llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); -- -- if (int128_ge(int128_make64(iova), llend)) { -- return; -- } -- end = int128_get64(int128_sub(llend, int128_one())); -- -- llsize = int128_sub(llend, int128_make64(iova)); -- -- trace_vfio_dma_unmap_ram(iova, end); -- -- if (memory_region_is_ram_device(section->mr)) { -- hwaddr pgmask; -- VFIOHostDMAWindow *hostwin = hostwin_from_range(container, iova, end); -- -- assert(hostwin); /* or region_add() would have failed */ -- -- pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; -- try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); -- } else if (memory_region_has_ram_discard_manager(section->mr)) { -- vfio_unregister_ram_discard_listener(container, section); -- /* Unregistering will trigger an unmap. */ -- try_unmap = false; -- } -- -- if (try_unmap) { -- if (int128_eq(llsize, int128_2_64())) { -- /* The unmap ioctl doesn't accept a full 64-bit span. */ -- llsize = int128_rshift(llsize, 1); -- ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -- if (ret) { -- error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -- "0x%"HWADDR_PRIx") = %d (%m)", -- container, iova, int128_get64(llsize), ret); -- } -- iova += int128_get64(llsize); -- } -- ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -- if (ret) { -- error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -- "0x%"HWADDR_PRIx") = %d (%m)", -- container, iova, int128_get64(llsize), ret); -- } -- } --} -- - static void vfio_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); - hwaddr iova, end; -- Int128 llend; -+ Int128 llend, llsize; -+ void *vaddr; - int ret; - VFIOHostDMAWindow *hostwin; - Error *err = NULL; -@@ -1209,7 +1092,38 @@ static void vfio_listener_region_add(MemoryListener *listener, - return; - } - -- if (vfio_dma_map_ram_section(container, section, &err)) { -+ vaddr = memory_region_get_ram_ptr(section->mr) + -+ section->offset_within_region + -+ (iova - section->offset_within_address_space); -+ -+ trace_vfio_listener_region_add_ram(iova, end, vaddr); -+ -+ llsize = int128_sub(llend, int128_make64(iova)); -+ -+ if (memory_region_is_ram_device(section->mr)) { -+ hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; -+ -+ if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) { -+ trace_vfio_listener_region_add_no_dma_map( -+ memory_region_name(section->mr), -+ section->offset_within_address_space, -+ int128_getlo(section->size), -+ pgmask + 1); -+ return; -+ } -+ } -+ -+ ret = vfio_dma_map(container, iova, int128_get64(llsize), -+ vaddr, section->readonly); -+ if (ret) { -+ error_setg(&err, "vfio_dma_map(%p, 0x%"HWADDR_PRIx", " -+ "0x%"HWADDR_PRIx", %p) = %d (%m)", -+ container, iova, int128_get64(llsize), vaddr, ret); -+ if (memory_region_is_ram_device(section->mr)) { -+ /* Allow unexpected mappings not to be fatal for RAM devices */ -+ error_report_err(err); -+ return; -+ } - goto fail; - } - -@@ -1243,6 +1157,10 @@ static void vfio_listener_region_del(MemoryListener *listener, - MemoryRegionSection *section) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); -+ hwaddr iova, end; -+ Int128 llend, llsize; -+ int ret; -+ bool try_unmap = true; - - if (vfio_listener_skipped_section(section)) { - trace_vfio_listener_region_del_skip( -@@ -1282,7 +1200,53 @@ static void vfio_listener_region_del(MemoryListener *listener, - */ - } - -- vfio_dma_unmap_ram_section(container, section); -+ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -+ llend = int128_make64(section->offset_within_address_space); -+ llend = int128_add(llend, section->size); -+ llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); -+ -+ if (int128_ge(int128_make64(iova), llend)) { -+ return; -+ } -+ end = int128_get64(int128_sub(llend, int128_one())); -+ -+ llsize = int128_sub(llend, int128_make64(iova)); -+ -+ trace_vfio_listener_region_del(iova, end); -+ -+ if (memory_region_is_ram_device(section->mr)) { -+ hwaddr pgmask; -+ VFIOHostDMAWindow *hostwin = hostwin_from_range(container, iova, end); -+ -+ assert(hostwin); /* or region_add() would have failed */ -+ -+ pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; -+ try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); -+ } else if (memory_region_has_ram_discard_manager(section->mr)) { -+ vfio_unregister_ram_discard_listener(container, section); -+ /* Unregistering will trigger an unmap. */ -+ try_unmap = false; -+ } -+ -+ if (try_unmap) { -+ if (int128_eq(llsize, int128_2_64())) { -+ /* The unmap ioctl doesn't accept a full 64-bit span. */ -+ llsize = int128_rshift(llsize, 1); -+ ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -+ if (ret) { -+ error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -+ "0x%"HWADDR_PRIx") = %d (%m)", -+ container, iova, int128_get64(llsize), ret); -+ } -+ iova += int128_get64(llsize); -+ } -+ ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -+ if (ret) { -+ error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -+ "0x%"HWADDR_PRIx") = %d (%m)", -+ container, iova, int128_get64(llsize), ret); -+ } -+ } - - memory_region_unref(section->mr); - -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index a37563a315..0ef1b5f4a6 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -99,10 +99,10 @@ vfio_iommu_map_notify(const char *op, uint64_t iova_start, uint64_t iova_end) "i - vfio_listener_region_add_skip(uint64_t start, uint64_t end) "SKIPPING region_add 0x%"PRIx64" - 0x%"PRIx64 - vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to liobn fd %d" - vfio_listener_region_add_iommu(uint64_t start, uint64_t end) "region_add [iommu] 0x%"PRIx64" - 0x%"PRIx64 --vfio_dma_map_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]" -+vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]" - vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA" - vfio_listener_region_del_skip(uint64_t start, uint64_t end) "SKIPPING region_del 0x%"PRIx64" - 0x%"PRIx64 --vfio_dma_unmap_ram(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64 -+vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64 - vfio_disconnect_container(int fd) "close container->fd=%d" - vfio_put_group(int fd) "close group->fd=%d" - vfio_get_device(const char * name, unsigned int flags, unsigned int num_regions, unsigned int num_irqs) "Device %s flags: %u, regions: %u, irqs: %u" --- -2.27.0 - diff --git a/Revert-vfio-Introduce-helpers-to-mark-dirty-pages-of.patch b/Revert-vfio-Introduce-helpers-to-mark-dirty-pages-of.patch deleted file mode 100644 index 8285b070f6004fc37d9a34104ca0646cfbd45cc3..0000000000000000000000000000000000000000 --- a/Revert-vfio-Introduce-helpers-to-mark-dirty-pages-of.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 9664a2d7b040a41d75067f4c58bf72c705e4a13b Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:23 +0800 -Subject: [PATCH 07/36] Revert "vfio: Introduce helpers to mark dirty pages of - a RAM section" - -This reverts commit 1675d767aa9bd496178b4d74e01a40dbbd97eccb. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 22 ++++++++-------------- - 1 file changed, 8 insertions(+), 14 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 6136b1ef61..bdfcc854fe 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1566,19 +1566,6 @@ err_out: - return ret; - } - --static int vfio_dma_sync_ram_section_dirty_bitmap(VFIOContainer *container, -- MemoryRegionSection *section) --{ -- ram_addr_t ram_addr; -- -- ram_addr = memory_region_get_ram_addr(section->mr) + -- section->offset_within_region; -- -- return vfio_get_dirty_bitmap(container, -- REAL_HOST_PAGE_ALIGN(section->offset_within_address_space), -- int128_get64(section->size), ram_addr); --} -- - typedef struct { - IOMMUNotifier n; - VFIOGuestIOMMU *giommu; -@@ -1663,6 +1650,8 @@ static int vfio_sync_ram_discard_listener_dirty_bitmap(VFIOContainer *container, - static int vfio_sync_dirty_bitmap(VFIOContainer *container, - MemoryRegionSection *section) - { -+ ram_addr_t ram_addr; -+ - if (memory_region_is_iommu(section->mr)) { - VFIOGuestIOMMU *giommu; - -@@ -1693,7 +1682,12 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container, - return vfio_sync_ram_discard_listener_dirty_bitmap(container, section); - } - -- return vfio_dma_sync_ram_section_dirty_bitmap(container, section); -+ ram_addr = memory_region_get_ram_addr(section->mr) + -+ section->offset_within_region; -+ -+ return vfio_get_dirty_bitmap(container, -+ REAL_HOST_PAGE_ALIGN(section->offset_within_address_space), -+ int128_get64(section->size), ram_addr); - } - - static void vfio_listener_log_sync(MemoryListener *listener, --- -2.27.0 - diff --git a/Revert-vfio-Introduce-hostwin_from_range-helper.patch b/Revert-vfio-Introduce-hostwin_from_range-helper.patch deleted file mode 100644 index b130eff19ee950478afbd3c1329b978783f0e920..0000000000000000000000000000000000000000 --- a/Revert-vfio-Introduce-hostwin_from_range-helper.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 66fce3f7e9754345cf53afe3efd1b5bb5e322399 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:46 +0800 -Subject: [PATCH 25/36] Revert "vfio: Introduce hostwin_from_range helper" - -This reverts commit 85232739b4852f1a51dde58c9007ed0deb17c2f2. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 36 +++++++++++++++++++----------------- - 1 file changed, 19 insertions(+), 17 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index d358789f19..d7533637c9 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -909,19 +909,6 @@ static void vfio_unregister_ram_discard_listener(VFIOContainer *container, - g_free(vrdl); - } - --static VFIOHostDMAWindow * --hostwin_from_range(VFIOContainer *container, hwaddr iova, hwaddr end) --{ -- VFIOHostDMAWindow *hostwin; -- -- QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -- if (hostwin->min_iova <= iova && end <= hostwin->max_iova) { -- return hostwin; -- } -- } -- return NULL; --} -- - static void vfio_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { -@@ -931,6 +918,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - void *vaddr; - int ret; - VFIOHostDMAWindow *hostwin; -+ bool hostwin_found; - Error *err = NULL; - - if (vfio_listener_skipped_section(section)) { -@@ -1023,8 +1011,15 @@ static void vfio_listener_region_add(MemoryListener *listener, - #endif - } - -- hostwin = hostwin_from_range(container, iova, end); -- if (!hostwin) { -+ hostwin_found = false; -+ QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -+ if (hostwin->min_iova <= iova && end <= hostwin->max_iova) { -+ hostwin_found = true; -+ break; -+ } -+ } -+ -+ if (!hostwin_found) { - error_setg(&err, "Container %p can't map guest IOVA region" - " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, container, iova, end); - goto fail; -@@ -1216,9 +1211,16 @@ static void vfio_listener_region_del(MemoryListener *listener, - - if (memory_region_is_ram_device(section->mr)) { - hwaddr pgmask; -- VFIOHostDMAWindow *hostwin = hostwin_from_range(container, iova, end); -+ VFIOHostDMAWindow *hostwin; -+ bool hostwin_found = false; - -- assert(hostwin); /* or region_add() would have failed */ -+ QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -+ if (hostwin->min_iova <= iova && end <= hostwin->max_iova) { -+ hostwin_found = true; -+ break; -+ } -+ } -+ assert(hostwin_found); /* or region_add() would have failed */ - - pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; - try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); --- -2.27.0 - diff --git a/Revert-vfio-Pass-stage-1-MSI-bindings-to-the-host.patch b/Revert-vfio-Pass-stage-1-MSI-bindings-to-the-host.patch deleted file mode 100644 index f8a574876bfa4f9175673a4cef14ab36ead80b0e..0000000000000000000000000000000000000000 --- a/Revert-vfio-Pass-stage-1-MSI-bindings-to-the-host.patch +++ /dev/null @@ -1,260 +0,0 @@ -From 17190414cd411d23f1fc14c3d44d7b9f210f12b0 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:42 +0800 -Subject: [PATCH 22/36] Revert "vfio: Pass stage 1 MSI bindings to the host" - -This reverts commit 8b4fbe869f8a1f510896c86067d2e4fc3dc82eb9. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 59 --------------------------- - hw/vfio/pci.c | 76 +---------------------------------- - hw/vfio/trace-events | 2 - - include/hw/vfio/vfio-common.h | 12 ------ - 4 files changed, 2 insertions(+), 147 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 1f78af121d..58f8a43a43 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -774,65 +774,6 @@ static void vfio_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - } - } - --int vfio_iommu_set_msi_binding(VFIOContainer *container, int n, -- IOMMUTLBEntry *iotlb) --{ -- struct vfio_iommu_type1_set_msi_binding ustruct; -- VFIOMSIBinding *binding; -- int ret; -- -- QLIST_FOREACH(binding, &container->msibinding_list, next) { -- if (binding->index == n) { -- return 0; -- } -- } -- -- ustruct.argsz = sizeof(struct vfio_iommu_type1_set_msi_binding); -- ustruct.iova = iotlb->iova; -- ustruct.flags = VFIO_IOMMU_BIND_MSI; -- ustruct.gpa = iotlb->translated_addr; -- ustruct.size = iotlb->addr_mask + 1; -- ret = ioctl(container->fd, VFIO_IOMMU_SET_MSI_BINDING , &ustruct); -- if (ret) { -- error_report("%s: failed to register the stage1 MSI binding (%m)", -- __func__); -- return ret; -- } -- binding = g_new0(VFIOMSIBinding, 1); -- binding->iova = ustruct.iova; -- binding->gpa = ustruct.gpa; -- binding->size = ustruct.size; -- binding->index = n; -- -- QLIST_INSERT_HEAD(&container->msibinding_list, binding, next); -- return 0; --} -- --int vfio_iommu_unset_msi_binding(VFIOContainer *container, int n) --{ -- struct vfio_iommu_type1_set_msi_binding ustruct; -- VFIOMSIBinding *binding, *tmp; -- int ret; -- -- ustruct.argsz = sizeof(struct vfio_iommu_type1_set_msi_binding); -- QLIST_FOREACH_SAFE(binding, &container->msibinding_list, next, tmp) { -- if (binding->index != n) { -- continue; -- } -- ustruct.flags = VFIO_IOMMU_UNBIND_MSI; -- ustruct.iova = binding->iova; -- ret = ioctl(container->fd, VFIO_IOMMU_SET_MSI_BINDING , &ustruct); -- if (ret) { -- error_report("Failed to unregister the stage1 MSI binding " -- "for iova=0x%"PRIx64" (%m)", binding->iova); -- } -- QLIST_REMOVE(binding, next); -- g_free(binding); -- return ret; -- } -- return 0; --} -- - static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - { - VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 99c52a0944..ae5e014e5d 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -365,65 +365,6 @@ static void vfio_msi_interrupt(void *opaque) - notify(&vdev->pdev, nr); - } - --static bool vfio_iommu_require_msi_binding(IOMMUMemoryRegion *iommu_mr) --{ -- bool msi_translate = false, nested = false; -- -- memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_MSI_TRANSLATE, -- (void *)&msi_translate); -- memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_VFIO_NESTED, -- (void *)&nested); -- if (!nested || !msi_translate) { -- return false; -- } -- return true; --} -- --static int vfio_register_msi_binding(VFIOPCIDevice *vdev, -- int vector_n, bool set) --{ -- VFIOContainer *container = vdev->vbasedev.group->container; -- PCIDevice *dev = &vdev->pdev; -- AddressSpace *as = pci_device_iommu_address_space(dev); -- IOMMUMemoryRegionClass *imrc; -- IOMMUMemoryRegion *iommu_mr; -- IOMMUTLBEntry entry; -- MSIMessage msg; -- -- if (as == &address_space_memory) { -- return 0; -- } -- -- iommu_mr = IOMMU_MEMORY_REGION(as->root); -- if (!vfio_iommu_require_msi_binding(iommu_mr)) { -- return 0; -- } -- -- /* MSI doorbell address is translated by an IOMMU */ -- -- if (!set) { /* unregister */ -- trace_vfio_unregister_msi_binding(vdev->vbasedev.name, vector_n); -- -- return vfio_iommu_unset_msi_binding(container, vector_n); -- } -- -- msg = pci_get_msi_message(dev, vector_n); -- imrc = memory_region_get_iommu_class_nocheck(iommu_mr); -- -- rcu_read_lock(); -- entry = imrc->translate(iommu_mr, msg.address, IOMMU_WO, 0); -- rcu_read_unlock(); -- -- if (entry.perm == IOMMU_NONE) { -- return -ENOENT; -- } -- -- trace_vfio_register_msi_binding(vdev->vbasedev.name, vector_n, -- msg.address, entry.translated_addr); -- -- return vfio_iommu_set_msi_binding(container, vector_n, &entry); --} -- - static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) - { - struct vfio_irq_set *irq_set; -@@ -441,7 +382,7 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) - fds = (int32_t *)&irq_set->data; - - for (i = 0; i < vdev->nr_vectors; i++) { -- int ret, fd = -1; -+ int fd = -1; - - /* - * MSI vs MSI-X - The guest has direct access to MSI mask and pending -@@ -450,12 +391,6 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) - * KVM signaling path only when configured and unmasked. - */ - if (vdev->msi_vectors[i].use) { -- ret = vfio_register_msi_binding(vdev, i, true); -- if (ret) { -- error_report("%s failed to register S1 MSI binding " -- "for vector %d(%d)", vdev->vbasedev.name, i, ret); -- goto out; -- } - if (vdev->msi_vectors[i].virq < 0 || - (msix && msix_is_masked(&vdev->pdev, i))) { - fd = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt); -@@ -469,7 +404,6 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) - - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set); - --out: - g_free(irq_set); - - return ret; -@@ -784,8 +718,7 @@ static void vfio_msi_disable_common(VFIOPCIDevice *vdev) - - static void vfio_msix_disable(VFIOPCIDevice *vdev) - { -- int ret, i; -- -+ int i; - - msix_unset_vector_notifiers(&vdev->pdev); - -@@ -797,11 +730,6 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev) - if (vdev->msi_vectors[i].use) { - vfio_msix_vector_release(&vdev->pdev, i); - msix_vector_unuse(&vdev->pdev, i); -- ret = vfio_register_msi_binding(vdev, i, false); -- if (ret) { -- error_report("%s: failed to unregister S1 MSI binding " -- "for vector %d(%d)", vdev->vbasedev.name, i, ret); -- } - } - } - -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 35bd415d6d..20069935f5 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -120,8 +120,6 @@ vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype - vfio_dma_unmap_overflow_workaround(void) "" - vfio_iommu_addr_inv_iotlb(int asid, uint64_t addr, uint64_t size, uint64_t nb_granules, bool leaf) "nested IOTLB invalidate asid=%d, addr=0x%"PRIx64" granule_size=0x%"PRIx64" nb_granules=0x%"PRIx64" leaf=%d" - vfio_iommu_asid_inv_iotlb(int asid) "nested IOTLB invalidate asid=%d" --vfio_register_msi_binding(const char *name, int vector, uint64_t giova, uint64_t gdb) "%s: register vector %d gIOVA=0x%"PRIx64 "-> gDB=0x%"PRIx64" stage 1 mapping" --vfio_unregister_msi_binding(const char *name, int vector) "%s: unregister vector %d stage 1 mapping" - - # platform.c - vfio_platform_base_device_init(char *name, int groupid) "%s belongs to group #%d" -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index a838a939e4..0234f5e1b1 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -74,14 +74,6 @@ typedef struct VFIOAddressSpace { - QLIST_ENTRY(VFIOAddressSpace) list; - } VFIOAddressSpace; - --typedef struct VFIOMSIBinding { -- int index; -- hwaddr iova; -- hwaddr gpa; -- hwaddr size; -- QLIST_ENTRY(VFIOMSIBinding) next; --} VFIOMSIBinding; -- - struct VFIOGroup; - - typedef struct VFIODMARange { -@@ -111,7 +103,6 @@ typedef struct VFIOContainer { - QLIST_HEAD(, VFIOGroup) group_list; - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; - QLIST_HEAD(, VFIODMARange) dma_list; -- QLIST_HEAD(, VFIOMSIBinding) msibinding_list; - QLIST_ENTRY(VFIOContainer) next; - } VFIOContainer; - -@@ -231,9 +222,6 @@ VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp); - void vfio_put_group(VFIOGroup *group); - int vfio_get_device(VFIOGroup *group, const char *name, - VFIODevice *vbasedev, Error **errp); --int vfio_iommu_set_msi_binding(VFIOContainer *container, int n, -- IOMMUTLBEntry *entry); --int vfio_iommu_unset_msi_binding(VFIOContainer *container, int n); - - extern const MemoryRegionOps vfio_region_ops; - typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; --- -2.27.0 - diff --git a/Revert-vfio-Set-up-nested-stage-mappings.patch b/Revert-vfio-Set-up-nested-stage-mappings.patch deleted file mode 100644 index 46f0127531cdefaa50d380f52c7633ef6b9332d9..0000000000000000000000000000000000000000 --- a/Revert-vfio-Set-up-nested-stage-mappings.patch +++ /dev/null @@ -1,266 +0,0 @@ -From 72b7903e406b7011ccba7a3ebbdfe790b421e9fc Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:43 +0800 -Subject: [PATCH 23/36] Revert "vfio: Set up nested stage mappings" - -This reverts commit 96581a5ee46e89dbc9e1ebe247b00adefb1c7a41. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 139 ++----------------------------------------- - hw/vfio/pci.c | 21 ------- - hw/vfio/trace-events | 2 - - 3 files changed, 5 insertions(+), 157 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 58f8a43a43..b3dc090840 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -707,73 +707,6 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, - return true; - } - --/* Propagate a guest IOTLB invalidation to the host (nested mode) */ --static void vfio_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) --{ -- VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); -- struct vfio_iommu_type1_cache_invalidate ustruct = {}; -- VFIOContainer *container = giommu->container; -- int ret; -- -- assert(iotlb->perm == IOMMU_NONE); -- -- ustruct.argsz = sizeof(ustruct); -- ustruct.flags = 0; -- ustruct.info.argsz = sizeof(struct iommu_cache_invalidate_info); -- ustruct.info.version = IOMMU_CACHE_INVALIDATE_INFO_VERSION_1; -- ustruct.info.cache = IOMMU_CACHE_INV_TYPE_IOTLB; -- -- switch (iotlb->granularity) { -- case IOMMU_INV_GRAN_DOMAIN: -- ustruct.info.granularity = IOMMU_INV_GRANU_DOMAIN; -- break; -- case IOMMU_INV_GRAN_PASID: -- { -- struct iommu_inv_pasid_info *pasid_info; -- int archid = -1; -- -- pasid_info = &ustruct.info.granu.pasid_info; -- ustruct.info.granularity = IOMMU_INV_GRANU_PASID; -- if (iotlb->flags & IOMMU_INV_FLAGS_ARCHID) { -- pasid_info->flags |= IOMMU_INV_ADDR_FLAGS_ARCHID; -- archid = iotlb->arch_id; -- } -- pasid_info->archid = archid; -- trace_vfio_iommu_asid_inv_iotlb(archid); -- break; -- } -- case IOMMU_INV_GRAN_ADDR: -- { -- hwaddr start = iotlb->iova + giommu->iommu_offset; -- struct iommu_inv_addr_info *addr_info; -- size_t size = iotlb->addr_mask + 1; -- int archid = -1; -- -- addr_info = &ustruct.info.granu.addr_info; -- ustruct.info.granularity = IOMMU_INV_GRANU_ADDR; -- if (iotlb->leaf) { -- addr_info->flags |= IOMMU_INV_ADDR_FLAGS_LEAF; -- } -- if (iotlb->flags & IOMMU_INV_FLAGS_ARCHID) { -- addr_info->flags |= IOMMU_INV_ADDR_FLAGS_ARCHID; -- archid = iotlb->arch_id; -- } -- addr_info->archid = archid; -- addr_info->addr = start; -- addr_info->granule_size = size; -- addr_info->nb_granules = 1; -- trace_vfio_iommu_addr_inv_iotlb(archid, start, size, -- 1, iotlb->leaf); -- break; -- } -- } -- -- ret = ioctl(container->fd, VFIO_IOMMU_CACHE_INVALIDATE, &ustruct); -- if (ret) { -- error_report("%p: failed to invalidate CACHE (%d)", container, ret); -- } --} -- - static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - { - VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); -@@ -1107,35 +1040,6 @@ static void vfio_dma_unmap_ram_section(VFIOContainer *container, - } - } - --static void vfio_prereg_listener_region_add(MemoryListener *listener, -- MemoryRegionSection *section) --{ -- VFIOContainer *container = -- container_of(listener, VFIOContainer, prereg_listener); -- Error *err = NULL; -- -- if (!memory_region_is_ram(section->mr)) { -- return; -- } -- -- vfio_dma_map_ram_section(container, section, &err); -- if (err) { -- error_report_err(err); -- } --} --static void vfio_prereg_listener_region_del(MemoryListener *listener, -- MemoryRegionSection *section) --{ -- VFIOContainer *container = -- container_of(listener, VFIOContainer, prereg_listener); -- -- if (!memory_region_is_ram(section->mr)) { -- return; -- } -- -- vfio_dma_unmap_ram_section(container, section); --} -- - static void vfio_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { -@@ -1246,10 +1150,9 @@ static void vfio_listener_region_add(MemoryListener *listener, - memory_region_ref(section->mr); - - if (memory_region_is_iommu(section->mr)) { -- IOMMUNotify notify; - VFIOGuestIOMMU *giommu; - IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr); -- int iommu_idx, flags; -+ int iommu_idx; - - trace_vfio_listener_region_add_iommu(iova, end); - /* -@@ -1268,18 +1171,8 @@ static void vfio_listener_region_add(MemoryListener *listener, - llend = int128_sub(llend, int128_one()); - iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr, - MEMTXATTRS_UNSPECIFIED); -- -- if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -- /* IOTLB unmap notifier to propagate guest IOTLB invalidations */ -- flags = IOMMU_NOTIFIER_UNMAP; -- notify = vfio_iommu_unmap_notify; -- } else { -- /* MAP/UNMAP IOTLB notifier */ -- flags = IOMMU_NOTIFIER_IOTLB_EVENTS; -- notify = vfio_iommu_map_notify; -- } -- -- iommu_notifier_init(&giommu->n, notify, flags, -+ iommu_notifier_init(&giommu->n, vfio_iommu_map_notify, -+ IOMMU_NOTIFIER_IOTLB_EVENTS, - section->offset_within_region, - int128_get64(llend), - iommu_idx); -@@ -1299,9 +1192,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - goto fail; - } - QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next); -- if (flags & IOMMU_NOTIFIER_MAP) { -- memory_region_iommu_replay(giommu->iommu, &giommu->n); -- } -+ memory_region_iommu_replay(giommu->iommu, &giommu->n); - - return; - } -@@ -1781,16 +1672,10 @@ static const MemoryListener vfio_memory_listener = { - .log_clear = vfio_listener_log_clear, - }; - --static MemoryListener vfio_memory_prereg_listener = { -- .region_add = vfio_prereg_listener_region_add, -- .region_del = vfio_prereg_listener_region_del, --}; -- - static void vfio_listener_release(VFIOContainer *container) - { - memory_listener_unregister(&container->listener); -- if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || -- container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -+ if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { - memory_listener_unregister(&container->prereg_listener); - } - } -@@ -2466,20 +2351,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - vfio_get_iommu_info_migration(container, info); - } - g_free(info); -- -- if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -- container->prereg_listener = vfio_memory_prereg_listener; -- memory_listener_register(&container->prereg_listener, -- &address_space_memory); -- if (container->error) { -- memory_listener_unregister(&container->prereg_listener); -- ret = -1; -- error_propagate_prepend(errp, container->error, -- "RAM memory listener initialization failed " -- "for container"); -- goto free_container_exit; -- } -- } - break; - } - case VFIO_SPAPR_TCE_v2_IOMMU: -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index ae5e014e5d..7b45353ce2 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2797,25 +2797,6 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev) - vdev->req_enabled = false; - } - --static int vfio_iommu_set_pasid_table(PCIBus *bus, int32_t devfn, -- IOMMUConfig *config) --{ -- PCIDevice *pdev = bus->devices[devfn]; -- VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); -- VFIOContainer *container = vdev->vbasedev.group->container; -- struct vfio_iommu_type1_set_pasid_table info; -- -- info.argsz = sizeof(info); -- info.flags = VFIO_PASID_TABLE_FLAG_SET; -- memcpy(&info.config, &config->pasid_cfg, sizeof(config->pasid_cfg)); -- -- return ioctl(container->fd, VFIO_IOMMU_SET_PASID_TABLE, &info); --} -- --static PCIPASIDOps vfio_pci_pasid_ops = { -- .set_pasid_table = vfio_iommu_set_pasid_table, --}; -- - static void vfio_realize(PCIDevice *pdev, Error **errp) - { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); -@@ -3127,8 +3108,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - vfio_register_req_notifier(vdev); - vfio_setup_resetfn_quirk(vdev); - -- pci_setup_pasid_ops(pdev, &vfio_pci_pasid_ops); -- - return; - - out_deregister: -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 20069935f5..a37563a315 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -118,8 +118,6 @@ vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Devic - vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]" - vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8" - vfio_dma_unmap_overflow_workaround(void) "" --vfio_iommu_addr_inv_iotlb(int asid, uint64_t addr, uint64_t size, uint64_t nb_granules, bool leaf) "nested IOTLB invalidate asid=%d, addr=0x%"PRIx64" granule_size=0x%"PRIx64" nb_granules=0x%"PRIx64" leaf=%d" --vfio_iommu_asid_inv_iotlb(int asid) "nested IOTLB invalidate asid=%d" - - # platform.c - vfio_platform_base_device_init(char *name, int groupid) "%s belongs to group #%d" --- -2.27.0 - diff --git a/Revert-vfio-common-Add-address-alignment-check-in-vf.patch b/Revert-vfio-common-Add-address-alignment-check-in-vf.patch deleted file mode 100644 index 6425c7b77f465c414eb85438cfcd061aefee34aa..0000000000000000000000000000000000000000 --- a/Revert-vfio-common-Add-address-alignment-check-in-vf.patch +++ /dev/null @@ -1,44 +0,0 @@ -From d0a16f250666ebd38c059ca86f161fade23640cf Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:09 +0800 -Subject: [PATCH 01/36] Revert "vfio/common: Add address alignment check in - vfio_listener_region_del" - -This reverts commit 00c553f53657bf4bc165d859187215dba7110246. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 10 ---------- - 1 file changed, 10 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 4d45c2b625..89c49f5508 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1411,8 +1411,6 @@ static void vfio_listener_region_del(MemoryListener *listener, - MemoryRegionSection *section) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); -- hwaddr iova; -- Int128 llend; - - if (vfio_listener_skipped_section(section)) { - trace_vfio_listener_region_del_skip( -@@ -1462,14 +1460,6 @@ static void vfio_listener_region_del(MemoryListener *listener, - */ - } - -- iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -- llend = int128_make64(section->offset_within_address_space); -- llend = int128_add(llend, section->size); -- llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); -- if (int128_ge(int128_make64(iova), llend)) { -- return; -- } -- - vfio_dma_unmap_ram_section(container, section); - - memory_region_unref(section->mr); --- -2.27.0 - diff --git a/Revert-vfio-common-Avoid-unmap-ram-section-at-vfio_l.patch b/Revert-vfio-common-Avoid-unmap-ram-section-at-vfio_l.patch deleted file mode 100644 index de4377c3412f60a7cadbb9f3dd34beafc57466b1..0000000000000000000000000000000000000000 --- a/Revert-vfio-common-Avoid-unmap-ram-section-at-vfio_l.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 2dc27b19fd8a17b23b112e84b9d7286d8c5f30ca Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:25 +0800 -Subject: [PATCH 08/36] Revert "vfio/common: Avoid unmap ram section at - vfio_listener_region_del() in nested mode" - -This reverts commit 9d7b782a0b2c5288e82f3064b4c5b7bf18887280. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 10 ---------- - 1 file changed, 10 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index bdfcc854fe..d05a485808 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1441,16 +1441,6 @@ static void vfio_listener_region_del(MemoryListener *listener, - } - } - -- /* -- * In nested mode, stage 2 (gpa->hpa) and the stage 1 -- * (giova->gpa) are set separately. The ram section -- * will be unmapped in vfio_prereg_listener_region_del(). -- * Hence it doesn't need to unmap ram section here. -- */ -- if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -- return; -- } -- - /* - * FIXME: We assume the one big unmap below is adequate to - * remove any individual page mappings in the IOMMU which --- -2.27.0 - diff --git a/Revert-vfio-common-Fix-incorrect-address-alignment-i.patch b/Revert-vfio-common-Fix-incorrect-address-alignment-i.patch deleted file mode 100644 index 52a4c32f6c25b69b10dd5f370eb07a2b71f29d35..0000000000000000000000000000000000000000 --- a/Revert-vfio-common-Fix-incorrect-address-alignment-i.patch +++ /dev/null @@ -1,33 +0,0 @@ -From b5cee7126a75ea0e1797760fd5d7dfd89028b8a8 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:14 +0800 -Subject: [PATCH 02/36] Revert "vfio/common: Fix incorrect address alignment in - vfio_dma_map_ram_section" - -This reverts commit c2a4ce033db6ab74256e28da382c797a98047d4b. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 89c49f5508..65f3979492 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1059,10 +1059,10 @@ static int vfio_dma_map_ram_section(VFIOContainer *container, - - assert(memory_region_is_ram(section->mr)); - -- iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -+ iova = TARGET_PAGE_ALIGN(section->offset_within_address_space); - llend = int128_make64(section->offset_within_address_space); - llend = int128_add(llend, section->size); -- llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); -+ llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK)); - end = int128_get64(int128_sub(llend, int128_one())); - - vaddr = memory_region_get_ram_ptr(section->mr) + --- -2.27.0 - diff --git a/Revert-vfio-pci-Implement-return_page_response-page-.patch b/Revert-vfio-pci-Implement-return_page_response-page-.patch deleted file mode 100644 index ba345328c0ed5ced58b019945ebbe4bd4a8cce6b..0000000000000000000000000000000000000000 --- a/Revert-vfio-pci-Implement-return_page_response-page-.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 50e365a162cb7dd39d724fa1c5823e82d184af3a Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:26 +0800 -Subject: [PATCH 09/36] Revert "vfio/pci: Implement return_page_response page - response callback" - -This reverts commit 6bbf810edebdb89a6958519ee3adfb1888520231. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/pci.c | 123 -------------------------------------------------- - hw/vfio/pci.h | 2 - - 2 files changed, 125 deletions(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 8e24f9c7d1..c54e62fe8f 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2693,61 +2693,6 @@ out: - g_free(fault_region_info); - } - --static void vfio_init_fault_response_regions(VFIOPCIDevice *vdev, Error **errp) --{ -- struct vfio_region_info *fault_region_info = NULL; -- struct vfio_region_info_cap_fault *cap_fault; -- VFIODevice *vbasedev = &vdev->vbasedev; -- struct vfio_info_cap_header *hdr; -- char *fault_region_name; -- int ret; -- -- ret = vfio_get_dev_region_info(&vdev->vbasedev, -- VFIO_REGION_TYPE_NESTED, -- VFIO_REGION_SUBTYPE_NESTED_DMA_FAULT_RESPONSE, -- &fault_region_info); -- if (ret) { -- goto out; -- } -- -- hdr = vfio_get_region_info_cap(fault_region_info, -- VFIO_REGION_INFO_CAP_DMA_FAULT_RESPONSE); -- if (!hdr) { -- error_setg(errp, "failed to retrieve DMA FAULT RESPONSE capability"); -- goto out; -- } -- cap_fault = container_of(hdr, struct vfio_region_info_cap_fault, -- header); -- if (cap_fault->version != 1) { -- error_setg(errp, "Unsupported DMA FAULT RESPONSE API version %d", -- cap_fault->version); -- goto out; -- } -- -- fault_region_name = g_strdup_printf("%s DMA FAULT RESPONSE %d", -- vbasedev->name, -- fault_region_info->index); -- -- ret = vfio_region_setup(OBJECT(vdev), vbasedev, -- &vdev->dma_fault_response_region, -- fault_region_info->index, -- fault_region_name); -- g_free(fault_region_name); -- if (ret) { -- error_setg_errno(errp, -ret, -- "failed to set up the DMA FAULT RESPONSE region %d", -- fault_region_info->index); -- goto out; -- } -- -- ret = vfio_region_mmap(&vdev->dma_fault_response_region); -- if (ret) { -- error_setg_errno(errp, -ret, "Failed to mmap the DMA FAULT RESPONSE queue"); -- } --out: -- g_free(fault_region_info); --} -- - static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) - { - VFIODevice *vbasedev = &vdev->vbasedev; -@@ -2823,12 +2768,6 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) - return; - } - -- vfio_init_fault_response_regions(vdev, &err); -- if (err) { -- error_propagate(errp, err); -- return; -- } -- - irq_info.index = VFIO_PCI_ERR_IRQ_INDEX; - - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info); -@@ -3007,68 +2946,8 @@ static int vfio_iommu_set_pasid_table(PCIBus *bus, int32_t devfn, - return ioctl(container->fd, VFIO_IOMMU_SET_PASID_TABLE, &info); - } - --static int vfio_iommu_return_page_response(PCIBus *bus, int32_t devfn, -- IOMMUPageResponse *resp) --{ -- PCIDevice *pdev = bus->devices[devfn]; -- VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); -- struct iommu_page_response *response = &resp->resp; -- struct vfio_region_dma_fault_response header; -- struct iommu_page_response *queue; -- char *queue_buffer = NULL; -- ssize_t bytes; -- -- if (!vdev->dma_fault_response_region.mem) { -- return -EINVAL; -- } -- -- /* read the header */ -- bytes = pread(vdev->vbasedev.fd, &header, sizeof(header), -- vdev->dma_fault_response_region.fd_offset); -- if (bytes != sizeof(header)) { -- error_report("%s unable to read the fault region header (0x%lx)", -- __func__, bytes); -- return -1; -- } -- -- /* Normally the fault queue is mmapped */ -- queue = (struct iommu_page_response *)vdev->dma_fault_response_region.mmaps[0].mmap; -- if (!queue) { -- size_t queue_size = header.nb_entries * header.entry_size; -- -- error_report("%s: fault queue not mmapped: slower fault handling", -- vdev->vbasedev.name); -- -- queue_buffer = g_malloc(queue_size); -- bytes = pread(vdev->vbasedev.fd, queue_buffer, queue_size, -- vdev->dma_fault_response_region.fd_offset + header.offset); -- if (bytes != queue_size) { -- error_report("%s unable to read the fault queue (0x%lx)", -- __func__, bytes); -- return -1; -- } -- -- queue = (struct iommu_page_response *)queue_buffer; -- } -- /* deposit the new response in the queue and increment the head */ -- memcpy(queue + header.head, response, header.entry_size); -- -- vdev->fault_response_head_index = -- (vdev->fault_response_head_index + 1) % header.nb_entries; -- bytes = pwrite(vdev->vbasedev.fd, &vdev->fault_response_head_index, 4, -- vdev->dma_fault_response_region.fd_offset); -- if (bytes != 4) { -- error_report("%s unable to write the fault response region head index (0x%lx)", -- __func__, bytes); -- } -- g_free(queue_buffer); -- -- return 0; --} -- - static PCIPASIDOps vfio_pci_pasid_ops = { - .set_pasid_table = vfio_iommu_set_pasid_table, -- .return_page_response = vfio_iommu_return_page_response, - }; - - static void vfio_dma_fault_notifier_handler(void *opaque) -@@ -3532,7 +3411,6 @@ static void vfio_instance_finalize(Object *obj) - vfio_display_finalize(vdev); - vfio_bars_finalize(vdev); - vfio_region_finalize(&vdev->dma_fault_region); -- vfio_region_finalize(&vdev->dma_fault_response_region); - g_free(vdev->emulated_config_bits); - g_free(vdev->rom); - /* -@@ -3554,7 +3432,6 @@ static void vfio_exitfn(PCIDevice *pdev) - vfio_unregister_err_notifier(vdev); - vfio_unregister_ext_irq_notifiers(vdev); - vfio_region_exit(&vdev->dma_fault_region); -- vfio_region_exit(&vdev->dma_fault_response_region); - pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); - if (vdev->irqchip_change_notifier.notify) { - kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index 61b3bf1303..03ac8919ef 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -147,8 +147,6 @@ struct VFIOPCIDevice { - VFIOPCIExtIRQ *ext_irqs; - VFIORegion dma_fault_region; - uint32_t fault_tail_index; -- VFIORegion dma_fault_response_region; -- uint32_t fault_response_head_index; - int (*resetfn)(struct VFIOPCIDevice *); - uint32_t vendor_id; - uint32_t device_id; --- -2.27.0 - diff --git a/Revert-vfio-pci-Implement-the-DMA-fault-handler.patch b/Revert-vfio-pci-Implement-the-DMA-fault-handler.patch deleted file mode 100644 index 6e4ba3b6a611a88157a65d9a33c0f12098578169..0000000000000000000000000000000000000000 --- a/Revert-vfio-pci-Implement-the-DMA-fault-handler.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 013220b686022a2e4ddb6a3d50af467275d25070 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:37 +0800 -Subject: [PATCH 18/36] Revert "vfio/pci: Implement the DMA fault handler" - -This reverts commit d33cc7eccb68c6a1488804c94ff5c1197ee0fc6e. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/pci.c | 50 -------------------------------------------------- - hw/vfio/pci.h | 1 - - 2 files changed, 51 deletions(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index c54e62fe8f..76bc9d3506 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2953,60 +2953,10 @@ static PCIPASIDOps vfio_pci_pasid_ops = { - static void vfio_dma_fault_notifier_handler(void *opaque) - { - VFIOPCIExtIRQ *ext_irq = opaque; -- VFIOPCIDevice *vdev = ext_irq->vdev; -- PCIDevice *pdev = &vdev->pdev; -- AddressSpace *as = pci_device_iommu_address_space(pdev); -- IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(as->root); -- struct vfio_region_dma_fault header; -- struct iommu_fault *queue; -- char *queue_buffer = NULL; -- ssize_t bytes; - - if (!event_notifier_test_and_clear(&ext_irq->notifier)) { - return; - } -- -- bytes = pread(vdev->vbasedev.fd, &header, sizeof(header), -- vdev->dma_fault_region.fd_offset); -- if (bytes != sizeof(header)) { -- error_report("%s unable to read the fault region header (0x%lx)", -- __func__, bytes); -- return; -- } -- -- /* Normally the fault queue is mmapped */ -- queue = (struct iommu_fault *)vdev->dma_fault_region.mmaps[0].mmap; -- if (!queue) { -- size_t queue_size = header.nb_entries * header.entry_size; -- -- error_report("%s: fault queue not mmapped: slower fault handling", -- vdev->vbasedev.name); -- -- queue_buffer = g_malloc(queue_size); -- bytes = pread(vdev->vbasedev.fd, queue_buffer, queue_size, -- vdev->dma_fault_region.fd_offset + header.offset); -- if (bytes != queue_size) { -- error_report("%s unable to read the fault queue (0x%lx)", -- __func__, bytes); -- return; -- } -- -- queue = (struct iommu_fault *)queue_buffer; -- } -- -- while (vdev->fault_tail_index != header.head) { -- memory_region_inject_faults(iommu_mr, 1, -- &queue[vdev->fault_tail_index]); -- vdev->fault_tail_index = -- (vdev->fault_tail_index + 1) % header.nb_entries; -- } -- bytes = pwrite(vdev->vbasedev.fd, &vdev->fault_tail_index, 4, -- vdev->dma_fault_region.fd_offset); -- if (bytes != 4) { -- error_report("%s unable to write the fault region tail index (0x%lx)", -- __func__, bytes); -- } -- g_free(queue_buffer); - } - - static int vfio_register_ext_irq_handler(VFIOPCIDevice *vdev, -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index 03ac8919ef..eef91065f1 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -146,7 +146,6 @@ struct VFIOPCIDevice { - EventNotifier req_notifier; - VFIOPCIExtIRQ *ext_irqs; - VFIORegion dma_fault_region; -- uint32_t fault_tail_index; - int (*resetfn)(struct VFIOPCIDevice *); - uint32_t vendor_id; - uint32_t device_id; --- -2.27.0 - diff --git a/Revert-vfio-pci-Register-handler-for-iommu-fault.patch b/Revert-vfio-pci-Register-handler-for-iommu-fault.patch deleted file mode 100644 index 2ef811e63af8b80e771801d5576a2e03f4e1cd7a..0000000000000000000000000000000000000000 --- a/Revert-vfio-pci-Register-handler-for-iommu-fault.patch +++ /dev/null @@ -1,161 +0,0 @@ -From f32fc48313dadeb6469c00660bd96331e120030f Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:40 +0800 -Subject: [PATCH 20/36] Revert "vfio/pci: Register handler for iommu fault" - -This reverts commit 574455d1363e818905e05cd23ef0948e83a16a51. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/pci.c | 81 +-------------------------------------------------- - hw/vfio/pci.h | 7 ----- - 2 files changed, 1 insertion(+), 87 deletions(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 37a70932c6..99c52a0944 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2888,76 +2888,6 @@ static PCIPASIDOps vfio_pci_pasid_ops = { - .set_pasid_table = vfio_iommu_set_pasid_table, - }; - --static void vfio_dma_fault_notifier_handler(void *opaque) --{ -- VFIOPCIExtIRQ *ext_irq = opaque; -- -- if (!event_notifier_test_and_clear(&ext_irq->notifier)) { -- return; -- } --} -- --static int vfio_register_ext_irq_handler(VFIOPCIDevice *vdev, -- uint32_t type, uint32_t subtype, -- IOHandler *handler) --{ -- int32_t fd, ext_irq_index, index; -- struct vfio_irq_info *irq_info; -- Error *err = NULL; -- EventNotifier *n; -- int ret; -- -- ret = vfio_get_dev_irq_info(&vdev->vbasedev, type, subtype, &irq_info); -- if (ret) { -- return ret; -- } -- index = irq_info->index; -- ext_irq_index = irq_info->index - VFIO_PCI_NUM_IRQS; -- g_free(irq_info); -- -- vdev->ext_irqs[ext_irq_index].vdev = vdev; -- vdev->ext_irqs[ext_irq_index].index = index; -- n = &vdev->ext_irqs[ext_irq_index].notifier; -- -- ret = event_notifier_init(n, 0); -- if (ret) { -- error_report("vfio: Unable to init event notifier for ext irq %d(%d)", -- ext_irq_index, ret); -- return ret; -- } -- -- fd = event_notifier_get_fd(n); -- qemu_set_fd_handler(fd, vfio_dma_fault_notifier_handler, NULL, -- &vdev->ext_irqs[ext_irq_index]); -- -- ret = vfio_set_irq_signaling(&vdev->vbasedev, index, 0, -- VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err); -- if (ret) { -- error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); -- qemu_set_fd_handler(fd, NULL, NULL, vdev); -- event_notifier_cleanup(n); -- } -- return ret; --} -- --static void vfio_unregister_ext_irq_notifiers(VFIOPCIDevice *vdev) --{ -- VFIODevice *vbasedev = &vdev->vbasedev; -- Error *err = NULL; -- int i; -- -- for (i = 0; i < vbasedev->num_irqs - VFIO_PCI_NUM_IRQS; i++) { -- if (vfio_set_irq_signaling(vbasedev, i + VFIO_PCI_NUM_IRQS , 0, -- VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { -- error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); -- } -- qemu_set_fd_handler(event_notifier_get_fd(&vdev->ext_irqs[i].notifier), -- NULL, NULL, vdev); -- event_notifier_cleanup(&vdev->ext_irqs[i].notifier); -- } -- g_free(vdev->ext_irqs); --} -- - static void vfio_realize(PCIDevice *pdev, Error **errp) - { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); -@@ -2968,7 +2898,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - ssize_t len; - struct stat st; - int groupid; -- int i, ret, nb_ext_irqs; -+ int i, ret; - bool is_mdev; - - if (!vdev->vbasedev.sysfsdev) { -@@ -3056,11 +2986,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - goto error; - } - -- nb_ext_irqs = vdev->vbasedev.num_irqs - VFIO_PCI_NUM_IRQS; -- if (nb_ext_irqs > 0) { -- vdev->ext_irqs = g_new0(VFIOPCIExtIRQ, nb_ext_irqs); -- } -- - vfio_populate_device(vdev, &err); - if (err) { - error_propagate(errp, err); -@@ -3272,9 +3197,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - - vfio_register_err_notifier(vdev); - vfio_register_req_notifier(vdev); -- vfio_register_ext_irq_handler(vdev, VFIO_IRQ_TYPE_NESTED, -- VFIO_IRQ_SUBTYPE_DMA_FAULT, -- vfio_dma_fault_notifier_handler); - vfio_setup_resetfn_quirk(vdev); - - pci_setup_pasid_ops(pdev, &vfio_pci_pasid_ops); -@@ -3317,7 +3239,6 @@ static void vfio_exitfn(PCIDevice *pdev) - - vfio_unregister_req_notifier(vdev); - vfio_unregister_err_notifier(vdev); -- vfio_unregister_ext_irq_notifiers(vdev); - pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); - if (vdev->irqchip_change_notifier.notify) { - kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index a8b06737fb..64777516d1 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -114,12 +114,6 @@ typedef struct VFIOMSIXInfo { - unsigned long *pending; - } VFIOMSIXInfo; - --typedef struct VFIOPCIExtIRQ { -- struct VFIOPCIDevice *vdev; -- EventNotifier notifier; -- uint32_t index; --} VFIOPCIExtIRQ; -- - #define TYPE_VFIO_PCI "vfio-pci" - OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI) - -@@ -144,7 +138,6 @@ struct VFIOPCIDevice { - PCIHostDeviceAddress host; - EventNotifier err_notifier; - EventNotifier req_notifier; -- VFIOPCIExtIRQ *ext_irqs; - int (*resetfn)(struct VFIOPCIDevice *); - uint32_t vendor_id; - uint32_t device_id; --- -2.27.0 - diff --git a/Revert-vfio-pci-Set-up-the-DMA-FAULT-region.patch b/Revert-vfio-pci-Set-up-the-DMA-FAULT-region.patch deleted file mode 100644 index eb3aa8a2c267be50450e9f839a5694e6da8b7d85..0000000000000000000000000000000000000000 --- a/Revert-vfio-pci-Set-up-the-DMA-FAULT-region.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0e9cc7c0a60ace8baeab6e32f49770afbeec6f5d Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:38 +0800 -Subject: [PATCH 19/36] Revert "vfio/pci: Set up the DMA FAULT region" - -This reverts commit e701d0fef4fbb7935d6aa7d22d82eb2dcfee2431. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/pci.c | 64 --------------------------------------------------- - hw/vfio/pci.h | 1 - - 2 files changed, 65 deletions(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 76bc9d3506..37a70932c6 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2638,67 +2638,11 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp) - return 0; - } - --static void vfio_init_fault_regions(VFIOPCIDevice *vdev, Error **errp) --{ -- struct vfio_region_info *fault_region_info = NULL; -- struct vfio_region_info_cap_fault *cap_fault; -- VFIODevice *vbasedev = &vdev->vbasedev; -- struct vfio_info_cap_header *hdr; -- char *fault_region_name; -- int ret; -- -- ret = vfio_get_dev_region_info(&vdev->vbasedev, -- VFIO_REGION_TYPE_NESTED, -- VFIO_REGION_SUBTYPE_NESTED_DMA_FAULT, -- &fault_region_info); -- if (ret) { -- goto out; -- } -- -- hdr = vfio_get_region_info_cap(fault_region_info, -- VFIO_REGION_INFO_CAP_DMA_FAULT); -- if (!hdr) { -- error_setg(errp, "failed to retrieve DMA FAULT capability"); -- goto out; -- } -- cap_fault = container_of(hdr, struct vfio_region_info_cap_fault, -- header); -- if (cap_fault->version != 1) { -- error_setg(errp, "Unsupported DMA FAULT API version %d", -- cap_fault->version); -- goto out; -- } -- -- fault_region_name = g_strdup_printf("%s DMA FAULT %d", -- vbasedev->name, -- fault_region_info->index); -- -- ret = vfio_region_setup(OBJECT(vdev), vbasedev, -- &vdev->dma_fault_region, -- fault_region_info->index, -- fault_region_name); -- g_free(fault_region_name); -- if (ret) { -- error_setg_errno(errp, -ret, -- "failed to set up the DMA FAULT region %d", -- fault_region_info->index); -- goto out; -- } -- -- ret = vfio_region_mmap(&vdev->dma_fault_region); -- if (ret) { -- error_setg_errno(errp, -ret, "Failed to mmap the DMA FAULT queue"); -- } --out: -- g_free(fault_region_info); --} -- - static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) - { - VFIODevice *vbasedev = &vdev->vbasedev; - struct vfio_region_info *reg_info; - struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) }; -- Error *err = NULL; - int i, ret = -1; - - /* Sanity check device */ -@@ -2762,12 +2706,6 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) - } - } - -- vfio_init_fault_regions(vdev, &err); -- if (err) { -- error_propagate(errp, err); -- return; -- } -- - irq_info.index = VFIO_PCI_ERR_IRQ_INDEX; - - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info); -@@ -3360,7 +3298,6 @@ static void vfio_instance_finalize(Object *obj) - - vfio_display_finalize(vdev); - vfio_bars_finalize(vdev); -- vfio_region_finalize(&vdev->dma_fault_region); - g_free(vdev->emulated_config_bits); - g_free(vdev->rom); - /* -@@ -3381,7 +3318,6 @@ static void vfio_exitfn(PCIDevice *pdev) - vfio_unregister_req_notifier(vdev); - vfio_unregister_err_notifier(vdev); - vfio_unregister_ext_irq_notifiers(vdev); -- vfio_region_exit(&vdev->dma_fault_region); - pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); - if (vdev->irqchip_change_notifier.notify) { - kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index eef91065f1..a8b06737fb 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -145,7 +145,6 @@ struct VFIOPCIDevice { - EventNotifier err_notifier; - EventNotifier req_notifier; - VFIOPCIExtIRQ *ext_irqs; -- VFIORegion dma_fault_region; - int (*resetfn)(struct VFIOPCIDevice *); - uint32_t vendor_id; - uint32_t device_id; --- -2.27.0 - diff --git a/Revert-vfio.h-and-iommu.h-header-update-against-5.10.patch b/Revert-vfio.h-and-iommu.h-header-update-against-5.10.patch deleted file mode 100644 index 6e27cd39e63c9fb0f9f506de5c400e0de7802b6e..0000000000000000000000000000000000000000 --- a/Revert-vfio.h-and-iommu.h-header-update-against-5.10.patch +++ /dev/null @@ -1,703 +0,0 @@ -From d3b9b26c9bb53b00b1441b3edad446ffea1ad8ff Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 18 Nov 2022 15:22:58 +0800 -Subject: [PATCH 35/36] Revert "vfio.h and iommu.h header update against 5.10" - -This reverts commit 36b65d7312a343cb636e6963b8262dce9420ebc6. - -Signed-off-by: Kunkun Jiang ---- - linux-headers/linux/iommu.h | 395 ------------------------------------ - linux-headers/linux/vfio.h | 220 +------------------- - 2 files changed, 2 insertions(+), 613 deletions(-) - delete mode 100644 linux-headers/linux/iommu.h - -diff --git a/linux-headers/linux/iommu.h b/linux-headers/linux/iommu.h -deleted file mode 100644 -index 773b7dc2d6..0000000000 ---- a/linux-headers/linux/iommu.h -+++ /dev/null -@@ -1,395 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ --/* -- * IOMMU user API definitions -- */ -- --#ifndef IOMMU_H --#define IOMMU_H -- --#include -- --#define IOMMU_FAULT_PERM_READ (1 << 0) /* read */ --#define IOMMU_FAULT_PERM_WRITE (1 << 1) /* write */ --#define IOMMU_FAULT_PERM_EXEC (1 << 2) /* exec */ --#define IOMMU_FAULT_PERM_PRIV (1 << 3) /* privileged */ -- --/* Generic fault types, can be expanded IRQ remapping fault */ --enum iommu_fault_type { -- IOMMU_FAULT_DMA_UNRECOV = 1, /* unrecoverable fault */ -- IOMMU_FAULT_PAGE_REQ, /* page request fault */ --}; -- --enum iommu_fault_reason { -- IOMMU_FAULT_REASON_UNKNOWN = 0, -- -- /* Could not access the PASID table (fetch caused external abort) */ -- IOMMU_FAULT_REASON_PASID_FETCH, -- -- /* PASID entry is invalid or has configuration errors */ -- IOMMU_FAULT_REASON_BAD_PASID_ENTRY, -- -- /* -- * PASID is out of range (e.g. exceeds the maximum PASID -- * supported by the IOMMU) or disabled. -- */ -- IOMMU_FAULT_REASON_PASID_INVALID, -- -- /* -- * An external abort occurred fetching (or updating) a translation -- * table descriptor -- */ -- IOMMU_FAULT_REASON_WALK_EABT, -- -- /* -- * Could not access the page table entry (Bad address), -- * actual translation fault -- */ -- IOMMU_FAULT_REASON_PTE_FETCH, -- -- /* Protection flag check failed */ -- IOMMU_FAULT_REASON_PERMISSION, -- -- /* access flag check failed */ -- IOMMU_FAULT_REASON_ACCESS, -- -- /* Output address of a translation stage caused Address Size fault */ -- IOMMU_FAULT_REASON_OOR_ADDRESS, --}; -- --/** -- * struct iommu_fault_unrecoverable - Unrecoverable fault data -- * @reason: reason of the fault, from &enum iommu_fault_reason -- * @flags: parameters of this fault (IOMMU_FAULT_UNRECOV_* values) -- * @pasid: Process Address Space ID -- * @perm: requested permission access using by the incoming transaction -- * (IOMMU_FAULT_PERM_* values) -- * @addr: offending page address -- * @fetch_addr: address that caused a fetch abort, if any -- */ --struct iommu_fault_unrecoverable { -- __u32 reason; --#define IOMMU_FAULT_UNRECOV_PASID_VALID (1 << 0) --#define IOMMU_FAULT_UNRECOV_ADDR_VALID (1 << 1) --#define IOMMU_FAULT_UNRECOV_FETCH_ADDR_VALID (1 << 2) -- __u32 flags; -- __u32 pasid; -- __u32 perm; -- __u64 addr; -- __u64 fetch_addr; --}; -- --/** -- * struct iommu_fault_page_request - Page Request data -- * @flags: encodes whether the corresponding fields are valid and whether this -- * is the last page in group (IOMMU_FAULT_PAGE_REQUEST_* values). -- * When IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID is set, the page response -- * must have the same PASID value as the page request. When it is clear, -- * the page response should not have a PASID. -- * @pasid: Process Address Space ID -- * @grpid: Page Request Group Index -- * @perm: requested page permissions (IOMMU_FAULT_PERM_* values) -- * @addr: page address -- * @private_data: device-specific private information -- */ --struct iommu_fault_page_request { --#define IOMMU_FAULT_PAGE_REQUEST_PASID_VALID (1 << 0) --#define IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE (1 << 1) --#define IOMMU_FAULT_PAGE_REQUEST_PRIV_DATA (1 << 2) --#define IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID (1 << 3) -- __u32 flags; -- __u32 pasid; -- __u32 grpid; -- __u32 perm; -- __u64 addr; -- __u64 private_data[2]; --}; -- --/** -- * struct iommu_fault - Generic fault data -- * @type: fault type from &enum iommu_fault_type -- * @padding: reserved for future use (should be zero) -- * @event: fault event, when @type is %IOMMU_FAULT_DMA_UNRECOV -- * @prm: Page Request message, when @type is %IOMMU_FAULT_PAGE_REQ -- * @padding2: sets the fault size to allow for future extensions -- */ --struct iommu_fault { -- __u32 type; -- __u32 padding; -- union { -- struct iommu_fault_unrecoverable event; -- struct iommu_fault_page_request prm; -- __u8 padding2[56]; -- }; --}; -- --/** -- * enum iommu_page_response_code - Return status of fault handlers -- * @IOMMU_PAGE_RESP_SUCCESS: Fault has been handled and the page tables -- * populated, retry the access. This is "Success" in PCI PRI. -- * @IOMMU_PAGE_RESP_FAILURE: General error. Drop all subsequent faults from -- * this device if possible. This is "Response Failure" in PCI PRI. -- * @IOMMU_PAGE_RESP_INVALID: Could not handle this fault, don't retry the -- * access. This is "Invalid Request" in PCI PRI. -- */ --enum iommu_page_response_code { -- IOMMU_PAGE_RESP_SUCCESS = 0, -- IOMMU_PAGE_RESP_INVALID, -- IOMMU_PAGE_RESP_FAILURE, --}; -- --/** -- * struct iommu_page_response - Generic page response information -- * @argsz: User filled size of this data -- * @version: API version of this structure -- * @flags: encodes whether the corresponding fields are valid -- * (IOMMU_FAULT_PAGE_RESPONSE_* values) -- * @pasid: Process Address Space ID -- * @grpid: Page Request Group Index -- * @code: response code from &enum iommu_page_response_code -- */ --struct iommu_page_response { -- __u32 argsz; --#define IOMMU_PAGE_RESP_VERSION_1 1 -- __u32 version; --#define IOMMU_PAGE_RESP_PASID_VALID (1 << 0) -- __u32 flags; -- __u32 pasid; -- __u32 grpid; -- __u32 code; --}; -- --/* defines the granularity of the invalidation */ --enum iommu_inv_granularity { -- IOMMU_INV_GRANU_DOMAIN, /* domain-selective invalidation */ -- IOMMU_INV_GRANU_PASID, /* PASID-selective invalidation */ -- IOMMU_INV_GRANU_ADDR, /* page-selective invalidation */ -- IOMMU_INV_GRANU_NR, /* number of invalidation granularities */ --}; -- --/** -- * struct iommu_inv_addr_info - Address Selective Invalidation Structure -- * -- * @flags: indicates the granularity of the address-selective invalidation -- * - If the PASID bit is set, the @pasid field is populated and the invalidation -- * relates to cache entries tagged with this PASID and matching the address -- * range. -- * - If ARCHID bit is set, @archid is populated and the invalidation relates -- * to cache entries tagged with this architecture specific ID and matching -- * the address range. -- * - Both PASID and ARCHID can be set as they may tag different caches. -- * - If neither PASID or ARCHID is set, global addr invalidation applies. -- * - The LEAF flag indicates whether only the leaf PTE caching needs to be -- * invalidated and other paging structure caches can be preserved. -- * @pasid: process address space ID -- * @archid: architecture-specific ID -- * @addr: first stage/level input address -- * @granule_size: page/block size of the mapping in bytes -- * @nb_granules: number of contiguous granules to be invalidated -- */ --struct iommu_inv_addr_info { --#define IOMMU_INV_ADDR_FLAGS_PASID (1 << 0) --#define IOMMU_INV_ADDR_FLAGS_ARCHID (1 << 1) --#define IOMMU_INV_ADDR_FLAGS_LEAF (1 << 2) -- __u32 flags; -- __u32 archid; -- __u64 pasid; -- __u64 addr; -- __u64 granule_size; -- __u64 nb_granules; --}; -- --/** -- * struct iommu_inv_pasid_info - PASID Selective Invalidation Structure -- * -- * @flags: indicates the granularity of the PASID-selective invalidation -- * - If the PASID bit is set, the @pasid field is populated and the invalidation -- * relates to cache entries tagged with this PASID and matching the address -- * range. -- * - If the ARCHID bit is set, the @archid is populated and the invalidation -- * relates to cache entries tagged with this architecture specific ID and -- * matching the address range. -- * - Both PASID and ARCHID can be set as they may tag different caches. -- * - At least one of PASID or ARCHID must be set. -- * @pasid: process address space ID -- * @archid: architecture-specific ID -- */ --struct iommu_inv_pasid_info { --#define IOMMU_INV_PASID_FLAGS_PASID (1 << 0) --#define IOMMU_INV_PASID_FLAGS_ARCHID (1 << 1) -- __u32 flags; -- __u32 archid; -- __u64 pasid; --}; -- --/** -- * struct iommu_cache_invalidate_info - First level/stage invalidation -- * information -- * @argsz: User filled size of this data -- * @version: API version of this structure -- * @cache: bitfield that allows to select which caches to invalidate -- * @granularity: defines the lowest granularity used for the invalidation: -- * domain > PASID > addr -- * @padding: reserved for future use (should be zero) -- * @pasid_info: invalidation data when @granularity is %IOMMU_INV_GRANU_PASID -- * @addr_info: invalidation data when @granularity is %IOMMU_INV_GRANU_ADDR -- * -- * Not all the combinations of cache/granularity are valid: -- * -- * +--------------+---------------+---------------+---------------+ -- * | type / | DEV_IOTLB | IOTLB | PASID | -- * | granularity | | | cache | -- * +==============+===============+===============+===============+ -- * | DOMAIN | N/A | Y | Y | -- * +--------------+---------------+---------------+---------------+ -- * | PASID | Y | Y | Y | -- * +--------------+---------------+---------------+---------------+ -- * | ADDR | Y | Y | N/A | -- * +--------------+---------------+---------------+---------------+ -- * -- * Invalidations by %IOMMU_INV_GRANU_DOMAIN don't take any argument other than -- * @version and @cache. -- * -- * If multiple cache types are invalidated simultaneously, they all -- * must support the used granularity. -- */ --struct iommu_cache_invalidate_info { -- __u32 argsz; --#define IOMMU_CACHE_INVALIDATE_INFO_VERSION_1 1 -- __u32 version; --/* IOMMU paging structure cache */ --#define IOMMU_CACHE_INV_TYPE_IOTLB (1 << 0) /* IOMMU IOTLB */ --#define IOMMU_CACHE_INV_TYPE_DEV_IOTLB (1 << 1) /* Device IOTLB */ --#define IOMMU_CACHE_INV_TYPE_PASID (1 << 2) /* PASID cache */ --#define IOMMU_CACHE_INV_TYPE_NR (3) -- __u8 cache; -- __u8 granularity; -- __u8 padding[6]; -- union { -- struct iommu_inv_pasid_info pasid_info; -- struct iommu_inv_addr_info addr_info; -- } granu; --}; -- --/** -- * struct iommu_gpasid_bind_data_vtd - Intel VT-d specific data on device and guest -- * SVA binding. -- * -- * @flags: VT-d PASID table entry attributes -- * @pat: Page attribute table data to compute effective memory type -- * @emt: Extended memory type -- * -- * Only guest vIOMMU selectable and effective options are passed down to -- * the host IOMMU. -- */ --struct iommu_gpasid_bind_data_vtd { --#define IOMMU_SVA_VTD_GPASID_SRE (1 << 0) /* supervisor request */ --#define IOMMU_SVA_VTD_GPASID_EAFE (1 << 1) /* extended access enable */ --#define IOMMU_SVA_VTD_GPASID_PCD (1 << 2) /* page-level cache disable */ --#define IOMMU_SVA_VTD_GPASID_PWT (1 << 3) /* page-level write through */ --#define IOMMU_SVA_VTD_GPASID_EMTE (1 << 4) /* extended mem type enable */ --#define IOMMU_SVA_VTD_GPASID_CD (1 << 5) /* PASID-level cache disable */ --#define IOMMU_SVA_VTD_GPASID_LAST (1 << 6) -- __u64 flags; -- __u32 pat; -- __u32 emt; --}; -- --#define IOMMU_SVA_VTD_GPASID_MTS_MASK (IOMMU_SVA_VTD_GPASID_CD | \ -- IOMMU_SVA_VTD_GPASID_EMTE | \ -- IOMMU_SVA_VTD_GPASID_PCD | \ -- IOMMU_SVA_VTD_GPASID_PWT) -- --/** -- * struct iommu_gpasid_bind_data - Information about device and guest PASID binding -- * @argsz: User filled size of this data -- * @version: Version of this data structure -- * @format: PASID table entry format -- * @flags: Additional information on guest bind request -- * @gpgd: Guest page directory base of the guest mm to bind -- * @hpasid: Process address space ID used for the guest mm in host IOMMU -- * @gpasid: Process address space ID used for the guest mm in guest IOMMU -- * @addr_width: Guest virtual address width -- * @padding: Reserved for future use (should be zero) -- * @vtd: Intel VT-d specific data -- * -- * Guest to host PASID mapping can be an identity or non-identity, where guest -- * has its own PASID space. For non-identify mapping, guest to host PASID lookup -- * is needed when VM programs guest PASID into an assigned device. VMM may -- * trap such PASID programming then request host IOMMU driver to convert guest -- * PASID to host PASID based on this bind data. -- */ --struct iommu_gpasid_bind_data { -- __u32 argsz; --#define IOMMU_GPASID_BIND_VERSION_1 1 -- __u32 version; --#define IOMMU_PASID_FORMAT_INTEL_VTD 1 --#define IOMMU_PASID_FORMAT_LAST 2 -- __u32 format; -- __u32 addr_width; --#define IOMMU_SVA_GPASID_VAL (1 << 0) /* guest PASID valid */ -- __u64 flags; -- __u64 gpgd; -- __u64 hpasid; -- __u64 gpasid; -- __u8 padding[8]; -- /* Vendor specific data */ -- union { -- struct iommu_gpasid_bind_data_vtd vtd; -- } vendor; --}; -- --/** -- * struct iommu_pasid_smmuv3 - ARM SMMUv3 Stream Table Entry stage 1 related -- * information -- * @version: API version of this structure -- * @s1fmt: STE s1fmt (format of the CD table: single CD, linear table -- * or 2-level table) -- * @s1dss: STE s1dss (specifies the behavior when @pasid_bits != 0 -- * and no PASID is passed along with the incoming transaction) -- * @padding: reserved for future use (should be zero) -- * -- * The PASID table is referred to as the Context Descriptor (CD) table on ARM -- * SMMUv3. Please refer to the ARM SMMU 3.x spec (ARM IHI 0070A) for full -- * details. -- */ --struct iommu_pasid_smmuv3 { --#define PASID_TABLE_SMMUV3_CFG_VERSION_1 1 -- __u32 version; -- __u8 s1fmt; -- __u8 s1dss; -- __u8 padding[2]; --}; -- --/** -- * struct iommu_pasid_table_config - PASID table data used to bind guest PASID -- * table to the host IOMMU -- * @argsz: User filled size of this data -- * @version: API version to prepare for future extensions -- * @base_ptr: guest physical address of the PASID table -- * @format: format of the PASID table -- * @pasid_bits: number of PASID bits used in the PASID table -- * @config: indicates whether the guest translation stage must -- * be translated, bypassed or aborted. -- * @padding: reserved for future use (should be zero) -- * @vendor_data.smmuv3: table information when @format is -- * %IOMMU_PASID_FORMAT_SMMUV3 -- */ --struct iommu_pasid_table_config { -- __u32 argsz; --#define PASID_TABLE_CFG_VERSION_1 1 -- __u32 version; -- __u64 base_ptr; --#define IOMMU_PASID_FORMAT_SMMUV3 1 -- __u32 format; -- __u8 pasid_bits; --#define IOMMU_PASID_CONFIG_TRANSLATE 1 --#define IOMMU_PASID_CONFIG_BYPASS 2 --#define IOMMU_PASID_CONFIG_ABORT 3 -- __u8 config; -- __u8 padding[2]; -- union { -- struct iommu_pasid_smmuv3 smmuv3; -- } vendor_data; --}; -- --#endif /* _UAPI_IOMMU_H */ -diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h -index cf8e208fac..f4ff038e8c 100644 ---- a/linux-headers/linux/vfio.h -+++ b/linux-headers/linux/vfio.h -@@ -14,7 +14,6 @@ - - #include - #include --#include - - #define VFIO_API_VERSION 0 - -@@ -335,7 +334,6 @@ struct vfio_region_info_cap_type { - #define VFIO_REGION_TYPE_GFX (1) - #define VFIO_REGION_TYPE_CCW (2) - #define VFIO_REGION_TYPE_MIGRATION (3) --#define VFIO_REGION_TYPE_NESTED (4) - - /* sub-types for VFIO_REGION_TYPE_PCI_* */ - -@@ -364,10 +362,6 @@ struct vfio_region_info_cap_type { - /* sub-types for VFIO_REGION_TYPE_GFX */ - #define VFIO_REGION_SUBTYPE_GFX_EDID (1) - --/* sub-types for VFIO_REGION_TYPE_NESTED */ --#define VFIO_REGION_SUBTYPE_NESTED_DMA_FAULT (1) --#define VFIO_REGION_SUBTYPE_NESTED_DMA_FAULT_RESPONSE (2) -- - /** - * struct vfio_region_gfx_edid - EDID region layout. - * -@@ -727,30 +721,11 @@ struct vfio_irq_info { - #define VFIO_IRQ_INFO_MASKABLE (1 << 1) - #define VFIO_IRQ_INFO_AUTOMASKED (1 << 2) - #define VFIO_IRQ_INFO_NORESIZE (1 << 3) --#define VFIO_IRQ_INFO_FLAG_CAPS (1 << 4) /* Info supports caps */ - __u32 index; /* IRQ index */ - __u32 count; /* Number of IRQs within this index */ -- __u32 cap_offset; /* Offset within info struct of first cap */ - }; - #define VFIO_DEVICE_GET_IRQ_INFO _IO(VFIO_TYPE, VFIO_BASE + 9) - --/* -- * The irq type capability allows IRQs unique to a specific device or -- * class of devices to be exposed. -- * -- * The structures below define version 1 of this capability. -- */ --#define VFIO_IRQ_INFO_CAP_TYPE 3 -- --struct vfio_irq_info_cap_type { -- struct vfio_info_cap_header header; -- __u32 type; /* global per bus driver */ -- __u32 subtype; /* type specific */ --}; -- --#define VFIO_IRQ_TYPE_NESTED (1) --#define VFIO_IRQ_SUBTYPE_DMA_FAULT (1) -- - /** - * VFIO_DEVICE_SET_IRQS - _IOW(VFIO_TYPE, VFIO_BASE + 10, struct vfio_irq_set) - * -@@ -852,8 +827,7 @@ enum { - VFIO_PCI_MSIX_IRQ_INDEX, - VFIO_PCI_ERR_IRQ_INDEX, - VFIO_PCI_REQ_IRQ_INDEX, -- VFIO_PCI_NUM_IRQS = 5 /* Fixed user ABI, IRQ indexes >=5 use */ -- /* device specific cap to define content */ -+ VFIO_PCI_NUM_IRQS - }; - - /* -@@ -1038,68 +1012,6 @@ struct vfio_device_feature { - */ - #define VFIO_DEVICE_FEATURE_PCI_VF_TOKEN (0) - --/* -- * Capability exposed by the DMA fault region -- * @version: ABI version -- */ --#define VFIO_REGION_INFO_CAP_DMA_FAULT 6 -- --struct vfio_region_info_cap_fault { -- struct vfio_info_cap_header header; -- __u32 version; --}; -- --/* -- * Capability exposed by the DMA fault response region -- * @version: ABI version -- */ --#define VFIO_REGION_INFO_CAP_DMA_FAULT_RESPONSE 7 -- --struct vfio_region_info_cap_fault_response { -- struct vfio_info_cap_header header; -- __u32 version; --}; -- --/* -- * DMA Fault Region Layout -- * @tail: index relative to the start of the ring buffer at which the -- * consumer finds the next item in the buffer -- * @entry_size: fault ring buffer entry size in bytes -- * @nb_entries: max capacity of the fault ring buffer -- * @offset: ring buffer offset relative to the start of the region -- * @head: index relative to the start of the ring buffer at which the -- * producer (kernel) inserts items into the buffers -- */ --struct vfio_region_dma_fault { -- /* Write-Only */ -- __u32 tail; -- /* Read-Only */ -- __u32 entry_size; -- __u32 nb_entries; -- __u32 offset; -- __u32 head; --}; -- --/* -- * DMA Fault Response Region Layout -- * @head: index relative to the start of the ring buffer at which the -- * producer (userspace) insert responses into the buffer -- * @entry_size: fault ring buffer entry size in bytes -- * @nb_entries: max capacity of the fault ring buffer -- * @offset: ring buffer offset relative to the start of the region -- * @tail: index relative to the start of the ring buffer at which the -- * consumer (kernel) finds the next item in the buffer -- */ --struct vfio_region_dma_fault_response { -- /* Write-Only */ -- __u32 head; -- /* Read-Only */ -- __u32 entry_size; -- __u32 nb_entries; -- __u32 offset; -- __u32 tail; --}; -- - /* -------- API for Type1 VFIO IOMMU -------- */ - - /** -@@ -1212,7 +1124,7 @@ struct vfio_iommu_type1_dma_map { - struct vfio_bitmap { - __u64 pgsize; /* page size for bitmap in bytes */ - __u64 size; /* in bytes */ -- __u64 *data; /* one bit per page */ -+ __u64 *data; /* one bit per page */ - }; - - /** -@@ -1338,134 +1250,6 @@ struct vfio_iommu_type1_dirty_bitmap_get { - - #define VFIO_IOMMU_DIRTY_PAGES _IO(VFIO_TYPE, VFIO_BASE + 17) - --/* -- * VFIO_IOMMU_BIND_PROCESS -- * -- * Allocate a PASID for a process address space, and use it to attach this -- * process to all devices in the container. Devices can then tag their DMA -- * traffic with the returned @pasid to perform transactions on the associated -- * virtual address space. Mapping and unmapping buffers is performed by standard -- * functions such as mmap and malloc. -- * -- * If flag is VFIO_IOMMU_BIND_PID, @pid contains the pid of a foreign process to -- * bind. Otherwise the current task is bound. Given that the caller owns the -- * device, setting this flag grants the caller read and write permissions on the -- * entire address space of foreign process described by @pid. Therefore, -- * permission to perform the bind operation on a foreign process is governed by -- * the ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check. See man ptrace(2) -- * for more information. -- * -- * On success, VFIO writes a Process Address Space ID (PASID) into @pasid. This -- * ID is unique to a process and can be used on all devices in the container. -- * -- * On fork, the child inherits the device fd and can use the bonds setup by its -- * parent. Consequently, the child has R/W access on the address spaces bound by -- * its parent. After an execv, the device fd is closed and the child doesn't -- * have access to the address space anymore. -- * -- * To remove a bond between process and container, VFIO_IOMMU_UNBIND ioctl is -- * issued with the same parameters. If a pid was specified in VFIO_IOMMU_BIND, -- * it should also be present for VFIO_IOMMU_UNBIND. Otherwise unbind the current -- * task from the container. -- */ --struct vfio_iommu_type1_bind_process { -- __u32 flags; --#define VFIO_IOMMU_BIND_PID (1 << 0) -- __u32 pasid; -- __s32 pid; --}; -- --/* -- * Only mode supported at the moment is VFIO_IOMMU_BIND_PROCESS, which takes -- * vfio_iommu_type1_bind_process in data. -- */ --struct vfio_iommu_type1_bind { -- __u32 argsz; -- __u32 flags; --#define VFIO_IOMMU_BIND_PROCESS (1 << 0) -- __u8 data[]; --}; -- --/* -- * VFIO_IOMMU_BIND - _IOWR(VFIO_TYPE, VFIO_BASE + 22, struct vfio_iommu_bind) -- * -- * Manage address spaces of devices in this container. Initially a TYPE1 -- * container can only have one address space, managed with -- * VFIO_IOMMU_MAP/UNMAP_DMA. -- * -- * An IOMMU of type VFIO_TYPE1_NESTING_IOMMU can be managed by both MAP/UNMAP -- * and BIND ioctls at the same time. MAP/UNMAP acts on the stage-2 (host) page -- * tables, and BIND manages the stage-1 (guest) page tables. Other types of -- * IOMMU may allow MAP/UNMAP and BIND to coexist, where MAP/UNMAP controls -- * non-PASID traffic and BIND controls PASID traffic. But this depends on the -- * underlying IOMMU architecture and isn't guaranteed. -- * -- * Availability of this feature depends on the device, its bus, the underlying -- * IOMMU and the CPU architecture. -- * -- * returns: 0 on success, -errno on failure. -- */ --#define VFIO_IOMMU_BIND _IO(VFIO_TYPE, VFIO_BASE + 22) -- --/* -- * VFIO_IOMMU_UNBIND - _IOWR(VFIO_TYPE, VFIO_BASE + 23, struct vfio_iommu_bind) -- * -- * Undo what was done by the corresponding VFIO_IOMMU_BIND ioctl. -- */ --#define VFIO_IOMMU_UNBIND _IO(VFIO_TYPE, VFIO_BASE + 23) -- --/* -- * VFIO_IOMMU_SET_PASID_TABLE - _IOWR(VFIO_TYPE, VFIO_BASE + 18, -- * struct vfio_iommu_type1_set_pasid_table) -- * -- * The SET operation passes a PASID table to the host while the -- * UNSET operation detaches the one currently programmed. It is -- * allowed to "SET" the table several times without unsetting as -- * long as the table config does not stay IOMMU_PASID_CONFIG_TRANSLATE. -- */ --struct vfio_iommu_type1_set_pasid_table { -- __u32 argsz; -- __u32 flags; --#define VFIO_PASID_TABLE_FLAG_SET (1 << 0) --#define VFIO_PASID_TABLE_FLAG_UNSET (1 << 1) -- struct iommu_pasid_table_config config; /* used on SET */ --}; -- --#define VFIO_IOMMU_SET_PASID_TABLE _IO(VFIO_TYPE, VFIO_BASE + 18) -- --/** -- * VFIO_IOMMU_CACHE_INVALIDATE - _IOWR(VFIO_TYPE, VFIO_BASE + 19, -- * struct vfio_iommu_type1_cache_invalidate) -- * -- * Propagate guest IOMMU cache invalidation to the host. -- */ --struct vfio_iommu_type1_cache_invalidate { -- __u32 argsz; -- __u32 flags; -- struct iommu_cache_invalidate_info info; --}; --#define VFIO_IOMMU_CACHE_INVALIDATE _IO(VFIO_TYPE, VFIO_BASE + 19) -- --/** -- * VFIO_IOMMU_SET_MSI_BINDING - _IOWR(VFIO_TYPE, VFIO_BASE + 20, -- * struct vfio_iommu_type1_set_msi_binding) -- * -- * Pass a stage 1 MSI doorbell mapping to the host so that this -- * latter can build a nested stage2 mapping. Or conversely tear -- * down a previously bound stage 1 MSI binding. -- */ --struct vfio_iommu_type1_set_msi_binding { -- __u32 argsz; -- __u32 flags; --#define VFIO_IOMMU_BIND_MSI (1 << 0) --#define VFIO_IOMMU_UNBIND_MSI (1 << 1) -- __u64 iova; /* MSI guest IOVA */ -- /* Fields below are used on BIND */ -- __u64 gpa; /* MSI guest physical address */ -- __u64 size; /* size of stage1 mapping (bytes) */ --}; --#define VFIO_IOMMU_SET_MSI_BINDING _IO(VFIO_TYPE, VFIO_BASE + 20) -- - /* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */ - - /* --- -2.27.0 - diff --git a/Revert-vhost-add-support-for-configure-interrupt.patch b/Revert-vhost-add-support-for-configure-interrupt.patch deleted file mode 100644 index e33069230c0926a876a8d82a69d9d3c3b8a372f2..0000000000000000000000000000000000000000 --- a/Revert-vhost-add-support-for-configure-interrupt.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 529074fd45a543a9259441e02652c3ac60673d07 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 09:53:34 +0800 -Subject: [PATCH] Revert "vhost: add support for configure interrupt" - -This reverts commit f7220a7ce21604a4bc6260ccca4dc9068c1f27f2. - -Fixes: f7220a7ce2 ("vhost: add support for configure interrupt") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 76 --------------------------------------- - include/hw/virtio/vhost.h | 4 --- - 2 files changed, 80 deletions(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index caa53443ab..2f9bb96d63 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -1581,67 +1581,6 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, - } - } - --bool vhost_config_pending(struct vhost_dev *hdev) --{ -- assert(hdev->vhost_ops); -- if ((hdev->started == false) || -- (hdev->vhost_ops->vhost_set_config_call == NULL)) { -- return false; -- } -- -- EventNotifier *notifier = -- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; -- return event_notifier_test_and_clear(notifier); --} -- --void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask) --{ -- int fd; -- int r; -- EventNotifier *notifier = -- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; -- EventNotifier *config_notifier = &vdev->config_notifier; -- assert(hdev->vhost_ops); -- -- if ((hdev->started == false) || -- (hdev->vhost_ops->vhost_set_config_call == NULL)) { -- return; -- } -- if (mask) { -- assert(vdev->use_guest_notifier_mask); -- fd = event_notifier_get_fd(notifier); -- } else { -- fd = event_notifier_get_fd(config_notifier); -- } -- r = hdev->vhost_ops->vhost_set_config_call(hdev, fd); -- if (r < 0) { -- VHOST_OPS_DEBUG(r, "vhost_set_config_call failed"); -- } --} -- --static void vhost_stop_config_intr(struct vhost_dev *dev) --{ -- int fd = -1; -- assert(dev->vhost_ops); -- if (dev->vhost_ops->vhost_set_config_call) { -- dev->vhost_ops->vhost_set_config_call(dev, fd); -- } --} -- --static void vhost_start_config_intr(struct vhost_dev *dev) --{ -- int r; -- -- assert(dev->vhost_ops); -- int fd = event_notifier_get_fd(&dev->vdev->config_notifier); -- if (dev->vhost_ops->vhost_set_config_call) { -- r = dev->vhost_ops->vhost_set_config_call(dev, fd); -- if (!r) { -- event_notifier_set(&dev->vdev->config_notifier); -- } -- } --} -- - uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits, - uint64_t features) - { -@@ -1854,16 +1793,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - } - } - -- r = event_notifier_init( -- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0); -- if (r < 0) { -- return r; -- } -- event_notifier_test_and_clear( -- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); -- if (!vdev->use_guest_notifier_mask) { -- vhost_config_mask(hdev, vdev, true); -- } - if (hdev->log_enabled) { - uint64_t log_base; - -@@ -1896,7 +1825,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - vhost_device_iotlb_miss(hdev, vq->used_phys, true); - } - } -- vhost_start_config_intr(hdev); - return 0; - fail_log: - vhost_log_put(hdev, false); -@@ -1922,9 +1850,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) - - /* should only be called after backend is connected */ - assert(hdev->vhost_ops); -- event_notifier_test_and_clear( -- &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); -- event_notifier_test_and_clear(&vdev->config_notifier); - - if (hdev->vhost_ops->vhost_dev_start) { - hdev->vhost_ops->vhost_dev_start(hdev, false); -@@ -1942,7 +1867,6 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) - } - memory_listener_unregister(&hdev->iommu_listener); - } -- vhost_stop_config_intr(hdev); - vhost_log_put(hdev, true); - hdev->started = false; - hdev->vdev = NULL; -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index 2ae5c3bfd8..86f36f0106 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -29,7 +29,6 @@ struct vhost_virtqueue { - unsigned long long used_phys; - unsigned used_size; - EventNotifier masked_notifier; -- EventNotifier masked_config_notifier; - struct vhost_dev *dev; - }; - -@@ -38,7 +37,6 @@ typedef unsigned long vhost_log_chunk_t; - #define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t)) - #define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS) - #define VHOST_INVALID_FEATURE_BIT (0xff) --#define VHOST_QUEUE_NUM_CONFIG_INR 0 - - struct vhost_log { - unsigned long long size; -@@ -118,8 +116,6 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); - void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); - int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); - void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); --bool vhost_config_pending(struct vhost_dev *hdev); --void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask); - - /* Test and clear masked event pending status. - * Should be called after unmask to avoid losing events. --- -2.27.0 - diff --git a/Revert-vhost-introduce-new-VhostOps-vhost_set_config.patch b/Revert-vhost-introduce-new-VhostOps-vhost_set_config.patch deleted file mode 100644 index 7a33b479461f428e4205c98d475909d28aef3378..0000000000000000000000000000000000000000 --- a/Revert-vhost-introduce-new-VhostOps-vhost_set_config.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0ad1ce1ff54a4d654c00e4a3b95361b519f4fd37 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 09:43:37 +0800 -Subject: [PATCH] Revert "vhost: introduce new VhostOps vhost_set_config_call" - -This reverts commit af8377d0e9437401ad30d80a27ab1fcf8252fad1. - -Signed-off-by: fangyi ---- - include/hw/virtio/vhost-backend.h | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h -index bd1c7dfe4f..a64708f456 100644 ---- a/include/hw/virtio/vhost-backend.h -+++ b/include/hw/virtio/vhost-backend.h -@@ -125,8 +125,6 @@ typedef int (*vhost_vq_get_addr_op)(struct vhost_dev *dev, - typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id); - - typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev); --typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev, -- int fd); - typedef void (*vhost_set_used_memslots_op)(struct vhost_dev *dev); - typedef unsigned int (*vhost_get_used_memslots_op)(void); - -@@ -175,7 +173,6 @@ typedef struct VhostOps { - vhost_vq_get_addr_op vhost_vq_get_addr; - vhost_get_device_id_op vhost_get_device_id; - vhost_force_iommu_op vhost_force_iommu; -- vhost_set_config_call_op vhost_set_config_call; - vhost_set_used_memslots_op vhost_set_used_memslots; - vhost_get_used_memslots_op vhost_get_used_memslots; - } VhostOps; --- -2.27.0 - diff --git a/Revert-vhost-vdpa-add-support-for-config-interrupt.patch b/Revert-vhost-vdpa-add-support-for-config-interrupt.patch deleted file mode 100644 index 725ea3bb7685e708936022754a8012ae96f06cdb..0000000000000000000000000000000000000000 --- a/Revert-vhost-vdpa-add-support-for-config-interrupt.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 92df45517567838512512f093f418067c857e8dc Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 09:58:20 +0800 -Subject: [PATCH] Revert "vhost-vdpa: add support for config interrupt" - -This reverts commit 634f7c89fbd78f57d00d5d6b39c0ade9df1fe27f. - -Fixes: 634f7c89fb ("vhost-vdpa: add support for config interrupt") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/trace-events | 1 - - hw/virtio/vhost-vdpa.c | 7 ------- - 2 files changed, 8 deletions(-) - -diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events -index 39c36ff7a6..650e521e35 100644 ---- a/hw/virtio/trace-events -+++ b/hw/virtio/trace-events -@@ -53,7 +53,6 @@ vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRI - vhost_vdpa_set_owner(void *dev) "dev: %p" - vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64 - vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64 --vhost_vdpa_set_config_call(void *dev, int fd)"dev: %p fd: %d" - - # virtio.c - virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u" -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index d8fba0b714..25a2f570a2 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -737,12 +737,6 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev, - trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd); - return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file); - } --static int vhost_vdpa_set_config_call(struct vhost_dev *dev, -- int fd) --{ -- trace_vhost_vdpa_set_config_call(dev, fd); -- return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, &fd); --} - - static int vhost_vdpa_get_features(struct vhost_dev *dev, - uint64_t *features) -@@ -823,7 +817,6 @@ const VhostOps vdpa_ops = { - .vhost_get_device_id = vhost_vdpa_get_device_id, - .vhost_vq_get_addr = vhost_vdpa_vq_get_addr, - .vhost_force_iommu = vhost_vdpa_force_iommu, -- .vhost_set_config_call = vhost_vdpa_set_config_call, - .vhost_set_used_memslots = vhost_vdpa_set_used_memslots, - .vhost_get_used_memslots = vhost_vdpa_get_used_memslots, - }; --- -2.27.0 - diff --git a/Revert-virtio-add-support-for-configure-interrupt.patch b/Revert-virtio-add-support-for-configure-interrupt.patch deleted file mode 100644 index 41dfe165aa7a468d14e81188cb0e834efbe431f3..0000000000000000000000000000000000000000 --- a/Revert-virtio-add-support-for-configure-interrupt.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 3ee9abc7cdd10ccb7057a523326fec21fb01a7bb Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 09:55:19 +0800 -Subject: [PATCH] Revert "virtio: add support for configure interrupt" - -This reverts commit 081f864f56307551f59c5e934e3f30a7290d0faa. - -Fixes: 081f864f56 ("virtio: add support for configure interrupt") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio.c | 29 ----------------------------- - include/hw/virtio/virtio.h | 4 ---- - 2 files changed, 33 deletions(-) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 05409b84d1..c1497f59aa 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -3547,14 +3547,7 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n) - virtio_irq(vq); - } - } --static void virtio_config_guest_notifier_read(EventNotifier *n) --{ -- VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier); - -- if (event_notifier_test_and_clear(n)) { -- virtio_notify_config(vdev); -- } --} - void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, - bool with_irqfd) - { -@@ -3571,23 +3564,6 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, - } - } - --void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev, -- bool assign, bool with_irqfd) --{ -- EventNotifier *n; -- n = &vdev->config_notifier; -- if (assign && !with_irqfd) { -- event_notifier_set_handler(n, virtio_config_guest_notifier_read); -- } else { -- event_notifier_set_handler(n, NULL); -- } -- if (!assign) { -- /* Test and clear notifier before closing it,*/ -- /* in case poll callback didn't have time to run. */ -- virtio_config_guest_notifier_read(n); -- } --} -- - EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq) - { - return &vq->guest_notifier; -@@ -3661,11 +3637,6 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq) - return &vq->host_notifier; - } - --EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev) --{ -- return &vdev->config_notifier; --} -- - void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled) - { - vq->host_notifier_enabled = enabled; -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index 8788ccd1f3..c113a5b864 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -112,7 +112,6 @@ struct VirtIODevice - bool use_guest_notifier_mask; - AddressSpace *dma_as; - QLIST_HEAD(, VirtQueue) *vector_queues; -- EventNotifier config_notifier; - }; - - struct VirtioDeviceClass { -@@ -316,14 +315,11 @@ uint16_t virtio_get_queue_index(VirtQueue *vq); - EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq); - void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, - bool with_irqfd); --void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev, -- bool assign, bool with_irqfd); - int virtio_device_start_ioeventfd(VirtIODevice *vdev); - int virtio_device_grab_ioeventfd(VirtIODevice *vdev); - void virtio_device_release_ioeventfd(VirtIODevice *vdev); - bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev); - EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq); --EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev); - void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled); - void virtio_queue_host_notifier_read(EventNotifier *n); - void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx, --- -2.27.0 - diff --git a/Revert-virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch b/Revert-virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch deleted file mode 100644 index b87ac1372ca8fb968bdad497358035b407735089..0000000000000000000000000000000000000000 --- a/Revert-virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 01e4e3aa5f2e2e44b72e81e76a74821edf2debd3 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 10:05:16 +0800 -Subject: [PATCH] Revert "virtio: introduce macro IRTIO_CONFIG_IRQ_IDX" - -This reverts commit bf1d85c166c19af95dbd27b1faba1d2909732323. - -Fixes: bf1d85c166 ("virtio: introduce macro IRTIO_CONFIG_IRQ_IDX") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/display/vhost-user-gpu.c | 6 ------ - hw/net/virtio-net.c | 10 ++-------- - hw/virtio/vhost-user-fs.c | 6 ------ - hw/virtio/vhost-vsock-common.c | 6 ------ - hw/virtio/virtio-crypto.c | 6 ------ - include/hw/virtio/virtio.h | 3 --- - 6 files changed, 2 insertions(+), 35 deletions(-) - -diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c -index 73ad3d84c9..49df56cd14 100644 ---- a/hw/display/vhost-user-gpu.c -+++ b/hw/display/vhost-user-gpu.c -@@ -485,9 +485,6 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx) - { - VhostUserGPU *g = VHOST_USER_GPU(vdev); - -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return false; -- } - return vhost_virtqueue_pending(&g->vhost->dev, idx); - } - -@@ -496,9 +493,6 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask) - { - VhostUserGPU *g = VHOST_USER_GPU(vdev); - -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return; -- } - vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask); - } - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 7537f44d10..3bd786cc22 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3195,9 +3195,6 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) - VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx)); - assert(n->vhost_started); -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return false; -- } - return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx); - } - -@@ -3207,11 +3204,8 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, - VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx)); - assert(n->vhost_started); -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return; -- } -- -- vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask); -+ vhost_net_virtqueue_mask(get_vhost_net(nc->peer), -+ vdev, idx, mask); - } - - static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features) -diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c -index 90c2bc9c5d..fc7dcc96ef 100644 ---- a/hw/virtio/vhost-user-fs.c -+++ b/hw/virtio/vhost-user-fs.c -@@ -161,9 +161,6 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx, - { - VHostUserFS *fs = VHOST_USER_FS(vdev); - -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return; -- } - vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask); - } - -@@ -171,9 +168,6 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx) - { - VHostUserFS *fs = VHOST_USER_FS(vdev); - -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return false; -- } - return vhost_virtqueue_pending(&fs->vhost_dev, idx); - } - -diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c -index b1f0d46209..ed706681ac 100644 ---- a/hw/virtio/vhost-vsock-common.c -+++ b/hw/virtio/vhost-vsock-common.c -@@ -125,9 +125,6 @@ static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx, - { - VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); - -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return; -- } - vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask); - } - -@@ -136,9 +133,6 @@ static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev, - { - VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); - -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return false; -- } - return vhost_virtqueue_pending(&vvc->vhost_dev, idx); - } - -diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c -index 52ba34ef1e..274c7b4dea 100644 ---- a/hw/virtio/virtio-crypto.c -+++ b/hw/virtio/virtio-crypto.c -@@ -953,9 +953,6 @@ static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, - - assert(vcrypto->vhost_started); - -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return; -- } - cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask); - } - -@@ -966,9 +963,6 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx) - - assert(vcrypto->vhost_started); - -- if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return false; -- } - return cryptodev_vhost_virtqueue_pending(vdev, queue, idx); - } - -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index c113a5b864..7472145821 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -68,9 +68,6 @@ typedef struct VirtQueueElement - - #define VIRTIO_NO_VECTOR 0xffff - --/* special index value used internally for config irqs */ --#define VIRTIO_CONFIG_IRQ_IDX -1 -- - #define TYPE_VIRTIO_DEVICE "virtio-device" - OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE) - --- -2.27.0 - diff --git a/Revert-virtio-mmio-add-support-for-configure-interru.patch b/Revert-virtio-mmio-add-support-for-configure-interru.patch deleted file mode 100644 index b87a9798a28fb85308f20c690ae64cfcee56b40b..0000000000000000000000000000000000000000 --- a/Revert-virtio-mmio-add-support-for-configure-interru.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 9633634fe4395000e88c8ab829ec756c7132d3bf Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 09:48:17 +0800 -Subject: [PATCH] Revert "virtio-mmio: add support for configure interrupt" - -This reverts commit d48185f1a40d4e4ed2fa2873a42b2a5eb8748256. - -Fixes: d48185f1a4 ("virtio-mmio: add support for configure interrupt") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-mmio.c | 27 --------------------------- - 1 file changed, 27 deletions(-) - -diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c -index 809132018b..72da12fea5 100644 ---- a/hw/virtio/virtio-mmio.c -+++ b/hw/virtio/virtio-mmio.c -@@ -673,30 +673,7 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign, - - return 0; - } --static int virtio_mmio_set_config_guest_notifier(DeviceState *d, bool assign) --{ -- VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); -- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -- VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); -- bool with_irqfd = false; -- EventNotifier *notifier = virtio_config_get_guest_notifier(vdev); -- int r = 0; - -- if (assign) { -- r = event_notifier_init(notifier, 0); -- if (r < 0) { -- return r; -- } -- virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -- } else { -- virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -- event_notifier_cleanup(notifier); -- } -- if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) { -- vdc->guest_notifier_mask(vdev, VIRTIO_CONFIG_IRQ_IDX, !assign); -- } -- return r; --} - static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, - bool assign) - { -@@ -718,10 +695,6 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, - goto assign_error; - } - } -- r = virtio_mmio_set_config_guest_notifier(d, assign); -- if (r < 0) { -- goto assign_error; -- } - - return 0; - --- -2.27.0 - diff --git a/Revert-virtio-net-add-support-for-configure-interrup.patch b/Revert-virtio-net-add-support-for-configure-interrup.patch deleted file mode 100644 index 845af47c343c5a50da512bf3e1e11f3004419034..0000000000000000000000000000000000000000 --- a/Revert-virtio-net-add-support-for-configure-interrup.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 4f6f9e62214a008523b054c82d663d14d82a2c86 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 09:50:43 +0800 -Subject: [PATCH] Revert "virtio-net: add support for configure interrupt" - -This reverts commit 497679d51087090d5a22fd265d1b96cf92d49d9d. - -Fixes: 497679d510 ("virtio-net: add support for configure interrupt") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/net/vhost_net.c | 9 --------- - include/net/vhost_net.h | 2 -- - 2 files changed, 11 deletions(-) - -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index d5a92144bb..bea053a742 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -524,15 +524,6 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, - vhost_virtqueue_mask(&net->dev, dev, idx, mask); - } - --bool vhost_net_config_pending(VHostNetState *net) --{ -- return vhost_config_pending(&net->dev); --} -- --void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask) --{ -- vhost_config_mask(&net->dev, dev, mask); --} - VHostNetState *get_vhost_net(NetClientState *nc) - { - VHostNetState *vhost_net = 0; -diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h -index 1844f0ed46..7bdbf484e4 100644 ---- a/include/net/vhost_net.h -+++ b/include/net/vhost_net.h -@@ -39,8 +39,6 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data, - bool vhost_net_virtqueue_pending(VHostNetState *net, int n); - void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, - int idx, bool mask); --bool vhost_net_config_pending(VHostNetState *net); --void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask); - int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr); - VHostNetState *get_vhost_net(NetClientState *nc); - --- -2.27.0 - diff --git a/Revert-virtio-pci-add-support-for-configure-interrup.patch b/Revert-virtio-pci-add-support-for-configure-interrup.patch deleted file mode 100644 index 0ce8a4be4715ab23b1b6feb1d7747a477e94bd08..0000000000000000000000000000000000000000 --- a/Revert-virtio-pci-add-support-for-configure-interrup.patch +++ /dev/null @@ -1,215 +0,0 @@ -From b97597030e537248f3986589cfc4a32a3e7eb8f5 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 09:46:06 +0800 -Subject: [PATCH] Revert "virtio-pci: add support for configure interrupt" - -This reverts commit d5d24d859c3957ea1674d0e102f96439cdbfe93a. - -Fixes: d5d24d859c ("virtio-pci: add support for configure interrupt") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 92 ++++++------------------------------------ - hw/virtio/virtio-pci.h | 4 +- - 2 files changed, 13 insertions(+), 83 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 90237f523e..75be770971 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -812,8 +812,7 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, - VirtQueue *vq; - - if (queue_no == VIRTIO_CONFIG_IRQ_IDX) { -- *n = virtio_config_get_guest_notifier(vdev); -- *vector = vdev->config_vector; -+ return -1; - } else { - if (!virtio_queue_get_num(vdev, queue_no)) { - return -1; -@@ -888,10 +887,6 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - return ret; - } - --static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy) --{ -- return kvm_virtio_pci_vector_use_one(proxy, VIRTIO_CONFIG_IRQ_IDX); --} - - static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy, - int queue_no) -@@ -929,11 +924,6 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - } - } - --static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy) --{ -- kvm_virtio_pci_vector_release_one(proxy, VIRTIO_CONFIG_IRQ_IDX); --} -- - static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy, - unsigned int queue_no, - unsigned int vector, -@@ -1015,17 +1005,9 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - } - vq = virtio_vector_next_queue(vq); - } -- /* unmask config intr */ -- n = virtio_config_get_guest_notifier(vdev); -- ret = virtio_pci_one_vector_unmask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, -- msg, n); -- if (ret < 0) { -- goto undo_config; -- } -+ - return 0; --undo_config: -- n = virtio_config_get_guest_notifier(vdev); -- virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n); -+ - undo: - vq = virtio_vector_first_queue(vdev, vector); - while (vq && unmasked >= 0) { -@@ -1059,8 +1041,6 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) - } - vq = virtio_vector_next_queue(vq); - } -- n = virtio_config_get_guest_notifier(vdev); -- virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n); - } - - static void virtio_pci_vector_poll(PCIDevice *dev, -@@ -1092,34 +1072,6 @@ static void virtio_pci_vector_poll(PCIDevice *dev, - msix_set_pending(dev, vector); - } - } -- /* poll the config intr */ -- ret = virtio_pci_get_notifier(proxy, VIRTIO_CONFIG_IRQ_IDX, ¬ifier, -- &vector); -- if (ret < 0) { -- return; -- } -- if (vector < vector_start || vector >= vector_end || -- !msix_is_masked(dev, vector)) { -- return; -- } -- if (k->guest_notifier_pending) { -- if (k->guest_notifier_pending(vdev, VIRTIO_CONFIG_IRQ_IDX)) { -- msix_set_pending(dev, vector); -- } -- } else if (event_notifier_test_and_clear(notifier)) { -- msix_set_pending(dev, vector); -- } --} -- --void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq, -- int n, bool assign, -- bool with_irqfd) --{ -- if (n == VIRTIO_CONFIG_IRQ_IDX) { -- virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -- } else { -- virtio_queue_set_guest_notifier_fd_handler(vq, assign, with_irqfd); -- } - } - - static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, -@@ -1128,25 +1080,17 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, - VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); -- VirtQueue *vq = NULL; -- EventNotifier *notifier = NULL; -- -- if (n == VIRTIO_CONFIG_IRQ_IDX) { -- notifier = virtio_config_get_guest_notifier(vdev); -- } else { -- vq = virtio_get_queue(vdev, n); -- notifier = virtio_queue_get_guest_notifier(vq); -- } -+ VirtQueue *vq = virtio_get_queue(vdev, n); -+ EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); - - if (assign) { - int r = event_notifier_init(notifier, 0); - if (r < 0) { - return r; - } -- virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, true, with_irqfd); -+ virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); - } else { -- virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, false, -- with_irqfd); -+ virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); - event_notifier_cleanup(notifier); - } - -@@ -1188,7 +1132,6 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - msix_unset_vector_notifiers(&proxy->pci_dev); - if (proxy->vector_irqfd) { - kvm_virtio_pci_vector_release(proxy, nvqs); -- kvm_virtio_pci_vector_config_release(proxy); - g_free(proxy->vector_irqfd); - proxy->vector_irqfd = NULL; - } -@@ -1204,11 +1147,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - goto assign_error; - } - } -- r = virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, assign, -- with_irqfd); -- if (r < 0) { -- goto config_assign_error; -- } -+ - /* Must set vector notifier after guest notifier has been assigned */ - if ((with_irqfd || k->guest_notifier_mask) && assign) { - if (with_irqfd) { -@@ -1217,14 +1156,11 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - msix_nr_vectors_allocated(&proxy->pci_dev)); - r = kvm_virtio_pci_vector_use(proxy, nvqs); - if (r < 0) { -- goto config_assign_error; -+ goto assign_error; - } - } -- r = kvm_virtio_pci_vector_config_use(proxy); -- if (r < 0) { -- goto config_error; -- } -- r = msix_set_vector_notifiers(&proxy->pci_dev, virtio_pci_vector_unmask, -+ r = msix_set_vector_notifiers(&proxy->pci_dev, -+ virtio_pci_vector_unmask, - virtio_pci_vector_mask, - virtio_pci_vector_poll); - if (r < 0) { -@@ -1239,11 +1175,7 @@ notifiers_error: - assert(assign); - kvm_virtio_pci_vector_release(proxy, nvqs); - } --config_error: -- kvm_virtio_pci_vector_config_release(proxy); --config_assign_error: -- virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, !assign, -- with_irqfd); -+ - assign_error: - /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ - assert(assign); -diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h -index 6d8e071d8d..d95b1a13a5 100644 ---- a/hw/virtio/virtio-pci.h -+++ b/hw/virtio/virtio-pci.h -@@ -256,7 +256,5 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t); - * @fixed_queues. - */ - unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues); --void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq, -- int n, bool assign, -- bool with_irqfd); -+ - #endif --- -2.27.0 - diff --git a/Revert-virtio-pci-decouple-notifier-from-interrupt-p.patch b/Revert-virtio-pci-decouple-notifier-from-interrupt-p.patch deleted file mode 100644 index deda743bbaec5d395b57755c5c350524db3ba722..0000000000000000000000000000000000000000 --- a/Revert-virtio-pci-decouple-notifier-from-interrupt-p.patch +++ /dev/null @@ -1,255 +0,0 @@ -From 38c0a07985c6616c43ee98caf7054ddd49dcd34e Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 10:02:59 +0800 -Subject: [PATCH] Revert "virtio-pci: decouple notifier from interrupt process" - -This reverts commit e3480ef81f6fb61cc9c04e3b5be8b7e84484fc05. - -Fixes: e3480ef81f ("virtio-pci: decouple notifier from interrupt process") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 88 +++++++++++++++--------------------------- - 1 file changed, 31 insertions(+), 57 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 85d7357f66..21c0ec3b1b 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -789,41 +789,29 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy, - } - - static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy, -- EventNotifier *n, -+ unsigned int queue_no, - unsigned int vector) - { - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ VirtQueue *vq = virtio_get_queue(vdev, queue_no); -+ EventNotifier *n = virtio_queue_get_guest_notifier(vq); - return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq); - } - - static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy, -- EventNotifier *n , -+ unsigned int queue_no, - unsigned int vector) - { -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ VirtQueue *vq = virtio_get_queue(vdev, queue_no); -+ EventNotifier *n = virtio_queue_get_guest_notifier(vq); - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; - int ret; - - ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq); - assert(ret == 0); - } --static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, -- EventNotifier **n, unsigned int *vector) --{ -- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -- VirtQueue *vq; -- -- if (queue_no == VIRTIO_CONFIG_IRQ_IDX) { -- return -1; -- } else { -- if (!virtio_queue_get_num(vdev, queue_no)) { -- return -1; -- } -- *vector = virtio_queue_vector(vdev, queue_no); -- vq = virtio_get_queue(vdev, queue_no); -- *n = virtio_queue_get_guest_notifier(vq); -- } -- return 0; --} - - static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - { -@@ -832,15 +820,12 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - unsigned int vector; - int ret, queue_no; -- EventNotifier *n; -+ - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -+ vector = virtio_queue_vector(vdev, queue_no); - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; - } -@@ -852,7 +837,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - * Otherwise, delay until unmasked in the frontend. - */ - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); -+ ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); - if (ret < 0) { - kvm_virtio_pci_vq_vector_release(proxy, vector); - goto undo; -@@ -868,11 +853,7 @@ undo: - continue; - } - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); - } - kvm_virtio_pci_vq_vector_release(proxy, vector); - } -@@ -886,16 +867,12 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - unsigned int vector; - int queue_no; - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- EventNotifier *n; -- int ret ; -+ - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -+ vector = virtio_queue_vector(vdev, queue_no); - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; - } -@@ -903,20 +880,21 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - * Otherwise, it was cleaned when masked in the frontend. - */ - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); - } - kvm_virtio_pci_vq_vector_release(proxy, vector); - } - } - --static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy, -+static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, - unsigned int queue_no, - unsigned int vector, -- MSIMessage msg, -- EventNotifier *n) -+ MSIMessage msg) - { - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -+ VirtQueue *vq = virtio_get_queue(vdev, queue_no); -+ EventNotifier *n = virtio_queue_get_guest_notifier(vq); - VirtIOIRQFD *irqfd; - int ret = 0; - -@@ -943,15 +921,14 @@ static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy, - event_notifier_set(n); - } - } else { -- ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); -+ ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); - } - return ret; - } - --static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy, -+static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, - unsigned int queue_no, -- unsigned int vector, -- EventNotifier *n) -+ unsigned int vector) - { - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -@@ -962,7 +939,7 @@ static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy, - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { - k->guest_notifier_mask(vdev, queue_no, true); - } else { -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); - } - } - -@@ -972,7 +949,6 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtQueue *vq = virtio_vector_first_queue(vdev, vector); -- EventNotifier *n; - int ret, index, unmasked = 0; - - while (vq) { -@@ -981,8 +957,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - break; - } - if (index < proxy->nvqs_with_notifiers) { -- n = virtio_queue_get_guest_notifier(vq); -- ret = virtio_pci_one_vector_unmask(proxy, index, vector, msg, n); -+ ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg); - if (ret < 0) { - goto undo; - } -@@ -998,8 +973,7 @@ undo: - while (vq && unmasked >= 0) { - index = virtio_get_queue_index(vq); - if (index < proxy->nvqs_with_notifiers) { -- n = virtio_queue_get_guest_notifier(vq); -- virtio_pci_one_vector_mask(proxy, index, vector, n); -+ virtio_pci_vq_vector_mask(proxy, index, vector); - --unmasked; - } - vq = virtio_vector_next_queue(vq); -@@ -1012,17 +986,15 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) - VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtQueue *vq = virtio_vector_first_queue(vdev, vector); -- EventNotifier *n; - int index; - - while (vq) { - index = virtio_get_queue_index(vq); -- n = virtio_queue_get_guest_notifier(vq); - if (!virtio_queue_get_num(vdev, index)) { - break; - } - if (index < proxy->nvqs_with_notifiers) { -- virtio_pci_one_vector_mask(proxy, index, vector, n); -+ virtio_pci_vq_vector_mask(proxy, index, vector); - } - vq = virtio_vector_next_queue(vq); - } -@@ -1038,17 +1010,19 @@ static void virtio_pci_vector_poll(PCIDevice *dev, - int queue_no; - unsigned int vector; - EventNotifier *notifier; -- int ret; -+ VirtQueue *vq; - - for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { -- ret = virtio_pci_get_notifier(proxy, queue_no, ¬ifier, &vector); -- if (ret < 0) { -+ if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -+ vector = virtio_queue_vector(vdev, queue_no); - if (vector < vector_start || vector >= vector_end || - !msix_is_masked(dev, vector)) { - continue; - } -+ vq = virtio_get_queue(vdev, queue_no); -+ notifier = virtio_queue_get_guest_notifier(vq); - if (k->guest_notifier_pending) { - if (k->guest_notifier_pending(vdev, queue_no)) { - msix_set_pending(dev, vector); --- -2.27.0 - diff --git a/Revert-virtio-pci-decouple-the-single-vector-from-th.patch b/Revert-virtio-pci-decouple-the-single-vector-from-th.patch deleted file mode 100644 index 45fa977abb728ec2043f1b54175e7adf5b4bd9ac..0000000000000000000000000000000000000000 --- a/Revert-virtio-pci-decouple-the-single-vector-from-th.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 074043d5d6c2610a320d2bc7d8649b7eff9c806e Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Wed, 22 Nov 2023 10:01:17 +0800 -Subject: [PATCH] Revert "virtio-pci: decouple the single vector from the - interrupt process" - -This reverts commit 316011b8a74e777eb3ba03171cd701a291c28867. - -Fixes: 316011b8a7 ("virtio-pci: decouple the single vector from the interrupt process") -Cc: "Cindy Lu" -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 131 ++++++++++++++++++----------------------- - 1 file changed, 58 insertions(+), 73 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 75be770971..85d7357f66 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -762,6 +762,7 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev, - } - - static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, -+ unsigned int queue_no, - unsigned int vector) - { - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; -@@ -824,103 +825,87 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, - return 0; - } - --static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no) -+static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - { -- unsigned int vector; -- int ret; -- EventNotifier *n; - PCIDevice *dev = &proxy->pci_dev; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- return ret; -- } -- if (vector >= msix_nr_vectors_allocated(dev)) { -- return 0; -- } -- ret = kvm_virtio_pci_vq_vector_use(proxy, vector); -- if (ret < 0) { -- goto undo; -- } -- /* -- * If guest supports masking, set up irqfd now. -- * Otherwise, delay until unmasked in the frontend. -- */ -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); -+ unsigned int vector; -+ int ret, queue_no; -+ EventNotifier *n; -+ for (queue_no = 0; queue_no < nvqs; queue_no++) { -+ if (!virtio_queue_get_num(vdev, queue_no)) { -+ break; -+ } -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ continue; -+ } -+ ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector); - if (ret < 0) { -- kvm_virtio_pci_vq_vector_release(proxy, vector); - goto undo; - } -+ /* If guest supports masking, set up irqfd now. -+ * Otherwise, delay until unmasked in the frontend. -+ */ -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); -+ if (ret < 0) { -+ kvm_virtio_pci_vq_vector_release(proxy, vector); -+ goto undo; -+ } -+ } - } -- - return 0; --undo: - -- vector = virtio_queue_vector(vdev, queue_no); -- if (vector >= msix_nr_vectors_allocated(dev)) { -- return ret; -- } -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- return ret; -+undo: -+ while (--queue_no >= 0) { -+ vector = virtio_queue_vector(vdev, queue_no); -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ continue; - } -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -- } -- return ret; --} --static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) --{ -- int queue_no; -- int ret = 0; -- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -- -- for (queue_no = 0; queue_no < nvqs; queue_no++) { -- if (!virtio_queue_get_num(vdev, queue_no)) { -- return -1; -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); - } -- ret = kvm_virtio_pci_vector_use_one(proxy, queue_no); -+ kvm_virtio_pci_vq_vector_release(proxy, vector); - } - return ret; - } - -- --static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy, -- int queue_no) -+static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - { -+ PCIDevice *dev = &proxy->pci_dev; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - unsigned int vector; -- EventNotifier *n; -- int ret; -- VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- PCIDevice *dev = &proxy->pci_dev; -- -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- return; -- } -- if (vector >= msix_nr_vectors_allocated(dev)) { -- return; -- } -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -- } -- kvm_virtio_pci_vq_vector_release(proxy, vector); --} -- --static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) --{ - int queue_no; -- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -- -+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -+ EventNotifier *n; -+ int ret ; - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- kvm_virtio_pci_vector_release_one(proxy, queue_no); -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ continue; -+ } -+ /* If guest supports masking, clean up irqfd now. -+ * Otherwise, it was cleaned when masked in the frontend. -+ */ -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ } -+ kvm_virtio_pci_vq_vector_release(proxy, vector); - } - } - --- -2.27.0 - diff --git a/Update-bench-code-for-addressing-CI-problem.patch b/Update-bench-code-for-addressing-CI-problem.patch deleted file mode 100644 index 4f808f139c366ca7130655bef11cefbd8ec56e86..0000000000000000000000000000000000000000 --- a/Update-bench-code-for-addressing-CI-problem.patch +++ /dev/null @@ -1,615 +0,0 @@ -From 4fe9da6fdaa5a9a12fdb26bf2a8c5abfccabf9e9 Mon Sep 17 00:00:00 2001 -From: ling xu -Date: Wed, 16 Nov 2022 23:29:23 +0800 -Subject: [PATCH] Update bench-code for addressing CI problem - -mainline inclusion -from mainline-v8.0.0-rc0 -commit cc98c9fd5c17b8ab62ad91b183060d8f70b9d00d -category: feature -feature: AVX512 support for xbzrle_encode_buffer -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6Z50P - -Intel-SIG: commit cc98c9fd5c17 ("Update bench-code for addressing CI problem") - -------------------------------------- - -Update bench-code for addressing CI problem - -Unit test code is in test-xbzrle.c, and benchmark code is in xbzrle-bench.c -for performance benchmarking. we have modified xbzrle-bench.c to address -CI problem. - -Signed-off-by: ling xu -Co-authored-by: Zhou Zhao -Co-authored-by: Jun Jin -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -Signed-off-by: Aichun Shi ---- - tests/bench/meson.build | 6 + - tests/bench/xbzrle-bench.c | 469 +++++++++++++++++++++++++++++++++++++ - tests/unit/test-xbzrle.c | 39 ++- - 3 files changed, 509 insertions(+), 5 deletions(-) - create mode 100644 tests/bench/xbzrle-bench.c - -diff --git a/tests/bench/meson.build b/tests/bench/meson.build -index 00b3c209dc..54bc8938a8 100644 ---- a/tests/bench/meson.build -+++ b/tests/bench/meson.build -@@ -3,6 +3,12 @@ qht_bench = executable('qht-bench', - sources: 'qht-bench.c', - dependencies: [qemuutil]) - -+if have_system -+xbzrle_bench = executable('xbzrle-bench', -+ sources: 'xbzrle-bench.c', -+ dependencies: [qemuutil,migration]) -+endif -+ - executable('atomic_add-bench', - sources: files('atomic_add-bench.c'), - dependencies: [qemuutil], -diff --git a/tests/bench/xbzrle-bench.c b/tests/bench/xbzrle-bench.c -new file mode 100644 -index 0000000000..8848a3a32d ---- /dev/null -+++ b/tests/bench/xbzrle-bench.c -@@ -0,0 +1,469 @@ -+/* -+ * Xor Based Zero Run Length Encoding unit tests. -+ * -+ * Copyright 2013 Red Hat, Inc. and/or its affiliates -+ * -+ * Authors: -+ * Orit Wasserman -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ * -+ */ -+#include "qemu/osdep.h" -+#include "qemu/cutils.h" -+#include "../migration/xbzrle.h" -+ -+#if defined(CONFIG_AVX512BW_OPT) -+#define XBZRLE_PAGE_SIZE 4096 -+static bool is_cpu_support_avx512bw; -+#include "qemu/cpuid.h" -+static void __attribute__((constructor)) init_cpu_flag(void) -+{ -+ unsigned max = __get_cpuid_max(0, NULL); -+ int a, b, c, d; -+ is_cpu_support_avx512bw = false; -+ if (max >= 1) { -+ __cpuid(1, a, b, c, d); -+ /* We must check that AVX is not just available, but usable. */ -+ if ((c & bit_OSXSAVE) && (c & bit_AVX) && max >= 7) { -+ int bv; -+ __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0)); -+ __cpuid_count(7, 0, a, b, c, d); -+ /* 0xe6: -+ * XCR0[7:5] = 111b (OPMASK state, upper 256-bit of ZMM0-ZMM15 -+ * and ZMM16-ZMM31 state are enabled by OS) -+ * XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS) -+ */ -+ if ((bv & 0xe6) == 0xe6 && (b & bit_AVX512BW)) { -+ is_cpu_support_avx512bw = true; -+ } -+ } -+ } -+ return ; -+} -+ -+struct ResTime { -+ float t_raw; -+ float t_512; -+}; -+ -+ -+/* Function prototypes -+int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen, -+ uint8_t *dst, int dlen); -+*/ -+static void encode_decode_zero(struct ResTime *res) -+{ -+ uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ int i = 0; -+ int dlen = 0, dlen512 = 0; -+ int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); -+ -+ for (i = diff_len; i > 0; i--) { -+ buffer[1000 + i] = i; -+ buffer512[1000 + i] = i; -+ } -+ -+ buffer[1000 + diff_len + 3] = 103; -+ buffer[1000 + diff_len + 5] = 105; -+ -+ buffer512[1000 + diff_len + 3] = 103; -+ buffer512[1000 + diff_len + 5] = 105; -+ -+ /* encode zero page */ -+ time_t t_start, t_end, t_start512, t_end512; -+ t_start = clock(); -+ dlen = xbzrle_encode_buffer(buffer, buffer, XBZRLE_PAGE_SIZE, compressed, -+ XBZRLE_PAGE_SIZE); -+ t_end = clock(); -+ float time_val = difftime(t_end, t_start); -+ g_assert(dlen == 0); -+ -+ t_start512 = clock(); -+ dlen512 = xbzrle_encode_buffer_avx512(buffer512, buffer512, XBZRLE_PAGE_SIZE, -+ compressed512, XBZRLE_PAGE_SIZE); -+ t_end512 = clock(); -+ float time_val512 = difftime(t_end512, t_start512); -+ g_assert(dlen512 == 0); -+ -+ res->t_raw = time_val; -+ res->t_512 = time_val512; -+ -+ g_free(buffer); -+ g_free(compressed); -+ g_free(buffer512); -+ g_free(compressed512); -+ -+} -+ -+static void test_encode_decode_zero_avx512(void) -+{ -+ int i; -+ float time_raw = 0.0, time_512 = 0.0; -+ struct ResTime res; -+ for (i = 0; i < 10000; i++) { -+ encode_decode_zero(&res); -+ time_raw += res.t_raw; -+ time_512 += res.t_512; -+ } -+ printf("Zero test:\n"); -+ printf("Raw xbzrle_encode time is %f ms\n", time_raw); -+ printf("512 xbzrle_encode time is %f ms\n", time_512); -+} -+ -+static void encode_decode_unchanged(struct ResTime *res) -+{ -+ uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ int i = 0; -+ int dlen = 0, dlen512 = 0; -+ int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); -+ -+ for (i = diff_len; i > 0; i--) { -+ test[1000 + i] = i + 4; -+ test512[1000 + i] = i + 4; -+ } -+ -+ test[1000 + diff_len + 3] = 107; -+ test[1000 + diff_len + 5] = 109; -+ -+ test512[1000 + diff_len + 3] = 107; -+ test512[1000 + diff_len + 5] = 109; -+ -+ /* test unchanged buffer */ -+ time_t t_start, t_end, t_start512, t_end512; -+ t_start = clock(); -+ dlen = xbzrle_encode_buffer(test, test, XBZRLE_PAGE_SIZE, compressed, -+ XBZRLE_PAGE_SIZE); -+ t_end = clock(); -+ float time_val = difftime(t_end, t_start); -+ g_assert(dlen == 0); -+ -+ t_start512 = clock(); -+ dlen512 = xbzrle_encode_buffer_avx512(test512, test512, XBZRLE_PAGE_SIZE, -+ compressed512, XBZRLE_PAGE_SIZE); -+ t_end512 = clock(); -+ float time_val512 = difftime(t_end512, t_start512); -+ g_assert(dlen512 == 0); -+ -+ res->t_raw = time_val; -+ res->t_512 = time_val512; -+ -+ g_free(test); -+ g_free(compressed); -+ g_free(test512); -+ g_free(compressed512); -+ -+} -+ -+static void test_encode_decode_unchanged_avx512(void) -+{ -+ int i; -+ float time_raw = 0.0, time_512 = 0.0; -+ struct ResTime res; -+ for (i = 0; i < 10000; i++) { -+ encode_decode_unchanged(&res); -+ time_raw += res.t_raw; -+ time_512 += res.t_512; -+ } -+ printf("Unchanged test:\n"); -+ printf("Raw xbzrle_encode time is %f ms\n", time_raw); -+ printf("512 xbzrle_encode time is %f ms\n", time_512); -+} -+ -+static void encode_decode_1_byte(struct ResTime *res) -+{ -+ uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE); -+ uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE); -+ int dlen = 0, rc = 0, dlen512 = 0, rc512 = 0; -+ uint8_t buf[2]; -+ uint8_t buf512[2]; -+ -+ test[XBZRLE_PAGE_SIZE - 1] = 1; -+ test512[XBZRLE_PAGE_SIZE - 1] = 1; -+ -+ time_t t_start, t_end, t_start512, t_end512; -+ t_start = clock(); -+ dlen = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed, -+ XBZRLE_PAGE_SIZE); -+ t_end = clock(); -+ float time_val = difftime(t_end, t_start); -+ g_assert(dlen == (uleb128_encode_small(&buf[0], 4095) + 2)); -+ -+ rc = xbzrle_decode_buffer(compressed, dlen, buffer, XBZRLE_PAGE_SIZE); -+ g_assert(rc == XBZRLE_PAGE_SIZE); -+ g_assert(memcmp(test, buffer, XBZRLE_PAGE_SIZE) == 0); -+ -+ t_start512 = clock(); -+ dlen512 = xbzrle_encode_buffer_avx512(buffer512, test512, XBZRLE_PAGE_SIZE, -+ compressed512, XBZRLE_PAGE_SIZE); -+ t_end512 = clock(); -+ float time_val512 = difftime(t_end512, t_start512); -+ g_assert(dlen512 == (uleb128_encode_small(&buf512[0], 4095) + 2)); -+ -+ rc512 = xbzrle_decode_buffer(compressed512, dlen512, buffer512, -+ XBZRLE_PAGE_SIZE); -+ g_assert(rc512 == XBZRLE_PAGE_SIZE); -+ g_assert(memcmp(test512, buffer512, XBZRLE_PAGE_SIZE) == 0); -+ -+ res->t_raw = time_val; -+ res->t_512 = time_val512; -+ -+ g_free(buffer); -+ g_free(compressed); -+ g_free(test); -+ g_free(buffer512); -+ g_free(compressed512); -+ g_free(test512); -+ -+} -+ -+static void test_encode_decode_1_byte_avx512(void) -+{ -+ int i; -+ float time_raw = 0.0, time_512 = 0.0; -+ struct ResTime res; -+ for (i = 0; i < 10000; i++) { -+ encode_decode_1_byte(&res); -+ time_raw += res.t_raw; -+ time_512 += res.t_512; -+ } -+ printf("1 byte test:\n"); -+ printf("Raw xbzrle_encode time is %f ms\n", time_raw); -+ printf("512 xbzrle_encode time is %f ms\n", time_512); -+} -+ -+static void encode_decode_overflow(struct ResTime *res) -+{ -+ uint8_t *compressed = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ int i = 0, rc = 0, rc512 = 0; -+ -+ for (i = 0; i < XBZRLE_PAGE_SIZE / 2 - 1; i++) { -+ test[i * 2] = 1; -+ test512[i * 2] = 1; -+ } -+ -+ /* encode overflow */ -+ time_t t_start, t_end, t_start512, t_end512; -+ t_start = clock(); -+ rc = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed, -+ XBZRLE_PAGE_SIZE); -+ t_end = clock(); -+ float time_val = difftime(t_end, t_start); -+ g_assert(rc == -1); -+ -+ t_start512 = clock(); -+ rc512 = xbzrle_encode_buffer_avx512(buffer512, test512, XBZRLE_PAGE_SIZE, -+ compressed512, XBZRLE_PAGE_SIZE); -+ t_end512 = clock(); -+ float time_val512 = difftime(t_end512, t_start512); -+ g_assert(rc512 == -1); -+ -+ res->t_raw = time_val; -+ res->t_512 = time_val512; -+ -+ g_free(buffer); -+ g_free(compressed); -+ g_free(test); -+ g_free(buffer512); -+ g_free(compressed512); -+ g_free(test512); -+ -+} -+ -+static void test_encode_decode_overflow_avx512(void) -+{ -+ int i; -+ float time_raw = 0.0, time_512 = 0.0; -+ struct ResTime res; -+ for (i = 0; i < 10000; i++) { -+ encode_decode_overflow(&res); -+ time_raw += res.t_raw; -+ time_512 += res.t_512; -+ } -+ printf("Overflow test:\n"); -+ printf("Raw xbzrle_encode time is %f ms\n", time_raw); -+ printf("512 xbzrle_encode time is %f ms\n", time_512); -+} -+ -+static void encode_decode_range_avx512(struct ResTime *res) -+{ -+ uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE); -+ uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE); -+ uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ int i = 0, rc = 0, rc512 = 0; -+ int dlen = 0, dlen512 = 0; -+ -+ int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1006); -+ -+ for (i = diff_len; i > 0; i--) { -+ buffer[1000 + i] = i; -+ test[1000 + i] = i + 4; -+ buffer512[1000 + i] = i; -+ test512[1000 + i] = i + 4; -+ } -+ -+ buffer[1000 + diff_len + 3] = 103; -+ test[1000 + diff_len + 3] = 107; -+ -+ buffer[1000 + diff_len + 5] = 105; -+ test[1000 + diff_len + 5] = 109; -+ -+ buffer512[1000 + diff_len + 3] = 103; -+ test512[1000 + diff_len + 3] = 107; -+ -+ buffer512[1000 + diff_len + 5] = 105; -+ test512[1000 + diff_len + 5] = 109; -+ -+ /* test encode/decode */ -+ time_t t_start, t_end, t_start512, t_end512; -+ t_start = clock(); -+ dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, compressed, -+ XBZRLE_PAGE_SIZE); -+ t_end = clock(); -+ float time_val = difftime(t_end, t_start); -+ rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE); -+ g_assert(rc < XBZRLE_PAGE_SIZE); -+ g_assert(memcmp(test, buffer, XBZRLE_PAGE_SIZE) == 0); -+ -+ t_start512 = clock(); -+ dlen512 = xbzrle_encode_buffer_avx512(test512, buffer512, XBZRLE_PAGE_SIZE, -+ compressed512, XBZRLE_PAGE_SIZE); -+ t_end512 = clock(); -+ float time_val512 = difftime(t_end512, t_start512); -+ rc512 = xbzrle_decode_buffer(compressed512, dlen512, test512, XBZRLE_PAGE_SIZE); -+ g_assert(rc512 < XBZRLE_PAGE_SIZE); -+ g_assert(memcmp(test512, buffer512, XBZRLE_PAGE_SIZE) == 0); -+ -+ res->t_raw = time_val; -+ res->t_512 = time_val512; -+ -+ g_free(buffer); -+ g_free(compressed); -+ g_free(test); -+ g_free(buffer512); -+ g_free(compressed512); -+ g_free(test512); -+ -+} -+ -+static void test_encode_decode_avx512(void) -+{ -+ int i; -+ float time_raw = 0.0, time_512 = 0.0; -+ struct ResTime res; -+ for (i = 0; i < 10000; i++) { -+ encode_decode_range_avx512(&res); -+ time_raw += res.t_raw; -+ time_512 += res.t_512; -+ } -+ printf("Encode decode test:\n"); -+ printf("Raw xbzrle_encode time is %f ms\n", time_raw); -+ printf("512 xbzrle_encode time is %f ms\n", time_512); -+} -+ -+static void encode_decode_random(struct ResTime *res) -+{ -+ uint8_t *buffer = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed = g_malloc(XBZRLE_PAGE_SIZE); -+ uint8_t *test = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *buffer512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ uint8_t *compressed512 = g_malloc(XBZRLE_PAGE_SIZE); -+ uint8_t *test512 = g_malloc0(XBZRLE_PAGE_SIZE); -+ int i = 0, rc = 0, rc512 = 0; -+ int dlen = 0, dlen512 = 0; -+ -+ int diff_len = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1); -+ /* store the index of diff */ -+ int dirty_index[diff_len]; -+ for (int j = 0; j < diff_len; j++) { -+ dirty_index[j] = g_test_rand_int_range(0, XBZRLE_PAGE_SIZE - 1); -+ } -+ for (i = diff_len - 1; i >= 0; i--) { -+ buffer[dirty_index[i]] = i; -+ test[dirty_index[i]] = i + 4; -+ buffer512[dirty_index[i]] = i; -+ test512[dirty_index[i]] = i + 4; -+ } -+ -+ time_t t_start, t_end, t_start512, t_end512; -+ t_start = clock(); -+ dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, compressed, -+ XBZRLE_PAGE_SIZE); -+ t_end = clock(); -+ float time_val = difftime(t_end, t_start); -+ rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE); -+ g_assert(rc < XBZRLE_PAGE_SIZE); -+ -+ t_start512 = clock(); -+ dlen512 = xbzrle_encode_buffer_avx512(test512, buffer512, XBZRLE_PAGE_SIZE, -+ compressed512, XBZRLE_PAGE_SIZE); -+ t_end512 = clock(); -+ float time_val512 = difftime(t_end512, t_start512); -+ rc512 = xbzrle_decode_buffer(compressed512, dlen512, test512, XBZRLE_PAGE_SIZE); -+ g_assert(rc512 < XBZRLE_PAGE_SIZE); -+ -+ res->t_raw = time_val; -+ res->t_512 = time_val512; -+ -+ g_free(buffer); -+ g_free(compressed); -+ g_free(test); -+ g_free(buffer512); -+ g_free(compressed512); -+ g_free(test512); -+ -+} -+ -+static void test_encode_decode_random_avx512(void) -+{ -+ int i; -+ float time_raw = 0.0, time_512 = 0.0; -+ struct ResTime res; -+ for (i = 0; i < 10000; i++) { -+ encode_decode_random(&res); -+ time_raw += res.t_raw; -+ time_512 += res.t_512; -+ } -+ printf("Random test:\n"); -+ printf("Raw xbzrle_encode time is %f ms\n", time_raw); -+ printf("512 xbzrle_encode time is %f ms\n", time_512); -+} -+#endif -+ -+int main(int argc, char **argv) -+{ -+ g_test_init(&argc, &argv, NULL); -+ g_test_rand_int(); -+ #if defined(CONFIG_AVX512BW_OPT) -+ if (likely(is_cpu_support_avx512bw)) { -+ g_test_add_func("/xbzrle/encode_decode_zero", test_encode_decode_zero_avx512); -+ g_test_add_func("/xbzrle/encode_decode_unchanged", -+ test_encode_decode_unchanged_avx512); -+ g_test_add_func("/xbzrle/encode_decode_1_byte", test_encode_decode_1_byte_avx512); -+ g_test_add_func("/xbzrle/encode_decode_overflow", -+ test_encode_decode_overflow_avx512); -+ g_test_add_func("/xbzrle/encode_decode", test_encode_decode_avx512); -+ g_test_add_func("/xbzrle/encode_decode_random", test_encode_decode_random_avx512); -+ } -+ #endif -+ return g_test_run(); -+} -diff --git a/tests/unit/test-xbzrle.c b/tests/unit/test-xbzrle.c -index 795d6f1cba..baa364b443 100644 ---- a/tests/unit/test-xbzrle.c -+++ b/tests/unit/test-xbzrle.c -@@ -17,6 +17,35 @@ - - #define XBZRLE_PAGE_SIZE 4096 - -+int (*xbzrle_encode_buffer_func)(uint8_t *, uint8_t *, int, -+ uint8_t *, int) = xbzrle_encode_buffer; -+#if defined(CONFIG_AVX512BW_OPT) -+#include "qemu/cpuid.h" -+static void __attribute__((constructor)) init_cpu_flag(void) -+{ -+ unsigned max = __get_cpuid_max(0, NULL); -+ int a, b, c, d; -+ if (max >= 1) { -+ __cpuid(1, a, b, c, d); -+ /* We must check that AVX is not just available, but usable. */ -+ if ((c & bit_OSXSAVE) && (c & bit_AVX) && max >= 7) { -+ int bv; -+ __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0)); -+ __cpuid_count(7, 0, a, b, c, d); -+ /* 0xe6: -+ * XCR0[7:5] = 111b (OPMASK state, upper 256-bit of ZMM0-ZMM15 -+ * and ZMM16-ZMM31 state are enabled by OS) -+ * XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS) -+ */ -+ if ((bv & 0xe6) == 0xe6 && (b & bit_AVX512BW)) { -+ xbzrle_encode_buffer_func = xbzrle_encode_buffer_avx512; -+ } -+ } -+ } -+ return ; -+} -+#endif -+ - static void test_uleb(void) - { - uint32_t i, val; -@@ -55,7 +84,7 @@ static void test_encode_decode_zero(void) - buffer[1000 + diff_len + 5] = 105; - - /* encode zero page */ -- dlen = xbzrle_encode_buffer(buffer, buffer, XBZRLE_PAGE_SIZE, compressed, -+ dlen = xbzrle_encode_buffer_func(buffer, buffer, XBZRLE_PAGE_SIZE, compressed, - XBZRLE_PAGE_SIZE); - g_assert(dlen == 0); - -@@ -79,7 +108,7 @@ static void test_encode_decode_unchanged(void) - test[1000 + diff_len + 5] = 109; - - /* test unchanged buffer */ -- dlen = xbzrle_encode_buffer(test, test, XBZRLE_PAGE_SIZE, compressed, -+ dlen = xbzrle_encode_buffer_func(test, test, XBZRLE_PAGE_SIZE, compressed, - XBZRLE_PAGE_SIZE); - g_assert(dlen == 0); - -@@ -97,7 +126,7 @@ static void test_encode_decode_1_byte(void) - - test[XBZRLE_PAGE_SIZE - 1] = 1; - -- dlen = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed, -+ dlen = xbzrle_encode_buffer_func(buffer, test, XBZRLE_PAGE_SIZE, compressed, - XBZRLE_PAGE_SIZE); - g_assert(dlen == (uleb128_encode_small(&buf[0], 4095) + 2)); - -@@ -122,7 +151,7 @@ static void test_encode_decode_overflow(void) - } - - /* encode overflow */ -- rc = xbzrle_encode_buffer(buffer, test, XBZRLE_PAGE_SIZE, compressed, -+ rc = xbzrle_encode_buffer_func(buffer, test, XBZRLE_PAGE_SIZE, compressed, - XBZRLE_PAGE_SIZE); - g_assert(rc == -1); - -@@ -153,7 +182,7 @@ static void encode_decode_range(void) - test[1000 + diff_len + 5] = 109; - - /* test encode/decode */ -- dlen = xbzrle_encode_buffer(test, buffer, XBZRLE_PAGE_SIZE, compressed, -+ dlen = xbzrle_encode_buffer_func(test, buffer, XBZRLE_PAGE_SIZE, compressed, - XBZRLE_PAGE_SIZE); - - rc = xbzrle_decode_buffer(compressed, dlen, test, XBZRLE_PAGE_SIZE); --- -2.27.0 - diff --git a/Use-post-increment-only-in-inffast.c.patch b/Use-post-increment-only-in-inffast.c.patch deleted file mode 100644 index e5d16d054cf49281aea941f54758d69e981d7a8c..0000000000000000000000000000000000000000 --- a/Use-post-increment-only-in-inffast.c.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 97021cac0565f57d14a3e285399dd2208c66c358 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Sat, 12 Feb 2022 15:00:25 +0800 -Subject: [PATCH] Use post-increment only in inffast.c. - -Fix CVE-2016-9841 - -patch link: https://github.com/madler/zlib/commit/9aaec95 - -An old inffast.c optimization turns out to not be optimal anymore -with modern compilers, and furthermore was not compliant with the -C standard, for which decrementing a pointer before its allocated -memory is undefined. Per the recommendation of a security audit of -the zlib code by Trail of Bits and TrustInSoft, in support of the -Mozilla Foundation, this "optimization" was removed, in order to -avoid the possibility of undefined behavior. - -Signed-off-by: Yan Wang ---- - roms/u-boot/lib/zlib/inffast.c | 87 +++++++++++++++++------------------------- - 1 file changed, 34 insertions(+), 53 deletions(-) - -diff --git a/roms/u-boot/lib/zlib/inffast.c b/roms/u-boot/lib/zlib/inffast.c -index e3c7f3b..cdc778e 100644 ---- a/roms/u-boot/lib/zlib/inffast.c -+++ b/roms/u-boot/lib/zlib/inffast.c -@@ -12,25 +12,6 @@ - - #ifndef ASMINF - --/* Allow machine dependent optimization for post-increment or pre-increment. -- Based on testing to date, -- Pre-increment preferred for: -- - PowerPC G3 (Adler) -- - MIPS R5000 (Randers-Pehrson) -- Post-increment preferred for: -- - none -- No measurable difference: -- - Pentium III (Anderson) -- - M68060 (Nikl) -- */ --#ifdef POSTINC --# define OFF 0 --# define PUP(a) *(a)++ --#else --# define OFF 1 --# define PUP(a) *++(a) --#endif -- - /* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is -@@ -97,7 +78,7 @@ void inflate_fast(z_streamp strm, unsigned start) - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; -- in = strm->next_in - OFF; -+ in = strm->next_in; - last = in + (strm->avail_in - 5); - if (in > last && strm->avail_in > 5) { - /* -@@ -107,7 +88,7 @@ void inflate_fast(z_streamp strm, unsigned start) - strm->avail_in = 0xffffffff - (uintptr_t)in; - last = in + (strm->avail_in - 5); - } -- out = strm->next_out - OFF; -+ out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); - #ifdef INFLATE_STRICT -@@ -128,9 +109,9 @@ void inflate_fast(z_streamp strm, unsigned start) - input data or output space */ - do { - if (bits < 15) { -- hold += (unsigned long)(PUP(in)) << bits; -+ hold += (unsigned long)(*in++) << bits; - bits += 8; -- hold += (unsigned long)(PUP(in)) << bits; -+ hold += (unsigned long)(*in++) << bits; - bits += 8; - } - this = lcode[hold & lmask]; -@@ -143,14 +124,14 @@ void inflate_fast(z_streamp strm, unsigned start) - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); -- PUP(out) = (unsigned char)(this.val); -+ *out++ = (unsigned char)(this.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { -- hold += (unsigned long)(PUP(in)) << bits; -+ hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); -@@ -159,9 +140,9 @@ void inflate_fast(z_streamp strm, unsigned start) - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { -- hold += (unsigned long)(PUP(in)) << bits; -+ hold += (unsigned long)(*in++) << bits; - bits += 8; -- hold += (unsigned long)(PUP(in)) << bits; -+ hold += (unsigned long)(*in++) << bits; - bits += 8; - } - this = dcode[hold & dmask]; -@@ -174,10 +155,10 @@ void inflate_fast(z_streamp strm, unsigned start) - dist = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (bits < op) { -- hold += (unsigned long)(PUP(in)) << bits; -+ hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { -- hold += (unsigned long)(PUP(in)) << bits; -+ hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } -@@ -200,13 +181,13 @@ void inflate_fast(z_streamp strm, unsigned start) - state->mode = BAD; - break; - } -- from = window - OFF; -+ from = window; - if (write == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { -- PUP(out) = PUP(from); -+ *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } -@@ -217,14 +198,14 @@ void inflate_fast(z_streamp strm, unsigned start) - if (op < len) { /* some from end of window */ - len -= op; - do { -- PUP(out) = PUP(from); -+ *out++ = *from++; - } while (--op); -- from = window - OFF; -+ from = window; - if (write < len) { /* some from start of window */ - op = write; - len -= op; - do { -- PUP(out) = PUP(from); -+ *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } -@@ -235,21 +216,21 @@ void inflate_fast(z_streamp strm, unsigned start) - if (op < len) { /* some from window */ - len -= op; - do { -- PUP(out) = PUP(from); -+ *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { -- PUP(out) = PUP(from); -- PUP(out) = PUP(from); -- PUP(out) = PUP(from); -+ *out++ = *from++; -+ *out++ = *from++; -+ *out++ = *from++; - len -= 3; - } - if (len) { -- PUP(out) = PUP(from); -+ *out++ = *from++; - if (len > 1) -- PUP(out) = PUP(from); -+ *out++ = *from++; - } - } - else { -@@ -259,25 +240,25 @@ void inflate_fast(z_streamp strm, unsigned start) - from = out - dist; /* copy direct from output */ - /* minimum length is three */ - /* Align out addr */ -- if (!((long)(out - 1 + OFF) & 1)) { -- PUP(out) = PUP(from); -+ if (!((long)(out - 1) & 1)) { -+ *out++ = *from++; - len--; - } -- sout = (unsigned short *)(out - OFF); -+ sout = (unsigned short *)(out); - if (dist > 2 ) { - unsigned short *sfrom; - -- sfrom = (unsigned short *)(from - OFF); -+ sfrom = (unsigned short *)(from); - loops = len >> 1; - do -- PUP(sout) = get_unaligned(++sfrom); -+ *sout++ = get_unaligned(++sfrom); - while (--loops); -- out = (unsigned char *)sout + OFF; -- from = (unsigned char *)sfrom + OFF; -+ out = (unsigned char *)sout; -+ from = (unsigned char *)sfrom; - } else { /* dist == 1 or dist == 2 */ - unsigned short pat16; - -- pat16 = *(sout-2+2*OFF); -+ pat16 = *(sout-2); - if (dist == 1) - #if defined(__BIG_ENDIAN) - pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8); -@@ -288,12 +269,12 @@ void inflate_fast(z_streamp strm, unsigned start) - #endif - loops = len >> 1; - do -- PUP(sout) = pat16; -+ *sout++ = pat16; - while (--loops); -- out = (unsigned char *)sout + OFF; -+ out = (unsigned char *)sout; - } - if (len & 1) -- PUP(out) = PUP(from); -+ *out++ = *from++; - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ -@@ -329,8 +310,8 @@ void inflate_fast(z_streamp strm, unsigned start) - hold &= (1U << bits) - 1; - - /* update state and return */ -- strm->next_in = in + OFF; -- strm->next_out = out + OFF; -+ strm->next_in = in; -+ strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); --- -1.9.1 - diff --git a/accel-kvm-Add-pre-park-vCPU-support.patch b/accel-kvm-Add-pre-park-vCPU-support.patch deleted file mode 100644 index e3433842aefc7dd4faf0e827c8824f0898363652..0000000000000000000000000000000000000000 --- a/accel-kvm-Add-pre-park-vCPU-support.patch +++ /dev/null @@ -1,64 +0,0 @@ -From c950cda47386360e37a89dfa7029d83e33888a40 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 13:04:40 +0800 -Subject: [PATCH] accel/kvm: Add pre-park vCPU support - -For that KVM do not support dynamic adjustment of vCPU count, -we must pre-park all possible vCPU at start. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - accel/kvm/kvm-all.c | 23 +++++++++++++++++++++++ - include/sysemu/kvm.h | 1 + - 2 files changed, 24 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 8a98446b7c..f2ce5cd45a 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -433,6 +433,29 @@ void kvm_destroy_vcpu(CPUState *cpu) - } - } - -+int kvm_create_parked_vcpu(unsigned long vcpu_id) -+{ -+ KVMState *s = kvm_state; -+ struct KVMParkedVcpu *vcpu = NULL; -+ int ret; -+ -+ DPRINTF("kvm_create_parked_vcpu\n"); -+ -+ ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id); -+ if (ret < 0) { -+ DPRINTF("kvm_create_vcpu failed\n"); -+ goto err; -+ } -+ -+ vcpu = g_malloc0(sizeof(*vcpu)); -+ vcpu->vcpu_id = vcpu_id; -+ vcpu->kvm_fd = ret; -+ QLIST_INSERT_HEAD(&s->kvm_parked_vcpus, vcpu, node); -+ -+err: -+ return ret; -+} -+ - static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id) - { - struct KVMParkedVcpu *cpu; -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 7b22aeb6ae..2623775c27 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -221,6 +221,7 @@ int kvm_has_pit_state2(void); - int kvm_has_many_ioeventfds(void); - int kvm_has_gsi_routing(void); - int kvm_has_intx_set_mask(void); -+int kvm_create_parked_vcpu(unsigned long vcpu_id); - - /** - * kvm_arm_supports_user_irq --- -2.27.0 - diff --git a/accel-kvm-Free-as-when-an-error-occurred.patch b/accel-kvm-Free-as-when-an-error-occurred.patch deleted file mode 100644 index 64aa45f85e39c25132fcdea3c2ea047c9d368490..0000000000000000000000000000000000000000 --- a/accel-kvm-Free-as-when-an-error-occurred.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6ccda2ece6d08b1bf0622109c2a1f3eeca813089 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 28 Aug 2023 19:43:06 +0800 -Subject: [PATCH] accel/kvm: Free as when an error occurred - -cheery-pick from 4625742cd2aeb1400407889a2f7a5b4c75437818 - -An error may occur after s->as is allocated, for example if the -KVM_CREATE_VM ioctl call fails. - -Signed-off-by: Akihiko Odaki -Message-id: 20230727073134.134102-6-akihiko.odaki@daynix.com -Reviewed-by: Peter Maydell -[PMM: tweaked commit message] -Signed-off-by: Peter Maydell -Signed-off-by: qihao_yewu ---- - accel/kvm/kvm-all.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 799d993f6c..9c8d3a916e 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2589,6 +2589,7 @@ err: - if (s->fd != -1) { - close(s->fd); - } -+ g_free(s->as); - g_free(s->memory_listener.slots); - - return ret; --- -2.41.0.windows.1 - diff --git a/accel-kvm-Make-kvm_dirty_ring_reaper_init-void.patch b/accel-kvm-Make-kvm_dirty_ring_reaper_init-void.patch deleted file mode 100644 index d65b940990f8107458942c91d0ced7f6a312df0f..0000000000000000000000000000000000000000 --- a/accel-kvm-Make-kvm_dirty_ring_reaper_init-void.patch +++ /dev/null @@ -1,58 +0,0 @@ -From e11f4d10f843f46a8659d0134220f8712f15b451 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 28 Aug 2023 19:04:32 +0800 -Subject: [PATCH] accel/kvm: Make kvm_dirty_ring_reaper_init() void -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 43a5e377f42d1d3ed12ea562196f723b354ce411 - -The returned value was always zero and had no meaning. - -Signed-off-by: Akihiko Odaki -Message-id: 20230727073134.134102-7-akihiko.odaki@daynix.com -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: qihao_yewu ---- - accel/kvm/kvm-all.c | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 799d993f6c..83881e1d96 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -1436,15 +1436,13 @@ static void *kvm_dirty_ring_reaper_thread(void *data) - return NULL; - } - --static int kvm_dirty_ring_reaper_init(KVMState *s) -+static void kvm_dirty_ring_reaper_init(KVMState *s) - { - struct KVMDirtyRingReaper *r = &s->reaper; - - qemu_thread_create(&r->reaper_thr, "kvm-reaper", - kvm_dirty_ring_reaper_thread, - s, QEMU_THREAD_JOINABLE); -- -- return 0; - } - - static void kvm_region_add(MemoryListener *listener, -@@ -2573,10 +2571,7 @@ static int kvm_init(MachineState *ms) - } - - if (s->kvm_dirty_ring_size) { -- ret = kvm_dirty_ring_reaper_init(s); -- if (ret) { -- goto err; -- } -+ kvm_dirty_ring_reaper_init(s); - } - - return 0; --- -2.41.0.windows.1 - diff --git a/accel-kvm-kvm-all-Introduce-kvm_dirty_ring_size-func.patch b/accel-kvm-kvm-all-Introduce-kvm_dirty_ring_size-func.patch deleted file mode 100644 index 6e9274e1b505f296a1a8ee8ea23cffcb2dab352e..0000000000000000000000000000000000000000 --- a/accel-kvm-kvm-all-Introduce-kvm_dirty_ring_size-func.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 85583352f3bc28badd4cb336517f6a4eb440d5b0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Sun, 26 Jun 2022 01:38:34 +0800 -Subject: [PATCH 2/3] accel/kvm/kvm-all: Introduce kvm_dirty_ring_size function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce kvm_dirty_ring_size util function to help calculate -dirty ring ful time. - -Signed-off-by: Hyman Huang(黄勇) -Acked-by: Peter Xu -Message-Id: -Signed-off-by: Dr. David Alan Gilbert ---- - accel/kvm/kvm-all.c | 5 +++++ - accel/stubs/kvm-stub.c | 5 +++++ - include/sysemu/kvm.h | 2 ++ - 3 files changed, 12 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 3bc6eb6294..d0c4310507 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -2332,6 +2332,11 @@ bool kvm_dirty_ring_enabled(void) - return kvm_state->kvm_dirty_ring_size ? true : false; - } - -+uint32_t kvm_dirty_ring_size(void) -+{ -+ return kvm_state->kvm_dirty_ring_size; -+} -+ - static int kvm_init(MachineState *ms) - { - MachineClass *mc = MACHINE_GET_CLASS(ms); -diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c -index 5319573e00..1128cb2928 100644 ---- a/accel/stubs/kvm-stub.c -+++ b/accel/stubs/kvm-stub.c -@@ -152,4 +152,9 @@ bool kvm_dirty_ring_enabled(void) - { - return false; - } -+ -+uint32_t kvm_dirty_ring_size(void) -+{ -+ return 0; -+} - #endif -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 2623775c27..19c5c8402a 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -549,4 +549,6 @@ bool kvm_cpu_check_are_resettable(void); - bool kvm_arch_cpu_check_are_resettable(void); - - bool kvm_dirty_ring_enabled(void); -+ -+uint32_t kvm_dirty_ring_size(void); - #endif --- -2.27.0 - diff --git a/accel-kvm-kvm-all-Refactor-per-vcpu-dirty-ring-reapi.patch b/accel-kvm-kvm-all-Refactor-per-vcpu-dirty-ring-reapi.patch deleted file mode 100644 index bec0b4ae7caed2091b9e86430974b892475a0dbe..0000000000000000000000000000000000000000 --- a/accel-kvm-kvm-all-Refactor-per-vcpu-dirty-ring-reapi.patch +++ /dev/null @@ -1,106 +0,0 @@ -From c6f781e50e75fc2e6b819291b6c5ce6c212f018b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Sun, 26 Jun 2022 01:38:30 +0800 -Subject: [PATCH 1/3] accel/kvm/kvm-all: Refactor per-vcpu dirty ring reaping -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a non-required argument 'CPUState' to kvm_dirty_ring_reap so -that it can cover single vcpu dirty-ring-reaping scenario. - -Signed-off-by: Hyman Huang(黄勇) -Reviewed-by: Peter Xu -Message-Id: -Signed-off-by: Dr. David Alan Gilbert ---- - accel/kvm/kvm-all.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index f2ce5cd45a..3bc6eb6294 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -773,17 +773,20 @@ static uint32_t kvm_dirty_ring_reap_one(KVMState *s, CPUState *cpu) - } - - /* Must be with slots_lock held */ --static uint64_t kvm_dirty_ring_reap_locked(KVMState *s) -+static uint64_t kvm_dirty_ring_reap_locked(KVMState *s, CPUState* cpu) - { - int ret; -- CPUState *cpu; - uint64_t total = 0; - int64_t stamp; - - stamp = get_clock(); - -- CPU_FOREACH(cpu) { -- total += kvm_dirty_ring_reap_one(s, cpu); -+ if (cpu) { -+ total = kvm_dirty_ring_reap_one(s, cpu); -+ } else { -+ CPU_FOREACH(cpu) { -+ total += kvm_dirty_ring_reap_one(s, cpu); -+ } - } - - if (total) { -@@ -804,7 +807,7 @@ static uint64_t kvm_dirty_ring_reap_locked(KVMState *s) - * Currently for simplicity, we must hold BQL before calling this. We can - * consider to drop the BQL if we're clear with all the race conditions. - */ --static uint64_t kvm_dirty_ring_reap(KVMState *s) -+static uint64_t kvm_dirty_ring_reap(KVMState *s, CPUState *cpu) - { - uint64_t total; - -@@ -824,7 +827,7 @@ static uint64_t kvm_dirty_ring_reap(KVMState *s) - * reset below. - */ - kvm_slots_lock(); -- total = kvm_dirty_ring_reap_locked(s); -+ total = kvm_dirty_ring_reap_locked(s, cpu); - kvm_slots_unlock(); - - return total; -@@ -871,7 +874,7 @@ static void kvm_dirty_ring_flush(void) - * vcpus out in a synchronous way. - */ - kvm_cpu_synchronize_kick_all(); -- kvm_dirty_ring_reap(kvm_state); -+ kvm_dirty_ring_reap(kvm_state, NULL); - trace_kvm_dirty_ring_flush(1); - } - -@@ -1415,7 +1418,7 @@ static void kvm_set_phys_mem(KVMMemoryListener *kml, - * Not easy. Let's cross the fingers until it's fixed. - */ - if (kvm_state->kvm_dirty_ring_size) { -- kvm_dirty_ring_reap_locked(kvm_state); -+ kvm_dirty_ring_reap_locked(kvm_state, NULL); - } else { - kvm_slot_get_dirty_log(kvm_state, mem); - } -@@ -1487,7 +1490,7 @@ static void *kvm_dirty_ring_reaper_thread(void *data) - r->reaper_state = KVM_DIRTY_RING_REAPER_REAPING; - - qemu_mutex_lock_iothread(); -- kvm_dirty_ring_reap(s); -+ kvm_dirty_ring_reap(s, NULL); - qemu_mutex_unlock_iothread(); - - r->reaper_iteration++; -@@ -2957,7 +2960,7 @@ int kvm_cpu_exec(CPUState *cpu) - */ - trace_kvm_dirty_ring_full(cpu->cpu_index); - qemu_mutex_lock_iothread(); -- kvm_dirty_ring_reap(kvm_state); -+ kvm_dirty_ring_reap(kvm_state, NULL); - qemu_mutex_unlock_iothread(); - ret = 0; - break; --- -2.27.0 - diff --git a/accel-tcg-Optimize-jump-cache-flush-during-tlb-range.patch b/accel-tcg-Optimize-jump-cache-flush-during-tlb-range.patch deleted file mode 100644 index 403e3bb6221e1331bc769b8a6cfbccc48c5fb773..0000000000000000000000000000000000000000 --- a/accel-tcg-Optimize-jump-cache-flush-during-tlb-range.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 28ca488c585c556ce04419f927d13d46771e1ea4 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 18 Jul 2023 06:29:51 +0000 -Subject: [PATCH] accel/tcg: Optimize jump cache flush during tlb range flush - mainline inclusion commit cfc2a2d69d59f02b32df3098ce17e10ab86d43c6 category: - bugfix - ---------------------------------------------------------------- - -When the length of the range is large enough, clearing the whole cache is -faster than iterating over the (possibly extremely large) set of pages -contained in the range. - -This mimics the pre-existing similar optimization done on the flush of the -tlb itself. - -Signed-off-by: Idan Horowitz -Message-Id: <20220110164754.1066025-1-idan.horowitz@gmail.com> -Reviewed-by: Richard Henderson -Signed-off-by: Richard Henderson - -Signed-off-by: tangbinzy ---- - accel/tcg/cputlb.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c -index b69a953447..03526fa1ab 100644 ---- a/accel/tcg/cputlb.c -+++ b/accel/tcg/cputlb.c -@@ -783,6 +783,15 @@ static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu, - } - qemu_spin_unlock(&env_tlb(env)->c.lock); - -+ /* -+ * If the length is larger than the jump cache size, then it will take -+ * longer to clear each entry individually than it will to clear it all. -+ */ -+ if (d.len >= (TARGET_PAGE_SIZE * TB_JMP_CACHE_SIZE)) { -+ cpu_tb_jmp_cache_clear(cpu); -+ return; -+ } -+ - for (target_ulong i = 0; i < d.len; i += TARGET_PAGE_SIZE) { - tb_flush_jmp_cache(cpu, d.addr + i); - } --- -2.41.0.windows.1 - diff --git a/accel-tcg-cpu-exec-Fix-precise-single-stepping-after.patch b/accel-tcg-cpu-exec-Fix-precise-single-stepping-after.patch deleted file mode 100644 index cd77f90f5700c110aa8c3478320750c01770b585..0000000000000000000000000000000000000000 --- a/accel-tcg-cpu-exec-Fix-precise-single-stepping-after.patch +++ /dev/null @@ -1,48 +0,0 @@ -From ddca9c0cba8e3c858b7998c67ae2739f58b5b681 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 21 Jul 2023 06:41:38 +0000 -Subject: [PATCH] accel/tcg/cpu-exec: Fix precise single-stepping after - interrupt mainline inclusion commit 5b7b197c87cefbd24bd1936614fd4e00ccc279ab - category: bugfix - ---------------------------------------------------------------- - -In some cases, cpu->exit_request can be false after handling the -interrupt, leading to another TB being executed instead of returning -to the main loop. - -Fix this by returning true unconditionally when in single-step mode. - -Fixes: ba3c35d9c402 ("tcg/cpu-exec: precise single-stepping after an interrupt") -Signed-off-by: Luc Michel -Message-Id: <20220214132656.11397-1-lmichel@kalray.eu> -[rth: Unlock iothread mutex; simplify indentation] -Signed-off-by: Richard Henderson - -Signed-off-by: tangbinzy ---- - accel/tcg/cpu-exec.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c -index 409ec8c38c..7fb87afedc 100644 ---- a/accel/tcg/cpu-exec.c -+++ b/accel/tcg/cpu-exec.c -@@ -798,8 +798,12 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, - * raised when single-stepping so that GDB doesn't miss the - * next instruction. - */ -- cpu->exception_index = -- (cpu->singlestep_enabled ? EXCP_DEBUG : -1); -+ if (unlikely(cpu->singlestep_enabled)) { -+ cpu->exception_index = EXCP_DEBUG; -+ qemu_mutex_unlock_iothread(); -+ return true; -+ } -+ cpu->exception_index = -1; - *last_tb = NULL; - } - /* The target hook may have updated the 'cpu->interrupt_request'; --- -2.41.0.windows.1 - diff --git a/acpi-cpu-Prepare-build_cpus_aml-for-arm-virt.patch b/acpi-cpu-Prepare-build_cpus_aml-for-arm-virt.patch deleted file mode 100644 index 49477add34fd88544d959e8e973d97fa348a022c..0000000000000000000000000000000000000000 --- a/acpi-cpu-Prepare-build_cpus_aml-for-arm-virt.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 1ab75151c0a486ebdbe50d29c9677c7bc1f05929 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Wed, 22 Apr 2020 16:11:13 +0800 -Subject: [PATCH] acpi/cpu: Prepare build_cpus_aml for arm virt - -We will reuse build_cpus_aml to build DSDT cpus aml in arm/virt -ACPI to realize cpu hotplug. Three points are added. - -1. Make ACPI IO address space configurable, because ARM64 platforms - don't use port IO for ACPI IO space. -2. Add GICC struct building support in _MAT of cpu aml. -3. Let the hotplug method parameter can be NULL, because ACPI GED - will realize it. - -Besides, CPU CPPC building is injected. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/acpi/cpu.c | 27 ++++++++++++++++++++------- - hw/i386/acpi-build.c | 2 +- - include/hw/acpi/cpu.h | 3 ++- - 3 files changed, 23 insertions(+), 9 deletions(-) - -diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c -index b20903ea30..a9c2ee952a 100644 ---- a/hw/acpi/cpu.c -+++ b/hw/acpi/cpu.c -@@ -343,7 +343,8 @@ const VMStateDescription vmstate_cpu_hotplug = { - void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, - hwaddr io_base, - const char *res_root, -- const char *event_handler_method) -+ const char *event_handler_method, -+ AmlRegionSpace rs) - { - Aml *ifctx; - Aml *field; -@@ -371,13 +372,18 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, - aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0)); - - crs = aml_resource_template(); -- aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1, -- ACPI_CPU_HOTPLUG_REG_LEN)); -+ if (rs == AML_SYSTEM_IO) { -+ aml_append(crs, aml_io(AML_DECODE16, io_base, io_base, 1, -+ ACPI_CPU_HOTPLUG_REG_LEN)); -+ } else { -+ aml_append(crs, aml_memory32_fixed(io_base, -+ ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE)); -+ } - aml_append(cpu_ctrl_dev, aml_name_decl("_CRS", crs)); - - /* declare CPU hotplug MMIO region with related access fields */ - aml_append(cpu_ctrl_dev, -- aml_operation_region("PRST", AML_SYSTEM_IO, aml_int(io_base), -+ aml_operation_region("PRST", rs, aml_int(io_base), - ACPI_CPU_HOTPLUG_REG_LEN)); - - field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, -@@ -663,6 +669,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, - aml_append(dev, aml_name_decl("_UID", uid)); - } - -+ assert(adevc); -+ if (adevc->cpu_cppc) { -+ adevc->cpu_cppc(adev, i, arch_ids->len, dev); -+ } -+ - method = aml_method("_STA", 0, AML_SERIALIZED); - aml_append(method, aml_return(aml_call1(CPU_STS_METHOD, uid))); - aml_append(dev, method); -@@ -703,9 +714,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, - aml_append(sb_scope, cpus_dev); - aml_append(table, sb_scope); - -- method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED); -- aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD)); -- aml_append(table, method); -+ if (event_handler_method) { -+ method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED); -+ aml_append(method, aml_call0("\\_SB.CPUS." CPU_SCAN_METHOD)); -+ aml_append(table, method); -+ } - - g_free(cphp_res_path); - } -diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c -index a99c6e4fe3..1ce2d67c2e 100644 ---- a/hw/i386/acpi-build.c -+++ b/hw/i386/acpi-build.c -@@ -1513,7 +1513,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, - .fw_unplugs_cpu = pm->smi_on_cpu_unplug, - }; - build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base, -- "\\_SB.PCI0", "\\_GPE._E02"); -+ "\\_SB.PCI0", "\\_GPE._E02", AML_SYSTEM_IO); - } - - if (pcms->memhp_io_base && nr_mem) { -diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h -index 999caaf510..a0fdc44bdd 100644 ---- a/include/hw/acpi/cpu.h -+++ b/include/hw/acpi/cpu.h -@@ -58,7 +58,8 @@ typedef struct CPUHotplugFeatures { - void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, - hwaddr io_base, - const char *res_root, -- const char *event_handler_method); -+ const char *event_handler_method, -+ AmlRegionSpace rs); - - void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list); - --- -2.27.0 - diff --git a/acpi-fix-QEMU-crash-when-started-with-SLIC-table.patch b/acpi-fix-QEMU-crash-when-started-with-SLIC-table.patch deleted file mode 100644 index 8532cce569d605f136aa1becfa4b638fe293bf1c..0000000000000000000000000000000000000000 --- a/acpi-fix-QEMU-crash-when-started-with-SLIC-table.patch +++ /dev/null @@ -1,90 +0,0 @@ -From ad7b272f693e2fbf4a74c47f566b6c3f8c27247c Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 27 Dec 2021 14:31:17 -0500 -Subject: [PATCH 1/6] acpi: fix QEMU crash when started with SLIC table -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -if QEMU is started with used provided SLIC table blob, - - -acpitable sig=SLIC,oem_id='CRASH ',oem_table_id="ME",oem_rev=00002210,asl_compiler_id="",asl_compiler_rev=00000000,data=/dev/null -it will assert with: - - hw/acpi/aml-build.c:61:build_append_padded_str: assertion failed: (len <= maxlen) - -and following backtrace: - - ... - build_append_padded_str (array=0x555556afe320, str=0x555556afdb2e "CRASH ME", maxlen=0x6, pad=0x20) at hw/acpi/aml-build.c:61 - acpi_table_begin (desc=0x7fffffffd1b0, array=0x555556afe320) at hw/acpi/aml-build.c:1727 - build_fadt (tbl=0x555556afe320, linker=0x555557ca3830, f=0x7fffffffd318, oem_id=0x555556afdb2e "CRASH ME", oem_table_id=0x555556afdb34 "ME") at hw/acpi/aml-build.c:2064 - ... - -which happens due to acpi_table_begin() expecting NULL terminated -oem_id and oem_table_id strings, which is normally the case, but -in case of user provided SLIC table, oem_id points to table's blob -directly and as result oem_id became longer than expected. - -Fix issue by handling oem_id consistently and make acpi_get_slic_oem() -return NULL terminated strings. - -PS: -After [1] refactoring, oem_id semantics became inconsistent, where -NULL terminated string was coming from machine and old way pointer -into byte array coming from -acpitable option. That used to work -since build_header() wasn't expecting NULL terminated string and -blindly copied the 1st 6 bytes only. - -However commit [2] broke that by replacing build_header() with -acpi_table_begin(), which was expecting NULL terminated string -and was checking oem_id size. - -1) 602b45820 ("acpi: Permit OEM ID and OEM table ID fields to be changed") -2) -Fixes: 4b56e1e4eb08 ("acpi: build_fadt: use acpi_table_begin()/acpi_table_end() instead of build_header()") -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/786 -Signed-off-by: Igor Mammedov -Message-Id: <20211227193120.1084176-2-imammedo@redhat.com> -Reviewed-by: Philippe Mathieu-Daudé -Tested-by: Denis Lisov -Tested-by: Alexander Tsoy -Cc: qemu-stable@nongnu.org -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - hw/acpi/core.c | 4 ++-- - hw/i386/acpi-build.c | 2 ++ - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/hw/acpi/core.c b/hw/acpi/core.c -index eb631caa91..a2d790d432 100644 ---- a/hw/acpi/core.c -+++ b/hw/acpi/core.c -@@ -346,8 +346,8 @@ int acpi_get_slic_oem(AcpiSlicOem *oem) - struct acpi_table_header *hdr = (void *)(u - sizeof(hdr->_length)); - - if (memcmp(hdr->sig, "SLIC", 4) == 0) { -- oem->id = hdr->oem_id; -- oem->table_id = hdr->oem_table_id; -+ oem->id = g_strndup(hdr->oem_id, 6); -+ oem->table_id = g_strndup(hdr->oem_table_id, 8); - return 0; - } - } -diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c -index 1ce2d67c2e..0ec2932ec2 100644 ---- a/hw/i386/acpi-build.c -+++ b/hw/i386/acpi-build.c -@@ -2721,6 +2721,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) - - /* Cleanup memory that's no longer used. */ - g_array_free(table_offsets, true); -+ g_free(slic_oem.id); -+ g_free(slic_oem.table_id); - } - - static void acpi_ram_update(MemoryRegion *mr, GArray *data) --- -2.27.0 - diff --git a/acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch b/acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch deleted file mode 100644 index 12a279ea615113b4d249e5bf8524f961778fb3b3..0000000000000000000000000000000000000000 --- a/acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 603cbcc5efdd35f518a5bd0a5067d40c2c4eb8d6 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 3 Apr 2020 15:41:01 +0800 -Subject: [PATCH] acpi/ged: Extend ACPI GED to support CPU hotplug - -This adds a new GED event called ACPI_GED_CPU_HOTPLUG_EVT. -The basic workflow is that: GED sends this event to guest, -then ACPI driver in guest will call _EVT method of GED aml, -then _EVT will call CSCN method in cpus aml to get status of -all cpus. - -The status of cpus is maintained by CPUHotplugState in GED and -is made accessable to guest through memory region. - -This also adds migration support to CPUHotplugState. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++- - hw/acpi/cpu.c | 1 - - hw/acpi/generic_event_device.c | 35 ++++++++++++++++++++++++++ - hw/arm/Kconfig | 1 + - include/hw/acpi/cpu.h | 2 ++ - include/hw/acpi/generic_event_device.h | 4 +++ - 6 files changed, 44 insertions(+), 2 deletions(-) - -diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst -index 0bd3f9399f..3acd6fcd8b 100644 ---- a/docs/specs/acpi_hw_reduced_hotplug.rst -+++ b/docs/specs/acpi_hw_reduced_hotplug.rst -@@ -64,7 +64,8 @@ GED IO interface (4 byte access) - 0: Memory hotplug event - 1: System power down event - 2: NVDIMM hotplug event -- 3-31: Reserved -+ 3: CPU hotplug event -+ 4-31: Reserved - - **write_access:** - -diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c -index a9c2ee952a..f9ce0a7f41 100644 ---- a/hw/acpi/cpu.c -+++ b/hw/acpi/cpu.c -@@ -6,7 +6,6 @@ - #include "trace.h" - #include "sysemu/numa.h" - --#define ACPI_CPU_HOTPLUG_REG_LEN 12 - #define ACPI_CPU_SELECTOR_OFFSET_WR 0 - #define ACPI_CPU_FLAGS_OFFSET_RW 4 - #define ACPI_CPU_CMD_OFFSET_WR 5 -diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c -index e28457a7d1..042a8ef8a5 100644 ---- a/hw/acpi/generic_event_device.c -+++ b/hw/acpi/generic_event_device.c -@@ -25,6 +25,7 @@ static const uint32_t ged_supported_events[] = { - ACPI_GED_MEM_HOTPLUG_EVT, - ACPI_GED_PWR_DOWN_EVT, - ACPI_GED_NVDIMM_HOTPLUG_EVT, -+ ACPI_GED_CPU_HOTPLUG_EVT, - }; - - /* -@@ -117,6 +118,9 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev, - aml_notify(aml_name("\\_SB.NVDR"), - aml_int(0x80))); - break; -+ case ACPI_GED_CPU_HOTPLUG_EVT: -+ aml_append(if_ctx, aml_call0("\\_SB.CPUS.CSCN")); -+ break; - default: - /* - * Please make sure all the events in ged_supported_events[] -@@ -234,6 +238,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev, - } else { - acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp); - } -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp); - } else { - error_setg(errp, "virt: device plug request for unsupported device" - " type: %s", object_get_typename(OBJECT(dev))); -@@ -279,6 +285,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) - sel = ACPI_GED_PWR_DOWN_EVT; - } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) { - sel = ACPI_GED_NVDIMM_HOTPLUG_EVT; -+ } else if (ev & ACPI_CPU_HOTPLUG_STATUS) { -+ sel = ACPI_GED_CPU_HOTPLUG_EVT; - } else { - /* Unknown event. Return without generating interrupt. */ - warn_report("GED: Unsupported event %d. No irq injected", ev); -@@ -311,6 +319,16 @@ static const VMStateDescription vmstate_memhp_state = { - } - }; - -+static const VMStateDescription vmstate_cpuhp_state = { -+ .name = "acpi-ged/cpuhp", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField[]) { -+ VMSTATE_CPU_HOTPLUG(cpuhp_state, AcpiGedState), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ - static const VMStateDescription vmstate_ged_state = { - .name = "acpi-ged-state", - .version_id = 1, -@@ -360,6 +378,7 @@ static const VMStateDescription vmstate_acpi_ged = { - .subsections = (const VMStateDescription * []) { - &vmstate_memhp_state, - &vmstate_ghes_state, -+ &vmstate_cpuhp_state, - NULL - } - }; -@@ -370,6 +389,7 @@ static void acpi_ged_initfn(Object *obj) - AcpiGedState *s = ACPI_GED(dev); - SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - GEDState *ged_st = &s->ged_state; -+ MachineClass *mc; - - memory_region_init_io(&ged_st->evt, obj, &ged_evt_ops, ged_st, - TYPE_ACPI_GED, ACPI_GED_EVT_SEL_LEN); -@@ -393,6 +413,21 @@ static void acpi_ged_initfn(Object *obj) - memory_region_init_io(&ged_st->regs, obj, &ged_regs_ops, ged_st, - TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT); - sysbus_init_mmio(sbd, &ged_st->regs); -+ -+ mc = MACHINE_GET_CLASS(qdev_get_machine()); -+ if (!mc->possible_cpu_arch_ids) { -+ /* -+ * MachineClass should support possible_cpu_arch_ids in -+ * cpu_hotplug_hw_init below. -+ */ -+ return; -+ } -+ -+ memory_region_init(&s->container_cpuhp, OBJECT(dev), "cpuhp container", -+ ACPI_CPU_HOTPLUG_REG_LEN); -+ sysbus_init_mmio(sbd, &s->container_cpuhp); -+ cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev), -+ &s->cpuhp_state, 0); - } - - static void acpi_ged_class_init(ObjectClass *class, void *data) -diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig -index 2d37d29f02..006a4b4c4b 100644 ---- a/hw/arm/Kconfig -+++ b/hw/arm/Kconfig -@@ -27,6 +27,7 @@ config ARM_VIRT - select DIMM - select ACPI_HW_REDUCED - select ACPI_APEI -+ select ACPI_CPU_HOTPLUG - - config CHEETAH - bool -diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h -index a0fdc44bdd..d521025830 100644 ---- a/include/hw/acpi/cpu.h -+++ b/include/hw/acpi/cpu.h -@@ -17,6 +17,8 @@ - #include "hw/acpi/aml-build.h" - #include "hw/hotplug.h" - -+#define ACPI_CPU_HOTPLUG_REG_LEN 12 -+ - typedef struct AcpiCpuStatus { - struct CPUState *cpu; - uint64_t arch_id; -diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h -index d49217c445..6bb2ade385 100644 ---- a/include/hw/acpi/generic_event_device.h -+++ b/include/hw/acpi/generic_event_device.h -@@ -63,6 +63,7 @@ - #include "hw/acpi/memory_hotplug.h" - #include "hw/acpi/ghes.h" - #include "qom/object.h" -+#include "hw/acpi/cpu.h" - - #define ACPI_POWER_BUTTON_DEVICE "PWRB" - -@@ -97,6 +98,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) - #define ACPI_GED_MEM_HOTPLUG_EVT 0x1 - #define ACPI_GED_PWR_DOWN_EVT 0x2 - #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4 -+#define ACPI_GED_CPU_HOTPLUG_EVT 0x8 - - typedef struct GEDState { - MemoryRegion evt; -@@ -108,6 +110,8 @@ struct AcpiGedState { - SysBusDevice parent_obj; - MemHotplugState memhp_state; - MemoryRegion container_memhp; -+ CPUHotplugState cpuhp_state; -+ MemoryRegion container_cpuhp; - GEDState ged_state; - uint32_t ged_event_bitmap; - qemu_irq irq; --- -2.27.0 - diff --git a/acpi-madt-Add-pre-sizing-capability-to-MADT-GICC-str.patch b/acpi-madt-Add-pre-sizing-capability-to-MADT-GICC-str.patch deleted file mode 100644 index 47d18ea6aa6fff4b8e8fce353f5fa0c3405b8291..0000000000000000000000000000000000000000 --- a/acpi-madt-Add-pre-sizing-capability-to-MADT-GICC-str.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 8bd05cdb811e868c54ef28ac558c7efb7cf610b9 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 13:40:44 +0800 -Subject: [PATCH] acpi/madt: Add pre-sizing capability to MADT GICC struct - -The count of possible CPUs is exposed to guest through the count -of MADT GICC struct, so we should pre-sizing MADT GICC too. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt-acpi-build.c | 25 +++++++++++++++++++------ - 1 file changed, 19 insertions(+), 6 deletions(-) - -diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c -index 7cb320d9f2..a16b54086e 100644 ---- a/hw/arm/virt-acpi-build.c -+++ b/hw/arm/virt-acpi-build.c -@@ -787,8 +787,16 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i, - ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i)); - uint64_t physical_base_address = 0, gich = 0, gicv = 0; - uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0; -- uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ? -- PPI(VIRTUAL_PMU_IRQ) : 0; -+ uint32_t pmu_interrupt, enabled; -+ static bool pmu; -+ -+ if (i == 0) { -+ pmu = arm_feature(&armcpu->env, ARM_FEATURE_PMU); -+ } -+ /* FEATURE_PMU should be all enabled or disabled for CPUs */ -+ assert(!armcpu || arm_feature(&armcpu->env, ARM_FEATURE_PMU) == pmu); -+ pmu_interrupt = pmu ? PPI(VIRTUAL_PMU_IRQ) : 0; -+ enabled = armcpu || force_enabled ? 1 /* Enabled */ : 0 /* Disabled */; - - if (vms->gic_version == 2) { - physical_base_address = memmap[VIRT_GIC_CPU].base; -@@ -803,7 +811,7 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i, - build_append_int_noprefix(table_data, i, 4); /* GIC ID */ - build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ - /* Flags */ -- build_append_int_noprefix(table_data, 1, 4); /* Enabled */ -+ build_append_int_noprefix(table_data, enabled, 4); /* Enabled */ - /* Parking Protocol Version */ - build_append_int_noprefix(table_data, 0, 4); - /* Performance Interrupt GSIV */ -@@ -817,7 +825,7 @@ void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i, - build_append_int_noprefix(table_data, vgic_interrupt, 4); - build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/ - /* MPIDR */ -- build_append_int_noprefix(table_data, armcpu->mp_affinity, 8); -+ build_append_int_noprefix(table_data, possible_cpus->cpus[i].arch_id, 8); - } - - static void -@@ -825,9 +833,14 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - { - int i; - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); -+ MachineClass *mc = MACHINE_GET_CLASS(vms); -+ MachineState *ms = MACHINE(vms); -+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); - const MemMapEntry *memmap = vms->memmap; - AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = vms->oem_id, - .oem_table_id = vms->oem_table_id }; -+ /* The MADT GICC numbers */ -+ int num_cpu = ms->smp.cpus; - - acpi_table_begin(&table, table_data); - /* Local Interrupt Controller Address */ -@@ -846,8 +859,8 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - build_append_int_noprefix(table_data, vms->gic_version, 1); - build_append_int_noprefix(table_data, 0, 3); /* Reserved */ - -- for (i = 0; i < MACHINE(vms)->smp.cpus; i++) { -- virt_madt_cpu_entry(NULL, i, NULL, table_data, false); -+ for (i = 0; i < num_cpu; i++) { -+ virt_madt_cpu_entry(NULL, i, possible_cpus, table_data, false); - } - - if (vms->gic_version == 3) { --- -2.27.0 - diff --git a/acpi-madt-Factor-out-the-building-of-MADT-GICC-struc.patch b/acpi-madt-Factor-out-the-building-of-MADT-GICC-struc.patch deleted file mode 100644 index d322c8d1098dedcfcdc328c8e5e9c5b2bf035010..0000000000000000000000000000000000000000 --- a/acpi-madt-Factor-out-the-building-of-MADT-GICC-struc.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 4f50ed900713acc14c971c07165fa83670d3f2b8 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Mon, 13 Jan 2020 19:02:20 +0800 -Subject: [PATCH] acpi/madt: Factor out the building of MADT GICC struct - -To realize CPU hotplug, the cpus aml within ACPI DSDT should contain -_MAT mathod, which is equal to the GICC struct in ACPI MADT. Factor -out the GICC building code from ACPI MADT and reuse it in build_cpus_aml. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt-acpi-build.c | 77 ++++++++++++++++++++++------------------ - include/hw/arm/virt.h | 4 +++ - 2 files changed, 47 insertions(+), 34 deletions(-) - -diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c -index 1ca705654b..64b1ed8672 100644 ---- a/hw/arm/virt-acpi-build.c -+++ b/hw/arm/virt-acpi-build.c -@@ -771,6 +771,48 @@ static void build_append_gicr(GArray *table_data, uint64_t base, uint32_t size) - build_append_int_noprefix(table_data, size, 4); /* Discovery Range Length */ - } - -+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int i, -+ const CPUArchIdList *possible_cpus, GArray *table_data, -+ bool force_enabled) -+{ -+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine()); -+ const MemMapEntry *memmap = vms->memmap; -+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i)); -+ uint64_t physical_base_address = 0, gich = 0, gicv = 0; -+ uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0; -+ uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ? -+ PPI(VIRTUAL_PMU_IRQ) : 0; -+ -+ if (vms->gic_version == 2) { -+ physical_base_address = memmap[VIRT_GIC_CPU].base; -+ gicv = memmap[VIRT_GIC_VCPU].base; -+ gich = memmap[VIRT_GIC_HYP].base; -+ } -+ -+ /* 5.2.12.14 GIC Structure */ -+ build_append_int_noprefix(table_data, 0xB, 1); /* Type */ -+ build_append_int_noprefix(table_data, 76, 1); /* Length */ -+ build_append_int_noprefix(table_data, 0, 2); /* Reserved */ -+ build_append_int_noprefix(table_data, i, 4); /* GIC ID */ -+ build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ -+ /* Flags */ -+ build_append_int_noprefix(table_data, 1, 4); /* Enabled */ -+ /* Parking Protocol Version */ -+ build_append_int_noprefix(table_data, 0, 4); -+ /* Performance Interrupt GSIV */ -+ build_append_int_noprefix(table_data, pmu_interrupt, 4); -+ build_append_int_noprefix(table_data, 0, 8); /* Parked Address */ -+ /* Physical Base Address */ -+ build_append_int_noprefix(table_data, physical_base_address, 8); -+ build_append_int_noprefix(table_data, gicv, 8); /* GICV */ -+ build_append_int_noprefix(table_data, gich, 8); /* GICH */ -+ /* VGIC Maintenance interrupt */ -+ build_append_int_noprefix(table_data, vgic_interrupt, 4); -+ build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/ -+ /* MPIDR */ -+ build_append_int_noprefix(table_data, armcpu->mp_affinity, 8); -+} -+ - static void - build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - { -@@ -798,40 +840,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - build_append_int_noprefix(table_data, 0, 3); /* Reserved */ - - for (i = 0; i < MACHINE(vms)->smp.cpus; i++) { -- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i)); -- uint64_t physical_base_address = 0, gich = 0, gicv = 0; -- uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0; -- uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ? -- PPI(VIRTUAL_PMU_IRQ) : 0; -- -- if (vms->gic_version == 2) { -- physical_base_address = memmap[VIRT_GIC_CPU].base; -- gicv = memmap[VIRT_GIC_VCPU].base; -- gich = memmap[VIRT_GIC_HYP].base; -- } -- -- /* 5.2.12.14 GIC Structure */ -- build_append_int_noprefix(table_data, 0xB, 1); /* Type */ -- build_append_int_noprefix(table_data, 76, 1); /* Length */ -- build_append_int_noprefix(table_data, 0, 2); /* Reserved */ -- build_append_int_noprefix(table_data, i, 4); /* GIC ID */ -- build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ -- /* Flags */ -- build_append_int_noprefix(table_data, 1, 4); /* Enabled */ -- /* Parking Protocol Version */ -- build_append_int_noprefix(table_data, 0, 4); -- /* Performance Interrupt GSIV */ -- build_append_int_noprefix(table_data, pmu_interrupt, 4); -- build_append_int_noprefix(table_data, 0, 8); /* Parked Address */ -- /* Physical Base Address */ -- build_append_int_noprefix(table_data, physical_base_address, 8); -- build_append_int_noprefix(table_data, gicv, 8); /* GICV */ -- build_append_int_noprefix(table_data, gich, 8); /* GICH */ -- /* VGIC Maintenance interrupt */ -- build_append_int_noprefix(table_data, vgic_interrupt, 4); -- build_append_int_noprefix(table_data, 0, 8); /* GICR Base Address*/ -- /* MPIDR */ -- build_append_int_noprefix(table_data, armcpu->mp_affinity, 8); -+ virt_madt_cpu_entry(NULL, i, NULL, table_data, false); - } - - if (vms->gic_version == 3) { -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index a4356cf736..36639e8d3e 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -38,6 +38,7 @@ - #include "sysemu/kvm.h" - #include "hw/intc/arm_gicv3_common.h" - #include "qom/object.h" -+#include "hw/acpi/acpi_dev_interface.h" - - #define NUM_GICV2M_SPIS 64 - #define NUM_VIRTIO_TRANSPORTS 32 -@@ -181,6 +182,9 @@ OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE) - - void virt_acpi_setup(VirtMachineState *vms); - bool virt_is_acpi_enabled(VirtMachineState *vms); -+void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid, -+ const CPUArchIdList *cpu_list, GArray *entry, -+ bool force_enabled); - - /* Return the number of used redistributor regions */ - static inline int virt_gicv3_redist_region_count(VirtMachineState *vms) --- -2.27.0 - diff --git a/acpi-modify-build_ppt-del-macro-add-arm-build_pptt.patch b/acpi-modify-build_ppt-del-macro-add-arm-build_pptt.patch deleted file mode 100644 index a877196b6bde891c0ac037df6320e68bfce06fec..0000000000000000000000000000000000000000 --- a/acpi-modify-build_ppt-del-macro-add-arm-build_pptt.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 69564ae0e54345391ceceadb6cde9a09db01c2d9 Mon Sep 17 00:00:00 2001 -From: saarloos <9090-90-90-9090@163.com> -Date: Mon, 23 May 2022 20:59:51 +0800 -Subject: [PATCH] arm/acpi: Fix when make qemu-system-aarch64 at x86_64 host - bios_tables_test fail reason: __aarch64__ macro let build_pptt at x86_64 and - aarch64 host build different function that let bios_tables_test fail. - -Signed-off-by: Yangzi Zhang ---- - hw/acpi/aml-build.c | 5 +---- - hw/arm/virt-acpi-build.c | 2 +- - include/hw/acpi/aml-build.h | 7 +++---- - 3 files changed, 5 insertions(+), 9 deletions(-) - -diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c -index c4edaafa4a..39b8d807c0 100644 ---- a/hw/acpi/aml-build.c -+++ b/hw/acpi/aml-build.c -@@ -2016,7 +2016,6 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, - } - } - --#ifdef __aarch64__ - /* - * ACPI spec, Revision 6.3 - * 5.2.29.2 Cache Type Structure (Type 1) -@@ -2072,7 +2071,7 @@ static void build_cache_hierarchy_node(GArray *tbl, uint32_t next_level, - * ACPI spec, Revision 6.3 - * 5.2.29 Processor Properties Topology Table (PPTT) - */ --void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, -+void build_pptt_arm(GArray *table_data, BIOSLinker *linker, MachineState *ms, - const char *oem_id, const char *oem_table_id) - { - MachineClass *mc = MACHINE_GET_CLASS(ms); -@@ -2172,7 +2171,6 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - acpi_table_end(linker, &table); - } - --#else - /* - * ACPI spec, Revision 6.3 - * 5.2.29 Processor Properties Topology Table (PPTT) -@@ -2263,7 +2261,6 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - g_queue_free(list); - acpi_table_end(linker, &table); - } --#endif - - /* build rev1/rev3/rev5.1 FADT */ - void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f, -diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c -index 1101161d70..89cecdd8e6 100644 ---- a/hw/arm/virt-acpi-build.c -+++ b/hw/arm/virt-acpi-build.c -@@ -1070,7 +1070,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) - - if (!vmc->no_cpu_topology) { - acpi_add_table(table_offsets, tables_blob); -- build_pptt(tables_blob, tables->linker, ms, -+ build_pptt_arm(tables_blob, tables->linker, ms, - vms->oem_id, vms->oem_table_id); - } - -diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h -index 2e00d2e208..5e9b72c024 100644 ---- a/include/hw/acpi/aml-build.h -+++ b/include/hw/acpi/aml-build.h -@@ -221,9 +221,7 @@ struct AcpiBuildTables { - BIOSLinker *linker; - } AcpiBuildTables; - --#ifdef __aarch64__ - /* Definitions of the hardcoded cache info*/ -- - typedef enum { - ARM_L1D_CACHE, - ARM_L1I_CACHE, -@@ -266,8 +264,6 @@ struct offset_status { - uint32_t l1i_offset; - }; - --#endif -- - typedef - struct CrsRangeEntry { - uint64_t base; -@@ -542,6 +538,9 @@ void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms, - void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - const char *oem_id, const char *oem_table_id); - -+void build_pptt_arm(GArray *table_data, BIOSLinker *linker, MachineState *ms, -+ const char *oem_id, const char *oem_table_id); -+ - void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f, - const char *oem_id, const char *oem_table_id); - --- -2.35.1.windows.2 - diff --git a/acpi-pcihp-pcie-set-power-on-cap-on-parent-slot.patch b/acpi-pcihp-pcie-set-power-on-cap-on-parent-slot.patch deleted file mode 100644 index 1a70fcc60f27a127024e2d9cfe506f268685a4e1..0000000000000000000000000000000000000000 --- a/acpi-pcihp-pcie-set-power-on-cap-on-parent-slot.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 6c92ab0387c2af443142a0cc47134389711a14dc Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Tue, 1 Mar 2022 10:11:59 -0500 -Subject: [PATCH 5/6] acpi: pcihp: pcie: set power on cap on parent slot - -on creation a PCIDevice has power turned on at the end of pci_qdev_realize() -however later on if PCIe slot isn't populated with any children -it's power is turned off. It's fine if native hotplug is used -as plug callback will power slot on among other things. -However when ACPI hotplug is enabled it replaces native PCIe plug -callbacks with ACPI specific ones (acpi_pcihp_device_*plug_cb) and -as result slot stays powered off. It works fine as ACPI hotplug -on guest side takes care of enumerating/initializing hotplugged -device. But when later guest is migrated, call chain introduced by] -commit d5daff7d312 (pcie: implement slot power control for pcie root ports) - - pcie_cap_slot_post_load() - -> pcie_cap_update_power() - -> pcie_set_power_device() - -> pci_set_power() - -> pci_update_mappings() - -will disable earlier initialized BARs for the hotplugged device -in powered off slot due to commit 23786d13441 (pci: implement power state) -which disables BARs if power is off. - -Fix it by setting PCI_EXP_SLTCTL_PCC to PCI_EXP_SLTCTL_PWR_ON -on slot (root port/downstream port) at the time a device -hotplugged into it. As result PCI_EXP_SLTCTL_PWR_ON is migrated -to target and above call chain keeps device plugged into it -powered on. - -Fixes: d5daff7d312 ("pcie: implement slot power control for pcie root ports") -Fixes: 23786d13441 ("pci: implement power state") -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2053584 -Suggested-by: "Michael S. Tsirkin" -Signed-off-by: Igor Mammedov -Message-Id: <20220301151200.3507298-3-imammedo@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: wanbo ---- - hw/acpi/pcihp.c | 12 +++++++++++- - hw/pci/pcie.c | 11 +++++++++++ - include/hw/pci/pcie.h | 1 + - 3 files changed, 23 insertions(+), 1 deletion(-) - -diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c -index a5e182dd3a..be0e846b34 100644 ---- a/hw/acpi/pcihp.c -+++ b/hw/acpi/pcihp.c -@@ -32,6 +32,7 @@ - #include "hw/pci/pci_bridge.h" - #include "hw/pci/pci_host.h" - #include "hw/pci/pcie_port.h" -+#include "hw/pci-bridge/xio3130_downstream.h" - #include "hw/i386/acpi-build.h" - #include "hw/acpi/acpi.h" - #include "hw/pci/pci_bus.h" -@@ -341,6 +342,8 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, - { - PCIDevice *pdev = PCI_DEVICE(dev); - int slot = PCI_SLOT(pdev->devfn); -+ PCIDevice *bridge; -+ PCIBus *bus; - int bsel; - - /* Don't send event when device is enabled during qemu machine creation: -@@ -370,7 +373,14 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, - return; - } - -- bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev)); -+ bus = pci_get_bus(pdev); -+ bridge = pci_bridge_get_device(bus); -+ if (object_dynamic_cast(OBJECT(bridge), TYPE_PCIE_ROOT_PORT) || -+ object_dynamic_cast(OBJECT(bridge), TYPE_XIO3130_DOWNSTREAM)) { -+ pcie_cap_slot_enable_power(bridge); -+ } -+ -+ bsel = acpi_pcihp_get_bsel(bus); - g_assert(bsel >= 0); - s->acpi_pcihp_pci_status[bsel].up |= (1U << slot); - acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); -diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c -index 30c09ed943..a2d1ae6021 100644 ---- a/hw/pci/pcie.c -+++ b/hw/pci/pcie.c -@@ -365,6 +365,17 @@ static void hotplug_event_clear(PCIDevice *dev) - } - } - -+void pcie_cap_slot_enable_power(PCIDevice *dev) -+{ -+ uint8_t *exp_cap = dev->config + dev->exp.exp_cap; -+ uint32_t sltcap = pci_get_long(exp_cap + PCI_EXP_SLTCAP); -+ -+ if (sltcap & PCI_EXP_SLTCAP_PCP) { -+ pci_set_word_by_mask(exp_cap + PCI_EXP_SLTCTL, -+ PCI_EXP_SLTCTL_PCC, PCI_EXP_SLTCTL_PWR_ON); -+ } -+} -+ - static void pcie_set_power_device(PCIBus *bus, PCIDevice *dev, void *opaque) - { - bool *power = opaque; -diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h -index 6063bee0ec..c27368d077 100644 ---- a/include/hw/pci/pcie.h -+++ b/include/hw/pci/pcie.h -@@ -112,6 +112,7 @@ void pcie_cap_slot_write_config(PCIDevice *dev, - uint32_t addr, uint32_t val, int len); - int pcie_cap_slot_post_load(void *opaque, int version_id); - void pcie_cap_slot_push_attention_button(PCIDevice *dev); -+void pcie_cap_slot_enable_power(PCIDevice *dev); - - void pcie_cap_root_init(PCIDevice *dev); - void pcie_cap_root_reset(PCIDevice *dev); --- -2.27.0 - diff --git a/acpi-validate-hotplug-selector-on-access.patch b/acpi-validate-hotplug-selector-on-access.patch deleted file mode 100644 index 0506bd943319533917a0fdbd2b948e6b18729a12..0000000000000000000000000000000000000000 --- a/acpi-validate-hotplug-selector-on-access.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1205bf5738346fe9f217f5db08500b12b812aafa Mon Sep 17 00:00:00 2001 -From: "Michael S. Tsirkin" -Date: Tue, 21 Dec 2021 09:45:44 -0500 -Subject: [PATCH 1/2] acpi: validate hotplug selector on access -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When bus is looked up on a pci write, we didn't -validate that the lookup succeeded. -Fuzzers thus can trigger QEMU crash by dereferencing the NULL -bus pointer. - -Fixes: b32bd763a1 ("pci: introduce acpi-index property for PCI device") -Fixes: CVE-2021-4158 -Cc: "Igor Mammedov" -Fixes: https://gitlab.com/qemu-project/qemu/-/issues/770 -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Ani Sinha ---- - hw/acpi/pcihp.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c -index 30405b5113..a5e182dd3a 100644 ---- a/hw/acpi/pcihp.c -+++ b/hw/acpi/pcihp.c -@@ -491,6 +491,9 @@ static void pci_write(void *opaque, hwaddr addr, uint64_t data, - } - - bus = acpi_pcihp_find_hotplug_bus(s, s->hotplug_select); -+ if (!bus) { -+ break; -+ } - QTAILQ_FOREACH_SAFE(kid, &bus->qbus.children, sibling, next) { - Object *o = OBJECT(kid->child); - PCIDevice *dev = PCI_DEVICE(o); --- -2.27.0 - diff --git a/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch b/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch deleted file mode 100644 index 0bc4707a244ebc8366648250c75755e8446c6e44..0000000000000000000000000000000000000000 --- a/add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch +++ /dev/null @@ -1,74 +0,0 @@ -From ec35c96006851a956a7e401f29af0ffe137c4bb9 Mon Sep 17 00:00:00 2001 -From: Jiadong Zeng -Date: Tue, 8 Feb 2022 22:56:37 +0800 -Subject: [PATCH] add Phytium's CPU models: FT-2000+ and Tengyun-S2500. - -Signed-off-by: Jiadong Zeng -Signed-off-by: Mingwang Li ---- - hw/arm/virt.c | 2 ++ - target/arm/cpu64.c | 28 ++++++++++++++++++++++++++++ - 2 files changed, 30 insertions(+) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index a4a35584e9..3c972fdab0 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -202,6 +202,8 @@ static const char *valid_cpus[] = { - ARM_CPU_TYPE_NAME("cortex-a57"), - ARM_CPU_TYPE_NAME("cortex-a72"), - ARM_CPU_TYPE_NAME("Kunpeng-920"), -+ ARM_CPU_TYPE_NAME("FT-2000+"), -+ ARM_CPU_TYPE_NAME("Tengyun-S2500"), - ARM_CPU_TYPE_NAME("a64fx"), - ARM_CPU_TYPE_NAME("host"), - ARM_CPU_TYPE_NAME("max"), -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 556b6f3691..08d886de7b 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -676,6 +676,32 @@ static Property arm_cpu_pauth_property = - static Property arm_cpu_pauth_impdef_property = - DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false); - -+static void aarch64_max_ft2000plus_initfn(Object *obj) -+{ -+ ARMCPU *cpu = ARM_CPU(obj); -+ -+ if (kvm_enabled()) { -+ kvm_arm_set_cpu_features_from_host(cpu); -+ kvm_arm_add_vcpu_properties(obj); -+ } else { -+ aarch64_a72_initfn(obj); -+ cpu->midr = 0x70186622; -+ } -+} -+ -+static void aarch64_max_tengyun_s2500_initfn(Object *obj) -+{ -+ ARMCPU *cpu = ARM_CPU(obj); -+ -+ if (kvm_enabled()) { -+ kvm_arm_set_cpu_features_from_host(cpu); -+ kvm_arm_add_vcpu_properties(obj); -+ } else { -+ aarch64_a72_initfn(obj); -+ cpu->midr = 0x70186632; -+ } -+} -+ - /* -cpu max: if KVM is enabled, like -cpu host (best possible with this host); - * otherwise, a CPU with as many features enabled as our emulation supports. - * The version of '-cpu max' for qemu-system-arm is defined in cpu.c; -@@ -914,6 +940,8 @@ static const ARMCPUInfo aarch64_cpus[] = { - { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, - { .name = "cortex-a72", .initfn = aarch64_a72_initfn }, - { .name = "Kunpeng-920", .initfn = aarch64_kunpeng_920_initfn}, -+ { .name = "FT-2000+", .initfn = aarch64_max_ft2000plus_initfn }, -+ { .name = "Tengyun-S2500", .initfn = aarch64_max_tengyun_s2500_initfn }, - { .name = "a64fx", .initfn = aarch64_a64fx_initfn }, - { .name = "max", .initfn = aarch64_max_initfn }, - }; --- -2.27.0 - diff --git a/aio-posix-fix-build-failure-io_uring-2.2.patch b/aio-posix-fix-build-failure-io_uring-2.2.patch deleted file mode 100644 index 8096bc124f14b7667d2219628bc0acde406a6758..0000000000000000000000000000000000000000 --- a/aio-posix-fix-build-failure-io_uring-2.2.patch +++ /dev/null @@ -1,56 +0,0 @@ -From f900bc66931458b824274027417b6375610c8d9a Mon Sep 17 00:00:00 2001 -From: Haiyue Wang -Date: Tue, 22 Feb 2022 00:24:01 +0800 -Subject: [PATCH] aio-posix: fix build failure io_uring 2.2 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The io_uring fixed "Don't truncate addr fields to 32-bit on 32-bit": -https://git.kernel.dk/cgit/liburing/commit/?id=d84c29b19ed0b130000619cff40141bb1fc3615b - -This leads to build failure: -../util/fdmon-io_uring.c: In function ‘add_poll_remove_sqe’: -../util/fdmon-io_uring.c:182:36: error: passing argument 2 of ‘io_uring_prep_poll_remove’ makes integer from pointer without a cast [-Werror=int-conversion] - 182 | io_uring_prep_poll_remove(sqe, node); - | ^~~~ - | | - | AioHandler * -In file included from /root/io/qemu/include/block/aio.h:18, - from ../util/aio-posix.h:20, - from ../util/fdmon-io_uring.c:49: -/usr/include/liburing.h:415:17: note: expected ‘__u64’ {aka ‘long long unsigned int’} but argument is of type ‘AioHandler *’ - 415 | __u64 user_data) - | ~~~~~~^~~~~~~~~ -cc1: all warnings being treated as errors - -Use LIBURING_HAVE_DATA64 to check whether the io_uring supports 64-bit -variants of the get/set userdata, to convert the paramter to the right -data type. - -Signed-off-by: Haiyue Wang -Message-Id: <20220221162401.45415-1-haiyue.wang@intel.com> -Signed-off-by: Stefan Hajnoczi ---- - util/fdmon-io_uring.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c -index 1461dfa407..ab43052dd7 100644 ---- a/util/fdmon-io_uring.c -+++ b/util/fdmon-io_uring.c -@@ -179,7 +179,11 @@ static void add_poll_remove_sqe(AioContext *ctx, AioHandler *node) - { - struct io_uring_sqe *sqe = get_sqe(ctx); - -+#ifdef LIBURING_HAVE_DATA64 -+ io_uring_prep_poll_remove(sqe, (__u64)(uintptr_t)node); -+#else - io_uring_prep_poll_remove(sqe, node); -+#endif - } - - /* Add a timeout that self-cancels when another cqe becomes ready */ --- -2.41.0.windows.1 - diff --git a/aio-posix-fix-race-between-epoll-upgrade-and-aio_set.patch b/aio-posix-fix-race-between-epoll-upgrade-and-aio_set.patch deleted file mode 100644 index 3d2aed800cfbe2c3d3779f7df0520e4408ea392c..0000000000000000000000000000000000000000 --- a/aio-posix-fix-race-between-epoll-upgrade-and-aio_set.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 4ab8e11adf5878d1f298a682b37d7de4632a3a8b Mon Sep 17 00:00:00 2001 -From: wangmeiyang -Date: Fri, 28 Apr 2023 15:22:07 +0800 -Subject: [PATCH] aio-posix: fix race between epoll upgrade and - aio_set_fd_handler() - -If another thread calls aio_set_fd_handler() while the IOThread event -loop is upgrading from ppoll(2) to epoll(7) then we might miss new -AioHandlers. The epollfd will not monitor the new AioHandler's fd, -resulting in hangs. - -Take the AioHandler list lock while upgrading to epoll. This prevents -AioHandlers from changing while epoll is being set up. If we cannot lock -because we're in a nested event loop, then don't upgrade to epoll (it -will happen next time we're not in a nested call). - -The downside to taking the lock is that the aio_set_fd_handler() thread -has to wait until the epoll upgrade is finished, which involves many -epoll_ctl(2) system calls. However, this scenario is rare and I couldn't -think of another solution that is still simple. - -origin commit: https://gitlab.com/qemu-project/qemu/-/commit/e62da98527fa35fe5f532cded01a33edf9fbe7b2 -Signed-off-by: Meiyang Wang -Reported-by: Qing Wang -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2090998 -Cc: Paolo Bonzini -Cc: Fam Zheng -Signed-off-by: Stefan Hajnoczi -Message-Id: <20230323144859.1338495-1-stefanha@redhat.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - util/fdmon-epoll.c | 25 ++++++++++++++++++------- - 1 file changed, 18 insertions(+), 7 deletions(-) - -diff --git a/util/fdmon-epoll.c b/util/fdmon-epoll.c -index e11a8a022e..1683aa1105 100644 ---- a/util/fdmon-epoll.c -+++ b/util/fdmon-epoll.c -@@ -127,6 +127,8 @@ static bool fdmon_epoll_try_enable(AioContext *ctx) - - bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd) - { -+ bool ok; -+ - if (ctx->epollfd < 0) { - return false; - } -@@ -136,14 +138,23 @@ bool fdmon_epoll_try_upgrade(AioContext *ctx, unsigned npfd) - return false; - } - -- if (npfd >= EPOLL_ENABLE_THRESHOLD) { -- if (fdmon_epoll_try_enable(ctx)) { -- return true; -- } else { -- fdmon_epoll_disable(ctx); -- } -+ if (npfd < EPOLL_ENABLE_THRESHOLD) { -+ return false; -+ } -+ -+ /* The list must not change while we add fds to epoll */ -+ if (!qemu_lockcnt_dec_if_lock(&ctx->list_lock)) { -+ return false; -+ } -+ -+ ok = fdmon_epoll_try_enable(ctx); -+ -+ qemu_lockcnt_inc_and_unlock(&ctx->list_lock); -+ -+ if (!ok) { -+ fdmon_epoll_disable(ctx); - } -- return false; -+ return ok; - } - - void fdmon_epoll_setup(AioContext *ctx) --- -2.27.0 - diff --git a/aio-posix-zero-out-io_uring-sqe-user_data.patch b/aio-posix-zero-out-io_uring-sqe-user_data.patch deleted file mode 100644 index 5c038442acb64408743ae6719a63e9bae44aa7f6..0000000000000000000000000000000000000000 --- a/aio-posix-zero-out-io_uring-sqe-user_data.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c670a3038a0b7dffda79672a63c84609459218c6 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Tue, 12 Sep 2023 10:22:09 +0800 -Subject: [PATCH] aio-posix: zero out io_uring sqe user_data - -cheery-pick from 87ec6f55af38e29be5b2b65a8acf84da73e06d06 - -liburing does not clear sqe->user_data. We must do it ourselves to avoid -undefined behavior in process_cqe() when user_data is used. - -Note that fdmon-io_uring is currently disabled, so this is a latent bug -that does not affect users. Let's merge this fix now to make it easier -to enable fdmon-io_uring in the future (and I'm working on that). - -Signed-off-by: Stefan Hajnoczi -Message-ID: <20230426212639.82310-1-stefanha@redhat.com> -Signed-off-by: qihao_yewu ---- - util/fdmon-io_uring.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util/fdmon-io_uring.c b/util/fdmon-io_uring.c -index ab43052dd7..35165bcb46 100644 ---- a/util/fdmon-io_uring.c -+++ b/util/fdmon-io_uring.c -@@ -184,6 +184,7 @@ static void add_poll_remove_sqe(AioContext *ctx, AioHandler *node) - #else - io_uring_prep_poll_remove(sqe, node); - #endif -+ io_uring_sqe_set_data(sqe, NULL); - } - - /* Add a timeout that self-cancels when another cqe becomes ready */ -@@ -197,6 +198,7 @@ static void add_timeout_sqe(AioContext *ctx, int64_t ns) - - sqe = get_sqe(ctx); - io_uring_prep_timeout(sqe, &ts, 1, 0); -+ io_uring_sqe_set_data(sqe, NULL); - } - - /* Add sqes from ctx->submit_list for submission */ --- -2.41.0.windows.1 - diff --git a/arm-cpu-assign-arm_get_arch_id-handler-to-get_arch_i.patch b/arm-cpu-assign-arm_get_arch_id-handler-to-get_arch_i.patch deleted file mode 100644 index 91c7181ebca41c090d7909392cd1ac884c70869b..0000000000000000000000000000000000000000 --- a/arm-cpu-assign-arm_get_arch_id-handler-to-get_arch_i.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 42072fd4b33125959d825a0c5cee0d1122072f71 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 10:17:27 +0800 -Subject: [PATCH] arm/cpu: assign arm_get_arch_id handler to get_arch_id hook - -This hook will be called in get_cpu_status, which is called -during cpu hotplug. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - target/arm/cpu.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index 65163f5135..f06ba29885 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -2557,6 +2557,13 @@ static const struct TCGCPUOps arm_tcg_ops = { - }; - #endif /* CONFIG_TCG */ - -+static int64_t arm_cpu_get_arch_id(CPUState *cs) -+{ -+ ARMCPU *cpu = ARM_CPU(cs); -+ -+ return cpu->mp_affinity; -+} -+ - static void arm_cpu_class_init(ObjectClass *oc, void *data) - { - ARMCPUClass *acc = ARM_CPU_CLASS(oc); -@@ -2575,6 +2582,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) - cc->set_pc = arm_cpu_set_pc; - cc->gdb_read_register = arm_cpu_gdb_read_register; - cc->gdb_write_register = arm_cpu_gdb_write_register; -+ cc->get_arch_id = arm_cpu_get_arch_id; - #ifndef CONFIG_USER_ONLY - cc->sysemu_ops = &arm_sysemu_ops; - #endif --- -2.27.0 - diff --git a/arm-virt-Add-CPU-hotplug-framework.patch b/arm-virt-Add-CPU-hotplug-framework.patch deleted file mode 100644 index 4fdcf9f088e9c309a8b5b935978ef389d3af5aee..0000000000000000000000000000000000000000 --- a/arm-virt-Add-CPU-hotplug-framework.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 209b3e4e522b8f7f41e495feaade96ee9a91e46a Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 3 Apr 2020 16:16:18 +0800 -Subject: [PATCH] arm/virt: Add CPU hotplug framework - -Establish the CPU hotplug framework for arm/virt, we will add -necessary code legs to this framework gradually to realize CPU -hotplug finally. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt.c | 19 ++++++++++++++++++- - 1 file changed, 18 insertions(+), 1 deletion(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 9b73c479c4..11155fcb70 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -2586,6 +2586,18 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev, - dev, &error_abort); - } - -+static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ /* Currently nothing to do */ -+} -+ -+static void virt_cpu_plug(HotplugHandler *hotplug_dev, -+ DeviceState *dev, Error **errp) -+{ -+ /* Currently nothing to do */ -+} -+ - static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) - { -@@ -2619,6 +2631,8 @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, - qdev_prop_set_uint32(dev, "len-reserved-regions", 1); - qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str); - g_free(resv_prop_str); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ virt_cpu_pre_plug(hotplug_dev, dev, errp); - } - } - -@@ -2637,6 +2651,8 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, - } - if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - virt_memory_plug(hotplug_dev, dev, errp); -+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { -+ virt_cpu_plug(hotplug_dev, dev, errp); - } - if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { - PCIDevice *pdev = PCI_DEVICE(dev); -@@ -2717,7 +2733,8 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, - MachineClass *mc = MACHINE_GET_CLASS(machine); - - if (device_is_dynamic_sysbus(mc, dev) || -- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) { -+ (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) || -+ (object_dynamic_cast(OBJECT(dev), TYPE_CPU))) { - return HOTPLUG_HANDLER(machine); - } - if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) { --- -2.27.0 - diff --git a/arm-virt-Add-CPU-topology-support.patch b/arm-virt-Add-CPU-topology-support.patch deleted file mode 100644 index 016b3ed684491491637525b2edad0b24d099d0d2..0000000000000000000000000000000000000000 --- a/arm-virt-Add-CPU-topology-support.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 5454c00908236dcabcbf9ae246ccb69e1fcea72e Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Mon, 6 Apr 2020 10:54:35 +0800 -Subject: [PATCH] arm/virt: Add CPU topology support - -The CPU topology specified by user (through -smp options) is used in -ACPI PPTT. Now we will use this information to locate which CPU to -plug or unplug. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt.c | 87 ++++++++++++++++++++++++++++++++++++++- - include/hw/arm/topology.h | 68 ++++++++++++++++++++++++++++++ - qapi/machine.json | 2 + - target/arm/cpu.c | 4 ++ - target/arm/cpu.h | 4 ++ - 5 files changed, 163 insertions(+), 2 deletions(-) - create mode 100644 include/hw/arm/topology.h - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 11155fcb70..a12e718686 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -39,6 +39,7 @@ - #include "hw/sysbus.h" - #include "hw/arm/boot.h" - #include "hw/arm/primecell.h" -+#include "hw/arm/topology.h" - #include "hw/arm/virt.h" - #include "hw/block/flash.h" - #include "hw/vfio/vfio-calxeda-xgmac.h" -@@ -2524,6 +2525,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) - int n; - unsigned int max_cpus = ms->smp.max_cpus; - VirtMachineState *vms = VIRT_MACHINE(ms); -+ ARMCPUTopoInfo topo; - - if (ms->possible_cpus) { - assert(ms->possible_cpus->len == max_cpus); -@@ -2535,10 +2537,19 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) - ms->possible_cpus->len = max_cpus; - for (n = 0; n < ms->possible_cpus->len; n++) { - ms->possible_cpus->cpus[n].type = ms->cpu_type; -+ ms->possible_cpus->cpus[n].vcpus_count = 1; - ms->possible_cpus->cpus[n].arch_id = - virt_cpu_mp_affinity(vms, n); -+ -+ topo_ids_from_idx(n, ms->smp.clusters, ms->smp.cores, ms->smp.threads, &topo); -+ ms->possible_cpus->cpus[n].props.has_socket_id = true; -+ ms->possible_cpus->cpus[n].props.socket_id = topo.pkg_id; -+ ms->possible_cpus->cpus[n].props.has_cluster_id = true; -+ ms->possible_cpus->cpus[n].props.cluster_id = topo.cluster_id; -+ ms->possible_cpus->cpus[n].props.has_core_id = true; -+ ms->possible_cpus->cpus[n].props.core_id = topo.core_id; - ms->possible_cpus->cpus[n].props.has_thread_id = true; -- ms->possible_cpus->cpus[n].props.thread_id = n; -+ ms->possible_cpus->cpus[n].props.thread_id = topo.smt_id; - } - return ms->possible_cpus; - } -@@ -2589,7 +2600,79 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev, - static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) - { -- /* Currently nothing to do */ -+ CPUState *cs = CPU(dev); -+ ARMCPUTopoInfo topo; -+ ARMCPU *cpu = ARM_CPU(dev); -+ MachineState *ms = MACHINE(hotplug_dev); -+ int smp_clusters = ms->smp.clusters; -+ int smp_cores = ms->smp.cores; -+ int smp_threads = ms->smp.threads; -+ -+ /* if cpu idx is not set, set it based on socket/cluster/core/thread -+ * properties -+ */ -+ if (cs->cpu_index == UNASSIGNED_CPU_INDEX) { -+ int max_socket = ms->smp.max_cpus / smp_threads / smp_cores / smp_clusters; -+ if (cpu->socket_id < 0 || cpu->socket_id >= max_socket) { -+ error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u", -+ cpu->socket_id, max_socket - 1); -+ return; -+ } -+ if (cpu->cluster_id < 0 || cpu->cluster_id >= smp_clusters) { -+ error_setg(errp, "Invalid CPU cluster-id: %u must be in range 0:%u", -+ cpu->cluster_id, smp_clusters - 1); -+ return; -+ } -+ if (cpu->core_id < 0 || cpu->core_id >= smp_cores) { -+ error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u", -+ cpu->core_id, smp_cores - 1); -+ return; -+ } -+ if (cpu->thread_id < 0 || cpu->thread_id >= smp_threads) { -+ error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u", -+ cpu->thread_id, smp_threads - 1); -+ return; -+ } -+ -+ topo.pkg_id = cpu->socket_id; -+ topo.cluster_id = cpu->cluster_id; -+ topo.core_id = cpu->core_id; -+ topo.smt_id = cpu->thread_id; -+ cs->cpu_index = idx_from_topo_ids(smp_clusters, smp_cores, smp_threads, &topo); -+ } -+ -+ /* if 'address' properties socket-id/cluster-id/core-id/thread-id are not -+ * set, set them so that machine_query_hotpluggable_cpus would show correct -+ * values -+ */ -+ topo_ids_from_idx(cs->cpu_index, smp_clusters, smp_cores, smp_threads, &topo); -+ if (cpu->socket_id != -1 && cpu->socket_id != topo.pkg_id) { -+ error_setg(errp, "property socket-id: %u doesn't match set idx:" -+ " 0x%x (socket-id: %u)", cpu->socket_id, cs->cpu_index, topo.pkg_id); -+ return; -+ } -+ cpu->socket_id = topo.pkg_id; -+ -+ if (cpu->cluster_id != -1 && cpu->cluster_id != topo.cluster_id) { -+ error_setg(errp, "property cluster-id: %u doesn't match set idx:" -+ " 0x%x (cluster-id: %u)", cpu->cluster_id, cs->cpu_index, topo.cluster_id); -+ return; -+ } -+ cpu->cluster_id = topo.cluster_id; -+ -+ if (cpu->core_id != -1 && cpu->core_id != topo.core_id) { -+ error_setg(errp, "property core-id: %u doesn't match set idx:" -+ " 0x%x (core-id: %u)", cpu->core_id, cs->cpu_index, topo.core_id); -+ return; -+ } -+ cpu->core_id = topo.core_id; -+ -+ if (cpu->thread_id != -1 && cpu->thread_id != topo.smt_id) { -+ error_setg(errp, "property thread-id: %u doesn't match set idx:" -+ " 0x%x (thread-id: %u)", cpu->thread_id, cs->cpu_index, topo.smt_id); -+ return; -+ } -+ cpu->thread_id = topo.smt_id; - } - - static void virt_cpu_plug(HotplugHandler *hotplug_dev, -diff --git a/include/hw/arm/topology.h b/include/hw/arm/topology.h -new file mode 100644 -index 0000000000..d0dad1a9a3 ---- /dev/null -+++ b/include/hw/arm/topology.h -@@ -0,0 +1,68 @@ -+/* -+ * ARM CPU topology data structures and functions -+ * -+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO.,LTD. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, see . -+ */ -+ -+#ifndef HW_ARM_TOPOLOGY_H -+#define HW_ARM_TOPOLOGY_H -+ -+typedef struct ARMCPUTopoInfo { -+ unsigned pkg_id; -+ unsigned cluster_id; -+ unsigned core_id; -+ unsigned smt_id; -+} ARMCPUTopoInfo; -+ -+/* Calculate (contiguous) CPU index based on topology */ -+static inline unsigned idx_from_topo_ids(unsigned nr_clusters, -+ unsigned nr_cores, -+ unsigned nr_threads, -+ const ARMCPUTopoInfo *topo) -+{ -+ assert(nr_clusters > 0); -+ assert(nr_cores > 0); -+ assert(nr_threads > 0); -+ assert(topo != NULL); -+ -+ return topo->pkg_id * nr_clusters * nr_cores * nr_threads + -+ topo->cluster_id * nr_cores + -+ topo->core_id * nr_threads + -+ topo->smt_id; -+} -+ -+/* Calculate thread/core/cluster/package topology -+ * based on (contiguous) CPU index -+ */ -+static inline void topo_ids_from_idx(unsigned cpu_index, -+ unsigned nr_clusters, -+ unsigned nr_cores, -+ unsigned nr_threads, -+ ARMCPUTopoInfo *topo) -+{ -+ assert(nr_clusters > 0); -+ assert(nr_cores > 0); -+ assert(nr_threads > 0); -+ assert(topo != NULL); -+ -+ topo->smt_id = cpu_index % nr_threads; -+ topo->core_id = cpu_index / nr_threads % nr_cores; -+ topo->cluster_id = cpu_index / nr_threads / nr_cores % nr_clusters; -+ topo->pkg_id = cpu_index / nr_threads / nr_cores / nr_clusters; -+} -+ -+#endif /* HW_ARM_TOPOLOGY_H */ -+ -diff --git a/qapi/machine.json b/qapi/machine.json -index 8faa51074e..6822cafe2e 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -868,6 +868,7 @@ - # @node-id: NUMA node ID the CPU belongs to - # @socket-id: socket number within node/board the CPU belongs to - # @die-id: die number within socket the CPU belongs to (since 4.1) -+# @cluster-id: cluster number within die the CPU belongs to (since 6.2) - # @core-id: core number within die the CPU belongs to - # @thread-id: thread number within core the CPU belongs to - # -@@ -883,6 +884,7 @@ - 'data': { '*node-id': 'int', - '*socket-id': 'int', - '*die-id': 'int', -+ '*cluster-id': 'int', - '*core-id': 'int', - '*thread-id': 'int' - } -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index f06ba29885..9fd8e57971 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -2507,6 +2507,10 @@ static Property arm_cpu_properties[] = { - DEFINE_PROP_UINT64("mp-affinity", ARMCPU, - mp_affinity, ARM64_AFFINITY_INVALID), - DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID), -+ DEFINE_PROP_INT32("socket-id", ARMCPU, socket_id, -1), -+ DEFINE_PROP_INT32("cluster-id", ARMCPU, cluster_id, -1), -+ DEFINE_PROP_INT32("core-id", ARMCPU, core_id, -1), -+ DEFINE_PROP_INT32("thread-id", ARMCPU, thread_id, -1), - DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1), - DEFINE_PROP_END_OF_LIST() - }; -diff --git a/target/arm/cpu.h b/target/arm/cpu.h -index 947897d5ac..eb804dffaa 100644 ---- a/target/arm/cpu.h -+++ b/target/arm/cpu.h -@@ -1006,6 +1006,10 @@ struct ARMCPU { - QLIST_HEAD(, ARMELChangeHook) el_change_hooks; - - int32_t node_id; /* NUMA node this CPU belongs to */ -+ int32_t socket_id; -+ int32_t cluster_id; -+ int32_t core_id; -+ int32_t thread_id; - - /* Used to synchronize KVM and QEMU in-kernel device levels */ - uint8_t device_irq_level; --- -2.27.0 - diff --git a/arm-virt-Add-cpu_hotplug_enabled-field.patch b/arm-virt-Add-cpu_hotplug_enabled-field.patch deleted file mode 100644 index 0ae840c7cdae03104a7bb317f98c872399e4eafb..0000000000000000000000000000000000000000 --- a/arm-virt-Add-cpu_hotplug_enabled-field.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 965eb25b03f6977a7656dce3ac5cdb4c95bfe003 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 13:50:40 +0800 -Subject: [PATCH] arm/virt: Add cpu_hotplug_enabled field - -Some conditions must be satisfied to support CPU hotplug, including -ACPI, GED, 64bit CPU, GICv3. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt.c | 7 +++++++ - include/hw/arm/virt.h | 1 + - 2 files changed, 8 insertions(+) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index b1224fb1e4..45a0a045b1 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -2008,6 +2008,7 @@ static void machvirt_init(MachineState *machine) - { - VirtMachineState *vms = VIRT_MACHINE(machine); - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine); -+ MachineState *ms = MACHINE(machine); - MachineClass *mc = MACHINE_GET_CLASS(machine); - const CPUArchIdList *possible_cpus; - MemoryRegion *sysmem = get_system_memory(); -@@ -2017,6 +2018,7 @@ static void machvirt_init(MachineState *machine) - bool has_ged = !vmc->no_ged; - unsigned int smp_cpus = machine->smp.cpus; - unsigned int max_cpus = machine->smp.max_cpus; -+ ObjectClass *cpu_class; - - /* - * In accelerated mode, the memory map is computed earlier in kvm_type() -@@ -2106,6 +2108,11 @@ static void machvirt_init(MachineState *machine) - create_fdt(vms); - qemu_log("cpu init start\n"); - -+ cpu_class = object_class_by_name(ms->cpu_type); -+ vms->cpu_hotplug_enabled = has_ged && firmware_loaded && -+ virt_is_acpi_enabled(vms) && vms->gic_version == 3 && -+ !!object_class_dynamic_cast(cpu_class, TYPE_AARCH64_CPU); -+ - possible_cpus = mc->possible_cpu_arch_ids(machine); - assert(possible_cpus->len == max_cpus); - for (n = 0; n < possible_cpus->len; n++) { -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index 947d41f767..c371d377e0 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -149,6 +149,7 @@ struct VirtMachineState { - bool its; - bool tcg_its; - bool virt; -+ bool cpu_hotplug_enabled; - bool ras; - bool mte; - OnOffAuto acpi; --- -2.27.0 - diff --git a/arm-virt-Attach-ACPI-CPU-hotplug-support-to-virt.patch b/arm-virt-Attach-ACPI-CPU-hotplug-support-to-virt.patch deleted file mode 100644 index 174c3de0ee3cd29515413a2316c8ad0cd70441a9..0000000000000000000000000000000000000000 --- a/arm-virt-Attach-ACPI-CPU-hotplug-support-to-virt.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 6b0f94aee82c7558d79e5ec28437483c4873dc65 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Sun, 5 Apr 2020 16:03:15 +0800 -Subject: [PATCH] arm/virt: Attach ACPI CPU hotplug support to virt - -Attach cpus aml building and GED support for CPU hotplug to -arm/virt, but currently we make it diabled by not add CPU -hotplug event to GED. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt-acpi-build.c | 15 ++++++++++++++- - hw/arm/virt.c | 6 ++++++ - include/hw/arm/virt.h | 1 + - 3 files changed, 21 insertions(+), 1 deletion(-) - -diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c -index a93d223879..7cb320d9f2 100644 ---- a/hw/arm/virt-acpi-build.c -+++ b/hw/arm/virt-acpi-build.c -@@ -937,6 +937,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - const int *irqmap = vms->irqmap; - AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = vms->oem_id, - .oem_table_id = vms->oem_table_id }; -+ bool cpu_aml_built = false; - - acpi_table_begin(&table, table_data); - dsdt = init_aml_allocator(); -@@ -947,7 +948,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - * the RTC ACPI device at all when using UEFI. - */ - scope = aml_scope("\\_SB"); -- acpi_dsdt_add_cpus(scope, vms); - acpi_dsdt_add_uart(scope, &memmap[VIRT_UART], - (irqmap[VIRT_UART] + ARM_SPI_BASE)); - if (vmc->acpi_expose_flash) { -@@ -977,6 +977,19 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - AML_SYSTEM_MEMORY, - memmap[VIRT_PCDIMM_ACPI].base); - } -+ -+ if (event & ACPI_GED_CPU_HOTPLUG_EVT) { -+ CPUHotplugFeatures opts = { -+ .acpi_1_compatible = false, .has_legacy_cphp = false -+ }; -+ build_cpus_aml(dsdt, ms, opts, memmap[VIRT_CPU_ACPI].base, -+ "\\_SB", NULL, AML_SYSTEM_MEMORY); -+ cpu_aml_built = true; -+ } -+ } -+ -+ if (!cpu_aml_built) { -+ acpi_dsdt_add_cpus(scope, vms); - } - - acpi_dsdt_add_power_button(scope); -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 3299d674c8..9b73c479c4 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -154,6 +154,7 @@ static const MemMapEntry base_memmap[] = { - [VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN}, - [VIRT_PVTIME] = { 0x090a0000, 0x00010000 }, - [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 }, -+ [VIRT_CPU_ACPI] = { 0x090c0000, ACPI_CPU_HOTPLUG_REG_LEN }, - [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, - [VIRT_CPUFREQ] = { 0x0b000000, 0x00010000 }, - /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ -@@ -697,6 +698,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms) - event |= ACPI_GED_NVDIMM_HOTPLUG_EVT; - } - -+ /* event |= ACPI_GED_CPU_HOTPLUG_EVT; -+ * Currently CPU hotplug is not enabled. -+ */ -+ - dev = qdev_new(TYPE_ACPI_GED); - qdev_prop_set_uint32(dev, "ged-event", event); - -@@ -706,6 +711,7 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms) - - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base); -+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, vms->memmap[VIRT_CPU_ACPI].base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq)); - - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index fe26709e1a..2a838620d8 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -88,6 +88,7 @@ enum { - VIRT_ACPI_GED, - VIRT_NVDIMM_ACPI, - VIRT_PVTIME, -+ VIRT_CPU_ACPI, - VIRT_LOWMEMMAP_LAST, - }; - --- -2.27.0 - diff --git a/arm-virt-Correct-timing-of-executing-cpu_synchronize.patch b/arm-virt-Correct-timing-of-executing-cpu_synchronize.patch deleted file mode 100644 index b89aadb240dcadbbe7429e4488c802d262d18634..0000000000000000000000000000000000000000 --- a/arm-virt-Correct-timing-of-executing-cpu_synchronize.patch +++ /dev/null @@ -1,52 +0,0 @@ -From c3f86c199885506cfddde0dfc235c04e0897d591 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 14 Feb 2023 20:33:40 +0800 -Subject: [PATCH] arm/virt: Correct timing of executing - cpu_synchronize_post_init for hot-plugged cpus - -When the CPU starts normally, cpu_synchronize_post_init is executed -after GICv3 is implemented. This order should be followed when dealing -with hot-plugged CPUs. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/virt.c | 1 + - hw/core/cpu-common.c | 6 ++---- - 2 files changed, 3 insertions(+), 4 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 4716f9baaa..7d5b332594 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -2798,6 +2798,7 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, - } - - /* Register CPU reset and trigger it manually */ -+ cpu_synchronize_post_init(cs); - cpu_synchronize_state(cs); - cpu_hotplug_register_reset(ncpu); - cpu_hotplug_reset_manually(ncpu); -diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c -index b8d1d820cb..2213840260 100644 ---- a/hw/core/cpu-common.c -+++ b/hw/core/cpu-common.c -@@ -206,14 +206,12 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) - } - } - -+#ifdef __aarch64__ - if (dev->hotplugged) { - cpu_synchronize_post_init(cpu); -- --#ifdef __aarch64__ -- if (!kvm_enabled()) --#endif - cpu_resume(cpu); - } -+#endif - - /* NOTE: latest generic point where the cpu is fully realized */ - trace_init_vcpu(cpu); --- -2.27.0 - diff --git a/arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch b/arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch deleted file mode 100644 index 817c1250d43df826828be38f1a3aa2d27d30b476..0000000000000000000000000000000000000000 --- a/arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 41f30679648676d4d62b1ae9026dde77fa9895d5 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 14 Feb 2023 20:39:07 +0800 -Subject: [PATCH] arm/virt: Correct timing of pause all vcpus for hot-plugged - CPUs - -When dealing with hot-plugging cpus, it may fail when realize cpu. -Such a failure would make paused vcpus unrecoverable. So we only -pause all vcpus when needed. Add removed some unnecessary checks. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/virt.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 7d5b332594..4c876fcf16 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -2747,13 +2747,6 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, - &error_abort); - } - } -- -- /* If we use KVM accel, we should pause all vcpus to -- * allow hot access of vcpu registers. -- */ -- if (dev->hotplugged && kvm_enabled()) { -- pause_all_vcpus(); -- } - } - - static void virt_cpu_plug(HotplugHandler *hotplug_dev, -@@ -2773,6 +2766,10 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, - - /* For CPU that is cold/hot plugged */ - if (ncpu >= ms->smp.cpus) { -+ if (dev->hotplugged) { -+ pause_all_vcpus(); -+ } -+ - /* Realize GIC related parts of CPU */ - assert(vms->gic_version == 3); - gicv3 = ARM_GICV3_COMMON(vms->gic); -@@ -2803,6 +2800,10 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, - cpu_hotplug_register_reset(ncpu); - cpu_hotplug_reset_manually(ncpu); - cpu_synchronize_post_reset(cs); -+ -+ if (dev->hotplugged) { -+ resume_all_vcpus(); -+ } - } - - if (dev->hotplugged && kvm_enabled()) { --- -2.27.0 - diff --git a/arm-virt-Fix-vcpu-hotplug-idx_from_topo_ids.patch b/arm-virt-Fix-vcpu-hotplug-idx_from_topo_ids.patch deleted file mode 100644 index 4562e47afef277358290e1bf15664e42db143d5f..0000000000000000000000000000000000000000 --- a/arm-virt-Fix-vcpu-hotplug-idx_from_topo_ids.patch +++ /dev/null @@ -1,29 +0,0 @@ -From add7ed9bb57490e29371a542d47891b7c9210c43 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Sun, 6 Nov 2022 06:36:15 +0800 -Subject: [PATCH 1/3] arm/virt: Fix vcpu hotplug idx_from_topo_ids - -Add missing "nr_threads" when compute cpu index. - -Fixes: 5454c0090823 ("arm/virt: Add CPU topology support") -Signed-off-by: Keqian Zhu ---- - include/hw/arm/topology.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/hw/arm/topology.h b/include/hw/arm/topology.h -index d0dad1a9a3..33e4a0d552 100644 ---- a/include/hw/arm/topology.h -+++ b/include/hw/arm/topology.h -@@ -39,7 +39,7 @@ static inline unsigned idx_from_topo_ids(unsigned nr_clusters, - assert(topo != NULL); - - return topo->pkg_id * nr_clusters * nr_cores * nr_threads + -- topo->cluster_id * nr_cores + -+ topo->cluster_id * nr_cores * nr_threads + - topo->core_id * nr_threads + - topo->smt_id; - } --- -2.27.0 - diff --git a/arm-virt-Pre-sizing-MADT-GICC-GICv3-and-Pre-park-KVM.patch b/arm-virt-Pre-sizing-MADT-GICC-GICv3-and-Pre-park-KVM.patch deleted file mode 100644 index 134cdbe252c59ee6cad7494c9635e8436acbdd7f..0000000000000000000000000000000000000000 --- a/arm-virt-Pre-sizing-MADT-GICC-GICv3-and-Pre-park-KVM.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 3063d421cd68937ece290bc02151cc15b7ec33d0 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 13:55:11 +0800 -Subject: [PATCH] arm/virt: Pre-sizing MADT-GICC GICv3 and Pre-park KVM vCPU - -Establish all pre-sizing facilities based on cpu_hotplug_enabled -field. - -Note: PPTT is constructed for possible_cpus, so it does not need -to pre-sizing it. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt-acpi-build.c | 3 +++ - hw/arm/virt.c | 14 ++++++++++++-- - target/arm/kvm.c | 4 ++-- - 3 files changed, 17 insertions(+), 4 deletions(-) - -diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c -index a16b54086e..1101161d70 100644 ---- a/hw/arm/virt-acpi-build.c -+++ b/hw/arm/virt-acpi-build.c -@@ -859,6 +859,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - build_append_int_noprefix(table_data, vms->gic_version, 1); - build_append_int_noprefix(table_data, 0, 3); /* Reserved */ - -+ if (vms->cpu_hotplug_enabled) { -+ num_cpu = ms->smp.max_cpus; -+ } - for (i = 0; i < num_cpu; i++) { - virt_madt_cpu_entry(NULL, i, possible_cpus, table_data, false); - } -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 45a0a045b1..4eb1b44729 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -833,6 +833,9 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem) - unsigned int smp_cpus = ms->smp.cpus; - uint32_t nb_redist_regions = 0; - -+ if (vms->cpu_hotplug_enabled) { -+ num_cpus = ms->smp.max_cpus; -+ } - assert(num_cpus >= smp_cpus); - - gictype = (type == 3) ? gicv3_class_name() : gic_class_name(); -@@ -2119,8 +2122,15 @@ static void machvirt_init(MachineState *machine) - Object *cpuobj; - CPUState *cs; - -+ if (kvm_enabled() && vms->cpu_hotplug_enabled) { -+ if (kvm_create_parked_vcpu(n) < 0) { -+ error_report("mach-virt: Create KVM parked vCPU failed"); -+ exit(1); -+ } -+ } -+ - if (n >= smp_cpus) { -- break; -+ continue; - } - - cpuobj = object_new(possible_cpus->cpus[n].type); -@@ -2208,7 +2218,7 @@ static void machvirt_init(MachineState *machine) - } - - vms->bootinfo.ram_size = machine->ram_size; -- vms->bootinfo.nb_cpus = smp_cpus; -+ vms->bootinfo.nb_cpus = vms->cpu_hotplug_enabled ? max_cpus : smp_cpus; - vms->bootinfo.board_id = -1; - vms->bootinfo.loader_start = vms->memmap[VIRT_MEM].base; - vms->bootinfo.get_dtb = machvirt_dtb; -diff --git a/target/arm/kvm.c b/target/arm/kvm.c -index 59d556724f..29ac3f40e0 100644 ---- a/target/arm/kvm.c -+++ b/target/arm/kvm.c -@@ -262,9 +262,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - - cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE); - -- if (ms->smp.cpus > 256 && -+ if (ms->smp.max_cpus > 256 && - !kvm_check_extension(s, KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) { -- error_report("Using more than 256 vcpus requires a host kernel " -+ error_report("Using more than max 256 vcpus requires a host kernel " - "with KVM_CAP_ARM_IRQ_LINE_LAYOUT_2"); - ret = -EINVAL; - } --- -2.27.0 - diff --git a/arm-virt-Start-up-CPU-hot-plug-and-cold-plug.patch b/arm-virt-Start-up-CPU-hot-plug-and-cold-plug.patch deleted file mode 100644 index d4970f16b93686535d83709d379356dd68a4e14c..0000000000000000000000000000000000000000 --- a/arm-virt-Start-up-CPU-hot-plug-and-cold-plug.patch +++ /dev/null @@ -1,237 +0,0 @@ -From a2d8cf86a379bb161cdae850824c9e80fb370599 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 14:16:40 +0800 -Subject: [PATCH] arm/virt: Start up CPU hot-plug and cold-plug - -All the CPU hotplug facilities are ready. Assemble them -to start up CPU hot-plug capability for arm/virt. - -This also adds CPU cold plug support to arm virt machine -board. CPU cold plug means adding CPU by using "-device -xx-arm-cpu" when we bring up Qemu. - -Signed-off-by: Salil Mehta -Signed-off-by: Keqian Zhu ---- - hw/arm/virt.c | 110 ++++++++++++++++++++++++++++++++++++++++-- - hw/core/cpu-common.c | 4 ++ - include/hw/arm/virt.h | 1 + - target/arm/cpu.c | 2 + - 4 files changed, 113 insertions(+), 4 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 4eb1b44729..b81d22d68f 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -52,6 +52,8 @@ - #include "sysemu/tpm.h" - #include "sysemu/kvm.h" - #include "sysemu/hvf.h" -+#include "sysemu/cpus.h" -+#include "sysemu/hw_accel.h" - #include "hw/loader.h" - #include "qapi/error.h" - #include "qemu/bitops.h" -@@ -703,9 +705,9 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms) - event |= ACPI_GED_NVDIMM_HOTPLUG_EVT; - } - -- /* event |= ACPI_GED_CPU_HOTPLUG_EVT; -- * Currently CPU hotplug is not enabled. -- */ -+ if (vms->cpu_hotplug_enabled) { -+ event |= ACPI_GED_CPU_HOTPLUG_EVT; -+ } - - dev = qdev_new(TYPE_ACPI_GED); - qdev_prop_set_uint32(dev, "ged-event", event); -@@ -2555,11 +2557,18 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, - VirtMachineState *vms = VIRT_MACHINE(hotplug_dev); - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(hotplug_dev); - const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); -+ const CPUArchId *cpu_slot = NULL; - MemoryRegion *sysmem = get_system_memory(); - int smp_clusters = ms->smp.clusters; - int smp_cores = ms->smp.cores; - int smp_threads = ms->smp.threads; - -+ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { -+ error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", -+ ms->cpu_type); -+ return; -+ } -+ - /* if cpu idx is not set, set it based on socket/cluster/core/thread - * properties - */ -@@ -2593,6 +2602,20 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, - cs->cpu_index = idx_from_topo_ids(smp_clusters, smp_cores, smp_threads, &topo); - } - -+ /* Some hotplug capability checks */ -+ if (cs->cpu_index >= ms->smp.cpus) { -+ if (!vms->acpi_dev) { -+ error_setg(errp, "CPU cold/hot plug is disabled: " -+ "missing acpi device."); -+ return; -+ } -+ if (!vms->cpu_hotplug_enabled) { -+ error_setg(errp, "CPU cold/hot plug is disabled: " -+ "should use AArch64 CPU and GICv3."); -+ return; -+ } -+ } -+ - /* if 'address' properties socket-id/cluster-id/core-id/thread-id are not - * set, set them so that machine_query_hotpluggable_cpus would show correct - * values -@@ -2631,6 +2654,13 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, - object_property_set_int(cpuobj, "mp-affinity", - possible_cpus->cpus[cs->cpu_index].arch_id, NULL); - -+ cpu_slot = &possible_cpus->cpus[cs->cpu_index]; -+ if (cpu_slot->cpu) { -+ error_setg(errp, "CPU[%d] with mp_affinity %" PRIu64 " exists", -+ cs->cpu_index, cpu->mp_affinity); -+ return; -+ } -+ - numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj), - &error_fatal); - -@@ -2716,12 +2746,83 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, - &error_abort); - } - } -+ -+ /* If we use KVM accel, we should pause all vcpus to -+ * allow hot access of vcpu registers. -+ */ -+ if (dev->hotplugged && kvm_enabled()) { -+ pause_all_vcpus(); -+ } - } - - static void virt_cpu_plug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) - { -- /* Currently nothing to do */ -+ CPUArchId *cpu_slot; -+ CPUState *cs = CPU(dev); -+ int ncpu = cs->cpu_index; -+ MachineState *ms = MACHINE(hotplug_dev); -+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev); -+ bool pmu = object_property_get_bool(OBJECT(first_cpu), "pmu", NULL); -+ bool steal_time = object_property_get_bool(OBJECT(first_cpu), -+ "kvm-steal-time", NULL); -+ GICv3State *gicv3; -+ ARMGICv3CommonClass *agcc; -+ Error *local_err = NULL; -+ -+ /* For CPU that is cold/hot plugged */ -+ if (ncpu >= ms->smp.cpus) { -+ /* Realize GIC related parts of CPU */ -+ assert(vms->gic_version == 3); -+ gicv3 = ARM_GICV3_COMMON(vms->gic); -+ agcc = ARM_GICV3_COMMON_GET_CLASS(gicv3); -+ agcc->cpu_hotplug_realize(gicv3, ncpu); -+ connect_gic_cpu_irqs(vms, ncpu); -+ -+ /* Init PMU and steal_time part */ -+ if (kvm_enabled()) { -+ hwaddr pvtime_reg_base = vms->memmap[VIRT_PVTIME].base; -+ -+ if (pmu) { -+ assert(arm_feature(&ARM_CPU(cs)->env, ARM_FEATURE_PMU)); -+ if (kvm_irqchip_in_kernel()) { -+ kvm_arm_pmu_set_irq(cs, PPI(VIRTUAL_PMU_IRQ)); -+ } -+ kvm_arm_pmu_init(cs); -+ } -+ if (steal_time) { -+ kvm_arm_pvtime_init(cs, pvtime_reg_base + -+ ncpu * PVTIME_SIZE_PER_CPU); -+ } -+ } -+ -+ /* Register CPU reset and trigger it manually */ -+ cpu_synchronize_state(cs); -+ cpu_hotplug_register_reset(ncpu); -+ cpu_hotplug_reset_manually(ncpu); -+ cpu_synchronize_post_reset(cs); -+ } -+ -+ if (dev->hotplugged && kvm_enabled()) { -+ resume_all_vcpus(); -+ } -+ -+ if (vms->acpi_dev) { -+ hotplug_handler_plug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err); -+ if (local_err) { -+ goto out; -+ } -+ } -+ -+ vms->boot_cpus++; -+ if (vms->fw_cfg) { -+ fw_cfg_modify_i16(vms->fw_cfg, FW_CFG_NB_CPUS, vms->boot_cpus); -+ } -+ -+ cpu_slot = &ms->possible_cpus->cpus[ncpu]; -+ cpu_slot->cpu = OBJECT(dev); -+out: -+ error_propagate(errp, local_err); - } - - static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev, -@@ -2940,6 +3041,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) - mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); - mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; - mc->kvm_type = virt_kvm_type; -+ mc->has_hotpluggable_cpus = true; - assert(!mc->get_hotplug_handler); - mc->get_hotplug_handler = virt_machine_get_hotplug_handler; - hc->pre_plug = virt_machine_device_pre_plug_cb; -diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c -index 9e3241b430..b8d1d820cb 100644 ---- a/hw/core/cpu-common.c -+++ b/hw/core/cpu-common.c -@@ -208,6 +208,10 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) - - if (dev->hotplugged) { - cpu_synchronize_post_init(cpu); -+ -+#ifdef __aarch64__ -+ if (!kvm_enabled()) -+#endif - cpu_resume(cpu); - } - -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index c371d377e0..4ddee19b18 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -168,6 +168,7 @@ struct VirtMachineState { - uint32_t msi_phandle; - uint32_t iommu_phandle; - int psci_conduit; -+ uint32_t boot_cpus; - hwaddr highest_gpa; - DeviceState *gic; - DeviceState *acpi_dev; -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index 9fd8e57971..d550022f18 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -2580,6 +2580,8 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) - device_class_set_props(dc, arm_cpu_properties); - device_class_set_parent_reset(dc, arm_cpu_reset, &acc->parent_reset); - -+ dc->user_creatable = true; -+ - cc->class_by_name = arm_cpu_class_by_name; - cc->has_work = arm_cpu_has_work; - cc->dump_state = arm_cpu_dump_state; --- -2.27.0 - diff --git a/arm-virt-acpi-Extend-cpufreq-to-support-max_cpus.patch b/arm-virt-acpi-Extend-cpufreq-to-support-max_cpus.patch deleted file mode 100644 index 501573c5e2cd6e783537befb38024aa6d17b24bd..0000000000000000000000000000000000000000 --- a/arm-virt-acpi-Extend-cpufreq-to-support-max_cpus.patch +++ /dev/null @@ -1,66 +0,0 @@ -From e3522e63a2f14c3c7d8cd603099b6bb51087f43b Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Wed, 22 Apr 2020 19:52:58 +0800 -Subject: [PATCH] arm/virt/acpi: Extend cpufreq to support max_cpus - -We will support CPU hotplug soon, so extend memory region size to -allow hotplugged CPU access cpufreq space. - -Signed-off-by: Keqian Zhu ---- - hw/acpi/cpufreq.c | 15 ++++++--------- - 1 file changed, 6 insertions(+), 9 deletions(-) - -diff --git a/hw/acpi/cpufreq.c b/hw/acpi/cpufreq.c -index a84db490b3..a76f7b8fa2 100644 ---- a/hw/acpi/cpufreq.c -+++ b/hw/acpi/cpufreq.c -@@ -83,6 +83,7 @@ typedef struct CpuhzState { - uint32_t PerformanceLimited; - uint32_t LowestFreq; - uint32_t NominalFreq; -+ uint32_t num_cpu; - uint32_t reg_size; - } CpuhzState; - -@@ -93,10 +94,7 @@ static uint64_t cpufreq_read(void *opaque, hwaddr offset, unsigned size) - uint64_t r; - uint64_t n; - -- MachineState *ms = MACHINE(qdev_get_machine()); -- unsigned int smp_cpus = ms->smp.cpus; -- -- if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) { -+ if (offset >= s->num_cpu * CPPC_REG_PER_CPU_STRIDE) { - warn_report("cpufreq_read: offset 0x%lx out of range", offset); - return 0; - } -@@ -163,11 +161,10 @@ static uint64_t cpufreq_read(void *opaque, hwaddr offset, unsigned size) - static void cpufreq_write(void *opaque, hwaddr offset, - uint64_t value, unsigned size) - { -+ CpuhzState *s = CPUFREQ(opaque); - uint64_t n; -- MachineState *ms = MACHINE(qdev_get_machine()); -- unsigned int smp_cpus = ms->smp.cpus; - -- if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) { -+ if (offset >= s->num_cpu * CPPC_REG_PER_CPU_STRIDE) { - error_printf("cpufreq_write: offset 0x%lx out of range", offset); - return; - } -@@ -248,9 +245,9 @@ static void cpufreq_init(Object *obj) - CpuhzState *s = CPUFREQ(obj); - - MachineState *ms = MACHINE(qdev_get_machine()); -- unsigned int smp_cpus = ms->smp.cpus; -+ s->num_cpu = ms->smp.max_cpus; - -- s->reg_size = smp_cpus * CPPC_REG_PER_CPU_STRIDE; -+ s->reg_size = s->num_cpu * CPPC_REG_PER_CPU_STRIDE; - if (s->reg_size > MAX_SUPPORT_SPACE) { - error_report("Required space 0x%x excesses the max support 0x%x", - s->reg_size, MAX_SUPPORT_SPACE); --- -2.27.0 - diff --git a/arm-virt-acpi-Factor-out-CPPC-building-from-DSDT-CPU.patch b/arm-virt-acpi-Factor-out-CPPC-building-from-DSDT-CPU.patch deleted file mode 100644 index fe171fe867386edc37f5ae7a84868623699549f4..0000000000000000000000000000000000000000 --- a/arm-virt-acpi-Factor-out-CPPC-building-from-DSDT-CPU.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 06837491e2ece2fdd6fe6cc8572aaab52fbdcb3e Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Wed, 22 Apr 2020 15:58:27 +0800 -Subject: [PATCH] arm/virt/acpi: Factor out CPPC building from DSDT CPU aml - -When CPU hotplug is enabled, we will use build_cpus_aml instead of -acpi_dsdt_add_cpus, so factor out CPPC building and we can reuse it -in build_cpus_aml. - -Signed-off-by: Keqian Zhu ---- - hw/arm/virt-acpi-build.c | 33 +++++++++++++++++----------- - hw/arm/virt.c | 1 + - include/hw/acpi/acpi_dev_interface.h | 2 ++ - include/hw/arm/virt.h | 2 ++ - 4 files changed, 25 insertions(+), 13 deletions(-) - -diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c -index 64b1ed8672..a93d223879 100644 ---- a/hw/arm/virt-acpi-build.c -+++ b/hw/arm/virt-acpi-build.c -@@ -120,8 +120,24 @@ static void acpi_dsdt_add_cppc(Aml *dev, uint64_t cpu_base, int *regs_offset) - aml_append(dev, aml_name_decl("_CPC", cpc)); - } - --static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms, -- const MemMapEntry *cppc_memmap) -+void virt_acpi_dsdt_cpu_cppc(AcpiDeviceIf *adev, int ncpu, int num_cpu, Aml *dev) -+{ -+ VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine()); -+ const MemMapEntry *cppc_memmap = &vms->memmap[VIRT_CPUFREQ]; -+ -+ /* -+ * Append _CPC and _PSD to support CPU frequence show -+ * Check CPPC available by DESIRED_PERF register -+ */ -+ if (cppc_regs_offset[DESIRED_PERF] != -1) { -+ acpi_dsdt_add_cppc(dev, -+ cppc_memmap->base + ncpu * CPPC_REG_PER_CPU_STRIDE, -+ cppc_regs_offset); -+ acpi_dsdt_add_psd(dev, num_cpu); -+ } -+} -+ -+static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms) - { - MachineState *ms = MACHINE(vms); - uint16_t i; -@@ -131,16 +147,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms, - aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007"))); - aml_append(dev, aml_name_decl("_UID", aml_int(i))); - -- /* -- * Append _CPC and _PSD to support CPU frequence show -- * Check CPPC available by DESIRED_PERF register -- */ -- if (cppc_regs_offset[DESIRED_PERF] != -1) { -- acpi_dsdt_add_cppc(dev, -- cppc_memmap->base + i * CPPC_REG_PER_CPU_STRIDE, -- cppc_regs_offset); -- acpi_dsdt_add_psd(dev, ms->smp.cpus); -- } -+ virt_acpi_dsdt_cpu_cppc(NULL, i, ms->smp.cpus, dev); - - aml_append(scope, dev); - } -@@ -940,7 +947,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - * the RTC ACPI device at all when using UEFI. - */ - scope = aml_scope("\\_SB"); -- acpi_dsdt_add_cpus(scope, vms, &memmap[VIRT_CPUFREQ]); -+ acpi_dsdt_add_cpus(scope, vms); - acpi_dsdt_add_uart(scope, &memmap[VIRT_UART], - (irqmap[VIRT_UART] + ARM_SPI_BASE)); - if (vmc->acpi_expose_flash) { -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 44c29070c4..3299d674c8 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -702,6 +702,7 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms) - - adevc = ACPI_DEVICE_IF_GET_CLASS(dev); - adevc->madt_cpu = virt_madt_cpu_entry; -+ adevc->cpu_cppc = virt_acpi_dsdt_cpu_cppc; - - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base); -diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h -index ea6056ab92..601931433a 100644 ---- a/include/hw/acpi/acpi_dev_interface.h -+++ b/include/hw/acpi/acpi_dev_interface.h -@@ -5,6 +5,7 @@ - #include "qom/object.h" - #include "hw/boards.h" - #include "hw/qdev-core.h" -+#include "hw/acpi/aml-build.h" - - /* These values are part of guest ABI, and can not be changed */ - typedef enum { -@@ -55,5 +56,6 @@ struct AcpiDeviceIfClass { - void (*madt_cpu)(AcpiDeviceIf *adev, int uid, - const CPUArchIdList *apic_ids, GArray *entry, - bool force_enabled); -+ void (*cpu_cppc)(AcpiDeviceIf *adev, int uid, int num_cpu, Aml *dev); - }; - #endif -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index 36639e8d3e..fe26709e1a 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -185,6 +185,8 @@ bool virt_is_acpi_enabled(VirtMachineState *vms); - void virt_madt_cpu_entry(AcpiDeviceIf *adev, int uid, - const CPUArchIdList *cpu_list, GArray *entry, - bool force_enabled); -+void virt_acpi_dsdt_cpu_cppc(AcpiDeviceIf *adev, int uid, -+ int num_cpu, Aml *dev); - - /* Return the number of used redistributor regions */ - static inline int virt_gicv3_redist_region_count(VirtMachineState *vms) --- -2.27.0 - diff --git a/arm-virt-gic-Construct-irqs-connection-from-create_g.patch b/arm-virt-gic-Construct-irqs-connection-from-create_g.patch deleted file mode 100644 index c16cb0ecacb898a5348c2fe50f12b5ba79ff3f6e..0000000000000000000000000000000000000000 --- a/arm-virt-gic-Construct-irqs-connection-from-create_g.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 03e050611d6dc9909166fd31dd11abf6fd5012ea Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Sun, 5 Apr 2020 15:29:16 +0800 -Subject: [PATCH] arm/virt/gic: Construct irqs connection from create_gic - -Make the irqs can be connected to for individual CPU. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt.c | 90 ++++++++++++++++++++++++++++----------------------- - 1 file changed, 49 insertions(+), 41 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 149e0245d7..0af0a996a1 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -772,6 +772,54 @@ static void create_v2m(VirtMachineState *vms) - vms->msi_controller = VIRT_MSI_CTRL_GICV2M; - } - -+static void connect_gic_cpu_irqs(VirtMachineState *vms, int i) -+{ -+ DeviceState *cpudev = DEVICE(qemu_get_cpu(i)); -+ SysBusDevice *gicbusdev = SYS_BUS_DEVICE(vms->gic); -+ int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS; -+ int num_cpus = object_property_get_uint(OBJECT(vms->gic), "num-cpu", NULL); -+ int gic_type = vms->gic_version; -+ int irq; -+ /* Mapping from the output timer irq lines from the CPU to the -+ * GIC PPI inputs we use for the virt board. -+ */ -+ const int timer_irq[] = { -+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ, -+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ, -+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ, -+ [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ, -+ }; -+ -+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) { -+ qdev_connect_gpio_out(cpudev, irq, -+ qdev_get_gpio_in(vms->gic, -+ ppibase + timer_irq[irq])); -+ } -+ -+ if (gic_type == 3) { -+ qemu_irq irq = qdev_get_gpio_in(vms->gic, -+ ppibase + ARCH_GIC_MAINT_IRQ); -+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", -+ 0, irq); -+ } else if (vms->virt) { -+ qemu_irq irq = qdev_get_gpio_in(vms->gic, -+ ppibase + ARCH_GIC_MAINT_IRQ); -+ sysbus_connect_irq(gicbusdev, i + 4 * num_cpus, irq); -+ } -+ -+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, -+ qdev_get_gpio_in(vms->gic, ppibase -+ + VIRTUAL_PMU_IRQ)); -+ -+ sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); -+ sysbus_connect_irq(gicbusdev, i + num_cpus, -+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); -+ sysbus_connect_irq(gicbusdev, i + 2 * num_cpus, -+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); -+ sysbus_connect_irq(gicbusdev, i + 3 * num_cpus, -+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); -+} -+ - static void create_gic(VirtMachineState *vms, MemoryRegion *mem) - { - MachineState *ms = MACHINE(vms); -@@ -849,47 +897,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem) - * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs. - */ - for (i = 0; i < smp_cpus; i++) { -- DeviceState *cpudev = DEVICE(qemu_get_cpu(i)); -- int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS; -- int irq; -- /* Mapping from the output timer irq lines from the CPU to the -- * GIC PPI inputs we use for the virt board. -- */ -- const int timer_irq[] = { -- [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ, -- [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ, -- [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ, -- [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ, -- }; -- -- for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) { -- qdev_connect_gpio_out(cpudev, irq, -- qdev_get_gpio_in(vms->gic, -- ppibase + timer_irq[irq])); -- } -- -- if (type == 3) { -- qemu_irq irq = qdev_get_gpio_in(vms->gic, -- ppibase + ARCH_GIC_MAINT_IRQ); -- qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", -- 0, irq); -- } else if (vms->virt) { -- qemu_irq irq = qdev_get_gpio_in(vms->gic, -- ppibase + ARCH_GIC_MAINT_IRQ); -- sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq); -- } -- -- qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, -- qdev_get_gpio_in(vms->gic, ppibase -- + VIRTUAL_PMU_IRQ)); -- -- sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); -- sysbus_connect_irq(gicbusdev, i + smp_cpus, -- qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); -- sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus, -- qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); -- sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus, -- qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); -+ connect_gic_cpu_irqs(vms, i); - } - - fdt_add_gic_node(vms); --- -2.27.0 - diff --git a/arm64-Add-the-cpufreq-device-to-show-cpufreq-info-to.patch b/arm64-Add-the-cpufreq-device-to-show-cpufreq-info-to.patch deleted file mode 100644 index 005ac1e8d8ba2b927c4a4e5644d26cb83a3e50d6..0000000000000000000000000000000000000000 --- a/arm64-Add-the-cpufreq-device-to-show-cpufreq-info-to.patch +++ /dev/null @@ -1,616 +0,0 @@ -From e7e28e79988eb671051d0d2af0eb010314c83d41 Mon Sep 17 00:00:00 2001 -From: Ying Fang -Date: Tue, 8 Feb 2022 21:01:09 +0800 -Subject: [PATCH 24/24] arm64: Add the cpufreq device to show cpufreq info to - guest - -On ARM64 platform, cpu frequency is retrieved via ACPI CPPC. -A virtual cpufreq device based on ACPI CPPC is created to -present cpu frequency info to the guest. - -The default frequency is set to host cpu nominal frequency, -which is obtained from the host CPPC sysfs. Other performance -data are set to the same value, since we don't support guest -performance scaling here. - -Performance counters are also not emulated and they simply -return 1 if read, and guest should fallback to use desired -performance value as the current performance. - -Guest kernel version above 4.18 is required to make it work. - -This series is backported from: -https://patchwork.kernel.org/cover/11379943/ - -Signed-off-by: Ying Fang -Signed-off-by: Yanan Wang ---- - configs/devices/aarch64-softmmu/default.mak | 1 + - hw/acpi/aml-build.c | 22 ++ - hw/acpi/cpufreq.c | 283 ++++++++++++++++++++ - hw/acpi/meson.build | 1 + - hw/arm/virt-acpi-build.c | 77 +++++- - hw/arm/virt.c | 13 + - hw/char/Kconfig | 4 + - include/hw/acpi/acpi-defs.h | 38 +++ - include/hw/acpi/aml-build.h | 3 + - include/hw/arm/virt.h | 1 + - tests/data/acpi/virt/DSDT | Bin 5196 -> 5669 bytes - tests/data/acpi/virt/DSDT.memhp | Bin 6557 -> 7030 bytes - tests/data/acpi/virt/DSDT.numamem | Bin 5196 -> 5669 bytes - tests/data/acpi/virt/DSDT.pxb | Bin 7679 -> 8152 bytes - 14 files changed, 441 insertions(+), 2 deletions(-) - create mode 100644 hw/acpi/cpufreq.c - -diff --git a/configs/devices/aarch64-softmmu/default.mak b/configs/devices/aarch64-softmmu/default.mak -index cf43ac8da1..c7a710a0f1 100644 ---- a/configs/devices/aarch64-softmmu/default.mak -+++ b/configs/devices/aarch64-softmmu/default.mak -@@ -6,3 +6,4 @@ include ../arm-softmmu/default.mak - CONFIG_XLNX_ZYNQMP_ARM=y - CONFIG_XLNX_VERSAL=y - CONFIG_SBSA_REF=y -+CONFIG_CPUFREQ=y -diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c -index bebf49622b..c4edaafa4a 100644 ---- a/hw/acpi/aml-build.c -+++ b/hw/acpi/aml-build.c -@@ -1554,6 +1554,28 @@ Aml *aml_sleep(uint64_t msec) - return var; - } - -+/* ACPI 5.0b: 6.4.3.7 Generic Register Descriptor */ -+Aml *aml_generic_register(AmlRegionSpace rs, uint8_t reg_width, -+ uint8_t reg_offset, AmlAccessType type, uint64_t addr) -+{ -+ int i; -+ Aml *var = aml_alloc(); -+ build_append_byte(var->buf, 0x82); /* Generic Register Descriptor */ -+ build_append_byte(var->buf, 0x0C); /* Length, bits[7:0] value = 0x0C */ -+ build_append_byte(var->buf, 0); /* Length, bits[15:8] value = 0 */ -+ build_append_byte(var->buf, rs); /* Address Space ID */ -+ build_append_byte(var->buf, reg_width); /* Register Bit Width */ -+ build_append_byte(var->buf, reg_offset); /* Register Bit Offset */ -+ build_append_byte(var->buf, type); /* Access Size */ -+ -+ /* Register address */ -+ for (i = 0; i < 8; i++) { -+ build_append_byte(var->buf, extract64(addr, i * 8, 8)); -+ } -+ -+ return var; -+} -+ - static uint8_t Hex2Byte(const char *src) - { - int hi, lo; -diff --git a/hw/acpi/cpufreq.c b/hw/acpi/cpufreq.c -new file mode 100644 -index 0000000000..a84db490b3 ---- /dev/null -+++ b/hw/acpi/cpufreq.c -@@ -0,0 +1,283 @@ -+/* -+ * ACPI CPPC register device -+ * -+ * Support for showing CPU frequency in guest OS. -+ * -+ * Copyright (c) 2019 HUAWEI TECHNOLOGIES CO.,LTD. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, see . -+ */ -+ -+#include "qemu/osdep.h" -+#include "hw/sysbus.h" -+#include "chardev/char.h" -+#include "qemu/log.h" -+#include "trace.h" -+#include "qemu/option.h" -+#include "sysemu/sysemu.h" -+#include "hw/acpi/acpi-defs.h" -+#include "qemu/cutils.h" -+#include "qemu/error-report.h" -+#include "hw/boards.h" -+ -+#define TYPE_CPUFREQ "cpufreq" -+#define CPUFREQ(obj) OBJECT_CHECK(CpuhzState, (obj), TYPE_CPUFREQ) -+#define NOMINAL_FREQ_FILE "/sys/devices/system/cpu/cpu0/acpi_cppc/nominal_freq" -+#define CPU_MAX_FREQ_FILE "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" -+#define HZ_MAX_LENGTH 1024 -+#define MAX_SUPPORT_SPACE 0x10000 -+ -+/* -+ * Since Hi1616 will not support CPPC, we simply use its nominal frequency as -+ * the default. -+ */ -+#define DEFAULT_HZ 2400 -+ -+int cppc_regs_offset[CPPC_REG_COUNT] = { -+ [HIGHEST_PERF] = 0, -+ [NOMINAL_PERF] = 4, -+ [LOW_NON_LINEAR_PERF] = 8, -+ [LOWEST_PERF] = 12, -+ [GUARANTEED_PERF] = 16, -+ [DESIRED_PERF] = 20, -+ [MIN_PERF] = -1, -+ [MAX_PERF] = -1, -+ [PERF_REDUC_TOLERANCE] = -1, -+ [TIME_WINDOW] = -1, -+ [CTR_WRAP_TIME] = -1, -+ [REFERENCE_CTR] = 24, -+ [DELIVERED_CTR] = 32, -+ [PERF_LIMITED] = 40, -+ [ENABLE] = -1, -+ [AUTO_SEL_ENABLE] = -1, -+ [AUTO_ACT_WINDOW] = -1, -+ [ENERGY_PERF] = -1, -+ [REFERENCE_PERF] = -1, -+ [LOWEST_FREQ] = 44, -+ [NOMINAL_FREQ] = 48, -+}; -+ -+typedef struct CpuhzState { -+ SysBusDevice parent_obj; -+ -+ MemoryRegion iomem; -+ uint32_t HighestPerformance; -+ uint32_t NominalPerformance; -+ uint32_t LowestNonlinearPerformance; -+ uint32_t LowestPerformance; -+ uint32_t GuaranteedPerformance; -+ uint32_t DesiredPerformance; -+ uint64_t ReferencePerformanceCounter; -+ uint64_t DeliveredPerformanceCounter; -+ uint32_t PerformanceLimited; -+ uint32_t LowestFreq; -+ uint32_t NominalFreq; -+ uint32_t reg_size; -+} CpuhzState; -+ -+ -+static uint64_t cpufreq_read(void *opaque, hwaddr offset, unsigned size) -+{ -+ CpuhzState *s = (CpuhzState *)opaque; -+ uint64_t r; -+ uint64_t n; -+ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ unsigned int smp_cpus = ms->smp.cpus; -+ -+ if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) { -+ warn_report("cpufreq_read: offset 0x%lx out of range", offset); -+ return 0; -+ } -+ -+ n = offset % CPPC_REG_PER_CPU_STRIDE; -+ switch (n) { -+ case 0: -+ r = s->HighestPerformance; -+ break; -+ case 4: -+ r = s->NominalPerformance; -+ break; -+ case 8: -+ r = s->LowestNonlinearPerformance; -+ break; -+ case 12: -+ r = s->LowestPerformance; -+ break; -+ case 16: -+ r = s->GuaranteedPerformance; -+ break; -+ case 20: -+ r = s->DesiredPerformance; -+ break; -+ /* -+ * We don't have real counters and it is hard to emulate, so always set the -+ * counter value to 1 to rely on Linux to use the DesiredPerformance value -+ * directly. -+ */ -+ case 24: -+ r = s->ReferencePerformanceCounter; -+ break; -+ /* -+ * Guest may still access the register by 32bit; add the process to -+ * eliminate unnecessary warnings. -+ */ -+ case 28: -+ r = s->ReferencePerformanceCounter >> 32; -+ break; -+ case 32: -+ r = s->DeliveredPerformanceCounter; -+ break; -+ case 36: -+ r = s->DeliveredPerformanceCounter >> 32; -+ break; -+ -+ case 40: -+ r = s->PerformanceLimited; -+ break; -+ case 44: -+ r = s->LowestFreq; -+ break; -+ case 48: -+ r = s->NominalFreq; -+ break; -+ default: -+ error_printf("cpufreq_read: Bad offset 0x%lx\n", offset); -+ r = 0; -+ break; -+ } -+ return r; -+} -+ -+static void cpufreq_write(void *opaque, hwaddr offset, -+ uint64_t value, unsigned size) -+{ -+ uint64_t n; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ unsigned int smp_cpus = ms->smp.cpus; -+ -+ if (offset >= smp_cpus * CPPC_REG_PER_CPU_STRIDE) { -+ error_printf("cpufreq_write: offset 0x%lx out of range", offset); -+ return; -+ } -+ -+ n = offset % CPPC_REG_PER_CPU_STRIDE; -+ -+ switch (n) { -+ case 20: -+ break; -+ default: -+ error_printf("cpufreq_write: Bad offset 0x%lx\n", offset); -+ } -+} -+ -+static uint32_t CPPC_Read(const char *hostpath) -+{ -+ int fd; -+ char buffer[HZ_MAX_LENGTH] = { 0 }; -+ uint64_t hz; -+ int len; -+ const char *endptr = NULL; -+ int ret; -+ -+ fd = qemu_open_old(hostpath, O_RDONLY); -+ if (fd < 0) { -+ return 0; -+ } -+ -+ len = read(fd, buffer, HZ_MAX_LENGTH); -+ qemu_close(fd); -+ if (len <= 0) { -+ return 0; -+ } -+ ret = qemu_strtoul(buffer, &endptr, 0, &hz); -+ if (ret < 0) { -+ return 0; -+ } -+ return (uint32_t)hz; -+} -+ -+static const MemoryRegionOps cpufreq_ops = { -+ .read = cpufreq_read, -+ .write = cpufreq_write, -+ .endianness = DEVICE_NATIVE_ENDIAN, -+}; -+ -+static void hz_init(CpuhzState *s) -+{ -+ uint32_t hz; -+ -+ hz = CPPC_Read(NOMINAL_FREQ_FILE); -+ if (hz == 0) { -+ hz = CPPC_Read(CPU_MAX_FREQ_FILE); -+ if (hz == 0) { -+ hz = DEFAULT_HZ; -+ } else { -+ /* Value in CpuMaxFrequency is in KHz unit; convert to MHz */ -+ hz = hz / 1000; -+ } -+ } -+ -+ s->HighestPerformance = hz; -+ s->NominalPerformance = hz; -+ s->LowestNonlinearPerformance = hz; -+ s->LowestPerformance = hz; -+ s->GuaranteedPerformance = hz; -+ s->DesiredPerformance = hz; -+ s->ReferencePerformanceCounter = 1; -+ s->DeliveredPerformanceCounter = 1; -+ s->PerformanceLimited = 0; -+ s->LowestFreq = hz; -+ s->NominalFreq = hz; -+} -+ -+static void cpufreq_init(Object *obj) -+{ -+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj); -+ CpuhzState *s = CPUFREQ(obj); -+ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ unsigned int smp_cpus = ms->smp.cpus; -+ -+ s->reg_size = smp_cpus * CPPC_REG_PER_CPU_STRIDE; -+ if (s->reg_size > MAX_SUPPORT_SPACE) { -+ error_report("Required space 0x%x excesses the max support 0x%x", -+ s->reg_size, MAX_SUPPORT_SPACE); -+ goto err_end; -+ } -+ -+ memory_region_init_io(&s->iomem, OBJECT(s), &cpufreq_ops, s, "cpufreq", -+ s->reg_size); -+ sysbus_init_mmio(sbd, &s->iomem); -+ hz_init(s); -+ return; -+ -+err_end: -+ /* Set desired perf register offset to -1 to indicate no support for CPPC */ -+ cppc_regs_offset[DESIRED_PERF] = -1; -+} -+ -+static const TypeInfo cpufreq_arm_info = { -+ .name = TYPE_CPUFREQ, -+ .parent = TYPE_SYS_BUS_DEVICE, -+ .instance_size = sizeof(CpuhzState), -+ .instance_init = cpufreq_init, -+}; -+ -+static void cpufreq_register_types(void) -+{ -+ type_register_static(&cpufreq_arm_info); -+} -+ -+type_init(cpufreq_register_types) -diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build -index adf6347bc4..448ea6afb4 100644 ---- a/hw/acpi/meson.build -+++ b/hw/acpi/meson.build -@@ -25,6 +25,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_X86_ICH', if_true: files('ich9.c', 'tco.c')) - acpi_ss.add(when: 'CONFIG_IPMI', if_true: files('ipmi.c'), if_false: files('ipmi-stub.c')) - acpi_ss.add(when: 'CONFIG_PC', if_false: files('acpi-x86-stub.c')) - acpi_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c')) -+acpi_ss.add(when: 'CONFIG_CPUFREQ', if_true: files('cpufreq.c')) - softmmu_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c')) - softmmu_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss) - softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-stub.c', 'aml-build-stub.c', -diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c -index 674f902652..1ca705654b 100644 ---- a/hw/arm/virt-acpi-build.c -+++ b/hw/arm/virt-acpi-build.c -@@ -60,7 +60,68 @@ - - #define ACPI_BUILD_TABLE_SIZE 0x20000 - --static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms) -+static void acpi_dsdt_add_psd(Aml *dev, int cpus) -+{ -+ Aml *pkg; -+ Aml *sub; -+ -+ sub = aml_package(5); -+ aml_append(sub, aml_int(5)); -+ aml_append(sub, aml_int(0)); -+ /* Assume all vCPUs belong to the same domain */ -+ aml_append(sub, aml_int(0)); -+ /* SW_ANY: OSPM coordinate, initiate on any processor */ -+ aml_append(sub, aml_int(0xFD)); -+ aml_append(sub, aml_int(cpus)); -+ -+ pkg = aml_package(1); -+ aml_append(pkg, sub); -+ -+ aml_append(dev, aml_name_decl("_PSD", pkg)); -+} -+ -+static void acpi_dsdt_add_cppc(Aml *dev, uint64_t cpu_base, int *regs_offset) -+{ -+ Aml *cpc; -+ int i; -+ -+ /* Use version 3 of CPPC table from ACPI 6.3 */ -+ cpc = aml_package(23); -+ aml_append(cpc, aml_int(23)); -+ aml_append(cpc, aml_int(3)); -+ -+ for (i = 0; i < CPPC_REG_COUNT; i++) { -+ Aml *res; -+ uint8_t reg_width; -+ uint8_t acc_type; -+ uint64_t addr; -+ -+ if (regs_offset[i] == -1) { -+ reg_width = 0; -+ acc_type = AML_ANY_ACC; -+ addr = 0; -+ } else { -+ addr = cpu_base + regs_offset[i]; -+ if (i == REFERENCE_CTR || i == DELIVERED_CTR) { -+ reg_width = 64; -+ acc_type = AML_QWORD_ACC; -+ } else { -+ reg_width = 32; -+ acc_type = AML_DWORD_ACC; -+ } -+ } -+ -+ res = aml_resource_template(); -+ aml_append(res, aml_generic_register(AML_SYSTEM_MEMORY, reg_width, 0, -+ acc_type, addr)); -+ aml_append(cpc, res); -+ } -+ -+ aml_append(dev, aml_name_decl("_CPC", cpc)); -+} -+ -+static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms, -+ const MemMapEntry *cppc_memmap) - { - MachineState *ms = MACHINE(vms); - uint16_t i; -@@ -69,6 +130,18 @@ static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms) - Aml *dev = aml_device("C%.03X", i); - aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007"))); - aml_append(dev, aml_name_decl("_UID", aml_int(i))); -+ -+ /* -+ * Append _CPC and _PSD to support CPU frequence show -+ * Check CPPC available by DESIRED_PERF register -+ */ -+ if (cppc_regs_offset[DESIRED_PERF] != -1) { -+ acpi_dsdt_add_cppc(dev, -+ cppc_memmap->base + i * CPPC_REG_PER_CPU_STRIDE, -+ cppc_regs_offset); -+ acpi_dsdt_add_psd(dev, ms->smp.cpus); -+ } -+ - aml_append(scope, dev); - } - } -@@ -858,7 +931,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) - * the RTC ACPI device at all when using UEFI. - */ - scope = aml_scope("\\_SB"); -- acpi_dsdt_add_cpus(scope, vms); -+ acpi_dsdt_add_cpus(scope, vms, &memmap[VIRT_CPUFREQ]); - acpi_dsdt_add_uart(scope, &memmap[VIRT_UART], - (irqmap[VIRT_UART] + ARM_SPI_BASE)); - if (vmc->acpi_expose_flash) { -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 529c0d38b6..0538d258fa 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -154,6 +154,7 @@ static const MemMapEntry base_memmap[] = { - [VIRT_PVTIME] = { 0x090a0000, 0x00010000 }, - [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 }, - [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, -+ [VIRT_CPUFREQ] = { 0x0b000000, 0x00010000 }, - /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ - [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 }, - [VIRT_SECURE_MEM] = { 0x0e000000, 0x01000000 }, -@@ -931,6 +932,16 @@ static void create_uart(const VirtMachineState *vms, int uart, - g_free(nodename); - } - -+static void create_cpufreq(const VirtMachineState *vms, MemoryRegion *mem) -+{ -+ hwaddr base = vms->memmap[VIRT_CPUFREQ].base; -+ DeviceState *dev = qdev_new("cpufreq"); -+ SysBusDevice *s = SYS_BUS_DEVICE(dev); -+ -+ sysbus_realize_and_unref(s, &error_fatal); -+ memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0)); -+} -+ - static void create_rtc(const VirtMachineState *vms) - { - char *nodename; -@@ -2190,6 +2201,8 @@ static void machvirt_init(MachineState *machine) - - create_uart(vms, VIRT_UART, sysmem, serial_hd(0)); - -+ create_cpufreq(vms, sysmem); -+ - if (vms->secure) { - create_secure_ram(vms, secure_sysmem, secure_tag_sysmem); - create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1)); -diff --git a/hw/char/Kconfig b/hw/char/Kconfig -index 6b6cf2fc1d..335a60c2c1 100644 ---- a/hw/char/Kconfig -+++ b/hw/char/Kconfig -@@ -71,3 +71,7 @@ config GOLDFISH_TTY - - config SHAKTI_UART - bool -+ -+config CPUFREQ -+ bool -+ default y -diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h -index c97e8633ad..ab86583228 100644 ---- a/include/hw/acpi/acpi-defs.h -+++ b/include/hw/acpi/acpi-defs.h -@@ -92,4 +92,42 @@ typedef struct AcpiFadtData { - #define ACPI_FADT_ARM_PSCI_COMPLIANT (1 << 0) - #define ACPI_FADT_ARM_PSCI_USE_HVC (1 << 1) - -+/* -+ * CPPC register definition from kernel header -+ * include/acpi/cppc_acpi.h -+ * The last element is newly added for easy use -+ */ -+enum cppc_regs { -+ HIGHEST_PERF, -+ NOMINAL_PERF, -+ LOW_NON_LINEAR_PERF, -+ LOWEST_PERF, -+ GUARANTEED_PERF, -+ DESIRED_PERF, -+ MIN_PERF, -+ MAX_PERF, -+ PERF_REDUC_TOLERANCE, -+ TIME_WINDOW, -+ CTR_WRAP_TIME, -+ REFERENCE_CTR, -+ DELIVERED_CTR, -+ PERF_LIMITED, -+ ENABLE, -+ AUTO_SEL_ENABLE, -+ AUTO_ACT_WINDOW, -+ ENERGY_PERF, -+ REFERENCE_PERF, -+ LOWEST_FREQ, -+ NOMINAL_FREQ, -+ CPPC_REG_COUNT, -+}; -+ -+#define CPPC_REG_PER_CPU_STRIDE 0x40 -+ -+/* -+ * Offset for each CPPC register; -1 for unavailable -+ * The whole register space is unavailable if desired perf offset is -1. -+ */ -+extern int cppc_regs_offset[CPPC_REG_COUNT]; -+ - #endif -diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h -index 8e8ad8029e..2e00d2e208 100644 ---- a/include/hw/acpi/aml-build.h -+++ b/include/hw/acpi/aml-build.h -@@ -429,6 +429,9 @@ Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz, - uint8_t channel); - Aml *aml_sleep(uint64_t msec); - Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source); -+Aml *aml_generic_register(AmlRegionSpace rs, uint8_t reg_width, -+ uint8_t reg_offset, AmlAccessType type, -+ uint64_t addr); - - /* Block AML object primitives */ - Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index dc6b66ffc8..a4356cf736 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -70,6 +70,7 @@ enum { - VIRT_GIC_REDIST, - VIRT_SMMU, - VIRT_UART, -+ VIRT_CPUFREQ, - VIRT_MMIO, - VIRT_RTC, - VIRT_FW_CFG, - --- -2.27.0 - diff --git a/artist-set-memory-region-owners-for-buffers-to-the-a.patch b/artist-set-memory-region-owners-for-buffers-to-the-a.patch deleted file mode 100644 index 4513e1e242c3ee0789b7c1facf98726a4d105285..0000000000000000000000000000000000000000 --- a/artist-set-memory-region-owners-for-buffers-to-the-a.patch +++ /dev/null @@ -1,37 +0,0 @@ -From db2e1d340763e23180e4709e4ddf33390f2e49ea Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 17 Nov 2023 09:00:01 +0000 -Subject: [PATCH] artist: set memory region owners for buffers to the artist - device mainline inclusion commit 39fbaeca096a9bf6cbe2af88572c1cb2aa62aa8c - category: bugfix - ---------------------------------------------------------------- - -This fixes the output of "info qom-tree" so that the buffers appear as children -of the artist device, rather than underneath the "unattached" container. - -Signed-off-by: Mark Cave-Ayland -Message-Id: <20220624160839.886649-1-mark.cave-ayland@ilande.co.uk> -Reviewed-by: Helge Deller - -Signed-off-by: tangbinzy ---- - hw/display/artist.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/display/artist.c b/hw/display/artist.c -index 21b7fd1b44..1767203477 100644 ---- a/hw/display/artist.c -+++ b/hw/display/artist.c -@@ -1359,7 +1359,7 @@ static void artist_create_buffer(ARTISTState *s, const char *name, - { - struct vram_buffer *buf = s->vram_buffer + idx; - -- memory_region_init_ram(&buf->mr, NULL, name, width * height, -+ memory_region_init_ram(&buf->mr, OBJECT(s), name, width * height, - &error_fatal); - memory_region_add_subregion_overlap(&s->mem_as_root, *offset, &buf->mr, 0); - --- -2.27.0 - diff --git a/balloon-Fix-a-misleading-error-message.patch b/balloon-Fix-a-misleading-error-message.patch deleted file mode 100644 index e0f7cdc81da2c8af25954d5783b00a6eb8a5093d..0000000000000000000000000000000000000000 --- a/balloon-Fix-a-misleading-error-message.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0c24a55d582e8219b64f2090cbdd21027d496bb1 Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Mon, 27 Nov 2023 10:44:31 +0800 -Subject: [PATCH] balloon: Fix a misleading error message - -cherry picked from eeef44b3a583637265f602882a0d058a52e3a33b - -The error message - - {"execute": "balloon", "arguments":{"value": -1}} - {"error": {"class": "GenericError", "desc": "Parameter 'target' expects a size"}} - -points to 'target' instead of 'value'. Fix: - - {"error": {"class": "GenericError", "desc": "Parameter 'value' expects a size"}} - -Root cause: qmp_balloon()'s parameter is named @target. Rename it to -@value to match the QAPI schema. - -Signed-off-by: Markus Armbruster -Message-ID: <20231031111059.3407803-7-armbru@redhat.com> -Reviewed-by: David Hildenbrand -Reviewed-by: Michael S. Tsirkin -Tested-by: Mario Casquero - -Signed-off-by: boringandboring ---- - softmmu/balloon.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/softmmu/balloon.c b/softmmu/balloon.c -index e0e8969a4b..fda7af832e 100644 ---- a/softmmu/balloon.c -+++ b/softmmu/balloon.c -@@ -90,17 +90,17 @@ BalloonInfo *qmp_query_balloon(Error **errp) - return info; - } - --void qmp_balloon(int64_t target, Error **errp) -+void qmp_balloon(int64_t value, Error **errp) - { - if (!have_balloon(errp)) { - return; - } - -- if (target <= 0) { -- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "target", "a size"); -+ if (value <= 0) { -+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "value", "a size"); - return; - } - -- trace_balloon_event(balloon_opaque, target); -- balloon_event_fn(balloon_opaque, target); -+ trace_balloon_event(balloon_opaque, value); -+ balloon_event_fn(balloon_opaque, value); - } --- -2.27.0 - diff --git a/bios-tables-test-Allow-changes-to-q35-SSDT.dimmpxm-f.patch b/bios-tables-test-Allow-changes-to-q35-SSDT.dimmpxm-f.patch deleted file mode 100644 index 8228abcd539d2ad17cd911cfc7a5281b7beda939..0000000000000000000000000000000000000000 --- a/bios-tables-test-Allow-changes-to-q35-SSDT.dimmpxm-f.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 00c4115a1388ee72295b99fce1f6ad49bf761134 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Thu, 10 Feb 2022 17:08:08 +0800 -Subject: [PATCH] bios-tables-test: Allow changes to q35/SSDT.dimmpxm file - -List test/data/acpi/q35/SSDT.dimmpxm as the expected files allowed to -be changed in tests/qtest/bios-tables-test-allowed-diff.h - -Signed-off-by: Yan Wang ---- - tests/qtest/bios-tables-test-allowed-diff.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index dfb8523c8b..81148a604f 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1 +1,2 @@ - /* List of comma-separated changed AML files to ignore */ -+"tests/data/acpi/q35/SSDT.dimmpxm", --- -2.27.0 - diff --git a/bios-tables-test-Update-expected-q35-SSDT.dimmpxm-fi.patch b/bios-tables-test-Update-expected-q35-SSDT.dimmpxm-fi.patch deleted file mode 100644 index 6cfa1f203d183536ae36b3eed2255310e0e4e50d..0000000000000000000000000000000000000000 --- a/bios-tables-test-Update-expected-q35-SSDT.dimmpxm-fi.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 8940f11a055da0a744d10b53cf999dea7967be25 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Thu, 10 Feb 2022 17:12:35 +0800 -Subject: [PATCH] bios-tables-test: Update expected q35/SSDT.dimmpxm file - -Run ./tests/data/acpi/rebuild-expected-aml.sh from build directory -to update q35/SSDT.dimmpxm file. Also empty bios-tables-test-allowed-diff.h. - -The disassembled differences between actual and expected SSDT.dimmpxm: - - /* - * Intel ACPI Component Architecture - * AML/ASL+ Disassembler version 20210604 (64-bit version) - * Copyright (c) 2000 - 2021 Intel Corporation - * - * Disassembling to symbolic ASL+ operators - * -- * Disassembly of tests/data/acpi/q35/SSDT.dimmpxm, Thu Feb 10 15:03:52 2022 -+ * Disassembly of /tmp/aml-CK68G1, Thu Feb 10 15:03:52 2022 - * - * Original Table Header: - * Signature "SSDT" - * Length 0x000002DE (734) - * Revision 0x01 -- * Checksum 0x06 -+ * Checksum 0x16 - * OEM ID "BOCHS " - * OEM Table ID "NVDIMM " - * OEM Revision 0x00000001 (1) - * Compiler ID "BXPC" - * Compiler Version 0x00000001 (1) - */ - DefinitionBlock ("", "SSDT", 1, "BOCHS ", "NVDIMM ", 0x00000001) - { - Scope (\_SB) - { - Device (NVDR) - { - Name (_HID, "ACPI0012" /* NVDIMM Root Device */) // _HID: Hardware ID - Method (NCAL, 5, Serialized) - { - Local6 = MEMA /* \MEMA */ -@@ -187,19 +187,19 @@ - { - Return (NCAL (Arg0, Arg1, Arg2, Arg3, 0x02)) - } - } - - Device (NV02) - { - Name (_ADR, 0x03) // _ADR: Address - Method (_DSM, 4, NotSerialized) // _DSM: Device-Specific Method - { - Return (NCAL (Arg0, Arg1, Arg2, Arg3, 0x03)) - } - } - } - } - -- Name (MEMA, 0x07FFF000) -+ Name (MEMA, 0x07FFE000) - } - -Signed-off-by: Yan Wang ---- - tests/data/acpi/q35/SSDT.dimmpxm | Bin 734 -> 734 bytes - tests/qtest/bios-tables-test-allowed-diff.h | 1 - - 2 files changed, 1 deletion(-) - -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index 81148a604f..dfb8523c8b 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1,2 +1 @@ - /* List of comma-separated changed AML files to ignore */ --"tests/data/acpi/q35/SSDT.dimmpxm", --- -2.27.0 - diff --git a/block-Add-error-retry-param-setting.patch b/block-Add-error-retry-param-setting.patch deleted file mode 100644 index 4facb3f8c1fca5e941ee5154bd2459ae8309b8f8..0000000000000000000000000000000000000000 --- a/block-Add-error-retry-param-setting.patch +++ /dev/null @@ -1,227 +0,0 @@ -From a58fda7b158441c645e143bf658d12914ffbc7b8 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:50 +0800 -Subject: [PATCH 6/7] block: Add error retry param setting - -Add "retry_interval" and "retry_timeout" parameter for drive and device -option. These parameter are valid only when werror/rerror=retry. - -eg. --drive file=image,rerror=retry,retry_interval=1000,retry_timeout=5000 - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - block/block-backend.c | 13 +++++++-- - blockdev.c | 50 ++++++++++++++++++++++++++++++++++ - hw/block/block.c | 10 +++++++ - include/hw/block/block.h | 7 ++++- - include/sysemu/block-backend.h | 5 ++++ - 5 files changed, 81 insertions(+), 4 deletions(-) - -diff --git a/block/block-backend.c b/block/block-backend.c -index 37e21c473e..d3d90a95a5 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -35,9 +35,6 @@ - - static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); - --/* block backend default retry interval */ --#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 -- - typedef struct BlockBackendAioNotifier { - void (*attached_aio_context)(AioContext *new_context, void *opaque); - void (*detach_aio_context)(void *opaque); -@@ -1766,6 +1763,16 @@ void blk_drain_all(void) - bdrv_drain_all_end(); - } - -+void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval) -+{ -+ blk->retry_interval = interval; -+} -+ -+void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout) -+{ -+ blk->retry_timeout = timeout; -+} -+ - static bool blk_error_retry_timeout(BlockBackend *blk) - { - /* No timeout set, infinite retries. */ -diff --git a/blockdev.c b/blockdev.c -index 6f1981635b..10a73fa423 100644 ---- a/blockdev.c -+++ b/blockdev.c -@@ -480,6 +480,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, - const char *buf; - int bdrv_flags = 0; - int on_read_error, on_write_error; -+ int64_t retry_interval, retry_timeout; - bool account_invalid, account_failed; - bool writethrough, read_only; - BlockBackend *blk; -@@ -572,6 +573,10 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, - } - } - -+ retry_interval = qemu_opt_get_number(opts, "retry_interval", -+ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL); -+ retry_timeout = qemu_opt_get_number(opts, "retry_timeout", 0); -+ - if (snapshot) { - bdrv_flags |= BDRV_O_SNAPSHOT; - } -@@ -635,6 +640,11 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, - - blk_set_enable_write_cache(blk, !writethrough); - blk_set_on_error(blk, on_read_error, on_write_error); -+ if (on_read_error == BLOCKDEV_ON_ERROR_RETRY || -+ on_write_error == BLOCKDEV_ON_ERROR_RETRY) { -+ blk_set_on_error_retry_interval(blk, retry_interval); -+ blk_set_on_error_retry_timeout(blk, retry_timeout); -+ } - - if (!monitor_add_blk(blk, id, errp)) { - blk_unref(blk); -@@ -761,6 +771,14 @@ QemuOptsList qemu_legacy_drive_opts = { - .name = "werror", - .type = QEMU_OPT_STRING, - .help = "write error action", -+ },{ -+ .name = "retry_interval", -+ .type = QEMU_OPT_NUMBER, -+ .help = "interval for retry action in millisecond", -+ },{ -+ .name = "retry_timeout", -+ .type = QEMU_OPT_NUMBER, -+ .help = "timeout for retry action in millisecond", - },{ - .name = "copy-on-read", - .type = QEMU_OPT_BOOL, -@@ -783,6 +801,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, - BlockInterfaceType type; - int max_devs, bus_id, unit_id, index; - const char *werror, *rerror; -+ int64_t retry_interval, retry_timeout; - bool read_only = false; - bool copy_on_read; - const char *filename; -@@ -990,6 +1009,29 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, - qdict_put_str(bs_opts, "rerror", rerror); - } - -+ if (qemu_opt_find(legacy_opts, "retry_interval")) { -+ if ((werror == NULL || strcmp(werror, "retry")) && -+ (rerror == NULL || strcmp(rerror, "retry"))) { -+ error_setg(errp, "retry_interval is only supported " -+ "by werror/rerror=retry"); -+ goto fail; -+ } -+ retry_interval = qemu_opt_get_number(legacy_opts, "retry_interval", -+ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL); -+ qdict_put_int(bs_opts, "retry_interval", retry_interval); -+ } -+ -+ if (qemu_opt_find(legacy_opts, "retry_timeout")) { -+ if ((werror == NULL || strcmp(werror, "retry")) && -+ (rerror == NULL || strcmp(rerror, "retry"))) { -+ error_setg(errp, "retry_timeout is only supported " -+ "by werror/rerror=retry"); -+ goto fail; -+ } -+ retry_timeout = qemu_opt_get_number(legacy_opts, "retry_timeout", 0); -+ qdict_put_int(bs_opts, "retry_timeout", retry_timeout); -+ } -+ - /* Actual block device init: Functionality shared with blockdev-add */ - blk = blockdev_init(filename, bs_opts, errp); - bs_opts = NULL; -@@ -3806,6 +3848,14 @@ QemuOptsList qemu_common_drive_opts = { - .name = "werror", - .type = QEMU_OPT_STRING, - .help = "write error action", -+ },{ -+ .name = "retry_interval", -+ .type = QEMU_OPT_NUMBER, -+ .help = "interval for retry action in millisecond", -+ },{ -+ .name = "retry_timeout", -+ .type = QEMU_OPT_NUMBER, -+ .help = "timeout for retry action in millisecond", - },{ - .name = BDRV_OPT_READ_ONLY, - .type = QEMU_OPT_BOOL, -diff --git a/hw/block/block.c b/hw/block/block.c -index d47ebf005a..26c0767552 100644 ---- a/hw/block/block.c -+++ b/hw/block/block.c -@@ -206,6 +206,16 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool readonly, - blk_set_enable_write_cache(blk, wce); - blk_set_on_error(blk, rerror, werror); - -+ if (rerror == BLOCKDEV_ON_ERROR_RETRY || -+ werror == BLOCKDEV_ON_ERROR_RETRY) { -+ if (conf->retry_interval >= 0) { -+ blk_set_on_error_retry_interval(blk, conf->retry_interval); -+ } -+ if (conf->retry_timeout >= 0) { -+ blk_set_on_error_retry_timeout(blk, conf->retry_timeout); -+ } -+ } -+ - return true; - } - -diff --git a/include/hw/block/block.h b/include/hw/block/block.h -index 5902c0440a..24fb7d77af 100644 ---- a/include/hw/block/block.h -+++ b/include/hw/block/block.h -@@ -33,6 +33,8 @@ typedef struct BlockConf { - bool share_rw; - BlockdevOnError rerror; - BlockdevOnError werror; -+ int64_t retry_interval; -+ int64_t retry_timeout; - } BlockConf; - - static inline unsigned int get_physical_block_exp(BlockConf *conf) -@@ -79,7 +81,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) - DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \ - BLOCKDEV_ON_ERROR_AUTO), \ - DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \ -- BLOCKDEV_ON_ERROR_AUTO) -+ BLOCKDEV_ON_ERROR_AUTO), \ -+ DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \ -+ -1), \ -+ DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1) - - /* Backend access helpers */ - -diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h -index 56a403883d..887c19ff5d 100644 ---- a/include/sysemu/block-backend.h -+++ b/include/sysemu/block-backend.h -@@ -25,6 +25,9 @@ - */ - #include "block/block.h" - -+/* block backend default retry interval */ -+#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 -+ - /* Callbacks for block device models */ - typedef struct BlockDevOps { - /* -@@ -198,6 +201,8 @@ void blk_inc_in_flight(BlockBackend *blk); - void blk_dec_in_flight(BlockBackend *blk); - void blk_drain(BlockBackend *blk); - void blk_drain_all(void); -+void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval); -+void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout); - void blk_error_retry_reset_timeout(BlockBackend *blk); - void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, - BlockdevOnError on_write_error); --- -2.27.0 - diff --git a/block-Add-sanity-check-when-setting-retry-parameters.patch b/block-Add-sanity-check-when-setting-retry-parameters.patch deleted file mode 100644 index d48fa5d654a4d5eb2e50b2336715bbeff40242a5..0000000000000000000000000000000000000000 --- a/block-Add-sanity-check-when-setting-retry-parameters.patch +++ /dev/null @@ -1,156 +0,0 @@ -From f329ec9bd971ba7776cadb57e7311bfb6da41060 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 18 Mar 2021 19:45:11 +0800 -Subject: [PATCH 9/9] block: Add sanity check when setting retry parameters - -Add sanity check when setting retry parameters to avoid invalid retry -configuration. - -Signed-off-by: Jiahui Cen -Signed-off-by: Alex Chen ---- - hw/core/qdev-prop-internal.h | 2 ++ - hw/core/qdev-properties-system.c | 45 +++++++++++++++++++++++++++++ - hw/core/qdev-properties.c | 4 +-- - include/hw/block/block.h | 7 +++-- - include/hw/qdev-properties-system.h | 8 +++++ - 5 files changed, 61 insertions(+), 5 deletions(-) - -diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h -index d7b77844fe..68b1b9d10c 100644 ---- a/hw/core/qdev-prop-internal.h -+++ b/hw/core/qdev-prop-internal.h -@@ -22,6 +22,8 @@ void qdev_propinfo_set_default_value_uint(ObjectProperty *op, - - void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp); -+void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp); - void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp); - -diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c -index 6a6ff03be7..b93ed9b4dd 100644 ---- a/hw/core/qdev-properties-system.c -+++ b/hw/core/qdev-properties-system.c -@@ -612,6 +612,51 @@ const PropertyInfo qdev_prop_blockdev_on_error = { - .set_default_value = qdev_propinfo_set_default_value_enum, - }; - -+static void set_retry_time(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ DeviceState *dev = DEVICE(obj); -+ Property *prop = opaque; -+ int64_t value, *ptr = object_field_prop_ptr(obj, prop); -+ Error *local_err = NULL; -+ -+ if (dev->realized) { -+ qdev_prop_set_after_realize(dev, name, errp); -+ return; -+ } -+ -+ visit_type_int64(v, name, &value, &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return; -+ } -+ -+ /* value should not be negative */ -+ if (value < 0) { -+ error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, -+ dev->id ? : "", name, (int64_t)value, 0L, LONG_MAX); -+ return; -+ } -+ -+ *ptr = value; -+} -+ -+const PropertyInfo qdev_prop_blockdev_retry_interval = { -+ .name = "BlockdevRetryInterval", -+ .description = "Interval for retry error handling policy", -+ .get = qdev_propinfo_get_int64, -+ .set = set_retry_time, -+ .set_default_value = qdev_propinfo_set_default_value_int, -+}; -+ -+const PropertyInfo qdev_prop_blockdev_retry_timeout = { -+ .name = "BlockdevRetryTimeout", -+ .description = "Timeout for retry error handling policy", -+ .get = qdev_propinfo_get_int64, -+ .set = set_retry_time, -+ .set_default_value = qdev_propinfo_set_default_value_int, -+}; -+ - /* --- BIOS CHS translation */ - - QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int)); -diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c -index c34aac6ebc..2d5f662663 100644 ---- a/hw/core/qdev-properties.c -+++ b/hw/core/qdev-properties.c -@@ -396,7 +396,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name, - visit_type_uint64(v, name, ptr, errp); - } - --static void get_int64(Object *obj, Visitor *v, const char *name, -+void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) - { - Property *prop = opaque; -@@ -423,7 +423,7 @@ const PropertyInfo qdev_prop_uint64 = { - - const PropertyInfo qdev_prop_int64 = { - .name = "int64", -- .get = get_int64, -+ .get = qdev_propinfo_get_int64, - .set = set_int64, - .set_default_value = qdev_propinfo_set_default_value_int, - }; -diff --git a/include/hw/block/block.h b/include/hw/block/block.h -index 24fb7d77af..282929e8f0 100644 ---- a/include/hw/block/block.h -+++ b/include/hw/block/block.h -@@ -82,9 +82,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) - BLOCKDEV_ON_ERROR_AUTO), \ - DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \ - BLOCKDEV_ON_ERROR_AUTO), \ -- DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \ -- -1), \ -- DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1) -+ DEFINE_PROP_BLOCKDEV_RETRY_INTERVAL("retry_interval", _state, \ -+ _conf.retry_interval, 1000), \ -+ DEFINE_PROP_BLOCKDEV_RETRY_TIMEOUT("retry_timeout", _state, \ -+ _conf.retry_timeout, 0) - - /* Backend access helpers */ - -diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h -index 0ac327ae60..906a027676 100644 ---- a/include/hw/qdev-properties-system.h -+++ b/include/hw/qdev-properties-system.h -@@ -9,6 +9,8 @@ extern const PropertyInfo qdev_prop_reserved_region; - extern const PropertyInfo qdev_prop_multifd_compression; - extern const PropertyInfo qdev_prop_losttickpolicy; - extern const PropertyInfo qdev_prop_blockdev_on_error; -+extern const PropertyInfo qdev_prop_blockdev_retry_interval; -+extern const PropertyInfo qdev_prop_blockdev_retry_timeout; - extern const PropertyInfo qdev_prop_bios_chs_trans; - extern const PropertyInfo qdev_prop_fdc_drive_type; - extern const PropertyInfo qdev_prop_drive; -@@ -47,6 +49,12 @@ extern const PropertyInfo qdev_prop_pcie_link_width; - #define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \ - DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \ - BlockdevOnError) -+#define DEFINE_PROP_BLOCKDEV_RETRY_INTERVAL(_n, _s, _f, _d) \ -+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_retry_interval, \ -+ int64_t) -+#define DEFINE_PROP_BLOCKDEV_RETRY_TIMEOUT(_n, _s, _f, _d) \ -+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_retry_timeout, \ -+ int64_t) - #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \ - DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int) - #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \ --- -2.27.0 - diff --git a/block-Fix-misleading-hexadecimal-format.patch b/block-Fix-misleading-hexadecimal-format.patch deleted file mode 100644 index 6fa36720c955991662dc1aa34ecaf5dec27f81df..0000000000000000000000000000000000000000 --- a/block-Fix-misleading-hexadecimal-format.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 23ba08631691242000e60f85a9d0a67a42dcca3b Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 4 Aug 2023 08:26:16 +0000 -Subject: [PATCH] block: Fix misleading hexadecimal format mainline inclusion - commit 3f1db95917bf0b4accaf8f56d43f795fed1fb733 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -"0x%u" format is very misleading, replace by "0x%x". - -Found running: - - $ git grep -E '0x%[0-9]*([lL]*|" ?PRI)[dDuU]' block/ - -Inspired-by: Richard Henderson -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Hanna Reitz -Reviewed-by: Daniel P. Berrangé -Reviewed-by: Denis V. Lunev -Message-id: 20220323114718.58714-2-philippe.mathieu.daude@gmail.com -Signed-off-by: Stefan Hajnoczi - -Signed-off-by: tangbinzy ---- - block/parallels-ext.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/block/parallels-ext.c b/block/parallels-ext.c -index e0dd0975c6..b0e1c1aa47 100644 ---- a/block/parallels-ext.c -+++ b/block/parallels-ext.c -@@ -260,7 +260,7 @@ static int parallels_parse_format_extension(BlockDriverState *bs, - break; - - default: -- error_setg(errp, "Unknown feature: 0x%" PRIu64, fh.magic); -+ error_setg(errp, "Unknown feature: 0x%" PRIx64, fh.magic); - goto fail; - } - --- -2.41.0.windows.1 - diff --git a/block-backend-Add-device-specific-retry-callback.patch b/block-backend-Add-device-specific-retry-callback.patch deleted file mode 100644 index 04465292d66e8652846ffb8683a6c19c1a2ba701..0000000000000000000000000000000000000000 --- a/block-backend-Add-device-specific-retry-callback.patch +++ /dev/null @@ -1,54 +0,0 @@ -From dfda8c57de71f2f10b57cf21b1e36f18d4ed37a3 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:47 +0800 -Subject: [PATCH 3/7] block-backend: Add device specific retry callback - -Add retry_request_cb in BlockDevOps to do device specific retry action. -Backend's timer would be registered only when the backend is set 'retry' -on errors and the device supports retry action. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - block/block-backend.c | 8 ++++++++ - include/sysemu/block-backend.h | 4 ++++ - 2 files changed, 12 insertions(+) - -diff --git a/block/block-backend.c b/block/block-backend.c -index 257cd775c0..24003adf0b 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -1018,6 +1018,14 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, - blk->dev_ops = ops; - blk->dev_opaque = opaque; - -+ if ((blk->on_read_error == BLOCKDEV_ON_ERROR_RETRY || -+ blk->on_write_error == BLOCKDEV_ON_ERROR_RETRY) && -+ ops->retry_request_cb) { -+ blk->retry_timer = aio_timer_new(blk->ctx, QEMU_CLOCK_REALTIME, -+ SCALE_MS, ops->retry_request_cb, -+ opaque); -+ } -+ - /* Are we currently quiesced? Should we enforce this right now? */ - if (blk->quiesce_counter && ops->drained_begin) { - ops->drained_begin(opaque); -diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h -index e5e1524f06..a7a13d47de 100644 ---- a/include/sysemu/block-backend.h -+++ b/include/sysemu/block-backend.h -@@ -70,6 +70,10 @@ typedef struct BlockDevOps { - * Is the device still busy? - */ - bool (*drained_poll)(void *opaque); -+ /* -+ * Runs when retrying failed requests. -+ */ -+ void (*retry_request_cb)(void *opaque); - } BlockDevOps; - - /* This struct is embedded in (the private) BlockBackend struct and contains --- -2.27.0 - diff --git a/block-backend-Add-timeout-support-for-retry.patch b/block-backend-Add-timeout-support-for-retry.patch deleted file mode 100644 index a3b79e2e9aaea6752caec1f652acd9957a0574bd..0000000000000000000000000000000000000000 --- a/block-backend-Add-timeout-support-for-retry.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 953590f4854d75e6051237f668c9fb393235f471 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:49 +0800 -Subject: [PATCH 5/7] block-backend: Add timeout support for retry - -Retry should only be triggered when timeout is not reached, so let's check -timeout before retry. Device should also reset retry_start_time after -successful retry. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - block/block-backend.c | 25 ++++++++++++++++++++++++- - include/sysemu/block-backend.h | 1 + - 2 files changed, 25 insertions(+), 1 deletion(-) - -diff --git a/block/block-backend.c b/block/block-backend.c -index 5a016d32fa..37e21c473e 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -1766,6 +1766,29 @@ void blk_drain_all(void) - bdrv_drain_all_end(); - } - -+static bool blk_error_retry_timeout(BlockBackend *blk) -+{ -+ /* No timeout set, infinite retries. */ -+ if (!blk->retry_timeout) { -+ return false; -+ } -+ -+ /* The first time an error occurs. */ -+ if (!blk->retry_start_time) { -+ blk->retry_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); -+ return false; -+ } -+ -+ return qemu_clock_get_ms(QEMU_CLOCK_REALTIME) > (blk->retry_start_time + -+ blk->retry_timeout); -+} -+ -+void blk_error_retry_reset_timeout(BlockBackend *blk) -+{ -+ if (blk->retry_timer && blk->retry_start_time) -+ blk->retry_start_time = 0; -+} -+ - void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, - BlockdevOnError on_write_error) - { -@@ -1794,7 +1817,7 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, - case BLOCKDEV_ON_ERROR_IGNORE: - return BLOCK_ERROR_ACTION_IGNORE; - case BLOCKDEV_ON_ERROR_RETRY: -- return (blk->retry_timer) ? -+ return (blk->retry_timer && !blk_error_retry_timeout(blk)) ? - BLOCK_ERROR_ACTION_RETRY : BLOCK_ERROR_ACTION_REPORT; - case BLOCKDEV_ON_ERROR_AUTO: - default: -diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h -index a7a13d47de..56a403883d 100644 ---- a/include/sysemu/block-backend.h -+++ b/include/sysemu/block-backend.h -@@ -198,6 +198,7 @@ void blk_inc_in_flight(BlockBackend *blk); - void blk_dec_in_flight(BlockBackend *blk); - void blk_drain(BlockBackend *blk); - void blk_drain_all(void); -+void blk_error_retry_reset_timeout(BlockBackend *blk); - void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, - BlockdevOnError on_write_error); - BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read); --- -2.27.0 - diff --git a/block-backend-Enable-retry-action-on-errors.patch b/block-backend-Enable-retry-action-on-errors.patch deleted file mode 100644 index ee56c455009a3946459efa1313b43452efcd3262..0000000000000000000000000000000000000000 --- a/block-backend-Enable-retry-action-on-errors.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 2e1c75e5a0339d2bf417e5a4437d8e627a303286 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:48 +0800 -Subject: [PATCH 4/7] block-backend: Enable retry action on errors - -Enable retry action when backend's retry timer is available. It would -trigger the timer to do device specific retry action. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - block/block-backend.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/block/block-backend.c b/block/block-backend.c -index 24003adf0b..5a016d32fa 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -1793,6 +1793,9 @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read, - return BLOCK_ERROR_ACTION_REPORT; - case BLOCKDEV_ON_ERROR_IGNORE: - return BLOCK_ERROR_ACTION_IGNORE; -+ case BLOCKDEV_ON_ERROR_RETRY: -+ return (blk->retry_timer) ? -+ BLOCK_ERROR_ACTION_RETRY : BLOCK_ERROR_ACTION_REPORT; - case BLOCKDEV_ON_ERROR_AUTO: - default: - abort(); -@@ -1840,6 +1843,10 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action, - qemu_system_vmstop_request_prepare(); - send_qmp_error_event(blk, action, is_read, error); - qemu_system_vmstop_request(RUN_STATE_IO_ERROR); -+ } else if (action == BLOCK_ERROR_ACTION_RETRY) { -+ timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + -+ blk->retry_interval); -+ send_qmp_error_event(blk, action, is_read, error); - } else { - send_qmp_error_event(blk, action, is_read, error); - } --- -2.27.0 - diff --git a/block-backend-Introduce-retry-timer.patch b/block-backend-Introduce-retry-timer.patch deleted file mode 100644 index 5a0bc334c48ee597ca35b3da2771c258e9ee26e8..0000000000000000000000000000000000000000 --- a/block-backend-Introduce-retry-timer.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 4dc180e87fb641f64fce7be3a0807488d0cc0a51 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:46 +0800 -Subject: [PATCH 2/7] block-backend: Introduce retry timer - -Add a timer to regularly trigger retry on errors. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - block/block-backend.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/block/block-backend.c b/block/block-backend.c -index 12ef80ea17..257cd775c0 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -35,6 +35,9 @@ - - static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb); - -+/* block backend default retry interval */ -+#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000 -+ - typedef struct BlockBackendAioNotifier { - void (*attached_aio_context)(AioContext *new_context, void *opaque); - void (*detach_aio_context)(void *opaque); -@@ -95,6 +98,15 @@ struct BlockBackend { - * Accessed with atomic ops. - */ - unsigned int in_flight; -+ -+ /* Timer for retry on errors. */ -+ QEMUTimer *retry_timer; -+ /* Interval in ms to trigger next retry. */ -+ int64_t retry_interval; -+ /* Start time of the first error. Used to check timeout. */ -+ int64_t retry_start_time; -+ /* Retry timeout. 0 represents infinite retry. */ -+ int64_t retry_timeout; - }; - - typedef struct BlockBackendAIOCB { -@@ -353,6 +365,11 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm) - blk->on_read_error = BLOCKDEV_ON_ERROR_REPORT; - blk->on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; - -+ blk->retry_timer = NULL; -+ blk->retry_interval = BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL; -+ blk->retry_start_time = 0; -+ blk->retry_timeout = 0; -+ - block_acct_init(&blk->stats); - - qemu_co_queue_init(&blk->queued_requests); -@@ -471,6 +488,10 @@ static void blk_delete(BlockBackend *blk) - QTAILQ_REMOVE(&block_backends, blk, link); - drive_info_del(blk->legacy_dinfo); - block_acct_cleanup(&blk->stats); -+ if (blk->retry_timer) { -+ timer_del(blk->retry_timer); -+ timer_free(blk->retry_timer); -+ } - g_free(blk); - } - --- -2.27.0 - diff --git a/block-backend-Stop-retrying-when-draining.patch b/block-backend-Stop-retrying-when-draining.patch deleted file mode 100644 index baf5c6c35333786da98e82334cf8b84eb59eaa38..0000000000000000000000000000000000000000 --- a/block-backend-Stop-retrying-when-draining.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 06db37983cfd20d7e92001ac3cb06867a281f1c9 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 25 Feb 2021 18:03:57 +0800 -Subject: [PATCH 8/9] block-backend: Stop retrying when draining - -Retrying failed requests when draining would make the draining hung. So it -is better not to trigger the retry timer when draining. And after the -virtual devices go back to work, they would retry those queued requests. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - block/block-backend.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/block/block-backend.c b/block/block-backend.c -index d3d90a95a5..49d236b2a4 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -1874,9 +1874,11 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action, - send_qmp_error_event(blk, action, is_read, error); - qemu_system_vmstop_request(RUN_STATE_IO_ERROR); - } else if (action == BLOCK_ERROR_ACTION_RETRY) { -- timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + -- blk->retry_interval); -- send_qmp_error_event(blk, action, is_read, error); -+ if (!blk->quiesce_counter) { -+ timer_mod(blk->retry_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + -+ blk->retry_interval); -+ send_qmp_error_event(blk, action, is_read, error); -+ } - } else { - send_qmp_error_event(blk, action, is_read, error); - } --- -2.27.0 - diff --git a/block-backend-prevent-dangling-BDS-pointers-across-a.patch b/block-backend-prevent-dangling-BDS-pointers-across-a.patch deleted file mode 100644 index 9ffabfd42982e99e1d105a42ec425085c371b322..0000000000000000000000000000000000000000 --- a/block-backend-prevent-dangling-BDS-pointers-across-a.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 6363172843fd756c61d6a3725ad5b3a385eddc87 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 21 Mar 2023 03:02:58 +0000 -Subject: [PATCH] block-backend: prevent dangling BDS pointers across - aio_poll() mainline inclusion commit 1e3552dbd28359d35967b7c28dc86cde1bc29205 - category: bugfix - ---------------------------------------------------------------- - -The BlockBackend root child can change when aio_poll() is invoked. This -happens when a temporary filter node is removed upon blockjob -completion, for example. - -Functions in block/block-backend.c must be aware of this when using a -blk_bs() pointer across aio_poll() because the BlockDriverState refcnt -may reach 0, resulting in a stale pointer. - -One example is scsi_device_purge_requests(), which calls blk_drain() to -wait for in-flight requests to cancel. If the backup blockjob is active, -then the BlockBackend root child is a temporary filter BDS owned by the -blockjob. The blockjob can complete during bdrv_drained_begin() and the -last reference to the BDS is released when the temporary filter node is -removed. This results in a use-after-free when blk_drain() calls -bdrv_drained_end(bs) on the dangling pointer. - -Explicitly hold a reference to bs across block APIs that invoke -aio_poll(). - -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2021778 -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2036178 -Signed-off-by: Stefan Hajnoczi -Message-Id: <20220111153613.25453-2-stefanha@redhat.com> -Signed-off-by: Kevin Wolf - -Signed-off-by: tangbinzy ---- - block/block-backend.c | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - -diff --git a/block/block-backend.c b/block/block-backend.c -index 49d236b2a4..3a757fb746 100644 ---- a/block/block-backend.c -+++ b/block/block-backend.c -@@ -840,16 +840,22 @@ BlockBackend *blk_by_public(BlockBackendPublic *public) - void blk_remove_bs(BlockBackend *blk) - { - ThrottleGroupMember *tgm = &blk->public.throttle_group_member; -- BlockDriverState *bs; - BdrvChild *root; - - notifier_list_notify(&blk->remove_bs_notifiers, blk); - if (tgm->throttle_state) { -- bs = blk_bs(blk); -+ BlockDriverState *bs = blk_bs(blk); -+ -+ /* -+ * Take a ref in case blk_bs() changes across bdrv_drained_begin(), for -+ * example, if a temporary filter node is removed by a blockjob. -+ */ -+ bdrv_ref(bs); - bdrv_drained_begin(bs); - throttle_group_detach_aio_context(tgm); - throttle_group_attach_aio_context(tgm, qemu_get_aio_context()); - bdrv_drained_end(bs); -+ bdrv_unref(bs); - } - - blk_update_root_state(blk); -@@ -1731,6 +1737,7 @@ void blk_drain(BlockBackend *blk) - BlockDriverState *bs = blk_bs(blk); - - if (bs) { -+ bdrv_ref(bs); - bdrv_drained_begin(bs); - } - -@@ -1740,6 +1747,7 @@ void blk_drain(BlockBackend *blk) - - if (bs) { - bdrv_drained_end(bs); -+ bdrv_unref(bs); - } - } - -@@ -2112,10 +2120,13 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, - int ret; - - if (bs) { -+ bdrv_ref(bs); -+ - if (update_root_node) { - ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root, - errp); - if (ret < 0) { -+ bdrv_unref(bs); - return ret; - } - } -@@ -2125,6 +2136,8 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, - throttle_group_attach_aio_context(tgm, new_context); - bdrv_drained_end(bs); - } -+ -+ bdrv_unref(bs); - } - - blk->ctx = new_context; -@@ -2394,11 +2407,13 @@ void blk_io_limits_disable(BlockBackend *blk) - ThrottleGroupMember *tgm = &blk->public.throttle_group_member; - assert(tgm->throttle_state); - if (bs) { -+ bdrv_ref(bs); - bdrv_drained_begin(bs); - } - throttle_group_unregister_tgm(tgm); - if (bs) { - bdrv_drained_end(bs); -+ bdrv_unref(bs); - } - } - --- -2.27.0 - diff --git a/block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch b/block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch deleted file mode 100644 index 3d454ecc4935d6ff4206b8b47d76962cfc4ee673..0000000000000000000000000000000000000000 --- a/block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d0586db311e8b78732923ce46f149fdf8251a59c Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 16:10:22 +0800 -Subject: [PATCH] block: bugfix: Don't pause vm when NOSPACE EIO happened - -When backend disk is FULL and disk IO type is 'dataplane', -QEMU will pause the vm, and this may cause endless-loop in -QEMU main thread if we do the snapshot merge now. - -When backend disk is FULL, only reporting an error rather -than pausing the virtual machine. - -Signed-off-by: wangjian161 ---- - blockdev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/blockdev.c b/blockdev.c -index 37e3ee6f26..3ce294ec4a 100644 ---- a/blockdev.c -+++ b/blockdev.c -@@ -556,7 +556,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, - qdict_put_str(bs_opts, "driver", buf); - } - -- on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; -+ on_write_error = BLOCKDEV_ON_ERROR_REPORT; - if ((buf = qemu_opt_get(opts, "werror")) != NULL) { - on_write_error = parse_block_error_action(buf, 0, &error); - if (error) { --- -2.27.0 - diff --git a/block-bugfix-disable-process-AIO-when-attach-scsi-di.patch b/block-bugfix-disable-process-AIO-when-attach-scsi-di.patch deleted file mode 100644 index 30a1bacb258e52e0203d081f1aee0b6093735f5f..0000000000000000000000000000000000000000 --- a/block-bugfix-disable-process-AIO-when-attach-scsi-di.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 87d8b7dcd880e0cef0c043dfef5ae649652cfe21 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 11:51:43 +0800 -Subject: [PATCH] block: bugfix: disable process AIO when attach scsi disk - -When initializing the virtio-scsi disk, hd_geometry_guess() will -be called to process AIO. At this time, the scsi disk has not -been fully initialized, and some fields in struct SCSIDiskState, -such as vendor and version, are NULL. If processing AIO at this -time, qemu may crash down. - -Add aio_disable_external() before hd_geometry_guess() to disable -processing AIO at that time. - -Signed-off-by: wangjian161 ---- - hw/block/block.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/hw/block/block.c b/hw/block/block.c -index 26c0767552..2cfc93a68e 100644 ---- a/hw/block/block.c -+++ b/hw/block/block.c -@@ -224,9 +224,16 @@ bool blkconf_geometry(BlockConf *conf, int *ptrans, - Error **errp) - { - if (!conf->cyls && !conf->heads && !conf->secs) { -+ AioContext *ctx = blk_get_aio_context(conf->blk); -+ -+ /* Callers may not expect this function to dispatch aio handlers, so -+ * disable external aio such as guest device emulation. -+ */ -+ aio_disable_external(ctx); - hd_geometry_guess(conf->blk, - &conf->cyls, &conf->heads, &conf->secs, - ptrans); -+ aio_enable_external(ctx); - } else if (ptrans && *ptrans == BIOS_ATA_TRANSLATION_AUTO) { - *ptrans = hd_bios_chs_auto_trans(conf->cyls, conf->heads, conf->secs); - } --- -2.27.0 - diff --git a/block-disallow-block-jobs-when-there-is-a-BDRV_O_INA.patch b/block-disallow-block-jobs-when-there-is-a-BDRV_O_INA.patch deleted file mode 100644 index f243df9947f7acea06bb5ca06ebbbf53fb95968c..0000000000000000000000000000000000000000 --- a/block-disallow-block-jobs-when-there-is-a-BDRV_O_INA.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0a2c96ee5a3463e82397afb9cb36f340a93264c2 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 11:29:15 +0800 -Subject: [PATCH] block: disallow block jobs when there is a BDRV_O_INACTIVE - flag - -Currently, migration will put a BDRV_O_INACTIVE flag -on bs's open_flags until another resume being called. In that case, -any IO from vm or block jobs will cause a qemu crash with an assert -'assert(!(bs->open_flags & BDRV_O_INACTIVE))' failure in bdrv_co_pwritev -function. we hereby disallow block jobs by faking a blocker. - -Signed-off-by: wangjian161 ---- - block.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/block.c b/block.c -index 0ac5b163d2..26c3982567 100644 ---- a/block.c -+++ b/block.c -@@ -6692,6 +6692,22 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp) - bdrv_get_device_or_node_name(bs)); - return true; - } -+ -+ /* -+ * When migration puts a BDRV_O_INACTIVE flag on driver's open_flags, -+ * we fake a blocker that doesn't exist. From now on, block jobs -+ * will not be permitted. -+ */ -+ if ((op == BLOCK_OP_TYPE_RESIZE || op == BLOCK_OP_TYPE_COMMIT_SOURCE || -+ op == BLOCK_OP_TYPE_MIRROR_SOURCE || op == BLOCK_OP_TYPE_MIRROR_TARGET) && -+ (bs->open_flags & BDRV_O_INACTIVE)) { -+ if (errp) { -+ error_setg(errp, "block device is in use by migration with" -+ " a driver BDRV_O_INACTIVE flag setted"); -+ } -+ return true; -+ } -+ - return false; - } - --- -2.27.0 - diff --git a/block-enable-cache-mode-of-empty-cdrom.patch b/block-enable-cache-mode-of-empty-cdrom.patch deleted file mode 100644 index 3a5c0b1dcdb858aef4653fbb6155e7fff28deec3..0000000000000000000000000000000000000000 --- a/block-enable-cache-mode-of-empty-cdrom.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 21b172a3ce13c3b499e4265628f7d7c7e1189749 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 11:18:21 +0800 -Subject: [PATCH] block: enable cache mode of empty cdrom - -enable cache mode even if cdrom is empty - -Signed-off-by: wangjian161 ---- - blockdev.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/blockdev.c b/blockdev.c -index 10a73fa423..37e3ee6f26 100644 ---- a/blockdev.c -+++ b/blockdev.c -@@ -492,6 +492,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, - QDict *interval_dict = NULL; - QList *interval_list = NULL; - const char *id; -+ const char *cache; - BlockdevDetectZeroesOptions detect_zeroes = - BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF; - const char *throttling_group = NULL; -@@ -583,6 +584,21 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, - - read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false); - -+ if (!file || !*file) { -+ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH); -+ if (cache && !strcmp(cache, "on")) { -+ bdrv_flags |= BDRV_O_NO_FLUSH; -+ } -+ -+ cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_DIRECT); -+ if (cache && !strcmp(cache, "on")) { -+ bdrv_flags |= BDRV_O_NOCACHE; -+ } -+ -+ qdict_del(bs_opts, BDRV_OPT_CACHE_NO_FLUSH); -+ qdict_del(bs_opts, BDRV_OPT_CACHE_DIRECT); -+ } -+ - /* init */ - if ((!file || !*file) && !qdict_size(bs_opts)) { - BlockBackendRootState *blk_rs; --- -2.27.0 - diff --git a/block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch b/block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch deleted file mode 100644 index 61ca0571f2638052ff454c2586a5bbb57bd514fe..0000000000000000000000000000000000000000 --- a/block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 2d37c08cc6f274c48a4a65a446788e946f0363c0 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Wed, 28 Jun 2023 10:58:55 +0800 -Subject: [PATCH] block/iscsi: fix double-free on BUSY or similar statuses - -cheery-pick from 5080152e2ef6cde7aa692e29880c62bd54acb750 - -Commit 8c460269aa77 ("iscsi: base all handling of check condition on -scsi_sense_to_errno", 2019-07-15) removed a "goto out" so that the -same coroutine is re-entered twice; once from iscsi_co_generic_cb, -once from the timer callback iscsi_retry_timer_expired. This can -cause a crash. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1378 -Reported-by: Grzegorz Zdanowski -Signed-off-by: Paolo Bonzini -Signed-off-by: qihao_yewu ---- - block/iscsi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/block/iscsi.c b/block/iscsi.c -index 57aa07a40d..61ccb58fc8 100644 ---- a/block/iscsi.c -+++ b/block/iscsi.c -@@ -268,6 +268,7 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status, - timer_mod(&iTask->retry_timer, - qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + retry_time); - iTask->do_retry = 1; -+ return; - } else if (status == SCSI_STATUS_CHECK_CONDITION) { - int error = iscsi_translate_sense(&task->sense); - if (error == EAGAIN) { --- -2.41.0.windows.1 - diff --git a/block-mirror-fix-file-system-went-to-read-only-after.patch b/block-mirror-fix-file-system-went-to-read-only-after.patch deleted file mode 100644 index 2126e83278425742c52f2cbd5f391fee7a70c3a0..0000000000000000000000000000000000000000 --- a/block-mirror-fix-file-system-went-to-read-only-after.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7448eb87ee59856aa0f0853f2aa5b803c832fccf Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 10 Feb 2022 21:37:49 +0800 -Subject: [PATCH] block/mirror: fix file-system went to read-only after - block-mirror - -config vm disk with prdm, keep the disk writing data continuously -during block-mirror, the file-system will went to read-only after -block-mirror, fix it. - -Signed-off-by: caojinhua -Signed-off-by: jiangdongxu ---- - block/mirror.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/block/mirror.c b/block/mirror.c -index efec2c7674..b7f0cba9b9 100644 ---- a/block/mirror.c -+++ b/block/mirror.c -@@ -1640,7 +1640,7 @@ static BlockJob *mirror_start_job( - * reads on the top, while disabling it in the intermediate nodes, and make - * the backing chain writable. */ - mirror_top_bs = bdrv_new_open_driver(&bdrv_mirror_top, filter_node_name, -- BDRV_O_RDWR, errp); -+ BDRV_O_RDWR | BDRV_O_NOCACHE, errp); - if (mirror_top_bs == NULL) { - return NULL; - } --- -2.27.0 - diff --git a/block-monitor-Fix-crash-when-executing-HMP-commit.patch b/block-monitor-Fix-crash-when-executing-HMP-commit.patch deleted file mode 100644 index 9f57f31d8f29e3dde2ed4b4f0bee8fcfb89cc01d..0000000000000000000000000000000000000000 --- a/block-monitor-Fix-crash-when-executing-HMP-commit.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 33dfb9d81a8cfe17aaa3f0804cbd491b06d38cd6 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Tue, 27 Jun 2023 14:40:13 +0800 -Subject: [PATCH] block/monitor: Fix crash when executing HMP commit - -cheery-pick from b7b814cd87a5fbe9f0fb5732dd28932699317bda - -hmp_commit() calls blk_is_available() from a non-coroutine context (and -in the main loop). blk_is_available() is a co_wrapper_mixed_bdrv_rdlock -function, and in the non-coroutine context it calls AIO_WAIT_WHILE(), -which crashes if the aio_context lock is not taken before. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1615 -Signed-off-by: Wang Liang -Message-Id: <20230424103902.45265-1-wangliangzz@126.com> -Reviewed-by: Emanuele Giuseppe Esposito -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf -(cherry picked from commit 8c1e8fb2e7fc2cbeb57703e143965a4cd3ad301a) -Signed-off-by: Michael Tokarev -Signed-off-by: qihao_yewu ---- - block/monitor/block-hmp-cmds.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c -index 2ac4aedfff..44f0af3430 100644 ---- a/block/monitor/block-hmp-cmds.c -+++ b/block/monitor/block-hmp-cmds.c -@@ -213,15 +213,17 @@ void hmp_commit(Monitor *mon, const QDict *qdict) - error_report("Device '%s' not found", device); - return; - } -- if (!blk_is_available(blk)) { -- error_report("Device '%s' has no medium", device); -- return; -- } - - bs = bdrv_skip_implicit_filters(blk_bs(blk)); - aio_context = bdrv_get_aio_context(bs); - aio_context_acquire(aio_context); - -+ if (!blk_is_available(blk)) { -+ error_report("Device '%s' has no medium", device); -+ aio_context_release(aio_context); -+ return; -+ } -+ - ret = bdrv_commit(bs); - - aio_context_release(aio_context); --- -2.41.0.windows.1 - diff --git a/block-nbd-Assert-there-are-no-timers-when-closed.patch b/block-nbd-Assert-there-are-no-timers-when-closed.patch deleted file mode 100644 index da3badd97ae37bc26297c8a7de35e5fa022a3d9a..0000000000000000000000000000000000000000 --- a/block-nbd-Assert-there-are-no-timers-when-closed.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 8353d0d6a31042ba7c54696ef1ec59eb883d647f Mon Sep 17 00:00:00 2001 -From: Zhang Bo -Date: Mon, 29 Aug 2022 15:37:08 +0800 -Subject: [PATCH 4/5] block/nbd: Assert there are no timers when closed - -Our two timers must not remain armed beyond nbd_clear_bdrvstate(), or -they will access freed data when they fire. - -This patch is separate from the patches that actually fix the issue -(HEAD^^ and HEAD^) so that you can run the associated regression iotest -(281) on a configuration that reproducibly exposes the bug. - -Reviewed-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Hanna Reitz -Signed-off-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Zhang Bo ---- - block/nbd.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/block/nbd.c b/block/nbd.c -index 5ff8a57314..dc6c3f3bbc 100644 ---- a/block/nbd.c -+++ b/block/nbd.c -@@ -110,6 +110,10 @@ static void nbd_clear_bdrvstate(BlockDriverState *bs) - - yank_unregister_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name)); - -+ /* Must not leave timers behind that would access freed data */ -+ assert(!s->reconnect_delay_timer); -+ assert(!s->open_timer); -+ - object_unref(OBJECT(s->tlscreds)); - qapi_free_SocketAddress(s->saddr); - s->saddr = NULL; --- -2.27.0 - diff --git a/block-nbd-Delete-open-timer-when-done.patch b/block-nbd-Delete-open-timer-when-done.patch deleted file mode 100644 index f8cebada722ac193250137c90c6691f7136f4b22..0000000000000000000000000000000000000000 --- a/block-nbd-Delete-open-timer-when-done.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 6a49e752439f02ef9ccaac30d14acf185e31a261 Mon Sep 17 00:00:00 2001 -From: Zhang Bo -Date: Mon, 29 Aug 2022 15:35:36 +0800 -Subject: [PATCH 3/5] block/nbd: Delete open timer when done - -We start the open timer to cancel the connection attempt after a while. -Once nbd_do_establish_connection() has returned, the attempt is over, -and we no longer need the timer. - -Delete it before returning from nbd_open(), so that it does not persist -for longer. It has no use after nbd_open(), and just like the reconnect -delay timer, it might well be dangerous if it were to fire afterwards. - -Reviewed-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Hanna Reitz -Signed-off-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Zhang Bo ---- - block/nbd.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/block/nbd.c b/block/nbd.c -index 16cd7fef77..5ff8a57314 100644 ---- a/block/nbd.c -+++ b/block/nbd.c -@@ -1885,11 +1885,19 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, - goto fail; - } - -+ /* -+ * The connect attempt is done, so we no longer need this timer. -+ * Delete it, because we do not want it to be around when this node -+ * is drained or closed. -+ */ -+ open_timer_del(s); -+ - nbd_client_connection_enable_retry(s->conn); - - return 0; - - fail: -+ open_timer_del(s); - nbd_clear_bdrvstate(bs); - return ret; - } --- -2.27.0 - diff --git a/block-nbd-Delete-reconnect-delay-timer-when-done.patch b/block-nbd-Delete-reconnect-delay-timer-when-done.patch deleted file mode 100644 index b7ca363f09737b48f723b99af7ac0f39fc043e60..0000000000000000000000000000000000000000 --- a/block-nbd-Delete-reconnect-delay-timer-when-done.patch +++ /dev/null @@ -1,45 +0,0 @@ -From a4d001a08ce1279b121cb870c378ddeb0825f2bc Mon Sep 17 00:00:00 2001 -From: Zhang Bo -Date: Mon, 29 Aug 2022 15:34:07 +0800 -Subject: [PATCH 2/5] block/nbd: Delete reconnect delay timer when done - -We start the reconnect delay timer to cancel the reconnection attempt -after a while. Once nbd_co_do_establish_connection() has returned, this -attempt is over, and we no longer need the timer. - -Delete it before returning from nbd_reconnect_attempt(), so that it does -not persist beyond the I/O request that was paused for reconnecting; we -do not want it to fire in a drained section, because all sort of things -can happen in such a section (e.g. the AioContext might be changed, and -we do not want the timer to fire in the wrong context; or the BDS might -even be deleted, and so the timer CB would access already-freed data). - -Reviewed-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Hanna Reitz -Signed-off-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Zhang Bo ---- - block/nbd.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/block/nbd.c b/block/nbd.c -index 63dbfa807d..16cd7fef77 100644 ---- a/block/nbd.c -+++ b/block/nbd.c -@@ -381,6 +381,13 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) - } - - nbd_co_do_establish_connection(s->bs, NULL); -+ -+ /* -+ * The reconnect attempt is done (maybe successfully, maybe not), so -+ * we no longer need this timer. Delete it so it will not outlive -+ * this I/O request (so draining removes all timers). -+ */ -+ reconnect_delay_timer_del(s); - } - - static coroutine_fn int nbd_receive_replies(BDRVNBDState *s, uint64_t handle) --- -2.27.0 - diff --git a/block-nbd-Move-s-ioc-on-AioContext-change.patch b/block-nbd-Move-s-ioc-on-AioContext-change.patch deleted file mode 100644 index f39430e46062687ee2f3c125d2d3d953fa95ed19..0000000000000000000000000000000000000000 --- a/block-nbd-Move-s-ioc-on-AioContext-change.patch +++ /dev/null @@ -1,97 +0,0 @@ -From ba810e3b3800f0d084a2dd324a9dea89c9320548 Mon Sep 17 00:00:00 2001 -From: Zhang Bo -Date: Mon, 29 Aug 2022 15:38:19 +0800 -Subject: [PATCH 5/5] block/nbd: Move s->ioc on AioContext change - -s->ioc must always be attached to the NBD node's AioContext. If that -context changes, s->ioc must be attached to the new context. - -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2033626 -Reviewed-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Hanna Reitz -Signed-off-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Zhang Bo ---- - block/nbd.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - -diff --git a/block/nbd.c b/block/nbd.c -index dc6c3f3bbc..5853d85d60 100644 ---- a/block/nbd.c -+++ b/block/nbd.c -@@ -2055,6 +2055,42 @@ static void nbd_cancel_in_flight(BlockDriverState *bs) - nbd_co_establish_connection_cancel(s->conn); - } - -+static void nbd_attach_aio_context(BlockDriverState *bs, -+ AioContext *new_context) -+{ -+ BDRVNBDState *s = bs->opaque; -+ -+ /* The open_timer is used only during nbd_open() */ -+ assert(!s->open_timer); -+ -+ /* -+ * The reconnect_delay_timer is scheduled in I/O paths when the -+ * connection is lost, to cancel the reconnection attempt after a -+ * given time. Once this attempt is done (successfully or not), -+ * nbd_reconnect_attempt() ensures the timer is deleted before the -+ * respective I/O request is resumed. -+ * Since the AioContext can only be changed when a node is drained, -+ * the reconnect_delay_timer cannot be active here. -+ */ -+ assert(!s->reconnect_delay_timer); -+ -+ if (s->ioc) { -+ qio_channel_attach_aio_context(s->ioc, new_context); -+ } -+} -+ -+static void nbd_detach_aio_context(BlockDriverState *bs) -+{ -+ BDRVNBDState *s = bs->opaque; -+ -+ assert(!s->open_timer); -+ assert(!s->reconnect_delay_timer); -+ -+ if (s->ioc) { -+ qio_channel_detach_aio_context(s->ioc); -+ } -+} -+ - static BlockDriver bdrv_nbd = { - .format_name = "nbd", - .protocol_name = "nbd", -@@ -2078,6 +2114,9 @@ static BlockDriver bdrv_nbd = { - .bdrv_dirname = nbd_dirname, - .strong_runtime_opts = nbd_strong_runtime_opts, - .bdrv_cancel_in_flight = nbd_cancel_in_flight, -+ -+ .bdrv_attach_aio_context = nbd_attach_aio_context, -+ .bdrv_detach_aio_context = nbd_detach_aio_context, - }; - - static BlockDriver bdrv_nbd_tcp = { -@@ -2103,6 +2142,9 @@ static BlockDriver bdrv_nbd_tcp = { - .bdrv_dirname = nbd_dirname, - .strong_runtime_opts = nbd_strong_runtime_opts, - .bdrv_cancel_in_flight = nbd_cancel_in_flight, -+ -+ .bdrv_attach_aio_context = nbd_attach_aio_context, -+ .bdrv_detach_aio_context = nbd_detach_aio_context, - }; - - static BlockDriver bdrv_nbd_unix = { -@@ -2128,6 +2170,9 @@ static BlockDriver bdrv_nbd_unix = { - .bdrv_dirname = nbd_dirname, - .strong_runtime_opts = nbd_strong_runtime_opts, - .bdrv_cancel_in_flight = nbd_cancel_in_flight, -+ -+ .bdrv_attach_aio_context = nbd_attach_aio_context, -+ .bdrv_detach_aio_context = nbd_detach_aio_context, - }; - - static void bdrv_nbd_init(void) --- -2.27.0 - diff --git a/block-nbd.c-Fixed-IO-request-coroutine-not-being-wak.patch b/block-nbd.c-Fixed-IO-request-coroutine-not-being-wak.patch deleted file mode 100644 index 99bbf55ac5026d120c2c492e2e3079bd41657b53..0000000000000000000000000000000000000000 --- a/block-nbd.c-Fixed-IO-request-coroutine-not-being-wak.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 09f03d6bd8842b58e6a1e50cf9c44a788b8d2693 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 4 Aug 2023 07:40:46 +0000 -Subject: [PATCH] block/nbd.c: Fixed IO request coroutine not being wakeup - when kill NBD server mainline inclusion commit - 6690302b848e5b55e3e3da34f0ee7fd9f8602e23 category: bugfix - ---------------------------------------------------------------- - -During the IO stress test, the IO request coroutine has a probability that is -can't be awakened when the NBD server is killed. - -The GDB stack is as follows: -(gdb) bt -0 0x00007f2ff990cbf6 in __ppoll (fds=0x55575de85000, nfds=1, timeout=, sigmask=0x0) at ../sysdeps/unix/sysv/linux/ppoll.c:44 -1 0x000055575c302e7c in qemu_poll_ns (fds=0x55575de85000, nfds=1, timeout=599999603140) at ../util/qemu-timer.c:348 -2 0x000055575c2d3c34 in fdmon_poll_wait (ctx=0x55575dc480f0, ready_list=0x7ffd9dd1dae0, timeout=599999603140) at ../util/fdmon-poll.c:80 -3 0x000055575c2d350d in aio_poll (ctx=0x55575dc480f0, blocking=true) at ../util/aio-posix.c:655 -4 0x000055575c16eabd in bdrv_do_drained_begin(bs=0x55575dee7fe0, recursive=false, parent=0x0, ignore_bds_parents=false, poll=true)at ../block/io.c:474 -5 0x000055575c16eba6 in bdrv_drained_begin (bs=0x55575dee7fe0) at ../block/io.c:480 -6 0x000055575c1aff33 in quorum_del_child (bs=0x55575dee7fe0, child=0x55575dcea690, errp=0x7ffd9dd1dd08) at ../block/quorum.c:1130 -7 0x000055575c14239b in bdrv_del_child (parent_bs=0x55575dee7fe0, child=0x55575dcea690, errp=0x7ffd9dd1dd08) at ../block.c:7705 -8 0x000055575c12da28 in qmp_x_blockdev_change(parent=0x55575df404c0 "colo-disk0", has_child=true, child=0x55575de867f0 "children.1", has_node=false, no de=0x0, errp=0x7ffd9dd1dd08) at ../blockdev.c:3676 -9 0x000055575c258435 in qmp_marshal_x_blockdev_change (args=0x7f2fec008190, ret=0x7f2ff7b0bd98, errp=0x7f2ff7b0bd90) at qapi/qapi-commands-block-core.c :1675 -10 0x000055575c2c6201 in do_qmp_dispatch_bh (opaque=0x7f2ff7b0be30) at ../qapi/qmp-dispatch.c:129 -11 0x000055575c2ebb1c in aio_bh_call (bh=0x55575dc429c0) at ../util/async.c:141 -12 0x000055575c2ebc2a in aio_bh_poll (ctx=0x55575dc480f0) at ../util/async.c:169 -13 0x000055575c2d2d96 in aio_dispatch (ctx=0x55575dc480f0) at ../util/aio-posix.c:415 -14 0x000055575c2ec07f in aio_ctx_dispatch (source=0x55575dc480f0, callback=0x0, user_data=0x0) at ../util/async.c:311 -15 0x00007f2ff9e7cfbd in g_main_context_dispatch () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 -16 0x000055575c2fd581 in glib_pollfds_poll () at ../util/main-loop.c:232 -17 0x000055575c2fd5ff in os_host_main_loop_wait (timeout=0) at ../util/main-loop.c:255 -18 0x000055575c2fd710 in main_loop_wait (nonblocking=0) at ../util/main-loop.c:531 -19 0x000055575bfa7588 in qemu_main_loop () at ../softmmu/runstate.c:726 -20 0x000055575bbee57a in main (argc=60, argv=0x7ffd9dd1e0e8, envp=0x7ffd9dd1e2d0) at ../softmmu/main.c:50 - -(gdb) qemu coroutine 0x55575e16aac0 -0 0x000055575c2ee7dc in qemu_coroutine_switch (from_=0x55575e16aac0, to_=0x7f2ff830fba0, action=COROUTINE_YIELD) at ../util/coroutine-ucontext.c:302 -1 0x000055575c2fe2a9 in qemu_coroutine_yield () at ../util/qemu-coroutine.c:195 -2 0x000055575c2fe93c in qemu_co_queue_wait_impl (queue=0x55575dc46170, lock=0x7f2b32ad9850) at ../util/qemu-coroutine-lock.c:56 -3 0x000055575c17ddfb in nbd_co_send_request (bs=0x55575ebfaf20, request=0x7f2b32ad9920, qiov=0x55575dfc15d8) at ../block/nbd.c:478 -4 0x000055575c17f931 in nbd_co_request (bs=0x55575ebfaf20, request=0x7f2b32ad9920, write_qiov=0x55575dfc15d8) at ../block/nbd.c:1182 -5 0x000055575c17fe14 in nbd_client_co_pwritev (bs=0x55575ebfaf20, offset=403487858688, bytes=4538368, qiov=0x55575dfc15d8, flags=0) at ../block/nbd.c:1284 -6 0x000055575c170d25 in bdrv_driver_pwritev (bs=0x55575ebfaf20, offset=403487858688, bytes=4538368, qiov=0x55575dfc15d8, qiov_offset=0, flags=0) - at ../block/io.c:1264 -7 0x000055575c1733b4 in bdrv_aligned_pwritev - (child=0x55575dff6890, req=0x7f2b32ad9ad0, offset=403487858688, bytes=4538368, align=1, qiov=0x55575dfc15d8, qiov_offset=0, flags=0) at ../block/io.c:2126 -8 0x000055575c173c67 in bdrv_co_pwritev_part (child=0x55575dff6890, offset=403487858688, bytes=4538368, qiov=0x55575dfc15d8, qiov_offset=0, flags=0) - at ../block/io.c:2314 -9 0x000055575c17391b in bdrv_co_pwritev (child=0x55575dff6890, offset=403487858688, bytes=4538368, qiov=0x55575dfc15d8, flags=0) at ../block/io.c:2233 -10 0x000055575c1ee506 in replication_co_writev (bs=0x55575e9824f0, sector_num=788062224, remaining_sectors=8864, qiov=0x55575dfc15d8, flags=0) - at ../block/replication.c:270 -11 0x000055575c170eed in bdrv_driver_pwritev (bs=0x55575e9824f0, offset=403487858688, bytes=4538368, qiov=0x55575dfc15d8, qiov_offset=0, flags=0) - at ../block/io.c:1297 -12 0x000055575c1733b4 in bdrv_aligned_pwritev - (child=0x55575dcea690, req=0x7f2b32ad9e00, offset=403487858688, bytes=4538368, align=512, qiov=0x55575dfc15d8, qiov_offset=0, flags=0) - at ../block/io.c:2126 -13 0x000055575c173c67 in bdrv_co_pwritev_part (child=0x55575dcea690, offset=403487858688, bytes=4538368, qiov=0x55575dfc15d8, qiov_offset=0, flags=0) - at ../block/io.c:2314 -14 0x000055575c17391b in bdrv_co_pwritev (child=0x55575dcea690, offset=403487858688, bytes=4538368, qiov=0x55575dfc15d8, flags=0) at ../block/io.c:2233 -15 0x000055575c1aeffa in write_quorum_entry (opaque=0x7f2fddaf8c50) at ../block/quorum.c:699 -16 0x000055575c2ee4db in coroutine_trampoline (i0=1578543808, i1=21847) at ../util/coroutine-ucontext.c:173 -17 0x00007f2ff9855660 in __start_context () at ../sysdeps/unix/sysv/linux/x86_64/__start_context.S:91 - -When we do failover in COLO mode, QEMU will hang while it is waiting for -the in-flight IO. From the call trace, we can see the IO request coroutine -has yielded in nbd_co_send_request(). When we kill the NBD server, it will never -be wake up. Actually, when we do IO stress test, it will have a lot of -requests in free_sema queue. When the NBD server is killed, current -MAX_NBD_REQUESTS finishes with errors but they wake up at most -MAX_NBD_REQEUSTS from the queue. So, let's move qemu_co_queue_next out -to fix this issue. - -Signed-off-by: Lei Rao -Message-Id: <20220309074844.275450-1-lei.rao@intel.com> -Reviewed-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Eric Blake - -Signed-off-by: tangbinzy ---- - block/nbd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/block/nbd.c b/block/nbd.c -index 5853d85d60..33adfddc41 100644 ---- a/block/nbd.c -+++ b/block/nbd.c -@@ -529,8 +529,8 @@ err: - if (i != -1) { - s->requests[i].coroutine = NULL; - s->in_flight--; -- qemu_co_queue_next(&s->free_sema); - } -+ qemu_co_queue_next(&s->free_sema); - } - qemu_co_mutex_unlock(&s->send_mutex); - return rc; --- -2.41.0.windows.1 - diff --git a/block-nfs-Fix-32-bit-Windows-build.patch b/block-nfs-Fix-32-bit-Windows-build.patch deleted file mode 100644 index 257ed1be0cc3c02cea69a64f143a64148197c239..0000000000000000000000000000000000000000 --- a/block-nfs-Fix-32-bit-Windows-build.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 5969f357385914e29a847c030d195cb8476f38c4 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Thu, 3 Aug 2023 19:19:26 +0800 -Subject: [PATCH] block/nfs: Fix 32-bit Windows build - -cheery-pick from 588fec8a4c3fe9e0d1cb3f7ea6fdd46221e42814 - -libnfs.h declares nfs_fstat() as the following for win32: - -int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, -struct __stat64 *st); - -The 'st' parameter should be of type 'struct __stat64'. The -codes happen to build successfully for 64-bit Windows, but it -does not build for 32-bit Windows. - -Fixes: 6542aa9c75bc ("block: add native support for NFS") -Fixes: 18a8056e0bc7 ("block/nfs: cache allocated filesize for read-only files") -Signed-off-by: Bin Meng -Message-Id: <20220908132817.1831008-6-bmeng.cn@gmail.com> -Reviewed-by: Stefan Weil -Signed-off-by: Stefan Weil -Signed-off-by: qihao_yewu ---- - block/nfs.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/block/nfs.c b/block/nfs.c -index 577aea1d22..56b25829cf 100644 ---- a/block/nfs.c -+++ b/block/nfs.c -@@ -418,7 +418,11 @@ static int64_t nfs_client_open(NFSClient *client, BlockdevOptionsNfs *opts, - int flags, int open_flags, Error **errp) - { - int64_t ret = -EINVAL; -+#ifdef _WIN32 -+ struct __stat64 st; -+#else - struct stat st; -+#endif - char *file = NULL, *strp = NULL; - - qemu_mutex_init(&client->mutex); -@@ -781,7 +785,11 @@ static int nfs_reopen_prepare(BDRVReopenState *state, - BlockReopenQueue *queue, Error **errp) - { - NFSClient *client = state->bs->opaque; -+#ifdef _WIN32 -+ struct __stat64 st; -+#else - struct stat st; -+#endif - int ret = 0; - - if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) { --- -2.41.0.windows.1 - diff --git a/block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch b/block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch deleted file mode 100644 index eb0595fa8c37155f12a61a658046482cb34f1b88..0000000000000000000000000000000000000000 --- a/block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ba31baabf9ad582c8a256a58123c036b6a70ba15 Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Fri, 1 Dec 2023 10:00:41 +0800 -Subject: [PATCH] block/nvme: fix infinite loop in nvme_free_req_queue_cb() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit cf4fbc3030c974fff726756a7ceef8386cdf500b - -When the request free list is exhausted the coroutine waits on -q->free_req_queue for the next free request. Whenever a request is -completed a BH is scheduled to invoke nvme_free_req_queue_cb() and wake -up waiting coroutines. - -1. nvme_get_free_req() waits for a free request: - - while (q->free_req_head == -1) { - ... - trace_nvme_free_req_queue_wait(q->s, q->index); - qemu_co_queue_wait(&q->free_req_queue, &q->lock); - ... - } - -2. nvme_free_req_queue_cb() wakes up the coroutine: - - while (qemu_co_enter_next(&q->free_req_queue, &q->lock)) { - ^--- infinite loop when free_req_head == -1 - } - -nvme_free_req_queue_cb() and the coroutine form an infinite loop when -q->free_req_head == -1. Fix this by checking q->free_req_head in -nvme_free_req_queue_cb(). If the free request list is exhausted, don't -wake waiting coroutines. Eventually an in-flight request will complete -and the BH will be scheduled again, guaranteeing forward progress. - -Signed-off-by: Stefan Hajnoczi -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20211208152246.244585-1-stefanha@redhat.com -Signed-off-by: Stefan Hajnoczi -Signed-off-by: Luo Yifan ---- - block/nvme.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/block/nvme.c b/block/nvme.c -index e4f336d79c..fa360b9b3c 100644 ---- a/block/nvme.c -+++ b/block/nvme.c -@@ -206,8 +206,9 @@ static void nvme_free_req_queue_cb(void *opaque) - NVMeQueuePair *q = opaque; - - qemu_mutex_lock(&q->lock); -- while (qemu_co_enter_next(&q->free_req_queue, &q->lock)) { -- /* Retry all pending requests */ -+ while (q->free_req_head != -1 && -+ qemu_co_enter_next(&q->free_req_queue, &q->lock)) { -+ /* Retry waiting requests */ - } - qemu_mutex_unlock(&q->lock); - } --- -2.27.0 - diff --git a/block-rbd-fix-write-zeroes-with-growing-images.patch b/block-rbd-fix-write-zeroes-with-growing-images.patch deleted file mode 100644 index ce19d29193c4016e57532bc5da852c7e844eb63f..0000000000000000000000000000000000000000 --- a/block-rbd-fix-write-zeroes-with-growing-images.patch +++ /dev/null @@ -1,76 +0,0 @@ -From c0caaf3367912df00107e6cd49809a48ccc566fb Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 4 Aug 2023 08:03:35 +0000 -Subject: [PATCH] block/rbd: fix write zeroes with growing images mainline - inclusion commit cc5387a544325c26dcf124ac7d3999389c24e5c6 category: bugfix - ---------------------------------------------------------------- - -Commit d24f80234b ("block/rbd: increase dynamically the image size") -added a workaround to support growing images (eg. qcow2), resizing -the image before write operations that exceed the current size. - -We recently added support for write zeroes and without the -workaround we can have problems with qcow2. - -So let's move the resize into qemu_rbd_start_co() and do it when -the command is RBD_AIO_WRITE or RBD_AIO_WRITE_ZEROES. - -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2020993 -Fixes: c56ac27d2a ("block/rbd: add write zeroes support") -Signed-off-by: Stefano Garzarella -Message-Id: <20220317162638.41192-1-sgarzare@redhat.com> -Signed-off-by: Hanna Reitz - -Signed-off-by: tangbinzy ---- - block/rbd.c | 26 ++++++++++++++------------ - 1 file changed, 14 insertions(+), 12 deletions(-) - -diff --git a/block/rbd.c b/block/rbd.c -index 92dfb6083b..ccb14efd55 100644 ---- a/block/rbd.c -+++ b/block/rbd.c -@@ -1107,6 +1107,20 @@ static int coroutine_fn qemu_rbd_start_co(BlockDriverState *bs, - - assert(!qiov || qiov->size == bytes); - -+ if (cmd == RBD_AIO_WRITE || cmd == RBD_AIO_WRITE_ZEROES) { -+ /* -+ * RBD APIs don't allow us to write more than actual size, so in order -+ * to support growing images, we resize the image before write -+ * operations that exceed the current size. -+ */ -+ if (offset + bytes > s->image_size) { -+ int r = qemu_rbd_resize(bs, offset + bytes); -+ if (r < 0) { -+ return r; -+ } -+ } -+ } -+ - r = rbd_aio_create_completion(&task, - (rbd_callback_t) qemu_rbd_completion_cb, &c); - if (r < 0) { -@@ -1182,18 +1196,6 @@ coroutine_fn qemu_rbd_co_pwritev(BlockDriverState *bs, int64_t offset, - int64_t bytes, QEMUIOVector *qiov, - BdrvRequestFlags flags) - { -- BDRVRBDState *s = bs->opaque; -- /* -- * RBD APIs don't allow us to write more than actual size, so in order -- * to support growing images, we resize the image before write -- * operations that exceed the current size. -- */ -- if (offset + bytes > s->image_size) { -- int r = qemu_rbd_resize(bs, offset + bytes); -- if (r < 0) { -- return r; -- } -- } - return qemu_rbd_start_co(bs, offset, bytes, qiov, flags, RBD_AIO_WRITE); - } - --- -2.41.0.windows.1 - diff --git a/block-rbd-workaround-for-ceph-issue-53784.patch b/block-rbd-workaround-for-ceph-issue-53784.patch deleted file mode 100644 index efd6225bffa6eee217ab61383e3f940298861ffe..0000000000000000000000000000000000000000 --- a/block-rbd-workaround-for-ceph-issue-53784.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 43302c8f56518cd467578fa084d64fd42c59348c Mon Sep 17 00:00:00 2001 -From: Peter Lieven -Date: Thu, 13 Jan 2022 15:44:26 +0100 -Subject: [PATCH] block/rbd: workaround for ceph issue #53784 - -librbd had a bug until early 2022 that affected all versions of ceph that -supported fast-diff. This bug results in reporting of incorrect offsets -if the offset parameter to rbd_diff_iterate2 is not object aligned. - -This patch works around this bug for pre Quincy versions of librbd. - -Fixes: 0347a8fd4c3faaedf119be04c197804be40a384b -Cc: qemu-stable@nongnu.org -Signed-off-by: Peter Lieven -Message-Id: <20220113144426.4036493-3-pl@kamp.de> -Reviewed-by: Ilya Dryomov -Reviewed-by: Stefano Garzarella -Tested-by: Stefano Garzarella -Signed-off-by: Kevin Wolf ---- - block/rbd.c | 42 ++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 40 insertions(+), 2 deletions(-) - -diff --git a/block/rbd.c b/block/rbd.c -index def96292e0..92dfb6083b 100644 ---- a/block/rbd.c -+++ b/block/rbd.c -@@ -1320,6 +1320,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, - int status, r; - RBDDiffIterateReq req = { .offs = offset }; - uint64_t features, flags; -+ uint64_t head = 0; - - assert(offset + bytes <= s->image_size); - -@@ -1347,7 +1348,43 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, - return status; - } - -- r = rbd_diff_iterate2(s->image, NULL, offset, bytes, true, true, -+#if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 17, 0) -+ /* -+ * librbd had a bug until early 2022 that affected all versions of ceph that -+ * supported fast-diff. This bug results in reporting of incorrect offsets -+ * if the offset parameter to rbd_diff_iterate2 is not object aligned. -+ * Work around this bug by rounding down the offset to object boundaries. -+ * This is OK because we call rbd_diff_iterate2 with whole_object = true. -+ * However, this workaround only works for non cloned images with default -+ * striping. -+ * -+ * See: https://tracker.ceph.com/issues/53784 -+ */ -+ -+ /* check if RBD image has non-default striping enabled */ -+ if (features & RBD_FEATURE_STRIPINGV2) { -+ return status; -+ } -+ -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -+ /* -+ * check if RBD image is a clone (= has a parent). -+ * -+ * rbd_get_parent_info is deprecated from Nautilus onwards, but the -+ * replacement rbd_get_parent is not present in Luminous and Mimic. -+ */ -+ if (rbd_get_parent_info(s->image, NULL, 0, NULL, 0, NULL, 0) != -ENOENT) { -+ return status; -+ } -+#pragma GCC diagnostic pop -+ -+ head = req.offs & (s->object_size - 1); -+ req.offs -= head; -+ bytes += head; -+#endif -+ -+ r = rbd_diff_iterate2(s->image, NULL, req.offs, bytes, true, true, - qemu_rbd_diff_iterate_cb, &req); - if (r < 0 && r != QEMU_RBD_EXIT_DIFF_ITERATE2) { - return status; -@@ -1366,7 +1403,8 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, - status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID; - } - -- *pnum = req.bytes; -+ assert(req.bytes > head); -+ *pnum = req.bytes - head; - return status; - } - --- -2.27.0 - diff --git a/block-use-unsigned-for-in_flight-field-on-driver-sta.patch b/block-use-unsigned-for-in_flight-field-on-driver-sta.patch deleted file mode 100644 index 5ff052c60e6eb12a718b004a0f19de951ec3ee14..0000000000000000000000000000000000000000 --- a/block-use-unsigned-for-in_flight-field-on-driver-sta.patch +++ /dev/null @@ -1,54 +0,0 @@ -From d82b2052d61cd57fb2ebf53f633cb0ff272d16c3 Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:53:08 -0800 -Subject: [PATCH] block: use 'unsigned' for in_flight field on driver state - -cherry picked from commit 1b8f777673985af366de099ad4e41d334b36fb12 - -This patch makes in_flight field 'unsigned' for BDRVNBDState and -MirrorBlockJob. This matches the definition of this field on BDS -and is generically correct - we should never get negative value here. - -Signed-off-by: Denis V. Lunev -CC: John Snow -CC: Vladimir Sementsov-Ogievskiy -CC: Kevin Wolf -CC: Hanna Reitz -CC: Eric Blake -Reviewed-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Wanghe Xiao ---- - block/mirror.c | 2 +- - block/nbd.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/block/mirror.c b/block/mirror.c -index b7f0cba9b9..d1863565c4 100644 ---- a/block/mirror.c -+++ b/block/mirror.c -@@ -72,7 +72,7 @@ typedef struct MirrorBlockJob { - - uint64_t last_pause_ns; - unsigned long *in_flight_bitmap; -- int in_flight; -+ unsigned in_flight; - int64_t bytes_in_flight; - QTAILQ_HEAD(, MirrorOp) ops_in_flight; - int ret; -diff --git a/block/nbd.c b/block/nbd.c -index 33adfddc41..a543e68d2f 100644 ---- a/block/nbd.c -+++ b/block/nbd.c -@@ -76,7 +76,7 @@ typedef struct BDRVNBDState { - CoQueue free_sema; - - CoMutex receive_mutex; -- int in_flight; -+ unsigned in_flight; - NBDClientState state; - - QEMUTimer *reconnect_delay_timer; --- -2.27.0 - diff --git a/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch b/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch deleted file mode 100644 index 5802835732b041606945c051bc2a5c5917ebb282..0000000000000000000000000000000000000000 --- a/bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 02a17066ac3dfb5e53b72b15a80643154990191b Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 10 Feb 2022 21:50:28 +0800 -Subject: [PATCH] bugfix: fix eventfds may double free when vm_id reused in - ivshmem - -As the ivshmem Server-Client Protol describes, when a -client disconnects from the server, server sends disconnect -notifications to the other clients. And the other clients -will free the eventfds of the disconnected client according -to the client ID. If the client ID is reused, the eventfds -may be double freed. - -It will be solved by setting eventfds to NULL after freeing -and allocating memory for it when it's used. - -Signed-off-by: Peng Liang -Signed-off-by: jiangdongxu ---- - hw/misc/ivshmem.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c -index 1ba4a98377..05f06ed6cf 100644 ---- a/hw/misc/ivshmem.c -+++ b/hw/misc/ivshmem.c -@@ -400,6 +400,7 @@ static void close_peer_eventfds(IVShmemState *s, int posn) - } - - g_free(s->peers[posn].eventfds); -+ s->peers[posn].eventfds = NULL; - s->peers[posn].nb_eventfds = 0; - } - -@@ -530,6 +531,10 @@ static void process_msg_connect(IVShmemState *s, uint16_t posn, int fd, - close(fd); - return; - } -+ if (peer->eventfds == NULL) { -+ peer->eventfds = g_new0(EventNotifier, s->vectors); -+ peer->nb_eventfds = 0; -+ } - vector = peer->nb_eventfds++; - - IVSHMEM_DPRINTF("eventfds[%d][%d] = %d\n", posn, vector, fd); --- -2.27.0 - diff --git a/bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch b/bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch deleted file mode 100644 index f463c6b4b060133576134775c5c5c5ddcd400d92..0000000000000000000000000000000000000000 --- a/bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch +++ /dev/null @@ -1,67 +0,0 @@ -From f14ea0bd2596f94ad926009411b8ffda9c2c2cda Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 10 Feb 2022 22:42:23 +0800 -Subject: [PATCH] bugfix: fix mmio information leak and ehci vm escape 0-day - vulnerability - -Signed-off-by: Yutao Ai -Signed-off-by: jiangdongxu ---- - hw/usb/core.c | 20 ++++++++++++++++++-- - hw/usb/hcd-ehci.c | 2 ++ - 2 files changed, 20 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/core.c b/hw/usb/core.c -index 51b36126ca..a62826e051 100644 ---- a/hw/usb/core.c -+++ b/hw/usb/core.c -@@ -206,7 +206,15 @@ static void do_token_in(USBDevice *s, USBPacket *p) - - case SETUP_STATE_DATA: - if (s->setup_buf[0] & USB_DIR_IN) { -- int len = s->setup_len - s->setup_index; -+ int len; -+ if (s->setup_len > sizeof(s->data_buf)) { -+ fprintf(stderr, -+ "usb_generic_handle_packet: ctrl buffer too small do_token_in(%d > %zu)\n", -+ s->setup_len, sizeof(s->data_buf)); -+ p->status = USB_RET_STALL; -+ return; -+ } -+ len = s->setup_len - s->setup_index; - if (len > p->iov.size) { - len = p->iov.size; - } -@@ -244,7 +252,15 @@ static void do_token_out(USBDevice *s, USBPacket *p) - - case SETUP_STATE_DATA: - if (!(s->setup_buf[0] & USB_DIR_IN)) { -- int len = s->setup_len - s->setup_index; -+ int len; -+ if (s->setup_len > sizeof(s->data_buf)) { -+ fprintf(stderr, -+ "usb_generic_handle_packet: ctrl buffer too small do_token_out(%d > %zu)\n", -+ s->setup_len, sizeof(s->data_buf)); -+ p->status = USB_RET_STALL; -+ return; -+ } -+ len = s->setup_len - s->setup_index; - if (len > p->iov.size) { - len = p->iov.size; - } -diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c -index 6caa7ac6c2..1415107315 100644 ---- a/hw/usb/hcd-ehci.c -+++ b/hw/usb/hcd-ehci.c -@@ -612,6 +612,8 @@ static void ehci_free_queue(EHCIQueue *q, const char *warn) - ehci_trace_guest_bug(q->ehci, warn); - } - QTAILQ_REMOVE(head, q, next); -+ memset(q, 0, sizeof(*q)); -+ *(volatile char *)q = *(volatile char *)q; - g_free(q); - } - --- -2.27.0 - diff --git a/bugfix-fix-possible-memory-leak.patch b/bugfix-fix-possible-memory-leak.patch deleted file mode 100644 index 3e6a611ed470f6d0acdbbaa2889bcbd90c089353..0000000000000000000000000000000000000000 --- a/bugfix-fix-possible-memory-leak.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 03e7e232a323c45205d3c6ecb7d8e52e7209d9eb Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 10 Feb 2022 22:12:50 +0800 -Subject: [PATCH] bugfix: fix possible memory leak - -Signed-off-by: caojinhua -Signed-off-by: jiangdongxu ---- - migration/savevm.c | 2 ++ - qga/main.c | 18 +++++++++++++----- - 2 files changed, 15 insertions(+), 5 deletions(-) - -diff --git a/migration/savevm.c b/migration/savevm.c -index d59e976d50..803cd9004d 100644 ---- a/migration/savevm.c -+++ b/migration/savevm.c -@@ -1427,6 +1427,7 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, - ret = vmstate_save(f, se, vmdesc); - if (ret) { - qemu_file_set_error(f, ret); -+ json_writer_free(vmdesc); - return ret; - } - trace_savevm_section_end(se->idstr, se->section_id, 0); -@@ -1443,6 +1444,7 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, - error_report("%s: bdrv_inactivate_all() failed (%d)", - __func__, ret); - qemu_file_set_error(f, ret); -+ json_writer_free(vmdesc); - return ret; - } - } -diff --git a/qga/main.c b/qga/main.c -index 15fd3a4149..6f09a689ac 100644 ---- a/qga/main.c -+++ b/qga/main.c -@@ -1283,7 +1283,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) - if (g_mkdir_with_parents(config->state_dir, S_IRWXU) == -1) { - g_critical("unable to create (an ancestor of) the state directory" - " '%s': %s", config->state_dir, strerror(errno)); -- return NULL; -+ goto failed; - } - #endif - -@@ -1308,7 +1308,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) - if (!log_file) { - g_critical("unable to open specified log file: %s", - strerror(errno)); -- return NULL; -+ goto failed; - } - s->log_file = log_file; - } -@@ -1319,7 +1319,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) - s->pstate_filepath, - ga_is_frozen(s))) { - g_critical("failed to load persistent state"); -- return NULL; -+ goto failed; - } - - config->blacklist = ga_command_blacklist_init(config->blacklist); -@@ -1340,7 +1340,7 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) - #ifndef _WIN32 - if (!register_signal_handlers()) { - g_critical("failed to register signal handlers"); -- return NULL; -+ goto failed; - } - #endif - -@@ -1353,12 +1353,20 @@ static GAState *initialize_agent(GAConfig *config, int socket_activation) - s->wakeup_event = CreateEvent(NULL, TRUE, FALSE, TEXT("WakeUp")); - if (s->wakeup_event == NULL) { - g_critical("CreateEvent failed"); -- return NULL; -+ goto failed; - } - #endif - - ga_state = s; - return s; -+failed: -+ g_free(s->pstate_filepath); -+ g_free(s->state_filepath_isfrozen); -+ if (s->log_file) { -+ fclose(s->log_file); -+ } -+ g_free(s); -+ return NULL; - } - - static void cleanup_agent(GAState *s) --- -2.27.0 - diff --git a/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch b/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch deleted file mode 100644 index 48c7970efa46bf78c772159cae0c501ff997ae1a..0000000000000000000000000000000000000000 --- a/bugfix-fix-some-illegal-memory-access-and-memory-lea.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0a0a490c805fadc7191489277e77fbf9688b39ab Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 10 Feb 2022 21:32:37 +0800 -Subject: [PATCH] bugfix: fix some illegal memory access and memory leak - -Signed-off-by: yuxiating -Signed-off-by: jiangdongxu ---- - contrib/elf2dmp/main.c | 1 + - hw/display/cirrus_vga.c | 2 +- - util/range.c | 1 + - 3 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c -index 20b477d582..3f0d1eb709 100644 ---- a/contrib/elf2dmp/main.c -+++ b/contrib/elf2dmp/main.c -@@ -125,6 +125,7 @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, struct pdb_reader *pdb, - - if (va_space_rw(vs, KdDebuggerDataBlock, kdbg, kdbg_hdr.Size, 0)) { - eprintf("Failed to extract entire KDBG\n"); -+ free(kdbg); - return NULL; - } - -diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c -index fdca6ca659..c66ed801ef 100644 ---- a/hw/display/cirrus_vga.c -+++ b/hw/display/cirrus_vga.c -@@ -834,7 +834,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) - word alignment, so we keep them for the next line */ - /* XXX: keep alignment to speed up transfer */ - end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; -- copy_count = s->cirrus_srcptr_end - end_ptr; -+ copy_count = MIN(s->cirrus_srcptr_end - end_ptr, CIRRUS_BLTBUFSIZE); - memmove(s->cirrus_bltbuf, end_ptr, copy_count); - s->cirrus_srcptr = s->cirrus_bltbuf + copy_count; - s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; -diff --git a/util/range.c b/util/range.c -index 098d9d2dc0..83d1a6c302 100644 ---- a/util/range.c -+++ b/util/range.c -@@ -65,6 +65,7 @@ GList *range_list_insert(GList *list, Range *data) - range_extend(l->data, l->next->data); - g_free(l->next->data); - new_l = g_list_delete_link(list, l->next); -+ l->next = NULL; - assert(new_l == list); - } - --- -2.27.0 - diff --git a/bugfix-irq-Avoid-covering-object-refcount-of-qemu_ir.patch b/bugfix-irq-Avoid-covering-object-refcount-of-qemu_ir.patch deleted file mode 100644 index 5a329c7f1d4ed1472e22909b75bcd56cd92b32a0..0000000000000000000000000000000000000000 --- a/bugfix-irq-Avoid-covering-object-refcount-of-qemu_ir.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 32353a7838f9ff38c5bd768252a79bd8e485658b Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Mon, 27 Jul 2020 20:39:07 +0800 -Subject: [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq - -Avoid covering object refcount of qemu_irq, otherwise it may causes -memory leak. - -Signed-off-by: Keqian Zhu ---- - hw/core/irq.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/hw/core/irq.c b/hw/core/irq.c -index 8a9cbdd556..700a6373d8 100644 ---- a/hw/core/irq.c -+++ b/hw/core/irq.c -@@ -126,7 +126,10 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n) - int i; - qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n); - for (i = 0; i < n; i++) { -- *old_irqs[i] = *gpio_in[i]; -+ old_irqs[i]->handler = gpio_in[i]->handler; -+ old_irqs[i]->opaque = gpio_in[i]->opaque; -+ old_irqs[i]->n = gpio_in[i]->n; -+ - gpio_in[i]->handler = handler; - gpio_in[i]->opaque = &old_irqs[i]; - } --- -2.27.0 - diff --git a/bugfix-pointer-double-free-in-func-qemu_savevm_state.patch b/bugfix-pointer-double-free-in-func-qemu_savevm_state.patch deleted file mode 100644 index e6e0c2d8d212c18d4120c3c17f135cf00ad6f934..0000000000000000000000000000000000000000 --- a/bugfix-pointer-double-free-in-func-qemu_savevm_state.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 48ff0d29c594ccfa80a3d58c97bdb7e656c8f541 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Mon, 20 Jun 2022 17:19:44 +0800 -Subject: [PATCH 9/9] bugfix: pointer double free in func - qemu_savevm_state_complete_precopy_non_iterable - -vmdesc defined in qemu_savevm_state_complete_precopy_non_iterable is a g_autoptr, -it will be auto freed when function return. thus when we call json_writer_free -before function return to free vmdesc, it will be double freed. fix it. - -Signed-off-by: jiangdongxu ---- - migration/savevm.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/migration/savevm.c b/migration/savevm.c -index 803cd9004d..d59e976d50 100644 ---- a/migration/savevm.c -+++ b/migration/savevm.c -@@ -1427,7 +1427,6 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, - ret = vmstate_save(f, se, vmdesc); - if (ret) { - qemu_file_set_error(f, ret); -- json_writer_free(vmdesc); - return ret; - } - trace_savevm_section_end(se->idstr, se->section_id, 0); -@@ -1444,7 +1443,6 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f, - error_report("%s: bdrv_inactivate_all() failed (%d)", - __func__, ret); - qemu_file_set_error(f, ret); -- json_writer_free(vmdesc); - return ret; - } - } --- -2.27.0 - diff --git a/chardev-char-socket-set-s-listener-NULL-in-char_sock.patch b/chardev-char-socket-set-s-listener-NULL-in-char_sock.patch deleted file mode 100644 index 5567ce3f0d27e38af08c7970e87f78a6d25ffe0e..0000000000000000000000000000000000000000 --- a/chardev-char-socket-set-s-listener-NULL-in-char_sock.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 936bf87a5acca3414625768c351fcc4e378fa30d Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Mon, 8 May 2023 00:24:18 -0700 -Subject: [PATCH] chardev/char-socket: set s->listener = NULL in - char_socket_finalize -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit b8a7f51f59e28d5a8e0c07ed3919cc9695560ed2 - -After live migration with virtio block device, qemu crash at: - - #0 0x000055914f46f795 in object_dynamic_cast_assert (obj=0x559151b7b090, typename=0x55914f80fbc4 "qio-channel", file=0x55914f80fb90 "/images/testvfe/sw/qemu.gerrit/include/io/channel.h", line=30, func=0x55914f80fcb8 <__func__.17257> "QIO_CHANNEL") at ../qom/object.c:872 - #1 0x000055914f480d68 in QIO_CHANNEL (obj=0x559151b7b090) at /images/testvfe/sw/qemu.gerrit/include/io/channel.h:29 - #2 0x000055914f4812f8 in qio_net_listener_set_client_func_full (listener=0x559151b7a720, func=0x55914f580b97 , data=0x5591519f4ea0, notify=0x0, context=0x0) at ../io/net-listener.c:166 - #3 0x000055914f580059 in tcp_chr_update_read_handler (chr=0x5591519f4ea0) at ../chardev/char-socket.c:637 - #4 0x000055914f583dca in qemu_chr_be_update_read_handlers (s=0x5591519f4ea0, context=0x0) at ../chardev/char.c:226 - #5 0x000055914f57b7c9 in qemu_chr_fe_set_handlers_full (b=0x559152bf23a0, fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, opaque=0x0, context=0x0, set_open=false, sync_state=true) at ../chardev/char-fe.c:279 - #6 0x000055914f57b86d in qemu_chr_fe_set_handlers (b=0x559152bf23a0, fd_can_read=0x0, fd_read=0x0, fd_event=0x0, be_change=0x0, opaque=0x0, context=0x0, set_open=false) at ../chardev/char-fe.c:304 - #7 0x000055914f378caf in vhost_user_async_close (d=0x559152bf21a0, chardev=0x559152bf23a0, vhost=0x559152bf2420, cb=0x55914f2fb8c1 ) at ../hw/virtio/vhost-user.c:2725 - #8 0x000055914f2fba40 in vhost_user_blk_event (opaque=0x559152bf21a0, event=CHR_EVENT_CLOSED) at ../hw/block/vhost-user-blk.c:395 - #9 0x000055914f58388c in chr_be_event (s=0x5591519f4ea0, event=CHR_EVENT_CLOSED) at ../chardev/char.c:61 - #10 0x000055914f583905 in qemu_chr_be_event (s=0x5591519f4ea0, event=CHR_EVENT_CLOSED) at ../chardev/char.c:81 - #11 0x000055914f581275 in char_socket_finalize (obj=0x5591519f4ea0) at ../chardev/char-socket.c:1083 - #12 0x000055914f46f073 in object_deinit (obj=0x5591519f4ea0, type=0x5591519055c0) at ../qom/object.c:680 - #13 0x000055914f46f0e5 in object_finalize (data=0x5591519f4ea0) at ../qom/object.c:694 - #14 0x000055914f46ff06 in object_unref (objptr=0x5591519f4ea0) at ../qom/object.c:1202 - #15 0x000055914f4715a4 in object_finalize_child_property (obj=0x559151b76c50, name=0x559151b7b250 "char3", opaque=0x5591519f4ea0) at ../qom/object.c:1747 - #16 0x000055914f46ee86 in object_property_del_all (obj=0x559151b76c50) at ../qom/object.c:632 - #17 0x000055914f46f0d2 in object_finalize (data=0x559151b76c50) at ../qom/object.c:693 - #18 0x000055914f46ff06 in object_unref (objptr=0x559151b76c50) at ../qom/object.c:1202 - #19 0x000055914f4715a4 in object_finalize_child_property (obj=0x559151b6b560, name=0x559151b76630 "chardevs", opaque=0x559151b76c50) at ../qom/object.c:1747 - #20 0x000055914f46ef67 in object_property_del_child (obj=0x559151b6b560, child=0x559151b76c50) at ../qom/object.c:654 - #21 0x000055914f46f042 in object_unparent (obj=0x559151b76c50) at ../qom/object.c:673 - #22 0x000055914f58632a in qemu_chr_cleanup () at ../chardev/char.c:1189 - #23 0x000055914f16c66c in qemu_cleanup () at ../softmmu/runstate.c:830 - #24 0x000055914eee7b9e in qemu_default_main () at ../softmmu/main.c:38 - #25 0x000055914eee7bcc in main (argc=86, argv=0x7ffc97cb8d88) at ../softmmu/main.c:48 - -In char_socket_finalize after s->listener freed, event callback function -vhost_user_blk_event will be called to handle CHR_EVENT_CLOSED. -vhost_user_blk_event is calling qio_net_listener_set_client_func_full which -is still using s->listener. - -Setting s->listener = NULL after object_unref(OBJECT(s->listener)) can -solve this issue. - -Signed-off-by: Yajun Wu -Acked-by: Jiri Pirko -Message-Id: <20230214021430.3638579-1-yajunw@nvidia.com> -Reviewed-by: Marc-André Lureau -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin - -Signed-off-by: Wanghe Xiao ---- - chardev/char-socket.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/chardev/char-socket.c b/chardev/char-socket.c -index 57ae53304a..459b9b72bd 100644 ---- a/chardev/char-socket.c -+++ b/chardev/char-socket.c -@@ -1142,6 +1142,7 @@ static void char_socket_finalize(Object *obj) - qio_net_listener_set_client_func_full(s->listener, NULL, NULL, - NULL, chr->gcontext); - object_unref(OBJECT(s->listener)); -+ s->listener = NULL; - } - if (s->tls_creds) { - object_unref(OBJECT(s->tls_creds)); --- -2.41.0.windows.1 - diff --git a/chardev-fix-segfault-in-finalize.patch b/chardev-fix-segfault-in-finalize.patch deleted file mode 100644 index 9a1813bbd46875cbfcd36e8a13827d363ecec271..0000000000000000000000000000000000000000 --- a/chardev-fix-segfault-in-finalize.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 670866f0349229045c5cddaeb08f07347bb7583b Mon Sep 17 00:00:00 2001 -From: cmss_dx -Date: Tue, 29 Nov 2022 02:12:06 +0000 -Subject: [PATCH 01/17] chardev: fix segfault in finalize -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mainline inclusion -from mainline-v7.2.0-rc2 -commit fc0c128531ed55f058bfbad4f1348ebd9a0187f2 -category: bugfix - ------------------------ - -If finalize chardev-msmouse or chardev-wctable is called immediately after -init it cases QEMU to crash with segfault. This happens because of -QTAILQ_REMOVE in qemu_input_handler_unregister tries to dereference -NULL pointer. -For instance, this error can be reproduced via qom-list-properties -command. - -Signed-off-by: Maksim Davydov davydov-max@yandex-team.ru -Reviewed-by: Marc-André Lureau marcandre.lureau@redhat.com -Reviewed-by: Vladimir Sementsov-Ogievskiy vsementsov@yandex-team.ru -Message-Id: 20220825165247.33704-1-davydov-max@yandex-team.ru - -Signed-off-by: cmss_dx ---- - chardev/msmouse.c | 4 +++- - chardev/wctablet.c | 4 +++- - 2 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/chardev/msmouse.c b/chardev/msmouse.c -index eb9231dcdb..2cc1b16561 100644 ---- a/chardev/msmouse.c -+++ b/chardev/msmouse.c -@@ -146,7 +146,9 @@ static void char_msmouse_finalize(Object *obj) - { - MouseChardev *mouse = MOUSE_CHARDEV(obj); - -- qemu_input_handler_unregister(mouse->hs); -+ if (mouse->hs) { -+ qemu_input_handler_unregister(mouse->hs); -+ } - } - - static QemuInputHandler msmouse_handler = { -diff --git a/chardev/wctablet.c b/chardev/wctablet.c -index e8b292c43c..43bdf6b608 100644 ---- a/chardev/wctablet.c -+++ b/chardev/wctablet.c -@@ -319,7 +319,9 @@ static void wctablet_chr_finalize(Object *obj) - { - TabletChardev *tablet = WCTABLET_CHARDEV(obj); - -- qemu_input_handler_unregister(tablet->hs); -+ if (tablet->hs) { -+ qemu_input_handler_unregister(tablet->hs); -+ } - } - - static void wctablet_chr_open(Chardev *chr, --- -2.27.0 - diff --git a/chardev-report-the-handshake-error.patch b/chardev-report-the-handshake-error.patch deleted file mode 100644 index 57066235dd00df0568fb28b2c08b65da47df38b9..0000000000000000000000000000000000000000 --- a/chardev-report-the-handshake-error.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 30f9cc7263e44faf2b43c4fdf3d7c64ffb409502 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 14 Aug 2023 14:37:36 +0800 -Subject: [PATCH] chardev: report the handshake error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 81cd34a359a36656d2f6542226235bd318ff8873 - -This can help to debug connection issues. - -Related to: -https://bugzilla.redhat.com/show_bug.cgi?id=2196182 - -Signed-off-by: Marc-André Lureau -Reviewed-by: Daniel P. Berrangé -Message-Id: <20230510072531.3937189-1-marcandre.lureau@redhat.com> -Signed-off-by: qihao_yewu ---- - chardev/char-socket.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/chardev/char-socket.c b/chardev/char-socket.c -index 459b9b72bd..ef5d3053f3 100644 ---- a/chardev/char-socket.c -+++ b/chardev/char-socket.c -@@ -819,8 +819,12 @@ static void tcp_chr_websock_handshake(QIOTask *task, gpointer user_data) - { - Chardev *chr = user_data; - SocketChardev *s = user_data; -+ Error *err = NULL; - -- if (qio_task_propagate_error(task, NULL)) { -+ if (qio_task_propagate_error(task, &err)) { -+ error_reportf_err(err, -+ "websock handshake of character device %s failed: ", -+ chr->label); - tcp_chr_disconnect(chr); - } else { - if (s->do_telnetopt) { -@@ -855,8 +859,12 @@ static void tcp_chr_tls_handshake(QIOTask *task, - { - Chardev *chr = user_data; - SocketChardev *s = user_data; -+ Error *err = NULL; - -- if (qio_task_propagate_error(task, NULL)) { -+ if (qio_task_propagate_error(task, &err)) { -+ error_reportf_err(err, -+ "TLS handshake of character device %s failed: ", -+ chr->label); - tcp_chr_disconnect(chr); - } else { - if (s->is_websock) { --- -2.41.0.windows.1 - diff --git a/configure-Add-.-on-front-of-glob-of-config-devices.m.patch b/configure-Add-.-on-front-of-glob-of-config-devices.m.patch deleted file mode 100644 index 1da3c3931a8b8cf68e19b630a685334f1d66a260..0000000000000000000000000000000000000000 --- a/configure-Add-.-on-front-of-glob-of-config-devices.m.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 05facfc2f1442dc96b862fff97dde7f600a41491 Mon Sep 17 00:00:00 2001 -From: wangjinlei -Date: Thu, 24 Nov 2022 19:33:04 +0800 -Subject: [PATCH 26/29] configure: Add './' on front of glob of - */config-devices.mak.d -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Shellcheck warns that in - rm -f */config-devices.mak.d -the glob might expand to something with a '-' in it, which would -then be misinterpreted as an option to rm. Fix this by adding './'. - -Signed-off-by: Peter Maydell -Reviewed-by: Marc-André Lureau -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20220825150703.4074125-5-peter.maydell@linaro.org - -Signed-off-by: wangjinlei ---- - configure | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure b/configure -index 8cbf186296..7e81444ade 100755 ---- a/configure -+++ b/configure -@@ -1479,7 +1479,7 @@ exit 0 - fi - - # Remove old dependency files to make sure that they get properly regenerated --rm -f */config-devices.mak.d -+rm -f ./*/config-devices.mak.d - - if test -z "$python" - then --- -2.27.0 - diff --git a/configure-Add-missing-quoting-for-some-easy-cases.patch b/configure-Add-missing-quoting-for-some-easy-cases.patch deleted file mode 100644 index f6eb4a31eb938d7f1b499fc786e2c1a829cadf7d..0000000000000000000000000000000000000000 --- a/configure-Add-missing-quoting-for-some-easy-cases.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 6f1b97c06f116945553846cb0c5c3d949c953890 Mon Sep 17 00:00:00 2001 -From: wangjinlei -Date: Thu, 24 Nov 2022 19:29:07 +0800 -Subject: [PATCH 19/29] configure: Add missing quoting for some easy cases -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This commit adds quotes in some places which: - * are spotted by shellcheck - * are obviously incorrect - * are easy to fix just by adding the quotes - -It doesn't attempt fix all of the places shellcheck finds errors, -or even all the ones which are easy to fix. It's just a random -sampling which is hopefully easy to review and which cuts -down the size of the problem for next time somebody wants to -try to look at shellcheck errors. - -Signed-off-by: Peter Maydell -Reviewed-by: Marc-André Lureau -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20220825150703.4074125-4-peter.maydell@linaro.org - -Signed-off-by: wangjinlei ---- - configure | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/configure b/configure -index 8cbf186296..737572c8e6 100755 ---- a/configure -+++ b/configure -@@ -57,7 +57,7 @@ GNUmakefile: ; - - EOF - cd build -- exec $source_path/configure "$@" -+ exec "$source_path/configure" "$@" - fi - - # Temporary directory used for files created while -@@ -728,7 +728,7 @@ fi - - werror="" - --. $source_path/scripts/meson-buildoptions.sh -+. "$source_path/scripts/meson-buildoptions.sh" - - meson_options= - meson_option_parse() { -@@ -745,7 +745,7 @@ for opt do - case "$opt" in - --help|-h) show_help=yes - ;; -- --version|-V) exec cat $source_path/VERSION -+ --version|-V) exec cat "$source_path/VERSION" - ;; - --prefix=*) prefix="$optarg" - ;; -@@ -1503,7 +1503,7 @@ python="$python -B" - if test -z "$meson"; then - if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.59.3; then - meson=meson -- elif test $git_submodules_action != 'ignore' ; then -+ elif test "$git_submodules_action" != 'ignore' ; then - meson=git - elif test -e "${source_path}/meson/meson.py" ; then - meson=internal -@@ -3352,7 +3352,7 @@ if test "$QEMU_GA_DISTRO" = ""; then - QEMU_GA_DISTRO=Linux - fi - if test "$QEMU_GA_VERSION" = ""; then -- QEMU_GA_VERSION=$(cat $source_path/VERSION) -+ QEMU_GA_VERSION=$(cat "$source_path"/VERSION) - fi - - QEMU_GA_MSI_MINGW_DLL_PATH="$($pkg_config --variable=prefix glib-2.0)/bin" -@@ -3790,7 +3790,7 @@ fi - for target in $target_list; do - target_dir="$target" - target_name=$(echo $target | cut -d '-' -f 1) -- mkdir -p $target_dir -+ mkdir -p "$target_dir" - case $target in - *-user) symlink "../qemu-$target_name" "$target_dir/qemu-$target_name" ;; - *) symlink "../qemu-system-$target_name" "$target_dir/qemu-system-$target_name" ;; --- -2.27.0 - diff --git a/configure-Check-mkdir-result-directly-not-via.patch b/configure-Check-mkdir-result-directly-not-via.patch deleted file mode 100644 index c8bc9fb2ed237e70f4d682d98456b7bce71b78f8..0000000000000000000000000000000000000000 --- a/configure-Check-mkdir-result-directly-not-via.patch +++ /dev/null @@ -1,39 +0,0 @@ -From d5ad002a22aade5086722fd9aa2addf2f95e52c3 Mon Sep 17 00:00:00 2001 -From: wangjinlei -Date: Thu, 24 Nov 2022 19:39:33 +0800 -Subject: [PATCH 27/29] configure: Check mkdir result directly, not via $? -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Shellcheck warns that we have one place where we run a command and -then check if it failed using $?; this is better written to simply -check the command in the 'if' statement directly. - -Signed-off-by: Peter Maydell -Reviewed-by: Marc-André Lureau -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20220825150703.4074125-7-peter.maydell@linaro.org - -Signed-off-by: wangjinlei ---- - configure | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/configure b/configure -index 8cbf186296..561c86c913 100755 ---- a/configure -+++ b/configure -@@ -67,8 +67,7 @@ fi - # it when configure exits.) - TMPDIR1="config-temp" - rm -rf "${TMPDIR1}" --mkdir -p "${TMPDIR1}" --if [ $? -ne 0 ]; then -+if ! mkdir -p "${TMPDIR1}"; then - echo "ERROR: failed to create temporary directory" - exit 1 - fi --- -2.27.0 - diff --git a/configure-Remove-unused-meson_args-variable.patch b/configure-Remove-unused-meson_args-variable.patch deleted file mode 100644 index 559d60988b7674650b160028d6565a7b6538a71d..0000000000000000000000000000000000000000 --- a/configure-Remove-unused-meson_args-variable.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 280fca570579e659aa38def7f55151eea4f42712 Mon Sep 17 00:00:00 2001 -From: wangjinlei -Date: Thu, 24 Nov 2022 15:38:49 +0800 -Subject: [PATCH 17/29] configure: Remove unused meson_args variable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The meson_args variable was added in commit 3b4da13293482134b, but -was not used in that commit and isn't used today. Delete the -unnecessary assignment. - -Signed-off-by: Peter Maydell -Reviewed-by: Marc-André Lureau -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20220825150703.4074125-3-peter.maydell@linaro.org - -Signed-off-by: wangjinlei ---- - configure | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/configure b/configure -index e12ef3d842..8cbf186296 100755 ---- a/configure -+++ b/configure -@@ -361,7 +361,6 @@ plugins="$default_feature" - rng_none="no" - secret_keyring="$default_feature" - meson="" --meson_args="" - ninja="" - gio="$default_feature" - skip_meson=no --- -2.27.0 - diff --git a/configure-Remove-unused-python_version-variable.patch b/configure-Remove-unused-python_version-variable.patch deleted file mode 100644 index a18f502cf772e5a0754f9ea507e3864a28738231..0000000000000000000000000000000000000000 --- a/configure-Remove-unused-python_version-variable.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6933c65bc3835f69f2c774c7d27c8ebcd05d55d6 Mon Sep 17 00:00:00 2001 -From: wangjinlei -Date: Thu, 24 Nov 2022 14:54:20 +0800 -Subject: [PATCH 16/29] configure: Remove unused python_version variable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Shellcheck correctly reports that we set python_version and never use -it. This is a leftover from commit f9332757898a7: we used to use -python_version purely to as part of the summary information printed -at the end of a configure run, and that commit changed to printing -the information from meson (which looks up the python version -itself). Remove the unused variable. - -Signed-off-by: Peter Maydell -Reviewed-by: Marc-André Lureau -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20220825150703.4074125-2-peter.maydell@linaro.org - -Signed-off-by: wangjinlei ---- - configure | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/configure b/configure -index 0ae7bcf065..e12ef3d842 100755 ---- a/configure -+++ b/configure -@@ -1498,9 +1498,6 @@ if ! $python -c 'import sys; sys.exit(sys.version_info < (3,6))'; then - "Use --python=/path/to/python to specify a supported Python." - fi - --# Preserve python version since some functionality is dependent on it --python_version=$($python -c 'import sys; print("%d.%d.%d" % (sys.version_info[0], sys.version_info[1], sys.version_info[2]))' 2>/dev/null) -- - # Suppress writing compiled files - python="$python -B" - --- -2.27.0 - diff --git a/configure-meson-move-AVX-tests-to-meson.patch b/configure-meson-move-AVX-tests-to-meson.patch deleted file mode 100644 index 2a11ed781621fef6cf0de748a20a6f56a5e725cd..0000000000000000000000000000000000000000 --- a/configure-meson-move-AVX-tests-to-meson.patch +++ /dev/null @@ -1,290 +0,0 @@ -From 54625fb7d039ef746f88ad0bf78515e96af7305d Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 8 Nov 2021 13:38:58 +0100 -Subject: [PATCH] configure, meson: move AVX tests to meson - -mainline inclusion -from mainline-v7.0.0-rc0 -commit 622753d2fb501509ab03c241d476815f378d4ba5 -category: feature -feature: AVX512 support for xbzrle_encode_buffer -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6Z50P - -Intel-SIG: commit 622753d2fb50 ("configure, meson: move AVX tests to meson") - -------------------------------------- - -configure, meson: move AVX tests to meson - -For consistency with other tests, --enable-avx2 and --enable-avx512f -fail to compile on x86 systems if cpuid.h is not available. - -Reviewed-by: Richard Henderson -Signed-off-by: Paolo Bonzini -Signed-off-by: Aichun Shi ---- - configure | 103 ---------------------------------- - meson.build | 50 ++++++++++++++++- - meson_options.txt | 4 ++ - scripts/meson-buildoptions.sh | 6 ++ - 4 files changed, 58 insertions(+), 105 deletions(-) - -diff --git a/configure b/configure -index a84dc891cc..d7a4502a8b 100755 ---- a/configure -+++ b/configure -@@ -329,8 +329,6 @@ qom_cast_debug="yes" - trace_backends="log" - trace_file="trace" - opengl="$default_feature" --cpuid_h="no" --avx2_opt="$default_feature" - guest_agent="$default_feature" - guest_agent_with_vss="no" - guest_agent_ntddscsi="no" -@@ -1053,14 +1051,6 @@ for opt do - ;; - --disable-tools) want_tools="no" - ;; -- --disable-avx2) avx2_opt="no" -- ;; -- --enable-avx2) avx2_opt="yes" -- ;; -- --disable-avx512f) avx512f_opt="no" -- ;; -- --enable-avx512f) avx512f_opt="yes" -- ;; - --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane) - echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2 - ;; -@@ -1456,8 +1446,6 @@ cat << EOF - tpm TPM support - libssh ssh block device support - numa libnuma support -- avx2 AVX2 optimization support -- avx512f AVX512F optimization support - replication replication support - opengl opengl support - xfsctl xfsctl support -@@ -2893,85 +2881,6 @@ else # "$safe_stack" = "" - fi - fi - --######################################## --# check if cpuid.h is usable. -- --cat > $TMPC << EOF --#include --int main(void) { -- unsigned a, b, c, d; -- int max = __get_cpuid_max(0, 0); -- -- if (max >= 1) { -- __cpuid(1, a, b, c, d); -- } -- -- if (max >= 7) { -- __cpuid_count(7, 0, a, b, c, d); -- } -- -- return 0; --} --EOF --if compile_prog "" "" ; then -- cpuid_h=yes --fi -- --########################################## --# avx2 optimization requirement check --# --# There is no point enabling this if cpuid.h is not usable, --# since we won't be able to select the new routines. -- --if test "$cpuid_h" = "yes" && test "$avx2_opt" != "no"; then -- cat > $TMPC << EOF --#pragma GCC push_options --#pragma GCC target("avx2") --#include --#include --static int bar(void *a) { -- __m256i x = *(__m256i *)a; -- return _mm256_testz_si256(x, x); --} --int main(int argc, char *argv[]) { return bar(argv[0]); } --EOF -- if compile_object "-Werror" ; then -- avx2_opt="yes" -- else -- avx2_opt="no" -- fi --fi -- --########################################## --# avx512f optimization requirement check --# --# There is no point enabling this if cpuid.h is not usable, --# since we won't be able to select the new routines. --# by default, it is turned off. --# if user explicitly want to enable it, check environment -- --if test "$cpuid_h" = "yes" && test "$avx512f_opt" = "yes"; then -- cat > $TMPC << EOF --#pragma GCC push_options --#pragma GCC target("avx512f") --#include --#include --static int bar(void *a) { -- __m512i x = *(__m512i *)a; -- return _mm512_test_epi64_mask(x, x); --} --int main(int argc, char *argv[]) --{ -- return bar(argv[0]); --} --EOF -- if ! compile_object "-Werror" ; then -- avx512f_opt="no" -- fi --else -- avx512f_opt="no" --fi -- - ######################################## - # check if __[u]int128_t is usable. - -@@ -3587,14 +3496,6 @@ if test "$opengl" = "yes" ; then - echo "OPENGL_LIBS=$opengl_libs" >> $config_host_mak - fi - --if test "$avx2_opt" = "yes" ; then -- echo "CONFIG_AVX2_OPT=y" >> $config_host_mak --fi -- --if test "$avx512f_opt" = "yes" ; then -- echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak --fi -- - # XXX: suppress that - if [ "$bsd" = "yes" ] ; then - echo "CONFIG_BSD=y" >> $config_host_mak -@@ -3627,10 +3528,6 @@ if test "$have_tsan" = "yes" && test "$have_tsan_iface_fiber" = "yes" ; then - echo "CONFIG_TSAN=y" >> $config_host_mak - fi - --if test "$cpuid_h" = "yes" ; then -- echo "CONFIG_CPUID_H=y" >> $config_host_mak --fi -- - if test "$int128" = "yes" ; then - echo "CONFIG_INT128=y" >> $config_host_mak - fi -diff --git a/meson.build b/meson.build -index d80426b3e8..9f77254861 100644 ---- a/meson.build -+++ b/meson.build -@@ -1750,6 +1750,52 @@ config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' - return getauxval(AT_HWCAP) == 0; - }''')) - -+have_cpuid_h = cc.links(''' -+ #include -+ int main(void) { -+ unsigned a, b, c, d; -+ unsigned max = __get_cpuid_max(0, 0); -+ -+ if (max >= 1) { -+ __cpuid(1, a, b, c, d); -+ } -+ -+ if (max >= 7) { -+ __cpuid_count(7, 0, a, b, c, d); -+ } -+ -+ return 0; -+ }''') -+config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) -+ -+config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ -+ .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \ -+ .require(cc.links(''' -+ #pragma GCC push_options -+ #pragma GCC target("avx2") -+ #include -+ #include -+ static int bar(void *a) { -+ __m256i x = *(__m256i *)a; -+ return _mm256_testz_si256(x, x); -+ } -+ int main(int argc, char *argv[]) { return bar(argv[0]); } -+ '''), error_message: 'AVX2 not available').allowed()) -+ -+config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \ -+ .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \ -+ .require(cc.links(''' -+ #pragma GCC push_options -+ #pragma GCC target("avx512f") -+ #include -+ #include -+ static int bar(void *a) { -+ __m512i x = *(__m512i *)a; -+ return _mm512_test_epi64_mask(x, x); -+ } -+ int main(int argc, char *argv[]) { return bar(argv[0]); } -+ '''), error_message: 'AVX512F not available').allowed()) -+ - config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + ''' - #include - #include -@@ -3271,8 +3317,8 @@ summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')} - summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')} - summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')} - summary_info += {'memory allocator': get_option('malloc')} --summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')} --summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')} -+summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} -+summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')} - summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')} - summary_info += {'gcov': get_option('b_coverage')} - summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')} -diff --git a/meson_options.txt b/meson_options.txt -index e392323732..e9cbe48cb9 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -66,6 +66,10 @@ option('cfi_debug', type: 'boolean', value: 'false', - description: 'Verbose errors in case of CFI violation') - option('multiprocess', type: 'feature', value: 'auto', - description: 'Out of process device emulation support') -+option('avx2', type: 'feature', value: 'auto', -+ description: 'AVX2 optimizations') -+option('avx512f', type: 'feature', value: 'disabled', -+ description: 'AVX512F optimizations') - - option('attr', type : 'feature', value : 'auto', - description: 'attr/xattr support') -diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh -index 7a17ff4218..b994bf16f0 100644 ---- a/scripts/meson-buildoptions.sh -+++ b/scripts/meson-buildoptions.sh -@@ -25,6 +25,8 @@ meson_options_help() { - printf "%s\n" ' alsa ALSA sound support' - printf "%s\n" ' attr attr/xattr support' - printf "%s\n" ' auth-pam PAM access control' -+ printf "%s\n" ' avx2 AVX2 optimizations' -+ printf "%s\n" ' avx512f AVX512F optimizations' - printf "%s\n" ' bpf eBPF support' - printf "%s\n" ' brlapi brlapi character device driver' - printf "%s\n" ' bzip2 bzip2 support for DMG images' -@@ -107,6 +109,10 @@ _meson_option_parse() { - --disable-attr) printf "%s" -Dattr=disabled ;; - --enable-auth-pam) printf "%s" -Dauth_pam=enabled ;; - --disable-auth-pam) printf "%s" -Dauth_pam=disabled ;; -+ --enable-avx2) printf "%s" -Davx2=enabled ;; -+ --disable-avx2) printf "%s" -Davx2=disabled ;; -+ --enable-avx512f) printf "%s" -Davx512f=enabled ;; -+ --disable-avx512f) printf "%s" -Davx512f=disabled ;; - --enable-bpf) printf "%s" -Dbpf=enabled ;; - --disable-bpf) printf "%s" -Dbpf=disabled ;; - --enable-brlapi) printf "%s" -Dbrlapi=enabled ;; --- -2.27.0 - diff --git a/core-cpu-common-Fix-the-wrong-ifdef-__aarch64__.patch b/core-cpu-common-Fix-the-wrong-ifdef-__aarch64__.patch deleted file mode 100644 index 79a70ec61e2c13e21eeffa39769f3dc5a7c67f91..0000000000000000000000000000000000000000 --- a/core-cpu-common-Fix-the-wrong-ifdef-__aarch64__.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a6f84e8f2c1fef8ca8f48f81e2e6a1b823d9a90e Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 21 Apr 2023 14:53:46 +0800 -Subject: [PATCH] core/cpu-common: Fix the wrong '#ifdef __aarch64__' - -commit c3f86c199885 ("arm/virt: Correct timing of executing -cpu_synchronize_post_init for hot-plugged cpus") used the -wrong '#ifdef __aarch64__'. It should be '#ifndef __aarch64__'. - -Fixes: c3f86c199885 ("arm/virt: Correct timing of executing -cpu_synchronize_post_init for hot-plugged cpus") -Signed-off-by: Kunkun Jiang ---- - hw/core/cpu-common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c -index 2213840260..92d15f2f49 100644 ---- a/hw/core/cpu-common.c -+++ b/hw/core/cpu-common.c -@@ -206,7 +206,7 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) - } - } - --#ifdef __aarch64__ -+#ifndef __aarch64__ - if (dev->hotplugged) { - cpu_synchronize_post_init(cpu); - cpu_resume(cpu); --- -2.27.0 - diff --git a/coro-support-live-patch-for-libcare.patch b/coro-support-live-patch-for-libcare.patch deleted file mode 100644 index 5e287eb8965a7dceae982963097dc196874f3347..0000000000000000000000000000000000000000 --- a/coro-support-live-patch-for-libcare.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 2135fe8e9c4d459d3f06babf3bfd71b5387b0214 Mon Sep 17 00:00:00 2001 -From: jiang-dawei15 -Date: Tue, 15 Mar 2022 10:28:34 +0800 -Subject: [PATCH] coro: support live patch for libcare - -Description: -For coroutine live patch, we need find all coroutines stack and check them -before patching. There is no structure to manage all coroutines in qemu. So we -add a list which contain all running coroutines to accelerate libcare live -patch. ---- - include/qemu/coroutine_int.h | 3 ++- - util/coroutine-ucontext.c | 52 ++++++++++++++++++++++++++++++++++++ - util/qemu-coroutine.c | 4 +++ - 3 files changed, 58 insertions(+), 1 deletion(-) - -diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h -index 1da148552f..11b550a0fc 100644 ---- a/include/qemu/coroutine_int.h -+++ b/include/qemu/coroutine_int.h -@@ -73,5 +73,6 @@ Coroutine *qemu_coroutine_new(void); - void qemu_coroutine_delete(Coroutine *co); - CoroutineAction qemu_coroutine_switch(Coroutine *from, Coroutine *to, - CoroutineAction action); -- -+void qemu_coroutine_info_add(const Coroutine *co_); -+void qemu_coroutine_info_delete(const Coroutine *co_); - #endif -diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c -index 904b375192..23ab7cdf74 100644 ---- a/util/coroutine-ucontext.c -+++ b/util/coroutine-ucontext.c -@@ -79,6 +79,19 @@ union cc_arg { - int i[2]; - }; - -+/** -+ * coroutines list for libcare -+ */ -+struct CoroutineInformation { -+ sigjmp_buf *env; -+ QLIST_ENTRY(CoroutineInformation) next; -+}; -+ -+static QemuMutex coro_mtx; -+QLIST_HEAD(, CoroutineInformation) coro_info_list = QLIST_HEAD_INITIALIZER(pool); -+int coro_env_offset = offsetof(struct CoroutineInformation, env); -+int coro_next_offset = offsetof(struct CoroutineInformation, next); -+ - /* - * QEMU_ALWAYS_INLINE only does so if __OPTIMIZE__, so we cannot use it. - * always_inline is required to avoid TSan runtime fatal errors. -@@ -330,3 +343,42 @@ bool qemu_in_coroutine(void) - { - return current && current->caller; - } -+ -+static void __attribute__((constructor)) coro_mutex_init(void) -+{ -+ qemu_mutex_init(&coro_mtx); -+} -+ -+void qemu_coroutine_info_add(const Coroutine *co_) -+{ -+ CoroutineUContext *co; -+ struct CoroutineInformation *coro_info; -+ -+ /* save coroutine env to coro_info_list */ -+ co = DO_UPCAST(CoroutineUContext, base, co_); -+ coro_info = g_malloc0(sizeof(struct CoroutineInformation)); -+ coro_info->env = &co->env; -+ -+ qemu_mutex_lock(&coro_mtx); -+ QLIST_INSERT_HEAD(&coro_info_list, coro_info, next); -+ qemu_mutex_unlock(&coro_mtx); -+} -+ -+void qemu_coroutine_info_delete(const Coroutine *co_) -+{ -+ CoroutineUContext *co; -+ struct CoroutineInformation *coro_info; -+ -+ /* Remove relative coroutine env info from coro_info_list */ -+ co = DO_UPCAST(CoroutineUContext, base, co_); -+ -+ qemu_mutex_lock(&coro_mtx); -+ QLIST_FOREACH(coro_info, &coro_info_list, next) { -+ if (coro_info->env == &co->env) { -+ QLIST_REMOVE(coro_info, next); -+ g_free(coro_info); -+ break; -+ } -+ } -+ qemu_mutex_unlock(&coro_mtx); -+} -diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c -index b9586d6929..9c81336d8e 100644 ---- a/util/qemu-coroutine.c -+++ b/util/qemu-coroutine.c -@@ -75,6 +75,8 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque) - co = qemu_coroutine_new(); - } - -+ qemu_coroutine_info_add(co); -+ - co->entry = entry; - co->entry_arg = opaque; - QSIMPLEQ_INIT(&co->co_queue_wakeup); -@@ -85,6 +87,8 @@ static void coroutine_delete(Coroutine *co) - { - co->caller = NULL; - -+ qemu_coroutine_info_delete(co); -+ - if (CONFIG_COROUTINE_POOL) { - if (release_pool_size < POOL_BATCH_SIZE * 2) { - QSLIST_INSERT_HEAD_ATOMIC(&release_pool, co, pool_next); --- -2.27.0 - diff --git a/cpu-add-Cortex-A72-processor-kvm-target-support-v2.patch b/cpu-add-Cortex-A72-processor-kvm-target-support-v2.patch deleted file mode 100644 index a98198975b194350bdfc574a426704f213f5cbba..0000000000000000000000000000000000000000 --- a/cpu-add-Cortex-A72-processor-kvm-target-support-v2.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 8ddc2bcb196a34cc641d50b057550e4b11dc8700 Mon Sep 17 00:00:00 2001 -From: Xu Yandong -Date: Wed, 9 Feb 2022 17:39:34 +0800 -Subject: [PATCH 3/3] cpu: add Cortex-A72 processor kvm target support - -The ARM Cortex-A72 is ARMv8-A micro-architecture, -add kvm target to ARM Cortex-A72 processor definition. - -Signed-off-by: Xu Yandong -Signed-off-by: Mingwang Li ---- - target/arm/cpu64.c | 2 +- - target/arm/kvm-consts.h | 3 +++ - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 26419fe994..1b56261964 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -202,6 +202,7 @@ static void aarch64_a72_initfn(Object *obj) - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,cortex-a72"; -+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_GENERIC_V8; - set_feature(&cpu->env, ARM_FEATURE_V8); - set_feature(&cpu->env, ARM_FEATURE_NEON); - set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); -@@ -265,7 +266,6 @@ static void aarch64_kunpeng_920_initfn(Object *obj) - cpu->isar.id_aa64dfr0 = 0x110305408; - cpu->isar.id_aa64isar0 = 0x10211120; - cpu->isar.id_aa64mmfr0 = 0x101125; -- cpu->kvm_target = KVM_ARM_TARGET_GENERIC_V8; - } - - void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) -diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h -index 580f1c1fee..5f1311ade7 100644 ---- a/target/arm/kvm-consts.h -+++ b/target/arm/kvm-consts.h -@@ -130,6 +130,8 @@ MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED); - #define QEMU_KVM_ARM_TARGET_CORTEX_A57 2 - #define QEMU_KVM_ARM_TARGET_XGENE_POTENZA 3 - #define QEMU_KVM_ARM_TARGET_CORTEX_A53 4 -+/* Generic ARM v8 target */ -+#define QEMU_KVM_ARM_TARGET_GENERIC_V8 5 - - /* There's no kernel define for this: sentinel value which - * matches no KVM target value for either 64 or 32 bit -@@ -141,6 +143,7 @@ MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53); -+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_GENERIC_V8, KVM_ARM_TARGET_GENERIC_V8); - - #define CP_REG_ARM64 0x6000000000000000ULL - #define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000 --- -2.27.0 - diff --git a/cpu-add-Cortex-A72-processor-kvm-target-support.patch b/cpu-add-Cortex-A72-processor-kvm-target-support.patch deleted file mode 100644 index 9a83a8d560cde00b49675184bb86c780c0a33691..0000000000000000000000000000000000000000 --- a/cpu-add-Cortex-A72-processor-kvm-target-support.patch +++ /dev/null @@ -1,51 +0,0 @@ -From f0da7fa5230b5f771570b2c12288e4a56a20dd97 Mon Sep 17 00:00:00 2001 -From: Xu Yandong -Date: Tue, 8 Feb 2022 22:18:55 +0800 -Subject: [PATCH] cpu: add Cortex-A72 processor kvm target support - -The ARM Cortex-A72 is ARMv8-A micro-architecture, -add kvm target to ARM Cortex-A72 processor definition. - -Signed-off-by: Xu Yandong -Signed-off-by: Mingwang Li ---- - target/arm/cpu64.c | 1 + - target/arm/kvm-consts.h | 3 +++ - 2 files changed, 4 insertions(+) - -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index aaca79f7c3..556b6f3691 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -202,6 +202,7 @@ static void aarch64_a72_initfn(Object *obj) - ARMCPU *cpu = ARM_CPU(obj); - - cpu->dtb_compatible = "arm,cortex-a72"; -+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_GENERIC_V8; - set_feature(&cpu->env, ARM_FEATURE_V8); - set_feature(&cpu->env, ARM_FEATURE_NEON); - set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); -diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h -index 580f1c1fee..5f1311ade7 100644 ---- a/target/arm/kvm-consts.h -+++ b/target/arm/kvm-consts.h -@@ -130,6 +130,8 @@ MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED); - #define QEMU_KVM_ARM_TARGET_CORTEX_A57 2 - #define QEMU_KVM_ARM_TARGET_XGENE_POTENZA 3 - #define QEMU_KVM_ARM_TARGET_CORTEX_A53 4 -+/* Generic ARM v8 target */ -+#define QEMU_KVM_ARM_TARGET_GENERIC_V8 5 - - /* There's no kernel define for this: sentinel value which - * matches no KVM target value for either 64 or 32 bit -@@ -141,6 +143,7 @@ MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA); - MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53); -+MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_GENERIC_V8, KVM_ARM_TARGET_GENERIC_V8); - - #define CP_REG_ARM64 0x6000000000000000ULL - #define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000 --- -2.27.0 - diff --git a/cpu-add-Kunpeng-920-cpu-support.patch b/cpu-add-Kunpeng-920-cpu-support.patch deleted file mode 100644 index 5e24be91c6cf13417cb239f561c60bd4704c0711..0000000000000000000000000000000000000000 --- a/cpu-add-Kunpeng-920-cpu-support.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 8ebab06c4824626ab4d7204133cd1e7b9c67f468 Mon Sep 17 00:00:00 2001 -From: Xu Yandong -Date: Tue, 8 Feb 2022 21:36:22 +0800 -Subject: [PATCH] cpu: add Kunpeng-920 cpu support - -Add the Kunpeng-920 CPU model - -Signed-off-by: Xu Yandong -Signed-off-by: Mingwang Li ---- - hw/arm/virt.c | 1 + - target/arm/cpu64.c | 21 +++++++++++++++++++++ - 2 files changed, 22 insertions(+) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 30da05dfe0..a4a35584e9 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -201,6 +201,7 @@ static const char *valid_cpus[] = { - ARM_CPU_TYPE_NAME("cortex-a53"), - ARM_CPU_TYPE_NAME("cortex-a57"), - ARM_CPU_TYPE_NAME("cortex-a72"), -+ ARM_CPU_TYPE_NAME("Kunpeng-920"), - ARM_CPU_TYPE_NAME("a64fx"), - ARM_CPU_TYPE_NAME("host"), - ARM_CPU_TYPE_NAME("max"), -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 019edc66c9..aaca79f7c3 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -248,6 +248,26 @@ static void aarch64_a72_initfn(Object *obj) - define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo); - } - -+static void aarch64_kunpeng_920_initfn(Object *obj) -+{ -+ ARMCPU *cpu = ARM_CPU(obj); -+ -+ /* -+ * Hisilicon Kunpeng-920 CPU is similar to cortex-a72, -+ * so first initialize cpu data as cortex-a72, -+ * and then update the special register. -+ */ -+ aarch64_a72_initfn(obj); -+ -+ cpu->midr = 0x480fd010; -+ cpu->ctr = 0x84448004; -+ cpu->isar.id_aa64pfr0 = 0x11001111; -+ cpu->isar.id_aa64dfr0 = 0x110305408; -+ cpu->isar.id_aa64isar0 = 0x10211120; -+ cpu->isar.id_aa64mmfr0 = 0x101125; -+ cpu->kvm_target = KVM_ARM_TARGET_GENERIC_V8; -+} -+ - void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) - { - /* -@@ -892,6 +912,7 @@ static const ARMCPUInfo aarch64_cpus[] = { - { .name = "cortex-a57", .initfn = aarch64_a57_initfn }, - { .name = "cortex-a53", .initfn = aarch64_a53_initfn }, - { .name = "cortex-a72", .initfn = aarch64_a72_initfn }, -+ { .name = "Kunpeng-920", .initfn = aarch64_kunpeng_920_initfn}, - { .name = "a64fx", .initfn = aarch64_a64fx_initfn }, - { .name = "max", .initfn = aarch64_max_initfn }, - }; --- -2.27.0 - diff --git a/cpu-features-fix-bug-for-memory-leakage.patch b/cpu-features-fix-bug-for-memory-leakage.patch deleted file mode 100644 index cb7010440d9d395acd9bb0bc9792de279a4d4088..0000000000000000000000000000000000000000 --- a/cpu-features-fix-bug-for-memory-leakage.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 12706113392018fd7aa6471a3cbada62f0180539 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Wed, 9 Feb 2022 12:51:19 +0800 -Subject: [PATCH 13/15] cpu/features: fix bug for memory leakage - -strList hash not free after used, Fix it. ---- - target/i386/cpu.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index aa9e636800..b9690e3250 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -4752,6 +4752,7 @@ static void x86_cpu_get_unavailable_features(Object *obj, Visitor *v, - - x86_cpu_list_feature_names(xc->filtered_features, &result); - visit_type_strList(v, "unavailable-features", &result, errp); -+ qapi_free_strList(result); - } - - /* Check for missing features that may prevent the CPU class from --- -2.27.0 - diff --git a/cpu-parse-feature-to-avoid-failure.patch b/cpu-parse-feature-to-avoid-failure.patch deleted file mode 100644 index 4ae42d904b815b115399e9560f3e456de96c712f..0000000000000000000000000000000000000000 --- a/cpu-parse-feature-to-avoid-failure.patch +++ /dev/null @@ -1,68 +0,0 @@ -From ef83cde8dd2c9b404527354489b14d2bd238733d Mon Sep 17 00:00:00 2001 -From: Xu Yandong -Date: Tue, 8 Feb 2022 20:48:17 +0800 -Subject: [PATCH] cpu: parse +/- feature to avoid failure - -To avoid cpu feature parse failure, +/- feature is added. - -Signed-off-by: Xu Yandong -Signed-off-by: Mingwang Li ---- - target/arm/cpu64.c | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 15245a60a8..019edc66c9 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -933,10 +933,47 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs) - return g_strdup("aarch64"); - } - -+/* Parse "+feature,-feature,feature=foo" CPU feature string -+ */ -+static void arm_cpu_parse_featurestr(const char *typename, char *features, -+ Error **errp ) -+{ -+ char *featurestr; -+ char *val; -+ static bool cpu_globals_initialized; -+ -+ if (cpu_globals_initialized) { -+ return; -+ } -+ cpu_globals_initialized = true; -+ -+ featurestr = features ? strtok(features, ",") : NULL; -+ while (featurestr) { -+ val = strchr(featurestr, '='); -+ if (val) { -+ GlobalProperty *prop = g_new0(typeof(*prop), 1); -+ *val = 0; -+ val++; -+ prop->driver = typename; -+ prop->property = g_strdup(featurestr); -+ prop->value = g_strdup(val); -+ qdev_prop_register_global(prop); -+ } else if (featurestr[0] == '+' || featurestr[0] == '-') { -+ warn_report("Ignore %s feature\n", featurestr); -+ } else { -+ error_setg(errp, "Expected key=value format, found %s.", -+ featurestr); -+ return; -+ } -+ featurestr = strtok(NULL, ","); -+ } -+} -+ - static void aarch64_cpu_class_init(ObjectClass *oc, void *data) - { - CPUClass *cc = CPU_CLASS(oc); - -+ cc->parse_features = arm_cpu_parse_featurestr; - cc->gdb_read_register = aarch64_cpu_gdb_read_register; - cc->gdb_write_register = aarch64_cpu_gdb_write_register; - cc->gdb_num_core_regs = 34; --- -2.27.0 - diff --git a/cpus-Introduce-cpu_list_generation_id.patch b/cpus-Introduce-cpu_list_generation_id.patch deleted file mode 100644 index 23cc872659803aa33121a55578f37ef9f294faef..0000000000000000000000000000000000000000 --- a/cpus-Introduce-cpu_list_generation_id.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 6e057dd5df580f0e525d808f5476ee973280371d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Sun, 26 Jun 2022 01:38:31 +0800 -Subject: [PATCH 2/3] cpus: Introduce cpu_list_generation_id -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce cpu_list_generation_id to track cpu list generation so -that cpu hotplug/unplug can be detected during measurement of -dirty page rate. - -cpu_list_generation_id could be used to detect changes of cpu -list, which is prepared for dirty page rate measurement. - -Signed-off-by: Hyman Huang(黄勇) -Reviewed-by: Peter Xu -Message-Id: <06e1f1362b2501a471dce796abb065b04f320fa5.1656177590.git.huangy81@chinatelecom.cn> -Signed-off-by: Dr. David Alan Gilbert ---- - cpus-common.c | 8 ++++++++ - include/exec/cpu-common.h | 1 + - 2 files changed, 9 insertions(+) - -diff --git a/cpus-common.c b/cpus-common.c -index 6e73d3e58d..31c6415f37 100644 ---- a/cpus-common.c -+++ b/cpus-common.c -@@ -73,6 +73,12 @@ static int cpu_get_free_index(void) - } - - CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus); -+static unsigned int cpu_list_generation_id; -+ -+unsigned int cpu_list_generation_id_get(void) -+{ -+ return cpu_list_generation_id; -+} - - void cpu_list_add(CPUState *cpu) - { -@@ -84,6 +90,7 @@ void cpu_list_add(CPUState *cpu) - assert(!cpu_index_auto_assigned); - } - QTAILQ_INSERT_TAIL_RCU(&cpus, cpu, node); -+ cpu_list_generation_id++; - } - - void cpu_list_remove(CPUState *cpu) -@@ -96,6 +103,7 @@ void cpu_list_remove(CPUState *cpu) - - QTAILQ_REMOVE_RCU(&cpus, cpu, node); - cpu->cpu_index = UNASSIGNED_CPU_INDEX; -+ cpu_list_generation_id++; - } - - CPUState *qemu_get_cpu(int index) -diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h -index 039d422bf4..cdee668f20 100644 ---- a/include/exec/cpu-common.h -+++ b/include/exec/cpu-common.h -@@ -11,6 +11,7 @@ - void qemu_init_cpu_list(void); - void cpu_list_lock(void); - void cpu_list_unlock(void); -+unsigned int cpu_list_generation_id_get(void); - - void tcg_flush_softmmu_tlb(CPUState *cs); - --- -2.27.0 - diff --git a/crypto-remove-shadowed-ret-variable.patch b/crypto-remove-shadowed-ret-variable.patch deleted file mode 100644 index ee0bf6ddcf428c7788233bb564fea4ae9123240d..0000000000000000000000000000000000000000 --- a/crypto-remove-shadowed-ret-variable.patch +++ /dev/null @@ -1,36 +0,0 @@ -From b055bedb3fba592ab7e73615faf29854a18b0abc Mon Sep 17 00:00:00 2001 -From: qihao -Date: Tue, 10 Oct 2023 15:24:35 +0800 -Subject: [PATCH] crypto: remove shadowed 'ret' variable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 3cc9fe177f412494f084923149338c51dd232b9b - -Both instances of 'ret' are used to store a gnutls API return code. - -Signed-off-by: Daniel P. Berrangé -Message-ID: <20230922160644.438631-2-berrange@redhat.com> -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Markus Armbruster -Signed-off-by: qihao_yewu ---- - crypto/tls-cipher-suites.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/crypto/tls-cipher-suites.c b/crypto/tls-cipher-suites.c -index 5e4f597464..d0df4badc0 100644 ---- a/crypto/tls-cipher-suites.c -+++ b/crypto/tls-cipher-suites.c -@@ -52,7 +52,6 @@ GByteArray *qcrypto_tls_cipher_suites_get_data(QCryptoTLSCipherSuites *obj, - byte_array = g_byte_array_new(); - - for (i = 0;; i++) { -- int ret; - unsigned idx; - const char *name; - IANA_TLS_CIPHER cipher; --- -2.41.0.windows.1 - diff --git a/curl-Fix-error-path-in-curl_open.patch b/curl-Fix-error-path-in-curl_open.patch deleted file mode 100644 index 215bd7ac46b77b42a1b8531447702af8268edc66..0000000000000000000000000000000000000000 --- a/curl-Fix-error-path-in-curl_open.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 745dd52e9a737f2d1e16fdc79b0f701d63df3606 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Thu, 16 Mar 2023 16:20:44 +0800 -Subject: [PATCH] curl: Fix error path in curl_open() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -g_hash_table_destroy() and g_hash_table_foreach_remove() (called by -curl_drop_all_sockets()) both require the table to be non-NULL, or will -print assertion failures (just print, no abort). -There are several paths in curl_open() that can lead to the out_noclean -label without s->sockets being allocated, so clean it only if it has -been allocated. -Example reproducer: -$ qemu-img info -f http '' -qemu-img: GLib: g_hash_table_foreach_remove: assertion 'hash_table != NULL' failed -qemu-img: GLib: g_hash_table_destroy: assertion 'hash_table != NULL' failed -qemu-img: Could not open '': http curl driver cannot handle the URL '' (does not start with 'http://') - -Closes: https://gitlab.com/qemu-project/qemu/-/issues/1475 -Suggested-by: Daniel P. Berrangé -Signed-off-by: Hanna Czenczek -Signed-off-by: jianchunfu ---- - block/curl.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/block/curl.c b/block/curl.c -index 4a8ae2b269..5aebb08002 100644 ---- a/block/curl.c -+++ b/block/curl.c -@@ -821,8 +821,10 @@ out_noclean: - g_free(s->username); - g_free(s->proxyusername); - g_free(s->proxypassword); -- curl_drop_all_sockets(s->sockets); -- g_hash_table_destroy(s->sockets); -+ if (s->sockets) { -+ curl_drop_all_sockets(s->sockets); -+ g_hash_table_destroy(s->sockets); -+ } - qemu_opts_del(opts); - return -EINVAL; - } --- -2.27.0 - diff --git a/disas-hppa-Show-hexcode-of-instruction-along-with-di.patch b/disas-hppa-Show-hexcode-of-instruction-along-with-di.patch deleted file mode 100644 index 16cd69a7ef3a4994c3604bc2dcbb551860b0190f..0000000000000000000000000000000000000000 --- a/disas-hppa-Show-hexcode-of-instruction-along-with-di.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 7949977cef7b7b4170dad873f9b5788f0c4e40ee Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Mon, 27 Nov 2023 10:54:54 +0800 -Subject: [PATCH] disas/hppa: Show hexcode of instruction along with - disassembly - -cherry picked from 2f926bfd5b79e6219ae65a1e530b38f37d62b384 - -On hppa many instructions can be expressed by different bytecodes. -To be able to debug qemu translation bugs it's therefore necessary to see the -currently executed byte codes without the need to lookup the sequence without -the full executable. -With this patch the instruction byte code is shown beside the disassembly. - -Signed-off-by: Helge Deller -Reviewed-by: Richard Henderson - -Signed-off-by: boringandboring ---- - disas/hppa.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/disas/hppa.c b/disas/hppa.c -index dcf9a47f34..cce4f4aa37 100644 ---- a/disas/hppa.c -+++ b/disas/hppa.c -@@ -1968,6 +1968,10 @@ print_insn_hppa (bfd_vma memaddr, disassemble_info *info) - - insn = bfd_getb32 (buffer); - -+ info->fprintf_func(info->stream, " %02x %02x %02x %02x ", -+ (insn >> 24) & 0xff, (insn >> 16) & 0xff, -+ (insn >> 8) & 0xff, insn & 0xff); -+ - for (i = 0; i < NUMOPCODES; ++i) - { - const struct pa_opcode *opcode = &pa_opcodes[i]; -@@ -2826,6 +2830,6 @@ print_insn_hppa (bfd_vma memaddr, disassemble_info *info) - return sizeof (insn); - } - } -- (*info->fprintf_func) (info->stream, "#%8x", insn); -+ info->fprintf_func(info->stream, ""); - return sizeof (insn); - } --- -2.27.0 - diff --git a/disas-riscv-Fix-ctzw-disassemble.patch b/disas-riscv-Fix-ctzw-disassemble.patch deleted file mode 100644 index 8157ce2bd2df8728cbd395ffdbce43b19cc6ce16..0000000000000000000000000000000000000000 --- a/disas-riscv-Fix-ctzw-disassemble.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 6872e7bf919dd5f2852c07850899cdb510eccfdf Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Tue, 1 Aug 2023 23:46:43 -0700 -Subject: [PATCH] disas/riscv Fix ctzw disassemble - -cherry picked from commit 270629024df1f9f4e704ce8325f958858c5cbff7 - -Due to typo in opcode list, ctzw is disassembled as clzw instruction. - -Signed-off-by: Ivan Klokov -Fixes: 02c1b569a15b ("disas/riscv: Add Zb[abcs] instructions") -Reviewed-by: Weiwei Li -Reviewed-by: Daniel Henrique Barboza -Message-ID: <20230217151459.54649-1-ivan.klokov@syntacore.com> -Signed-off-by: Palmer Dabbelt - -Signed-off-by: Wanghe Xiao ---- - disas/riscv.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/disas/riscv.c b/disas/riscv.c -index 793ad14c27..6768ec8188 100644 ---- a/disas/riscv.c -+++ b/disas/riscv.c -@@ -1189,7 +1189,7 @@ const rv_opcode_data opcode_data[] = { - { "max", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, - { "maxu", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, - { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, -- { "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, -+ { "ctzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, - { "slli.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, - { "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, --- -2.41.0.windows.1 - diff --git a/disas-riscv-Fix-the-typo-of-inverted-order-of-pmpadd.patch b/disas-riscv-Fix-the-typo-of-inverted-order-of-pmpadd.patch deleted file mode 100644 index 3185723a95d72a6d00a33aeebacd62eb74ca3c90..0000000000000000000000000000000000000000 --- a/disas-riscv-Fix-the-typo-of-inverted-order-of-pmpadd.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 80fd3d8f92b8a2c3b640d1dfa436da8331b37b01 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 16 Oct 2023 09:47:25 +0800 -Subject: [PATCH] disas/riscv: Fix the typo of inverted order of pmpaddr13 and - pmpaddr14 - -cheery-pick from cffa9954908830276c93b430681f66cc0e599aef - -Fix the inverted order of pmpaddr13 and pmpaddr14 in csr_name(). - -Signed-off-by: Alvin Chang -Reviewed-by: Alistair Francis -Message-ID: <20230907084500.328-1-alvinga@andestech.com> -Signed-off-by: Alistair Francis -Signed-off-by: qihao_yewu ---- - disas/riscv.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/disas/riscv.c b/disas/riscv.c -index 6768ec8188..ad7b978815 100644 ---- a/disas/riscv.c -+++ b/disas/riscv.c -@@ -1307,8 +1307,8 @@ static const char *csr_name(int csrno) - case 0x03ba: return "pmpaddr10"; - case 0x03bb: return "pmpaddr11"; - case 0x03bc: return "pmpaddr12"; -- case 0x03bd: return "pmpaddr14"; -- case 0x03be: return "pmpaddr13"; -+ case 0x03bd: return "pmpaddr13"; -+ case 0x03be: return "pmpaddr14"; - case 0x03bf: return "pmpaddr15"; - case 0x0780: return "mtohost"; - case 0x0781: return "mfromhost"; --- -2.41.0.windows.1 - diff --git a/display-qxl-render-fix-race-condition-in-qxl_cursor-.patch b/display-qxl-render-fix-race-condition-in-qxl_cursor-.patch deleted file mode 100644 index 4470b651d1ef340493dabceb063e80370d3ee830..0000000000000000000000000000000000000000 --- a/display-qxl-render-fix-race-condition-in-qxl_cursor-.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 98c106af8a2f761f615690494b425aed57b308db Mon Sep 17 00:00:00 2001 -From: Mauro Matteo Cascella -Date: Thu, 7 Apr 2022 10:11:06 +0200 -Subject: [PATCH 1/2] display/qxl-render: fix race condition in qxl_cursor - (CVE-2021-4207) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Avoid fetching 'width' and 'height' a second time to prevent possible -race condition. Refer to security advisory -https://starlabs.sg/advisories/22-4207/ for more information. - -Fixes: CVE-2021-4207 -Signed-off-by: Mauro Matteo Cascella -Reviewed-by: Marc-André Lureau -Message-Id: <20220407081106.343235-1-mcascell@redhat.com> -Signed-off-by: Gerd Hoffmann ---- - hw/display/qxl-render.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c -index d28849b121..237ed293ba 100644 ---- a/hw/display/qxl-render.c -+++ b/hw/display/qxl-render.c -@@ -266,7 +266,7 @@ static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor, - } - break; - case SPICE_CURSOR_TYPE_ALPHA: -- size = sizeof(uint32_t) * cursor->header.width * cursor->header.height; -+ size = sizeof(uint32_t) * c->width * c->height; - qxl_unpack_chunks(c->data, size, qxl, &cursor->chunk, group_id); - if (qxl->debug > 2) { - cursor_print_ascii_art(c, "qxl/alpha"); --- -2.27.0 - diff --git a/dma-Have-dma_buf_read-dma_buf_write-take-a-void-poin.patch b/dma-Have-dma_buf_read-dma_buf_write-take-a-void-poin.patch deleted file mode 100644 index c62656c98b34fa3df2cdd3da4c35847f9282ddc7..0000000000000000000000000000000000000000 --- a/dma-Have-dma_buf_read-dma_buf_write-take-a-void-poin.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 0f43c97e5a88131fc5d30dc2150d3265c99725d7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 16 Dec 2021 11:27:23 +0100 -Subject: [PATCH 09/25] dma: Have dma_buf_read() / dma_buf_write() take a void - pointer -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -DMA operations are run on any kind of buffer, not arrays of -uint8_t. Convert dma_buf_read/dma_buf_write functions to take -a void pointer argument and save us pointless casts to uint8_t *. - -Remove this pointless casts in the megasas device model. - -Reviewed-by: Klaus Jensen -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-9-philmd@redhat.com> ---- - hw/scsi/megasas.c | 22 +++++++++++----------- - include/sysemu/dma.h | 4 ++-- - softmmu/dma-helpers.c | 4 ++-- - 3 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index 6d21bf9fdd..fac46c54ab 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -847,7 +847,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd) - MFI_INFO_PDMIX_SATA | - MFI_INFO_PDMIX_LD); - -- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); - return MFI_STAT_OK; - } - -@@ -877,7 +877,7 @@ static int megasas_mfc_get_defaults(MegasasState *s, MegasasCmd *cmd) - info.disable_preboot_cli = 1; - info.cluster_disable = 1; - -- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); - return MFI_STAT_OK; - } - -@@ -898,7 +898,7 @@ static int megasas_dcmd_get_bios_info(MegasasState *s, MegasasCmd *cmd) - info.expose_all_drives = 1; - } - -- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); - return MFI_STAT_OK; - } - -@@ -909,7 +909,7 @@ static int megasas_dcmd_get_fw_time(MegasasState *s, MegasasCmd *cmd) - - fw_time = cpu_to_le64(megasas_fw_time()); - -- cmd->iov_size -= dma_buf_read((uint8_t *)&fw_time, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&fw_time, dcmd_size, &cmd->qsg); - return MFI_STAT_OK; - } - -@@ -936,7 +936,7 @@ static int megasas_event_info(MegasasState *s, MegasasCmd *cmd) - info.shutdown_seq_num = cpu_to_le32(s->shutdown_event); - info.boot_seq_num = cpu_to_le32(s->boot_event); - -- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); - return MFI_STAT_OK; - } - -@@ -1005,7 +1005,7 @@ static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd) - info.size = cpu_to_le32(offset); - info.count = cpu_to_le32(num_pd_disks); - -- cmd->iov_size -= dma_buf_read((uint8_t *)&info, offset, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, offset, &cmd->qsg); - return MFI_STAT_OK; - } - -@@ -1171,7 +1171,7 @@ static int megasas_dcmd_ld_get_list(MegasasState *s, MegasasCmd *cmd) - info.ld_count = cpu_to_le32(num_ld_disks); - trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks); - -- resid = dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg); -+ resid = dma_buf_read(&info, dcmd_size, &cmd->qsg); - cmd->iov_size = dcmd_size - resid; - return MFI_STAT_OK; - } -@@ -1220,7 +1220,7 @@ static int megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd) - info.size = dcmd_size; - trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks); - -- resid = dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg); -+ resid = dma_buf_read(&info, dcmd_size, &cmd->qsg); - cmd->iov_size = dcmd_size - resid; - return MFI_STAT_OK; - } -@@ -1389,7 +1389,7 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd) - ld_offset += sizeof(struct mfi_ld_config); - } - -- cmd->iov_size -= dma_buf_read((uint8_t *)data, info->size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(data, info->size, &cmd->qsg); - return MFI_STAT_OK; - } - -@@ -1419,7 +1419,7 @@ static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd) - info.ecc_bucket_leak_rate = cpu_to_le16(1440); - info.expose_encl_devices = 1; - -- cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); - return MFI_STAT_OK; - } - -@@ -1464,7 +1464,7 @@ static int megasas_dcmd_set_properties(MegasasState *s, MegasasCmd *cmd) - dcmd_size); - return MFI_STAT_INVALID_PARAMETER; - } -- dma_buf_write((uint8_t *)&info, dcmd_size, &cmd->qsg); -+ dma_buf_write(&info, dcmd_size, &cmd->qsg); - trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size); - return MFI_STAT_OK; - } -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index 97ff6f29f8..0d5b836013 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -302,8 +302,8 @@ BlockAIOCB *dma_blk_read(BlockBackend *blk, - BlockAIOCB *dma_blk_write(BlockBackend *blk, - QEMUSGList *sg, uint64_t offset, uint32_t align, - BlockCompletionFunc *cb, void *opaque); --uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg); --uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg); -+uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg); -+uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg); - - void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, - QEMUSGList *sg, enum BlockAcctType type); -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index 09e29997ee..7f37548394 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -317,12 +317,12 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg, - return resid; - } - --uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg) -+uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg) - { - return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE); - } - --uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg) -+uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg) - { - return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE); - } --- -2.27.0 - diff --git a/dma-Have-dma_buf_rw-take-a-void-pointer.patch b/dma-Have-dma_buf_rw-take-a-void-pointer.patch deleted file mode 100644 index 7dd112de0ae73d05813a71a9e3c45176d0b9290e..0000000000000000000000000000000000000000 --- a/dma-Have-dma_buf_rw-take-a-void-pointer.patch +++ /dev/null @@ -1,38 +0,0 @@ -From cb11b87fe29fa0f4ee664bacff242ed34bf3f33e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 16 Dec 2021 11:24:56 +0100 -Subject: [PATCH 08/25] dma: Have dma_buf_rw() take a void pointer -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -DMA operations are run on any kind of buffer, not arrays of -uint8_t. Convert dma_buf_rw() to take a void pointer argument -to save us pointless casts to uint8_t *. - -Reviewed-by: Klaus Jensen -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-8-philmd@redhat.com> ---- - softmmu/dma-helpers.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index 3c06a2fedd..09e29997ee 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -294,9 +294,10 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk, - } - - --static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg, -+static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg, - DMADirection dir) - { -+ uint8_t *ptr = buf; - uint64_t resid; - int sg_cur_index; - --- -2.27.0 - diff --git a/dma-Let-dma_buf_read-take-MemTxAttrs-argument.patch b/dma-Let-dma_buf_read-take-MemTxAttrs-argument.patch deleted file mode 100644 index 1fd0aba5720b2375070fe8f4acc24e14dbc33d31..0000000000000000000000000000000000000000 --- a/dma-Let-dma_buf_read-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,218 +0,0 @@ -From ccdbeeb4171a532acc75ee2b78253aa24b3faa73 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Wed, 15 Dec 2021 23:29:52 +0100 -Subject: [PATCH 13/25] dma: Let dma_buf_read() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling -dma_buf_read(). - -Keep the default MEMTXATTRS_UNSPECIFIED in the few callers. - -Reviewed-by: Klaus Jensen -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-13-philmd@redhat.com> ---- - hw/ide/ahci.c | 4 ++-- - hw/nvme/ctrl.c | 2 +- - hw/scsi/megasas.c | 24 ++++++++++++------------ - hw/scsi/scsi-bus.c | 2 +- - include/sysemu/dma.h | 2 +- - softmmu/dma-helpers.c | 5 ++--- - 6 files changed, 19 insertions(+), 20 deletions(-) - -diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c -index 8e27fb8b35..1e482738de 100644 ---- a/hw/ide/ahci.c -+++ b/hw/ide/ahci.c -@@ -1386,7 +1386,7 @@ static void ahci_pio_transfer(const IDEDMA *dma) - if (is_write) { - dma_buf_write(s->data_ptr, size, &s->sg, attrs); - } else { -- dma_buf_read(s->data_ptr, size, &s->sg); -+ dma_buf_read(s->data_ptr, size, &s->sg, attrs); - } - } - -@@ -1481,7 +1481,7 @@ static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write) - } - - if (is_write) { -- dma_buf_read(p, l, &s->sg); -+ dma_buf_read(p, l, &s->sg, MEMTXATTRS_UNSPECIFIED); - } else { - dma_buf_write(p, l, &s->sg, MEMTXATTRS_UNSPECIFIED); - } -diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index e1a531d5d6..462f79a1f6 100644 ---- a/hw/nvme/ctrl.c -+++ b/hw/nvme/ctrl.c -@@ -1152,7 +1152,7 @@ static uint16_t nvme_tx(NvmeCtrl *n, NvmeSg *sg, uint8_t *ptr, uint32_t len, - if (dir == NVME_TX_DIRECTION_TO_DEVICE) { - residual = dma_buf_write(ptr, len, &sg->qsg, attrs); - } else { -- residual = dma_buf_read(ptr, len, &sg->qsg); -+ residual = dma_buf_read(ptr, len, &sg->qsg, attrs); - } - - if (unlikely(residual)) { -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index 72376d92f6..f1c4d5782b 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -847,7 +847,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd) - MFI_INFO_PDMIX_SATA | - MFI_INFO_PDMIX_LD); - -- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - return MFI_STAT_OK; - } - -@@ -877,7 +877,7 @@ static int megasas_mfc_get_defaults(MegasasState *s, MegasasCmd *cmd) - info.disable_preboot_cli = 1; - info.cluster_disable = 1; - -- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - return MFI_STAT_OK; - } - -@@ -898,7 +898,7 @@ static int megasas_dcmd_get_bios_info(MegasasState *s, MegasasCmd *cmd) - info.expose_all_drives = 1; - } - -- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - return MFI_STAT_OK; - } - -@@ -909,7 +909,7 @@ static int megasas_dcmd_get_fw_time(MegasasState *s, MegasasCmd *cmd) - - fw_time = cpu_to_le64(megasas_fw_time()); - -- cmd->iov_size -= dma_buf_read(&fw_time, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&fw_time, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - return MFI_STAT_OK; - } - -@@ -936,7 +936,7 @@ static int megasas_event_info(MegasasState *s, MegasasCmd *cmd) - info.shutdown_seq_num = cpu_to_le32(s->shutdown_event); - info.boot_seq_num = cpu_to_le32(s->boot_event); - -- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - return MFI_STAT_OK; - } - -@@ -1005,7 +1005,7 @@ static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd) - info.size = cpu_to_le32(offset); - info.count = cpu_to_le32(num_pd_disks); - -- cmd->iov_size -= dma_buf_read(&info, offset, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, offset, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - return MFI_STAT_OK; - } - -@@ -1099,7 +1099,7 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun, - info->connected_port_bitmap = 0x1; - info->device_speed = 1; - info->link_speed = 1; -- resid = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg); -+ resid = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - g_free(cmd->iov_buf); - cmd->iov_size = dcmd_size - resid; - cmd->iov_buf = NULL; -@@ -1171,7 +1171,7 @@ static int megasas_dcmd_ld_get_list(MegasasState *s, MegasasCmd *cmd) - info.ld_count = cpu_to_le32(num_ld_disks); - trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks); - -- resid = dma_buf_read(&info, dcmd_size, &cmd->qsg); -+ resid = dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - cmd->iov_size = dcmd_size - resid; - return MFI_STAT_OK; - } -@@ -1220,7 +1220,7 @@ static int megasas_dcmd_ld_list_query(MegasasState *s, MegasasCmd *cmd) - info.size = dcmd_size; - trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks); - -- resid = dma_buf_read(&info, dcmd_size, &cmd->qsg); -+ resid = dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - cmd->iov_size = dcmd_size - resid; - return MFI_STAT_OK; - } -@@ -1270,7 +1270,7 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun, - info->ld_config.span[0].num_blocks = info->size; - info->ld_config.span[0].array_ref = cpu_to_le16(sdev_id); - -- resid = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg); -+ resid = dma_buf_read(cmd->iov_buf, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - g_free(cmd->iov_buf); - cmd->iov_size = dcmd_size - resid; - cmd->iov_buf = NULL; -@@ -1389,7 +1389,7 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd) - ld_offset += sizeof(struct mfi_ld_config); - } - -- cmd->iov_size -= dma_buf_read(data, info->size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(data, info->size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - return MFI_STAT_OK; - } - -@@ -1419,7 +1419,7 @@ static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd) - info.ecc_bucket_leak_rate = cpu_to_le16(1440); - info.expose_encl_devices = 1; - -- cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg); -+ cmd->iov_size -= dma_buf_read(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - return MFI_STAT_OK; - } - -diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c -index 6fe30327b1..2b613ad2b3 100644 ---- a/hw/scsi/scsi-bus.c -+++ b/hw/scsi/scsi-bus.c -@@ -1428,7 +1428,7 @@ void scsi_req_data(SCSIRequest *req, int len) - - buf = scsi_req_get_buf(req); - if (req->cmd.mode == SCSI_XFER_FROM_DEV) { -- req->resid = dma_buf_read(buf, len, req->sg); -+ req->resid = dma_buf_read(buf, len, req->sg, MEMTXATTRS_UNSPECIFIED); - } else { - req->resid = dma_buf_write(buf, len, req->sg, MEMTXATTRS_UNSPECIFIED); - } -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index e3dd74a9c4..fd8f16003d 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -302,7 +302,7 @@ BlockAIOCB *dma_blk_read(BlockBackend *blk, - BlockAIOCB *dma_blk_write(BlockBackend *blk, - QEMUSGList *sg, uint64_t offset, uint32_t align, - BlockCompletionFunc *cb, void *opaque); --uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg); -+uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs); - uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs); - - void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index 2f1a241b81..a391773c29 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -316,10 +316,9 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg, - return resid; - } - --uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg) -+uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs) - { -- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE, -- MEMTXATTRS_UNSPECIFIED); -+ return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE, attrs); - } - - uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs) --- -2.27.0 - diff --git a/dma-Let-dma_buf_rw-propagate-MemTxResult.patch b/dma-Let-dma_buf_rw-propagate-MemTxResult.patch deleted file mode 100644 index c35f6df059af7a67195e1222000377578bb664d3..0000000000000000000000000000000000000000 --- a/dma-Let-dma_buf_rw-propagate-MemTxResult.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 829b5bede922364061540abc51e80bb2e8b39085 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Wed, 15 Dec 2021 23:38:52 +0100 -Subject: [PATCH 14/25] dma: Let dma_buf_rw() propagate MemTxResult -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -dma_memory_rw() returns a MemTxResult type. Do not discard -it, return it to the caller. - -Since dma_buf_rw() was previously returning the QEMUSGList -size not consumed, add an extra argument where this size -can be stored. - -Update the 2 callers. - -Reviewed-by: Klaus Jensen -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-14-philmd@redhat.com> ---- - softmmu/dma-helpers.c | 25 +++++++++++++++++++------ - 1 file changed, 19 insertions(+), 6 deletions(-) - -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index a391773c29..b0be156479 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -294,12 +294,14 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk, - } - - --static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg, -- DMADirection dir, MemTxAttrs attrs) -+static MemTxResult dma_buf_rw(void *buf, int32_t len, uint64_t *residp, -+ QEMUSGList *sg, DMADirection dir, -+ MemTxAttrs attrs) - { - uint8_t *ptr = buf; - uint64_t resid; - int sg_cur_index; -+ MemTxResult res = MEMTX_OK; - - resid = sg->size; - sg_cur_index = 0; -@@ -307,23 +309,34 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg, - while (len > 0) { - ScatterGatherEntry entry = sg->sg[sg_cur_index++]; - int32_t xfer = MIN(len, entry.len); -- dma_memory_rw(sg->as, entry.base, ptr, xfer, dir, attrs); -+ res |= dma_memory_rw(sg->as, entry.base, ptr, xfer, dir, attrs); - ptr += xfer; - len -= xfer; - resid -= xfer; - } - -- return resid; -+ if (residp) { -+ *residp = resid; -+ } -+ return res; - } - - uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs) - { -- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE, attrs); -+ uint64_t resid; -+ -+ dma_buf_rw(ptr, len, &resid, sg, DMA_DIRECTION_FROM_DEVICE, attrs); -+ -+ return resid; - } - - uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs) - { -- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE, attrs); -+ uint64_t resid; -+ -+ dma_buf_rw(ptr, len, &resid, sg, DMA_DIRECTION_TO_DEVICE, attrs); -+ -+ return resid; - } - - void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, --- -2.27.0 - diff --git a/dma-Let-dma_buf_rw-take-MemTxAttrs-argument.patch b/dma-Let-dma_buf_rw-take-MemTxAttrs-argument.patch deleted file mode 100644 index ef234b49e16a48a5c9b4a73a2b30c41cd1f2a660..0000000000000000000000000000000000000000 --- a/dma-Let-dma_buf_rw-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 1afc40c527dd25dd02d4b4d78530542d25d2d739 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Wed, 15 Dec 2021 22:59:46 +0100 -Subject: [PATCH 11/25] dma: Let dma_buf_rw() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling dma_buf_rw(). - -Keep the default MEMTXATTRS_UNSPECIFIED in the 2 callers. - -Reviewed-by: Klaus Jensen -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-11-philmd@redhat.com> ---- - softmmu/dma-helpers.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index 7f37548394..fa81d2b386 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -295,7 +295,7 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk, - - - static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg, -- DMADirection dir) -+ DMADirection dir, MemTxAttrs attrs) - { - uint8_t *ptr = buf; - uint64_t resid; -@@ -307,8 +307,7 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg, - while (len > 0) { - ScatterGatherEntry entry = sg->sg[sg_cur_index++]; - int32_t xfer = MIN(len, entry.len); -- dma_memory_rw(sg->as, entry.base, ptr, xfer, dir, -- MEMTXATTRS_UNSPECIFIED); -+ dma_memory_rw(sg->as, entry.base, ptr, xfer, dir, attrs); - ptr += xfer; - len -= xfer; - resid -= xfer; -@@ -319,12 +318,14 @@ static uint64_t dma_buf_rw(void *buf, int32_t len, QEMUSGList *sg, - - uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg) - { -- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE); -+ return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_FROM_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - } - - uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg) - { -- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE); -+ return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - } - - void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, --- -2.27.0 - diff --git a/dma-Let-dma_buf_write-take-MemTxAttrs-argument.patch b/dma-Let-dma_buf_write-take-MemTxAttrs-argument.patch deleted file mode 100644 index 85f8f92a444a2d8d683e52f6a62a9bed607a7e38..0000000000000000000000000000000000000000 --- a/dma-Let-dma_buf_write-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,126 +0,0 @@ -From f08ff9489ec9d42246b038d90df11457928d6886 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Wed, 15 Dec 2021 23:02:21 +0100 -Subject: [PATCH 12/25] dma: Let dma_buf_write() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling -dma_buf_write(). - -Keep the default MEMTXATTRS_UNSPECIFIED in the few callers. - -Reviewed-by: Klaus Jensen -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-12-philmd@redhat.com> ---- - hw/ide/ahci.c | 6 ++++-- - hw/nvme/ctrl.c | 3 ++- - hw/scsi/megasas.c | 2 +- - hw/scsi/scsi-bus.c | 2 +- - include/sysemu/dma.h | 2 +- - softmmu/dma-helpers.c | 5 ++--- - 6 files changed, 11 insertions(+), 9 deletions(-) - -diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c -index 7580bd2a96..8e27fb8b35 100644 ---- a/hw/ide/ahci.c -+++ b/hw/ide/ahci.c -@@ -1381,8 +1381,10 @@ static void ahci_pio_transfer(const IDEDMA *dma) - has_sglist ? "" : "o"); - - if (has_sglist && size) { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; -+ - if (is_write) { -- dma_buf_write(s->data_ptr, size, &s->sg); -+ dma_buf_write(s->data_ptr, size, &s->sg, attrs); - } else { - dma_buf_read(s->data_ptr, size, &s->sg); - } -@@ -1481,7 +1483,7 @@ static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write) - if (is_write) { - dma_buf_read(p, l, &s->sg); - } else { -- dma_buf_write(p, l, &s->sg); -+ dma_buf_write(p, l, &s->sg, MEMTXATTRS_UNSPECIFIED); - } - - /* free sglist, update byte count */ -diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index 5f573c417b..e1a531d5d6 100644 ---- a/hw/nvme/ctrl.c -+++ b/hw/nvme/ctrl.c -@@ -1146,10 +1146,11 @@ static uint16_t nvme_tx(NvmeCtrl *n, NvmeSg *sg, uint8_t *ptr, uint32_t len, - assert(sg->flags & NVME_SG_ALLOC); - - if (sg->flags & NVME_SG_DMA) { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - uint64_t residual; - - if (dir == NVME_TX_DIRECTION_TO_DEVICE) { -- residual = dma_buf_write(ptr, len, &sg->qsg); -+ residual = dma_buf_write(ptr, len, &sg->qsg, attrs); - } else { - residual = dma_buf_read(ptr, len, &sg->qsg); - } -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index fac46c54ab..72376d92f6 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -1464,7 +1464,7 @@ static int megasas_dcmd_set_properties(MegasasState *s, MegasasCmd *cmd) - dcmd_size); - return MFI_STAT_INVALID_PARAMETER; - } -- dma_buf_write(&info, dcmd_size, &cmd->qsg); -+ dma_buf_write(&info, dcmd_size, &cmd->qsg, MEMTXATTRS_UNSPECIFIED); - trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size); - return MFI_STAT_OK; - } -diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c -index 9d37f490ce..6fe30327b1 100644 ---- a/hw/scsi/scsi-bus.c -+++ b/hw/scsi/scsi-bus.c -@@ -1430,7 +1430,7 @@ void scsi_req_data(SCSIRequest *req, int len) - if (req->cmd.mode == SCSI_XFER_FROM_DEV) { - req->resid = dma_buf_read(buf, len, req->sg); - } else { -- req->resid = dma_buf_write(buf, len, req->sg); -+ req->resid = dma_buf_write(buf, len, req->sg, MEMTXATTRS_UNSPECIFIED); - } - scsi_req_continue(req); - } -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index 0d5b836013..e3dd74a9c4 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -303,7 +303,7 @@ BlockAIOCB *dma_blk_write(BlockBackend *blk, - QEMUSGList *sg, uint64_t offset, uint32_t align, - BlockCompletionFunc *cb, void *opaque); - uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg); --uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg); -+uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs); - - void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, - QEMUSGList *sg, enum BlockAcctType type); -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index fa81d2b386..2f1a241b81 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -322,10 +322,9 @@ uint64_t dma_buf_read(void *ptr, int32_t len, QEMUSGList *sg) - MEMTXATTRS_UNSPECIFIED); - } - --uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg) -+uint64_t dma_buf_write(void *ptr, int32_t len, QEMUSGList *sg, MemTxAttrs attrs) - { -- return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE, -- MEMTXATTRS_UNSPECIFIED); -+ return dma_buf_rw(ptr, len, sg, DMA_DIRECTION_TO_DEVICE, attrs); - } - - void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, --- -2.27.0 - diff --git a/dma-Let-dma_memory_map-take-MemTxAttrs-argument.patch b/dma-Let-dma_memory_map-take-MemTxAttrs-argument.patch deleted file mode 100644 index 08dac5d1cbebc8d1040b7f65990ab133d1d6195b..0000000000000000000000000000000000000000 --- a/dma-Let-dma_memory_map-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 61b0b2e243c382da97cc97c6a96ee8e14197fd33 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 3 Sep 2020 11:00:47 +0200 -Subject: [PATCH 07/25] dma: Let dma_memory_map() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling -dma_memory_map(). - -Patch created mechanically using spatch with this script: - - @@ - expression E1, E2, E3, E4; - @@ - - dma_memory_map(E1, E2, E3, E4) - + dma_memory_map(E1, E2, E3, E4, MEMTXATTRS_UNSPECIFIED) - -Reviewed-by: Richard Henderson -Reviewed-by: Li Qiang -Reviewed-by: Edgar E. Iglesias -Signed-off-by: Philippe Mathieu-Daudé -Acked-by: Stefan Hajnoczi -Message-Id: <20211223115554.3155328-7-philmd@redhat.com> ---- - hw/display/virtio-gpu.c | 10 ++++++---- - hw/hyperv/vmbus.c | 8 +++++--- - hw/ide/ahci.c | 8 +++++--- - hw/usb/libhw.c | 3 ++- - hw/virtio/virtio.c | 6 ++++-- - include/hw/pci/pci.h | 3 ++- - include/sysemu/dma.h | 5 +++-- - softmmu/dma-helpers.c | 3 ++- - 8 files changed, 29 insertions(+), 17 deletions(-) - -diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c -index d78b9700c7..c6dc818988 100644 ---- a/hw/display/virtio-gpu.c -+++ b/hw/display/virtio-gpu.c -@@ -814,8 +814,9 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g, - - do { - len = l; -- map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, -- a, &len, DMA_DIRECTION_TO_DEVICE); -+ map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, a, &len, -+ DMA_DIRECTION_TO_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - if (!map) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for" - " element %d\n", __func__, e); -@@ -1252,8 +1253,9 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, - for (i = 0; i < res->iov_cnt; i++) { - hwaddr len = res->iov[i].iov_len; - res->iov[i].iov_base = -- dma_memory_map(VIRTIO_DEVICE(g)->dma_as, -- res->addrs[i], &len, DMA_DIRECTION_TO_DEVICE); -+ dma_memory_map(VIRTIO_DEVICE(g)->dma_as, res->addrs[i], &len, -+ DMA_DIRECTION_TO_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - - if (!res->iov[i].iov_base || len != res->iov[i].iov_len) { - /* Clean up the half-a-mapping we just created... */ -diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c -index dbce3b35fb..8aad29f1bb 100644 ---- a/hw/hyperv/vmbus.c -+++ b/hw/hyperv/vmbus.c -@@ -373,7 +373,8 @@ static ssize_t gpadl_iter_io(GpadlIter *iter, void *buf, uint32_t len) - - maddr = (iter->gpadl->gfns[idx] << TARGET_PAGE_BITS) | off_in_page; - -- iter->map = dma_memory_map(iter->as, maddr, &mlen, iter->dir); -+ iter->map = dma_memory_map(iter->as, maddr, &mlen, iter->dir, -+ MEMTXATTRS_UNSPECIFIED); - if (mlen != pgleft) { - dma_memory_unmap(iter->as, iter->map, mlen, iter->dir, 0); - iter->map = NULL; -@@ -490,7 +491,8 @@ int vmbus_map_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov, - goto err; - } - -- iov[ret_cnt].iov_base = dma_memory_map(sgl->as, a, &l, dir); -+ iov[ret_cnt].iov_base = dma_memory_map(sgl->as, a, &l, dir, -+ MEMTXATTRS_UNSPECIFIED); - if (!l) { - ret = -EFAULT; - goto err; -@@ -566,7 +568,7 @@ static vmbus_ring_buffer *ringbuf_map_hdr(VMBusRingBufCommon *ringbuf) - dma_addr_t mlen = sizeof(*rb); - - rb = dma_memory_map(ringbuf->as, ringbuf->rb_addr, &mlen, -- DMA_DIRECTION_FROM_DEVICE); -+ DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED); - if (mlen != sizeof(*rb)) { - dma_memory_unmap(ringbuf->as, rb, mlen, - DMA_DIRECTION_FROM_DEVICE, 0); -diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c -index 256b58026a..7580bd2a96 100644 ---- a/hw/ide/ahci.c -+++ b/hw/ide/ahci.c -@@ -249,7 +249,8 @@ static void map_page(AddressSpace *as, uint8_t **ptr, uint64_t addr, - dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len); - } - -- *ptr = dma_memory_map(as, addr, &len, DMA_DIRECTION_FROM_DEVICE); -+ *ptr = dma_memory_map(as, addr, &len, DMA_DIRECTION_FROM_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - if (len < wanted && *ptr) { - dma_memory_unmap(as, *ptr, len, DMA_DIRECTION_FROM_DEVICE, len); - *ptr = NULL; -@@ -939,7 +940,8 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, - - /* map PRDT */ - if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len, -- DMA_DIRECTION_TO_DEVICE))){ -+ DMA_DIRECTION_TO_DEVICE, -+ MEMTXATTRS_UNSPECIFIED))){ - trace_ahci_populate_sglist_no_map(ad->hba, ad->port_no); - return -1; - } -@@ -1301,7 +1303,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot) - tbl_addr = le64_to_cpu(cmd->tbl_addr); - cmd_len = 0x80; - cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len, -- DMA_DIRECTION_TO_DEVICE); -+ DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED); - if (!cmd_fis) { - trace_handle_cmd_badfis(s, port); - return -1; -diff --git a/hw/usb/libhw.c b/hw/usb/libhw.c -index 9c33a1640f..f350eae443 100644 ---- a/hw/usb/libhw.c -+++ b/hw/usb/libhw.c -@@ -36,7 +36,8 @@ int usb_packet_map(USBPacket *p, QEMUSGList *sgl) - - while (len) { - dma_addr_t xlen = len; -- mem = dma_memory_map(sgl->as, base, &xlen, dir); -+ mem = dma_memory_map(sgl->as, base, &xlen, dir, -+ MEMTXATTRS_UNSPECIFIED); - if (!mem) { - goto err; - } -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 120672672e..f8ab48e6bd 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -1306,7 +1306,8 @@ static bool virtqueue_map_desc(VirtIODevice *vdev, unsigned int *p_num_sg, - iov[num_sg].iov_base = dma_memory_map(vdev->dma_as, pa, &len, - is_write ? - DMA_DIRECTION_FROM_DEVICE : -- DMA_DIRECTION_TO_DEVICE); -+ DMA_DIRECTION_TO_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - if (!iov[num_sg].iov_base) { - virtio_error(vdev, "virtio: bogus descriptor or out of resources"); - goto out; -@@ -1355,7 +1356,8 @@ static void virtqueue_map_iovec(VirtIODevice *vdev, struct iovec *sg, - sg[i].iov_base = dma_memory_map(vdev->dma_as, - addr[i], &len, is_write ? - DMA_DIRECTION_FROM_DEVICE : -- DMA_DIRECTION_TO_DEVICE); -+ DMA_DIRECTION_TO_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - if (!sg[i].iov_base) { - error_report("virtio: error trying to map MMIO memory"); - exit(1); -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index c72d61bfd8..c3d5e06364 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -890,7 +890,8 @@ static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr, - { - void *buf; - -- buf = dma_memory_map(pci_get_address_space(dev), addr, plen, dir); -+ buf = dma_memory_map(pci_get_address_space(dev), addr, plen, dir, -+ MEMTXATTRS_UNSPECIFIED); - return buf; - } - -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index 522682bf38..97ff6f29f8 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -202,16 +202,17 @@ MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr, - * @addr: address within that address space - * @len: pointer to length of buffer; updated on return - * @dir: indicates the transfer direction -+ * @attrs: memory attributes - */ - static inline void *dma_memory_map(AddressSpace *as, - dma_addr_t addr, dma_addr_t *len, -- DMADirection dir) -+ DMADirection dir, MemTxAttrs attrs) - { - hwaddr xlen = *len; - void *p; - - p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE, -- MEMTXATTRS_UNSPECIFIED); -+ attrs); - *len = xlen; - return p; - } -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index 5bf76fff6b..3c06a2fedd 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -143,7 +143,8 @@ static void dma_blk_cb(void *opaque, int ret) - while (dbs->sg_cur_index < dbs->sg->nsg) { - cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte; - cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte; -- mem = dma_memory_map(dbs->sg->as, cur_addr, &cur_len, dbs->dir); -+ mem = dma_memory_map(dbs->sg->as, cur_addr, &cur_len, dbs->dir, -+ MEMTXATTRS_UNSPECIFIED); - /* - * Make reads deterministic in icount mode. Windows sometimes issues - * disk read requests with overlapping SGs. It leads --- -2.27.0 - diff --git a/dma-Let-dma_memory_read-write-take-MemTxAttrs-argume.patch b/dma-Let-dma_memory_read-write-take-MemTxAttrs-argume.patch deleted file mode 100644 index c96bd6ca8fba12fadf5f8c56582204fb3aeaf836..0000000000000000000000000000000000000000 --- a/dma-Let-dma_memory_read-write-take-MemTxAttrs-argume.patch +++ /dev/null @@ -1,1450 +0,0 @@ -From cb3acb1c694d7a6ce4424789f5e5a1b6becc551a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 3 Sep 2020 10:08:29 +0200 -Subject: [PATCH 06/25] dma: Let dma_memory_read/write() take MemTxAttrs - argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling -dma_memory_read() or dma_memory_write(). - -Patch created mechanically using spatch with this script: - - @@ - expression E1, E2, E3, E4; - @@ - ( - - dma_memory_read(E1, E2, E3, E4) - + dma_memory_read(E1, E2, E3, E4, MEMTXATTRS_UNSPECIFIED) - | - - dma_memory_write(E1, E2, E3, E4) - + dma_memory_write(E1, E2, E3, E4, MEMTXATTRS_UNSPECIFIED) - ) - -Reviewed-by: Richard Henderson -Reviewed-by: Li Qiang -Reviewed-by: Edgar E. Iglesias -Signed-off-by: Philippe Mathieu-Daudé -Acked-by: Stefan Hajnoczi -Message-Id: <20211223115554.3155328-6-philmd@redhat.com> ---- - hw/arm/musicpal.c | 13 +++++++------ - hw/arm/smmu-common.c | 3 ++- - hw/arm/smmuv3.c | 14 +++++++++----- - hw/core/generic-loader.c | 3 ++- - hw/dma/pl330.c | 12 ++++++++---- - hw/dma/sparc32_dma.c | 16 ++++++++++------ - hw/dma/xlnx-zynq-devcfg.c | 6 ++++-- - hw/dma/xlnx_dpdma.c | 10 ++++++---- - hw/i386/amd_iommu.c | 16 +++++++++------- - hw/i386/intel_iommu.c | 28 +++++++++++++++++----------- - hw/ide/macio.c | 2 +- - hw/intc/xive.c | 7 ++++--- - hw/misc/bcm2835_property.c | 3 ++- - hw/misc/macio/mac_dbdma.c | 10 ++++++---- - hw/net/allwinner-sun8i-emac.c | 18 ++++++++++++------ - hw/net/ftgmac100.c | 25 ++++++++++++++++--------- - hw/net/imx_fec.c | 32 ++++++++++++++++++++------------ - hw/net/npcm7xx_emc.c | 20 ++++++++++++-------- - hw/nvram/fw_cfg.c | 9 ++++++--- - hw/pci-host/pnv_phb3.c | 5 +++-- - hw/pci-host/pnv_phb3_msi.c | 9 ++++++--- - hw/pci-host/pnv_phb4.c | 5 +++-- - hw/sd/allwinner-sdhost.c | 14 ++++++++------ - hw/sd/sdhci.c | 35 ++++++++++++++++++++++------------- - hw/usb/hcd-dwc2.c | 8 ++++---- - hw/usb/hcd-ehci.c | 6 ++++-- - hw/usb/hcd-ohci.c | 18 +++++++++++------- - hw/usb/hcd-xhci.c | 18 +++++++++++------- - include/hw/ppc/spapr_vio.h | 6 ++++-- - include/sysemu/dma.h | 20 ++++++++++++-------- - 30 files changed, 241 insertions(+), 150 deletions(-) - -diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c -index 2d612cc0c9..2680ec55b5 100644 ---- a/hw/arm/musicpal.c -+++ b/hw/arm/musicpal.c -@@ -185,13 +185,13 @@ static void eth_rx_desc_put(AddressSpace *dma_as, uint32_t addr, - cpu_to_le16s(&desc->buffer_size); - cpu_to_le32s(&desc->buffer); - cpu_to_le32s(&desc->next); -- dma_memory_write(dma_as, addr, desc, sizeof(*desc)); -+ dma_memory_write(dma_as, addr, desc, sizeof(*desc), MEMTXATTRS_UNSPECIFIED); - } - - static void eth_rx_desc_get(AddressSpace *dma_as, uint32_t addr, - mv88w8618_rx_desc *desc) - { -- dma_memory_read(dma_as, addr, desc, sizeof(*desc)); -+ dma_memory_read(dma_as, addr, desc, sizeof(*desc), MEMTXATTRS_UNSPECIFIED); - le32_to_cpus(&desc->cmdstat); - le16_to_cpus(&desc->bytes); - le16_to_cpus(&desc->buffer_size); -@@ -215,7 +215,7 @@ static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size) - eth_rx_desc_get(&s->dma_as, desc_addr, &desc); - if ((desc.cmdstat & MP_ETH_RX_OWN) && desc.buffer_size >= size) { - dma_memory_write(&s->dma_as, desc.buffer + s->vlan_header, -- buf, size); -+ buf, size, MEMTXATTRS_UNSPECIFIED); - desc.bytes = size + s->vlan_header; - desc.cmdstat &= ~MP_ETH_RX_OWN; - s->cur_rx[i] = desc.next; -@@ -241,13 +241,13 @@ static void eth_tx_desc_put(AddressSpace *dma_as, uint32_t addr, - cpu_to_le16s(&desc->bytes); - cpu_to_le32s(&desc->buffer); - cpu_to_le32s(&desc->next); -- dma_memory_write(dma_as, addr, desc, sizeof(*desc)); -+ dma_memory_write(dma_as, addr, desc, sizeof(*desc), MEMTXATTRS_UNSPECIFIED); - } - - static void eth_tx_desc_get(AddressSpace *dma_as, uint32_t addr, - mv88w8618_tx_desc *desc) - { -- dma_memory_read(dma_as, addr, desc, sizeof(*desc)); -+ dma_memory_read(dma_as, addr, desc, sizeof(*desc), MEMTXATTRS_UNSPECIFIED); - le32_to_cpus(&desc->cmdstat); - le16_to_cpus(&desc->res); - le16_to_cpus(&desc->bytes); -@@ -269,7 +269,8 @@ static void eth_send(mv88w8618_eth_state *s, int queue_index) - if (desc.cmdstat & MP_ETH_TX_OWN) { - len = desc.bytes; - if (len < 2048) { -- dma_memory_read(&s->dma_as, desc.buffer, buf, len); -+ dma_memory_read(&s->dma_as, desc.buffer, buf, len, -+ MEMTXATTRS_UNSPECIFIED); - qemu_send_packet(qemu_get_queue(s->nic), buf, len); - } - desc.cmdstat &= ~MP_ETH_TX_OWN; -diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c -index 2ec4222c93..f253a27e1a 100644 ---- a/hw/arm/smmu-common.c -+++ b/hw/arm/smmu-common.c -@@ -193,7 +193,8 @@ static int get_pte(dma_addr_t baseaddr, uint32_t index, uint64_t *pte, - dma_addr_t addr = baseaddr + index * sizeof(*pte); - - /* TODO: guarantee 64-bit single-copy atomicity */ -- ret = dma_memory_read(&address_space_memory, addr, pte, sizeof(*pte)); -+ ret = dma_memory_read(&address_space_memory, addr, pte, sizeof(*pte), -+ MEMTXATTRS_UNSPECIFIED); - - if (ret != MEMTX_OK) { - info->type = SMMU_PTW_ERR_WALK_EABT; -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 291e3a12e8..2bd9f22055 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -106,7 +106,8 @@ static inline MemTxResult queue_read(SMMUQueue *q, void *data) - { - dma_addr_t addr = Q_CONS_ENTRY(q); - -- return dma_memory_read(&address_space_memory, addr, data, q->entry_size); -+ return dma_memory_read(&address_space_memory, addr, data, q->entry_size, -+ MEMTXATTRS_UNSPECIFIED); - } - - static MemTxResult queue_write(SMMUQueue *q, void *data) -@@ -114,7 +115,8 @@ static MemTxResult queue_write(SMMUQueue *q, void *data) - dma_addr_t addr = Q_PROD_ENTRY(q); - MemTxResult ret; - -- ret = dma_memory_write(&address_space_memory, addr, data, q->entry_size); -+ ret = dma_memory_write(&address_space_memory, addr, data, q->entry_size, -+ MEMTXATTRS_UNSPECIFIED); - if (ret != MEMTX_OK) { - return ret; - } -@@ -289,7 +291,8 @@ static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf, - - trace_smmuv3_get_ste(addr); - /* TODO: guarantee 64-bit single-copy atomicity */ -- ret = dma_memory_read(&address_space_memory, addr, buf, sizeof(*buf)); -+ ret = dma_memory_read(&address_space_memory, addr, buf, sizeof(*buf), -+ MEMTXATTRS_UNSPECIFIED); - if (ret != MEMTX_OK) { - qemu_log_mask(LOG_GUEST_ERROR, - "Cannot fetch pte at address=0x%"PRIx64"\n", addr); -@@ -310,7 +313,8 @@ static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t ssid, - - trace_smmuv3_get_cd(addr); - /* TODO: guarantee 64-bit single-copy atomicity */ -- ret = dma_memory_read(&address_space_memory, addr, buf, sizeof(*buf)); -+ ret = dma_memory_read(&address_space_memory, addr, buf, sizeof(*buf), -+ MEMTXATTRS_UNSPECIFIED); - if (ret != MEMTX_OK) { - qemu_log_mask(LOG_GUEST_ERROR, - "Cannot fetch pte at address=0x%"PRIx64"\n", addr); -@@ -416,7 +420,7 @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste, - l1ptr = (dma_addr_t)(strtab_base + l1_ste_offset * sizeof(l1std)); - /* TODO: guarantee 64-bit single-copy atomicity */ - ret = dma_memory_read(&address_space_memory, l1ptr, &l1std, -- sizeof(l1std)); -+ sizeof(l1std), MEMTXATTRS_UNSPECIFIED); - if (ret != MEMTX_OK) { - qemu_log_mask(LOG_GUEST_ERROR, - "Could not read L1PTR at 0X%"PRIx64"\n", l1ptr); -diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c -index d14f932eea..9a24ffb880 100644 ---- a/hw/core/generic-loader.c -+++ b/hw/core/generic-loader.c -@@ -57,7 +57,8 @@ static void generic_loader_reset(void *opaque) - - if (s->data_len) { - assert(s->data_len < sizeof(s->data)); -- dma_memory_write(s->cpu->as, s->addr, &s->data, s->data_len); -+ dma_memory_write(s->cpu->as, s->addr, &s->data, s->data_len, -+ MEMTXATTRS_UNSPECIFIED); - } - } - -diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c -index 0cb46191c1..31ce01b7c5 100644 ---- a/hw/dma/pl330.c -+++ b/hw/dma/pl330.c -@@ -1111,7 +1111,8 @@ static inline const PL330InsnDesc *pl330_fetch_insn(PL330Chan *ch) - uint8_t opcode; - int i; - -- dma_memory_read(ch->parent->mem_as, ch->pc, &opcode, 1); -+ dma_memory_read(ch->parent->mem_as, ch->pc, &opcode, 1, -+ MEMTXATTRS_UNSPECIFIED); - for (i = 0; insn_desc[i].size; i++) { - if ((opcode & insn_desc[i].opmask) == insn_desc[i].opcode) { - return &insn_desc[i]; -@@ -1125,7 +1126,8 @@ static inline void pl330_exec_insn(PL330Chan *ch, const PL330InsnDesc *insn) - uint8_t buf[PL330_INSN_MAXSIZE]; - - assert(insn->size <= PL330_INSN_MAXSIZE); -- dma_memory_read(ch->parent->mem_as, ch->pc, buf, insn->size); -+ dma_memory_read(ch->parent->mem_as, ch->pc, buf, insn->size, -+ MEMTXATTRS_UNSPECIFIED); - insn->exec(ch, buf[0], &buf[1], insn->size - 1); - } - -@@ -1189,7 +1191,8 @@ static int pl330_exec_cycle(PL330Chan *channel) - if (q != NULL && q->len <= pl330_fifo_num_free(&s->fifo)) { - int len = q->len - (q->addr & (q->len - 1)); - -- dma_memory_read(s->mem_as, q->addr, buf, len); -+ dma_memory_read(s->mem_as, q->addr, buf, len, -+ MEMTXATTRS_UNSPECIFIED); - trace_pl330_exec_cycle(q->addr, len); - if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) { - pl330_hexdump(buf, len); -@@ -1220,7 +1223,8 @@ static int pl330_exec_cycle(PL330Chan *channel) - fifo_res = pl330_fifo_get(&s->fifo, buf, len, q->tag); - } - if (fifo_res == PL330_FIFO_OK || q->z) { -- dma_memory_write(s->mem_as, q->addr, buf, len); -+ dma_memory_write(s->mem_as, q->addr, buf, len, -+ MEMTXATTRS_UNSPECIFIED); - trace_pl330_exec_cycle(q->addr, len); - if (trace_event_get_state_backends(TRACE_PL330_HEXDUMP)) { - pl330_hexdump(buf, len); -diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c -index 03bc500878..0ef13c5e9a 100644 ---- a/hw/dma/sparc32_dma.c -+++ b/hw/dma/sparc32_dma.c -@@ -81,11 +81,11 @@ void ledma_memory_read(void *opaque, hwaddr addr, - addr |= s->dmaregs[3]; - trace_ledma_memory_read(addr, len); - if (do_bswap) { -- dma_memory_read(&is->iommu_as, addr, buf, len); -+ dma_memory_read(&is->iommu_as, addr, buf, len, MEMTXATTRS_UNSPECIFIED); - } else { - addr &= ~1; - len &= ~1; -- dma_memory_read(&is->iommu_as, addr, buf, len); -+ dma_memory_read(&is->iommu_as, addr, buf, len, MEMTXATTRS_UNSPECIFIED); - for(i = 0; i < len; i += 2) { - bswap16s((uint16_t *)(buf + i)); - } -@@ -103,7 +103,8 @@ void ledma_memory_write(void *opaque, hwaddr addr, - addr |= s->dmaregs[3]; - trace_ledma_memory_write(addr, len); - if (do_bswap) { -- dma_memory_write(&is->iommu_as, addr, buf, len); -+ dma_memory_write(&is->iommu_as, addr, buf, len, -+ MEMTXATTRS_UNSPECIFIED); - } else { - addr &= ~1; - len &= ~1; -@@ -114,7 +115,8 @@ void ledma_memory_write(void *opaque, hwaddr addr, - for(i = 0; i < l; i += 2) { - tmp_buf[i >> 1] = bswap16(*(uint16_t *)(buf + i)); - } -- dma_memory_write(&is->iommu_as, addr, tmp_buf, l); -+ dma_memory_write(&is->iommu_as, addr, tmp_buf, l, -+ MEMTXATTRS_UNSPECIFIED); - len -= l; - buf += l; - addr += l; -@@ -148,7 +150,8 @@ void espdma_memory_read(void *opaque, uint8_t *buf, int len) - IOMMUState *is = (IOMMUState *)s->iommu; - - trace_espdma_memory_read(s->dmaregs[1], len); -- dma_memory_read(&is->iommu_as, s->dmaregs[1], buf, len); -+ dma_memory_read(&is->iommu_as, s->dmaregs[1], buf, len, -+ MEMTXATTRS_UNSPECIFIED); - s->dmaregs[1] += len; - } - -@@ -158,7 +161,8 @@ void espdma_memory_write(void *opaque, uint8_t *buf, int len) - IOMMUState *is = (IOMMUState *)s->iommu; - - trace_espdma_memory_write(s->dmaregs[1], len); -- dma_memory_write(&is->iommu_as, s->dmaregs[1], buf, len); -+ dma_memory_write(&is->iommu_as, s->dmaregs[1], buf, len, -+ MEMTXATTRS_UNSPECIFIED); - s->dmaregs[1] += len; - } - -diff --git a/hw/dma/xlnx-zynq-devcfg.c b/hw/dma/xlnx-zynq-devcfg.c -index e33112b6f0..f5ad1a0d22 100644 ---- a/hw/dma/xlnx-zynq-devcfg.c -+++ b/hw/dma/xlnx-zynq-devcfg.c -@@ -161,12 +161,14 @@ static void xlnx_zynq_devcfg_dma_go(XlnxZynqDevcfg *s) - btt = MIN(btt, dmah->dest_len); - } - DB_PRINT("reading %x bytes from %x\n", btt, dmah->src_addr); -- dma_memory_read(&address_space_memory, dmah->src_addr, buf, btt); -+ dma_memory_read(&address_space_memory, dmah->src_addr, buf, btt, -+ MEMTXATTRS_UNSPECIFIED); - dmah->src_len -= btt; - dmah->src_addr += btt; - if (loopback && (dmah->src_len || dmah->dest_len)) { - DB_PRINT("writing %x bytes from %x\n", btt, dmah->dest_addr); -- dma_memory_write(&address_space_memory, dmah->dest_addr, buf, btt); -+ dma_memory_write(&address_space_memory, dmah->dest_addr, buf, btt, -+ MEMTXATTRS_UNSPECIFIED); - dmah->dest_len -= btt; - dmah->dest_addr += btt; - } -diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c -index 967548abd3..2d7eae72cd 100644 ---- a/hw/dma/xlnx_dpdma.c -+++ b/hw/dma/xlnx_dpdma.c -@@ -652,7 +652,7 @@ size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel, - } - - if (dma_memory_read(&address_space_memory, desc_addr, &desc, -- sizeof(DPDMADescriptor))) { -+ sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED)) { - s->registers[DPDMA_EISR] |= ((1 << 1) << channel); - xlnx_dpdma_update_irq(s); - s->operation_finished[channel] = true; -@@ -708,7 +708,8 @@ size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel, - if (dma_memory_read(&address_space_memory, - source_addr[0], - &s->data[channel][ptr], -- line_size)) { -+ line_size, -+ MEMTXATTRS_UNSPECIFIED)) { - s->registers[DPDMA_ISR] |= ((1 << 12) << channel); - xlnx_dpdma_update_irq(s); - DPRINTF("Can't get data.\n"); -@@ -736,7 +737,8 @@ size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel, - if (dma_memory_read(&address_space_memory, - source_addr[frag], - &(s->data[channel][ptr]), -- fragment_len)) { -+ fragment_len, -+ MEMTXATTRS_UNSPECIFIED)) { - s->registers[DPDMA_ISR] |= ((1 << 12) << channel); - xlnx_dpdma_update_irq(s); - DPRINTF("Can't get data.\n"); -@@ -754,7 +756,7 @@ size_t xlnx_dpdma_start_operation(XlnxDPDMAState *s, uint8_t channel, - DPRINTF("update the descriptor with the done flag set.\n"); - xlnx_dpdma_desc_set_done(&desc); - dma_memory_write(&address_space_memory, desc_addr, &desc, -- sizeof(DPDMADescriptor)); -+ sizeof(DPDMADescriptor), MEMTXATTRS_UNSPECIFIED); - } - - if (xlnx_dpdma_desc_completion_interrupt(&desc)) { -diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c -index 91fe34ae58..4d13d8e697 100644 ---- a/hw/i386/amd_iommu.c -+++ b/hw/i386/amd_iommu.c -@@ -181,7 +181,7 @@ static void amdvi_log_event(AMDVIState *s, uint64_t *evt) - } - - if (dma_memory_write(&address_space_memory, s->evtlog + s->evtlog_tail, -- evt, AMDVI_EVENT_LEN)) { -+ evt, AMDVI_EVENT_LEN, MEMTXATTRS_UNSPECIFIED)) { - trace_amdvi_evntlog_fail(s->evtlog, s->evtlog_tail); - } - -@@ -376,7 +376,8 @@ static void amdvi_completion_wait(AMDVIState *s, uint64_t *cmd) - } - if (extract64(cmd[0], 0, 1)) { - if (dma_memory_write(&address_space_memory, addr, &data, -- AMDVI_COMPLETION_DATA_SIZE)) { -+ AMDVI_COMPLETION_DATA_SIZE, -+ MEMTXATTRS_UNSPECIFIED)) { - trace_amdvi_completion_wait_fail(addr); - } - } -@@ -502,7 +503,7 @@ static void amdvi_cmdbuf_exec(AMDVIState *s) - uint64_t cmd[2]; - - if (dma_memory_read(&address_space_memory, s->cmdbuf + s->cmdbuf_head, -- cmd, AMDVI_COMMAND_SIZE)) { -+ cmd, AMDVI_COMMAND_SIZE, MEMTXATTRS_UNSPECIFIED)) { - trace_amdvi_command_read_fail(s->cmdbuf, s->cmdbuf_head); - amdvi_log_command_error(s, s->cmdbuf + s->cmdbuf_head); - return; -@@ -836,7 +837,7 @@ static bool amdvi_get_dte(AMDVIState *s, int devid, uint64_t *entry) - uint32_t offset = devid * AMDVI_DEVTAB_ENTRY_SIZE; - - if (dma_memory_read(&address_space_memory, s->devtab + offset, entry, -- AMDVI_DEVTAB_ENTRY_SIZE)) { -+ AMDVI_DEVTAB_ENTRY_SIZE, MEMTXATTRS_UNSPECIFIED)) { - trace_amdvi_dte_get_fail(s->devtab, offset); - /* log error accessing dte */ - amdvi_log_devtab_error(s, devid, s->devtab + offset, 0); -@@ -881,7 +882,8 @@ static inline uint64_t amdvi_get_pte_entry(AMDVIState *s, uint64_t pte_addr, - { - uint64_t pte; - -- if (dma_memory_read(&address_space_memory, pte_addr, &pte, sizeof(pte))) { -+ if (dma_memory_read(&address_space_memory, pte_addr, -+ &pte, sizeof(pte), MEMTXATTRS_UNSPECIFIED)) { - trace_amdvi_get_pte_hwerror(pte_addr); - amdvi_log_pagetab_error(s, devid, pte_addr, 0); - pte = 0; -@@ -1048,7 +1050,7 @@ static int amdvi_get_irte(AMDVIState *s, MSIMessage *origin, uint64_t *dte, - trace_amdvi_ir_irte(irte_root, offset); - - if (dma_memory_read(&address_space_memory, irte_root + offset, -- irte, sizeof(*irte))) { -+ irte, sizeof(*irte), MEMTXATTRS_UNSPECIFIED)) { - trace_amdvi_ir_err("failed to get irte"); - return -AMDVI_IR_GET_IRTE; - } -@@ -1108,7 +1110,7 @@ static int amdvi_get_irte_ga(AMDVIState *s, MSIMessage *origin, uint64_t *dte, - trace_amdvi_ir_irte(irte_root, offset); - - if (dma_memory_read(&address_space_memory, irte_root + offset, -- irte, sizeof(*irte))) { -+ irte, sizeof(*irte), MEMTXATTRS_UNSPECIFIED)) { - trace_amdvi_ir_err("failed to get irte_ga"); - return -AMDVI_IR_GET_IRTE; - } -diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c -index fae282ef5e..6501d93f7e 100644 ---- a/hw/i386/intel_iommu.c -+++ b/hw/i386/intel_iommu.c -@@ -569,7 +569,8 @@ static int vtd_get_root_entry(IntelIOMMUState *s, uint8_t index, - dma_addr_t addr; - - addr = s->root + index * sizeof(*re); -- if (dma_memory_read(&address_space_memory, addr, re, sizeof(*re))) { -+ if (dma_memory_read(&address_space_memory, addr, -+ re, sizeof(*re), MEMTXATTRS_UNSPECIFIED)) { - re->lo = 0; - return -VTD_FR_ROOT_TABLE_INV; - } -@@ -602,7 +603,8 @@ static int vtd_get_context_entry_from_root(IntelIOMMUState *s, - } - - addr = addr + index * ce_size; -- if (dma_memory_read(&address_space_memory, addr, ce, ce_size)) { -+ if (dma_memory_read(&address_space_memory, addr, -+ ce, ce_size, MEMTXATTRS_UNSPECIFIED)) { - return -VTD_FR_CONTEXT_TABLE_INV; - } - -@@ -639,8 +641,8 @@ static uint64_t vtd_get_slpte(dma_addr_t base_addr, uint32_t index) - assert(index < VTD_SL_PT_ENTRY_NR); - - if (dma_memory_read(&address_space_memory, -- base_addr + index * sizeof(slpte), &slpte, -- sizeof(slpte))) { -+ base_addr + index * sizeof(slpte), -+ &slpte, sizeof(slpte), MEMTXATTRS_UNSPECIFIED)) { - slpte = (uint64_t)-1; - return slpte; - } -@@ -704,7 +706,8 @@ static int vtd_get_pdire_from_pdir_table(dma_addr_t pasid_dir_base, - index = VTD_PASID_DIR_INDEX(pasid); - entry_size = VTD_PASID_DIR_ENTRY_SIZE; - addr = pasid_dir_base + index * entry_size; -- if (dma_memory_read(&address_space_memory, addr, pdire, entry_size)) { -+ if (dma_memory_read(&address_space_memory, addr, -+ pdire, entry_size, MEMTXATTRS_UNSPECIFIED)) { - return -VTD_FR_PASID_TABLE_INV; - } - -@@ -728,7 +731,8 @@ static int vtd_get_pe_in_pasid_leaf_table(IntelIOMMUState *s, - index = VTD_PASID_TABLE_INDEX(pasid); - entry_size = VTD_PASID_ENTRY_SIZE; - addr = addr + index * entry_size; -- if (dma_memory_read(&address_space_memory, addr, pe, entry_size)) { -+ if (dma_memory_read(&address_space_memory, addr, -+ pe, entry_size, MEMTXATTRS_UNSPECIFIED)) { - return -VTD_FR_PASID_TABLE_INV; - } - -@@ -2275,7 +2279,8 @@ static bool vtd_get_inv_desc(IntelIOMMUState *s, - uint32_t dw = s->iq_dw ? 32 : 16; - dma_addr_t addr = base_addr + offset * dw; - -- if (dma_memory_read(&address_space_memory, addr, inv_desc, dw)) { -+ if (dma_memory_read(&address_space_memory, addr, -+ inv_desc, dw, MEMTXATTRS_UNSPECIFIED)) { - error_report_once("Read INV DESC failed."); - return false; - } -@@ -2308,8 +2313,9 @@ static bool vtd_process_wait_desc(IntelIOMMUState *s, VTDInvDesc *inv_desc) - dma_addr_t status_addr = inv_desc->hi; - trace_vtd_inv_desc_wait_sw(status_addr, status_data); - status_data = cpu_to_le32(status_data); -- if (dma_memory_write(&address_space_memory, status_addr, &status_data, -- sizeof(status_data))) { -+ if (dma_memory_write(&address_space_memory, status_addr, -+ &status_data, sizeof(status_data), -+ MEMTXATTRS_UNSPECIFIED)) { - trace_vtd_inv_desc_wait_write_fail(inv_desc->hi, inv_desc->lo); - return false; - } -@@ -3120,8 +3126,8 @@ static int vtd_irte_get(IntelIOMMUState *iommu, uint16_t index, - } - - addr = iommu->intr_root + index * sizeof(*entry); -- if (dma_memory_read(&address_space_memory, addr, entry, -- sizeof(*entry))) { -+ if (dma_memory_read(&address_space_memory, addr, -+ entry, sizeof(*entry), MEMTXATTRS_UNSPECIFIED)) { - error_report_once("%s: read failed: ind=0x%x addr=0x%" PRIx64, - __func__, index, addr); - return -VTD_FR_IR_ROOT_INVAL; -diff --git a/hw/ide/macio.c b/hw/ide/macio.c -index b03d401ceb..f08318cf97 100644 ---- a/hw/ide/macio.c -+++ b/hw/ide/macio.c -@@ -97,7 +97,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) - /* Non-block ATAPI transfer - just copy to RAM */ - s->io_buffer_size = MIN(s->io_buffer_size, io->len); - dma_memory_write(&address_space_memory, io->addr, s->io_buffer, -- s->io_buffer_size); -+ s->io_buffer_size, MEMTXATTRS_UNSPECIFIED); - io->len = 0; - ide_atapi_cmd_ok(s); - m->dma_active = false; -diff --git a/hw/intc/xive.c b/hw/intc/xive.c -index 190194d27f..f15f98588a 100644 ---- a/hw/intc/xive.c -+++ b/hw/intc/xive.c -@@ -1246,8 +1246,8 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon) - uint64_t qaddr = qaddr_base + (qindex << 2); - uint32_t qdata = -1; - -- if (dma_memory_read(&address_space_memory, qaddr, &qdata, -- sizeof(qdata))) { -+ if (dma_memory_read(&address_space_memory, qaddr, -+ &qdata, sizeof(qdata), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to read EQ @0x%" - HWADDR_PRIx "\n", qaddr); - return; -@@ -1311,7 +1311,8 @@ static void xive_end_enqueue(XiveEND *end, uint32_t data) - uint32_t qdata = cpu_to_be32((qgen << 31) | (data & 0x7fffffff)); - uint32_t qentries = 1 << (qsize + 10); - -- if (dma_memory_write(&address_space_memory, qaddr, &qdata, sizeof(qdata))) { -+ if (dma_memory_write(&address_space_memory, qaddr, -+ &qdata, sizeof(qdata), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to write END data @0x%" - HWADDR_PRIx "\n", qaddr); - return; -diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c -index 73941bdae9..76ea511d53 100644 ---- a/hw/misc/bcm2835_property.c -+++ b/hw/misc/bcm2835_property.c -@@ -69,7 +69,8 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) - break; - case 0x00010003: /* Get board MAC address */ - resplen = sizeof(s->macaddr.a); -- dma_memory_write(&s->dma_as, value + 12, s->macaddr.a, resplen); -+ dma_memory_write(&s->dma_as, value + 12, s->macaddr.a, resplen, -+ MEMTXATTRS_UNSPECIFIED); - break; - case 0x00010004: /* Get board serial */ - qemu_log_mask(LOG_UNIMP, -diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c -index e220f1a927..efcc02609f 100644 ---- a/hw/misc/macio/mac_dbdma.c -+++ b/hw/misc/macio/mac_dbdma.c -@@ -94,7 +94,7 @@ static void dbdma_cmdptr_load(DBDMA_channel *ch) - DBDMA_DPRINTFCH(ch, "dbdma_cmdptr_load 0x%08x\n", - ch->regs[DBDMA_CMDPTR_LO]); - dma_memory_read(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO], -- &ch->current, sizeof(dbdma_cmd)); -+ &ch->current, sizeof(dbdma_cmd), MEMTXATTRS_UNSPECIFIED); - } - - static void dbdma_cmdptr_save(DBDMA_channel *ch) -@@ -104,7 +104,7 @@ static void dbdma_cmdptr_save(DBDMA_channel *ch) - le16_to_cpu(ch->current.xfer_status), - le16_to_cpu(ch->current.res_count)); - dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO], -- &ch->current, sizeof(dbdma_cmd)); -+ &ch->current, sizeof(dbdma_cmd), MEMTXATTRS_UNSPECIFIED); - } - - static void kill_channel(DBDMA_channel *ch) -@@ -371,7 +371,8 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr, - return; - } - -- dma_memory_read(&address_space_memory, addr, ¤t->cmd_dep, len); -+ dma_memory_read(&address_space_memory, addr, ¤t->cmd_dep, len, -+ MEMTXATTRS_UNSPECIFIED); - - if (conditional_wait(ch)) - goto wait; -@@ -403,7 +404,8 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr, - return; - } - -- dma_memory_write(&address_space_memory, addr, ¤t->cmd_dep, len); -+ dma_memory_write(&address_space_memory, addr, ¤t->cmd_dep, len, -+ MEMTXATTRS_UNSPECIFIED); - - if (conditional_wait(ch)) - goto wait; -diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c -index ff611f18fb..ecc0245fe8 100644 ---- a/hw/net/allwinner-sun8i-emac.c -+++ b/hw/net/allwinner-sun8i-emac.c -@@ -350,7 +350,8 @@ static void allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s, - FrameDescriptor *desc, - uint32_t phys_addr) - { -- dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc)); -+ dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc), -+ MEMTXATTRS_UNSPECIFIED); - } - - static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s, -@@ -402,7 +403,8 @@ static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s, - FrameDescriptor *desc, - uint32_t phys_addr) - { -- dma_memory_write(&s->dma_as, phys_addr, desc, sizeof(*desc)); -+ dma_memory_write(&s->dma_as, phys_addr, desc, sizeof(*desc), -+ MEMTXATTRS_UNSPECIFIED); - } - - static bool allwinner_sun8i_emac_can_receive(NetClientState *nc) -@@ -460,7 +462,8 @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState *nc, - << RX_DESC_STATUS_FRM_LEN_SHIFT; - } - -- dma_memory_write(&s->dma_as, desc.addr, buf, desc_bytes); -+ dma_memory_write(&s->dma_as, desc.addr, buf, desc_bytes, -+ MEMTXATTRS_UNSPECIFIED); - allwinner_sun8i_emac_flush_desc(s, &desc, s->rx_desc_curr); - trace_allwinner_sun8i_emac_receive(s->rx_desc_curr, desc.addr, - desc_bytes); -@@ -512,7 +515,8 @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s) - desc.status |= TX_DESC_STATUS_LENGTH_ERR; - break; - } -- dma_memory_read(&s->dma_as, desc.addr, packet_buf + packet_bytes, bytes); -+ dma_memory_read(&s->dma_as, desc.addr, packet_buf + packet_bytes, -+ bytes, MEMTXATTRS_UNSPECIFIED); - packet_bytes += bytes; - desc.status &= ~DESC_STATUS_CTL; - allwinner_sun8i_emac_flush_desc(s, &desc, s->tx_desc_curr); -@@ -634,7 +638,8 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset, - break; - case REG_TX_CUR_BUF: /* Transmit Current Buffer */ - if (s->tx_desc_curr != 0) { -- dma_memory_read(&s->dma_as, s->tx_desc_curr, &desc, sizeof(desc)); -+ dma_memory_read(&s->dma_as, s->tx_desc_curr, &desc, sizeof(desc), -+ MEMTXATTRS_UNSPECIFIED); - value = desc.addr; - } else { - value = 0; -@@ -647,7 +652,8 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset, - break; - case REG_RX_CUR_BUF: /* Receive Current Buffer */ - if (s->rx_desc_curr != 0) { -- dma_memory_read(&s->dma_as, s->rx_desc_curr, &desc, sizeof(desc)); -+ dma_memory_read(&s->dma_as, s->rx_desc_curr, &desc, sizeof(desc), -+ MEMTXATTRS_UNSPECIFIED); - value = desc.addr; - } else { - value = 0; -diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c -index 25685ba3a9..83ef0a783e 100644 ---- a/hw/net/ftgmac100.c -+++ b/hw/net/ftgmac100.c -@@ -453,7 +453,8 @@ static void do_phy_ctl(FTGMAC100State *s) - - static int ftgmac100_read_bd(FTGMAC100Desc *bd, dma_addr_t addr) - { -- if (dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd))) { -+ if (dma_memory_read(&address_space_memory, addr, -+ bd, sizeof(*bd), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to read descriptor @ 0x%" - HWADDR_PRIx "\n", __func__, addr); - return -1; -@@ -473,7 +474,8 @@ static int ftgmac100_write_bd(FTGMAC100Desc *bd, dma_addr_t addr) - lebd.des1 = cpu_to_le32(bd->des1); - lebd.des2 = cpu_to_le32(bd->des2); - lebd.des3 = cpu_to_le32(bd->des3); -- if (dma_memory_write(&address_space_memory, addr, &lebd, sizeof(lebd))) { -+ if (dma_memory_write(&address_space_memory, addr, -+ &lebd, sizeof(lebd), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to write descriptor @ 0x%" - HWADDR_PRIx "\n", __func__, addr); - return -1; -@@ -554,7 +556,8 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring, - len = sizeof(s->frame) - frame_size; - } - -- if (dma_memory_read(&address_space_memory, bd.des3, ptr, len)) { -+ if (dma_memory_read(&address_space_memory, bd.des3, -+ ptr, len, MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to read packet @ 0x%x\n", - __func__, bd.des3); - s->isr |= FTGMAC100_INT_AHB_ERR; -@@ -1030,20 +1033,24 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, - bd.des1 = lduw_be_p(buf + 14) | FTGMAC100_RXDES1_VLANTAG_AVAIL; - - if (s->maccr & FTGMAC100_MACCR_RM_VLAN) { -- dma_memory_write(&address_space_memory, buf_addr, buf, 12); -- dma_memory_write(&address_space_memory, buf_addr + 12, buf + 16, -- buf_len - 16); -+ dma_memory_write(&address_space_memory, buf_addr, buf, 12, -+ MEMTXATTRS_UNSPECIFIED); -+ dma_memory_write(&address_space_memory, buf_addr + 12, -+ buf + 16, buf_len - 16, -+ MEMTXATTRS_UNSPECIFIED); - } else { -- dma_memory_write(&address_space_memory, buf_addr, buf, buf_len); -+ dma_memory_write(&address_space_memory, buf_addr, buf, -+ buf_len, MEMTXATTRS_UNSPECIFIED); - } - } else { - bd.des1 = 0; -- dma_memory_write(&address_space_memory, buf_addr, buf, buf_len); -+ dma_memory_write(&address_space_memory, buf_addr, buf, buf_len, -+ MEMTXATTRS_UNSPECIFIED); - } - buf += buf_len; - if (size < 4) { - dma_memory_write(&address_space_memory, buf_addr + buf_len, -- crc_ptr, 4 - size); -+ crc_ptr, 4 - size, MEMTXATTRS_UNSPECIFIED); - crc_ptr += 4 - size; - } - -diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c -index 9c7035bc94..0db9aaf76a 100644 ---- a/hw/net/imx_fec.c -+++ b/hw/net/imx_fec.c -@@ -387,19 +387,22 @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val) - - static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr) - { -- dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd)); -+ dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd), -+ MEMTXATTRS_UNSPECIFIED); - - trace_imx_fec_read_bd(addr, bd->flags, bd->length, bd->data); - } - - static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t addr) - { -- dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd)); -+ dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd), -+ MEMTXATTRS_UNSPECIFIED); - } - - static void imx_enet_read_bd(IMXENETBufDesc *bd, dma_addr_t addr) - { -- dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd)); -+ dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd), -+ MEMTXATTRS_UNSPECIFIED); - - trace_imx_enet_read_bd(addr, bd->flags, bd->length, bd->data, - bd->option, bd->status); -@@ -407,7 +410,8 @@ static void imx_enet_read_bd(IMXENETBufDesc *bd, dma_addr_t addr) - - static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr) - { -- dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd)); -+ dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd), -+ MEMTXATTRS_UNSPECIFIED); - } - - static void imx_eth_update(IMXFECState *s) -@@ -474,7 +478,8 @@ static void imx_fec_do_tx(IMXFECState *s) - len = ENET_MAX_FRAME_SIZE - frame_size; - s->regs[ENET_EIR] |= ENET_INT_BABT; - } -- dma_memory_read(&address_space_memory, bd.data, ptr, len); -+ dma_memory_read(&address_space_memory, bd.data, ptr, len, -+ MEMTXATTRS_UNSPECIFIED); - ptr += len; - frame_size += len; - if (bd.flags & ENET_BD_L) { -@@ -555,7 +560,8 @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index) - len = ENET_MAX_FRAME_SIZE - frame_size; - s->regs[ENET_EIR] |= ENET_INT_BABT; - } -- dma_memory_read(&address_space_memory, bd.data, ptr, len); -+ dma_memory_read(&address_space_memory, bd.data, ptr, len, -+ MEMTXATTRS_UNSPECIFIED); - ptr += len; - frame_size += len; - if (bd.flags & ENET_BD_L) { -@@ -1103,11 +1109,12 @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf, - buf_len += size - 4; - } - buf_addr = bd.data; -- dma_memory_write(&address_space_memory, buf_addr, buf, buf_len); -+ dma_memory_write(&address_space_memory, buf_addr, buf, buf_len, -+ MEMTXATTRS_UNSPECIFIED); - buf += buf_len; - if (size < 4) { - dma_memory_write(&address_space_memory, buf_addr + buf_len, -- crc_ptr, 4 - size); -+ crc_ptr, 4 - size, MEMTXATTRS_UNSPECIFIED); - crc_ptr += 4 - size; - } - bd.flags &= ~ENET_BD_E; -@@ -1210,8 +1217,8 @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf, - */ - const uint8_t zeros[2] = { 0 }; - -- dma_memory_write(&address_space_memory, buf_addr, -- zeros, sizeof(zeros)); -+ dma_memory_write(&address_space_memory, buf_addr, zeros, -+ sizeof(zeros), MEMTXATTRS_UNSPECIFIED); - - buf_addr += sizeof(zeros); - buf_len -= sizeof(zeros); -@@ -1220,11 +1227,12 @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf, - shift16 = false; - } - -- dma_memory_write(&address_space_memory, buf_addr, buf, buf_len); -+ dma_memory_write(&address_space_memory, buf_addr, buf, buf_len, -+ MEMTXATTRS_UNSPECIFIED); - buf += buf_len; - if (size < 4) { - dma_memory_write(&address_space_memory, buf_addr + buf_len, -- crc_ptr, 4 - size); -+ crc_ptr, 4 - size, MEMTXATTRS_UNSPECIFIED); - crc_ptr += 4 - size; - } - bd.flags &= ~ENET_BD_E; -diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c -index 7c892f820f..df2efe1bf8 100644 ---- a/hw/net/npcm7xx_emc.c -+++ b/hw/net/npcm7xx_emc.c -@@ -200,7 +200,8 @@ static void emc_update_irq_from_reg_change(NPCM7xxEMCState *emc) - - static int emc_read_tx_desc(dma_addr_t addr, NPCM7xxEMCTxDesc *desc) - { -- if (dma_memory_read(&address_space_memory, addr, desc, sizeof(*desc))) { -+ if (dma_memory_read(&address_space_memory, addr, desc, -+ sizeof(*desc), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%" - HWADDR_PRIx "\n", __func__, addr); - return -1; -@@ -221,7 +222,7 @@ static int emc_write_tx_desc(const NPCM7xxEMCTxDesc *desc, dma_addr_t addr) - le_desc.status_and_length = cpu_to_le32(desc->status_and_length); - le_desc.ntxdsa = cpu_to_le32(desc->ntxdsa); - if (dma_memory_write(&address_space_memory, addr, &le_desc, -- sizeof(le_desc))) { -+ sizeof(le_desc), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%" - HWADDR_PRIx "\n", __func__, addr); - return -1; -@@ -231,7 +232,8 @@ static int emc_write_tx_desc(const NPCM7xxEMCTxDesc *desc, dma_addr_t addr) - - static int emc_read_rx_desc(dma_addr_t addr, NPCM7xxEMCRxDesc *desc) - { -- if (dma_memory_read(&address_space_memory, addr, desc, sizeof(*desc))) { -+ if (dma_memory_read(&address_space_memory, addr, desc, -+ sizeof(*desc), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%" - HWADDR_PRIx "\n", __func__, addr); - return -1; -@@ -252,7 +254,7 @@ static int emc_write_rx_desc(const NPCM7xxEMCRxDesc *desc, dma_addr_t addr) - le_desc.reserved = cpu_to_le32(desc->reserved); - le_desc.nrxdsa = cpu_to_le32(desc->nrxdsa); - if (dma_memory_write(&address_space_memory, addr, &le_desc, -- sizeof(le_desc))) { -+ sizeof(le_desc), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%" - HWADDR_PRIx "\n", __func__, addr); - return -1; -@@ -360,7 +362,8 @@ static void emc_try_send_next_packet(NPCM7xxEMCState *emc) - buf = malloced_buf; - } - -- if (dma_memory_read(&address_space_memory, next_buf_addr, buf, length)) { -+ if (dma_memory_read(&address_space_memory, next_buf_addr, buf, -+ length, MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read packet @ 0x%x\n", - __func__, next_buf_addr); - emc_set_mista(emc, REG_MISTA_TXBERR); -@@ -545,10 +548,11 @@ static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1) - - buf_addr = rx_desc.rxbsa; - emc->regs[REG_CRXBSA] = buf_addr; -- if (dma_memory_write(&address_space_memory, buf_addr, buf, len) || -+ if (dma_memory_write(&address_space_memory, buf_addr, buf, -+ len, MEMTXATTRS_UNSPECIFIED) || - (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC) && -- dma_memory_write(&address_space_memory, buf_addr + len, crc_ptr, -- 4))) { -+ dma_memory_write(&address_space_memory, buf_addr + len, -+ crc_ptr, 4, MEMTXATTRS_UNSPECIFIED))) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: Bus error writing packet\n", - __func__); - emc_set_mista(emc, REG_MISTA_RXBERR); -diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c -index f7803fe3c3..9b91b15cb0 100644 ---- a/hw/nvram/fw_cfg.c -+++ b/hw/nvram/fw_cfg.c -@@ -357,7 +357,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s) - dma_addr = s->dma_addr; - s->dma_addr = 0; - -- if (dma_memory_read(s->dma_as, dma_addr, &dma, sizeof(dma))) { -+ if (dma_memory_read(s->dma_as, dma_addr, -+ &dma, sizeof(dma), MEMTXATTRS_UNSPECIFIED)) { - stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control), - FW_CFG_DMA_CTL_ERROR); - return; -@@ -419,7 +420,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s) - */ - if (read) { - if (dma_memory_write(s->dma_as, dma.address, -- &e->data[s->cur_offset], len)) { -+ &e->data[s->cur_offset], len, -+ MEMTXATTRS_UNSPECIFIED)) { - dma.control |= FW_CFG_DMA_CTL_ERROR; - } - } -@@ -427,7 +429,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s) - if (!e->allow_write || - len != dma.length || - dma_memory_read(s->dma_as, dma.address, -- &e->data[s->cur_offset], len)) { -+ &e->data[s->cur_offset], len, -+ MEMTXATTRS_UNSPECIFIED)) { - dma.control |= FW_CFG_DMA_CTL_ERROR; - } else if (e->write_cb) { - e->write_cb(e->callback_opaque, s->cur_offset, len); -diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c -index a7f9685005..947efa77dc 100644 ---- a/hw/pci-host/pnv_phb3.c -+++ b/hw/pci-host/pnv_phb3.c -@@ -715,7 +715,8 @@ static bool pnv_phb3_resolve_pe(PnvPhb3DMASpace *ds) - bus_num = pci_bus_num(ds->bus); - addr = rtt & PHB_RTT_BASE_ADDRESS_MASK; - addr += 2 * ((bus_num << 8) | ds->devfn); -- if (dma_memory_read(&address_space_memory, addr, &rte, sizeof(rte))) { -+ if (dma_memory_read(&address_space_memory, addr, &rte, -+ sizeof(rte), MEMTXATTRS_UNSPECIFIED)) { - phb3_error(ds->phb, "Failed to read RTT entry at 0x%"PRIx64, addr); - /* Set error bits ? fence ? ... */ - return false; -@@ -794,7 +795,7 @@ static void pnv_phb3_translate_tve(PnvPhb3DMASpace *ds, hwaddr addr, - /* Grab the TCE address */ - taddr = base | (((addr >> sh) & ((1ul << tbl_shift) - 1)) << 3); - if (dma_memory_read(&address_space_memory, taddr, &tce, -- sizeof(tce))) { -+ sizeof(tce), MEMTXATTRS_UNSPECIFIED)) { - phb3_error(phb, "Failed to read TCE at 0x%"PRIx64, taddr); - return; - } -diff --git a/hw/pci-host/pnv_phb3_msi.c b/hw/pci-host/pnv_phb3_msi.c -index 099d2092a2..8bcbc2cc4f 100644 ---- a/hw/pci-host/pnv_phb3_msi.c -+++ b/hw/pci-host/pnv_phb3_msi.c -@@ -53,7 +53,8 @@ static bool phb3_msi_read_ive(PnvPHB3 *phb, int srcno, uint64_t *out_ive) - return false; - } - -- if (dma_memory_read(&address_space_memory, ive_addr, &ive, sizeof(ive))) { -+ if (dma_memory_read(&address_space_memory, ive_addr, -+ &ive, sizeof(ive), MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "Failed to read IVE at 0x%" PRIx64, - ive_addr); - return false; -@@ -73,7 +74,8 @@ static void phb3_msi_set_p(Phb3MsiState *msi, int srcno, uint8_t gen) - return; - } - -- if (dma_memory_write(&address_space_memory, ive_addr + 4, &p, 1)) { -+ if (dma_memory_write(&address_space_memory, ive_addr + 4, -+ &p, 1, MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, - "Failed to write IVE (set P) at 0x%" PRIx64, ive_addr); - } -@@ -89,7 +91,8 @@ static void phb3_msi_set_q(Phb3MsiState *msi, int srcno) - return; - } - -- if (dma_memory_write(&address_space_memory, ive_addr + 5, &q, 1)) { -+ if (dma_memory_write(&address_space_memory, ive_addr + 5, -+ &q, 1, MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, - "Failed to write IVE (set Q) at 0x%" PRIx64, ive_addr); - } -diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c -index 5c375a9f28..4e17a48d35 100644 ---- a/hw/pci-host/pnv_phb4.c -+++ b/hw/pci-host/pnv_phb4.c -@@ -891,7 +891,8 @@ static bool pnv_phb4_resolve_pe(PnvPhb4DMASpace *ds) - bus_num = pci_bus_num(ds->bus); - addr = rtt & PHB_RTT_BASE_ADDRESS_MASK; - addr += 2 * PCI_BUILD_BDF(bus_num, ds->devfn); -- if (dma_memory_read(&address_space_memory, addr, &rte, sizeof(rte))) { -+ if (dma_memory_read(&address_space_memory, addr, &rte, -+ sizeof(rte), MEMTXATTRS_UNSPECIFIED)) { - phb_error(ds->phb, "Failed to read RTT entry at 0x%"PRIx64, addr); - /* Set error bits ? fence ? ... */ - return false; -@@ -961,7 +962,7 @@ static void pnv_phb4_translate_tve(PnvPhb4DMASpace *ds, hwaddr addr, - /* Grab the TCE address */ - taddr = base | (((addr >> sh) & ((1ul << tbl_shift) - 1)) << 3); - if (dma_memory_read(&address_space_memory, taddr, &tce, -- sizeof(tce))) { -+ sizeof(tce), MEMTXATTRS_UNSPECIFIED)) { - phb_error(ds->phb, "Failed to read TCE at 0x%"PRIx64, taddr); - return; - } -diff --git a/hw/sd/allwinner-sdhost.c b/hw/sd/allwinner-sdhost.c -index 9166d6638d..de5bc49e68 100644 ---- a/hw/sd/allwinner-sdhost.c -+++ b/hw/sd/allwinner-sdhost.c -@@ -311,7 +311,8 @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s, - uint8_t buf[1024]; - - /* Read descriptor */ -- dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc)); -+ dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc), -+ MEMTXATTRS_UNSPECIFIED); - if (desc->size == 0) { - desc->size = klass->max_desc_size; - } else if (desc->size > klass->max_desc_size) { -@@ -337,23 +338,24 @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s, - /* Write to SD bus */ - if (is_write) { - dma_memory_read(&s->dma_as, -- (desc->addr & DESC_SIZE_MASK) + num_done, -- buf, buf_bytes); -+ (desc->addr & DESC_SIZE_MASK) + num_done, buf, -+ buf_bytes, MEMTXATTRS_UNSPECIFIED); - sdbus_write_data(&s->sdbus, buf, buf_bytes); - - /* Read from SD bus */ - } else { - sdbus_read_data(&s->sdbus, buf, buf_bytes); - dma_memory_write(&s->dma_as, -- (desc->addr & DESC_SIZE_MASK) + num_done, -- buf, buf_bytes); -+ (desc->addr & DESC_SIZE_MASK) + num_done, buf, -+ buf_bytes, MEMTXATTRS_UNSPECIFIED); - } - num_done += buf_bytes; - } - - /* Clear hold flag and flush descriptor */ - desc->status &= ~DESC_STATUS_HOLD; -- dma_memory_write(&s->dma_as, desc_addr, desc, sizeof(*desc)); -+ dma_memory_write(&s->dma_as, desc_addr, desc, sizeof(*desc), -+ MEMTXATTRS_UNSPECIFIED); - - return num_done; - } -diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c -index c9dc065cc5..e0bbc90344 100644 ---- a/hw/sd/sdhci.c -+++ b/hw/sd/sdhci.c -@@ -616,8 +616,8 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) - s->blkcnt--; - } - } -- dma_memory_write(s->dma_as, s->sdmasysad, -- &s->fifo_buffer[begin], s->data_count - begin); -+ dma_memory_write(s->dma_as, s->sdmasysad, &s->fifo_buffer[begin], -+ s->data_count - begin, MEMTXATTRS_UNSPECIFIED); - s->sdmasysad += s->data_count - begin; - if (s->data_count == block_size) { - s->data_count = 0; -@@ -637,8 +637,8 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) - s->data_count = block_size; - boundary_count -= block_size - begin; - } -- dma_memory_read(s->dma_as, s->sdmasysad, -- &s->fifo_buffer[begin], s->data_count - begin); -+ dma_memory_read(s->dma_as, s->sdmasysad, &s->fifo_buffer[begin], -+ s->data_count - begin, MEMTXATTRS_UNSPECIFIED); - s->sdmasysad += s->data_count - begin; - if (s->data_count == block_size) { - sdbus_write_data(&s->sdbus, s->fifo_buffer, block_size); -@@ -670,9 +670,11 @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s) - - if (s->trnmod & SDHC_TRNS_READ) { - sdbus_read_data(&s->sdbus, s->fifo_buffer, datacnt); -- dma_memory_write(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt); -+ dma_memory_write(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt, -+ MEMTXATTRS_UNSPECIFIED); - } else { -- dma_memory_read(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt); -+ dma_memory_read(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt, -+ MEMTXATTRS_UNSPECIFIED); - sdbus_write_data(&s->sdbus, s->fifo_buffer, datacnt); - } - s->blkcnt--; -@@ -694,7 +696,8 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr) - hwaddr entry_addr = (hwaddr)s->admasysaddr; - switch (SDHC_DMA_TYPE(s->hostctl1)) { - case SDHC_CTRL_ADMA2_32: -- dma_memory_read(s->dma_as, entry_addr, &adma2, sizeof(adma2)); -+ dma_memory_read(s->dma_as, entry_addr, &adma2, sizeof(adma2), -+ MEMTXATTRS_UNSPECIFIED); - adma2 = le64_to_cpu(adma2); - /* The spec does not specify endianness of descriptor table. - * We currently assume that it is LE. -@@ -705,7 +708,8 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr) - dscr->incr = 8; - break; - case SDHC_CTRL_ADMA1_32: -- dma_memory_read(s->dma_as, entry_addr, &adma1, sizeof(adma1)); -+ dma_memory_read(s->dma_as, entry_addr, &adma1, sizeof(adma1), -+ MEMTXATTRS_UNSPECIFIED); - adma1 = le32_to_cpu(adma1); - dscr->addr = (hwaddr)(adma1 & 0xFFFFF000); - dscr->attr = (uint8_t)extract32(adma1, 0, 7); -@@ -717,10 +721,13 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr) - } - break; - case SDHC_CTRL_ADMA2_64: -- dma_memory_read(s->dma_as, entry_addr, &dscr->attr, 1); -- dma_memory_read(s->dma_as, entry_addr + 2, &dscr->length, 2); -+ dma_memory_read(s->dma_as, entry_addr, &dscr->attr, 1, -+ MEMTXATTRS_UNSPECIFIED); -+ dma_memory_read(s->dma_as, entry_addr + 2, &dscr->length, 2, -+ MEMTXATTRS_UNSPECIFIED); - dscr->length = le16_to_cpu(dscr->length); -- dma_memory_read(s->dma_as, entry_addr + 4, &dscr->addr, 8); -+ dma_memory_read(s->dma_as, entry_addr + 4, &dscr->addr, 8, -+ MEMTXATTRS_UNSPECIFIED); - dscr->addr = le64_to_cpu(dscr->addr); - dscr->attr &= (uint8_t) ~0xC0; - dscr->incr = 12; -@@ -785,7 +792,8 @@ static void sdhci_do_adma(SDHCIState *s) - } - dma_memory_write(s->dma_as, dscr.addr, - &s->fifo_buffer[begin], -- s->data_count - begin); -+ s->data_count - begin, -+ MEMTXATTRS_UNSPECIFIED); - dscr.addr += s->data_count - begin; - if (s->data_count == block_size) { - s->data_count = 0; -@@ -810,7 +818,8 @@ static void sdhci_do_adma(SDHCIState *s) - } - dma_memory_read(s->dma_as, dscr.addr, - &s->fifo_buffer[begin], -- s->data_count - begin); -+ s->data_count - begin, -+ MEMTXATTRS_UNSPECIFIED); - dscr.addr += s->data_count - begin; - if (s->data_count == block_size) { - sdbus_write_data(&s->sdbus, s->fifo_buffer, block_size); -diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c -index e1d96acf7e..8755e9cbb0 100644 ---- a/hw/usb/hcd-dwc2.c -+++ b/hw/usb/hcd-dwc2.c -@@ -272,8 +272,8 @@ static void dwc2_handle_packet(DWC2State *s, uint32_t devadr, USBDevice *dev, - - if (pid != USB_TOKEN_IN) { - trace_usb_dwc2_memory_read(hcdma, tlen); -- if (dma_memory_read(&s->dma_as, hcdma, -- s->usb_buf[chan], tlen) != MEMTX_OK) { -+ if (dma_memory_read(&s->dma_as, hcdma, s->usb_buf[chan], tlen, -+ MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_read failed\n", - __func__); - } -@@ -328,8 +328,8 @@ babble: - - if (pid == USB_TOKEN_IN) { - trace_usb_dwc2_memory_write(hcdma, actual); -- if (dma_memory_write(&s->dma_as, hcdma, s->usb_buf[chan], -- actual) != MEMTX_OK) { -+ if (dma_memory_write(&s->dma_as, hcdma, s->usb_buf[chan], actual, -+ MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_write failed\n", - __func__); - } -diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c -index 1415107315..0289b3696d 100644 ---- a/hw/usb/hcd-ehci.c -+++ b/hw/usb/hcd-ehci.c -@@ -383,7 +383,8 @@ static inline int get_dwords(EHCIState *ehci, uint32_t addr, - } - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { -- dma_memory_read(ehci->as, addr, buf, sizeof(*buf)); -+ dma_memory_read(ehci->as, addr, buf, sizeof(*buf), -+ MEMTXATTRS_UNSPECIFIED); - *buf = le32_to_cpu(*buf); - } - -@@ -405,7 +406,8 @@ static inline int put_dwords(EHCIState *ehci, uint32_t addr, - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - uint32_t tmp = cpu_to_le32(*buf); -- dma_memory_write(ehci->as, addr, &tmp, sizeof(tmp)); -+ dma_memory_write(ehci->as, addr, &tmp, sizeof(tmp), -+ MEMTXATTRS_UNSPECIFIED); - } - - return num; -diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c -index 56e2315c73..a93d6b2e98 100644 ---- a/hw/usb/hcd-ohci.c -+++ b/hw/usb/hcd-ohci.c -@@ -452,7 +452,8 @@ static inline int get_dwords(OHCIState *ohci, - addr += ohci->localmem_base; - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { -- if (dma_memory_read(ohci->as, addr, buf, sizeof(*buf))) { -+ if (dma_memory_read(ohci->as, addr, -+ buf, sizeof(*buf), MEMTXATTRS_UNSPECIFIED)) { - return -1; - } - *buf = le32_to_cpu(*buf); -@@ -471,7 +472,8 @@ static inline int put_dwords(OHCIState *ohci, - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - uint32_t tmp = cpu_to_le32(*buf); -- if (dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp))) { -+ if (dma_memory_write(ohci->as, addr, -+ &tmp, sizeof(tmp), MEMTXATTRS_UNSPECIFIED)) { - return -1; - } - } -@@ -488,7 +490,8 @@ static inline int get_words(OHCIState *ohci, - addr += ohci->localmem_base; - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { -- if (dma_memory_read(ohci->as, addr, buf, sizeof(*buf))) { -+ if (dma_memory_read(ohci->as, addr, -+ buf, sizeof(*buf), MEMTXATTRS_UNSPECIFIED)) { - return -1; - } - *buf = le16_to_cpu(*buf); -@@ -507,7 +510,8 @@ static inline int put_words(OHCIState *ohci, - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - uint16_t tmp = cpu_to_le16(*buf); -- if (dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp))) { -+ if (dma_memory_write(ohci->as, addr, -+ &tmp, sizeof(tmp), MEMTXATTRS_UNSPECIFIED)) { - return -1; - } - } -@@ -537,8 +541,8 @@ static inline int ohci_read_iso_td(OHCIState *ohci, - static inline int ohci_read_hcca(OHCIState *ohci, - dma_addr_t addr, struct ohci_hcca *hcca) - { -- return dma_memory_read(ohci->as, addr + ohci->localmem_base, -- hcca, sizeof(*hcca)); -+ return dma_memory_read(ohci->as, addr + ohci->localmem_base, hcca, -+ sizeof(*hcca), MEMTXATTRS_UNSPECIFIED); - } - - static inline int ohci_put_ed(OHCIState *ohci, -@@ -572,7 +576,7 @@ static inline int ohci_put_hcca(OHCIState *ohci, - return dma_memory_write(ohci->as, - addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET, - (char *)hcca + HCCA_WRITEBACK_OFFSET, -- HCCA_WRITEBACK_SIZE); -+ HCCA_WRITEBACK_SIZE, MEMTXATTRS_UNSPECIFIED); - } - - /* Read/Write the contents of a TD from/to main memory. */ -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 08cd63e159..c76091c657 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -488,7 +488,7 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, dma_addr_t addr, - - assert((len % sizeof(uint32_t)) == 0); - -- dma_memory_read(xhci->as, addr, buf, len); -+ dma_memory_read(xhci->as, addr, buf, len, MEMTXATTRS_UNSPECIFIED); - - for (i = 0; i < (len / sizeof(uint32_t)); i++) { - buf[i] = le32_to_cpu(buf[i]); -@@ -508,7 +508,7 @@ static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr, - for (i = 0; i < n; i++) { - tmp[i] = cpu_to_le32(buf[i]); - } -- dma_memory_write(xhci->as, addr, tmp, len); -+ dma_memory_write(xhci->as, addr, tmp, len, MEMTXATTRS_UNSPECIFIED); - } - - static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport) -@@ -619,7 +619,7 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v) - ev_trb.status, ev_trb.control); - - addr = intr->er_start + TRB_SIZE*intr->er_ep_idx; -- dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE); -+ dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE, MEMTXATTRS_UNSPECIFIED); - - intr->er_ep_idx++; - if (intr->er_ep_idx >= intr->er_size) { -@@ -680,7 +680,8 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, - - while (1) { - TRBType type; -- dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE); -+ dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE, -+ MEMTXATTRS_UNSPECIFIED); - trb->addr = ring->dequeue; - trb->ccs = ring->ccs; - le64_to_cpus(&trb->parameter); -@@ -727,7 +728,8 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) - - while (1) { - TRBType type; -- dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE); -+ dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE, -+ MEMTXATTRS_UNSPECIFIED); - le64_to_cpus(&trb.parameter); - le32_to_cpus(&trb.status); - le32_to_cpus(&trb.control); -@@ -782,7 +784,8 @@ static void xhci_er_reset(XHCIState *xhci, int v) - xhci_die(xhci); - return; - } -- dma_memory_read(xhci->as, erstba, &seg, sizeof(seg)); -+ dma_memory_read(xhci->as, erstba, &seg, sizeof(seg), -+ MEMTXATTRS_UNSPECIFIED); - le32_to_cpus(&seg.addr_low); - le32_to_cpus(&seg.addr_high); - le32_to_cpus(&seg.size); -@@ -2398,7 +2401,8 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx) - /* TODO: actually implement real values here */ - bw_ctx[0] = 0; - memset(&bw_ctx[1], 80, xhci->numports); /* 80% */ -- dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx)); -+ dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx), -+ MEMTXATTRS_UNSPECIFIED); - - return CC_SUCCESS; - } -diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h -index c90e74a67d..5d2ea8e665 100644 ---- a/include/hw/ppc/spapr_vio.h -+++ b/include/hw/ppc/spapr_vio.h -@@ -97,14 +97,16 @@ static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr, - static inline int spapr_vio_dma_read(SpaprVioDevice *dev, uint64_t taddr, - void *buf, uint32_t size) - { -- return (dma_memory_read(&dev->as, taddr, buf, size) != 0) ? -+ return (dma_memory_read(&dev->as, taddr, -+ buf, size, MEMTXATTRS_UNSPECIFIED) != 0) ? - H_DEST_PARM : H_SUCCESS; - } - - static inline int spapr_vio_dma_write(SpaprVioDevice *dev, uint64_t taddr, - const void *buf, uint32_t size) - { -- return (dma_memory_write(&dev->as, taddr, buf, size) != 0) ? -+ return (dma_memory_write(&dev->as, taddr, -+ buf, size, MEMTXATTRS_UNSPECIFIED) != 0) ? - H_DEST_PARM : H_SUCCESS; - } - -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index e8ad42226f..522682bf38 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -143,12 +143,14 @@ static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr, - * @addr: address within that address space - * @buf: buffer with the data transferred - * @len: length of the data transferred -+ * @attrs: memory transaction attributes - */ - static inline MemTxResult dma_memory_read(AddressSpace *as, dma_addr_t addr, -- void *buf, dma_addr_t len) -+ void *buf, dma_addr_t len, -+ MemTxAttrs attrs) - { - return dma_memory_rw(as, addr, buf, len, -- DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED); -+ DMA_DIRECTION_TO_DEVICE, attrs); - } - - /** -@@ -162,12 +164,14 @@ static inline MemTxResult dma_memory_read(AddressSpace *as, dma_addr_t addr, - * @addr: address within that address space - * @buf: buffer with the data transferred - * @len: the number of bytes to write -+ * @attrs: memory transaction attributes - */ - static inline MemTxResult dma_memory_write(AddressSpace *as, dma_addr_t addr, -- const void *buf, dma_addr_t len) -+ const void *buf, dma_addr_t len, -+ MemTxAttrs attrs) - { - return dma_memory_rw(as, addr, (void *)buf, len, -- DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED); -+ DMA_DIRECTION_FROM_DEVICE, attrs); - } - - /** -@@ -239,7 +243,7 @@ static inline void dma_memory_unmap(AddressSpace *as, - dma_addr_t addr) \ - { \ - uint##_bits##_t val; \ -- dma_memory_read(as, addr, &val, (_bits) / 8); \ -+ dma_memory_read(as, addr, &val, (_bits) / 8, MEMTXATTRS_UNSPECIFIED); \ - return _end##_bits##_to_cpu(val); \ - } \ - static inline void st##_sname##_##_end##_dma(AddressSpace *as, \ -@@ -247,20 +251,20 @@ static inline void dma_memory_unmap(AddressSpace *as, - uint##_bits##_t val) \ - { \ - val = cpu_to_##_end##_bits(val); \ -- dma_memory_write(as, addr, &val, (_bits) / 8); \ -+ dma_memory_write(as, addr, &val, (_bits) / 8, MEMTXATTRS_UNSPECIFIED); \ - } - - static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr) - { - uint8_t val; - -- dma_memory_read(as, addr, &val, 1); -+ dma_memory_read(as, addr, &val, 1, MEMTXATTRS_UNSPECIFIED); - return val; - } - - static inline void stb_dma(AddressSpace *as, dma_addr_t addr, uint8_t val) - { -- dma_memory_write(as, addr, &val, 1); -+ dma_memory_write(as, addr, &val, 1, MEMTXATTRS_UNSPECIFIED); - } - - DEFINE_LDST_DMA(uw, w, 16, le); --- -2.27.0 - diff --git a/dma-Let-dma_memory_rw-take-MemTxAttrs-argument.patch b/dma-Let-dma_memory_rw-take-MemTxAttrs-argument.patch deleted file mode 100644 index 10952641b716a148d50b8dbc4a3d207d0426214f..0000000000000000000000000000000000000000 --- a/dma-Let-dma_memory_rw-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,154 +0,0 @@ -From a3bdca7d4684ecb0b785f14020e68b4ba80831b0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 3 Sep 2020 09:37:43 +0200 -Subject: [PATCH 05/25] dma: Let dma_memory_rw() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling -dma_memory_rw(). - -Reviewed-by: Richard Henderson -Reviewed-by: Li Qiang -Reviewed-by: Edgar E. Iglesias -Signed-off-by: Philippe Mathieu-Daudé -Acked-by: Stefan Hajnoczi -Message-Id: <20211223115554.3155328-5-philmd@redhat.com> ---- - hw/intc/spapr_xive.c | 3 ++- - hw/usb/hcd-ohci.c | 10 ++++++---- - include/hw/pci/pci.h | 3 ++- - include/sysemu/dma.h | 11 ++++++----- - softmmu/dma-helpers.c | 3 ++- - 5 files changed, 18 insertions(+), 12 deletions(-) - -diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c -index 4ec659b93e..eae95c716f 100644 ---- a/hw/intc/spapr_xive.c -+++ b/hw/intc/spapr_xive.c -@@ -1684,7 +1684,8 @@ static target_ulong h_int_esb(PowerPCCPU *cpu, - mmio_addr = xive->vc_base + xive_source_esb_mgmt(xsrc, lisn) + offset; - - if (dma_memory_rw(&address_space_memory, mmio_addr, &data, 8, -- (flags & SPAPR_XIVE_ESB_STORE))) { -+ (flags & SPAPR_XIVE_ESB_STORE), -+ MEMTXATTRS_UNSPECIFIED)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to access ESB @0x%" - HWADDR_PRIx "\n", mmio_addr); - return H_HARDWARE; -diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c -index 1cf2816772..56e2315c73 100644 ---- a/hw/usb/hcd-ohci.c -+++ b/hw/usb/hcd-ohci.c -@@ -586,7 +586,8 @@ static int ohci_copy_td(OHCIState *ohci, struct ohci_td *td, - if (n > len) - n = len; - -- if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir)) { -+ if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, -+ n, dir, MEMTXATTRS_UNSPECIFIED)) { - return -1; - } - if (n == len) { -@@ -595,7 +596,7 @@ static int ohci_copy_td(OHCIState *ohci, struct ohci_td *td, - ptr = td->be & ~0xfffu; - buf += n; - if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, -- len - n, dir)) { -+ len - n, dir, MEMTXATTRS_UNSPECIFIED)) { - return -1; - } - return 0; -@@ -613,7 +614,8 @@ static int ohci_copy_iso_td(OHCIState *ohci, - if (n > len) - n = len; - -- if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir)) { -+ if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, -+ n, dir, MEMTXATTRS_UNSPECIFIED)) { - return -1; - } - if (n == len) { -@@ -622,7 +624,7 @@ static int ohci_copy_iso_td(OHCIState *ohci, - ptr = end_addr & ~0xfffu; - buf += n; - if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, -- len - n, dir)) { -+ len - n, dir, MEMTXATTRS_UNSPECIFIED)) { - return -1; - } - return 0; -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index 809eb32f4a..c72d61bfd8 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -823,7 +823,8 @@ static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr, - void *buf, dma_addr_t len, - DMADirection dir) - { -- return dma_memory_rw(pci_get_address_space(dev), addr, buf, len, dir); -+ return dma_memory_rw(pci_get_address_space(dev), addr, buf, len, -+ dir, MEMTXATTRS_UNSPECIFIED); - } - - /** -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index 3be803cf3f..e8ad42226f 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -121,15 +121,15 @@ static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as, - * @buf: buffer with the data transferred - * @len: the number of bytes to read or write - * @dir: indicates the transfer direction -+ * @attrs: memory transaction attributes - */ - static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr, - void *buf, dma_addr_t len, -- DMADirection dir) -+ DMADirection dir, MemTxAttrs attrs) - { - dma_barrier(as, dir); - -- return dma_memory_rw_relaxed(as, addr, buf, len, dir, -- MEMTXATTRS_UNSPECIFIED); -+ return dma_memory_rw_relaxed(as, addr, buf, len, dir, attrs); - } - - /** -@@ -147,7 +147,8 @@ static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr, - static inline MemTxResult dma_memory_read(AddressSpace *as, dma_addr_t addr, - void *buf, dma_addr_t len) - { -- return dma_memory_rw(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE); -+ return dma_memory_rw(as, addr, buf, len, -+ DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED); - } - - /** -@@ -166,7 +167,7 @@ static inline MemTxResult dma_memory_write(AddressSpace *as, dma_addr_t addr, - const void *buf, dma_addr_t len) - { - return dma_memory_rw(as, addr, (void *)buf, len, -- DMA_DIRECTION_FROM_DEVICE); -+ DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED); - } - - /** -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index 1f07217ad4..5bf76fff6b 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -305,7 +305,8 @@ static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg, - while (len > 0) { - ScatterGatherEntry entry = sg->sg[sg_cur_index++]; - int32_t xfer = MIN(len, entry.len); -- dma_memory_rw(sg->as, entry.base, ptr, xfer, dir); -+ dma_memory_rw(sg->as, entry.base, ptr, xfer, dir, -+ MEMTXATTRS_UNSPECIFIED); - ptr += xfer; - len -= xfer; - resid -= xfer; --- -2.27.0 - diff --git a/dma-Let-dma_memory_rw_relaxed-take-MemTxAttrs-argume.patch b/dma-Let-dma_memory_rw_relaxed-take-MemTxAttrs-argume.patch deleted file mode 100644 index 4ad294345116f6589e243939706d48bca32430c3..0000000000000000000000000000000000000000 --- a/dma-Let-dma_memory_rw_relaxed-take-MemTxAttrs-argume.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 167e155f710ec769a1db9df92ad6a077bf6225a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 3 Sep 2020 09:30:10 +0200 -Subject: [PATCH 04/25] dma: Let dma_memory_rw_relaxed() take MemTxAttrs - argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We will add the MemTxAttrs argument to dma_memory_rw() in -the next commit. Since dma_memory_rw_relaxed() is only used -by dma_memory_rw(), modify it first in a separate commit to -keep the next commit easier to review. - -Reviewed-by: Richard Henderson -Reviewed-by: Li Qiang -Reviewed-by: Edgar E. Iglesias -Signed-off-by: Philippe Mathieu-Daudé -Acked-by: Stefan Hajnoczi -Message-Id: <20211223115554.3155328-4-philmd@redhat.com> ---- - include/sysemu/dma.h | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index d23516f020..3be803cf3f 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -83,9 +83,10 @@ static inline bool dma_memory_valid(AddressSpace *as, - static inline MemTxResult dma_memory_rw_relaxed(AddressSpace *as, - dma_addr_t addr, - void *buf, dma_addr_t len, -- DMADirection dir) -+ DMADirection dir, -+ MemTxAttrs attrs) - { -- return address_space_rw(as, addr, MEMTXATTRS_UNSPECIFIED, -+ return address_space_rw(as, addr, attrs, - buf, len, dir == DMA_DIRECTION_FROM_DEVICE); - } - -@@ -93,7 +94,9 @@ static inline MemTxResult dma_memory_read_relaxed(AddressSpace *as, - dma_addr_t addr, - void *buf, dma_addr_t len) - { -- return dma_memory_rw_relaxed(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE); -+ return dma_memory_rw_relaxed(as, addr, buf, len, -+ DMA_DIRECTION_TO_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - } - - static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as, -@@ -102,7 +105,8 @@ static inline MemTxResult dma_memory_write_relaxed(AddressSpace *as, - dma_addr_t len) - { - return dma_memory_rw_relaxed(as, addr, (void *)buf, len, -- DMA_DIRECTION_FROM_DEVICE); -+ DMA_DIRECTION_FROM_DEVICE, -+ MEMTXATTRS_UNSPECIFIED); - } - - /** -@@ -124,7 +128,8 @@ static inline MemTxResult dma_memory_rw(AddressSpace *as, dma_addr_t addr, - { - dma_barrier(as, dir); - -- return dma_memory_rw_relaxed(as, addr, buf, len, dir); -+ return dma_memory_rw_relaxed(as, addr, buf, len, dir, -+ MEMTXATTRS_UNSPECIFIED); - } - - /** --- -2.27.0 - diff --git a/dma-Let-dma_memory_set-take-MemTxAttrs-argument.patch b/dma-Let-dma_memory_set-take-MemTxAttrs-argument.patch deleted file mode 100644 index 5d7cc93535b828c8f9dcd66c6a931b58af4688fc..0000000000000000000000000000000000000000 --- a/dma-Let-dma_memory_set-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,94 +0,0 @@ -From ba242eb5be5fdfdccf22d2d818880ed9c89ababd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 3 Sep 2020 10:28:32 +0200 -Subject: [PATCH 03/25] dma: Let dma_memory_set() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling -dma_memory_set(). - -Reviewed-by: Richard Henderson -Reviewed-by: Li Qiang -Reviewed-by: Edgar E. Iglesias -Signed-off-by: Philippe Mathieu-Daudé -Acked-by: Stefan Hajnoczi -Message-Id: <20211223115554.3155328-3-philmd@redhat.com> ---- - hw/nvram/fw_cfg.c | 3 ++- - include/hw/ppc/spapr_vio.h | 3 ++- - include/sysemu/dma.h | 3 ++- - softmmu/dma-helpers.c | 5 ++--- - 4 files changed, 8 insertions(+), 6 deletions(-) - -diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c -index c06b30de11..f7803fe3c3 100644 ---- a/hw/nvram/fw_cfg.c -+++ b/hw/nvram/fw_cfg.c -@@ -399,7 +399,8 @@ static void fw_cfg_dma_transfer(FWCfgState *s) - * tested before. - */ - if (read) { -- if (dma_memory_set(s->dma_as, dma.address, 0, len)) { -+ if (dma_memory_set(s->dma_as, dma.address, 0, len, -+ MEMTXATTRS_UNSPECIFIED)) { - dma.control |= FW_CFG_DMA_CTL_ERROR; - } - } -diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h -index 4c45f1579f..c90e74a67d 100644 ---- a/include/hw/ppc/spapr_vio.h -+++ b/include/hw/ppc/spapr_vio.h -@@ -111,7 +111,8 @@ static inline int spapr_vio_dma_write(SpaprVioDevice *dev, uint64_t taddr, - static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr, - uint8_t c, uint32_t size) - { -- return (dma_memory_set(&dev->as, taddr, c, size) != 0) ? -+ return (dma_memory_set(&dev->as, taddr, -+ c, size, MEMTXATTRS_UNSPECIFIED) != 0) ? - H_DEST_PARM : H_SUCCESS; - } - -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index 296f3b57c9..d23516f020 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -175,9 +175,10 @@ static inline MemTxResult dma_memory_write(AddressSpace *as, dma_addr_t addr, - * @addr: address within that address space - * @c: constant byte to fill the memory - * @len: the number of bytes to fill with the constant byte -+ * @attrs: memory transaction attributes - */ - MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr, -- uint8_t c, dma_addr_t len); -+ uint8_t c, dma_addr_t len, MemTxAttrs attrs); - - /** - * address_space_map: Map a physical memory region into a host virtual address. -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index 7d766a5e89..1f07217ad4 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -19,7 +19,7 @@ - /* #define DEBUG_IOMMU */ - - MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr, -- uint8_t c, dma_addr_t len) -+ uint8_t c, dma_addr_t len, MemTxAttrs attrs) - { - dma_barrier(as, DMA_DIRECTION_FROM_DEVICE); - -@@ -31,8 +31,7 @@ MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr, - memset(fillbuf, c, FILLBUF_SIZE); - while (len > 0) { - l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE; -- error |= address_space_write(as, addr, MEMTXATTRS_UNSPECIFIED, -- fillbuf, l); -+ error |= address_space_write(as, addr, attrs, fillbuf, l); - len -= l; - addr += l; - } --- -2.27.0 - diff --git a/dma-Let-dma_memory_valid-take-MemTxAttrs-argument.patch b/dma-Let-dma_memory_valid-take-MemTxAttrs-argument.patch deleted file mode 100644 index 6b466b7048e4e56e01c68e63060816ca6d6a4c40..0000000000000000000000000000000000000000 --- a/dma-Let-dma_memory_valid-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 46e7b55f326a115f42019add488a1ca1887aa89c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 3 Sep 2020 09:28:49 +0200 -Subject: [PATCH 02/25] dma: Let dma_memory_valid() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling -dma_memory_valid(). - -Reviewed-by: Richard Henderson -Reviewed-by: Li Qiang -Reviewed-by: Edgar E. Iglesias -Signed-off-by: Philippe Mathieu-Daudé -Acked-by: Stefan Hajnoczi -Message-Id: <20211223115554.3155328-2-philmd@redhat.com> ---- - include/hw/ppc/spapr_vio.h | 2 +- - include/sysemu/dma.h | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h -index 4bea87f39c..4c45f1579f 100644 ---- a/include/hw/ppc/spapr_vio.h -+++ b/include/hw/ppc/spapr_vio.h -@@ -91,7 +91,7 @@ static inline void spapr_vio_irq_pulse(SpaprVioDevice *dev) - static inline bool spapr_vio_dma_valid(SpaprVioDevice *dev, uint64_t taddr, - uint32_t size, DMADirection dir) - { -- return dma_memory_valid(&dev->as, taddr, size, dir); -+ return dma_memory_valid(&dev->as, taddr, size, dir, MEMTXATTRS_UNSPECIFIED); - } - - static inline int spapr_vio_dma_read(SpaprVioDevice *dev, uint64_t taddr, -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index 3201e7901d..296f3b57c9 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -73,11 +73,11 @@ static inline void dma_barrier(AddressSpace *as, DMADirection dir) - * dma_memory_{read,write}() and check for errors */ - static inline bool dma_memory_valid(AddressSpace *as, - dma_addr_t addr, dma_addr_t len, -- DMADirection dir) -+ DMADirection dir, MemTxAttrs attrs) - { - return address_space_access_valid(as, addr, len, - dir == DMA_DIRECTION_FROM_DEVICE, -- MEMTXATTRS_UNSPECIFIED); -+ attrs); - } - - static inline MemTxResult dma_memory_rw_relaxed(AddressSpace *as, --- -2.27.0 - diff --git a/dma-Let-ld-_dma-propagate-MemTxResult.patch b/dma-Let-ld-_dma-propagate-MemTxResult.patch deleted file mode 100644 index baee5efe1157c72ae4bef43ff999613f3fd22d2a..0000000000000000000000000000000000000000 --- a/dma-Let-ld-_dma-propagate-MemTxResult.patch +++ /dev/null @@ -1,171 +0,0 @@ -From e52e5e44ca9afd06639cc166b60cc8fbdb081593 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 22:31:11 +0100 -Subject: [PATCH 18/25] dma: Let ld*_dma() propagate MemTxResult -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -dma_memory_read() returns a MemTxResult type. Do not discard -it, return it to the caller. - -Update the few callers. - -Reviewed-by: Richard Henderson -Reviewed-by: Cédric Le Goater -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-19-philmd@redhat.com> ---- - hw/intc/pnv_xive.c | 8 ++++---- - hw/usb/hcd-xhci.c | 7 ++++--- - include/hw/pci/pci.h | 6 ++++-- - include/hw/ppc/spapr_vio.h | 6 +++++- - include/sysemu/dma.h | 25 ++++++++++++------------- - 5 files changed, 29 insertions(+), 23 deletions(-) - -diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c -index d9249bbc0c..bb207514f2 100644 ---- a/hw/intc/pnv_xive.c -+++ b/hw/intc/pnv_xive.c -@@ -172,7 +172,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type, - - /* Get the page size of the indirect table. */ - vsd_addr = vsd & VSD_ADDRESS_MASK; -- vsd = ldq_be_dma(&address_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED); -+ ldq_be_dma(&address_space_memory, vsd_addr, &vsd, MEMTXATTRS_UNSPECIFIED); - - if (!(vsd & VSD_ADDRESS_MASK)) { - #ifdef XIVE_DEBUG -@@ -195,8 +195,8 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type, - /* Load the VSD we are looking for, if not already done */ - if (vsd_idx) { - vsd_addr = vsd_addr + vsd_idx * XIVE_VSD_SIZE; -- vsd = ldq_be_dma(&address_space_memory, vsd_addr, -- MEMTXATTRS_UNSPECIFIED); -+ ldq_be_dma(&address_space_memory, vsd_addr, &vsd, -+ MEMTXATTRS_UNSPECIFIED); - - if (!(vsd & VSD_ADDRESS_MASK)) { - #ifdef XIVE_DEBUG -@@ -543,7 +543,7 @@ static uint64_t pnv_xive_vst_per_subpage(PnvXive *xive, uint32_t type) - - /* Get the page size of the indirect table. */ - vsd_addr = vsd & VSD_ADDRESS_MASK; -- vsd = ldq_be_dma(&address_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED); -+ ldq_be_dma(&address_space_memory, vsd_addr, &vsd, MEMTXATTRS_UNSPECIFIED); - - if (!(vsd & VSD_ADDRESS_MASK)) { - #ifdef XIVE_DEBUG -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 1f7b796ce3..30c477f36e 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -2063,7 +2063,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, - assert(slotid >= 1 && slotid <= xhci->numslots); - - dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); -- poctx = ldq_le_dma(xhci->as, dcbaap + 8 * slotid, MEMTXATTRS_UNSPECIFIED); -+ ldq_le_dma(xhci->as, dcbaap + 8 * slotid, &poctx, MEMTXATTRS_UNSPECIFIED); - ictx = xhci_mask64(pictx); - octx = xhci_mask64(poctx); - -@@ -3433,6 +3433,7 @@ static int usb_xhci_post_load(void *opaque, int version_id) - uint32_t slot_ctx[4]; - uint32_t ep_ctx[5]; - int slotid, epid, state; -+ uint64_t addr; - - dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); - -@@ -3441,8 +3442,8 @@ static int usb_xhci_post_load(void *opaque, int version_id) - if (!slot->addressed) { - continue; - } -- slot->ctx = xhci_mask64(ldq_le_dma(xhci->as, dcbaap + 8 * slotid, -- MEMTXATTRS_UNSPECIFIED)); -+ ldq_le_dma(xhci->as, dcbaap + 8 * slotid, &addr, MEMTXATTRS_UNSPECIFIED); -+ slot->ctx = xhci_mask64(addr); - xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx)); - slot->uport = xhci_lookup_uport(xhci, slot_ctx); - if (!slot->uport) { -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index b287b3a19f..71c6513641 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -869,8 +869,10 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \ - dma_addr_t addr) \ - { \ -- return ld##_l##_dma(pci_get_address_space(dev), addr, \ -- MEMTXATTRS_UNSPECIFIED); \ -+ uint##_bits##_t val; \ -+ ld##_l##_dma(pci_get_address_space(dev), addr, &val, \ -+ MEMTXATTRS_UNSPECIFIED); \ -+ return val; \ - } \ - static inline void st##_s##_pci_dma(PCIDevice *dev, \ - dma_addr_t addr, uint##_bits##_t val) \ -diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h -index d2ec9b0637..7eae1a4847 100644 ---- a/include/hw/ppc/spapr_vio.h -+++ b/include/hw/ppc/spapr_vio.h -@@ -127,7 +127,11 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr, - #define vio_stq(_dev, _addr, _val) \ - (stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED)) - #define vio_ldq(_dev, _addr) \ -- (ldq_be_dma(&(_dev)->as, (_addr), MEMTXATTRS_UNSPECIFIED)) -+ ({ \ -+ uint64_t _val; \ -+ ldq_be_dma(&(_dev)->as, (_addr), &_val, MEMTXATTRS_UNSPECIFIED); \ -+ _val; \ -+ }) - - int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq); - -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index 895044d747..b3faef41b2 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -240,14 +240,15 @@ static inline void dma_memory_unmap(AddressSpace *as, - } - - #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \ -- static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \ -- dma_addr_t addr, \ -- MemTxAttrs attrs) \ -- { \ -- uint##_bits##_t val; \ -- dma_memory_read(as, addr, &val, (_bits) / 8, attrs); \ -- return _end##_bits##_to_cpu(val); \ -- } \ -+ static inline MemTxResult ld##_lname##_##_end##_dma(AddressSpace *as, \ -+ dma_addr_t addr, \ -+ uint##_bits##_t *pval, \ -+ MemTxAttrs attrs) \ -+ { \ -+ MemTxResult res = dma_memory_read(as, addr, pval, (_bits) / 8, attrs); \ -+ _end##_bits##_to_cpus(pval); \ -+ return res; \ -+ } \ - static inline MemTxResult st##_sname##_##_end##_dma(AddressSpace *as, \ - dma_addr_t addr, \ - uint##_bits##_t val, \ -@@ -257,12 +258,10 @@ static inline void dma_memory_unmap(AddressSpace *as, - return dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \ - } - --static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs attrs) -+static inline MemTxResult ldub_dma(AddressSpace *as, dma_addr_t addr, -+ uint8_t *val, MemTxAttrs attrs) - { -- uint8_t val; -- -- dma_memory_read(as, addr, &val, 1, attrs); -- return val; -+ return dma_memory_read(as, addr, val, 1, attrs); - } - - static inline MemTxResult stb_dma(AddressSpace *as, dma_addr_t addr, --- -2.27.0 - diff --git a/dma-Let-ld-_dma-take-MemTxAttrs-argument.patch b/dma-Let-ld-_dma-take-MemTxAttrs-argument.patch deleted file mode 100644 index 749564c738a44fb8ac43551855b0ae15a52a56f2..0000000000000000000000000000000000000000 --- a/dma-Let-ld-_dma-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 52cca6d99c5c59d6550d3729f84ffcba50ff4ed3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 22:18:07 +0100 -Subject: [PATCH 16/25] dma: Let ld*_dma() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling ld*_dma(). - -Keep the default MEMTXATTRS_UNSPECIFIED in the few callers. - -Reviewed-by: Richard Henderson -Reviewed-by: Cédric Le Goater -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-17-philmd@redhat.com> ---- - hw/intc/pnv_xive.c | 7 ++++--- - hw/usb/hcd-xhci.c | 6 +++--- - include/hw/pci/pci.h | 3 ++- - include/hw/ppc/spapr_vio.h | 3 ++- - include/sysemu/dma.h | 11 ++++++----- - 5 files changed, 17 insertions(+), 13 deletions(-) - -diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c -index ad43483612..d9249bbc0c 100644 ---- a/hw/intc/pnv_xive.c -+++ b/hw/intc/pnv_xive.c -@@ -172,7 +172,7 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type, - - /* Get the page size of the indirect table. */ - vsd_addr = vsd & VSD_ADDRESS_MASK; -- vsd = ldq_be_dma(&address_space_memory, vsd_addr); -+ vsd = ldq_be_dma(&address_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED); - - if (!(vsd & VSD_ADDRESS_MASK)) { - #ifdef XIVE_DEBUG -@@ -195,7 +195,8 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type, - /* Load the VSD we are looking for, if not already done */ - if (vsd_idx) { - vsd_addr = vsd_addr + vsd_idx * XIVE_VSD_SIZE; -- vsd = ldq_be_dma(&address_space_memory, vsd_addr); -+ vsd = ldq_be_dma(&address_space_memory, vsd_addr, -+ MEMTXATTRS_UNSPECIFIED); - - if (!(vsd & VSD_ADDRESS_MASK)) { - #ifdef XIVE_DEBUG -@@ -542,7 +543,7 @@ static uint64_t pnv_xive_vst_per_subpage(PnvXive *xive, uint32_t type) - - /* Get the page size of the indirect table. */ - vsd_addr = vsd & VSD_ADDRESS_MASK; -- vsd = ldq_be_dma(&address_space_memory, vsd_addr); -+ vsd = ldq_be_dma(&address_space_memory, vsd_addr, MEMTXATTRS_UNSPECIFIED); - - if (!(vsd & VSD_ADDRESS_MASK)) { - #ifdef XIVE_DEBUG -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index c76091c657..1f7b796ce3 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -2063,7 +2063,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, - assert(slotid >= 1 && slotid <= xhci->numslots); - - dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); -- poctx = ldq_le_dma(xhci->as, dcbaap + 8 * slotid); -+ poctx = ldq_le_dma(xhci->as, dcbaap + 8 * slotid, MEMTXATTRS_UNSPECIFIED); - ictx = xhci_mask64(pictx); - octx = xhci_mask64(poctx); - -@@ -3441,8 +3441,8 @@ static int usb_xhci_post_load(void *opaque, int version_id) - if (!slot->addressed) { - continue; - } -- slot->ctx = -- xhci_mask64(ldq_le_dma(xhci->as, dcbaap + 8 * slotid)); -+ slot->ctx = xhci_mask64(ldq_le_dma(xhci->as, dcbaap + 8 * slotid, -+ MEMTXATTRS_UNSPECIFIED)); - xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx)); - slot->uport = xhci_lookup_uport(xhci, slot_ctx); - if (!slot->uport) { -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index 52e2ca2f2e..b287b3a19f 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -869,7 +869,8 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \ - dma_addr_t addr) \ - { \ -- return ld##_l##_dma(pci_get_address_space(dev), addr); \ -+ return ld##_l##_dma(pci_get_address_space(dev), addr, \ -+ MEMTXATTRS_UNSPECIFIED); \ - } \ - static inline void st##_s##_pci_dma(PCIDevice *dev, \ - dma_addr_t addr, uint##_bits##_t val) \ -diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h -index e87f8e6f59..d2ec9b0637 100644 ---- a/include/hw/ppc/spapr_vio.h -+++ b/include/hw/ppc/spapr_vio.h -@@ -126,7 +126,8 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr, - (stl_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED)) - #define vio_stq(_dev, _addr, _val) \ - (stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED)) --#define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr))) -+#define vio_ldq(_dev, _addr) \ -+ (ldq_be_dma(&(_dev)->as, (_addr), MEMTXATTRS_UNSPECIFIED)) - - int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq); - -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index 009dd3ca96..d1635f5587 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -241,10 +241,11 @@ static inline void dma_memory_unmap(AddressSpace *as, - - #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \ - static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \ -- dma_addr_t addr) \ -+ dma_addr_t addr, \ -+ MemTxAttrs attrs) \ - { \ - uint##_bits##_t val; \ -- dma_memory_read(as, addr, &val, (_bits) / 8, MEMTXATTRS_UNSPECIFIED); \ -+ dma_memory_read(as, addr, &val, (_bits) / 8, attrs); \ - return _end##_bits##_to_cpu(val); \ - } \ - static inline void st##_sname##_##_end##_dma(AddressSpace *as, \ -@@ -253,14 +254,14 @@ static inline void dma_memory_unmap(AddressSpace *as, - MemTxAttrs attrs) \ - { \ - val = cpu_to_##_end##_bits(val); \ -- dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \ -+ dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \ - } - --static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr) -+static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs attrs) - { - uint8_t val; - -- dma_memory_read(as, addr, &val, 1, MEMTXATTRS_UNSPECIFIED); -+ dma_memory_read(as, addr, &val, 1, attrs); - return val; - } - --- -2.27.0 - diff --git a/dma-Let-st-_dma-propagate-MemTxResult.patch b/dma-Let-st-_dma-propagate-MemTxResult.patch deleted file mode 100644 index ff45a0a90f8fdbb8cf0f6d56bba8bed5ff4c14a9..0000000000000000000000000000000000000000 --- a/dma-Let-st-_dma-propagate-MemTxResult.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 323fc6abd2b727d888acaec1788bb7b7aefa295b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 23:56:14 +0100 -Subject: [PATCH 17/25] dma: Let st*_dma() propagate MemTxResult -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -dma_memory_write() returns a MemTxResult type. Do not discard -it, return it to the caller. - -Reviewed-by: Richard Henderson -Reviewed-by: Cédric Le Goater -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-18-philmd@redhat.com> ---- - include/sysemu/dma.h | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index d1635f5587..895044d747 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -248,13 +248,13 @@ static inline void dma_memory_unmap(AddressSpace *as, - dma_memory_read(as, addr, &val, (_bits) / 8, attrs); \ - return _end##_bits##_to_cpu(val); \ - } \ -- static inline void st##_sname##_##_end##_dma(AddressSpace *as, \ -- dma_addr_t addr, \ -- uint##_bits##_t val, \ -- MemTxAttrs attrs) \ -- { \ -- val = cpu_to_##_end##_bits(val); \ -- dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \ -+ static inline MemTxResult st##_sname##_##_end##_dma(AddressSpace *as, \ -+ dma_addr_t addr, \ -+ uint##_bits##_t val, \ -+ MemTxAttrs attrs) \ -+ { \ -+ val = cpu_to_##_end##_bits(val); \ -+ return dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \ - } - - static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs attrs) -@@ -265,10 +265,10 @@ static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr, MemTxAttrs att - return val; - } - --static inline void stb_dma(AddressSpace *as, dma_addr_t addr, -- uint8_t val, MemTxAttrs attrs) -+static inline MemTxResult stb_dma(AddressSpace *as, dma_addr_t addr, -+ uint8_t val, MemTxAttrs attrs) - { -- dma_memory_write(as, addr, &val, 1, attrs); -+ return dma_memory_write(as, addr, &val, 1, attrs); - } - - DEFINE_LDST_DMA(uw, w, 16, le); --- -2.27.0 - diff --git a/dma-Let-st-_dma-take-MemTxAttrs-argument.patch b/dma-Let-st-_dma-take-MemTxAttrs-argument.patch deleted file mode 100644 index c4e021d06ab1b01ca065762322568fcb6ba0a7e2..0000000000000000000000000000000000000000 --- a/dma-Let-st-_dma-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,116 +0,0 @@ -From c9fb8525402c4a3d3e3f5c104a289fbf080fcda3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 23:53:34 +0100 -Subject: [PATCH 15/25] dma: Let st*_dma() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling st*_dma(). - -Keep the default MEMTXATTRS_UNSPECIFIED in the few callers. - -Reviewed-by: Richard Henderson -Reviewed-by: Cédric Le Goater -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-16-philmd@redhat.com> ---- - hw/nvram/fw_cfg.c | 4 ++-- - include/hw/pci/pci.h | 3 ++- - include/hw/ppc/spapr_vio.h | 12 ++++++++---- - include/sysemu/dma.h | 10 ++++++---- - 4 files changed, 18 insertions(+), 11 deletions(-) - -diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c -index 9b91b15cb0..e5f3c98184 100644 ---- a/hw/nvram/fw_cfg.c -+++ b/hw/nvram/fw_cfg.c -@@ -360,7 +360,7 @@ static void fw_cfg_dma_transfer(FWCfgState *s) - if (dma_memory_read(s->dma_as, dma_addr, - &dma, sizeof(dma), MEMTXATTRS_UNSPECIFIED)) { - stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control), -- FW_CFG_DMA_CTL_ERROR); -+ FW_CFG_DMA_CTL_ERROR, MEMTXATTRS_UNSPECIFIED); - return; - } - -@@ -446,7 +446,7 @@ static void fw_cfg_dma_transfer(FWCfgState *s) - } - - stl_be_dma(s->dma_as, dma_addr + offsetof(FWCfgDmaAccess, control), -- dma.control); -+ dma.control, MEMTXATTRS_UNSPECIFIED); - - trace_fw_cfg_read(s, 0); - } -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index c7177646a4..52e2ca2f2e 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -874,7 +874,8 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - static inline void st##_s##_pci_dma(PCIDevice *dev, \ - dma_addr_t addr, uint##_bits##_t val) \ - { \ -- st##_s##_dma(pci_get_address_space(dev), addr, val); \ -+ st##_s##_dma(pci_get_address_space(dev), addr, val, \ -+ MEMTXATTRS_UNSPECIFIED); \ - } - - PCI_DMA_DEFINE_LDST(ub, b, 8); -diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h -index 5d2ea8e665..e87f8e6f59 100644 ---- a/include/hw/ppc/spapr_vio.h -+++ b/include/hw/ppc/spapr_vio.h -@@ -118,10 +118,14 @@ static inline int spapr_vio_dma_set(SpaprVioDevice *dev, uint64_t taddr, - H_DEST_PARM : H_SUCCESS; - } - --#define vio_stb(_dev, _addr, _val) (stb_dma(&(_dev)->as, (_addr), (_val))) --#define vio_sth(_dev, _addr, _val) (stw_be_dma(&(_dev)->as, (_addr), (_val))) --#define vio_stl(_dev, _addr, _val) (stl_be_dma(&(_dev)->as, (_addr), (_val))) --#define vio_stq(_dev, _addr, _val) (stq_be_dma(&(_dev)->as, (_addr), (_val))) -+#define vio_stb(_dev, _addr, _val) \ -+ (stb_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED)) -+#define vio_sth(_dev, _addr, _val) \ -+ (stw_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED)) -+#define vio_stl(_dev, _addr, _val) \ -+ (stl_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED)) -+#define vio_stq(_dev, _addr, _val) \ -+ (stq_be_dma(&(_dev)->as, (_addr), (_val), MEMTXATTRS_UNSPECIFIED)) - #define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr))) - - int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq); -diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h -index fd8f16003d..009dd3ca96 100644 ---- a/include/sysemu/dma.h -+++ b/include/sysemu/dma.h -@@ -249,10 +249,11 @@ static inline void dma_memory_unmap(AddressSpace *as, - } \ - static inline void st##_sname##_##_end##_dma(AddressSpace *as, \ - dma_addr_t addr, \ -- uint##_bits##_t val) \ -+ uint##_bits##_t val, \ -+ MemTxAttrs attrs) \ - { \ - val = cpu_to_##_end##_bits(val); \ -- dma_memory_write(as, addr, &val, (_bits) / 8, MEMTXATTRS_UNSPECIFIED); \ -+ dma_memory_write(as, addr, &val, (_bits) / 8, attrs); \ - } - - static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr) -@@ -263,9 +264,10 @@ static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr) - return val; - } - --static inline void stb_dma(AddressSpace *as, dma_addr_t addr, uint8_t val) -+static inline void stb_dma(AddressSpace *as, dma_addr_t addr, -+ uint8_t val, MemTxAttrs attrs) - { -- dma_memory_write(as, addr, &val, 1, MEMTXATTRS_UNSPECIFIED); -+ dma_memory_write(as, addr, &val, 1, attrs); - } - - DEFINE_LDST_DMA(uw, w, 16, le); --- -2.27.0 - diff --git a/doc-Add-the-SGX-numa-description.patch b/doc-Add-the-SGX-numa-description.patch deleted file mode 100644 index 92889422e538fc278e887567332d62914df8f3ed..0000000000000000000000000000000000000000 --- a/doc-Add-the-SGX-numa-description.patch +++ /dev/null @@ -1,81 +0,0 @@ -From adba5254ecbd9eace360d8eb3d5c635d3acd8d71 Mon Sep 17 00:00:00 2001 -From: Yang Zhong -Date: Mon, 1 Nov 2021 12:20:08 -0400 -Subject: [PATCH 3/9] doc: Add the SGX numa description - -mainline inclusion -from mainline-v7.0.0-rc0 -commit d1889b36098c79e2e6ac90faf3d0dc5ec0057677 -category: feature -feature: NUMA support for SGX EPC sections -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5K27A - -Intel-SIG: commit d1889b36098c ("doc: Add the SGX numa description") - -------------------------------------- - -doc: Add the SGX numa description - -Add the SGX numa reference command and how to check if -SGX numa is support or not with multiple EPC sections. - -Signed-off-by: Yang Zhong -Message-Id: <20211101162009.62161-5-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - docs/system/i386/sgx.rst | 31 +++++++++++++++++++++++++++---- - 1 file changed, 27 insertions(+), 4 deletions(-) - -diff --git a/docs/system/i386/sgx.rst b/docs/system/i386/sgx.rst -index f8fade5ac2..0f0a73f758 100644 ---- a/docs/system/i386/sgx.rst -+++ b/docs/system/i386/sgx.rst -@@ -141,8 +141,7 @@ To launch a SGX guest: - |qemu_system_x86| \\ - -cpu host,+sgx-provisionkey \\ - -object memory-backend-epc,id=mem1,size=64M,prealloc=on \\ -- -object memory-backend-epc,id=mem2,size=28M \\ -- -M sgx-epc.0.memdev=mem1,sgx-epc.1.memdev=mem2 -+ -M sgx-epc.0.memdev=mem1,sgx-epc.0.node=0 - - Utilizing SGX in the guest requires a kernel/OS with SGX support. - The support can be determined in guest by:: -@@ -152,8 +151,32 @@ The support can be determined in guest by:: - and SGX epc info by:: - - $ dmesg | grep sgx -- [ 1.242142] sgx: EPC section 0x180000000-0x181bfffff -- [ 1.242319] sgx: EPC section 0x181c00000-0x1837fffff -+ [ 0.182807] sgx: EPC section 0x140000000-0x143ffffff -+ [ 0.183695] sgx: [Firmware Bug]: Unable to map EPC section to online node. Fallback to the NUMA node 0. -+ -+To launch a SGX numa guest: -+ -+.. parsed-literal:: -+ -+ |qemu_system_x86| \\ -+ -cpu host,+sgx-provisionkey \\ -+ -object memory-backend-ram,size=2G,host-nodes=0,policy=bind,id=node0 \\ -+ -object memory-backend-epc,id=mem0,size=64M,prealloc=on,host-nodes=0,policy=bind \\ -+ -numa node,nodeid=0,cpus=0-1,memdev=node0 \\ -+ -object memory-backend-ram,size=2G,host-nodes=1,policy=bind,id=node1 \\ -+ -object memory-backend-epc,id=mem1,size=28M,prealloc=on,host-nodes=1,policy=bind \\ -+ -numa node,nodeid=1,cpus=2-3,memdev=node1 \\ -+ -M sgx-epc.0.memdev=mem0,sgx-epc.0.node=0,sgx-epc.1.memdev=mem1,sgx-epc.1.node=1 -+ -+and SGX epc numa info by:: -+ -+ $ dmesg | grep sgx -+ [ 0.369937] sgx: EPC section 0x180000000-0x183ffffff -+ [ 0.370259] sgx: EPC section 0x184000000-0x185bfffff -+ -+ $ dmesg | grep SRAT -+ [ 0.009981] ACPI: SRAT: Node 0 PXM 0 [mem 0x180000000-0x183ffffff] -+ [ 0.009982] ACPI: SRAT: Node 1 PXM 1 [mem 0x184000000-0x185bfffff] - - References - ---------- --- -2.27.0 - diff --git a/doc-Update-multi-thread-compression-doc.patch b/doc-Update-multi-thread-compression-doc.patch deleted file mode 100644 index d020d23bb07bd6ec16f5e6470b760c72b33f6275..0000000000000000000000000000000000000000 --- a/doc-Update-multi-thread-compression-doc.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 213bd45d2c5337f10216c69c13f0438dd40c58d8 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Sat, 30 Jan 2021 16:36:47 +0800 -Subject: [PATCH 14/14] doc: Update multi-thread compression doc - -Modify the doc to fit the previous changes. - -Signed-off-by: Chuan Zheng -Signed-off-by: Zeyu Jin -Signed-off-by: Ying Fang ---- - docs/multi-thread-compression.txt | 31 ++++++++++++++++++------------- - 1 file changed, 18 insertions(+), 13 deletions(-) - -diff --git a/docs/multi-thread-compression.txt b/docs/multi-thread-compression.txt -index bb88c6bdf1..d429963cb0 100644 ---- a/docs/multi-thread-compression.txt -+++ b/docs/multi-thread-compression.txt -@@ -33,14 +33,15 @@ thread compression can be used to accelerate the compression process. - - The decompression speed of Zlib is at least 4 times as quick as - compression, if the source and destination CPU have equal speed, --keeping the compression thread count 4 times the decompression --thread count can avoid resource waste. -+and you choose Zlib as compression method, keeping the compression -+thread count 4 times the decompression thread count can avoid resource waste. - - Compression level can be used to control the compression speed and the --compression ratio. High compression ratio will take more time, level 0 --stands for no compression, level 1 stands for the best compression --speed, and level 9 stands for the best compression ratio. Users can --select a level number between 0 and 9. -+compression ratio. High compression ratio will take more time, -+level 1 stands for the best compression speed, and higher level means higher -+compression ration. For Zlib, users can select a level number between 0 and 9, -+where level 0 stands for no compression. For Zstd, users can select a -+level number between 1 and 22. - - - When to use the multiple thread compression in live migration -@@ -116,16 +117,19 @@ to support the multiple thread compression migration: - 2. Activate compression on the source: - {qemu} migrate_set_capability compress on - --3. Set the compression thread count on source: -+3. Set the compression method: -+ {qemu} migrate_set_parameter compress_method zstd -+ -+4. Set the compression thread count on source: - {qemu} migrate_set_parameter compress_threads 12 - --4. Set the compression level on the source: -+5. Set the compression level on the source: - {qemu} migrate_set_parameter compress_level 1 - --5. Set the decompression thread count on destination: -+6. Set the decompression thread count on destination: - {qemu} migrate_set_parameter decompress_threads 3 - --6. Start outgoing migration: -+7. Start outgoing migration: - {qemu} migrate -d tcp:destination.host:4444 - {qemu} info migrate - Capabilities: ... compress: on -@@ -136,6 +140,7 @@ The following are the default settings: - compress_threads: 8 - decompress_threads: 2 - compress_level: 1 (which means best speed) -+ compress_method: zlib - - So, only the first two steps are required to use the multiple - thread compression in migration. You can do more if the default -@@ -143,7 +148,7 @@ settings are not appropriate. - - TODO - ==== --Some faster (de)compression method such as LZ4 and Quicklz can help --to reduce the CPU consumption when doing (de)compression. If using --these faster (de)compression method, less (de)compression threads -+Comparing to Zlib, Some faster (de)compression method such as LZ4 -+and Quicklz can help to reduce the CPU consumption when doing (de)compression. -+If using these faster (de)compression method, less (de)compression threads - are needed when doing the migration. --- -2.27.0 - diff --git a/docs-Add-generic-vhost-vdpa-device-documentation.patch b/docs-Add-generic-vhost-vdpa-device-documentation.patch deleted file mode 100644 index 19572c705f06992a0c111a3c252ea9b7434dd782..0000000000000000000000000000000000000000 --- a/docs-Add-generic-vhost-vdpa-device-documentation.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 8e62b2af62ea165f6bb7dbd1128ed1542a63eb6b Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Sat, 12 Nov 2022 22:40:13 +0800 -Subject: [PATCH 6/7] docs: Add generic vhost-vdpa device documentation - -Signed-off-by: Longpeng ---- - docs/system/device-emulation.rst | 1 + - .../devices/vhost-vdpa-generic-device.rst | 46 +++++++++++++++++++ - 2 files changed, 47 insertions(+) - create mode 100644 docs/system/devices/vhost-vdpa-generic-device.rst - -diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst -index 19944f526c..ef299a2fcd 100644 ---- a/docs/system/device-emulation.rst -+++ b/docs/system/device-emulation.rst -@@ -89,3 +89,4 @@ Emulated Devices - devices/vhost-user.rst - devices/virtio-pmem.rst - devices/vhost-user-rng.rst -+ devices/vhost-vdpa-generic-device.rst -diff --git a/docs/system/devices/vhost-vdpa-generic-device.rst b/docs/system/devices/vhost-vdpa-generic-device.rst -new file mode 100644 -index 0000000000..25fbcac60e ---- /dev/null -+++ b/docs/system/devices/vhost-vdpa-generic-device.rst -@@ -0,0 +1,46 @@ -+ -+========================= -+vhost-vDPA generic device -+========================= -+ -+This document explains the usage of the vhost-vDPA generic device. -+ -+Description -+----------- -+ -+vDPA(virtio data path acceleration) device is a device that uses a datapath -+which complies with the virtio specifications with vendor specific control -+path. -+ -+QEMU provides two types of vhost-vDPA devices to enable the vDPA device, one -+is type sensitive which means QEMU needs to know the actual device type -+(e.g. net, blk, scsi) and another is called "vhost-vDPA generic device" which -+is type insensitive -+ -+The vhost-vDPA generic device builds on the vhost-vdpa subsystem and virtio -+subsystem. It is quite small, but it can support any type of virtio device. -+ -+Examples -+-------- -+ -+Prepare the vhost-vDPA backends first: -+ -+:: -+ host# ls -l /dev/vhost-vdpa-* -+ crw------- 1 root root 236, 0 Nov 2 00:49 /dev/vhost-vdpa-0 -+ -+Start QEMU with virtio-mmio bus: -+ -+:: -+ host# qemu-system \ -+ -M microvm -m 512 -smp 2 -kernel ... -initrd ... \ -+ -device vhost-vdpa-device,vhostdev=/dev/vhost-vdpa-0 \ -+ ... -+ -+Start QEMU with virtio-pci bus: -+ -+:: -+ host# qemu-system \ -+ -M pc -m 512 -smp 2 \ -+ -device vhost-vdpa-device-pci,vhostdev=/dev/vhost-vdpa-0 \ -+ ...\ --- -2.27.0 - diff --git a/docs-about-build-platforms-Refine-the-distro-support.patch b/docs-about-build-platforms-Refine-the-distro-support.patch deleted file mode 100644 index f775939d8a7669f61a887e112eeb2ec33af3bc47..0000000000000000000000000000000000000000 --- a/docs-about-build-platforms-Refine-the-distro-support.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 97db7448bb28e42fae5acb3eb556cfa03a11e0a8 Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Wed, 2 Aug 2023 00:02:08 -0700 -Subject: [PATCH] docs/about/build-platforms: Refine the distro support policy - -cherry picked from commit 270629024df1f9f4e704ce8325f958858c5cbff7 - -For long-term distributions that release a new version only very -seldom, we limit the support to five years after the initial release. -Otherwise, we might need to support distros like openSUSE 15 for -up to 7 or even more years in total due to our "two more years -after the next major release" rule, which is just way too much to -handle in a project like QEMU that only has limited human resources. - -Message-Id: <20230223193257.1068205-1-thuth@redhat.com> -Reviewed-by: Markus Armbruster -Signed-off-by: Thomas Huth - -Signed-off-by: Wanghe Xiao ---- - docs/about/build-platforms.rst | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/docs/about/build-platforms.rst b/docs/about/build-platforms.rst -index c29a4b8fe6..d893a2be1c 100644 ---- a/docs/about/build-platforms.rst -+++ b/docs/about/build-platforms.rst -@@ -67,7 +67,8 @@ Non-supported architectures may be removed in the future following the - Linux OS, macOS, FreeBSD, NetBSD, OpenBSD - ----------------------------------------- - --The project aims to support the most recent major version at all times. Support -+The project aims to support the most recent major version at all times for -+up to five years after its initial release. Support - for the previous major version will be dropped 2 years after the new major - version is released or when the vendor itself drops support, whichever comes - first. In this context, third-party efforts to extend the lifetime of a distro --- -2.41.0.windows.1 - diff --git a/dsoundaudio-fix-crackling-audio-recordings.patch b/dsoundaudio-fix-crackling-audio-recordings.patch deleted file mode 100644 index a697ca842861bd82642cbb6b058528f124b47ea8..0000000000000000000000000000000000000000 --- a/dsoundaudio-fix-crackling-audio-recordings.patch +++ /dev/null @@ -1,62 +0,0 @@ -From b1985a8f51ce0496aa4e8802c42a64b90f1f891d Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 21 Mar 2023 02:50:07 +0000 -Subject: [PATCH] dsoundaudio: fix crackling audio recordings mainline - inclusion commit 9d90ceb27461d7d0d172fd941b812d511794a6c6 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -Audio recordings with the DirectSound backend don't sound right. -A look a the Microsoft online documentation tells us why. - -From the DirectSound Programming Guide, Capture Buffer Information: -'You can safely copy data from the buffer only up to the read -cursor.' - -Change the code to read up to the read cursor instead of the -capture cursor. - -Signed-off-by: Volker Rümelin -Message-Id: <20211226154017.6067-2-vr_qemu@t-online.de> -Signed-off-by: Gerd Hoffmann - -Signed-off-by: tangbinzy ---- - audio/dsoundaudio.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c -index cfc79c129e..3dd2c4d4a6 100644 ---- a/audio/dsoundaudio.c -+++ b/audio/dsoundaudio.c -@@ -536,13 +536,12 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size) - DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; - LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer; - HRESULT hr; -- DWORD cpos, rpos, act_size; -+ DWORD rpos, act_size; - size_t req_size; - int err; - void *ret; - -- hr = IDirectSoundCaptureBuffer_GetCurrentPosition( -- dscb, &cpos, ds->first_time ? &rpos : NULL); -+ hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, NULL, &rpos); - if (FAILED(hr)) { - dsound_logerr(hr, "Could not get capture buffer position\n"); - *size = 0; -@@ -554,7 +553,7 @@ static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size) - ds->first_time = false; - } - -- req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul); -+ req_size = audio_ring_dist(rpos, hw->pos_emul, hw->size_emul); - req_size = MIN(*size, MIN(req_size, hw->size_emul - hw->pos_emul)); - - if (req_size == 0) { --- -2.27.0 - diff --git a/e1000-set-RX-descriptor-status-in-a-separate-operati.patch b/e1000-set-RX-descriptor-status-in-a-separate-operati.patch deleted file mode 100644 index ffa0f9654e24dbee18add738aead20bf835d4adc..0000000000000000000000000000000000000000 --- a/e1000-set-RX-descriptor-status-in-a-separate-operati.patch +++ /dev/null @@ -1,89 +0,0 @@ -From dcebeb0f7acf549620faff1badf73baba04b2068 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 17 Nov 2023 10:15:09 +0000 -Subject: [PATCH] e1000: set RX descriptor status in a separate operation - mainline inclusion commit 034d00d4858161e1d4cff82d8d230bce874a04d3 category: - bugfix - ---------------------------------------------------------------- - -The code of setting RX descriptor status field maybe work fine in -previously, however with the update of glibc version, it shows two -issues when guest using dpdk receive packets: - - 1. The dpdk has a certain probability getting wrong buffer_addr - - this impact may be not obvious, such as lost a packet once in - a while - - 2. The dpdk may consume a packet twice when scan the RX desc queue - over again - - this impact will lead a infinite wait in Qemu, since the RDT - (tail pointer) be inscreased to equal to RDH by unexpected, - which regard as the RX desc queue is full - -Write a whole of RX desc with DD flag on is not quite correct, because -when the underlying implementation of memcpy using XMM registers to -copy e1000_rx_desc (when AVX or something else CPU feature is usable), -the bytes order of desc writing to memory is indeterminacy - -We can use full-scale test case to reproduce the issue-2 by -https://github.com/BASM/qemu_dpdk_e1000_test (thanks to Leonid Myravjev) - -I also write a POC test case at https://github.com/cdkey/e1000_poc -which can reproduce both of them, and easy to verify the patch effect. - -The hw watchpoint also shows that, when Qemu using XMM related instructions -writing 16 bytes e1000_rx_desc, concurrent with DPDK using movb -writing 1 byte status, the final result of writing to memory will be one -of them, if it made by Qemu which DD flag is on, DPDK will consume it -again. - -Setting DD status in a separate operation, can prevent the impact of -disorder memory writing by memcpy, also avoid unexpected data when -concurrent writing status by qemu and guest dpdk. - -Links: https://lore.kernel.org/qemu-devel/20200102110504.GG121208@stefanha-x1.localdomain/T/ - -Reported-by: Leonid Myravjev -Cc: Stefan Hajnoczi -Cc: Paolo Bonzini -Cc: Michael S. Tsirkin -Cc: qemu-stable@nongnu.org -Tested-by: Jing Zhang -Reviewed-by: Frank Lee -Signed-off-by: Ding Hui -Signed-off-by: Jason Wang - -Signed-off-by: tangbinzy ---- - hw/net/e1000.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/hw/net/e1000.c b/hw/net/e1000.c -index f5bc81296d..e26e0a64c1 100644 ---- a/hw/net/e1000.c -+++ b/hw/net/e1000.c -@@ -979,7 +979,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) - base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH]; - pci_dma_read(d, base, &desc, sizeof(desc)); - desc.special = vlan_special; -- desc.status |= (vlan_status | E1000_RXD_STAT_DD); -+ desc.status &= ~E1000_RXD_STAT_DD; - if (desc.buffer_addr) { - if (desc_offset < size) { - size_t iov_copy; -@@ -1013,6 +1013,9 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) - DBGOUT(RX, "Null RX descriptor!!\n"); - } - pci_dma_write(d, base, &desc, sizeof(desc)); -+ desc.status |= (vlan_status | E1000_RXD_STAT_DD); -+ pci_dma_write(d, base + offsetof(struct e1000_rx_desc, status), -+ &desc.status, sizeof(desc.status)); - - if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) - s->mac_reg[RDH] = 0; --- -2.27.0 - diff --git a/exec-memory-Extract-address_space_set-from-dma_memor.patch b/exec-memory-Extract-address_space_set-from-dma_memor.patch deleted file mode 100644 index e42d70b2c6bf139a5e200a1e6dee186672691e12..0000000000000000000000000000000000000000 --- a/exec-memory-Extract-address_space_set-from-dma_memor.patch +++ /dev/null @@ -1,116 +0,0 @@ -From d9a1de34f34c853dc8596ba64b5d9c5d33c2f0cd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Sat, 15 Jan 2022 21:37:23 +0100 -Subject: [PATCH 1/5] exec/memory: Extract address_space_set() from - dma_memory_set() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -dma_memory_set() does a DMA barrier, set the address space with -a constant value. The constant value filling code is not specific -to DMA and can be used for AddressSpace. Extract it as a new -helper: address_space_set(). - -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Laurent Vivier -Reviewed-by: Stefano Garzarella -Reviewed-by: Richard Henderson -[lv: rebase] -Signed-off-by: Laurent Vivier -Reviewed-by: David Hildenbrand -Reviewed-by: Peter Xu -Message-Id: <20220115203725.3834712-2-laurent@vivier.eu> -Signed-off-by: zhangxinhao ---- - include/exec/memory.h | 16 ++++++++++++++++ - softmmu/dma-helpers.c | 15 +-------------- - softmmu/physmem.c | 19 +++++++++++++++++++ - 3 files changed, 36 insertions(+), 14 deletions(-) - -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 3e84d62e40..afa6039a9f 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -2966,6 +2966,22 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr, - } - } - -+/** -+ * address_space_set: Fill address space with a constant byte. -+ * -+ * Return a MemTxResult indicating whether the operation succeeded -+ * or failed (eg unassigned memory, device rejected the transaction, -+ * IOMMU fault). -+ * -+ * @as: #AddressSpace to be accessed -+ * @addr: address within that address space -+ * @c: constant byte to fill the memory -+ * @len: the number of bytes to fill with the constant byte -+ * @attrs: memory transaction attributes -+ */ -+MemTxResult address_space_set(AddressSpace *as, hwaddr addr, -+ uint8_t c, hwaddr len, MemTxAttrs attrs); -+ - #ifdef NEED_CPU_H - /* enum device_endian to MemOp. */ - static inline MemOp devend_memop(enum device_endian end) -diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c -index b0be156479..c2028b6585 100644 ---- a/softmmu/dma-helpers.c -+++ b/softmmu/dma-helpers.c -@@ -23,20 +23,7 @@ MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr, - { - dma_barrier(as, DMA_DIRECTION_FROM_DEVICE); - --#define FILLBUF_SIZE 512 -- uint8_t fillbuf[FILLBUF_SIZE]; -- int l; -- MemTxResult error = MEMTX_OK; -- -- memset(fillbuf, c, FILLBUF_SIZE); -- while (len > 0) { -- l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE; -- error |= address_space_write(as, addr, attrs, fillbuf, l); -- len -= l; -- addr += l; -- } -- -- return error; -+ return address_space_set(as, addr, c, len, attrs); - } - - void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint, -diff --git a/softmmu/physmem.c b/softmmu/physmem.c -index be39a49ceb..0e709ae384 100644 ---- a/softmmu/physmem.c -+++ b/softmmu/physmem.c -@@ -2983,6 +2983,25 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - } - } - -+MemTxResult address_space_set(AddressSpace *as, hwaddr addr, -+ uint8_t c, hwaddr len, MemTxAttrs attrs) -+{ -+#define FILLBUF_SIZE 512 -+ uint8_t fillbuf[FILLBUF_SIZE]; -+ int l; -+ MemTxResult error = MEMTX_OK; -+ -+ memset(fillbuf, c, FILLBUF_SIZE); -+ while (len > 0) { -+ l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE; -+ error |= address_space_write(as, addr, attrs, fillbuf, l); -+ len -= l; -+ addr += l; -+ } -+ -+ return error; -+} -+ - void cpu_physical_memory_rw(hwaddr addr, void *buf, - hwaddr len, bool is_write) - { --- -2.27.0 - diff --git a/feature-Add-log-for-each-modules.patch b/feature-Add-log-for-each-modules.patch deleted file mode 100644 index 62d2f1ad4960d4eca4d464d88a7d5c3b894a59e6..0000000000000000000000000000000000000000 --- a/feature-Add-log-for-each-modules.patch +++ /dev/null @@ -1,262 +0,0 @@ -From 1a0b974a0aaff667a76972403c28c66416c2947b Mon Sep 17 00:00:00 2001 -From: "wangxinxin.wang@huawei.com" -Date: Tue, 27 Jun 2017 17:42:23 +0800 -Subject: [PATCH 2/3] feature: Add log for each modules - -add log for each modules. - -Signed-off-by: miaoyubo -Signed-off-by: Jingyi Wang ---- - accel/kvm/kvm-all.c | 5 ++++- - hw/char/virtio-serial-bus.c | 5 +++++ - hw/pci/pci.c | 1 + - hw/usb/bus.c | 6 ++++++ - hw/usb/host-libusb.c | 5 +++++ - hw/virtio/virtio-scsi-pci.c | 3 +++ - monitor/monitor.c | 1 + - monitor/qmp-cmds.c | 3 +++ - os-posix.c | 1 + - qapi/qmp-dispatch.c | 15 +++++++++++++++ - softmmu/qdev-monitor.c | 5 +++++ - 11 files changed, 49 insertions(+), 1 deletion(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index b128d311c2..8a98446b7c 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -1751,7 +1751,10 @@ void kvm_irqchip_commit_routes(KVMState *s) - s->irq_routes->flags = 0; - trace_kvm_irqchip_commit_routes(); - ret = kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s->irq_routes); -- assert(ret == 0); -+ if (ret < 0) { -+ error_report("Set GSI routing failed: %m"); -+ abort(); -+ } - } - - static void kvm_add_routing_entry(KVMState *s, -diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c -index f01ec2137c..edb7a44ee9 100644 ---- a/hw/char/virtio-serial-bus.c -+++ b/hw/char/virtio-serial-bus.c -@@ -257,6 +257,8 @@ static size_t send_control_event(VirtIOSerial *vser, uint32_t port_id, - virtio_stw_p(vdev, &cpkt.value, value); - - trace_virtio_serial_send_control_event(port_id, event, value); -+ qemu_log("virtio serial port %d send control message" -+ " event = %d, value = %d\n", port_id, event, value); - return send_control_msg(vser, &cpkt, sizeof(cpkt)); - } - -@@ -364,6 +366,9 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) - cpkt.value = virtio_lduw_p(vdev, &gcpkt->value); - - trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value); -+ qemu_log("virtio serial port '%u' handle control message" -+ " event = %d, value = %d\n", -+ virtio_ldl_p(vdev, &gcpkt->id), cpkt.event, cpkt.value); - - if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) { - if (!cpkt.value) { -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 850735fc46..0743dc7c42 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -2411,6 +2411,7 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, - } else { - snprintf(name, sizeof(name), "%s.rom", object_get_typename(OBJECT(pdev))); - } -+ qemu_log("add rom file: %s\n", name); - pdev->has_rom = true; - memory_region_init_rom(&pdev->rom, OBJECT(pdev), name, pdev->romsize, &error_fatal); - ptr = memory_region_get_ram_ptr(&pdev->rom); -diff --git a/hw/usb/bus.c b/hw/usb/bus.c -index 92d6ed5626..20cd9b6e6f 100644 ---- a/hw/usb/bus.c -+++ b/hw/usb/bus.c -@@ -536,6 +536,10 @@ void usb_check_attach(USBDevice *dev, Error **errp) - bus->qbus.name, port->path, portspeed); - return; - } -+ -+ qemu_log("attach usb device \"%s\" (%s speed) to VM bus \"%s\", " -+ "port \"%s\" (%s speed)\n", dev->product_desc, devspeed, -+ bus->qbus.name, port->path, portspeed); - } - - void usb_device_attach(USBDevice *dev, Error **errp) -@@ -564,6 +568,8 @@ int usb_device_detach(USBDevice *dev) - - usb_detach(port); - dev->attached = false; -+ qemu_log("detach usb device \"%s\" from VM bus \"%s\", port \"%s\"\n", -+ dev->product_desc, bus->qbus.name, port->path); - return 0; - } - -diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c -index 8f521ad586..3394b04f50 100644 ---- a/hw/usb/host-libusb.c -+++ b/hw/usb/host-libusb.c -@@ -992,6 +992,8 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd) - - rc = libusb_open(dev, &s->dh); - if (rc != 0) { -+ qemu_log("libusb open usb device bus %d, device %d failed\n", -+ bus_num, addr); - goto fail; - } - } else { -@@ -1019,6 +1021,7 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd) - - libusb_get_device_descriptor(dev, &s->ddesc); - usb_host_get_port(s->dev, s->port, sizeof(s->port)); -+ qemu_log("open a host usb device on bus %d, device %d\n", bus_num, addr); - - usb_ep_init(udev); - usb_host_ep_update(s); -@@ -1146,6 +1149,8 @@ static int usb_host_close(USBHostDevice *s) - usb_device_detach(udev); - } - -+ qemu_log("begin to reset the usb device, bus : %d, device : %d\n", -+ s->bus_num, s->addr); - usb_host_release_interfaces(s); - libusb_reset_device(s->dh); - usb_host_attach_kernel(s); -diff --git a/hw/virtio/virtio-scsi-pci.c b/hw/virtio/virtio-scsi-pci.c -index 97fab74236..498f9e2c98 100644 ---- a/hw/virtio/virtio-scsi-pci.c -+++ b/hw/virtio/virtio-scsi-pci.c -@@ -18,6 +18,7 @@ - #include "hw/qdev-properties.h" - #include "hw/virtio/virtio-scsi.h" - #include "qemu/module.h" -+#include "qemu/log.h" - #include "virtio-pci.h" - #include "qom/object.h" - -@@ -51,6 +52,8 @@ static void virtio_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) - VirtIOSCSIConf *conf = &dev->vdev.parent_obj.conf; - char *bus_name; - -+ qemu_log("virtio scsi HBA %s begin to initialize.\n", -+ !proxy->id ? "NULL" : proxy->id); - if (conf->num_queues == VIRTIO_SCSI_AUTO_NUM_QUEUES) { - conf->num_queues = - virtio_pci_optimal_num_queues(VIRTIO_SCSI_VQ_NUM_FIXED); -diff --git a/monitor/monitor.c b/monitor/monitor.c -index 621e79eb66..28206bedc4 100644 ---- a/monitor/monitor.c -+++ b/monitor/monitor.c -@@ -23,6 +23,7 @@ - */ - - #include "qemu/osdep.h" -+#include "qemu/log.h" - #include "monitor-internal.h" - #include "qapi/error.h" - #include "qapi/opts-visitor.h" -diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c -index 98868cee03..d71beace6a 100644 ---- a/monitor/qmp-cmds.c -+++ b/monitor/qmp-cmds.c -@@ -21,6 +21,7 @@ - #include "sysemu/sysemu.h" - #include "qemu/config-file.h" - #include "qemu/uuid.h" -+#include "qemu/log.h" - #include "chardev/char.h" - #include "ui/qemu-spice.h" - #include "ui/console.h" -@@ -150,8 +151,10 @@ void qmp_cont(Error **errp) - } - - if (runstate_check(RUN_STATE_INMIGRATE)) { -+ qemu_log("qmp cont is received in migration\n"); - autostart = 1; - } else { -+ qemu_log("qmp cont is received and vm is started\n"); - vm_start(); - } - } -diff --git a/os-posix.c b/os-posix.c -index ae6c9f2a5e..306c442bc8 100644 ---- a/os-posix.c -+++ b/os-posix.c -@@ -322,6 +322,7 @@ int os_mlock(void) - #ifdef HAVE_MLOCKALL - int ret = 0; - -+ qemu_log("do mlockall\n"); - ret = mlockall(MCL_CURRENT | MCL_FUTURE); - if (ret < 0) { - error_report("mlockall: %s", strerror(errno)); -diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c -index bb005594d3..392ddb097c 100644 ---- a/qapi/qmp-dispatch.c -+++ b/qapi/qmp-dispatch.c -@@ -26,6 +26,7 @@ - #include "qemu/coroutine.h" - #include "qemu/main-loop.h" - #include "qemu/log.h" -+#include "qapi/qmp/qstring.h" - - Visitor *qobject_input_visitor_new_qmp(QObject *obj) - { -@@ -221,6 +222,20 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, - - assert(!(oob && qemu_in_coroutine())); - assert(monitor_cur() == NULL); -+ -+ json = qobject_to_json(QOBJECT(args)); -+ if (json) { -+ if ((strcmp(command, "query-block-jobs") != 0) -+ && (strcmp(command, "query-migrate") != 0) -+ && (strcmp(command, "query-blockstats") != 0) -+ && (strcmp(command, "query-balloon") != 0) -+ && (strcmp(command, "set_password") != 0)) { -+ qemu_log("qmp_cmd_name: %s, arguments: %s\n", -+ command, json->str); -+ } -+ g_string_free(json, true); -+ } -+ - if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) { - monitor_set_cur(qemu_coroutine_self(), cur_mon); - cmd->fn(args, &ret, &err); -diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c -index 4a20f5dbd7..05e1d88d99 100644 ---- a/softmmu/qdev-monitor.c -+++ b/softmmu/qdev-monitor.c -@@ -636,6 +636,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, - if (path != NULL) { - bus = qbus_find(path, errp); - if (!bus) { -+ qemu_log("can not find bus for %s\n", driver); - return NULL; - } - if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) { -@@ -706,6 +707,8 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, - object_set_properties_from_keyval(&dev->parent_obj, dev->opts, from_json, - errp); - if (*errp) { -+ qemu_log("the bus %s -driver %s set property failed\n", -+ bus ? bus->name : "None", driver); - goto err_del_dev; - } - qemu_log("add qdev %s:%s success\n", driver, dev->id ? dev->id : "none"); -@@ -730,6 +733,8 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp) - - ret = qdev_device_add_from_qdict(qdict, false, errp); - if (ret) { -+ qemu_log("add qdev %s:%s success\n", qemu_opt_get(opts, "driver"), -+ qemu_opts_id(opts) ? qemu_opts_id(opts) : "none"); - qemu_opts_del(opts); - } - qobject_unref(qdict); --- -2.30.0 - diff --git a/feature-Add-logs-for-vm-start-and-destroy.patch b/feature-Add-logs-for-vm-start-and-destroy.patch deleted file mode 100644 index 0b6484d4c3f8186eb1f3863ffc34f3a46f3858bc..0000000000000000000000000000000000000000 --- a/feature-Add-logs-for-vm-start-and-destroy.patch +++ /dev/null @@ -1,157 +0,0 @@ -From afbf800fa1f5e104a5edf116db4956289990ebe1 Mon Sep 17 00:00:00 2001 -From: "wangxinxin.wang@huawei.com" -Date: Thu, 22 Jun 2017 08:30:04 +0800 -Subject: [PATCH 3/3] feature: Add logs for vm start and destroy - -Add QEMU_LOG for vm start and destroy - -Signed-off-by: miaoyubo -Signed-off-by: Jingyi Wang ---- - hw/acpi/core.c | 4 ++++ - hw/core/reset.c | 2 ++ - softmmu/main.c | 2 ++ - softmmu/runstate.c | 2 ++ - softmmu/vl.c | 6 ++++++ - 5 files changed, 16 insertions(+) - -diff --git a/hw/acpi/core.c b/hw/acpi/core.c -index 1e004d0078..eb631caa91 100644 ---- a/hw/acpi/core.c -+++ b/hw/acpi/core.c -@@ -24,6 +24,7 @@ - #include "hw/acpi/acpi.h" - #include "hw/nvram/fw_cfg.h" - #include "qemu/config-file.h" -+#include "qemu/log.h" - #include "qapi/error.h" - #include "qapi/opts-visitor.h" - #include "qapi/qapi-events-run-state.h" -@@ -560,13 +561,16 @@ static void acpi_pm1_cnt_write(ACPIREGS *ar, uint16_t val) - uint16_t sus_typ = (val >> 10) & 7; - switch (sus_typ) { - case 0: /* soft power off */ -+ qemu_log("VM will be soft power off\n"); - qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); - break; - case 1: -+ qemu_log("VM will be suspend state\n"); - qemu_system_suspend_request(); - break; - default: - if (sus_typ == ar->pm1.cnt.s4_val) { /* S4 request */ -+ qemu_log("VM will be S4 state\n"); - qapi_event_send_suspend_disk(); - qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); - } -diff --git a/hw/core/reset.c b/hw/core/reset.c -index 9c477f2bf5..e923723d38 100644 ---- a/hw/core/reset.c -+++ b/hw/core/reset.c -@@ -25,6 +25,7 @@ - - #include "qemu/osdep.h" - #include "qemu/queue.h" -+#include "qemu/log.h" - #include "sysemu/reset.h" - - /* reset/shutdown handler */ -@@ -64,6 +65,7 @@ void qemu_devices_reset(void) - { - QEMUResetEntry *re, *nre; - -+ qemu_log("reset all devices\n"); - /* reset all devices */ - QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) { - re->func(re->opaque); -diff --git a/softmmu/main.c b/softmmu/main.c -index 639c67ff48..0acb41bd30 100644 ---- a/softmmu/main.c -+++ b/softmmu/main.c -@@ -23,6 +23,7 @@ - */ - - #include "qemu/osdep.h" -+#include "qemu/log.h" - #include "qemu-common.h" - #include "sysemu/sysemu.h" - -@@ -47,6 +48,7 @@ int main(int argc, char **argv) - int main(int argc, char **argv, char **envp) - { - qemu_init(argc, argv, envp); -+ qemu_log("qemu enter main_loop\n"); - qemu_main_loop(); - qemu_cleanup(); - -diff --git a/softmmu/runstate.c b/softmmu/runstate.c -index 5736d908db..52fc3b7d6f 100644 ---- a/softmmu/runstate.c -+++ b/softmmu/runstate.c -@@ -708,9 +708,11 @@ static bool main_loop_should_exit(void) - } - if (qemu_powerdown_requested()) { - qemu_system_powerdown(); -+ qemu_log("domain is power down by outside operation\n"); - } - if (qemu_vmstop_requested(&r)) { - vm_stop(r); -+ qemu_log("domain is stopped by outside operation\n"); - } - return false; - } -diff --git a/softmmu/vl.c b/softmmu/vl.c -index d9e4c619d3..d8996f3d6e 100644 ---- a/softmmu/vl.c -+++ b/softmmu/vl.c -@@ -26,6 +26,7 @@ - #include "qemu-common.h" - #include "qemu/datadir.h" - #include "qemu/units.h" -+#include "qemu/log.h" - #include "exec/cpu-common.h" - #include "hw/qdev-properties.h" - #include "qapi/compat-policy.h" -@@ -2680,6 +2681,7 @@ static void qemu_create_cli_devices(void) - } - - /* init generic devices */ -+ qemu_log("device init start\n"); - rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE); - qemu_opts_foreach(qemu_find_opts("device"), - device_init_func, NULL, &error_fatal); -@@ -2819,6 +2821,7 @@ void qemu_init(int argc, char **argv, char **envp) - - qemu_init_subsystems(); - -+ qemu_log("qemu pid is %d, options parsing start\n", getpid()); - /* first pass of option parsing */ - optind = 1; - while (optind < argc) { -@@ -3027,6 +3030,7 @@ void qemu_init(int argc, char **argv, char **envp) - exit(0); - break; - case QEMU_OPTION_m: -+ qemu_log("memory options parse start\n"); - opts = qemu_opts_parse_noisily(qemu_find_opts("memory"), - optarg, true); - if (!opts) { -@@ -3744,6 +3748,7 @@ void qemu_init(int argc, char **argv, char **envp) - */ - - machine_class = MACHINE_GET_CLASS(current_machine); -+ qemu_log("configure accelerator %s start\n", machine_class->name); - if (!qtest_enabled() && machine_class->deprecation_reason) { - error_report("Machine type '%s' is deprecated: %s", - machine_class->name, machine_class->deprecation_reason); -@@ -3757,6 +3762,7 @@ void qemu_init(int argc, char **argv, char **envp) - - qemu_create_late_backends(); - -+ qemu_log("machine init start\n"); - /* parse features once if machine provides default cpu_type */ - current_machine->cpu_type = machine_class->default_cpu_type; - if (cpu_option) { --- -2.30.0 - diff --git a/fix-compilation-errors-of-sw64-architecture-on-x86-p.patch b/fix-compilation-errors-of-sw64-architecture-on-x86-p.patch deleted file mode 100644 index 8f2cdc1e05db186c75495d919353fb794f1c3755..0000000000000000000000000000000000000000 --- a/fix-compilation-errors-of-sw64-architecture-on-x86-p.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 58471cd8dcf8e6a66113ddf9bb4ac45c89bbd57b Mon Sep 17 00:00:00 2001 -From: lifeng 71117973 -Date: Wed, 2 Nov 2022 11:19:55 +0800 -Subject: [PATCH 1/2] fix compilation errors of sw64 architecture on x86 - platform - ---- - target/sw64/float_helper.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/target/sw64/float_helper.c b/target/sw64/float_helper.c -index ad1c3cce48..c8e0845afc 100644 ---- a/target/sw64/float_helper.c -+++ b/target/sw64/float_helper.c -@@ -653,7 +653,6 @@ void helper_ieee_input(CPUSW64State *env, uint64_t val) - { - #ifndef CONFIG_USER_ONLY - uint32_t exp = (uint32_t)(val >> 52) & 0x7ff; -- uint64_t frac = val & 0xfffffffffffffull; - - if (exp == 0x7ff) { - /* Infinity or NaN. */ --- -2.27.0 - diff --git a/fix-qemu-core-when-vhost-user-net-config-with-server.patch b/fix-qemu-core-when-vhost-user-net-config-with-server.patch deleted file mode 100644 index a5253016a612d1faf009a6245a1288e7ec659817..0000000000000000000000000000000000000000 --- a/fix-qemu-core-when-vhost-user-net-config-with-server.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 228609b7d942639a1ac8a9ba2816b6bb7cbc5ab8 Mon Sep 17 00:00:00 2001 -From: caojinhuahw -Date: Mon, 19 Dec 2022 12:35:50 +0000 -Subject: [PATCH 2/2] fix qemu-core when vhost-user-net config with server mode - -commit 3a223111d7 set default reconnect for vhost-user-net -device, if vhost-user-net config with server mode will -casuse the core when ovs client stop. -tcp_chr_disconnect ---> set tcp_char state disconnect -tcp_chr start reconnect ---> set tcp_char state connecting -tcp_char is listen ---> call tcp_chr_accept() -fun tcp_char_accept() set tcp_char state to connecting, but -current tcp_char state already is connecting, assert failed -in tcp_char_change_state() raise qemu core - assert(s->state == TCP_CHARDEV_STATE_DISCONNECTED) - -this commit check tcp_char mode, if tcp_char config with server -mode, dont set reconnect time for tcp_chr. - -fix: 3a223111d7 vhost-user: Add support reconnect vhost-user socket - -Signed-off-by: caojinhuahw ---- - chardev/char-socket.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/chardev/char-socket.c b/chardev/char-socket.c -index b1e9f43ec6..57ae53304a 100644 ---- a/chardev/char-socket.c -+++ b/chardev/char-socket.c -@@ -403,6 +403,12 @@ static void tcp_chr_set_reconnect_time(Chardev *chr, - void qemu_chr_set_reconnect_time(Chardev *chr, int64_t reconnect_time) - { - ChardevClass *cc = CHARDEV_GET_CLASS(chr); -+ SocketChardev *s = SOCKET_CHARDEV(chr); -+ -+ /* if sock dev is listen, dont set reconnect time */ -+ if (s->is_listen) { -+ return; -+ } - - if (cc->chr_set_reconnect_time) { - cc->chr_set_reconnect_time(chr, reconnect_time); --- -2.27.0 - diff --git a/fix-qmp-command-migrate-set-parameters.patch b/fix-qmp-command-migrate-set-parameters.patch deleted file mode 100644 index ab7fb31af146319002d90ab407b35c099e4647e9..0000000000000000000000000000000000000000 --- a/fix-qmp-command-migrate-set-parameters.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 05526b64c8201bb7395927a81ceef3723c1ce57e Mon Sep 17 00:00:00 2001 -From: mayunlong -Date: Fri, 23 Dec 2022 10:43:46 +0800 -Subject: [PATCH] fix qmp command migrate-set-parameters - -params didn't apply after excute qmp command migrate-set-parameters, -this resulted in another qmp command(query-migrate-parameters) error. - -Signed-off-by:mayunlong ---- - migration/migration.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/migration/migration.c b/migration/migration.c -index 33d5832e47..2ec116f901 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -1621,6 +1621,10 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp) - s->parameters.decompress_threads = params->decompress_threads; - } - -+ if (params->has_compress_method) { -+ s->parameters.compress_method = params->compress_method; -+ } -+ - if (params->has_throttle_trigger_threshold) { - s->parameters.throttle_trigger_threshold = params->throttle_trigger_threshold; - } --- -2.27.0 - diff --git a/fixed-the-error-that-no-bios-file-soft-link-was-crea.patch b/fixed-the-error-that-no-bios-file-soft-link-was-crea.patch deleted file mode 100644 index 4bc85c4d97a838a18ebe4f209b17d6009161c955..0000000000000000000000000000000000000000 --- a/fixed-the-error-that-no-bios-file-soft-link-was-crea.patch +++ /dev/null @@ -1,28 +0,0 @@ -From cf6be03a1f5b7595a2ecada71fa8aa30de744703 Mon Sep 17 00:00:00 2001 -From: lifeng 71117973 -Date: Wed, 2 Nov 2022 17:20:50 +0800 -Subject: [PATCH 2/2] fixed the error that no bios file soft link was created - in the build directory when compiling the sw64 architecture - ---- - configure | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/configure b/configure -index 9569d7a3d0..0ae7bcf065 100755 ---- a/configure -+++ b/configure -@@ -3861,7 +3861,9 @@ for bios_file in \ - $source_path/pc-bios/u-boot.* \ - $source_path/pc-bios/edk2-*.fd.bz2 \ - $source_path/pc-bios/palcode-* \ -- $source_path/pc-bios/qemu_vga.ndrv -+ $source_path/pc-bios/qemu_vga.ndrv \ -+ $source_path/pc-bios/core* \ -+ $source_path/pc-bios/uefi-bios-sw - - do - LINKS="$LINKS pc-bios/$(basename $bios_file)" --- -2.27.0 - diff --git a/fixup-compile-on-loongarch64-machine.patch b/fixup-compile-on-loongarch64-machine.patch deleted file mode 100644 index 1dfe04895207aef9a2da3dc3fc3d9557b4e9814c..0000000000000000000000000000000000000000 --- a/fixup-compile-on-loongarch64-machine.patch +++ /dev/null @@ -1,26 +0,0 @@ -From c952962cda3daf05323b383485d834ffc8e16f4f Mon Sep 17 00:00:00 2001 -From: lixianglai -Date: Wed, 29 Mar 2023 02:48:04 -0400 -Subject: [PATCH] fixup compile on loongarch64 machine. - -Add function kvm_arch_accel_class_init definition on loongarch64 machine. - -Signed-off-by: lixianglai ---- - target/loongarch64/kvm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/target/loongarch64/kvm.c b/target/loongarch64/kvm.c -index 2b0159bb32..21f6d5695f 100644 ---- a/target/loongarch64/kvm.c -+++ b/target/loongarch64/kvm.c -@@ -1364,3 +1364,6 @@ int kvm_arch_msi_data_to_gsi(uint32_t data) - { - abort(); - } -+void kvm_arch_accel_class_init(ObjectClass *oc) -+{ -+} --- -2.27.0 - diff --git a/freeclock-add-qmp-command-to-get-time-offset-of-vm-i.patch b/freeclock-add-qmp-command-to-get-time-offset-of-vm-i.patch deleted file mode 100644 index e16b514e4f0d8db9fe55a393ed1c9ce434228334..0000000000000000000000000000000000000000 --- a/freeclock-add-qmp-command-to-get-time-offset-of-vm-i.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 124d427a1fdae2d1eeed433093ec4ab78b81237e Mon Sep 17 00:00:00 2001 -From: "shenghualong@huawei.com" -Date: Thu, 10 Feb 2022 11:11:37 +0800 -Subject: [PATCH] freeclock: add qmp command to get time offset of vm in - seconds - -When setting the system time in VM, a RTC_CHANGE event will be reported. -However, if libvirt is restarted while the event is be reporting, the -event will be lost and we will get the old time (not the time we set in -VM) after rebooting the VM. - -We save the delta time in QEMU and add a rtc-date-diff qmp to get the -delta time so that libvirt can get the latest time in VM according to -the qmp after libvirt is restarted. - -Signed-off-by: Peng Liang -Signed-off-by: zhangxinhao ---- - include/qemu-common.h | 4 +++- - monitor/qmp-cmds.c | 5 +++++ - qapi/misc.json | 9 +++++++++ - qapi/pragma.json | 3 ++- - softmmu/rtc.c | 13 ++++++++++++- - 5 files changed, 31 insertions(+), 3 deletions(-) - -diff --git a/include/qemu-common.h b/include/qemu-common.h -index 73bcf763ed..9ed8832152 100644 ---- a/include/qemu-common.h -+++ b/include/qemu-common.h -@@ -27,7 +27,9 @@ int qemu_main(int argc, char **argv, char **envp); - #endif - - void qemu_get_timedate(struct tm *tm, int offset); --int qemu_timedate_diff(struct tm *tm); -+time_t qemu_timedate_diff(struct tm *tm); -+time_t get_rtc_date_diff(void); -+void set_rtc_date_diff(time_t diff); - - void *qemu_oom_check(void *ptr); - -diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c -index 343353e27a..98868cee03 100644 ---- a/monitor/qmp-cmds.c -+++ b/monitor/qmp-cmds.c -@@ -466,3 +466,8 @@ HumanReadableText *qmp_x_query_irq(Error **errp) - - return human_readable_text_from_str(buf); - } -+ -+int64_t qmp_query_rtc_date_diff(Error **errp) -+{ -+ return get_rtc_date_diff(); -+} -diff --git a/qapi/misc.json b/qapi/misc.json -index 358548abe1..5b6d653682 100644 ---- a/qapi/misc.json -+++ b/qapi/misc.json -@@ -527,3 +527,12 @@ - 'data': { '*option': 'str' }, - 'returns': ['CommandLineOptionInfo'], - 'allow-preconfig': true } -+ -+## -+# @query-rtc-date-diff: -+# -+# get vm's time offset -+# -+# Since: 2.8 -+## -+{ 'command': 'query-rtc-date-diff', 'returns': 'int64' } -diff --git a/qapi/pragma.json b/qapi/pragma.json -index 3bc0335d1f..b37f6de445 100644 ---- a/qapi/pragma.json -+++ b/qapi/pragma.json -@@ -26,7 +26,8 @@ - 'qom-get', - 'query-tpm-models', - 'query-tpm-types', -- 'ringbuf-read' ], -+ 'ringbuf-read', -+ 'query-rtc-date-diff' ], - # Externally visible types whose member names may use uppercase - 'member-name-exceptions': [ # visible in: - 'ACPISlotType', # query-acpi-ospm-status -diff --git a/softmmu/rtc.c b/softmmu/rtc.c -index 5632684fc9..57bb8bba7c 100644 ---- a/softmmu/rtc.c -+++ b/softmmu/rtc.c -@@ -43,6 +43,7 @@ static time_t rtc_ref_start_datetime; - static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */ - static int rtc_host_datetime_offset = -1; /* valid & used only with - RTC_BASE_DATETIME */ -+static time_t rtc_date_diff = 0; - QEMUClockType rtc_clock; - /***********************************************************/ - /* RTC reference time/date access */ -@@ -84,7 +85,7 @@ void qemu_get_timedate(struct tm *tm, int offset) - } - } - --int qemu_timedate_diff(struct tm *tm) -+time_t qemu_timedate_diff(struct tm *tm) - { - time_t seconds; - -@@ -107,6 +108,16 @@ int qemu_timedate_diff(struct tm *tm) - return seconds - qemu_ref_timedate(QEMU_CLOCK_HOST); - } - -+time_t get_rtc_date_diff(void) -+{ -+ return rtc_date_diff; -+} -+ -+void set_rtc_date_diff(time_t diff) -+{ -+ rtc_date_diff = diff; -+} -+ - static void configure_rtc_base_datetime(const char *startdate) - { - time_t rtc_start_datetime; --- -2.27.0 - diff --git a/freeclock-set-rtc_date_diff-for-X86.patch b/freeclock-set-rtc_date_diff-for-X86.patch deleted file mode 100644 index ab4e9d237bbb8c3f4e90808e45bbe6eeaa8c7f20..0000000000000000000000000000000000000000 --- a/freeclock-set-rtc_date_diff-for-X86.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 3d0846d864384be3d08a54ca6e2ce247a5cee952 Mon Sep 17 00:00:00 2001 -From: liuxiangdong -Date: Thu, 10 Feb 2022 14:25:30 +0800 -Subject: [PATCH] freeclock: set rtc_date_diff for X86 - -Set rtc_date_diff in mc146818rtc. - -Signed-off-by: liuxiangdong -Signed-off-by: zhangxinhao ---- - hw/rtc/mc146818rtc.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c -index 4fbafddb22..af1df9aaeb 100644 ---- a/hw/rtc/mc146818rtc.c -+++ b/hw/rtc/mc146818rtc.c -@@ -616,7 +616,8 @@ static void rtc_set_time(RTCState *s) - s->base_rtc = mktimegm(&tm); - s->last_update = qemu_clock_get_ns(rtc_clock); - -- qapi_event_send_rtc_change(qemu_timedate_diff(&tm)); -+ set_rtc_date_diff(qemu_timedate_diff(&tm)); -+ qapi_event_send_rtc_change(get_rtc_date_diff()); - } - - static void rtc_set_cmos(RTCState *s, const struct tm *tm) --- -2.27.0 - diff --git a/freeclock-set-rtc_date_diff-for-arm.patch b/freeclock-set-rtc_date_diff-for-arm.patch deleted file mode 100644 index 6156fe13bd9406dcc0d38d37d8005c5ea6dada45..0000000000000000000000000000000000000000 --- a/freeclock-set-rtc_date_diff-for-arm.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 1e6bae1d13302594b6e63d88e8627fa477966cf4 Mon Sep 17 00:00:00 2001 -From: "shenghualong@huawei.com" -Date: Thu, 10 Feb 2022 14:23:28 +0800 -Subject: [PATCH] freeclock: set rtc_date_diff for arm - -Set rtc_date_diff in pl031. - -Signed-off-by: Peng Liang -Signed-off-by: zhangxinhao ---- - hw/rtc/pl031.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c -index e7ced90b02..da8b061e91 100644 ---- a/hw/rtc/pl031.c -+++ b/hw/rtc/pl031.c -@@ -143,7 +143,8 @@ static void pl031_write(void * opaque, hwaddr offset, - s->tick_offset += value - pl031_get_count(s); - - qemu_get_timedate(&tm, s->tick_offset); -- qapi_event_send_rtc_change(qemu_timedate_diff(&tm)); -+ set_rtc_date_diff(qemu_timedate_diff(&tm)); -+ qapi_event_send_rtc_change(get_rtc_date_diff()); - - pl031_set_alarm(s); - break; --- -2.27.0 - diff --git a/gdb-xml-Fix-size-of-EFER-register-on-i386-architectu.patch b/gdb-xml-Fix-size-of-EFER-register-on-i386-architectu.patch deleted file mode 100644 index 129b51edac31d41d51f494a077e9e58ee8978223..0000000000000000000000000000000000000000 --- a/gdb-xml-Fix-size-of-EFER-register-on-i386-architectu.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 9fd0035ff518ab3d2d4ee2578176fb562f9eb161 Mon Sep 17 00:00:00 2001 -From: cmss_dx -Date: Wed, 23 Nov 2022 06:05:06 +0000 -Subject: [PATCH 06/29] gdb-xml: Fix size of EFER register on i386 architecture - when debugged by GDB mainline inclusion from mainline-v7.2.0-rc2 commit - 75ac231c67cdb13f0609943fab5499963858b587 category: bugfix - --------------------------------------------- - -Before this commit, there were contradictory descriptions about size of EFER -register. -Line 113 says the size is 8 bytes. -Line 129 says the size is 4 bytes. - -As a result, when GDB is debugging an OS running on QEMU, the GDB cannot -read 'g' packets correctly. This 'g' packet transmits values of each -registers of machine emulated by QEMU to GDB. QEMU, the packet sender, -assign 4 bytes for EFER in 'g' packet based on the line 113. -GDB, the packet receiver, extract 8 bytes for EFER in 'g' packet based on -the line 129. Therefore, all registers located behind EFER in 'g' packet -has been shifted 4 bytes in GDB. - -After this commit, GDB can read 'g' packets correctly. - -Signed-off-by: TaiseiIto -Message-Id: -Signed-off-by: Paolo Bonzini - -Signed-off-by: cmss_dx ---- - gdb-xml/i386-32bit.xml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb-xml/i386-32bit.xml b/gdb-xml/i386-32bit.xml -index 872fcea9c2..7a66a02b67 100644 ---- a/gdb-xml/i386-32bit.xml -+++ b/gdb-xml/i386-32bit.xml -@@ -110,7 +110,7 @@ - - - -- -+ - - - --- -2.27.0 - diff --git a/gdb-xml-fix-duplicate-register-in-arm-neon.xml.patch b/gdb-xml-fix-duplicate-register-in-arm-neon.xml.patch deleted file mode 100644 index 792af946a3d03eea07bb7333f55298b3c624c8a4..0000000000000000000000000000000000000000 --- a/gdb-xml-fix-duplicate-register-in-arm-neon.xml.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7010b0dd1b6f27b14a0c02c81944513fbd60deab Mon Sep 17 00:00:00 2001 -From: jipengfei_yewu -Date: Mon, 18 Dec 2023 09:58:38 +0000 -Subject: [PATCH] gdb-xml: fix duplicate register in arm-neon.xml -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 940bb5fa9ca9f71fcc0d06e9de9ac3ab7415d0f2 - -Signed-off-by: jipengfei_yewu -Reviewed-by: Richard Henderson -Fixes: 56aebc8916 ("Add GDB XML register description support") -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Alex Bennée -Message-Id: <20231106185112.2755262-3-alex.bennee@linaro.org> ---- - gdb-xml/arm-neon.xml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gdb-xml/arm-neon.xml b/gdb-xml/arm-neon.xml -index 9dce0a996f..d61f6b8549 100644 ---- a/gdb-xml/arm-neon.xml -+++ b/gdb-xml/arm-neon.xml -@@ -76,7 +76,7 @@ - - - -- -+ - - - --- -2.27.0 - diff --git a/gitlab-Disable-plugins-for-cross-i386-tci.patch b/gitlab-Disable-plugins-for-cross-i386-tci.patch deleted file mode 100644 index a2960a0e6646b4f2e4088e6a1d714f20ab7c3c49..0000000000000000000000000000000000000000 --- a/gitlab-Disable-plugins-for-cross-i386-tci.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d301917340f0d0196fb8e346a5d489e9be329a0a Mon Sep 17 00:00:00 2001 -From: jipengfei -Date: Fri, 30 Jun 2023 21:33:34 +0800 -Subject: [PATCH] gitlab: Disable plugins for cross-i386-tci - -There are timeouts in the cross-i386-tci job that are related to plugins. -Restrict this job to basic TCI testing. - -cheery-pick from 0cc889c8826cefa5b80110d31a62273b56aa1832 - -Signed-off-by: jipengfei_yewu -Signed-off-by: Richard Henderson -Acked-by: Thomas Huth -Message-Id: <20230629130844.151453-1-richard.henderson@linaro.org> ---- - .gitlab-ci.d/crossbuilds.yml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml -index 17d6cb3e45..d06bf5f57d 100644 ---- a/.gitlab-ci.d/crossbuilds.yml -+++ b/.gitlab-ci.d/crossbuilds.yml -@@ -65,7 +65,7 @@ cross-i386-tci: - variables: - IMAGE: fedora-i386-cross - ACCEL: tcg-interpreter -- EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user -+ EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user --disable-plugins - MAKE_CHECK_ARGS: check check-tcg - - cross-mips-system: --- -2.41.0.windows.1 - diff --git a/hmp-Improve-sync-profile-error-message.patch b/hmp-Improve-sync-profile-error-message.patch deleted file mode 100644 index 703bbe85f458193426476cdd1d7dcf13d6809ee5..0000000000000000000000000000000000000000 --- a/hmp-Improve-sync-profile-error-message.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 3860a3a40673bdbcf8f8fde9017e9e1ecbd82b36 Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Mon, 27 Nov 2023 16:09:24 +0800 -Subject: [PATCH] hmp: Improve sync-profile error message -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from 7200fb211ef306c36d5e9060263b2a4d2f6d4700 - -Improve - - (qemu) sync-profile of - Error: Invalid parameter 'of' - -to - - Error: invalid parameter 'of', expecting 'on', 'off', or 'reset' - -Signed-off-by: Markus Armbruster -Message-ID: <20231031111059.3407803-3-armbru@redhat.com> -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Dr. David Alan Gilbert ---- - monitor/hmp-cmds.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c -index 9570011232..5246c82e14 100644 ---- a/monitor/hmp-cmds.c -+++ b/monitor/hmp-cmds.c -@@ -46,7 +46,6 @@ - #include "qapi/qapi-visit-migration.h" - #include "qapi/qmp/qdict.h" - #include "qapi/qapi-visit-migration.h" --#include "qapi/qmp/qerror.h" - #include "qapi/string-input-visitor.h" - #include "qapi/string-output-visitor.h" - #include "qom/object_interfaces.h" -@@ -920,7 +919,8 @@ void hmp_sync_profile(Monitor *mon, const QDict *qdict) - } else { - Error *err = NULL; - -- error_setg(&err, QERR_INVALID_PARAMETER, op); -+ error_setg(&err, "invalid parameter '%s'," -+ " expecting 'on', 'off', or 'reset'", op); - hmp_handle_error(mon, err); - } - } --- -2.27.0 - diff --git a/host-vdpa-make-notifiers-_init-_uninit-symmetric.patch b/host-vdpa-make-notifiers-_init-_uninit-symmetric.patch deleted file mode 100644 index 5cfe9aa9455b9e6d982e5064ace7c28979c37723..0000000000000000000000000000000000000000 --- a/host-vdpa-make-notifiers-_init-_uninit-symmetric.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 8bba9208da0aa994b91d9568b58241e94b5d46fc Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 26 Jul 2023 02:21:47 +0000 -Subject: [PATCH] host-vdpa: make notifiers _init()/_uninit() symmetric - mainline inclusion commit b1f030a0a2e281193b09350c0281c0084e84bcf4 category: - bugfix - ---------------------------------------------------------------- - -vhost_vdpa_host_notifiers_init() initializes queue notifiers -for queues "dev->vq_index" to queue "dev->vq_index + dev->nvqs", -whereas vhost_vdpa_host_notifiers_uninit() uninitializes the -same notifiers for queue "0" to queue "dev->nvqs". - -This asymmetry seems buggy, fix that by using dev->vq_index -as the base for both. - -Fixes: d0416d487bd5 ("vhost-vdpa: map virtqueue notification area if possible") -Cc: jasowang@redhat.com -Signed-off-by: Laurent Vivier -Message-Id: <20220211161309.1385839-1-lvivier@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Stefano Garzarella -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin - -Signed-off-by: tangbinzy ---- - hw/virtio/vhost-vdpa.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 225c9b1730..287025ef93 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -381,15 +381,6 @@ static void vhost_vdpa_host_notifier_uninit(struct vhost_dev *dev, - } - } - --static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n) --{ -- int i; -- -- for (i = 0; i < n; i++) { -- vhost_vdpa_host_notifier_uninit(dev, i); -- } --} -- - static int vhost_vdpa_host_notifier_init(struct vhost_dev *dev, int queue_index) - { - size_t page_size = qemu_real_host_page_size; -@@ -429,6 +420,15 @@ err: - return -1; - } - -+static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n) -+{ -+ int i; -+ -+ for (i = dev->vq_index; i < dev->vq_index + n; i++) { -+ vhost_vdpa_host_notifier_uninit(dev, i); -+ } -+} -+ - static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev) - { - int i; -@@ -442,7 +442,7 @@ static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev) - return; - - err: -- vhost_vdpa_host_notifiers_uninit(dev, i); -+ vhost_vdpa_host_notifiers_uninit(dev, i - dev->vq_index); - return; - } - --- -2.41.0.windows.1 - diff --git a/hostmem-default-the-amount-of-prealloc-threads-to-sm.patch b/hostmem-default-the-amount-of-prealloc-threads-to-sm.patch deleted file mode 100644 index a37cb4d42de22761115980357769461fdb912fc7..0000000000000000000000000000000000000000 --- a/hostmem-default-the-amount-of-prealloc-threads-to-sm.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 1a1ea4307536f142aff5ea17b9dc73ffe3a35c79 Mon Sep 17 00:00:00 2001 -From: Jaroslav Jindrak -Date: Tue, 17 May 2022 14:38:58 +0200 -Subject: [PATCH 3/3] hostmem: default the amount of prealloc-threads to - smp-cpus - -Prior to the introduction of the prealloc-threads property, the amount -of threads used to preallocate memory was derived from the value of -smp-cpus passed to qemu, the amount of physical cpus of the host -and a hardcoded maximum value. When the prealloc-threads property -was introduced, it included a default of 1 in backends/hostmem.c and -a default of smp-cpus using the sugar API for the property itself. The -latter default is not used when the property is not specified on qemu's -command line, so guests that were not adjusted for this change suddenly -started to use the default of 1 thread to preallocate memory, which -resulted in observable slowdowns in guest boots for guests with large -memory (e.g. when using libvirt <8.2.0 or managing guests manually). - -This commit restores the original behavior for these cases while not -impacting guests started with the prealloc-threads property in any way. - -Fixes: 220c1fd864e9d ("hostmem: introduce "prealloc-threads" property") -Signed-off-by: Jaroslav Jindrak -Message-Id: <20220517123858.7933-1-dzejrou@gmail.com> -Signed-off-by: Paolo Bonzini ---- - backends/hostmem.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/backends/hostmem.c b/backends/hostmem.c -index 4c05862ed5..c9ddaec849 100644 ---- a/backends/hostmem.c -+++ b/backends/hostmem.c -@@ -273,7 +273,7 @@ static void host_memory_backend_init(Object *obj) - backend->merge = machine_mem_merge(machine); - backend->dump = machine_dump_guest_core(machine); - backend->reserve = true; -- backend->prealloc_threads = 1; -+ backend->prealloc_threads = machine->smp.cpus; - } - - static void host_memory_backend_post_init(Object *obj) --- -2.27.0 - diff --git a/hugepages-hugepages-files-maybe-leftover.patch b/hugepages-hugepages-files-maybe-leftover.patch deleted file mode 100644 index 611f1eace32aebf33917851b1a3833984efab124..0000000000000000000000000000000000000000 --- a/hugepages-hugepages-files-maybe-leftover.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 3cb1b0ce091998532a30793e3272925da4e6f3aa Mon Sep 17 00:00:00 2001 -From: Jiajie Li -Date: Mon, 7 Feb 2022 14:31:34 +0800 -Subject: [PATCH 1/2] hugepages: hugepages files maybe leftover - -Before qemu uses the hugepage memory directory /dev/hugepages/libvirt/qemu/xxx, -The directory may be deleted because of the destroy virtual machine. -Cause qemu to create files directly under /dev/hugepages/libvirt/qemu/. -After the file is created, the file is not cleaned up by unlink, -and when the virtual machine is destroyed, libvirt will only clean up -/dev/hugepages/libvirt/qemu/xxx directory. After creating the hugepage file, -execute unlink to clean up the file to fix the problem. - -Signed-off-by: Jinhua Cao -Signed-off-by: Jiajie Li ---- - include/qemu/mmap-alloc.h | 3 +++ - softmmu/physmem.c | 10 +++++++++- - util/mmap-alloc.c | 22 ++++++++++++++++++++++ - 3 files changed, 34 insertions(+), 1 deletion(-) - -diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h -index 90d0eee705..707202e5be 100644 ---- a/include/qemu/mmap-alloc.h -+++ b/include/qemu/mmap-alloc.h -@@ -1,6 +1,9 @@ - #ifndef QEMU_MMAP_ALLOC_H - #define QEMU_MMAP_ALLOC_H - -+#define HUGETLBFS_MAGIC 0x958458f6 -+ -+size_t qemu_fd_getfiletype(int fd); - - size_t qemu_fd_getpagesize(int fd); - -diff --git a/softmmu/physmem.c b/softmmu/physmem.c -index 3524c04c2a..3b9a61448c 100644 ---- a/softmmu/physmem.c -+++ b/softmmu/physmem.c -@@ -1496,7 +1496,14 @@ static int file_ram_open(const char *path, - /* @path names a file that doesn't exist, create it */ - fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0644); - if (fd >= 0) { -- *created = true; -+ info_report("open %s success \n", path); -+ /* if fd file type is HUGETLBFS_MAGIC, unlink it, */ -+ /* in case to prevent residue after qemu killed */ -+ if (qemu_fd_getfiletype(fd) == HUGETLBFS_MAGIC) { -+ unlink(path); -+ } else { -+ *created = true; -+ } - break; - } - } else if (errno == EISDIR) { -@@ -1515,6 +1522,7 @@ static int file_ram_open(const char *path, - - fd = mkstemp(filename); - if (fd >= 0) { -+ info_report("mkstemp %s success \n", filename); - unlink(filename); - g_free(filename); - break; -diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c -index 893d864354..4993dd5bfa 100644 ---- a/util/mmap-alloc.c -+++ b/util/mmap-alloc.c -@@ -29,6 +29,28 @@ - #include - #endif - -+size_t qemu_fd_getfiletype(int fd) -+{ -+ struct statfs fs; -+ int ret; -+ -+ if (fd != -1) { -+ do { -+ ret = fstatfs(fd, &fs); -+ } while (ret != 0 && errno == EINTR); -+ -+ if (ret != 0) { -+ fprintf(stderr, "Couldn't fstatfs() fd: %s\n", -+ strerror(errno)); -+ return -1; -+ } -+ return fs.f_type; -+ } else { -+ fprintf(stderr, "fd is invalid \n"); -+ return -1; -+ } -+} -+ - size_t qemu_fd_getpagesize(int fd) - { - #ifdef CONFIG_LINUX --- -2.27.0 - diff --git a/hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch b/hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch deleted file mode 100644 index 8d917c601aada976bd645909de6b1b370ee18262..0000000000000000000000000000000000000000 --- a/hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch +++ /dev/null @@ -1,60 +0,0 @@ -From fa15ed1690bbfd95e2df6efafcb034198e9b637a Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Tue, 16 Aug 2022 17:49:57 +0800 -Subject: [PATCH] hw/acpi: Add ospm_status hook implementation for acpi-ged - -Setup an ARM virtual machine of machine virt and execute qmp "query-acpi-ospm-status" -causes segmentation fault with following dumpstack: - #1 0x0000aaaaab64235c in qmp_query_acpi_ospm_status (errp=errp@entry=0xfffffffff030) at ../monitor/qmp-cmds.c:312 - #2 0x0000aaaaabfc4e20 in qmp_marshal_query_acpi_ospm_status (args=, ret=0xffffea4ffe90, errp=0xffffea4ffe88) at qapi/qapi-commands-acpi.c:63 - #3 0x0000aaaaabff8ba0 in do_qmp_dispatch_bh (opaque=0xffffea4ffe98) at ../qapi/qmp-dispatch.c:128 - #4 0x0000aaaaac02e594 in aio_bh_call (bh=0xffffe0004d80) at ../util/async.c:150 - #5 aio_bh_poll (ctx=ctx@entry=0xaaaaad0f6040) at ../util/async.c:178 - #6 0x0000aaaaac00bd40 in aio_dispatch (ctx=ctx@entry=0xaaaaad0f6040) at ../util/aio-posix.c:421 - #7 0x0000aaaaac02e010 in aio_ctx_dispatch (source=0xaaaaad0f6040, callback=, user_data=) at ../util/async.c:320 - #8 0x0000fffff76f6884 in g_main_context_dispatch () at /usr/lib64/libglib-2.0.so.0 - #9 0x0000aaaaac0452d4 in glib_pollfds_poll () at ../util/main-loop.c:297 - #10 os_host_main_loop_wait (timeout=0) at ../util/main-loop.c:320 - #11 main_loop_wait (nonblocking=nonblocking@entry=0) at ../util/main-loop.c:596 - #12 0x0000aaaaab5c9e50 in qemu_main_loop () at ../softmmu/runstate.c:734 - #13 0x0000aaaaab185370 in qemu_main (argc=argc@entry=47, argv=argv@entry=0xfffffffff518, envp=envp@entry=0x0) at ../softmmu/main.c:38 - #14 0x0000aaaaab16f99c in main (argc=47, argv=0xfffffffff518) at ../softmmu/main.c:47 - -Fixes: ebb62075021a ("hw/acpi: Add ACPI Generic Event Device Support") -Signed-off-by: Keqian Zhu -Reviewed-by: Igor Mammedov -Message-id: 20220816094957.31700-1-zhukeqian1@huawei.com -Signed-off-by: Peter Maydell ---- - hw/acpi/generic_event_device.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c -index 042a8ef8a5..53e9112d9f 100644 ---- a/hw/acpi/generic_event_device.c -+++ b/hw/acpi/generic_event_device.c -@@ -273,6 +273,13 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev, - } - } - -+static void acpi_ged_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) -+{ -+ AcpiGedState *s = ACPI_GED(adev); -+ -+ acpi_memory_ospm_status(&s->memhp_state, list); -+} -+ - static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) - { - AcpiGedState *s = ACPI_GED(adev); -@@ -444,6 +451,7 @@ static void acpi_ged_class_init(ObjectClass *class, void *data) - hc->unplug_request = acpi_ged_unplug_request_cb; - hc->unplug = acpi_ged_unplug_cb; - -+ adevc->ospm_status = acpi_ged_ospm_status; - adevc->send_event = acpi_ged_send_event; - } - --- -2.27.0 - diff --git a/hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch b/hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch deleted file mode 100644 index 4b48446f091a79bc91de8327878adf6252c52cfa..0000000000000000000000000000000000000000 --- a/hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 9e8ccc2a868e719233a34946106859461c057ade Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 14 Feb 2023 20:28:11 +0800 -Subject: [PATCH] hw/acpi: Support acpi-ged to report CPU's OST info - -Setup an ARM virtual machine of machine virt and execute qmp -"query-acpi-ospm-status" but can not get the CPU's OST info. - -Signed-off-by: Kunkun Jiang ---- - hw/acpi/generic_event_device.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c -index 53e9112d9f..9118681662 100644 ---- a/hw/acpi/generic_event_device.c -+++ b/hw/acpi/generic_event_device.c -@@ -278,6 +278,7 @@ static void acpi_ged_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) - AcpiGedState *s = ACPI_GED(adev); - - acpi_memory_ospm_status(&s->memhp_state, list); -+ acpi_cpu_ospm_status(&s->cpuhp_state, list); - } - - static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) --- -2.27.0 - diff --git a/hw-acpi-aml-build-Improve-scalability-of-PPTT-genera.patch b/hw-acpi-aml-build-Improve-scalability-of-PPTT-genera.patch deleted file mode 100644 index 0525989485e8ce7ea6180b3d8b933ab70dfe74ef..0000000000000000000000000000000000000000 --- a/hw-acpi-aml-build-Improve-scalability-of-PPTT-genera.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 66c935b435d90ef9c1ae4446c5edc07cbd8ba0ed Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Fri, 7 Jan 2022 16:32:29 +0800 -Subject: [PATCH 17/24] hw/acpi/aml-build: Improve scalability of PPTT - generation - -Use g_queue APIs to reduce the nested loops and code indentation -with the processor hierarchy levels increasing. Consenquently, -it's more scalable to add new topology level to build_pptt. - -No functional change intended. - -Signed-off-by: Yanan Wang -Reviewed-by: Andrew Jones -Message-id: 20220107083232.16256-4-wangyanan55@huawei.com -Signed-off-by: Peter Maydell ---- - hw/acpi/aml-build.c | 50 +++++++++++++++++++++++++++++---------------- - 1 file changed, 32 insertions(+), 18 deletions(-) - -diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c -index b3b3310df3..6aaedca2e5 100644 ---- a/hw/acpi/aml-build.c -+++ b/hw/acpi/aml-build.c -@@ -2001,7 +2001,10 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, - void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - const char *oem_id, const char *oem_table_id) - { -- int pptt_start = table_data->len; -+ GQueue *list = g_queue_new(); -+ guint pptt_start = table_data->len; -+ guint parent_offset; -+ guint length, i; - int uid = 0; - int socket; - AcpiTable table = { .sig = "PPTT", .rev = 2, -@@ -2010,9 +2013,8 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - acpi_table_begin(&table, table_data); - - for (socket = 0; socket < ms->smp.sockets; socket++) { -- uint32_t socket_offset = table_data->len - pptt_start; -- int core; -- -+ g_queue_push_tail(list, -+ GUINT_TO_POINTER(table_data->len - pptt_start)); - build_processor_hierarchy_node( - table_data, - /* -@@ -2021,35 +2023,47 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - */ - (1 << 0), - 0, socket, NULL, 0); -+ } - -- for (core = 0; core < ms->smp.cores; core++) { -- uint32_t core_offset = table_data->len - pptt_start; -- int thread; -+ length = g_queue_get_length(list); -+ for (i = 0; i < length; i++) { -+ int core; - -+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); -+ for (core = 0; core < ms->smp.cores; core++) { - if (ms->smp.threads > 1) { -+ g_queue_push_tail(list, -+ GUINT_TO_POINTER(table_data->len - pptt_start)); - build_processor_hierarchy_node( - table_data, - (0 << 0), /* not a physical package */ -- socket_offset, core, NULL, 0); -- -- for (thread = 0; thread < ms->smp.threads; thread++) { -- build_processor_hierarchy_node( -- table_data, -- (1 << 1) | /* ACPI Processor ID valid */ -- (1 << 2) | /* Processor is a Thread */ -- (1 << 3), /* Node is a Leaf */ -- core_offset, uid++, NULL, 0); -- } -+ parent_offset, core, NULL, 0); - } else { - build_processor_hierarchy_node( - table_data, - (1 << 1) | /* ACPI Processor ID valid */ - (1 << 3), /* Node is a Leaf */ -- socket_offset, uid++, NULL, 0); -+ parent_offset, uid++, NULL, 0); - } - } - } - -+ length = g_queue_get_length(list); -+ for (i = 0; i < length; i++) { -+ int thread; -+ -+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); -+ for (thread = 0; thread < ms->smp.threads; thread++) { -+ build_processor_hierarchy_node( -+ table_data, -+ (1 << 1) | /* ACPI Processor ID valid */ -+ (1 << 2) | /* Processor is a Thread */ -+ (1 << 3), /* Node is a Leaf */ -+ parent_offset, uid++, NULL, 0); -+ } -+ } -+ -+ g_queue_free(list); - acpi_table_end(linker, &table); - } - --- -2.27.0 - diff --git a/hw-acpi-aml-build-Support-cluster-level-in-PPTT-gene.patch b/hw-acpi-aml-build-Support-cluster-level-in-PPTT-gene.patch deleted file mode 100644 index 17542a05a23ab3037961b1d4e970d9b1d32efd34..0000000000000000000000000000000000000000 --- a/hw-acpi-aml-build-Support-cluster-level-in-PPTT-gene.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 9c16924ba0a77c34246b69e8b1faee219f266445 Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Fri, 7 Jan 2022 16:32:31 +0800 -Subject: [PATCH 19/24] hw/acpi/aml-build: Support cluster level in PPTT - generation - -Support CPU cluster topology level in generation of ACPI -Processor Properties Topology Table (PPTT). - -Signed-off-by: Yanan Wang -Reviewed-by: Andrew Jones -Message-id: 20220107083232.16256-6-wangyanan55@huawei.com -Signed-off-by: Peter Maydell ---- - hw/acpi/aml-build.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c -index 6aaedca2e5..bb2cad63b5 100644 ---- a/hw/acpi/aml-build.c -+++ b/hw/acpi/aml-build.c -@@ -2001,6 +2001,7 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, - void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - const char *oem_id, const char *oem_table_id) - { -+ MachineClass *mc = MACHINE_GET_CLASS(ms); - GQueue *list = g_queue_new(); - guint pptt_start = table_data->len; - guint parent_offset; -@@ -2025,6 +2026,23 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - 0, socket, NULL, 0); - } - -+ if (mc->smp_props.clusters_supported) { -+ length = g_queue_get_length(list); -+ for (i = 0; i < length; i++) { -+ int cluster; -+ -+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); -+ for (cluster = 0; cluster < ms->smp.clusters; cluster++) { -+ g_queue_push_tail(list, -+ GUINT_TO_POINTER(table_data->len - pptt_start)); -+ build_processor_hierarchy_node( -+ table_data, -+ (0 << 0), /* not a physical package */ -+ parent_offset, cluster, NULL, 0); -+ } -+ } -+ } -+ - length = g_queue_get_length(list); - for (i = 0; i < length; i++) { - int core; --- -2.27.0 - diff --git a/hw-arm-ast2600-Fix-address-mapping-of-second-SPI-con.patch b/hw-arm-ast2600-Fix-address-mapping-of-second-SPI-con.patch deleted file mode 100644 index 9935b5e9a54dc36340f77f73771a39798be3ac7b..0000000000000000000000000000000000000000 --- a/hw-arm-ast2600-Fix-address-mapping-of-second-SPI-con.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 13a37e4130fbdfcd9a5027b4339eee592ee76889 Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Mon, 4 Dec 2023 11:01:29 +0800 -Subject: [PATCH] hw/arm: ast2600: Fix address mapping of second SPI controller -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 08048cbd5e7dc0a0359ccb8c7968e4d011174801 - -Address should be 0x1E631000 and not 0x1E641000 as initially introduced. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/838 -Fixes: f25c0ae1079d ("aspeed/soc: Add AST2600 support") -Suggested-by: Troy Lee -Signed-off-by: Cédric Le Goater -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20220126083520.4135713-1-clg@kaod.org -Signed-off-by: Peter Maydell -Signed-off-by: Luo Yifan ---- - hw/arm/aspeed_ast2600.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c -index 0384357a95..d83a70300e 100644 ---- a/hw/arm/aspeed_ast2600.c -+++ b/hw/arm/aspeed_ast2600.c -@@ -27,7 +27,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = { - [ASPEED_DEV_PWM] = 0x1E610000, - [ASPEED_DEV_FMC] = 0x1E620000, - [ASPEED_DEV_SPI1] = 0x1E630000, -- [ASPEED_DEV_SPI2] = 0x1E641000, -+ [ASPEED_DEV_SPI2] = 0x1E631000, - [ASPEED_DEV_EHCI1] = 0x1E6A1000, - [ASPEED_DEV_EHCI2] = 0x1E6A3000, - [ASPEED_DEV_MII1] = 0x1E650000, --- -2.27.0 - diff --git a/hw-arm-boot-Add-manually-register-and-trigger-of-CPU.patch b/hw-arm-boot-Add-manually-register-and-trigger-of-CPU.patch deleted file mode 100644 index 0055d3b37ec334de1912824a8c78e9d81321a6cd..0000000000000000000000000000000000000000 --- a/hw-arm-boot-Add-manually-register-and-trigger-of-CPU.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 9dc22ff87eb61a8b2bcc5892961ec432986893c9 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Thu, 9 Apr 2020 09:31:22 +0800 -Subject: [PATCH] hw/arm/boot: Add manually register and trigger of CPU reset - -We need to register and trigger CPU reset manually for hotplugged -CPU. Besides, we gather CPU reset handlers of all CPUs because CPU -reset should happen before GIC reset. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/boot.c | 18 ++++++++++++++++++ - hw/core/reset.c | 25 +++++++++++++++++++++++++ - include/hw/arm/boot.h | 3 +++ - include/sysemu/reset.h | 4 ++++ - 4 files changed, 50 insertions(+) - -diff --git a/hw/arm/boot.c b/hw/arm/boot.c -index 21024f7999..3d45de1772 100644 ---- a/hw/arm/boot.c -+++ b/hw/arm/boot.c -@@ -814,6 +814,24 @@ static void do_cpu_reset(void *opaque) - } - } - -+void cpu_hotplug_register_reset(int ncpu) -+{ -+ CPUState *cpu_0 = qemu_get_cpu(0); -+ CPUState *cpu = qemu_get_cpu(ncpu); -+ QEMUResetEntry *entry = qemu_get_reset_entry(do_cpu_reset, cpu_0); -+ -+ assert(entry); -+ /* Gather the reset handlers of all CPUs */ -+ qemu_register_reset_after(entry, do_cpu_reset, cpu); -+} -+ -+void cpu_hotplug_reset_manually(int ncpu) -+{ -+ CPUState *cpu = qemu_get_cpu(ncpu); -+ -+ do_cpu_reset(cpu); -+} -+ - /** - * load_image_to_fw_cfg() - Load an image file into an fw_cfg entry identified - * by key. -diff --git a/hw/core/reset.c b/hw/core/reset.c -index e923723d38..314d332111 100644 ---- a/hw/core/reset.c -+++ b/hw/core/reset.c -@@ -48,6 +48,31 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque) - QTAILQ_INSERT_TAIL(&reset_handlers, re, entry); - } - -+QEMUResetEntry *qemu_get_reset_entry(QEMUResetHandler *func, -+ void *opaque) -+{ -+ QEMUResetEntry *re; -+ -+ QTAILQ_FOREACH(re, &reset_handlers, entry) { -+ if (re->func == func && re->opaque == opaque) { -+ return re; -+ } -+ } -+ -+ return NULL; -+} -+ -+void qemu_register_reset_after(QEMUResetEntry *entry, -+ QEMUResetHandler *func, -+ void *opaque) -+{ -+ QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry)); -+ -+ re->func = func; -+ re->opaque = opaque; -+ QTAILQ_INSERT_AFTER(&reset_handlers, entry, re, entry); -+} -+ - void qemu_unregister_reset(QEMUResetHandler *func, void *opaque) - { - QEMUResetEntry *re; -diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h -index ce2b48b88b..c3c4d3ea79 100644 ---- a/include/hw/arm/boot.h -+++ b/include/hw/arm/boot.h -@@ -119,6 +119,9 @@ struct arm_boot_info { - arm_endianness endianness; - }; - -+void cpu_hotplug_register_reset(int ncpu); -+void cpu_hotplug_reset_manually(int ncpu); -+ - /** - * arm_load_kernel - Loads memory with everything needed to boot - * -diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h -index 0b0d6d7598..f3ff26c637 100644 ---- a/include/sysemu/reset.h -+++ b/include/sysemu/reset.h -@@ -2,7 +2,11 @@ - #define QEMU_SYSEMU_RESET_H - - typedef void QEMUResetHandler(void *opaque); -+typedef struct QEMUResetEntry QEMUResetEntry; - -+QEMUResetEntry *qemu_get_reset_entry(QEMUResetHandler *func, void *opaque); -+void qemu_register_reset_after(QEMUResetEntry *entry, -+ QEMUResetHandler *func, void *opaque); - void qemu_register_reset(QEMUResetHandler *func, void *opaque); - void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); - void qemu_devices_reset(void); --- -2.27.0 - diff --git a/hw-arm-fsl-imx-Do-not-ignore-Error-argument.patch b/hw-arm-fsl-imx-Do-not-ignore-Error-argument.patch deleted file mode 100644 index 8cc37891158df31ef5a281fba9921968b07ecd59..0000000000000000000000000000000000000000 --- a/hw-arm-fsl-imx-Do-not-ignore-Error-argument.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 81c2b665d9ea6670677f35aa1ab2ad68d6e73aa4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Mon, 20 Nov 2023 12:51:15 +0100 -Subject: [PATCH] hw/arm/fsl-imx: Do not ignore Error argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mainline inclusion -commit 0cbb56c236a4a28f5149eed227d74bb737321cfc -category: bugfix - --------------------------------------------------------- - -Both i.MX25 and i.MX6 SoC models ignore the Error argument when -setting the PHY number. Pick &error_abort which is the error -used by the i.MX7 SoC (see commit 1f7197deb0 "ability to change -the FEC PHY on i.MX7 processor"). - -Fixes: 74c1330582 ("ability to change the FEC PHY on i.MX25 processor") -Fixes: a9c167a3c4 ("ability to change the FEC PHY on i.MX6 processor") -Signed-off-by: Philippe Mathieu-Daudé -Message-id: 20231120115116.76858-1-philmd@linaro.org -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell -Signed-off-by: zhujun2 ---- - hw/arm/fsl-imx25.c | 3 ++- - hw/arm/fsl-imx6.c | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c -index 24c4374590..9aabbf7f58 100644 ---- a/hw/arm/fsl-imx25.c -+++ b/hw/arm/fsl-imx25.c -@@ -169,7 +169,8 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp) - epit_table[i].irq)); - } - -- object_property_set_uint(OBJECT(&s->fec), "phy-num", s->phy_num, &err); -+ object_property_set_uint(OBJECT(&s->fec), "phy-num", s->phy_num, -+ &error_abort); - qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]); - - if (!sysbus_realize(SYS_BUS_DEVICE(&s->fec), errp)) { -diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c -index 00dafe3f62..c4b95dc7a7 100644 ---- a/hw/arm/fsl-imx6.c -+++ b/hw/arm/fsl-imx6.c -@@ -377,7 +377,8 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp) - spi_table[i].irq)); - } - -- object_property_set_uint(OBJECT(&s->eth), "phy-num", s->phy_num, &err); -+ object_property_set_uint(OBJECT(&s->eth), "phy-num", s->phy_num, -+ &error_abort); - qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]); - if (!sysbus_realize(SYS_BUS_DEVICE(&s->eth), errp)) { - return; --- -2.27.0 - diff --git a/hw-arm-smmu-common-Allow-domain-invalidation-for-NH_.patch b/hw-arm-smmu-common-Allow-domain-invalidation-for-NH_.patch deleted file mode 100644 index d92b5edd5a76cec878d9d7ddb1af9698360280b8..0000000000000000000000000000000000000000 --- a/hw-arm-smmu-common-Allow-domain-invalidation-for-NH_.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 876d18c962f0ead31d8458cd7ac19178be78455c Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Fri, 19 Mar 2021 12:22:48 -0400 -Subject: [PATCH] hw/arm/smmu-common: Allow domain invalidation for - NH_ALL/NSNH_ALL - -NH_ALL/NSNH_ALL corresponds to a domain granularity invalidation, -ie. all the notifier range gets invalidation, whatever the ASID. -So let's set the granularity to IOMMU_INV_GRAN_DOMAIN to allow -the consumer to benefit from the info if it can. - -Signed-off-by: Eric Auger -Suggested-by: chenxiang (M) -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmu-common.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c -index 3a1ecf81d6..2ec4222c93 100644 ---- a/hw/arm/smmu-common.c -+++ b/hw/arm/smmu-common.c -@@ -477,6 +477,7 @@ static void smmu_unmap_notifier_range(IOMMUNotifier *n) - event.entry.iova = n->start; - event.entry.perm = IOMMU_NONE; - event.entry.addr_mask = n->end - n->start; -+ event.entry.granularity = IOMMU_INV_GRAN_DOMAIN; - - memory_region_notify_iommu_one(n, &event); - } --- -2.27.0 - diff --git a/hw-arm-smmuv3-Advertise-MSI_TRANSLATE-attribute.patch b/hw-arm-smmuv3-Advertise-MSI_TRANSLATE-attribute.patch deleted file mode 100644 index e8d397824f80fff77c7260bfb4dcec67e410b250..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Advertise-MSI_TRANSLATE-attribute.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 5a759ab19d508361053e388694546216705d173b Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 28 Aug 2018 09:21:53 -0400 -Subject: [PATCH] hw/arm/smmuv3: Advertise MSI_TRANSLATE attribute - -The SMMUv3 has the peculiarity to translate MSI -transactionss. let's advertise the corresponding -attribute. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 9b87d16217..12f354a0d5 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -1596,6 +1596,9 @@ static int smmuv3_get_attr(IOMMUMemoryRegion *iommu, - if (attr == IOMMU_ATTR_VFIO_NESTED) { - *(bool *) data = true; - return 0; -+ } else if (attr == IOMMU_ATTR_MSI_TRANSLATE) { -+ *(bool *) data = true; -+ return 0; - } - return -EINVAL; - } --- -2.27.0 - diff --git a/hw-arm-smmuv3-Allow-MAP-notifiers.patch b/hw-arm-smmuv3-Allow-MAP-notifiers.patch deleted file mode 100644 index 1d82532d1262f420e3d4bb39f27579d85f437026..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Allow-MAP-notifiers.patch +++ /dev/null @@ -1,37 +0,0 @@ -From dc126664134989975ce9ab9e7d5d2c8916628bf6 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Wed, 18 Mar 2020 11:17:36 +0100 -Subject: [PATCH] hw/arm/smmuv3: Allow MAP notifiers - -We now have all bricks to support nested paging. This -uses MAP notifiers to map the MSIs. So let's allow MAP -notifiers to be registered. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 8 -------- - 1 file changed, 8 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 9aeb420428..45f21c53fe 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -1628,14 +1628,6 @@ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu, - return -EINVAL; - } - -- if (new & IOMMU_NOTIFIER_MAP) { -- error_setg(errp, -- "device %02x.%02x.%x requires iommu MAP notifier which is " -- "not currently supported", pci_bus_num(sdev->bus), -- PCI_SLOT(sdev->devfn), PCI_FUNC(sdev->devfn)); -- return -EINVAL; -- } -- - if (old == IOMMU_NOTIFIER_NONE) { - trace_smmuv3_notify_flag_add(iommu->parent_obj.name); - QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next); --- -2.27.0 - diff --git a/hw-arm-smmuv3-Fill-the-IOTLBEntry-arch_id-on-NH_VA-i.patch b/hw-arm-smmuv3-Fill-the-IOTLBEntry-arch_id-on-NH_VA-i.patch deleted file mode 100644 index 646a95bd19bab7b28a797433b0321edc45512657..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Fill-the-IOTLBEntry-arch_id-on-NH_VA-i.patch +++ /dev/null @@ -1,34 +0,0 @@ -From dcda615b3d9b1acffee3d31d57974cc9e4bd0dee Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 4 Sep 2018 08:48:33 -0400 -Subject: [PATCH] hw/arm/smmuv3: Fill the IOTLBEntry arch_id on NH_VA - invalidation - -When the guest invalidates one S1 entry, it passes the asid. -When propagating this invalidation downto the host, the asid -information also must be passed. So let's fill the arch_id field -introduced for that purpose and accordingly set the flags to -indicate its presence. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 3416f6a639..696c588f08 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -833,6 +833,8 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - event.entry.iova = iova; - event.entry.addr_mask = num_pages * (1 << granule) - 1; - event.entry.perm = IOMMU_NONE; -+ event.entry.flags = IOMMU_INV_FLAGS_ARCHID; -+ event.entry.arch_id = asid; - - memory_region_notify_iommu_one(n, &event); - } --- -2.27.0 - diff --git a/hw-arm-smmuv3-Fill-the-IOTLBEntry-leaf-field-on-NH_V.patch b/hw-arm-smmuv3-Fill-the-IOTLBEntry-leaf-field-on-NH_V.patch deleted file mode 100644 index f5f3db19ea9ca70944d1da3be402ce800226d08c..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Fill-the-IOTLBEntry-leaf-field-on-NH_V.patch +++ /dev/null @@ -1,77 +0,0 @@ -From c219274b7b6a472d7340a4f72a052ba33ed19659 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 14 Mar 2019 09:55:13 -0400 -Subject: [PATCH] hw/arm/smmuv3: Fill the IOTLBEntry leaf field on NH_VA - invalidation - -Let's propagate the leaf attribute throughout the invalidation path. -This hint is used to reduce the scope of the invalidations to the -last level of translation. Not enforcing it induces large performance -penalties in nested mode. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 696c588f08..ad816e850c 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -800,7 +800,7 @@ epilogue: - static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - IOMMUNotifier *n, - int asid, dma_addr_t iova, -- uint8_t tg, uint64_t num_pages) -+ uint8_t tg, uint64_t num_pages, bool leaf) - { - SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu); - IOMMUTLBEvent event = {}; -@@ -835,6 +835,7 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - event.entry.perm = IOMMU_NONE; - event.entry.flags = IOMMU_INV_FLAGS_ARCHID; - event.entry.arch_id = asid; -+ event.entry.leaf = leaf; - - memory_region_notify_iommu_one(n, &event); - } -@@ -866,7 +867,7 @@ static void smmuv3_notify_asid(IOMMUMemoryRegion *mr, - - /* invalidate an asid/iova range tuple in all mr's */ - static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova, -- uint8_t tg, uint64_t num_pages) -+ uint8_t tg, uint64_t num_pages, bool leaf) - { - SMMUDevice *sdev; - -@@ -878,7 +879,7 @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova, - tg, num_pages); - - IOMMU_NOTIFIER_FOREACH(n, mr) { -- smmuv3_notify_iova(mr, n, asid, iova, tg, num_pages); -+ smmuv3_notify_iova(mr, n, asid, iova, tg, num_pages, leaf); - } - } - } -@@ -903,7 +904,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd) - - if (!tg) { - trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, 1, ttl, leaf); -- smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1); -+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1, leaf); - smmu_iotlb_inv_iova(s, asid, addr, tg, 1, ttl); - return; - } -@@ -921,7 +922,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd) - - num_pages = (mask + 1) >> granule; - trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf); -- smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages); -+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages, leaf); - smmu_iotlb_inv_iova(s, asid, addr, tg, num_pages, ttl); - addr += mask + 1; - } --- -2.27.0 - diff --git a/hw-arm-smmuv3-Implement-fault-injection.patch b/hw-arm-smmuv3-Implement-fault-injection.patch deleted file mode 100644 index 5ecb6da751ece0b759505e47ea49e254234787ef..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Implement-fault-injection.patch +++ /dev/null @@ -1,107 +0,0 @@ -From d31c754470b4b651d0e19c66738fbcc8fc6abf3c Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 13 Sep 2018 14:24:45 +0200 -Subject: [PATCH] hw/arm/smmuv3: Implement fault injection - -We convert iommu_fault structs received from the kernel -into the data struct used by the emulation code and record -the evnts into the virtual event queue. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 71 insertions(+) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 58139f707d..9aeb420428 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -1660,6 +1660,76 @@ static int smmuv3_get_attr(IOMMUMemoryRegion *iommu, - return -EINVAL; - } - -+struct iommu_fault; -+ -+static inline int -+smmuv3_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, -+ struct iommu_fault *buf) -+{ -+#ifdef __linux__ -+ SMMUDevice *sdev = container_of(iommu_mr, SMMUDevice, iommu); -+ SMMUv3State *s3 = sdev->smmu; -+ uint32_t sid = smmu_get_sid(sdev); -+ int i; -+ -+ for (i = 0; i < count; i++) { -+ SMMUEventInfo info = {}; -+ struct iommu_fault_unrecoverable *record; -+ -+ if (buf[i].type != IOMMU_FAULT_DMA_UNRECOV) { -+ continue; -+ } -+ -+ info.sid = sid; -+ record = &buf[i].event; -+ -+ switch (record->reason) { -+ case IOMMU_FAULT_REASON_PASID_INVALID: -+ info.type = SMMU_EVT_C_BAD_SUBSTREAMID; -+ /* TODO further fill info.u.c_bad_substream */ -+ break; -+ case IOMMU_FAULT_REASON_PASID_FETCH: -+ info.type = SMMU_EVT_F_CD_FETCH; -+ break; -+ case IOMMU_FAULT_REASON_BAD_PASID_ENTRY: -+ info.type = SMMU_EVT_C_BAD_CD; -+ /* TODO further fill info.u.c_bad_cd */ -+ break; -+ case IOMMU_FAULT_REASON_WALK_EABT: -+ info.type = SMMU_EVT_F_WALK_EABT; -+ info.u.f_walk_eabt.addr = record->addr; -+ info.u.f_walk_eabt.addr2 = record->fetch_addr; -+ break; -+ case IOMMU_FAULT_REASON_PTE_FETCH: -+ info.type = SMMU_EVT_F_TRANSLATION; -+ info.u.f_translation.addr = record->addr; -+ break; -+ case IOMMU_FAULT_REASON_OOR_ADDRESS: -+ info.type = SMMU_EVT_F_ADDR_SIZE; -+ info.u.f_addr_size.addr = record->addr; -+ break; -+ case IOMMU_FAULT_REASON_ACCESS: -+ info.type = SMMU_EVT_F_ACCESS; -+ info.u.f_access.addr = record->addr; -+ break; -+ case IOMMU_FAULT_REASON_PERMISSION: -+ info.type = SMMU_EVT_F_PERMISSION; -+ info.u.f_permission.addr = record->addr; -+ break; -+ default: -+ warn_report("%s Unexpected fault reason received from host: %d", -+ __func__, record->reason); -+ continue; -+ } -+ -+ smmuv3_record_event(s3, &info); -+ } -+ return 0; -+#else -+ return -1; -+#endif -+} -+ - static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - void *data) - { -@@ -1668,6 +1738,7 @@ static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - imrc->translate = smmuv3_translate; - imrc->notify_flag_changed = smmuv3_notify_flag_changed; - imrc->get_attr = smmuv3_get_attr; -+ imrc->inject_faults = smmuv3_inject_faults; - } - - static const TypeInfo smmuv3_type_info = { --- -2.27.0 - diff --git a/hw-arm-smmuv3-Improve-stage1-ASID-invalidation.patch b/hw-arm-smmuv3-Improve-stage1-ASID-invalidation.patch deleted file mode 100644 index 505bec39045c01a65e90863f940dc28011f7b400..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Improve-stage1-ASID-invalidation.patch +++ /dev/null @@ -1,107 +0,0 @@ -From de53feaa37a267a21ed30a642e1e64c5fcfbc4a4 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Sun, 14 Feb 2021 12:30:57 -0500 -Subject: [PATCH] hw/arm/smmuv3: Improve stage1 ASID invalidation - -At the moment ASID invalidation command (CMD_TLBI_NH_ASID) is -propagated as a domain invalidation (the whole notifier range -is invalidated independently on any ASID information). - -The new granularity field now allows to be more precise and -restrict the invalidation to a peculiar ASID. Set the corresponding -fields and flag. - -We still keep the iova and addr_mask settings for consumers that -do not support the new fields, like VHOST. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- - hw/arm/trace-events | 1 + - 2 files changed, 43 insertions(+), 2 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 94e2c658f8..da5dac1ba5 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -836,6 +836,31 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - memory_region_notify_iommu_one(n, &event); - } - -+/** -+ * smmuv3_notify_asid - call the notifier @n for a given asid -+ * -+ * @mr: IOMMU mr region handle -+ * @n: notifier to be called -+ * @asid: address space ID or negative value if we don't care -+ */ -+static void smmuv3_notify_asid(IOMMUMemoryRegion *mr, -+ IOMMUNotifier *n, int asid) -+{ -+ IOMMUTLBEvent event = {}; -+ -+ event.type = IOMMU_NOTIFIER_UNMAP; -+ event.entry.target_as = &address_space_memory; -+ event.entry.perm = IOMMU_NONE; -+ event.entry.granularity = IOMMU_INV_GRAN_PASID; -+ event.entry.flags = IOMMU_INV_FLAGS_ARCHID; -+ event.entry.arch_id = asid; -+ event.entry.iova = n->start; -+ event.entry.addr_mask = n->end - n->start; -+ -+ memory_region_notify_iommu_one(n, &event); -+} -+ -+ - /* invalidate an asid/iova range tuple in all mr's */ - static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova, - uint8_t tg, uint64_t num_pages) -@@ -913,6 +938,22 @@ smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) - return true; - } - -+static void smmuv3_s1_asid_inval(SMMUState *s, uint16_t asid) -+{ -+ SMMUDevice *sdev; -+ -+ trace_smmuv3_s1_asid_inval(asid); -+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) { -+ IOMMUMemoryRegion *mr = &sdev->iommu; -+ IOMMUNotifier *n; -+ -+ IOMMU_NOTIFIER_FOREACH(n, mr) { -+ smmuv3_notify_asid(mr, n, asid); -+ } -+ } -+ smmu_iotlb_inv_asid(s, asid); -+} -+ - static int smmuv3_cmdq_consume(SMMUv3State *s) - { - SMMUState *bs = ARM_SMMU(s); -@@ -1027,8 +1068,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) - uint16_t asid = CMD_ASID(&cmd); - - trace_smmuv3_cmdq_tlbi_nh_asid(asid); -- smmu_inv_notifiers_all(&s->smmu_state); -- smmu_iotlb_inv_asid(bs, asid); -+ smmuv3_s1_asid_inval(bs, asid); - break; - } - case SMMU_CMD_TLBI_NH_ALL: -diff --git a/hw/arm/trace-events b/hw/arm/trace-events -index 2dee296c8f..1447ad5a90 100644 ---- a/hw/arm/trace-events -+++ b/hw/arm/trace-events -@@ -46,6 +46,7 @@ smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=0x%x" - smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid=0x%x (hits=%d, misses=%d, hit rate=%d)" - smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid=0x%x (hits=%d, misses=%d, hit rate=%d)" - smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid=%d asid=%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d" -+smmuv3_s1_asid_inval(int asid) "asid=%d" - smmuv3_cmdq_tlbi_nh(void) "" - smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d" - smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x" --- -2.27.0 - diff --git a/hw-arm-smmuv3-Pass-stage-1-configurations-to-the-hos.patch b/hw-arm-smmuv3-Pass-stage-1-configurations-to-the-hos.patch deleted file mode 100644 index 012c5d0071dc9f1bce50e706958e55fb443230d2..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Pass-stage-1-configurations-to-the-hos.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 2e5929ec2a35a7a227dc7ba70a557a84993a366d Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 9 Aug 2018 21:04:19 +0200 -Subject: [PATCH] hw/arm/smmuv3: Pass stage 1 configurations to the host - -In case PASID PciOps are set for the device we call -the set_pasid_table() callback on each STE update. - -This allows to pass the guest stage 1 configuration -to the host and apply it at physical level. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmu-internal.h | 1 + - hw/arm/smmuv3.c | 71 ++++++++++++++++++++++++++++++++++++------ - hw/arm/trace-events | 1 + - 3 files changed, 64 insertions(+), 9 deletions(-) - -diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h -index 2d75b31953..5ef8c598c6 100644 ---- a/hw/arm/smmu-internal.h -+++ b/hw/arm/smmu-internal.h -@@ -105,6 +105,7 @@ typedef struct SMMUIOTLBPageInvInfo { - } SMMUIOTLBPageInvInfo; - - typedef struct SMMUSIDRange { -+ SMMUState *state; - uint32_t start; - uint32_t end; - } SMMUSIDRange; -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index ad816e850c..58139f707d 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -16,6 +16,10 @@ - * with this program; if not, see . - */ - -+#ifdef __linux__ -+#include "linux/iommu.h" -+#endif -+ - #include "qemu/osdep.h" - #include "qemu/bitops.h" - #include "hw/irq.h" -@@ -928,6 +932,61 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd) - } - } - -+static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) -+{ -+#ifdef __linux__ -+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid); -+ SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid, -+ .inval_ste_allowed = true}; -+ IOMMUConfig iommu_config = {}; -+ SMMUTransCfg *cfg; -+ SMMUDevice *sdev; -+ -+ if (!mr) { -+ return; -+ } -+ -+ sdev = container_of(mr, SMMUDevice, iommu); -+ -+ /* flush QEMU config cache */ -+ smmuv3_flush_config(sdev); -+ -+ if (!pci_device_is_pasid_ops_set(sdev->bus, sdev->devfn)) { -+ return; -+ } -+ -+ cfg = smmuv3_get_config(sdev, &event); -+ -+ if (!cfg) { -+ return; -+ } -+ -+ iommu_config.pasid_cfg.argsz = sizeof(struct iommu_pasid_table_config); -+ iommu_config.pasid_cfg.version = PASID_TABLE_CFG_VERSION_1; -+ iommu_config.pasid_cfg.format = IOMMU_PASID_FORMAT_SMMUV3; -+ iommu_config.pasid_cfg.base_ptr = cfg->s1ctxptr; -+ iommu_config.pasid_cfg.pasid_bits = 0; -+ iommu_config.pasid_cfg.vendor_data.smmuv3.version = PASID_TABLE_SMMUV3_CFG_VERSION_1; -+ -+ if (cfg->disabled || cfg->bypassed) { -+ iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_BYPASS; -+ } else if (cfg->aborted) { -+ iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_ABORT; -+ } else { -+ iommu_config.pasid_cfg.config = IOMMU_PASID_CONFIG_TRANSLATE; -+ } -+ -+ trace_smmuv3_notify_config_change(mr->parent_obj.name, -+ iommu_config.pasid_cfg.config, -+ iommu_config.pasid_cfg.base_ptr); -+ -+ if (pci_device_set_pasid_table(sdev->bus, sdev->devfn, &iommu_config)) { -+ error_report("Failed to pass PASID table to host for iommu mr %s (%m)", -+ mr->parent_obj.name); -+ } -+#endif -+} -+ - static gboolean - smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) - { -@@ -938,6 +997,7 @@ smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data) - if (sid < sid_range->start || sid > sid_range->end) { - return false; - } -+ smmuv3_notify_config_change(sid_range->state, sid); - trace_smmuv3_config_cache_inv(sid); - return true; - } -@@ -1008,22 +1068,14 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) - case SMMU_CMD_CFGI_STE: - { - uint32_t sid = CMD_SID(&cmd); -- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid); -- SMMUDevice *sdev; - - if (CMD_SSEC(&cmd)) { - cmd_error = SMMU_CERROR_ILL; - break; - } - -- if (!mr) { -- break; -- } -- - trace_smmuv3_cmdq_cfgi_ste(sid); -- sdev = container_of(mr, SMMUDevice, iommu); -- smmuv3_flush_config(sdev); -- -+ smmuv3_notify_config_change(bs, sid); - break; - } - case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */ -@@ -1038,6 +1090,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) - } - - mask = (1ULL << (range + 1)) - 1; -+ sid_range.state = bs; - sid_range.start = sid & ~mask; - sid_range.end = sid_range.start + mask; - -diff --git a/hw/arm/trace-events b/hw/arm/trace-events -index 1447ad5a90..d9851d663e 100644 ---- a/hw/arm/trace-events -+++ b/hw/arm/trace-events -@@ -53,4 +53,5 @@ smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x" - smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s" - smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s" - smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64 -+smmuv3_notify_config_change(const char *name, uint8_t config, uint64_t s1ctxptr) "iommu mr=%s config=%d s1ctxptr=0x%"PRIx64 - --- -2.27.0 - diff --git a/hw-arm-smmuv3-Post-load-stage-1-configurations-to-th.patch b/hw-arm-smmuv3-Post-load-stage-1-configurations-to-th.patch deleted file mode 100644 index 0fc5f84460a60655713b48766bed2b7599042431..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Post-load-stage-1-configurations-to-th.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 1b95c995f032c21bf6607dda8ede0f5856bb190a Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 11 May 2021 10:08:16 +0800 -Subject: [PATCH] hw/arm/smmuv3: Post-load stage 1 configurations to the host - -In nested mode, we call the set_pasid_table() callback on each -STE update to pass the guest stage 1 configuration to the host -and apply it at physical level. - -In the case of live migration, we need to manually call the -set_pasid_table() to load the guest stage 1 configurations to -the host. If this operation fails, the migration fails. - -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 33 ++++++++++++++++++++++++++++----- - 1 file changed, 28 insertions(+), 5 deletions(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 45f21c53fe..291e3a12e8 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -932,7 +932,7 @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd) - } - } - --static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) -+static int smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) - { - #ifdef __linux__ - IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid); -@@ -941,9 +941,10 @@ static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) - IOMMUConfig iommu_config = {}; - SMMUTransCfg *cfg; - SMMUDevice *sdev; -+ int ret; - - if (!mr) { -- return; -+ return 0; - } - - sdev = container_of(mr, SMMUDevice, iommu); -@@ -952,13 +953,13 @@ static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) - smmuv3_flush_config(sdev); - - if (!pci_device_is_pasid_ops_set(sdev->bus, sdev->devfn)) { -- return; -+ return 0; - } - - cfg = smmuv3_get_config(sdev, &event); - - if (!cfg) { -- return; -+ return 0; - } - - iommu_config.pasid_cfg.argsz = sizeof(struct iommu_pasid_table_config); -@@ -980,10 +981,13 @@ static void smmuv3_notify_config_change(SMMUState *bs, uint32_t sid) - iommu_config.pasid_cfg.config, - iommu_config.pasid_cfg.base_ptr); - -- if (pci_device_set_pasid_table(sdev->bus, sdev->devfn, &iommu_config)) { -+ ret = pci_device_set_pasid_table(sdev->bus, sdev->devfn, &iommu_config); -+ if (ret) { - error_report("Failed to pass PASID table to host for iommu mr %s (%m)", - mr->parent_obj.name); - } -+ -+ return ret; - #endif - } - -@@ -1553,6 +1557,24 @@ static void smmu_realize(DeviceState *d, Error **errp) - smmu_init_irq(s, dev); - } - -+static int smmuv3_post_load(void *opaque, int version_id) -+{ -+ SMMUv3State *s3 = opaque; -+ SMMUState *s = &(s3->smmu_state); -+ SMMUDevice *sdev; -+ int ret = 0; -+ -+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) { -+ uint32_t sid = smmu_get_sid(sdev); -+ ret = smmuv3_notify_config_change(s, sid); -+ if (ret) { -+ break; -+ } -+ } -+ -+ return ret; -+} -+ - static const VMStateDescription vmstate_smmuv3_queue = { - .name = "smmuv3_queue", - .version_id = 1, -@@ -1571,6 +1593,7 @@ static const VMStateDescription vmstate_smmuv3 = { - .version_id = 1, - .minimum_version_id = 1, - .priority = MIG_PRI_IOMMU, -+ .post_load = smmuv3_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT32(features, SMMUv3State), - VMSTATE_UINT8(sid_size, SMMUv3State), --- -2.27.0 - diff --git a/hw-arm-smmuv3-Store-the-PASID-table-GPA-in-the-trans.patch b/hw-arm-smmuv3-Store-the-PASID-table-GPA-in-the-trans.patch deleted file mode 100644 index 3bbf1dadc18e41dbfe5859f337c79d42ef557c0b..0000000000000000000000000000000000000000 --- a/hw-arm-smmuv3-Store-the-PASID-table-GPA-in-the-trans.patch +++ /dev/null @@ -1,45 +0,0 @@ -From f937ce4124d57eea27d516957a2efa0e7fbdf198 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 9 Aug 2018 20:56:44 +0200 -Subject: [PATCH] hw/arm/smmuv3: Store the PASID table GPA in the translation - config - -For VFIO integration we will need to pass the Context Descriptor (CD) -table GPA to the host. The CD table is also referred to as the PASID -table. Its GPA corresponds to the s1ctrptr field of the Stream Table -Entry. So let's decode and store it in the configuration structure. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 1 + - include/hw/arm/smmu-common.h | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 12f354a0d5..3416f6a639 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -358,6 +358,7 @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg, - "SMMUv3 S1 stalling fault model not allowed yet\n"); - goto bad_ste; - } -+ cfg->s1ctxptr = STE_CTXPTR(ste); - return 0; - - bad_ste: -diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h -index 706be3c6d0..d578339935 100644 ---- a/include/hw/arm/smmu-common.h -+++ b/include/hw/arm/smmu-common.h -@@ -76,6 +76,7 @@ typedef struct SMMUTransCfg { - uint8_t tbi; /* Top Byte Ignore */ - uint16_t asid; - SMMUTransTableInfo tt[2]; -+ dma_addr_t s1ctxptr; - uint32_t iotlb_hits; /* counts IOTLB hits for this asid */ - uint32_t iotlb_misses; /* counts IOTLB misses for this asid */ - } SMMUTransCfg; --- -2.27.0 - diff --git a/hw-arm-virt-Assign-virt_madt_cpu_entry-to-acpi_ged-m.patch b/hw-arm-virt-Assign-virt_madt_cpu_entry-to-acpi_ged-m.patch deleted file mode 100644 index 71aea39369b48af8680a8071e2234860adfb77a1..0000000000000000000000000000000000000000 --- a/hw-arm-virt-Assign-virt_madt_cpu_entry-to-acpi_ged-m.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ae74dda87e172ce82a8180d1a2e9c62904390f91 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 10:05:54 +0800 -Subject: [PATCH] hw/arm/virt: Assign virt_madt_cpu_entry to acpi_ged madt_cpu - hook - -In build_cpus_aml, we will invoke this hook to build _MAT -aml mehtod for cpus. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 47e98f09e8..44c29070c4 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -684,6 +684,7 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) - static inline DeviceState *create_acpi_ged(VirtMachineState *vms) - { - DeviceState *dev; -+ AcpiDeviceIfClass *adevc; - MachineState *ms = MACHINE(vms); - int irq = vms->irqmap[VIRT_ACPI_GED]; - uint32_t event = ACPI_GED_PWR_DOWN_EVT; -@@ -699,6 +700,9 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms) - dev = qdev_new(TYPE_ACPI_GED); - qdev_prop_set_uint32(dev, "ged-event", event); - -+ adevc = ACPI_DEVICE_IF_GET_CLASS(dev); -+ adevc->madt_cpu = virt_madt_cpu_entry; -+ - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq)); --- -2.27.0 - diff --git a/hw-arm-virt-Check-for-attempt-to-use-TrustZone-with-.patch b/hw-arm-virt-Check-for-attempt-to-use-TrustZone-with-.patch deleted file mode 100644 index f395c38dea1247a63e682d8e0e2bb91051c1ab50..0000000000000000000000000000000000000000 --- a/hw-arm-virt-Check-for-attempt-to-use-TrustZone-with-.patch +++ /dev/null @@ -1,57 +0,0 @@ -From fd9cd16407e9d98807c631521ff1fcb83bfefac4 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 21 Aug 2023 06:21:27 +0000 -Subject: [PATCH] hw/arm/virt: Check for attempt to use TrustZone with KVM or - HVF mainline inclusion commit 78255ce392dc8596f9886476ad1e5c3c67f1c10a - category: bugfix - ---------------------------------------------------------------- - -It's not possible to provide the guest with the Security extensions -(TrustZone) when using KVM or HVF, because the hardware -virtualization extensions don't permit running EL3 guest code. -However, we weren't checking for this combination, with the result -that QEMU would assert if you tried it: - -$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none -Unexpected error in object_property_find_err() at ../../qom/object.c:1304: -qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found -Aborted - -Check for this combination of options and report an error, in the -same way we already do for attempts to give a KVM or HVF guest the -Virtualization or MTE extensions. Now we will report: - -qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961 -Signed-off-by: Peter Maydell -Reviewed-by: Richard Henderson -Message-id: 20220404155301.566542-1-peter.maydell@linaro.org - -Signed-off-by: tangbinzy ---- - hw/arm/virt.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 4c876fcf16..93554cccf1 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -2097,6 +2097,13 @@ static void machvirt_init(MachineState *machine) - exit(1); - } - -+ if (vms->secure && (kvm_enabled() || hvf_enabled())) { -+ error_report("mach-virt: %s does not support providing " -+ "Security extensions (TrustZone) to the guest CPU", -+ kvm_enabled() ? "KVM" : "HVF"); -+ exit(1); -+ } -+ - if (vms->virt && (kvm_enabled() || hvf_enabled())) { - error_report("mach-virt: %s does not support providing " - "Virtualization extensions to the guest CPU", --- -2.41.0.windows.1 - diff --git a/hw-arm-virt-Factor-out-some-CPU-init-codes-to-pre_pl.patch b/hw-arm-virt-Factor-out-some-CPU-init-codes-to-pre_pl.patch deleted file mode 100644 index fe733c62e37890f92821268c623da3adf22b7499..0000000000000000000000000000000000000000 --- a/hw-arm-virt-Factor-out-some-CPU-init-codes-to-pre_pl.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 7838609e9a7743af03c58ae46afd26070b2feea6 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Mon, 6 Apr 2020 12:50:54 +0800 -Subject: [PATCH] hw/arm/virt: Factor out some CPU init codes to pre_plug hook - -The init path of hotplugged CPU is pre_plug/realize/plug, so we -must move these init code in machvirt_init to pre_plug hook, to -let them be shared by all CPUs. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt.c | 197 ++++++++++++++++++++++++++------------------------ - 1 file changed, 103 insertions(+), 94 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index a12e718686..149e0245d7 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -213,6 +213,10 @@ static const char *valid_cpus[] = { - ARM_CPU_TYPE_NAME("max"), - }; - -+static MemoryRegion *secure_sysmem; -+static MemoryRegion *tag_sysmem; -+static MemoryRegion *secure_tag_sysmem; -+ - static bool cpu_type_valid(const char *cpu) - { - int i; -@@ -1990,9 +1994,6 @@ static void machvirt_init(MachineState *machine) - MachineClass *mc = MACHINE_GET_CLASS(machine); - const CPUArchIdList *possible_cpus; - MemoryRegion *sysmem = get_system_memory(); -- MemoryRegion *secure_sysmem = NULL; -- MemoryRegion *tag_sysmem = NULL; -- MemoryRegion *secure_tag_sysmem = NULL; - int n, virt_max_cpus; - bool firmware_loaded; - bool aarch64 = true; -@@ -2099,100 +2100,11 @@ static void machvirt_init(MachineState *machine) - } - - cpuobj = object_new(possible_cpus->cpus[n].type); -- object_property_set_int(cpuobj, "mp-affinity", -- possible_cpus->cpus[n].arch_id, NULL); -+ aarch64 &= object_property_get_bool(cpuobj, "aarch64", NULL); - - cs = CPU(cpuobj); - cs->cpu_index = n; - -- numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj), -- &error_fatal); -- -- aarch64 &= object_property_get_bool(cpuobj, "aarch64", NULL); -- -- if (!vms->secure) { -- object_property_set_bool(cpuobj, "has_el3", false, NULL); -- } -- -- if (!vms->virt && object_property_find(cpuobj, "has_el2")) { -- object_property_set_bool(cpuobj, "has_el2", false, NULL); -- } -- -- if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) { -- object_property_set_int(cpuobj, "psci-conduit", vms->psci_conduit, -- NULL); -- -- /* Secondary CPUs start in PSCI powered-down state */ -- if (n > 0) { -- object_property_set_bool(cpuobj, "start-powered-off", true, -- NULL); -- } -- } -- -- if (vmc->kvm_no_adjvtime && -- object_property_find(cpuobj, "kvm-no-adjvtime")) { -- object_property_set_bool(cpuobj, "kvm-no-adjvtime", true, NULL); -- } -- -- if (vmc->no_kvm_steal_time && -- object_property_find(cpuobj, "kvm-steal-time")) { -- object_property_set_bool(cpuobj, "kvm-steal-time", false, NULL); -- } -- -- if (vmc->no_pmu && object_property_find(cpuobj, "pmu")) { -- object_property_set_bool(cpuobj, "pmu", false, NULL); -- } -- -- if (object_property_find(cpuobj, "reset-cbar")) { -- object_property_set_int(cpuobj, "reset-cbar", -- vms->memmap[VIRT_CPUPERIPHS].base, -- &error_abort); -- } -- -- object_property_set_link(cpuobj, "memory", OBJECT(sysmem), -- &error_abort); -- if (vms->secure) { -- object_property_set_link(cpuobj, "secure-memory", -- OBJECT(secure_sysmem), &error_abort); -- } -- -- if (vms->mte) { -- /* Create the memory region only once, but link to all cpus. */ -- if (!tag_sysmem) { -- /* -- * The property exists only if MemTag is supported. -- * If it is, we must allocate the ram to back that up. -- */ -- if (!object_property_find(cpuobj, "tag-memory")) { -- error_report("MTE requested, but not supported " -- "by the guest CPU"); -- exit(1); -- } -- -- tag_sysmem = g_new(MemoryRegion, 1); -- memory_region_init(tag_sysmem, OBJECT(machine), -- "tag-memory", UINT64_MAX / 32); -- -- if (vms->secure) { -- secure_tag_sysmem = g_new(MemoryRegion, 1); -- memory_region_init(secure_tag_sysmem, OBJECT(machine), -- "secure-tag-memory", UINT64_MAX / 32); -- -- /* As with ram, secure-tag takes precedence over tag. */ -- memory_region_add_subregion_overlap(secure_tag_sysmem, 0, -- tag_sysmem, -1); -- } -- } -- -- object_property_set_link(cpuobj, "tag-memory", OBJECT(tag_sysmem), -- &error_abort); -- if (vms->secure) { -- object_property_set_link(cpuobj, "secure-tag-memory", -- OBJECT(secure_tag_sysmem), -- &error_abort); -- } -- } -- - qdev_realize(DEVICE(cpuobj), NULL, &error_fatal); - object_unref(cpuobj); - } -@@ -2600,10 +2512,16 @@ static void virt_memory_plug(HotplugHandler *hotplug_dev, - static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) - { -- CPUState *cs = CPU(dev); - ARMCPUTopoInfo topo; -+ Object *cpuobj = OBJECT(dev); -+ CPUState *cs = CPU(dev); - ARMCPU *cpu = ARM_CPU(dev); - MachineState *ms = MACHINE(hotplug_dev); -+ MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev); -+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev); -+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(hotplug_dev); -+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); -+ MemoryRegion *sysmem = get_system_memory(); - int smp_clusters = ms->smp.clusters; - int smp_cores = ms->smp.cores; - int smp_threads = ms->smp.threads; -@@ -2673,6 +2591,97 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, - return; - } - cpu->thread_id = topo.smt_id; -+ -+ /* Init some properties */ -+ -+ object_property_set_int(cpuobj, "mp-affinity", -+ possible_cpus->cpus[cs->cpu_index].arch_id, NULL); -+ -+ numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj), -+ &error_fatal); -+ -+ if (!vms->secure) { -+ object_property_set_bool(cpuobj, "has_el3", false, NULL); -+ } -+ -+ if (!vms->virt && object_property_find(cpuobj, "has_el2")) { -+ object_property_set_bool(cpuobj, "has_el2", false, NULL); -+ } -+ -+ if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED) { -+ object_property_set_int(cpuobj, "psci-conduit", vms->psci_conduit, -+ NULL); -+ -+ /* Secondary CPUs start in PSCI powered-down state */ -+ if (cs->cpu_index > 0) { -+ object_property_set_bool(cpuobj, "start-powered-off", true, -+ NULL); -+ } -+ } -+ -+ if (vmc->kvm_no_adjvtime && -+ object_property_find(cpuobj, "kvm-no-adjvtime")) { -+ object_property_set_bool(cpuobj, "kvm-no-adjvtime", true, NULL); -+ } -+ -+ if (vmc->no_kvm_steal_time && -+ object_property_find(cpuobj, "kvm-steal-time")) { -+ object_property_set_bool(cpuobj, "kvm-steal-time", false, NULL); -+ } -+ -+ if (vmc->no_pmu && object_property_find(cpuobj, "pmu")) { -+ object_property_set_bool(cpuobj, "pmu", false, NULL); -+ } -+ -+ if (object_property_find(cpuobj, "reset-cbar")) { -+ object_property_set_int(cpuobj, "reset-cbar", -+ vms->memmap[VIRT_CPUPERIPHS].base, -+ &error_abort); -+ } -+ -+ object_property_set_link(cpuobj, "memory", OBJECT(sysmem), -+ &error_abort); -+ if (vms->secure) { -+ object_property_set_link(cpuobj, "secure-memory", -+ OBJECT(secure_sysmem), &error_abort); -+ } -+ -+ if (vms->mte) { -+ /* Create the memory region only once, but link to all cpus. */ -+ if (!tag_sysmem) { -+ /* -+ * The property exists only if MemTag is supported. -+ * If it is, we must allocate the ram to back that up. -+ */ -+ if (!object_property_find(cpuobj, "tag-memory")) { -+ error_report("MTE requested, but not supported " -+ "by the guest CPU"); -+ exit(1); -+ } -+ -+ tag_sysmem = g_new(MemoryRegion, 1); -+ memory_region_init(tag_sysmem, OBJECT(ms), -+ "tag-memory", UINT64_MAX / 32); -+ -+ if (vms->secure) { -+ secure_tag_sysmem = g_new(MemoryRegion, 1); -+ memory_region_init(secure_tag_sysmem, OBJECT(ms), -+ "secure-tag-memory", UINT64_MAX / 32); -+ -+ /* As with ram, secure-tag takes precedence over tag. */ -+ memory_region_add_subregion_overlap(secure_tag_sysmem, 0, -+ tag_sysmem, -1); -+ } -+ } -+ -+ object_property_set_link(cpuobj, "tag-memory", OBJECT(tag_sysmem), -+ &error_abort); -+ if (vms->secure) { -+ object_property_set_link(cpuobj, "secure-tag-memory", -+ OBJECT(secure_tag_sysmem), -+ &error_abort); -+ } -+ } - } - - static void virt_cpu_plug(HotplugHandler *hotplug_dev, --- -2.27.0 - diff --git a/hw-arm-virt-Fix-devicetree-warnings-about-the-virtio.patch b/hw-arm-virt-Fix-devicetree-warnings-about-the-virtio.patch deleted file mode 100644 index 7c10bc0991de50b11b968b53d4bb1fee8ec1696d..0000000000000000000000000000000000000000 --- a/hw-arm-virt-Fix-devicetree-warnings-about-the-virtio.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 9fdae653dc60c96fad416abb1b5294f767fcb3c5 Mon Sep 17 00:00:00 2001 -From: cmss_dx -Date: Wed, 23 Nov 2022 08:10:00 +0000 -Subject: [PATCH 11/29] hw/arm/virt: Fix devicetree warnings about the - virtio-iommu node mainline inclusion from mainline-v7.2.0-rc1 commit - 7cd5d384bb298ce3c595a3774213b5b478881ac8 category: bugfix - --------------------------------- - -The "PCI Bus Binding to: IEEE Std 1275-1994" defines the compatible -string for a PCIe bus or endpoint as "pci," or -similar. Since the initial binding for PCI virtio-iommu didn't follow -this rule, it was modified to accept both strings and ensure backward -compatibility. Also, the unit-name for the node should be -"device,function". - -Fix corresponding dt-validate and dtc warnings: - - pcie@10000000: virtio_iommu@16:compatible: ['virtio,pci-iommu'] does not contain items matching the given schema - pcie@10000000: Unevaluated properties are not allowed (... 'virtio_iommu@16' were unexpected) - From schema: linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml - virtio_iommu@16: compatible: 'oneOf' conditional failed, one must be fixed: - ['virtio,pci-iommu'] is too short - 'pci1af4,1057' was expected - From schema: dtschema/schemas/pci/pci-bus.yaml - - Warning (pci_device_reg): /pcie@10000000/virtio_iommu@16: PCI unit address format error, expected "2,0" - -Signed-off-by: Jean-Philippe Brucker -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell - -Signed-off-by: cmss_dx ---- - hw/arm/virt.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index b81d22d68f..4716f9baaa 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -1470,14 +1470,15 @@ static void create_smmu(const VirtMachineState *vms, - - static void create_virtio_iommu_dt_bindings(VirtMachineState *vms) - { -- const char compat[] = "virtio,pci-iommu"; -+ const char compat[] = "virtio,pci-iommu\0pci1af4,1057"; - uint16_t bdf = vms->virtio_iommu_bdf; - MachineState *ms = MACHINE(vms); - char *node; - - vms->iommu_phandle = qemu_fdt_alloc_phandle(ms->fdt); - -- node = g_strdup_printf("%s/virtio_iommu@%d", vms->pciehb_nodename, bdf); -+ node = g_strdup_printf("%s/virtio_iommu@%x,%x", vms->pciehb_nodename, -+ PCI_SLOT(bdf), PCI_FUNC(bdf)); - qemu_fdt_add_subnode(ms->fdt, node); - qemu_fdt_setprop(ms->fdt, node, "compatible", compat, sizeof(compat)); - qemu_fdt_setprop_sized_cells(ms->fdt, node, "reg", --- -2.27.0 - diff --git a/hw-arm-virt-Support-CPU-cluster-on-ARM-virt-machine.patch b/hw-arm-virt-Support-CPU-cluster-on-ARM-virt-machine.patch deleted file mode 100644 index cd3241f25dc6a437d65bfeb4a3017b189440dd9b..0000000000000000000000000000000000000000 --- a/hw-arm-virt-Support-CPU-cluster-on-ARM-virt-machine.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 1fab7ee365c8daccedd19d3a1be56babe36afcc6 Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Fri, 7 Jan 2022 16:32:27 +0800 -Subject: [PATCH 15/24] hw/arm/virt: Support CPU cluster on ARM virt machine - -ARM64 machines like Kunpeng Family Server Chips have a level -of hardware topology in which a group of CPU cores share L3 -cache tag or L2 cache. For example, Kunpeng 920 typically -has 6 or 8 clusters in each NUMA node (also represent range -of CPU die), and each cluster has 4 CPU cores. All clusters -share L3 cache data, but CPU cores in each cluster share a -local L3 tag. - -Running a guest kernel with Cluster-Aware Scheduling on the -Hosts which have physical clusters, if we can design a vCPU -topology with cluster level for guest kernel and then have -a dedicated vCPU pinning, the guest will gain scheduling -performance improvement from cache affinity of CPU cluster. - -So let's enable the support for this new parameter on ARM -virt machines. After this patch, we can define a 4-level -CPU hierarchy like: cpus=*,maxcpus=*,sockets=*,clusters=*, -cores=*,threads=*. - -Signed-off-by: Yanan Wang -Reviewed-by: Andrew Jones -Message-id: 20220107083232.16256-2-wangyanan55@huawei.com -Signed-off-by: Peter Maydell ---- - hw/arm/virt.c | 1 + - qemu-options.hx | 10 ++++++++++ - 2 files changed, 11 insertions(+) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 3c972fdab0..6ca9cbe2cf 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -2704,6 +2704,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) - hc->unplug_request = virt_machine_device_unplug_request_cb; - hc->unplug = virt_machine_device_unplug_cb; - mc->nvdimm_supported = true; -+ mc->smp_props.clusters_supported = true; - mc->auto_enable_numa_with_memhp = true; - mc->auto_enable_numa_with_memdev = true; - mc->default_ram_id = "mach-virt.ram"; -diff --git a/qemu-options.hx b/qemu-options.hx -index 0f26f7dad7..74d335e4c3 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -277,6 +277,16 @@ SRST - - -smp 16,sockets=2,dies=2,cores=2,threads=2,maxcpus=16 - -+ The following sub-option defines a CPU topology hierarchy (2 sockets -+ totally on the machine, 2 clusters per socket, 2 cores per cluster, -+ 2 threads per core) for ARM virt machines which support sockets/clusters -+ /cores/threads. Some members of the option can be omitted but their values -+ will be automatically computed: -+ -+ :: -+ -+ -smp 16,sockets=2,clusters=2,cores=2,threads=2,maxcpus=16 -+ - Historically preference was given to the coarsest topology parameters - when computing missing values (ie sockets preferred over cores, which - were preferred over threads), however, this behaviour is considered --- -2.27.0 - diff --git a/hw-arm-virt-Support-cluster-level-in-DT-cpu-map.patch b/hw-arm-virt-Support-cluster-level-in-DT-cpu-map.patch deleted file mode 100644 index 2d43030f818bee075d09e0403e7e29410f406a92..0000000000000000000000000000000000000000 --- a/hw-arm-virt-Support-cluster-level-in-DT-cpu-map.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 38d9ae59b9344f13198e6b4de03b04787bd6b89d Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Fri, 7 Jan 2022 16:32:28 +0800 -Subject: [PATCH 16/24] hw/arm/virt: Support cluster level in DT cpu-map - -Support one cluster level between core and physical package in the -cpu-map of Arm/virt devicetree. This is also consistent with Linux -Doc "Documentation/devicetree/bindings/cpu/cpu-topology.txt". - -Signed-off-by: Yanan Wang -Reviewed-by: Andrew Jones -Message-id: 20220107083232.16256-3-wangyanan55@huawei.com -Signed-off-by: Peter Maydell ---- - hw/arm/virt.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 6ca9cbe2cf..ddcb73f714 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -434,9 +434,8 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) - * can contain several layers of clustering within a single physical - * package and cluster nodes can be contained in parent cluster nodes. - * -- * Given that cluster is not yet supported in the vCPU topology, -- * we currently generate one cluster node within each socket node -- * by default. -+ * Note: currently we only support one layer of clustering within -+ * each physical package. - */ - qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map"); - -@@ -446,14 +445,16 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) - - if (ms->smp.threads > 1) { - map_path = g_strdup_printf( -- "/cpus/cpu-map/socket%d/cluster0/core%d/thread%d", -- cpu / (ms->smp.cores * ms->smp.threads), -+ "/cpus/cpu-map/socket%d/cluster%d/core%d/thread%d", -+ cpu / (ms->smp.clusters * ms->smp.cores * ms->smp.threads), -+ (cpu / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters, - (cpu / ms->smp.threads) % ms->smp.cores, - cpu % ms->smp.threads); - } else { - map_path = g_strdup_printf( -- "/cpus/cpu-map/socket%d/cluster0/core%d", -- cpu / ms->smp.cores, -+ "/cpus/cpu-map/socket%d/cluster%d/core%d", -+ cpu / (ms->smp.clusters * ms->smp.cores), -+ (cpu / ms->smp.cores) % ms->smp.clusters, - cpu % ms->smp.cores); - } - qemu_fdt_add_path(ms->fdt, map_path); --- -2.27.0 - diff --git a/hw-arm-xlnx-zynqmp-fix-unsigned-error-when-checking-.patch b/hw-arm-xlnx-zynqmp-fix-unsigned-error-when-checking-.patch deleted file mode 100644 index 0968345e28418c949f5c25f680f78db5bbaabd42..0000000000000000000000000000000000000000 --- a/hw-arm-xlnx-zynqmp-fix-unsigned-error-when-checking-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From a1ecbf056603b4fabf8b5ab8a79f70a27fef06ee Mon Sep 17 00:00:00 2001 -From: jipengfei_yewu -Date: Sun, 24 Sep 2023 19:39:33 +0800 -Subject: [PATCH] hw/arm/xlnx-zynqmp: fix unsigned error when checking the RPUs - number -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When passing --smp with a number lower than XLNX_ZYNQMP_NUM_APU_CPUS, -the expression (ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS) will result -in a positive number as ms->smp.cpus is a unsigned int. -This will raise the following error afterwards, as Qemu will try to -instantiate some additional RPUs. - | $ qemu-system-aarch64 --smp 1 -M xlnx-zcu102 - | ** - | ERROR:../src/tcg/tcg.c:777:tcg_register_thread: - | assertion failed: (n < tcg_max_ctxs) - -cheery-pick from c9ba1c9f02cfede5329f504cdda6fd3a256e0434 - -Signed-off-by: jipengfei_yewu -Signed-off-by: Clément Chigot -Reviewed-by: Francisco Iglesias -Tested-by: Francisco Iglesias -Message-id: 20230524143714.565792-1-chigot@adacore.com -Signed-off-by: Peter Maydell ---- - hw/arm/xlnx-zynqmp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c -index 1c52a575aa..2ffc6df70b 100644 ---- a/hw/arm/xlnx-zynqmp.c -+++ b/hw/arm/xlnx-zynqmp.c -@@ -194,7 +194,7 @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s, - const char *boot_cpu, Error **errp) - { - int i; -- int num_rpus = MIN(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS, -+ int num_rpus = MIN((int)(ms->smp.cpus - XLNX_ZYNQMP_NUM_APU_CPUS), - XLNX_ZYNQMP_NUM_RPU_CPUS); - - if (num_rpus <= 0) { --- -2.41.0.windows.1 - diff --git a/hw-arm64-add-vcpu-cache-info-support.patch b/hw-arm64-add-vcpu-cache-info-support.patch deleted file mode 100644 index 3e8c82e626cca3592709f99af77a7092eddc3207..0000000000000000000000000000000000000000 --- a/hw-arm64-add-vcpu-cache-info-support.patch +++ /dev/null @@ -1,353 +0,0 @@ -From c5cd762bb7513b6df07e26f4eb619dccbd1918b7 Mon Sep 17 00:00:00 2001 -From: Ying Fang -Date: Tue, 8 Feb 2022 11:31:15 +0800 -Subject: [PATCH 23/24] hw/arm64: add vcpu cache info support - -Support VCPU Cache info by dtb and PPTT table, including L1, L2 and L3 Cache. - -Signed-off-by: zhanghailiang -Signed-off-by: Honghao -Signed-off-by: Ying Fang -Signed-off-by: Yanan Wang ---- - hw/acpi/aml-build.c | 158 ++++++++++++++++++++++++++++++++++++ - hw/arm/virt.c | 72 ++++++++++++++++ - include/hw/acpi/aml-build.h | 47 +++++++++++ - tests/data/acpi/virt/PPTT | Bin 96 -> 208 bytes - 4 files changed, 277 insertions(+) - -diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c -index bb2cad63b5..bebf49622b 100644 ---- a/hw/acpi/aml-build.c -+++ b/hw/acpi/aml-build.c -@@ -1994,6 +1994,163 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags, - } - } - -+#ifdef __aarch64__ -+/* -+ * ACPI spec, Revision 6.3 -+ * 5.2.29.2 Cache Type Structure (Type 1) -+ */ -+static void build_cache_hierarchy_node(GArray *tbl, uint32_t next_level, -+ uint32_t cache_type) -+{ -+ build_append_byte(tbl, 1); -+ build_append_byte(tbl, 24); -+ build_append_int_noprefix(tbl, 0, 2); -+ build_append_int_noprefix(tbl, 127, 4); -+ build_append_int_noprefix(tbl, next_level, 4); -+ -+ switch (cache_type) { -+ case ARM_L1D_CACHE: /* L1 dcache info */ -+ build_append_int_noprefix(tbl, ARM_L1DCACHE_SIZE, 4); -+ build_append_int_noprefix(tbl, ARM_L1DCACHE_SETS, 4); -+ build_append_byte(tbl, ARM_L1DCACHE_ASSOCIATIVITY); -+ build_append_byte(tbl, ARM_L1DCACHE_ATTRIBUTES); -+ build_append_int_noprefix(tbl, ARM_L1DCACHE_LINE_SIZE, 2); -+ break; -+ case ARM_L1I_CACHE: /* L1 icache info */ -+ build_append_int_noprefix(tbl, ARM_L1ICACHE_SIZE, 4); -+ build_append_int_noprefix(tbl, ARM_L1ICACHE_SETS, 4); -+ build_append_byte(tbl, ARM_L1ICACHE_ASSOCIATIVITY); -+ build_append_byte(tbl, ARM_L1ICACHE_ATTRIBUTES); -+ build_append_int_noprefix(tbl, ARM_L1ICACHE_LINE_SIZE, 2); -+ break; -+ case ARM_L2_CACHE: /* L2 cache info */ -+ build_append_int_noprefix(tbl, ARM_L2CACHE_SIZE, 4); -+ build_append_int_noprefix(tbl, ARM_L2CACHE_SETS, 4); -+ build_append_byte(tbl, ARM_L2CACHE_ASSOCIATIVITY); -+ build_append_byte(tbl, ARM_L2CACHE_ATTRIBUTES); -+ build_append_int_noprefix(tbl, ARM_L2CACHE_LINE_SIZE, 2); -+ break; -+ case ARM_L3_CACHE: /* L3 cache info */ -+ build_append_int_noprefix(tbl, ARM_L3CACHE_SIZE, 4); -+ build_append_int_noprefix(tbl, ARM_L3CACHE_SETS, 4); -+ build_append_byte(tbl, ARM_L3CACHE_ASSOCIATIVITY); -+ build_append_byte(tbl, ARM_L3CACHE_ATTRIBUTES); -+ build_append_int_noprefix(tbl, ARM_L3CACHE_LINE_SIZE, 2); -+ break; -+ default: -+ build_append_int_noprefix(tbl, 0, 4); -+ build_append_int_noprefix(tbl, 0, 4); -+ build_append_byte(tbl, 0); -+ build_append_byte(tbl, 0); -+ build_append_int_noprefix(tbl, 0, 2); -+ } -+} -+ -+/* -+ * ACPI spec, Revision 6.3 -+ * 5.2.29 Processor Properties Topology Table (PPTT) -+ */ -+void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, -+ const char *oem_id, const char *oem_table_id) -+{ -+ MachineClass *mc = MACHINE_GET_CLASS(ms); -+ GQueue *list = g_queue_new(); -+ guint pptt_start = table_data->len; -+ guint parent_offset; -+ guint length, i; -+ int uid = 0; -+ int socket; -+ AcpiTable table = { .sig = "PPTT", .rev = 2, -+ .oem_id = oem_id, .oem_table_id = oem_table_id }; -+ -+ acpi_table_begin(&table, table_data); -+ -+ for (socket = 0; socket < ms->smp.sockets; socket++) { -+ uint32_t l3_cache_offset = table_data->len - pptt_start; -+ build_cache_hierarchy_node(table_data, 0, ARM_L3_CACHE); -+ -+ g_queue_push_tail(list, -+ GUINT_TO_POINTER(table_data->len - pptt_start)); -+ build_processor_hierarchy_node( -+ table_data, -+ /* -+ * Physical package - represents the boundary -+ * of a physical package -+ */ -+ (1 << 0), -+ 0, socket, &l3_cache_offset, 1); -+ } -+ -+ if (mc->smp_props.clusters_supported) { -+ length = g_queue_get_length(list); -+ for (i = 0; i < length; i++) { -+ int cluster; -+ -+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); -+ for (cluster = 0; cluster < ms->smp.clusters; cluster++) { -+ g_queue_push_tail(list, -+ GUINT_TO_POINTER(table_data->len - pptt_start)); -+ build_processor_hierarchy_node( -+ table_data, -+ (0 << 0), /* not a physical package */ -+ parent_offset, cluster, NULL, 0); -+ } -+ } -+ } -+ -+ length = g_queue_get_length(list); -+ for (i = 0; i < length; i++) { -+ int core; -+ -+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); -+ for (core = 0; core < ms->smp.cores; core++) { -+ uint32_t priv_rsrc[3] = {}; -+ priv_rsrc[0] = table_data->len - pptt_start; /* L2 cache offset */ -+ build_cache_hierarchy_node(table_data, 0, ARM_L2_CACHE); -+ -+ priv_rsrc[1] = table_data->len - pptt_start; /* L1 dcache offset */ -+ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1D_CACHE); -+ -+ priv_rsrc[2] = table_data->len - pptt_start; /* L1 icache offset */ -+ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1I_CACHE); -+ -+ if (ms->smp.threads > 1) { -+ g_queue_push_tail(list, -+ GUINT_TO_POINTER(table_data->len - pptt_start)); -+ build_processor_hierarchy_node( -+ table_data, -+ (0 << 0), /* not a physical package */ -+ parent_offset, core, priv_rsrc, 3); -+ } else { -+ build_processor_hierarchy_node( -+ table_data, -+ (1 << 1) | /* ACPI Processor ID valid */ -+ (1 << 3), /* Node is a Leaf */ -+ parent_offset, uid++, priv_rsrc, 3); -+ } -+ } -+ } -+ -+ length = g_queue_get_length(list); -+ for (i = 0; i < length; i++) { -+ int thread; -+ -+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list)); -+ for (thread = 0; thread < ms->smp.threads; thread++) { -+ build_processor_hierarchy_node( -+ table_data, -+ (1 << 1) | /* ACPI Processor ID valid */ -+ (1 << 2) | /* Processor is a Thread */ -+ (1 << 3), /* Node is a Leaf */ -+ parent_offset, uid++, NULL, 0); -+ } -+ } -+ -+ g_queue_free(list); -+ acpi_table_end(linker, &table); -+} -+ -+#else - /* - * ACPI spec, Revision 6.3 - * 5.2.29 Processor Properties Topology Table (PPTT) -@@ -2084,6 +2241,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, - g_queue_free(list); - acpi_table_end(linker, &table); - } -+#endif - - /* build rev1/rev3/rev5.1 FADT */ - void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f, -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index ddcb73f714..529c0d38b6 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -350,6 +350,72 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms) - GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags); - } - -+static void fdt_add_l3cache_nodes(const VirtMachineState *vms) -+{ -+ int i; -+ const MachineState *ms = MACHINE(vms); -+ int cpus_per_socket = ms->smp.clusters * ms->smp.cores * ms->smp.threads; -+ int sockets = (ms->smp.cpus + cpus_per_socket - 1) / cpus_per_socket; -+ -+ for (i = 0; i < sockets; i++) { -+ char *nodename = g_strdup_printf("/cpus/l3-cache%d", i); -+ -+ qemu_fdt_add_subnode(ms->fdt, nodename); -+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache"); -+ qemu_fdt_setprop_string(ms->fdt, nodename, "cache-unified", "true"); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-level", 3); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", 0x2000000); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", 128); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", 2048); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", -+ qemu_fdt_alloc_phandle(ms->fdt)); -+ g_free(nodename); -+ } -+} -+ -+static void fdt_add_l2cache_nodes(const VirtMachineState *vms) -+{ -+ const MachineState *ms = MACHINE(vms); -+ int cpus_per_socket = ms->smp.clusters * ms->smp.cores * ms->smp.threads; -+ int cpu; -+ -+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) { -+ char *next_path = g_strdup_printf("/cpus/l3-cache%d", -+ cpu / cpus_per_socket); -+ char *nodename = g_strdup_printf("/cpus/l2-cache%d", cpu); -+ -+ qemu_fdt_add_subnode(ms->fdt, nodename); -+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache"); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", 0x80000); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", 64); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", 1024); -+ qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache", -+ next_path); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", -+ qemu_fdt_alloc_phandle(ms->fdt)); -+ -+ g_free(next_path); -+ g_free(nodename); -+ } -+} -+ -+static void fdt_add_l1cache_prop(const VirtMachineState *vms, -+ char *nodename, int cpu) -+{ -+ const MachineState *ms = MACHINE(vms); -+ char *cachename = g_strdup_printf("/cpus/l2-cache%d", cpu); -+ -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-size", 0x10000); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-line-size", 64); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-sets", 256); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-size", 0x10000); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-line-size", 64); -+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-sets", 256); -+ qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache", -+ cachename); -+ g_free(cachename); -+} -+ - static void fdt_add_cpu_nodes(const VirtMachineState *vms) - { - int cpu; -@@ -384,6 +450,11 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) - qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", addr_cells); - qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0); - -+ if (!vmc->no_cpu_topology) { -+ fdt_add_l3cache_nodes(vms); -+ fdt_add_l2cache_nodes(vms); -+ } -+ - for (cpu = smp_cpus - 1; cpu >= 0; cpu--) { - char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu); - ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu)); -@@ -413,6 +484,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) - } - - if (!vmc->no_cpu_topology) { -+ fdt_add_l1cache_prop(vms, nodename, cpu); - qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", - qemu_fdt_alloc_phandle(ms->fdt)); - } -diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h -index 8346003a22..8e8ad8029e 100644 ---- a/include/hw/acpi/aml-build.h -+++ b/include/hw/acpi/aml-build.h -@@ -221,6 +221,53 @@ struct AcpiBuildTables { - BIOSLinker *linker; - } AcpiBuildTables; - -+#ifdef __aarch64__ -+/* Definitions of the hardcoded cache info*/ -+ -+typedef enum { -+ ARM_L1D_CACHE, -+ ARM_L1I_CACHE, -+ ARM_L2_CACHE, -+ ARM_L3_CACHE -+} ArmCacheType; -+ -+/* L1 data cache: */ -+#define ARM_L1DCACHE_SIZE 65536 -+#define ARM_L1DCACHE_SETS 256 -+#define ARM_L1DCACHE_ASSOCIATIVITY 4 -+#define ARM_L1DCACHE_ATTRIBUTES 2 -+#define ARM_L1DCACHE_LINE_SIZE 64 -+ -+/* L1 instruction cache: */ -+#define ARM_L1ICACHE_SIZE 65536 -+#define ARM_L1ICACHE_SETS 256 -+#define ARM_L1ICACHE_ASSOCIATIVITY 4 -+#define ARM_L1ICACHE_ATTRIBUTES 4 -+#define ARM_L1ICACHE_LINE_SIZE 64 -+ -+/* Level 2 unified cache: */ -+#define ARM_L2CACHE_SIZE 524288 -+#define ARM_L2CACHE_SETS 1024 -+#define ARM_L2CACHE_ASSOCIATIVITY 8 -+#define ARM_L2CACHE_ATTRIBUTES 10 -+#define ARM_L2CACHE_LINE_SIZE 64 -+ -+/* Level 3 unified cache: */ -+#define ARM_L3CACHE_SIZE 33554432 -+#define ARM_L3CACHE_SETS 2048 -+#define ARM_L3CACHE_ASSOCIATIVITY 15 -+#define ARM_L3CACHE_ATTRIBUTES 10 -+#define ARM_L3CACHE_LINE_SIZE 128 -+ -+struct offset_status { -+ uint32_t parent; -+ uint32_t l2_offset; -+ uint32_t l1d_offset; -+ uint32_t l1i_offset; -+}; -+ -+#endif -+ - typedef - struct CrsRangeEntry { - uint64_t base; - --- -2.27.0 - diff --git a/hw-audio-intel-hda-Do-not-ignore-DMA-overrun-errors.patch b/hw-audio-intel-hda-Do-not-ignore-DMA-overrun-errors.patch deleted file mode 100644 index 40cd09857957336c87f6bd96ed8f9421210b0db9..0000000000000000000000000000000000000000 --- a/hw-audio-intel-hda-Do-not-ignore-DMA-overrun-errors.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 2defe49a69b324499953c9b8c55f18e22ca74631 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Sat, 18 Dec 2021 17:09:10 +0100 -Subject: [PATCH 23/25] hw/audio/intel-hda: Do not ignore DMA overrun errors -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Per the "High Definition Audio Specification" manual (rev. 1.0a), -section "3.3.30 Offset 5Dh: RIRBSTS - RIRB Status": - - Response Overrun Interrupt Status (RIRBOIS): - - Hardware sets this bit to a 1 when an overrun occurs in the RIRB. - An interrupt may be generated if the Response Overrun Interrupt - Control bit is set. - - This bit will be set if the RIRB DMA engine is not able to write - the incoming responses to memory before additional incoming - responses overrun the internal FIFO. - - When hardware detects an overrun, it will drop the responses which - overrun the buffer and set the RIRBOIS status bit to indicate the - error condition. Optionally, if the RIRBOIC is set, the hardware - will also generate an error to alert software to the problem. - -QEMU emulates the DMA engine with the stl_le_pci_dma() calls. This -function returns a MemTxResult indicating whether the DMA access -was successful. -Handle any MemTxResult error as "DMA engine is not able to write the -incoming responses to memory" and raise the Overrun Interrupt flag -when this case occurs. - -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211218160912.1591633-2-philmd@redhat.com> -Signed-off-by: Thomas Huth ---- - hw/audio/intel-hda.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c -index 2b55d52150..0c1017edbb 100644 ---- a/hw/audio/intel-hda.c -+++ b/hw/audio/intel-hda.c -@@ -350,6 +350,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res - IntelHDAState *d = container_of(bus, IntelHDAState, codecs); - hwaddr addr; - uint32_t wp, ex; -+ MemTxResult res = MEMTX_OK; - - if (d->ics & ICH6_IRS_BUSY) { - dprint(d, 2, "%s: [irr] response 0x%x, cad 0x%x\n", -@@ -368,8 +369,12 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res - ex = (solicited ? 0 : (1 << 4)) | dev->cad; - wp = (d->rirb_wp + 1) & 0xff; - addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase); -- stl_le_pci_dma(&d->pci, addr + 8 * wp, response, attrs); -- stl_le_pci_dma(&d->pci, addr + 8 * wp + 4, ex, attrs); -+ res |= stl_le_pci_dma(&d->pci, addr + 8 * wp, response, attrs); -+ res |= stl_le_pci_dma(&d->pci, addr + 8 * wp + 4, ex, attrs); -+ if (res != MEMTX_OK && (d->rirb_ctl & ICH6_RBCTL_OVERRUN_EN)) { -+ d->rirb_sts |= ICH6_RBSTS_OVERRUN; -+ intel_hda_update_irq(d); -+ } - d->rirb_wp = wp; - - dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n", --- -2.27.0 - diff --git a/hw-audio-intel-hda-Restrict-DMA-engine-to-memories-n.patch b/hw-audio-intel-hda-Restrict-DMA-engine-to-memories-n.patch deleted file mode 100644 index 0e2508bdc2b34e7a38089d2bfb3ed74b51b41f5e..0000000000000000000000000000000000000000 --- a/hw-audio-intel-hda-Restrict-DMA-engine-to-memories-n.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f8b3b2e8d09320cab4cccab2dcbaab799d2dbd7a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Sat, 18 Dec 2021 17:09:11 +0100 -Subject: [PATCH 24/25] hw/audio/intel-hda: Restrict DMA engine to memories - (not MMIO devices) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Issue #542 reports a reentrancy problem when the DMA engine accesses -the HDA controller I/O registers. Fix by restricting the DMA engine -to memories regions (forbidding MMIO devices such the HDA controller). - -Reported-by: OSS-Fuzz (Issue 28435) -Reported-by: Alexander Bulekov -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Thomas Huth -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/542 -CVE: CVE-2021-3611 -Message-Id: <20211218160912.1591633-3-philmd@redhat.com> -Signed-off-by: Thomas Huth ---- - hw/audio/intel-hda.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c -index 0c1017edbb..3aa57d274e 100644 ---- a/hw/audio/intel-hda.c -+++ b/hw/audio/intel-hda.c -@@ -345,7 +345,7 @@ static void intel_hda_corb_run(IntelHDAState *d) - - static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t response) - { -- const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; -+ const MemTxAttrs attrs = { .memory = true }; - HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus); - IntelHDAState *d = container_of(bus, IntelHDAState, codecs); - hwaddr addr; --- -2.27.0 - diff --git a/hw-audio-intel-hda-fix-stream-reset.patch b/hw-audio-intel-hda-fix-stream-reset.patch deleted file mode 100644 index ef80b5d4a0414e2f58539828825890f7bb3a62c6..0000000000000000000000000000000000000000 --- a/hw-audio-intel-hda-fix-stream-reset.patch +++ /dev/null @@ -1,47 +0,0 @@ -From b42ad03f9e1fcdd7cac13789038621173f754294 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 21 Mar 2023 02:38:36 +0000 -Subject: [PATCH] hw/audio/intel-hda: fix stream reset mainline inclusion - commit ecd5f2882fdd10f798984eb52abd00ffc78c2ef7 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -Quote from: -High Definition Audio Specification 1.0a, section 3.3.35 - -Offset 80: {IOB}SDnCTL Stream Reset (SRST): Writing a 1 causes -the corresponding stream to be reset. The Stream Descriptor -registers (except the SRST bit itself) ... are reset. - -Change the code to reset the Stream Descriptor Control and Status -registers except the SRST bit. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/757 -Signed-off-by: Volker Rümelin -Message-Id: <20211226154017.6067-3-vr_qemu@t-online.de> -Signed-off-by: Gerd Hoffmann - -Signed-off-by: tangbinzy ---- - hw/audio/intel-hda.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c -index 3aa57d274e..78a47bc08c 100644 ---- a/hw/audio/intel-hda.c -+++ b/hw/audio/intel-hda.c -@@ -586,7 +586,7 @@ static void intel_hda_set_st_ctl(IntelHDAState *d, const IntelHDAReg *reg, uint3 - if (st->ctl & 0x01) { - /* reset */ - dprint(d, 1, "st #%d: reset\n", reg->stream); -- st->ctl = SD_STS_FIFO_READY << 24; -+ st->ctl = SD_STS_FIFO_READY << 24 | SD_CTL_STREAM_RESET; - } - if ((st->ctl & 0x02) != (old & 0x02)) { - uint32_t stnr = (st->ctl >> 20) & 0x0f; --- -2.27.0 - diff --git a/hw-block-fdc-Prevent-end-of-track-overrun-CVE-2021-3.patch b/hw-block-fdc-Prevent-end-of-track-overrun-CVE-2021-3.patch deleted file mode 100644 index 99c174c780c89c4a540935a14fcb3e876c9e707b..0000000000000000000000000000000000000000 --- a/hw-block-fdc-Prevent-end-of-track-overrun-CVE-2021-3.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 4c72f406e3ff02844977fcd8bc696080088d3d08 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 18 Nov 2021 12:57:32 +0100 -Subject: [PATCH 5/6] hw/block/fdc: Prevent end-of-track overrun - (CVE-2021-3507) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Per the 82078 datasheet, if the end-of-track (EOT byte in -the FIFO) is more than the number of sectors per side, the -command is terminated unsuccessfully: - -* 5.2.5 DATA TRANSFER TERMINATION - - The 82078 supports terminal count explicitly through - the TC pin and implicitly through the underrun/over- - run and end-of-track (EOT) functions. For full sector - transfers, the EOT parameter can define the last - sector to be transferred in a single or multisector - transfer. If the last sector to be transferred is a par- - tial sector, the host can stop transferring the data in - mid-sector, and the 82078 will continue to complete - the sector as if a hardware TC was received. The - only difference between these implicit functions and - TC is that they return "abnormal termination" result - status. Such status indications can be ignored if they - were expected. - -* 6.1.3 READ TRACK - - This command terminates when the EOT specified - number of sectors have been read. If the 82078 - does not find an I D Address Mark on the diskette - after the second· occurrence of a pulse on the - INDX# pin, then it sets the IC code in Status Regis- - ter 0 to "01" (Abnormal termination), sets the MA bit - in Status Register 1 to "1", and terminates the com- - mand. - -* 6.1.6 VERIFY - - Refer to Table 6-6 and Table 6-7 for information - concerning the values of MT and EC versus SC and - EOT value. - -* Table 6·6. Result Phase Table - -* Table 6-7. Verify Command Result Phase Table - -Fix by aborting the transfer when EOT > # Sectors Per Side. - -Cc: qemu-stable@nongnu.org -Cc: Hervé Poussineau -Fixes: baca51faff0 ("floppy driver: disk geometry auto detect") -Reported-by: Alexander Bulekov -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/339 -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211118115733.4038610-2-philmd@redhat.com> -Reviewed-by: Hanna Reitz -Signed-off-by: Kevin Wolf ---- - hw/block/fdc.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/block/fdc.c b/hw/block/fdc.c -index 21d18ac2e3..24b05406e6 100644 ---- a/hw/block/fdc.c -+++ b/hw/block/fdc.c -@@ -1529,6 +1529,14 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction) - int tmp; - fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]); - tmp = (fdctrl->fifo[6] - ks + 1); -+ if (tmp < 0) { -+ FLOPPY_DPRINTF("invalid EOT: %d\n", tmp); -+ fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00); -+ fdctrl->fifo[3] = kt; -+ fdctrl->fifo[4] = kh; -+ fdctrl->fifo[5] = ks; -+ return; -+ } - if (fdctrl->fifo[0] & 0x80) - tmp += fdctrl->fifo[6]; - fdctrl->data_len *= tmp; --- -2.27.0 - diff --git a/hw-char-fix-qcode-array-bounds-check-in-ESCC-impl.patch b/hw-char-fix-qcode-array-bounds-check-in-ESCC-impl.patch deleted file mode 100644 index 9a00eb1be6f93ff6a03e40d44b1226b69c53070b..0000000000000000000000000000000000000000 --- a/hw-char-fix-qcode-array-bounds-check-in-ESCC-impl.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 308cd236694ac13e2c45293b670b536b63765e62 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 4 Sep 2023 07:27:24 +0000 -Subject: [PATCH] hw/char: fix qcode array bounds check in ESCC impl mainline - inclusion commit 9aaf11e7f2b5487b684e900cf164f0aef25f72ab category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -There was an off-by-1 in the qcode conversion array bounds -check. - -Fixes: e709a61a8fe1076a487376fd657544418a38ba06 -Reported-by: Peter Maydell -Reviewed-by: Peter Maydell -Signed-off-by: Daniel P. Berrangé - -Signed-off-by: tangbinzy ---- - hw/char/escc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/char/escc.c b/hw/char/escc.c -index 8755d8d34f..17a908c59b 100644 ---- a/hw/char/escc.c -+++ b/hw/char/escc.c -@@ -828,7 +828,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src, - } - } - -- if (qcode > qemu_input_map_qcode_to_sun_len) { -+ if (qcode >= qemu_input_map_qcode_to_sun_len) { - return; - } - --- -2.41.0.windows.1 - diff --git a/hw-char-pl011-fix-baud-rate-calculation.patch b/hw-char-pl011-fix-baud-rate-calculation.patch deleted file mode 100644 index 1921910ab02423536971975c965b3aa3c89ec5f4..0000000000000000000000000000000000000000 --- a/hw-char-pl011-fix-baud-rate-calculation.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 07639839666f134834b060a63d6b172812092366 Mon Sep 17 00:00:00 2001 -From: cmss_dx -Date: Mon, 28 Nov 2022 02:50:07 +0000 -Subject: [PATCH 28/29] hw/char/pl011: fix baud rate calculation mainline - inclusion from mainline-v7.2.0-rc2 commit - 31cb769c317e0623cbe2a3e8da437b6cd7ddef9b category: bugfix - --------------------------------- - -The PL011 TRM says that "UARTIBRD = 0 is invalid and UARTFBRD is ignored -when this is the case". But the code looks at FBRD for the invalid case. -Fix this. - -Signed-off-by: Baruch Siach -Message-id: 1408f62a2e45665816527d4845ffde650957d5ab.1665051588.git.baruchs-c@neureality.ai -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell - -Signed-off-by: cmss_dx ---- - hw/char/pl011.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/char/pl011.c b/hw/char/pl011.c -index 8ca2a4ed68..b24ccfeac7 100644 ---- a/hw/char/pl011.c -+++ b/hw/char/pl011.c -@@ -176,7 +176,7 @@ static unsigned int pl011_get_baudrate(const PL011State *s) - { - uint64_t clk; - -- if (s->fbrd == 0) { -+ if (s->ibrd == 0) { - return 0; - } - --- -2.27.0 - diff --git a/hw-core-Rename-smp_parse-machine_parse_smp_config.patch b/hw-core-Rename-smp_parse-machine_parse_smp_config.patch deleted file mode 100644 index 8537cc6adec12daacbd87f61ab6e36656117c8b0..0000000000000000000000000000000000000000 --- a/hw-core-Rename-smp_parse-machine_parse_smp_config.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 2ce1daae407033e689a559b7346523b18651ee0a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 11 Nov 2021 10:21:23 +0100 -Subject: [PATCH 09/24] hw/core: Rename smp_parse() -> - machine_parse_smp_config() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -All methods related to MachineState are prefixed with "machine_". -smp_parse() does not need to be an exception. Rename it and -const'ify the SMPConfiguration argument, since it doesn't need -to be modified. - -Reviewed-by: Andrew Jones -Reviewed-by: Richard Henderson -Reviewed-by: Yanan Wang -Tested-by: Yanan Wang -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211216132015.815493-9-philmd@redhat.com> ---- - hw/core/machine-smp.c | 6 ++++-- - hw/core/machine.c | 2 +- - include/hw/boards.h | 3 ++- - tests/unit/test-smp-parse.c | 8 ++++---- - 4 files changed, 11 insertions(+), 8 deletions(-) - -diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c -index 116a0cbbfa..2cbfd57429 100644 ---- a/hw/core/machine-smp.c -+++ b/hw/core/machine-smp.c -@@ -44,7 +44,8 @@ static char *cpu_hierarchy_to_string(MachineState *ms) - } - - /* -- * smp_parse - Generic function used to parse the given SMP configuration -+ * machine_parse_smp_config: Generic function used to parse the given -+ * SMP configuration - * - * Any missing parameter in "cpus/maxcpus/sockets/cores/threads" will be - * automatically computed based on the provided ones. -@@ -63,7 +64,8 @@ static char *cpu_hierarchy_to_string(MachineState *ms) - * introduced topology members which are likely to be target specific should - * be directly set as 1 if they are omitted (e.g. dies for PC since 4.1). - */ --void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp) -+void machine_parse_smp_config(MachineState *ms, -+ const SMPConfiguration *config, Error **errp) - { - MachineClass *mc = MACHINE_GET_CLASS(ms); - unsigned cpus = config->has_cpus ? config->cpus : 0; -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 53a99abc56..3993c534b9 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -761,7 +761,7 @@ static void machine_set_smp(Object *obj, Visitor *v, const char *name, - return; - } - -- smp_parse(ms, config, errp); -+ machine_parse_smp_config(ms, config, errp); - } - - static void machine_class_init(ObjectClass *oc, void *data) -diff --git a/include/hw/boards.h b/include/hw/boards.h -index 9c1c190104..7597cec440 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -34,7 +34,8 @@ HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine); - void machine_set_cpu_numa_node(MachineState *machine, - const CpuInstanceProperties *props, - Error **errp); --void smp_parse(MachineState *ms, SMPConfiguration *config, Error **errp); -+void machine_parse_smp_config(MachineState *ms, -+ const SMPConfiguration *config, Error **errp); - - /** - * machine_class_allow_dynamic_sysbus_dev: Add type to list of valid devices -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index 0f98c9509e..b6df8137fc 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -337,7 +337,7 @@ static const struct SMPTestData data_with_dies_invalid[] = { - }, - }; - --static char *smp_config_to_string(SMPConfiguration *config) -+static char *smp_config_to_string(const SMPConfiguration *config) - { - return g_strdup_printf( - "(SMPConfiguration) {\n" -@@ -371,7 +371,7 @@ static char *cpu_topology_to_string(const CpuTopology *topo) - topo->cores, topo->threads, topo->max_cpus); - } - --static void check_parse(MachineState *ms, SMPConfiguration *config, -+static void check_parse(MachineState *ms, const SMPConfiguration *config, - const CpuTopology *expect_topo, const char *expect_err, - bool is_valid) - { -@@ -380,8 +380,8 @@ static void check_parse(MachineState *ms, SMPConfiguration *config, - g_autofree char *output_topo_str = NULL; - Error *err = NULL; - -- /* call the generic parser smp_parse() */ -- smp_parse(ms, config, &err); -+ /* call the generic parser */ -+ machine_parse_smp_config(ms, config, &err); - - output_topo_str = cpu_topology_to_string(&ms->smp); - --- -2.27.0 - diff --git a/hw-core-machine-Fix-the-missing-consideration-of-clu.patch b/hw-core-machine-Fix-the-missing-consideration-of-clu.patch deleted file mode 100644 index 5adcd2b3bd0c91f274a000b76d15c76f45c51ae4..0000000000000000000000000000000000000000 --- a/hw-core-machine-Fix-the-missing-consideration-of-clu.patch +++ /dev/null @@ -1,85 +0,0 @@ -From bbf1fc67fb642833a23793081e812c36691c4df6 Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Mon, 6 Mar 2023 20:50:33 +0800 -Subject: [PATCH] hw/core/machine:Fix the missing consideration of cluster-id - -Commit 5454c00908236 introduced the cluster-id for CPU -topology parameter "cluster", but has not fully considered -all the areas where we need to check cluster-id, e.g, when -assigning CPUs to numa nodes. - -If we have multiple clusters and multiple numa nodes for -a guest like below: --smp cpus=8,maxcpus=8,sockets=1,dies=1,clusters=2,cores=4,threads=1 --numa node nodeid=0,cpus=0-3 --numa node nodeid=1,cpus=4-7 -QEMU will wrongly assign all the CPUs to numa0, because there -is no check about cluster_id of each CPU in function -machine_set_cpu_numa_node. Fix it. - -Also, fix some other areas which missed to verified cluster-id. - -Fixes: 5454c00908236 ("arm/virt: Add CPU topology support") -Signed-off-by: Yanan Wang ---- - hw/core/machine-hmp-cmds.c | 3 +++ - hw/core/machine.c | 15 +++++++++++++++ - 2 files changed, 18 insertions(+) - -diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c -index 4e2f319aeb..c4f63b1d63 100644 ---- a/hw/core/machine-hmp-cmds.c -+++ b/hw/core/machine-hmp-cmds.c -@@ -77,6 +77,9 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict) - if (c->has_die_id) { - monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id); - } -+ if (c->has_cluster_id) { -+ monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n", c->cluster_id); -+ } - if (c->has_core_id) { - monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id); - } -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 45fb0fd2eb..cb539104a1 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -686,6 +686,11 @@ void machine_set_cpu_numa_node(MachineState *machine, - return; - } - -+ if (props->has_cluster_id && !slot->props.has_cluster_id) { -+ error_setg(errp, "cluster-id is not supported"); -+ return; -+ } -+ - /* skip slots with explicit mismatch */ - if (props->has_thread_id && props->thread_id != slot->props.thread_id) { - continue; -@@ -695,6 +700,10 @@ void machine_set_cpu_numa_node(MachineState *machine, - continue; - } - -+ if (props->has_cluster_id && props->cluster_id != slot->props.cluster_id) { -+ continue; -+ } -+ - if (props->has_die_id && props->die_id != slot->props.die_id) { - continue; - } -@@ -989,6 +998,12 @@ static char *cpu_slot_to_string(const CPUArchId *cpu) - } - g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id); - } -+ if (cpu->props.has_cluster_id) { -+ if (s->len) { -+ g_string_append_printf(s, ", "); -+ } -+ g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id); -+ } - if (cpu->props.has_core_id) { - if (s->len) { - g_string_append_printf(s, ", "); --- -2.27.0 - diff --git a/hw-core-machine-Introduce-CPU-cluster-topology-suppo.patch b/hw-core-machine-Introduce-CPU-cluster-topology-suppo.patch deleted file mode 100644 index 39956fbd8ae741e31fdf2c4a2eca362a6ec9f891..0000000000000000000000000000000000000000 --- a/hw-core-machine-Introduce-CPU-cluster-topology-suppo.patch +++ /dev/null @@ -1,283 +0,0 @@ -From bf4a20a82bd4804842dd2960db30e0be7ecb2d32 Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Tue, 28 Dec 2021 17:22:09 +0800 -Subject: [PATCH 11/24] hw/core/machine: Introduce CPU cluster topology support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The new Cluster-Aware Scheduling support has landed in Linux 5.16, -which has been proved to benefit the scheduling performance (e.g. -load balance and wake_affine strategy) on both x86_64 and AArch64. - -So now in Linux 5.16 we have four-level arch-neutral CPU topology -definition like below and a new scheduler level for clusters. -struct cpu_topology { - int thread_id; - int core_id; - int cluster_id; - int package_id; - int llc_id; - cpumask_t thread_sibling; - cpumask_t core_sibling; - cpumask_t cluster_sibling; - cpumask_t llc_sibling; -} - -A cluster generally means a group of CPU cores which share L2 cache -or other mid-level resources, and it is the shared resources that -is used to improve scheduler's behavior. From the point of view of -the size range, it's between CPU die and CPU core. For example, on -some ARM64 Kunpeng servers, we have 6 clusters in each NUMA node, -and 4 CPU cores in each cluster. The 4 CPU cores share a separate -L2 cache and a L3 cache tag, which brings cache affinity advantage. - -In virtualization, on the Hosts which have pClusters (physical -clusters), if we can design a vCPU topology with cluster level for -guest kernel and have a dedicated vCPU pinning. A Cluster-Aware -Guest kernel can also make use of the cache affinity of CPU clusters -to gain similar scheduling performance. - -This patch adds infrastructure for CPU cluster level topology -configuration and parsing, so that the user can specify cluster -parameter if their machines support it. - -Signed-off-by: Yanan Wang -Message-Id: <20211228092221.21068-3-wangyanan55@huawei.com> -Reviewed-by: Philippe Mathieu-Daudé -[PMD: Added '(since 7.0)' to @clusters in qapi/machine.json] -Signed-off-by: Philippe Mathieu-Daudé ---- - hw/core/machine-smp.c | 26 +++++++++++++++++++------- - hw/core/machine.c | 3 +++ - include/hw/boards.h | 6 +++++- - qapi/machine.json | 5 ++++- - qemu-options.hx | 7 ++++--- - softmmu/vl.c | 3 +++ - 6 files changed, 38 insertions(+), 12 deletions(-) - -diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c -index 2cbfd57429..b39ed21e65 100644 ---- a/hw/core/machine-smp.c -+++ b/hw/core/machine-smp.c -@@ -37,6 +37,10 @@ static char *cpu_hierarchy_to_string(MachineState *ms) - g_string_append_printf(s, " * dies (%u)", ms->smp.dies); - } - -+ if (mc->smp_props.clusters_supported) { -+ g_string_append_printf(s, " * clusters (%u)", ms->smp.clusters); -+ } -+ - g_string_append_printf(s, " * cores (%u)", ms->smp.cores); - g_string_append_printf(s, " * threads (%u)", ms->smp.threads); - -@@ -71,6 +75,7 @@ void machine_parse_smp_config(MachineState *ms, - unsigned cpus = config->has_cpus ? config->cpus : 0; - unsigned sockets = config->has_sockets ? config->sockets : 0; - unsigned dies = config->has_dies ? config->dies : 0; -+ unsigned clusters = config->has_clusters ? config->clusters : 0; - unsigned cores = config->has_cores ? config->cores : 0; - unsigned threads = config->has_threads ? config->threads : 0; - unsigned maxcpus = config->has_maxcpus ? config->maxcpus : 0; -@@ -82,6 +87,7 @@ void machine_parse_smp_config(MachineState *ms, - if ((config->has_cpus && config->cpus == 0) || - (config->has_sockets && config->sockets == 0) || - (config->has_dies && config->dies == 0) || -+ (config->has_clusters && config->clusters == 0) || - (config->has_cores && config->cores == 0) || - (config->has_threads && config->threads == 0) || - (config->has_maxcpus && config->maxcpus == 0)) { -@@ -97,8 +103,13 @@ void machine_parse_smp_config(MachineState *ms, - error_setg(errp, "dies not supported by this machine's CPU topology"); - return; - } -+ if (!mc->smp_props.clusters_supported && clusters > 1) { -+ error_setg(errp, "clusters not supported by this machine's CPU topology"); -+ return; -+ } - - dies = dies > 0 ? dies : 1; -+ clusters = clusters > 0 ? clusters : 1; - - /* compute missing values based on the provided ones */ - if (cpus == 0 && maxcpus == 0) { -@@ -113,41 +124,42 @@ void machine_parse_smp_config(MachineState *ms, - if (sockets == 0) { - cores = cores > 0 ? cores : 1; - threads = threads > 0 ? threads : 1; -- sockets = maxcpus / (dies * cores * threads); -+ sockets = maxcpus / (dies * clusters * cores * threads); - } else if (cores == 0) { - threads = threads > 0 ? threads : 1; -- cores = maxcpus / (sockets * dies * threads); -+ cores = maxcpus / (sockets * dies * clusters * threads); - } - } else { - /* prefer cores over sockets since 6.2 */ - if (cores == 0) { - sockets = sockets > 0 ? sockets : 1; - threads = threads > 0 ? threads : 1; -- cores = maxcpus / (sockets * dies * threads); -+ cores = maxcpus / (sockets * dies * clusters * threads); - } else if (sockets == 0) { - threads = threads > 0 ? threads : 1; -- sockets = maxcpus / (dies * cores * threads); -+ sockets = maxcpus / (dies * clusters * cores * threads); - } - } - - /* try to calculate omitted threads at last */ - if (threads == 0) { -- threads = maxcpus / (sockets * dies * cores); -+ threads = maxcpus / (sockets * dies * clusters * cores); - } - } - -- maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * cores * threads; -+ maxcpus = maxcpus > 0 ? maxcpus : sockets * dies * clusters * cores * threads; - cpus = cpus > 0 ? cpus : maxcpus; - - ms->smp.cpus = cpus; - ms->smp.sockets = sockets; - ms->smp.dies = dies; -+ ms->smp.clusters = clusters; - ms->smp.cores = cores; - ms->smp.threads = threads; - ms->smp.max_cpus = maxcpus; - - /* sanity-check of the computed topology */ -- if (sockets * dies * cores * threads != maxcpus) { -+ if (sockets * dies * clusters * cores * threads != maxcpus) { - g_autofree char *topo_msg = cpu_hierarchy_to_string(ms); - error_setg(errp, "Invalid CPU topology: " - "product of the hierarchy must match maxcpus: " -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 3993c534b9..a4a2df405f 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -742,10 +742,12 @@ static void machine_get_smp(Object *obj, Visitor *v, const char *name, - .has_cpus = true, .cpus = ms->smp.cpus, - .has_sockets = true, .sockets = ms->smp.sockets, - .has_dies = true, .dies = ms->smp.dies, -+ .has_clusters = true, .clusters = ms->smp.clusters, - .has_cores = true, .cores = ms->smp.cores, - .has_threads = true, .threads = ms->smp.threads, - .has_maxcpus = true, .maxcpus = ms->smp.max_cpus, - }; -+ - if (!visit_type_SMPConfiguration(v, name, &config, &error_abort)) { - return; - } -@@ -932,6 +934,7 @@ static void machine_initfn(Object *obj) - ms->smp.max_cpus = mc->default_cpus; - ms->smp.sockets = 1; - ms->smp.dies = 1; -+ ms->smp.clusters = 1; - ms->smp.cores = 1; - ms->smp.threads = 1; - } -diff --git a/include/hw/boards.h b/include/hw/boards.h -index 7597cec440..f49a2578ea 100644 ---- a/include/hw/boards.h -+++ b/include/hw/boards.h -@@ -129,10 +129,12 @@ typedef struct { - * SMPCompatProps: - * @prefer_sockets - whether sockets are preferred over cores in smp parsing - * @dies_supported - whether dies are supported by the machine -+ * @clusters_supported - whether clusters are supported by the machine - */ - typedef struct { - bool prefer_sockets; - bool dies_supported; -+ bool clusters_supported; - } SMPCompatProps; - - /** -@@ -299,7 +301,8 @@ typedef struct DeviceMemoryState { - * @cpus: the number of present logical processors on the machine - * @sockets: the number of sockets on the machine - * @dies: the number of dies in one socket -- * @cores: the number of cores in one die -+ * @clusters: the number of clusters in one die -+ * @cores: the number of cores in one cluster - * @threads: the number of threads in one core - * @max_cpus: the maximum number of logical processors on the machine - */ -@@ -307,6 +310,7 @@ typedef struct CpuTopology { - unsigned int cpus; - unsigned int sockets; - unsigned int dies; -+ unsigned int clusters; - unsigned int cores; - unsigned int threads; - unsigned int max_cpus; -diff --git a/qapi/machine.json b/qapi/machine.json -index f1839acf20..8faa51074e 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -1396,7 +1396,9 @@ - # - # @dies: number of dies per socket in the CPU topology - # --# @cores: number of cores per die in the CPU topology -+# @clusters: number of clusters per die in the CPU topology (since 7.0) -+# -+# @cores: number of cores per cluster in the CPU topology - # - # @threads: number of threads per core in the CPU topology - # -@@ -1408,6 +1410,7 @@ - '*cpus': 'int', - '*sockets': 'int', - '*dies': 'int', -+ '*clusters': 'int', - '*cores': 'int', - '*threads': 'int', - '*maxcpus': 'int' } } -diff --git a/qemu-options.hx b/qemu-options.hx -index 7a59db7764..0f26f7dad7 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -206,13 +206,14 @@ SRST - ERST - - DEF("smp", HAS_ARG, QEMU_OPTION_smp, -- "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]\n" -+ "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]\n" - " set the number of initial CPUs to 'n' [default=1]\n" - " maxcpus= maximum number of total CPUs, including\n" - " offline CPUs for hotplug, etc\n" - " sockets= number of sockets on the machine board\n" - " dies= number of dies in one socket\n" -- " cores= number of cores in one die\n" -+ " clusters= number of clusters in one die\n" -+ " cores= number of cores in one cluster\n" - " threads= number of threads in one core\n" - "Note: Different machines may have different subsets of the CPU topology\n" - " parameters supported, so the actual meaning of the supported parameters\n" -@@ -228,7 +229,7 @@ DEF("smp", HAS_ARG, QEMU_OPTION_smp, - " must be set as 1 in the purpose of correct parsing.\n", - QEMU_ARCH_ALL) - SRST --``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]`` -+``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]`` - Simulate a SMP system with '\ ``n``\ ' CPUs initially present on - the machine type board. On boards supporting CPU hotplug, the optional - '\ ``maxcpus``\ ' parameter can be set to enable further CPUs to be -diff --git a/softmmu/vl.c b/softmmu/vl.c -index 620a1f1367..d9e4c619d3 100644 ---- a/softmmu/vl.c -+++ b/softmmu/vl.c -@@ -726,6 +726,9 @@ static QemuOptsList qemu_smp_opts = { - }, { - .name = "dies", - .type = QEMU_OPT_NUMBER, -+ }, { -+ .name = "clusters", -+ .type = QEMU_OPT_NUMBER, - }, { - .name = "cores", - .type = QEMU_OPT_NUMBER, --- -2.27.0 - diff --git a/hw-core-resettable-fix-reset-level-counting.patch b/hw-core-resettable-fix-reset-level-counting.patch deleted file mode 100644 index 9c17651df636f6a23b99f27ca937330c1b9a9751..0000000000000000000000000000000000000000 --- a/hw-core-resettable-fix-reset-level-counting.patch +++ /dev/null @@ -1,82 +0,0 @@ -From a6943e9033df97862b3ec0438ec85ff0abfb59c0 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Fri, 25 Nov 2022 09:44:11 +0800 -Subject: [PATCH 20/29] hw/core/resettable: fix reset level counting - -The code for handling the reset level count in the Resettable code -has two issues: -The reset count is only decremented for the 1->0 case. This means -that if there's ever a nested reset that takes the count to 2 then it -will never again be decremented. Eventually the count will exceed -the '50' limit in resettable_phase_enter() and QEMU will trip over -the assertion failure. The repro case in issue 1266 is an example of -this that happens now the SCSI subsystem uses three-phase reset. -Secondly, the count is decremented only after the exit phase handler -is called. Moving the reset count decrement from "just after" to -"just before" calling the exit phase handler allows -resettable_is_in_reset() to return false during the handler -execution. -This simplifies reset handling in resettable devices. Typically, a -function that updates the device state will just need to read the -current reset state and not anymore treat the "in a reset-exit -transition" as a special case. -Note that the semantics change to the *_is_in_reset() functions -will have no effect on the current codebase, because only two -devices (hw/char/cadence_uart.c and hw/misc/zynq_sclr.c) currently -call those functions, and in neither case do they do it from the -device's exit phase methed. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1266 -Signed-off-by: Damien Hedde -Buglink: https://bugs.launchpad.net/qemu/+bug/1905297 -Reported-by: Michael Peter -[PMM: adjust the docs paragraph changed to get the name of the - 'enter' phase right and to clarify exactly when the count is - adjusted; rewrite the commit message] -Signed-off-by: Peter Maydell -Signed-off-by: jianchunfu ---- - docs/devel/reset.rst | 8 +++++--- - hw/core/resettable.c | 3 +-- - 2 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/docs/devel/reset.rst b/docs/devel/reset.rst -index abea1102dc..7cc6a6b314 100644 ---- a/docs/devel/reset.rst -+++ b/docs/devel/reset.rst -@@ -210,9 +210,11 @@ Polling the reset state - Resettable interface provides the ``resettable_is_in_reset()`` function. - This function returns true if the object parameter is currently under reset. - --An object is under reset from the beginning of the *init* phase to the end of --the *exit* phase. During all three phases, the function will return that the --object is in reset. -+An object is under reset from the beginning of the *enter* phase (before -+either its children or its own enter method is called) to the *exit* -+phase. During *enter* and *hold* phase only, the function will return that the -+object is in reset. The state is changed after the *exit* is propagated to -+its children and just before calling the object's own *exit* method. - - This function may be used if the object behavior has to be adapted - while in reset state. For example if a device has an irq input, -diff --git a/hw/core/resettable.c b/hw/core/resettable.c -index 96a99ce39e..c3df75c6ba 100644 ---- a/hw/core/resettable.c -+++ b/hw/core/resettable.c -@@ -201,12 +201,11 @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type) - resettable_child_foreach(rc, obj, resettable_phase_exit, NULL, type); - - assert(s->count > 0); -- if (s->count == 1) { -+ if (--s->count == 0) { - trace_resettable_phase_exit_exec(obj, obj_typename, !!rc->phases.exit); - if (rc->phases.exit && !resettable_get_tr_func(rc, obj)) { - rc->phases.exit(obj); - } -- s->count = 0; - } - s->exit_phase_in_progress = false; - trace_resettable_phase_exit_end(obj, obj_typename, s->count); --- -2.27.0 - diff --git a/hw-display-ati_2d-Fix-buffer-overflow-in-ati_2d_blt-.patch b/hw-display-ati_2d-Fix-buffer-overflow-in-ati_2d_blt-.patch deleted file mode 100644 index 8f865075327b7885677c8da4bfc7b57e9e2281f9..0000000000000000000000000000000000000000 --- a/hw-display-ati_2d-Fix-buffer-overflow-in-ati_2d_blt-.patch +++ /dev/null @@ -1,83 +0,0 @@ -From d1d13b1f86a5ac0520dc7369873d6478b583af04 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Mon, 6 Sep 2021 17:31:03 +0200 -Subject: [PATCH 6/6] hw/display/ati_2d: Fix buffer overflow in ati_2d_blt - (CVE-2021-3638) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When building QEMU with DEBUG_ATI defined then running with -'-device ati-vga,romfile="" -d unimp,guest_errors -trace ati\*' -we get: - - ati_mm_write 4 0x16c0 DP_CNTL <- 0x1 - ati_mm_write 4 0x146c DP_GUI_MASTER_CNTL <- 0x2 - ati_mm_write 4 0x16c8 DP_MIX <- 0xff0000 - ati_mm_write 4 0x16c4 DP_DATATYPE <- 0x2 - ati_mm_write 4 0x224 CRTC_OFFSET <- 0x0 - ati_mm_write 4 0x142c DST_PITCH_OFFSET <- 0xfe00000 - ati_mm_write 4 0x1420 DST_Y <- 0x3fff - ati_mm_write 4 0x1410 DST_HEIGHT <- 0x3fff - ati_mm_write 4 0x1588 DST_WIDTH_X <- 0x3fff3fff - ati_2d_blt: vram:0x7fff5fa00000 addr:0 ds:0x7fff61273800 stride:2560 bpp:32 rop:0xff - ati_2d_blt: 0 0 0, 0 127 0, (0,0) -> (16383,16383) 16383x16383 > ^ - ati_2d_blt: pixman_fill(dst:0x7fff5fa00000, stride:254, bpp:8, x:16383, y:16383, w:16383, h:16383, xor:0xff000000) - Thread 3 "qemu-system-i38" received signal SIGSEGV, Segmentation fault. - (gdb) bt - #0 0x00007ffff7f62ce0 in sse2_fill.lto_priv () at /lib64/libpixman-1.so.0 - #1 0x00007ffff7f09278 in pixman_fill () at /lib64/libpixman-1.so.0 - #2 0x0000555557b5a9af in ati_2d_blt (s=0x631000028800) at hw/display/ati_2d.c:196 - #3 0x0000555557b4b5a2 in ati_mm_write (opaque=0x631000028800, addr=5512, data=1073692671, size=4) at hw/display/ati.c:843 - #4 0x0000555558b90ec4 in memory_region_write_accessor (mr=0x631000039cc0, addr=5512, ..., size=4, ...) at softmmu/memory.c:492 - -Commit 584acf34cb0 ("ati-vga: Fix reverse bit blts") introduced -the local dst_x and dst_y which adjust the (x, y) coordinates -depending on the direction in the SRCCOPY ROP3 operation, but -forgot to address the same issue for the PATCOPY, BLACKNESS and -WHITENESS operations, which also call pixman_fill(). - -Fix that now by using the adjusted coordinates in the pixman_fill -call, and update the related debug printf(). - -Reported-by: Qiang Liu -Fixes: 584acf34cb0 ("ati-vga: Fix reverse bit blts") -Signed-off-by: Philippe Mathieu-Daudé -Tested-by: Mauro Matteo Cascella -Message-Id: <20210906153103.1661195-1-philmd@redhat.com> -Signed-off-by: Gerd Hoffmann -Signed-off-by: wanbo ---- - hw/display/ati_2d.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c -index 4dc10ea795..692bec91de 100644 ---- a/hw/display/ati_2d.c -+++ b/hw/display/ati_2d.c -@@ -84,7 +84,7 @@ void ati_2d_blt(ATIVGAState *s) - DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d %c %c\n", - s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset, - s->regs.src_pitch, s->regs.dst_pitch, s->regs.default_pitch, -- s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y, -+ s->regs.src_x, s->regs.src_y, dst_x, dst_y, - s->regs.dst_width, s->regs.dst_height, - (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? '>' : '<'), - (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? 'v' : '^')); -@@ -180,11 +180,11 @@ void ati_2d_blt(ATIVGAState *s) - dst_stride /= sizeof(uint32_t); - DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n", - dst_bits, dst_stride, bpp, -- s->regs.dst_x, s->regs.dst_y, -+ dst_x, dst_y, - s->regs.dst_width, s->regs.dst_height, - filler); - pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, -- s->regs.dst_x, s->regs.dst_y, -+ dst_x, dst_y, - s->regs.dst_width, s->regs.dst_height, - filler); - if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr && --- -2.27.0 - diff --git a/hw-display-next-fb-Fix-comment-typo.patch b/hw-display-next-fb-Fix-comment-typo.patch deleted file mode 100644 index f23a0732040f7dab84df7f2daa7a24c8e84f8482..0000000000000000000000000000000000000000 --- a/hw-display-next-fb-Fix-comment-typo.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7252e8e0f5a4c43854efa3e31071a678f4e61d37 Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 01:49:31 -0800 -Subject: [PATCH] hw/display/next-fb: Fix comment typo -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit c1966f515d9bb6d8ed7076f4bebdc45407700100 - -Signed-off-by: Evgeny Ermakov -Message-Id: <20221125160849.23711-1-evgeny.v.ermakov@gmail.com> -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Peter Maydell -Signed-off-by: Thomas Huth -Signed-off-by: Wanghe Xiao ---- - hw/display/next-fb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/display/next-fb.c b/hw/display/next-fb.c -index dd6a1aa8ae..8446ff3c00 100644 ---- a/hw/display/next-fb.c -+++ b/hw/display/next-fb.c -@@ -126,7 +126,7 @@ static void nextfb_class_init(ObjectClass *oc, void *data) - set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); - dc->realize = nextfb_realize; - -- /* Note: This device does not any state that we have to reset or migrate */ -+ /* Note: This device does not have any state that we have to reset or migrate */ - } - - static const TypeInfo nextfb_info = { --- -2.27.0 - diff --git a/hw-display-qxl-Assert-memory-slot-fits-in-preallocat.patch b/hw-display-qxl-Assert-memory-slot-fits-in-preallocat.patch deleted file mode 100644 index ac6fa16c5fddff9f37e3babd328d60d29229b9c5..0000000000000000000000000000000000000000 --- a/hw-display-qxl-Assert-memory-slot-fits-in-preallocat.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ff99b327473454e3be7a89554ccbae856bcb7e3b Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Mon, 5 Dec 2022 16:09:13 +0800 -Subject: [PATCH 17/17] hw/display/qxl: Assert memory slot fits in preallocated - MemoryRegion -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Assert memory slot fits in preallocated MemoryRegion. - -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: Stefan Hajnoczi -Signed-off-by: jianchunfu ---- - hw/display/qxl.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/display/qxl.c b/hw/display/qxl.c -index 2a4b2d4158..bcd9e8716a 100644 ---- a/hw/display/qxl.c -+++ b/hw/display/qxl.c -@@ -1372,6 +1372,7 @@ static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, - qxl_set_guest_bug(d, "%s: pci_region = %d", __func__, pci_region); - return 1; - } -+ assert(guest_end - pci_start <= memory_region_size(mr)); - - virt_start = (intptr_t)memory_region_get_ram_ptr(mr); - memslot.slot_id = slot_id; --- -2.27.0 - diff --git a/hw-display-qxl-Avoid-buffer-overrun-in-qxl_phys2virt.patch b/hw-display-qxl-Avoid-buffer-overrun-in-qxl_phys2virt.patch deleted file mode 100644 index befedd54b6ae7836a30e5df1f7950c697428fb86..0000000000000000000000000000000000000000 --- a/hw-display-qxl-Avoid-buffer-overrun-in-qxl_phys2virt.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0c4e22da6bd0d2c15e53cb0b38f13ef11a3bd370 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Mon, 5 Dec 2022 16:24:43 +0800 -Subject: [PATCH 16/17] hw/display/qxl: Avoid buffer overrun in qxl_phys2virt - (CVE-2022-4144) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Have qxl_get_check_slot_offset() return false if the requested -buffer size does not fit within the slot memory region. -Similarly qxl_phys2virt() now returns NULL in such case, and -qxl_dirty_one_surface() aborts. -This avoids buffer overrun in the host pointer returned by -memory_region_get_ram_ptr(). - -Fixes: CVE-2022-4144 (out-of-bounds read) -Reported-by: Wenxu Yin (@awxylitol) -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1336 -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: Stefan Hajnoczi -Signed-off-by: jianchunfu ---- - hw/display/qxl.c | 27 +++++++++++++++++++++++---- - hw/display/qxl.h | 2 +- - 2 files changed, 24 insertions(+), 5 deletions(-) - -diff --git a/hw/display/qxl.c b/hw/display/qxl.c -index aa9065183e..2a4b2d4158 100644 ---- a/hw/display/qxl.c -+++ b/hw/display/qxl.c -@@ -1412,11 +1412,13 @@ static void qxl_reset_surfaces(PCIQXLDevice *d) - - /* can be also called from spice server thread context */ - static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, -- uint32_t *s, uint64_t *o) -+ uint32_t *s, uint64_t *o, -+ size_t size_requested) - { - uint64_t phys = le64_to_cpu(pqxl); - uint32_t slot = (phys >> (64 - 8)) & 0xff; - uint64_t offset = phys & 0xffffffffffff; -+ uint64_t size_available; - - if (slot >= NUM_MEMSLOTS) { - qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot, -@@ -1440,6 +1442,23 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, - slot, offset, qxl->guest_slots[slot].size); - return false; - } -+ size_available = memory_region_size(qxl->guest_slots[slot].mr); -+ if (qxl->guest_slots[slot].offset + offset >= size_available) { -+ qxl_set_guest_bug(qxl, -+ "slot %d offset %"PRIu64" > region size %"PRIu64"\n", -+ slot, qxl->guest_slots[slot].offset + offset, -+ size_available); -+ return false; -+ } -+ size_available -= qxl->guest_slots[slot].offset + offset; -+ if (size_requested > size_available) { -+ qxl_set_guest_bug(qxl, -+ "slot %d offset %"PRIu64" size %zu: " -+ "overrun by %"PRIu64" bytes\n", -+ slot, offset, size_requested, -+ size_requested - size_available); -+ return false; -+ } - - *s = slot; - *o = offset; -@@ -1459,7 +1478,7 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id, - offset = le64_to_cpu(pqxl) & 0xffffffffffff; - return (void *)(intptr_t)offset; - case MEMSLOT_GROUP_GUEST: -- if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset)) { -+ if (!qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size)) { - return NULL; - } - ptr = memory_region_get_ram_ptr(qxl->guest_slots[slot].mr); -@@ -1925,9 +1944,9 @@ static void qxl_dirty_one_surface(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, - uint32_t slot; - bool rc; - -- rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset); -- assert(rc == true); - size = (uint64_t)height * abs(stride); -+ rc = qxl_get_check_slot_offset(qxl, pqxl, &slot, &offset, size); -+ assert(rc == true); - trace_qxl_surfaces_dirty(qxl->id, offset, size); - qxl_set_dirty(qxl->guest_slots[slot].mr, - qxl->guest_slots[slot].offset + offset, -diff --git a/hw/display/qxl.h b/hw/display/qxl.h -index c784315daa..89ca832cf9 100644 ---- a/hw/display/qxl.h -+++ b/hw/display/qxl.h -@@ -157,7 +157,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCIQXLDevice, PCI_QXL) - * - * Returns a host pointer to a buffer placed at offset @phys within the - * active slot @group_id of the PCI VGA RAM memory region associated with -- * the @qxl device. If the slot is inactive, or the offset is out -+ * the @qxl device. If the slot is inactive, or the offset + size are out - * of the memory region, returns NULL. - * - * Use with care; by the time this function returns, the returned pointer is --- -2.27.0 - diff --git a/hw-display-qxl-Document-qxl_phys2virt.patch b/hw-display-qxl-Document-qxl_phys2virt.patch deleted file mode 100644 index de1640d5f2bb08a19e4869d58d6e16e1e784ac0b..0000000000000000000000000000000000000000 --- a/hw-display-qxl-Document-qxl_phys2virt.patch +++ /dev/null @@ -1,49 +0,0 @@ -From c1747d1812a725b424745c6d1b291c176ed67bd3 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Mon, 5 Dec 2022 15:16:31 +0800 -Subject: [PATCH 14/17] hw/display/qxl: Document qxl_phys2virt() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reviewed-by: Marc-André Lureau -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: Stefan Hajnoczi -Signed-off-by: jianchunfu ---- - hw/display/qxl.h | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/hw/display/qxl.h b/hw/display/qxl.h -index 30d21f4d0b..c938f88a2f 100644 ---- a/hw/display/qxl.h -+++ b/hw/display/qxl.h -@@ -147,6 +147,25 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCIQXLDevice, PCI_QXL) - #define QXL_DEFAULT_REVISION (QXL_REVISION_STABLE_V12 + 1) - - /* qxl.c */ -+/** -+ * qxl_phys2virt: Get a pointer within a PCI VRAM memory region. -+ * -+ * @qxl: QXL device -+ * @phys: physical offset of buffer within the VRAM -+ * @group_id: memory slot group -+ * -+ * Returns a host pointer to a buffer placed at offset @phys within the -+ * active slot @group_id of the PCI VGA RAM memory region associated with -+ * the @qxl device. If the slot is inactive, or the offset is out -+ * of the memory region, returns NULL. -+ * -+ * Use with care; by the time this function returns, the returned pointer is -+ * not protected by RCU anymore. If the caller is not within an RCU critical -+ * section and does not hold the iothread lock, it must have other means of -+ * protecting the pointer, such as a reference to the region that includes -+ * the incoming ram_addr_t. -+ * -+ */ - void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); - void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...) - GCC_FMT_ATTR(2, 3); --- -2.27.0 - diff --git a/hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch b/hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch deleted file mode 100644 index bc141323dd8b8b8b7def7410ab2f9839694f0be4..0000000000000000000000000000000000000000 --- a/hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 2f991f98ba28e71ffc2ffdf704ee6568293a8bf0 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Mon, 5 Dec 2022 15:21:45 +0800 -Subject: [PATCH 13/17] hw/display/qxl: Have qxl_log_command Return early if no - log_cmd handler -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Only 3 command types are logged: no need to call qxl_phys2virt() -for the other types. Using different cases will help to pass -different structure sizes to qxl_phys2virt() in a pair of commits. - -Reviewed-by: Marc-André Lureau -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: Stefan Hajnoczi -Signed-off-by: jianchunfu ---- - hw/display/qxl-logger.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c -index 68bfa47568..1bcf803db6 100644 ---- a/hw/display/qxl-logger.c -+++ b/hw/display/qxl-logger.c -@@ -247,6 +247,16 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) - qxl_name(qxl_type, ext->cmd.type), - compat ? "(compat)" : ""); - -+ switch (ext->cmd.type) { -+ case QXL_CMD_DRAW: -+ break; -+ case QXL_CMD_SURFACE: -+ break; -+ case QXL_CMD_CURSOR: -+ break; -+ default: -+ goto out; -+ } - data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); - if (!data) { - return 1; -@@ -269,6 +279,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) - qxl_log_cmd_cursor(qxl, data, ext->group_id); - break; - } -+out: - fprintf(stderr, "\n"); - return 0; - } --- -2.27.0 - diff --git a/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch b/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch deleted file mode 100644 index a923444fcd7db2725da333dd13db0fc1f9b57c97..0000000000000000000000000000000000000000 --- a/hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 21082249be3cb9f5dd000f9d5f84e01548f825c9 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Mon, 5 Dec 2022 16:05:23 +0800 -Subject: [PATCH 15/17] hw/display/qxl: Pass requested buffer size to - qxl_phys2virt() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently qxl_phys2virt() doesn't check for buffer overrun. -In order to do so in the next commit, pass the buffer size -as argument. -For QXLCursor in qxl_render_cursor() -> qxl_cursor() we -verify the size of the chunked data ahead, checking we can -access 'sizeof(QXLCursor) + chunk->data_size' bytes. -Since in the SPICE_CURSOR_TYPE_MONO case the cursor is -assumed to fit in one chunk, no change are required. -In SPICE_CURSOR_TYPE_ALPHA the ahead read is handled in -qxl_unpack_chunks(). - -Signed-off-by: Philippe Mathieu-Daudé -Acked-by: Gerd Hoffmann -Signed-off-by: Stefan Hajnoczi -Signed-off-by: jianchunfu ---- - hw/display/qxl-logger.c | 11 ++++++++--- - hw/display/qxl-render.c | 20 ++++++++++++++++---- - hw/display/qxl.c | 14 +++++++++----- - hw/display/qxl.h | 4 +++- - 4 files changed, 36 insertions(+), 13 deletions(-) - -diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c -index 1bcf803db6..35c38f6252 100644 ---- a/hw/display/qxl-logger.c -+++ b/hw/display/qxl-logger.c -@@ -106,7 +106,7 @@ static int qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id) - QXLImage *image; - QXLImageDescriptor *desc; - -- image = qxl_phys2virt(qxl, addr, group_id); -+ image = qxl_phys2virt(qxl, addr, group_id, sizeof(QXLImage)); - if (!image) { - return 1; - } -@@ -214,7 +214,8 @@ int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id) - cmd->u.set.position.y, - cmd->u.set.visible ? "yes" : "no", - cmd->u.set.shape); -- cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id); -+ cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id, -+ sizeof(QXLCursor)); - if (!cursor) { - return 1; - } -@@ -236,6 +237,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) - { - bool compat = ext->flags & QXL_COMMAND_FLAG_COMPAT; - void *data; -+ size_t datasz; - int ret; - - if (!qxl->cmdlog) { -@@ -249,15 +251,18 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext) - - switch (ext->cmd.type) { - case QXL_CMD_DRAW: -+ datasz = compat ? sizeof(QXLCompatDrawable) : sizeof(QXLDrawable); - break; - case QXL_CMD_SURFACE: -+ datasz = sizeof(QXLSurfaceCmd); - break; - case QXL_CMD_CURSOR: -+ datasz = sizeof(QXLCursorCmd); - break; - default: - goto out; - } -- data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); -+ data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, datasz); - if (!data) { - return 1; - } -diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c -index ca217004bf..fcfd40c3ac 100644 ---- a/hw/display/qxl-render.c -+++ b/hw/display/qxl-render.c -@@ -107,7 +107,9 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl) - qxl->guest_primary.resized = 0; - qxl->guest_primary.data = qxl_phys2virt(qxl, - qxl->guest_primary.surface.mem, -- MEMSLOT_GROUP_GUEST); -+ MEMSLOT_GROUP_GUEST, -+ qxl->guest_primary.abs_stride -+ * height); - if (!qxl->guest_primary.data) { - goto end; - } -@@ -228,7 +230,8 @@ static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl, - if (offset == size) { - return; - } -- chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id); -+ chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id, -+ sizeof(QXLDataChunk) + chunk->data_size); - if (!chunk) { - return; - } -@@ -295,7 +298,8 @@ fail: - /* called from spice server thread context only */ - int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) - { -- QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); -+ QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, -+ sizeof(QXLCursorCmd)); - QXLCursor *cursor; - QEMUCursor *c; - -@@ -314,7 +318,15 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext) - } - switch (cmd->type) { - case QXL_CURSOR_SET: -- cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id); -+ /* First read the QXLCursor to get QXLDataChunk::data_size ... */ -+ cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id, -+ sizeof(QXLCursor)); -+ if (!cursor) { -+ return 1; -+ } -+ /* Then read including the chunked data following QXLCursor. */ -+ cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id, -+ sizeof(QXLCursor) + cursor->chunk.data_size); - if (!cursor) { - return 1; - } -diff --git a/hw/display/qxl.c b/hw/display/qxl.c -index 29c80b4289..aa9065183e 100644 ---- a/hw/display/qxl.c -+++ b/hw/display/qxl.c -@@ -274,7 +274,8 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay) - QXL_IO_MONITORS_CONFIG_ASYNC)); - } - -- cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST); -+ cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, MEMSLOT_GROUP_GUEST, -+ sizeof(QXLMonitorsConfig)); - if (cfg != NULL && cfg->count == 1) { - qxl->guest_primary.resized = 1; - qxl->guest_head0_width = cfg->heads[0].width; -@@ -459,7 +460,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) - switch (le32_to_cpu(ext->cmd.type)) { - case QXL_CMD_SURFACE: - { -- QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); -+ QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, -+ sizeof(QXLSurfaceCmd)); - - if (!cmd) { - return 1; -@@ -494,7 +496,8 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) - } - case QXL_CMD_CURSOR: - { -- QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id); -+ QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id, -+ sizeof(QXLCursorCmd)); - - if (!cmd) { - return 1; -@@ -1444,7 +1447,8 @@ static bool qxl_get_check_slot_offset(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, - } - - /* can be also called from spice server thread context */ --void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id) -+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id, -+ size_t size) - { - uint64_t offset; - uint32_t slot; -@@ -1952,7 +1956,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl) - } - - cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i], -- MEMSLOT_GROUP_GUEST); -+ MEMSLOT_GROUP_GUEST, sizeof(QXLSurfaceCmd)); - assert(cmd); - assert(cmd->type == QXL_SURFACE_CMD_CREATE); - qxl_dirty_one_surface(qxl, cmd->u.surface_create.data, -diff --git a/hw/display/qxl.h b/hw/display/qxl.h -index c938f88a2f..c784315daa 100644 ---- a/hw/display/qxl.h -+++ b/hw/display/qxl.h -@@ -153,6 +153,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCIQXLDevice, PCI_QXL) - * @qxl: QXL device - * @phys: physical offset of buffer within the VRAM - * @group_id: memory slot group -+ * @size: size of the buffer - * - * Returns a host pointer to a buffer placed at offset @phys within the - * active slot @group_id of the PCI VGA RAM memory region associated with -@@ -166,7 +167,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(PCIQXLDevice, PCI_QXL) - * the incoming ram_addr_t. - * - */ --void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); -+void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id, -+ size_t size); - void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...) - GCC_FMT_ATTR(2, 3); - --- -2.27.0 - diff --git a/hw-elf_ops-clear-uninitialized-segment-space.patch b/hw-elf_ops-clear-uninitialized-segment-space.patch deleted file mode 100644 index f502e7dfc43fe6b5dd92139007e7df7c21ebc263..0000000000000000000000000000000000000000 --- a/hw-elf_ops-clear-uninitialized-segment-space.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 081ccc809448bec8e2bf144b2d49e64ed01b0e9f Mon Sep 17 00:00:00 2001 -From: Laurent Vivier -Date: Sat, 15 Jan 2022 21:37:24 +0100 -Subject: [PATCH 2/5] hw/elf_ops: clear uninitialized segment space -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When the mem_size of the segment is bigger than the file_size, -and if this space doesn't overlap another segment, it needs -to be cleared. - -This bug is very similar to the one we had for linux-user, -22d113b52f41 ("linux-user: Fix loading of BSS segments"), -where .bss section is encoded as an extension of the the data -one by setting the segment p_memsz > p_filesz. - -Signed-off-by: Laurent Vivier -[PMD: Use recently added address_space_set()] -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Stefano Garzarella -Reviewed-by: Richard Henderson -Message-Id: <20220115203725.3834712-3-laurent@vivier.eu> -Signed-off-by: zhangxinhao ---- - hw/core/loader.c | 4 ++++ - include/hw/elf_ops.h | 13 +++++++++++++ - 2 files changed, 17 insertions(+) - -diff --git a/hw/core/loader.c b/hw/core/loader.c -index 052a0fd719..19edb928e9 100644 ---- a/hw/core/loader.c -+++ b/hw/core/loader.c -@@ -1164,9 +1164,13 @@ static void rom_reset(void *unused) - if (rom->mr) { - void *host = memory_region_get_ram_ptr(rom->mr); - memcpy(host, rom->data, rom->datasize); -+ memset(host + rom->datasize, 0, rom->romsize - rom->datasize); - } else { - address_space_write_rom(rom->as, rom->addr, MEMTXATTRS_UNSPECIFIED, - rom->data, rom->datasize); -+ address_space_set(rom->as, rom->addr + rom->datasize, 0, -+ rom->romsize - rom->datasize, -+ MEMTXATTRS_UNSPECIFIED); - } - if (rom->isrom) { - /* rom needs to be written only once */ -diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h -index 995de8495c..7c3b1d0f6c 100644 ---- a/include/hw/elf_ops.h -+++ b/include/hw/elf_ops.h -@@ -555,6 +555,19 @@ static ssize_t glue(load_elf, SZ)(const char *name, int fd, - if (res != MEMTX_OK) { - goto fail; - } -+ /* -+ * We need to zero'ify the space that is not copied -+ * from file -+ */ -+ if (file_size < mem_size) { -+ res = address_space_set(as ? as : &address_space_memory, -+ addr + file_size, 0, -+ mem_size - file_size, -+ MEMTXATTRS_UNSPECIFIED); -+ if (res != MEMTX_OK) { -+ goto fail; -+ } -+ } - } - } - --- -2.27.0 - diff --git a/hw-hyperv-hyperv.c-Use-device_cold_reset-instead-of-.patch b/hw-hyperv-hyperv.c-Use-device_cold_reset-instead-of-.patch deleted file mode 100644 index e7ccad56ee0c89e77a8dc14491355a2ec4b4e208..0000000000000000000000000000000000000000 --- a/hw-hyperv-hyperv.c-Use-device_cold_reset-instead-of-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 9ba48faf402e5964e1ab74decd8eddbc496082c9 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Fri, 25 Nov 2022 11:05:17 +0800 -Subject: [PATCH 25/29] hw/hyperv/hyperv.c: Use device_cold_reset() instead of - device_legacy_reset() - -The semantic difference between the deprecated device_legacy_reset() -function and the newer device_cold_reset() function is that the new -function resets both the device itself and any qbuses it owns, -whereas the legacy function resets just the device itself and nothing -else. In hyperv_synic_reset() we reset a SynICState, which has no -qbuses, so for this purpose the two functions behave identically and -we can stop using the deprecated one. - -Signed-off-by: Peter Maydell -Signed-off-by: jianchunfu ---- - hw/hyperv/hyperv.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c -index cb1074f234..220481a1ca 100644 ---- a/hw/hyperv/hyperv.c -+++ b/hw/hyperv/hyperv.c -@@ -150,7 +150,7 @@ void hyperv_synic_reset(CPUState *cs) - SynICState *synic = get_synic(cs); - - if (synic) { -- device_legacy_reset(DEVICE(synic)); -+ device_cold_reset(DEVICE(synic)); - } - } - --- -2.27.0 - diff --git a/hw-i2c-pmbus_device-Fix-modifying-QOM-class-internal.patch b/hw-i2c-pmbus_device-Fix-modifying-QOM-class-internal.patch deleted file mode 100644 index 9b528ba567fd101ba7e93f7ab049f52ef3e4e650..0000000000000000000000000000000000000000 --- a/hw-i2c-pmbus_device-Fix-modifying-QOM-class-internal.patch +++ /dev/null @@ -1,63 +0,0 @@ -From b2314562968c124503dbd08529a2bef39701aaa7 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Wed, 6 Sep 2023 20:30:27 +0800 -Subject: [PATCH] hw/i2c/pmbus_device: Fix modifying QOM class internals from - instance -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from f0e4588fd4ae39d1ad46f19c76ed298f89e61d6a - -QOM object instance should not modify its class state (because -all other objects instanciated from this class get affected). - -Instead of modifying the PMBusDeviceClass 'device_num_pages' field -the first time a instance is initialized (in pmbus_pages_alloc), -introduce a new pmbus_pages_num() helper which returns the page -number from the class without modifying the class state. - -The code logic become slighly simplified. - -Inspired-by: Bernhard Beschow -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Richard Henderson -Message-Id: <20230523064408.57941-4-philmd@linaro.org> -Signed-off-by: qihao_yewu ---- - hw/i2c/pmbus_device.c | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - -diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c -index 24f8f522d9..f39cd532de 100644 ---- a/hw/i2c/pmbus_device.c -+++ b/hw/i2c/pmbus_device.c -@@ -166,15 +166,18 @@ static void pmbus_quick_cmd(SMBusDevice *smd, uint8_t read) - } - } - --static void pmbus_pages_alloc(PMBusDevice *pmdev) -+static uint8_t pmbus_pages_num(PMBusDevice *pmdev) - { -+ const PMBusDeviceClass *k = PMBUS_DEVICE_GET_CLASS(pmdev); -+ - /* some PMBus devices don't use the PAGE command, so they get 1 page */ -- PMBusDeviceClass *k = PMBUS_DEVICE_GET_CLASS(pmdev); -- if (k->device_num_pages == 0) { -- k->device_num_pages = 1; -- } -- pmdev->num_pages = k->device_num_pages; -- pmdev->pages = g_new0(PMBusPage, k->device_num_pages); -+ return k->device_num_pages ? : 1; -+} -+ -+static void pmbus_pages_alloc(PMBusDevice *pmdev) -+{ -+ pmdev->num_pages = pmbus_pages_num(pmdev); -+ pmdev->pages = g_new0(PMBusPage, pmdev->num_pages); - } - - void pmbus_check_limits(PMBusDevice *pmdev) --- -2.41.0.windows.1 - diff --git a/hw-i386-Use-device_cold_reset-to-reset-the-APIC.patch b/hw-i386-Use-device_cold_reset-to-reset-the-APIC.patch deleted file mode 100644 index 1777d54fa3f607606064137e870e118af4a60a85..0000000000000000000000000000000000000000 --- a/hw-i386-Use-device_cold_reset-to-reset-the-APIC.patch +++ /dev/null @@ -1,51 +0,0 @@ -From b65da0b1f73a47754a5056b89948d06d9eeaf596 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Fri, 25 Nov 2022 11:00:24 +0800 -Subject: [PATCH 24/29] hw/i386: Use device_cold_reset() to reset the APIC - -The semantic difference between the deprecated device_legacy_reset() -function and the newer device_cold_reset() function is that the new -function resets both the device itself and any qbuses it owns, -whereas the legacy function resets just the device itself and nothing -else. -The pc_machine_reset() and microvm_machine_reset() functions use -device_legacy_reset() to reset the APIC; this is an APICCommonState -and does not have any qbuses, so for this purpose the two functions -behave identically and we can stop using the deprecated one. - -Signed-off-by: Peter Maydell -Signed-off-by: jianchunfu ---- - hw/i386/microvm.c | 2 +- - hw/i386/pc.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c -index 4b3b1dd262..3ee95f9b4d 100644 ---- a/hw/i386/microvm.c -+++ b/hw/i386/microvm.c -@@ -486,7 +486,7 @@ static void microvm_machine_reset(MachineState *machine) - cpu = X86_CPU(cs); - - if (cpu->apic_state) { -- device_legacy_reset(cpu->apic_state); -+ device_cold_reset(cpu->apic_state); - } - } - } -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index a2ef40ecbc..4870ce0f96 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -1642,7 +1642,7 @@ static void pc_machine_reset(MachineState *machine) - cpu = X86_CPU(cs); - - if (cpu->apic_state) { -- device_legacy_reset(cpu->apic_state); -+ device_cold_reset(cpu->apic_state); - } - } - } --- -2.27.0 - diff --git a/hw-i386-pc-Add-missing-property-descriptions.patch b/hw-i386-pc-Add-missing-property-descriptions.patch deleted file mode 100644 index d5e699cb077f40d2587ac888692b05053bfd6f7c..0000000000000000000000000000000000000000 --- a/hw-i386-pc-Add-missing-property-descriptions.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 5ce3662809ab7a594fcbe024eb81416e8556f5ea Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Thu, 7 Dec 2023 19:13:02 +0800 -Subject: [PATCH] hw/i386/pc: Add missing property descriptions - -cherry picked from 44bff3767ced18845adb2612a2cf9691d8769d41 - -When running "qemu-system-x86_64 -M pc,help" I noticed that some -properties were still missing their description. Add them now so -that users get at least a slightly better idea what they are all -about. - -Signed-off-by: Thomas Huth -Message-Id: <20211206134255.94784-1-thuth@redhat.com> -Reviewed-by: Igor Mammedov -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: boringandboring ---- - hw/i386/pc.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index c5f430f83d..7003ea1a05 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -1726,15 +1726,23 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - - object_class_property_add_bool(oc, PC_MACHINE_SMBUS, - pc_machine_get_smbus, pc_machine_set_smbus); -+ object_class_property_set_description(oc, PC_MACHINE_SMBUS, -+ "Enable/disable system management bus"); - - object_class_property_add_bool(oc, PC_MACHINE_SATA, - pc_machine_get_sata, pc_machine_set_sata); -+ object_class_property_set_description(oc, PC_MACHINE_SATA, -+ "Enable/disable Serial ATA bus"); - - object_class_property_add_bool(oc, PC_MACHINE_PIT, - pc_machine_get_pit, pc_machine_set_pit); -+ object_class_property_set_description(oc, PC_MACHINE_PIT, -+ "Enable/disable Intel 8254 programmable interval timer emulation"); - - object_class_property_add_bool(oc, "hpet", - pc_machine_get_hpet, pc_machine_set_hpet); -+ object_class_property_set_description(oc, "hpet", -+ "Enable/disable high precision event timer emulation"); - - object_class_property_add_bool(oc, "default-bus-bypass-iommu", - pc_machine_get_default_bus_bypass_iommu, --- -2.27.0 - diff --git a/hw-ide-atapi.c-Correct-typos-CD-CDROM-CD-ROM.patch b/hw-ide-atapi.c-Correct-typos-CD-CDROM-CD-ROM.patch deleted file mode 100644 index 672ab70952fb78c15854cc1d0a4ce7bff17c4ee3..0000000000000000000000000000000000000000 --- a/hw-ide-atapi.c-Correct-typos-CD-CDROM-CD-ROM.patch +++ /dev/null @@ -1,41 +0,0 @@ -From c8c702a9970572800626be337e3b5c8b44e4bcca Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:43:50 -0800 -Subject: [PATCH] hw/ide/atapi.c: Correct typos (CD-CDROM -> CD-ROM) - -cherry picked from commit 99337bd1e3a323d07dc29da99cf3f48d3990ad81 - -Signed-off-by: Lev Kujawski -Reviewed-by: Laurent Vivier -Message-Id: <20220528204702.167912-1-lkujaw@member.fsf.org> -Signed-off-by: Laurent Vivier -Signed-off-by: Wanghe Xiao ---- - hw/ide/atapi.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c -index b626199e3d..88b2890faf 100644 ---- a/hw/ide/atapi.c -+++ b/hw/ide/atapi.c -@@ -318,7 +318,7 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size) - } - } - --/* start a CD-CDROM read command */ -+/* start a CD-ROM read command */ - static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors, - int sector_size) - { -@@ -417,7 +417,7 @@ eot: - ide_set_inactive(s, false); - } - --/* start a CD-CDROM read command with DMA */ -+/* start a CD-ROM read command with DMA */ - /* XXX: test if DMA is available */ - static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors, - int sector_size) --- -2.27.0 - diff --git a/hw-ide-microdrive-Use-device_cold_reset-for-self-res.patch b/hw-ide-microdrive-Use-device_cold_reset-for-self-res.patch deleted file mode 100644 index f289626dd405e0635a20730412dd28da058f234b..0000000000000000000000000000000000000000 --- a/hw-ide-microdrive-Use-device_cold_reset-for-self-res.patch +++ /dev/null @@ -1,77 +0,0 @@ -From a9269ae78f478e70ba58df388b8110c7e9c81035 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Fri, 25 Nov 2022 10:53:29 +0800 -Subject: [PATCH 23/29] hw/ide/microdrive: Use device_cold_reset() for - self-resets - -Currently the microdrive code uses device_legacy_reset() to reset -itself, and has its reset method call reset on the IDE bus as the -last thing it does. Switch to using device_cold_reset(). -The only concrete microdrive device is the TYPE_DSCM1XXXX; it is not -command-line pluggable, so it is used only by the old pxa2xx Arm -boards 'akita', 'borzoi', 'spitz', 'terrier' and 'tosa'. -You might think that this would result in the IDE bus being -reset automatically, but it does not, because the IDEBus type -does not set the BusClass::reset method. Instead the controller -must explicitly call ide_bus_reset(). We therefore leave that -call in md_reset(). -Note also that because the PCMCIA card device is a direct subclass of -TYPE_DEVICE and we don't model the PCMCIA controller-to-card -interface as a qbus, PCMCIA cards are not on any qbus and so they -don't get reset when the system is reset. The reset only happens via -the dscm1xxxx_attach() and dscm1xxxx_detach() functions during -machine creation. -Because our aim here is merely to try to get rid of calls to the -device_legacy_reset() function, we leave these other dubious -reset-related issues alone. (They all stem from this code being -absolutely ancient.) - -Signed-off-by: Peter Maydell -Signed-off-by: jianchunfu ---- - hw/ide/microdrive.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c -index 6df9b4cbbe..56c5be3655 100644 ---- a/hw/ide/microdrive.c -+++ b/hw/ide/microdrive.c -@@ -175,7 +175,7 @@ static void md_attr_write(PCMCIACardState *card, uint32_t at, uint8_t value) - case 0x00: /* Configuration Option Register */ - s->opt = value & 0xcf; - if (value & OPT_SRESET) { -- device_legacy_reset(DEVICE(s)); -+ device_cold_reset(DEVICE(s)); - } - md_interrupt_update(s); - break; -@@ -318,7 +318,7 @@ static void md_common_write(PCMCIACardState *card, uint32_t at, uint16_t value) - case 0xe: /* Device Control */ - s->ctrl = value; - if (value & CTRL_SRST) { -- device_legacy_reset(DEVICE(s)); -+ device_cold_reset(DEVICE(s)); - } - md_interrupt_update(s); - break; -@@ -543,7 +543,7 @@ static int dscm1xxxx_attach(PCMCIACardState *card) - md->attr_base = pcc->cis[0x74] | (pcc->cis[0x76] << 8); - md->io_base = 0x0; - -- device_legacy_reset(DEVICE(md)); -+ device_cold_reset(DEVICE(md)); - md_interrupt_update(md); - - return 0; -@@ -553,7 +553,7 @@ static int dscm1xxxx_detach(PCMCIACardState *card) - { - MicroDriveState *md = MICRODRIVE(card); - -- device_legacy_reset(DEVICE(md)); -+ device_cold_reset(DEVICE(md)); - return 0; - } - --- -2.27.0 - diff --git a/hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch b/hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch deleted file mode 100644 index cf1bd37de19b3a21dd1ffc7544efaafde72439a7..0000000000000000000000000000000000000000 --- a/hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5c3db1128c90e0fa2bec139de6022aea0ae2ad12 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Wed, 15 Dec 2021 19:24:19 +0100 -Subject: [PATCH 1/3] hw/intc/arm_gicv3: Check for !MEMTX_OK instead of - MEMTX_ERROR -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Quoting Peter Maydell: - - "These MEMTX_* aren't from the memory transaction - API functions; they're just being used by gicd_readl() and - friends as a way to indicate a success/failure so that the - actual MemoryRegionOps read/write fns like gicv3_dist_read() - can log a guest error." - -We are going to introduce more MemTxResult bits, so it is -safer to check for !MEMTX_OK rather than MEMTX_ERROR. - -Reviewed-by: Peter Xu -Reviewed-by: David Hildenbrand -Reviewed-by: Peter Maydell -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: Peter Maydell ---- - hw/intc/arm_gicv3_redist.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c -index c8ff3eca08..99b11ca5ee 100644 ---- a/hw/intc/arm_gicv3_redist.c -+++ b/hw/intc/arm_gicv3_redist.c -@@ -462,7 +462,7 @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data, - break; - } - -- if (r == MEMTX_ERROR) { -+ if (r != MEMTX_OK) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: invalid guest read at offset " TARGET_FMT_plx - " size %u\n", __func__, offset, size); -@@ -521,7 +521,7 @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data, - break; - } - -- if (r == MEMTX_ERROR) { -+ if (r != MEMTX_OK) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: invalid guest write at offset " TARGET_FMT_plx - " size %u\n", __func__, offset, size); --- -2.27.0 - diff --git a/hw-intc-arm_gicv3-ICC_PMR_EL1-high-bits-should-be-RA.patch b/hw-intc-arm_gicv3-ICC_PMR_EL1-high-bits-should-be-RA.patch deleted file mode 100644 index 92d2b86e043b65d42a950acb354bfba61ea39666..0000000000000000000000000000000000000000 --- a/hw-intc-arm_gicv3-ICC_PMR_EL1-high-bits-should-be-RA.patch +++ /dev/null @@ -1,54 +0,0 @@ -From bd71d640e5d3731a91ccd6cc4ded251d401b4b2d Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Tue, 28 Nov 2023 09:38:09 +0800 -Subject: [PATCH] hw/intc/arm_gicv3: ICC_PMR_EL1 high bits should be RAZ - -cherry picked from 70726a15bc7e61d16f3efe5bfd9b061ca077f533 - -The ICC_PMR_ELx and ICV_PMR_ELx bit masks returned from -ic{c,v}_fullprio_mask should technically also remove any -bit above 7 as these are marked reserved (read 0) and should -therefore should not be written as anything other than 0. - -This was noted during a run of a proprietary test system and -discused on the mailing list [1] and initially thought not to -be an issue due to RES0 being technically allowed to be -written to and read back as long as the implementation does -not use the RES0 bits. It is very possible that the values -are used in comparison without masking, as pointed out by -Peter in [2], if (cs->hppi.prio >= cs->icc_pmr_el1) may well -do the wrong thing. - -Masking these values in ic{c,v}_fullprio_mask() should fix -this and prevent any future problems with playing with the -values. - -[1]: https://lists.nongnu.org/archive/html/qemu-arm/2023-11/msg00607.html -[2]: https://lists.nongnu.org/archive/html/qemu-arm/2023-11/msg00737.html - -Signed-off-by: Ben Dooks -Message-id: 20231116172818.792364-1-ben.dooks@codethink.co.uk -Suggested-by: Peter Maydell -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell -Signed-off-by: boringandboring ---- - hw/intc/arm_gicv3_cpuif.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c -index 274a40a40c..eaa1381b3d 100644 ---- a/hw/intc/arm_gicv3_cpuif.c -+++ b/hw/intc/arm_gicv3_cpuif.c -@@ -137,7 +137,7 @@ static uint32_t icv_fullprio_mask(GICv3CPUState *cs) - * with the group priority, whose mask depends on the value of VBPR - * for the interrupt group.) - */ -- return ~0U << (8 - cs->vpribits); -+ return (~0U << (8 - cs->vpribits)) & 0xff; - } - - static int ich_highest_active_virt_prio(GICv3CPUState *cs) --- -2.27.0 - diff --git a/hw-intc-gicv3-Add-CPU-hotplug-realize-hook.patch b/hw-intc-gicv3-Add-CPU-hotplug-realize-hook.patch deleted file mode 100644 index 926a619152e8af57e0c55b2664d4b2d0c4fc9445..0000000000000000000000000000000000000000 --- a/hw-intc-gicv3-Add-CPU-hotplug-realize-hook.patch +++ /dev/null @@ -1,171 +0,0 @@ -From e94b8dc43d416b3ebf316faf14309fe4c4d0b4f0 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Mon, 6 Apr 2020 11:26:35 +0800 -Subject: [PATCH] hw/intc/gicv3: Add CPU hotplug realize hook - -GICv3 exposes individual CPU realization capability through -this hook. It will be used for hotplugged CPU. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/intc/arm_gicv3.c | 17 ++++++++++++++++- - hw/intc/arm_gicv3_common.c | 8 ++++++++ - hw/intc/arm_gicv3_kvm.c | 11 +++++++++++ - include/hw/intc/arm_gicv3.h | 2 ++ - include/hw/intc/arm_gicv3_common.h | 4 ++++ - 5 files changed, 41 insertions(+), 1 deletion(-) - -diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c -index 40016cb84a..9591cfbcc0 100644 ---- a/hw/intc/arm_gicv3.c -+++ b/hw/intc/arm_gicv3.c -@@ -376,6 +376,19 @@ static const MemoryRegionOps gic_ops[] = { - } - }; - -+static void gicv3_cpu_realize(GICv3State *s, int i) -+{ -+ gicv3_init_one_cpuif(s, i); -+} -+ -+static void arm_gicv3_cpu_hotplug_realize(GICv3State *s, int ncpu) -+{ -+ ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s); -+ -+ agc->parent_cpu_hotplug_realize(s, ncpu); -+ gicv3_cpu_realize(s, ncpu); -+} -+ - static void arm_gic_realize(DeviceState *dev, Error **errp) - { - /* Device instance realize function for the GIC sysbus device */ -@@ -393,7 +406,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) - gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops); - - for (i = 0; i < s->num_cpu; i++) { -- gicv3_init_one_cpuif(s, i); -+ gicv3_cpu_realize(s, i); - } - } - -@@ -403,6 +416,8 @@ static void arm_gicv3_class_init(ObjectClass *klass, void *data) - ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass); - ARMGICv3Class *agc = ARM_GICV3_CLASS(klass); - -+ agc->parent_cpu_hotplug_realize = agcc->cpu_hotplug_realize; -+ agcc->cpu_hotplug_realize = arm_gicv3_cpu_hotplug_realize; - agcc->post_load = arm_gicv3_post_load; - device_class_set_parent_realize(dc, arm_gic_realize, &agc->parent_realize); - } -diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c -index 1a11d1986d..f8ef6817a4 100644 ---- a/hw/intc/arm_gicv3_common.c -+++ b/hw/intc/arm_gicv3_common.c -@@ -311,6 +311,11 @@ static void arm_gicv3_common_cpu_realize(GICv3State *s, int ncpu) - gicv3_set_gicv3state(cpu, &s->cpu[ncpu]); - } - -+static void arm_gicv3_common_cpu_hotplug_realize(GICv3State *s, int ncpu) -+{ -+ arm_gicv3_common_cpu_realize(s, ncpu); -+} -+ - static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) - { - GICv3State *s = ARM_GICV3_COMMON(dev); -@@ -371,6 +376,7 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) - - for (i = 0; i < s->num_cpu; i++) { - CPUState *cpu = qemu_get_cpu(i); -+ - uint64_t cpu_affid; - - arm_gicv3_common_cpu_realize(s, i); -@@ -537,12 +543,14 @@ static Property arm_gicv3_common_properties[] = { - static void arm_gicv3_common_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); -+ ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass); - ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_CLASS(klass); - - dc->reset = arm_gicv3_common_reset; - dc->realize = arm_gicv3_common_realize; - device_class_set_props(dc, arm_gicv3_common_properties); - dc->vmsd = &vmstate_gicv3; -+ agcc->cpu_hotplug_realize = arm_gicv3_common_cpu_hotplug_realize; - albifc->arm_linux_init = arm_gic_common_linux_init; - } - -diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c -index 596b31998b..95271e754b 100644 ---- a/hw/intc/arm_gicv3_kvm.c -+++ b/hw/intc/arm_gicv3_kvm.c -@@ -76,6 +76,7 @@ struct KVMARMGICv3Class { - ARMGICv3CommonClass parent_class; - DeviceRealize parent_realize; - void (*parent_reset)(DeviceState *dev); -+ CPUHotplugRealize parent_cpu_hotplug_realize; - }; - - static void kvm_arm_gicv3_set_irq(void *opaque, int irq, int level) -@@ -771,6 +772,14 @@ static void kvm_arm_gicv3_cpu_realize(GICv3State *s, int ncpu) - define_arm_cp_regs(cpu, gicv3_cpuif_reginfo); - } - -+static void kvm_arm_gicv3_cpu_hotplug_realize(GICv3State *s, int ncpu) -+{ -+ KVMARMGICv3Class *kagcc = KVM_ARM_GICV3_GET_CLASS(s); -+ -+ kagcc->parent_cpu_hotplug_realize(s, ncpu); -+ kvm_arm_gicv3_cpu_realize(s, ncpu); -+} -+ - static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) - { - GICv3State *s = KVM_ARM_GICV3(dev); -@@ -881,6 +890,8 @@ static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data) - ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass); - KVMARMGICv3Class *kgc = KVM_ARM_GICV3_CLASS(klass); - -+ kgc->parent_cpu_hotplug_realize = agcc->cpu_hotplug_realize; -+ agcc->cpu_hotplug_realize = kvm_arm_gicv3_cpu_hotplug_realize; - agcc->pre_save = kvm_arm_gicv3_get; - agcc->post_load = kvm_arm_gicv3_put; - device_class_set_parent_realize(dc, kvm_arm_gicv3_realize, -diff --git a/include/hw/intc/arm_gicv3.h b/include/hw/intc/arm_gicv3.h -index a81a6ae7ec..e360556bd5 100644 ---- a/include/hw/intc/arm_gicv3.h -+++ b/include/hw/intc/arm_gicv3.h -@@ -26,6 +26,8 @@ struct ARMGICv3Class { - ARMGICv3CommonClass parent_class; - /*< public >*/ - -+ CPUHotplugRealize parent_cpu_hotplug_realize; -+ - DeviceRealize parent_realize; - }; - -diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h -index fc38e4b7dc..c208a191ff 100644 ---- a/include/hw/intc/arm_gicv3_common.h -+++ b/include/hw/intc/arm_gicv3_common.h -@@ -306,11 +306,15 @@ typedef struct ARMGICv3CommonClass ARMGICv3CommonClass; - DECLARE_OBJ_CHECKERS(GICv3State, ARMGICv3CommonClass, - ARM_GICV3_COMMON, TYPE_ARM_GICV3_COMMON) - -+typedef void (*CPUHotplugRealize)(GICv3State *s, int ncpu); -+ - struct ARMGICv3CommonClass { - /*< private >*/ - SysBusDeviceClass parent_class; - /*< public >*/ - -+ CPUHotplugRealize cpu_hotplug_realize; -+ - void (*pre_save)(GICv3State *s); - void (*post_load)(GICv3State *s); - }; --- -2.27.0 - diff --git a/hw-mem-nvdimm-fix-error-message-for-unarmed-flag.patch b/hw-mem-nvdimm-fix-error-message-for-unarmed-flag.patch deleted file mode 100644 index 88bb34e10ac60d7cf606f6c6062855441fea4b05..0000000000000000000000000000000000000000 --- a/hw-mem-nvdimm-fix-error-message-for-unarmed-flag.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b1201fb95d14f5564d4df28ab53d16676d335934 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Wed, 23 Nov 2022 10:57:07 +0800 -Subject: [PATCH 05/29] hw/mem/nvdimm: fix error message for 'unarmed' flag -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In the ACPI specification [1], the 'unarmed' bit is set when a device -cannot accept a persistent write. This means that when a memdev is -read-only, the 'unarmed' flag must be turned on. The logic is correct, -just changing the error message. -[1] ACPI NFIT NVDIMM Region Mapping Structure "NVDIMM State Flags" Bit 3 - -Fixes: dbd730e859 ("nvdimm: check -object memory-backend-file, readonly=on option") -Signed-off-by: Julia Suvorova -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Pankaj Gupta -Reviewed-by: Philippe Mathieu-Daudé -Acked-by: David Hildenbrand -Signed-off-by: jianchunfu ---- - hw/mem/nvdimm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c -index 7397b67156..8df1d7e088 100644 ---- a/hw/mem/nvdimm.c -+++ b/hw/mem/nvdimm.c -@@ -149,7 +149,7 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp) - if (!nvdimm->unarmed && memory_region_is_rom(mr)) { - HostMemoryBackend *hostmem = dimm->hostmem; - -- error_setg(errp, "'unarmed' property must be off since memdev %s " -+ error_setg(errp, "'unarmed' property must be 'on' since memdev %s " - "is read-only", - object_get_canonical_path_component(OBJECT(hostmem))); - return; --- -2.27.0 - diff --git a/hw-net-Fix-read-of-uninitialized-memory-in-ftgmac100.patch b/hw-net-Fix-read-of-uninitialized-memory-in-ftgmac100.patch deleted file mode 100644 index 55ad629995ea8e03e4a2e985ae900959d2e1e0e9..0000000000000000000000000000000000000000 --- a/hw-net-Fix-read-of-uninitialized-memory-in-ftgmac100.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 967c8f6e799756baf95c025ba8107206c3afd398 Mon Sep 17 00:00:00 2001 -From: dinglimin_yewu -Date: Thu, 28 Sep 2023 16:25:23 +0800 -Subject: [PATCH] hw/net: Fix read of uninitialized memory in ftgmac100 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 036e98e5c2b4e25c8d6ccbddb85c7ab05a753f6a - -With the `size += 4` before the call to `crc32`, the CRC calculation -would overrun the buffer. Size is used in the while loop starting on -line 1009 to determine how much data to write back, with the last -four bytes coming from `crc_ptr`, so do need to increase it, but should -do this after the computation. - -I'm unsure why this use of uninitialized memory in the CRC doesn't -result in CRC errors, but it seems clear to me that it should not be -included in the calculation. - -Signed-off-by: Stephen Longfield -Reviewed-by: Hao Wu -Reviewed-by: Joel Stanley -Message-Id: <20221220221437.3303721-1-slongfield@google.com> -Signed-off-by: Cédric Le Goater -Signed-off-by: dinglimin_yewu ---- - hw/net/ftgmac100.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c -index 83ef0a783e..d3bf14be53 100644 ---- a/hw/net/ftgmac100.c -+++ b/hw/net/ftgmac100.c -@@ -980,9 +980,9 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, - return size; - } - -- /* 4 bytes for the CRC. */ -- size += 4; - crc = cpu_to_be32(crc32(~0, buf, size)); -+ /* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */ -+ size += 4; - crc_ptr = (uint8_t *) &crc; - - /* Huge frames are truncated. */ --- -2.41.0.windows.1 - diff --git a/hw-net-cadence_gem.c-spelling-fixes-Octects.patch b/hw-net-cadence_gem.c-spelling-fixes-Octects.patch deleted file mode 100644 index 31ebc99f4cd161bfdaed64a15f4e8621061da394..0000000000000000000000000000000000000000 --- a/hw-net-cadence_gem.c-spelling-fixes-Octects.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 2e37d6ac7713c9962cb006900d18e83df54e8e0f Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Fri, 24 Nov 2023 00:21:31 -0800 -Subject: [PATCH] hw/net/cadence_gem.c: spelling fixes: Octects - -Signed-off-by: zhujun2 ---- - hw/net/cadence_gem.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c -index 24b3a0ff66..21e1bd091f 100644 ---- a/hw/net/cadence_gem.c -+++ b/hw/net/cadence_gem.c -@@ -81,8 +81,8 @@ - #define GEM_IPGSTRETCH (0x000000BC / 4) /* IPG Stretch reg */ - #define GEM_SVLAN (0x000000C0 / 4) /* Stacked VLAN reg */ - #define GEM_MODID (0x000000FC / 4) /* Module ID reg */ --#define GEM_OCTTXLO (0x00000100 / 4) /* Octects transmitted Low reg */ --#define GEM_OCTTXHI (0x00000104 / 4) /* Octects transmitted High reg */ -+#define GEM_OCTTXLO (0x00000100 / 4) /* Octets transmitted Low reg */ -+#define GEM_OCTTXHI (0x00000104 / 4) /* Octets transmitted High reg */ - #define GEM_TXCNT (0x00000108 / 4) /* Error-free Frames transmitted */ - #define GEM_TXBCNT (0x0000010C / 4) /* Error-free Broadcast Frames */ - #define GEM_TXMCNT (0x00000110 / 4) /* Error-free Multicast Frame */ -@@ -101,8 +101,8 @@ - #define GEM_LATECOLLCNT (0x00000144 / 4) /* Late Collision Frames */ - #define GEM_DEFERTXCNT (0x00000148 / 4) /* Deferred Transmission Frames */ - #define GEM_CSENSECNT (0x0000014C / 4) /* Carrier Sense Error Counter */ --#define GEM_OCTRXLO (0x00000150 / 4) /* Octects Received register Low */ --#define GEM_OCTRXHI (0x00000154 / 4) /* Octects Received register High */ -+#define GEM_OCTRXLO (0x00000150 / 4) /* Octets Received register Low */ -+#define GEM_OCTRXHI (0x00000154 / 4) /* Octets Received register High */ - #define GEM_RXCNT (0x00000158 / 4) /* Error-free Frames Received */ - #define GEM_RXBROADCNT (0x0000015C / 4) /* Error-free Broadcast Frames RX */ - #define GEM_RXMULTICNT (0x00000160 / 4) /* Error-free Multicast Frames RX */ --- -2.27.0 - diff --git a/hw-net-can-fix-Xilinx-ZynqMP-CAN-RX-FIFO-logic.patch b/hw-net-can-fix-Xilinx-ZynqMP-CAN-RX-FIFO-logic.patch deleted file mode 100644 index 1b308514351cb76c7f798a6cbcfd393a27738103..0000000000000000000000000000000000000000 --- a/hw-net-can-fix-Xilinx-ZynqMP-CAN-RX-FIFO-logic.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 071249a10ebc2cd8af68ee72d409e23c6bc0ea7c Mon Sep 17 00:00:00 2001 -From: cmss_dx -Date: Wed, 30 Nov 2022 01:52:08 -0500 -Subject: [PATCH 04/17] hw/net/can: fix Xilinx ZynqMP CAN RX FIFO logic - -mainline inclusion -from mainline-v7.2.0-rc2 -commit fb96d131eec66ecb2993c544058a8cb2c9c3521f -category: bugfix - ------------------------ - -For consistency, function "update_rx_fifo()" should use the RX FIFO -register field names, not the TX FIFO ones, even if they refer to the -same bit positions in the register. - -Signed-off-by: Anton Kochkov -Reviewed-by: Francisco Iglesias -Message-id: 20220817141754.2105981-1-anton.kochkov@proton.me -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1123 -[PMM: tweaked commit message] -Signed-off-by: Peter Maydell - -Signed-off-by: cmss_dx ---- - hw/net/can/xlnx-zynqmp-can.c | 32 ++++++++++++++++---------------- - 1 file changed, 16 insertions(+), 16 deletions(-) - -diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c -index 22bb8910fa..78a76a8ce2 100644 ---- a/hw/net/can/xlnx-zynqmp-can.c -+++ b/hw/net/can/xlnx-zynqmp-can.c -@@ -696,30 +696,30 @@ static void update_rx_fifo(XlnxZynqMPCANState *s, const qemu_can_frame *frame) - timestamp)); - - /* First 32 bit of the data. */ -- fifo32_push(&s->rx_fifo, deposit32(0, R_TXFIFO_DATA1_DB3_SHIFT, -- R_TXFIFO_DATA1_DB3_LENGTH, -+ fifo32_push(&s->rx_fifo, deposit32(0, R_RXFIFO_DATA1_DB3_SHIFT, -+ R_RXFIFO_DATA1_DB3_LENGTH, - frame->data[0]) | -- deposit32(0, R_TXFIFO_DATA1_DB2_SHIFT, -- R_TXFIFO_DATA1_DB2_LENGTH, -+ deposit32(0, R_RXFIFO_DATA1_DB2_SHIFT, -+ R_RXFIFO_DATA1_DB2_LENGTH, - frame->data[1]) | -- deposit32(0, R_TXFIFO_DATA1_DB1_SHIFT, -- R_TXFIFO_DATA1_DB1_LENGTH, -+ deposit32(0, R_RXFIFO_DATA1_DB1_SHIFT, -+ R_RXFIFO_DATA1_DB1_LENGTH, - frame->data[2]) | -- deposit32(0, R_TXFIFO_DATA1_DB0_SHIFT, -- R_TXFIFO_DATA1_DB0_LENGTH, -+ deposit32(0, R_RXFIFO_DATA1_DB0_SHIFT, -+ R_RXFIFO_DATA1_DB0_LENGTH, - frame->data[3])); - /* Last 32 bit of the data. */ -- fifo32_push(&s->rx_fifo, deposit32(0, R_TXFIFO_DATA2_DB7_SHIFT, -- R_TXFIFO_DATA2_DB7_LENGTH, -+ fifo32_push(&s->rx_fifo, deposit32(0, R_RXFIFO_DATA2_DB7_SHIFT, -+ R_RXFIFO_DATA2_DB7_LENGTH, - frame->data[4]) | -- deposit32(0, R_TXFIFO_DATA2_DB6_SHIFT, -- R_TXFIFO_DATA2_DB6_LENGTH, -+ deposit32(0, R_RXFIFO_DATA2_DB6_SHIFT, -+ R_RXFIFO_DATA2_DB6_LENGTH, - frame->data[5]) | -- deposit32(0, R_TXFIFO_DATA2_DB5_SHIFT, -- R_TXFIFO_DATA2_DB5_LENGTH, -+ deposit32(0, R_RXFIFO_DATA2_DB5_SHIFT, -+ R_RXFIFO_DATA2_DB5_LENGTH, - frame->data[6]) | -- deposit32(0, R_TXFIFO_DATA2_DB4_SHIFT, -- R_TXFIFO_DATA2_DB4_LENGTH, -+ deposit32(0, R_RXFIFO_DATA2_DB4_SHIFT, -+ R_RXFIFO_DATA2_DB4_LENGTH, - frame->data[7])); - - ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1); --- -2.27.0 - diff --git a/hw-net-npcm7xx_emc-fix-missing-queue_flush.patch b/hw-net-npcm7xx_emc-fix-missing-queue_flush.patch deleted file mode 100644 index bce9a4f925f61e43711dae879a820c206619cf4a..0000000000000000000000000000000000000000 --- a/hw-net-npcm7xx_emc-fix-missing-queue_flush.patch +++ /dev/null @@ -1,75 +0,0 @@ -From cf11e02156e202db1be5e9c85b67d5dfaa56ce48 Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Mon, 4 Dec 2023 10:28:53 +0800 -Subject: [PATCH] hw/net: npcm7xx_emc fix missing queue_flush -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 530cd6c26df47c4f294c6335c9829e6c968fe7a8 - -The rx_active boolean change to true should always trigger a try_read -call that flushes the queue. - -Signed-off-by: Patrick Venture -Reviewed-by: Philippe Mathieu-Daudé -Message-id: 20211203221002.1719306-1-venture@google.com -Signed-off-by: Peter Maydell -Signed-off-by: Luo Yifan ---- - hw/net/npcm7xx_emc.c | 18 ++++++++---------- - 1 file changed, 8 insertions(+), 10 deletions(-) - -diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c -index df2efe1bf8..9a2328935c 100644 ---- a/hw/net/npcm7xx_emc.c -+++ b/hw/net/npcm7xx_emc.c -@@ -286,6 +286,12 @@ static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag) - emc_set_mista(emc, mista_flag); - } - -+static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc) -+{ -+ emc->rx_active = true; -+ qemu_flush_queued_packets(qemu_get_queue(emc->nic)); -+} -+ - static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc, - const NPCM7xxEMCTxDesc *tx_desc, - uint32_t desc_addr) -@@ -585,13 +591,6 @@ static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1) - return len; - } - --static void emc_try_receive_next_packet(NPCM7xxEMCState *emc) --{ -- if (emc_can_receive(qemu_get_queue(emc->nic))) { -- qemu_flush_queued_packets(qemu_get_queue(emc->nic)); -- } --} -- - static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size) - { - NPCM7xxEMCState *emc = opaque; -@@ -707,7 +706,7 @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset, - emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA; - } - if (value & REG_MCMDR_RXON) { -- emc->rx_active = true; -+ emc_enable_rx_and_flush(emc); - } else { - emc_halt_rx(emc, 0); - } -@@ -743,8 +742,7 @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset, - break; - case REG_RSDR: - if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) { -- emc->rx_active = true; -- emc_try_receive_next_packet(emc); -+ emc_enable_rx_and_flush(emc); - } - break; - case REG_MIIDA: --- -2.27.0 - diff --git a/hw-net-rocker-fix-security-vulnerability.patch b/hw-net-rocker-fix-security-vulnerability.patch deleted file mode 100644 index c841e9709c0b60127be40a7f163f3f9fcd0124bc..0000000000000000000000000000000000000000 --- a/hw-net-rocker-fix-security-vulnerability.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 9a8de722b047ba66f70e87fb29b877935c187457 Mon Sep 17 00:00:00 2001 -From: Lichang Zhao -Date: Thu, 10 Feb 2022 16:54:06 +0800 -Subject: [PATCH] hw/net/rocker: fix security vulnerability - -fix security vulnerability - -Signed-off-by: Lichang zhao -Signed-off-by: Jinhao Gao ---- - hw/net/rocker/rocker_of_dpa.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c -index b3b8c5bb6d..8ac26e6beb 100644 ---- a/hw/net/rocker/rocker_of_dpa.c -+++ b/hw/net/rocker/rocker_of_dpa.c -@@ -2070,6 +2070,7 @@ static int of_dpa_cmd_add_l2_flood(OfDpa *of_dpa, OfDpaGroup *group, - err_out: - group->l2_flood.group_count = 0; - g_free(group->l2_flood.group_ids); -+ group->l2_flood.group_ids = NULL; - g_free(tlvs); - - return err; --- -2.27.0 - diff --git a/hw-net-virtio-net-make-some-VirtIONet-const.patch b/hw-net-virtio-net-make-some-VirtIONet-const.patch deleted file mode 100644 index f2ff4b1bc903bd2a83f546bab732a25c6367dbb7..0000000000000000000000000000000000000000 --- a/hw-net-virtio-net-make-some-VirtIONet-const.patch +++ /dev/null @@ -1,44 +0,0 @@ -From f6e12a7c892c5e823157f6b84955544ff659e980 Mon Sep 17 00:00:00 2001 -From: jipengfei -Date: Fri, 30 Jun 2023 22:19:22 +0800 -Subject: [PATCH] hw/net/virtio-net: make some VirtIONet const -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The VirtIONet structure is not modified in -virtio_net_supported_guest_offloads(). -Therefore, make it const to allow this function to -accept const variables. - -cheery-pick from 705e89cfaafc54491482742a756cf661b48608d2 - -Signed-off-by: jipengfei_yewu -Signed-off-by: Hawkins Jiawei -Reviewed-by: Eugenio Pérez -Message-Id: <489b09c3998ac09b9135e57a7dd8c56a4be8cdf9.1685704856.git.yin31149@gmail.com> -Tested-by: Lei Yang -Reviewed-by: Eugenio Pérez -Tested-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - hw/net/virtio-net.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 4946b65e22..3bd786cc22 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -811,7 +811,7 @@ static uint64_t virtio_net_guest_offloads_by_features(uint32_t features) - return guest_offloads_mask & features; - } - --static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n) -+static inline uint64_t virtio_net_supported_guest_offloads(const VirtIONet *n) - { - VirtIODevice *vdev = VIRTIO_DEVICE(n); - return virtio_net_guest_offloads_by_features(vdev->guest_features); --- -2.41.0.windows.1 - diff --git a/hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch b/hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch deleted file mode 100644 index 90631fb16d28b26ee5e95b419eb8b4eca1294bb4..0000000000000000000000000000000000000000 --- a/hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ad2660c287ff03d0190eff5f841452e618d368ff Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 24 Mar 2023 07:16:21 +0000 -Subject: [PATCH] hw/net/vmxnet3: Log guest-triggerable errors using - LOG_GUEST_ERROR mainline inclusion commit - f3e5a17593b972a9a6079ccf7677b4389d74d5a1 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -The "Interrupt Cause" register (VMXNET3_REG_ICR) is read-only. -Write accesses are ignored. Log them with as LOG_GUEST_ERROR -instead of aborting: - - [R +0.239743] writeq 0xe0002031 0x46291a5a55460800 - ERROR:hw/net/vmxnet3.c:1819:vmxnet3_io_bar1_write: code should not be reached - Thread 1 "qemu-system-i38" received signal SIGABRT, Aborted. - (gdb) bt - #3 0x74c397d3 in __GI_abort () at abort.c:79 - #4 0x76d3cd4c in g_assertion_message (domain=, file=, line=, func=, message=) at ../glib/gtestutils.c:3223 - #5 0x76d9d45f in g_assertion_message_expr - (domain=0x0, file=0x59fc2e53 "hw/net/vmxnet3.c", line=1819, func=0x59fc11e0 <__func__.vmxnet3_io_bar1_write> "vmxnet3_io_bar1_write", expr=) - at ../glib/gtestutils.c:3249 - #6 0x57e80a3a in vmxnet3_io_bar1_write (opaque=0x62814100, addr=56, val=70, size=4) at hw/net/vmxnet3.c:1819 - #7 0x58c2d894 in memory_region_write_accessor (mr=0x62816b90, addr=56, value=0x7fff9450, size=4, shift=0, mask=4294967295, attrs=...) at softmmu/memory.c:492 - #8 0x58c2d1d2 in access_with_adjusted_size (addr=56, value=0x7fff9450, size=1, access_size_min=4, access_size_max=4, access_fn= - 0x58c2d290 , mr=0x62816b90, attrs=...) at softmmu/memory.c:554 - #9 0x58c2bae7 in memory_region_dispatch_write (mr=0x62816b90, addr=56, data=70, op=MO_8, attrs=...) at softmmu/memory.c:1504 - #10 0x58bfd034 in flatview_write_continue (fv=0x606000181700, addr=0xe0002038, attrs=..., ptr=0x7fffb9e0, len=1, addr1=56, l=1, mr=0x62816b90) - at softmmu/physmem.c:2782 - #11 0x58beba00 in flatview_write (fv=0x606000181700, addr=0xe0002031, attrs=..., buf=0x7fffb9e0, len=8) at softmmu/physmem.c:2822 - #12 0x58beb589 in address_space_write (as=0x608000015f20, addr=0xe0002031, attrs=..., buf=0x7fffb9e0, len=8) at softmmu/physmem.c:2914 - -Reported-by: Dike -Reported-by: Duhao <504224090@qq.com> -BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=2032932 -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: Jason Wang - -Signed-off-by: tangbinzy ---- - hw/net/vmxnet3.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c -index f65af4e9ef..0b7acf7f89 100644 ---- a/hw/net/vmxnet3.c -+++ b/hw/net/vmxnet3.c -@@ -1816,7 +1816,9 @@ vmxnet3_io_bar1_write(void *opaque, - case VMXNET3_REG_ICR: - VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d", - val, size); -- g_assert_not_reached(); -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "%s: write to read-only register VMXNET3_REG_ICR\n", -+ TYPE_VMXNET3); - break; - - /* Event Cause Register */ --- -2.27.0 - diff --git a/hw-net-vmxnet3-allow-VMXNET3_MAX_MTU-itself-as-a-val.patch b/hw-net-vmxnet3-allow-VMXNET3_MAX_MTU-itself-as-a-val.patch deleted file mode 100644 index 8219c0f9d855aae5aeeeed4076fb8fe3e8ef6a84..0000000000000000000000000000000000000000 --- a/hw-net-vmxnet3-allow-VMXNET3_MAX_MTU-itself-as-a-val.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 2d7c5ea10b443c33ffe2c21de5a495bd6d2a67bd Mon Sep 17 00:00:00 2001 -From: qihao -Date: Wed, 28 Jun 2023 09:37:04 +0800 -Subject: [PATCH] hw/net/vmxnet3: allow VMXNET3_MAX_MTU itself as a value - -cheery-pick from b209cc4556d56938fa8a933670b8fb98c036af37 - -Currently, VMXNET3_MAX_MTU itself (being 9000) is not considered a -valid value for the MTU, but a guest running ESXi 7.0 might try to -set it and fail the assert [0]. - -In the Linux kernel, dev->max_mtu itself is a valid value for the MTU -and for the vmxnet3 driver it's 9000, so a guest running Linux will -also fail the assert when trying to set an MTU of 9000. - -VMXNET3_MAX_MTU and s->mtu don't seem to be used in relation to buffer -allocations/accesses, so allowing the upper limit itself as a value -should be fine. - -[0]: https://forum.proxmox.com/threads/114011/ - -Fixes: d05dcd94ae ("net: vmxnet3: validate configuration values during activate (CVE-2021-20203)") -Signed-off-by: Fiona Ebner -Signed-off-by: Jason Wang -(cherry picked from commit 099a63828130843741d317cb28e936f468b2b53b) -Signed-off-by: Michael Tokarev -Signed-off-by: qihao_yewu ---- - hw/net/vmxnet3.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c -index 0b7acf7f89..a2037583bf 100644 ---- a/hw/net/vmxnet3.c -+++ b/hw/net/vmxnet3.c -@@ -1441,7 +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); -+ assert(VMXNET3_MIN_MTU <= s->mtu && s->mtu <= VMXNET3_MAX_MTU); - VMW_CFPRN("MTU is %u", s->mtu); - - s->max_rx_frags = --- -2.41.0.windows.1 - diff --git a/hw-nvme-Avoid-dynamic-stack-allocation.patch b/hw-nvme-Avoid-dynamic-stack-allocation.patch deleted file mode 100644 index aaa5f740eeb3a4a3c808b264c10fd5a4594eb1f4..0000000000000000000000000000000000000000 --- a/hw-nvme-Avoid-dynamic-stack-allocation.patch +++ /dev/null @@ -1,38 +0,0 @@ -From aa1f9c961de247522e772275635b7f15bf5bb13f Mon Sep 17 00:00:00 2001 -From: dinglimin -Date: Sat, 16 Sep 2023 17:20:08 +0800 -Subject: [PATCH] hw/nvme: Avoid dynamic stack allocation - -cheery-pick from b3c8246750b7077add335559341268f2956f6470 - -Instead of using a variable-length array in nvme_map_prp(), -allocate on the stack with a g_autofree pointer. - -The codebase has very few VLAs, and if we can get rid of them all we -can make the compiler error on new additions. This is a defensive -measure against security bugs where an on-stack dynamic allocation -isn't correctly size-checked (e.g. CVE-2021-3527). - -Signed-off-by: Peter Maydell -Signed-off-by: Klaus Jensen -Signed-off-by: dinglimin_yewu ---- - hw/nvme/ctrl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index debd3916dd..d64dd9c361 100644 ---- a/hw/nvme/ctrl.c -+++ b/hw/nvme/ctrl.c -@@ -702,7 +702,7 @@ static uint16_t nvme_map_prp(NvmeCtrl *n, NvmeSg *sg, uint64_t prp1, - len -= trans_len; - if (len) { - if (len > n->page_size) { -- uint64_t prp_list[n->max_prp_ents]; -+ g_autofree uint64_t *prp_list = g_new(uint64_t, n->max_prp_ents); - uint32_t nents, prp_trans; - int i = 0; - --- -2.41.0.windows.1 - diff --git a/hw-nvme-Change-alignment-in-dma-functions-for-nvme_b.patch b/hw-nvme-Change-alignment-in-dma-functions-for-nvme_b.patch deleted file mode 100644 index 65165c0425637cc6e42e8636c63785d1128f69bf..0000000000000000000000000000000000000000 --- a/hw-nvme-Change-alignment-in-dma-functions-for-nvme_b.patch +++ /dev/null @@ -1,91 +0,0 @@ -From f0ac211aab73b5b78795cd7bc94e0159c8e3cc1a Mon Sep 17 00:00:00 2001 -From: wangmeiyang -Date: Fri, 26 May 2023 11:03:29 +0800 -Subject: [PATCH] hw/nvme: Change alignment in dma functions for nvme_blk_* - -Since the nvme_blk_read/write are used by both the data and metadata -portions of the IO, it can't have the 512B alignment requirement. -Without this change any metadata transfer, which length isn't a multiple -of 512B and which is bigger than 512B, will result in only a partial -transfer. - -origin commit: https://gitlab.com/qemu-project/qemu/-/commit/9b4f01812f69ad6066725338c89945bb61f41823 -Signed-off-by: Meiyang Wang -Signed-off-by: Mateusz Kozlowski -Reviewed-by: Klaus Jensen -Signed-off-by: Klaus Jensen ---- - hw/nvme/ctrl.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - -diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index 40fbda3b03..282abdda91 100644 ---- a/hw/nvme/ctrl.c -+++ b/hw/nvme/ctrl.c -@@ -1263,26 +1263,28 @@ uint16_t nvme_bounce_mdata(NvmeCtrl *n, uint8_t *ptr, uint32_t len, - } - - static inline void nvme_blk_read(BlockBackend *blk, int64_t offset, -- BlockCompletionFunc *cb, NvmeRequest *req) -+ uint32_t align, BlockCompletionFunc *cb, -+ NvmeRequest *req) - { - assert(req->sg.flags & NVME_SG_ALLOC); - - if (req->sg.flags & NVME_SG_DMA) { -- req->aiocb = dma_blk_read(blk, &req->sg.qsg, offset, BDRV_SECTOR_SIZE, -- cb, req); -+ req->aiocb = dma_blk_read(blk, &req->sg.qsg, offset, align, cb, req); - } else { - req->aiocb = blk_aio_preadv(blk, offset, &req->sg.iov, 0, cb, req); - } - } - - static inline void nvme_blk_write(BlockBackend *blk, int64_t offset, -- BlockCompletionFunc *cb, NvmeRequest *req) -+ uint32_t align, BlockCompletionFunc *cb, -+ NvmeRequest *req) - { - assert(req->sg.flags & NVME_SG_ALLOC); - - if (req->sg.flags & NVME_SG_DMA) { - req->aiocb = dma_blk_write(blk, &req->sg.qsg, offset, BDRV_SECTOR_SIZE, - cb, req); -+ req->aiocb = dma_blk_write(blk, &req->sg.qsg, offset, align, cb, req); - } else { - req->aiocb = blk_aio_pwritev(blk, offset, &req->sg.iov, 0, cb, req); - } -@@ -1958,10 +1960,10 @@ static void nvme_rw_cb(void *opaque, int ret) - } - - if (req->cmd.opcode == NVME_CMD_READ) { -- return nvme_blk_read(blk, offset, nvme_rw_complete_cb, req); -+ return nvme_blk_read(blk, offset, 1, nvme_rw_complete_cb, req); - } - -- return nvme_blk_write(blk, offset, nvme_rw_complete_cb, req); -+ return nvme_blk_write(blk, offset, 1, nvme_rw_complete_cb, req); - } - } - -@@ -3145,7 +3147,7 @@ static uint16_t nvme_read(NvmeCtrl *n, NvmeRequest *req) - - block_acct_start(blk_get_stats(blk), &req->acct, data_size, - BLOCK_ACCT_READ); -- nvme_blk_read(blk, data_offset, nvme_rw_cb, req); -+ nvme_blk_read(blk, data_offset, BDRV_SECTOR_SIZE, nvme_rw_cb, req); - return NVME_NO_COMPLETE; - - invalid: -@@ -3272,7 +3274,7 @@ static uint16_t nvme_do_write(NvmeCtrl *n, NvmeRequest *req, bool append, - - block_acct_start(blk_get_stats(blk), &req->acct, data_size, - BLOCK_ACCT_WRITE); -- nvme_blk_write(blk, data_offset, nvme_rw_cb, req); -+ nvme_blk_write(blk, data_offset, BDRV_SECTOR_SIZE, nvme_rw_cb, req); - } else { - req->aiocb = blk_aio_pwrite_zeroes(blk, data_offset, data_size, - BDRV_REQ_MAY_UNMAP, nvme_rw_cb, --- -2.41.0.windows.1 - diff --git a/hw-nvme-fix-CVE-2021-3929.patch b/hw-nvme-fix-CVE-2021-3929.patch deleted file mode 100644 index c00c465c8d531679bbfe78ad85e59297fc972980..0000000000000000000000000000000000000000 --- a/hw-nvme-fix-CVE-2021-3929.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 4f45d3a6a7c7803d31705e58f0e6356024998ef8 Mon Sep 17 00:00:00 2001 -From: Klaus Jensen -Date: Fri, 17 Dec 2021 10:44:01 +0100 -Subject: [PATCH] hw/nvme: fix CVE-2021-3929 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes CVE-2021-3929 "locally" by denying DMA to the iomem of the -device itself. This still allows DMA to MMIO regions of other devices -(e.g. doing P2P DMA to the controller memory buffer of another NVMe -device). - -Fixes: CVE-2021-3929 -Reported-by: Qiuhao Li -Reviewed-by: Keith Busch -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Klaus Jensen ---- - hw/nvme/ctrl.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index 462f79a1f6..40fbda3b03 100644 ---- a/hw/nvme/ctrl.c -+++ b/hw/nvme/ctrl.c -@@ -357,6 +357,24 @@ static inline void *nvme_addr_to_pmr(NvmeCtrl *n, hwaddr addr) - return memory_region_get_ram_ptr(&n->pmr.dev->mr) + (addr - n->pmr.cba); - } - -+static inline bool nvme_addr_is_iomem(NvmeCtrl *n, hwaddr addr) -+{ -+ hwaddr hi, lo; -+ -+ /* -+ * The purpose of this check is to guard against invalid "local" access to -+ * the iomem (i.e. controller registers). Thus, we check against the range -+ * covered by the 'bar0' MemoryRegion since that is currently composed of -+ * two subregions (the NVMe "MBAR" and the MSI-X table/pba). Note, however, -+ * that if the device model is ever changed to allow the CMB to be located -+ * in BAR0 as well, then this must be changed. -+ */ -+ lo = n->bar0.addr; -+ hi = lo + int128_get64(n->bar0.size); -+ -+ return addr >= lo && addr < hi; -+} -+ - static int nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size) - { - hwaddr hi = addr + size - 1; -@@ -614,6 +632,10 @@ static uint16_t nvme_map_addr(NvmeCtrl *n, NvmeSg *sg, hwaddr addr, size_t len) - - trace_pci_nvme_map_addr(addr, len); - -+ if (nvme_addr_is_iomem(n, addr)) { -+ return NVME_DATA_TRAS_ERROR; -+ } -+ - if (nvme_addr_is_cmb(n, addr)) { - cmb = true; - } else if (nvme_addr_is_pmr(n, addr)) { --- -2.27.0 - diff --git a/hw-nvme-fix-memory-leak-in-nvme_dsm.patch b/hw-nvme-fix-memory-leak-in-nvme_dsm.patch deleted file mode 100644 index 501c8d629e522d782a9d4b7b8e01ec15ec4680c5..0000000000000000000000000000000000000000 --- a/hw-nvme-fix-memory-leak-in-nvme_dsm.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2a3757a66aad487b64afb8935015c408fd9fdcbb Mon Sep 17 00:00:00 2001 -From: wangmeiyang -Date: Fri, 28 Apr 2023 12:01:45 +0800 -Subject: [PATCH] hw/nvme: fix memory leak in nvme_dsm -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The iocb (and the allocated memory to hold LBA ranges) leaks if reading -the LBA ranges fails. - -Fix this by adding a free and an unref of the iocb. - -origin commit: https://gitlab.com/qemu-project/qemu/-/commit/4b32319cdacd99be983e1a74128289ef52c5964e -Signed-off-by: Meiyang Wang -Reported-by: Coverity (CID 1508281) -Fixes: d7d1474fd85d ("hw/nvme: reimplement dsm to allow cancellation") -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Klaus Jensen ---- - hw/nvme/ctrl.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index 40fbda3b03..5f1515828b 100644 ---- a/hw/nvme/ctrl.c -+++ b/hw/nvme/ctrl.c -@@ -2381,6 +2381,9 @@ static uint16_t nvme_dsm(NvmeCtrl *n, NvmeRequest *req) - status = nvme_h2c(n, (uint8_t *)iocb->range, sizeof(NvmeDsmRange) * nr, - req); - if (status) { -+ g_free(iocb->range); -+ qemu_aio_unref(iocb); -+ - return status; - } - --- -2.27.0 - diff --git a/hw-nvme-fix-missing-DNR-on-compare-failure.patch b/hw-nvme-fix-missing-DNR-on-compare-failure.patch deleted file mode 100644 index 32fe676050ca40b1b0503c175f0bb88b2c49ec6b..0000000000000000000000000000000000000000 --- a/hw-nvme-fix-missing-DNR-on-compare-failure.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 5d4fdfc6639103d0ea5754537886921e59abb2fc Mon Sep 17 00:00:00 2001 -From: wangmeiyang -Date: Fri, 26 May 2023 10:52:48 +0800 -Subject: [PATCH] hw/nvme: fix missing DNR on compare failure - -Even if the host is somehow using compare to do compare-and-write, the -host should be notified immediately about the compare failure and not -have to wait for the driver to potentially retry the command. - -origin commit: https://gitlab.com/qemu-project/qemu/-/commit/ca2a091802872b265bc6007a2d36276d51d8e4b3 -Signed-off-by: Meiyang Wang -Fixes: 0a384f923f51 ("hw/block/nvme: add compare command") -Reported-by: Jim Harris -Signed-off-by: Klaus Jensen ---- - hw/nvme/ctrl.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index 40fbda3b03..0b4df77e3c 100644 ---- a/hw/nvme/ctrl.c -+++ b/hw/nvme/ctrl.c -@@ -2123,7 +2123,7 @@ static void nvme_compare_mdata_cb(void *opaque, int ret) - - for (bufp = buf; mbufp < end; bufp += ns->lbaf.ms, mbufp += ns->lbaf.ms) { - if (memcmp(bufp + pil, mbufp + pil, ns->lbaf.ms - pil)) { -- req->status = NVME_CMP_FAILURE; -+ req->status = NVME_CMP_FAILURE | NVME_DNR; - goto out; - } - } -@@ -2132,7 +2132,7 @@ static void nvme_compare_mdata_cb(void *opaque, int ret) - } - - if (memcmp(buf, ctx->mdata.bounce, ctx->mdata.iov.size)) { -- req->status = NVME_CMP_FAILURE; -+ req->status = NVME_CMP_FAILURE | NVME_DNR; - goto out; - } - -@@ -2181,7 +2181,7 @@ static void nvme_compare_data_cb(void *opaque, int ret) - } - - if (memcmp(buf, ctx->data.bounce, ctx->data.iov.size)) { -- req->status = NVME_CMP_FAILURE; -+ req->status = NVME_CMP_FAILURE | NVME_DNR; - goto out; - } - --- -2.41.0.windows.1 - diff --git a/hw-pci-Fix-a-typo.patch b/hw-pci-Fix-a-typo.patch deleted file mode 100644 index 7ecad41c6cb4f537b12bb6c7498794838bb41068..0000000000000000000000000000000000000000 --- a/hw-pci-Fix-a-typo.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c7fe3321e6abb3502a7d4366c9fdbe690bfa9ea9 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Fri, 17 Mar 2023 11:04:01 +0800 -Subject: [PATCH] hw/pci: Fix a typo -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fix 'interrutp' typo. - -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: jianchunfu ---- - hw/pci/pci.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 0743dc7c42..b89c36ab80 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -1579,7 +1579,7 @@ void pci_device_set_intx_routing_notifier(PCIDevice *dev, - * 9.1: Interrupt routing. Table 9-1 - * - * the PCI Express Base Specification, Revision 2.1 -- * 2.2.8.1: INTx interrutp signaling - Rules -+ * 2.2.8.1: INTx interrupt signaling - Rules - * the Implementation Note - * Table 2-20 - */ --- -2.27.0 - diff --git a/hw-pci-Trace-IRQ-routing-on-PCI-topology.patch b/hw-pci-Trace-IRQ-routing-on-PCI-topology.patch deleted file mode 100644 index 873bfcd92456d2a213e4cb7ca3b3efd3c72d80ce..0000000000000000000000000000000000000000 --- a/hw-pci-Trace-IRQ-routing-on-PCI-topology.patch +++ /dev/null @@ -1,65 +0,0 @@ -From b5e972454b1c4784c6b8e163016a237c084a1b46 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Fri, 17 Mar 2023 11:12:02 +0800 -Subject: [PATCH] hw/pci: Trace IRQ routing on PCI topology -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Trace how IRQ are rooted from EP to RC. - -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: jianchunfu ---- - hw/pci/pci.c | 8 ++++++++ - hw/pci/trace-events | 1 + - 2 files changed, 9 insertions(+) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index b89c36ab80..96dcc738f2 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -269,11 +269,15 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change) - { - PCIBus *bus; - for (;;) { -+ int dev_irq = irq_num; - bus = pci_get_bus(pci_dev); - if (!bus) { - return; - } - irq_num = bus->map_irq(pci_dev, irq_num); -+ trace_pci_route_irq(dev_irq, DEVICE(pci_dev)->canonical_path, irq_num, -+ pci_bus_is_root(bus) ? "root-complex" -+ : DEVICE(bus->parent_dev)->canonical_path); - if (bus->set_irq) - break; - pci_dev = bus->parent_dev; -@@ -1531,8 +1535,12 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin) - PCIBus *bus; - - do { -+ int dev_irq = pin; - bus = pci_get_bus(dev); - pin = bus->map_irq(dev, pin); -+ trace_pci_route_irq(dev_irq, DEVICE(dev)->canonical_path, pin, -+ pci_bus_is_root(bus) ? "root-complex" -+ : DEVICE(bus->parent_dev)->canonical_path); - dev = bus->parent_dev; - } while (dev); - -diff --git a/hw/pci/trace-events b/hw/pci/trace-events -index fc777d0b5e..7e294b7e8a 100644 ---- a/hw/pci/trace-events -+++ b/hw/pci/trace-events -@@ -3,6 +3,7 @@ - # pci.c - pci_update_mappings_del(void *d, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "d=%p %02x:%02x.%x %d,0x%"PRIx64"+0x%"PRIx64 - pci_update_mappings_add(void *d, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "d=%p %02x:%02x.%x %d,0x%"PRIx64"+0x%"PRIx64 -+pci_route_irq(int dev_irq, const char *dev_path, int parent_irq, const char *parent_path) "IRQ %d @%s -> IRQ %d @%s" - - # pci_host.c - pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x" --- -2.27.0 - diff --git a/hw-pci-bridge-pxb-Fix-missing-swizzle.patch b/hw-pci-bridge-pxb-Fix-missing-swizzle.patch deleted file mode 100644 index 9d114f54d4291c662a5a8456f1032146e812d5a4..0000000000000000000000000000000000000000 --- a/hw-pci-bridge-pxb-Fix-missing-swizzle.patch +++ /dev/null @@ -1,52 +0,0 @@ -From bf6161d03c1d6a8cb378a2f84743aa45b0ddf84b Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 26 Jul 2023 02:34:48 +0000 -Subject: [PATCH] hw/pci-bridge/pxb: Fix missing swizzle mainline inclusion - commit e609301b458bf6daba478299dc5aea5d1fbaea39 category: bugfix - ---------------------------------------------------------------- - -pxb_map_irq_fn() handled the necessary removal of the swizzle -applied to the PXB interrupts by the bus to which it was attached -but neglected to apply the normal swizzle for PCI root ports -on the expander bridge. - -Result of this was on ARM virt, the PME interrupts for a second -RP on a PXB instance were miss-routed to #45 rather than #46. - -Tested with a selection of different configurations with 1 to 5 -RP per PXB instance. Note on my x86 test setup the PME interrupts -are not triggered so I haven't been able to test this. - -Signed-off-by: Jonathan Cameron -Cc: Michael S. Tsirkin -Cc: Marcel Apfelbaum -Message-Id: <20220118174855.19325-1-Jonathan.Cameron@huawei.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin - -Signed-off-by: tangbinzy ---- - hw/pci-bridge/pci_expander_bridge.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c -index 10e6e7c2ab..de932286b5 100644 ---- a/hw/pci-bridge/pci_expander_bridge.c -+++ b/hw/pci-bridge/pci_expander_bridge.c -@@ -192,6 +192,12 @@ static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin) - { - PCIDevice *pxb = pci_get_bus(pci_dev)->parent_dev; - -+ /* -+ * First carry out normal swizzle to handle -+ * multple root ports on a pxb instance. -+ */ -+ pin = pci_swizzle_map_irq_fn(pci_dev, pin); -+ - /* - * The bios does not index the pxb slot number when - * it computes the IRQ because it resides on bus 0 --- -2.41.0.windows.1 - diff --git a/hw-ppc-Kconfig-MAC_NEWWORLD-should-always-select-USB.patch b/hw-ppc-Kconfig-MAC_NEWWORLD-should-always-select-USB.patch deleted file mode 100644 index 524446612bf5c87080b046f6fda81df1cd239e1b..0000000000000000000000000000000000000000 --- a/hw-ppc-Kconfig-MAC_NEWWORLD-should-always-select-USB.patch +++ /dev/null @@ -1,43 +0,0 @@ -From f2ee3b11fc10dd5353beb8efca7d919668dd332c Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 26 Jun 2023 11:04:33 +0800 -Subject: [PATCH] hw/ppc/Kconfig: MAC_NEWWORLD should always select - USB_OHCI_PCI -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick 9ec08f3569be3bc8bfd4d9b8b0445b9136910661 - -The PowerMacs have an OHCI controller soldered on the motherboard, -so this should always be enabled for the "mac99" machine. -This fixes the problem that QEMU aborts when the user tries to run -the "mac99" machine with a build that has been compiled with the -"--without-default-devices" configure switch. - -Signed-off-by: Thomas Huth -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Richard Henderson -Reviewed-by: Mark Cave-Ayland -Message-Id: <20230530102041.55527-1-thuth@redhat.com> -Signed-off-by: Daniel Henrique Barboza -Signed-off-by: qihao_yewu ---- - hw/ppc/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig -index 400511c6b7..9e0b7184e3 100644 ---- a/hw/ppc/Kconfig -+++ b/hw/ppc/Kconfig -@@ -119,6 +119,7 @@ config MAC_NEWWORLD - select MAC_PMU - select UNIN_PCI - select FW_CFG_PPC -+ select USB_OHCI_PCI - - config E500 - bool --- -2.41.0.windows.1 - diff --git a/hw-ppc-spapr_pci.c-Use-device_cold_reset-rather-than.patch b/hw-ppc-spapr_pci.c-Use-device_cold_reset-rather-than.patch deleted file mode 100644 index a9522e50023d1d9b8d2c205b06df67b9118b80a0..0000000000000000000000000000000000000000 --- a/hw-ppc-spapr_pci.c-Use-device_cold_reset-rather-than.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 77c0eacba702ad1799b71b00315313e1f9de2e1a Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Fri, 25 Nov 2022 10:44:28 +0800 -Subject: [PATCH 22/29] hw/ppc/spapr_pci.c: Use device_cold_reset() rather than - device_legacy_reset() - -In spapr_phb_children_reset() we call device_legacy_reset() to reset any -QOM children of the SPAPR PCI host bridge device. This will not reset -any qbus such a child might own. Switch to device_cold_reset(), which will -reset both the device and its buses. (If the child has no qbuses then -there will be no change in behaviour.) - -Signed-off-by: Peter Maydell -Signed-off-by: jianchunfu ---- - hw/ppc/spapr_pci.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c -index 5bfd4aa9e5..d3367e8578 100644 ---- a/hw/ppc/spapr_pci.c -+++ b/hw/ppc/spapr_pci.c -@@ -2044,7 +2044,7 @@ static int spapr_phb_children_reset(Object *child, void *opaque) - DeviceState *dev = (DeviceState *) object_dynamic_cast(child, TYPE_DEVICE); - - if (dev) { -- device_legacy_reset(dev); -+ device_cold_reset(dev); - } - - return 0; --- -2.27.0 - diff --git a/hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch b/hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch deleted file mode 100644 index 07ca361f450df2d31f5ec3ec736d7bcc1e4a43c7..0000000000000000000000000000000000000000 --- a/hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 38f8c09d9916e76d2907d68fbe69115aef3a5310 Mon Sep 17 00:00:00 2001 -From: Yuval Shaia -Date: Sun, 3 Apr 2022 12:52:34 +0300 -Subject: [PATCH] hw/pvrdma: Protect against buggy or malicious guest driver - -Guest driver might execute HW commands when shared buffers are not yet -allocated. -This could happen on purpose (malicious guest) or because of some other -guest/host address mapping error. -We need to protect againts such case. - -Fixes: CVE-2022-1050 - -Reported-by: Raven -Signed-off-by: Yuval Shaia -Message-Id: <20220403095234.2210-1-yuval.shaia.ml@gmail.com> -Signed-off-by: Laurent Vivier -Signed-off-by: liuxiangdong ---- - hw/rdma/vmw/pvrdma_cmd.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/rdma/vmw/pvrdma_cmd.c b/hw/rdma/vmw/pvrdma_cmd.c -index da7ddfa548..89db963c46 100644 ---- a/hw/rdma/vmw/pvrdma_cmd.c -+++ b/hw/rdma/vmw/pvrdma_cmd.c -@@ -796,6 +796,12 @@ int pvrdma_exec_cmd(PVRDMADev *dev) - - dsr_info = &dev->dsr_info; - -+ if (!dsr_info->dsr) { -+ /* Buggy or malicious guest driver */ -+ rdma_error_report("Exec command without dsr, req or rsp buffers"); -+ goto out; -+ } -+ - if (dsr_info->req->hdr.cmd >= sizeof(cmd_handlers) / - sizeof(struct cmd_handler)) { - rdma_error_report("Unsupported command"); --- -2.27.0 - diff --git a/hw-pvrdma-Protect-against-buggy-or-malicious-guest-driver.patch b/hw-pvrdma-Protect-against-buggy-or-malicious-guest-driver.patch deleted file mode 100644 index edc0d62fcecfeb7f5746ceaeb5ac7a98d34186ee..0000000000000000000000000000000000000000 --- a/hw-pvrdma-Protect-against-buggy-or-malicious-guest-driver.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 6532f02449e7a001bc74ea43690d6e1a87a7e3fc Mon Sep 17 00:00:00 2001 -From: Yuval Shaia -Date: Wed, 1 Mar 2023 16:29:26 +0200 -Subject: [PATCH] hw/pvrdma: Protect against buggy or malicious guest driver - -Guest driver allocates and initialize page tables to be used as a ring -of descriptors for CQ and async events. -The page table that represents the ring, along with the number of pages -in the page table is passed to the device. -Currently our device supports only one page table for a ring. - -Let's make sure that the number of page table entries the driver -reports, do not exceeds the one page table size. - -Reported-by: Soul Chen -Signed-off-by: Yuval Shaia -Fixes: CVE-2023-1544 -Message-ID: <20230301142926.18686-1-yuval.shaia.ml@gmail.com> -Signed-off-by: Thomas Huth ---- - hw/rdma/vmw/pvrdma_main.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c -index 91206dbb8e..f99b12a592 100644 ---- a/hw/rdma/vmw/pvrdma_main.c -+++ b/hw/rdma/vmw/pvrdma_main.c -@@ -91,19 +91,33 @@ static int init_dev_ring(PvrdmaRing *ring, PvrdmaRingState **ring_state, - dma_addr_t dir_addr, uint32_t num_pages) - { - uint64_t *dir, *tbl; -- int rc = 0; -+ int max_pages, rc = 0; - - if (!num_pages) { - rdma_error_report("Ring pages count must be strictly positive"); - return -EINVAL; - } - -+ /* -+ * Make sure we can satisfy the requested number of pages in a single -+ * TARGET_PAGE_SIZE sized page table (taking into account that first entry -+ * is reserved for ring-state) -+ */ -+ max_pages = TARGET_PAGE_SIZE / sizeof(dma_addr_t) - 1; -+ if (num_pages > max_pages) { -+ rdma_error_report("Maximum pages on a single directory must not exceed %d\n", -+ max_pages); -+ return -EINVAL; -+ } -+ - dir = rdma_pci_dma_map(pci_dev, dir_addr, TARGET_PAGE_SIZE); - if (!dir) { - rdma_error_report("Failed to map to page directory (ring %s)", name); - rc = -ENOMEM; - goto out; - } -+ -+ /* We support only one page table for a ring */ - tbl = rdma_pci_dma_map(pci_dev, dir[0], TARGET_PAGE_SIZE); - if (!tbl) { - rdma_error_report("Failed to map to page table (ring %s)", name); --- -2.27.0 - diff --git a/hw-qdev-Cosmetic-around-documentation.patch b/hw-qdev-Cosmetic-around-documentation.patch deleted file mode 100644 index cacee6c6a06e3ee2e6f1cb1686e3ec0c2b3d2768..0000000000000000000000000000000000000000 --- a/hw-qdev-Cosmetic-around-documentation.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 14c2249a3caa3afc6252ac61fb700378c4d32a40 Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Thu, 7 Dec 2023 11:13:33 +0800 -Subject: [PATCH] hw/qdev: Cosmetic around documentation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from 694804ed7b26e66e114a2330887187d697a0d92b - -Add empty lines to have a clearer distinction between different -functions declarations. - -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Yanan Wang -Message-Id: <20211218130437.1516929-2-f4bug@amsat.org> -Signed-off-by: Philippe Mathieu-Daudé -Signed-off-by: boringandboring ---- - include/hw/qdev-core.h | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h -index 20d3066595..59a822ffce 100644 ---- a/include/hw/qdev-core.h -+++ b/include/hw/qdev-core.h -@@ -321,6 +321,7 @@ compat_props_add(GPtrArray *arr, - * The returned object has a reference count of 1. - */ - DeviceState *qdev_new(const char *name); -+ - /** - * qdev_try_new: Try to create a device on the heap - * @name: device type to create -@@ -329,6 +330,7 @@ DeviceState *qdev_new(const char *name); - * does not exist, rather than asserting. - */ - DeviceState *qdev_try_new(const char *name); -+ - /** - * qdev_realize: Realize @dev. - * @dev: device to realize -@@ -347,6 +349,7 @@ DeviceState *qdev_try_new(const char *name); - * qdev_realize_and_unref() instead. - */ - bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp); -+ - /** - * qdev_realize_and_unref: Realize @dev and drop a reference - * @dev: device to realize -@@ -372,6 +375,7 @@ bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp); - * would be incorrect. For that use case you want qdev_realize(). - */ - bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp); -+ - /** - * qdev_unrealize: Unrealize a device - * @dev: device to unrealize -@@ -450,6 +454,7 @@ typedef enum { - * For named input GPIO lines, use qdev_get_gpio_in_named(). - */ - qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); -+ - /** - * qdev_get_gpio_in_named: Get one of a device's named input GPIO lines - * @dev: Device whose GPIO we want -@@ -497,6 +502,7 @@ qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n); - * For named output GPIO lines, use qdev_connect_gpio_out_named(). - */ - void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); -+ - /** - * qdev_connect_gpio_out: Connect one of a device's anonymous output GPIO lines - * @dev: Device whose GPIO to connect -@@ -524,6 +530,7 @@ void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); - */ - void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, - qemu_irq pin); -+ - /** - * qdev_get_gpio_out_connector: Get the qemu_irq connected to an output GPIO - * @dev: Device whose output GPIO we are interested in -@@ -541,6 +548,7 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, - * by the platform-bus subsystem. - */ - qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n); -+ - /** - * qdev_intercept_gpio_out: Intercept an existing GPIO connection - * @dev: Device to intercept the outbound GPIO line from -@@ -582,6 +590,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name); - * hold of an input GPIO line to manipulate it. - */ - void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); -+ - /** - * qdev_init_gpio_out: create an array of anonymous output GPIO lines - * @dev: Device to create output GPIOs for -@@ -610,6 +619,7 @@ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); - * handler. - */ - void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); -+ - /** - * qdev_init_gpio_out: create an array of named output GPIO lines - * @dev: Device to create output GPIOs for -@@ -623,6 +633,7 @@ void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); - */ - void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, - const char *name, int n); -+ - /** - * qdev_init_gpio_in_named_with_opaque: create an array of input GPIO lines - * for the specified device --- -2.27.0 - diff --git a/hw-riscv-boot-Reduce-FDT-address-alignment-constrain.patch b/hw-riscv-boot-Reduce-FDT-address-alignment-constrain.patch deleted file mode 100644 index ca3125a43beed631db6e1fc0c283aa22914839d9..0000000000000000000000000000000000000000 --- a/hw-riscv-boot-Reduce-FDT-address-alignment-constrain.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 919af9a7472996b17c45fcd508ae29ec58117e8c Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:39:26 -0800 -Subject: [PATCH] hw/riscv: boot: Reduce FDT address alignment constraints - -cherry picked from commit ec2c62dacc186893a6ce63089f96b1906dd68804 - -We previously stored the device tree at a 16MB alignment from the end of -memory (or 3GB). This means we need at least 16MB of memory to be able -to do this. We don't actually need the FDT to be 16MB aligned, so let's -drop it down to 2MB so that we can support systems with less memory, -while also allowing FDT size expansion. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/992 -Signed-off-by: Alistair Francis -Reviewed-by: Atish Patra -Reviewed-by: Bin Meng -Tested-by: Bin Meng -Message-Id: <20220608062015.317894-1-alistair.francis@opensource.wdc.com> -Signed-off-by: Alistair Francis -Signed-off-by: Wanghe Xiao ---- - hw/riscv/boot.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c -index 519fa455a1..c035aa68f5 100644 ---- a/hw/riscv/boot.c -+++ b/hw/riscv/boot.c -@@ -217,11 +217,11 @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) - /* - * We should put fdt as far as possible to avoid kernel/initrd overwriting - * its content. But it should be addressable by 32 bit system as well. -- * Thus, put it at an 16MB aligned address that less than fdt size from the -+ * Thus, put it at an 2MB aligned address that less than fdt size from the - * end of dram or 3GB whichever is lesser. - */ - temp = MIN(dram_end, 3072 * MiB); -- fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB); -+ fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); - - ret = fdt_pack(fdt); - /* Should only fail if we've built a corrupted tree */ --- -2.27.0 - diff --git a/hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch b/hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch deleted file mode 100644 index caa2cc1911056b6715a49c3712a97527e7e86e10..0000000000000000000000000000000000000000 --- a/hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 612fe39ec96f7171501dd3b86af7ca2d9a8efbfe Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Thu, 16 Mar 2023 16:27:05 +0800 -Subject: [PATCH] hw/riscv: virt: Simplify virt_{get,set}_aclint() - -There is no need to declare an intermediate "MachineState *ms". - -Signed-off-by: Bin Meng -Signed-off-by: jianchunfu ---- - hw/riscv/virt.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c -index 3af074148e..cd03ba1d76 100644 ---- a/hw/riscv/virt.c -+++ b/hw/riscv/virt.c -@@ -984,16 +984,14 @@ static void virt_machine_instance_init(Object *obj) - - static bool virt_get_aclint(Object *obj, Error **errp) - { -- MachineState *ms = MACHINE(obj); -- RISCVVirtState *s = RISCV_VIRT_MACHINE(ms); -+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); - - return s->have_aclint; - } - - static void virt_set_aclint(Object *obj, bool value, Error **errp) - { -- MachineState *ms = MACHINE(obj); -- RISCVVirtState *s = RISCV_VIRT_MACHINE(ms); -+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); - - s->have_aclint = value; - } --- -2.27.0 - diff --git a/hw-rx-rx-gdbsim-DTB-load-address-aligned-of-16byte.patch b/hw-rx-rx-gdbsim-DTB-load-address-aligned-of-16byte.patch deleted file mode 100644 index b1959c8c107b7a909844a7b96d590cd534e52a54..0000000000000000000000000000000000000000 --- a/hw-rx-rx-gdbsim-DTB-load-address-aligned-of-16byte.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 97928027aadb358cdee1a2d0c4152979d867b575 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 21 Aug 2023 06:33:49 +0000 -Subject: [PATCH] hw/rx: rx-gdbsim DTB load address aligned of 16byte. - mainline inclusion commit bcc6f33b671d223a1d7b81491d45c58b35ed6e3e category: - bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -Linux kernel required alined address of DTB. -But missing align in dtb load function. -Fixed to load to the correct address. - -Signed-off-by: Yoshinori Sato -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20220207132758.84403-1-ysato@users.sourceforge.jp> -Signed-off-by: Richard Henderson - -Signed-off-by: tangbinzy ---- - hw/rx/rx-gdbsim.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/rx/rx-gdbsim.c b/hw/rx/rx-gdbsim.c -index 75d1fec6ca..887083737b 100644 ---- a/hw/rx/rx-gdbsim.c -+++ b/hw/rx/rx-gdbsim.c -@@ -142,7 +142,7 @@ static void rx_gdbsim_init(MachineState *machine) - exit(1); - } - /* DTB is located at the end of SDRAM space. */ -- dtb_offset = machine->ram_size - dtb_size; -+ dtb_offset = ROUND_DOWN(machine->ram_size - dtb_size, 16); - rom_add_blob_fixed("dtb", dtb, dtb_size, - SDRAM_BASE + dtb_offset); - /* Set dtb address to R1 */ --- -2.41.0.windows.1 - diff --git a/hw-scsi-lsi53c895a-Do-not-abort-when-DMA-requested-a.patch b/hw-scsi-lsi53c895a-Do-not-abort-when-DMA-requested-a.patch deleted file mode 100644 index 36c85f00192d6db85b41ecda9fa5834071ecbbb1..0000000000000000000000000000000000000000 --- a/hw-scsi-lsi53c895a-Do-not-abort-when-DMA-requested-a.patch +++ /dev/null @@ -1,71 +0,0 @@ -From eb84ec128104b04861283adbc8b0fe7d11f638c0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Tue, 23 Nov 2021 12:17:31 +0100 -Subject: [PATCH 1/4] hw/scsi/lsi53c895a: Do not abort when DMA requested and - no data queued -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If asked for DMA request and no data is available, simply wait -for data to be queued, do not abort. This fixes: - - $ cat << EOF | \ - qemu-system-i386 -nographic -M q35,accel=qtest -serial none \ - -monitor none -qtest stdio -trace lsi* \ - -drive if=none,id=drive0,file=null-co://,file.read-zeroes=on,format=raw \ - -device lsi53c895a,id=scsi0 -device scsi-hd,drive=drive0,bus=scsi0.0,channel=0,scsi-id=0,lun=0 - lsi_reset Reset - lsi_reg_write Write reg DSP2 0x2e = 0xff - lsi_reg_write Write reg DSP3 0x2f = 0xff - lsi_execute_script SCRIPTS dsp=0xffff0000 opcode 0x184a3900 arg 0x4a8b2d75 - qemu-system-i386: hw/scsi/lsi53c895a.c:624: lsi_do_dma: Assertion `s->current' failed. - - (gdb) bt - #5 0x00007ffff4e8a3a6 in __GI___assert_fail - (assertion=0x5555560accbc "s->current", file=0x5555560acc28 "hw/scsi/lsi53c895a.c", line=624, function=0x5555560adb18 "lsi_do_dma") at assert.c:101 - #6 0x0000555555aa33b9 in lsi_do_dma (s=0x555557805ac0, out=1) at hw/scsi/lsi53c895a.c:624 - #7 0x0000555555aa5042 in lsi_execute_script (s=0x555557805ac0) at hw/scsi/lsi53c895a.c:1250 - #8 0x0000555555aa757a in lsi_reg_writeb (s=0x555557805ac0, offset=47, val=255 '\377') at hw/scsi/lsi53c895a.c:1984 - #9 0x0000555555aa875b in lsi_mmio_write (opaque=0x555557805ac0, addr=47, val=255, size=1) at hw/scsi/lsi53c895a.c:2095 - -Cc: qemu-stable@nongnu.org -Cc: Gerd Hoffmann -Cc: Vadim Rozenfeld -Cc: Stefan Hajnoczi -Reported-by: Jérôme Poulin -Reported-by: Ruhr-University -Reported-by: Gaoning Pan -Reported-by: Cheolwoo Myung -Fixes: b96a0da06bd ("lsi: move dma_len+dma_buf into lsi_request") -BugLink: https://bugs.launchpad.net/qemu/+bug/697510 -BugLink: https://bugs.launchpad.net/qemu/+bug/1905521 -BugLink: https://bugs.launchpad.net/qemu/+bug/1908515 -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/84 -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/305 -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/552 -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Laurent Vivier -Message-Id: <20211123111732.83137-2-philmd@redhat.com> -Signed-off-by: Paolo Bonzini ---- - hw/scsi/lsi53c895a.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c -index 85e907a785..4c431adb77 100644 ---- a/hw/scsi/lsi53c895a.c -+++ b/hw/scsi/lsi53c895a.c -@@ -621,8 +621,7 @@ static void lsi_do_dma(LSIState *s, int out) - dma_addr_t addr; - SCSIDevice *dev; - -- assert(s->current); -- if (!s->current->dma_len) { -+ if (!s->current || !s->current->dma_len) { - /* Wait until data is available. */ - trace_lsi_do_dma_unavailable(); - return; --- -2.27.0 - diff --git a/hw-scsi-megasas-Use-uint32_t-for-reply-queue-head-ta.patch b/hw-scsi-megasas-Use-uint32_t-for-reply-queue-head-ta.patch deleted file mode 100644 index 4577f84f01eebfb61f991aa4d951f487c4b5b588..0000000000000000000000000000000000000000 --- a/hw-scsi-megasas-Use-uint32_t-for-reply-queue-head-ta.patch +++ /dev/null @@ -1,79 +0,0 @@ -From e430aa3df353a19370ebd91421f5a545fa4ce211 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 22:43:05 +0100 -Subject: [PATCH 01/25] hw/scsi/megasas: Use uint32_t for reply queue head/tail - values -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -While the reply queue values fit in 16-bit, they are accessed -as 32-bit: - - 661: s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa); - 662: s->reply_queue_head %= MEGASAS_MAX_FRAMES; - 663: s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa); - 664: s->reply_queue_tail %= MEGASAS_MAX_FRAMES; - -Having: - - 41:#define MEGASAS_MAX_FRAMES 2048 /* Firmware limit at 65535 */ - -In order to update the ld/st*_pci_dma() API to pass the address -of the value to access, it is simpler to have the head/tail declared -as 32-bit values. Replace the uint16_t by uint32_t, wasting 4 bytes in -the MegasasState structure. - -Acked-by: Richard Henderson -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-20-philmd@redhat.com> ---- - hw/scsi/megasas.c | 4 ++-- - hw/scsi/trace-events | 8 ++++---- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index 4ff51221d4..6d21bf9fdd 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -109,8 +109,8 @@ struct MegasasState { - uint64_t reply_queue_pa; - void *reply_queue; - uint16_t reply_queue_len; -- uint16_t reply_queue_head; -- uint16_t reply_queue_tail; -+ uint32_t reply_queue_head; -+ uint32_t reply_queue_tail; - uint64_t consumer_pa; - uint64_t producer_pa; - -diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events -index 92d5b40f89..ae8551f279 100644 ---- a/hw/scsi/trace-events -+++ b/hw/scsi/trace-events -@@ -42,18 +42,18 @@ mptsas_config_sas_phy(void *dev, int address, int port, int phy_handle, int dev_ - - # megasas.c - megasas_init_firmware(uint64_t pa) "pa 0x%" PRIx64 " " --megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at 0x%" PRIx64 " len %d head 0x%" PRIx64 " tail 0x%" PRIx64 " flags 0x%x" -+megasas_init_queue(uint64_t queue_pa, int queue_len, uint32_t head, uint32_t tail, uint32_t flags) "queue at 0x%" PRIx64 " len %d head 0x%" PRIx32 " tail 0x%" PRIx32 " flags 0x%x" - megasas_initq_map_failed(int frame) "scmd %d: failed to map queue" - megasas_initq_mapped(uint64_t pa) "queue already mapped at 0x%" PRIx64 - megasas_initq_mismatch(int queue_len, int fw_cmds) "queue size %d max fw cmds %d" - megasas_qf_mapped(unsigned int index) "skip mapped frame 0x%x" - megasas_qf_new(unsigned int index, uint64_t frame) "frame 0x%x addr 0x%" PRIx64 - megasas_qf_busy(unsigned long pa) "all frames busy for frame 0x%lx" --megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, unsigned int head, unsigned int tail, int busy) "frame 0x%x count %d context 0x%" PRIx64 " head 0x%x tail 0x%x busy %d" --megasas_qf_update(unsigned int head, unsigned int tail, unsigned int busy) "head 0x%x tail 0x%x busy %d" -+megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, uint32_t head, uint32_t tail, unsigned int busy) "frame 0x%x count %d context 0x%" PRIx64 " head 0x%" PRIx32 " tail 0x%" PRIx32 " busy %u" -+megasas_qf_update(uint32_t head, uint32_t tail, unsigned int busy) "head 0x%" PRIx32 " tail 0x%" PRIx32 " busy %u" - megasas_qf_map_failed(int cmd, unsigned long frame) "scmd %d: frame %lu" - megasas_qf_complete_noirq(uint64_t context) "context 0x%" PRIx64 " " --megasas_qf_complete(uint64_t context, unsigned int head, unsigned int tail, int busy) "context 0x%" PRIx64 " head 0x%x tail 0x%x busy %d" -+megasas_qf_complete(uint64_t context, uint32_t head, uint32_t tail, int busy) "context 0x%" PRIx64 " head 0x%" PRIx32 " tail 0x%" PRIx32 " busy %u" - megasas_frame_busy(uint64_t addr) "frame 0x%" PRIx64 " busy" - megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd) "scmd %d: MFI cmd 0x%x" - megasas_handle_scsi(const char *frame, int bus, int dev, int lun, void *sdev, unsigned long size) "%s dev %x/%x/%x sdev %p xfer %lu" --- -2.27.0 - diff --git a/hw-scsi-vhost-scsi-don-t-double-close-vhostfd-on-err.patch b/hw-scsi-vhost-scsi-don-t-double-close-vhostfd-on-err.patch deleted file mode 100644 index 84db18055bf4c0b9627b072c8d2de7c669ce60d5..0000000000000000000000000000000000000000 --- a/hw-scsi-vhost-scsi-don-t-double-close-vhostfd-on-err.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 69f5f16cee63b0d07ee612b59a0d125780c13bdb Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Fri, 8 Dec 2023 09:13:42 +0800 -Subject: [PATCH] hw/scsi/vhost-scsi: don't double close vhostfd on error - -cherry picked from 539ba1acacb11a0f27a7e7ff7e2a7c1294e0a1ea - -vhost_dev_init calls vhost_dev_cleanup on error, which closes vhostfd, -don't double close it. - -Signed-off-by: Daniil Tatianin -Message-Id: <20211129132358.1110372-2-d-tatianin@yandex-team.ru> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: boringandboring ---- - hw/scsi/vhost-scsi.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c -index b0a9c45e43..5536cc8a88 100644 ---- a/hw/scsi/vhost-scsi.c -+++ b/hw/scsi/vhost-scsi.c -@@ -220,6 +220,11 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) - ret = vhost_dev_init(&vsc->dev, (void *)(uintptr_t)vhostfd, - VHOST_BACKEND_TYPE_KERNEL, 0, errp); - if (ret < 0) { -+ /* -+ * vhost_dev_init calls vhost_dev_cleanup on error, which closes -+ * vhostfd, don't double close it. -+ */ -+ vhostfd = -1; - goto free_vqs; - } - -@@ -240,7 +245,9 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) - error_free(vsc->migration_blocker); - virtio_scsi_common_unrealize(dev); - close_fd: -- close(vhostfd); -+ if (vhostfd >= 0) { -+ close(vhostfd); -+ } - return; - } - --- -2.27.0 - diff --git a/hw-scsi-vhost-scsi-don-t-leak-vqs-on-error.patch b/hw-scsi-vhost-scsi-don-t-leak-vqs-on-error.patch deleted file mode 100644 index 5d898ce546de60926c05cce0fede7bbf0102b9e6..0000000000000000000000000000000000000000 --- a/hw-scsi-vhost-scsi-don-t-leak-vqs-on-error.patch +++ /dev/null @@ -1,55 +0,0 @@ -From ad55425ad09197b443c150828ac16dbf4242141f Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Thu, 7 Dec 2023 19:45:33 +0800 -Subject: [PATCH] hw/scsi/vhost-scsi: don't leak vqs on error - -cherry picked from b259772afc29ef6af4e911d8e695dd7e2ed31066 - -vhost_dev_init calls vhost_dev_cleanup in case of an error during -initialization, which zeroes out the entire vsc->dev as well as the -vsc->dev.vqs pointer. This prevents us from properly freeing it in free_vqs. -Keep a local copy of the pointer so we can free it later. - -Signed-off-by: Daniil Tatianin -Message-Id: <20211129132358.1110372-1-d-tatianin@yandex-team.ru> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: boringandboring ---- - hw/scsi/vhost-scsi.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c -index b0a9c45e43..2fbc7f039d 100644 ---- a/hw/scsi/vhost-scsi.c -+++ b/hw/scsi/vhost-scsi.c -@@ -170,6 +170,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) - Error *err = NULL; - int vhostfd = -1; - int ret; -+ struct vhost_virtqueue *vqs = NULL; - - if (!vs->conf.wwpn) { - error_setg(errp, "vhost-scsi: missing wwpn"); -@@ -213,7 +214,8 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) - } - - vsc->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; -- vsc->dev.vqs = g_new0(struct vhost_virtqueue, vsc->dev.nvqs); -+ vqs = g_new0(struct vhost_virtqueue, vsc->dev.nvqs); -+ vsc->dev.vqs = vqs; - vsc->dev.vq_index = 0; - vsc->dev.backend_features = 0; - -@@ -232,7 +234,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) - return; - - free_vqs: -- g_free(vsc->dev.vqs); -+ g_free(vqs); - if (!vsc->migratable) { - migrate_del_blocker(vsc->migration_blocker); - } --- -2.27.0 - diff --git a/hw-ssi-Fix-Linux-driver-init-issue-with-xilinx_spi.patch b/hw-ssi-Fix-Linux-driver-init-issue-with-xilinx_spi.patch deleted file mode 100644 index 4b74eaa48d2e14530138f4a7915c729f4a03b777..0000000000000000000000000000000000000000 --- a/hw-ssi-Fix-Linux-driver-init-issue-with-xilinx_spi.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 58a192d877acfe06964d91ef831597f833ac4f0c Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Mon, 14 Aug 2023 18:57:59 -0700 -Subject: [PATCH] hw/ssi: Fix Linux driver init issue with xilinx_spi - -cherry picked from commit a0eaa126af3c5a43937a22c58cfb9bb36e4a5001 - -The problem is that the Linux driver expects the master transaction inhibit -bit(R_SPICR_MTI) to be set during driver initialization so that it can -detect the fifo size but QEMU defaults it to zero out of reset. The -datasheet indicates this bit is active on reset. - -See page 25, SPI Control Register section: -https://www.xilinx.com/content/dam/xilinx/support/documents/ip_documentation/axi_quad_spi/v3_2/pg153-axi-quad-spi.pdf - -Signed-off-by: Chris Rauer -Message-id: 20230323182811.2641044-1-crauer@google.com -Reviewed-by: Edgar E. Iglesias -Signed-off-by: Peter Maydell -Signed-off-by: Wanghe Xiao ---- - hw/ssi/xilinx_spi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c -index b2819a7ff0..92e7cabf42 100644 ---- a/hw/ssi/xilinx_spi.c -+++ b/hw/ssi/xilinx_spi.c -@@ -156,6 +156,7 @@ static void xlx_spi_do_reset(XilinxSPI *s) - txfifo_reset(s); - - s->regs[R_SPISSR] = ~0; -+ s->regs[R_SPICR] = R_SPICR_MTI; - xlx_spi_update_irq(s); - xlx_spi_update_cs(s); - } --- -2.41.0.windows.1 - diff --git a/hw-timer-npcm7xx_timer-Prevent-timer-from-counting-d.patch b/hw-timer-npcm7xx_timer-Prevent-timer-from-counting-d.patch deleted file mode 100644 index c554bb4c3e77d88c4224611962cacc7936e2b478..0000000000000000000000000000000000000000 --- a/hw-timer-npcm7xx_timer-Prevent-timer-from-counting-d.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 7f5cf2958ee5d178d058470031b96a82d3002a5c Mon Sep 17 00:00:00 2001 -From: qihao -Date: Wed, 1 Nov 2023 19:00:34 +0800 -Subject: [PATCH] hw/timer/npcm7xx_timer: Prevent timer from counting down past - zero - -cheery-pick from 9ef2629712680e70cbf39d8b6cb1ec0e0e2e72fa - -The counter register is only 24-bits and counts down. If the timer is -running but the qtimer to reset it hasn't fired off yet, there is a chance -the regster read can return an invalid result. - -Signed-off-by: Chris Rauer -Message-id: 20230922181411.2697135-1-crauer@google.com -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell -Signed-off-by: qihao_yewu ---- - hw/timer/npcm7xx_timer.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c -index 32f5e021f8..a8bd93aeb2 100644 ---- a/hw/timer/npcm7xx_timer.c -+++ b/hw/timer/npcm7xx_timer.c -@@ -138,6 +138,9 @@ static int64_t npcm7xx_timer_count_to_ns(NPCM7xxTimer *t, uint32_t count) - /* Convert a time interval in nanoseconds to a timer cycle count. */ - static uint32_t npcm7xx_timer_ns_to_count(NPCM7xxTimer *t, int64_t ns) - { -+ if (ns < 0) { -+ return 0; -+ } - return clock_ns_to_ticks(t->ctrl->clock, ns) / - npcm7xx_tcsr_prescaler(t->tcsr); - } --- -2.27.0 - diff --git a/hw-usb-dev-mtp-Use-g_mkdir.patch b/hw-usb-dev-mtp-Use-g_mkdir.patch deleted file mode 100644 index 4e866717a8a86eae95e563f8cbc6ebbb3ddd14ba..0000000000000000000000000000000000000000 --- a/hw-usb-dev-mtp-Use-g_mkdir.patch +++ /dev/null @@ -1,48 +0,0 @@ -From af6c51e5ef35cdf966888fb6874944d9615384a8 Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:20:54 -0800 -Subject: [PATCH] hw/usb: dev-mtp: Use g_mkdir() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 34b55848a15bca120d9b9381881c40b045409ee9 - -Use g_mkdir() to create a directory on all platforms. - -Signed-off-by: Bin Meng -Acked-by: Gerd Hoffmann -Signed-off-by: Alex Bennée -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20221006151927.2079583-8-bmeng.cn@gmail.com> -Message-Id: <20221027183637.2772968-15-alex.bennee@linaro.org> -Signed-off-by: Wanghe Xiao ---- - hw/usb/dev-mtp.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c -index c1d1694fd0..882f6bc72f 100644 ---- a/hw/usb/dev-mtp.c -+++ b/hw/usb/dev-mtp.c -@@ -15,7 +15,7 @@ - #include "qemu/error-report.h" - #include - #include -- -+#include - #include - - -@@ -1623,7 +1623,7 @@ static void usb_mtp_write_data(MTPState *s, uint32_t handle) - if (s->dataset.filename) { - path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename); - if (s->dataset.format == FMT_ASSOCIATION) { -- ret = mkdir(path, mask); -+ ret = g_mkdir(path, mask); - if (!ret) { - usb_mtp_queue_result(s, RES_OK, d->trans, 3, - QEMU_STORAGE_ID, --- -2.27.0 - diff --git a/hw-usb-hcd-ehci-fix-writeback-order.patch b/hw-usb-hcd-ehci-fix-writeback-order.patch deleted file mode 100644 index 8d0d61187c5bacca8ad56d6815f153f2fcd73cc3..0000000000000000000000000000000000000000 --- a/hw-usb-hcd-ehci-fix-writeback-order.patch +++ /dev/null @@ -1,64 +0,0 @@ -From fc52088f7aa8a1be3b3c7d135a2aebd28ba4c673 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 6 Nov 2023 06:57:46 +0000 -Subject: [PATCH] hw/usb/hcd-ehci: fix writeback order mainline inclusion - commit f471e8b060798f26a7fc339c6152f82f22a7b33d category: bugfix - ---------------------------------------------------------------- - -The 'active' bit passes control over a qTD between the guest and the -controller: set to 1 by guest to enable execution by the controller, -and the controller sets it to '0' to hand back control to the guest. - -ehci_state_writeback write two dwords to main memory using DMA: -the third dword of the qTD (containing dt, total bytes to transfer, -cpage, cerr and status) and the fourth dword of the qTD (containing -the offset). - -This commit makes sure the fourth dword is written before the third, -avoiding a race condition where a new offset written into the qTD -by the guest after it observed the status going to go to '0' gets -overwritten by a 'late' DMA writeback of the previous offset. - -This race condition could lead to 'cpage out of range (5)' errors, -and reproduced by: - -./qemu-system-x86_64 -enable-kvm -bios $SEABIOS/bios.bin -m 4096 -device usb-ehci -blockdev driver=file,read-only=on,filename=/home/aengelen/Downloads/openSUSE-Tumbleweed-DVD-i586-Snapshot20220428-Media.iso,node-name=iso -device usb-storage,drive=iso,bootindex=0 -chardev pipe,id=shell,path=/tmp/pipe -device virtio-serial -device virtconsole,chardev=shell -device virtio-rng-pci -serial mon:stdio -nographic - -(press a key, select 'Installation' (2), and accept the default -values. On my machine the 'cpage out of range' is reproduced while -loading the Linux Kernel about once per 7 attempts. With the fix in -this commit it no longer fails) - -This problem was previously reported as a seabios problem in -https://mail.coreboot.org/hyperkitty/list/seabios@seabios.org/thread/OUTHT5ISSQJGXPNTUPY3O5E5EPZJCHM3/ -and as a nixos CI build failure in -https://github.com/NixOS/nixpkgs/issues/170803 - -Signed-off-by: Arnout Engelen -Signed-off-by: Gerd Hoffmann - -Signed-off-by: tangbinzy ---- - hw/usb/hcd-ehci.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c -index 0289b3696d..f9aa567f5d 100644 ---- a/hw/usb/hcd-ehci.c -+++ b/hw/usb/hcd-ehci.c -@@ -2013,7 +2013,10 @@ static int ehci_state_writeback(EHCIQueue *q) - ehci_trace_qtd(q, NLPTR_GET(p->qtdaddr), (EHCIqtd *) &q->qh.next_qtd); - qtd = (uint32_t *) &q->qh.next_qtd; - addr = NLPTR_GET(p->qtdaddr); -- put_dwords(q->ehci, addr + 2 * sizeof(uint32_t), qtd + 2, 2); -+ /* First write back the offset */ -+ put_dwords(q->ehci, addr + 3 * sizeof(uint32_t), qtd + 3, 1); -+ /* Then write back the token, clearing the 'active' bit */ -+ put_dwords(q->ehci, addr + 2 * sizeof(uint32_t), qtd + 2, 1); - ehci_free_packet(p); - - /* --- -2.27.0 - diff --git a/hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch b/hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch deleted file mode 100644 index 2caeb1c9b5b6a36043914a1eb3afce01b1f35521..0000000000000000000000000000000000000000 --- a/hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 95970127dcd1d5d2f365f87fa888e5f0baa3cd10 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Thu, 4 Aug 2022 15:13:00 +0200 -Subject: [PATCH] hw/usb/hcd-xhci: Fix unbounded loop in - xhci_ring_chain_length() (CVE-2020-14394) - -The loop condition in xhci_ring_chain_length() is under control of -the guest, and additionally the code does not check for failed DMA -transfers (e.g. if reaching the end of the RAM), so the loop there -could run for a very long time or even forever. Fix it by checking -the return value of dma_memory_read() and by introducing a maximum -loop length. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/646 -Message-Id: <20220804131300.96368-1-thuth@redhat.com> -Reviewed-by: Mauro Matteo Cascella -Acked-by: Gerd Hoffmann -Signed-off-by: Thomas Huth ---- - hw/usb/hcd-xhci.c | 23 +++++++++++++++++++---- - 1 file changed, 19 insertions(+), 4 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 47fb79aa4d..ac02548dcf 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -21,6 +21,7 @@ - - #include "qemu/osdep.h" - #include "qemu/timer.h" -+#include "qemu/log.h" - #include "qemu/module.h" - #include "qemu/queue.h" - #include "migration/vmstate.h" -@@ -726,10 +727,14 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) - bool control_td_set = 0; - uint32_t link_cnt = 0; - -- while (1) { -+ do { - TRBType type; -- dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE, -- MEMTXATTRS_UNSPECIFIED); -+ if (dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE, -+ MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) { -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n", -+ __func__); -+ return -1; -+ } - le64_to_cpus(&trb.parameter); - le32_to_cpus(&trb.status); - le32_to_cpus(&trb.control); -@@ -763,7 +768,17 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) - if (!control_td_set && !(trb.control & TRB_TR_CH)) { - return length; - } -- } -+ -+ /* -+ * According to the xHCI spec, Transfer Ring segments should have -+ * a maximum size of 64 kB (see chapter "6 Data Structures") -+ */ -+ } while (length < TRB_LINK_LIMIT * 65536 / TRB_SIZE); -+ -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: exceeded maximum tranfer ring size!\n", -+ __func__); -+ -+ return -1; - } - - static void xhci_er_reset(XHCIState *xhci, int v) --- -2.27.0 - diff --git a/hw-usb-hcd-xhci-Reset-the-XHCIState-with-device_cold.patch b/hw-usb-hcd-xhci-Reset-the-XHCIState-with-device_cold.patch deleted file mode 100644 index 30610073dbe2e61c473b2aa451f318f57b953904..0000000000000000000000000000000000000000 --- a/hw-usb-hcd-xhci-Reset-the-XHCIState-with-device_cold.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 5f738b6b95efbdd8d9398b45e038287c5dd3c413 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Fri, 25 Nov 2022 10:00:58 +0800 -Subject: [PATCH 21/29] hw/usb/hcd-xhci: Reset the XHCIState with - device_cold_reset() - -Currently the hcd-xhci-pci and hcd-xhci-sysbus devices, which are -mostly wrappers around the TYPE_XHCI device, which is a direct -subclass of TYPE_DEVICE. Since TYPE_DEVICE devices are not on any -qbus and do not get automatically reset, the wrapper devices both -reset the TYPE_XHCI device in their own reset functions. However, -they do this using device_legacy_reset(), which will reset the device -itself but not any bus it has. -Switch to device_cold_reset(), which avoids using a deprecated -function and also propagates reset along any child buses. - -Signed-off-by: Peter Maydell -Signed-off-by: jianchunfu ---- - hw/usb/hcd-xhci-pci.c | 2 +- - hw/usb/hcd-xhci-sysbus.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c -index e934b1a5b1..643d4643e4 100644 ---- a/hw/usb/hcd-xhci-pci.c -+++ b/hw/usb/hcd-xhci-pci.c -@@ -85,7 +85,7 @@ static void xhci_pci_reset(DeviceState *dev) - { - XHCIPciState *s = XHCI_PCI(dev); - -- device_legacy_reset(DEVICE(&s->xhci)); -+ device_cold_reset(DEVICE(&s->xhci)); - } - - static int xhci_pci_vmstate_post_load(void *opaque, int version_id) -diff --git a/hw/usb/hcd-xhci-sysbus.c b/hw/usb/hcd-xhci-sysbus.c -index a14e438196..faf57b4797 100644 ---- a/hw/usb/hcd-xhci-sysbus.c -+++ b/hw/usb/hcd-xhci-sysbus.c -@@ -29,7 +29,7 @@ void xhci_sysbus_reset(DeviceState *dev) - { - XHCISysbusState *s = XHCI_SYSBUS(dev); - -- device_legacy_reset(DEVICE(&s->xhci)); -+ device_cold_reset(DEVICE(&s->xhci)); - } - - static void xhci_sysbus_realize(DeviceState *dev, Error **errp) --- -2.27.0 - diff --git a/hw-usb-hcd-xhci.c-spelling-tranfer.patch b/hw-usb-hcd-xhci.c-spelling-tranfer.patch deleted file mode 100644 index c5a5189d41f8cd1bc8b6ebf8bb68cf8720caadbd..0000000000000000000000000000000000000000 --- a/hw-usb-hcd-xhci.c-spelling-tranfer.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 755899cd2cb3d808717da99fa1447c3c81cc0dce Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Thu, 7 Dec 2023 18:03:12 -0800 -Subject: [PATCH] hw/usb/hcd-xhci.c: spelling: tranfer - -mainline inclusion -commit d68640f515320bf38617b68c970b569997cf0444 -category: bugfix - ---------------------------------------------------------------- - -Fixes: effaf5a240e03020f4ae953e10b764622c3e87cc -Signed-off-by: Michael Tokarev -Reviewed-by: Thomas Huth -Reviewed-by: Stefan Weil -Message-Id: <20221105114851.306206-1-mjt@msgid.tls.msk.ru> -Signed-off-by: Gerd Hoffmann -Signed-off-by: zhujun2 ---- - hw/usb/hcd-xhci.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index ac02548dcf..40300e1bcd 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -775,7 +775,7 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) - */ - } while (length < TRB_LINK_LIMIT * 65536 / TRB_SIZE); - -- qemu_log_mask(LOG_GUEST_ERROR, "%s: exceeded maximum tranfer ring size!\n", -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: exceeded maximum transfer ring size!\n", - __func__); - - return -1; --- -2.27.0 - diff --git a/hw-usb-imx-Fix-out-of-bounds-access-in-imx_usbphy_re.patch b/hw-usb-imx-Fix-out-of-bounds-access-in-imx_usbphy_re.patch deleted file mode 100644 index b2656f2fc11a0301191078d5291e63db49bd5522..0000000000000000000000000000000000000000 --- a/hw-usb-imx-Fix-out-of-bounds-access-in-imx_usbphy_re.patch +++ /dev/null @@ -1,72 +0,0 @@ -From b8822efafc2012de3e92700afc7524df027c914b Mon Sep 17 00:00:00 2001 -From: Guenter Roeck -Date: Thu, 16 Mar 2023 16:49:26 -0700 -Subject: [PATCH] hw/usb/imx: Fix out of bounds access in imx_usbphy_read() - -The i.MX USB Phy driver does not check register ranges, resulting in out of -bounds accesses if an attempt is made to access non-existing PHY registers. -Add range check and conditionally report bad accesses to fix the problem. - -While at it, also conditionally log attempted writes to non-existing or -read-only registers. - -Reported-by: Qiang Liu -Signed-off-by: Guenter Roeck -Tested-by: Qiang Liu -Message-id: 20230316234926.208874-1-linux@roeck-us.net -Link: https://gitlab.com/qemu-project/qemu/-/issues/1408 -Fixes: 0701a5efa015 ("hw/usb: Add basic i.MX USB Phy support") -Signed-off-by: Guenter Roeck -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell ---- - hw/usb/imx-usb-phy.c | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/imx-usb-phy.c b/hw/usb/imx-usb-phy.c -index 5d7a549e34..1a97b36a11 100644 ---- a/hw/usb/imx-usb-phy.c -+++ b/hw/usb/imx-usb-phy.c -@@ -13,6 +13,7 @@ - #include "qemu/osdep.h" - #include "hw/usb/imx-usb-phy.h" - #include "migration/vmstate.h" -+#include "qemu/log.h" - #include "qemu/module.h" - - static const VMStateDescription vmstate_imx_usbphy = { -@@ -90,7 +91,15 @@ static uint64_t imx_usbphy_read(void *opaque, hwaddr offset, unsigned size) - value = s->usbphy[index - 3]; - break; - default: -- value = s->usbphy[index]; -+ if (index < USBPHY_MAX) { -+ value = s->usbphy[index]; -+ } else { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "%s: Read from non-existing USB PHY register 0x%" -+ HWADDR_PRIx "\n", -+ __func__, offset); -+ value = 0; -+ } - break; - } - return (uint64_t)value; -@@ -168,7 +177,13 @@ static void imx_usbphy_write(void *opaque, hwaddr offset, uint64_t value, - s->usbphy[index - 3] ^= value; - break; - default: -- /* Other registers are read-only */ -+ /* Other registers are read-only or do not exist */ -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "%s: Write to %s USB PHY register 0x%" -+ HWADDR_PRIx "\n", -+ __func__, -+ index >= USBPHY_MAX ? "non-existing" : "read-only", -+ offset); - break; - } - } --- -2.27.0 - diff --git a/hw-usb-reduce-the-vpcu-cost-of-UHCI-when-VNC-disconn.patch b/hw-usb-reduce-the-vpcu-cost-of-UHCI-when-VNC-disconn.patch deleted file mode 100644 index ef734a61a77554550863159a804acf5019f40328..0000000000000000000000000000000000000000 --- a/hw-usb-reduce-the-vpcu-cost-of-UHCI-when-VNC-disconn.patch +++ /dev/null @@ -1,459 +0,0 @@ -From 93f01916f0c1e11f38edb8ccc4118c940d9c089f Mon Sep 17 00:00:00 2001 -From: eillon -Date: Tue, 8 Feb 2022 22:43:59 -0500 -Subject: [PATCH] hw/usb: reduce the vpcu cost of UHCI when VNC disconnect - -Reduce the vpcu cost by set a lower FRAME_TIMER_FREQ of the UHCI -when VNC client disconnected. This can reduce about 3% cost of -vcpu thread. - -Signed-off-by: eillon ---- - hw/usb/core.c | 5 ++-- - hw/usb/desc.c | 7 +++-- - hw/usb/dev-hid.c | 2 +- - hw/usb/hcd-uhci.c | 63 ++++++++++++++++++++++++++++++++++------ - hw/usb/hcd-uhci.h | 1 + - hw/usb/host-libusb.c | 32 ++++++++++++++++++++ - include/hw/usb.h | 1 + - include/qemu/timer.h | 28 ++++++++++++++++++ - ui/vnc.c | 4 +++ - util/qemu-timer.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ - 10 files changed, 197 insertions(+), 15 deletions(-) - -diff --git a/hw/usb/core.c b/hw/usb/core.c -index 975f76250a..51b36126ca 100644 ---- a/hw/usb/core.c -+++ b/hw/usb/core.c -@@ -87,7 +87,7 @@ void usb_device_reset(USBDevice *dev) - return; - } - usb_device_handle_reset(dev); -- dev->remote_wakeup = 0; -+ dev->remote_wakeup &= ~USB_DEVICE_REMOTE_WAKEUP; - dev->addr = 0; - dev->state = USB_STATE_DEFAULT; - } -@@ -105,7 +105,8 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream) - */ - return; - } -- if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) { -+ if ((dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP) -+ && dev->port && dev->port->ops->wakeup) { - dev->port->ops->wakeup(dev->port); - } - if (bus->ops->wakeup_endpoint) { -diff --git a/hw/usb/desc.c b/hw/usb/desc.c -index 8b6eaea407..78bbe74c71 100644 ---- a/hw/usb/desc.c -+++ b/hw/usb/desc.c -@@ -751,7 +751,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p, - if (config->bmAttributes & USB_CFG_ATT_SELFPOWER) { - data[0] |= 1 << USB_DEVICE_SELF_POWERED; - } -- if (dev->remote_wakeup) { -+ if (dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP) { - data[0] |= 1 << USB_DEVICE_REMOTE_WAKEUP; - } - data[1] = 0x00; -@@ -761,14 +761,15 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p, - } - case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { -- dev->remote_wakeup = 0; -+ dev->remote_wakeup &= ~USB_DEVICE_REMOTE_WAKEUP; - ret = 0; - } - trace_usb_clear_device_feature(dev->addr, value, ret); - break; - case DeviceOutRequest | USB_REQ_SET_FEATURE: -+ dev->remote_wakeup |= USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED; - if (value == USB_DEVICE_REMOTE_WAKEUP) { -- dev->remote_wakeup = 1; -+ dev->remote_wakeup |= USB_DEVICE_REMOTE_WAKEUP; - ret = 0; - } - trace_usb_set_device_feature(dev->addr, value, ret); -diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c -index 1c7ae97c30..9fb89f6955 100644 ---- a/hw/usb/dev-hid.c -+++ b/hw/usb/dev-hid.c -@@ -745,7 +745,7 @@ static int usb_ptr_post_load(void *opaque, int version_id) - { - USBHIDState *s = opaque; - -- if (s->dev.remote_wakeup) { -+ if (s->dev.remote_wakeup & USB_DEVICE_REMOTE_WAKEUP) { - hid_pointer_activate(&s->hid); - } - return 0; -diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c -index d1b5657d72..693c68f445 100644 ---- a/hw/usb/hcd-uhci.c -+++ b/hw/usb/hcd-uhci.c -@@ -44,6 +44,8 @@ - #include "hcd-uhci.h" - - #define FRAME_TIMER_FREQ 1000 -+#define FRAME_TIMER_FREQ_LAZY 10 -+#define USB_DEVICE_NEED_NORMAL_FREQ "QEMU USB Tablet" - - #define FRAME_MAX_LOOPS 256 - -@@ -111,6 +113,22 @@ static void uhci_async_cancel(UHCIAsync *async); - static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td); - static void uhci_resume(void *opaque); - -+static int64_t uhci_frame_timer_freq = FRAME_TIMER_FREQ_LAZY; -+ -+static void uhci_set_frame_freq(int freq) -+{ -+ if (freq <= 0) { -+ return; -+ } -+ -+ uhci_frame_timer_freq = freq; -+} -+ -+static qemu_usb_controller qemu_uhci = { -+ .name = "uhci", -+ .qemu_set_freq = uhci_set_frame_freq, -+}; -+ - static inline int32_t uhci_queue_token(UHCI_TD *td) - { - if ((td->token & (0xf << 15)) == 0) { -@@ -353,7 +371,7 @@ static int uhci_post_load(void *opaque, int version_id) - - if (version_id < 2) { - s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + -- (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ); -+ (NANOSECONDS_PER_SECOND / uhci_frame_timer_freq); - } - return 0; - } -@@ -394,8 +412,29 @@ static void uhci_port_write(void *opaque, hwaddr addr, - if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) { - /* start frame processing */ - trace_usb_uhci_schedule_start(); -- s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + -- (NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ); -+ -+ /* -+ * If the frequency of frame_timer is too slow, Guest OS (Win2012) would become -+ * blue-screen after hotplugging some vcpus. -+ * If this USB device support the remote-wakeup, the UHCI controller -+ * will enter global suspend mode when there is no input for several seconds. -+ * In this case, Qemu will delete the frame_timer. Since the frame_timer has been deleted, -+ * there is no influence to the performance of Vms. So, we can change the frequency to 1000. -+ * After that the frequency will be safe when we trigger the frame_timer again. -+ * Excepting this, there are two ways to change the frequency: -+ * 1)VNC connect/disconnect;2)attach/detach USB device. -+ */ -+ if ((uhci_frame_timer_freq != FRAME_TIMER_FREQ) -+ && (s->ports[0].port.dev) -+ && (!memcmp(s->ports[0].port.dev->product_desc, -+ USB_DEVICE_NEED_NORMAL_FREQ, strlen(USB_DEVICE_NEED_NORMAL_FREQ))) -+ && (s->ports[0].port.dev->remote_wakeup & USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED)) { -+ qemu_log("turn up the frequency of UHCI controller to %d\n", FRAME_TIMER_FREQ); -+ uhci_frame_timer_freq = FRAME_TIMER_FREQ; -+ } -+ -+ s->frame_time = NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ; -+ s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->frame_time; - timer_mod(s->frame_timer, s->expire_time); - s->status &= ~UHCI_STS_HCHALTED; - } else if (!(val & UHCI_CMD_RS)) { -@@ -1083,7 +1122,6 @@ static void uhci_frame_timer(void *opaque) - UHCIState *s = opaque; - uint64_t t_now, t_last_run; - int i, frames; -- const uint64_t frame_t = NANOSECONDS_PER_SECOND / FRAME_TIMER_FREQ; - - s->completions_only = false; - qemu_bh_cancel(s->bh); -@@ -1099,14 +1137,14 @@ static void uhci_frame_timer(void *opaque) - } - - /* We still store expire_time in our state, for migration */ -- t_last_run = s->expire_time - frame_t; -+ t_last_run = s->expire_time - s->frame_time; - t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - - /* Process up to MAX_FRAMES_PER_TICK frames */ -- frames = (t_now - t_last_run) / frame_t; -+ frames = (t_now - t_last_run) / s->frame_time; - if (frames > s->maxframes) { - int skipped = frames - s->maxframes; -- s->expire_time += skipped * frame_t; -+ s->expire_time += skipped * s->frame_time; - s->frnum = (s->frnum + skipped) & 0x7ff; - frames -= skipped; - } -@@ -1123,7 +1161,7 @@ static void uhci_frame_timer(void *opaque) - /* The spec says frnum is the frame currently being processed, and - * the guest must look at frnum - 1 on interrupt, so inc frnum now */ - s->frnum = (s->frnum + 1) & 0x7ff; -- s->expire_time += frame_t; -+ s->expire_time += s->frame_time; - } - - /* Complete the previous frame(s) */ -@@ -1134,7 +1172,12 @@ static void uhci_frame_timer(void *opaque) - } - s->pending_int_mask = 0; - -- timer_mod(s->frame_timer, t_now + frame_t); -+ /* expire_time is calculated from last frame_time, we should calculate it -+ * according to new frame_time which equals to -+ * NANOSECONDS_PER_SECOND / uhci_frame_timer_freq */ -+ s->expire_time -= s->frame_time - NANOSECONDS_PER_SECOND / uhci_frame_timer_freq; -+ s->frame_time = NANOSECONDS_PER_SECOND / uhci_frame_timer_freq; -+ timer_mod(s->frame_timer, t_now + s->frame_time); - } - - static const MemoryRegionOps uhci_ioport_ops = { -@@ -1196,8 +1239,10 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp) - s->bh = qemu_bh_new(uhci_bh, s); - s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s); - s->num_ports_vmstate = NB_PORTS; -+ s->frame_time = NANOSECONDS_PER_SECOND / uhci_frame_timer_freq; - QTAILQ_INIT(&s->queues); - -+ qemu_register_usb_controller(&qemu_uhci, QEMU_USB_CONTROLLER_UHCI); - memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s, - "uhci", 0x20); - -diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h -index c85ab7868e..5194d22ab4 100644 ---- a/hw/usb/hcd-uhci.h -+++ b/hw/usb/hcd-uhci.h -@@ -50,6 +50,7 @@ typedef struct UHCIState { - uint16_t status; - uint16_t intr; /* interrupt enable register */ - uint16_t frnum; /* frame number */ -+ uint64_t frame_time; /* frame time in ns */ - uint32_t fl_base_addr; /* frame list base address */ - uint8_t sof_timing; - uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */ -diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c -index d0d46dd0a4..8f521ad586 100644 ---- a/hw/usb/host-libusb.c -+++ b/hw/usb/host-libusb.c -@@ -945,6 +945,30 @@ static void usb_host_ep_update(USBHostDevice *s) - libusb_free_config_descriptor(conf); - } - -+static unsigned int usb_get_controller_type(int speed) -+{ -+ unsigned int type = MAX_USB_CONTROLLER_TYPES; -+ -+ switch (speed) { -+ case USB_SPEED_SUPER: -+ type = QEMU_USB_CONTROLLER_XHCI; -+ break; -+ case USB_SPEED_HIGH: -+ type = QEMU_USB_CONTROLLER_EHCI; -+ break; -+ case USB_SPEED_FULL: -+ type = QEMU_USB_CONTROLLER_UHCI; -+ break; -+ case USB_SPEED_LOW: -+ type = QEMU_USB_CONTROLLER_OHCI; -+ break; -+ default: -+ break; -+ } -+ -+ return type; -+} -+ - static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd) - { - USBDevice *udev = USB_DEVICE(s); -@@ -1054,6 +1078,12 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd) - } - - trace_usb_host_open_success(bus_num, addr); -+ -+ /* change ehci frame time freq when USB passthrough */ -+ qemu_log("usb host speed is %d\n", udev->speed); -+ qemu_timer_set_mode(QEMU_TIMER_USB_NORMAL_MODE, -+ usb_get_controller_type(udev->speed)); -+ - return 0; - - fail: -@@ -1129,6 +1159,8 @@ static int usb_host_close(USBHostDevice *s) - } - - usb_host_auto_check(NULL); -+ qemu_timer_set_mode(QEMU_TIMER_USB_LAZY_MODE, -+ usb_get_controller_type(udev->speed)); - return 0; - } - -diff --git a/include/hw/usb.h b/include/hw/usb.h -index 33668dd0a9..fa3a176159 100644 ---- a/include/hw/usb.h -+++ b/include/hw/usb.h -@@ -142,6 +142,7 @@ - - #define USB_DEVICE_SELF_POWERED 0 - #define USB_DEVICE_REMOTE_WAKEUP 1 -+#define USB_DEVICE_REMOTE_WAKEUP_IS_SUPPORTED 2 - - #define USB_DT_DEVICE 0x01 - #define USB_DT_CONFIG 0x02 -diff --git a/include/qemu/timer.h b/include/qemu/timer.h -index 88ef114689..d263fad9a4 100644 ---- a/include/qemu/timer.h -+++ b/include/qemu/timer.h -@@ -91,6 +91,34 @@ struct QEMUTimer { - int scale; - }; - -+#define QEMU_USB_NORMAL_FREQ 1000 -+#define QEMU_USB_LAZY_FREQ 10 -+#define MAX_USB_CONTROLLER_TYPES 4 -+#define QEMU_USB_CONTROLLER_OHCI 0 -+#define QEMU_USB_CONTROLLER_UHCI 1 -+#define QEMU_USB_CONTROLLER_EHCI 2 -+#define QEMU_USB_CONTROLLER_XHCI 3 -+ -+typedef void (*QEMUSetFreqHandler) (int freq); -+ -+typedef struct qemu_usb_controller { -+ const char *name; -+ QEMUSetFreqHandler qemu_set_freq; -+} qemu_usb_controller; -+ -+typedef qemu_usb_controller* qemu_usb_controller_ptr; -+ -+enum qemu_timer_mode { -+ QEMU_TIMER_USB_NORMAL_MODE = 1 << 0, /* Set when VNC connect or -+ * with usb dev passthrough -+ */ -+ QEMU_TIMER_USB_LAZY_MODE = 1 << 1, /* Set when VNC disconnect */ -+}; -+ -+int qemu_register_usb_controller(qemu_usb_controller_ptr controller, -+ unsigned int type); -+int qemu_timer_set_mode(enum qemu_timer_mode mode, unsigned int type); -+ - extern QEMUTimerListGroup main_loop_tlg; - - /* -diff --git a/ui/vnc.c b/ui/vnc.c -index af02522e84..bc86c20370 100644 ---- a/ui/vnc.c -+++ b/ui/vnc.c -@@ -1379,6 +1379,8 @@ void vnc_disconnect_finish(VncState *vs) - g_free(vs->zrle); - g_free(vs->tight); - g_free(vs); -+ -+ qemu_timer_set_mode(QEMU_TIMER_USB_LAZY_MODE, QEMU_USB_CONTROLLER_UHCI); - } - - size_t vnc_client_io_error(VncState *vs, ssize_t ret, Error *err) -@@ -3333,6 +3335,8 @@ static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc, - } - } - } -+ -+ qemu_timer_set_mode(QEMU_TIMER_USB_NORMAL_MODE, QEMU_USB_CONTROLLER_UHCI); - } - - void vnc_start_protocol(VncState *vs) -diff --git a/util/qemu-timer.c b/util/qemu-timer.c -index f36c75e594..40e8c83722 100644 ---- a/util/qemu-timer.c -+++ b/util/qemu-timer.c -@@ -23,6 +23,7 @@ - */ - - #include "qemu/osdep.h" -+#include "qemu/log.h" - #include "qemu/main-loop.h" - #include "qemu/timer.h" - #include "qemu/lockable.h" -@@ -75,6 +76,74 @@ struct QEMUTimerList { - QemuEvent timers_done_ev; - }; - -+typedef struct qemu_controller_timer_state { -+ qemu_usb_controller_ptr controller; -+ int refs; -+} controller_timer_state; -+ -+typedef controller_timer_state* controller_timer_state_ptr; -+ -+static controller_timer_state uhci_timer_state = { -+ .controller = NULL, -+ .refs = 0, -+}; -+ -+static controller_timer_state_ptr \ -+ qemu_usb_controller_tab[MAX_USB_CONTROLLER_TYPES] = {NULL, -+ &uhci_timer_state, -+ NULL, NULL}; -+ -+int qemu_register_usb_controller(qemu_usb_controller_ptr controller, -+ unsigned int type) -+{ -+ if (type != QEMU_USB_CONTROLLER_UHCI) { -+ return 0; -+ } -+ -+ /* for companion EHCI controller will create three UHCI controllers, -+ * we init it only once. -+ */ -+ if (!qemu_usb_controller_tab[type]->controller) { -+ qemu_log("the usb controller (%d) registed frame handler\n", type); -+ qemu_usb_controller_tab[type]->controller = controller; -+ } -+ -+ return 0; -+} -+ -+int qemu_timer_set_mode(enum qemu_timer_mode mode, unsigned int type) -+{ -+ if (type != QEMU_USB_CONTROLLER_UHCI) { -+ qemu_log("the usb controller (%d) no need change frame frep\n", type); -+ return 0; -+ } -+ -+ if (!qemu_usb_controller_tab[type]->controller) { -+ qemu_log("the usb controller (%d) not registed yet\n", type); -+ return 0; -+ } -+ -+ if (mode == QEMU_TIMER_USB_NORMAL_MODE) { -+ if (qemu_usb_controller_tab[type]->refs++ > 0) { -+ return 0; -+ } -+ qemu_usb_controller_tab[type]->controller-> -+ qemu_set_freq(QEMU_USB_NORMAL_FREQ); -+ qemu_log("Set the controller (%d) of freq %d HZ,\n", -+ type, QEMU_USB_NORMAL_FREQ); -+ } else { -+ if (--qemu_usb_controller_tab[type]->refs > 0) { -+ return 0; -+ } -+ qemu_usb_controller_tab[type]->controller-> -+ qemu_set_freq(QEMU_USB_LAZY_FREQ); -+ qemu_log("Set the controller(type:%d) of freq %d HZ,\n", -+ type, QEMU_USB_LAZY_FREQ); -+ } -+ -+ return 0; -+} -+ - /** - * qemu_clock_ptr: - * @type: type of clock --- -2.27.0 - diff --git a/hw-vfio-pci-quirks-Sanitize-capability-pointer.patch b/hw-vfio-pci-quirks-Sanitize-capability-pointer.patch deleted file mode 100644 index c6c480839523301648eb24f82915a85df1d001e7..0000000000000000000000000000000000000000 --- a/hw-vfio-pci-quirks-Sanitize-capability-pointer.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 193240c79f5c95aaf86b2998975189f1873ebcec Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Fri, 18 Aug 2023 14:41:45 +0800 -Subject: [PATCH] hw/vfio/pci-quirks: Sanitize capability pointer Coverity - reports a tained scalar when traversing the capabilities chain (CID 1516589). - In practice I've never seen a device with a chain so broken as to cause an - issue, but it's also pretty easy to sanitize. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fixes: f6b30c1 ("hw/vfio/pci-quirks: Support alternate offset for -GPUDirect Cliques") -Signed-off-by: Alex Williamson -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater - -Signed-off-by: Zhongrui Tang ---- - hw/vfio/pci-quirks.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c -index 7a8e6efcdc..a911e04a79 100644 ---- a/hw/vfio/pci-quirks.c -+++ b/hw/vfio/pci-quirks.c -@@ -1717,6 +1717,12 @@ const PropertyInfo qdev_prop_nv_gpudirect_clique = { - .set = set_nv_gpudirect_clique_id, - }; - -+static bool is_valid_std_cap_offset(uint8_t pos) -+{ -+ return (pos >= PCI_STD_HEADER_SIZEOF && -+ pos <= (PCI_CFG_SPACE_SIZE - PCI_CAP_SIZEOF)); -+} -+ - static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp) - { - PCIDevice *pdev = &vdev->pdev; -@@ -1750,7 +1756,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp) - */ - ret = pread(vdev->vbasedev.fd, &tmp, 1, - vdev->config_offset + PCI_CAPABILITY_LIST); -- if (ret != 1 || !tmp) { -+ if (ret != 1 || !is_valid_std_cap_offset(tmp)) { - error_setg(errp, "NVIDIA GPUDirect Clique ID: error getting cap list"); - return -EINVAL; - } -@@ -1762,7 +1768,7 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp) - d4_conflict = true; - } - tmp = pdev->config[tmp + PCI_CAP_LIST_NEXT]; -- } while (tmp); -+ } while (is_valid_std_cap_offset(tmp)); - - if (!c8_conflict) { - pos = 0xC8; --- -2.41.0.windows.1 - diff --git a/hw-vfio-pci-quirks-Support-alternate-offset-for-GPUD.patch b/hw-vfio-pci-quirks-Support-alternate-offset-for-GPUD.patch deleted file mode 100644 index 7232ad3a34f8df7436134aec2368f1cf6c6c695c..0000000000000000000000000000000000000000 --- a/hw-vfio-pci-quirks-Support-alternate-offset-for-GPUD.patch +++ /dev/null @@ -1,95 +0,0 @@ -From d672e2f137933b26bd9b3488a873830435eadba5 Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Thu, 3 Aug 2023 15:10:16 +0800 -Subject: [PATCH] hw/vfio/pci-quirks: Support alternate offset for GPUDirect - Cliques -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -NVIDIA Turing and newer GPUs implement the MSI-X capability at the offset -previously reserved for use by hypervisors to implement the GPUDirect -Cliques capability. A revised specification provides an alternate -location. Add a config space walk to the quirk to check for conflicts, -allowing us to fall back to the new location or generate an error at the -quirk setup rather than when the real conflicting capability is added -should there be no available location. - -Signed-off-by: Alex Williamson -Reviewed-by: Cédric Le Goater -Signed-off-by: Cédric Le Goater - -Signed-off-by: Zhongrui Tang ---- - hw/vfio/pci-quirks.c | 41 ++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 40 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c -index 1222ccff0b..7a8e6efcdc 100644 ---- a/hw/vfio/pci-quirks.c -+++ b/hw/vfio/pci-quirks.c -@@ -1677,6 +1677,9 @@ void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev) - * +---------------------------------+---------------------------------+ - * - * https://lists.gnu.org/archive/html/qemu-devel/2017-08/pdfUda5iEpgOS.pdf -+ * -+ * Specification for Turning and later GPU architectures: -+ * https://lists.gnu.org/archive/html/qemu-devel/2023-06/pdf142OR4O4c2.pdf - */ - static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v, - const char *name, void *opaque, -@@ -1717,7 +1720,9 @@ const PropertyInfo qdev_prop_nv_gpudirect_clique = { - static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp) - { - PCIDevice *pdev = &vdev->pdev; -- int ret, pos = 0xC8; -+ int ret, pos; -+ bool c8_conflict = false, d4_conflict = false; -+ uint8_t tmp; - - if (vdev->nv_gpudirect_clique == 0xFF) { - return 0; -@@ -1734,6 +1739,40 @@ static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp) - return -EINVAL; - } - -+ /* -+ * Per the updated specification above, it's recommended to use offset -+ * D4h for Turing and later GPU architectures due to a conflict of the -+ * MSI-X capability at C8h. We don't know how to determine the GPU -+ * architecture, instead we walk the capability chain to mark conflicts -+ * and choose one or error based on the result. -+ * -+ * NB. Cap list head in pdev->config is already cleared, read from device. -+ */ -+ ret = pread(vdev->vbasedev.fd, &tmp, 1, -+ vdev->config_offset + PCI_CAPABILITY_LIST); -+ if (ret != 1 || !tmp) { -+ error_setg(errp, "NVIDIA GPUDirect Clique ID: error getting cap list"); -+ return -EINVAL; -+ } -+ -+ do { -+ if (tmp == 0xC8) { -+ c8_conflict = true; -+ } else if (tmp == 0xD4) { -+ d4_conflict = true; -+ } -+ tmp = pdev->config[tmp + PCI_CAP_LIST_NEXT]; -+ } while (tmp); -+ -+ if (!c8_conflict) { -+ pos = 0xC8; -+ } else if (!d4_conflict) { -+ pos = 0xD4; -+ } else { -+ error_setg(errp, "NVIDIA GPUDirect Clique ID: invalid config space"); -+ return -EINVAL; -+ } -+ - ret = pci_add_capability(pdev, PCI_CAP_ID_VNDR, pos, 8, errp); - if (ret < 0) { - error_prepend(errp, "Failed to add NVIDIA GPUDirect cap: "); --- -2.41.0.windows.1 - diff --git a/hw-vhost-user-blk-turn-on-VIRTIO_BLK_F_SIZE_MAX-feat.patch b/hw-vhost-user-blk-turn-on-VIRTIO_BLK_F_SIZE_MAX-feat.patch deleted file mode 100644 index 1c874a42f4dfe5b583aa612a2b6f7ff612fe45a4..0000000000000000000000000000000000000000 --- a/hw-vhost-user-blk-turn-on-VIRTIO_BLK_F_SIZE_MAX-feat.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 4f66d261c0f20189e387de57baca17167cc542ab Mon Sep 17 00:00:00 2001 -From: Andy Pei -Date: Mon, 3 Jan 2022 17:28:12 +0800 -Subject: [PATCH] hw/vhost-user-blk: turn on VIRTIO_BLK_F_SIZE_MAX feature for - virtio blk device - -Turn on pre-defined feature VIRTIO_BLK_F_SIZE_MAX for virtio blk device to -avoid guest DMA request sizes which are too large for hardware spec. - -Signed-off-by: dinglimin -Signed-off-by: Andy Pei -Message-Id: <1641202092-149677-1-git-send-email-andy.pei@intel.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Acked-by: Raphael Norwitz ---- - hw/block/vhost-user-blk.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c -index ba13cb87e5..eb1264afc7 100644 ---- a/hw/block/vhost-user-blk.c -+++ b/hw/block/vhost-user-blk.c -@@ -252,6 +252,7 @@ static uint64_t vhost_user_blk_get_features(VirtIODevice *vdev, - VHostUserBlk *s = VHOST_USER_BLK(vdev); - - /* Turn on pre-defined features */ -+ virtio_add_feature(&features, VIRTIO_BLK_F_SIZE_MAX); - virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX); - virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY); - virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY); --- -2.27.0 - diff --git a/hw-virtio-add-some-vhost-user-trace-events.patch b/hw-virtio-add-some-vhost-user-trace-events.patch deleted file mode 100644 index 5979d6250ac21e9b2d5adde6501a64bb86c7c894..0000000000000000000000000000000000000000 --- a/hw-virtio-add-some-vhost-user-trace-events.patch +++ /dev/null @@ -1,70 +0,0 @@ -From f5b5cba0b86caacdea334725bedcdfb689504b3a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alex=20Benn=C3=A9e?= -Date: Tue, 2 Aug 2022 10:49:57 +0100 -Subject: [PATCH] hw/virtio: add some vhost-user trace events -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -These are useful for tracing the lifetime of vhost-user connections. - -Signed-off-by: Alex Bennée -Message-Id: <20220802095010.3330793-10-alex.bennee@linaro.org> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: fangyi ---- - hw/virtio/trace-events | 4 ++++ - hw/virtio/vhost.c | 6 ++++++ - 2 files changed, 10 insertions(+) - -diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events -index 63c7668e5b..b8a33b2a83 100644 ---- a/hw/virtio/trace-events -+++ b/hw/virtio/trace-events -@@ -8,6 +8,10 @@ vhost_region_add_section_aligned(const char *name, uint64_t gpa, uint64_t size, - vhost_section(const char *name) "%s" - vhost_reject_section(const char *name, int d) "%s:%d" - vhost_iotlb_miss(void *dev, int step) "%p step %d" -+vhost_dev_cleanup(void *dev) "%p" -+vhost_dev_start(void *dev, const char *name) "%p:%s" -+vhost_dev_stop(void *dev, const char *name) "%p:%s" -+ - - # vhost-user.c - vhost_user_postcopy_end_entry(void) "" -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index c1f5cb5b91..86c727d2ab 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -1460,6 +1460,8 @@ void vhost_dev_cleanup(struct vhost_dev *hdev) - { - int i; - -+ trace_vhost_dev_cleanup(hdev); -+ - for (i = 0; i < hdev->nvqs; ++i) { - vhost_virtqueue_cleanup(hdev->vqs + i); - } -@@ -1766,6 +1768,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - /* should only be called after backend is connected */ - assert(hdev->vhost_ops); - -+ trace_vhost_dev_start(hdev, vdev->name); -+ - vdev->vhost_started = true; - hdev->started = true; - hdev->vdev = vdev; -@@ -1852,6 +1856,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) - /* should only be called after backend is connected */ - assert(hdev->vhost_ops); - -+ trace_vhost_dev_stop(hdev, vdev->name); -+ - if (hdev->vhost_ops->vhost_dev_start) { - hdev->vhost_ops->vhost_dev_start(hdev, false); - } --- -2.27.0 - diff --git a/hw-virtio-add-vhost_user_-read-write-trace-points.patch b/hw-virtio-add-vhost_user_-read-write-trace-points.patch deleted file mode 100644 index ca9de06066b268c039c0c4a58a0a029cea815c5c..0000000000000000000000000000000000000000 --- a/hw-virtio-add-vhost_user_-read-write-trace-points.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 57451ee8e278827ef0ab592d565c14076dd62fd0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alex=20Benn=C3=A9e?= -Date: Mon, 21 Mar 2022 15:30:27 +0000 -Subject: [PATCH] hw/virtio: add vhost_user_[read|write] trace points -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -These are useful when trying to debug the initial vhost-user -negotiation, especially when it hard to get logging from the low level -library on the other side. - -Signed-off-by: Alex Bennée - -Message-Id: <20220321153037.3622127-4-alex.bennee@linaro.org> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: fangyi ---- - hw/virtio/trace-events | 2 ++ - hw/virtio/vhost-user.c | 4 ++++ - 2 files changed, 6 insertions(+) - -diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events -index 37c1555330..63c7668e5b 100644 ---- a/hw/virtio/trace-events -+++ b/hw/virtio/trace-events -@@ -21,6 +21,8 @@ vhost_user_set_mem_table_withfd(int index, const char *name, uint64_t memory_siz - vhost_user_postcopy_waker(const char *rb, uint64_t rb_offset) "%s + 0x%"PRIx64 - vhost_user_postcopy_waker_found(uint64_t client_addr) "0x%"PRIx64 - vhost_user_postcopy_waker_nomatch(const char *rb, uint64_t rb_offset) "%s + 0x%"PRIx64 -+vhost_user_read(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32"" -+vhost_user_write(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32"" - - # vhost-vdpa.c - vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8 -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index 358dc82010..ea6d40eb5f 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -491,6 +491,8 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg, - return ret < 0 ? -saved_errno : -EIO; - } - -+ trace_vhost_user_write(msg->hdr.request, msg->hdr.flags); -+ - return 0; - } - -@@ -544,6 +546,8 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base, - } - } - -+ trace_vhost_user_read(msg.hdr.request, msg.hdr.flags); -+ - return 0; - } - --- -2.27.0 - diff --git a/hw-virtio-fix-typo-in-VIRTIO_CONFIG_IRQ_IDX-comments.patch b/hw-virtio-fix-typo-in-VIRTIO_CONFIG_IRQ_IDX-comments.patch deleted file mode 100644 index 76a7d1c9bc309e0974acef7804821dc5d27645ed..0000000000000000000000000000000000000000 --- a/hw-virtio-fix-typo-in-VIRTIO_CONFIG_IRQ_IDX-comments.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 6cbac9f34c67e2a2e28109152957f5eca35b6e73 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alex=20Benn=C3=A9e?= -Date: Mon, 10 Jul 2023 16:35:05 +0100 -Subject: [PATCH] hw/virtio: fix typo in VIRTIO_CONFIG_IRQ_IDX comments -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fixes: 544f0278af (virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX) -Signed-off-by: Alex Bennée -Message-Id: <20230710153522.3469097-4-alex.bennee@linaro.org> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/display/vhost-user-gpu.c | 4 ++-- - hw/net/virtio-net.c | 4 ++-- - hw/virtio/vhost-user-fs.c | 4 ++-- - hw/virtio/vhost-vsock-common.c | 4 ++-- - hw/virtio/virtio-crypto.c | 4 ++-- - 5 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c -index 1c78272a83..4363e34db1 100644 ---- a/hw/display/vhost-user-gpu.c -+++ b/hw/display/vhost-user-gpu.c -@@ -487,7 +487,7 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx) - - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - -@@ -504,7 +504,7 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask) - - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index ae37b3461b..3e1fa6adf3 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3249,7 +3249,7 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) - } - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return false - */ - -@@ -3281,7 +3281,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, - } - /* - *Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - -diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c -index 0c6ecd3b4f..5ac5dcce49 100644 ---- a/hw/virtio/vhost-user-fs.c -+++ b/hw/virtio/vhost-user-fs.c -@@ -163,7 +163,7 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx, - - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - -@@ -179,7 +179,7 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx) - - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - -diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c -index e4a8d90f4c..b9cf5f3f29 100644 ---- a/hw/virtio/vhost-vsock-common.c -+++ b/hw/virtio/vhost-vsock-common.c -@@ -127,7 +127,7 @@ static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx, - - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - -@@ -144,7 +144,7 @@ static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev, - - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - -diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c -index 9f7dcc88ba..61b421aab3 100644 ---- a/hw/virtio/virtio-crypto.c -+++ b/hw/virtio/virtio-crypto.c -@@ -960,7 +960,7 @@ static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, - - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - -@@ -979,7 +979,7 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx) - - /* - * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -- * as the Marco of configure interrupt's IDX, If this driver does not -+ * as the macro of configure interrupt's IDX, If this driver does not - * support, the function will return - */ - --- -2.27.0 - diff --git a/hw-virtio-fix-vhost_user_read-tracepoint.patch b/hw-virtio-fix-vhost_user_read-tracepoint.patch deleted file mode 100644 index 6185ae48b4fcd425b364ebd27e5903c9266e5a49..0000000000000000000000000000000000000000 --- a/hw-virtio-fix-vhost_user_read-tracepoint.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 09081b494d4aad3137fd375f5f18edc63c7e5d10 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alex=20Benn=C3=A9e?= -Date: Thu, 28 Jul 2022 14:55:03 +0100 -Subject: [PATCH] hw/virtio: fix vhost_user_read tracepoint -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -As reads happen in the callback we were never seeing them. We only -really care about the header so move the tracepoint to when the header -is complete. - -Fixes: 6ca6d8ee9d (hw/virtio: add vhost_user_[read|write] trace points) -Signed-off-by: Alex Bennée -Acked-by: Jason Wang -Message-Id: <20220728135503.1060062-5-alex.bennee@linaro.org> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-user.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index ea6d40eb5f..937b3021e9 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -297,6 +297,8 @@ static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg) - return -EPROTO; - } - -+ trace_vhost_user_read(msg->hdr.request, msg->hdr.flags); -+ - return 0; - } - -@@ -546,8 +548,6 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base, - } - } - -- trace_vhost_user_read(msg.hdr.request, msg.hdr.flags); -- - return 0; - } - --- -2.27.0 - diff --git a/hw-virtio-gracefully-handle-unset-vhost_dev-vdev.patch b/hw-virtio-gracefully-handle-unset-vhost_dev-vdev.patch deleted file mode 100644 index b2dea4b59ec023616bfdb8936e09520368846251..0000000000000000000000000000000000000000 --- a/hw-virtio-gracefully-handle-unset-vhost_dev-vdev.patch +++ /dev/null @@ -1,52 +0,0 @@ -From edbbc82bdf7cdb21604bb1c8b4a222691b3c3665 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alex=20Benn=C3=A9e?= -Date: Thu, 28 Jul 2022 14:55:01 +0100 -Subject: [PATCH] hw/virtio: gracefully handle unset vhost_dev vdev -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -I've noticed asserts firing because we query the status of vdev after -a vhost connection is closed down. Rather than faulting on the NULL -indirect just quietly reply false. - -Signed-off-by: Alex Bennée -Message-Id: <20220728135503.1060062-3-alex.bennee@linaro.org> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 2f0ddd35d6..8e8657fb0d 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -310,7 +310,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size) - dev->log_size = size; - } - --static int vhost_dev_has_iommu(struct vhost_dev *dev) -+static bool vhost_dev_has_iommu(struct vhost_dev *dev) - { - VirtIODevice *vdev = dev->vdev; - -@@ -320,8 +320,12 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev) - * does not have IOMMU, there's no need to enable this feature - * which may cause unnecessary IOTLB miss/update transactions. - */ -- return virtio_bus_device_iommu_enabled(vdev) && -- virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); -+ if (vdev) { -+ return virtio_bus_device_iommu_enabled(vdev) && -+ virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); -+ } else { -+ return false; -+ } - } - - static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr, --- -2.27.0 - diff --git a/hw-virtio-vdpa-Fix-leak-of-host-notifier-memory-regi.patch b/hw-virtio-vdpa-Fix-leak-of-host-notifier-memory-regi.patch deleted file mode 100644 index ada19f02f2e7c43c6b1392d4f86acdf5ba9c58d7..0000000000000000000000000000000000000000 --- a/hw-virtio-vdpa-Fix-leak-of-host-notifier-memory-regi.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 862a150140b95bbd23d174307aacd06f65d36f1c Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 21 Jul 2023 07:26:44 +0000 -Subject: [PATCH] hw/virtio: vdpa: Fix leak of host-notifier memory-region - mainline inclusion commit 98f7607ecda00dea3cbb2ed7b4427c96846efb83 category: - bugfix - ---------------------------------------------------------------- - -If call virtio_queue_set_host_notifier_mr fails, should free -host-notifier memory-region. - -This problem can trigger a coredump with some vDPA drivers (mlx5, -but not with the vdpasim), if we unplug the virtio-net card from -the guest after a stop/start. - -The same fix has been done for vhost-user: - 1f89d3b91e3e ("hw/virtio: Fix leak of host-notifier memory-region") - -Fixes: d0416d487bd5 ("vhost-vdpa: map virtqueue notification area if possible") -Cc: jasowang@redhat.com -Resolves: https://bugzilla.redhat.com/2027208 -Signed-off-by: Laurent Vivier -Message-Id: <20220211170259.1388734-1-lvivier@redhat.com> -Cc: qemu-stable@nongnu.org -Acked-by: Jason Wang -Reviewed-by: Stefano Garzarella -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin - -Signed-off-by: tangbinzy ---- - hw/virtio/vhost-vdpa.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index f285edb786..225c9b1730 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -417,6 +417,7 @@ static int vhost_vdpa_host_notifier_init(struct vhost_dev *dev, int queue_index) - g_free(name); - - if (virtio_queue_set_host_notifier_mr(vdev, queue_index, &n->mr, true)) { -+ object_unparent(OBJECT(&n->mr)); - munmap(addr, page_size); - goto err; - } --- -2.41.0.windows.1 - diff --git a/hw-virtio-vhost-Fix-typo-in-comment.patch b/hw-virtio-vhost-Fix-typo-in-comment.patch deleted file mode 100644 index e3da1d04e45f6b5925d50d875a21591ce0f7c69d..0000000000000000000000000000000000000000 --- a/hw-virtio-vhost-Fix-typo-in-comment.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 7c0b752e2bfd9c6e12570d7a9229a6f733d9ca59 Mon Sep 17 00:00:00 2001 -From: Leonardo Garcia -Date: Tue, 23 Nov 2021 08:48:31 -0300 -Subject: [PATCH] hw/virtio/vhost: Fix typo in comment. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Leonardo Garcia -Reviewed-by: Laurent Vivier -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: -Signed-off-by: Laurent Vivier -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 22ec9e1ef7..2f0ddd35d6 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -318,7 +318,7 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev) - * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support - * incremental memory mapping API via IOTLB API. For platform that - * does not have IOMMU, there's no need to enable this feature -- * which may cause unnecessary IOTLB miss/update trnasactions. -+ * which may cause unnecessary IOTLB miss/update transactions. - */ - return virtio_bus_device_iommu_enabled(vdev) && - virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); --- -2.27.0 - diff --git a/hw-virtio-virtio-iommu-pci-Enforce-the-device-is-plu.patch b/hw-virtio-virtio-iommu-pci-Enforce-the-device-is-plu.patch deleted file mode 100644 index f442f06b339a0ced45647349d10ee50bdeb7fba0..0000000000000000000000000000000000000000 --- a/hw-virtio-virtio-iommu-pci-Enforce-the-device-is-plu.patch +++ /dev/null @@ -1,69 +0,0 @@ -From a2323aa79da71c92e818306f1e18184619309a35 Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:03:07 -0800 -Subject: [PATCH] hw/virtio/virtio-iommu-pci: Enforce the device is plugged on - the root bus - -cherry picked from commit e72cfabf4ef2f0031e5d0b8129fb1533d383654d - -In theory the virtio-iommu-pci could be plugged anywhere in the PCIe -topology and as long as the dt/acpi info are properly built this should -work. However at the moment we fail to do that because the -virtio-iommu-pci BDF is not computed at plug time and in that case -vms->virtio_iommu_bdf gets an incorrect value. - -For instance if the virtio-iommu-pci is plugged onto a pcie root port -and the virtio-iommu protects a virtio-block-pci device the guest does -not boot. - -So let's do not pretend we do support this case and fail the initialize() -if we detect the virtio-iommu-pci is plugged anywhere else than on the -root bus. Anyway this ability is not needed. - -Signed-off-by: Eric Auger -Message-Id: <20221012163448.121368-1-eric.auger@redhat.com> -Reviewed-by: Jean-Philippe Brucker -Tested-by: Jean-Philippe Brucker -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Wanghe Xiao ---- - hw/virtio/virtio-iommu-pci.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c -index a160ae6b41..37eb2fb979 100644 ---- a/hw/virtio/virtio-iommu-pci.c -+++ b/hw/virtio/virtio-iommu-pci.c -@@ -44,6 +44,7 @@ static Property virtio_iommu_pci_properties[] = { - static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) - { - VirtIOIOMMUPCI *dev = VIRTIO_IOMMU_PCI(vpci_dev); -+ PCIBus *pbus = pci_get_bus(&vpci_dev->pci_dev); - DeviceState *vdev = DEVICE(&dev->vdev); - VirtIOIOMMU *s = VIRTIO_IOMMU(vdev); - -@@ -65,11 +66,17 @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) - s->reserved_regions[i].type != VIRTIO_IOMMU_RESV_MEM_T_MSI) { - error_setg(errp, "reserved region %d has an invalid type", i); - error_append_hint(errp, "Valid values are 0 and 1\n"); -- } -+ return; -+ } - } -+ if (!pci_bus_is_root(pbus)) { -+ error_setg(errp, "virtio-iommu-pci must be plugged on the root bus"); -+ return; -+ } -+ - object_property_set_link(OBJECT(dev), "primary-bus", -- OBJECT(pci_get_bus(&vpci_dev->pci_dev)), -- &error_abort); -+ OBJECT(pbus), &error_abort); -+ - virtio_pci_force_virtio_1(vpci_dev); - qdev_realize(vdev, BUS(&vpci_dev->bus), errp); - } --- -2.27.0 - diff --git a/hw-virtio-virtio-pmem-Replace-impossible-check-by-as.patch b/hw-virtio-virtio-pmem-Replace-impossible-check-by-as.patch deleted file mode 100644 index 4721ee7b8a877cc7cfc440cf488c7aa63f4bb046..0000000000000000000000000000000000000000 --- a/hw-virtio-virtio-pmem-Replace-impossible-check-by-as.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 12eed71f72cbb5d81b14f66fde254058f121979a Mon Sep 17 00:00:00 2001 -From: qihao -Date: Wed, 25 Oct 2023 17:44:42 +0800 -Subject: [PATCH] hw/virtio/virtio-pmem: Replace impossible check by assertion -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 184256d261cfc773360f14a80092ace5a716bb8f - -The get_memory_region() handler is used when (un)plugging the -device, which can only occur *after* it is realized. - -virtio_pmem_realize() ensure the instance can not be realized -without 'memdev'. Remove the superfluous check, replacing it -by an assertion. - -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Michael S. Tsirkin -Reviewed-by: Manos Pitsidianakis -Message-Id: <20231017140150.44995-2-philmd@linaro.org> -Signed-off-by: qihao_yewu ---- - hw/virtio/virtio-pmem.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c -index d1aeb90a31..39f3949a3b 100644 ---- a/hw/virtio/virtio-pmem.c -+++ b/hw/virtio/virtio-pmem.c -@@ -149,10 +149,7 @@ static void virtio_pmem_fill_device_info(const VirtIOPMEM *pmem, - static MemoryRegion *virtio_pmem_get_memory_region(VirtIOPMEM *pmem, - Error **errp) - { -- if (!pmem->memdev) { -- error_setg(errp, "'%s' property must be set", VIRTIO_PMEM_MEMDEV_PROP); -- return NULL; -- } -+ assert(pmem->memdev); - - return &pmem->memdev->mr; - } --- -2.41.0.windows.1 - diff --git a/hw-xen-xen_pt-fix-uninitialized-variable.patch b/hw-xen-xen_pt-fix-uninitialized-variable.patch deleted file mode 100644 index f511ca006dd76be4dde41205ab74607d25a2ef5e..0000000000000000000000000000000000000000 --- a/hw-xen-xen_pt-fix-uninitialized-variable.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 26bc780b9357bc50131242915175cf1db8c82b0e Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Tue, 1 Aug 2023 23:30:04 -0700 -Subject: [PATCH] hw/xen/xen_pt: fix uninitialized variable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 3856734d80fbf46683e4080117ed961f5ab1300b - -xen_pt_config_reg_init() reads only that many bytes as the size of the -register that is being initialized. It uses -xen_host_pci_get_{byte,word,long} and casts its last argument to -expected pointer type. This means for smaller registers higher bits of -'val' are not initialized. Then, the function fails if any of those -higher bits are set. - -Fix this by initializing 'val' with zero. - -Signed-off-by: Marek Marczykowski-Górecki -Reviewed-by: Stefano Stabellini -Message-Id: <20230127050815.4155276-1-marmarek@invisiblethingslab.com> -Signed-off-by: Anthony PERARD - -Signed-off-by: Wanghe Xiao ---- - hw/xen/xen_pt_config_init.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c -index c5c4e943a8..e7bcbe4c4f 100644 ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -1924,7 +1924,7 @@ static void xen_pt_config_reg_init(XenPCIPassthroughState *s, - if (reg->init) { - uint32_t host_mask, size_mask; - unsigned int offset; -- uint32_t val; -+ uint32_t val = 0; - - /* initialize emulate register */ - rc = reg->init(s, reg_entry->reg, --- -2.41.0.windows.1 - diff --git a/i386-Add-new-CPU-model-SapphireRapids.patch b/i386-Add-new-CPU-model-SapphireRapids.patch deleted file mode 100644 index 9286476608a2b0cf722b3ff473904dc67c99cfc4..0000000000000000000000000000000000000000 --- a/i386-Add-new-CPU-model-SapphireRapids.patch +++ /dev/null @@ -1,221 +0,0 @@ -From f91b5ed322bbb6d793fca7005ac350d466fff232 Mon Sep 17 00:00:00 2001 -From: "Wang, Lei" -Date: Thu, 11 Aug 2022 22:57:51 -0700 -Subject: [PATCH] i386: Add new CPU model SapphireRapids - -The new CPU model mostly inherits features from Icelake-Server, while -adding new features: - - AMX (Advance Matrix eXtensions) - - Bus Lock Debug Exception -and new instructions: - - AVX VNNI (Vector Neural Network Instruction): - - VPDPBUS: Multiply and Add Unsigned and Signed Bytes - - VPDPBUSDS: Multiply and Add Unsigned and Signed Bytes with Saturation - - VPDPWSSD: Multiply and Add Signed Word Integers - - VPDPWSSDS: Multiply and Add Signed Integers with Saturation - - FP16: Replicates existing AVX512 computational SP (FP32) instructions - using FP16 instead of FP32 for ~2X performance gain - - SERIALIZE: Provide software with a simple way to force the processor to - complete all modifications, faster, allowed in all privilege levels and - not causing an unconditional VM exit - - TSX Suspend Load Address Tracking: Allows programmers to choose which - memory accesses do not need to be tracked in the TSX read set - - AVX512_BF16: Vector Neural Network Instructions supporting BFLOAT16 - inputs and conversion instructions from IEEE single precision - - fast zero-length MOVSB (KVM doesn't support yet) - - fast short STOSB (KVM doesn't support yet) - - fast short CMPSB, SCASB (KVM doesn't support yet) - -Features that may be added in future versions: - - CET (virtualization support hasn't been merged) - -Signed-off-by: Wang, Lei -Reviewed-by: Robert Hoo -Message-Id: <20220812055751.14553-1-lei4.wang@intel.com> -Reviewed-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 133 +++++++++++++++++++++++++++++++++++++++++++++- - target/i386/cpu.h | 4 ++ - 2 files changed, 135 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 7122af303d..61cd7abcaa 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3529,6 +3529,135 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ } - } - }, -+ { -+ .name = "SapphireRapids", -+ .level = 0x20, -+ .vendor = CPUID_VENDOR_INTEL, -+ .family = 6, -+ .model = 143, -+ .stepping = 4, -+ /* -+ * please keep the ascending order so that we can have a clear view of -+ * bit position of each feature. -+ */ -+ .features[FEAT_1_EDX] = -+ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | -+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | -+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | -+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | -+ CPUID_SSE | CPUID_SSE2, -+ .features[FEAT_1_ECX] = -+ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | -+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | -+ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | -+ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | -+ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, -+ .features[FEAT_8000_0001_EDX] = -+ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | -+ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, -+ .features[FEAT_8000_0001_ECX] = -+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, -+ .features[FEAT_8000_0008_EBX] = -+ CPUID_8000_0008_EBX_WBNOINVD, -+ .features[FEAT_7_0_EBX] = -+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE | -+ CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | -+ CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM | -+ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | -+ CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | -+ CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT | -+ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_SHA_NI | -+ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL, -+ .features[FEAT_7_0_ECX] = -+ CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | -+ CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | -+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | -+ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | -+ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 | -+ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, -+ .features[FEAT_7_0_EDX] = -+ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | -+ CPUID_7_0_EDX_TSX_LDTRK | CPUID_7_0_EDX_AMX_BF16 | -+ CPUID_7_0_EDX_AVX512_FP16 | CPUID_7_0_EDX_AMX_TILE | -+ CPUID_7_0_EDX_AMX_INT8 | CPUID_7_0_EDX_SPEC_CTRL | -+ CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD, -+ .features[FEAT_ARCH_CAPABILITIES] = -+ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | -+ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | -+ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO, -+ .features[FEAT_XSAVE] = -+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | -+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES | CPUID_D_1_EAX_XFD, -+ .features[FEAT_6_EAX] = -+ CPUID_6_EAX_ARAT, -+ .features[FEAT_7_1_EAX] = -+ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16 | -+ CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC, -+ .features[FEAT_VMX_BASIC] = -+ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, -+ .features[FEAT_VMX_ENTRY_CTLS] = -+ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | -+ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, -+ .features[FEAT_VMX_EPT_VPID_CAPS] = -+ MSR_VMX_EPT_EXECONLY | -+ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_PAGE_WALK_LENGTH_5 | -+ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | -+ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | -+ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | -+ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, -+ .features[FEAT_VMX_EXIT_CTLS] = -+ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | -+ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | -+ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | -+ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, -+ .features[FEAT_VMX_MISC] = -+ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | -+ MSR_VMX_MISC_VMWRITE_VMEXIT, -+ .features[FEAT_VMX_PINBASED_CTLS] = -+ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | -+ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | -+ VMX_PIN_BASED_POSTED_INTR, -+ .features[FEAT_VMX_PROCBASED_CTLS] = -+ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | -+ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | -+ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | -+ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | -+ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | -+ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | -+ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | -+ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | -+ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | -+ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | -+ VMX_CPU_BASED_PAUSE_EXITING | -+ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, -+ .features[FEAT_VMX_SECONDARY_CTLS] = -+ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | -+ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | -+ VMX_SECONDARY_EXEC_RDTSCP | -+ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | -+ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | -+ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | -+ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | -+ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -+ VMX_SECONDARY_EXEC_RDRAND_EXITING | -+ VMX_SECONDARY_EXEC_ENABLE_INVPCID | -+ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | -+ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | -+ VMX_SECONDARY_EXEC_XSAVES, -+ .features[FEAT_VMX_VMFUNC] = -+ MSR_VMX_VMFUNC_EPT_SWITCHING, -+ .xlevel = 0x80000008, -+ .model_id = "Intel Xeon Processor (SapphireRapids)", -+ .versions = (X86CPUVersionDefinition[]) { -+ { .version = 1 }, -+ { /* end of list */ }, -+ }, -+ }, - { - .name = "Denverton", - .level = 21, -@@ -5619,7 +5748,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - break; - } - case 0x1D: { -- /* AMX TILE */ -+ /* AMX TILE, for now hardcoded for Sapphire Rapids*/ - *eax = 0; - *ebx = 0; - *ecx = 0; -@@ -5640,7 +5769,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - break; - } - case 0x1E: { -- /* AMX TMUL */ -+ /* AMX TMUL, for now hardcoded for Sapphire Rapids */ - *eax = 0; - *ebx = 0; - *ecx = 0; -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 7a32dabf12..d0c7791a1e 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -857,10 +857,14 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_0_EDX_SERIALIZE (1U << 14) - /* TSX Suspend Load Address Tracking instruction */ - #define CPUID_7_0_EDX_TSX_LDTRK (1U << 16) -+/* AMX_BF16 instruction */ -+#define CPUID_7_0_EDX_AMX_BF16 (1U << 22) - /* AVX512_FP16 instruction */ - #define CPUID_7_0_EDX_AVX512_FP16 (1U << 23) - /* AMX tile (two-dimensional register) */ - #define CPUID_7_0_EDX_AMX_TILE (1U << 24) -+/* AMX_INT8 instruction */ -+#define CPUID_7_0_EDX_AMX_INT8 (1U << 25) - /* Speculation Control */ - #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) - /* Single Thread Indirect Branch Predictors */ --- -2.27.0 - diff --git a/i386-add-notify-VM-exit-support.patch b/i386-add-notify-VM-exit-support.patch deleted file mode 100644 index 83f47d1faec6f878420069ab274d41e49ec594d6..0000000000000000000000000000000000000000 --- a/i386-add-notify-VM-exit-support.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 06d1ed3c9e3b736944e5267ffc8d341801fb758b Mon Sep 17 00:00:00 2001 -From: Chenyi Qiang -Date: Thu, 29 Sep 2022 15:20:14 +0800 -Subject: [PATCH] i386: add notify VM exit support - -from mainline-v7.2.0-rc0 -commit e2e69f6bb907a70ac518230c54e98e7abcb0c911 -category: feature -feature: Notify VM Exit -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6GWQE - -Intel-SIG: commit e2e69f6bb907 ("i386: add notify VM exit support") - ------------------------------------------------------------------- - -i386: add notify VM exit support - -There are cases that malicious virtual machine can cause CPU stuck (due -to event windows don't open up), e.g., infinite loop in microcode when -nested #AC (CVE-2015-5307). No event window means no event (NMI, SMI and -IRQ) can be delivered. It leads the CPU to be unavailable to host or -other VMs. Notify VM exit is introduced to mitigate such kind of -attacks, which will generate a VM exit if no event window occurs in VM -non-root mode for a specified amount of time (notify window). - -A new KVM capability KVM_CAP_X86_NOTIFY_VMEXIT is exposed to user space -so that the user can query the capability and set the expected notify -window when creating VMs. The format of the argument when enabling this -capability is as follows: - Bit 63:32 - notify window specified in qemu command - Bit 31:0 - some flags (e.g. KVM_X86_NOTIFY_VMEXIT_ENABLED is set to - enable the feature.) - -Users can configure the feature by a new (x86 only) accel property: - qemu -accel kvm,notify-vmexit=run|internal-error|disable,notify-window=n - -The default option of notify-vmexit is run, which will enable the -capability and do nothing if the exit happens. The internal-error option -raises a KVM internal error if it happens. The disable option does not -enable the capability. The default value of notify-window is 0. It is valid -only when notify-vmexit is not disabled. The valid range of notify-window -is non-negative. It is even safe to set it to zero since there's an -internal hardware threshold to be added to ensure no false positive. - -Because a notify VM exit may happen with VM_CONTEXT_INVALID set in exit -qualification (no cases are anticipated that would set this bit), which -means VM context is corrupted. It would be reflected in the flags of -KVM_EXIT_NOTIFY exit. If KVM_NOTIFY_CONTEXT_INVALID bit is set, raise a KVM -internal error unconditionally. - -Acked-by: Peter Xu -Signed-off-by: Chenyi Qiang -Message-Id: <20220929072014.20705-5-chenyi.qiang@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - accel/kvm/kvm-all.c | 2 + - qapi/run-state.json | 17 ++++++++ - qemu-options.hx | 11 +++++ - target/i386/kvm/kvm.c | 98 +++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 128 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 91d93facf2..799d993f6c 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -3602,6 +3602,8 @@ static void kvm_accel_instance_init(Object *obj) - s->kernel_irqchip_split = ON_OFF_AUTO_AUTO; - /* KVM dirty ring is by default off */ - s->kvm_dirty_ring_size = 0; -+ s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN; -+ s->notify_window = 0; - } - - static void kvm_accel_class_init(ObjectClass *oc, void *data) -diff --git a/qapi/run-state.json b/qapi/run-state.json -index 43d66d700f..08c38b2c67 100644 ---- a/qapi/run-state.json -+++ b/qapi/run-state.json -@@ -638,3 +638,20 @@ - { 'struct': 'MemoryFailureFlags', - 'data': { 'action-required': 'bool', - 'recursive': 'bool'} } -+ -+## -+# @NotifyVmexitOption: -+# -+# An enumeration of the options specified when enabling notify VM exit -+# -+# @run: enable the feature, do nothing and continue if the notify VM exit happens. -+# -+# @internal-error: enable the feature, raise a internal error if the notify -+# VM exit happens. -+# -+# @disable: disable the feature. -+# -+# Since: 7.2 -+## -+{ 'enum': 'NotifyVmexitOption', -+ 'data': [ 'run', 'internal-error', 'disable' ] } -\ No newline at end of file -diff --git a/qemu-options.hx b/qemu-options.hx -index 047d28a357..3c9b0f022c 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -152,6 +152,7 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel, - " split-wx=on|off (enable TCG split w^x mapping)\n" - " tb-size=n (TCG translation block cache size)\n" - " dirty-ring-size=n (KVM dirty ring GFN count, default 0)\n" -+ " notify-vmexit=run|internal-error|disable,notify-window=n (enable notify VM exit and set notify window, x86 only)\n" - " thread=single|multi (enable multi-threaded TCG)\n", QEMU_ARCH_ALL) - SRST - ``-accel name[,prop=value[,...]]`` -@@ -203,6 +204,16 @@ SRST - is disabled (dirty-ring-size=0). When enabled, KVM will instead - record dirty pages in a bitmap. - -+ ``notify-vmexit=run|internal-error|disable,notify-window=n`` -+ Enables or disables notify VM exit support on x86 host and specify -+ the corresponding notify window to trigger the VM exit if enabled. -+ ``run`` option enables the feature. It does nothing and continue -+ if the exit happens. ``internal-error`` option enables the feature. -+ It raises a internal error. ``disable`` option doesn't enable the feature. -+ This feature can mitigate the CPU stuck issue due to event windows don't -+ open up for a specified of time (i.e. notify-window). -+ Default: notify-vmexit=run,notify-window=0. -+ - ERST - - DEF("smp", HAS_ARG, QEMU_OPTION_smp, -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index e2f28ce958..b8257e7e5f 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -15,6 +15,7 @@ - #include "qemu/osdep.h" - #include "qapi/qapi-events-run-state.h" - #include "qapi/error.h" -+#include "qapi/visitor.h" - #include - #include - #include -@@ -2496,6 +2497,21 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - } - } - -+ if (s->notify_vmexit != NOTIFY_VMEXIT_OPTION_DISABLE && -+ kvm_check_extension(s, KVM_CAP_X86_NOTIFY_VMEXIT)) { -+ uint64_t notify_window_flags = -+ ((uint64_t)s->notify_window << 32) | -+ KVM_X86_NOTIFY_VMEXIT_ENABLED | -+ KVM_X86_NOTIFY_VMEXIT_USER; -+ ret = kvm_vm_enable_cap(s, KVM_CAP_X86_NOTIFY_VMEXIT, 0, -+ notify_window_flags); -+ if (ret < 0) { -+ error_report("kvm: Failed to enable notify vmexit cap: %s", -+ strerror(-ret)); -+ return ret; -+ } -+ } -+ - return 0; - } - -@@ -4839,6 +4855,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - X86CPU *cpu = X86_CPU(cs); - uint64_t code; - int ret; -+ bool ctx_invalid; -+ char str[256]; -+ KVMState *state; - - switch (run->exit_reason) { - case KVM_EXIT_HLT: -@@ -4894,6 +4913,21 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - /* already handled in kvm_arch_post_run */ - ret = 0; - break; -+ case KVM_EXIT_NOTIFY: -+ ctx_invalid = !!(run->notify.flags & KVM_NOTIFY_CONTEXT_INVALID); -+ state = KVM_STATE(current_accel()); -+ sprintf(str, "Encounter a notify exit with %svalid context in" -+ " guest. There can be possible misbehaves in guest." -+ " Please have a look.", ctx_invalid ? "in" : ""); -+ if (ctx_invalid || -+ state->notify_vmexit == NOTIFY_VMEXIT_OPTION_INTERNAL_ERROR) { -+ warn_report("KVM internal error: %s", str); -+ ret = -1; -+ } else { -+ warn_report_once("KVM: %s", str); -+ ret = 0; -+ } -+ break; - default: - fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); - ret = -1; -@@ -5169,6 +5203,70 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask) - } - } - -+static int kvm_arch_get_notify_vmexit(Object *obj, Error **errp) -+{ -+ KVMState *s = KVM_STATE(obj); -+ return s->notify_vmexit; -+} -+ -+static void kvm_arch_set_notify_vmexit(Object *obj, int value, Error **errp) -+{ -+ KVMState *s = KVM_STATE(obj); -+ -+ if (s->fd != -1) { -+ error_setg(errp, "Cannot set properties after the accelerator has been initialized"); -+ return; -+ } -+ -+ s->notify_vmexit = value; -+} -+ -+static void kvm_arch_get_notify_window(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) -+{ -+ KVMState *s = KVM_STATE(obj); -+ uint32_t value = s->notify_window; -+ -+ visit_type_uint32(v, name, &value, errp); -+} -+ -+static void kvm_arch_set_notify_window(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) -+{ -+ KVMState *s = KVM_STATE(obj); -+ Error *error = NULL; -+ uint32_t value; -+ -+ if (s->fd != -1) { -+ error_setg(errp, "Cannot set properties after the accelerator has been initialized"); -+ return; -+ } -+ -+ visit_type_uint32(v, name, &value, &error); -+ if (error) { -+ error_propagate(errp, error); -+ return; -+ } -+ -+ s->notify_window = value; -+} -+ - void kvm_arch_accel_class_init(ObjectClass *oc) - { -+ object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOption", -+ &NotifyVmexitOption_lookup, -+ kvm_arch_get_notify_vmexit, -+ kvm_arch_set_notify_vmexit); -+ object_class_property_set_description(oc, "notify-vmexit", -+ "Enable notify VM exit"); -+ -+ object_class_property_add(oc, "notify-window", "uint32", -+ kvm_arch_get_notify_window, -+ kvm_arch_set_notify_window, -+ NULL, NULL); -+ object_class_property_set_description(oc, "notify-window", -+ "Clock cycles without an event window " -+ "after which a notification VM exit occurs"); - } --- -2.27.0 - diff --git a/i386-cache-passthrough-Update-AMD-8000_001D.EAX-25-1.patch b/i386-cache-passthrough-Update-AMD-8000_001D.EAX-25-1.patch deleted file mode 100644 index 7ffe327361a0156af4134d1fa57e987b5ada1b1a..0000000000000000000000000000000000000000 --- a/i386-cache-passthrough-Update-AMD-8000_001D.EAX-25-1.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 475988057789a1f4dcd7354c8a07fd37dcbac79f Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Thu, 10 Feb 2022 20:06:01 +0800 -Subject: [PATCH] i386: cache passthrough: Update AMD 8000_001D.EAX[25:14] - based on vCPU topo - -On AMD target, when host cache passthrough is disabled we will -emulate the guest caches with default values and initialize the -shared cpu list of the caches based on vCPU topology. However -when host cache passthrough is enabled, the shared cpu list is -consistent with host regardless what the vCPU topology is. - -For example, when cache passthrough is enabled, running a guest -with vThreads=1 on a host with pThreads=2, we will get that there -are every *two* logical vCPUs sharing a L1/L2 cache, which is not -consistent with the vCPU topology (vThreads=1). - -So let's reinitialize BITs[25:14] of AMD CPUID 8000_001D.EAX -based on the actual vCPU topology instead of host pCPU topology. - -Signed-off-by: Yanan Wang ---- - target/i386/cpu.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index c1fe2895fd..002e32650d 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -5724,9 +5724,31 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - } - break; - case 0x8000001D: -+ /* Populate AMD Processor Cache Information */ - *eax = 0; - if (cpu->cache_info_passthrough) { - host_cpuid(index, count, eax, ebx, ecx, edx); -+ -+ /* -+ * Clear BITs[25:14] and then update them based on the guest -+ * vCPU topology, like what we do in encode_cache_cpuid8000001d -+ * when cache_info_passthrough is not enabled. -+ */ -+ *eax &= ~0x03FFC000; -+ switch (count) { -+ case 0: /* L1 dcache info */ -+ case 1: /* L1 icache info */ -+ case 2: /* L2 cache info */ -+ *eax |= ((topo_info.threads_per_core - 1) << 14); -+ break; -+ case 3: /* L3 cache info */ -+ *eax |= ((topo_info.cores_per_die * -+ topo_info.threads_per_core - 1) << 14); -+ break; -+ default: /* end of info */ -+ *eax = *ebx = *ecx = *edx = 0; -+ break; -+ } - break; - } - switch (count) { --- -2.27.0 - diff --git a/i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch b/i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch deleted file mode 100644 index a0fc157bf3e84734665871a86ca53bb25e5bbec5..0000000000000000000000000000000000000000 --- a/i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 3eaa433ca1cbee753698893b7732819ba2e31302 Mon Sep 17 00:00:00 2001 -From: Jian Wang -Date: Thu, 10 Feb 2022 19:43:55 +0800 -Subject: [PATCH] i386: cache passthrough: Update Intel CPUID4.EAX[25:14] based - on vCPU topo - -On Intel target, when host cache passthrough is disabled we will -emulate the guest caches with default values and initialize the -shared cpu list of the caches based on vCPU topology. However when -host cache passthrough is enabled, the shared cpu list is consistent -with host regardless what the vCPU topology is. - -For example, when cache passthrough is enabled, running a guest -with vThreads=1 on a host with pThreads=2, we will get that there -are every *two* logical vCPUs sharing a L1/L2 cache, which is not -consistent with the vCPU topology (vThreads=1). - -So let's reinitialize BITs[25:14] of Intel CPUID 4 based on the -actual vCPU topology instead of host pCPU topology. - -Signed-off-by: Jian Wang -Signed-off-by: Yanan Wang ---- - target/i386/cpu.c | 27 +++++++++++++++++++++++---- - 1 file changed, 23 insertions(+), 4 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 868cf3e7e8..c1fe2895fd 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -5196,7 +5196,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - { - X86CPU *cpu = env_archcpu(env); - CPUState *cs = env_cpu(env); -- uint32_t die_offset; -+ uint32_t die_offset, smt_width; - uint32_t limit; - uint32_t signature[3]; - X86CPUTopoInfo topo_info; -@@ -5205,6 +5205,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - topo_info.cores_per_die = cs->nr_cores; - topo_info.threads_per_core = cs->nr_threads; - -+ die_offset = apicid_die_offset(&topo_info); -+ smt_width = apicid_smt_width(&topo_info); -+ - /* Calculate & apply limits for different index ranges */ - if (index >= 0xC0000000) { - limit = env->cpuid_xlevel2; -@@ -5272,8 +5275,25 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - /* cache info: needed for Core compatibility */ - if (cpu->cache_info_passthrough) { - host_cpuid(index, count, eax, ebx, ecx, edx); -- /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */ -- *eax &= ~0xFC000000; -+ /* -+ * QEMU gives out its own APIC IDs, never pass down bits 31..26. -+ * Update the cache topo bits 25..14, according to the guest -+ * vCPU topology instead of the host pCPU topology. -+ */ -+ *eax &= ~0xFFFFC000; -+ switch (count) { -+ case 0: /* L1 dcache info */ -+ case 1: /* L1 icache info */ -+ case 2: /* L2 cache info */ -+ *eax |= ((1 << smt_width) - 1) << 14; -+ break; -+ case 3: /* L3 cache info */ -+ *eax |= ((1 << die_offset) - 1) << 14; -+ break; -+ default: /* end of info */ -+ *eax = *ebx = *ecx = *edx = 0; -+ break; -+ } - if ((*eax & 31) && cs->nr_cores > 1) { - *eax |= (cs->nr_cores - 1) << 26; - } -@@ -5298,7 +5318,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - eax, ebx, ecx, edx); - break; - case 3: /* L3 cache info */ -- die_offset = apicid_die_offset(&topo_info); - if (cpu->enable_l3_cache) { - encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache, - (1 << die_offset), cs->nr_cores, --- -2.27.0 - diff --git a/i386-cpu-fix-compile-error-in-all-target-configure.patch b/i386-cpu-fix-compile-error-in-all-target-configure.patch deleted file mode 100644 index 0cadfa1a02feaf82b60c2582d8de35c8d040dafd..0000000000000000000000000000000000000000 --- a/i386-cpu-fix-compile-error-in-all-target-configure.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 11498c2d92e703923d373b64ad3f33aec5f383f2 Mon Sep 17 00:00:00 2001 -From: Jiajie Li -Date: Thu, 17 Feb 2022 09:51:13 +0800 -Subject: [PATCH] i386/cpu: fix compile error in all target configure - -When compile with `./configure && make -j`, there will be -error: "unknown type name `ram_addr_t`", fix the error by -adding compilation macro to control it. - -Signed-off-by: Jiajie Li ---- - target/i386/cpu.c | 16 ++++++++-------- - target/i386/cpu.h | 2 ++ - 2 files changed, 10 insertions(+), 8 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index a4732a7372..d9dca1dafb 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6711,14 +6711,6 @@ static bool x86_cpu_get_paging_enabled(const CPUState *cs) - - return cpu->env.cr[0] & CR0_PG_MASK; - } --#endif /* !CONFIG_USER_ONLY */ -- --static void x86_cpu_set_pc(CPUState *cs, vaddr value) --{ -- X86CPU *cpu = X86_CPU(cs); -- -- cpu->env.eip = value; --} - - /* At present, we check the vm is *LARGE* or not, i.e. whether - * the memory size is more than 4T or not. -@@ -6736,6 +6728,14 @@ void x86_cpu_adjuest_by_ram_size(ram_addr_t ram_size, X86CPU *cpu) - cpu->fill_mtrr_mask = true; - } - } -+#endif /* !CONFIG_USER_ONLY */ -+ -+static void x86_cpu_set_pc(CPUState *cs, vaddr value) -+{ -+ X86CPU *cpu = X86_CPU(cs); -+ -+ cpu->env.eip = value; -+} - - int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request) - { -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 6f777fd6ca..d9296a9abc 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -1842,10 +1842,12 @@ struct X86CPU { - extern const VMStateDescription vmstate_x86_cpu; - #endif - -+#ifndef CONFIG_USER_ONLY - #define DEFAULT_VM_CPU_PHYS_BITS 42 - #define LARGE_VM_CPU_PHYS_BITS 46 - - void x86_cpu_adjuest_by_ram_size(ram_addr_t ram_size, X86CPU *cpu); -+#endif - - int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request); - --- -2.27.0 - diff --git a/i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch b/i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch deleted file mode 100644 index e4bc275fcfd83192deeaa07eb72f6f308c456cf1..0000000000000000000000000000000000000000 --- a/i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 752fe0479931f6ef512b6a048fb50364505ff713 Mon Sep 17 00:00:00 2001 -From: Chenyi Qiang -Date: Thu, 29 Sep 2022 15:20:11 +0800 -Subject: [PATCH] i386: kvm: extend kvm_{get, put}_vcpu_events to support - pending triple fault - -from mainline-v7.2.0-rc0 -commit 12f89a39cf3c5760cba82ce68929d748961f62df -category: feature -feature: Notify VM Exit -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6GWQE - -Intel-SIG: commit 12f89a39cf3c ("i386: kvm: extend kvm_{get, put}_vcpu_events to support pending triple fault") - ------------------------------------------------------------------- - -i386: kvm: extend kvm_{get, put}_vcpu_events to support pending triple fault - -For the direct triple faults, i.e. hardware detected and KVM morphed -to VM-Exit, KVM will never lose them. But for triple faults sythesized -by KVM, e.g. the RSM path, if KVM exits to userspace before the request -is serviced, userspace could migrate the VM and lose the triple fault. - -A new flag KVM_VCPUEVENT_VALID_TRIPLE_FAULT is defined to signal that -the event.triple_fault_pending field contains a valid state if the -KVM_CAP_X86_TRIPLE_FAULT_EVENT capability is enabled. - -Acked-by: Peter Xu -Signed-off-by: Chenyi Qiang -Message-Id: <20220929072014.20705-2-chenyi.qiang@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 1 + - target/i386/cpu.h | 1 + - target/i386/kvm/kvm.c | 20 ++++++++++++++++++++ - target/i386/machine.c | 20 ++++++++++++++++++++ - 4 files changed, 42 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 551b47ab1e..e3cea8397c 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6018,6 +6018,7 @@ static void x86_cpu_reset(DeviceState *dev) - env->exception_has_payload = false; - env->exception_payload = 0; - env->nmi_injected = false; -+ env->triple_fault_pending = false; - #if !defined(CONFIG_USER_ONLY) - /* We hard-wire the BSP to the first CPU. */ - apic_designate_bsp(cpu->apic_state, s->cpu_index == 0); -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 290f1beaea..4f7fa87b95 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -1698,6 +1698,7 @@ typedef struct CPUX86State { - uint8_t has_error_code; - uint8_t exception_has_payload; - uint64_t exception_payload; -+ uint8_t triple_fault_pending; - uint32_t ins_len; - uint32_t sipi_vector; - bool tsc_valid; -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 5b15e0430b..e97d967c73 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -127,6 +127,7 @@ static int has_xsave2; - static int has_xcrs; - static int has_pit_state2; - static int has_exception_payload; -+static int has_triple_fault_event; - - static bool has_msr_mcg_ext_ctl; - -@@ -2380,6 +2381,16 @@ int kvm_arch_init(MachineState *ms, KVMState *s) - } - } - -+ has_triple_fault_event = kvm_check_extension(s, KVM_CAP_X86_TRIPLE_FAULT_EVENT); -+ if (has_triple_fault_event) { -+ ret = kvm_vm_enable_cap(s, KVM_CAP_X86_TRIPLE_FAULT_EVENT, 0, true); -+ if (ret < 0) { -+ error_report("kvm: Failed to enable triple fault event cap: %s", -+ strerror(-ret)); -+ return ret; -+ } -+ } -+ - ret = kvm_get_supported_msrs(s); - if (ret < 0) { - return ret; -@@ -4004,6 +4015,11 @@ static int kvm_put_vcpu_events(X86CPU *cpu, int level) - } - } - -+ if (has_triple_fault_event) { -+ events.flags |= KVM_VCPUEVENT_VALID_TRIPLE_FAULT; -+ events.triple_fault.pending = env->triple_fault_pending; -+ } -+ - return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_VCPU_EVENTS, &events); - } - -@@ -4073,6 +4089,10 @@ static int kvm_get_vcpu_events(X86CPU *cpu) - } - } - -+ if (events.flags & KVM_VCPUEVENT_VALID_TRIPLE_FAULT) { -+ env->triple_fault_pending = events.triple_fault.pending; -+ } -+ - env->sipi_vector = events.sipi_vector; - - return 0; -diff --git a/target/i386/machine.c b/target/i386/machine.c -index 3977e9d8f8..41cf5c0053 100644 ---- a/target/i386/machine.c -+++ b/target/i386/machine.c -@@ -1497,6 +1497,25 @@ static const VMStateDescription vmstate_amx_xtile = { - }; - #endif - -+static bool triple_fault_needed(void *opaque) -+{ -+ X86CPU *cpu = opaque; -+ CPUX86State *env = &cpu->env; -+ -+ return env->triple_fault_pending; -+} -+ -+static const VMStateDescription vmstate_triple_fault = { -+ .name = "cpu/triple_fault", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .needed = triple_fault_needed, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT8(env.triple_fault_pending, X86CPU), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ - const VMStateDescription vmstate_x86_cpu = { - .name = "cpu", - .version_id = 12, -@@ -1639,6 +1658,7 @@ const VMStateDescription vmstate_x86_cpu = { - #ifdef TARGET_X86_64 - &vmstate_amx_xtile, - #endif -+ &vmstate_triple_fault, - NULL - } - }; --- -2.27.0 - diff --git a/i386-sev-Avoid-SEV-ES-crash-due-to-missing-MSR_EFER_.patch b/i386-sev-Avoid-SEV-ES-crash-due-to-missing-MSR_EFER_.patch deleted file mode 100644 index 50fd9c46e8e9da698371afa990cd4eb2a4e6659d..0000000000000000000000000000000000000000 --- a/i386-sev-Avoid-SEV-ES-crash-due-to-missing-MSR_EFER_.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 92b95a2982e192b90b45a988afe81e253862690f Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Thu, 7 Dec 2023 20:06:08 +0800 -Subject: [PATCH] i386/sev: Avoid SEV-ES crash due to missing MSR_EFER_LMA - bit -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - - Commit 7191f24c7fcf ("accel/kvm/kvm-all: Handle register access errors") - added error checking for KVM_SET_SREGS/KVM_SET_SREGS2. In doing so, it - exposed a long-running bug in current KVM support for SEV-ES where the - kernel assumes that MSR_EFER_LMA will be set explicitly by the guest - kernel, in which case EFER write traps would result in KVM eventually - seeing MSR_EFER_LMA get set and recording it in such a way that it would - be subsequently visible when accessing it via KVM_GET_SREGS/etc. - - However, guest kernels currently rely on MSR_EFER_LMA getting set - automatically when MSR_EFER_LME is set and paging is enabled via - CR0_PG_MASK. As a result, the EFER write traps don't actually expose the - MSR_EFER_LMA bit, even though it is set internally, and when QEMU - subsequently tries to pass this EFER value back to KVM via - KVM_SET_SREGS* it will fail various sanity checks and return -EINVAL, - which is now considered fatal due to the aforementioned QEMU commit. - - This can be addressed by inferring the MSR_EFER_LMA bit being set when - paging is enabled and MSR_EFER_LME is set, and synthesizing it to ensure - the expected bits are all present in subsequent handling on the host - side. - - Ultimately, this handling will be implemented in the host kernel, but to - avoid breaking QEMU's SEV-ES support when using older host kernels, the - same handling can be done in QEMU just after fetching the register - values via KVM_GET_SREGS*. Implement that here. - - Cc: Paolo Bonzini - Cc: Marcelo Tosatti - Cc: Tom Lendacky - Cc: Akihiko Odaki - Cc: Philippe Mathieu-Daudé - Cc: Lara Lazier - Cc: Vitaly Kuznetsov - Cc: Maxim Levitsky - Cc: - Fixes: 7191f24c7fcf ("accel/kvm/kvm-all: Handle register access errors") - Signed-off-by: Michael Roth - Acked-by: Paolo Bonzini - Signed-off-by: Stefan Hajnoczi - Message-ID: <20231206155821.1194551-1-michael.roth@amd.com> - - Signed-off-by: Zhongrui Tang ---- - target/i386/kvm/kvm.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 55ee75e844..54e48530ad 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -3420,6 +3420,10 @@ static int kvm_get_sregs(X86CPU *cpu) - env->cr[4] = sregs.cr4; - - env->efer = sregs.efer; -+ if (sev_es_enabled() && env->efer & MSR_EFER_LME && -+ env->cr[0] & CR0_PG_MASK) { -+ env->efer |= MSR_EFER_LMA; -+ } - - /* changes to apic base and cr8/tpr are read back via kvm_arch_post_run */ - x86_update_hflags(env); --- -2.27.0 - diff --git a/i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch b/i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch deleted file mode 100644 index f207f407048f49c972b8bf75548b081b567395a2..0000000000000000000000000000000000000000 --- a/i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 3c283ea7ca1902b9d221897fd65c5edb1d16e004 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Fri, 11 Feb 2022 20:33:47 +0800 -Subject: [PATCH] i6300esb watchdog: bugfix: Add a runstate transition - -QEMU will abort() for the reasons now: - - invalid runstate transition: 'prelaunch' -> 'postmigrate' - Aborted - -This happens when: - |<- watchdog timeout happened, then sets reset_requested to - | SHUTDOWN_CAUSE_GUEST_RESET; - |<- hot-migration thread sets vm state to RUN_STATE_FINISH_MIGRATE - | before the last time of migration; - |<- main thread gets the change of reset_requested and triggers - | reset, then sets vm state to RUN_STATE_PRELAUNCH; - |<- hot-migration thread sets vm state to RUN_STATE_POSTMIGRATE. - -Then 'prelaunch' -> 'postmigrate' runstate transition will happen. -It is legal so add this transition to runstate_transitions_def. - -Signed-off-by: Jinhua Cao ---- - softmmu/runstate.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/softmmu/runstate.c b/softmmu/runstate.c -index 5736d908db..680994cdf8 100644 ---- a/softmmu/runstate.c -+++ b/softmmu/runstate.c -@@ -115,6 +115,7 @@ static const RunStateTransition runstate_transitions_def[] = { - { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, - { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE }, - { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE }, -+ { RUN_STATE_PRELAUNCH, RUN_STATE_POSTMIGRATE }, - - { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING }, - { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED }, --- -2.27.0 - diff --git a/ide-Increment-BB-in-flight-counter-for-TRIM-BH.patch b/ide-Increment-BB-in-flight-counter-for-TRIM-BH.patch deleted file mode 100644 index 9b551dc45668660ba0aed49220acca7f415901f0..0000000000000000000000000000000000000000 --- a/ide-Increment-BB-in-flight-counter-for-TRIM-BH.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 31ae365f6c13d1bdad9d4eefe6e9f00928e5dd64 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 26 Jul 2023 02:50:59 +0000 -Subject: [PATCH] ide: Increment BB in-flight counter for TRIM BH mainline - inclusion commit 7e5cdb345f77d76cb4877fe6230c4e17a7d0d0ca category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -When we still have an AIOCB registered for DMA operations, we try to -settle the respective operation by draining the BlockBackend associated -with the IDE device. - -However, this assumes that every DMA operation is associated with an -increment of the BlockBackend’s in-flight counter (e.g. through some -ongoing I/O operation), so that draining the BB until its in-flight -counter reaches 0 will settle all DMA operations. That is not the case: -For TRIM, the guest can issue a zero-length operation that will not -result in any I/O operation forwarded to the BlockBackend, and also not -increment the in-flight counter in any other way. In such a case, -blk_drain() will be a no-op if no other operations are in flight. - -It is clear that if blk_drain() is a no-op, the value of -s->bus->dma->aiocb will not change between checking it in the `if` -condition and asserting that it is NULL after blk_drain(). - -The particular problem is that ide_issue_trim() creates a BH -(ide_trim_bh_cb()) to settle the TRIM request: iocb->common.cb() is -ide_dma_cb(), which will either create a new request, or find the -transfer to be done and call ide_set_inactive(), which clears -s->bus->dma->aiocb. Therefore, the blk_drain() must wait for -ide_trim_bh_cb() to run, which currently it will not always do. - -To fix this issue, we increment the BlockBackend's in-flight counter -when the TRIM operation begins (in ide_issue_trim(), when the -ide_trim_bh_cb() BH is created) and decrement it when ide_trim_bh_cb() -is done. - -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2029980 -Suggested-by: Paolo Bonzini -Signed-off-by: Hanna Reitz -Message-Id: <20220120142259.120189-1-hreitz@redhat.com> -Reviewed-by: Paolo Bonzini -Reviewed-by: John Snow -Tested-by: John Snow - -Signed-off-by: tangbinzy ---- - hw/ide/core.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/hw/ide/core.c b/hw/ide/core.c -index e28f8aad61..15138225be 100644 ---- a/hw/ide/core.c -+++ b/hw/ide/core.c -@@ -433,12 +433,16 @@ static const AIOCBInfo trim_aiocb_info = { - static void ide_trim_bh_cb(void *opaque) - { - TrimAIOCB *iocb = opaque; -+ BlockBackend *blk = iocb->s->blk; - - iocb->common.cb(iocb->common.opaque, iocb->ret); - - qemu_bh_delete(iocb->bh); - iocb->bh = NULL; - qemu_aio_unref(iocb); -+ -+ /* Paired with an increment in ide_issue_trim() */ -+ blk_dec_in_flight(blk); - } - - static void ide_issue_trim_cb(void *opaque, int ret) -@@ -508,6 +512,9 @@ BlockAIOCB *ide_issue_trim( - IDEState *s = opaque; - TrimAIOCB *iocb; - -+ /* Paired with a decrement in ide_trim_bh_cb() */ -+ blk_inc_in_flight(s->blk); -+ - iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque); - iocb->s = s; - iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb); --- -2.41.0.windows.1 - diff --git a/ide-ahci-add-check-to-avoid-null-dereference-CVE-201.patch b/ide-ahci-add-check-to-avoid-null-dereference-CVE-201.patch deleted file mode 100644 index 7cd2ccff36dc717b01363728e5d48f6be9661e0e..0000000000000000000000000000000000000000 --- a/ide-ahci-add-check-to-avoid-null-dereference-CVE-201.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 9169beed83ea77059a7240aae5621dcfb3178cba Mon Sep 17 00:00:00 2001 -From: Prasad J Pandit -Date: Mon, 21 Jun 2021 09:22:35 +0800 -Subject: [PATCH] ide: ahci: add check to avoid null dereference - (CVE-2019-12067) - -Fix CVE-2019-12067 - -AHCI emulator while committing DMA buffer in ahci_commit_buf() -may do a NULL dereference if the command header 'ad->cur_cmd' -is null. Add check to avoid it. - -Reported-by: Bugs SysSec -Signed-off-by: Prasad J Pandit - -Signed-off-by: Jiajie Li -Signed-off-by: Yan Wang ---- - hw/ide/ahci.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c -index a94c6e26fb..256b58026a 100644 ---- a/hw/ide/ahci.c -+++ b/hw/ide/ahci.c -@@ -1459,8 +1459,10 @@ static void ahci_commit_buf(const IDEDMA *dma, uint32_t tx_bytes) - { - AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); - -- tx_bytes += le32_to_cpu(ad->cur_cmd->status); -- ad->cur_cmd->status = cpu_to_le32(tx_bytes); -+ if (ad->cur_cmd) { -+ tx_bytes += le32_to_cpu(ad->cur_cmd->status); -+ ad->cur_cmd->status = cpu_to_le32(tx_bytes); -+ } - } - - static int ahci_dma_rw_buf(const IDEDMA *dma, bool is_write) --- -2.27.0 - diff --git a/include-hw-start-documenting-the-vhost-API.patch b/include-hw-start-documenting-the-vhost-API.patch deleted file mode 100644 index f53f07c16a49f4984360332dd0d01249ebc02fb3..0000000000000000000000000000000000000000 --- a/include-hw-start-documenting-the-vhost-API.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 6e43246f43753030a247c23cd6082792a588817b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alex=20Benn=C3=A9e?= -Date: Mon, 21 Mar 2022 15:30:34 +0000 -Subject: [PATCH] include/hw: start documenting the vhost API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -While trying to get my head around the nest of interactions for vhost -devices I though I could start by documenting the key API functions. -This patch documents the main API hooks for creating and starting a -vhost device as well as how the configuration changes are handled. - -Signed-off-by: Alex Bennée -Cc: Michael S. Tsirkin -Cc: Stefan Hajnoczi -Cc: Marc-André Lureau -Message-Id: <20220321153037.3622127-11-alex.bennee@linaro.org> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - include/hw/virtio/vhost.h | 132 +++++++++++++++++++++++++++++++++++--- - 1 file changed, 122 insertions(+), 10 deletions(-) - -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index 86f36f0106..d7ab2579ff 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -61,6 +61,12 @@ typedef struct VhostDevConfigOps { - } VhostDevConfigOps; - - struct vhost_memory; -+ -+/** -+ * struct vhost_dev - common vhost_dev structure -+ * @vhost_ops: backend specific ops -+ * @config_ops: ops for config changes (see @vhost_dev_set_config_notifier) -+ */ - struct vhost_dev { - VirtIODevice *vdev; - MemoryListener memory_listener; -@@ -108,15 +114,129 @@ struct vhost_net { - NetClientState *nc; - }; - -+/** -+ * vhost_dev_init() - initialise the vhost interface -+ * @hdev: the common vhost_dev structure -+ * @opaque: opaque ptr passed to backend (vhost/vhost-user/vdpa) -+ * @backend_type: type of backend -+ * @busyloop_timeout: timeout for polling virtqueue -+ * @errp: error handle -+ * -+ * The initialisation of the vhost device will trigger the -+ * initialisation of the backend and potentially capability -+ * negotiation of backend interface. Configuration of the VirtIO -+ * itself won't happen until the interface is started. -+ * -+ * Return: 0 on success, non-zero on error while setting errp. -+ */ - int vhost_dev_init(struct vhost_dev *hdev, void *opaque, - VhostBackendType backend_type, - uint32_t busyloop_timeout, Error **errp); -+ -+/** -+ * vhost_dev_cleanup() - tear down and cleanup vhost interface -+ * @hdev: the common vhost_dev structure -+ */ - void vhost_dev_cleanup(struct vhost_dev *hdev); --int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); --void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); -+ -+/** -+ * vhost_dev_enable_notifiers() - enable event notifiers -+ * @hdev: common vhost_dev structure -+ * @vdev: the VirtIODevice structure -+ * -+ * Enable notifications directly to the vhost device rather than being -+ * triggered by QEMU itself. Notifications should be enabled before -+ * the vhost device is started via @vhost_dev_start. -+ * -+ * Return: 0 on success, < 0 on error. -+ */ - int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); -+ -+/** -+ * vhost_dev_disable_notifiers - disable event notifications -+ * @hdev: common vhost_dev structure -+ * @vdev: the VirtIODevice structure -+ * -+ * Disable direct notifications to vhost device. -+ */ - void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); - -+/** -+ * vhost_dev_start() - start the vhost device -+ * @hdev: common vhost_dev structure -+ * @vdev: the VirtIODevice structure -+ * -+ * Starts the vhost device. From this point VirtIO feature negotiation -+ * can start and the device can start processing VirtIO transactions. -+ * -+ * Return: 0 on success, < 0 on error. -+ */ -+int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); -+ -+/** -+ * vhost_dev_stop() - stop the vhost device -+ * @hdev: common vhost_dev structure -+ * @vdev: the VirtIODevice structure -+ * -+ * Stop the vhost device. After the device is stopped the notifiers -+ * can be disabled (@vhost_dev_disable_notifiers) and the device can -+ * be torn down (@vhost_dev_cleanup). -+ */ -+void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); -+ -+/** -+ * DOC: vhost device configuration handling -+ * -+ * The VirtIO device configuration space is used for rarely changing -+ * or initialisation time parameters. The configuration can be updated -+ * by either the guest driver or the device itself. If the device can -+ * change the configuration over time the vhost handler should -+ * register a @VhostDevConfigOps structure with -+ * @vhost_dev_set_config_notifier so the guest can be notified. Some -+ * devices register a handler anyway and will signal an error if an -+ * unexpected config change happens. -+ */ -+ -+/** -+ * vhost_dev_get_config() - fetch device configuration -+ * @hdev: common vhost_dev_structure -+ * @config: pointer to device appropriate config structure -+ * @config_len: size of device appropriate config structure -+ * -+ * Return: 0 on success, < 0 on error while setting errp -+ */ -+int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config, -+ uint32_t config_len, Error **errp); -+ -+/** -+ * vhost_dev_set_config() - set device configuration -+ * @hdev: common vhost_dev_structure -+ * @data: pointer to data to set -+ * @offset: offset into configuration space -+ * @size: length of set -+ * @flags: @VhostSetConfigType flags -+ * -+ * By use of @offset/@size a subset of the configuration space can be -+ * written to. The @flags are used to indicate if it is a normal -+ * transaction or related to migration. -+ * -+ * Return: 0 on success, non-zero on error -+ */ -+int vhost_dev_set_config(struct vhost_dev *dev, const uint8_t *data, -+ uint32_t offset, uint32_t size, uint32_t flags); -+ -+/** -+ * vhost_dev_set_config_notifier() - register VhostDevConfigOps -+ * @hdev: common vhost_dev_structure -+ * @ops: notifier ops -+ * -+ * If the device is expected to change configuration a notifier can be -+ * setup to handle the case. -+ */ -+void vhost_dev_set_config_notifier(struct vhost_dev *dev, -+ const VhostDevConfigOps *ops); -+ -+ - /* Test and clear masked event pending status. - * Should be called after unmask to avoid losing events. - */ -@@ -136,14 +256,6 @@ int vhost_net_set_backend(struct vhost_dev *hdev, - struct vhost_vring_file *file); - - int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write); --int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config, -- uint32_t config_len, Error **errp); --int vhost_dev_set_config(struct vhost_dev *dev, const uint8_t *data, -- uint32_t offset, uint32_t size, uint32_t flags); --/* notifier callback in case vhost device config space changed -- */ --void vhost_dev_set_config_notifier(struct vhost_dev *dev, -- const VhostDevConfigOps *ops); - - void vhost_dev_reset_inflight(struct vhost_inflight *inflight); - void vhost_dev_free_inflight(struct vhost_inflight *inflight); --- -2.27.0 - diff --git a/intc-gicv3-Add-pre-sizing-capability-to-GICv3.patch b/intc-gicv3-Add-pre-sizing-capability-to-GICv3.patch deleted file mode 100644 index a68cdcbeecbc625c0313bc0bcf2b206eea5c8c17..0000000000000000000000000000000000000000 --- a/intc-gicv3-Add-pre-sizing-capability-to-GICv3.patch +++ /dev/null @@ -1,358 +0,0 @@ -From 3ed7dcc4a8ccf443d125e7908d8293b562c68d4b Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 13:15:35 +0800 -Subject: [PATCH] intc/gicv3: Add pre-sizing capability to GICv3 - -Currently GICv3 supports fixed smp_cpus CPUs, and all CPUs are -present always. Now we want to pre-sizing GICv3 to support max_cpus -CPUs and not all of them are present always, so some sizing codes -should be concerned. - -GIC irqs, GICR and GICC are pre-created for all possible CPUs at -start, but only smp_cpus CPUs are realize and irqs of smp_cpus CPUs -are connected. - -Other code changes are mainly for arm_gicv3, and we do little about -kvm_arm_gicv3 becasue KVM will deal with the sizing information properly. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/arm/virt.c | 17 +++++++++++---- - hw/intc/arm_gicv3.c | 43 +++++++++++++++++++++++++------------- - hw/intc/arm_gicv3_common.c | 22 +++++++++++++++++-- - hw/intc/arm_gicv3_cpuif.c | 4 ++++ - hw/intc/arm_gicv3_kvm.c | 28 ++++++++++++++++++++++++- - include/hw/arm/virt.h | 3 ++- - 6 files changed, 95 insertions(+), 22 deletions(-) - -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 0af0a996a1..b1224fb1e4 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -827,14 +827,19 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem) - SysBusDevice *gicbusdev; - const char *gictype; - int type = vms->gic_version, i; -+ /* The max number of CPUs suppored by GIC */ -+ unsigned int num_cpus = ms->smp.cpus; -+ /* The number of CPUs present before boot */ - unsigned int smp_cpus = ms->smp.cpus; - uint32_t nb_redist_regions = 0; - -+ assert(num_cpus >= smp_cpus); -+ - gictype = (type == 3) ? gicv3_class_name() : gic_class_name(); - - vms->gic = qdev_new(gictype); - qdev_prop_set_uint32(vms->gic, "revision", type); -- qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus); -+ qdev_prop_set_uint32(vms->gic, "num-cpu", num_cpus); - /* Note that the num-irq property counts both internal and external - * interrupts; there are always 32 of the former (mandated by GIC spec). - */ -@@ -846,7 +851,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem) - if (type == 3) { - uint32_t redist0_capacity = - vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE; -- uint32_t redist0_count = MIN(smp_cpus, redist0_capacity); -+ uint32_t redist0_count = MIN(num_cpus, redist0_capacity); - - nb_redist_regions = virt_gicv3_redist_region_count(vms); - -@@ -867,7 +872,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem) - vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE; - - qdev_prop_set_uint32(vms->gic, "redist-region-count[1]", -- MIN(smp_cpus - redist0_count, redist1_capacity)); -+ MIN(num_cpus - redist0_count, redist1_capacity)); - } - } else { - if (!kvm_irqchip_in_kernel()) { -@@ -894,7 +899,11 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem) - - /* Wire the outputs from each CPU's generic timer and the GICv3 - * maintenance interrupt signal to the appropriate GIC PPI inputs, -- * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs. -+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's -+ * inputs. -+ * -+ * The irqs of remaining CPUs (if we has) will be connected during -+ * hotplugging. - */ - for (i = 0; i < smp_cpus; i++) { - connect_gic_cpu_irqs(vms, i); -diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c -index 9591cfbcc0..864d4e4034 100644 ---- a/hw/intc/arm_gicv3.c -+++ b/hw/intc/arm_gicv3.c -@@ -19,6 +19,7 @@ - #include "qapi/error.h" - #include "qemu/module.h" - #include "hw/intc/arm_gicv3.h" -+#include "hw/core/cpu.h" - #include "gicv3_internal.h" - - static bool irqbetter(GICv3CPUState *cs, int irq, uint8_t prio) -@@ -217,7 +218,9 @@ static void gicv3_update_noirqset(GICv3State *s, int start, int len) - assert(len > 0); - - for (i = 0; i < s->num_cpu; i++) { -- s->cpu[i].seenbetter = false; -+ if (qemu_get_cpu(i)) { -+ s->cpu[i].seenbetter = false; -+ } - } - - /* Find the highest priority pending interrupt in this range. */ -@@ -259,16 +262,18 @@ static void gicv3_update_noirqset(GICv3State *s, int start, int len) - * now be the new best one). - */ - for (i = 0; i < s->num_cpu; i++) { -- GICv3CPUState *cs = &s->cpu[i]; -+ if (qemu_get_cpu(i)) { -+ GICv3CPUState *cs = &s->cpu[i]; - -- if (cs->seenbetter) { -- cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq); -- } -+ if (cs->seenbetter) { -+ cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq); -+ } - -- if (!cs->seenbetter && cs->hppi.prio != 0xff && -- cs->hppi.irq >= start && cs->hppi.irq < start + len) { -- gicv3_full_update_noirqset(s); -- break; -+ if (!cs->seenbetter && cs->hppi.prio != 0xff && -+ cs->hppi.irq >= start && cs->hppi.irq < start + len) { -+ gicv3_full_update_noirqset(s); -+ break; -+ } - } - } - } -@@ -279,7 +284,9 @@ void gicv3_update(GICv3State *s, int start, int len) - - gicv3_update_noirqset(s, start, len); - for (i = 0; i < s->num_cpu; i++) { -- gicv3_cpuif_update(&s->cpu[i]); -+ if (qemu_get_cpu(i)) { -+ gicv3_cpuif_update(&s->cpu[i]); -+ } - } - } - -@@ -291,7 +298,9 @@ void gicv3_full_update_noirqset(GICv3State *s) - int i; - - for (i = 0; i < s->num_cpu; i++) { -- s->cpu[i].hppi.prio = 0xff; -+ if (qemu_get_cpu(i)) { -+ s->cpu[i].hppi.prio = 0xff; -+ } - } - - /* Note that we can guarantee that these functions will not -@@ -302,7 +311,9 @@ void gicv3_full_update_noirqset(GICv3State *s) - gicv3_update_noirqset(s, GIC_INTERNAL, s->num_irq - GIC_INTERNAL); - - for (i = 0; i < s->num_cpu; i++) { -- gicv3_redist_update_noirqset(&s->cpu[i]); -+ if (qemu_get_cpu(i)) { -+ gicv3_redist_update_noirqset(&s->cpu[i]); -+ } - } - } - -@@ -315,7 +326,9 @@ void gicv3_full_update(GICv3State *s) - - gicv3_full_update_noirqset(s); - for (i = 0; i < s->num_cpu; i++) { -- gicv3_cpuif_update(&s->cpu[i]); -+ if (qemu_get_cpu(i)) { -+ gicv3_cpuif_update(&s->cpu[i]); -+ } - } - } - -@@ -406,7 +419,9 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) - gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops); - - for (i = 0; i < s->num_cpu; i++) { -- gicv3_cpu_realize(s, i); -+ if (qemu_get_cpu(i)) { -+ gicv3_cpu_realize(s, i); -+ } - } - } - -diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c -index f8ef6817a4..a4976b2ba0 100644 ---- a/hw/intc/arm_gicv3_common.c -+++ b/hw/intc/arm_gicv3_common.c -@@ -24,12 +24,14 @@ - #include "qemu/osdep.h" - #include "qapi/error.h" - #include "qemu/module.h" -+#include "qemu/error-report.h" - #include "hw/core/cpu.h" - #include "hw/intc/arm_gicv3_common.h" - #include "hw/qdev-properties.h" - #include "migration/vmstate.h" - #include "gicv3_internal.h" - #include "hw/arm/linux-boot-if.h" -+#include "hw/boards.h" - #include "sysemu/kvm.h" - - -@@ -377,9 +379,14 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) - for (i = 0; i < s->num_cpu; i++) { - CPUState *cpu = qemu_get_cpu(i); - -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ MachineClass *mc = MACHINE_GET_CLASS(ms); -+ const CPUArchIdList *possible_cpus = NULL; - uint64_t cpu_affid; - -- arm_gicv3_common_cpu_realize(s, i); -+ if (cpu) { -+ arm_gicv3_common_cpu_realize(s, i); -+ } - - /* Pre-construct the GICR_TYPER: - * For our implementation: -@@ -393,7 +400,18 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) - * VLPIS == 0 (virtual LPIs not supported) - * PLPIS == 0 (physical LPIs not supported) - */ -- cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL); -+ if (cpu) { -+ cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL); -+ } else { -+ if (!mc->possible_cpu_arch_ids) { -+ error_report("MachineClass must implement possible_cpu_arch_ids " -+ "hook to support pre-sizing GICv3"); -+ exit(1); -+ } -+ -+ possible_cpus = mc->possible_cpu_arch_ids(ms); -+ cpu_affid = possible_cpus->cpus[i].arch_id; -+ } - - /* The CPU mp-affinity property is in MPIDR register format; squash - * the affinity bytes into 32 bits as the GICR_TYPER has them. -diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c -index 70809bcddd..274a40a40c 100644 ---- a/hw/intc/arm_gicv3_cpuif.c -+++ b/hw/intc/arm_gicv3_cpuif.c -@@ -1676,6 +1676,10 @@ static void icc_generate_sgi(CPUARMState *env, GICv3CPUState *cs, - aff, targetlist); - - for (i = 0; i < s->num_cpu; i++) { -+ if (!qemu_get_cpu(i)) { -+ continue; -+ } -+ - GICv3CPUState *ocs = &s->cpu[i]; - - if (irm) { -diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c -index 95271e754b..2e2b08e31f 100644 ---- a/hw/intc/arm_gicv3_kvm.c -+++ b/hw/intc/arm_gicv3_kvm.c -@@ -342,6 +342,10 @@ static void kvm_arm_gicv3_put(GICv3State *s) - for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { - GICv3CPUState *c = &s->cpu[ncpu]; - -+ if (!qemu_get_cpu(ncpu)) { -+ continue; -+ } -+ - reg64 = c->gicr_propbaser; - regl = (uint32_t)reg64; - kvm_gicr_access(s, GICR_PROPBASER, ncpu, ®l, true); -@@ -361,6 +365,10 @@ static void kvm_arm_gicv3_put(GICv3State *s) - for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { - GICv3CPUState *c = &s->cpu[ncpu]; - -+ if (!qemu_get_cpu(ncpu)) { -+ continue; -+ } -+ - reg = c->gicr_ctlr; - kvm_gicr_access(s, GICR_CTLR, ncpu, ®, true); - -@@ -457,6 +465,10 @@ static void kvm_arm_gicv3_put(GICv3State *s) - GICv3CPUState *c = &s->cpu[ncpu]; - int num_pri_bits; - -+ if (!qemu_get_cpu(ncpu)) { -+ continue; -+ } -+ - kvm_gicc_access(s, ICC_SRE_EL1, ncpu, &c->icc_sre_el1, true); - kvm_gicc_access(s, ICC_CTLR_EL1, ncpu, - &c->icc_ctlr_el1[GICV3_NS], true); -@@ -524,6 +536,10 @@ static void kvm_arm_gicv3_get(GICv3State *s) - /* Redistributor state (one per CPU) */ - - for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { -+ if (!qemu_get_cpu(ncpu)) { -+ continue; -+ } -+ - GICv3CPUState *c = &s->cpu[ncpu]; - - kvm_gicr_access(s, GICR_CTLR, ncpu, ®, false); -@@ -559,6 +575,10 @@ static void kvm_arm_gicv3_get(GICv3State *s) - - if (redist_typer & GICR_TYPER_PLPIS) { - for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { -+ if (!qemu_get_cpu(ncpu)) { -+ continue; -+ } -+ - GICv3CPUState *c = &s->cpu[ncpu]; - - kvm_gicr_access(s, GICR_PROPBASER, ncpu, ®l, false); -@@ -612,6 +632,10 @@ static void kvm_arm_gicv3_get(GICv3State *s) - */ - - for (ncpu = 0; ncpu < s->num_cpu; ncpu++) { -+ if (!qemu_get_cpu(ncpu)) { -+ continue; -+ } -+ - GICv3CPUState *c = &s->cpu[ncpu]; - int num_pri_bits; - -@@ -805,7 +829,9 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) - gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL); - - for (i = 0; i < s->num_cpu; i++) { -- kvm_arm_gicv3_cpu_realize(s, i); -+ if (qemu_get_cpu(i)) { -+ kvm_arm_gicv3_cpu_realize(s, i); -+ } - } - - /* Try to create the device via the device control API */ -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index 2a838620d8..947d41f767 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -196,8 +196,9 @@ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms) - vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE; - - assert(vms->gic_version == VIRT_GIC_VERSION_3); -+ GICv3State *s = ARM_GICV3_COMMON(vms->gic); - -- return MACHINE(vms)->smp.cpus > redist0_capacity ? 2 : 1; -+ return s->num_cpu > redist0_capacity ? 2 : 1; - } - - #endif /* QEMU_ARM_VIRT_H */ --- -2.27.0 - diff --git a/intc-gicv3_common-Factor-out-arm_gicv3_common_cpu_re.patch b/intc-gicv3_common-Factor-out-arm_gicv3_common_cpu_re.patch deleted file mode 100644 index 043573e8e69b51928402404d6bbc5fd8dd577e7d..0000000000000000000000000000000000000000 --- a/intc-gicv3_common-Factor-out-arm_gicv3_common_cpu_re.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 06cb0756a01796352861b4d47d59db1bde84ec6f Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 12:55:17 +0800 -Subject: [PATCH] intc/gicv3_common: Factor out arm_gicv3_common_cpu_realize - -The CPU object of hotplugged CPU will be defer-created (during -hotplug session), so we must factor out realization code to let -it can be applied to individual CPU. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/intc/arm_gicv3_common.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - -diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c -index 9884d2e39b..1a11d1986d 100644 ---- a/hw/intc/arm_gicv3_common.c -+++ b/hw/intc/arm_gicv3_common.c -@@ -301,6 +301,16 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler, - } - } - -+static void arm_gicv3_common_cpu_realize(GICv3State *s, int ncpu) -+{ -+ CPUState *cpu = qemu_get_cpu(ncpu); -+ -+ s->cpu[ncpu].cpu = cpu; -+ s->cpu[ncpu].gic = s; -+ /* Store GICv3CPUState in CPUARMState gicv3state pointer */ -+ gicv3_set_gicv3state(cpu, &s->cpu[ncpu]); -+} -+ - static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) - { - GICv3State *s = ARM_GICV3_COMMON(dev); -@@ -363,10 +373,7 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) - CPUState *cpu = qemu_get_cpu(i); - uint64_t cpu_affid; - -- s->cpu[i].cpu = cpu; -- s->cpu[i].gic = s; -- /* Store GICv3CPUState in CPUARMState gicv3state pointer */ -- gicv3_set_gicv3state(cpu, &s->cpu[i]); -+ arm_gicv3_common_cpu_realize(s, i); - - /* Pre-construct the GICR_TYPER: - * For our implementation: --- -2.27.0 - diff --git a/intc-gicv3_cpuif-Factor-out-gicv3_init_one_cpuif.patch b/intc-gicv3_cpuif-Factor-out-gicv3_init_one_cpuif.patch deleted file mode 100644 index 87c93443458f9c763eae9dfc0b0406f27a9b205e..0000000000000000000000000000000000000000 --- a/intc-gicv3_cpuif-Factor-out-gicv3_init_one_cpuif.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 62b5c897e367c3db477a680b7557662347677433 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 10:59:55 +0800 -Subject: [PATCH] intc/gicv3_cpuif: Factor out gicv3_init_one_cpuif - -The CPU object of hotplugged CPU will be defer-created (during -hotplug session), so we must factor out some code to let it can -be applied to individual CPU. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/intc/arm_gicv3.c | 5 +- - hw/intc/arm_gicv3_cpuif.c | 122 ++++++++++++++++++-------------------- - hw/intc/gicv3_internal.h | 2 +- - 3 files changed, 64 insertions(+), 65 deletions(-) - -diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c -index 9f5f815db9..40016cb84a 100644 ---- a/hw/intc/arm_gicv3.c -+++ b/hw/intc/arm_gicv3.c -@@ -382,6 +382,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) - GICv3State *s = ARM_GICV3(dev); - ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s); - Error *local_err = NULL; -+ int i; - - agc->parent_realize(dev, &local_err); - if (local_err) { -@@ -391,7 +392,9 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) - - gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops); - -- gicv3_init_cpuif(s); -+ for (i = 0; i < s->num_cpu; i++) { -+ gicv3_init_one_cpuif(s, i); -+ } - } - - static void arm_gicv3_class_init(ObjectClass *klass, void *data) -diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c -index 85fc369e55..70809bcddd 100644 ---- a/hw/intc/arm_gicv3_cpuif.c -+++ b/hw/intc/arm_gicv3_cpuif.c -@@ -2625,76 +2625,72 @@ static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque) - gicv3_cpuif_update(cs); - } - --void gicv3_init_cpuif(GICv3State *s) -+void gicv3_init_one_cpuif(GICv3State *s, int ncpu) - { - /* Called from the GICv3 realize function; register our system - * registers with the CPU - */ -- int i; -- -- for (i = 0; i < s->num_cpu; i++) { -- ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i)); -- GICv3CPUState *cs = &s->cpu[i]; -- -- /* Note that we can't just use the GICv3CPUState as an opaque pointer -- * in define_arm_cp_regs_with_opaque(), because when we're called back -- * it might be with code translated by CPU 0 but run by CPU 1, in -- * which case we'd get the wrong value. -- * So instead we define the regs with no ri->opaque info, and -- * get back to the GICv3CPUState from the CPUARMState. -+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(ncpu)); -+ GICv3CPUState *cs = &s->cpu[ncpu]; -+ -+ /* Note that we can't just use the GICv3CPUState as an opaque pointer -+ * in define_arm_cp_regs_with_opaque(), because when we're called back -+ * it might be with code translated by CPU 0 but run by CPU 1, in -+ * which case we'd get the wrong value. -+ * So instead we define the regs with no ri->opaque info, and -+ * get back to the GICv3CPUState from the CPUARMState. -+ */ -+ define_arm_cp_regs(cpu, gicv3_cpuif_reginfo); -+ if (arm_feature(&cpu->env, ARM_FEATURE_EL2) -+ && cpu->gic_num_lrs) { -+ int j; -+ -+ cs->num_list_regs = cpu->gic_num_lrs; -+ cs->vpribits = cpu->gic_vpribits; -+ cs->vprebits = cpu->gic_vprebits; -+ -+ /* Check against architectural constraints: getting these -+ * wrong would be a bug in the CPU code defining these, -+ * and the implementation relies on them holding. - */ -- define_arm_cp_regs(cpu, gicv3_cpuif_reginfo); -- if (arm_feature(&cpu->env, ARM_FEATURE_EL2) -- && cpu->gic_num_lrs) { -- int j; -- -- cs->num_list_regs = cpu->gic_num_lrs; -- cs->vpribits = cpu->gic_vpribits; -- cs->vprebits = cpu->gic_vprebits; -- -- /* Check against architectural constraints: getting these -- * wrong would be a bug in the CPU code defining these, -- * and the implementation relies on them holding. -- */ -- g_assert(cs->vprebits <= cs->vpribits); -- g_assert(cs->vprebits >= 5 && cs->vprebits <= 7); -- g_assert(cs->vpribits >= 5 && cs->vpribits <= 8); -+ g_assert(cs->vprebits <= cs->vpribits); -+ g_assert(cs->vprebits >= 5 && cs->vprebits <= 7); -+ g_assert(cs->vpribits >= 5 && cs->vpribits <= 8); - -- define_arm_cp_regs(cpu, gicv3_cpuif_hcr_reginfo); -+ define_arm_cp_regs(cpu, gicv3_cpuif_hcr_reginfo); - -- for (j = 0; j < cs->num_list_regs; j++) { -- /* Note that the AArch64 LRs are 64-bit; the AArch32 LRs -- * are split into two cp15 regs, LR (the low part, with the -- * same encoding as the AArch64 LR) and LRC (the high part). -- */ -- ARMCPRegInfo lr_regset[] = { -- { .name = "ICH_LRn_EL2", .state = ARM_CP_STATE_BOTH, -- .opc0 = 3, .opc1 = 4, .crn = 12, -- .crm = 12 + (j >> 3), .opc2 = j & 7, -- .type = ARM_CP_IO | ARM_CP_NO_RAW, -- .access = PL2_RW, -- .readfn = ich_lr_read, -- .writefn = ich_lr_write, -- }, -- { .name = "ICH_LRCn_EL2", .state = ARM_CP_STATE_AA32, -- .cp = 15, .opc1 = 4, .crn = 12, -- .crm = 14 + (j >> 3), .opc2 = j & 7, -- .type = ARM_CP_IO | ARM_CP_NO_RAW, -- .access = PL2_RW, -- .readfn = ich_lr_read, -- .writefn = ich_lr_write, -- }, -- REGINFO_SENTINEL -- }; -- define_arm_cp_regs(cpu, lr_regset); -- } -- if (cs->vprebits >= 6) { -- define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr1_reginfo); -- } -- if (cs->vprebits == 7) { -- define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo); -- } -+ for (j = 0; j < cs->num_list_regs; j++) { -+ /* Note that the AArch64 LRs are 64-bit; the AArch32 LRs -+ * are split into two cp15 regs, LR (the low part, with the -+ * same encoding as the AArch64 LR) and LRC (the high part). -+ */ -+ ARMCPRegInfo lr_regset[] = { -+ { .name = "ICH_LRn_EL2", .state = ARM_CP_STATE_BOTH, -+ .opc0 = 3, .opc1 = 4, .crn = 12, -+ .crm = 12 + (j >> 3), .opc2 = j & 7, -+ .type = ARM_CP_IO | ARM_CP_NO_RAW, -+ .access = PL2_RW, -+ .readfn = ich_lr_read, -+ .writefn = ich_lr_write, -+ }, -+ { .name = "ICH_LRCn_EL2", .state = ARM_CP_STATE_AA32, -+ .cp = 15, .opc1 = 4, .crn = 12, -+ .crm = 14 + (j >> 3), .opc2 = j & 7, -+ .type = ARM_CP_IO | ARM_CP_NO_RAW, -+ .access = PL2_RW, -+ .readfn = ich_lr_read, -+ .writefn = ich_lr_write, -+ }, -+ REGINFO_SENTINEL -+ }; -+ define_arm_cp_regs(cpu, lr_regset); -+ } -+ if (cs->vprebits >= 6) { -+ define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr1_reginfo); -+ } -+ if (cs->vprebits == 7) { -+ define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo); - } -- arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs); - } -+ arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs); - } -diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h -index b9c37453b0..65db012600 100644 ---- a/hw/intc/gicv3_internal.h -+++ b/hw/intc/gicv3_internal.h -@@ -495,7 +495,7 @@ void gicv3_redist_update_lpi(GICv3CPUState *cs); - */ - void gicv3_redist_update_lpi_only(GICv3CPUState *cs); - void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns); --void gicv3_init_cpuif(GICv3State *s); -+void gicv3_init_one_cpuif(GICv3State *s, int ncpu); - - /** - * gicv3_cpuif_update: --- -2.27.0 - diff --git a/intc-kvm_gicv3-Factor-out-kvm_arm_gicv3_cpu_realize.patch b/intc-kvm_gicv3-Factor-out-kvm_arm_gicv3_cpu_realize.patch deleted file mode 100644 index f9f4b940cc5efc5bb52f9be0f4b4e72c57e31769..0000000000000000000000000000000000000000 --- a/intc-kvm_gicv3-Factor-out-kvm_arm_gicv3_cpu_realize.patch +++ /dev/null @@ -1,46 +0,0 @@ -From dd03bc60712bd41a9606742ea4b769aa8e360655 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 10 Apr 2020 12:49:12 +0800 -Subject: [PATCH] intc/kvm_gicv3: Factor out kvm_arm_gicv3_cpu_realize - -The CPU object of hotplugged CPU will be defer-created (during -hotplug session), so we must factor out realization code to let -it can be applied to individual CPU. - -Signed-off-by: Keqian Zhu -Signed-off-by: Salil Mehta ---- - hw/intc/arm_gicv3_kvm.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c -index 5ec5ff9ef6..596b31998b 100644 ---- a/hw/intc/arm_gicv3_kvm.c -+++ b/hw/intc/arm_gicv3_kvm.c -@@ -764,6 +764,12 @@ static void vm_change_state_handler(void *opaque, bool running, - } - } - -+static void kvm_arm_gicv3_cpu_realize(GICv3State *s, int ncpu) -+{ -+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(ncpu)); -+ -+ define_arm_cp_regs(cpu, gicv3_cpuif_reginfo); -+} - - static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) - { -@@ -790,9 +796,7 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) - gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL); - - for (i = 0; i < s->num_cpu; i++) { -- ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i)); -- -- define_arm_cp_regs(cpu, gicv3_cpuif_reginfo); -+ kvm_arm_gicv3_cpu_realize(s, i); - } - - /* Try to create the device via the device control API */ --- -2.27.0 - diff --git a/io-remove-io-watch-if-TLS-channel-is-closed-during-h.patch b/io-remove-io-watch-if-TLS-channel-is-closed-during-h.patch deleted file mode 100644 index 73205745000ac9d3aa889999a2dc90fe6e64bc77..0000000000000000000000000000000000000000 --- a/io-remove-io-watch-if-TLS-channel-is-closed-during-h.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 979bb24c769a703c96067c9557d433492916aa67 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= -Date: Tue, 20 Jun 2023 09:45:34 +0100 -Subject: [PATCH] io: remove io watch if TLS channel is closed during handshake -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The TLS handshake make take some time to complete, during which time an -I/O watch might be registered with the main loop. If the owner of the -I/O channel invokes qio_channel_close() while the handshake is waiting -to continue the I/O watch must be removed. Failing to remove it will -later trigger the completion callback which the owner is not expecting -to receive. In the case of the VNC server, this results in a SEGV as -vnc_disconnect_start() tries to shutdown a client connection that is -already gone / NULL. - -CVE-2023-3354 -Reported-by: jiangyegen -Signed-off-by: Daniel P. Berrangé ---- - include/io/channel-tls.h | 1 + - io/channel-tls.c | 18 ++++++++++++------ - 2 files changed, 13 insertions(+), 6 deletions(-) - -diff --git a/include/io/channel-tls.h b/include/io/channel-tls.h -index 5672479e9e..26c67f17e2 100644 ---- a/include/io/channel-tls.h -+++ b/include/io/channel-tls.h -@@ -48,6 +48,7 @@ struct QIOChannelTLS { - QIOChannel *master; - QCryptoTLSSession *session; - QIOChannelShutdown shutdown; -+ guint hs_ioc_tag; - }; - - /** -diff --git a/io/channel-tls.c b/io/channel-tls.c -index 2ae1b92fc0..34476e6b7b 100644 ---- a/io/channel-tls.c -+++ b/io/channel-tls.c -@@ -195,12 +195,13 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc, - } - - trace_qio_channel_tls_handshake_pending(ioc, status); -- qio_channel_add_watch_full(ioc->master, -- condition, -- qio_channel_tls_handshake_io, -- data, -- NULL, -- context); -+ ioc->hs_ioc_tag = -+ qio_channel_add_watch_full(ioc->master, -+ condition, -+ qio_channel_tls_handshake_io, -+ data, -+ NULL, -+ context); - } - } - -@@ -215,6 +216,7 @@ static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc, - QIOChannelTLS *tioc = QIO_CHANNEL_TLS( - qio_task_get_source(task)); - -+ tioc->hs_ioc_tag = 0; - g_free(data); - qio_channel_tls_handshake_task(tioc, task, context); - -@@ -373,6 +375,10 @@ static int qio_channel_tls_close(QIOChannel *ioc, - { - QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); - -+ if (tioc->hs_ioc_tag) { -+ g_clear_handle_id(&tioc->hs_ioc_tag, g_source_remove); -+ } -+ - return qio_channel_close(tioc->master, errp); - } - --- -2.41.0.windows.1 - diff --git a/io_uring-fix-short-read-slow-path.patch b/io_uring-fix-short-read-slow-path.patch deleted file mode 100644 index 9a0722beb2f4a32655549749a363682f286c6126..0000000000000000000000000000000000000000 --- a/io_uring-fix-short-read-slow-path.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 78cb2c9c218155d048e566c5ac6d59961703b5d3 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 21 Nov 2023 06:14:40 +0000 -Subject: [PATCH] io_uring: fix short read slow path mainline inclusion commit - c06fc7ce147e57ab493bad9263f1601b8298484b category: bugfix - ---------------------------------------------------------------- - -sqeq.off here is the offset to read within the disk image, so obviously -not 'nread' (the amount we just read), but as the author meant to write -its current value incremented by the amount we just read. - -Normally recent versions of linux will not issue short reads, -but it can happen so we should fix this. - -This lead to weird image corruptions when short read happened - -Fixes: 6663a0a33764 ("block/io_uring: implements interfaces for io_uring") -Link: https://lkml.kernel.org/r/YrrFGO4A1jS0GI0G@atmark-techno.com -Signed-off-by: Dominique Martinet -Message-Id: <20220630010137.2518851-1-dominique.martinet@atmark-techno.com> -Reviewed-by: Hanna Reitz -Reviewed-by: Stefano Garzarella -Signed-off-by: Stefan Hajnoczi - -Signed-off-by: tangbinzy ---- - block/io_uring.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/block/io_uring.c b/block/io_uring.c -index dfa475cc87..e88d75d462 100644 ---- a/block/io_uring.c -+++ b/block/io_uring.c -@@ -89,7 +89,7 @@ static void luring_resubmit_short_read(LuringState *s, LuringAIOCB *luringcb, - trace_luring_resubmit_short_read(s, luringcb, nread); - - /* Update read position */ -- luringcb->total_read = nread; -+ luringcb->total_read += nread; - remaining = luringcb->qiov->size - luringcb->total_read; - - /* Shorten qiov */ -@@ -103,7 +103,7 @@ static void luring_resubmit_short_read(LuringState *s, LuringAIOCB *luringcb, - remaining); - - /* Update sqe */ -- luringcb->sqeq.off = nread; -+ luringcb->sqeq.off += nread; - luringcb->sqeq.addr = (__u64)(uintptr_t)luringcb->resubmit_qiov.iov; - luringcb->sqeq.len = luringcb->resubmit_qiov.niov; - --- -2.27.0 - diff --git a/iommu-Introduce-generic-header.patch b/iommu-Introduce-generic-header.patch deleted file mode 100644 index 84f3d77c057bee4e80d68e8dbf92c473089109f0..0000000000000000000000000000000000000000 --- a/iommu-Introduce-generic-header.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 5e312f7b41ec48dc7dc9805af9f52aa8ed393bf9 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 9 Jul 2019 12:20:12 +0200 -Subject: [PATCH] iommu: Introduce generic header - -This header is meant to exposes data types used by -several IOMMU devices such as struct for SVA and -nested stage configuration. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - include/hw/iommu/iommu.h | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - create mode 100644 include/hw/iommu/iommu.h - -diff --git a/include/hw/iommu/iommu.h b/include/hw/iommu/iommu.h -new file mode 100644 -index 0000000000..12092bda7b ---- /dev/null -+++ b/include/hw/iommu/iommu.h -@@ -0,0 +1,28 @@ -+/* -+ * common header for iommu devices -+ * -+ * Copyright Red Hat, Inc. 2019 -+ * -+ * Authors: -+ * Eric Auger -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2. See -+ * the COPYING file in the top-level directory. -+ */ -+ -+#ifndef QEMU_HW_IOMMU_IOMMU_H -+#define QEMU_HW_IOMMU_IOMMU_H -+#ifdef __linux__ -+#include -+#endif -+ -+typedef struct IOMMUConfig { -+ union { -+#ifdef __linux__ -+ struct iommu_pasid_table_config pasid_cfg; -+#endif -+ }; -+} IOMMUConfig; -+ -+ -+#endif /* QEMU_HW_IOMMU_IOMMU_H */ --- -2.27.0 - diff --git a/iotests-fix-default-machine-type-detection.patch b/iotests-fix-default-machine-type-detection.patch deleted file mode 100644 index 47910b76f6d8f200ae244a760e08d405feb28bdb..0000000000000000000000000000000000000000 --- a/iotests-fix-default-machine-type-detection.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 1c60628eef43847595723a65ff9fd57f38cc70de Mon Sep 17 00:00:00 2001 -From: jipengfei_yewu -Date: Mon, 18 Dec 2023 09:57:38 +0000 -Subject: [PATCH] iotests: fix default machine type detection - -The machine type is being detected based on "-M help" output, and we're -searching for the line ending with " (default)". However, in downstream -one of the machine types s marked as deprecated might become the -default, in which case this logic breaks as the line would now end with -" (default) (deprecated)". To fix potential issues here, let's relax -that requirement and detect the mere presence of " (default)" line -instead. - -cheery-pick from 3b7094fe8329c5c7bb0d685e1876aa30f59bece6 - -Signed-off-by: jipengfei_yewu -Signed-off-by: Andrey Drobyshev -Message-ID: <20231122121538.32903-1-andrey.drobyshev@virtuozzo.com> -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - tests/qemu-iotests/testenv.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py -index 26ae6945cc..993e9c56be 100644 ---- a/tests/qemu-iotests/testenv.py -+++ b/tests/qemu-iotests/testenv.py -@@ -40,7 +40,7 @@ def get_default_machine(qemu_prog: str) -> str: - - machines = outp.split('\n') - try: -- default_machine = next(m for m in machines if m.endswith(' (default)')) -+ default_machine = next(m for m in machines if ' (default)' in m) - except StopIteration: - return '' - default_machine = default_machine.split(' ', 1)[0] --- -2.27.0 - diff --git a/job.c-add-missing-notifier-initialization.patch b/job.c-add-missing-notifier-initialization.patch deleted file mode 100644 index ca795efe445ec045eba1e8ae718668442131deca..0000000000000000000000000000000000000000 --- a/job.c-add-missing-notifier-initialization.patch +++ /dev/null @@ -1,37 +0,0 @@ -From d8962af271345ae4d7880219a62abed76a0268e0 Mon Sep 17 00:00:00 2001 -From: Emanuele Giuseppe Esposito -Date: Wed, 3 Nov 2021 12:21:55 -0400 -Subject: [PATCH 1/6] job.c: add missing notifier initialization -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It seems that on_idle list is not properly initialized like -the other notifiers. - -Fixes: 34dc97b9a0e ("blockjob: Wake up BDS when job becomes idle") -Signed-off-by: Emanuele Giuseppe Esposito -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: Vladimir Sementsov-Ogievskiy -Signed-off-by: wanbo ---- - job.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/job.c b/job.c -index dbfa67bb0a..54db80df66 100644 ---- a/job.c -+++ b/job.c -@@ -352,6 +352,7 @@ void *job_create(const char *job_id, const JobDriver *driver, JobTxn *txn, - notifier_list_init(&job->on_finalize_completed); - notifier_list_init(&job->on_pending); - notifier_list_init(&job->on_ready); -+ notifier_list_init(&job->on_idle); - - job_state_transition(job, JOB_STATUS_CREATED); - aio_timer_init(qemu_get_aio_context(), &job->sleep_timer, --- -2.27.0 - diff --git a/kvm-allow-target-specific-accelerator-properties.patch b/kvm-allow-target-specific-accelerator-properties.patch deleted file mode 100644 index 6c8c536c33753f55cf70a3b9be18ed6d382a45b6..0000000000000000000000000000000000000000 --- a/kvm-allow-target-specific-accelerator-properties.patch +++ /dev/null @@ -1,129 +0,0 @@ -From f90dc9f811195fabd68faf2ca98b2fe5b4fbe3d0 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Thu, 29 Sep 2022 15:20:12 +0800 -Subject: [PATCH] kvm: allow target-specific accelerator properties - -from mainline-v7.2.0-rc0 -commit 3dba0a335cf5c53146b606be6ddfab4df81c464e -category: feature -feature: Notify VM Exit -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6GWQE - -Intel-SIG: commit 3dba0a335cf5 ("kvm: allow target-specific accelerator properties") - ------------------------------------------------------------------- - -kvm: allow target-specific accelerator properties - -Several hypervisor capabilities in KVM are target-specific. When exposed -to QEMU users as accelerator properties (i.e. -accel kvm,prop=value), they -should not be available for all targets. - -Add a hook for targets to add their own properties to -accel kvm, for -now no such property is defined. - -Signed-off-by: Paolo Bonzini -Message-Id: <20220929072014.20705-3-chenyi.qiang@intel.com> -Signed-off-by: Paolo Bonzini -[ remove changes in target/riscv/kvm.c since riscv kvm is not - supported in qemu-6.2.0 and linux 5.10 ] -Signed-off-by: Jason Zeng ---- - accel/kvm/kvm-all.c | 2 ++ - include/sysemu/kvm.h | 2 ++ - target/arm/kvm.c | 4 ++++ - target/i386/kvm/kvm.c | 4 ++++ - target/mips/kvm.c | 4 ++++ - target/ppc/kvm.c | 4 ++++ - target/s390x/kvm/kvm.c | 4 ++++ - 7 files changed, 24 insertions(+) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index 946ccb260b..e5681a6cd0 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -3703,6 +3703,8 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data) - NULL, NULL); - object_class_property_set_description(oc, "dirty-ring-size", - "Size of KVM dirty page ring buffer (default: 0, i.e. use bitmap)"); -+ -+ kvm_arch_accel_class_init(oc); - } - - static const TypeInfo kvm_accel_type = { -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 19c5c8402a..1ec9432493 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -334,6 +334,8 @@ bool kvm_device_supported(int vmfd, uint64_t type); - - extern const KVMCapabilityInfo kvm_arch_required_capabilities[]; - -+void kvm_arch_accel_class_init(ObjectClass *oc); -+ - void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run); - MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run); - -diff --git a/target/arm/kvm.c b/target/arm/kvm.c -index 29ac3f40e0..22ac5bcb97 100644 ---- a/target/arm/kvm.c -+++ b/target/arm/kvm.c -@@ -1095,3 +1095,7 @@ bool kvm_arch_cpu_check_are_resettable(void) - { - return true; - } -+ -+void kvm_arch_accel_class_init(ObjectClass *oc) -+{ -+} -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index e97d967c73..e2f28ce958 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -5168,3 +5168,7 @@ void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask) - mask &= ~BIT_ULL(bit); - } - } -+ -+void kvm_arch_accel_class_init(ObjectClass *oc) -+{ -+} -diff --git a/target/mips/kvm.c b/target/mips/kvm.c -index 086debd9f0..f80ac72dd1 100644 ---- a/target/mips/kvm.c -+++ b/target/mips/kvm.c -@@ -1295,3 +1295,7 @@ bool kvm_arch_cpu_check_are_resettable(void) - { - return true; - } -+ -+void kvm_arch_accel_class_init(ObjectClass *oc) -+{ -+} -diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index d73563045b..9693aab3c7 100644 ---- a/target/ppc/kvm.c -+++ b/target/ppc/kvm.c -@@ -2975,3 +2975,7 @@ bool kvm_arch_cpu_check_are_resettable(void) - { - return true; - } -+ -+void kvm_arch_accel_class_init(ObjectClass *oc) -+{ -+} -diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c -index 5b1fdb55c4..671d0f179c 100644 ---- a/target/s390x/kvm/kvm.c -+++ b/target/s390x/kvm/kvm.c -@@ -2562,3 +2562,7 @@ bool kvm_arch_cpu_check_are_resettable(void) - { - return true; - } -+ -+void kvm_arch_accel_class_init(ObjectClass *oc) -+{ -+} --- -2.27.0 - diff --git a/kvm-expose-struct-KVMState.patch b/kvm-expose-struct-KVMState.patch deleted file mode 100644 index 8514cd8828f28213822a69be8d5419e2b9ac8d08..0000000000000000000000000000000000000000 --- a/kvm-expose-struct-KVMState.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 9f7f9fdf2246c653673d07fccc07cdc6b03f8722 Mon Sep 17 00:00:00 2001 -From: Chenyi Qiang -Date: Thu, 29 Sep 2022 15:20:13 +0800 -Subject: [PATCH] kvm: expose struct KVMState - -from mainline-v7.2.0-rc0 -commit 5f8a6bce1f1080058ed29d716cae81ea805142ae -category: feature -feature: Notify VM Exit -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6GWQE - -Intel-SIG: commit 5f8a6bce1f10 ("kvm: expose struct KVMState") - ------------------------------------------------------------------- - -kvm: expose struct KVMState - -Expose struct KVMState out of kvm-all.c so that the field of struct -KVMState can be accessed when defining target-specific accelerator -properties. - -Signed-off-by: Chenyi Qiang -Message-Id: <20220929072014.20705-4-chenyi.qiang@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - accel/kvm/kvm-all.c | 74 -------------------------------------- - include/sysemu/kvm_int.h | 76 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 76 insertions(+), 74 deletions(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index e5681a6cd0..91d93facf2 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -72,86 +72,12 @@ - do { } while (0) - #endif - --#define KVM_MSI_HASHTAB_SIZE 256 -- - struct KVMParkedVcpu { - unsigned long vcpu_id; - int kvm_fd; - QLIST_ENTRY(KVMParkedVcpu) node; - }; - --enum KVMDirtyRingReaperState { -- KVM_DIRTY_RING_REAPER_NONE = 0, -- /* The reaper is sleeping */ -- KVM_DIRTY_RING_REAPER_WAIT, -- /* The reaper is reaping for dirty pages */ -- KVM_DIRTY_RING_REAPER_REAPING, --}; -- --/* -- * KVM reaper instance, responsible for collecting the KVM dirty bits -- * via the dirty ring. -- */ --struct KVMDirtyRingReaper { -- /* The reaper thread */ -- QemuThread reaper_thr; -- volatile uint64_t reaper_iteration; /* iteration number of reaper thr */ -- volatile enum KVMDirtyRingReaperState reaper_state; /* reap thr state */ --}; -- --struct KVMState --{ -- AccelState parent_obj; -- -- int nr_slots; -- int fd; -- int vmfd; -- int coalesced_mmio; -- int coalesced_pio; -- struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; -- bool coalesced_flush_in_progress; -- int vcpu_events; -- int robust_singlestep; -- int debugregs; --#ifdef KVM_CAP_SET_GUEST_DEBUG -- QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints; --#endif -- int max_nested_state_len; -- int many_ioeventfds; -- int intx_set_mask; -- int kvm_shadow_mem; -- bool kernel_irqchip_allowed; -- bool kernel_irqchip_required; -- OnOffAuto kernel_irqchip_split; -- bool sync_mmu; -- uint64_t manual_dirty_log_protect; -- /* The man page (and posix) say ioctl numbers are signed int, but -- * they're not. Linux, glibc and *BSD all treat ioctl numbers as -- * unsigned, and treating them as signed here can break things */ -- unsigned irq_set_ioctl; -- unsigned int sigmask_len; -- GHashTable *gsimap; --#ifdef KVM_CAP_IRQ_ROUTING -- struct kvm_irq_routing *irq_routes; -- int nr_allocated_irq_routes; -- unsigned long *used_gsi_bitmap; -- unsigned int gsi_count; -- QTAILQ_HEAD(, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; --#endif -- KVMMemoryListener memory_listener; -- QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; -- -- /* For "info mtree -f" to tell if an MR is registered in KVM */ -- int nr_as; -- struct KVMAs { -- KVMMemoryListener *ml; -- AddressSpace *as; -- } *as; -- uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */ -- uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */ -- struct KVMDirtyRingReaper reaper; --}; -- - KVMState *kvm_state; - bool kvm_kernel_irqchip; - bool kvm_split_irqchip; -diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h -index 1f5487d9b7..3b4adcdc10 100644 ---- a/include/sysemu/kvm_int.h -+++ b/include/sysemu/kvm_int.h -@@ -10,6 +10,7 @@ - #define QEMU_KVM_INT_H - - #include "exec/memory.h" -+#include "qapi/qapi-types-common.h" - #include "qemu/accel.h" - #include "sysemu/kvm.h" - -@@ -36,6 +37,81 @@ typedef struct KVMMemoryListener { - int as_id; - } KVMMemoryListener; - -+#define KVM_MSI_HASHTAB_SIZE 256 -+ -+enum KVMDirtyRingReaperState { -+ KVM_DIRTY_RING_REAPER_NONE = 0, -+ /* The reaper is sleeping */ -+ KVM_DIRTY_RING_REAPER_WAIT, -+ /* The reaper is reaping for dirty pages */ -+ KVM_DIRTY_RING_REAPER_REAPING, -+}; -+ -+/* -+ * KVM reaper instance, responsible for collecting the KVM dirty bits -+ * via the dirty ring. -+ */ -+struct KVMDirtyRingReaper { -+ /* The reaper thread */ -+ QemuThread reaper_thr; -+ volatile uint64_t reaper_iteration; /* iteration number of reaper thr */ -+ volatile enum KVMDirtyRingReaperState reaper_state; /* reap thr state */ -+}; -+struct KVMState -+{ -+ AccelState parent_obj; -+ -+ int nr_slots; -+ int fd; -+ int vmfd; -+ int coalesced_mmio; -+ int coalesced_pio; -+ struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; -+ bool coalesced_flush_in_progress; -+ int vcpu_events; -+ int robust_singlestep; -+ int debugregs; -+#ifdef KVM_CAP_SET_GUEST_DEBUG -+ QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints; -+#endif -+ int max_nested_state_len; -+ int many_ioeventfds; -+ int intx_set_mask; -+ int kvm_shadow_mem; -+ bool kernel_irqchip_allowed; -+ bool kernel_irqchip_required; -+ OnOffAuto kernel_irqchip_split; -+ bool sync_mmu; -+ uint64_t manual_dirty_log_protect; -+ /* The man page (and posix) say ioctl numbers are signed int, but -+ * they're not. Linux, glibc and *BSD all treat ioctl numbers as -+ * unsigned, and treating them as signed here can break things */ -+ unsigned irq_set_ioctl; -+ unsigned int sigmask_len; -+ GHashTable *gsimap; -+#ifdef KVM_CAP_IRQ_ROUTING -+ struct kvm_irq_routing *irq_routes; -+ int nr_allocated_irq_routes; -+ unsigned long *used_gsi_bitmap; -+ unsigned int gsi_count; -+ QTAILQ_HEAD(, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; -+#endif -+ KVMMemoryListener memory_listener; -+ QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; -+ -+ /* For "info mtree -f" to tell if an MR is registered in KVM */ -+ int nr_as; -+ struct KVMAs { -+ KVMMemoryListener *ml; -+ AddressSpace *as; -+ } *as; -+ uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */ -+ uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */ -+ struct KVMDirtyRingReaper reaper; -+ NotifyVmexitOption notify_vmexit; -+ uint32_t notify_window; -+}; -+ - void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, - AddressSpace *as, int as_id, const char *name); - --- -2.27.0 - diff --git a/libdecnumber-dpd-decimal64-Fix-compiler-warning-from.patch b/libdecnumber-dpd-decimal64-Fix-compiler-warning-from.patch deleted file mode 100644 index 095e731beea27e321d7924e1ce63a71652eb4e79..0000000000000000000000000000000000000000 --- a/libdecnumber-dpd-decimal64-Fix-compiler-warning-from.patch +++ /dev/null @@ -1,51 +0,0 @@ -From ddc9e2437ee5e9cd7fb0c0ad153c23feb9d9722b Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Thu, 1 Dec 2022 20:41:44 +0800 -Subject: [PATCH 05/17] libdecnumber/dpd/decimal64: Fix compiler warning from - Clang 15 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Clang 15 from Fedora 37 complains: - - ../libdecnumber/dpd/decimal64.c:620:8: error: variable 'n' set but - not used [-Werror,-Wunused-but-set-variable] - Int n; /* output bunch counter */ - ^ - 1 error generated. - -Remove the unused variable to silence the compiler warning. - -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Cédric Le Goater -Signed-off-by: Thomas Huth -Signed-off-by: tangzhongrui tangzhongrui@cmss.chinamobile.com ---- - libdecnumber/dpd/decimal64.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/libdecnumber/dpd/decimal64.c b/libdecnumber/dpd/decimal64.c -index 4816176410..f6fb2963d9 100644 ---- a/libdecnumber/dpd/decimal64.c -+++ b/libdecnumber/dpd/decimal64.c -@@ -617,7 +617,6 @@ static const uInt multies[]={131073, 26215, 5243, 1049, 210}; - #endif - void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { - Int cut; /* work */ -- Int n; /* output bunch counter */ - Int digits=dn->digits; /* digit countdown */ - uInt dpd; /* densely packed decimal value */ - uInt bin; /* binary value 0-999 */ -@@ -676,7 +675,7 @@ void decDigitsToDPD(const decNumber *dn, uInt *targ, Int shift) { - bin=0; /* [keep compiler quiet] */ - #endif - -- for(n=0; digits>0; n++) { /* each output bunch */ -+ while (digits > 0) { /* each output bunch */ - #if DECDPUN==3 /* fast path, 3-at-a-time */ - bin=*inu; /* 3 digits ready for convert */ - digits-=3; /* [may go negative] */ --- -2.27.0 - diff --git a/libvhost-user-Fix-VHOST_USER_ADD_MEM_REG-reply.patch b/libvhost-user-Fix-VHOST_USER_ADD_MEM_REG-reply.patch deleted file mode 100644 index 23cde54cf1dcfe1b0c45e11bacd681d928d20a27..0000000000000000000000000000000000000000 --- a/libvhost-user-Fix-VHOST_USER_ADD_MEM_REG-reply.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c2353941d94a5aeb8364dc5204c29a4fbb09437f Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 21 Nov 2023 06:47:43 +0000 -Subject: [PATCH] libvhost-user: Fix VHOST_USER_ADD_MEM_REG reply mainline - inclusion commit 7f27d20ded2f480f3e66d03f90ea71507b834276 category: bugfix - ---------------------------------------------------------------- - -With REPLY_NEEDED, libvhost-user sends both the acutal result and an -additional ACK reply for VHOST_USER_ADD_MEM_REG. This is incorrect, the -spec mandates that it behave the same with and without REPLY_NEEDED -because it always sends a reply. - -Fixes: ec94c8e621de96c50c2d381c8c9ec94f5beec7c1 -Signed-off-by: Kevin Wolf -Message-Id: <20220627134500.94842-4-kwolf@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin - -Signed-off-by: tangbinzy ---- - subprojects/libvhost-user/libvhost-user.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - -diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c -index 787f4d2d4f..8ab20138f4 100644 ---- a/subprojects/libvhost-user/libvhost-user.c -+++ b/subprojects/libvhost-user/libvhost-user.c -@@ -756,15 +756,9 @@ vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) { - - /* Send the message back to qemu with the addresses filled in. */ - vmsg->fd_num = 0; -- if (!vu_send_reply(dev, dev->sock, vmsg)) { -- vu_panic(dev, "failed to respond to add-mem-region for postcopy"); -- return false; -- } -- - DPRINT("Successfully added new region in postcopy\n"); - dev->nregions++; -- return false; -- -+ return true; - } else { - for (i = 0; i < dev->max_queues; i++) { - if (dev->vq[i].vring.desc) { --- -2.27.0 - diff --git a/libvhost-user-Fix-VHOST_USER_GET_MAX_MEM_SLOTS-reply.patch b/libvhost-user-Fix-VHOST_USER_GET_MAX_MEM_SLOTS-reply.patch deleted file mode 100644 index fac419155b747664531c0cdbd0487dc560248256..0000000000000000000000000000000000000000 --- a/libvhost-user-Fix-VHOST_USER_GET_MAX_MEM_SLOTS-reply.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 3e2df0133efdf3e3aea63f413b42e37bc6c87112 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 21 Nov 2023 06:36:05 +0000 -Subject: [PATCH] libvhost-user: Fix VHOST_USER_GET_MAX_MEM_SLOTS reply - mainline inclusion commit 69a5daec06f423843ce1bb9be5fb049314996f78 category: - bugfix - ---------------------------------------------------------------- - -With REPLY_NEEDED, libvhost-user sends both the acutal result and an -additional ACK reply for VHOST_USER_GET_MAX_MEM_SLOTS. This is -incorrect, the spec mandates that it behave the same with and without -REPLY_NEEDED because it always sends a reply. - -Fixes: 6fb2e173d20c9bbb5466183d33a3ad7dcd0375fa -Signed-off-by: Kevin Wolf -Message-Id: <20220627134500.94842-3-kwolf@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin - -Signed-off-by: tangbinzy ---- - subprojects/libvhost-user/libvhost-user.c | 11 ++--------- - 1 file changed, 2 insertions(+), 9 deletions(-) - -diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c -index 787f4d2d4f..27e7799262 100644 ---- a/subprojects/libvhost-user/libvhost-user.c -+++ b/subprojects/libvhost-user/libvhost-user.c -@@ -1788,18 +1788,11 @@ vu_handle_vring_kick(VuDev *dev, VhostUserMsg *vmsg) - - static bool vu_handle_get_max_memslots(VuDev *dev, VhostUserMsg *vmsg) - { -- vmsg->flags = VHOST_USER_REPLY_MASK | VHOST_USER_VERSION; -- vmsg->size = sizeof(vmsg->payload.u64); -- vmsg->payload.u64 = VHOST_USER_MAX_RAM_SLOTS; -- vmsg->fd_num = 0; -- -- if (!vu_message_write(dev, dev->sock, vmsg)) { -- vu_panic(dev, "Failed to send max ram slots: %s\n", strerror(errno)); -- } -+ vmsg_set_reply_u64(vmsg, VHOST_USER_MAX_RAM_SLOTS); - - DPRINT("u64: 0x%016"PRIx64"\n", (uint64_t) VHOST_USER_MAX_RAM_SLOTS); - -- return false; -+ return true; - } - - static bool --- -2.27.0 - diff --git a/linux-headers-Update-headers-to-Linux-5.18-rc6.patch b/linux-headers-Update-headers-to-Linux-5.18-rc6.patch deleted file mode 100644 index 4d066072dade0af8c64143d61aba34197210bb1c..0000000000000000000000000000000000000000 --- a/linux-headers-Update-headers-to-Linux-5.18-rc6.patch +++ /dev/null @@ -1,31 +0,0 @@ -From f639ed71c4baa5e40281ff9baa3ef312f37cf985 Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Sat, 14 May 2022 12:11:04 +0800 -Subject: [PATCH 1/7] linux-headers: Update headers to Linux 5.18-rc6 - -Update headers to 5.18-rc6. I need latest vhost changes. - -Signed-off-by: Longpeng ---- - linux-headers/linux/vhost.h | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h -index c998860d7b..5d99e7c242 100644 ---- a/linux-headers/linux/vhost.h -+++ b/linux-headers/linux/vhost.h -@@ -150,4 +150,11 @@ - /* Get the valid iova range */ - #define VHOST_VDPA_GET_IOVA_RANGE _IOR(VHOST_VIRTIO, 0x78, \ - struct vhost_vdpa_iova_range) -+ -+/* Get the config size */ -+#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x79, __u32) -+ -+/* Get the count of all virtqueues */ -+#define VHOST_VDPA_GET_VQS_COUNT _IOR(VHOST_VIRTIO, 0x80, __u32) -+ - #endif --- -2.27.0 - diff --git a/linux-headers-include-missing-changes-from-5.17.patch b/linux-headers-include-missing-changes-from-5.17.patch deleted file mode 100644 index 1461d59624cbb8fb7c64b24a6fc12789e104316b..0000000000000000000000000000000000000000 --- a/linux-headers-include-missing-changes-from-5.17.patch +++ /dev/null @@ -1,65 +0,0 @@ -From d6398243714a7a775c64e74dbd63c00863cb7e83 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Tue, 22 Feb 2022 17:58:11 +0100 -Subject: [PATCH 01/10] linux-headers: include missing changes from 5.17 - -mainline inclusion -from mainline-v7.0.0-rc0 -commit 1ea5208febcc068449b63282d72bb719ab67a466 -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit 1ea5208febcc ("linux-headers: include missing changes from 5.17") - ------------------------------------------------- - -linux-headers: include missing changes from 5.17 - -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - linux-headers/asm-x86/kvm.h | 3 +++ - linux-headers/linux/kvm.h | 7 +++++++ - 2 files changed, 10 insertions(+) - -diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h -index a6c327f8ad..2ab4f1818a 100644 ---- a/linux-headers/asm-x86/kvm.h -+++ b/linux-headers/asm-x86/kvm.h -@@ -437,6 +437,9 @@ struct kvm_sync_regs { - - #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001 - -+/* attributes for system fd (group 0) */ -+#define KVM_X86_XCOMP_GUEST_SUPP 0 -+ - struct kvm_vmx_nested_state_data { - __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; - __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 5d8e42b8f8..7870cd0280 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1112,6 +1112,10 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_BINARY_STATS_FD 203 - #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204 - #define KVM_CAP_ARM_MTE 205 -+#define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206 -+#define KVM_CAP_VM_GPA_BITS 207 -+#define KVM_CAP_XSAVE2 208 -+#define KVM_CAP_SYS_ATTRIBUTES 209 - - #define KVM_CAP_ARM_CPU_FEATURE 555 - -@@ -2006,4 +2010,7 @@ struct kvm_stats_desc { - - #define KVM_GET_STATS_FD _IO(KVMIO, 0xce) - -+/* Available with KVM_CAP_XSAVE2 */ -+#define KVM_GET_XSAVE2 _IOR(KVMIO, 0xcf, struct kvm_xsave) -+ - #endif /* __LINUX_KVM_H */ --- -2.27.0 - diff --git a/linux-headers-include-missing-changes-from-6.0.patch b/linux-headers-include-missing-changes-from-6.0.patch deleted file mode 100644 index 5d2ccc41df3a388eaa9ce4d7cb4fef04578ce853..0000000000000000000000000000000000000000 --- a/linux-headers-include-missing-changes-from-6.0.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 1e54d0c7bca44e2cf58c769e420c5ffcefb58ea1 Mon Sep 17 00:00:00 2001 -From: Jason Zeng -Date: Wed, 22 Feb 2023 13:59:37 +0800 -Subject: [PATCH] linux-headers: include missing changes from 6.0 - -Signed-off-by: Jason Zeng ---- - linux-headers/asm-x86/kvm.h | 6 +++++- - linux-headers/linux/kvm.h | 12 ++++++++++++ - 2 files changed, 17 insertions(+), 1 deletion(-) - -diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h -index 2ab4f1818a..46e730b62f 100644 ---- a/linux-headers/asm-x86/kvm.h -+++ b/linux-headers/asm-x86/kvm.h -@@ -324,6 +324,7 @@ struct kvm_reinject_control { - #define KVM_VCPUEVENT_VALID_SHADOW 0x00000004 - #define KVM_VCPUEVENT_VALID_SMM 0x00000008 - #define KVM_VCPUEVENT_VALID_PAYLOAD 0x00000010 -+#define KVM_VCPUEVENT_VALID_TRIPLE_FAULT 0x00000020 - - /* Interrupt shadow states */ - #define KVM_X86_SHADOW_INT_MOV_SS 0x01 -@@ -358,7 +359,10 @@ struct kvm_vcpu_events { - __u8 smm_inside_nmi; - __u8 latched_init; - } smi; -- __u8 reserved[27]; -+ struct { -+ __u8 pending; -+ } triple_fault; -+ __u8 reserved[26]; - __u8 exception_has_payload; - __u64 exception_payload; - }; -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 7870cd0280..cda9016d49 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -269,6 +269,7 @@ struct kvm_xen_exit { - #define KVM_EXIT_AP_RESET_HOLD 32 - #define KVM_EXIT_X86_BUS_LOCK 33 - #define KVM_EXIT_XEN 34 -+#define KVM_EXIT_NOTIFY 37 - - /* For KVM_EXIT_INTERNAL_ERROR */ - /* Emulate instruction failed. */ -@@ -469,6 +470,11 @@ struct kvm_run { - } msr; - /* KVM_EXIT_XEN */ - struct kvm_xen_exit xen; -+ /* KVM_EXIT_NOTIFY */ -+ struct { -+#define KVM_NOTIFY_CONTEXT_INVALID (1 << 0) -+ __u32 flags; -+ } notify; - /* Fix the size of the union. */ - char padding[256]; - }; -@@ -1116,6 +1122,8 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_VM_GPA_BITS 207 - #define KVM_CAP_XSAVE2 208 - #define KVM_CAP_SYS_ATTRIBUTES 209 -+#define KVM_CAP_X86_TRIPLE_FAULT_EVENT 218 -+#define KVM_CAP_X86_NOTIFY_VMEXIT 219 - - #define KVM_CAP_ARM_CPU_FEATURE 555 - -@@ -2013,4 +2021,8 @@ struct kvm_stats_desc { - /* Available with KVM_CAP_XSAVE2 */ - #define KVM_GET_XSAVE2 _IOR(KVMIO, 0xcf, struct kvm_xsave) - -+/* Available with KVM_CAP_X86_NOTIFY_VMEXIT */ -+#define KVM_X86_NOTIFY_VMEXIT_ENABLED (1ULL << 0) -+#define KVM_X86_NOTIFY_VMEXIT_USER (1ULL << 1) -+ - #endif /* __LINUX_KVM_H */ --- -2.27.0 - diff --git a/linux-headers-update-against-5.10-and-manual-clear-v.patch b/linux-headers-update-against-5.10-and-manual-clear-v.patch deleted file mode 100644 index 93d300675cb54678121161bfb63e0a35bfaffc6f..0000000000000000000000000000000000000000 --- a/linux-headers-update-against-5.10-and-manual-clear-v.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 40512773625a4f8ddd96a5af924f119b89a14706 Mon Sep 17 00:00:00 2001 -From: Zenghui Yu -Date: Sat, 8 May 2021 17:31:03 +0800 -Subject: [PATCH] linux-headers: update against 5.10 and manual clear vfio - dirty log series - -The new capability VFIO_DIRTY_LOG_MANUAL_CLEAR and the new ioctl -VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP_NOCLEAR and -VFIO_IOMMU_DIRTY_PAGES_FLAG_CLEAR_BITMAP have been introduced in -the kernel, update the header to add them. - -Signed-off-by: Zenghui Yu -Signed-off-by: Kunkun Jiang ---- - linux-headers/linux/vfio.h | 36 +++++++++++++++++++++++++++++++++++- - 1 file changed, 35 insertions(+), 1 deletion(-) - -diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h -index e680594f27..f4ff038e8c 100644 ---- a/linux-headers/linux/vfio.h -+++ b/linux-headers/linux/vfio.h -@@ -52,6 +52,16 @@ - /* Supports the vaddr flag for DMA map and unmap */ - #define VFIO_UPDATE_VADDR 10 - -+/* -+ * The vfio_iommu driver may support user clears dirty log manually, which means -+ * dirty log can be requested to not cleared automatically after dirty log is -+ * copied to userspace, it's user's duty to clear dirty log. -+ * -+ * Note: please refer to VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP_NOCLEAR and -+ * VFIO_IOMMU_DIRTY_PAGES_FLAG_CLEAR_BITMAP. -+ */ -+#define VFIO_DIRTY_LOG_MANUAL_CLEAR 11 -+ - /* - * The IOCTL interface is designed for extensibility by embedding the - * structure length (argsz) and flags into structures passed between -@@ -1196,8 +1206,30 @@ struct vfio_iommu_type1_dma_unmap { - * actual bitmap. If dirty pages logging is not enabled, an error will be - * returned. - * -- * Only one of the flags _START, _STOP and _GET may be specified at a time. -+ * The VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP_NOCLEAR flag is almost same as -+ * VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP, except that it requires underlying -+ * dirty bitmap is not cleared automatically. The user can clear it manually by -+ * calling the IOCTL with VFIO_IOMMU_DIRTY_PAGES_FLAG_CLEAR_BITMAP flag set. - * -+ * Calling the IOCTL with VFIO_IOMMU_DIRTY_PAGES_FLAG_CLEAR_BITMAP flag set, -+ * instructs the IOMMU driver to clear the dirty status of pages in a bitmap -+ * for IOMMU container for a given IOVA range. The user must specify the IOVA -+ * range, the bitmap and the pgsize through the structure -+ * vfio_iommu_type1_dirty_bitmap_get in the data[] portion. This interface -+ * supports clearing a bitmap of the smallest supported pgsize only and can be -+ * modified in future to clear a bitmap of any specified supported pgsize. The -+ * user must provide a memory area for the bitmap memory and specify its size -+ * in bitmap.size. One bit is used to represent one page consecutively starting -+ * from iova offset. The user should provide page size in bitmap.pgsize field. -+ * A bit set in the bitmap indicates that the page at that offset from iova is -+ * cleared the dirty status, and dirty tracking is re-enabled for that page. The -+ * caller must set argsz to a value including the size of structure -+ * vfio_iommu_dirty_bitmap_get, but excluing the size of the actual bitmap. If -+ * dirty pages logging is not enabled, an error will be returned. Note: user -+ * should clear dirty log before handle corresponding dirty pages. -+ * -+ * Only one of the flags _START, _STOP, _GET, _GET_NOCLEAR_, and _CLEAR may be -+ * specified at a time. - */ - struct vfio_iommu_type1_dirty_bitmap { - __u32 argsz; -@@ -1205,6 +1237,8 @@ struct vfio_iommu_type1_dirty_bitmap { - #define VFIO_IOMMU_DIRTY_PAGES_FLAG_START (1 << 0) - #define VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP (1 << 1) - #define VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP (1 << 2) -+#define VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP_NOCLEAR (1 << 3) -+#define VFIO_IOMMU_DIRTY_PAGES_FLAG_CLEAR_BITMAP (1 << 4) - __u8 data[]; - }; - --- -2.27.0 - diff --git a/linux-user-Add-strace-output-for-timer_settime64-sys.patch b/linux-user-Add-strace-output-for-timer_settime64-sys.patch deleted file mode 100644 index c940890f253d0fecd7f54f38e419a8430dc0419a..0000000000000000000000000000000000000000 --- a/linux-user-Add-strace-output-for-timer_settime64-sys.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 685f5a507be1f79b1a78fcff38923bc0670f0dc4 Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Fri, 9 Dec 2022 15:39:52 +0800 -Subject: [PATCH 1/2] linux-user: Add strace output for timer_settime64() - syscall - -Add missing timer_settime64() strace output and specify format for -timer_settime(). - -Signed-off-by: Helge Deller - -Message-Id: -Signed-off-by: Laurent Vivier -Signed-off-by: tangzhongrui ---- - linux-user/strace.list | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/linux-user/strace.list b/linux-user/strace.list -index 278596acd1..544869f1ab 100644 ---- a/linux-user/strace.list -+++ b/linux-user/strace.list -@@ -1522,7 +1522,10 @@ - { TARGET_NR_timer_gettime, "timer_gettime" , NULL, NULL, NULL }, - #endif - #ifdef TARGET_NR_timer_settime --{ TARGET_NR_timer_settime, "timer_settime" , NULL, NULL, NULL }, -+{ TARGET_NR_timer_settime, "timer_settime" , "%s(%d,%d,%p,%p)", NULL, NULL }, -+#endif -+#ifdef TARGET_NR_timer_settime64 -+{ TARGET_NR_timer_settime64, "timer_settime64" , "%s(%d,%d,%p,%p)", NULL, NULL }, - #endif - #ifdef TARGET_NR_timerfd - { TARGET_NR_timerfd, "timerfd" , NULL, NULL, NULL }, --- -2.27.0 - diff --git a/linux-user-always-translate-cmsg-when-recvmsg.patch b/linux-user-always-translate-cmsg-when-recvmsg.patch deleted file mode 100644 index fa2c965f41ca49c45780ea24db529f9b7afcd651..0000000000000000000000000000000000000000 --- a/linux-user-always-translate-cmsg-when-recvmsg.patch +++ /dev/null @@ -1,36 +0,0 @@ -From eb2a5f2f73e4cfaf20246fb3d3fb1b8bd5716606 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Tue, 22 Nov 2022 17:10:35 +0800 -Subject: [PATCH 03/29] linux-user: always translate cmsg when recvmsg - -It's possible that a message contains both normal payload and ancillary -data in the same message, and even if no ancillary data is available -this information should be passed to the target, otherwise the target -cmsghdr will be left uninitialized and the target is going to access -uninitialized memory if it expects cmsg. -Always call the function that translate cmsg when recvmsg, because that -function should be empty-cmsg-safe(it creates an empty cmsg in the target). - -Signed-off-by: Icenowy Zheng -Signed-off-by: jianchunfu ---- - linux-user/syscall.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index f1cfcc8104..fce2c03259 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -3296,7 +3296,8 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, - if (fd_trans_host_to_target_data(fd)) { - ret = fd_trans_host_to_target_data(fd)(msg.msg_iov->iov_base, - MIN(msg.msg_iov->iov_len, len)); -- } else { -+ } -+ if (!is_error(ret)) { - ret = host_to_target_cmsg(msgp, &msg); - } - if (!is_error(ret)) { --- -2.27.0 - diff --git a/linux-user-fix-strace-build-w-out-munlockall.patch b/linux-user-fix-strace-build-w-out-munlockall.patch deleted file mode 100644 index f3e17ce1e47dbbf292796de5f9116ab105336422..0000000000000000000000000000000000000000 --- a/linux-user-fix-strace-build-w-out-munlockall.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c51eaedcf9833a6edfcee1993e6651046fad1f59 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Thu, 30 Mar 2023 18:07:11 +0800 -Subject: [PATCH] linux-user: fix strace build w/out munlockall -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from d237b416b9499441b6833b91609ec840efd832b6 - -Signed-off-by: qihao_yewu -Signed-off-by: Mike Frysinger -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20230118090144.31155-1-vapier@gentoo.org> -Signed-off-by: Laurent Vivier ---- - linux-user/strace.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/linux-user/strace.c b/linux-user/strace.c -index 2cdbf030ba..37d66d0dff 100644 ---- a/linux-user/strace.c -+++ b/linux-user/strace.c -@@ -1368,7 +1368,8 @@ UNUSED static struct flags termios_lflags[] = { - FLAG_END, - }; - --UNUSED static struct flags mlockall_flags[] = { -+#ifdef TARGET_NR_mlockall -+static struct flags mlockall_flags[] = { - FLAG_TARGET(MCL_CURRENT), - FLAG_TARGET(MCL_FUTURE), - #ifdef MCL_ONFAULT -@@ -1376,6 +1377,7 @@ UNUSED static struct flags mlockall_flags[] = { - #endif - FLAG_END, - }; -+#endif - - /* IDs of the various system clocks */ - #define TARGET_CLOCK_REALTIME 0 --- -2.27.0 - diff --git a/log-Add-log-at-boot-cpu-init-for-aarch64.patch b/log-Add-log-at-boot-cpu-init-for-aarch64.patch deleted file mode 100644 index 7e76bcffa4e89fbb6182946802ef38c08b9c9722..0000000000000000000000000000000000000000 --- a/log-Add-log-at-boot-cpu-init-for-aarch64.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 2d3abbcc8f6c6db582d931ba194b26dd7148849f Mon Sep 17 00:00:00 2001 -From: "wanghaibin.wang" -Date: Mon, 16 Oct 2017 18:01:59 +0800 -Subject: [PATCH 1/3] log: Add log at boot & cpu init for aarch64 - -Add log at boot & cpu init for aarch64 - -Signed-off-by: miaoyubo -Signed-off-by: Jingyi Wang ---- - hw/arm/boot.c | 4 ++++ - hw/arm/virt.c | 3 +++ - 2 files changed, 7 insertions(+) - -diff --git a/hw/arm/boot.c b/hw/arm/boot.c -index 74ad397b1f..21024f7999 100644 ---- a/hw/arm/boot.c -+++ b/hw/arm/boot.c -@@ -12,6 +12,7 @@ - #include "qemu/datadir.h" - #include "qemu/error-report.h" - #include "qapi/error.h" -+#include "qemu/log.h" - #include - #include "hw/arm/boot.h" - #include "hw/arm/linux-boot-if.h" -@@ -1317,6 +1318,9 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) - * doesn't support secure. - */ - assert(!(info->secure_board_setup && kvm_enabled())); -+ -+ qemu_log("load the kernel\n"); -+ - info->kernel_filename = ms->kernel_filename; - info->kernel_cmdline = ms->kernel_cmdline; - info->initrd_filename = ms->initrd_filename; -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 0538d258fa..47e98f09e8 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -33,6 +33,7 @@ - #include "qemu/datadir.h" - #include "qemu/units.h" - #include "qemu/option.h" -+#include "qemu/log.h" - #include "monitor/qdev.h" - #include "qapi/error.h" - #include "hw/sysbus.h" -@@ -971,6 +972,7 @@ static void virt_powerdown_req(Notifier *n, void *opaque) - { - VirtMachineState *s = container_of(n, VirtMachineState, powerdown_notifier); - -+ qemu_log("send powerdown to vm.\n"); - if (s->acpi_dev) { - acpi_send_event(s->acpi_dev, ACPI_POWER_DOWN_STATUS); - } else { -@@ -2072,6 +2074,7 @@ static void machvirt_init(MachineState *machine) - } - - create_fdt(vms); -+ qemu_log("cpu init start\n"); - - possible_cpus = mc->possible_cpu_arch_ids(machine); - assert(possible_cpus->len == max_cpus); --- -2.30.0 - diff --git a/log-Add-some-logs-on-VM-runtime-path.patch b/log-Add-some-logs-on-VM-runtime-path.patch deleted file mode 100644 index 90408a3a2a9971f29abee70b9907aa1e45ad22cf..0000000000000000000000000000000000000000 --- a/log-Add-some-logs-on-VM-runtime-path.patch +++ /dev/null @@ -1,170 +0,0 @@ -From d0ed3afacd2af1cbfcfb615471ade3c8c4185c00 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Tue, 8 Feb 2022 15:48:01 +0800 -Subject: [PATCH] log: Add some logs on VM runtime path - -Add logs on VM runtime path, to make it easier to do trouble shooting. - -Signed-off-by: Ying Fang -Signed-off-by: Yan Wang ---- - hw/virtio/virtio-pci.c | 2 ++ - hw/virtio/virtio.c | 14 ++++++++++++-- - monitor/monitor.c | 9 +++++++++ - qapi/qmp-dispatch.c | 15 +++++++++++++++ - softmmu/qdev-monitor.c | 4 +++- - 5 files changed, 41 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 750aa47ec1..38a5dc1ba8 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -1772,7 +1772,9 @@ static void virtio_pci_device_unplugged(DeviceState *d) - VirtIOPCIProxy *proxy = VIRTIO_PCI(d); - bool modern = virtio_pci_modern(proxy); - bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY; -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - -+ qemu_log("unplug device name: %s\n", !vdev ? "NULL" : vdev->name); - virtio_pci_stop_ioeventfd(proxy); - - if (modern) { -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index ea7c079fb0..9b4ac58a16 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -1945,7 +1945,14 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t val) - k->set_status(vdev, val); - } - vdev->status = val; -- -+ if (val) { -+ qemu_log("%s device status is %d that means %s\n", -+ vdev->name, val, -+ (val & VIRTIO_CONFIG_S_DRIVER_OK) ? "DRIVER OK" : -+ (val & VIRTIO_CONFIG_S_DRIVER) ? "DRIVER" : -+ (val & VIRTIO_CONFIG_S_ACKNOWLEDGE) ? "ACKNOWLEDGE" : -+ (val & VIRTIO_CONFIG_S_FAILED) ? "FAILED" : "UNKNOWN"); -+ } - return 0; - } - -@@ -2389,8 +2396,11 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, - break; - } - -- if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) -+ if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) { -+ qemu_log("unacceptable queue_size (%d) or num (%d)\n", -+ queue_size, i); - abort(); -+ } - - vdev->vq[i].vring.num = queue_size; - vdev->vq[i].vring.num_default = queue_size; -diff --git a/monitor/monitor.c b/monitor/monitor.c -index 21c7a68758..013c628695 100644 ---- a/monitor/monitor.c -+++ b/monitor/monitor.c -@@ -29,6 +29,7 @@ - #include "qapi/qapi-emit-events.h" - #include "qapi/qapi-visit-control.h" - #include "qapi/qmp/qdict.h" -+#include "qapi/qmp/qjson.h" - #include "qemu/error-report.h" - #include "qemu/option.h" - #include "sysemu/qtest.h" -@@ -318,6 +319,7 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) - { - Monitor *mon; - MonitorQMP *qmp_mon; -+ GString *json; - - trace_monitor_protocol_event_emit(event, qdict); - QTAILQ_FOREACH(mon, &mon_list, entry) { -@@ -328,6 +330,13 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict) - qmp_mon = container_of(mon, MonitorQMP, common); - if (qmp_mon->commands != &qmp_cap_negotiation_commands) { - qmp_send_response(qmp_mon, qdict); -+ json = qobject_to_json(QOBJECT(qdict)); -+ if (json) { -+ if (!strstr(json->str, "RTC_CHANGE")) { -+ qemu_log("%s\n", json->str); -+ } -+ g_string_free(json, true); -+ } - } - } - } -diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c -index d378bccac7..bb005594d3 100644 ---- a/qapi/qmp-dispatch.c -+++ b/qapi/qmp-dispatch.c -@@ -25,6 +25,7 @@ - #include "qapi/qmp/qbool.h" - #include "qemu/coroutine.h" - #include "qemu/main-loop.h" -+#include "qemu/log.h" - - Visitor *qobject_input_visitor_new_qmp(QObject *obj) - { -@@ -147,6 +148,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, - QObject *id; - QObject *ret = NULL; - QDict *rsp = NULL; -+ GString *json; - - dict = qobject_to(QDict, request); - if (!dict) { -@@ -204,6 +206,19 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, - qobject_ref(args); - } - -+ json = qobject_to_json(QOBJECT(args)); -+ if (json) { -+ if ((strcmp(command, "query-block-jobs") != 0) -+ && (strcmp(command, "query-migrate") != 0) -+ && (strcmp(command, "query-blockstats") != 0) -+ && (strcmp(command, "query-balloon") != 0) -+ && (strcmp(command, "set_password") != 0)) { -+ qemu_log("qmp_cmd_name: %s, arguments: %s\n", -+ command, json->str); -+ } -+ g_string_free(json, true); -+ } -+ - assert(!(oob && qemu_in_coroutine())); - assert(monitor_cur() == NULL); - if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) { -diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c -index 01f3834db5..dfd6429bf3 100644 ---- a/softmmu/qdev-monitor.c -+++ b/softmmu/qdev-monitor.c -@@ -36,6 +36,7 @@ - #include "qemu/option.h" - #include "qemu/qemu-print.h" - #include "qemu/option_int.h" -+#include "qemu/log.h" - #include "sysemu/block-backend.h" - #include "migration/misc.h" - #include "migration/migration.h" -@@ -635,6 +636,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, - if (path != NULL) { - bus = qbus_find(path, errp); - if (!bus) { -+ error_setg(errp, "can not find bus for %s", driver); - return NULL; - } - if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) { -@@ -707,7 +709,7 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, - if (*errp) { - goto err_del_dev; - } -- -+ qemu_log("add qdev %s:%s success\n", driver, dev->id ? dev->id : "none"); - if (!qdev_realize(DEVICE(dev), bus, errp)) { - goto err_del_dev; - } --- -2.27.0 - diff --git a/log-Delete-redudant-qemu_log.patch b/log-Delete-redudant-qemu_log.patch deleted file mode 100644 index cc9baab1c5be346226688063c857804ccbc8844f..0000000000000000000000000000000000000000 --- a/log-Delete-redudant-qemu_log.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4b195103bc1e38c05eb67cd230051463b6dff03f Mon Sep 17 00:00:00 2001 -From: Jingyi Wang -Date: Mon, 14 Feb 2022 14:42:05 +0800 -Subject: [PATCH] log: Delete redudant qemu_log - -Delete redudant qemu_log in qmp_dispatch() - -Signed-off-by: Jingyi Wang ---- - qapi/qmp-dispatch.c | 14 -------------- - 1 file changed, 14 deletions(-) - -diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c -index 392ddb097c..e9ea5a70d4 100644 ---- a/qapi/qmp-dispatch.c -+++ b/qapi/qmp-dispatch.c -@@ -222,20 +222,6 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request, - - assert(!(oob && qemu_in_coroutine())); - assert(monitor_cur() == NULL); -- -- json = qobject_to_json(QOBJECT(args)); -- if (json) { -- if ((strcmp(command, "query-block-jobs") != 0) -- && (strcmp(command, "query-migrate") != 0) -- && (strcmp(command, "query-blockstats") != 0) -- && (strcmp(command, "query-balloon") != 0) -- && (strcmp(command, "set_password") != 0)) { -- qemu_log("qmp_cmd_name: %s, arguments: %s\n", -- command, json->str); -- } -- g_string_free(json, true); -- } -- - if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) { - monitor_set_cur(qemu_coroutine_self(), cur_mon); - cmd->fn(args, &ret, &err); --- -2.27.0 - diff --git a/memory-Add-IOMMU_ATTR_MSI_TRANSLATE-IOMMU-memory-reg.patch b/memory-Add-IOMMU_ATTR_MSI_TRANSLATE-IOMMU-memory-reg.patch deleted file mode 100644 index b06bc2514357ceda3aeff221ef2095f43885ada1..0000000000000000000000000000000000000000 --- a/memory-Add-IOMMU_ATTR_MSI_TRANSLATE-IOMMU-memory-reg.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 062923fd4e6d11e1b724f2dd059f8b0c6e65bf7a Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Mon, 25 Mar 2019 16:35:05 +0100 -Subject: [PATCH] memory: Add IOMMU_ATTR_MSI_TRANSLATE IOMMU memory region - attribute - -We introduce a new IOMMU Memory Region attribute, IOMMU_ATTR_MSI_TRANSLATE -which tells whether the virtual IOMMU translates MSIs. ARM SMMU -will expose this attribute since, as opposed to Intel DMAR, MSIs -are translated as any other DMA requests. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - include/exec/memory.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 864bcaeb01..76ef99ed27 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -323,6 +323,7 @@ typedef struct MemoryRegionClass { - enum IOMMUMemoryRegionAttr { - IOMMU_ATTR_SPAPR_TCE_FD, - IOMMU_ATTR_VFIO_NESTED, -+ IOMMU_ATTR_MSI_TRANSLATE, - }; - - /* --- -2.27.0 - diff --git a/memory-Add-IOMMU_ATTR_VFIO_NESTED-IOMMU-memory-regio.patch b/memory-Add-IOMMU_ATTR_VFIO_NESTED-IOMMU-memory-regio.patch deleted file mode 100644 index bb27247096c8d16f63ff7c55a7cb2a6827dccd16..0000000000000000000000000000000000000000 --- a/memory-Add-IOMMU_ATTR_VFIO_NESTED-IOMMU-memory-regio.patch +++ /dev/null @@ -1,72 +0,0 @@ -From b380e3e0c30fb68dbbfb1397f3c374adfff77ac4 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Mon, 1 Jul 2019 11:30:30 +0200 -Subject: [PATCH] memory: Add IOMMU_ATTR_VFIO_NESTED IOMMU memory region - attribute - -We introduce a new IOMMU Memory Region attribute, -IOMMU_ATTR_VFIO_NESTED that tells whether the virtual IOMMU -requires HW nested paging for VFIO integration. - -Current Intel virtual IOMMU device supports "Caching -Mode" and does not require 2 stages at physical level to be -integrated with VFIO. However SMMUv3 does not implement such -"caching mode" and requires to use HW nested paging. - -As such SMMUv3 is the first IOMMU device to advertise this -attribute. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmuv3.c | 12 ++++++++++++ - include/exec/memory.h | 3 ++- - 2 files changed, 14 insertions(+), 1 deletion(-) - -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index da5dac1ba5..9b87d16217 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -1589,6 +1589,17 @@ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu, - return 0; - } - -+static int smmuv3_get_attr(IOMMUMemoryRegion *iommu, -+ enum IOMMUMemoryRegionAttr attr, -+ void *data) -+{ -+ if (attr == IOMMU_ATTR_VFIO_NESTED) { -+ *(bool *) data = true; -+ return 0; -+ } -+ return -EINVAL; -+} -+ - static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - void *data) - { -@@ -1596,6 +1607,7 @@ static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - - imrc->translate = smmuv3_translate; - imrc->notify_flag_changed = smmuv3_notify_flag_changed; -+ imrc->get_attr = smmuv3_get_attr; - } - - static const TypeInfo smmuv3_type_info = { -diff --git a/include/exec/memory.h b/include/exec/memory.h -index c3180075e1..864bcaeb01 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -321,7 +321,8 @@ typedef struct MemoryRegionClass { - - - enum IOMMUMemoryRegionAttr { -- IOMMU_ATTR_SPAPR_TCE_FD -+ IOMMU_ATTR_SPAPR_TCE_FD, -+ IOMMU_ATTR_VFIO_NESTED, - }; - - /* --- -2.27.0 - diff --git a/memory-Add-new-fields-in-IOTLBEntry.patch b/memory-Add-new-fields-in-IOTLBEntry.patch deleted file mode 100644 index 5a85dbfd61ecea58ff1942d24a004b2ed82e6fdd..0000000000000000000000000000000000000000 --- a/memory-Add-new-fields-in-IOTLBEntry.patch +++ /dev/null @@ -1,184 +0,0 @@ -From da97cef20d4ee5a8f3942953836b35e7f7dd974f Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 4 Sep 2018 08:43:05 -0400 -Subject: [PATCH] memory: Add new fields in IOTLBEntry - -The current IOTLBEntry becomes too simple to interact with -some physical IOMMUs. IOTLBs can be invalidated with different -granularities: domain, pasid, addr. Current IOTLB entry only offers -page selective invalidation. Let's add a granularity field -that conveys this information. - -TLB entries are usually tagged with some ids such as the asid -or pasid. When propagating an invalidation command from the -guest to the host, we need to pass those IDs. - -Also we add a leaf field which indicates, in case of invalidation -notification, whether only cache entries for the last level of -translation are required to be invalidated. - -A flag field is introduced to inform whether those fields are set. - -To enforce all existing users do not use those new fields, -initialize the IOMMUTLBEvents when needed. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/arm/smmu-common.c | 2 +- - hw/arm/smmuv3.c | 2 +- - hw/i386/intel_iommu.c | 6 +++--- - hw/ppc/spapr_iommu.c | 2 +- - hw/virtio/virtio-iommu.c | 4 ++-- - include/exec/memory.h | 36 +++++++++++++++++++++++++++++++++++- - 6 files changed, 43 insertions(+), 9 deletions(-) - -diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c -index 0459850a93..3a1ecf81d6 100644 ---- a/hw/arm/smmu-common.c -+++ b/hw/arm/smmu-common.c -@@ -470,7 +470,7 @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid) - /* Unmap the whole notifier's range */ - static void smmu_unmap_notifier_range(IOMMUNotifier *n) - { -- IOMMUTLBEvent event; -+ IOMMUTLBEvent event = {}; - - event.type = IOMMU_NOTIFIER_UNMAP; - event.entry.target_as = &address_space_memory; -diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c -index 01b60bee49..94e2c658f8 100644 ---- a/hw/arm/smmuv3.c -+++ b/hw/arm/smmuv3.c -@@ -802,7 +802,7 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, - uint8_t tg, uint64_t num_pages) - { - SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu); -- IOMMUTLBEvent event; -+ IOMMUTLBEvent event = {}; - uint8_t granule; - - if (!tg) { -diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c -index f584449d8d..fae282ef5e 100644 ---- a/hw/i386/intel_iommu.c -+++ b/hw/i386/intel_iommu.c -@@ -1193,7 +1193,7 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start, - uint32_t offset; - uint64_t slpte; - uint64_t subpage_size, subpage_mask; -- IOMMUTLBEvent event; -+ IOMMUTLBEvent event = {}; - uint64_t iova = start; - uint64_t iova_next; - int ret = 0; -@@ -2425,7 +2425,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s, - VTDInvDesc *inv_desc) - { - VTDAddressSpace *vtd_dev_as; -- IOMMUTLBEvent event; -+ IOMMUTLBEvent event = {}; - struct VTDBus *vtd_bus; - hwaddr addr; - uint64_t sz; -@@ -3481,7 +3481,7 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n) - size = remain = end - start + 1; - - while (remain >= VTD_PAGE_SIZE) { -- IOMMUTLBEvent event; -+ IOMMUTLBEvent event = {}; - uint64_t mask = dma_aligned_pow2_mask(start, end, s->aw_bits); - uint64_t size = mask + 1; - -diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c -index db01071858..454df25d44 100644 ---- a/hw/ppc/spapr_iommu.c -+++ b/hw/ppc/spapr_iommu.c -@@ -449,7 +449,7 @@ static void spapr_tce_reset(DeviceState *dev) - static target_ulong put_tce_emu(SpaprTceTable *tcet, target_ulong ioba, - target_ulong tce) - { -- IOMMUTLBEvent event; -+ IOMMUTLBEvent event = {}; - hwaddr page_mask = IOMMU_PAGE_MASK(tcet->page_shift); - unsigned long index = (ioba - tcet->bus_offset) >> tcet->page_shift; - -diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c -index 1b23e8e18c..83ed2b82e6 100644 ---- a/hw/virtio/virtio-iommu.c -+++ b/hw/virtio/virtio-iommu.c -@@ -129,7 +129,7 @@ static void virtio_iommu_notify_map(IOMMUMemoryRegion *mr, hwaddr virt_start, - hwaddr virt_end, hwaddr paddr, - uint32_t flags) - { -- IOMMUTLBEvent event; -+ IOMMUTLBEvent event = {}; - IOMMUAccessFlags perm = IOMMU_ACCESS_FLAG(flags & VIRTIO_IOMMU_MAP_F_READ, - flags & VIRTIO_IOMMU_MAP_F_WRITE); - -@@ -154,7 +154,7 @@ static void virtio_iommu_notify_map(IOMMUMemoryRegion *mr, hwaddr virt_start, - static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start, - hwaddr virt_end) - { -- IOMMUTLBEvent event; -+ IOMMUTLBEvent event = {}; - uint64_t delta = virt_end - virt_start; - - if (!(mr->iommu_notify_flags & IOMMU_NOTIFIER_UNMAP)) { -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 20f1b27377..c3180075e1 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -113,14 +113,48 @@ typedef enum { - IOMMU_RW = 3, - } IOMMUAccessFlags; - -+/* Granularity of the cache invalidation */ -+typedef enum { -+ IOMMU_INV_GRAN_ADDR = 0, -+ IOMMU_INV_GRAN_PASID, -+ IOMMU_INV_GRAN_DOMAIN, -+} IOMMUInvGranularity; -+ - #define IOMMU_ACCESS_FLAG(r, w) (((r) ? IOMMU_RO : 0) | ((w) ? IOMMU_WO : 0)) - -+/** -+ * struct IOMMUTLBEntry - IOMMU TLB entry -+ * -+ * Structure used when performing a translation or when notifying MAP or -+ * UNMAP (invalidation) events -+ * -+ * @target_as: target address space -+ * @iova: IO virtual address (input) -+ * @translated_addr: translated address (output) -+ * @addr_mask: address mask (0xfff means 4K binding), must be multiple of 2 -+ * @perm: permission flag of the mapping (NONE encodes no mapping or -+ * invalidation notification) -+ * @granularity: granularity of the invalidation -+ * @flags: informs whether the following fields are set -+ * @arch_id: architecture specific ID tagging the TLB -+ * @pasid: PASID tagging the TLB -+ * @leaf: when @perm is NONE, indicates whether only caches for the last -+ * level of translation need to be invalidated. -+ */ - struct IOMMUTLBEntry { - AddressSpace *target_as; - hwaddr iova; - hwaddr translated_addr; -- hwaddr addr_mask; /* 0xfff = 4k translation */ -+ hwaddr addr_mask; - IOMMUAccessFlags perm; -+ IOMMUInvGranularity granularity; -+#define IOMMU_INV_FLAGS_PASID (1 << 0) -+#define IOMMU_INV_FLAGS_ARCHID (1 << 1) -+#define IOMMU_INV_FLAGS_LEAF (1 << 2) -+ uint32_t flags; -+ uint32_t arch_id; -+ uint32_t pasid; -+ bool leaf; - }; - - /* --- -2.27.0 - diff --git a/memory-Fix-wrong-end-address-dump.patch b/memory-Fix-wrong-end-address-dump.patch deleted file mode 100644 index f6b073c8715e057e797c6003bcec219567670f1e..0000000000000000000000000000000000000000 --- a/memory-Fix-wrong-end-address-dump.patch +++ /dev/null @@ -1,62 +0,0 @@ -From de10e9df6bcb2d56dcfd2017e66593e6e62dbb22 Mon Sep 17 00:00:00 2001 -From: cmss_dx -Date: Tue, 22 Nov 2022 09:56:55 +0000 -Subject: [PATCH 01/29] memory: Fix wrong end address dump mainline inclusion - from mainline-v7.2.0-rc1 commit f9c307c3f9dfda64355fd2c6d73b002913d6752c - category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - --------------------------------- - -The end address of memory region section isn't correctly calculated -which leads to overflowed mtree dump: - - Dispatch - Physical sections - ...... - #70 @0000000000002000..0000000000011fff io [ROOT] - #71 @0000000000005000..0000000000005fff (noname) - #72 @0000000000005000..0000000000014fff io [ROOT] - #73 @0000000000005658..0000000000005658 vmport - #74 @0000000000005659..0000000000015658 io [ROOT] - #75 @0000000000006000..0000000000015fff io [ROOT] - -After fix: - #70 @0000000000002000..0000000000004fff io [ROOT] - #71 @0000000000005000..0000000000005fff (noname) - #72 @0000000000005000..0000000000005657 io [ROOT] - #73 @0000000000005658..0000000000005658 vmport - #74 @0000000000005659..0000000000005fff io [ROOT] - #75 @0000000000006000..000000000000ffff io [ROOT] - -Fixes: 5e8fd94 ("memory: Rework "info mtree" to print flat views and dispatch trees") -Signed-off-by: Zhenzhong Duan -Reviewed-by: David Hildenbrand -Reviewed-by: Peter Xu -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20220622095912.3430583-1-zhenzhong.duan@intel.com> -Signed-off-by: Philippe Mathieu-Daudé - -Signed-off-by: cmss_dx ---- - softmmu/physmem.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/softmmu/physmem.c b/softmmu/physmem.c -index 0e709ae384..e5c3557d54 100644 ---- a/softmmu/physmem.c -+++ b/softmmu/physmem.c -@@ -3719,7 +3719,7 @@ void mtree_print_dispatch(AddressSpaceDispatch *d, MemoryRegion *root) - " %s%s%s%s%s", - i, - s->offset_within_address_space, -- s->offset_within_address_space + MR_SIZE(s->mr->size), -+ s->offset_within_address_space + MR_SIZE(s->size), - s->mr->name ? s->mr->name : "(noname)", - i < ARRAY_SIZE(names) ? names[i] : "", - s->mr == root ? " [ROOT]" : "", --- -2.27.0 - diff --git a/memory-Introduce-IOMMU-Memory-Region-inject_faults-A.patch b/memory-Introduce-IOMMU-Memory-Region-inject_faults-A.patch deleted file mode 100644 index e541d9e69d716560a8d5636a25d072b3d05c765f..0000000000000000000000000000000000000000 --- a/memory-Introduce-IOMMU-Memory-Region-inject_faults-A.patch +++ /dev/null @@ -1,88 +0,0 @@ -From d2dce19165f133935ff72e209f19bc43ab4d1421 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 13 Sep 2018 14:13:04 +0200 -Subject: [PATCH] memory: Introduce IOMMU Memory Region inject_faults API - -This new API allows to inject @count iommu_faults into -the IOMMU memory region. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - include/exec/memory.h | 24 ++++++++++++++++++++++++ - softmmu/memory.c | 10 ++++++++++ - 2 files changed, 34 insertions(+) - -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 76ef99ed27..3e84d62e40 100644 ---- a/include/exec/memory.h -+++ b/include/exec/memory.h -@@ -103,6 +103,8 @@ struct MemoryRegionSection { - bool nonvolatile; - }; - -+struct iommu_fault; -+ - typedef struct IOMMUTLBEntry IOMMUTLBEntry; - - /* See address_space_translate: bit 0 is read, bit 1 is write. */ -@@ -523,6 +525,19 @@ struct IOMMUMemoryRegionClass { - int (*iommu_set_page_size_mask)(IOMMUMemoryRegion *iommu, - uint64_t page_size_mask, - Error **errp); -+ -+ /* -+ * Inject @count faults into the IOMMU memory region -+ * -+ * Optional method: if this method is not provided, then -+ * memory_region_injection_faults() will return -ENOENT -+ * -+ * @iommu: the IOMMU memory region to inject the faults in -+ * @count: number of faults to inject -+ * @buf: fault buffer -+ */ -+ int (*inject_faults)(IOMMUMemoryRegion *iommu, int count, -+ struct iommu_fault *buf); - }; - - typedef struct RamDiscardListener RamDiscardListener; -@@ -1819,6 +1834,15 @@ int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr); - int memory_region_iommu_set_page_size_mask(IOMMUMemoryRegion *iommu_mr, - uint64_t page_size_mask, - Error **errp); -+/** -+ * memory_region_inject_faults : inject @count faults stored in @buf -+ * -+ * @iommu_mr: the IOMMU memory region -+ * @count: number of faults to be injected -+ * @buf: buffer containing the faults -+ */ -+int memory_region_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, -+ struct iommu_fault *buf); - - /** - * memory_region_name: get a memory region's name -diff --git a/softmmu/memory.c b/softmmu/memory.c -index 7340e19ff5..9f98209ab2 100644 ---- a/softmmu/memory.c -+++ b/softmmu/memory.c -@@ -2111,6 +2111,16 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm, - rdmc->unregister_listener(rdm, rdl); - } - -+int memory_region_inject_faults(IOMMUMemoryRegion *iommu_mr, int count, -+ struct iommu_fault *buf) -+{ -+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr); -+ if (!imrc->inject_faults) { -+ return -ENOENT; -+ } -+ return imrc->inject_faults(iommu_mr, count, buf); -+} -+ - void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) - { - uint8_t mask = 1 << client; --- -2.27.0 - diff --git a/migration-Add-compress_level-sanity-check.patch b/migration-Add-compress_level-sanity-check.patch deleted file mode 100644 index 0839f6a467edb5b0f9adfd457edbcf8604a4f8d3..0000000000000000000000000000000000000000 --- a/migration-Add-compress_level-sanity-check.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 84780210ac31e430d59b0c6d3d9f522c626b6380 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Sat, 30 Jan 2021 16:23:15 +0800 -Subject: [PATCH 13/14] migration: Add compress_level sanity check - -Zlib compression has level from 1 to 9. However Zstd compression has level -from 1 to 22 (level >= 20 not recommanded). Let's do sanity check here -to make sure a vaild compress_level is given by user. - -Signed-off-by: Chuan Zheng -Signed-off-by: Zeyu Jin -Signed-off-by: Ying Fang ---- - migration/migration.c | 30 ++++++++++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - -diff --git a/migration/migration.c b/migration/migration.c -index 07dc059251..f86dd8cccd 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -1320,14 +1320,40 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, - } - } - -+static bool compress_level_check(MigrationParameters *params, Error **errp) -+{ -+ switch (params->compress_method) { -+ case COMPRESS_METHOD_ZLIB: -+ if (params->compress_level > 9 || params->compress_level < 1) { -+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", -+ "a value in the range of 0 to 9 for Zlib method"); -+ return false; -+ } -+ break; -+#ifdef CONFIG_ZSTD -+ case COMPRESS_METHOD_ZSTD: -+ if (params->compress_level > 19 || params->compress_level < 1) { -+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", -+ "a value in the range of 1 to 19 for Zstd method"); -+ return false; -+ } -+ break; -+#endif -+ default: -+ error_setg(errp, "Checking compress_level failed for unknown reason"); -+ return false; -+ } -+ -+ return true; -+} -+ - /* - * Check whether the parameters are valid. Error will be put into errp - * (if provided). Return true if valid, otherwise false. - */ - static bool migrate_params_check(MigrationParameters *params, Error **errp) - { -- if (params->has_compress_level && -- (params->compress_level > 9)) { -+ if (params->has_compress_level && !compress_level_check(params, errp)) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level", - "a value between 0 and 9"); - return false; --- -2.27.0 - diff --git a/migration-Add-multi-thread-compress-method.patch b/migration-Add-multi-thread-compress-method.patch deleted file mode 100644 index b25d78785979829b5ff7c75d3cea72ee87cdbc3b..0000000000000000000000000000000000000000 --- a/migration-Add-multi-thread-compress-method.patch +++ /dev/null @@ -1,238 +0,0 @@ -From 39d851b5d5517fbcecc8d16229ae72ca152899b7 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Sat, 30 Jan 2021 14:57:54 +0800 -Subject: [PATCH 09/14] migration: Add multi-thread compress method - -A multi-thread compress method parameter is added to hold the method we -are going to use. By default the 'zlib' method is used to maintain the -compatibility as before. - -Signed-off-by: Chuan Zheng -Signed-off-by: Zeyu Jin -Signed-off-by: Ying Fang ---- - hw/core/qdev-properties-system.c | 11 +++++++++++ - include/hw/qdev-properties.h | 4 ++++ - migration/migration.c | 11 +++++++++++ - monitor/hmp-cmds.c | 13 +++++++++++++ - qapi/migration.json | 26 +++++++++++++++++++++++++- - 5 files changed, 64 insertions(+), 1 deletion(-) - -diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c -index a91f60567a..8c265bed6f 100644 ---- a/hw/core/qdev-properties-system.c -+++ b/hw/core/qdev-properties-system.c -@@ -1119,3 +1119,14 @@ const PropertyInfo qdev_prop_uuid = { - .set = set_uuid, - .set_default_value = set_default_uuid_auto, - }; -+ -+/* --- CompressMethod --- */ -+const PropertyInfo qdev_prop_compress_method = { -+ .name = "CompressMethod", -+ .description = "multi-thread compression method, " -+ "zlib", -+ .enum_table = &CompressMethod_lookup, -+ .get = qdev_propinfo_get_enum, -+ .set = qdev_propinfo_set_enum, -+ .set_default_value = qdev_propinfo_set_default_value_enum, -+}; -diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h -index f7925f67d0..ea129d65a6 100644 ---- a/include/hw/qdev-properties.h -+++ b/include/hw/qdev-properties.h -@@ -58,6 +58,7 @@ extern const PropertyInfo qdev_prop_int64; - extern const PropertyInfo qdev_prop_size; - extern const PropertyInfo qdev_prop_string; - extern const PropertyInfo qdev_prop_on_off_auto; -+extern const PropertyInfo qdev_prop_compress_method; - extern const PropertyInfo qdev_prop_size32; - extern const PropertyInfo qdev_prop_arraylen; - extern const PropertyInfo qdev_prop_link; -@@ -161,6 +162,9 @@ extern const PropertyInfo qdev_prop_link; - DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*) - #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \ - DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto) -+#define DEFINE_PROP_COMPRESS_METHOD(_n, _s, _f, _d) \ -+ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_compress_method, \ -+ CompressMethod) - #define DEFINE_PROP_SIZE32(_n, _s, _f, _d) \ - DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size32, uint32_t) - -diff --git a/migration/migration.c b/migration/migration.c -index abaf6f9e3d..fa3db87d75 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -83,6 +83,7 @@ - #define DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT 2 - /*0: means nocompress, 1: best speed, ... 9: best compress ratio */ - #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1 -+#define DEFAULT_MIGRATE_COMPRESS_METHOD COMPRESS_METHOD_ZLIB - /* Define default autoconverge cpu throttle migration parameters */ - #define DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD 50 - #define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20 -@@ -855,6 +856,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp) - params->compress_wait_thread = s->parameters.compress_wait_thread; - params->has_decompress_threads = true; - params->decompress_threads = s->parameters.decompress_threads; -+ params->has_compress_method = true; -+ params->compress_method = s->parameters.compress_method; - params->has_throttle_trigger_threshold = true; - params->throttle_trigger_threshold = s->parameters.throttle_trigger_threshold; - params->has_cpu_throttle_initial = true; -@@ -1491,6 +1494,10 @@ static void migrate_params_test_apply(MigrateSetParameters *params, - dest->decompress_threads = params->decompress_threads; - } - -+ if (params->has_compress_method) { -+ dest->compress_method = params->compress_method; -+ } -+ - if (params->has_throttle_trigger_threshold) { - dest->throttle_trigger_threshold = params->throttle_trigger_threshold; - } -@@ -4159,6 +4166,9 @@ static Property migration_properties[] = { - DEFINE_PROP_UINT8("x-decompress-threads", MigrationState, - parameters.decompress_threads, - DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT), -+ DEFINE_PROP_COMPRESS_METHOD("compress-method", MigrationState, -+ parameters.compress_method, -+ DEFAULT_MIGRATE_COMPRESS_METHOD), - DEFINE_PROP_UINT8("x-throttle-trigger-threshold", MigrationState, - parameters.throttle_trigger_threshold, - DEFAULT_MIGRATE_THROTTLE_TRIGGER_THRESHOLD), -@@ -4275,6 +4285,7 @@ static void migration_instance_init(Object *obj) - params->has_compress_level = true; - params->has_compress_threads = true; - params->has_decompress_threads = true; -+ params->has_compress_method = true; - params->has_throttle_trigger_threshold = true; - params->has_cpu_throttle_initial = true; - params->has_cpu_throttle_increment = true; -diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c -index 9c91bf93e9..294652034e 100644 ---- a/monitor/hmp-cmds.c -+++ b/monitor/hmp-cmds.c -@@ -45,6 +45,7 @@ - #include "qapi/qapi-visit-net.h" - #include "qapi/qapi-visit-migration.h" - #include "qapi/qmp/qdict.h" -+#include "qapi/qapi-visit-migration.h" - #include "qapi/qmp/qerror.h" - #include "qapi/string-input-visitor.h" - #include "qapi/string-output-visitor.h" -@@ -429,6 +430,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict) - MigrationParameter_str(MIGRATION_PARAMETER_DECOMPRESS_THREADS), - params->decompress_threads); - assert(params->has_throttle_trigger_threshold); -+ monitor_printf(mon, "%s: %s\n", -+ MigrationParameter_str(MIGRATION_PARAMETER_COMPRESS_METHOD), -+ CompressMethod_str(params->compress_method)); - monitor_printf(mon, "%s: %u\n", - MigrationParameter_str(MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD), - params->throttle_trigger_threshold); -@@ -1191,6 +1195,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) - MigrateSetParameters *p = g_new0(MigrateSetParameters, 1); - uint64_t valuebw = 0; - uint64_t cache_size; -+ CompressMethod compress_method; - Error *err = NULL; - int val, ret; - -@@ -1216,6 +1221,14 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) - p->has_decompress_threads = true; - visit_type_uint8(v, param, &p->decompress_threads, &err); - break; -+ case MIGRATION_PARAMETER_COMPRESS_METHOD: -+ p->has_compress_method = true; -+ visit_type_CompressMethod(v, param, &compress_method, &err); -+ if (err) { -+ break; -+ } -+ p->compress_method = compress_method; -+ break; - case MIGRATION_PARAMETER_THROTTLE_TRIGGER_THRESHOLD: - p->has_throttle_trigger_threshold = true; - visit_type_uint8(v, param, &p->throttle_trigger_threshold, &err); -diff --git a/qapi/migration.json b/qapi/migration.json -index bbfd48cf0b..3a76907ea9 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -596,6 +596,19 @@ - 'bitmaps': [ 'BitmapMigrationBitmapAlias' ] - } } - -+## -+# @CompressMethod: -+# -+# An enumeration of multi-thread compression methods. -+# -+# @zlib: use zlib compression method. -+# -+# Since: 5.0 -+# -+## -+{ 'enum': 'CompressMethod', -+ 'data': [ 'zlib' ] } -+ - ## - # @MigrationParameter: - # -@@ -632,6 +645,9 @@ - # compression, so set the decompress-threads to the number about 1/4 - # of compress-threads is adequate. - # -+# @compress-method: Which multi-thread compression method to use. -+# Defaults to none. (Since 5.0) -+# - # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period - # to trigger throttling. It is expressed as percentage. - # The default value is 50. (Since 5.0) -@@ -758,7 +774,7 @@ - 'data': ['announce-initial', 'announce-max', - 'announce-rounds', 'announce-step', - 'compress-level', 'compress-threads', 'decompress-threads', -- 'compress-wait-thread', 'throttle-trigger-threshold', -+ 'compress-wait-thread', 'compress-method', 'throttle-trigger-threshold', - 'cpu-throttle-initial', 'cpu-throttle-increment', - 'cpu-throttle-tailslow', - 'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth', -@@ -797,6 +813,9 @@ - # - # @decompress-threads: decompression thread count - # -+# @compress-method: Set compression method to use in multi-thread compression. -+# Defaults to none. (Since 5.0) -+# - # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period - # to trigger throttling. It is expressed as percentage. - # The default value is 50. (Since 5.0) -@@ -930,6 +949,7 @@ - '*compress-threads': 'uint8', - '*compress-wait-thread': 'bool', - '*decompress-threads': 'uint8', -+ '*compress-method': 'CompressMethod', - '*throttle-trigger-threshold': 'uint8', - '*cpu-throttle-initial': 'uint8', - '*cpu-throttle-increment': 'uint8', -@@ -995,6 +1015,9 @@ - # - # @decompress-threads: decompression thread count - # -+# @compress-method: Which multi-thread compression method to use. -+# Defaults to none. (Since 5.0) -+# - # @throttle-trigger-threshold: The ratio of bytes_dirty_period and bytes_xfer_period - # to trigger throttling. It is expressed as percentage. - # The default value is 50. (Since 5.0) -@@ -1128,6 +1151,7 @@ - '*compress-threads': 'uint8', - '*compress-wait-thread': 'bool', - '*decompress-threads': 'uint8', -+ '*compress-method': 'CompressMethod', - '*throttle-trigger-threshold': 'uint8', - '*cpu-throttle-initial': 'uint8', - '*cpu-throttle-increment': 'uint8', --- -2.27.0 - diff --git a/migration-Add-multi-thread-compress-ops.patch b/migration-Add-multi-thread-compress-ops.patch deleted file mode 100644 index 6e3b6c178ae40a9b16df95dab7859a0434663d38..0000000000000000000000000000000000000000 --- a/migration-Add-multi-thread-compress-ops.patch +++ /dev/null @@ -1,443 +0,0 @@ -From 5e4bc7ceaf81a4932c92e479e9add947b698395b Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Sat, 30 Jan 2021 15:57:31 +0800 -Subject: [PATCH 11/14] migration: Add multi-thread compress ops - -Add the MigrationCompressOps and MigrationDecompressOps structures to make -the compression method configurable for multi-thread compression migration. - -Signed-off-by: Chuan Zheng -Signed-off-by: Zeyu Jin -Signed-off-by: Ying Fang ---- - migration/migration.c | 9 ++ - migration/migration.h | 1 + - migration/ram.c | 269 ++++++++++++++++++++++++++++++------------ - 3 files changed, 201 insertions(+), 78 deletions(-) - -diff --git a/migration/migration.c b/migration/migration.c -index fa3db87d75..07dc059251 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -2456,6 +2456,15 @@ int migrate_decompress_threads(void) - return s->parameters.decompress_threads; - } - -+CompressMethod migrate_compress_method(void) -+{ -+ MigrationState *s; -+ -+ s = migrate_get_current(); -+ -+ return s->parameters.compress_method; -+} -+ - bool migrate_dirty_bitmaps(void) - { - MigrationState *s; -diff --git a/migration/migration.h b/migration/migration.h -index 8130b703eb..4ed4f555da 100644 ---- a/migration/migration.h -+++ b/migration/migration.h -@@ -355,6 +355,7 @@ int migrate_compress_level(void); - int migrate_compress_threads(void); - int migrate_compress_wait_thread(void); - int migrate_decompress_threads(void); -+CompressMethod migrate_compress_method(void); - bool migrate_use_events(void); - bool migrate_postcopy_blocktime(void); - bool migrate_background_snapshot(void); -diff --git a/migration/ram.c b/migration/ram.c -index 1176816fba..069560e7f9 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -417,6 +417,9 @@ struct CompressParam { - /* internally used fields */ - z_stream stream; - uint8_t *originbuf; -+ -+ /* for zlib compression */ -+ z_stream stream; - }; - typedef struct CompressParam CompressParam; - -@@ -428,12 +431,29 @@ struct DecompressParam { - void *des; - uint8_t *compbuf; - int len; -+ -+ /* for zlib compression */ - z_stream stream; - }; - typedef struct DecompressParam DecompressParam; - -+typedef struct { -+ int (*save_setup)(CompressParam *param); -+ void (*save_cleanup)(CompressParam *param); -+ ssize_t (*compress_data)(CompressParam *param, size_t size); -+} MigrationCompressOps; -+ -+typedef struct { -+ int (*load_setup)(DecompressParam *param); -+ void (*load_cleanup)(DecompressParam *param); -+ int (*decompress_data)(DecompressParam *param, uint8_t *dest, size_t size); -+ int (*check_len)(int len); -+} MigrationDecompressOps; -+ - static CompressParam *comp_param; - static QemuThread *compress_threads; -+static MigrationCompressOps *compress_ops; -+static MigrationDecompressOps *decompress_ops; - /* comp_done_cond is used to wake up the migration thread when - * one of the compression threads has finished the compression. - * comp_done_lock is used to co-work with comp_done_cond. -@@ -451,6 +471,157 @@ static QemuCond decomp_done_cond; - - static bool do_compress_ram_page(CompressParam *param, RAMBlock *block); - -+static int zlib_save_setup(CompressParam *param) -+{ -+ if (deflateInit(¶m->stream, -+ migrate_compress_level()) != Z_OK) { -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static ssize_t zlib_compress_data(CompressParam *param, size_t size) -+ -+ int err; -+ uint8_t *dest = NULL; -+ z_stream *stream = ¶m->stream; -+ uint8_t *p = param->originbuf; -+ QEMUFile *f = f = param->file; -+ ssize_t blen = qemu_put_compress_start(f, &dest); -+ -+ if (blen < compressBound(size)) { -+ return -1; -+ } -+ -+ err = deflateReset(stream); -+ if (err != Z_OK) { -+ return -1; -+ } -+ -+ stream->avail_in = size; -+ stream->next_in = p; -+ stream->avail_out = blen; -+ stream->next_out = dest; -+ -+ err = deflate(stream, Z_FINISH); -+ if (err != Z_STREAM_END) { -+ return -1; -+ } -+ -+ blen = stream->next_out - dest; -+ if (blen < 0) { -+ return -1; -+ } -+ -+ qemu_put_compress_end(f, blen); -+ return blen + sizeof(int32_t); -+} -+ -+static void zlib_save_cleanup(CompressParam *param) -+{ -+ deflateEnd(¶m->stream); -+} -+ -+static int zlib_load_setup(DecompressParam *param) -+{ -+ if (inflateInit(¶m->stream) != Z_OK) { -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int -+zlib_decompress_data(DecompressParam *param, uint8_t *dest, size_t size) -+{ -+ int err; -+ -+ z_stream *stream = ¶m->stream; -+ -+ err = inflateReset(stream); -+ if (err != Z_OK) { -+ return -1; -+ } -+ -+ stream->avail_in = param->len; -+ stream->next_in = param->compbuf; -+ stream->avail_out = size; -+ stream->next_out = dest; -+ -+ err = inflate(stream, Z_NO_FLUSH); -+ if (err != Z_STREAM_END) { -+ return -1; -+ } -+ -+ return stream->total_out; -+} -+ -+static void zlib_load_cleanup(DecompressParam *param) -+{ -+ inflateEnd(¶m->stream); -+} -+ -+static int zlib_check_len(int len) -+{ -+ return len < 0 || len > compressBound(TARGET_PAGE_SIZE); -+} -+ -+static int set_compress_ops(void) -+{ -+ compress_ops = g_new0(MigrationCompressOps, 1); -+ -+ switch (migrate_compress_method()) { -+ case COMPRESS_METHOD_ZLIB: -+ compress_ops->save_setup = zlib_save_setup; -+ compress_ops->save_cleanup = zlib_save_cleanup; -+ compress_ops->compress_data = zlib_compress_data; -+ break; -+ default: -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int set_decompress_ops(void) -+{ -+ decompress_ops = g_new0(MigrationDecompressOps, 1); -+ -+ switch (migrate_compress_method()) { -+ case COMPRESS_METHOD_ZLIB: -+ decompress_ops->load_setup = zlib_load_setup; -+ decompress_ops->load_cleanup = zlib_load_cleanup; -+ decompress_ops->decompress_data = zlib_decompress_data; -+ decompress_ops->check_len = zlib_check_len; -+ break; -+ default: -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static void clean_compress_ops(void) -+{ -+ compress_ops->save_setup = NULL; -+ compress_ops->save_cleanup = NULL; -+ compress_ops->compress_data = NULL; -+ -+ g_free(compress_ops); -+ compress_ops = NULL; -+} -+ -+static void clean_decompress_ops(void) -+{ -+ decompress_ops->load_setup = NULL; -+ decompress_ops->load_cleanup = NULL; -+ decompress_ops->decompress_data = NULL; -+ -+ g_free(decompress_ops); -+ decompress_ops = NULL; -+} -+ - static void *do_data_compress(void *opaque) - { - CompressParam *param = opaque; -@@ -508,7 +679,7 @@ static void compress_threads_save_cleanup(void) - qemu_thread_join(compress_threads + i); - qemu_mutex_destroy(&comp_param[i].mutex); - qemu_cond_destroy(&comp_param[i].cond); -- deflateEnd(&comp_param[i].stream); -+ compress_ops->save_cleanup(&comp_param[i]); - g_free(comp_param[i].originbuf); - qemu_fclose(comp_param[i].file); - comp_param[i].file = NULL; -@@ -519,6 +690,7 @@ static void compress_threads_save_cleanup(void) - g_free(comp_param); - compress_threads = NULL; - comp_param = NULL; -+ clean_compress_ops(); - } - - static int compress_threads_save_setup(void) -@@ -528,6 +700,12 @@ static int compress_threads_save_setup(void) - if (!migrate_use_compression()) { - return 0; - } -+ -+ if (set_compress_ops() < 0) { -+ clean_compress_ops(); -+ return -1; -+ } -+ - thread_count = migrate_compress_threads(); - compress_threads = g_new0(QemuThread, thread_count); - comp_param = g_new0(CompressParam, thread_count); -@@ -539,8 +717,7 @@ static int compress_threads_save_setup(void) - goto exit; - } - -- if (deflateInit(&comp_param[i].stream, -- migrate_compress_level()) != Z_OK) { -+ if (compress_ops->save_setup(&comp_param[i]) < 0) { - g_free(comp_param[i].originbuf); - goto exit; - } -@@ -1338,50 +1515,6 @@ static int ram_save_multifd_page(RAMState *rs, RAMBlock *block, - return 1; - } - --/* -- * Compress size bytes of data start at p and store the compressed -- * data to the buffer of f. -- * -- * Since the file is dummy file with empty_ops, return -1 if f has no space to -- * save the compressed data. -- */ --static ssize_t qemu_put_compression_data(CompressParam *param, size_t size) --{ -- int err; -- uint8_t *dest = NULL; -- z_stream *stream = ¶m->stream; -- uint8_t *p = param->originbuf; -- QEMUFile *f = f = param->file; -- ssize_t blen = qemu_put_compress_start(f, &dest); -- -- if (blen < compressBound(size)) { -- return -1; -- } -- -- err = deflateReset(stream); -- if (err != Z_OK) { -- return -1; -- } -- -- stream->avail_in = size; -- stream->next_in = p; -- stream->avail_out = blen; -- stream->next_out = dest; -- -- err = deflate(stream, Z_FINISH); -- if (err != Z_STREAM_END) { -- return -1; -- } -- -- blen = stream->next_out - dest; -- if (blen < 0) { -- return -1; -- } -- -- qemu_put_compress_end(f, blen); -- return blen + sizeof(int32_t); --} -- - static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) - { - RAMState *rs = ram_state; -@@ -1404,7 +1537,7 @@ static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) - * decompression - */ - memcpy(param->originbuf, p, TARGET_PAGE_SIZE); -- ret = qemu_put_compression_data(param, TARGET_PAGE_SIZE); -+ ret = compress_ops->compress_data(param, TARGET_PAGE_SIZE); - if (ret < 0) { - qemu_file_set_error(migrate_get_current()->to_dst_file, ret); - error_report("compressed data failed!"); -@@ -3413,32 +3546,6 @@ void ram_handle_compressed(void *host, uint8_t ch, uint64_t size) - } - } - --/* return the size after decompression, or negative value on error */ --static int --qemu_uncompress_data(DecompressParam *param, uint8_t *dest, size_t pagesize) --{ -- int err; -- -- z_stream *stream = ¶m->stream; -- -- err = inflateReset(stream); -- if (err != Z_OK) { -- return -1; -- } -- -- stream->avail_in = param->len; -- stream->next_in = param->compbuf; -- stream->avail_out = pagesize; -- stream->next_out = dest; -- -- err = inflate(stream, Z_NO_FLUSH); -- if (err != Z_STREAM_END) { -- return -1; -- } -- -- return stream->total_out; --} -- - static void *do_data_decompress(void *opaque) - { - DecompressParam *param = opaque; -@@ -3452,7 +3559,7 @@ static void *do_data_decompress(void *opaque) - param->des = 0; - qemu_mutex_unlock(¶m->mutex); - -- ret = qemu_uncompress_data(param, des, TARGET_PAGE_SIZE); -+ ret = decompress_ops->decompress_data(param, des, TARGET_PAGE_SIZE); - if (ret < 0 && migrate_get_current()->decompress_error_check) { - error_report("decompress data failed"); - qemu_file_set_error(decomp_file, ret); -@@ -3522,7 +3629,7 @@ static void compress_threads_load_cleanup(void) - qemu_thread_join(decompress_threads + i); - qemu_mutex_destroy(&decomp_param[i].mutex); - qemu_cond_destroy(&decomp_param[i].cond); -- inflateEnd(&decomp_param[i].stream); -+ decompress_ops->load_cleanup(&decomp_param[i]); - g_free(decomp_param[i].compbuf); - decomp_param[i].compbuf = NULL; - } -@@ -3531,6 +3638,7 @@ static void compress_threads_load_cleanup(void) - decompress_threads = NULL; - decomp_param = NULL; - decomp_file = NULL; -+ clean_decompress_ops(); - } - - static int compress_threads_load_setup(QEMUFile *f) -@@ -3541,6 +3649,11 @@ static int compress_threads_load_setup(QEMUFile *f) - return 0; - } - -+ if (set_decompress_ops() < 0) { -+ clean_decompress_ops(); -+ return -1; -+ } -+ - thread_count = migrate_decompress_threads(); - decompress_threads = g_new0(QemuThread, thread_count); - decomp_param = g_new0(DecompressParam, thread_count); -@@ -3548,7 +3661,7 @@ static int compress_threads_load_setup(QEMUFile *f) - qemu_cond_init(&decomp_done_cond); - decomp_file = f; - for (i = 0; i < thread_count; i++) { -- if (inflateInit(&decomp_param[i].stream) != Z_OK) { -+ if (decompress_ops->load_setup(&decomp_param[i]) < 0) { - goto exit; - } - -@@ -4156,7 +4269,7 @@ static int ram_load_precopy(QEMUFile *f) - - case RAM_SAVE_FLAG_COMPRESS_PAGE: - len = qemu_get_be32(f); -- if (len < 0 || len > compressBound(TARGET_PAGE_SIZE)) { -+ if (decompress_ops->check_len(len)) { - error_report("Invalid compressed data length: %d", len); - ret = -EINVAL; - break; --- -2.27.0 - diff --git a/migration-Add-zstd-support-in-multi-thread-compressi.patch b/migration-Add-zstd-support-in-multi-thread-compressi.patch deleted file mode 100644 index 416e2becfe69b9f00a9fa89a0fe5f998405274df..0000000000000000000000000000000000000000 --- a/migration-Add-zstd-support-in-multi-thread-compressi.patch +++ /dev/null @@ -1,239 +0,0 @@ -From bafba05f7405ba31213120d99679cc4b6c1be68e Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Sat, 30 Jan 2021 16:15:10 +0800 -Subject: [PATCH 12/14] migration: Add zstd support in multi-thread compression - -This patch enables zstd option in multi-thread compression. - -Signed-off-by: Chuan Zheng -Signed-off-by: Zeyu Jin -Signed-off-by: Ying Fang ---- - hw/core/qdev-properties-system.c | 2 +- - migration/ram.c | 131 ++++++++++++++++++++++++++++++- - qapi/migration.json | 3 +- - 3 files changed, 132 insertions(+), 4 deletions(-) - -diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c -index 8c265bed6f..6a6ff03be7 100644 ---- a/hw/core/qdev-properties-system.c -+++ b/hw/core/qdev-properties-system.c -@@ -1124,7 +1124,7 @@ const PropertyInfo qdev_prop_uuid = { - const PropertyInfo qdev_prop_compress_method = { - .name = "CompressMethod", - .description = "multi-thread compression method, " -- "zlib", -+ "zlib/zstd", - .enum_table = &CompressMethod_lookup, - .get = qdev_propinfo_get_enum, - .set = qdev_propinfo_set_enum, -diff --git a/migration/ram.c b/migration/ram.c -index 069560e7f9..c3484ee1a9 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -62,6 +62,11 @@ - #include "qemu/userfaultfd.h" - #endif /* defined(__linux__) */ - -+#ifdef CONFIG_ZSTD -+#include -+#include -+#endif -+ - /***********************************************************/ - /* ram save/restore */ - -@@ -415,11 +420,16 @@ struct CompressParam { - ram_addr_t offset; - - /* internally used fields */ -- z_stream stream; - uint8_t *originbuf; - - /* for zlib compression */ - z_stream stream; -+ -+#ifdef CONFIG_ZSTD -+ ZSTD_CStream *zstd_cs; -+ ZSTD_inBuffer in; -+ ZSTD_outBuffer out; -+#endif - }; - typedef struct CompressParam CompressParam; - -@@ -434,6 +444,11 @@ struct DecompressParam { - - /* for zlib compression */ - z_stream stream; -+#ifdef CONFIG_ZSTD -+ ZSTD_DStream *zstd_ds; -+ ZSTD_inBuffer in; -+ ZSTD_outBuffer out; -+#endif - }; - typedef struct DecompressParam DecompressParam; - -@@ -482,7 +497,7 @@ static int zlib_save_setup(CompressParam *param) - } - - static ssize_t zlib_compress_data(CompressParam *param, size_t size) -- -+{ - int err; - uint8_t *dest = NULL; - z_stream *stream = ¶m->stream; -@@ -567,6 +582,103 @@ static int zlib_check_len(int len) - return len < 0 || len > compressBound(TARGET_PAGE_SIZE); - } - -+#ifdef CONFIG_ZSTD -+static int zstd_save_setup(CompressParam *param) -+{ -+ int res; -+ param->zstd_cs = ZSTD_createCStream(); -+ if (!param->zstd_cs) { -+ return -1; -+ } -+ res = ZSTD_initCStream(param->zstd_cs, migrate_compress_level()); -+ if (ZSTD_isError(res)) { -+ return -1; -+ } -+ return 0; -+} -+static void zstd_save_cleanup(CompressParam *param) -+{ -+ ZSTD_freeCStream(param->zstd_cs); -+ param->zstd_cs = NULL; -+} -+static ssize_t zstd_compress_data(CompressParam *param, size_t size) -+{ -+ int ret; -+ uint8_t *dest = NULL; -+ uint8_t *p = param->originbuf; -+ QEMUFile *f = f = param->file; -+ ssize_t blen = qemu_put_compress_start(f, &dest); -+ if (blen < ZSTD_compressBound(size)) { -+ return -1; -+ } -+ param->out.dst = dest; -+ param->out.size = blen; -+ param->out.pos = 0; -+ param->in.src = p; -+ param->in.size = size; -+ param->in.pos = 0; -+ do { -+ ret = ZSTD_compressStream2(param->zstd_cs, ¶m->out, -+ ¶m->in, ZSTD_e_end); -+ } while (ret > 0 && (param->in.size - param->in.pos > 0) -+ && (param->out.size - param->out.pos > 0)); -+ if (ret > 0 && (param->in.size - param->in.pos > 0)) { -+ return -1; -+ } -+ if (ZSTD_isError(ret)) { -+ return -1; -+ } -+ blen = param->out.pos; -+ qemu_put_compress_end(f, blen); -+ return blen + sizeof(int32_t); -+} -+ -+static int zstd_load_setup(DecompressParam *param) -+{ -+ int ret; -+ param->zstd_ds = ZSTD_createDStream(); -+ if (!param->zstd_ds) { -+ return -1; -+ } -+ ret = ZSTD_initDStream(param->zstd_ds); -+ if (ZSTD_isError(ret)) { -+ return -1; -+ } -+ return 0; -+} -+static void zstd_load_cleanup(DecompressParam *param) -+{ -+ ZSTD_freeDStream(param->zstd_ds); -+ param->zstd_ds = NULL; -+} -+static int -+zstd_decompress_data(DecompressParam *param, uint8_t *dest, size_t size) -+{ -+ int ret; -+ param->out.dst = dest; -+ param->out.size = size; -+ param->out.pos = 0; -+ param->in.src = param->compbuf; -+ param->in.size = param->len; -+ param->in.pos = 0; -+ do { -+ ret = ZSTD_decompressStream(param->zstd_ds, ¶m->out, ¶m->in); -+ } while (ret > 0 && (param->in.size - param->in.pos > 0) -+ && (param->out.size - param->out.pos > 0)); -+ if (ret > 0 && (param->in.size - param->in.pos > 0)) { -+ return -1; -+ } -+ if (ZSTD_isError(ret)) { -+ return -1; -+ } -+ return ret; -+} -+static int zstd_check_len(int len) -+{ -+ return len < 0 || len > ZSTD_compressBound(TARGET_PAGE_SIZE); -+} -+#endif -+ - static int set_compress_ops(void) - { - compress_ops = g_new0(MigrationCompressOps, 1); -@@ -577,6 +689,13 @@ static int set_compress_ops(void) - compress_ops->save_cleanup = zlib_save_cleanup; - compress_ops->compress_data = zlib_compress_data; - break; -+#ifdef CONFIG_ZSTD -+ case COMPRESS_METHOD_ZSTD: -+ compress_ops->save_setup = zstd_save_setup; -+ compress_ops->save_cleanup = zstd_save_cleanup; -+ compress_ops->compress_data = zstd_compress_data; -+ break; -+#endif - default: - return -1; - } -@@ -595,6 +714,14 @@ static int set_decompress_ops(void) - decompress_ops->decompress_data = zlib_decompress_data; - decompress_ops->check_len = zlib_check_len; - break; -+#ifdef CONFIG_ZSTD -+ case COMPRESS_METHOD_ZSTD: -+ decompress_ops->load_setup = zstd_load_setup; -+ decompress_ops->load_cleanup = zstd_load_cleanup; -+ decompress_ops->decompress_data = zstd_decompress_data; -+ decompress_ops->check_len = zstd_check_len; -+ break; -+#endif - default: - return -1; - } -diff --git a/qapi/migration.json b/qapi/migration.json -index 3a76907ea9..d4ebc5f028 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -602,12 +602,13 @@ - # An enumeration of multi-thread compression methods. - # - # @zlib: use zlib compression method. -+# @zstd: use zstd compression method. - # - # Since: 5.0 - # - ## - { 'enum': 'CompressMethod', -- 'data': [ 'zlib' ] } -+ 'data': [ 'zlib', { 'name': 'zstd', 'if': 'CONFIG_ZSTD' } ] } - - ## - # @MigrationParameter: --- -2.27.0 - diff --git a/migration-Refactoring-multi-thread-compress-migratio.patch b/migration-Refactoring-multi-thread-compress-migratio.patch deleted file mode 100644 index 35f697bd5b2bbe079e4fd3886365064c5b710be4..0000000000000000000000000000000000000000 --- a/migration-Refactoring-multi-thread-compress-migratio.patch +++ /dev/null @@ -1,289 +0,0 @@ -From b871594aa1798ddcc7f5124e5b3e1c5d858c155c Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Sat, 30 Jan 2021 15:21:17 +0800 -Subject: [PATCH 10/14] migration: Refactoring multi-thread compress migration - -Code refactor for the compression procedure which includes: - -1. Move qemu_compress_data and qemu_put_compression_data from qemu-file.c to -ram.c, for the reason that most part of the code logical has nothing to do -with qemu-file. Besides, the decompression code is located at ram.c only. - -2. Simplify the function input arguments for compression and decompression. -Wrap the input into the param structure which already exists. This change also -makes the function much more flexible for other compression methods. - -Signed-off-by: Chuan Zheng -Signed-off-by: Zeyu Jin -Signed-off-by: Ying Fang ---- - migration/qemu-file.c | 61 ++++++------------------------- - migration/qemu-file.h | 4 +- - migration/ram.c | 85 +++++++++++++++++++++++++++++++------------ - 3 files changed, 75 insertions(+), 75 deletions(-) - -diff --git a/migration/qemu-file.c b/migration/qemu-file.c -index 6338d8e2ff..e07026da4f 100644 ---- a/migration/qemu-file.c -+++ b/migration/qemu-file.c -@@ -745,55 +745,6 @@ uint64_t qemu_get_be64(QEMUFile *f) - return v; - } - --/* return the size after compression, or negative value on error */ --static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len, -- const uint8_t *source, size_t source_len) --{ -- int err; -- -- err = deflateReset(stream); -- if (err != Z_OK) { -- return -1; -- } -- -- stream->avail_in = source_len; -- stream->next_in = (uint8_t *)source; -- stream->avail_out = dest_len; -- stream->next_out = dest; -- -- err = deflate(stream, Z_FINISH); -- if (err != Z_STREAM_END) { -- return -1; -- } -- -- return stream->next_out - dest; --} -- --/* Compress size bytes of data start at p and store the compressed -- * data to the buffer of f. -- * -- * Since the file is dummy file with empty_ops, return -1 if f has no space to -- * save the compressed data. -- */ --ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, -- const uint8_t *p, size_t size) --{ -- ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t); -- -- if (blen < compressBound(size)) { -- return -1; -- } -- -- blen = qemu_compress_data(stream, f->buf + f->buf_index + sizeof(int32_t), -- blen, p, size); -- if (blen < 0) { -- return -1; -- } -- -- qemu_put_be32(f, blen); -- add_buf_to_iovec(f, blen); -- return blen + sizeof(int32_t); --} - - /* Put the data in the buffer of f_src to the buffer of f_des, and - * then reset the buf_index of f_src to 0. -@@ -866,3 +817,15 @@ QIOChannel *qemu_file_get_ioc(QEMUFile *file) - { - return file->has_ioc ? QIO_CHANNEL(file->opaque) : NULL; - } -+ -+ssize_t qemu_put_compress_start(QEMUFile *f, uint8_t **dest_ptr) -+{ -+ *dest_ptr = f->buf + f->buf_index + sizeof(int32_t); -+ return IO_BUF_SIZE - f->buf_index - sizeof(int32_t); -+} -+ -+void qemu_put_compress_end(QEMUFile *f, unsigned int v) -+{ -+ qemu_put_be32(f, v); -+ add_buf_to_iovec(f, v); -+} -diff --git a/migration/qemu-file.h b/migration/qemu-file.h -index 3f36d4dc8c..617a1373ad 100644 ---- a/migration/qemu-file.h -+++ b/migration/qemu-file.h -@@ -139,8 +139,6 @@ bool qemu_file_is_writable(QEMUFile *f); - - size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset); - size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size); --ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, -- const uint8_t *p, size_t size); - int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src); - - /* -@@ -167,6 +165,8 @@ void ram_control_before_iterate(QEMUFile *f, uint64_t flags); - void ram_control_after_iterate(QEMUFile *f, uint64_t flags); - void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data); - -+ssize_t qemu_put_compress_start(QEMUFile *f, uint8_t **dest_ptr); -+void qemu_put_compress_end(QEMUFile *f, unsigned int v); - /* Whenever this is found in the data stream, the flags - * will be passed to ram_control_load_hook in the incoming-migration - * side. This lets before_ram_iterate/after_ram_iterate add -diff --git a/migration/ram.c b/migration/ram.c -index 863035d235..1176816fba 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -449,26 +449,22 @@ static QemuThread *decompress_threads; - static QemuMutex decomp_done_lock; - static QemuCond decomp_done_cond; - --static bool do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, -- ram_addr_t offset, uint8_t *source_buf); -+static bool do_compress_ram_page(CompressParam *param, RAMBlock *block); - - static void *do_data_compress(void *opaque) - { - CompressParam *param = opaque; - RAMBlock *block; -- ram_addr_t offset; - bool zero_page; - - qemu_mutex_lock(¶m->mutex); - while (!param->quit) { - if (param->block) { - block = param->block; -- offset = param->offset; - param->block = NULL; - qemu_mutex_unlock(¶m->mutex); - -- zero_page = do_compress_ram_page(param->file, ¶m->stream, -- block, offset, param->originbuf); -+ zero_page = do_compress_ram_page(param, block); - - qemu_mutex_lock(&comp_done_lock); - param->done = true; -@@ -1342,28 +1338,73 @@ static int ram_save_multifd_page(RAMState *rs, RAMBlock *block, - return 1; - } - --static bool do_compress_ram_page(QEMUFile *f, z_stream *stream, RAMBlock *block, -- ram_addr_t offset, uint8_t *source_buf) -+/* -+ * Compress size bytes of data start at p and store the compressed -+ * data to the buffer of f. -+ * -+ * Since the file is dummy file with empty_ops, return -1 if f has no space to -+ * save the compressed data. -+ */ -+static ssize_t qemu_put_compression_data(CompressParam *param, size_t size) -+{ -+ int err; -+ uint8_t *dest = NULL; -+ z_stream *stream = ¶m->stream; -+ uint8_t *p = param->originbuf; -+ QEMUFile *f = f = param->file; -+ ssize_t blen = qemu_put_compress_start(f, &dest); -+ -+ if (blen < compressBound(size)) { -+ return -1; -+ } -+ -+ err = deflateReset(stream); -+ if (err != Z_OK) { -+ return -1; -+ } -+ -+ stream->avail_in = size; -+ stream->next_in = p; -+ stream->avail_out = blen; -+ stream->next_out = dest; -+ -+ err = deflate(stream, Z_FINISH); -+ if (err != Z_STREAM_END) { -+ return -1; -+ } -+ -+ blen = stream->next_out - dest; -+ if (blen < 0) { -+ return -1; -+ } -+ -+ qemu_put_compress_end(f, blen); -+ return blen + sizeof(int32_t); -+} -+ -+static bool do_compress_ram_page(CompressParam *param, RAMBlock *block) - { - RAMState *rs = ram_state; -+ ram_addr_t offset = param->offset; - uint8_t *p = block->host + (offset & TARGET_PAGE_MASK); - bool zero_page = false; - int ret; - -- if (save_zero_page_to_file(rs, f, block, offset)) { -+ if (save_zero_page_to_file(rs, param->file, block, offset)) { - zero_page = true; - goto exit; - } - -- save_page_header(rs, f, block, offset | RAM_SAVE_FLAG_COMPRESS_PAGE); -+ save_page_header(rs, param->file, block, -+ offset | RAM_SAVE_FLAG_COMPRESS_PAGE); - - /* - * copy it to a internal buffer to avoid it being modified by VM - * so that we can catch up the error during compression and - * decompression - */ -- memcpy(source_buf, p, TARGET_PAGE_SIZE); -- ret = qemu_put_compression_data(f, stream, source_buf, TARGET_PAGE_SIZE); -+ memcpy(param->originbuf, p, TARGET_PAGE_SIZE); -+ ret = qemu_put_compression_data(param, TARGET_PAGE_SIZE); - if (ret < 0) { - qemu_file_set_error(migrate_get_current()->to_dst_file, ret); - error_report("compressed data failed!"); -@@ -3374,19 +3415,20 @@ void ram_handle_compressed(void *host, uint8_t ch, uint64_t size) - - /* return the size after decompression, or negative value on error */ - static int --qemu_uncompress_data(z_stream *stream, uint8_t *dest, size_t dest_len, -- const uint8_t *source, size_t source_len) -+qemu_uncompress_data(DecompressParam *param, uint8_t *dest, size_t pagesize) - { - int err; - -+ z_stream *stream = ¶m->stream; -+ - err = inflateReset(stream); - if (err != Z_OK) { - return -1; - } - -- stream->avail_in = source_len; -- stream->next_in = (uint8_t *)source; -- stream->avail_out = dest_len; -+ stream->avail_in = param->len; -+ stream->next_in = param->compbuf; -+ stream->avail_out = pagesize; - stream->next_out = dest; - - err = inflate(stream, Z_NO_FLUSH); -@@ -3400,22 +3442,17 @@ qemu_uncompress_data(z_stream *stream, uint8_t *dest, size_t dest_len, - static void *do_data_decompress(void *opaque) - { - DecompressParam *param = opaque; -- unsigned long pagesize; - uint8_t *des; -- int len, ret; -+ int ret; - - qemu_mutex_lock(¶m->mutex); - while (!param->quit) { - if (param->des) { - des = param->des; -- len = param->len; - param->des = 0; - qemu_mutex_unlock(¶m->mutex); - -- pagesize = TARGET_PAGE_SIZE; -- -- ret = qemu_uncompress_data(¶m->stream, des, pagesize, -- param->compbuf, len); -+ ret = qemu_uncompress_data(param, des, TARGET_PAGE_SIZE); - if (ret < 0 && migrate_get_current()->decompress_error_check) { - error_report("decompress data failed"); - qemu_file_set_error(decomp_file, ret); --- -2.27.0 - diff --git a/migration-Set-downtime_start-even-for-postcopy.patch b/migration-Set-downtime_start-even-for-postcopy.patch deleted file mode 100644 index 8aa72cb45c29beb8604b2910a892100f5fd04ae4..0000000000000000000000000000000000000000 --- a/migration-Set-downtime_start-even-for-postcopy.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 9708192479d7f6507392a338f8f43b3be4c8188d Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 18 Dec 2023 15:19:48 +0800 -Subject: [PATCH] migration: Set downtime_start even for postcopy - -cheery-pick from 62f5da7dd10a594fb30cebb5569dc738456f7131 - -Postcopy calculates its downtime separately. It always sets -MigrationState.downtime properly, but not MigrationState.downtime_start. - -Make postcopy do the same as other modes on properly recording the -timestamp when the VM is going to be stopped. Drop the temporary variable -in postcopy_start() along the way. - -Signed-off-by: Peter Xu -Reviewed-by: Fabiano Rosas -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -Message-ID: <20231030163346.765724-2-peterx@redhat.com> -Signed-off-by: qihao_yewu ---- - migration/migration.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/migration/migration.c b/migration/migration.c -index 6b5445853a..7ca5b58839 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -2989,7 +2989,6 @@ static int postcopy_start(MigrationState *ms) - int ret; - QIOChannelBuffer *bioc; - QEMUFile *fb; -- int64_t time_at_stop = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); - int64_t bandwidth = migrate_max_postcopy_bandwidth(); - bool restart_block = false; - int cur_state = MIGRATION_STATUS_ACTIVE; -@@ -3002,6 +3001,8 @@ static int postcopy_start(MigrationState *ms) - qemu_mutex_lock_iothread(); - trace_postcopy_start_set_run(); - -+ ms->downtime_start = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); -+ - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL); - global_state_store(); - ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); -@@ -3112,7 +3113,7 @@ static int postcopy_start(MigrationState *ms) - ms->postcopy_after_devices = true; - notifier_list_notify(&migration_state_notifiers, ms); - -- ms->downtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - time_at_stop; -+ ms->downtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - ms->downtime_start; - - qemu_mutex_unlock_iothread(); - --- -2.27.0 - diff --git a/migration-colo-More-accurate-update-checkpoint-time.patch b/migration-colo-More-accurate-update-checkpoint-time.patch deleted file mode 100644 index 21a4aad3d6658494bfcfd01464eaf09af55d8837..0000000000000000000000000000000000000000 --- a/migration-colo-More-accurate-update-checkpoint-time.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 3577b5c059bd3f83d47f72ef400e85160d56bc58 Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Fri, 1 Dec 2023 11:11:43 +0800 -Subject: [PATCH] migration/colo: More accurate update checkpoint time - -cherry picked from commit 0e0f0479e28c6c1a1d024b2e5200cade479d6901 - -Previous operation(like vm_start and replication_start_all) will consume -extra time before update the timer, so reduce time in this patch. - -Signed-off-by: Zhang Chen -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -Signed-off-by: Luo Yifan ---- - migration/colo.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/migration/colo.c b/migration/colo.c -index 2415325262..c8fadae956 100644 ---- a/migration/colo.c -+++ b/migration/colo.c -@@ -530,7 +530,6 @@ static void colo_process_checkpoint(MigrationState *s) - { - QIOChannelBuffer *bioc; - QEMUFile *fb = NULL; -- int64_t current_time = qemu_clock_get_ms(QEMU_CLOCK_HOST); - Error *local_err = NULL; - int ret; - -@@ -578,8 +577,8 @@ static void colo_process_checkpoint(MigrationState *s) - qemu_mutex_unlock_iothread(); - trace_colo_vm_state_change("stop", "run"); - -- timer_mod(s->colo_delay_timer, -- current_time + s->parameters.x_checkpoint_delay); -+ timer_mod(s->colo_delay_timer, qemu_clock_get_ms(QEMU_CLOCK_HOST) + -+ s->parameters.x_checkpoint_delay); - - while (s->state == MIGRATION_STATUS_COLO) { - if (failover_get_state() != FAILOVER_STATUS_NONE) { --- -2.27.0 - diff --git a/migration-dirtyrate-Refactor-dirty-page-rate-calcula.patch b/migration-dirtyrate-Refactor-dirty-page-rate-calcula.patch deleted file mode 100644 index 28097efe8306024337ef04bb3c44d6497abbfbec..0000000000000000000000000000000000000000 --- a/migration-dirtyrate-Refactor-dirty-page-rate-calcula.patch +++ /dev/null @@ -1,399 +0,0 @@ -From b6d1e022b7bb06faf2dcad3062b7061b59ef68a9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Sun, 26 Jun 2022 01:38:32 +0800 -Subject: [PATCH 3/3] migration/dirtyrate: Refactor dirty page rate calculation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -abstract out dirty log change logic into function -global_dirty_log_change. - -abstract out dirty page rate calculation logic via -dirty-ring into function vcpu_calculate_dirtyrate. - -abstract out mathematical dirty page rate calculation -into do_calculate_dirtyrate, decouple it from DirtyStat. - -rename set_sample_page_period to dirty_stat_wait, which -is well-understood and will be reused in dirtylimit. - -handle cpu hotplug/unplug scenario during measurement of -dirty page rate. - -export util functions outside migration. - -Signed-off-by: Hyman Huang(黄勇) -Reviewed-by: Peter Xu -Message-Id: <7b6f6f4748d5b3d017b31a0429e630229ae97538.1656177590.git.huangy81@chinatelecom.cn> -Signed-off-by: Dr. David Alan Gilbert ---- - include/sysemu/dirtyrate.h | 28 +++++ - migration/dirtyrate.c | 227 +++++++++++++++++++++++-------------- - migration/dirtyrate.h | 7 +- - 3 files changed, 174 insertions(+), 88 deletions(-) - create mode 100644 include/sysemu/dirtyrate.h - -diff --git a/include/sysemu/dirtyrate.h b/include/sysemu/dirtyrate.h -new file mode 100644 -index 0000000000..4d3b9a4902 ---- /dev/null -+++ b/include/sysemu/dirtyrate.h -@@ -0,0 +1,28 @@ -+/* -+ * dirty page rate helper functions -+ * -+ * Copyright (c) 2022 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_DIRTYRATE_H -+#define QEMU_DIRTYRATE_H -+ -+typedef struct VcpuStat { -+ int nvcpu; /* number of vcpu */ -+ DirtyRateVcpu *rates; /* array of dirty rate for each vcpu */ -+} VcpuStat; -+ -+int64_t vcpu_calculate_dirtyrate(int64_t calc_time_ms, -+ VcpuStat *stat, -+ unsigned int flag, -+ bool one_shot); -+ -+void global_dirty_log_change(unsigned int flag, -+ bool start); -+#endif -diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c -index 8043bc7946..c449095fc3 100644 ---- a/migration/dirtyrate.c -+++ b/migration/dirtyrate.c -@@ -46,7 +46,7 @@ static struct DirtyRateStat DirtyStat; - static DirtyRateMeasureMode dirtyrate_mode = - DIRTY_RATE_MEASURE_MODE_PAGE_SAMPLING; - --static int64_t set_sample_page_period(int64_t msec, int64_t initial_time) -+static int64_t dirty_stat_wait(int64_t msec, int64_t initial_time) - { - int64_t current_time; - -@@ -60,6 +60,132 @@ static int64_t set_sample_page_period(int64_t msec, int64_t initial_time) - return msec; - } - -+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 int64_t do_calculate_dirtyrate(DirtyPageRecord dirty_pages, -+ int64_t calc_time_ms) -+{ -+ uint64_t memory_size_MB; -+ uint64_t increased_dirty_pages = -+ dirty_pages.end_pages - dirty_pages.start_pages; -+ -+ memory_size_MB = (increased_dirty_pages * TARGET_PAGE_SIZE) >> 20; -+ -+ return memory_size_MB * 1000 / calc_time_ms; -+} -+ -+void global_dirty_log_change(unsigned int flag, bool start) -+{ -+ qemu_mutex_lock_iothread(); -+ if (start) { -+ memory_global_dirty_log_start(flag); -+ } else { -+ memory_global_dirty_log_stop(flag); -+ } -+ qemu_mutex_unlock_iothread(); -+} -+ -+/* -+ * global_dirty_log_sync -+ * 1. sync dirty log from kvm -+ * 2. stop dirty tracking if needed. -+ */ -+static void global_dirty_log_sync(unsigned int flag, bool one_shot) -+{ -+ qemu_mutex_lock_iothread(); -+ memory_global_dirty_log_sync(); -+ if (one_shot) { -+ memory_global_dirty_log_stop(flag); -+ } -+ qemu_mutex_unlock_iothread(); -+} -+ -+static DirtyPageRecord *vcpu_dirty_stat_alloc(VcpuStat *stat) -+{ -+ CPUState *cpu; -+ DirtyPageRecord *records; -+ int nvcpu = 0; -+ -+ CPU_FOREACH(cpu) { -+ nvcpu++; -+ } -+ -+ stat->nvcpu = nvcpu; -+ stat->rates = g_malloc0(sizeof(DirtyRateVcpu) * nvcpu); -+ -+ records = g_malloc0(sizeof(DirtyPageRecord) * nvcpu); -+ -+ return records; -+} -+ -+static void vcpu_dirty_stat_collect(VcpuStat *stat, -+ DirtyPageRecord *records, -+ bool start) -+{ -+ CPUState *cpu; -+ -+ CPU_FOREACH(cpu) { -+ record_dirtypages(records, cpu, start); -+ } -+} -+ -+int64_t vcpu_calculate_dirtyrate(int64_t calc_time_ms, -+ VcpuStat *stat, -+ unsigned int flag, -+ bool one_shot) -+{ -+ DirtyPageRecord *records; -+ int64_t init_time_ms; -+ int64_t duration; -+ int64_t dirtyrate; -+ int i = 0; -+ unsigned int gen_id; -+ -+retry: -+ init_time_ms = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); -+ -+ cpu_list_lock(); -+ gen_id = cpu_list_generation_id_get(); -+ records = vcpu_dirty_stat_alloc(stat); -+ vcpu_dirty_stat_collect(stat, records, true); -+ cpu_list_unlock(); -+ -+ duration = dirty_stat_wait(calc_time_ms, init_time_ms); -+ -+ global_dirty_log_sync(flag, one_shot); -+ -+ cpu_list_lock(); -+ if (gen_id != cpu_list_generation_id_get()) { -+ g_free(records); -+ g_free(stat->rates); -+ cpu_list_unlock(); -+ goto retry; -+ } -+ vcpu_dirty_stat_collect(stat, records, false); -+ cpu_list_unlock(); -+ -+ for (i = 0; i < stat->nvcpu; i++) { -+ dirtyrate = do_calculate_dirtyrate(records[i], duration); -+ -+ stat->rates[i].id = i; -+ stat->rates[i].dirty_rate = dirtyrate; -+ -+ trace_dirtyrate_do_calculate_vcpu(i, dirtyrate); -+ } -+ -+ g_free(records); -+ -+ return duration; -+} -+ - static bool is_sample_period_valid(int64_t sec) - { - if (sec < MIN_FETCH_DIRTYRATE_TIME_SEC || -@@ -396,44 +522,6 @@ static bool compare_page_hash_info(struct RamblockDirtyInfo *info, - return true; - } - --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 dirtyrate_global_dirty_log_start(void) --{ -- qemu_mutex_lock_iothread(); -- memory_global_dirty_log_start(GLOBAL_DIRTY_DIRTY_RATE); -- qemu_mutex_unlock_iothread(); --} -- --static void dirtyrate_global_dirty_log_stop(void) --{ -- qemu_mutex_lock_iothread(); -- memory_global_dirty_log_sync(); -- memory_global_dirty_log_stop(GLOBAL_DIRTY_DIRTY_RATE); -- qemu_mutex_unlock_iothread(); --} -- --static int64_t do_calculate_dirtyrate_vcpu(DirtyPageRecord dirty_pages) --{ -- uint64_t memory_size_MB; -- int64_t time_s; -- uint64_t increased_dirty_pages = -- dirty_pages.end_pages - dirty_pages.start_pages; -- -- memory_size_MB = (increased_dirty_pages * TARGET_PAGE_SIZE) >> 20; -- time_s = DirtyStat.calc_time; -- -- return memory_size_MB / time_s; --} -- - static inline void record_dirtypages_bitmap(DirtyPageRecord *dirty_pages, - bool start) - { -@@ -444,11 +532,6 @@ static inline void record_dirtypages_bitmap(DirtyPageRecord *dirty_pages, - } - } - --static void do_calculate_dirtyrate_bitmap(DirtyPageRecord dirty_pages) --{ -- DirtyStat.dirty_rate = do_calculate_dirtyrate_vcpu(dirty_pages); --} -- - static inline void dirtyrate_manual_reset_protect(void) - { - RAMBlock *block = NULL; -@@ -492,71 +575,49 @@ static void calculate_dirtyrate_dirty_bitmap(struct DirtyRateConfig config) - DirtyStat.start_time = start_time / 1000; - - msec = config.sample_period_seconds * 1000; -- msec = set_sample_page_period(msec, start_time); -+ msec = dirty_stat_wait(msec, start_time); - DirtyStat.calc_time = msec / 1000; - - /* -- * dirtyrate_global_dirty_log_stop do two things. -+ * do two things. - * 1. fetch dirty bitmap from kvm - * 2. stop dirty tracking - */ -- dirtyrate_global_dirty_log_stop(); -+ global_dirty_log_sync(GLOBAL_DIRTY_DIRTY_RATE, true); - - record_dirtypages_bitmap(&dirty_pages, false); - -- do_calculate_dirtyrate_bitmap(dirty_pages); -+ DirtyStat.dirty_rate = do_calculate_dirtyrate(dirty_pages, msec); - } - - static void calculate_dirtyrate_dirty_ring(struct DirtyRateConfig config) - { -- CPUState *cpu; -- int64_t msec = 0; -- int64_t start_time; -+ int64_t duration; - uint64_t dirtyrate = 0; - uint64_t dirtyrate_sum = 0; -- DirtyPageRecord *dirty_pages; -- int nvcpu = 0; - int i = 0; - -- CPU_FOREACH(cpu) { -- nvcpu++; -- } -- -- dirty_pages = g_new(DirtyPageRecord, nvcpu); -- -- DirtyStat.dirty_ring.nvcpu = nvcpu; -- DirtyStat.dirty_ring.rates = g_new(DirtyRateVcpu, nvcpu); -- -- dirtyrate_global_dirty_log_start(); -- -- CPU_FOREACH(cpu) { -- record_dirtypages(dirty_pages, cpu, true); -- } -- -- start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); -- DirtyStat.start_time = start_time / 1000; -+ /* start log sync */ -+ global_dirty_log_change(GLOBAL_DIRTY_DIRTY_RATE, true); - -- msec = config.sample_period_seconds * 1000; -- msec = set_sample_page_period(msec, start_time); -- DirtyStat.calc_time = msec / 1000; -+ DirtyStat.start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000; - -- dirtyrate_global_dirty_log_stop(); -+ /* calculate vcpu dirtyrate */ -+ duration = vcpu_calculate_dirtyrate(config.sample_period_seconds * 1000, -+ &DirtyStat.dirty_ring, -+ GLOBAL_DIRTY_DIRTY_RATE, -+ true); - -- CPU_FOREACH(cpu) { -- record_dirtypages(dirty_pages, cpu, false); -- } -+ DirtyStat.calc_time = duration / 1000; - -+ /* calculate vm dirtyrate */ - for (i = 0; i < DirtyStat.dirty_ring.nvcpu; i++) { -- dirtyrate = do_calculate_dirtyrate_vcpu(dirty_pages[i]); -- trace_dirtyrate_do_calculate_vcpu(i, dirtyrate); -- -- DirtyStat.dirty_ring.rates[i].id = i; -+ dirtyrate = DirtyStat.dirty_ring.rates[i].dirty_rate; - DirtyStat.dirty_ring.rates[i].dirty_rate = dirtyrate; - dirtyrate_sum += dirtyrate; - } - - DirtyStat.dirty_rate = dirtyrate_sum; -- g_free(dirty_pages); - } - - static void calculate_dirtyrate_sample_vm(struct DirtyRateConfig config) -@@ -574,7 +635,7 @@ static void calculate_dirtyrate_sample_vm(struct DirtyRateConfig config) - rcu_read_unlock(); - - msec = config.sample_period_seconds * 1000; -- msec = set_sample_page_period(msec, initial_time); -+ msec = dirty_stat_wait(msec, initial_time); - DirtyStat.start_time = initial_time / 1000; - DirtyStat.calc_time = msec / 1000; - -diff --git a/migration/dirtyrate.h b/migration/dirtyrate.h -index 69d4c5b865..594a5c0bb6 100644 ---- a/migration/dirtyrate.h -+++ b/migration/dirtyrate.h -@@ -13,6 +13,8 @@ - #ifndef QEMU_MIGRATION_DIRTYRATE_H - #define QEMU_MIGRATION_DIRTYRATE_H - -+#include "sysemu/dirtyrate.h" -+ - /* - * Sample 512 pages per GB as default. - */ -@@ -65,11 +67,6 @@ typedef struct SampleVMStat { - uint64_t total_block_mem_MB; /* size of total sampled pages in MB */ - } SampleVMStat; - --typedef struct VcpuStat { -- int nvcpu; /* number of vcpu */ -- DirtyRateVcpu *rates; /* array of dirty rate for each vcpu */ --} VcpuStat; -- - /* - * Store calculation statistics for each measure. - */ --- -2.27.0 - diff --git a/migration-dirtyrate-Replace-malloc-with-g_new.patch b/migration-dirtyrate-Replace-malloc-with-g_new.patch deleted file mode 100644 index 9e146a4a40b05ca9c747b3fd82854b7f82ac0209..0000000000000000000000000000000000000000 --- a/migration-dirtyrate-Replace-malloc-with-g_new.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 7cb2d342b9073ec9548202df6e1fb25fa4997d71 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Thu, 30 Jun 2022 11:34:50 +0000 -Subject: [PATCH] migration/dirtyrate: Replace malloc with g_new Using macro - g_new() to handling potential memory allocation failures in dirtyrate. - ---- - migration/dirtyrate.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/migration/dirtyrate.c b/migration/dirtyrate.c -index d65e744af9..8043bc7946 100644 ---- a/migration/dirtyrate.c -+++ b/migration/dirtyrate.c -@@ -157,7 +157,7 @@ static void cleanup_dirtyrate_stat(struct DirtyRateConfig config) - { - /* last calc-dirty-rate qmp use dirty ring mode */ - if (dirtyrate_mode == DIRTY_RATE_MEASURE_MODE_DIRTY_RING) { -- free(DirtyStat.dirty_ring.rates); -+ g_free(DirtyStat.dirty_ring.rates); - DirtyStat.dirty_ring.rates = NULL; - } - } -@@ -522,10 +522,10 @@ static void calculate_dirtyrate_dirty_ring(struct DirtyRateConfig config) - nvcpu++; - } - -- dirty_pages = malloc(sizeof(*dirty_pages) * nvcpu); -+ dirty_pages = g_new(DirtyPageRecord, nvcpu); - - DirtyStat.dirty_ring.nvcpu = nvcpu; -- DirtyStat.dirty_ring.rates = malloc(sizeof(DirtyRateVcpu) * nvcpu); -+ DirtyStat.dirty_ring.rates = g_new(DirtyRateVcpu, nvcpu); - - dirtyrate_global_dirty_log_start(); - -@@ -556,7 +556,7 @@ static void calculate_dirtyrate_dirty_ring(struct DirtyRateConfig config) - } - - DirtyStat.dirty_rate = dirtyrate_sum; -- free(dirty_pages); -+ g_free(dirty_pages); - } - - static void calculate_dirtyrate_sample_vm(struct DirtyRateConfig config) --- -2.27.0 - diff --git a/migration-fix-RAMBlock-add-NULL-check.patch b/migration-fix-RAMBlock-add-NULL-check.patch deleted file mode 100644 index 88cd6302d3f9e1a30451484121effcc9c5687a10..0000000000000000000000000000000000000000 --- a/migration-fix-RAMBlock-add-NULL-check.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 03569a14e7ae428bad59a4e11637c900ff436816 Mon Sep 17 00:00:00 2001 -From: jipengfei -Date: Mon, 18 Dec 2023 16:56:15 +0800 -Subject: [PATCH] migration: fix RAMBlock add NULL check - -qemu_ram_block_from_host() may return NULL, which will be dereferenced w/o -check. Usualy return value is checked for this function. -Found by Linux Verification Center (linuxtesting.org) with SVACE. - -cheery-pick from f75ed59f40bed3ce94adad4b3ebbb7bfacfdf4ab - -Signed-off-by: jipengfei_yewu -Signed-off-by: Dmitry Frolov -Reviewed-by: Fabiano Rosas -Reviewed-by: Peter Xu -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -Message-ID: <20231010104851.802947-1-frolov@swemel.ru> ---- - migration/ram.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/migration/ram.c b/migration/ram.c -index 862955f5b2..c245b04cf2 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -4679,6 +4679,11 @@ static void ram_mig_ram_block_resized(RAMBlockNotifier *n, void *host, - RAMBlock *rb = qemu_ram_block_from_host(host, false, &offset); - Error *err = NULL; - -+ if (!rb) { -+ error_report("RAM block not found"); -+ return; -+ } -+ - if (ramblock_is_ignored(rb)) { - return; - } --- -2.27.0 - diff --git a/migration-fix-populate_vfio_info.patch b/migration-fix-populate_vfio_info.patch deleted file mode 100644 index 8ac94db08e51ac914f150acab64e5d6be82061ff..0000000000000000000000000000000000000000 --- a/migration-fix-populate_vfio_info.patch +++ /dev/null @@ -1,49 +0,0 @@ -From bae3be01cc25c5532806c3255dbae19393e95686 Mon Sep 17 00:00:00 2001 -From: jipengfei -Date: Tue, 4 Apr 2023 20:16:33 +0800 -Subject: [PATCH] migration: fix populate_vfio_info -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Include CONFIG_DEVICES so that populate_vfio_info is instantiated for -CONFIG_VFIO. Without it, the 'info migrate' command never returns -info about vfio. - -Fixes: 43bd0bf30f ("migration: Move populate_vfio_info() into a separate file") - -cheery-pick from fa76c854ae837328187bef41d80af5d1ad36681f - -Signed-off-by: jipengfei_yewu -Reviewed-by: Marc-André Lureau -Reviewed-by: Thomas Huth -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela ---- - migration/target.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/migration/target.c b/migration/target.c -index 907ebf0a0a..00ca007f97 100644 ---- a/migration/target.c -+++ b/migration/target.c -@@ -8,6 +8,7 @@ - #include "qemu/osdep.h" - #include "qapi/qapi-types-migration.h" - #include "migration.h" -+#include CONFIG_DEVICES - - #ifdef CONFIG_VFIO - #include "hw/vfio/vfio-common.h" -@@ -17,7 +18,6 @@ void populate_vfio_info(MigrationInfo *info) - { - #ifdef CONFIG_VFIO - if (vfio_mig_active()) { -- info->has_vfio = true; - info->vfio = g_malloc0(sizeof(*info->vfio)); - info->vfio->transferred = vfio_mig_bytes_transferred(); - } --- -2.27.0 - diff --git a/migration-ram-Fix-error-handling-in-ram_write_tracki.patch b/migration-ram-Fix-error-handling-in-ram_write_tracki.patch deleted file mode 100644 index 73664338daf96c29244651ec53955a20ed628241..0000000000000000000000000000000000000000 --- a/migration-ram-Fix-error-handling-in-ram_write_tracki.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 93fc70a80b9734301472bb827cf3685366bfeb19 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Fri, 28 Jul 2023 10:39:55 +0800 -Subject: [PATCH] migration/ram: Fix error handling in - ram_write_tracking_start() - -cherry picked from commit 72ef3a370836aa07261ad7aaeea27ed5cbcee342 - -If something goes wrong during uffd_change_protection(), we would miss -to unregister uffd-wp and not release our reference. Fix it by -performing the uffd_change_protection(true) last. - -Note that a uffd_change_protection(false) on the recovery path without a -prior uffd_change_protection(false) is fine. - -Fixes: 278e2f551a09 ("migration: support UFFD write fault processing in ram_save_iterate()") -Cc: qemu-stable@nongnu.org -Reviewed-by: Peter Xu -Reviewed-by: Juan Quintela -Signed-off-by: David Hildenbrand -Signed-off-by: Juan Quintela -Signed-off-by: qihao_yewu ---- - migration/ram.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/migration/ram.c b/migration/ram.c -index 12b8c653d8..f422fd0bc2 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2140,13 +2140,14 @@ int ram_write_tracking_start(void) - block->max_length, UFFDIO_REGISTER_MODE_WP, NULL)) { - goto fail; - } -+ block->flags |= RAM_UF_WRITEPROTECT; -+ memory_region_ref(block->mr); -+ - /* Apply UFFD write protection to the block memory range */ - if (uffd_change_protection(rs->uffdio_fd, block->host, - block->max_length, true, false)) { - goto fail; - } -- block->flags |= RAM_UF_WRITEPROTECT; -- memory_region_ref(block->mr); - - trace_ram_write_tracking_ramblock_start(block->idstr, block->page_size, - block->host, block->max_length); --- -2.41.0.windows.1 - diff --git a/migration-ram-Fix-populate_read_range.patch b/migration-ram-Fix-populate_read_range.patch deleted file mode 100644 index 97e1488d65881a7d9422cbda96699abffae37a37..0000000000000000000000000000000000000000 --- a/migration-ram-Fix-populate_read_range.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 069ad2e6d5ce48c96519ff55ace2ca2bcdac94d5 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Thu, 27 Jul 2023 13:26:21 +0800 -Subject: [PATCH] migration/ram: Fix populate_read_range() - -cheery-pick from 5f19a4491941fdc5c5b50ce4ade6ffffe0f591b4 - -Unfortunately, commit f7b9dcfbcf44 broke populate_read_range(): the loop -end condition is very wrong, resulting in that function not populating the -full range. Lets' fix that. - -Fixes: f7b9dcfbcf44 ("migration/ram: Factor out populating pages readable in ram_block_populate_pages()") -Cc: qemu-stable@nongnu.org -Reviewed-by: Peter Xu -Reviewed-by: Juan Quintela -Signed-off-by: David Hildenbrand -Signed-off-by: Juan Quintela -Signed-off-by: qihao_yewu ---- - migration/ram.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/migration/ram.c b/migration/ram.c -index 12b8c653d8..444b6a7aa2 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -2020,13 +2020,15 @@ out: - static inline void populate_read_range(RAMBlock *block, ram_addr_t offset, - ram_addr_t size) - { -+ const ram_addr_t end = offset + size; -+ - /* - * We read one byte of each page; this will preallocate page tables if - * required and populate the shared zeropage on MAP_PRIVATE anonymous memory - * where no page was populated yet. This might require adaption when - * supporting other mappings, like shmem. - */ -- for (; offset < size; offset += block->page_size) { -+ for (; offset < end; offset += block->page_size) { - char tmp = *((char *)block->host + offset); - - /* Don't optimize the read out */ --- -2.41.0.windows.1 - diff --git a/migration-rdma-zore-out-head.repeat-to-make-the-erro.patch b/migration-rdma-zore-out-head.repeat-to-make-the-erro.patch deleted file mode 100644 index b6a630aea9df6ff570ba8c35e1050279a8ae0b92..0000000000000000000000000000000000000000 --- a/migration-rdma-zore-out-head.repeat-to-make-the-erro.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e65dfad1fd7832fc206f3a22479169fcb4527317 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 9 Oct 2023 18:11:54 +0800 -Subject: [PATCH] migration/rdma: zore out head.repeat to make the error more - clear - -cheery-pick from 2ada4b63f1764d13a2b9ca9cbeb5feda46ab6851 - -Previously, we got a confusion error that complains -the RDMAControlHeader.repeat: -qemu-system-x86_64: rdma: Too many requests in this message (3638950032).Bailing. - -Actually, it's caused by an unexpected RDMAControlHeader.type. -After this patch, error will become: -qemu-system-x86_64: Unknown control message QEMU FILE - -Reviewed-by: Fabiano Rosas -Reviewed-by: Peter Xu -Reviewed-by: Juan Quintela -Signed-off-by: Li Zhijian -Signed-off-by: Juan Quintela -Message-ID: <20230926100103.201564-2-lizhijian@fujitsu.com> -Signed-off-by: qihao_yewu ---- - migration/rdma.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/migration/rdma.c b/migration/rdma.c -index f5d3bbe7e9..60c856dd2f 100644 ---- a/migration/rdma.c -+++ b/migration/rdma.c -@@ -2866,7 +2866,7 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc, - size_t remaining = iov[i].iov_len; - uint8_t * data = (void *)iov[i].iov_base; - while (remaining) { -- RDMAControlHeader head; -+ RDMAControlHeader head = {}; - - len = MIN(remaining, RDMA_SEND_INCREMENT); - remaining -= len; --- -2.41.0.windows.1 - diff --git a/migration-report-compress-thread-pid-to-libvirt.patch b/migration-report-compress-thread-pid-to-libvirt.patch deleted file mode 100644 index 9d1194734acb3e5f0b704e5eb10006f20ffd9be8..0000000000000000000000000000000000000000 --- a/migration-report-compress-thread-pid-to-libvirt.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 16c188d246f8d74f3d25098effdb836cdeb17e16 Mon Sep 17 00:00:00 2001 -From: jipengfei -Date: Sat, 1 Jul 2023 13:08:53 +0800 -Subject: [PATCH] migration: report compress thread pid to libvirt - -Supports migrating compressed threads bound to physical cores,qemu need to tell libvirt the compress thread pids. - -Signed-off-by:jipengfei ---- - migration/ram.c | 3 +++ - qapi/migration.json | 13 +++++++++++++ - 2 files changed, 16 insertions(+) - -diff --git a/migration/ram.c b/migration/ram.c -index c3484ee1a9..c6c59b54d9 100644 ---- a/migration/ram.c -+++ b/migration/ram.c -@@ -755,6 +755,9 @@ static void *do_data_compress(void *opaque) - RAMBlock *block; - bool zero_page; - -+ /* report compress thread pids to libvirt */ -+ qapi_event_send_migration_compress_pid(qemu_get_thread_id()); -+ - qemu_mutex_lock(¶m->mutex); - while (!param->quit) { - if (param->block) { -diff --git a/qapi/migration.json b/qapi/migration.json -index 8e18fd30e4..e965f4329b 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -1308,6 +1308,19 @@ - { 'event': 'MIGRATION_PID', - 'data': { 'pid': 'int' } } - -+## -+# @MIGRATION_COMPRESS_PID: -+# -+# Emitted when compress thread appear -+# -+# @pid: pid of compress thread -+# -+# Since: 6.2 -+## -+{ 'event': 'MIGRATION_COMPRESS_PID', -+ 'data': { 'pid': 'int' } } -+ -+ - ## - # @COLOMessage: - # --- -2.41.0.windows.1 - diff --git a/migration-report-migration-related-thread-pid-to-lib.patch b/migration-report-migration-related-thread-pid-to-lib.patch deleted file mode 100644 index ea9a6b58f2292393d92b77d140324c34ff495c9d..0000000000000000000000000000000000000000 --- a/migration-report-migration-related-thread-pid-to-lib.patch +++ /dev/null @@ -1,54 +0,0 @@ -From f8bc91f17630ddf9272fba600f4452a3871b3fec Mon Sep 17 00:00:00 2001 -From: zhengchuan -Date: Mon, 5 Dec 2022 20:52:25 +0800 -Subject: [PATCH 4/5] migration: report migration related thread pid to libvirt - -in order to control migration thread cgroup, -we need to report migration related thread pid to libvirt - -Signed-off-by:zhengchuan ---- - migration/migration.c | 3 +++ - qapi/migration.json | 12 ++++++++++++ - 2 files changed, 15 insertions(+) - -diff --git a/migration/migration.c b/migration/migration.c -index f86dd8cccd..33d5832e47 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -3823,6 +3823,9 @@ static void *migration_thread(void *opaque) - MigThrError thr_error; - bool urgent = false; - -+ /* report migration thread pid to libvirt */ -+ qapi_event_send_migration_pid(qemu_get_thread_id()); -+ - rcu_register_thread(); - - object_ref(OBJECT(s)); -diff --git a/qapi/migration.json b/qapi/migration.json -index fee266017d..48e3d36d39 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -1284,6 +1284,18 @@ - { 'event': 'MIGRATION_PASS', - 'data': { 'pass': 'int' } } - -+## -+# @MIGRATION_PID: -+# -+# Emitted when migration thread appear -+# -+# @pid: pid of migration thread -+# -+# Since: EulerOS Virtual -+## -+{ 'event': 'MIGRATION_PID', -+ 'data': { 'pid': 'int' } } -+ - ## - # @COLOMessage: - # --- -2.27.0 - diff --git a/migration-report-multiFd-related-thread-pid-to-libvi.patch b/migration-report-multiFd-related-thread-pid-to-libvi.patch deleted file mode 100644 index 35b451db7464768c064f4f15f58104bd2b3b1e9c..0000000000000000000000000000000000000000 --- a/migration-report-multiFd-related-thread-pid-to-libvi.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 5bc58d9cecbcb56c2494ea4aee7cd8a4a988b403 Mon Sep 17 00:00:00 2001 -From: zhengchuan -Date: Mon, 5 Dec 2022 20:56:35 +0800 -Subject: [PATCH 5/5] migration: report multiFd related thread pid to libvirt - -report multiFd related thread pid to libvirt in order to -pin multiFd thread to different cpu. - -Signed-off-by:zhengchuan ---- - migration/multifd.c | 4 ++++ - qapi/migration.json | 12 ++++++++++++ - 2 files changed, 16 insertions(+) - -diff --git a/migration/multifd.c b/migration/multifd.c -index 7c9deb1921..0d3f66537c 100644 ---- a/migration/multifd.c -+++ b/migration/multifd.c -@@ -17,6 +17,7 @@ - #include "exec/ramblock.h" - #include "qemu/error-report.h" - #include "qapi/error.h" -+#include "qapi/qapi-events-migration.h" - #include "ram.h" - #include "migration.h" - #include "socket.h" -@@ -629,6 +630,9 @@ static void *multifd_send_thread(void *opaque) - int ret = 0; - uint32_t flags = 0; - -+ /* report multifd thread pid to libvirt */ -+ qapi_event_send_migration_multifd_pid(qemu_get_thread_id()); -+ - trace_multifd_send_thread_start(p->id); - rcu_register_thread(); - -diff --git a/qapi/migration.json b/qapi/migration.json -index 48e3d36d39..8e18fd30e4 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -1284,6 +1284,18 @@ - { 'event': 'MIGRATION_PASS', - 'data': { 'pass': 'int' } } - -+## -+# @MIGRATION_MULTIFD_PID: -+# -+# Emitted when multifd thread appear -+# -+# @pid: pid of multifd thread -+# -+# Since: EulerOS Virtual -+## -+{ 'event': 'MIGRATION_MULTIFD_PID', -+ 'data': { 'pid': 'int' } } -+ - ## - # @MIGRATION_PID: - # --- -2.27.0 - diff --git a/migration-skip-cache_drop-for-bios-bootloader-and-nv.patch b/migration-skip-cache_drop-for-bios-bootloader-and-nv.patch deleted file mode 100644 index d7f90b3e2cf859fecaf55cffaa886a08297ff5d4..0000000000000000000000000000000000000000 --- a/migration-skip-cache_drop-for-bios-bootloader-and-nv.patch +++ /dev/null @@ -1,47 +0,0 @@ -From d9fef6139e17976db194d73848baff543c4a2590 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Wed, 9 Feb 2022 08:49:41 +0800 -Subject: [PATCH 10/15] migration: skip cache_drop for bios bootloader and - nvram template - -Qemu enabled page cache dropping for raw device on the destionation host -during shared storage migration. -However, fsync may take 300ms to multiple seconds to return in multiple-migration -scene, because all domains in a host share bios bootloader file, skip cache_drop -for bios bootloader and nvram template to avoid downtime increase. ---- - block.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/block.c b/block.c -index 0ac5b163d2..91f123a354 100644 ---- a/block.c -+++ b/block.c -@@ -67,6 +67,9 @@ - - #define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */ - -+#define DEFAULT_BIOS_BOOT_LOADER_DIR "/usr/share/edk2" -+#define DEFAULT_NVRAM_TEMPLATE_DIR "/var/lib/libvirt/qemu/nvram" -+ - static QTAILQ_HEAD(, BlockDriverState) graph_bdrv_states = - QTAILQ_HEAD_INITIALIZER(graph_bdrv_states); - -@@ -6432,7 +6435,13 @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp) - return ret; - } - -- if (bs->drv->bdrv_co_invalidate_cache) { -+ /* -+ * It's not necessary for bios bootloader and nvram template to drop cache -+ * when migration, skip this step for them to avoid dowtime increase. -+ */ -+ if (bs->drv->bdrv_co_invalidate_cache && -+ !strstr(bs->filename, DEFAULT_BIOS_BOOT_LOADER_DIR) && -+ !strstr(bs->filename, DEFAULT_NVRAM_TEMPLATE_DIR)) { - bs->drv->bdrv_co_invalidate_cache(bs, &local_err); - if (local_err) { - bs->open_flags |= BDRV_O_INACTIVE; --- -2.27.0 - diff --git a/migration-xbzrle-fix-out-of-bounds-write-with-axv512.patch b/migration-xbzrle-fix-out-of-bounds-write-with-axv512.patch deleted file mode 100644 index 95afae2cf08463dc8d86f8a099b3e4750a3161f0..0000000000000000000000000000000000000000 --- a/migration-xbzrle-fix-out-of-bounds-write-with-axv512.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 553baa5eac50560c14ed216744062f542df17011 Mon Sep 17 00:00:00 2001 -From: Matheus Tavares Bernardino -Date: Mon, 13 Mar 2023 15:58:20 -0300 -Subject: [PATCH] migration/xbzrle: fix out-of-bounds write with axv512 - -mainline inclusion -from mainline-v8.0.0-rc1 -commit 1776b70f55c75541e9cab3423650a59b085162a9 -category: feature -feature: AVX512 support for xbzrle_encode_buffer -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6Z50P - -Intel-SIG: commit 1776b70f55c7 ("migration/xbzrle: fix out-of-bounds write with axv512") - -------------------------------------- - -migration/xbzrle: fix out-of-bounds write with axv512 - -xbzrle_encode_buffer_avx512() checks for overflows too scarcely in its -outer loop, causing out-of-bounds writes: - -$ ../configure --target-list=aarch64-softmmu --enable-sanitizers --enable-avx512bw -$ make tests/unit/test-xbzrle && ./tests/unit/test-xbzrle - -==5518==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62100000b100 at pc 0x561109a7714d bp 0x7ffed712a440 sp 0x7ffed712a430 -WRITE of size 1 at 0x62100000b100 thread T0 - #0 0x561109a7714c in uleb128_encode_small ../util/cutils.c:831 - #1 0x561109b67f6a in xbzrle_encode_buffer_avx512 ../migration/xbzrle.c:275 - #2 0x5611099a7428 in test_encode_decode_overflow ../tests/unit/test-xbzrle.c:153 - #3 0x7fb2fb65a58d (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x7a58d) - #4 0x7fb2fb65a333 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x7a333) - #5 0x7fb2fb65aa79 in g_test_run_suite (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x7aa79) - #6 0x7fb2fb65aa94 in g_test_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x7aa94) - #7 0x5611099a3a23 in main ../tests/unit/test-xbzrle.c:218 - #8 0x7fb2fa78c082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) - #9 0x5611099a608d in _start (/qemu/build/tests/unit/test-xbzrle+0x28408d) - -0x62100000b100 is located 0 bytes to the right of 4096-byte region [0x62100000a100,0x62100000b100) -allocated by thread T0 here: - #0 0x7fb2fb823a06 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:153 - #1 0x7fb2fb637ef0 in g_malloc0 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x57ef0) - -Fix that by performing the overflow check in the inner loop, instead. - -Signed-off-by: Matheus Tavares Bernardino -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -Signed-off-by: Aichun Shi ---- - migration/xbzrle.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/migration/xbzrle.c b/migration/xbzrle.c -index 21b92d4eae..c6f8b20917 100644 ---- a/migration/xbzrle.c -+++ b/migration/xbzrle.c -@@ -197,10 +197,6 @@ int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen, - __m512i r = _mm512_set1_epi32(0); - - while (count512s) { -- if (d + 2 > dlen) { -- return -1; -- } -- - int bytes_to_check = 64; - uint64_t mask = 0xffffffffffffffff; - if (count512s == 1) { -@@ -216,6 +212,9 @@ int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen, - - bool is_same = (comp & 0x1); - while (bytes_to_check) { -+ if (d + 2 > dlen) { -+ return -1; -+ } - if (is_same) { - if (nzrun_len) { - d += uleb128_encode_small(dst + d, nzrun_len); --- -2.27.0 - diff --git a/migration-xbzrle-use-ctz64-to-avoid-undefined-result.patch b/migration-xbzrle-use-ctz64-to-avoid-undefined-result.patch deleted file mode 100644 index a2dbddeac9ca1a2d31fddd2d9a665ed67ca21a41..0000000000000000000000000000000000000000 --- a/migration-xbzrle-use-ctz64-to-avoid-undefined-result.patch +++ /dev/null @@ -1,69 +0,0 @@ -From d4c03c1e41043f25e21889762bceb480abb56634 Mon Sep 17 00:00:00 2001 -From: Matheus Tavares Bernardino -Date: Mon, 13 Mar 2023 15:58:19 -0300 -Subject: [PATCH] migration/xbzrle: use ctz64 to avoid undefined result - -mainline inclusion -from mainline-v8.0.0-rc1 -commit d84a78d15d3af9ff28ceec6906a4b101bd545b55 -category: feature -feature: AVX512 support for xbzrle_encode_buffer -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6Z50P - -Intel-SIG: commit d84a78d15d3a ("migration/xbzrle: use ctz64 to avoid undefined result") - -------------------------------------- - -migration/xbzrle: use ctz64 to avoid undefined result - -__builtin_ctzll() produces undefined results when the argument is 0. -This can be seen through test-xbzrle, which produces the following -warning: - -../migration/xbzrle.c:265: runtime error: passing zero to ctz(), which is not a valid argument - -Replace __builtin_ctzll() with our ctz64() wrapper which properly -handles 0. - -Signed-off-by: Matheus Tavares Bernardino -Reviewed-by: Dr. David Alan Gilbert -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela -Signed-off-by: Aichun Shi ---- - migration/xbzrle.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/migration/xbzrle.c b/migration/xbzrle.c -index 05366e86c0..21b92d4eae 100644 ---- a/migration/xbzrle.c -+++ b/migration/xbzrle.c -@@ -12,6 +12,7 @@ - */ - #include "qemu/osdep.h" - #include "qemu/cutils.h" -+#include "qemu/host-utils.h" - #include "xbzrle.h" - - /* -@@ -233,7 +234,7 @@ int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen, - break; - } - never_same = false; -- num = __builtin_ctzll(~comp); -+ num = ctz64(~comp); - num = (num < bytes_to_check) ? num : bytes_to_check; - zrun_len += num; - bytes_to_check -= num; -@@ -262,7 +263,7 @@ int xbzrle_encode_buffer_avx512(uint8_t *old_buf, uint8_t *new_buf, int slen, - nzrun_len += 64; - break; - } -- num = __builtin_ctzll(comp); -+ num = ctz64(comp); - num = (num < bytes_to_check) ? num : bytes_to_check; - nzrun_len += num; - bytes_to_check -= num; --- -2.27.0 - diff --git a/monitor-Discard-BLOCK_IO_ERROR-event-when-VM-reboote.patch b/monitor-Discard-BLOCK_IO_ERROR-event-when-VM-reboote.patch deleted file mode 100644 index 13d16d03846771b316c9a42c3e616d473c299984..0000000000000000000000000000000000000000 --- a/monitor-Discard-BLOCK_IO_ERROR-event-when-VM-reboote.patch +++ /dev/null @@ -1,97 +0,0 @@ -From f5af9ac3c9af4602812060759f6f95da8725314b Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Thu, 10 Feb 2022 11:18:13 +0800 -Subject: [PATCH] monitor: Discard BLOCK_IO_ERROR event when VM rebooted - -Throttled event like QAPI_EVENT_BLOCK_IO_ERROR may be queued -to limit event rate. Event may be delivered when VM is rebooted -if the event was queued in the *monitor_qapi_event_state* hash table. -Which may casue VM pause and other related problems. -Such as seabios blocked during virtio-scsi initialization: - vring_add_buf(vq, sg, out_num, in_num, 0, 0); - vring_kick(vp, vq, 1); - ------------> VM paused here <----------- - /* Wait for reply */ - while (!vring_more_used(vq)) usleep(5); - -Signed-off-by: Yan Wang ---- - include/monitor/monitor.h | 2 ++ - monitor/monitor.c | 30 ++++++++++++++++++++++++++++++ - softmmu/runstate.c | 1 + - 3 files changed, 33 insertions(+) - -diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h -index 12d395d62d..847445f972 100644 ---- a/include/monitor/monitor.h -+++ b/include/monitor/monitor.h -@@ -56,4 +56,6 @@ void monitor_register_hmp(const char *name, bool info, - void monitor_register_hmp_info_hrt(const char *name, - HumanReadableText *(*handler)(Error **errp)); - -+void monitor_qapi_event_discard_io_error(void); -+ - #endif /* MONITOR_H */ -diff --git a/monitor/monitor.c b/monitor/monitor.c -index 013c628695..fb4ae9531c 100644 ---- a/monitor/monitor.c -+++ b/monitor/monitor.c -@@ -34,6 +34,9 @@ - #include "qemu/option.h" - #include "sysemu/qtest.h" - #include "trace.h" -+#include "qemu/log.h" -+#include "qapi/qmp/qjson.h" -+#include "qapi/qmp/qobject.h" - - /* - * To prevent flooding clients, events can be throttled. The -@@ -767,6 +770,33 @@ int monitor_init_opts(QemuOpts *opts, Error **errp) - return ret; - } - -+void monitor_qapi_event_discard_io_error(void) -+{ -+ GHashTableIter event_iter; -+ MonitorQAPIEventState *evstate; -+ gpointer key, value; -+ GString *json; -+ -+ qemu_mutex_lock(&monitor_lock); -+ g_hash_table_iter_init(&event_iter, monitor_qapi_event_state); -+ while (g_hash_table_iter_next(&event_iter, &key, &value)) { -+ evstate = key; -+ /* Only QAPI_EVENT_BLOCK_IO_ERROR is discarded */ -+ if (evstate->event == QAPI_EVENT_BLOCK_IO_ERROR) { -+ g_hash_table_iter_remove(&event_iter); -+ json = qobject_to_json(QOBJECT(evstate->qdict)); -+ qemu_log(" %s event discarded\n", json->str); -+ timer_del(evstate->timer); -+ timer_free(evstate->timer); -+ qobject_unref(evstate->data); -+ qobject_unref(evstate->qdict); -+ g_string_free(json, true); -+ g_free(evstate); -+ } -+ } -+ qemu_mutex_unlock(&monitor_lock); -+} -+ - QemuOptsList qemu_mon_opts = { - .name = "mon", - .implied_opt_name = "chardev", -diff --git a/softmmu/runstate.c b/softmmu/runstate.c -index 10d9b7365a..5736d908db 100644 ---- a/softmmu/runstate.c -+++ b/softmmu/runstate.c -@@ -448,6 +448,7 @@ void qemu_system_reset(ShutdownCause reason) - qapi_event_send_reset(shutdown_caused_by_guest(reason), reason); - } - cpu_synchronize_all_post_reset(); -+ monitor_qapi_event_discard_io_error(); - } - - /* --- -2.27.0 - diff --git a/monitor-limit-io-error-qmp-event-to-at-most-once-per.patch b/monitor-limit-io-error-qmp-event-to-at-most-once-per.patch deleted file mode 100644 index 2b3b02f82514599c996d2ba05950ac2445afd773..0000000000000000000000000000000000000000 --- a/monitor-limit-io-error-qmp-event-to-at-most-once-per.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 44f45b5c163efed5387dac40e229e0a50bf5921a Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Thu, 10 Feb 2022 11:35:58 +0800 -Subject: [PATCH] monitor: limit io error qmp event to at most once per 60s - -The speed of BLOCK IO ERROR event maybe very high (thousands per -second). If we report all BLOCK IO ERRORs, the log file will be flooded -with BLOCK IO ERROR event. So throttle it to at most once per 60s. - -Signed-off-by: Yan Wang ---- - monitor/monitor.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/monitor/monitor.c b/monitor/monitor.c -index fb4ae9531c..621e79eb66 100644 ---- a/monitor/monitor.c -+++ b/monitor/monitor.c -@@ -300,6 +300,7 @@ static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = { - [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS }, - [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS }, - [QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS }, -+ [QAPI_EVENT_BLOCK_IO_ERROR] = { 60L * 1000 * SCALE_MS }, - }; - - /* --- -2.27.0 - diff --git a/monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch b/monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch deleted file mode 100644 index d45cb3189c161de501ac329027b502ec60858546..0000000000000000000000000000000000000000 --- a/monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 7eb28408efe75192a0f976a197f8f1906d9073e8 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Wed, 9 Feb 2022 14:13:05 +0800 -Subject: [PATCH 14/15] monitor/qmp: drop inflight rsp if qmp client broken - -If libvirt restart while qemu is handle qmp message, libvirt will -reconnect qemu monitor socket, and query status of qemu by qmp. -But qemu may return last qmp respond to new connect socket, and libvirt -recv unexpected respond, So libvirt think qemu is abnormal, and will -kill qemu. - -This patch add qmp connect id, while reconnect id will change. While -respond to libvirt, judge if id is same, if not, drop this respond. ---- - monitor/monitor-internal.h | 1 + - monitor/qmp.c | 19 +++++++++++-------- - 2 files changed, 12 insertions(+), 8 deletions(-) - -diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h -index 3da3f86c6a..5435864add 100644 ---- a/monitor/monitor-internal.h -+++ b/monitor/monitor-internal.h -@@ -144,6 +144,7 @@ typedef struct { - const QmpCommandList *commands; - bool capab_offered[QMP_CAPABILITY__MAX]; /* capabilities offered */ - bool capab[QMP_CAPABILITY__MAX]; /* offered and accepted */ -+ uint64_t qmp_client_id; /*qmp client id, update if peer disconnect */ - /* - * Protects qmp request/response queue. - * Take monitor_lock first when you need both. -diff --git a/monitor/qmp.c b/monitor/qmp.c -index 092c527b6f..4d1ac66785 100644 ---- a/monitor/qmp.c -+++ b/monitor/qmp.c -@@ -125,18 +125,19 @@ void qmp_send_response(MonitorQMP *mon, const QDict *rsp) - * Null @rsp can only happen for commands with QCO_NO_SUCCESS_RESP. - * Nothing is emitted then. - */ --static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp) -+static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp, uint64_t req_client_id) - { -- if (rsp) { -- qmp_send_response(mon, rsp); -+ if (!rsp || (mon->qmp_client_id != req_client_id)) { -+ return; - } -+ qmp_send_response(mon, rsp); - } - - /* - * Runs outside of coroutine context for OOB commands, but in - * coroutine context for everything else. - */ --static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) -+static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req, uint64_t req_client_id) - { - QDict *rsp; - QDict *error; -@@ -156,7 +157,7 @@ static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req) - } - } - -- monitor_qmp_respond(mon, rsp); -+ monitor_qmp_respond(mon, rsp, req_client_id); - qobject_unref(rsp); - } - -@@ -315,13 +316,13 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data) - trace_monitor_qmp_cmd_in_band(id_json->str); - g_string_free(id_json, true); - } -- monitor_qmp_dispatch(mon, req_obj->req); -+ monitor_qmp_dispatch(mon, req_obj->req, mon->qmp_client_id); - } else { - assert(req_obj->err); - trace_monitor_qmp_err_in_band(error_get_pretty(req_obj->err)); - rsp = qmp_error_response(req_obj->err); - req_obj->err = NULL; -- monitor_qmp_respond(mon, rsp); -+ monitor_qmp_respond(mon, rsp, mon->qmp_client_id); - qobject_unref(rsp); - } - -@@ -366,7 +367,7 @@ static void handle_qmp_command(void *opaque, QObject *req, Error *err) - trace_monitor_qmp_cmd_out_of_band(id_json->str); - g_string_free(id_json, true); - } -- monitor_qmp_dispatch(mon, req); -+ monitor_qmp_dispatch(mon, req, mon->qmp_client_id); - qobject_unref(req); - return; - } -@@ -452,6 +453,7 @@ static void monitor_qmp_event(void *opaque, QEMUChrEvent event) - mon_refcount++; - break; - case CHR_EVENT_CLOSED: -+ mon->qmp_client_id++; - /* - * Note: this is only useful when the output of the chardev - * backend is still open. For example, when the backend is -@@ -505,6 +507,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp) - } - qemu_chr_fe_set_echo(&mon->common.chr, true); - -+ mon->qmp_client_id = 1; - /* Note: we run QMP monitor in I/O thread when @chr supports that */ - monitor_data_init(&mon->common, true, false, - qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT)); --- -2.27.0 - diff --git a/nbd-allow-reconnect-on-open-with-corresponding-new-o.patch b/nbd-allow-reconnect-on-open-with-corresponding-new-o.patch deleted file mode 100644 index 274536ba6cb5bbe05f9fa61d7aea2fa768cd11be..0000000000000000000000000000000000000000 --- a/nbd-allow-reconnect-on-open-with-corresponding-new-o.patch +++ /dev/null @@ -1,138 +0,0 @@ -From eb42fba27842e3ebc342f15847863b5e812a7919 Mon Sep 17 00:00:00 2001 -From: Zhang Bo -Date: Mon, 29 Aug 2022 15:28:55 +0800 -Subject: [PATCH 1/5] nbd: allow reconnect on open, with corresponding new - options - -It is useful when start of vm and start of nbd server are not -simple to sync. - -Signed-off-by: Vladimir Sementsov-Ogievskiy -Reviewed-by: Eric Blake -Signed-off-by: Zhang Bo ---- - block/nbd.c | 45 +++++++++++++++++++++++++++++++++++++++++++- - qapi/block-core.json | 9 ++++++++- - 2 files changed, 52 insertions(+), 2 deletions(-) - -diff --git a/block/nbd.c b/block/nbd.c -index 5ef462db1b..63dbfa807d 100644 ---- a/block/nbd.c -+++ b/block/nbd.c -@@ -80,6 +80,7 @@ typedef struct BDRVNBDState { - NBDClientState state; - - QEMUTimer *reconnect_delay_timer; -+ QEMUTimer *open_timer; - - NBDClientRequest requests[MAX_NBD_REQUESTS]; - NBDReply reply; -@@ -87,6 +88,7 @@ typedef struct BDRVNBDState { - - /* Connection parameters */ - uint32_t reconnect_delay; -+ uint32_t open_timeout; - SocketAddress *saddr; - char *export, *tlscredsid; - QCryptoTLSCreds *tlscreds; -@@ -218,6 +220,32 @@ static void nbd_teardown_connection(BlockDriverState *bs) - s->state = NBD_CLIENT_QUIT; - } - -+static void open_timer_del(BDRVNBDState *s) -+{ -+ if (s->open_timer) { -+ timer_free(s->open_timer); -+ s->open_timer = NULL; -+ } -+} -+ -+static void open_timer_cb(void *opaque) -+{ -+ BDRVNBDState *s = opaque; -+ -+ nbd_co_establish_connection_cancel(s->conn); -+ open_timer_del(s); -+} -+ -+static void open_timer_init(BDRVNBDState *s, uint64_t expire_time_ns) -+{ -+ assert(!s->open_timer); -+ s->open_timer = aio_timer_new(bdrv_get_aio_context(s->bs), -+ QEMU_CLOCK_REALTIME, -+ SCALE_NS, -+ open_timer_cb, s); -+ timer_mod(s->open_timer, expire_time_ns); -+} -+ - static bool nbd_client_connecting(BDRVNBDState *s) - { - NBDClientState state = qatomic_load_acquire(&s->state); -@@ -1742,6 +1770,15 @@ static QemuOptsList nbd_runtime_opts = { - "future requests before a successful reconnect will " - "immediately fail. Default 0", - }, -+ { -+ .name = "open-timeout", -+ .type = QEMU_OPT_NUMBER, -+ .help = "In seconds. If zero, the nbd driver tries the connection " -+ "only once, and fails to open if the connection fails. " -+ "If non-zero, the nbd driver will repeat connection " -+ "attempts until successful or until @open-timeout seconds " -+ "have elapsed. Default 0", -+ }, - { /* end of list */ } - }, - }; -@@ -1797,6 +1834,7 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options, - } - - s->reconnect_delay = qemu_opt_get_number(opts, "reconnect-delay", 0); -+ s->open_timeout = qemu_opt_get_number(opts, "open-timeout", 0); - - ret = 0; - -@@ -1828,7 +1866,12 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags, - s->conn = nbd_client_connection_new(s->saddr, true, s->export, - s->x_dirty_bitmap, s->tlscreds); - -- /* TODO: Configurable retry-until-timeout behaviour. */ -+ if (s->open_timeout) { -+ nbd_client_connection_enable_retry(s->conn); -+ open_timer_init(s, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + -+ s->open_timeout * NANOSECONDS_PER_SECOND); -+ } -+ - s->state = NBD_CLIENT_CONNECTING_WAIT; - ret = nbd_do_establish_connection(bs, errp); - if (ret < 0) { -diff --git a/qapi/block-core.json b/qapi/block-core.json -index e65fabe36d..618e417135 100644 ---- a/qapi/block-core.json -+++ b/qapi/block-core.json -@@ -4096,6 +4096,12 @@ - # future requests before a successful reconnect will - # immediately fail. Default 0 (Since 4.2) - # -+# @open-timeout: In seconds. If zero, the nbd driver tries the connection -+# only once, and fails to open if the connection fails. -+# If non-zero, the nbd driver will repeat connection attempts -+# until successful or until @open-timeout seconds have elapsed. -+# Default 0 (Since 7.0) -+# - # Features: - # @unstable: Member @x-dirty-bitmap is experimental. - # -@@ -4106,7 +4112,8 @@ - '*export': 'str', - '*tls-creds': 'str', - '*x-dirty-bitmap': { 'type': 'str', 'features': [ 'unstable' ] }, -- '*reconnect-delay': 'uint32' } } -+ '*reconnect-delay': 'uint32', -+ '*open-timeout': 'uint32' } } - - ## - # @BlockdevOptionsRaw: --- -2.27.0 - diff --git a/nbd-server.c-fix-invalid-read-after-client-was-alrea.patch b/nbd-server.c-fix-invalid-read-after-client-was-alrea.patch deleted file mode 100644 index b6ba4e43042cefc06fe36e3a932a1c5a764a5a1d..0000000000000000000000000000000000000000 --- a/nbd-server.c-fix-invalid-read-after-client-was-alrea.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 4b156248776f734d63fe37629d56c40234fda9c0 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 10:42:33 +0800 -Subject: [PATCH] nbd/server.c: fix invalid read after client was already free - -In the process of NBD equipment pressurization, executing QEMU NBD will -lead to the failure of IO distribution and go to NBD_ Out process of trip(). -If two or more IO go to the out process, client NBD will release in nbd_request_put(). -The user after free problem that is read again in close(). -Through the NBD_ Save the value of client > closing before the out process in trip -to solve the use after free problem. - -Signed-off-by: wangjian161 ---- - nbd/server.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/nbd/server.c b/nbd/server.c -index 4630dd7322..37515ed520 100644 ---- a/nbd/server.c -+++ b/nbd/server.c -@@ -2606,6 +2606,7 @@ static coroutine_fn void nbd_trip(void *opaque) - NBDRequestData *req; - NBDRequest request = { 0 }; /* GCC thinks it can be used uninitialized */ - int ret; -+ bool client_closing; - Error *local_err = NULL; - - trace_nbd_trip(); -@@ -2681,8 +2682,11 @@ disconnect: - if (local_err) { - error_reportf_err(local_err, "Disconnect client, due to: "); - } -+ client_closing = client->closing; - nbd_request_put(req); -- client_close(client, true); -+ if (!client_closing) { -+ client_close(client, true); -+ } - nbd_client_put(client); - } - --- -2.27.0 - diff --git a/net-Fix-a-misleading-error-message.patch b/net-Fix-a-misleading-error-message.patch deleted file mode 100644 index 75a49b12e60c6a8a5e20c02cc82d480e23df2d00..0000000000000000000000000000000000000000 --- a/net-Fix-a-misleading-error-message.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 1cc7783df04674ff375905cc9a8ec23f71617408 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Tue, 21 Nov 2023 20:40:24 +0800 -Subject: [PATCH] net: Fix a misleading error message - -cheery-pick from 0a4a1512e01228fc59b00d68e86f7099b6439773 - -The error message - - $ qemu-system-x86_64 -netdev user,id=net0,ipv6-net=fec0::0/ - qemu-system-x86_64: -netdev user,id=net0,ipv6-net=fec0::0/: Parameter 'ipv6-prefixlen' expects a number - -points to ipv6-prefixlen instead of ipv6-net. Fix: - - qemu-system-x86_64: -netdev user,id=net0,ipv6-net=fec0::0/: parameter 'ipv6-net' expects a number after '/' - -Signed-off-by: Markus Armbruster -Message-ID: <20231031111059.3407803-6-armbru@redhat.com> -Signed-off-by: qihao_yewu ---- - net/net.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/net/net.c b/net/net.c -index ed4b1c1740..daad8784ec 100644 ---- a/net/net.c -+++ b/net/net.c -@@ -1122,7 +1122,7 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp) - int ret = -1; - Visitor *v = opts_visitor_new(opts); - -- /* Parse convenience option format ip6-net=fec0::0[/64] */ -+ /* Parse convenience option format ipv6-net=fec0::0[/64] */ - const char *ip6_net = qemu_opt_get(opts, "ipv6-net"); - - if (ip6_net) { -@@ -1142,8 +1142,8 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp) - if (substrings[1] && - qemu_strtoul(substrings[1], NULL, 10, &prefix_len)) - { -- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, -- "ipv6-prefixlen", "a number"); -+ error_setg(errp, -+ "parameter 'ipv6-net' expects a number after '/'"); - goto out; - } - --- -2.27.0 - diff --git a/net-Fix-uninitialized-data-usage.patch b/net-Fix-uninitialized-data-usage.patch deleted file mode 100644 index d72c895855854c90ff16ce5c3908e6332d15dcbe..0000000000000000000000000000000000000000 --- a/net-Fix-uninitialized-data-usage.patch +++ /dev/null @@ -1,92 +0,0 @@ -From de8ab0c3b4e5f9aac9e7be00cfbd86d724bf036e Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 24 Mar 2023 07:42:33 +0000 -Subject: [PATCH] net: Fix uninitialized data usage mainline inclusion commit - e29919c93d19118610d64de9deb9c223024c0bc6 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -e.g. -1109 15:16:20.151506 Uninitialized bytes in ioctl_common_pre at offset 0 inside [0x7ffc516af9b8, 4) - 1109 15:16:20.151659 ==588974==WARNING: MemorySanitizer: use-of-uninitialized-value - 1109 15:16:20.312923 #0 0x5639b88acb21 in tap_probe_vnet_hdr_len third_party/qemu/net/tap-linux.c:183:9 - 1109 15:16:20.312952 #1 0x5639b88afd66 in net_tap_fd_init third_party/qemu/net/tap.c:409:9 - 1109 15:16:20.312954 #2 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19 - 1109 15:16:20.312956 #3 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13 - 1109 15:16:20.312957 #4 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9 - 1109 15:16:20.312958 #5 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15 - 1109 15:16:20.312960 #6 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11 - 1109 15:16:20.312961 #7 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14 - 1109 15:16:20.312962 #8 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9 - 1109 15:16:20.312964 #9 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5 - 1109 15:16:20.312965 #10 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5 - 1109 15:16:20.312967 #11 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5 - 1109 15:16:20.312968 #12 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2) - 1109 15:16:20.312969 #13 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120 - 1109 15:16:20.312970 - 1109 15:16:20.312975 Uninitialized value was stored to memory at - 1109 15:16:20.313393 #0 0x5639b88acbee in tap_probe_vnet_hdr_len third_party/qemu/net/tap-linux.c - 1109 15:16:20.313396 #1 0x5639b88afd66 in net_tap_fd_init third_party/qemu/net/tap.c:409:9 - 1109 15:16:20.313398 #2 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19 - 1109 15:16:20.313399 #3 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13 - 1109 15:16:20.313400 #4 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9 - 1109 15:16:20.313401 #5 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15 - 1109 15:16:20.313403 #6 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11 - 1109 15:16:20.313404 #7 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14 - 1109 15:16:20.313405 #8 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9 - 1109 15:16:20.313407 #9 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5 - 1109 15:16:20.313408 #10 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5 - 1109 15:16:20.313409 #11 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5 - 1109 15:16:20.313410 #12 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2) - 1109 15:16:20.313412 #13 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120 - 1109 15:16:20.313413 - 1109 15:16:20.313417 Uninitialized value was stored to memory at - 1109 15:16:20.313791 #0 0x5639b88affbd in net_tap_fd_init third_party/qemu/net/tap.c:400:26 - 1109 15:16:20.313826 #1 0x5639b88b2d1b in net_init_tap_one third_party/qemu/net/tap.c:681:19 - 1109 15:16:20.313829 #2 0x5639b88b16a8 in net_init_tap third_party/qemu/net/tap.c:912:13 - 1109 15:16:20.313831 #3 0x5639b8890175 in net_client_init1 third_party/qemu/net/net.c:1110:9 - 1109 15:16:20.313836 #4 0x5639b888f912 in net_client_init third_party/qemu/net/net.c:1208:15 - 1109 15:16:20.313838 #5 0x5639b8894aa5 in net_param_nic third_party/qemu/net/net.c:1588:11 - 1109 15:16:20.313839 #6 0x5639b900cd18 in qemu_opts_foreach third_party/qemu/util/qemu-option.c:1135:14 - 1109 15:16:20.313841 #7 0x5639b889393c in net_init_clients third_party/qemu/net/net.c:1612:9 - 1109 15:16:20.313843 #8 0x5639b717aaf3 in qemu_create_late_backends third_party/qemu/softmmu/vl.c:1962:5 - 1109 15:16:20.313844 #9 0x5639b717aaf3 in qemu_init third_party/qemu/softmmu/vl.c:3694:5 - 1109 15:16:20.313845 #10 0x5639b71083b8 in main third_party/qemu/softmmu/main.c:49:5 - 1109 15:16:20.313846 #11 0x7f464de1d8d2 in __libc_start_main (/usr/grte/v5/lib64/libc.so.6+0x628d2) - 1109 15:16:20.313847 #12 0x5639b6bbd389 in _start /usr/grte/v5/debug-src/src/csu/../sysdeps/x86_64/start.S:120 - 1109 15:16:20.313849 - 1109 15:16:20.313851 Uninitialized value was created by an allocation of 'ifr' in the stack frame of function 'tap_probe_vnet_hdr' - 1109 15:16:20.313855 #0 0x5639b88ac680 in tap_probe_vnet_hdr third_party/qemu/net/tap-linux.c:151 - 1109 15:16:20.313856 - 1109 15:16:20.313878 SUMMARY: MemorySanitizer: use-of-uninitialized-value third_party/qemu/net/tap-linux.c:183:9 in tap_probe_vnet_hdr_len - -Fixes: dc69004c7d8 ("net: move tap_probe_vnet_hdr() to tap-linux.c") -Reviewed-by: Hao Wu -Reviewed-by: Patrick Venture -Reviewed-by: Philippe Mathieu-Daud茅 -Signed-off-by: Peter Foley -Signed-off-by: Jason Wang - -Signed-off-by: tangbinzy ---- - net/tap-linux.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/net/tap-linux.c b/net/tap-linux.c -index 9584769740..5e70b93037 100644 ---- a/net/tap-linux.c -+++ b/net/tap-linux.c -@@ -150,6 +150,7 @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp) - int tap_probe_vnet_hdr(int fd, Error **errp) - { - struct ifreq ifr; -+ memset(&ifr, 0, sizeof(ifr)); - - if (ioctl(fd, TUNGETIFF, &ifr) != 0) { - /* TUNGETIFF is available since kernel v2.6.27 */ --- -2.27.0 - diff --git a/net-dump.c-Suppress-spurious-compiler-warning.patch b/net-dump.c-Suppress-spurious-compiler-warning.patch deleted file mode 100644 index 5db07d345719ea6895740fc529358d52c6eb4b0d..0000000000000000000000000000000000000000 --- a/net-dump.c-Suppress-spurious-compiler-warning.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 08801d190afd21f7d3db9a2cdce2b1528903ac2c Mon Sep 17 00:00:00 2001 -From: liuxiangdong -Date: Tue, 8 Feb 2022 15:10:25 +0800 -Subject: [PATCH] net/dump.c: Suppress spurious compiler warning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Compiling with gcc version 11.2.0 (Ubuntu 11.2.0-13ubuntu1) results in -a (spurious) warning: - - In function ‘dump_receive_iov’, - inlined from ‘filter_dump_receive_iov’ at ../net/dump.c:157:5: - ../net/dump.c:89:9: error: ‘writev’ specified size 18446744073709551600 -exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=] - 89 | if (writev(s->fd, dumpiov, cnt + 1) != sizeof(hdr) + caplen) { - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - In file included from /home/ptomsich/qemu/include/qemu/osdep.h:108, - from ../net/dump.c:25: - ../net/dump.c: In function ‘filter_dump_receive_iov’: - /usr/include/x86_64-linux-gnu/sys/uio.h:52:16: note: in a call to function -‘writev’ declared with attribute ‘read_only (2, 3)’ - 52 | extern ssize_t writev (int __fd, const struct iovec *__iovec, int -__count) - | ^~~~~~ - cc1: all warnings being treated as errors - -This change helps that version of GCC to understand what is going on -and suppresses this warning. - -Signed-off-by: Philipp Tomsich ---- - net/dump.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/dump.c b/net/dump.c -index a07ba62401..c32d3bf4e6 100644 ---- a/net/dump.c -+++ b/net/dump.c -@@ -86,7 +86,7 @@ static ssize_t dump_receive_iov(DumpState *s, const struct iovec *iov, int cnt) - dumpiov[0].iov_len = sizeof(hdr); - cnt = iov_copy(&dumpiov[1], cnt, iov, cnt, 0, caplen); - -- if (writev(s->fd, dumpiov, cnt + 1) != sizeof(hdr) + caplen) { -+ if (writev(s->fd, &dumpiov[0], cnt + 1) != sizeof(hdr) + caplen) { - error_report("network dump write error - stopping dump"); - close(s->fd); - s->fd = -1; --- -2.27.0 - diff --git a/net-eepro100-validate-various-address-valuesi-CVE-20.patch b/net-eepro100-validate-various-address-valuesi-CVE-20.patch deleted file mode 100644 index 47095713aabaf1232ac04d75dc97f189c67df4aa..0000000000000000000000000000000000000000 --- a/net-eepro100-validate-various-address-valuesi-CVE-20.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 5db012b1116d21c64da88ad206b3589ddf5f219b Mon Sep 17 00:00:00 2001 -From: zhouli57 -Date: Sat, 18 Dec 2021 09:39:57 +0800 -Subject: [PATCH] net: eepro100: validate various address - valuesi(CVE-2021-20255) - -fix CVE-2021-20255 - -patch link: https://lists.gnu.org/archive/html/qemu-devel/2021-02/msg06098.html - -fix CVE-2021-20255, sync patch from ostms platform. - -Signed-off-by: zhouli57 -Signed-off-by: Yan Wang ---- - hw/net/eepro100.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c -index 16e95ef9cc..2474cf3dc2 100644 ---- a/hw/net/eepro100.c -+++ b/hw/net/eepro100.c -@@ -279,6 +279,9 @@ typedef struct { - /* Quasi static device properties (no need to save them). */ - uint16_t stats_size; - bool has_extended_tcb_support; -+ -+ /* Flag to avoid recursions. */ -+ bool busy; - } EEPRO100State; - - /* Word indices in EEPROM. */ -@@ -837,6 +840,14 @@ static void action_command(EEPRO100State *s) - Therefore we limit the number of iterations. */ - unsigned max_loop_count = 16; - -+ if (s->busy) { -+ /* Prevent recursions. */ -+ logout("recursion in %s:%u\n", __FILE__, __LINE__); -+ return; -+ } -+ -+ s->busy = true; -+ - for (;;) { - bool bit_el; - bool bit_s; -@@ -933,6 +944,7 @@ static void action_command(EEPRO100State *s) - } - TRACE(OTHER, logout("CU list empty\n")); - /* List is empty. Now CU is idle or suspended. */ -+ s->busy = false; - } - - static void eepro100_cu_command(EEPRO100State * s, uint8_t val) --- -2.27.0 - diff --git a/net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch b/net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch deleted file mode 100644 index 2ff3a759f015ee40bfdc7ea0cbff242b8bba8e49..0000000000000000000000000000000000000000 --- a/net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 4e18cc43f7e83714da041d69d13265605c22c50c Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 24 Mar 2023 07:28:57 +0000 -Subject: [PATCH] net/eth: Don't consider ESP to be an IPv6 option header - mainline inclusion commit 9d6267b240c114d1a3cd314a08fd6e1339d34b83 category: - bugfix - ---------------------------------------------------------------- - -The IPv6 option headers all have in common that they start with some -common fields, in particular the type of the next header followed by the -extention header length. This is used to traverse the list of the -options. The ESP header does not follow that format, which can break the -IPv6 option header traversal code in eth_parse_ipv6_hdr(). - -The effect of that is that network interfaces such as vmxnet3 that use -the following call chain - eth_is_ip6_extension_header_type - eth_parse_ipv6_hdr - net_tx_pkt_parse_headers - net_tx_pkt_parse - vmxnet3_process_tx_queue -to send packets from the VM out to the host will drop packets of the -following structure: - Ethernet-Header(IPv6-Header(ESP(encrypted data))) - -Note that not all types of network interfaces use the net_tx_pkt_parse -function though, leading to inconsistent behavior regarding sending -those packets. The e1000 network interface for example does not suffer -from this limitation. - -By not considering ESP to be an IPv6 header we can allow sending those -packets out to the host on all types of network interfaces. - -Fixes: 75020a702151 ("Common definitions for VMWARE devices") -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/149 -Buglink: https://bugs.launchpad.net/qemu/+bug/1758091 -Signed-off-by: Thomas Jansen -Signed-off-by: Jason Wang - -Signed-off-by: tangbinzy ---- - net/eth.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/net/eth.c b/net/eth.c -index fe876d1a55..f074b2f9f3 100644 ---- a/net/eth.c -+++ b/net/eth.c -@@ -389,7 +389,6 @@ eth_is_ip6_extension_header_type(uint8_t hdr_type) - case IP6_HOP_BY_HOP: - case IP6_ROUTING: - case IP6_FRAGMENT: -- case IP6_ESP: - case IP6_AUTHENTICATION: - case IP6_DESTINATON: - case IP6_MOBILITY: --- -2.27.0 - diff --git a/net-tulip-Restrict-DMA-engine-to-memories.patch b/net-tulip-Restrict-DMA-engine-to-memories.patch deleted file mode 100644 index 5be976d55f72857085c77faa81accdd9ef24d88e..0000000000000000000000000000000000000000 --- a/net-tulip-Restrict-DMA-engine-to-memories.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 828774ed550d33e1cf8bf4bbc2a0fcf6fdf22094 Mon Sep 17 00:00:00 2001 -From: Zhang Bo -Date: Fri, 30 Sep 2022 12:24:58 +0800 -Subject: [PATCH] net: tulip: Restrict DMA engine to memories - -fix CVE-2022-2962. -The DMA engine is started by I/O access and then itself accesses the -I/O registers, triggering a reentrancy bug. - -The following log can reveal it: -==5637==ERROR: AddressSanitizer: stack-overflow - #0 0x5595435f6078 in tulip_xmit_list_update qemu/hw/net/tulip.c:673 - #1 0x5595435f204a in tulip_write qemu/hw/net/tulip.c:805:13 - #2 0x559544637f86 in memory_region_write_accessor qemu/softmmu/memory.c:492:5 - #3 0x5595446379fa in access_with_adjusted_size qemu/softmmu/memory.c:554:18 - #4 0x5595446372fa in memory_region_dispatch_write qemu/softmmu/memory.c - #5 0x55954468b74c in flatview_write_continue qemu/softmmu/physmem.c:2825:23 - #6 0x559544683662 in flatview_write qemu/softmmu/physmem.c:2867:12 - #7 0x5595446833f3 in address_space_write qemu/softmmu/physmem.c:2963:18 - #8 0x5595435fb082 in dma_memory_rw_relaxed qemu/include/sysemu/dma.h:87:12 - #9 0x5595435fb082 in dma_memory_rw qemu/include/sysemu/dma.h:130:12 - #10 0x5595435fb082 in dma_memory_write qemu/include/sysemu/dma.h:171:12 - #11 0x5595435fb082 in stl_le_dma qemu/include/sysemu/dma.h:272:1 - #12 0x5595435fb082 in stl_le_pci_dma qemu/include/hw/pci/pci.h:910:1 - #13 0x5595435fb082 in tulip_desc_write qemu/hw/net/tulip.c:101:9 - #14 0x5595435f7e3d in tulip_xmit_list_update qemu/hw/net/tulip.c:706:9 - #15 0x5595435f204a in tulip_write qemu/hw/net/tulip.c:805:13 - -Fix this bug by restricting the DMA engine to memories regions. - -Signed-off-by: Zheyu Ma -Signed-off-by: Jason Wang -Signed-off-by: Zhang Bo ---- - hw/net/tulip.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/net/tulip.c b/hw/net/tulip.c -index d5b6cc5ee6..5f8badefca 100644 ---- a/hw/net/tulip.c -+++ b/hw/net/tulip.c -@@ -70,7 +70,7 @@ static const VMStateDescription vmstate_pci_tulip = { - static void tulip_desc_read(TULIPState *s, hwaddr p, - struct tulip_descriptor *desc) - { -- const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; -+ const MemTxAttrs attrs = { .memory = true }; - - if (s->csr[0] & CSR0_DBO) { - ldl_be_pci_dma(&s->dev, p, &desc->status, attrs); -@@ -88,7 +88,7 @@ static void tulip_desc_read(TULIPState *s, hwaddr p, - static void tulip_desc_write(TULIPState *s, hwaddr p, - struct tulip_descriptor *desc) - { -- const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; -+ const MemTxAttrs attrs = { .memory = true }; - - if (s->csr[0] & CSR0_DBO) { - stl_be_pci_dma(&s->dev, p, desc->status, attrs); --- -2.27.0 - diff --git a/net-vhost-vdpa.c-Fix-clang-compilation-failure.patch b/net-vhost-vdpa.c-Fix-clang-compilation-failure.patch deleted file mode 100644 index 47ea2c8c7089fe46d337892afdd7bd71ca7791e4..0000000000000000000000000000000000000000 --- a/net-vhost-vdpa.c-Fix-clang-compilation-failure.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 02c67ab8c1f1e29bf8274d9b460dc2f07b8e195b Mon Sep 17 00:00:00 2001 -From: Peter Maydell -Date: Mon, 31 Oct 2022 13:29:01 +0000 -Subject: [PATCH] net/vhost-vdpa.c: Fix clang compilation failure - -Commit 8801ccd0500437 introduced a compilation failure with clang -version 10.0.0-4ubuntu1: - -../../net/vhost-vdpa.c:654:16: error: variable 'vdpa_device_fd' is -used uninitialized whenever 'if' condition is false -[-Werror,-Wsometimes-uninitialized] - } else if (opts->has_vhostfd) { - ^~~~~~~~~~~~~~~~~ -../../net/vhost-vdpa.c:662:33: note: uninitialized use occurs here - r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp); - ^~~~~~~~~~~~~~ -../../net/vhost-vdpa.c:654:12: note: remove the 'if' if its condition -is always true - } else if (opts->has_vhostfd) { - ^~~~~~~~~~~~~~~~~~~~~~~ -../../net/vhost-vdpa.c:629:23: note: initialize the variable -'vdpa_device_fd' to silence this warning - int vdpa_device_fd; - ^ - = 0 -1 error generated. - -It's a false positive -- the compiler doesn't manage to figure out -that the error checks further up mean that there's no code path where -vdpa_device_fd isn't initialized. Put another way, the problem is -that we check "if (opts->has_vhostfd)" when in fact that condition -must always be true. A cleverer static analyser would probably warn -that we were checking an always-true condition. - -Fix the compilation failure by removing the unnecessary if(). - -Fixes: 8801ccd0500437 ("vhost-vdpa: allow passing opened vhostfd to vhost-vdpa") -Signed-off-by: Peter Maydell -Message-Id: <20221031132901.1277150-1-peter.maydell@linaro.org> -Signed-off-by: Stefan Hajnoczi -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 58225649f9..c89f9d1243 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -659,7 +659,8 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - if (vdpa_device_fd == -1) { - return -errno; - } -- } else if (opts->has_vhostfd) { -+ } else { -+ /* has_vhostfd */ - vdpa_device_fd = monitor_fd_param(monitor_cur(), opts->vhostfd, errp); - if (vdpa_device_fd == -1) { - error_prepend(errp, "vhost-vdpa: unable to parse vhostfd: "); --- -2.27.0 - diff --git a/numa-Enable-numa-for-SGX-EPC-sections.patch b/numa-Enable-numa-for-SGX-EPC-sections.patch deleted file mode 100644 index 0eec4721ccb321406bc9ab74352ef3dc9102f5e1..0000000000000000000000000000000000000000 --- a/numa-Enable-numa-for-SGX-EPC-sections.patch +++ /dev/null @@ -1,291 +0,0 @@ -From c9071221ea67c7ee72fab5956e4c2c9da3fd39ef Mon Sep 17 00:00:00 2001 -From: Yang Zhong -Date: Mon, 1 Nov 2021 12:20:05 -0400 -Subject: [PATCH 1/9] numa: Enable numa for SGX EPC sections - -mainline inclusion -from mainline-v7.0.0-rc0 -commit 1105812382e1126d86dddc16b3700f8c79dc93d1 -category: feature -feature: NUMA support for SGX EPC sections -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5K27A - -Intel-SIG: commit 1105812382e1 ("numa: Enable numa for SGX EPC sections") - -------------------------------------- - -numa: Enable numa for SGX EPC sections - -The basic SGX did not enable numa for SGX EPC sections, which -result in all EPC sections located in numa node 0. This patch -enable SGX numa function in the guest and the EPC section can -work with RAM as one numa node. - -The Guest kernel related log: -[ 0.009981] ACPI: SRAT: Node 0 PXM 0 [mem 0x180000000-0x183ffffff] -[ 0.009982] ACPI: SRAT: Node 1 PXM 1 [mem 0x184000000-0x185bfffff] -The SRAT table can normally show SGX EPC sections menory info in different -numa nodes. - -The SGX EPC numa related command: - ...... - -m 4G,maxmem=20G \ - -smp sockets=2,cores=2 \ - -cpu host,+sgx-provisionkey \ - -object memory-backend-ram,size=2G,host-nodes=0,policy=bind,id=node0 \ - -object memory-backend-epc,id=mem0,size=64M,prealloc=on,host-nodes=0,policy=bind \ - -numa node,nodeid=0,cpus=0-1,memdev=node0 \ - -object memory-backend-ram,size=2G,host-nodes=1,policy=bind,id=node1 \ - -object memory-backend-epc,id=mem1,size=28M,prealloc=on,host-nodes=1,policy=bind \ - -numa node,nodeid=1,cpus=2-3,memdev=node1 \ - -M sgx-epc.0.memdev=mem0,sgx-epc.0.node=0,sgx-epc.1.memdev=mem1,sgx-epc.1.node=1 \ - ...... - -Signed-off-by: Yang Zhong -Message-Id: <20211101162009.62161-2-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - hw/core/numa.c | 5 ++--- - hw/i386/acpi-build.c | 2 ++ - hw/i386/sgx-epc.c | 3 +++ - hw/i386/sgx-stub.c | 4 ++++ - hw/i386/sgx.c | 44 +++++++++++++++++++++++++++++++++++++++ - include/hw/i386/sgx-epc.h | 3 +++ - monitor/hmp-cmds.c | 1 + - qapi/machine.json | 10 ++++++++- - qemu-options.hx | 4 ++-- - 9 files changed, 70 insertions(+), 6 deletions(-) - -diff --git a/hw/core/numa.c b/hw/core/numa.c -index e6050b2273..1aa05dcf42 100644 ---- a/hw/core/numa.c -+++ b/hw/core/numa.c -@@ -784,9 +784,8 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) - break; - case MEMORY_DEVICE_INFO_KIND_SGX_EPC: - se = value->u.sgx_epc.data; -- /* TODO: once we support numa, assign to right node */ -- node_mem[0].node_mem += se->size; -- node_mem[0].node_plugged_mem += se->size; -+ node_mem[se->node].node_mem += se->size; -+ node_mem[se->node].node_plugged_mem = 0; - break; - default: - g_assert_not_reached(); -diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c -index 0ec2932ec2..1e33e1f3d0 100644 ---- a/hw/i386/acpi-build.c -+++ b/hw/i386/acpi-build.c -@@ -2068,6 +2068,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) - nvdimm_build_srat(table_data); - } - -+ sgx_epc_build_srat(table_data); -+ - /* - * TODO: this part is not in ACPI spec and current linux kernel boots fine - * without these entries. But I recall there were issues the last time I -diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c -index e508827e78..96b2940d75 100644 ---- a/hw/i386/sgx-epc.c -+++ b/hw/i386/sgx-epc.c -@@ -21,6 +21,7 @@ - - static Property sgx_epc_properties[] = { - DEFINE_PROP_UINT64(SGX_EPC_ADDR_PROP, SGXEPCDevice, addr, 0), -+ DEFINE_PROP_UINT32(SGX_EPC_NUMA_NODE_PROP, SGXEPCDevice, node, 0), - DEFINE_PROP_LINK(SGX_EPC_MEMDEV_PROP, SGXEPCDevice, hostmem, - TYPE_MEMORY_BACKEND_EPC, HostMemoryBackendEpc *), - DEFINE_PROP_END_OF_LIST(), -@@ -139,6 +140,8 @@ static void sgx_epc_md_fill_device_info(const MemoryDeviceState *md, - se->memaddr = epc->addr; - se->size = object_property_get_uint(OBJECT(epc), SGX_EPC_SIZE_PROP, - NULL); -+ se->node = object_property_get_uint(OBJECT(epc), SGX_EPC_NUMA_NODE_PROP, -+ NULL); - se->memdev = object_get_canonical_path(OBJECT(epc->hostmem)); - - info->u.sgx_epc.data = se; -diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c -index c9b379e665..26833eb233 100644 ---- a/hw/i386/sgx-stub.c -+++ b/hw/i386/sgx-stub.c -@@ -6,6 +6,10 @@ - #include "qapi/error.h" - #include "qapi/qapi-commands-misc-target.h" - -+void sgx_epc_build_srat(GArray *table_data) -+{ -+} -+ - SGXInfo *qmp_query_sgx(Error **errp) - { - error_setg(errp, "SGX support is not compiled in"); -diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c -index 8fef3dd8fa..d04299904a 100644 ---- a/hw/i386/sgx.c -+++ b/hw/i386/sgx.c -@@ -23,6 +23,7 @@ - #include "sysemu/hw_accel.h" - #include "sysemu/reset.h" - #include -+#include "hw/acpi/aml-build.h" - - #define SGX_MAX_EPC_SECTIONS 8 - #define SGX_CPUID_EPC_INVALID 0x0 -@@ -36,6 +37,46 @@ - - #define RETRY_NUM 2 - -+static int sgx_epc_device_list(Object *obj, void *opaque) -+{ -+ GSList **list = opaque; -+ -+ if (object_dynamic_cast(obj, TYPE_SGX_EPC)) { -+ *list = g_slist_append(*list, DEVICE(obj)); -+ } -+ -+ object_child_foreach(obj, sgx_epc_device_list, opaque); -+ return 0; -+} -+ -+static GSList *sgx_epc_get_device_list(void) -+{ -+ GSList *list = NULL; -+ -+ object_child_foreach(qdev_get_machine(), sgx_epc_device_list, &list); -+ return list; -+} -+ -+void sgx_epc_build_srat(GArray *table_data) -+{ -+ GSList *device_list = sgx_epc_get_device_list(); -+ -+ for (; device_list; device_list = device_list->next) { -+ DeviceState *dev = device_list->data; -+ Object *obj = OBJECT(dev); -+ uint64_t addr, size; -+ int node; -+ -+ node = object_property_get_uint(obj, SGX_EPC_NUMA_NODE_PROP, -+ &error_abort); -+ addr = object_property_get_uint(obj, SGX_EPC_ADDR_PROP, &error_abort); -+ size = object_property_get_uint(obj, SGX_EPC_SIZE_PROP, &error_abort); -+ -+ build_srat_memory(table_data, addr, size, node, MEM_AFFINITY_ENABLED); -+ } -+ g_slist_free(device_list); -+} -+ - static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) - { - return (low & MAKE_64BIT_MASK(12, 20)) + -@@ -226,6 +267,9 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms) - /* set the memdev link with memory backend */ - object_property_parse(obj, SGX_EPC_MEMDEV_PROP, list->value->memdev, - &error_fatal); -+ /* set the numa node property for sgx epc object */ -+ object_property_set_uint(obj, SGX_EPC_NUMA_NODE_PROP, list->value->node, -+ &error_fatal); - object_property_set_bool(obj, "realized", true, &error_fatal); - object_unref(obj); - } -diff --git a/include/hw/i386/sgx-epc.h b/include/hw/i386/sgx-epc.h -index a6a65be854..581fac389a 100644 ---- a/include/hw/i386/sgx-epc.h -+++ b/include/hw/i386/sgx-epc.h -@@ -25,6 +25,7 @@ - #define SGX_EPC_ADDR_PROP "addr" - #define SGX_EPC_SIZE_PROP "size" - #define SGX_EPC_MEMDEV_PROP "memdev" -+#define SGX_EPC_NUMA_NODE_PROP "node" - - /** - * SGXEPCDevice: -@@ -38,6 +39,7 @@ typedef struct SGXEPCDevice { - - /* public */ - uint64_t addr; -+ uint32_t node; - HostMemoryBackendEpc *hostmem; - } SGXEPCDevice; - -@@ -56,6 +58,7 @@ typedef struct SGXEPCState { - } SGXEPCState; - - bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size); -+void sgx_epc_build_srat(GArray *table_data); - - static inline uint64_t sgx_epc_above_4g_end(SGXEPCState *sgx_epc) - { -diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c -index 294652034e..9570011232 100644 ---- a/monitor/hmp-cmds.c -+++ b/monitor/hmp-cmds.c -@@ -1823,6 +1823,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) - se->id ? se->id : ""); - monitor_printf(mon, " memaddr: 0x%" PRIx64 "\n", se->memaddr); - monitor_printf(mon, " size: %" PRIu64 "\n", se->size); -+ monitor_printf(mon, " node: %" PRId64 "\n", se->node); - monitor_printf(mon, " memdev: %s\n", se->memdev); - break; - default: -diff --git a/qapi/machine.json b/qapi/machine.json -index 6ed8488255..85c35e7fc5 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -1209,12 +1209,15 @@ - # - # @memdev: memory backend linked with device - # -+# @node: the numa node -+# - # Since: 6.2 - ## - { 'struct': 'SgxEPCDeviceInfo', - 'data': { '*id': 'str', - 'memaddr': 'size', - 'size': 'size', -+ 'node': 'int', - 'memdev': 'str' - } - } -@@ -1287,10 +1290,15 @@ - # - # @memdev: memory backend linked with device - # -+# @node: the numa node -+# - # Since: 6.2 - ## - { 'struct': 'SgxEPC', -- 'data': { 'memdev': 'str' } } -+ 'data': { 'memdev': 'str', -+ 'node': 'int' -+ } -+} - - ## - # @SgxEPCProperties: -diff --git a/qemu-options.hx b/qemu-options.hx -index 74d335e4c3..1aaf38c613 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -127,11 +127,11 @@ SRST - ERST - - DEF("M", HAS_ARG, QEMU_OPTION_M, -- " sgx-epc.0.memdev=memid\n", -+ " sgx-epc.0.memdev=memid,sgx-epc.0.node=numaid\n", - QEMU_ARCH_ALL) - - SRST --``sgx-epc.0.memdev=@var{memid}`` -+``sgx-epc.0.memdev=@var{memid},sgx-epc.0.node=@var{numaid}`` - Define an SGX EPC section. - ERST - --- -2.27.0 - diff --git a/numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch b/numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch deleted file mode 100644 index ef45f00ba17d0b0066e443225058addc0e53c2d9..0000000000000000000000000000000000000000 --- a/numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 86648f137c72241005327b55208eeeed8b3cfd5e Mon Sep 17 00:00:00 2001 -From: Yang Zhong -Date: Mon, 1 Nov 2021 12:20:07 -0400 -Subject: [PATCH 2/9] numa: Support SGX numa in the monitor and Libvirt - interfaces - -from mainline-v7.0.0-rc0 -commit 4755927ae12547c2e7cb22c5fa1b39038c6c11b1 -category: feature -feature: NUMA support for SGX EPC sections -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5K27A - -Intel-SIG: commit 4755927ae125 ("numa: Support SGX numa in the monitor and -Libvirt interfaces") - ------------------------------------- - -numa: Support SGX numa in the monitor and Libvirt interfaces - -Add the SGXEPCSection list into SGXInfo to show the multiple -SGX EPC sections detailed info, not the total size like before. -This patch can enable numa support for 'info sgx' command and -QMP interfaces. The new interfaces show each EPC section info -in one numa node. Libvirt can use QMP interface to get the -detailed host SGX EPC capabilities to decide how to allocate -host EPC sections to guest. - -(qemu) info sgx - SGX support: enabled - SGX1 support: enabled - SGX2 support: enabled - FLC support: enabled - NUMA node #0: size=67108864 - NUMA node #1: size=29360128 - -The QMP interface show: -(QEMU) query-sgx -{"return": {"sgx": true, "sgx2": true, "sgx1": true, "sections": \ -[{"node": 0, "size": 67108864}, {"node": 1, "size": 29360128}], "flc": true}} - -(QEMU) query-sgx-capabilities -{"return": {"sgx": true, "sgx2": true, "sgx1": true, "sections": \ -[{"node": 0, "size": 17070817280}, {"node": 1, "size": 17079205888}], "flc": true}} - -Signed-off-by: Yang Zhong -Message-Id: <20211101162009.62161-4-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - hw/i386/sgx.c | 51 +++++++++++++++++++++++++++++++++++-------- - qapi/misc-target.json | 19 ++++++++++++++-- - 2 files changed, 59 insertions(+), 11 deletions(-) - -diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c -index d04299904a..5de5dd0893 100644 ---- a/hw/i386/sgx.c -+++ b/hw/i386/sgx.c -@@ -83,11 +83,13 @@ static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) - ((high & MAKE_64BIT_MASK(0, 20)) << 32); - } - --static uint64_t sgx_calc_host_epc_section_size(void) -+static SGXEPCSectionList *sgx_calc_host_epc_sections(void) - { -+ SGXEPCSectionList *head = NULL, **tail = &head; -+ SGXEPCSection *section; - uint32_t i, type; - uint32_t eax, ebx, ecx, edx; -- uint64_t size = 0; -+ uint32_t j = 0; - - for (i = 0; i < SGX_MAX_EPC_SECTIONS; i++) { - host_cpuid(0x12, i + 2, &eax, &ebx, &ecx, &edx); -@@ -101,10 +103,13 @@ static uint64_t sgx_calc_host_epc_section_size(void) - break; - } - -- size += sgx_calc_section_metric(ecx, edx); -+ section = g_new0(SGXEPCSection, 1); -+ section->node = j++; -+ section->size = sgx_calc_section_metric(ecx, edx); -+ QAPI_LIST_APPEND(tail, section); - } - -- return size; -+ return head; - } - - static void sgx_epc_reset(void *opaque) -@@ -168,13 +173,35 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp) - info->sgx1 = eax & (1U << 0) ? true : false; - info->sgx2 = eax & (1U << 1) ? true : false; - -- info->section_size = sgx_calc_host_epc_section_size(); -+ info->sections = sgx_calc_host_epc_sections(); - - close(fd); - - return info; - } - -+static SGXEPCSectionList *sgx_get_epc_sections_list(void) -+{ -+ GSList *device_list = sgx_epc_get_device_list(); -+ SGXEPCSectionList *head = NULL, **tail = &head; -+ SGXEPCSection *section; -+ -+ for (; device_list; device_list = device_list->next) { -+ DeviceState *dev = device_list->data; -+ Object *obj = OBJECT(dev); -+ -+ section = g_new0(SGXEPCSection, 1); -+ section->node = object_property_get_uint(obj, SGX_EPC_NUMA_NODE_PROP, -+ &error_abort); -+ section->size = object_property_get_uint(obj, SGX_EPC_SIZE_PROP, -+ &error_abort); -+ QAPI_LIST_APPEND(tail, section); -+ } -+ g_slist_free(device_list); -+ -+ return head; -+} -+ - SGXInfo *qmp_query_sgx(Error **errp) - { - SGXInfo *info = NULL; -@@ -193,14 +220,13 @@ SGXInfo *qmp_query_sgx(Error **errp) - return NULL; - } - -- SGXEPCState *sgx_epc = &pcms->sgx_epc; - info = g_new0(SGXInfo, 1); - - info->sgx = true; - info->sgx1 = true; - info->sgx2 = true; - info->flc = true; -- info->section_size = sgx_epc->size; -+ info->sections = sgx_get_epc_sections_list(); - - return info; - } -@@ -208,6 +234,7 @@ SGXInfo *qmp_query_sgx(Error **errp) - void hmp_info_sgx(Monitor *mon, const QDict *qdict) - { - Error *err = NULL; -+ SGXEPCSectionList *section_list, *section; - g_autoptr(SGXInfo) info = qmp_query_sgx(&err); - - if (err) { -@@ -222,8 +249,14 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict) - info->sgx2 ? "enabled" : "disabled"); - monitor_printf(mon, "FLC support: %s\n", - info->flc ? "enabled" : "disabled"); -- monitor_printf(mon, "size: %" PRIu64 "\n", -- info->section_size); -+ -+ section_list = info->sections; -+ for (section = section_list; section; section = section->next) { -+ monitor_printf(mon, "NUMA node #%" PRId64 ": ", -+ section->value->node); -+ monitor_printf(mon, "size=%" PRIu64 "\n", -+ section->value->size); -+ } - } - - bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size) -diff --git a/qapi/misc-target.json b/qapi/misc-target.json -index 5aa2b95b7d..1022aa0184 100644 ---- a/qapi/misc-target.json -+++ b/qapi/misc-target.json -@@ -337,6 +337,21 @@ - 'if': 'TARGET_ARM' } - - -+## -+# @SGXEPCSection: -+# -+# Information about intel SGX EPC section info -+# -+# @node: the numa node -+# -+# @size: the size of epc section -+# -+# Since: 6.2 -+## -+{ 'struct': 'SGXEPCSection', -+ 'data': { 'node': 'int', -+ 'size': 'uint64'}} -+ - ## - # @SGXInfo: - # -@@ -350,7 +365,7 @@ - # - # @flc: true if FLC is supported - # --# @section-size: The EPC section size for guest -+# @sections: The EPC sections info for guest - # - # Since: 6.2 - ## -@@ -359,7 +374,7 @@ - 'sgx1': 'bool', - 'sgx2': 'bool', - 'flc': 'bool', -- 'section-size': 'uint64'}, -+ 'sections': ['SGXEPCSection']}, - 'if': 'TARGET_I386' } - - ## --- -2.27.0 - diff --git a/oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch b/oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch deleted file mode 100644 index 6e87543dfe4485d6799039e6783c165d87452a39..0000000000000000000000000000000000000000 --- a/oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch +++ /dev/null @@ -1,56 +0,0 @@ -From e5fc3a755c9ba9f18bc0416c60f745912cb5b104 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Wed, 9 Feb 2022 14:21:39 +0800 -Subject: [PATCH 15/15] oslib-posix: optimise vm startup time for 1G hugepage - -It takes quit a long time to clear 1G-hugepage, which makes glibc -pthread_create quit slow. -Create touch_pages threads in advance, and then handle the touch_pages -callback. Only read lock is held here. ---- - util/oslib-posix.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/util/oslib-posix.c b/util/oslib-posix.c -index e8bdb02e1d..18a38b9464 100644 ---- a/util/oslib-posix.c -+++ b/util/oslib-posix.c -@@ -84,6 +84,7 @@ typedef struct MemsetThread MemsetThread; - - static MemsetThread *memset_thread; - static int memset_num_threads; -+static int started_num_threads; - static bool memset_thread_failed; - - static QemuMutex page_mutex; -@@ -464,6 +465,10 @@ static void *do_touch_pages(void *arg) - } - qemu_mutex_unlock(&page_mutex); - -+ while (started_num_threads != memset_num_threads) { -+ smp_mb(); -+ } -+ - /* unblock SIGBUS */ - sigemptyset(&set); - sigaddset(&set, SIGBUS); -@@ -529,7 +534,7 @@ static bool touch_all_pages(char *area, size_t hpagesize, size_t numpages, - memset_thread = g_new0(MemsetThread, memset_num_threads); - numpages_per_thread = numpages / memset_num_threads; - leftover = numpages % memset_num_threads; -- for (i = 0; i < memset_num_threads; i++) { -+ for (i = 0, started_num_threads = 0; i < memset_num_threads; i++) { - memset_thread[i].addr = addr; - memset_thread[i].numpages = numpages_per_thread + (i < leftover); - memset_thread[i].hpagesize = hpagesize; -@@ -537,6 +542,7 @@ static bool touch_all_pages(char *area, size_t hpagesize, size_t numpages, - do_touch_pages, &memset_thread[i], - QEMU_THREAD_JOINABLE); - addr += memset_thread[i].numpages * hpagesize; -+ started_num_threads++; - } - - qemu_mutex_lock(&page_mutex); --- -2.27.0 - diff --git a/pci-Add-return_page_response-pci-ops.patch b/pci-Add-return_page_response-pci-ops.patch deleted file mode 100644 index 25e665f8bb14c8004760a11f67e8d7b572fc1b17..0000000000000000000000000000000000000000 --- a/pci-Add-return_page_response-pci-ops.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 228345cfa59c764e725e2d3680a4bc3ecb237609 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Fri, 6 Nov 2020 14:34:35 +0100 -Subject: [PATCH] pci: Add return_page_response pci ops - -Add a new PCI operation that allows to return page responses -to registered VFIO devices - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/pci/pci.c | 16 ++++++++++++++++ - include/hw/iommu/iommu.h | 8 ++++++++ - include/hw/pci/pci.h | 4 ++++ - 3 files changed, 28 insertions(+) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 4a9374c025..64db325d6b 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -2793,6 +2793,22 @@ int pci_device_set_pasid_table(PCIBus *bus, int32_t devfn, - return -ENOENT; - } - -+int pci_device_return_page_response(PCIBus *bus, int32_t devfn, -+ IOMMUPageResponse *resp) -+{ -+ PCIDevice *dev; -+ -+ if (!bus) { -+ return -EINVAL; -+ } -+ -+ dev = bus->devices[devfn]; -+ if (dev && dev->pasid_ops && dev->pasid_ops->return_page_response) { -+ return dev->pasid_ops->return_page_response(bus, devfn, resp); -+ } -+ return -ENOENT; -+} -+ - static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque) - { - Range *range = opaque; -diff --git a/include/hw/iommu/iommu.h b/include/hw/iommu/iommu.h -index 12092bda7b..5890f095b1 100644 ---- a/include/hw/iommu/iommu.h -+++ b/include/hw/iommu/iommu.h -@@ -24,5 +24,13 @@ typedef struct IOMMUConfig { - }; - } IOMMUConfig; - -+typedef struct IOMMUPageResponse { -+ union { -+#ifdef __linux__ -+ struct iommu_page_response resp; -+#endif -+ }; -+} IOMMUPageResponse; -+ - - #endif /* QEMU_HW_IOMMU_IOMMU_H */ -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index abffa12a99..809eb32f4a 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -268,6 +268,8 @@ typedef struct PCIReqIDCache PCIReqIDCache; - - struct PCIPASIDOps { - int (*set_pasid_table)(PCIBus *bus, int32_t devfn, IOMMUConfig *config); -+ int (*return_page_response)(PCIBus *bus, int32_t devfn, -+ IOMMUPageResponse *resp); - }; - typedef struct PCIPASIDOps PCIPASIDOps; - -@@ -508,6 +510,8 @@ void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque); - void pci_setup_pasid_ops(PCIDevice *dev, PCIPASIDOps *ops); - bool pci_device_is_pasid_ops_set(PCIBus *bus, int32_t devfn); - int pci_device_set_pasid_table(PCIBus *bus, int32_t devfn, IOMMUConfig *config); -+int pci_device_return_page_response(PCIBus *bus, int32_t devfn, -+ IOMMUPageResponse *resp); - - static inline void - pci_set_byte(uint8_t *config, uint8_t val) --- -2.27.0 - diff --git a/pci-Export-the-pci_intx-function.patch b/pci-Export-the-pci_intx-function.patch deleted file mode 100644 index 732b6717538c970b9326ca1107176100b7e88a4c..0000000000000000000000000000000000000000 --- a/pci-Export-the-pci_intx-function.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0d74ea5e0426c6ebf8666e8b88469b838d03ea01 Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Thu, 7 Dec 2023 16:55:35 +0800 -Subject: [PATCH] pci: Export the pci_intx() function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from 2fedf46e34d2377760b2d26cf85487b772bca6fa - -Move the pci_intx() definition to the PCI header file, so that it can -be called from other PCI files. It is used by the next patch. - -Signed-off-by: Frederic Barrat -Message-Id: <20211116170133.724751-3-fbarrat@linux.ibm.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Cédric Le Goater -Signed-off-by: boringandboring ---- - hw/pci/pci.c | 5 ----- - include/hw/pci/pci.h | 5 +++++ - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 7a62f0e1fc..9ea67dba31 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -1504,11 +1504,6 @@ static void pci_irq_handler(void *opaque, int irq_num, int level) - pci_change_irq_level(pci_dev, irq_num, change); - } - --static inline int pci_intx(PCIDevice *pci_dev) --{ -- return pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1; --} -- - qemu_irq pci_allocate_irq(PCIDevice *pci_dev) - { - int intx = pci_intx(pci_dev); -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index 5b36334a28..483d5c7c72 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -735,6 +735,11 @@ void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev); - qemu_irq pci_allocate_irq(PCIDevice *pci_dev); - void pci_set_irq(PCIDevice *pci_dev, int level); - -+static inline int pci_intx(PCIDevice *pci_dev) -+{ -+ return pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1; -+} -+ - static inline void pci_irq_assert(PCIDevice *pci_dev) - { - pci_set_irq(pci_dev, 1); --- -2.27.0 - diff --git a/pci-Fix-the-update-of-interrupt-disable-bit-in-PCI_C.patch b/pci-Fix-the-update-of-interrupt-disable-bit-in-PCI_C.patch deleted file mode 100644 index e2b162c06e787adcbdb6aff78ca98027f27297e5..0000000000000000000000000000000000000000 --- a/pci-Fix-the-update-of-interrupt-disable-bit-in-PCI_C.patch +++ /dev/null @@ -1,53 +0,0 @@ -From d81bf8c86e2b024f85d90e199181ae048134d4ee Mon Sep 17 00:00:00 2001 -From: Guoyi Tu -Date: Fri, 11 Aug 2023 22:46:51 +0800 -Subject: [PATCH] pci: Fix the update of interrupt disable bit in PCI_COMMAND - register - -The PCI_COMMAND register is located at offset 4 within -the PCI configuration space and occupies 2 bytes. The -interrupt disable bit is at the 10th bit, which corresponds -to the byte at offset 5 in the PCI configuration space. - -In our testing environment, the guest driver may directly -updates the byte at offset 5 in the PCI configuration space. -The backtrace looks like as following: - at hw/pci/pci.c:1442 - at hw/virtio/virtio-pci.c:605 - val=5, len=1) at hw/pci/pci_host.c:81 - -In this situation, the range_covers_byte function called -by the pci_default_write_config function will return false, -resulting in the inability to handle the interrupt disable -update event. - -To fix this issue, we can use the ranges_overlap function -instead of range_covers_byte to determine whether the interrupt -bit has been updated. - -Signed-off-by: Guoyi Tu -Signed-off-by: yuanminghao -Message-Id: -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Fixes: b6981cb57be5 ("pci: interrupt disable bit support") ---- - hw/pci/pci.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 3e6805d54a..3a4619e2a5 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -1471,7 +1471,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int - range_covers_byte(addr, l, PCI_COMMAND)) - pci_update_mappings(d); - -- if (range_covers_byte(addr, l, PCI_COMMAND)) { -+ if (ranges_overlap(addr, l, PCI_COMMAND, 2)) { - pci_update_irq_disabled(d, was_irq_disabled); - memory_region_set_enabled(&d->bus_master_enable_region, - (pci_get_word(d->config + PCI_COMMAND) --- -2.27.0 - diff --git a/pci-Let-ld-_pci_dma-propagate-MemTxResult.patch b/pci-Let-ld-_pci_dma-propagate-MemTxResult.patch deleted file mode 100644 index 91406d122841c2f8f9e06bcfccc3f7ac8a99ac31..0000000000000000000000000000000000000000 --- a/pci-Let-ld-_pci_dma-propagate-MemTxResult.patch +++ /dev/null @@ -1,292 +0,0 @@ -From d7e2bb6bba0b5b77b296ca99b26c0d0a4db0d9f0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 23:49:30 +0100 -Subject: [PATCH 22/25] pci: Let ld*_pci_dma() propagate MemTxResult -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -ld*_dma() returns a MemTxResult type. Do not discard -it, return it to the caller. - -Update the few callers. - -Reviewed-by: Richard Henderson -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-24-philmd@redhat.com> ---- - hw/audio/intel-hda.c | 2 +- - hw/net/eepro100.c | 25 ++++++++++--------------- - hw/net/tulip.c | 16 ++++++++-------- - hw/scsi/megasas.c | 21 ++++++++++++--------- - hw/scsi/mptsas.c | 16 +++++++++++----- - hw/scsi/vmw_pvscsi.c | 16 ++++++++++------ - include/hw/pci/pci.h | 17 ++++++++--------- - 7 files changed, 60 insertions(+), 53 deletions(-) - -diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c -index e34b7ab0e9..2b55d52150 100644 ---- a/hw/audio/intel-hda.c -+++ b/hw/audio/intel-hda.c -@@ -335,7 +335,7 @@ static void intel_hda_corb_run(IntelHDAState *d) - - rp = (d->corb_rp + 1) & 0xff; - addr = intel_hda_addr(d->corb_lbase, d->corb_ubase); -- verb = ldl_le_pci_dma(&d->pci, addr + 4 * rp, MEMTXATTRS_UNSPECIFIED); -+ ldl_le_pci_dma(&d->pci, addr + 4 * rp, &verb, MEMTXATTRS_UNSPECIFIED); - d->corb_rp = rp; - - dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __func__, rp, verb); -diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c -index 36dc1e22d7..9c178c1448 100644 ---- a/hw/net/eepro100.c -+++ b/hw/net/eepro100.c -@@ -772,18 +772,16 @@ static void tx_command(EEPRO100State *s) - } else { - /* Flexible mode. */ - uint8_t tbd_count = 0; -+ uint32_t tx_buffer_address; -+ uint16_t tx_buffer_size; -+ uint16_t tx_buffer_el; -+ - if (s->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) { - /* Extended Flexible TCB. */ - for (; tbd_count < 2; tbd_count++) { -- uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, -- tbd_address, -- attrs); -- uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, -- tbd_address + 4, -- attrs); -- uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, -- tbd_address + 6, -- attrs); -+ ldl_le_pci_dma(&s->dev, tbd_address, &tx_buffer_address, attrs); -+ lduw_le_pci_dma(&s->dev, tbd_address + 4, &tx_buffer_size, attrs); -+ lduw_le_pci_dma(&s->dev, tbd_address + 6, &tx_buffer_el, attrs); - tbd_address += 8; - TRACE(RXTX, logout - ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n", -@@ -799,12 +797,9 @@ static void tx_command(EEPRO100State *s) - } - tbd_address = tbd_array; - for (; tbd_count < s->tx.tbd_count; tbd_count++) { -- uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address, -- attrs); -- uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4, -- attrs); -- uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6, -- attrs); -+ ldl_le_pci_dma(&s->dev, tbd_address, &tx_buffer_address, attrs); -+ lduw_le_pci_dma(&s->dev, tbd_address + 4, &tx_buffer_size, attrs); -+ lduw_le_pci_dma(&s->dev, tbd_address + 6, &tx_buffer_el, attrs); - tbd_address += 8; - TRACE(RXTX, logout - ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n", -diff --git a/hw/net/tulip.c b/hw/net/tulip.c -index c76e4868f7..d5b6cc5ee6 100644 ---- a/hw/net/tulip.c -+++ b/hw/net/tulip.c -@@ -73,15 +73,15 @@ static void tulip_desc_read(TULIPState *s, hwaddr p, - const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - - if (s->csr[0] & CSR0_DBO) { -- desc->status = ldl_be_pci_dma(&s->dev, p, attrs); -- desc->control = ldl_be_pci_dma(&s->dev, p + 4, attrs); -- desc->buf_addr1 = ldl_be_pci_dma(&s->dev, p + 8, attrs); -- desc->buf_addr2 = ldl_be_pci_dma(&s->dev, p + 12, attrs); -+ ldl_be_pci_dma(&s->dev, p, &desc->status, attrs); -+ ldl_be_pci_dma(&s->dev, p + 4, &desc->control, attrs); -+ ldl_be_pci_dma(&s->dev, p + 8, &desc->buf_addr1, attrs); -+ ldl_be_pci_dma(&s->dev, p + 12, &desc->buf_addr2, attrs); - } else { -- desc->status = ldl_le_pci_dma(&s->dev, p, attrs); -- desc->control = ldl_le_pci_dma(&s->dev, p + 4, attrs); -- desc->buf_addr1 = ldl_le_pci_dma(&s->dev, p + 8, attrs); -- desc->buf_addr2 = ldl_le_pci_dma(&s->dev, p + 12, attrs); -+ ldl_le_pci_dma(&s->dev, p, &desc->status, attrs); -+ ldl_le_pci_dma(&s->dev, p + 4, &desc->control, attrs); -+ ldl_le_pci_dma(&s->dev, p + 8, &desc->buf_addr1, attrs); -+ ldl_le_pci_dma(&s->dev, p + 12, &desc->buf_addr2, attrs); - } - } - -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index 23380008e1..946050bf83 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -202,9 +202,12 @@ static uint64_t megasas_frame_get_context(MegasasState *s, - unsigned long frame) - { - PCIDevice *pci = &s->parent_obj; -- return ldq_le_pci_dma(pci, -- frame + offsetof(struct mfi_frame_header, context), -- MEMTXATTRS_UNSPECIFIED); -+ uint64_t val; -+ -+ ldq_le_pci_dma(pci, frame + offsetof(struct mfi_frame_header, context), -+ &val, MEMTXATTRS_UNSPECIFIED); -+ -+ return val; - } - - static bool megasas_frame_is_ieee_sgl(MegasasCmd *cmd) -@@ -535,8 +538,8 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s, - s->busy++; - - if (s->consumer_pa) { -- s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa, -- MEMTXATTRS_UNSPECIFIED); -+ ldl_le_pci_dma(pcid, s->consumer_pa, &s->reply_queue_tail, -+ MEMTXATTRS_UNSPECIFIED); - } - trace_megasas_qf_enqueue(cmd->index, cmd->count, cmd->context, - s->reply_queue_head, s->reply_queue_tail, s->busy); -@@ -567,14 +570,14 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context) - stl_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset, - context, attrs); - } -- s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa, attrs); -+ ldl_le_pci_dma(pci_dev, s->consumer_pa, &s->reply_queue_tail, attrs); - trace_megasas_qf_complete(context, s->reply_queue_head, - s->reply_queue_tail, s->busy); - } - - if (megasas_intr_enabled(s)) { - /* Update reply queue pointer */ -- s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa, attrs); -+ ldl_le_pci_dma(pci_dev, s->consumer_pa, &s->reply_queue_tail, attrs); - tail = s->reply_queue_head; - s->reply_queue_head = megasas_next_index(s, tail, s->fw_cmds); - trace_megasas_qf_update(s->reply_queue_head, s->reply_queue_tail, -@@ -678,9 +681,9 @@ static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd) - pa_lo = le32_to_cpu(initq->pi_addr_lo); - pa_hi = le32_to_cpu(initq->pi_addr_hi); - s->producer_pa = ((uint64_t) pa_hi << 32) | pa_lo; -- s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa, attrs); -+ ldl_le_pci_dma(pcid, s->producer_pa, &s->reply_queue_head, attrs); - s->reply_queue_head %= MEGASAS_MAX_FRAMES; -- s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa, attrs); -+ ldl_le_pci_dma(pcid, s->consumer_pa, &s->reply_queue_tail, attrs); - s->reply_queue_tail %= MEGASAS_MAX_FRAMES; - flags = le32_to_cpu(initq->flags); - if (flags & MFI_QUEUE_FLAG_CONTEXT64) { -diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c -index ac9f4dfcd2..5181b0c0b0 100644 ---- a/hw/scsi/mptsas.c -+++ b/hw/scsi/mptsas.c -@@ -177,10 +177,16 @@ static dma_addr_t mptsas_ld_sg_base(MPTSASState *s, uint32_t flags_and_length, - dma_addr_t addr; - - if (flags_and_length & MPI_SGE_FLAGS_64_BIT_ADDRESSING) { -- addr = ldq_le_pci_dma(pci, *sgaddr + 4, attrs); -+ uint64_t addr64; -+ -+ ldq_le_pci_dma(pci, *sgaddr + 4, &addr64, attrs); -+ addr = addr64; - *sgaddr += 12; - } else { -- addr = ldl_le_pci_dma(pci, *sgaddr + 4, attrs); -+ uint32_t addr32; -+ -+ ldl_le_pci_dma(pci, *sgaddr + 4, &addr32, attrs); -+ addr = addr32; - *sgaddr += 8; - } - return addr; -@@ -204,7 +210,7 @@ static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr) - dma_addr_t addr, len; - uint32_t flags_and_length; - -- flags_and_length = ldl_le_pci_dma(pci, sgaddr, MEMTXATTRS_UNSPECIFIED); -+ ldl_le_pci_dma(pci, sgaddr, &flags_and_length, MEMTXATTRS_UNSPECIFIED); - len = flags_and_length & MPI_SGE_LENGTH_MASK; - if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK) - != MPI_SGE_FLAGS_SIMPLE_ELEMENT || -@@ -235,8 +241,8 @@ static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr) - break; - } - -- flags_and_length = ldl_le_pci_dma(pci, next_chain_addr, -- MEMTXATTRS_UNSPECIFIED); -+ ldl_le_pci_dma(pci, next_chain_addr, &flags_and_length, -+ MEMTXATTRS_UNSPECIFIED); - if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK) - != MPI_SGE_FLAGS_CHAIN_ELEMENT) { - return MPI_IOCSTATUS_INVALID_SGL; -diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c -index 33e16f9111..4d9969f3b1 100644 ---- a/hw/scsi/vmw_pvscsi.c -+++ b/hw/scsi/vmw_pvscsi.c -@@ -50,10 +50,10 @@ - #define PVSCSI_MAX_CMD_DATA_WORDS \ - (sizeof(PVSCSICmdDescSetupRings)/sizeof(uint32_t)) - --#define RS_GET_FIELD(m, field) \ -- (ldl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \ -+#define RS_GET_FIELD(pval, m, field) \ -+ ldl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \ - (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), \ -- MEMTXATTRS_UNSPECIFIED)) -+ pval, MEMTXATTRS_UNSPECIFIED) - #define RS_SET_FIELD(m, field, val) \ - (stl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \ - (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val, \ -@@ -249,10 +249,11 @@ pvscsi_ring_cleanup(PVSCSIRingInfo *mgr) - static hwaddr - pvscsi_ring_pop_req_descr(PVSCSIRingInfo *mgr) - { -- uint32_t ready_ptr = RS_GET_FIELD(mgr, reqProdIdx); -+ uint32_t ready_ptr; - uint32_t ring_size = PVSCSI_MAX_NUM_PAGES_REQ_RING - * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE; - -+ RS_GET_FIELD(&ready_ptr, mgr, reqProdIdx); - if (ready_ptr != mgr->consumed_ptr - && ready_ptr - mgr->consumed_ptr < ring_size) { - uint32_t next_ready_ptr = -@@ -323,8 +324,11 @@ pvscsi_ring_flush_cmp(PVSCSIRingInfo *mgr) - static bool - pvscsi_ring_msg_has_room(PVSCSIRingInfo *mgr) - { -- uint32_t prodIdx = RS_GET_FIELD(mgr, msgProdIdx); -- uint32_t consIdx = RS_GET_FIELD(mgr, msgConsIdx); -+ uint32_t prodIdx; -+ uint32_t consIdx; -+ -+ RS_GET_FIELD(&prodIdx, mgr, msgProdIdx); -+ RS_GET_FIELD(&consIdx, mgr, msgConsIdx); - - return (prodIdx - consIdx) < (mgr->msg_len_mask + 1); - } -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index a9834e17e2..bfe3a6bca7 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -865,15 +865,14 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED); - } - --#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \ -- static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \ -- dma_addr_t addr, \ -- MemTxAttrs attrs) \ -- { \ -- uint##_bits##_t val; \ -- ld##_l##_dma(pci_get_address_space(dev), addr, &val, attrs); \ -- return val; \ -- } \ -+#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \ -+ static inline MemTxResult ld##_l##_pci_dma(PCIDevice *dev, \ -+ dma_addr_t addr, \ -+ uint##_bits##_t *val, \ -+ MemTxAttrs attrs) \ -+ { \ -+ return ld##_l##_dma(pci_get_address_space(dev), addr, val, attrs); \ -+ } \ - static inline MemTxResult st##_s##_pci_dma(PCIDevice *dev, \ - dma_addr_t addr, \ - uint##_bits##_t val, \ --- -2.27.0 - diff --git a/pci-Let-ld-_pci_dma-take-MemTxAttrs-argument.patch b/pci-Let-ld-_pci_dma-take-MemTxAttrs-argument.patch deleted file mode 100644 index cbe94d91e2ab0a1ed53f897affab8445bcceca65..0000000000000000000000000000000000000000 --- a/pci-Let-ld-_pci_dma-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,267 +0,0 @@ -From 0317671b81ebbff7187a1b836a2adde4fe16b762 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 23:45:06 +0100 -Subject: [PATCH 20/25] pci: Let ld*_pci_dma() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling ld*_pci_dma(). - -Keep the default MEMTXATTRS_UNSPECIFIED in the few callers. - -Reviewed-by: Richard Henderson -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-22-philmd@redhat.com> ---- - hw/audio/intel-hda.c | 2 +- - hw/net/eepro100.c | 19 +++++++++++++------ - hw/net/tulip.c | 18 ++++++++++-------- - hw/scsi/megasas.c | 16 ++++++++++------ - hw/scsi/mptsas.c | 10 ++++++---- - hw/scsi/vmw_pvscsi.c | 3 ++- - hw/usb/hcd-xhci.c | 1 + - include/hw/pci/pci.h | 6 +++--- - 8 files changed, 46 insertions(+), 29 deletions(-) - -diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c -index 3309ae0ea1..e34b7ab0e9 100644 ---- a/hw/audio/intel-hda.c -+++ b/hw/audio/intel-hda.c -@@ -335,7 +335,7 @@ static void intel_hda_corb_run(IntelHDAState *d) - - rp = (d->corb_rp + 1) & 0xff; - addr = intel_hda_addr(d->corb_lbase, d->corb_ubase); -- verb = ldl_le_pci_dma(&d->pci, addr + 4*rp); -+ verb = ldl_le_pci_dma(&d->pci, addr + 4 * rp, MEMTXATTRS_UNSPECIFIED); - d->corb_rp = rp; - - dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __func__, rp, verb); -diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c -index 160b9b0b4c..36dc1e22d7 100644 ---- a/hw/net/eepro100.c -+++ b/hw/net/eepro100.c -@@ -740,6 +740,7 @@ static void read_cb(EEPRO100State *s) - - static void tx_command(EEPRO100State *s) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - uint32_t tbd_array = s->tx.tbd_array_addr; - uint16_t tcb_bytes = s->tx.tcb_bytes & 0x3fff; - /* Sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes. */ -@@ -775,11 +776,14 @@ static void tx_command(EEPRO100State *s) - /* Extended Flexible TCB. */ - for (; tbd_count < 2; tbd_count++) { - uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, -- tbd_address); -+ tbd_address, -+ attrs); - uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, -- tbd_address + 4); -+ tbd_address + 4, -+ attrs); - uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, -- tbd_address + 6); -+ tbd_address + 6, -+ attrs); - tbd_address += 8; - TRACE(RXTX, logout - ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n", -@@ -795,9 +799,12 @@ static void tx_command(EEPRO100State *s) - } - tbd_address = tbd_array; - for (; tbd_count < s->tx.tbd_count; tbd_count++) { -- uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address); -- uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4); -- uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6); -+ uint32_t tx_buffer_address = ldl_le_pci_dma(&s->dev, tbd_address, -+ attrs); -+ uint16_t tx_buffer_size = lduw_le_pci_dma(&s->dev, tbd_address + 4, -+ attrs); -+ uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6, -+ attrs); - tbd_address += 8; - TRACE(RXTX, logout - ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n", -diff --git a/hw/net/tulip.c b/hw/net/tulip.c -index 1f2c79dd58..c76e4868f7 100644 ---- a/hw/net/tulip.c -+++ b/hw/net/tulip.c -@@ -70,16 +70,18 @@ static const VMStateDescription vmstate_pci_tulip = { - static void tulip_desc_read(TULIPState *s, hwaddr p, - struct tulip_descriptor *desc) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; -+ - if (s->csr[0] & CSR0_DBO) { -- desc->status = ldl_be_pci_dma(&s->dev, p); -- desc->control = ldl_be_pci_dma(&s->dev, p + 4); -- desc->buf_addr1 = ldl_be_pci_dma(&s->dev, p + 8); -- desc->buf_addr2 = ldl_be_pci_dma(&s->dev, p + 12); -+ desc->status = ldl_be_pci_dma(&s->dev, p, attrs); -+ desc->control = ldl_be_pci_dma(&s->dev, p + 4, attrs); -+ desc->buf_addr1 = ldl_be_pci_dma(&s->dev, p + 8, attrs); -+ desc->buf_addr2 = ldl_be_pci_dma(&s->dev, p + 12, attrs); - } else { -- desc->status = ldl_le_pci_dma(&s->dev, p); -- desc->control = ldl_le_pci_dma(&s->dev, p + 4); -- desc->buf_addr1 = ldl_le_pci_dma(&s->dev, p + 8); -- desc->buf_addr2 = ldl_le_pci_dma(&s->dev, p + 12); -+ desc->status = ldl_le_pci_dma(&s->dev, p, attrs); -+ desc->control = ldl_le_pci_dma(&s->dev, p + 4, attrs); -+ desc->buf_addr1 = ldl_le_pci_dma(&s->dev, p + 8, attrs); -+ desc->buf_addr2 = ldl_le_pci_dma(&s->dev, p + 12, attrs); - } - } - -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index b4d448370f..23380008e1 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -202,7 +202,9 @@ static uint64_t megasas_frame_get_context(MegasasState *s, - unsigned long frame) - { - PCIDevice *pci = &s->parent_obj; -- return ldq_le_pci_dma(pci, frame + offsetof(struct mfi_frame_header, context)); -+ return ldq_le_pci_dma(pci, -+ frame + offsetof(struct mfi_frame_header, context), -+ MEMTXATTRS_UNSPECIFIED); - } - - static bool megasas_frame_is_ieee_sgl(MegasasCmd *cmd) -@@ -533,7 +535,8 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s, - s->busy++; - - if (s->consumer_pa) { -- s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa); -+ s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa, -+ MEMTXATTRS_UNSPECIFIED); - } - trace_megasas_qf_enqueue(cmd->index, cmd->count, cmd->context, - s->reply_queue_head, s->reply_queue_tail, s->busy); -@@ -564,14 +567,14 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context) - stl_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset, - context, attrs); - } -- s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa); -+ s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa, attrs); - trace_megasas_qf_complete(context, s->reply_queue_head, - s->reply_queue_tail, s->busy); - } - - if (megasas_intr_enabled(s)) { - /* Update reply queue pointer */ -- s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa); -+ s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa, attrs); - tail = s->reply_queue_head; - s->reply_queue_head = megasas_next_index(s, tail, s->fw_cmds); - trace_megasas_qf_update(s->reply_queue_head, s->reply_queue_tail, -@@ -636,6 +639,7 @@ static void megasas_abort_command(MegasasCmd *cmd) - - static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - PCIDevice *pcid = PCI_DEVICE(s); - uint32_t pa_hi, pa_lo; - hwaddr iq_pa, initq_size = sizeof(struct mfi_init_qinfo); -@@ -674,9 +678,9 @@ static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd) - pa_lo = le32_to_cpu(initq->pi_addr_lo); - pa_hi = le32_to_cpu(initq->pi_addr_hi); - s->producer_pa = ((uint64_t) pa_hi << 32) | pa_lo; -- s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa); -+ s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa, attrs); - s->reply_queue_head %= MEGASAS_MAX_FRAMES; -- s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa); -+ s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa, attrs); - s->reply_queue_tail %= MEGASAS_MAX_FRAMES; - flags = le32_to_cpu(initq->flags); - if (flags & MFI_QUEUE_FLAG_CONTEXT64) { -diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c -index f6c7765544..ac9f4dfcd2 100644 ---- a/hw/scsi/mptsas.c -+++ b/hw/scsi/mptsas.c -@@ -172,14 +172,15 @@ static const int mpi_request_sizes[] = { - static dma_addr_t mptsas_ld_sg_base(MPTSASState *s, uint32_t flags_and_length, - dma_addr_t *sgaddr) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - PCIDevice *pci = (PCIDevice *) s; - dma_addr_t addr; - - if (flags_and_length & MPI_SGE_FLAGS_64_BIT_ADDRESSING) { -- addr = ldq_le_pci_dma(pci, *sgaddr + 4); -+ addr = ldq_le_pci_dma(pci, *sgaddr + 4, attrs); - *sgaddr += 12; - } else { -- addr = ldl_le_pci_dma(pci, *sgaddr + 4); -+ addr = ldl_le_pci_dma(pci, *sgaddr + 4, attrs); - *sgaddr += 8; - } - return addr; -@@ -203,7 +204,7 @@ static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr) - dma_addr_t addr, len; - uint32_t flags_and_length; - -- flags_and_length = ldl_le_pci_dma(pci, sgaddr); -+ flags_and_length = ldl_le_pci_dma(pci, sgaddr, MEMTXATTRS_UNSPECIFIED); - len = flags_and_length & MPI_SGE_LENGTH_MASK; - if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK) - != MPI_SGE_FLAGS_SIMPLE_ELEMENT || -@@ -234,7 +235,8 @@ static int mptsas_build_sgl(MPTSASState *s, MPTSASRequest *req, hwaddr addr) - break; - } - -- flags_and_length = ldl_le_pci_dma(pci, next_chain_addr); -+ flags_and_length = ldl_le_pci_dma(pci, next_chain_addr, -+ MEMTXATTRS_UNSPECIFIED); - if ((flags_and_length & MPI_SGE_FLAGS_ELEMENT_TYPE_MASK) - != MPI_SGE_FLAGS_CHAIN_ELEMENT) { - return MPI_IOCSTATUS_INVALID_SGL; -diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c -index 59c3e8ba04..33e16f9111 100644 ---- a/hw/scsi/vmw_pvscsi.c -+++ b/hw/scsi/vmw_pvscsi.c -@@ -52,7 +52,8 @@ - - #define RS_GET_FIELD(m, field) \ - (ldl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \ -- (m)->rs_pa + offsetof(struct PVSCSIRingsState, field))) -+ (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), \ -+ MEMTXATTRS_UNSPECIFIED)) - #define RS_SET_FIELD(m, field, val) \ - (stl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \ - (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val, \ -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 30c477f36e..47fb79aa4d 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -3444,6 +3444,7 @@ static int usb_xhci_post_load(void *opaque, int version_id) - } - ldq_le_dma(xhci->as, dcbaap + 8 * slotid, &addr, MEMTXATTRS_UNSPECIFIED); - slot->ctx = xhci_mask64(addr); -+ - xhci_dma_read_u32s(xhci, slot->ctx, slot_ctx, sizeof(slot_ctx)); - slot->uport = xhci_lookup_uport(xhci, slot_ctx); - if (!slot->uport) { -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index f6b0e843c1..d0f0d9bd50 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -867,11 +867,11 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - - #define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \ - static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \ -- dma_addr_t addr) \ -+ dma_addr_t addr, \ -+ MemTxAttrs attrs) \ - { \ - uint##_bits##_t val; \ -- ld##_l##_dma(pci_get_address_space(dev), addr, &val, \ -- MEMTXATTRS_UNSPECIFIED); \ -+ ld##_l##_dma(pci_get_address_space(dev), addr, &val, attrs); \ - return val; \ - } \ - static inline void st##_s##_pci_dma(PCIDevice *dev, \ --- -2.27.0 - diff --git a/pci-Let-pci_dma_rw-take-MemTxAttrs-argument.patch b/pci-Let-pci_dma_rw-take-MemTxAttrs-argument.patch deleted file mode 100644 index 58511afd9869fcba23deb729d16bfcc6363f09f6..0000000000000000000000000000000000000000 --- a/pci-Let-pci_dma_rw-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,88 +0,0 @@ -From de60977c6a41b6de65e74918024c150e44311940 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Wed, 15 Dec 2021 22:18:19 +0100 -Subject: [PATCH 10/25] pci: Let pci_dma_rw() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling pci_dma_rw(). - -Keep the default MEMTXATTRS_UNSPECIFIED in the few callers. - -Reviewed-by: Klaus Jensen -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-10-philmd@redhat.com> ---- - hw/audio/intel-hda.c | 3 ++- - hw/scsi/esp-pci.c | 2 +- - include/hw/pci/pci.h | 10 ++++++---- - 3 files changed, 9 insertions(+), 6 deletions(-) - -diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c -index 8ce9df64e3..fb3d34a4a0 100644 ---- a/hw/audio/intel-hda.c -+++ b/hw/audio/intel-hda.c -@@ -427,7 +427,8 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, - dprint(d, 3, "dma: entry %d, pos %d/%d, copy %d\n", - st->be, st->bp, st->bpl[st->be].len, copy); - -- pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output); -+ pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output, -+ MEMTXATTRS_UNSPECIFIED); - st->lpib += copy; - st->bp += copy; - buf += copy; -diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c -index dac054aeed..1792f84cea 100644 ---- a/hw/scsi/esp-pci.c -+++ b/hw/scsi/esp-pci.c -@@ -280,7 +280,7 @@ static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t *buf, int len, - len = pci->dma_regs[DMA_WBC]; - } - -- pci_dma_rw(PCI_DEVICE(pci), addr, buf, len, dir); -+ pci_dma_rw(PCI_DEVICE(pci), addr, buf, len, dir, MEMTXATTRS_UNSPECIFIED); - - /* update status registers */ - pci->dma_regs[DMA_WBC] -= len; -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index c3d5e06364..c7177646a4 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -821,10 +821,10 @@ static inline AddressSpace *pci_get_address_space(PCIDevice *dev) - */ - static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr, - void *buf, dma_addr_t len, -- DMADirection dir) -+ DMADirection dir, MemTxAttrs attrs) - { - return dma_memory_rw(pci_get_address_space(dev), addr, buf, len, -- dir, MEMTXATTRS_UNSPECIFIED); -+ dir, attrs); - } - - /** -@@ -842,7 +842,8 @@ static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr, - static inline MemTxResult pci_dma_read(PCIDevice *dev, dma_addr_t addr, - void *buf, dma_addr_t len) - { -- return pci_dma_rw(dev, addr, buf, len, DMA_DIRECTION_TO_DEVICE); -+ return pci_dma_rw(dev, addr, buf, len, -+ DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED); - } - - /** -@@ -860,7 +861,8 @@ static inline MemTxResult pci_dma_read(PCIDevice *dev, dma_addr_t addr, - static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - const void *buf, dma_addr_t len) - { -- return pci_dma_rw(dev, addr, (void *) buf, len, DMA_DIRECTION_FROM_DEVICE); -+ return pci_dma_rw(dev, addr, (void *) buf, len, -+ DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED); - } - - #define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \ --- -2.27.0 - diff --git a/pci-Let-st-_pci_dma-propagate-MemTxResult.patch b/pci-Let-st-_pci_dma-propagate-MemTxResult.patch deleted file mode 100644 index 6dc64011a2ea27cb9f4069f9f70cd6f782881086..0000000000000000000000000000000000000000 --- a/pci-Let-st-_pci_dma-propagate-MemTxResult.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b498014d3214e053cfc97d0d48bcaae3176764ca Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 23:47:30 +0100 -Subject: [PATCH 21/25] pci: Let st*_pci_dma() propagate MemTxResult -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -st*_dma() returns a MemTxResult type. Do not discard -it, return it to the caller. - -Reviewed-by: Richard Henderson -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-23-philmd@redhat.com> ---- - include/hw/pci/pci.h | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index d0f0d9bd50..a9834e17e2 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -874,12 +874,12 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - ld##_l##_dma(pci_get_address_space(dev), addr, &val, attrs); \ - return val; \ - } \ -- static inline void st##_s##_pci_dma(PCIDevice *dev, \ -- dma_addr_t addr, \ -- uint##_bits##_t val, \ -- MemTxAttrs attrs) \ -+ static inline MemTxResult st##_s##_pci_dma(PCIDevice *dev, \ -+ dma_addr_t addr, \ -+ uint##_bits##_t val, \ -+ MemTxAttrs attrs) \ - { \ -- st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \ -+ return st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \ - } - - PCI_DMA_DEFINE_LDST(ub, b, 8); --- -2.27.0 - diff --git a/pci-Let-st-_pci_dma-take-MemTxAttrs-argument.patch b/pci-Let-st-_pci_dma-take-MemTxAttrs-argument.patch deleted file mode 100644 index a99cd45746110861ac637eb09feadd22306e3df5..0000000000000000000000000000000000000000 --- a/pci-Let-st-_pci_dma-take-MemTxAttrs-argument.patch +++ /dev/null @@ -1,299 +0,0 @@ -From b823af328bc872734b0a2e4b0db3c5d2ec27a83f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Fri, 17 Dec 2021 22:39:42 +0100 -Subject: [PATCH 19/25] pci: Let st*_pci_dma() take MemTxAttrs argument -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let devices specify transaction attributes when calling st*_pci_dma(). - -Keep the default MEMTXATTRS_UNSPECIFIED in the few callers. - -Reviewed-by: Richard Henderson -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211223115554.3155328-21-philmd@redhat.com> ---- - hw/audio/intel-hda.c | 10 ++++++---- - hw/net/eepro100.c | 29 ++++++++++++++++++----------- - hw/net/tulip.c | 18 ++++++++++-------- - hw/scsi/megasas.c | 15 ++++++++++----- - hw/scsi/vmw_pvscsi.c | 3 ++- - include/hw/pci/pci.h | 11 ++++++----- - 6 files changed, 52 insertions(+), 34 deletions(-) - -diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c -index fb3d34a4a0..3309ae0ea1 100644 ---- a/hw/audio/intel-hda.c -+++ b/hw/audio/intel-hda.c -@@ -345,6 +345,7 @@ static void intel_hda_corb_run(IntelHDAState *d) - - static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t response) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus); - IntelHDAState *d = container_of(bus, IntelHDAState, codecs); - hwaddr addr; -@@ -367,8 +368,8 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res - ex = (solicited ? 0 : (1 << 4)) | dev->cad; - wp = (d->rirb_wp + 1) & 0xff; - addr = intel_hda_addr(d->rirb_lbase, d->rirb_ubase); -- stl_le_pci_dma(&d->pci, addr + 8*wp, response); -- stl_le_pci_dma(&d->pci, addr + 8*wp + 4, ex); -+ stl_le_pci_dma(&d->pci, addr + 8 * wp, response, attrs); -+ stl_le_pci_dma(&d->pci, addr + 8 * wp + 4, ex, attrs); - d->rirb_wp = wp; - - dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n", -@@ -394,6 +395,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res - static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, - uint8_t *buf, uint32_t len) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - HDACodecBus *bus = HDA_BUS(dev->qdev.parent_bus); - IntelHDAState *d = container_of(bus, IntelHDAState, codecs); - hwaddr addr; -@@ -428,7 +430,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, - st->be, st->bp, st->bpl[st->be].len, copy); - - pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output, -- MEMTXATTRS_UNSPECIFIED); -+ attrs); - st->lpib += copy; - st->bp += copy; - buf += copy; -@@ -451,7 +453,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output, - if (d->dp_lbase & 0x01) { - s = st - d->st; - addr = intel_hda_addr(d->dp_lbase & ~0x01, d->dp_ubase); -- stl_le_pci_dma(&d->pci, addr + 8*s, st->lpib); -+ stl_le_pci_dma(&d->pci, addr + 8 * s, st->lpib, attrs); - } - dprint(d, 3, "dma: --\n"); - -diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c -index 2474cf3dc2..160b9b0b4c 100644 ---- a/hw/net/eepro100.c -+++ b/hw/net/eepro100.c -@@ -703,6 +703,8 @@ static void set_ru_state(EEPRO100State * s, ru_state_t state) - - static void dump_statistics(EEPRO100State * s) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; -+ - /* Dump statistical data. Most data is never changed by the emulation - * and always 0, so we first just copy the whole block and then those - * values which really matter. -@@ -710,16 +712,18 @@ static void dump_statistics(EEPRO100State * s) - */ - pci_dma_write(&s->dev, s->statsaddr, &s->statistics, s->stats_size); - stl_le_pci_dma(&s->dev, s->statsaddr + 0, -- s->statistics.tx_good_frames); -+ s->statistics.tx_good_frames, attrs); - stl_le_pci_dma(&s->dev, s->statsaddr + 36, -- s->statistics.rx_good_frames); -+ s->statistics.rx_good_frames, attrs); - stl_le_pci_dma(&s->dev, s->statsaddr + 48, -- s->statistics.rx_resource_errors); -+ s->statistics.rx_resource_errors, attrs); - stl_le_pci_dma(&s->dev, s->statsaddr + 60, -- s->statistics.rx_short_frame_errors); -+ s->statistics.rx_short_frame_errors, attrs); - #if 0 -- stw_le_pci_dma(&s->dev, s->statsaddr + 76, s->statistics.xmt_tco_frames); -- stw_le_pci_dma(&s->dev, s->statsaddr + 78, s->statistics.rcv_tco_frames); -+ stw_le_pci_dma(&s->dev, s->statsaddr + 76, -+ s->statistics.xmt_tco_frames, attrs); -+ stw_le_pci_dma(&s->dev, s->statsaddr + 78, -+ s->statistics.rcv_tco_frames, attrs); - missing("CU dump statistical counters"); - #endif - } -@@ -836,6 +840,7 @@ static void set_multicast_list(EEPRO100State *s) - - static void action_command(EEPRO100State *s) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - /* The loop below won't stop if it gets special handcrafted data. - Therefore we limit the number of iterations. */ - unsigned max_loop_count = 16; -@@ -922,7 +927,7 @@ static void action_command(EEPRO100State *s) - } - /* Write new status. */ - stw_le_pci_dma(&s->dev, s->cb_address, -- s->tx.status | ok_status | STATUS_C); -+ s->tx.status | ok_status | STATUS_C, attrs); - if (bit_i) { - /* CU completed action. */ - eepro100_cx_interrupt(s); -@@ -949,6 +954,7 @@ static void action_command(EEPRO100State *s) - - static void eepro100_cu_command(EEPRO100State * s, uint8_t val) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - cu_state_t cu_state; - switch (val) { - case CU_NOP: -@@ -998,7 +1004,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val) - /* Dump statistical counters. */ - TRACE(OTHER, logout("val=0x%02x (dump stats)\n", val)); - dump_statistics(s); -- stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa005); -+ stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa005, attrs); - break; - case CU_CMD_BASE: - /* Load CU base. */ -@@ -1009,7 +1015,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val) - /* Dump and reset statistical counters. */ - TRACE(OTHER, logout("val=0x%02x (dump stats and reset)\n", val)); - dump_statistics(s); -- stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa007); -+ stl_le_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa007, attrs); - memset(&s->statistics, 0, sizeof(s->statistics)); - break; - case CU_SRESUME: -@@ -1624,6 +1630,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) - * - Magic packets should set bit 30 in power management driver register. - * - Interesting packets should set bit 29 in power management driver register. - */ -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - EEPRO100State *s = qemu_get_nic_opaque(nc); - uint16_t rfd_status = 0xa000; - #if defined(CONFIG_PAD_RECEIVED_FRAMES) -@@ -1738,9 +1745,9 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) - TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n", - rfd_command, rx.link, rx.rx_buf_addr, rfd_size)); - stw_le_pci_dma(&s->dev, s->ru_base + s->ru_offset + -- offsetof(eepro100_rx_t, status), rfd_status); -+ offsetof(eepro100_rx_t, status), rfd_status, attrs); - stw_le_pci_dma(&s->dev, s->ru_base + s->ru_offset + -- offsetof(eepro100_rx_t, count), size); -+ offsetof(eepro100_rx_t, count), size, attrs); - /* Early receive interrupt not supported. */ - #if 0 - eepro100_er_interrupt(s); -diff --git a/hw/net/tulip.c b/hw/net/tulip.c -index ca69f7ea5e..1f2c79dd58 100644 ---- a/hw/net/tulip.c -+++ b/hw/net/tulip.c -@@ -86,16 +86,18 @@ static void tulip_desc_read(TULIPState *s, hwaddr p, - static void tulip_desc_write(TULIPState *s, hwaddr p, - struct tulip_descriptor *desc) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; -+ - if (s->csr[0] & CSR0_DBO) { -- stl_be_pci_dma(&s->dev, p, desc->status); -- stl_be_pci_dma(&s->dev, p + 4, desc->control); -- stl_be_pci_dma(&s->dev, p + 8, desc->buf_addr1); -- stl_be_pci_dma(&s->dev, p + 12, desc->buf_addr2); -+ stl_be_pci_dma(&s->dev, p, desc->status, attrs); -+ stl_be_pci_dma(&s->dev, p + 4, desc->control, attrs); -+ stl_be_pci_dma(&s->dev, p + 8, desc->buf_addr1, attrs); -+ stl_be_pci_dma(&s->dev, p + 12, desc->buf_addr2, attrs); - } else { -- stl_le_pci_dma(&s->dev, p, desc->status); -- stl_le_pci_dma(&s->dev, p + 4, desc->control); -- stl_le_pci_dma(&s->dev, p + 8, desc->buf_addr1); -- stl_le_pci_dma(&s->dev, p + 12, desc->buf_addr2); -+ stl_le_pci_dma(&s->dev, p, desc->status, attrs); -+ stl_le_pci_dma(&s->dev, p + 4, desc->control, attrs); -+ stl_le_pci_dma(&s->dev, p + 8, desc->buf_addr1, attrs); -+ stl_le_pci_dma(&s->dev, p + 12, desc->buf_addr2, attrs); - } - } - -diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c -index f1c4d5782b..b4d448370f 100644 ---- a/hw/scsi/megasas.c -+++ b/hw/scsi/megasas.c -@@ -168,14 +168,16 @@ static void megasas_frame_set_cmd_status(MegasasState *s, - unsigned long frame, uint8_t v) - { - PCIDevice *pci = &s->parent_obj; -- stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, cmd_status), v); -+ stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, cmd_status), -+ v, MEMTXATTRS_UNSPECIFIED); - } - - static void megasas_frame_set_scsi_status(MegasasState *s, - unsigned long frame, uint8_t v) - { - PCIDevice *pci = &s->parent_obj; -- stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, scsi_status), v); -+ stb_pci_dma(pci, frame + offsetof(struct mfi_frame_header, scsi_status), -+ v, MEMTXATTRS_UNSPECIFIED); - } - - static inline const char *mfi_frame_desc(unsigned int cmd) -@@ -541,6 +543,7 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s, - - static void megasas_complete_frame(MegasasState *s, uint64_t context) - { -+ const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; - PCIDevice *pci_dev = PCI_DEVICE(s); - int tail, queue_offset; - -@@ -554,10 +557,12 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context) - */ - if (megasas_use_queue64(s)) { - queue_offset = s->reply_queue_head * sizeof(uint64_t); -- stq_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset, context); -+ stq_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset, -+ context, attrs); - } else { - queue_offset = s->reply_queue_head * sizeof(uint32_t); -- stl_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset, context); -+ stl_le_pci_dma(pci_dev, s->reply_queue_pa + queue_offset, -+ context, attrs); - } - s->reply_queue_tail = ldl_le_pci_dma(pci_dev, s->consumer_pa); - trace_megasas_qf_complete(context, s->reply_queue_head, -@@ -571,7 +576,7 @@ static void megasas_complete_frame(MegasasState *s, uint64_t context) - s->reply_queue_head = megasas_next_index(s, tail, s->fw_cmds); - trace_megasas_qf_update(s->reply_queue_head, s->reply_queue_tail, - s->busy); -- stl_le_pci_dma(pci_dev, s->producer_pa, s->reply_queue_head); -+ stl_le_pci_dma(pci_dev, s->producer_pa, s->reply_queue_head, attrs); - /* Notify HBA */ - if (msix_enabled(pci_dev)) { - trace_megasas_msix_raise(0); -diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c -index cd76bd67ab..59c3e8ba04 100644 ---- a/hw/scsi/vmw_pvscsi.c -+++ b/hw/scsi/vmw_pvscsi.c -@@ -55,7 +55,8 @@ - (m)->rs_pa + offsetof(struct PVSCSIRingsState, field))) - #define RS_SET_FIELD(m, field, val) \ - (stl_le_pci_dma(&container_of(m, PVSCSIState, rings)->parent_obj, \ -- (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val)) -+ (m)->rs_pa + offsetof(struct PVSCSIRingsState, field), val, \ -+ MEMTXATTRS_UNSPECIFIED)) - - struct PVSCSIClass { - PCIDeviceClass parent_class; -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index 71c6513641..f6b0e843c1 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -874,11 +874,12 @@ static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - MEMTXATTRS_UNSPECIFIED); \ - return val; \ - } \ -- static inline void st##_s##_pci_dma(PCIDevice *dev, \ -- dma_addr_t addr, uint##_bits##_t val) \ -- { \ -- st##_s##_dma(pci_get_address_space(dev), addr, val, \ -- MEMTXATTRS_UNSPECIFIED); \ -+ static inline void st##_s##_pci_dma(PCIDevice *dev, \ -+ dma_addr_t addr, \ -+ uint##_bits##_t val, \ -+ MemTxAttrs attrs) \ -+ { \ -+ st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \ - } - - PCI_DMA_DEFINE_LDST(ub, b, 8); --- -2.27.0 - diff --git a/pci-check-bus-pointer-before-dereference.patch b/pci-check-bus-pointer-before-dereference.patch deleted file mode 100644 index fbd30a32937a53dede688323163c8d229e93a054..0000000000000000000000000000000000000000 --- a/pci-check-bus-pointer-before-dereference.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 92da19fb18c234bb8872b9d8f7dedcc73e5fcafb Mon Sep 17 00:00:00 2001 -From: Prasad J Pandit -Date: Wed, 14 Oct 2020 15:00:20 +0800 -Subject: [PATCH] pci: check bus pointer before dereference - -fix CVE-2020-25742 - -patch link: https://lists.nongnu.org/archive/html/qemu-devel/2020-09/msg05294.html - -While mapping IRQ level in pci_change_irq_level() routine, -it does not check if pci_get_bus() returned a valid pointer. -It may lead to a NULL pointer dereference issue. Add check to -avoid it. - - -> https://ruhr-uni-bochum.sciebo.de/s/NNWP2GfwzYKeKwE?path=%2Flsi_nullptr1 - ==1183858==Hint: address points to the zero page. - #0 pci_change_irq_level hw/pci/pci.c:259 - #1 pci_irq_handler hw/pci/pci.c:1445 - #2 pci_set_irq hw/pci/pci.c:1463 - #3 lsi_set_irq hw/scsi/lsi53c895a.c:488 - #4 lsi_update_irq hw/scsi/lsi53c895a.c:523 - #5 lsi_script_scsi_interrupt hw/scsi/lsi53c895a.c:554 - #6 lsi_execute_script hw/scsi/lsi53c895a.c:1149 - #7 lsi_reg_writeb hw/scsi/lsi53c895a.c:1984 - #8 lsi_io_write hw/scsi/lsi53c895a.c:2146 - ... - -Reported-by: Ruhr-University -Signed-off-by: Prasad J Pandit -Signed-off-by: Yan Wang ---- - hw/pci/pci.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index e5993c1ef5..6d1c39a9de 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -270,6 +270,9 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change) - PCIBus *bus; - for (;;) { - bus = pci_get_bus(pci_dev); -+ if (!bus) { -+ return; -+ } - irq_num = bus->map_irq(pci_dev, irq_num); - if (bus->set_irq) - break; --- -2.27.0 - diff --git a/pci-expose-TYPE_XIO3130_DOWNSTREAM-name.patch b/pci-expose-TYPE_XIO3130_DOWNSTREAM-name.patch deleted file mode 100644 index 30d9615bca97e2c4585db878946965b8de7e6a9b..0000000000000000000000000000000000000000 --- a/pci-expose-TYPE_XIO3130_DOWNSTREAM-name.patch +++ /dev/null @@ -1,64 +0,0 @@ -From e88d2f15443811e40c4e1ba8299c12b35b75cb1e Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Tue, 1 Mar 2022 10:11:58 -0500 -Subject: [PATCH 4/6] pci: expose TYPE_XIO3130_DOWNSTREAM name - -Type name will be used in followup patch for cast check -in pcihp code. - -Signed-off-by: Igor Mammedov -Message-Id: <20220301151200.3507298-2-imammedo@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: wanbo ---- - hw/pci-bridge/xio3130_downstream.c | 3 ++- - include/hw/pci-bridge/xio3130_downstream.h | 15 +++++++++++++++ - 2 files changed, 17 insertions(+), 1 deletion(-) - create mode 100644 include/hw/pci-bridge/xio3130_downstream.h - -diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c -index 04aae72cd6..b17cafd359 100644 ---- a/hw/pci-bridge/xio3130_downstream.c -+++ b/hw/pci-bridge/xio3130_downstream.c -@@ -28,6 +28,7 @@ - #include "migration/vmstate.h" - #include "qapi/error.h" - #include "qemu/module.h" -+#include "hw/pci-bridge/xio3130_downstream.h" - - #define PCI_DEVICE_ID_TI_XIO3130D 0x8233 /* downstream port */ - #define XIO3130_REVISION 0x1 -@@ -173,7 +174,7 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data) - } - - static const TypeInfo xio3130_downstream_info = { -- .name = "xio3130-downstream", -+ .name = TYPE_XIO3130_DOWNSTREAM, - .parent = TYPE_PCIE_SLOT, - .class_init = xio3130_downstream_class_init, - .interfaces = (InterfaceInfo[]) { -diff --git a/include/hw/pci-bridge/xio3130_downstream.h b/include/hw/pci-bridge/xio3130_downstream.h -new file mode 100644 -index 0000000000..1d10139aea ---- /dev/null -+++ b/include/hw/pci-bridge/xio3130_downstream.h -@@ -0,0 +1,15 @@ -+/* -+ * TI X3130 pci express downstream port switch -+ * -+ * Copyright (C) 2022 Igor Mammedov -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#ifndef HW_PCI_BRIDGE_XIO3130_DOWNSTREAM_H -+#define HW_PCI_BRIDGE_XIO3130_DOWNSTREAM_H -+ -+#define TYPE_XIO3130_DOWNSTREAM "xio3130-downstream" -+ -+#endif -+ --- -2.27.0 - diff --git a/pci-fix-overflow-in-snprintf-string-formatting.patch b/pci-fix-overflow-in-snprintf-string-formatting.patch deleted file mode 100644 index e1e2e1b6cd2a2d5da17bbe351a363631018e50cf..0000000000000000000000000000000000000000 --- a/pci-fix-overflow-in-snprintf-string-formatting.patch +++ /dev/null @@ -1,106 +0,0 @@ -From b2d665abb4dbd3c91c0ceceebe537cf411f6c650 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 6 Nov 2023 06:35:28 +0000 -Subject: [PATCH] pci: fix overflow in snprintf string formatting mainline - inclusion commit 36f18c6989a3d1ff1d7a0e50b0868ef3958299b4 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -the code in pcibus_get_fw_dev_path contained the potential for a -stack buffer overflow of 1 byte, potentially writing to the stack an -extra NUL byte. - -This overflow could happen if the PCI slot is >= 0x10000000, -and the PCI function is >= 0x10000000, due to the size parameter -of snprintf being incorrectly calculated in the call: - - if (PCI_FUNC(d->devfn)) - snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn)); - -since the off obtained from a previous call to snprintf is added -instead of subtracted from the total available size of the buffer. - -Without the accurate size guard from snprintf, we end up writing in the -worst case: - -name (32) + "@" (1) + SLOT (8) + "," (1) + FUNC (8) + term NUL (1) = 51 bytes - -In order to provide something more robust, replace all of the code in -pcibus_get_fw_dev_path with a single call to g_strdup_printf, -so there is no need to rely on manual calculations. - -Found by compiling QEMU with FORTIFY_SOURCE=3 as the error: - -*** buffer overflow detected ***: terminated - -Thread 1 "qemu-system-x86" received signal SIGABRT, Aborted. -[Switching to Thread 0x7ffff642c380 (LWP 121307)] -0x00007ffff71ff55c in __pthread_kill_implementation () from /lib64/libc.so.6 -(gdb) bt - #0 0x00007ffff71ff55c in __pthread_kill_implementation () at /lib64/libc.so.6 - #1 0x00007ffff71ac6f6 in raise () at /lib64/libc.so.6 - #2 0x00007ffff7195814 in abort () at /lib64/libc.so.6 - #3 0x00007ffff71f279e in __libc_message () at /lib64/libc.so.6 - #4 0x00007ffff729767a in __fortify_fail () at /lib64/libc.so.6 - #5 0x00007ffff7295c36 in () at /lib64/libc.so.6 - #6 0x00007ffff72957f5 in __snprintf_chk () at /lib64/libc.so.6 - #7 0x0000555555b1c1fd in pcibus_get_fw_dev_path () - #8 0x0000555555f2bde4 in qdev_get_fw_dev_path_helper.constprop () - #9 0x0000555555f2bd86 in qdev_get_fw_dev_path_helper.constprop () - #10 0x00005555559a6e5d in get_boot_device_path () - #11 0x00005555559a712c in get_boot_devices_list () - #12 0x0000555555b1a3d0 in fw_cfg_machine_reset () - #13 0x0000555555bf4c2d in pc_machine_reset () - #14 0x0000555555c66988 in qemu_system_reset () - #15 0x0000555555a6dff6 in qdev_machine_creation_done () - #16 0x0000555555c79186 in qmp_x_exit_preconfig.part () - #17 0x0000555555c7b459 in qemu_init () - #18 0x0000555555960a29 in main () - -Found-by: Dario Faggioli -Found-by: Martin Liška -Cc: qemu-stable@nongnu.org -Signed-off-by: Claudio Fontana -Message-Id: <20220531114707.18830-1-cfontana@suse.de> -Reviewed-by: Ani Sinha - -Signed-off-by: tangbinzy ---- - hw/pci/pci.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index 3e6805d54a..6a5e8a3654 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -2588,15 +2588,15 @@ static char *pci_dev_fw_name(DeviceState *dev, char *buf, int len) - static char *pcibus_get_fw_dev_path(DeviceState *dev) - { - PCIDevice *d = (PCIDevice *)dev; -- char path[50], name[33]; -- int off; -- -- off = snprintf(path, sizeof(path), "%s@%x", -- pci_dev_fw_name(dev, name, sizeof name), -- PCI_SLOT(d->devfn)); -- if (PCI_FUNC(d->devfn)) -- snprintf(path + off, sizeof(path) + off, ",%x", PCI_FUNC(d->devfn)); -- return g_strdup(path); -+ char name[33]; -+ int has_func = !!PCI_FUNC(d->devfn); -+ -+ return g_strdup_printf("%s@%x%s%.*x", -+ pci_dev_fw_name(dev, name, sizeof(name)), -+ PCI_SLOT(d->devfn), -+ has_func ? "," : "", -+ has_func, -+ PCI_FUNC(d->devfn)); - } - - static char *pcibus_get_dev_path(DeviceState *dev) --- -2.27.0 - diff --git a/pci-introduce-PCIPASIDOps-to-PCIDevice.patch b/pci-introduce-PCIPASIDOps-to-PCIDevice.patch deleted file mode 100644 index f4cb611607899f89956b788e615d2d964b3a71ec..0000000000000000000000000000000000000000 --- a/pci-introduce-PCIPASIDOps-to-PCIDevice.patch +++ /dev/null @@ -1,127 +0,0 @@ -From c71485494970e7aa986be2b05bf7e2847017e264 Mon Sep 17 00:00:00 2001 -From: Liu Yi L -Date: Fri, 5 Jul 2019 19:01:36 +0800 -Subject: [PATCH] pci: introduce PCIPASIDOps to PCIDevice - -This patch introduces PCIPASIDOps for IOMMU related operations. - -https://lists.gnu.org/archive/html/qemu-devel/2018-03/msg00078.html -https://lists.gnu.org/archive/html/qemu-devel/2018-03/msg00940.html - -So far, to setup virt-SVA for assigned SVA capable device, needs to -configure host translation structures for specific pasid. (e.g. bind -guest page table to host and enable nested translation in host). -Besides, vIOMMU emulator needs to forward guest's cache invalidation -to host since host nested translation is enabled. e.g. on VT-d, guest -owns 1st level translation table, thus cache invalidation for 1st -level should be propagated to host. - -This patch adds two functions: alloc_pasid and free_pasid to support -guest pasid allocation and free. The implementations of the callbacks -would be device passthru modules. Like vfio. - -Cc: Kevin Tian -Cc: Jacob Pan -Cc: Peter Xu -Cc: Eric Auger -Cc: Yi Sun -Cc: David Gibson -Signed-off-by: Liu Yi L -Signed-off-by: Yi Sun -Signed-off-by: Kunkun Jiang ---- - hw/pci/pci.c | 34 ++++++++++++++++++++++++++++++++++ - include/hw/pci/pci.h | 11 +++++++++++ - 2 files changed, 45 insertions(+) - -diff --git a/hw/pci/pci.c b/hw/pci/pci.c -index e5993c1ef5..4a9374c025 100644 ---- a/hw/pci/pci.c -+++ b/hw/pci/pci.c -@@ -2759,6 +2759,40 @@ void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque) - bus->iommu_opaque = opaque; - } - -+void pci_setup_pasid_ops(PCIDevice *dev, PCIPASIDOps *ops) -+{ -+ assert(ops && !dev->pasid_ops); -+ dev->pasid_ops = ops; -+} -+ -+bool pci_device_is_pasid_ops_set(PCIBus *bus, int32_t devfn) -+{ -+ PCIDevice *dev; -+ -+ if (!bus) { -+ return false; -+ } -+ -+ dev = bus->devices[devfn]; -+ return !!(dev && dev->pasid_ops); -+} -+ -+int pci_device_set_pasid_table(PCIBus *bus, int32_t devfn, -+ IOMMUConfig *config) -+{ -+ PCIDevice *dev; -+ -+ if (!bus) { -+ return -EINVAL; -+ } -+ -+ dev = bus->devices[devfn]; -+ if (dev && dev->pasid_ops && dev->pasid_ops->set_pasid_table) { -+ return dev->pasid_ops->set_pasid_table(bus, devfn, config); -+ } -+ return -ENOENT; -+} -+ - static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque) - { - Range *range = opaque; -diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h -index e7cdf2d5ec..abffa12a99 100644 ---- a/include/hw/pci/pci.h -+++ b/include/hw/pci/pci.h -@@ -9,6 +9,7 @@ - - #include "hw/pci/pcie.h" - #include "qom/object.h" -+#include "hw/iommu/iommu.h" - - extern bool pci_available; - -@@ -265,6 +266,11 @@ struct PCIReqIDCache { - }; - typedef struct PCIReqIDCache PCIReqIDCache; - -+struct PCIPASIDOps { -+ int (*set_pasid_table)(PCIBus *bus, int32_t devfn, IOMMUConfig *config); -+}; -+typedef struct PCIPASIDOps PCIPASIDOps; -+ - struct PCIDevice { - DeviceState qdev; - bool partially_hotplugged; -@@ -361,6 +367,7 @@ struct PCIDevice { - /* ID of standby device in net_failover pair */ - char *failover_pair_id; - uint32_t acpi_index; -+ PCIPASIDOps *pasid_ops; - }; - - void pci_register_bar(PCIDevice *pci_dev, int region_num, -@@ -498,6 +505,10 @@ typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int); - AddressSpace *pci_device_iommu_address_space(PCIDevice *dev); - void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque); - -+void pci_setup_pasid_ops(PCIDevice *dev, PCIPASIDOps *ops); -+bool pci_device_is_pasid_ops_set(PCIBus *bus, int32_t devfn); -+int pci_device_set_pasid_table(PCIBus *bus, int32_t devfn, IOMMUConfig *config); -+ - static inline void - pci_set_byte(uint8_t *config, uint8_t val) - { --- -2.27.0 - diff --git a/pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch b/pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch deleted file mode 100644 index 7822fb936d6cedc0169e8abe2370ac030db7188a..0000000000000000000000000000000000000000 --- a/pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 2412c1968777a0fe77cb24dda935e3414e00ebb1 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Tue, 8 Feb 2022 16:10:31 +0800 -Subject: [PATCH 5/6] pcie: Add pcie-root-port fast plug/unplug feature - -If a device is plugged in the pcie-root-port when VM kernel is -booting, the kernel may wrongly disable the device. -This bug was brought in by two patches of the linux kernel: - -https://patchwork.kernel.org/patch/10575355/ -https://patchwork.kernel.org/patch/10766219/ - -VM runtime like kata uses this feature to boot microVM, -so we must fix it up. We hack into the pcie native hotplug -patch so that hotplug/unplug will work under this circumstance. - -Signed-off-by: Ying Fang -Signed-off-by: Yan Wang ---- - hw/core/machine.c | 2 ++ - hw/pci-bridge/gen_pcie_root_port.c | 2 ++ - hw/pci/pcie.c | 13 ++++++++++++- - include/hw/pci/pcie_port.h | 3 +++ - 4 files changed, 19 insertions(+), 1 deletion(-) - -diff --git a/hw/core/machine.c b/hw/core/machine.c -index 53a99ab..126e3e2 100644 ---- a/hw/core/machine.c -+++ b/hw/core/machine.c -@@ -121,6 +121,8 @@ const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0); - GlobalProperty hw_compat_3_1[] = { - { "pcie-root-port", "x-speed", "2_5" }, - { "pcie-root-port", "x-width", "1" }, -+ { "pcie-root-port", "fast-plug", "0" }, -+ { "pcie-root-port", "fast-unplug", "0" }, - { "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" }, - { "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" }, - { "tpm-crb", "ppi", "false" }, -diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c -index 20099a8..0bf9df9 100644 ---- a/hw/pci-bridge/gen_pcie_root_port.c -+++ b/hw/pci-bridge/gen_pcie_root_port.c -@@ -140,6 +140,8 @@ static Property gen_rp_props[] = { - speed, PCIE_LINK_SPEED_16), - DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot, - width, PCIE_LINK_WIDTH_32), -+ DEFINE_PROP_UINT8("fast-plug", PCIESlot, fast_plug, 0), -+ DEFINE_PROP_UINT8("fast-unplug", PCIESlot, fast_unplug, 0), - DEFINE_PROP_END_OF_LIST() - }; - -diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c -index d7d73a3..d7d1504 100644 ---- a/hw/pci/pcie.c -+++ b/hw/pci/pcie.c -@@ -526,6 +526,7 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, - uint8_t *exp_cap = hotplug_pdev->config + hotplug_pdev->exp.exp_cap; - uint32_t sltcap = pci_get_word(exp_cap + PCI_EXP_SLTCAP); - uint16_t sltctl = pci_get_word(exp_cap + PCI_EXP_SLTCTL); -+ PCIESlot *s = PCIE_SLOT(hotplug_pdev); - - /* Check if hot-unplug is disabled on the slot */ - if ((sltcap & PCI_EXP_SLTCAP_HPC) == 0) { -@@ -572,7 +573,17 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, - return; - } - -- pcie_cap_slot_push_attention_button(hotplug_pdev); -+ if ((pci_dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA) && s->fast_plug) { -+ pci_word_test_and_clear_mask(pci_dev->config + pci_dev->exp.exp_cap + PCI_EXP_LNKSTA, -+ PCI_EXP_LNKSTA_DLLLA); -+ } -+ -+ if (s->fast_unplug) { -+ pcie_cap_slot_event(hotplug_pdev, -+ PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP); -+ } else { -+ pcie_cap_slot_push_attention_button(hotplug_pdev); -+ } - } - - /* pci express slot for pci express root/downstream port -diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h -index e25b289..5b80a13 100644 ---- a/include/hw/pci/pcie_port.h -+++ b/include/hw/pci/pcie_port.h -@@ -51,6 +51,9 @@ struct PCIESlot { - uint8_t chassis; - uint16_t slot; - -+ uint8_t fast_plug; -+ uint8_t fast_unplug; -+ - PCIExpLinkSpeed speed; - PCIExpLinkWidth width; - --- -1.9.1 - diff --git a/pcie-Compat-with-devices-which-do-not-support-Link-W.patch b/pcie-Compat-with-devices-which-do-not-support-Link-W.patch deleted file mode 100644 index aeb31bbf66402b4db3fb510e53f9cc2f7e29abf3..0000000000000000000000000000000000000000 --- a/pcie-Compat-with-devices-which-do-not-support-Link-W.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 14d1ad1309a1bd035250512368221088c2f83f32 Mon Sep 17 00:00:00 2001 -From: fangying -Date: Wed, 18 Mar 2020 12:51:33 +0800 -Subject: [PATCH 6/6] pcie: Compat with devices which do not support Link - Width, such as ioh3420 - -We hack into PCI_EXP_LNKCAP to support device fast plug/unplug -for pcie-root-port. However some devices like ioh3420 does not -suport it, so PCI_EXP_LNKCAP is not set for such devices. - -Signed-off-by: Ying Fang -Signed-off-by: Yan Wang ---- - hw/pci/pcie.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c -index d7d1504..30c09ed 100644 ---- a/hw/pci/pcie.c -+++ b/hw/pci/pcie.c -@@ -92,13 +92,6 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev) - return; - } - -- /* Clear and fill LNKCAP from what was configured above */ -- pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP, -- PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS); -- pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, -- QEMU_PCI_EXP_LNKCAP_MLW(s->width) | -- QEMU_PCI_EXP_LNKCAP_MLS(s->speed)); -- - /* - * Link bandwidth notification is required for all root ports and - * downstream ports supporting links wider than x1 or multiple link -@@ -106,6 +99,12 @@ static void pcie_cap_fill_slot_lnk(PCIDevice *dev) - */ - if (s->width > QEMU_PCI_EXP_LNK_X1 || - s->speed > QEMU_PCI_EXP_LNK_2_5GT) { -+ /* Clear and fill LNKCAP from what was configured above */ -+ pci_long_test_and_clear_mask(exp_cap + PCI_EXP_LNKCAP, -+ PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS); -+ pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, -+ QEMU_PCI_EXP_LNKCAP_MLW(s->width) | -+ QEMU_PCI_EXP_LNKCAP_MLS(s->speed)); - pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKCAP, - PCI_EXP_LNKCAP_LBNC); - } --- -1.9.1 - diff --git a/pcie_aer-Don-t-trigger-a-LSI-if-none-are-defined.patch b/pcie_aer-Don-t-trigger-a-LSI-if-none-are-defined.patch deleted file mode 100644 index c4462b724006ede86401d7e38c385db71052aab2..0000000000000000000000000000000000000000 --- a/pcie_aer-Don-t-trigger-a-LSI-if-none-are-defined.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 77633ce67c1cff764fe4951a6837462f51ace8aa Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Thu, 7 Dec 2023 17:00:28 +0800 -Subject: [PATCH] pcie_aer: Don't trigger a LSI if none are defined -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from 20766514d602c50b870ae943aaa8e5b9e2e8a161 - -Skip triggering an LSI when the AER root error status is updated if no -LSI is defined for the device. We can have a root bridge with no LSI, -MSI and MSI-X defined, for example on POWER systems. - -Signed-off-by: Frederic Barrat -Message-Id: <20211116170133.724751-4-fbarrat@linux.ibm.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Cédric Le Goater -Signed-off-by: boringandboring ---- - hw/pci/pcie_aer.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c -index 27f9cc56af..e1a8a88c8c 100644 ---- a/hw/pci/pcie_aer.c -+++ b/hw/pci/pcie_aer.c -@@ -774,7 +774,9 @@ void pcie_aer_root_write_config(PCIDevice *dev, - uint32_t root_cmd = pci_get_long(aer_cap + PCI_ERR_ROOT_COMMAND); - /* 6.2.4.1.2 Interrupt Generation */ - if (!msix_enabled(dev) && !msi_enabled(dev)) { -- pci_set_irq(dev, !!(root_cmd & enabled_cmd)); -+ if (pci_intx(dev) != -1) { -+ pci_set_irq(dev, !!(root_cmd & enabled_cmd)); -+ } - return; - } - --- -2.27.0 - diff --git a/pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch b/pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch deleted file mode 100644 index a917143fd0d18befb2c11f0bf6bb0a11b758d218..0000000000000000000000000000000000000000 --- a/pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 696abba190a0daad488d709d733f0d1f10df6f89 Mon Sep 17 00:00:00 2001 -From: Ying Fang -Date: Mon, 29 Jul 2019 16:16:35 +0800 -Subject: [PATCH 1/6] pl011: reset read FIFO when UARTTIMSC=0 & UARTICR=0xffff - -We can enable ACPI when AArch64 Linux is booted with QEMU and UEFI (AAVMF). -When VM is booting and the SBSA driver has not initialized, writting data -that exceds 32 bytes will cause the read FIFO full and proceeding data will -be lost. The searil port appears to be stuck in this abnormal situation. - -A hack to reset read FIFO when UARTTIMSC=0 & UARTICR=0xffff appears to -resolve the issue. - -The question is fully discussed at -https://www.spinics.net/lists/linux-serial/msg23163.html - -Signed-off-by: Haibin Wang -Reviewed-by: Shannon Zhao -Reviewed-by: Ying Fang -Signed-off-by: Yan Wang ---- - hw/char/pl011.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/char/pl011.c b/hw/char/pl011.c -index 6e2d7f7..8ca2a4e 100644 ---- a/hw/char/pl011.c -+++ b/hw/char/pl011.c -@@ -255,6 +255,10 @@ static void pl011_write(void *opaque, hwaddr offset, - case 17: /* UARTICR */ - s->int_level &= ~value; - pl011_update(s); -+ if (!s->int_enabled && !s->int_level) { -+ s->read_count = 0; -+ s->read_pos = 0; -+ } - break; - case 18: /* UARTDMACR */ - s->dmacr = value; --- -1.9.1 - diff --git a/pl031-support-rtc-timer-property-for-pl031.patch b/pl031-support-rtc-timer-property-for-pl031.patch deleted file mode 100644 index b57f0e75965a62e7f929b740babe184546efa0c5..0000000000000000000000000000000000000000 --- a/pl031-support-rtc-timer-property-for-pl031.patch +++ /dev/null @@ -1,70 +0,0 @@ -From f8e5f099c5b6665e3ed9f397ddca9283148938a4 Mon Sep 17 00:00:00 2001 -From: Jinhao Gao -Date: Tue, 15 Feb 2022 17:02:08 +0800 -Subject: [PATCH] pl031: support rtc-timer property for pl031 - -This patch adds the rtc-timer property for pl031, we can get the -rtc time (UTC) through qmp command "qom-get date" with this property. - -Signed-off-by: Haibin Wang -Reviewed-by: Shannon Zhao -Reviewed-by: Ying Fang -Signed-off-by: Keqian Zhu -Signed-off-by: Jinhao Gao ---- - hw/rtc/pl031.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c -index da8b061e91..61a2948f77 100644 ---- a/hw/rtc/pl031.c -+++ b/hw/rtc/pl031.c -@@ -63,6 +63,15 @@ static uint32_t pl031_get_count(PL031State *s) - return s->tick_offset + now / NANOSECONDS_PER_SECOND; - } - -+static void pl031_get_date(Object *obj, struct tm *current_tm, Error **errp) -+{ -+ PL031State *s = PL031(obj); -+ time_t ti = pl031_get_count(s); -+ -+ /* Changed to UTC time */ -+ gmtime_r(&ti, current_tm); -+} -+ - static void pl031_set_alarm(PL031State *s) - { - uint32_t ticks; -@@ -201,6 +210,20 @@ static void pl031_init(Object *obj) - qemu_clock_get_ns(rtc_clock) / NANOSECONDS_PER_SECOND; - - s->timer = timer_new_ns(rtc_clock, pl031_interrupt, s); -+ object_property_add_tm(OBJECT(s), "date", pl031_get_date); -+} -+ -+static void pl031_realize(DeviceState *d, Error **errp) -+{ -+ object_property_add_alias(qdev_get_machine(), "rtc-time", -+ OBJECT(d), "date"); -+} -+ -+static void pl031_unrealize(DeviceState *d) -+{ -+ if (object_property_find(qdev_get_machine(), "rtc-time")) { -+ object_property_del(qdev_get_machine(), "rtc-time"); -+ } - } - - static void pl031_finalize(Object *obj) -@@ -337,6 +360,8 @@ static void pl031_class_init(ObjectClass *klass, void *data) - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->vmsd = &vmstate_pl031; -+ dc->realize = pl031_realize; -+ dc->unrealize = pl031_unrealize; - device_class_set_props(dc, pl031_properties); - } - --- -2.27.0 - diff --git a/plugins-make-qemu_plugin_user_exit-s-locking-order-c.patch b/plugins-make-qemu_plugin_user_exit-s-locking-order-c.patch deleted file mode 100644 index 6655be53f517249b9f6050596b06b24ef9c670b5..0000000000000000000000000000000000000000 --- a/plugins-make-qemu_plugin_user_exit-s-locking-order-c.patch +++ /dev/null @@ -1,66 +0,0 @@ -From a729d2730d9d30f6610e43f070cedd1d60ba022f Mon Sep 17 00:00:00 2001 -From: qihao -Date: Thu, 30 Mar 2023 17:58:32 +0800 -Subject: [PATCH] plugins: make qemu_plugin_user_exit's locking order - consistent with fork_start's -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 2bbbc1be8d9a21b25d0c80b9a7345074d54abd51 - -To fix potential deadlocks as reported by tsan. - -Signed-off-by: qihao_yewu -Reviewed-by: Richard Henderson -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Emilio Cota -Message-Id: <20230111151628.320011-6-cota@braap.org> -Signed-off-by: Alex Bennée -Message-Id: <20230124180127.1881110-31-alex.bennee@linaro.org> ---- - plugins/core.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - -diff --git a/plugins/core.c b/plugins/core.c -index 792262da08..e935e3c0c9 100644 ---- a/plugins/core.c -+++ b/plugins/core.c -@@ -500,10 +500,18 @@ void qemu_plugin_user_exit(void) - enum qemu_plugin_event ev; - CPUState *cpu; - -- QEMU_LOCK_GUARD(&plugin.lock); -+ /* -+ * Locking order: we must acquire locks in an order that is consistent -+ * with the one in fork_start(). That is: -+ * - start_exclusive(), which acquires qemu_cpu_list_lock, -+ * must be called before acquiring plugin.lock. -+ * - tb_flush(), which acquires mmap_lock(), must be called -+ * while plugin.lock is not held. -+ */ - - start_exclusive(); - -+ qemu_rec_mutex_lock(&plugin.lock); - /* un-register all callbacks except the final AT_EXIT one */ - for (ev = 0; ev < QEMU_PLUGIN_EV_MAX; ev++) { - if (ev != QEMU_PLUGIN_EV_ATEXIT) { -@@ -514,12 +522,12 @@ void qemu_plugin_user_exit(void) - } - } - -- tb_flush(current_cpu); -- - CPU_FOREACH(cpu) { - qemu_plugin_disable_mem_helpers(cpu); - } -+ qemu_rec_mutex_unlock(&plugin.lock); - -+ tb_flush(current_cpu); - end_exclusive(); - - /* now it's safe to handle the exit case */ --- -2.27.0 - diff --git a/ppc-spelling-fixes.patch b/ppc-spelling-fixes.patch deleted file mode 100644 index 127101b5e1852db4de3f9acb95856addece1b1dc..0000000000000000000000000000000000000000 --- a/ppc-spelling-fixes.patch +++ /dev/null @@ -1,271 +0,0 @@ -From 0adb55804594e60380450c7644a05f9cfc4ebb8a Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Sun, 26 Nov 2023 18:34:45 -0800 -Subject: [PATCH] ppc: spelling fixes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mainline inclusion -commit e6a19a6477407e57b4deb61aaa497a14d7db9626 -category: bugfix - -Signed-off-by: Michael Tokarev -Reviewed-by: Cédric Le Goater -Signed-off-by: zhujun2 ---- - hw/ppc/ppc.c | 2 +- - hw/ppc/prep_systemio.c | 2 +- - hw/ppc/spapr.c | 8 ++++---- - hw/ppc/spapr_hcall.c | 2 +- - hw/ppc/spapr_nvdimm.c | 2 +- - hw/ppc/spapr_pci_vfio.c | 2 +- - include/hw/ppc/openpic.h | 2 +- - include/hw/ppc/spapr.h | 2 +- - target/ppc/cpu-models.h | 4 ++-- - target/ppc/cpu.h | 2 +- - target/ppc/cpu_init.c | 2 +- - target/ppc/excp_helper.c | 2 +- - target/ppc/power8-pmu-regs.c.inc | 4 ++-- - target/ppc/translate/vmx-impl.c.inc | 4 ++-- - 14 files changed, 20 insertions(+), 20 deletions(-) - -diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c -index cf90ab7805..6396bbe523 100644 ---- a/hw/ppc/ppc.c -+++ b/hw/ppc/ppc.c -@@ -745,7 +745,7 @@ target_ulong cpu_ppc_load_decr(CPUPPCState *env) - decr = _cpu_ppc_load_decr(env, tb_env->decr_next); - - /* -- * If large decrementer is enabled then the decrementer is signed extened -+ * If large decrementer is enabled then the decrementer is signed extended - * to 64 bits, otherwise it is a 32 bit value. - */ - if (env->spr[SPR_LPCR] & LPCR_LD) { -diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c -index b2bd783248..e51da91de5 100644 ---- a/hw/ppc/prep_systemio.c -+++ b/hw/ppc/prep_systemio.c -@@ -39,7 +39,7 @@ - #define TYPE_PREP_SYSTEMIO "prep-systemio" - OBJECT_DECLARE_SIMPLE_TYPE(PrepSystemIoState, PREP_SYSTEMIO) - --/* Bit as defined in PowerPC Reference Plaform v1.1, sect. 6.1.5, p. 132 */ -+/* Bit as defined in PowerPC Reference Platform v1.1, sect. 6.1.5, p. 132 */ - #define PREP_BIT(n) (1 << (7 - (n))) - - struct PrepSystemIoState { -diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c -index 3b5fd749be..7f352ceaaa 100644 ---- a/hw/ppc/spapr.c -+++ b/hw/ppc/spapr.c -@@ -2488,7 +2488,7 @@ static void spapr_set_vsmt_mode(SpaprMachineState *spapr, Error **errp) - return; - } - -- /* Detemine the VSMT mode to use: */ -+ /* Determine the VSMT mode to use: */ - if (vsmt_user) { - if (spapr->vsmt < smp_threads) { - error_setg(errp, "Cannot support VSMT mode %d" -@@ -3016,7 +3016,7 @@ static int spapr_kvm_type(MachineState *machine, const char *vm_type) - { - /* - * The use of g_ascii_strcasecmp() for 'hv' and 'pr' is to -- * accomodate the 'HV' and 'PV' formats that exists in the -+ * accommodate the 'HV' and 'PV' formats that exists in the - * wild. The 'auto' mode is being introduced already as - * lower-case, thus we don't need to bother checking for - * "AUTO". -@@ -4250,7 +4250,7 @@ spapr_cpu_index_to_props(MachineState *machine, unsigned cpu_index) - CPUArchId *core_slot; - MachineClass *mc = MACHINE_GET_CLASS(machine); - -- /* make sure possible_cpu are intialized */ -+ /* make sure possible_cpu are initialized */ - mc->possible_cpu_arch_ids(machine); - /* get CPU core slot containing thread that matches cpu_index */ - core_slot = spapr_find_cpu_slot(machine, cpu_index, NULL); -@@ -4870,7 +4870,7 @@ static void spapr_machine_2_12_class_options(MachineClass *mc) - - /* We depend on kvm_enabled() to choose a default value for the - * hpt-max-page-size capability. Of course we can't do it here -- * because this is too early and the HW accelerator isn't initialzed -+ * because this is too early and the HW accelerator isn't initialized - * yet. Postpone this to machine init (see default_caps_with_cpu()). - */ - smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 0; -diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c -index 222c1b6bbd..5364bbcffa 100644 ---- a/hw/ppc/spapr_hcall.c -+++ b/hw/ppc/spapr_hcall.c -@@ -1532,7 +1532,7 @@ static void hypercall_register_types(void) - spapr_register_hypercall(H_GET_CPU_CHARACTERISTICS, - h_get_cpu_characteristics); - -- /* "debugger" hcalls (also used by SLOF). Note: We do -not- differenciate -+ /* "debugger" hcalls (also used by SLOF). Note: We do -not- differentiate - * here between the "CI" and the "CACHE" variants, they will use whatever - * mapping attributes qemu is using. When using KVM, the kernel will - * enforce the attributes more strongly -diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c -index 91de1052f2..b111380a45 100644 ---- a/hw/ppc/spapr_nvdimm.c -+++ b/hw/ppc/spapr_nvdimm.c -@@ -336,7 +336,7 @@ static target_ulong h_scm_bind_mem(PowerPCCPU *cpu, SpaprMachineState *spapr, - - /* - * Currently continue token should be zero qemu has already bound -- * everything and this hcall doesnt return H_BUSY. -+ * everything and this hcall doesn't return H_BUSY. - */ - if (continue_token > 0) { - return H_P5; -diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c -index 2a76b4e0b5..6326948143 100644 ---- a/hw/ppc/spapr_pci_vfio.c -+++ b/hw/ppc/spapr_pci_vfio.c -@@ -77,7 +77,7 @@ int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb, - * call. Now we just need to check the validity of the PCI - * pass-through devices (vfio-pci) under this sphb bus. - * We have already validated that all the devices under this sphb -- * are from same iommu group (within same PE) before comming here. -+ * are from same iommu group (within same PE) before coming here. - * - * Prior to linux commit 98ba956f6a389 ("powerpc/pseries/eeh: - * Rework device EEH PE determination") kernel would call -diff --git a/include/hw/ppc/openpic.h b/include/hw/ppc/openpic.h -index ebdaf8a493..44976e6b07 100644 ---- a/include/hw/ppc/openpic.h -+++ b/include/hw/ppc/openpic.h -@@ -14,7 +14,7 @@ enum { - OPENPIC_OUTPUT_INT = 0, /* IRQ */ - OPENPIC_OUTPUT_CINT, /* critical IRQ */ - OPENPIC_OUTPUT_MCK, /* Machine check event */ -- OPENPIC_OUTPUT_DEBUG, /* Inconditional debug event */ -+ OPENPIC_OUTPUT_DEBUG, /* Unconditional debug event */ - OPENPIC_OUTPUT_RESET, /* Core reset event */ - OPENPIC_OUTPUT_NB, - }; -diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h -index ee7504b976..316b80318e 100644 ---- a/include/hw/ppc/spapr.h -+++ b/include/hw/ppc/spapr.h -@@ -179,7 +179,7 @@ struct SpaprMachineState { - SpaprResizeHpt resize_hpt; - void *htab; - uint32_t htab_shift; -- uint64_t patb_entry; /* Process tbl registed in H_REGISTER_PROC_TBL */ -+ uint64_t patb_entry; /* Process tbl registered in H_REGISTER_PROC_TBL */ - SpaprPendingHpt *pending_hpt; /* in-progress resize */ - - hwaddr rma_size; -diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h -index 0952592759..75ea085bd5 100644 ---- a/target/ppc/cpu-models.h -+++ b/target/ppc/cpu-models.h -@@ -63,7 +63,7 @@ enum { - /* PowerPC 405 cores */ - CPU_POWERPC_405D2 = 0x20010000, - CPU_POWERPC_405D4 = 0x41810000, -- /* PowerPC 405 microcontrolers */ -+ /* PowerPC 405 microcontrollers */ - /* XXX: missing 0x200108a0 */ - CPU_POWERPC_405CRa = 0x40110041, - CPU_POWERPC_405CRb = 0x401100C5, -@@ -93,7 +93,7 @@ enum { - #define CPU_POWERPC_440 CPU_POWERPC_440GXf - /* PowerPC 440 cores */ - CPU_POWERPC_440_XILINX = 0x7ff21910, -- /* PowerPC 440 microcontrolers */ -+ /* PowerPC 440 microcontrollers */ - CPU_POWERPC_440EPa = 0x42221850, - CPU_POWERPC_440EPb = 0x422218D3, - CPU_POWERPC_440GPb = 0x40120440, -diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h -index e946da5f3a..26312f9d5f 100644 ---- a/target/ppc/cpu.h -+++ b/target/ppc/cpu.h -@@ -345,7 +345,7 @@ typedef struct ppc_v3_pate_t { - - /* PMU bits */ - #define MMCR0_FC PPC_BIT(32) /* Freeze Counters */ --#define MMCR0_PMAO PPC_BIT(56) /* Perf Monitor Alert Ocurred */ -+#define MMCR0_PMAO PPC_BIT(56) /* Perf Monitor Alert Occurred */ - #define MMCR0_PMAE PPC_BIT(37) /* Perf Monitor Alert Enable */ - #define MMCR0_EBE PPC_BIT(43) /* Perf Monitor EBB Enable */ - #define MMCR0_FCECE PPC_BIT(38) /* FC on Enabled Cond or Event */ -diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c -index 6695985e9b..986d16a24d 100644 ---- a/target/ppc/cpu_init.c -+++ b/target/ppc/cpu_init.c -@@ -7023,7 +7023,7 @@ static void register_970_lpar_sprs(CPUPPCState *env) - static void register_power5p_lpar_sprs(CPUPPCState *env) - { - #if !defined(CONFIG_USER_ONLY) -- /* Logical partitionning */ -+ /* Logical partitioning */ - spr_register_kvm_hv(env, SPR_LPCR, "LPCR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, -diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c -index 17607adbe4..f66063d55c 100644 ---- a/target/ppc/excp_helper.c -+++ b/target/ppc/excp_helper.c -@@ -312,7 +312,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) - - /* - * new interrupt handler msr preserves existing HV and ME unless -- * explicitly overriden -+ * explicitly overridden - */ - new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); - -diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc -index 7391851238..c58874752b 100644 ---- a/target/ppc/power8-pmu-regs.c.inc -+++ b/target/ppc/power8-pmu-regs.c.inc -@@ -16,7 +16,7 @@ - * Checks whether the Group A SPR (MMCR0, MMCR2, MMCRA, and the - * PMCs) has problem state read access. - * -- * Read acccess is granted for all PMCC values but 0b01, where a -+ * Read access is granted for all PMCC values but 0b01, where a - * Facility Unavailable Interrupt will occur. - */ - static bool spr_groupA_read_allowed(DisasContext *ctx) -@@ -33,7 +33,7 @@ static bool spr_groupA_read_allowed(DisasContext *ctx) - * Checks whether the Group A SPR (MMCR0, MMCR2, MMCRA, and the - * PMCs) has problem state write access. - * -- * Write acccess is granted for PMCC values 0b10 and 0b11. Userspace -+ * Write access is granted for PMCC values 0b10 and 0b11. Userspace - * writing with PMCC 0b00 will generate a Hypervisor Emulation - * Assistance Interrupt. Userspace writing with PMCC 0b01 will - * generate a Facility Unavailable Interrupt. -diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc -index 8eb8d3a067..f56f061d18 100644 ---- a/target/ppc/translate/vmx-impl.c.inc -+++ b/target/ppc/translate/vmx-impl.c.inc -@@ -127,7 +127,7 @@ static void gen_stve##name(DisasContext *ctx) \ - } - - GEN_VR_LDX(lvx, 0x07, 0x03); --/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */ -+/* As we don't emulate the cache, lvxl is strictly equivalent to lvx */ - GEN_VR_LDX(lvxl, 0x07, 0x0B); - - GEN_VR_LVE(bx, 0x07, 0x00, 1); -@@ -135,7 +135,7 @@ GEN_VR_LVE(hx, 0x07, 0x01, 2); - GEN_VR_LVE(wx, 0x07, 0x02, 4); - - GEN_VR_STX(svx, 0x07, 0x07); --/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */ -+/* As we don't emulate the cache, stvxl is strictly equivalent to stvx */ - GEN_VR_STX(svxl, 0x07, 0x0F); - - GEN_VR_STVE(bx, 0x07, 0x04, 1); --- -2.27.0 - diff --git a/ppc-vof-Fix-missed-fields-in-VOF-cleanup.patch b/ppc-vof-Fix-missed-fields-in-VOF-cleanup.patch deleted file mode 100644 index 93498aea9948c72aec58513ab36246283896ce44..0000000000000000000000000000000000000000 --- a/ppc-vof-Fix-missed-fields-in-VOF-cleanup.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 62083d43f24d801f74b8e0aee7693811c19a366d Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 18 Sep 2023 15:26:28 +0800 -Subject: [PATCH] ppc/vof: Fix missed fields in VOF cleanup -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 7b8589d7ce7e23f26ff53338d575a5cbd7818e28 - -Failing to reset the of_instance_last makes ihandle allocation continue -to increase, which causes record-replay replay fail to match the -recorded trace. - -Not resetting claimed_base makes VOF eventually run out of memory after -some resets. - -Cc: Alexey Kardashevskiy -Fixes: fc8c745d501 ("spapr: Implement Open Firmware client interface") -Signed-off-by: Nicholas Piggin -Reviewed-by: Alexey Kardashevskiy -Signed-off-by: Cédric Le Goater -Signed-off-by: qihao_yewu ---- - hw/ppc/vof.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c -index 73adc44ec2..b1aa0ceb8b 100644 ---- a/hw/ppc/vof.c -+++ b/hw/ppc/vof.c -@@ -1026,6 +1026,8 @@ void vof_cleanup(Vof *vof) - } - vof->claimed = NULL; - vof->of_instances = NULL; -+ vof->of_instance_last = 0; -+ vof->claimed_base = 0; - } - - void vof_build_dt(void *fdt, Vof *vof) --- -2.41.0.windows.1 - diff --git a/ps2-fix-oob-in-ps2-kbd.patch b/ps2-fix-oob-in-ps2-kbd.patch deleted file mode 100644 index a385968fd30566264e234cc57ef60a7ad03097a3..0000000000000000000000000000000000000000 --- a/ps2-fix-oob-in-ps2-kbd.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 19523565181bb6efb1b9f819d45a7ca8ea6eca19 Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Wed, 9 Feb 2022 11:21:28 +0800 -Subject: [PATCH 11/15] ps2: fix oob in ps2 kbd - -fix oob in ps2 kbd ---- - hw/input/ps2.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/input/ps2.c b/hw/input/ps2.c -index 9376a8f4ce..5d82ee3cdf 100644 ---- a/hw/input/ps2.c -+++ b/hw/input/ps2.c -@@ -205,7 +205,7 @@ void ps2_queue_noirq(PS2State *s, int b) - } - - q->data[q->wptr] = b; -- if (++q->wptr == PS2_BUFFER_SIZE) { -+ if (++q->wptr >= PS2_BUFFER_SIZE) { - q->wptr = 0; - } - q->count++; -@@ -578,7 +578,7 @@ uint32_t ps2_read_data(PS2State *s) - val = q->data[index]; - } else { - val = q->data[q->rptr]; -- if (++q->rptr == PS2_BUFFER_SIZE) { -+ if (++q->rptr >= PS2_BUFFER_SIZE) { - q->rptr = 0; - } - q->count--; --- -2.27.0 - diff --git a/qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch b/qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch deleted file mode 100644 index 0834e79ca19a45eed4a70dcea0e620413dcd77d9..0000000000000000000000000000000000000000 --- a/qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 646cfa4209dde2258891668576d32759e1479dfa Mon Sep 17 00:00:00 2001 -From: Yang Zhong -Date: Thu, 20 Jan 2022 17:31:04 -0500 -Subject: [PATCH 4/9] qapi: Cleanup SGX related comments and restore - @section-size -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mainline inclusion -from mainline-v7.0.0-rc0 -commit a66bd91f030827742778a9e0da19fe55716b4a60 -category: feature -feature: NUMA support for SGX EPC sections -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5K27A - -Intel-SIG: commit a66bd91f0308 ("qapi: Cleanup SGX related comments -and restore @section-size") - -------------------------------------- - -qapi: Cleanup SGX related comments and restore @section-size - -The SGX NUMA patches were merged into Qemu 7.0 release, we need -clarify detailed version history information and also change -some related comments, which make SGX related comments clearer. - -The QMP command schema promises backwards compatibility as standard. -We temporarily restore "@section-size", which can avoid incompatible -API breakage. The "@section-size" will be deprecated in 7.2 version. - -Suggested-by: Daniel P. Berrangé -Signed-off-by: Yang Zhong -Reviewed-by: Daniel P. Berrangé -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20220120223104.437161-1-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - docs/about/deprecated.rst | 13 +++++++++++++ - hw/i386/sgx.c | 11 +++++++++-- - qapi/machine.json | 4 ++-- - qapi/misc-target.json | 22 +++++++++++++++++----- - 4 files changed, 41 insertions(+), 9 deletions(-) - -diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst -index ff7488cb63..33925edf45 100644 ---- a/docs/about/deprecated.rst -+++ b/docs/about/deprecated.rst -@@ -270,6 +270,19 @@ accepted incorrect commands will return an error. Users should make sure that - all arguments passed to ``device_add`` are consistent with the documented - property types. - -+``query-sgx`` return value member ``section-size`` (since 7.0) -+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -+ -+Member ``section-size`` in return value elements with meta-type ``uint64`` is -+deprecated. Use ``sections`` instead. -+ -+ -+``query-sgx-capabilities`` return value member ``section-size`` (since 7.0) -+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -+ -+Member ``section-size`` in return value elements with meta-type ``uint64`` is -+deprecated. Use ``sections`` instead. -+ - System accelerators - ------------------- - -diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c -index 5de5dd0893..a2b318dd93 100644 ---- a/hw/i386/sgx.c -+++ b/hw/i386/sgx.c -@@ -83,7 +83,7 @@ static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) - ((high & MAKE_64BIT_MASK(0, 20)) << 32); - } - --static SGXEPCSectionList *sgx_calc_host_epc_sections(void) -+static SGXEPCSectionList *sgx_calc_host_epc_sections(uint64_t *size) - { - SGXEPCSectionList *head = NULL, **tail = &head; - SGXEPCSection *section; -@@ -106,6 +106,7 @@ static SGXEPCSectionList *sgx_calc_host_epc_sections(void) - section = g_new0(SGXEPCSection, 1); - section->node = j++; - section->size = sgx_calc_section_metric(ecx, edx); -+ *size += section->size; - QAPI_LIST_APPEND(tail, section); - } - -@@ -156,6 +157,7 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp) - { - SGXInfo *info = NULL; - uint32_t eax, ebx, ecx, edx; -+ uint64_t size = 0; - - int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); - if (fd < 0) { -@@ -173,7 +175,8 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp) - info->sgx1 = eax & (1U << 0) ? true : false; - info->sgx2 = eax & (1U << 1) ? true : false; - -- info->sections = sgx_calc_host_epc_sections(); -+ info->sections = sgx_calc_host_epc_sections(&size); -+ info->section_size = size; - - close(fd); - -@@ -220,12 +223,14 @@ SGXInfo *qmp_query_sgx(Error **errp) - return NULL; - } - -+ SGXEPCState *sgx_epc = &pcms->sgx_epc; - info = g_new0(SGXInfo, 1); - - info->sgx = true; - info->sgx1 = true; - info->sgx2 = true; - info->flc = true; -+ info->section_size = sgx_epc->size; - info->sections = sgx_get_epc_sections_list(); - - return info; -@@ -249,6 +254,8 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict) - info->sgx2 ? "enabled" : "disabled"); - monitor_printf(mon, "FLC support: %s\n", - info->flc ? "enabled" : "disabled"); -+ monitor_printf(mon, "size: %" PRIu64 "\n", -+ info->section_size); - - section_list = info->sections; - for (section = section_list; section; section = section->next) { -diff --git a/qapi/machine.json b/qapi/machine.json -index 85c35e7fc5..03cfb268a4 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -1209,7 +1209,7 @@ - # - # @memdev: memory backend linked with device - # --# @node: the numa node -+# @node: the numa node (Since: 7.0) - # - # Since: 6.2 - ## -@@ -1290,7 +1290,7 @@ - # - # @memdev: memory backend linked with device - # --# @node: the numa node -+# @node: the numa node (Since: 7.0) - # - # Since: 6.2 - ## -diff --git a/qapi/misc-target.json b/qapi/misc-target.json -index 1022aa0184..4bc45d2474 100644 ---- a/qapi/misc-target.json -+++ b/qapi/misc-target.json -@@ -344,9 +344,9 @@ - # - # @node: the numa node - # --# @size: the size of epc section -+# @size: the size of EPC section - # --# Since: 6.2 -+# Since: 7.0 - ## - { 'struct': 'SGXEPCSection', - 'data': { 'node': 'int', -@@ -365,7 +365,13 @@ - # - # @flc: true if FLC is supported - # --# @sections: The EPC sections info for guest -+# @section-size: The EPC section size for guest -+# Redundant with @sections. Just for backward compatibility. -+# -+# @sections: The EPC sections info for guest (Since: 7.0) -+# -+# Features: -+# @deprecated: Member @section-size is deprecated. Use @sections instead. - # - # Since: 6.2 - ## -@@ -374,6 +380,8 @@ - 'sgx1': 'bool', - 'sgx2': 'bool', - 'flc': 'bool', -+ 'section-size': { 'type': 'uint64', -+ 'features': [ 'deprecated' ] }, - 'sections': ['SGXEPCSection']}, - 'if': 'TARGET_I386' } - -@@ -390,7 +398,9 @@ - # - # -> { "execute": "query-sgx" } - # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, --# "flc": true, "section-size" : 0 } } -+# "flc": true, "section-size" : 96468992, -+# "sections": [{"node": 0, "size": 67108864}, -+# {"node": 1, "size": 29360128}]} } - # - ## - { 'command': 'query-sgx', 'returns': 'SGXInfo', 'if': 'TARGET_I386' } -@@ -408,7 +418,9 @@ - # - # -> { "execute": "query-sgx-capabilities" } - # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, --# "flc": true, "section-size" : 0 } } -+# "flc": true, "section-size" : 96468992, -+# "section" : [{"node": 0, "size": 67108864}, -+# {"node": 1, "size": 29360128}]} } - # - ## - { 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo', 'if': 'TARGET_I386' } --- -2.27.0 - diff --git a/qapi-block-Tidy-up-block-latency-histogram-set-docum.patch b/qapi-block-Tidy-up-block-latency-histogram-set-docum.patch deleted file mode 100644 index 73fc5b3c412668e83d1b7981a107c334840f20fd..0000000000000000000000000000000000000000 --- a/qapi-block-Tidy-up-block-latency-histogram-set-docum.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 880364a83e4c7a7e379136056d63346cbdd7c2f0 Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Sun, 30 Jul 2023 18:58:08 -0700 -Subject: [PATCH] qapi/block: Tidy up block-latency-histogram-set documentation - mainline inclusion commit e893b9e3b3a6029384253f768cdc06969732e517 category: - bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -Examples come out like - -Example - -set new histograms for all io types with intervals [0, 10), [10, - 50), [50, 100), [100, +inf): - -The sentence "set new histograms ..." starts with a lower case letter. -Capitalize it. Same for the other examples. - -Signed-off-by: Markus Armbruster -Message-ID: <20230720071610.1096458-3-armbru@redhat.com> -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: zhujun2 ---- - qapi/block.json | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/qapi/block.json b/qapi/block.json -index 82fcf2c914..71136db777 100644 ---- a/qapi/block.json -+++ b/qapi/block.json -@@ -529,7 +529,8 @@ - # Since: 4.0 - # - # Example: --# set new histograms for all io types with intervals -+ -+# Set new histograms for all io types with intervals - # [0, 10), [10, 50), [50, 100), [100, +inf): - # - # -> { "execute": "block-latency-histogram-set", -@@ -538,7 +539,8 @@ - # <- { "return": {} } - # - # Example: --# set new histogram only for write, other histograms will remain -+ -+# Set new histogram only for write, other histograms will remain - # not changed (or not created): - # - # -> { "execute": "block-latency-histogram-set", -@@ -547,7 +549,8 @@ - # <- { "return": {} } - # - # Example: --# set new histograms with the following intervals: -+ -+# Set new histograms with the following intervals: - # read, flush: [0, 10), [10, 50), [50, 100), [100, +inf) - # write: [0, 1000), [1000, 5000), [5000, +inf) - # -@@ -558,7 +561,8 @@ - # <- { "return": {} } - # - # Example: --# remove all latency histograms: -+ -+# Remove all latency histograms: - # - # -> { "execute": "block-latency-histogram-set", - # "arguments": { "id": "drive0" } } --- -2.41.0.windows.1 - diff --git a/qapi-block-core-Add-retry-option-for-error-action.patch b/qapi-block-core-Add-retry-option-for-error-action.patch deleted file mode 100644 index f1536884698c15c4470c3c049093d24ffcc8b4c9..0000000000000000000000000000000000000000 --- a/qapi-block-core-Add-retry-option-for-error-action.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 4c3d47e04886e072acc0e4fefdc49e9d1f6b4ad1 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:45 +0800 -Subject: [PATCH 1/7] qapi/block-core: Add retry option for error action - -Add a new error action 'retry' to support retry on errors. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - blockdev.c | 2 ++ - qapi/block-core.json | 4 ++-- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/blockdev.c b/blockdev.c -index b35072644e..6f1981635b 100644 ---- a/blockdev.c -+++ b/blockdev.c -@@ -333,6 +333,8 @@ static int parse_block_error_action(const char *buf, bool is_read, Error **errp) - return BLOCKDEV_ON_ERROR_STOP; - } else if (!strcmp(buf, "report")) { - return BLOCKDEV_ON_ERROR_REPORT; -+ } else if (!strcmp(buf, "retry")) { -+ return BLOCKDEV_ON_ERROR_RETRY; - } else { - error_setg(errp, "'%s' invalid %s error action", - buf, is_read ? "read" : "write"); -diff --git a/qapi/block-core.json b/qapi/block-core.json -index 1d3dd9cb48..804beabfb0 100644 ---- a/qapi/block-core.json -+++ b/qapi/block-core.json -@@ -1146,7 +1146,7 @@ - # Since: 1.3 - ## - { 'enum': 'BlockdevOnError', -- 'data': ['report', 'ignore', 'enospc', 'stop', 'auto'] } -+ 'data': ['report', 'ignore', 'enospc', 'stop', 'auto', 'retry'] } - - ## - # @MirrorSyncMode: -@@ -4952,7 +4952,7 @@ - # Since: 2.1 - ## - { 'enum': 'BlockErrorAction', -- 'data': [ 'ignore', 'report', 'stop' ] } -+ 'data': [ 'ignore', 'report', 'stop', 'retry' ] } - - - ## --- -2.27.0 - diff --git a/qapi-machine.json-Fix-incorrect-description-for-die-.patch b/qapi-machine.json-Fix-incorrect-description-for-die-.patch deleted file mode 100644 index a5e605aca092a558d266b46771b4020a81c4a33c..0000000000000000000000000000000000000000 --- a/qapi-machine.json-Fix-incorrect-description-for-die-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From b04e92ed13e49f666f62c8f3daa5746109caf17b Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Mon, 22 Nov 2021 11:26:51 +0800 -Subject: [PATCH 01/24] qapi/machine.json: Fix incorrect description for die-id - -In terms of scope, die-id should mean "the die number within -socket the CPU belongs to" instead of "the die number within -node/board the CPU belongs to". Fix it to avoid confusing -the Doc reader. - -Fixes: 176d2cda0d ("i386/cpu: Consolidate die-id validity in smp context") -Signed-off-by: Yanan Wang -Reviewed-by: Eric Blake -Message-Id: <20211122032651.16064-1-wangyanan55@huawei.com> -Signed-off-by: Paolo Bonzini ---- - qapi/machine.json | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/qapi/machine.json b/qapi/machine.json -index 067e3f5378..f1839acf20 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -867,7 +867,7 @@ - # - # @node-id: NUMA node ID the CPU belongs to - # @socket-id: socket number within node/board the CPU belongs to --# @die-id: die number within node/board the CPU belongs to (Since 4.1) -+# @die-id: die number within socket the CPU belongs to (since 4.1) - # @core-id: core number within die the CPU belongs to - # @thread-id: thread number within core the CPU belongs to - # --- -2.27.0 - diff --git a/qapi-qdev-Tidy-up-device_add-documentation.patch b/qapi-qdev-Tidy-up-device_add-documentation.patch deleted file mode 100644 index 877a89541d6a385970a0dd4738a5bc91b29c2832..0000000000000000000000000000000000000000 --- a/qapi-qdev-Tidy-up-device_add-documentation.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 32b601ed22d154e9423911b27541b35aa12d18bb Mon Sep 17 00:00:00 2001 -From: Markus Armbruster -Date: Thu, 20 Jul 2023 09:16:06 +0200 -Subject: [PATCH] qapi/qdev: Tidy up device_add documentation mainline - inclusion commit a9c72efd6d6d62ac84ae57ca55606747e04e8ba7 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -------------------------------------------------------------------- - -The notes section comes out like this: - - Notes - - Additional arguments depend on the type. - - 1. For detailed information about this command, please refer to the - ‘docs/qdev-device-use.txt’ file. - - 2. It’s possible to list device properties by running QEMU with the - “-device DEVICE,help” command-line argument, where DEVICE is the - device’s name - -The first item isn't numbered. Fix that: - - 1. Additional arguments depend on the type. - - 2. For detailed information about this command, please refer to the - ‘docs/qdev-device-use.txt’ file. - - 3. It’s possible to list device properties by running QEMU with the - “-device DEVICE,help” command-line argument, where DEVICE is the - device’s name - -Signed-off-by: Markus Armbruster -Message-ID: <20230720071610.1096458-4-armbru@redhat.com> -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: zhujun2 ---- - qapi/qdev.json | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/qapi/qdev.json b/qapi/qdev.json -index 69656b14df..ca96a0c6eb 100644 ---- a/qapi/qdev.json -+++ b/qapi/qdev.json -@@ -47,12 +47,12 @@ - # - # Notes: - # --# Additional arguments depend on the type. -+# 1. Additional arguments depend on the type. - # --# 1. For detailed information about this command, please refer to the -+# 2. For detailed information about this command, please refer to the - # 'docs/qdev-device-use.txt' file. - # --# 2. It's possible to list device properties by running QEMU with the -+# 3. It's possible to list device properties by running QEMU with the - # "-device DEVICE,help" command-line argument, where DEVICE is the - # device's name - # --- -2.41.0.windows.1 - diff --git a/qapi-support-updating-expected-test-output-via-make.patch b/qapi-support-updating-expected-test-output-via-make.patch deleted file mode 100644 index 1c30d71d34b51ed478141da9b5de4a5fc7a5ca91..0000000000000000000000000000000000000000 --- a/qapi-support-updating-expected-test-output-via-make.patch +++ /dev/null @@ -1,43 +0,0 @@ -From fb63e3343eaaf1d5aaf0a28e2f3ed2248a11e86a Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Mon, 7 Aug 2023 00:28:14 -0700 -Subject: [PATCH] qapi: support updating expected test output via make -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 7ce54db23048bfcc3ea6821525bf333b715c7655 - -It is possible to pass --update to tests/qapi-schema/test-qapi.py -to make it update the output files on error. This is inconvenient -to achieve though when test-qapi.py is run indirectly by make/meson. - -Instead simply allow for an env variable to be set: - - $ QAPI_TEST_UPDATE= make check-qapi-schema - -Signed-off-by: Daniel P. Berrangé -Message-Id: <20230420102619.348173-2-berrange@redhat.com> -Reviewed-by: Markus Armbruster -Signed-off-by: Markus Armbruster - -Signed-off-by: Wanghe Xiao ---- - tests/qapi-schema/test-qapi.py | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py -index 2160cef082..d58c31f539 100755 ---- a/tests/qapi-schema/test-qapi.py -+++ b/tests/qapi-schema/test-qapi.py -@@ -206,6 +206,7 @@ def main(argv): - parser.add_argument('-d', '--dir', action='store', default='', - help="directory containing tests") - parser.add_argument('-u', '--update', action='store_true', -+ default='QAPI_TEST_UPDATE' in os.environ, - help="update expected test results") - parser.add_argument('tests', nargs='*', metavar='TEST', action='store') - args = parser.parse_args() --- -2.41.0.windows.1 - diff --git a/qcow2-fix-memory-leak-in-qcow2_read_extensions.patch b/qcow2-fix-memory-leak-in-qcow2_read_extensions.patch deleted file mode 100644 index ae629423b0389acc4594c930a3360c82898a843b..0000000000000000000000000000000000000000 --- a/qcow2-fix-memory-leak-in-qcow2_read_extensions.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a999e010c6af90f0fc1ad9b998e2a9b760c40f1a Mon Sep 17 00:00:00 2001 -From: zhanghailiang -Date: Thu, 25 Jul 2019 16:05:11 +0800 -Subject: [PATCH 2/6] qcow2: fix memory leak in qcow2_read_extensions - -Free feature_table if it is failed in bdrv_pread. - -Signed-off-by: fangyi -Signed-off-by: Yan Wang ---- - block/qcow2.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/block/qcow2.c b/block/qcow2.c -index d509016..be90a89 100644 ---- a/block/qcow2.c -+++ b/block/qcow2.c -@@ -272,6 +272,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, - void *feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature)); - ret = bdrv_pread(bs->file, offset , feature_table, ext.len); - if (ret < 0) { -+ g_free(feature_table); - error_setg_errno(errp, -ret, "ERROR: ext_feature_table: " - "Could not read table"); - return ret; --- -1.9.1 - diff --git a/qdev-monitors-Fix-reundant-error_setg-of-qdev_add_de.patch b/qdev-monitors-Fix-reundant-error_setg-of-qdev_add_de.patch deleted file mode 100644 index e02dbf6f365184c098159a72f29b7e256d235dac..0000000000000000000000000000000000000000 --- a/qdev-monitors-Fix-reundant-error_setg-of-qdev_add_de.patch +++ /dev/null @@ -1,31 +0,0 @@ -From ada323e932c83271184a6ddba1cfd74a29378963 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Thu, 29 Jul 2021 15:24:48 +0800 -Subject: [PATCH] qdev/monitors: Fix reundant error_setg of qdev_add_device - -There is an extra log "error_setg" in qdev_add_device(). When -hot-plug a device, if the corresponding bus doesn't exist, it -will trigger an asseration "assert(*errp == NULL)". - -Fixes: 515a7970490 (log: Add some logs on VM runtime path) -Signed-off-by: Kunkun Jiang -Signed-off-by: Yan Wang ---- - softmmu/qdev-monitor.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c -index dfd6429bf3..4a20f5dbd7 100644 ---- a/softmmu/qdev-monitor.c -+++ b/softmmu/qdev-monitor.c -@@ -636,7 +636,6 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts, - if (path != NULL) { - bus = qbus_find(path, errp); - if (!bus) { -- error_setg(errp, "can not find bus for %s", driver); - return NULL; - } - if (!object_dynamic_cast(OBJECT(bus), dc->bus_type)) { --- -2.27.0 - diff --git a/qemu-6.2.0.tar.xz b/qemu-8.2.0.tar.xz similarity index 82% rename from qemu-6.2.0.tar.xz rename to qemu-8.2.0.tar.xz index da2f1cd0f62dc3048369fa1b4c459d005b104a79..6d13b5dd8d4d58c99a8d664ca6f207c9ae5c59b7 100644 Binary files a/qemu-6.2.0.tar.xz and b/qemu-8.2.0.tar.xz differ diff --git a/qemu-binfmt-conf.sh-fix-F-option.patch b/qemu-binfmt-conf.sh-fix-F-option.patch deleted file mode 100644 index ae61bef12259ae723eb403a49d8e4a456efbf08b..0000000000000000000000000000000000000000 --- a/qemu-binfmt-conf.sh-fix-F-option.patch +++ /dev/null @@ -1,40 +0,0 @@ -From f87df2b0761b55b24a9317f7694e2225a29c981d Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 23 Nov 2022 06:33:44 +0000 -Subject: [PATCH 09/29] qemu-binfmt-conf.sh: fix -F option mainline inclusion - commit 719fab3afad22f34f0c812a8956adc88ab3242ce category: bugfix - ------------------------------------------------------------- - -qemu-binfmt-conf.sh should use "-F" as short option for "--qemu-suffix". -Fix the getopt call to make this work. - -Fixes: 7155be7cda5c ("qemu-binfmt-conf.sh: allow to provide a suffix to the interpreter name") -Signed-off-by: Martin Wilck -Reviewed-by: Laurent Vivier -Message-Id: <20211129135100.3934-1-mwilck@suse.com> -Signed-off-by: Laurent Vivier - -Signed-off-by: tangbinzy ---- - scripts/qemu-binfmt-conf.sh | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh -index 7de996d536..e9bfeb94d3 100755 ---- a/scripts/qemu-binfmt-conf.sh -+++ b/scripts/qemu-binfmt-conf.sh -@@ -340,7 +340,9 @@ PERSISTENT=no - PRESERVE_ARG0=no - QEMU_SUFFIX="" - --options=$(getopt -o ds:Q:S:e:hc:p:g: -l debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,persistent:,preserve-argv0: -- "$@") -+_longopts="debian,systemd:,qemu-path:,qemu-suffix:,exportdir:,help,credential:,\ -+persistent:,preserve-argv0:" -+options=$(getopt -o ds:Q:S:e:hc:p:g:F: -l ${_longopts} -- "$@") - eval set -- "$options" - - while true ; do --- -2.27.0 - diff --git a/qemu-img-add-qemu-img-direct-create.patch b/qemu-img-add-qemu-img-direct-create.patch deleted file mode 100644 index 082c110f1e2f83c06724a17b51e2b9c5f2d0b1a2..0000000000000000000000000000000000000000 --- a/qemu-img-add-qemu-img-direct-create.patch +++ /dev/null @@ -1,534 +0,0 @@ -From 8832a7dcad4e09229537781ff8db98496aa6f533 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 21:27:53 +0800 -Subject: [PATCH] qemu-img: add qemu-img direct create - -Introdue buffer_size while creating raw file, then we -can controll the speed of direct write by: - qemu-img create -t 'cache' -o buffer_size='num' - -Signed-off-by: Jinhua Cao ---- - block/file-posix.c | 65 +++++++++++++++++++++-- - include/block/block_int.h | 2 + - qapi/block-core.json | 6 ++- - qemu-img-cmds.hx | 4 +- - qemu-img.c | 14 ++++- - tests/qemu-iotests/049.out | 102 ++++++++++++++++++------------------- - tests/qemu-iotests/099.out | 2 +- - 7 files changed, 134 insertions(+), 61 deletions(-) - -diff --git a/block/file-posix.c b/block/file-posix.c -index aed7529f44..5180fd1d0b 100644 ---- a/block/file-posix.c -+++ b/block/file-posix.c -@@ -128,6 +128,10 @@ - #define FTYPE_CD 1 - - #define MAX_BLOCKSIZE 4096 -+#define DEFAULT_BUFFER_SIZE 65536 -+#define BUFFER_ALIGN_SIZE 65536 -+#define MIN_BUFFER_SIZE 65536 -+#define MAX_BUFFER_SIZE 16777216 - - /* Posix file locking bytes. Libvirt takes byte 0, we start from higher bytes, - * leaving a few more bytes for its future use. */ -@@ -206,6 +210,8 @@ typedef struct RawPosixAIOData { - off_t aio_offset; - uint64_t aio_nbytes; - -+ size_t buffer_size; -+ - union { - struct { - struct iovec *iov; -@@ -2218,7 +2224,8 @@ static void raw_close(BlockDriverState *bs) - */ - static int coroutine_fn - raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset, -- PreallocMode prealloc, Error **errp) -+ PreallocMode prealloc, size_t buffer_size, -+ Error **errp) - { - RawPosixAIOData acb; - -@@ -2227,6 +2234,7 @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset, - .aio_fildes = fd, - .aio_type = QEMU_AIO_TRUNCATE, - .aio_offset = offset, -+ .buffer_size = buffer_size, - .truncate = { - .prealloc = prealloc, - .errp = errp, -@@ -2252,7 +2260,8 @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset, - - if (S_ISREG(st.st_mode)) { - /* Always resizes to the exact @offset */ -- return raw_regular_truncate(bs, s->fd, offset, prealloc, errp); -+ return raw_regular_truncate(bs, s->fd, offset, prealloc, -+ DEFAULT_BUFFER_SIZE, errp); - } - - if (prealloc != PREALLOC_MODE_OFF) { -@@ -2465,6 +2474,8 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) - int fd; - uint64_t perm, shared; - int result = 0; -+ int flags = O_RDWR | O_BINARY; -+ size_t buffer_size = DEFAULT_BUFFER_SIZE; - - /* Validate options and set default values */ - assert(options->driver == BLOCKDEV_DRIVER_FILE); -@@ -2484,9 +2495,19 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) - error_setg(errp, "Extent size hint is too large"); - goto out; - } -+ if (!file_opts->has_cache) { -+ file_opts->cache = g_strdup("writeback"); -+ } -+ if (file_opts->preallocation == PREALLOC_MODE_FULL && -+ !strcmp(file_opts->cache, "none")) { -+ flags |= O_DIRECT; -+ } -+ if (file_opts->has_buffersize) { -+ buffer_size = file_opts->buffersize; -+ } - - /* Create file */ -- fd = qemu_create(file_opts->filename, O_RDWR | O_BINARY, 0644, errp); -+ fd = qemu_create(file_opts->filename, flags, 0644, errp); - if (fd < 0) { - result = -errno; - goto out; -@@ -2521,7 +2542,8 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) - } - - /* Clear the file by truncating it to 0 */ -- result = raw_regular_truncate(NULL, fd, 0, PREALLOC_MODE_OFF, errp); -+ result = raw_regular_truncate(NULL, fd, 0, PREALLOC_MODE_OFF, -+ buffer_size, errp); - if (result < 0) { - goto out_unlock; - } -@@ -2565,7 +2587,8 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp) - /* Resize and potentially preallocate the file to the desired - * final size */ - result = raw_regular_truncate(NULL, fd, file_opts->size, -- file_opts->preallocation, errp); -+ file_opts->preallocation, -+ buffer_size, errp); - if (result < 0) { - goto out_unlock; - } -@@ -2586,6 +2609,7 @@ out_close: - error_setg_errno(errp, -result, "Could not close the new file"); - } - out: -+ g_free(file_opts->cache); - return result; - } - -@@ -2602,6 +2626,8 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv, - PreallocMode prealloc; - char *buf = NULL; - Error *local_err = NULL; -+ size_t buffersize = DEFAULT_BUFFER_SIZE; -+ char *cache = NULL; - - /* Skip file: protocol prefix */ - strstart(filename, "file:", &filename); -@@ -2624,6 +2650,21 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv, - return -EINVAL; - } - -+ buffersize = qemu_opt_get_size_del(opts, BLOCK_OPT_BUFFER_SIZE, -+ DEFAULT_BUFFER_SIZE); -+ if (buffersize < MIN_BUFFER_SIZE || buffersize > MAX_BUFFER_SIZE) { -+ error_setg_errno(errp, EINVAL, "Buffer size must be between %d " -+ "and %d", MIN_BUFFER_SIZE, MAX_BUFFER_SIZE); -+ return -EINVAL; -+ } -+ -+ cache = qemu_opt_get_del(opts, BLOCK_OPT_CACHE); -+ if (!cache) { -+ cache = g_strdup("writeback"); -+ } -+ -+ buffersize = ROUND_UP(buffersize, BUFFER_ALIGN_SIZE); -+ - options = (BlockdevCreateOptions) { - .driver = BLOCKDEV_DRIVER_FILE, - .u.file = { -@@ -2635,6 +2676,10 @@ static int coroutine_fn raw_co_create_opts(BlockDriver *drv, - .nocow = nocow, - .has_extent_size_hint = has_extent_size_hint, - .extent_size_hint = extent_size_hint, -+ .has_buffersize = true, -+ .buffersize = buffersize, -+ .has_cache = true, -+ .cache = cache, - }, - }; - return raw_co_create(&options, errp); -@@ -3133,6 +3178,16 @@ static QemuOptsList raw_create_opts = { - .type = QEMU_OPT_SIZE, - .help = "Extent size hint for the image file, 0 to disable" - }, -+ { -+ .name = BLOCK_OPT_CACHE, -+ .type = QEMU_OPT_STRING, -+ .help = "Cache mode (allowed values: writeback, none)" -+ }, -+ { -+ .name = BLOCK_OPT_BUFFER_SIZE, -+ .type = QEMU_OPT_SIZE, -+ .help = "write buffer size" -+ }, - { /* end of list */ } - } - }; -diff --git a/include/block/block_int.h b/include/block/block_int.h -index f4c75e8ba9..701f031102 100644 ---- a/include/block/block_int.h -+++ b/include/block/block_int.h -@@ -61,6 +61,8 @@ - #define BLOCK_OPT_DATA_FILE_RAW "data_file_raw" - #define BLOCK_OPT_COMPRESSION_TYPE "compression_type" - #define BLOCK_OPT_EXTL2 "extended_l2" -+#define BLOCK_OPT_CACHE "cache" -+#define BLOCK_OPT_BUFFER_SIZE "buffer_size" - - #define BLOCK_PROBE_BUF_SIZE 512 - -diff --git a/qapi/block-core.json b/qapi/block-core.json -index 804beabfb0..e65fabe36d 100644 ---- a/qapi/block-core.json -+++ b/qapi/block-core.json -@@ -4437,6 +4437,8 @@ - # @nocow: Turn off copy-on-write (valid only on btrfs; default: off) - # @extent-size-hint: Extent size hint to add to the image file; 0 for not - # adding an extent size hint (default: 1 MB, since 5.1) -+# @cache: Cache mode used to write the output disk image -+# @buffersize: Buffer size for creating image - # - # Since: 2.12 - ## -@@ -4445,7 +4447,9 @@ - 'size': 'size', - '*preallocation': 'PreallocMode', - '*nocow': 'bool', -- '*extent-size-hint': 'size'} } -+ '*extent-size-hint': 'size', -+ '*cache': 'str', -+ '*buffersize': 'size'} } - - ## - # @BlockdevCreateOptionsGluster: -diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx -index 72bcdcfbfa..ec6aa2886a 100644 ---- a/qemu-img-cmds.hx -+++ b/qemu-img-cmds.hx -@@ -52,9 +52,9 @@ SRST - ERST - - DEF("create", img_create, -- "create [--object objectdef] [-q] [-f fmt] [-b backing_file] [-F backing_fmt] [-u] [-o options] filename [size]") -+ "create [--object objectdef] [-q] [-f fmt] [-b backing_file] [-F backing_fmt] [-u] [-t cache] [-o options] filename [size]") - SRST --.. option:: create [--object OBJECTDEF] [-q] [-f FMT] [-b BACKING_FILE] [-F BACKING_FMT] [-u] [-o OPTIONS] FILENAME [SIZE] -+.. option:: create [--object OBJECTDEF] [-q] [-f FMT] [-b BACKING_FILE] [-F BACKING_FMT] [-u] [-t CACHE] [-o OPTIONS] FILENAME [SIZE] - ERST - - DEF("dd", img_dd, -diff --git a/qemu-img.c b/qemu-img.c -index f036a1d428..9409558772 100644 ---- a/qemu-img.c -+++ b/qemu-img.c -@@ -504,6 +504,7 @@ static int img_create(int argc, char **argv) - const char *base_fmt = NULL; - const char *filename; - const char *base_filename = NULL; -+ const char *cache = BDRV_DEFAULT_CACHE; - char *options = NULL; - Error *local_err = NULL; - bool quiet = false; -@@ -515,7 +516,7 @@ static int img_create(int argc, char **argv) - {"object", required_argument, 0, OPTION_OBJECT}, - {0, 0, 0, 0} - }; -- c = getopt_long(argc, argv, ":F:b:f:ho:qu", -+ c = getopt_long(argc, argv, ":F:b:f:t:ho:qu", - long_options, NULL); - if (c == -1) { - break; -@@ -539,6 +540,9 @@ static int img_create(int argc, char **argv) - case 'f': - fmt = optarg; - break; -+ case 't': -+ cache = optarg; -+ break; - case 'o': - if (accumulate_options(&options, optarg) < 0) { - goto fail; -@@ -582,6 +586,14 @@ static int img_create(int argc, char **argv) - error_exit("Unexpected argument: %s", argv[optind]); - } - -+ if (!options) { -+ options = g_strdup_printf(BLOCK_OPT_CACHE"=%s", cache); -+ } else { -+ char *old_options = options; -+ options = g_strdup_printf("%s,"BLOCK_OPT_CACHE"=%s", options, cache); -+ g_free(old_options); -+ } -+ - bdrv_img_create(filename, fmt, base_filename, base_fmt, - options, img_size, flags, quiet, &local_err); - if (local_err) { -diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out -index 8719c91b48..6aca1a7797 100644 ---- a/tests/qemu-iotests/049.out -+++ b/tests/qemu-iotests/049.out -@@ -4,90 +4,90 @@ QA output created by 049 - == 1. Traditional size parameter == - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16 cache=writeback - - == 2. Specifying size via -o == - - qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1048576 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1073741824 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1099511627776 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1024 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1536 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1572864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1610612736 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2 --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=1649267441664 lazy_refcounts=off refcount_bits=16 cache=writeback - - == 3. Invalid sizes == - -@@ -135,84 +135,84 @@ qemu-img: TEST_DIR/t.qcow2: The image size must be specified only once - == Check correct interpretation of suffixes for cluster size == - - qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1048576 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1048576 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=1024 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=512 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=524288 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=524288 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - == Check compat level option == - - qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16 cache=writeback - qemu-img: TEST_DIR/t.qcow2: Parameter 'version' does not accept value '0.42' - - qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16 cache=writeback - qemu-img: TEST_DIR/t.qcow2: Parameter 'version' does not accept value 'foobar' - - == Check preallocation option == - - qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=metadata compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=metadata compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - qemu-img: TEST_DIR/t.qcow2: Parameter 'preallocation' does not accept value '1234' - - == Check encryption option == - - qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=off cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=off cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=on encrypt.key-secret=sec0 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 encryption=on encrypt.key-secret=sec0 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 cache=writeback - - == Check lazy_refcounts option (only with v3) == - - qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=on refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=1.1 lazy_refcounts=on refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=off refcount_bits=16 cache=writeback - - qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M --Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=on refcount_bits=16 -+Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.10 lazy_refcounts=on refcount_bits=16 cache=writeback - qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater) - - == Expect error when backing file name is empty string == -diff --git a/tests/qemu-iotests/099.out b/tests/qemu-iotests/099.out -index 8cce627529..f6f8f25957 100644 ---- a/tests/qemu-iotests/099.out -+++ b/tests/qemu-iotests/099.out -@@ -1,6 +1,6 @@ - QA output created by 099 - Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072 --Formatting 'TEST_DIR/t.IMGFMT.compare', fmt=raw size=131072 -+Formatting 'TEST_DIR/t.IMGFMT.compare', fmt=raw size=131072 cache=writeback - - === Testing simple filename for blkverify === - --- -2.27.0 - diff --git a/qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch b/qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch deleted file mode 100644 index c96e5b429f72f4830bd7361891dbda78ac217cf6..0000000000000000000000000000000000000000 --- a/qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 724134432ef21f1fb2b18bbe55b891d31181ccca Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Fri, 11 Feb 2022 14:25:39 +0800 -Subject: [PATCH] qemu-img: block: dont blk_make_zero if discard_zeroes false - -Signed-off-by: Jinhua Cao ---- - block/file-posix.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/block/file-posix.c b/block/file-posix.c -index b283093e5b..aed7529f44 100644 ---- a/block/file-posix.c -+++ b/block/file-posix.c -@@ -804,7 +804,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options, - } - #endif - -- bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK; -+ bs->supported_zero_flags = s->discard_zeroes ? (BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) : 0; - if (S_ISREG(st.st_mode)) { - /* When extending regular files, we get zeros from the OS */ - bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE; --- -2.27.0 - diff --git a/qemu-img-create-cache-paramter-only-use-for-reg-file.patch b/qemu-img-create-cache-paramter-only-use-for-reg-file.patch deleted file mode 100644 index c4664e1bc4da6edd525606b11f334f4fea4bc851..0000000000000000000000000000000000000000 --- a/qemu-img-create-cache-paramter-only-use-for-reg-file.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 85a876e0d28eac4c71350baede38ca755fdf6df0 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 24 Mar 2022 17:12:49 +0800 -Subject: [PATCH] qemu-img create: 'cache' paramter only use for reg file image - -The paramter 'cache' is invalid for host device(/dev/xxx). If -'qemu-img create' operator performed on host device, the host -device not support 'cache' would result 'qemu-img create' execute -failed. - -Signed-off-by: Jinhua Cao ---- - qemu-img.c | 30 ++++++++++++++++++++++++------ - 1 file changed, 24 insertions(+), 6 deletions(-) - -diff --git a/qemu-img.c b/qemu-img.c -index 9409558772..059bf42fc1 100644 ---- a/qemu-img.c -+++ b/qemu-img.c -@@ -496,6 +496,22 @@ static int64_t cvtnum(const char *name, const char *value) - return cvtnum_full(name, value, 0, INT64_MAX); - } - -+static bool is_reg_file(const char *filename) -+{ -+ struct stat st; -+ -+ /* file not exist, file will be create later, so it's a reg file */ -+ if (access(filename, F_OK) == -1) { -+ return true; -+ } -+ -+ /* file exist, check file type */ -+ if (stat(filename, &st) >= 0 && S_ISREG(st.st_mode)) { -+ return true; -+ } -+ return false; -+} -+ - static int img_create(int argc, char **argv) - { - int c; -@@ -586,12 +602,14 @@ static int img_create(int argc, char **argv) - error_exit("Unexpected argument: %s", argv[optind]); - } - -- if (!options) { -- options = g_strdup_printf(BLOCK_OPT_CACHE"=%s", cache); -- } else { -- char *old_options = options; -- options = g_strdup_printf("%s,"BLOCK_OPT_CACHE"=%s", options, cache); -- g_free(old_options); -+ if (is_reg_file(filename)) { -+ if (!options) { -+ options = g_strdup_printf(BLOCK_OPT_CACHE"=%s", cache); -+ } else { -+ char *old_options = options; -+ options = g_strdup_printf("%s,"BLOCK_OPT_CACHE"=%s", options, cache); -+ g_free(old_options); -+ } - } - - bdrv_img_create(filename, fmt, base_filename, base_fmt, --- -2.27.0 - diff --git a/qemu-nbd-make-native-as-the-default-aio-mode.patch b/qemu-nbd-make-native-as-the-default-aio-mode.patch deleted file mode 100644 index c53f50a27d3d96cb9a970e73b381124c207b43ed..0000000000000000000000000000000000000000 --- a/qemu-nbd-make-native-as-the-default-aio-mode.patch +++ /dev/null @@ -1,35 +0,0 @@ -From de6f3fb0cf92e04c0989a9065910158eecbe4304 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 10:48:58 +0800 -Subject: [PATCH] qemu-nbd: make native as the default aio mode - -When the file system is dealing with multithreading concurrent writing to a file, -the performance will be degraded because of the lock. -At present, the default AIO mode of QEMU NBD is threads. In the case of large blocks, -because IO is divided into small pieces and multiple queues, it will become multithreading -concurrent writing the same file. Due to the file system, the performance will be greatly reduced. -If you change to native mode, this problem will not exist. - -Signed-off-by: wangjian161 ---- - qemu-nbd.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/qemu-nbd.c b/qemu-nbd.c -index c6c20df68a..15a4bc4018 100644 ---- a/qemu-nbd.c -+++ b/qemu-nbd.c -@@ -800,6 +800,10 @@ int main(int argc, char **argv) - trace_init_file(); - qemu_set_log(LOG_TRACE); - -+ if (!seen_aio && (flags & BDRV_O_NOCACHE)) { -+ flags |= BDRV_O_NATIVE_AIO; -+ } -+ - socket_activation = check_socket_activation(); - if (socket_activation == 0) { - setup_address_and_port(&bindto, &port); --- -2.27.0 - diff --git a/qemu-nbd-set-timeout-to-qemu-nbd-socket.patch b/qemu-nbd-set-timeout-to-qemu-nbd-socket.patch deleted file mode 100644 index 3ef9b6ae61755fa3f9289a91b14a0e4fa559304e..0000000000000000000000000000000000000000 --- a/qemu-nbd-set-timeout-to-qemu-nbd-socket.patch +++ /dev/null @@ -1,42 +0,0 @@ -From f665f7836a019cc8bb8d46d076508afc761923f0 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 10:55:08 +0800 -Subject: [PATCH] qemu-nbd: set timeout to qemu-nbd socket - -In case of insufficient memory and kill-9, -the NBD socket cannot be processed and stuck all the time. - -Signed-off-by: wangjian161 ---- - nbd/client.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/nbd/client.c b/nbd/client.c -index 30d5383cb1..8ed50140f2 100644 ---- a/nbd/client.c -+++ b/nbd/client.c -@@ -24,6 +24,8 @@ - #include "nbd-internal.h" - #include "qemu/cutils.h" - -+#define NBD_TIMEOUT_SECONDS 30 -+ - /* Definitions for opaque data types */ - - static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); -@@ -1301,6 +1303,12 @@ int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info, - } - } - -+ if (ioctl(fd, NBD_SET_TIMEOUT, NBD_TIMEOUT_SECONDS) < 0) { -+ int serrno = errno; -+ error_setg(errp, "Failed setting timeout"); -+ return -serrno; -+ } -+ - trace_nbd_init_finish(); - - return 0; --- -2.27.0 - diff --git a/qemu-options-Improve-readability-of-SMP-related-Docs.patch b/qemu-options-Improve-readability-of-SMP-related-Docs.patch deleted file mode 100644 index 63dc895ac31d7be9be0de1a0390a039a7f66b6f3..0000000000000000000000000000000000000000 --- a/qemu-options-Improve-readability-of-SMP-related-Docs.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 07991b049fc9ebdb62c311eda1535ad4831625e5 Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Tue, 28 Dec 2021 17:22:08 +0800 -Subject: [PATCH 10/24] qemu-options: Improve readability of SMP related Docs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We have a description in qemu-options.hx for each CPU topology -parameter to explain what it exactly means, and also an extra -declaration for the target-specific one, e.g. "for PC only" -when describing "dies", and "for PC, it's on one die" when -describing "cores". - -Now we are going to introduce one more non-generic parameter -"clusters", it will make the Doc less readable and if we still -continue to use the legacy way to describe it. - -So let's at first make two tweaks of the Docs to improve the -readability and also scalability: -1) In the -help text: Delete the extra specific declaration and - describe each topology parameter level by level. Then add a - note to declare that different machines may support different - subsets and the actual meaning of the supported parameters - will vary accordingly. -2) In the rST text: List all the sub-hierarchies currently - supported in QEMU, and correspondingly give an example of - -smp configuration for each of them. - -Signed-off-by: Yanan Wang -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20211228092221.21068-2-wangyanan55@huawei.com> -Signed-off-by: Philippe Mathieu-Daudé ---- - qemu-options.hx | 76 ++++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 59 insertions(+), 17 deletions(-) - -diff --git a/qemu-options.hx b/qemu-options.hx -index ae2c6dbbfc..7a59db7764 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -207,14 +207,26 @@ ERST - - DEF("smp", HAS_ARG, QEMU_OPTION_smp, - "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]\n" -- " set the number of CPUs to 'n' [default=1]\n" -+ " set the number of initial CPUs to 'n' [default=1]\n" - " maxcpus= maximum number of total CPUs, including\n" - " offline CPUs for hotplug, etc\n" -- " sockets= number of discrete sockets in the system\n" -- " dies= number of CPU dies on one socket (for PC only)\n" -- " cores= number of CPU cores on one socket (for PC, it's on one die)\n" -- " threads= number of threads on one CPU core\n", -- QEMU_ARCH_ALL) -+ " sockets= number of sockets on the machine board\n" -+ " dies= number of dies in one socket\n" -+ " cores= number of cores in one die\n" -+ " threads= number of threads in one core\n" -+ "Note: Different machines may have different subsets of the CPU topology\n" -+ " parameters supported, so the actual meaning of the supported parameters\n" -+ " will vary accordingly. For example, for a machine type that supports a\n" -+ " three-level CPU hierarchy of sockets/cores/threads, the parameters will\n" -+ " sequentially mean as below:\n" -+ " sockets means the number of sockets on the machine board\n" -+ " cores means the number of cores in one socket\n" -+ " threads means the number of threads in one core\n" -+ " For a particular machine type board, an expected CPU topology hierarchy\n" -+ " can be defined through the supported sub-option. Unsupported parameters\n" -+ " can also be provided in addition to the sub-option, but their values\n" -+ " must be set as 1 in the purpose of correct parsing.\n", -+ QEMU_ARCH_ALL) - SRST - ``-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,cores=cores][,threads=threads]`` - Simulate a SMP system with '\ ``n``\ ' CPUs initially present on -@@ -225,27 +237,57 @@ SRST - initial CPU count will match the maximum number. When only one of them - is given then the omitted one will be set to its counterpart's value. - Both parameters may be specified, but the maximum number of CPUs must -- be equal to or greater than the initial CPU count. Both parameters are -- subject to an upper limit that is determined by the specific machine -- type chosen. -- -- To control reporting of CPU topology information, the number of sockets, -- dies per socket, cores per die, and threads per core can be specified. -- The sum `` sockets * cores * dies * threads `` must be equal to the -- maximum CPU count. CPU targets may only support a subset of the topology -- parameters. Where a CPU target does not support use of a particular -- topology parameter, its value should be assumed to be 1 for the purpose -- of computing the CPU maximum count. -+ be equal to or greater than the initial CPU count. Product of the -+ CPU topology hierarchy must be equal to the maximum number of CPUs. -+ Both parameters are subject to an upper limit that is determined by -+ the specific machine type chosen. -+ -+ To control reporting of CPU topology information, values of the topology -+ parameters can be specified. Machines may only support a subset of the -+ parameters and different machines may have different subsets supported -+ which vary depending on capacity of the corresponding CPU targets. So -+ for a particular machine type board, an expected topology hierarchy can -+ be defined through the supported sub-option. Unsupported parameters can -+ also be provided in addition to the sub-option, but their values must be -+ set as 1 in the purpose of correct parsing. - - Either the initial CPU count, or at least one of the topology parameters - must be specified. The specified parameters must be greater than zero, - explicit configuration like "cpus=0" is not allowed. Values for any - omitted parameters will be computed from those which are given. -+ -+ For example, the following sub-option defines a CPU topology hierarchy -+ (2 sockets totally on the machine, 2 cores per socket, 2 threads per -+ core) for a machine that only supports sockets/cores/threads. -+ Some members of the option can be omitted but their values will be -+ automatically computed: -+ -+ :: -+ -+ -smp 8,sockets=2,cores=2,threads=2,maxcpus=8 -+ -+ The following sub-option defines a CPU topology hierarchy (2 sockets -+ totally on the machine, 2 dies per socket, 2 cores per die, 2 threads -+ per core) for PC machines which support sockets/dies/cores/threads. -+ Some members of the option can be omitted but their values will be -+ automatically computed: -+ -+ :: -+ -+ -smp 16,sockets=2,dies=2,cores=2,threads=2,maxcpus=16 -+ - Historically preference was given to the coarsest topology parameters - when computing missing values (ie sockets preferred over cores, which - were preferred over threads), however, this behaviour is considered - liable to change. Prior to 6.2 the preference was sockets over cores - over threads. Since 6.2 the preference is cores over sockets over threads. -+ -+ For example, the following option defines a machine board with 2 sockets -+ of 1 core before 6.2 and 1 socket of 2 cores after 6.2: -+ -+ :: -+ -+ -smp 2 - ERST - - DEF("numa", HAS_ARG, QEMU_OPTION_numa, --- -2.27.0 - diff --git a/qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch b/qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch deleted file mode 100644 index 7985a92790e80f44d2aaef55a0603bb8eb86b998..0000000000000000000000000000000000000000 --- a/qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 56f59125707c0222bbb5d7f820792aba17c3db08 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 11:10:42 +0800 -Subject: [PATCH] qemu-pr: fixed ioctl failed for multipath disk - -We use ioctl to detect multipath devices. However, we only set flags in -struct dm_ioctl (the argument to ioctl) and left other fields in random, -which may cause the failure of calling ioctl. Hence, we set other -fields to 0 to avoid the failure. - -Signed-off-by: wangjian161 ---- - scsi/qemu-pr-helper.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c -index f281daeced..bbb9b57741 100644 ---- a/scsi/qemu-pr-helper.c -+++ b/scsi/qemu-pr-helper.c -@@ -288,9 +288,12 @@ static void multipath_pr_init(void) - - static int is_mpath(int fd) - { -- struct dm_ioctl dm = { .flags = DM_NOFLUSH_FLAG }; -+ struct dm_ioctl dm; - struct dm_target_spec *tgt; - -+ memset(&dm, 0, sizeof(struct dm_ioctl)); -+ dm.flags = DM_NOFLUSH_FLAG; -+ - tgt = dm_dev_ioctl(fd, DM_TABLE_STATUS, &dm); - if (!tgt) { - if (errno == ENXIO) { --- -2.27.0 - diff --git a/qemu-timer-Skip-empty-timer-lists-before-locking-in-.patch b/qemu-timer-Skip-empty-timer-lists-before-locking-in-.patch deleted file mode 100644 index 2578891b45520ce59eb60b5f303c4d7fd4bfa9bb..0000000000000000000000000000000000000000 --- a/qemu-timer-Skip-empty-timer-lists-before-locking-in-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 274dd10230eef97714a2a283ecd8a8ce2ecbf687 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 6 Nov 2023 07:28:31 +0000 -Subject: [PATCH] qemu-timer: Skip empty timer lists before locking in - qemu_clock_deadline_ns_all mainline inclusion commit - 3f42906c9ab2c777a895b48b87b8107167e4a275 category: bugfix - ---------------------------------------------------------------- - -This decreases qemu_clock_deadline_ns_all's share from 23.2% to 13% in a -profile of icount-enabled aarch64-softmmu. - -Signed-off-by: Idan Horowitz -Reviewed-by: Richard Henderson -Message-Id: <20220114004358.299534-2-idan.horowitz@gmail.com> -Signed-off-by: Richard Henderson - -Signed-off-by: tangbinzy ---- - util/qemu-timer.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/util/qemu-timer.c b/util/qemu-timer.c -index 40e8c83722..c5b6dc987c 100644 ---- a/util/qemu-timer.c -+++ b/util/qemu-timer.c -@@ -330,6 +330,9 @@ int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask) - } - - QLIST_FOREACH(timer_list, &clock->timerlists, list) { -+ if (!qatomic_read(&timer_list->active_timers)) { -+ continue; -+ } - qemu_mutex_lock(&timer_list->active_timers_lock); - ts = timer_list->active_timers; - /* Skip all external timers */ --- -2.27.0 - diff --git a/qemu.spec b/qemu.spec index d773e3a690f5472abd056ae120f6c14cc7d44cae..f9825b33c91c5c7e83f0ee24000055abb538e090 100644 --- a/qemu.spec +++ b/qemu.spec @@ -2,9 +2,9 @@ %bcond_without rbd Name: qemu -Version: 6.2.0 -Release: 87 -Epoch: 10 +Version: 8.2.0 +Release: 1 +Epoch: 11 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 URL: http://www.qemu.org @@ -14,851 +14,6 @@ Source2: 99-qemu-guest-agent.rules Source3: bridge.conf Source4: BinDir.tar.gz -Patch0001: net-dump.c-Suppress-spurious-compiler-warning.patch -Patch0002: cpu-parse-feature-to-avoid-failure.patch -Patch0003: cpu-add-Kunpeng-920-cpu-support.patch -Patch0004: cpu-add-Cortex-A72-processor-kvm-target-support.patch -Patch0005: add-Phytium-s-CPU-models-FT-2000-and-Tengyun-S2500.patch -Patch0006: qapi-block-core-Add-retry-option-for-error-action.patch -Patch0007: block-backend-Introduce-retry-timer.patch -Patch0008: block-backend-Add-device-specific-retry-callback.patch -Patch0009: block-backend-Enable-retry-action-on-errors.patch -Patch0010: block-backend-Add-timeout-support-for-retry.patch -Patch0011: block-Add-error-retry-param-setting.patch -Patch0012: virtio_blk-Add-support-for-retry-on-errors.patch -Patch0013: vhost-cancel-migration-when-vhost-user-restarted-dur.patch -Patch0014: migration-Add-multi-thread-compress-method.patch -Patch0015: migration-Refactoring-multi-thread-compress-migratio.patch -Patch0016: migration-Add-multi-thread-compress-ops.patch -Patch0017: migration-Add-zstd-support-in-multi-thread-compressi.patch -Patch0018: migration-Add-compress_level-sanity-check.patch -Patch0019: doc-Update-multi-thread-compression-doc.patch -Patch0020: Revert-cpu-parse-feature-to-avoid-failure.patch -Patch0021: Revert-cpu-add-Cortex-A72-processor-kvm-target-suppo.patch -Patch0022: cpu-add-Cortex-A72-processor-kvm-target-support-v2.patch -Patch0023: hugepages-hugepages-files-maybe-leftover.patch -Patch0024: target-i386-Modify-the-VM-s-physical-bits-value-set-.patch -Patch0025: vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch -Patch0026: vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch -Patch0027: vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch -Patch0028: scsi-bus-Refactor-the-code-that-retries-requests.patch -Patch0029: scsi-disk-Add-support-for-retry-on-errors.patch -Patch0030: block-backend-Stop-retrying-when-draining.patch -Patch0031: block-Add-sanity-check-when-setting-retry-parameters.patch -Patch0032: migration-skip-cache_drop-for-bios-bootloader-and-nv.patch -Patch0033: ps2-fix-oob-in-ps2-kbd.patch -Patch0034: Currently-while-kvm-and-qemu-can-not-handle-some-kvm.patch -Patch0035: cpu-features-fix-bug-for-memory-leakage.patch -Patch0036: monitor-qmp-drop-inflight-rsp-if-qmp-client-broken.patch -Patch0037: oslib-posix-optimise-vm-startup-time-for-1G-hugepage.patch -Patch0038: nbd-server.c-fix-invalid-read-after-client-was-alrea.patch -Patch0039: qemu-nbd-make-native-as-the-default-aio-mode.patch -Patch0040: qemu-nbd-set-timeout-to-qemu-nbd-socket.patch -Patch0041: qemu-pr-fixed-ioctl-failed-for-multipath-disk.patch -Patch0042: block-enable-cache-mode-of-empty-cdrom.patch -Patch0043: block-disallow-block-jobs-when-there-is-a-BDRV_O_INA.patch -Patch0044: scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch -Patch0045: block-bugfix-disable-process-AIO-when-attach-scsi-di.patch -Patch0046: block-bugfix-Don-t-pause-vm-when-NOSPACE-EIO-happene.patch -Patch0047: scsi-bugfix-fix-division-by-zero.patch -Patch0048: i386-cache-passthrough-Update-Intel-CPUID4.EAX-25-14.patch -Patch0049: i386-cache-passthrough-Update-AMD-8000_001D.EAX-25-1.patch -Patch0050: target-arm-convert-isar-regs-to-array.patch -Patch0051: target-arm-parse-cpu-feature-related-options.patch -Patch0052: target-arm-register-CPU-features-for-property.patch -Patch0053: target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch -Patch0054: target-arm-introduce-CPU-feature-dependency-mechanis.patch -Patch0055: target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch -Patch0056: target-arm-Add-CPU-features-to-query-cpu-model-expan.patch -Patch0057: target-arm-Add-more-CPU-features.patch -Patch0058: target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch -Patch0059: target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch -Patch0060: target-arm-Fix-write-redundant-values-to-kvm.patch -Patch0061: target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch -Patch0062: target-arm-Update-the-ID-registers-of-Kunpeng-920.patch -Patch0063: freeclock-add-qmp-command-to-get-time-offset-of-vm-i.patch -Patch0064: freeclock-set-rtc_date_diff-for-arm.patch -Patch0065: freeclock-set-rtc_date_diff-for-X86.patch -Patch0066: hw-usb-reduce-the-vpcu-cost-of-UHCI-when-VNC-disconn.patch -Patch0067: hw-net-rocker-fix-security-vulnerability.patch -Patch0068: tests-Disable-filemonitor-testcase.patch -Patch0069: seabios-convert-value-of-be16_to_cpu-to-u64-before-s.patch -Patch0070: seabios-do-not-give-back-high-ram.patch -Patch0071: seabios-drop-yield-in-smp_setup.patch -Patch0072: seabios-fix-memory-leak-when-pci-check.patch -Patch0073: seabios-increase-the-seabios-high-mem-zone-size.patch -Patch0074: seabios-increase-the-seabios-minibiostable.patch -Patch0075: IPv6-add-support-for-IPv6-protocol.patch -Patch0076: Use-post-increment-only-in-inffast.c.patch -Patch0077: util-log-add-CONFIG_DISABLE_QEMU_LOG-macro.patch -Patch0078: log-Add-some-logs-on-VM-runtime-path.patch -Patch0079: qdev-monitors-Fix-reundant-error_setg-of-qdev_add_de.patch -Patch0080: bios-tables-test-Allow-changes-to-q35-SSDT.dimmpxm-f.patch -Patch0081: smbios-Add-missing-member-of-type-4-for-smbios-3.0.patch -Patch0082: net-eepro100-validate-various-address-valuesi-CVE-20.patch -Patch0083: pci-check-bus-pointer-before-dereference.patch -Patch0084: ide-ahci-add-check-to-avoid-null-dereference-CVE-201.patch -Patch0085: tap-return-err-when-tap-TUNGETIFF-fail.patch -Patch0086: xhci-check-reg-to-avoid-OOB-read.patch -Patch0087: monitor-Discard-BLOCK_IO_ERROR-event-when-VM-reboote.patch -Patch0088: monitor-limit-io-error-qmp-event-to-at-most-once-per.patch -Patch0089: linux-headers-update-against-5.10-and-manual-clear-v.patch -Patch0090: vfio-Maintain-DMA-mapping-range-for-the-container.patch -Patch0091: vfio-migration-Add-support-for-manual-clear-vfio-dir.patch -Patch0092: update-linux-headers-Import-iommu.h.patch -Patch0093: vfio.h-and-iommu.h-header-update-against-5.10.patch -Patch0094: memory-Add-new-fields-in-IOTLBEntry.patch -Patch0095: hw-arm-smmuv3-Improve-stage1-ASID-invalidation.patch -Patch0096: hw-arm-smmu-common-Allow-domain-invalidation-for-NH_.patch -Patch0097: memory-Add-IOMMU_ATTR_VFIO_NESTED-IOMMU-memory-regio.patch -Patch0098: memory-Add-IOMMU_ATTR_MSI_TRANSLATE-IOMMU-memory-reg.patch -Patch0099: memory-Introduce-IOMMU-Memory-Region-inject_faults-A.patch -Patch0100: iommu-Introduce-generic-header.patch -Patch0101: pci-introduce-PCIPASIDOps-to-PCIDevice.patch -Patch0102: vfio-Force-nested-if-iommu-requires-it.patch -Patch0103: vfio-Introduce-hostwin_from_range-helper.patch -Patch0104: vfio-Introduce-helpers-to-DMA-map-unmap-a-RAM-sectio.patch -Patch0105: vfio-Set-up-nested-stage-mappings.patch -Patch0106: vfio-Pass-stage-1-MSI-bindings-to-the-host.patch -Patch0107: vfio-Helper-to-get-IRQ-info-including-capabilities.patch -Patch0108: vfio-pci-Register-handler-for-iommu-fault.patch -Patch0109: vfio-pci-Set-up-the-DMA-FAULT-region.patch -Patch0110: vfio-pci-Implement-the-DMA-fault-handler.patch -Patch0111: hw-arm-smmuv3-Advertise-MSI_TRANSLATE-attribute.patch -Patch0112: hw-arm-smmuv3-Store-the-PASID-table-GPA-in-the-trans.patch -Patch0113: hw-arm-smmuv3-Fill-the-IOTLBEntry-arch_id-on-NH_VA-i.patch -Patch0114: hw-arm-smmuv3-Fill-the-IOTLBEntry-leaf-field-on-NH_V.patch -Patch0115: hw-arm-smmuv3-Pass-stage-1-configurations-to-the-hos.patch -Patch0116: hw-arm-smmuv3-Implement-fault-injection.patch -Patch0117: hw-arm-smmuv3-Allow-MAP-notifiers.patch -Patch0118: pci-Add-return_page_response-pci-ops.patch -Patch0119: vfio-pci-Implement-return_page_response-page-respons.patch -Patch0120: vfio-common-Avoid-unmap-ram-section-at-vfio_listener.patch -Patch0121: vfio-Introduce-helpers-to-mark-dirty-pages-of-a-RAM-.patch -Patch0122: vfio-Add-vfio_prereg_listener_log_sync-in-nested-sta.patch -Patch0123: vfio-Add-vfio_prereg_listener_log_clear-to-re-enable.patch -Patch0124: vfio-Add-vfio_prereg_listener_global_log_start-stop-.patch -Patch0125: hw-arm-smmuv3-Post-load-stage-1-configurations-to-th.patch -Patch0126: vfio-common-Fix-incorrect-address-alignment-in-vfio_.patch -Patch0127: vfio-common-Add-address-alignment-check-in-vfio_list.patch -Patch0128: log-Add-log-at-boot-cpu-init-for-aarch64.patch -Patch0129: feature-Add-log-for-each-modules.patch -Patch0130: feature-Add-logs-for-vm-start-and-destroy.patch -Patch0131: bugfix-fix-some-illegal-memory-access-and-memory-lea.patch -Patch0132: bugfix-fix-possible-memory-leak.patch -Patch0133: bugfix-fix-eventfds-may-double-free-when-vm_id-reuse.patch -Patch0134: block-mirror-fix-file-system-went-to-read-only-after.patch -Patch0135: bugfix-fix-mmio-information-leak-and-ehci-vm-escape-.patch -Patch0136: target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch -Patch0137: virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch -Patch0138: virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch -Patch0139: virtio-bugfix-clean-up-callback-when-del-virtqueue.patch -Patch0140: virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch -Patch0141: virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch -Patch0142: virtio-check-descriptor-numbers.patch -Patch0143: virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch -Patch0144: virtio-print-the-guest-virtio_net-features-that-host.patch -Patch0145: virtio-bugfix-check-the-value-of-caches-before-acces.patch -Patch0146: virtio-net-set-the-max-of-queue-size-to-4096.patch -Patch0147: virtio-net-update-the-default-and-max-of-rx-tx_queue.patch -Patch0148: vhost-user-add-unregister_savevm-when-vhost-user-cle.patch -Patch0149: qemu-img-block-dont-blk_make_zero-if-discard_zeroes-.patch -Patch0150: vhost-user-Add-support-reconnect-vhost-user-socket.patch -Patch0151: vhost-user-Set-the-acked_features-to-vm-s-featrue.patch -Patch0152: vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch -Patch0153: vhost-user-add-separate-memslot-counter-for-vhost-us.patch -Patch0154: vhost-user-quit-infinite-loop-while-used-memslots-is.patch -Patch0155: qmp-add-command-to-query-used-memslots-of-vhost-net-.patch -Patch0156: vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch -Patch0157: i6300esb-watchdog-bugfix-Add-a-runstate-transition.patch -Patch0158: bugfix-irq-Avoid-covering-object-refcount-of-qemu_ir.patch -Patch0159: seabios-add-check-to-avoid-dereference-NULL-pointer.patch -Patch0160: qemu-img-add-qemu-img-direct-create.patch -Patch0161: log-Delete-redudant-qemu_log.patch -Patch0162: bios-tables-test-Update-expected-q35-SSDT.dimmpxm-fi.patch -Patch0163: qapi-machine.json-Fix-incorrect-description-for-die-.patch -Patch0164: tests-unit-test-smp-parse-Pass-machine-type-as-argum.patch -Patch0165: tests-unit-test-smp-parse-Split-the-generic-test-in-.patch -Patch0166: tests-unit-test-smp-parse-Add-smp-with-dies-machine-.patch -Patch0167: tests-unit-test-smp-parse-Add-smp-generic-invalid-ma.patch -Patch0168: tests-unit-test-smp-parse-Add-smp-generic-valid-mach.patch -Patch0169: tests-unit-test-smp-parse-Simplify-pointer-to-compou.patch -Patch0170: tests-unit-test-smp-parse-Constify-some-pointer-stru.patch -Patch0171: hw-core-Rename-smp_parse-machine_parse_smp_config.patch -Patch0172: qemu-options-Improve-readability-of-SMP-related-Docs.patch -Patch0173: hw-core-machine-Introduce-CPU-cluster-topology-suppo.patch -Patch0174: tests-unit-test-smp-parse-Add-testcases-for-CPU-clus.patch -Patch0175: tests-unit-test-smp-parse-No-need-to-explicitly-zero.patch -Patch0176: tests-unit-test-smp-parse-Keep-default-MIN-MAX-CPUs-.patch -Patch0177: hw-arm-virt-Support-CPU-cluster-on-ARM-virt-machine.patch -Patch0178: hw-arm-virt-Support-cluster-level-in-DT-cpu-map.patch -Patch0179: hw-acpi-aml-build-Improve-scalability-of-PPTT-genera.patch -Patch0180: tests-acpi-bios-tables-test-Allow-changes-to-virt-PP.patch -Patch0181: hw-acpi-aml-build-Support-cluster-level-in-PPTT-gene.patch -Patch0182: tests-acpi-bios-table-test-Update-expected-virt-PPTT.patch -Patch0183: softmmu-device_tree-Silence-compiler-warning-with-en.patch -Patch0184: softmmu-device_tree-Remove-redundant-pointer-assignm.patch -Patch0185: hw-arm64-add-vcpu-cache-info-support.patch -Patch0186: arm64-Add-the-cpufreq-device-to-show-cpufreq-info-to.patch -Patch0187: Revert-qmp-add-command-to-query-used-memslots-of-vho.patch -Patch0188: target-arm-Fix-some-compile-errors.patch -Patch0189: pl031-support-rtc-timer-property-for-pl031.patch -Patch0190: i386-cpu-fix-compile-error-in-all-target-configure.patch -Patch0191: acpi-madt-Factor-out-the-building-of-MADT-GICC-struc.patch -Patch0192: hw-arm-virt-Assign-virt_madt_cpu_entry-to-acpi_ged-m.patch -Patch0193: arm-virt-acpi-Factor-out-CPPC-building-from-DSDT-CPU.patch -Patch0194: acpi-cpu-Prepare-build_cpus_aml-for-arm-virt.patch -Patch0195: acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch -Patch0196: arm-cpu-assign-arm_get_arch_id-handler-to-get_arch_i.patch -Patch0197: tests-acpi-bios-tables-test-Allow-changes-to-virt-DS.patch -Patch0198: arm-virt-Attach-ACPI-CPU-hotplug-support-to-virt.patch -Patch0199: tests-acpi-bios-table-test-Update-expected-virt-DSDT.patch -Patch0200: arm-virt-Add-CPU-hotplug-framework.patch -Patch0201: arm-virt-Add-CPU-topology-support.patch -Patch0202: test-numa-Adjust-aarch64-numa-test.patch -Patch0203: hw-arm-virt-Factor-out-some-CPU-init-codes-to-pre_pl.patch -Patch0204: hw-arm-boot-Add-manually-register-and-trigger-of-CPU.patch -Patch0205: arm-virt-gic-Construct-irqs-connection-from-create_g.patch -Patch0206: intc-gicv3_common-Factor-out-arm_gicv3_common_cpu_re.patch -Patch0207: intc-gicv3_cpuif-Factor-out-gicv3_init_one_cpuif.patch -Patch0208: intc-kvm_gicv3-Factor-out-kvm_arm_gicv3_cpu_realize.patch -Patch0209: hw-intc-gicv3-Add-CPU-hotplug-realize-hook.patch -Patch0210: accel-kvm-Add-pre-park-vCPU-support.patch -Patch0211: intc-gicv3-Add-pre-sizing-capability-to-GICv3.patch -Patch0212: acpi-madt-Add-pre-sizing-capability-to-MADT-GICC-str.patch -Patch0213: arm-virt-Add-cpu_hotplug_enabled-field.patch -Patch0214: arm-virt-acpi-Extend-cpufreq-to-support-max_cpus.patch -Patch0215: arm-virt-Pre-sizing-MADT-GICC-GICv3-and-Pre-park-KVM.patch -Patch0216: arm-virt-Start-up-CPU-hot-plug-and-cold-plug.patch -Patch0217: pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch -Patch0218: qcow2-fix-memory-leak-in-qcow2_read_extensions.patch -Patch0219: scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch -Patch0220: pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch -Patch0221: pcie-Compat-with-devices-which-do-not-support-Link-W.patch -Patch0222: scsi-bus-fix-unmatched-object_unref.patch -Patch0223: tools-virtiofsd-Add-rseq-syscall-to-the-seccomp-allo.patch -Patch0224: sw_64-Add-sw64-architecture-support.patch -Patch0225: coro-support-live-patch-for-libcare.patch -Patch0226: qemu-img-create-cache-paramter-only-use-for-reg-file.patch -Patch0227: scsi-bus-fix-incorrect-call-for-blk_error_retry_rese.patch -Patch0228: Revert-monitor-limit-io-error-qmp-event-to-at-most-o.patch -Patch0229: vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch -Patch0230: virtio-net-fix-map-leaking-on-error-during-receive.patch -Patch0231: vfio-pci-Ascend710-change-to-bar2-quirk.patch -Patch0232: display-qxl-render-fix-race-condition-in-qxl_cursor-.patch -Patch0233: ui-cursor-fix-integer-overflow-in-cursor_alloc-CVE-2.patch -Patch0234: hw-intc-arm_gicv3-Check-for-MEMTX_OK-instead-of-MEMT.patch -Patch0235: softmmu-physmem-Simplify-flatview_write-and-address_.patch -Patch0236: softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch -Patch0237: acpi-modify-build_ppt-del-macro-add-arm-build_pptt.patch -Patch0238: acpi-fix-QEMU-crash-when-started-with-SLIC-table.patch -Patch0239: tests-acpi-whitelist-expected-blobs-before-changing-.patch -Patch0240: tests-acpi-add-SLIC-table-test.patch -Patch0241: tests-acpi-SLIC-update-expected-blobs.patch -Patch0242: hw-block-fdc-Prevent-end-of-track-overrun-CVE-2021-3.patch -Patch0243: tests-qtest-fdc-test-Add-a-regression-test-for-CVE-2.patch -Patch0244: hw-scsi-megasas-Use-uint32_t-for-reply-queue-head-ta.patch -Patch0245: dma-Let-dma_memory_valid-take-MemTxAttrs-argument.patch -Patch0246: dma-Let-dma_memory_set-take-MemTxAttrs-argument.patch -Patch0247: dma-Let-dma_memory_rw_relaxed-take-MemTxAttrs-argume.patch -Patch0248: dma-Let-dma_memory_rw-take-MemTxAttrs-argument.patch -Patch0249: dma-Let-dma_memory_read-write-take-MemTxAttrs-argume.patch -Patch0250: dma-Let-dma_memory_map-take-MemTxAttrs-argument.patch -Patch0251: dma-Have-dma_buf_rw-take-a-void-pointer.patch -Patch0252: dma-Have-dma_buf_read-dma_buf_write-take-a-void-poin.patch -Patch0253: pci-Let-pci_dma_rw-take-MemTxAttrs-argument.patch -Patch0254: dma-Let-dma_buf_rw-take-MemTxAttrs-argument.patch -Patch0255: dma-Let-dma_buf_write-take-MemTxAttrs-argument.patch -Patch0256: dma-Let-dma_buf_read-take-MemTxAttrs-argument.patch -Patch0257: dma-Let-dma_buf_rw-propagate-MemTxResult.patch -Patch0258: dma-Let-st-_dma-take-MemTxAttrs-argument.patch -Patch0259: dma-Let-ld-_dma-take-MemTxAttrs-argument.patch -Patch0260: dma-Let-st-_dma-propagate-MemTxResult.patch -Patch0261: dma-Let-ld-_dma-propagate-MemTxResult.patch -Patch0262: pci-Let-st-_pci_dma-take-MemTxAttrs-argument.patch -Patch0263: pci-Let-ld-_pci_dma-take-MemTxAttrs-argument.patch -Patch0264: pci-Let-st-_pci_dma-propagate-MemTxResult.patch -Patch0265: pci-Let-ld-_pci_dma-propagate-MemTxResult.patch -Patch0266: hw-audio-intel-hda-Do-not-ignore-DMA-overrun-errors.patch -Patch0267: hw-audio-intel-hda-Restrict-DMA-engine-to-memories-n.patch -Patch0268: tests-qtest-intel-hda-test-Add-reproducer-for-issue-.patch -Patch0269: hw-nvme-fix-CVE-2021-3929.patch -Patch0270: acpi-validate-hotplug-selector-on-access.patch -Patch0271: virtiofsd-Drop-membership-of-all-supplementary-group.patch -Patch0272: softmmu-Always-initialize-xlat-in-address_space_tran.patch -Patch0273: numa-Enable-numa-for-SGX-EPC-sections.patch -Patch0274: numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch -Patch0275: doc-Add-the-SGX-numa-description.patch -Patch0276: qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch -Patch0277: target-ppc-add-error-report-when-fopen-fails-in-kvmp.patch -Patch0278: target-ppc-enhance-error-report-in-kvmppc_read_int_c.patch -Patch0279: target-ppc-use-g_autofree-in-kvmppc_read_int_cpu_dt.patch -Patch0280: target-ppc-exit-1-on-failure-in-kvmppc_get_clockfreq.patch -Patch0281: bugfix-pointer-double-free-in-func-qemu_savevm_state.patch -Patch0282: vhost-user-remove-VirtQ-notifier-restore.patch -Patch0283: vhost-user-fix-VirtQ-notifier-cleanup.patch -Patch0284: nbd-allow-reconnect-on-open-with-corresponding-new-o.patch -Patch0285: block-nbd-Delete-reconnect-delay-timer-when-done.patch -Patch0286: block-nbd-Delete-open-timer-when-done.patch -Patch0287: block-nbd-Assert-there-are-no-timers-when-closed.patch -Patch0288: block-nbd-Move-s-ioc-on-AioContext-change.patch -Patch0289: hw-scsi-lsi53c895a-Do-not-abort-when-DMA-requested-a.patch -Patch0291: tests-qtest-Add-fuzz-lsi53c895a-test.patch -Patch0292: scsi-lsi53c895a-fix-use-after-free-in-lsi_do_msgout-.patch -Patch0293: scsi-lsi53c895a-really-fix-use-after-free-in-lsi_do_.patch -Patch0294: hw-usb-hcd-xhci-Fix-unbounded-loop-in-xhci_ring_chai.patch -Patch0295: net-tulip-Restrict-DMA-engine-to-memories.patch -Patch0296: exec-memory-Extract-address_space_set-from-dma_memor.patch -Patch0297: hw-elf_ops-clear-uninitialized-segment-space.patch -Patch0298: vhost-also-check-queue-state-in-the-vhost_dev_set_lo.patch -Patch0299: vhost-net-fix-improper-cleanup-in-vhost_net_start.patch -Patch0300: virtio-net-setup-vhost_dev-and-notifiers-for-cvq-onl.patch -Patch0301: job.c-add-missing-notifier-initialization.patch -Patch0302: uas-add-missing-return.patch -Patch0303: qom-assert-integer-does-not-overflow.patch -Patch0304: pci-expose-TYPE_XIO3130_DOWNSTREAM-name.patch -Patch0305: acpi-pcihp-pcie-set-power-on-cap-on-parent-slot.patch -Patch0306: hw-display-ati_2d-Fix-buffer-overflow-in-ati_2d_blt-.patch -Patch0307: ui-vnc-clipboard-fix-integer-underflow-in-vnc_client.patch -Patch0308: Remove-the-unused-local-variable-records.patch -Patch0309: Remove-this-redundant-return.patch -Patch0310: hw-vhost-user-blk-turn-on-VIRTIO_BLK_F_SIZE_MAX-feat.patch -Patch0311: migration-dirtyrate-Replace-malloc-with-g_new.patch -Patch0312: accel-kvm-kvm-all-Refactor-per-vcpu-dirty-ring-reapi.patch -Patch0313: cpus-Introduce-cpu_list_generation_id.patch -Patch0314: migration-dirtyrate-Refactor-dirty-page-rate-calcula.patch -Patch0315: softmmu-dirtylimit-Implement-vCPU-dirtyrate-calculat.patch -Patch0316: accel-kvm-kvm-all-Introduce-kvm_dirty_ring_size-func.patch -Patch0317: softmmu-dirtylimit-Implement-virtual-CPU-throttle.patch -Patch0318: softmmu-dirtylimit-Implement-dirty-page-rate-limit.patch -Patch0319: tests-Add-dirty-page-rate-limit-test.patch -Patch0320: linux-headers-include-missing-changes-from-5.17.patch -Patch0321: x86-Fix-the-64-byte-boundary-enumeration-for-extende.patch -Patch0322: x86-Add-AMX-XTILECFG-and-XTILEDATA-components.patch -Patch0323: x86-Grant-AMX-permission-for-guest.patch -Patch0324: x86-Add-XFD-faulting-bit-for-state-components.patch -Patch0325: x86-Add-AMX-CPUIDs-enumeration.patch -Patch0326: x86-add-support-for-KVM_CAP_XSAVE2-and-AMX-state-mig.patch -Patch0327: x86-Support-XFD-and-AMX-xsave-data-migration.patch -Patch0328: target-i386-kvm-do-not-access-uninitialized-variable.patch -Patch0329: KVM-x86-workaround-invalid-CPUID-0xD-9-info-on-some-.patch -Patch0330: fix-compilation-errors-of-sw64-architecture-on-x86-p.patch -Patch0331: fixed-the-error-that-no-bios-file-soft-link-was-crea.patch -Patch0332: arm-virt-Fix-vcpu-hotplug-idx_from_topo_ids.patch -Patch0333: vfio-migration-Fix-incorrect-initialization-value-fo.patch -Patch0334: hostmem-default-the-amount-of-prealloc-threads-to-sm.patch -Patch0335: Revert-vfio-common-Add-address-alignment-check-in-vf.patch -Patch0336: Revert-vfio-common-Fix-incorrect-address-alignment-i.patch -Patch0337: Revert-hw-arm-smmuv3-Post-load-stage-1-configuration.patch -Patch0338: Revert-vfio-Add-vfio_prereg_listener_global_log_star.patch -Patch0339: Revert-vfio-Add-vfio_prereg_listener_log_clear-to-re.patch -Patch0340: Revert-vfio-Add-vfio_prereg_listener_log_sync-in-nes.patch -Patch0341: Revert-vfio-Introduce-helpers-to-mark-dirty-pages-of.patch -Patch0342: Revert-vfio-common-Avoid-unmap-ram-section-at-vfio_l.patch -Patch0343: Revert-vfio-pci-Implement-return_page_response-page-.patch -Patch0344: Revert-pci-Add-return_page_response-pci-ops.patch -Patch0345: Revert-hw-arm-smmuv3-Allow-MAP-notifiers.patch -Patch0346: Revert-hw-arm-smmuv3-Implement-fault-injection.patch -Patch0347: Revert-hw-arm-smmuv3-Pass-stage-1-configurations-to-.patch -Patch0348: Revert-hw-arm-smmuv3-Fill-the-IOTLBEntry-leaf-field-.patch -Patch0349: Revert-hw-arm-smmuv3-Fill-the-IOTLBEntry-arch_id-on-.patch -Patch0350: Revert-hw-arm-smmuv3-Store-the-PASID-table-GPA-in-th.patch -Patch0351: Revert-hw-arm-smmuv3-Advertise-MSI_TRANSLATE-attribu.patch -Patch0352: Revert-vfio-pci-Implement-the-DMA-fault-handler.patch -Patch0353: Revert-vfio-pci-Set-up-the-DMA-FAULT-region.patch -Patch0354: Revert-vfio-pci-Register-handler-for-iommu-fault.patch -Patch0355: Revert-vfio-Helper-to-get-IRQ-info-including-capabil.patch -Patch0356: Revert-vfio-Pass-stage-1-MSI-bindings-to-the-host.patch -Patch0357: Revert-vfio-Set-up-nested-stage-mappings.patch -Patch0359: Revert-vfio-Introduce-helpers-to-DMA-map-unmap-a-RAM.patch -Patch0360: Revert-vfio-Introduce-hostwin_from_range-helper.patch -Patch0361: Revert-vfio-Force-nested-if-iommu-requires-it.patch -Patch0362: Revert-pci-introduce-PCIPASIDOps-to-PCIDevice.patch -Patch0363: Revert-iommu-Introduce-generic-header.patch -Patch0364: Revert-memory-Introduce-IOMMU-Memory-Region-inject_f.patch -Patch0365: Revert-memory-Add-IOMMU_ATTR_MSI_TRANSLATE-IOMMU-mem.patch -Patch0366: Revert-memory-Add-IOMMU_ATTR_VFIO_NESTED-IOMMU-memor.patch -Patch0367: Revert-hw-arm-smmu-common-Allow-domain-invalidation-.patch -Patch0368: Revert-hw-arm-smmuv3-Improve-stage1-ASID-invalidatio.patch -Patch0369: Revert-memory-Add-new-fields-in-IOTLBEntry.patch -Patch0370: Revert-vfio.h-and-iommu.h-header-update-against-5.10.patch -Patch0371: Revert-update-linux-headers-Import-iommu.h.patch -Patch0372: memory-Fix-wrong-end-address-dump.patch -Patch0373: tests-vm-use-o-IdentitiesOnly-yes-for-ssh.patch -Patch0374: linux-user-always-translate-cmsg-when-recvmsg.patch -Patch0375: target-arm-Copy-the-entire-vector-in-DO_ZIP.patch -Patch0376: hw-mem-nvdimm-fix-error-message-for-unarmed-flag.patch -Patch0377: gdb-xml-Fix-size-of-EFER-register-on-i386-architectu.patch -Patch0378: tcg-tci-fix-logic-error-when-registering-helpers-via.patch -Patch0379: virtio-mem-Don-t-skip-alignment-checks-when-warning-.patch -Patch0380: qemu-binfmt-conf.sh-fix-F-option.patch -Patch0381: Fix-several-typos-in-documentation-found-by-codespel.patch -Patch0382: hw-arm-virt-Fix-devicetree-warnings-about-the-virtio.patch -Patch0383: target-hppa-Fix-deposit-assert-from-trans_shrpw_imm.patch -Patch0384: tcg-optimize-Fix-folding-of-vector-ops.patch -Patch0385: target-arm-Add-missing-FEAT_TLBIOS-instructions.patch -Patch0386: target-riscv-pmp-fix-no-pmp-illegal-intrs.patch -Patch0387: configure-Remove-unused-python_version-variable.patch -Patch0388: configure-Remove-unused-meson_args-variable.patch -Patch0389: target-imx-reload-cmp-timer-outside-of-the-reload-pt.patch -Patch0390: configure-Add-missing-quoting-for-some-easy-cases.patch -Patch0391: hw-core-resettable-fix-reset-level-counting.patch -Patch0392: hw-usb-hcd-xhci-Reset-the-XHCIState-with-device_cold.patch -Patch0393: hw-ppc-spapr_pci.c-Use-device_cold_reset-rather-than.patch -Patch0394: hw-ide-microdrive-Use-device_cold_reset-for-self-res.patch -Patch0395: hw-i386-Use-device_cold_reset-to-reset-the-APIC.patch -Patch0396: hw-hyperv-hyperv.c-Use-device_cold_reset-instead-of-.patch -Patch0397: configure-Add-.-on-front-of-glob-of-config-devices.m.patch -Patch0398: configure-Check-mkdir-result-directly-not-via.patch -Patch0399: hw-char-pl011-fix-baud-rate-calculation.patch -Patch0400: target-i386-kvm-fix-kvmclock_current_nsec-Assertion-.patch -Patch0401: linux-headers-Update-headers-to-Linux-5.18-rc6.patch -Patch0402: virtio-get-class_id-and-pci-device-id-by-the-virtio-.patch -Patch0403: vdpa-add-vdpa-dev-support.patch -Patch0404: vdpa-add-vdpa-dev-pci-support.patch -Patch0405: vdpa-dev-mark-the-device-as-unmigratable.patch -Patch0406: docs-Add-generic-vhost-vdpa-device-documentation.patch -Patch0407: vhost-vdpa-add-memslot-getter-setter-for-vhost-vdpa.patch -Patch0408: chardev-fix-segfault-in-finalize.patch -Patch0409: tests-avocado-raspi2_initrd-Wait-for-guest-shutdown-.patch -Patch0410: Add-flex-bison-to-debian-hexagon-cross.patch -Patch0411: hw-net-can-fix-Xilinx-ZynqMP-CAN-RX-FIFO-logic.patch -Patch0412: libdecnumber-dpd-decimal64-Fix-compiler-warning-from.patch -Patch0413: Fix-several-typos-in-documentation.patch -Patch0414: tests-avocado-use-new-rootfs-for-orangepi-test.patch -Patch0415: replay-Fix-declaration-of-replay_read_next_clock.patch -Patch0416: vhost-user-Refactor-vhost-acked-features-saving.patch -Patch0417: vhost-user-Refactor-the-chr_closed_bh.patch -Patch0418: vhost-user-Fix-the-virtio-features-negotiation-flaw.patch -Patch0419: tests-qtest-libqos-e1000e-Refer-common-PCI-ID-defini.patch -Patch0420: hw-display-qxl-Have-qxl_log_command-Return-early-if-.patch -Patch0421: hw-display-qxl-Document-qxl_phys2virt.patch -Patch0422: hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch -Patch0423: hw-display-qxl-Avoid-buffer-overrun-in-qxl_phys2virt.patch -Patch0424: hw-display-qxl-Assert-memory-slot-fits-in-preallocat.patch -Patch0425: target-arm-Use-kvm_arm_sve_supported-in-kvm_arm_get_.patch -Patch0426: target-arm-Set-KVM_ARM_VCPU_SVE-while-probing-the-ho.patch -Patch0427: target-arm-Move-sve-probe-inside-kvm-4.15-branch.patch -Patch0428: migration-report-migration-related-thread-pid-to-lib.patch -Patch0429: migration-report-multiFd-related-thread-pid-to-libvi.patch -Patch0430: vhost_net-keep-acked_feature-only-for-NET_CLIENT_DRI.patch -Patch0431: linux-user-Add-strace-output-for-timer_settime64-sys.patch -Patch0432: fix-qemu-core-when-vhost-user-net-config-with-server.patch -Patch0433: fix-qmp-command-migrate-set-parameters.patch -Patch0434: hw-acpi-Add-ospm_status-hook-implementation-for-acpi.patch -Patch0435: hw-acpi-Support-acpi-ged-to-report-CPU-s-OST-info.patch -Patch0436: arm-virt-Correct-timing-of-executing-cpu_synchronize.patch -Patch0437: arm-virt-Correct-timing-of-pause-all-vcpus-for-hot-p.patch -Patch0438: hw-core-machine-Fix-the-missing-consideration-of-clu.patch -Patch0439: tests-tcg-Fix-target-specific-Makefile-variables-pat.patch -Patch0440: tests-add-riscv-virt-machine-mapping-to-testenv.patch -Patch0441: curl-Fix-error-path-in-curl_open.patch -Patch0442: hw-riscv-virt-Simplify-virt_-get-set-_aclint.patch -Patch0443: hw-pci-Fix-a-typo.patch -Patch0444: hw-pci-Trace-IRQ-routing-on-PCI-topology.patch -Patch0445: Add-PowerManager-support.patch -Patch0446: Add-RTC-support.patch -Patch0447: Add-loongarch-machine.patch -Patch0448: Add-target-loongarch64.patch -Patch0449: Add-linux-headers-and-linux-user.patch -Patch0450: Add-disas-gdb.patch -Patch0451: Add-command-line.patch -Patch0452: Add-tcg.patch -Patch0453: Add-bios.patch -Patch0454: Add-compile-script.patch -Patch0455: hw-pvrdma-Protect-against-buggy-or-malicious-guest-d.patch -Patch0456: hw-audio-intel-hda-fix-stream-reset.patch -Patch0457: dsoundaudio-fix-crackling-audio-recordings.patch -Patch0458: linux-headers-include-missing-changes-from-6.0.patch -Patch0459: i386-kvm-extend-kvm_-get-put-_vcpu_events-to-support.patch -Patch0460: kvm-allow-target-specific-accelerator-properties.patch -Patch0461: kvm-expose-struct-KVMState.patch -Patch0462: i386-add-notify-VM-exit-support.patch -Patch0463: block-backend-prevent-dangling-BDS-pointers-across-a.patch -Patch0464: net-Fix-uninitialized-data-usage.patch -Patch0465: net-eth-Don-t-consider-ESP-to-be-an-IPv6-option-head.patch -Patch0466: hw-net-vmxnet3-Log-guest-triggerable-errors-using-LO.patch -Patch0467: fixup-compile-on-loongarch64-machine.patch -Patch0468: vhost-user-blk-fix-the-resize-crash.patch -Patch0469: plugins-make-qemu_plugin_user_exit-s-locking-order-c.patch -Patch0470: linux-user-fix-strace-build-w-out-munlockall.patch -Patch0471: ui-fix-crash-on-serial-reset-during-init.patch -Patch0472: qga-win-vss-requester_freeze-changes.patch -Patch0473: migration-fix-populate_vfio_info.patch -Patch0474: block-rbd-workaround-for-ceph-issue-53784.patch -Patch0475: target-i386-add-FZRM-FSRS-FSRC.patch -Patch0476: i386-Add-new-CPU-model-SapphireRapids.patch -Patch0477: core-cpu-common-Fix-the-wrong-ifdef-__aarch64__.patch -Patch0478: target-i386-Fix-sanity-check-on-max-APIC-ID-X2APIC-e.patch -Patch0479: target-i386-Set-maximum-APIC-ID-to-KVM-prior-to-vCPU.patch -Patch0480: hw-usb-imx-Fix-out-of-bounds-access-in-imx_usbphy_re.patch -Patch0481: target-i386-Add-SGX-aex-notify-and-EDECCSSA-support.patch -Patch0482: aio-posix-fix-race-between-epoll-upgrade-and-aio_set.patch -Patch0483: hw-nvme-fix-memory-leak-in-nvme_dsm.patch -Patch0484: target-i386-add-FSRM-to-TCG.patch -Patch0485: target-i386-KVM-allow-fast-string-operations-if-host.patch -Patch0486: configure-meson-move-AVX-tests-to-meson.patch -Patch0487: AVX512-support-for-xbzrle_encode_buffer.patch -Patch0488: Update-bench-code-for-addressing-CI-problem.patch -Patch0489: migration-xbzrle-use-ctz64-to-avoid-undefined-result.patch -Patch0490: migration-xbzrle-fix-out-of-bounds-write-with-axv512.patch -Patch0491: hw-nvme-fix-missing-DNR-on-compare-failure.patch -Patch0492: virtio-fix-reachable-assertion-due-to-stale-value-of.patch -Patch0493: hw-nvme-Change-alignment-in-dma-functions-for-nvme_b.patch -Patch0494: Fix-smp.cores-value-and-Fix-divide-0-error.patch -Patch0495: Add-lbt-support-for-kvm.patch -Patch0496: migration-report-compress-thread-pid-to-libvirt.patch -Patch0497: hw-ppc-Kconfig-MAC_NEWWORLD-should-always-select-USB.patch -Patch0498: virtio-gpu-add-a-FIXME-for-virtio_gpu_load.patch -Patch0499: block-monitor-Fix-crash-when-executing-HMP-commit.patch -Patch0500: vnc-avoid-underflow-when-accessing-user-provided-add.patch -Patch0501: qga-vss-win32-fix-warning-for-clang-15.patch -Patch0502: hw-net-vmxnet3-allow-VMXNET3_MAX_MTU-itself-as-a-val.patch -Patch0503: tests-tcg-fix-unused-variable-in-linux-test.patch -Patch0504: block-iscsi-fix-double-free-on-BUSY-or-similar-statu.patch -Patch0505: vfio-pci-Fix-a-segfault-in-vfio_realize.patch -Patch0506: gitlab-Disable-plugins-for-cross-i386-tci.patch -Patch0507: tcg-Reduce-tcg_assert_listed_vecop-scope.patch -Patch0508: 9pfs-prevent-opening-special-files-CVE-2023-2861.patch -Patch0509: accel-tcg-Optimize-jump-cache-flush-during-tlb-range.patch -Patch0510: hw-net-virtio-net-make-some-VirtIONet-const.patch -Patch0511: Allow-setting-up-to-8-bytes-with-the-generic-loader.patch -Patch0512: accel-tcg-cpu-exec-Fix-precise-single-stepping-after.patch -Patch0513: hw-virtio-vdpa-Fix-leak-of-host-notifier-memory-regi.patch -Patch0514: host-vdpa-make-notifiers-_init-_uninit-symmetric.patch -Patch0515: hw-pci-bridge-pxb-Fix-missing-swizzle.patch -Patch0516: ide-Increment-BB-in-flight-counter-for-TRIM-BH.patch -Patch0517: qga-win32-Remove-change-action-from-MSI-installer.patch -Patch0518: qga-win32-Use-rundll-for-VSS-installation.patch -Patch0519: test-vmstate-fix-bad-GTree-usage-use-after-free.patch -Patch0520: Check-and-report-for-incomplete-global-option-format.patch -Patch0521: migration-ram-Fix-populate_read_range.patch -Patch0522: vfio-Fix-vfio_get_dev_region-trace-event.patch -Patch0523: disas-riscv-Fix-ctzw-disassemble.patch -Patch0524: qapi-block-Tidy-up-block-latency-histogram-set-docum.patch -Patch0525: chardev-char-socket-set-s-listener-NULL-in-char_sock.patch -Patch0526: QGA-VSS-Add-wrapper-to-send-log-to-debugger-and-stde.patch -Patch0527: xen-block-Avoid-leaks-on-new-error-path.patch -Patch0528: docs-about-build-platforms-Refine-the-distro-support.patch -Patch0529: migration-ram-Fix-error-handling-in-ram_write_tracki.patch -Patch0530: hw-xen-xen_pt-fix-uninitialized-variable.patch -Patch0531: qapi-qdev-Tidy-up-device_add-documentation.patch -Patch0532: block-nfs-Fix-32-bit-Windows-build.patch -Patch0533: block-nbd.c-Fixed-IO-request-coroutine-not-being-wak.patch -Patch0534: block-rbd-fix-write-zeroes-with-growing-images.patch -Patch0535: block-Fix-misleading-hexadecimal-format.patch -Patch0536: qapi-support-updating-expected-test-output-via-make.patch -Patch0537: tests-vhost-user-test-release-mutex-on-protocol-viol.patch -Patch0538: qga-Fix-suspend-on-Linux-guests-without-systemd.patch -Patch0539: vhost-vdpa-do-not-cleanup-the-vdpa-vhost-net-structu.patch -Patch0540: virtio-crypto-verify-src-dst-buffer-length-for-sym-r.patch -Patch0541: sw_64-Added-sw64-architecture-related-updates.patch -Patch0542: aio-posix-fix-build-failure-io_uring-2.2.patch -Patch0543: test-Fix-test-crypto-secret-when-compiling-without-k.patch -Patch0544: accel-kvm-Free-as-when-an-error-occurred.patch -Patch0545: accel-kvm-Make-kvm_dirty_ring_reaper_init-void.patch -Patch0546: vhost-user-Use-correct-macro-name-TARGET_PPC64.patch -Patch0547: hw-rx-rx-gdbsim-DTB-load-address-aligned-of-16byte.patch -Patch0548: hw-arm-virt-Check-for-attempt-to-use-TrustZone-with-.patch -Patch0549: virtio-iommu-use-after-free-fix.patch -Patch0550: vhost-Drop-unused-eventfd_add-del-hooks.patch -Patch0551: chardev-report-the-handshake-error.patch -Patch0552: hw-ssi-Fix-Linux-driver-init-issue-with-xilinx_spi.patch -Patch0553: io-remove-io-watch-if-TLS-channel-is-closed-during-h.patch -Patch0554: hw-char-fix-qcode-array-bounds-check-in-ESCC-impl.patch -Patch0555: tulip-Assign-default-MAC-address-if-not-specified.patch -Patch0556: target-ppc-Fix-the-order-of-kvm_enable-judgment-abou.patch -Patch0557: tests-qtest-pflash-Clean-up-local-variable-shadowing.patch -Patch0558: ui-fix-crash-when-there-are-no-active_console.patch -Patch0559: ppc-vof-Fix-missed-fields-in-VOF-cleanup.patch -Patch0560: hw-nvme-Avoid-dynamic-stack-allocation.patch -Patch0561: aio-posix-zero-out-io_uring-sqe-user_data.patch -Patch0562: qtest-npcm7xx_pwm-test-Fix-memory-leak-in-mft_qom_se.patch -Patch0563: target-i386-fix-INVD-vmexit.patch -Patch0564: target-ppc-Fix-tlbie.patch -Patch0565: hw-net-Fix-read-of-uninitialized-memory-in-ftgmac100.patch -Patch0566: replay-fix-event-queue-flush-for-qemu-shutdown.patch -Patch0567: hw-vfio-pci-quirks-Support-alternate-offset-for-GPUD.patch -Patch0568: hw-vfio-pci-quirks-Sanitize-capability-pointer.patch -Patch0569: vhost-user-fs-Back-up-vqs-before-cleaning-up-vhost_d.patch -Patch0570: migration-rdma-zore-out-head.repeat-to-make-the-erro.patch -Patch0571: thread-pool-optimize-scheduling-of-completion-bottom.patch -Patch0572: hw-arm-xlnx-zynqmp-fix-unsigned-error-when-checking-.patch -Patch0573: hw-i2c-pmbus_device-Fix-modifying-QOM-class-internal.patch -Patch0574: crypto-remove-shadowed-ret-variable.patch -Patch0575: target-i386-add-support-for-FLUSH_L1D-feature.patch -Patch0576: target-i386-add-support-for-FB_CLEAR-feature.patch -Patch0577: target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch -Patch0578: target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch -Patch0579: target-i386-Allow-MCDT_NO-if-host-supports.patch -Patch0580: target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch -Patch0581: target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch -Patch0582: ui-vnc-clipboard-fix-infinite-loop-in-inflate_buffer.patch -Patch0583: qga-Fix-memory-leak-when-output-stream-is-unused.patch -Patch0584: disas-riscv-Fix-the-typo-of-inverted-order-of-pmpadd.patch -Patch0585: softmmu-dirtylimit-Add-parameter-check-for-hmp-set_v.patch -Patch0586: tests-Fix-printf-format-string-in-acpi-utils.c.patch -Patch0587: hw-virtio-virtio-pmem-Replace-impossible-check-by-as.patch -Patch0588: target-i386-Export-GDS_NO-bit-to-guests.patch -Patch0589: semihosting-fix-memleak-at-semihosting_arg_fallback.patch -Patch0590: semihosting-config-Merge-semihosting-config-option-g.patch -Patch0591: qemu-timer-Skip-empty-timer-lists-before-locking-in-.patch -Patch0592: hw-usb-hcd-ehci-fix-writeback-order.patch -Patch0593: pci-fix-overflow-in-snprintf-string-formatting.patch -Patch0594: tpm_crb-mark-command-buffer-as-dirty-on-request-comp.patch -Patch0595: hw-timer-npcm7xx_timer-Prevent-timer-from-counting-d.patch -Patch0596: pci-Fix-the-update-of-interrupt-disable-bit-in-PCI_C.patch -Patch0597: virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch -Patch0598: virtio-pci-decouple-notifier-from-interrupt-process.patch -Patch0599: virtio-pci-decouple-the-single-vector-from-the-inter.patch -Patch0600: vhost-vdpa-add-support-for-config-interrupt.patch -Patch0601: virtio-add-support-for-configure-interrupt.patch -Patch0602: vhost-add-support-for-configure-interrupt.patch -Patch0603: virtio-net-add-support-for-configure-interrupt.patch -Patch0604: virtio-mmio-add-support-for-configure-interrupt.patch -Patch0605: virtio-pci-add-support-for-configure-interrupt.patch -Patch0606: vhost-vdpa-stick-to-errno-error-return-convention.patch -Patch0607: vhost-user-stick-to-errno-error-return-convention.patch -Patch0608: vhost-stick-to-errno-error-return-convention.patch -Patch0609: vhost-introduce-new-VhostOps-vhost_set_config_call.patch -Patch0610: e1000-set-RX-descriptor-status-in-a-separate-operati.patch -Patch0611: virtio-iommu-Fix-the-partial-copy-of-probe-request.patch -Patch0612: artist-set-memory-region-owners-for-buffers-to-the-a.patch -Patch0613: qom-object-Remove-circular-include-dependency.patch -Patch0614: vga-avoid-crash-if-no-default-vga-card.patch -Patch0615: hw-pvrdma-Protect-against-buggy-or-malicious-guest-driver.patch -Patch0616: tracetool-avoid-invalid-escape-in-Python-string.patch -Patch0617: target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch -Patch0618: target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch -Patch0619: target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch -Patch0620: target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch -Patch0621: target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch -Patch0622: target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch -Patch0623: target-i386-Add-new-CPU-model-GraniteRapids.patch -Patch0624: target-i386-Adjust-feature-level-according-to-FEAT_7.patch -Patch0625: virtio-signal-after-wrapping-packed-used_idx.patch -Patch0626: Revert-vhost-introduce-new-VhostOps-vhost_set_config.patch -Patch0627: Revert-virtio-pci-add-support-for-configure-interrup.patch -Patch0628: Revert-virtio-mmio-add-support-for-configure-interru.patch -Patch0629: Revert-virtio-net-add-support-for-configure-interrup.patch -Patch0630: Revert-vhost-add-support-for-configure-interrupt.patch -Patch0631: Revert-virtio-add-support-for-configure-interrupt.patch -Patch0632: Revert-vhost-vdpa-add-support-for-config-interrupt.patch -Patch0633: Revert-virtio-pci-decouple-the-single-vector-from-th.patch -Patch0634: Revert-virtio-pci-decouple-notifier-from-interrupt-p.patch -Patch0635: Revert-virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch -Patch0636: vdpa-Make-ncs-autofree.patch -Patch0637: vhost-Add-VhostShadowVirtqueue.patch -Patch0638: vhost-Add-Shadow-VirtQueue-kick-forwarding-capabilit.patch -Patch0639: vhost-Add-Shadow-VirtQueue-call-forwarding-capabilit.patch -Patch0640: vhost-Add-vhost_svq_valid_features-to-shadow-vq.patch -Patch0641: virtio-Add-vhost_svq_get_vring_addr.patch -Patch0642: vdpa-adapt-vhost_ops-callbacks-to-svq.patch -Patch0643: vhost-Shadow-virtqueue-buffers-forwarding.patch -Patch0644: util-Add-iova_tree_alloc_map.patch -Patch0645: util-add-iova_tree_find_iova.patch -Patch0646: vhost-Add-VhostIOVATree.patch -Patch0647: vdpa-Add-custom-IOTLB-translations-to-SVQ.patch -Patch0648: vdpa-Adapt-vhost_vdpa_get_vring_base-to-SVQ.patch -Patch0649: vdpa-Never-set-log_base-addr-if-SVQ-is-enabled.patch -Patch0650: vdpa-Expose-VHOST_F_LOG_ALL-on-SVQ.patch -Patch0651: virtio-fix-enable-vhost-user-build-on-non-Linux.patch -Patch0652: vhost-vdpa-fix-typo-in-a-comment.patch -Patch0653: vdpa-Add-missing-tracing-to-batch-mapping-functions.patch -Patch0654: vhost-Track-descriptor-chain-in-private-at-SVQ.patch -Patch0655: vhost-Fix-device-s-used-descriptor-dequeue.patch -Patch0656: vdpa-Fix-bad-index-calculus-at-vhost_vdpa_get_vring_.patch -Patch0657: vdpa-Fix-index-calculus-at-vhost_vdpa_svqs_start.patch -Patch0658: vhost-Fix-element-in-vhost_svq_add-failure.patch -Patch0659: hw-virtio-add-vhost_user_-read-write-trace-points.patch -Patch0660: include-hw-start-documenting-the-vhost-API.patch -Patch0661: virtio-add-vhost-support-for-virtio-devices.patch -Patch0662: virtio-net-align-ctrl_vq-index-for-non-mq-guest-for-.patch -Patch0663: vhost-vdpa-fix-improper-cleanup-in-net_init_vhost_vd.patch -Patch0664: vhost-vdpa-backend-feature-should-set-only-once.patch -Patch0665: vhost-vdpa-change-name-and-polarity-for-vhost_vdpa_o.patch -Patch0666: virtio-net-don-t-handle-mq-request-in-userspace-hand.patch -Patch0667: util-Return-void-on-iova_tree_remove.patch -Patch0668: vhost-move-descriptor-translation-to-vhost_svq_vring.patch -Patch0669: virtio-net-Expose-MAC_TABLE_ENTRIES.patch -Patch0670: virtio-net-Expose-ctrl-virtqueue-logic.patch -Patch0671: vdpa-Avoid-compiler-to-squash-reads-to-used-idx.patch -Patch0672: vhost-Reorder-vhost_svq_kick.patch -Patch0673: vhost-Move-vhost_svq_kick-call-to-vhost_svq_add.patch -Patch0674: vhost-Check-for-queue-full-at-vhost_svq_add.patch -Patch0675: vhost-Decouple-vhost_svq_add-from-VirtQueueElement.patch -Patch0676: vhost-Add-SVQDescState.patch -Patch0677: vhost-Track-number-of-descs-in-SVQDescState.patch -Patch0678: vhost-add-vhost_svq_push_elem.patch -Patch0679: vhost-Expose-vhost_svq_add.patch -Patch0680: vhost-add-vhost_svq_poll.patch -Patch0681: vhost-Add-svq-avail_handler-callback.patch -Patch0682: vdpa-Export-vhost_vdpa_dma_map-and-unmap-calls.patch -Patch0683: vdpa-manual-forward-CVQ-buffers.patch -Patch0684: vdpa-Buffer-CVQ-support-on-shadow-virtqueue.patch -Patch0685: vdpa-Extract-get-features-part-from-vhost_vdpa_get_m.patch -Patch0686: vdpa-Add-device-migration-blocker.patch -Patch0687: vdpa-Add-x-svq-to-NetdevVhostVDPAOptions.patch -Patch0688: vhost-Get-vring-base-from-vq-not-svq.patch -Patch0689: vdpa-Fix-memory-listener-deletions-of-iova-tree.patch -Patch0690: vdpa-Fix-file-descriptor-leak-on-get-features-error.patch -Patch0691: vdpa-Skip-the-maps-not-in-the-iova-tree.patch -Patch0692: vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch -Patch0693: util-accept-iova_tree_remove_parameter-by-value.patch -Patch0694: vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch -Patch0695: vdpa-Make-SVQ-vring-unmapping-return-void.patch -Patch0696: vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch -Patch0697: vhost_net-Add-NetClientInfo-start-callback.patch -Patch0698: vhost_net-Add-NetClientInfo-stop-callback.patch -Patch0699: vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch -Patch0700: vdpa-Move-command-buffers-map-to-start-of-net-device.patch -Patch0701: vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch -Patch0702: vhost_net-add-NetClientState-load-callback.patch -Patch0703: vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch -Patch0704: vdpa-Delete-CVQ-migration-blocker.patch -Patch0705: vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch -Patch0706: vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch -Patch0707: vdpa-Add-vhost_vdpa_net_load_mq.patch -Patch0708: vdpa-validate-MQ-CVQ-commands.patch -Patch0709: virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch -Patch0710: vdpa-Allow-MQ-feature-in-SVQ.patch -Patch0711: hw-virtio-add-some-vhost-user-trace-events.patch -Patch0712: vdpa-Delete-duplicated-vdpa_feature_bits-entry.patch -Patch0713: vdpa-Remove-shadow-CVQ-command-check.patch -Patch0714: vhost-vdpa-allow-passing-opened-vhostfd-to-vhost-vdp.patch -Patch0715: net-vhost-vdpa.c-Fix-clang-compilation-failure.patch -Patch0716: vhost-vdpa-fix-assert-virtio_net_get_subqueue-nc-asy.patch -Patch0717: vhost-enable-vrings-in-vhost_dev_start-for-vhost-use.patch -Patch0718: vdpa-use-v-shadow_vqs_enabled-in-vhost_vdpa_svqs_sta.patch -Patch0719: vhost-set-SVQ-device-call-handler-at-SVQ-start.patch -Patch0720: vhost-allocate-SVQ-device-file-descriptors-at-device.patch -Patch0721: vdpa-add-vhost_vdpa_net_valid_svq_features.patch -Patch0722: vdpa-request-iova_range-only-once.patch -Patch0723: vdpa-move-SVQ-vring-features-check-to-net.patch -Patch0724: vdpa-allocate-SVQ-array-unconditionally.patch -Patch0725: vdpa-add-asid-parameter-to-vhost_vdpa_dma_map-unmap.patch -Patch0726: vdpa-store-x-svq-parameter-in-VhostVDPAState.patch -Patch0727: vdpa-add-shadow_data-to-vhost_vdpa.patch -Patch0728: vdpa-always-start-CVQ-in-SVQ-mode-if-possible.patch -Patch0729: hw-virtio-vhost-Fix-typo-in-comment.patch -Patch0730: hw-virtio-gracefully-handle-unset-vhost_dev-vdev.patch -Patch0731: vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch -Patch0732: vdpa-handle-VIRTIO_NET_CTRL_ANNOUNCE-in-vhost_vdpa_n.patch -Patch0733: vdpa-do-not-handle-VIRTIO_NET_F_GUEST_ANNOUNCE-in-vh.patch -Patch0734: virtio-introduce-macro-VIRTIO_CONFIG_IRQ_IDX.patch -Patch0735: virtio-pci-decouple-notifier-from-interrupt-process-new.patch -Patch0736: virtio-pci-decouple-the-single-vector-from-the-inter-new.patch -Patch0737: vhost-introduce-new-VhostOps-vhost_set_config_call-new.patch -Patch0738: vhost-vdpa-add-support-for-config-interrupt-new.patch -Patch0739: virtio-add-support-for-configure-interrupt-new.patch -Patch0740: vhost-add-support-for-configure-interrupt-new.patch -Patch0741: virtio-net-add-support-for-configure-interrupt-new.patch -Patch0742: virtio-mmio-add-support-for-configure-interrupt-new.patch -Patch0743: virtio-pci-add-support-for-configure-interrupt-new.patch -Patch0744: vdpa-dev-get-iova-range-explicitly.patch -Patch0745: vdpa-harden-the-error-path-if-get_iova_range-failed.patch -Patch0746: vdpa-commit-all-host-notifier-MRs-in-a-single-MR-tra.patch -Patch0747: virtio-crypto-verify-src-dst-buffer-length-for-sym-request.patch -Patch0748: vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch -Patch0749: vhost-move-iova_tree-set-to-vhost_svq_start.patch -Patch0750: vhost-fix-possible-wrap-in-SVQ-descriptor-ring.patch -Patch0751: vhost-Fix-false-positive-out-of-bounds.patch -Patch0752: hw-virtio-fix-vhost_user_read-tracepoint.patch -Patch0753: vdpa-Fix-possible-use-after-free-for-VirtQueueElemen.patch -Patch0754: vdpa-fix-not-using-CVQ-buffer-in-case-of-error.patch -Patch0755: vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_.patch -Patch0756: vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_-new.patch -Patch0757: vdpa-net-block-migration-if-the-device-has-CVQ.patch -Patch0758: vdpa-do-not-block-migration-if-device-has-cvq-and-x-.patch -Patch0759: vdpa-fix-VHOST_BACKEND_F_IOTLB_ASID-flag-check.patch -Patch0760: virtio-net-clear-guest_announce-feature-if-no-cvq-ba.patch -Patch0761: hw-virtio-fix-typo-in-VIRTIO_CONFIG_IRQ_IDX-comments.patch -Patch0762: virtio-i2c-Check-notifier-helpers-for-VIRTIO_CONFIG_.patch -Patch0763: vhost-fix-the-fd-leak.patch -Patch0764: vhost-release-virtqueue-objects-in-error-path.patch -Patch0765: vdpa-stop-all-svq-on-device-deletion.patch -Patch0766: net-Fix-a-misleading-error-message.patch -Patch0767: qsd-Unlink-absolute-PID-file-path.patch -Patch0768: libvhost-user-Fix-VHOST_USER_ADD_MEM_REG-reply.patch -Patch0769: io_uring-fix-short-read-slow-path.patch -Patch0770: libvhost-user-Fix-VHOST_USER_GET_MAX_MEM_SLOTS-reply.patch -Patch0771: tests-qtest-check-the-return-value.patch -Patch0772: hw-net-cadence_gem.c-spelling-fixes-Octects.patch -Patch0773: hw-arm-fsl-imx-Do-not-ignore-Error-argument.patch -Patch0774: xen-pass-through-don-t-create-needless-register-grou.patch -Patch0775: spapr-pci-Correct-does-not-support-hotplugging-error.patch -Patch0776: hmp-Improve-sync-profile-error-message.patch -Patch0777: qga-Improve-guest-exec-status-error-message.patch -Patch0778: ui-qmp-cmds-Improve-two-error-messages.patch -Patch0779: tcg-loongarch64-Fix-tcg_out_mov-Aborted.patch -Patch0780: disas-hppa-Show-hexcode-of-instruction-along-with-di.patch -Patch0781: target-arm-Don-t-set-syndrome-ISS-for-loads-and-stor.patch -Patch0782: balloon-Fix-a-misleading-error-message.patch -Patch0783: target-i386-cpu-Improve-error-message-for-property-v.patch -Patch0784: tests-qtest-migration-test.c-spelling-fix-bandwith.patch -Patch0785: xen-pass-through-merge-emulated-bits-correctly.patch -Patch0786: hw-display-next-fb-Fix-comment-typo.patch -Patch0787: hw-virtio-virtio-iommu-pci-Enforce-the-device-is-plu.patch -Patch0788: hw-ide-atapi.c-Correct-typos-CD-CDROM-CD-ROM.patch -Patch0789: trivial-typos-namesapce.patch -Patch0790: tests-qtest-Fix-two-format-strings.patch -Patch0791: sphinx-change-default-language-to-en.patch -Patch0792: block-use-unsigned-for-in_flight-field-on-driver-sta.patch -Patch0793: Fix-STM32F2XX-USART-data-register-readout.patch -Patch0794: Revert-hw-virtio-virtio-iommu-pci-Enforce-the-device.patch -Patch0795: hw-riscv-boot-Reduce-FDT-address-alignment-constrain.patch -Patch0796: vhost-user-blk-propagate-error-return-from-generic-v.patch -Patch0797: vhost-user-blk-reconnect-on-any-error-during-realize.patch -Patch0798: hw-arm-ast2600-Fix-address-mapping-of-second-SPI-con.patch -Patch0799: Add-dummy-Aspeed-AST2600-Display-Port-MCU-DPMCU.patch -Patch0800: hw-net-npcm7xx_emc-fix-missing-queue_flush.patch -Patch0801: block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch -Patch0802: scripts-entitlement.sh-Use-backward-compatible-cp-fl.patch -Patch0803: migration-colo-More-accurate-update-checkpoint-time.patch -Patch0804: Fixed-a-QEMU-hang-when-guest-poweroff-in-COLO-mode.patch -Patch0805: hw-intc-arm_gicv3-ICC_PMR_EL1-high-bits-should-be-RA.patch -Patch0806: target-ppc-cpu-models-Remove-the-default-CPU-alias.patch -Patch0807: hw-usb-dev-mtp-Use-g_mkdir.patch -Patch0808: ui-gtk-prevent-ui-lock-up-when-dpy_gl_update-called-.patch -Patch0809: vhost-fix-null-pointer-access.patch -Patch0810: vhost-vdpa-add-VHOST_BACKEND_F_BYTEMAPLOG.patch -Patch0811: vhost-vdpa-add-migration-log-ops-for-VhostOps.patch -Patch0812: vhost-introduce-bytemap-for-vhost-backend-logging.patch -Patch0813: vhost-add-vhost_dev_suspend-resume_op.patch -Patch0814: vhost-implement-vhost-vdpa-suspend-resume.patch -Patch0815: vhost-implement-vhost_vdpa_device_suspend-resume.patch -Patch0816: vhost-implement-savevm_hanlder-for-vdpa-device.patch -Patch0817: vhost-implement-migration-state-notifier-for-vdpa-de.patch -Patch0818: vhost-implement-post-resume-bh.patch -Patch0819: vdpa-implement-vdpa-device-migration.patch -Patch0820: vdpa-move-memory-listener-to-the-realize-stage.patch -Patch0821: hw-usb-hcd-xhci.c-spelling-tranfer.patch -Patch0822: ui-vnc-clipboard-fix-inflate_buffer.patch -Patch0823: i386-sev-Avoid-SEV-ES-crash-due-to-missing-MSR_EFER_.patch -Patch0824: tests-avocado-mark-ReplayKernelNormal.test_mips64el_.patch -Patch0825: tests-unit-fix-a-Wformat-truncation-warning.patch -Patch0826: hw-qdev-Cosmetic-around-documentation.patch -Patch0827: pci-Export-the-pci_intx-function.patch -Patch0828: pcie_aer-Don-t-trigger-a-LSI-if-none-are-defined.patch -Patch0829: hw-i386-pc-Add-missing-property-descriptions.patch -Patch0830: hw-scsi-vhost-scsi-don-t-leak-vqs-on-error.patch -Patch0831: virtio-vhost-vsock-don-t-double-close-vhostfd-remove.patch -Patch0832: hw-scsi-vhost-scsi-don-t-double-close-vhostfd-on-err.patch -Patch0833: ppc-spelling-fixes.patch -Patch0834: s390x-Fix-spelling-errors.patch -Patch0835: migration-fix-RAMBlock-add-NULL-check.patch -Patch0836: iotests-fix-default-machine-type-detection.patch -Patch0837: gdb-xml-fix-duplicate-register-in-arm-neon.xml.patch -Patch0838: migration-Set-downtime_start-even-for-postcopy.patch -Patch0839: revert-tcg-loongarch64-Fix-tcg_out_mov-Aborted.patch -Patch0840: shadow_dev-introduce-shadow-dev-for-virtio-net-devic.patch -Patch0841: vdpa-set-vring-enable-only-if-the-vring-address-has-.patch -Patch0842: vdpa-correct-param-passed-in-when-unregister-save.patch -Patch0843: vdpa-support-vdpa-device-suspend-resume.patch -Patch0844: vdpa-don-t-suspend-resume-device-when-vdpa-device-no.patch -Patch0845: vdpa-suspend-function-return-0-when-the-vdpa-device-.patch - - BuildRequires: flex BuildRequires: gcc BuildRequires: make @@ -918,7 +73,7 @@ BuildRequires: spice-server-devel # for upgrade from qemu-kvm Provides: qemu-kvm -Obsoletes: qemu-kvm < 10:6.2.0 +Obsoletes: qemu-kvm < 11:8.2.0 Requires(post): /usr/bin/getent Requires(post): /usr/sbin/groupadd @@ -1072,10 +227,9 @@ qemubuilddir="build" tar xf %{SOURCE4} cd BinDir/ -\cp -r -a * ../ +\cp -r -a . ../ cd ../ - ./configure \ --prefix=%{_prefix} \ --target-list="${buildarch} ${targetarch}" \ @@ -1091,7 +245,7 @@ cd ../ --firmwarepath=%{_datadir}/%{name} \ --with-pkgversion=%{name}-%{version}-%{release} \ --python=/usr/bin/python3 \ - --enable-slirp=system \ + --disable-slirp \ --enable-slirp-smbd \ --enable-gtk \ --enable-docs \ @@ -1112,7 +266,6 @@ cd ../ --enable-vhost-kernel \ --enable-vhost-user-blk-server \ --enable-vhost-vdpa \ - --enable-vhost-vsock \ --enable-tpm \ --enable-modules \ --enable-libssh \ @@ -1140,6 +293,7 @@ cd ../ make %{?_smp_mflags} $buildldflags V=1 + cp ${qemubuilddir}/${buildarch}/qemu-system-* qemu-kvm %install @@ -1219,9 +373,7 @@ rm -rf %{buildroot}%{_libdir}/%{name}/ui-spice-core.so rm -rf %{buildroot}%{_libexecdir}/vhost-user-gpu rm -rf %{buildroot}%{_datadir}/%{name}/vhost-user/50-qemu-gpu.json -rm -rf %{buildroot}%{_datadir}/%{name}/vhost-user/50-qemu-virtiofsd.json %ifarch ppc64le -rm -rf %{buildroot}%{_datadir}/%{name}/opensbi-riscv*.elf %endif %if %{with rbd} @@ -1266,10 +418,17 @@ getent passwd qemu >/dev/null || \ %{_libdir}/%{name}/hw-display-virtio-vga-gl.so %{_libdir}/%{name}/hw-display-virtio-vga.so %endif + %{_libdir}/%{name}/hw-display-virtio-gpu-gl.so %{_libdir}/%{name}/hw-display-virtio-gpu-pci-gl.so %{_libdir}/%{name}/hw-display-virtio-gpu-pci.so %{_libdir}/%{name}/hw-display-virtio-gpu.so +%{_libdir}/%{name}/audio-dbus.so +%{_libdir}/%{name}/ui-dbus.so +%{_libdir}/%{name}/ui-egl-headless.so +%{_docdir}/%{name}/dbus-dbusindex.html +%{_datadir}/%{name}/vof-nvram.bin +%{_datadir}/%{name}/vof.bin %{_datadir}/%{name}/efi-virtio.rom %{_datadir}/%{name}/efi-e1000.rom %{_datadir}/%{name}/efi-e1000e.rom @@ -1294,7 +453,6 @@ getent passwd qemu >/dev/null || \ %{_bindir}/qemu-keymap %{_bindir}/qemu-pr-helper %{_libexecdir}/virtfs-proxy-helper -%{_libexecdir}/virtiofsd %{_unitdir}/qemu-pr-helper.service %{_unitdir}/qemu-pr-helper.socket %attr(4755, root, root) %{_libexecdir}/qemu-bridge-helper @@ -1322,9 +480,9 @@ getent passwd qemu >/dev/null || \ %{_datadir}/%{name}/multiboot.bin %{_datadir}/%{name}/multiboot_dma.bin %{_datadir}/%{name}/kvmvapic.bin -%{_datadir}/%{name}/sgabios.bin %endif + %files system-aarch64 %{_bindir}/qemu-system-aarch64 @@ -1354,7 +512,6 @@ getent passwd qemu >/dev/null || \ %{_datadir}/%{name}/multiboot.bin %{_datadir}/%{name}/multiboot_dma.bin %{_datadir}/%{name}/kvmvapic.bin -%{_datadir}/%{name}/sgabios.bin %endif %ifarch ppc64le @@ -1367,15 +524,14 @@ getent passwd qemu >/dev/null || \ %files system-riscv %{_bindir}/qemu-system-riscv32 %{_bindir}/qemu-system-riscv64 -%{_datadir}/%{name}/opensbi-riscv*.bin +%{_datadir}/%{name}/opensbi-riscv32-generic-fw_dynamic.* +%{_datadir}/%{name}/opensbi-riscv64-generic-fw_dynamic.* %ifnarch ppc64le -%{_datadir}/%{name}/opensbi-riscv*.elf %endif %ifarch loongarch64 %files system-loongarch64 %{_bindir}/qemu-system-loongarch64 -%{_datadir}/%{name}/loongarch_*.bin %{_libdir}/%{name}/audio-oss.so %{_libdir}/%{name}/ui-curses.so %{_libdir}/%{name}/ui-gtk.so @@ -1390,7 +546,6 @@ getent passwd qemu >/dev/null || \ %endif %ifnarch loongarch64 -%exclude %{_datadir}/%{name}/loongarch_*.bin %endif %files help @@ -1408,7 +563,6 @@ getent passwd qemu >/dev/null || \ %{_mandir}/man1/qemu-img.1* %{_mandir}/man1/qemu-storage-daemon.1* %{_mandir}/man1/virtfs-proxy-helper.1* -%{_mandir}/man1/virtiofsd.1* %{_mandir}/man7/qemu-block-drivers.7* %{_mandir}/man7/qemu-cpu-models.7* %{_mandir}/man7/qemu-ga-ref.7* @@ -1456,958 +610,5 @@ getent passwd qemu >/dev/null || \ %endif %changelog -* Fri Dec 22 2023 - 10:6.2.0-87 -- vdpa: suspend function return 0 when the vdpa device is stopped -- vdpa: don't suspend/resume device when vdpa device not started -- vdpa: support vdpa device suspend/resume -- vdpa: correct param passed in when unregister save -- vdpa: set vring enable only if the vring address has already been set -- shadow_dev: introduce shadow dev for virtio-net device -- revert "tcg/loongarch64: Fix tcg_out_mov() Aborted" -- migration: Set downtime_start even for postcopy -- gdb-xml: fix duplicate register in arm-neon.xml -- iotests: fix default machine type detection -- migration: fix RAMBlock add NULL check -- s390x: Fix spelling errors -- ppc: spelling fixes -- hw/scsi/vhost-scsi: don't double close vhostfd on error -- virtio/vhost-vsock: don't double close vhostfd, remove redundant cleanup -- hw/scsi/vhost-scsi: don't leak vqs on error -- hw/i386/pc: Add missing property descriptions -- pcie_aer: Don't trigger a LSI if none are defined -- pci: Export the pci_intx() function -- hw/qdev: Cosmetic around documentation -- tests/unit: fix a -Wformat-truncation warning -- tests/avocado: mark ReplayKernelNormal.test_mips64el_malta as flaky -- i386/sev: Avoid SEV-ES crash due to missing MSR_EFER_LMA bit -- ui/vnc-clipboard: fix inflate_buffer -- hw/usb/hcd-xhci.c: spelling: tranfer - -* Tue Dec 5 2023 - 10:6.2.0-86 -- vdpa: move memory listener to the realize stage -- vdpa: implement vdpa device migration -- vhost: implement post resume bh -- vhost: implement migration state notifier for vdpa device -- vhost: implement savevm_hanlder for vdpa device -- vhost: implement vhost_vdpa_device_suspend/resume -- vhost: implement vhost-vdpa suspend/resume -- vhost: add vhost_dev_suspend/resume_op -- vhost: introduce bytemap for vhost backend logging -- vhost-vdpa: add migration log ops for VhostOps -- vhost-vdpa: add VHOST_BACKEND_F_BYTEMAPLOG -- vhost: fix null pointer access -- ui/gtk: prevent ui lock up when dpy_gl_update called again before current draw event occurs -- hw/usb: dev-mtp: Use g_mkdir() -- target/ppc/cpu-models: Remove the "default" CPU alias -- hw/intc/arm_gicv3: ICC_PMR_EL1 high bits should be RAZ -- Fixed a QEMU hang when guest poweroff in COLO mode -- migration/colo: More accurate update checkpoint time -- scripts/entitlement.sh: Use backward-compatible cp flags -- block/nvme: fix infinite loop in nvme_free_req_queue_cb() -- hw/net: npcm7xx_emc fix missing queue_flush -- Add dummy Aspeed AST2600 Display Port MCU (DPMCU) -- hw/arm: ast2600: Fix address mapping of second SPI controller -- vhost-user-blk: reconnect on any error during realize -- vhost-user-blk: propagate error return from generic vhost -- hw/riscv: boot: Reduce FDT address alignment constraints -- Revert "hw/virtio/virtio-iommu-pci: Enforce the device is plugged on the root bus" -- Fix STM32F2XX USART data register readout -- block: use 'unsigned' for in_flight field on driver state -- sphinx: change default language to 'en' -- tests/qtest: Fix two format strings -- trivial typos: namesapce -- hw/ide/atapi.c: Correct typos (CD-CDROM -> CD-ROM) -- hw/virtio/virtio-iommu-pci: Enforce the device is plugged on the root bus -- hw/display/next-fb: Fix comment typo -- xen/pass-through: merge emulated bits correctly mainline inclusion commit be9c61da9fc57eb7d293f380d0805ca6f46c2657 category: bugfix -- tests/qtest/migration-test.c: spelling fix: bandwith -- target/i386/cpu: Improve error message for property "vendor" -- balloon: Fix a misleading error message -- target/arm: Don't set syndrome ISS for loads and stores with writeback mainline inclusion commit 53ae2fdef1f5661cbaa2ea571c517f98e6041cb8 category: bugfix -- disas/hppa: Show hexcode of instruction along with disassembly -- tcg/loongarch64: Fix tcg_out_mov() Aborted -- ui/qmp-cmds: Improve two error messages -- qga: Improve guest-exec-status error message -- hmp: Improve sync-profile error message -- spapr/pci: Correct "does not support hotplugging error messages -- xen/pass-through: don't create needless register group mainline inclusion commit c0e86b7624cb9d6db03e0d48cf82659e5b89a6a6 category: bugfix - -* Fri Dec 1 2023 - 10:6.2.0-85 -- spec: Add support for the ppc64le platform - -* Tue Nov 28 2023 - 10:6.2.0-84 -- hw/arm/fsl-imx: Do not ignore Error argument -- hw/net/cadence_gem.c: spelling fixes: Octects -- tests/qtest: check the return value -- libvhost-user: Fix VHOST_USER_GET_MAX_MEM_SLOTS reply mainline inclusion commit 69a5daec06f423843ce1bb9be5fb049314996f78 category: bugfix -- io_uring: fix short read slow path mainline inclusion commit c06fc7ce147e57ab493bad9263f1601b8298484b category: bugfix -- libvhost-user: Fix VHOST_USER_ADD_MEM_REG reply mainline inclusion commit 7f27d20ded2f480f3e66d03f90ea71507b834276 category: bugfix -- qsd: Unlink absolute PID file path mainline inclusion commit 9d8f8233b9fa525a7e37350fbc18877051128c5d category: bugfix -- net: Fix a misleading error message -- vdpa: stop all svq on device deletion -- vhost: release virtqueue objects in error path -- vhost: fix the fd leak -- virtio: i2c: Check notifier helpers for VIRTIO_CONFIG_IRQ_IDX -- hw/virtio: fix typo in VIRTIO_CONFIG_IRQ_IDX comments -- virtio-net: clear guest_announce feature if no cvq backend -- vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check -- vdpa: do not block migration if device has cvq and x-svq=on -- vdpa net: block migration if the device has CVQ -- vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in _load_mq() -- vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in _load_mac() -- vdpa: fix not using CVQ buffer in case of error -- vdpa: Fix possible use-after-free for VirtQueueElement -- hw/virtio: fix vhost_user_read tracepoint -- vhost: Fix false positive out-of-bounds -- vhost: fix possible wrap in SVQ descriptor ring -- vhost: move iova_tree set to vhost_svq_start -- vhost: Always store new kick fd on vhost_svq_set_svq_kick_fd -- virtio-crypto: verify src&dst buffer length for sym request -- vdpa: commit all host notifier MRs in a single MR transaction -- vdpa: harden the error path if get_iova_range failed -- vdpa-dev: get iova range explicitly -- virtio-pci: add support for configure interrupt -- virtio-mmio: add support for configure interrupt -- virtio-net: add support for configure interrupt -- vhost: add support for configure interrupt -- virtio: add support for configure interrupt -- vhost-vdpa: add support for config interrupt -- vhost: introduce new VhostOps vhost_set_config_call -- virtio-pci: decouple the single vector from the interrupt process -- virtio-pci: decouple notifier from interrupt process -- virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX -- vdpa: do not handle VIRTIO_NET_F_GUEST_ANNOUNCE in vhost-vdpa -- vdpa: handle VIRTIO_NET_CTRL_ANNOUNCE in vhost_vdpa_net_handle_ctrl_avail -- vhost: fix vq dirty bitmap syncing when vIOMMU is enabled -- hw/virtio: gracefully handle unset vhost_dev vdev -- hw/virtio/vhost: Fix typo in comment. -- vdpa: always start CVQ in SVQ mode if possible -- vdpa: add shadow_data to vhost_vdpa -- vdpa: store x-svq parameter in VhostVDPAState -- vdpa: add asid parameter to vhost_vdpa_dma_map/unmap -- vdpa: allocate SVQ array unconditionally -- vdpa: move SVQ vring features check to net/ -- vdpa: request iova_range only once -- vdpa: add vhost_vdpa_net_valid_svq_features -- vhost: allocate SVQ device file descriptors at device start -- vhost: set SVQ device call handler at SVQ start -- vdpa: use v->shadow_vqs_enabled in vhost_vdpa_svqs_start & stop -- vhost: enable vrings in vhost_dev_start() for vhost-user devices -- vhost-vdpa: fix assert !virtio_net_get_subqueue(nc)->async_tx.elem in virtio_net_reset -- net/vhost-vdpa.c: Fix clang compilation failure -- vhost-vdpa: allow passing opened vhostfd to vhost-vdpa -- vdpa: Remove shadow CVQ command check -- vdpa: Delete duplicated vdpa_feature_bits entry -- hw/virtio: add some vhost-user trace events -- vdpa: Allow MQ feature in SVQ -- virtio-net: Update virtio-net curr_queue_pairs in vdpa backends -- vdpa: validate MQ CVQ commands -- vdpa: Add vhost_vdpa_net_load_mq -- vdpa: extract vhost_vdpa_net_load_mac from vhost_vdpa_net_load -- vdpa: Make VhostVDPAState cvq_cmd_in_buffer control ack type -- vdpa: Delete CVQ migration blocker -- vdpa: Add virtio-net mac address via CVQ at start -- vhost_net: add NetClientState->load() callback -- vdpa: extract vhost_vdpa_net_cvq_add from vhost_vdpa_net_handle_ctrl_avail -- vdpa: Move command buffers map to start of net device -- vdpa: add net_vhost_vdpa_cvq_info NetClientInfo -- vhost_net: Add NetClientInfo stop callback -- vhost_net: Add NetClientInfo start callback -- vdpa: Use ring hwaddr at vhost_vdpa_svq_unmap_ring -- vdpa: Make SVQ vring unmapping return void -- vdpa: Remove SVQ vring from iova_tree at shutdown -- util: accept iova_tree_remove_parameter by value -- vdpa: do not save failed dma maps in SVQ iova tree -- vdpa: Skip the maps not in the iova tree -- vdpa: Fix file descriptor leak on get features error -- vdpa: Fix memory listener deletions of iova tree -- vhost: Get vring base from vq, not svq -- vdpa: Add x-svq to NetdevVhostVDPAOptions -- vdpa: Add device migration blocker -- vdpa: Extract get features part from vhost_vdpa_get_max_queue_pairs -- vdpa: Buffer CVQ support on shadow virtqueue -- vdpa: manual forward CVQ buffers -- vdpa: Export vhost_vdpa_dma_map and unmap calls -- vhost: Add svq avail_handler callback -- vhost: add vhost_svq_poll -- vhost: Expose vhost_svq_add -- vhost: add vhost_svq_push_elem -- vhost: Track number of descs in SVQDescState -- vhost: Add SVQDescState -- vhost: Decouple vhost_svq_add from VirtQueueElement -- vhost: Check for queue full at vhost_svq_add -- vhost: Move vhost_svq_kick call to vhost_svq_add -- vhost: Reorder vhost_svq_kick -- vdpa: Avoid compiler to squash reads to used idx -- virtio-net: Expose ctrl virtqueue logic -- virtio-net: Expose MAC_TABLE_ENTRIES -- vhost: move descriptor translation to vhost_svq_vring_write_descs -- util: Return void on iova_tree_remove -- virtio-net: don't handle mq request in userspace handler for vhost-vdpa -- vhost-vdpa: change name and polarity for vhost_vdpa_one_time_request() -- vhost-vdpa: backend feature should set only once -- vhost-vdpa: fix improper cleanup in net_init_vhost_vdpa -- virtio-net: align ctrl_vq index for non-mq guest for vhost_vdpa -- virtio: add vhost support for virtio devices -- include/hw: start documenting the vhost API -- hw/virtio: add vhost_user_[read|write] trace points -- vhost: Fix element in vhost_svq_add failure -- vdpa: Fix index calculus at vhost_vdpa_svqs_start -- vdpa: Fix bad index calculus at vhost_vdpa_get_vring_base -- vhost: Fix device's used descriptor dequeue -- vhost: Track descriptor chain in private at SVQ -- vdpa: Add missing tracing to batch mapping functions -- vhost-vdpa: fix typo in a comment -- virtio: fix --enable-vhost-user build on non-Linux -- vdpa: Expose VHOST_F_LOG_ALL on SVQ -- vdpa: Never set log_base addr if SVQ is enabled -- vdpa: Adapt vhost_vdpa_get_vring_base to SVQ -- vdpa: Add custom IOTLB translations to SVQ -- vhost: Add VhostIOVATree -- util: add iova_tree_find_iova -- util: Add iova_tree_alloc_map -- vhost: Shadow virtqueue buffers forwarding -- vdpa: adapt vhost_ops callbacks to svq -- virtio: Add vhost_svq_get_vring_addr -- vhost: Add vhost_svq_valid_features to shadow vq -- vhost: Add Shadow VirtQueue call forwarding capabilities -- vhost: Add Shadow VirtQueue kick forwarding capabilities -- vhost: Add VhostShadowVirtqueue -- vdpa: Make ncs autofree -- Revert "virtio: introduce macro IRTIO_CONFIG_IRQ_IDX" -- Revert "virtio-pci: decouple notifier from interrupt process" -- Revert "virtio-pci: decouple the single vector from the interrupt process" -- Revert "vhost-vdpa: add support for config interrupt" -- Revert "virtio: add support for configure interrupt" -- Revert "vhost: add support for configure interrupt" -- Revert "virtio-net: add support for configure interrupt" -- Revert "virtio-mmio: add support for configure interrupt" -- Revert "virtio-pci: add support for configure interrupt" -- Revert "vhost: introduce new VhostOps vhost_set_config_call" -- virtio: signal after wrapping packed used_idx -- target/i386: Adjust feature level according to FEAT_7_1_EDX -- target/i386: Add new CPU model GraniteRapids -- target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration -- target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration -- target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration -- target/i386: Add support for AVX-IFMA in CPUID enumeration -- target/i386: Add support for AMX-FP16 in CPUID enumeration -- target/i386: Add support for CMPCCXADD in CPUID enumeration -- tracetool: avoid invalid escape in Python string -- hw/pvrdma: Protect against buggy or malicious guest driver -- vga: avoid crash if no default vga card mainline inclusion commit 6985d8ede92494f3b791de01e8ee9306eb6d5e4a category: bugfix -- qom/object: Remove circular include dependency mainline inclusion commit 5bba9bcfbb42e7c016626420e148a1bf1b080835 category: bugfix -- artist: set memory region owners for buffers to the artist device mainline inclusion commit 39fbaeca096a9bf6cbe2af88572c1cb2aa62aa8c category: bugfix -- virtio-iommu: Fix the partial copy of probe request mainline inclusion commit 45461aace83d961e933b27519b81d17b4c690514 category: bugfix -- e1000: set RX descriptor status in a separate operation mainline inclusion commit 034d00d4858161e1d4cff82d8d230bce874a04d3 category: bugfix -- vhost: introduce new VhostOps vhost_set_config_call -- vhost: stick to -errno error return convention -- vhost-user: stick to -errno error return convention -- vhost-vdpa: stick to -errno error return convention -- virtio-pci: add support for configure interrupt -- virtio-mmio: add support for configure interrupt -- virtio-net: add support for configure interrupt -- vhost: add support for configure interrupt -- virtio: add support for configure interrupt -- vhost-vdpa: add support for config interrupt -- virtio-pci: decouple the single vector from the interrupt process -- virtio-pci: decouple notifier from interrupt process -- virtio: introduce macro IRTIO_CONFIG_IRQ_IDX -- pci: Fix the update of interrupt disable bit in PCI_COMMAND register -- hw/timer/npcm7xx_timer: Prevent timer from counting down past zero -- tpm_crb: mark command buffer as dirty on request completion mainline inclusion commit e37a0ef4605e5d2041785ff3fc89ca6021faf7a0 category: bugfix -- pci: fix overflow in snprintf string formatting mainline inclusion commit 36f18c6989a3d1ff1d7a0e50b0868ef3958299b4 category: bugfix -- hw/usb/hcd-ehci: fix writeback order mainline inclusion commit f471e8b060798f26a7fc339c6152f82f22a7b33d category: bugfix -- qemu-timer: Skip empty timer lists before locking in qemu_clock_deadline_ns_all mainline inclusion commit 3f42906c9ab2c777a895b48b87b8107167e4a275 category: bugfix -- semihosting/config: Merge --semihosting-config option groups mainline inclusion commit 90c072e063737e9e8f431489bbd334452f89056e category: bugfix -- semihosting: fix memleak at semihosting_arg_fallback -- target/i386: Export GDS_NO bit to guests - -* Mon Oct 30 2023 - 10:6.2.0-83 -- hw/virtio/virtio-pmem: Replace impossible check by assertion -- tests: Fix printf format string in acpi-utils.c -- softmmu/dirtylimit: Add parameter check for hmp "set_vcpu_dirty_limit" -- disas/riscv: Fix the typo of inverted order of pmpaddr13 and pmpaddr14 -- qga: Fix memory leak when output stream is unused -- ui/vnc-clipboard: fix infinite loop in inflate_buffer (CVE-2023-3255) -- target/i386: Add few security fix bits in ARCH_CAPABILITIES into SapphireRapids CPU model -- target/i386: Add new bit definitions of MSR_IA32_ARCH_CAPABILITIES -- target/i386: Allow MCDT_NO if host supports -- target/i386: Add support for MCDT_NO in CPUID enumeration -- target/i386: Export MSR_ARCH_CAPABILITIES bits to guests -- target/i386: add support for FB_CLEAR feature -- target/i386: add support for FLUSH_L1D feature -- crypto: remove shadowed 'ret' variable -- hw/i2c/pmbus_device: Fix modifying QOM class internals from instance -- hw/arm/xlnx-zynqmp: fix unsigned error when checking the RPUs number - -* Mon Oct 30 2023 - 10:6.2.0-82 -- thread-pool: optimize scheduling of completion bottom half -- migration/rdma: zore out head.repeat to make the error more clear -- vhost-user-fs: Back up vqs before cleaning up vhost_dev -- hw/vfio/pci-quirks: Sanitize capability pointer -- hw/vfio/pci-quirks: Support alternate offset for GPUDirect Cliques -- replay: fix event queue flush for qemu shutdown -- hw/net: Fix read of uninitialized memory in ftgmac100 -- target/ppc: Fix tlbie -- target/i386: fix INVD vmexit -- qtest/npcm7xx_pwm-test: Fix memory leak in mft_qom_set -- aio-posix: zero out io_uring sqe user_data - -* Mon Oct 30 2023 - 10:6.2.0-81 -- hw/nvme: Avoid dynamic stack allocation -- ppc/vof: Fix missed fields in VOF cleanup -- ui: fix crash when there are no active_console -- tests/qtest/pflash: Clean up local variable shadowing -- target/ppc: Fix the order of kvm_enable judgment about kvmppc_set_interrupt() -- tulip: Assign default MAC address if not specified -- hw/char: fix qcode array bounds check in ESCC impl - -* Sat Sep 9 2023 - 10:6.2.0-80 -- io: remove io watch if TLS channel is closed during handshake -- hw/ssi: Fix Linux driver init issue with xilinx_spi -- chardev: report the handshake error -- vhost: Drop unused eventfd_add|del hooks -- virtio-iommu: use-after-free fix -- hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF -- hw/rx: rx-gdbsim DTB load address aligned of 16byte -- vhost-user: Use correct macro name TARGET_PPC64 -- accel/kvm: Make kvm_dirty_ring_reaper_init() void -- accel/kvm: Free as when an error occurred - -* Mon Aug 28 2023 - 10:6.2.0-79 -- test: Fix test-crypto-secret when compiling without keyring support -- aio-posix: fix build failure io_uring 2.2 - -* Tue Aug 15 2023 - 10:6.2.0-78 -- sw_64: Added sw64 architecture related updates -- virtio-crypto: verify src&dst buffer length for sym request -- vhost-vdpa: do not cleanup the vdpa/vhost-net structures if peer nic is present -- qga: Fix suspend on Linux guests without systemd -- tests: vhost-user-test: release mutex on protocol violation -- qapi: support updating expected test output via make -- block: Fix misleading hexadecimal format -- block/rbd: fix write zeroes with growing images -- block/nbd.c: Fixed IO request coroutine not being wakeup when kill NBD server -- block/nfs: Fix 32-bit Windows build -- qapi/qdev: Tidy up device_add documentation -- hw/xen/xen_pt: fix uninitialized variable -- migration/ram: Fix error handling in ram_write_tracking_start() -- docs/about/build-platforms: Refine the distro support policy -- xen-block: Avoid leaks on new error path -- QGA VSS: Add wrapper to send log to debugger and stderr -- chardev/char-socket: set s->listener = NULL in char_socket_finalize -- qapi/block: Tidy up block-latency-histogram-set documentation -- disas/riscv Fix ctzw disassemble -- vfio: Fix vfio_get_dev_region() trace event -- migration/ram: Fix populate_read_range() -- Check and report for incomplete 'global' option format - -* Mon Aug 7 2023 - 10:6.2.0-77 -- test-vmstate: fix bad GTree usage, use-after-free - -* Fri Jul 28 2023 - 10:6.2.0-76 -- qga/win32: Use rundll for VSS installation -- qga/win32: Remove change action from MSI installer -- ide: Increment BB in-flight counter for TRIM BH -- hw/pci-bridge/pxb: Fix missing swizzle -- host-vdpa: make notifiers _init()/_uninit() symmetric -- hw/virtio: vdpa: Fix leak of host-notifier memory-region -- accel/tcg/cpu-exec: Fix precise single-stepping after interrupt -- Allow setting up to 8 bytes with the generic loader -- hw/net/virtio-net: make some VirtIONet const -- accel/tcg: Optimize jump cache flush during tlb range flush -- 9pfs: prevent opening special files (CVE-2023-2861) -- tcg: Reduce tcg_assert_listed_vecop() scope -- gitlab: Disable plugins for cross-i386-tci -- vfio/pci: Fix a segfault in vfio_realize -- block/iscsi: fix double-free on BUSY or similar statuses -- tests/tcg: fix unused variable in linux-test -- hw/net/vmxnet3: allow VMXNET3_MAX_MTU itself as a value -- qga/vss-win32: fix warning for clang++-15 -- vnc: avoid underflow when accessing user-provided address -- block/monitor: Fix crash when executing HMP commit -- virtio-gpu: add a FIXME for virtio_gpu_load() -- hw/ppc/Kconfig: MAC_NEWWORLD should always select USB_OHCI_PCI -- migration: report compress thread pid to libvirt - -* Thu Jun 29 2023 - 10:6.2.0-75 -- Add lbt support for kvm. -- Fix smp.cores value and Fix divide 0 error -- hw/nvme: Change alignment in dma functions for nvme_blk_* -- virtio: fix reachable assertion due to stale value of cached region size -- hw/nvme: fix missing DNR on compare failure - -* Thu May 25 2023 - 10:6.2.0-74 -- spec: delete repetitive man8/qemu-ga.8* from qemu-guest-agent package - -* Fri May 19 2023 - 10:6.2.0-73 -- spec: delete useless core3-hmcode/core3-reset/uefi-bios-sw - -* Wed May 17 2023 - 10:6.2.0-72 -- migration/xbzrle: fix out-of-bounds write with axv512 -- migration/xbzrle: use ctz64 to avoid undefined result -- Update bench-code for addressing CI problem -- AVX512 support for xbzrle_encode_buffer -- configure, meson: move AVX tests to meson -- target/i386: KVM: allow fast string operations if host supports them -- target/i386: add FSRM to TCG -- hw/nvme: fix memory leak in nvme_dsm -- aio-posix: fix race between epoll upgrade and aio_set_fd_handler() -- target/i386: Add SGX aex-notify and EDECCSSA support -- hw/usb/imx: Fix out of bounds access in imx_usbphy_read() -- target/i386: Set maximum APIC ID to KVM prior to vCPU creation -- target/i386: Fix sanity check on max APIC ID / X2APIC enablement - -* Sat Apr 22 2023 - 10:6.2.0-71 -- vhost-user-blk: fix the resize crash -- plugins: make qemu_plugin_user_exit's locking order consistent with fork_start's -- linux-user: fix strace build w/out munlockall -- ui: fix crash on serial reset, during init -- qga/win/vss: requester_freeze changes -- migration: fix populate_vfio_info -- block/rbd: workaround for ceph issue #53784 -- target/i386: add FZRM, FSRS, FSRC -- i386: Add new CPU model SapphireRapids -- core/cpu-common: Fix the wrong '#ifdef __aarch64__' - -* Thu Mar 30 2023 - 10:6.2.0-70 -- Add spice buildrequires for loongarch. - -* Wed Mar 29 2023 - 10:6.2.0-69 -- fixup compile error. Add function kvm_arch_accel_class_init definition on loongarch64 machine. - -* Wed Mar 29 2023 - 10:6.2.0-68 -- modify qemu.spec to add (riscv virt) machine mapping to testenv from v7.0.0 - -* Tue Mar 28 2023 - 10:6.2.0-67 -- hw/net/vmxnet3: Log guest-triggerable errors using LOG_GUEST_ERROR mainline -- net/eth: Don't consider ESP to be an IPv6 option header mainline -- net: Fix uninitialized data usage mainline -- block-backend: prevent dangling BDS pointers across aio_poll() mainline inclusion -- i386: add notify VM exit support -- kvm: expose struct KVMState -- kvm: allow target-specific accelerator properties -- i386: kvm: extend kvm_{get, put}_vcpu_events to support pending triple fault -- linux-headers: include missing changes from 6.0 -- dsoundaudio: fix crackling audio recordings mainline -- hw/audio/intel-hda: fix stream reset mainline -- hw/pvrdma: Protect against buggy or malicious guest driver -- qemu support for loongarch -- hw/pci: Trace IRQ routing on PCI topology -- hw/pci: Fix a typo -- hw/riscv: virt: Simplify virt_{get,set}_aclint() -- curl: Fix error path in curl_open() -- tests: add (riscv virt) machine mapping to testenv from v7.0.0 -- tests/tcg: Fix target-specific Makefile variables path for user-mode mainline -- hw/core/machine:Fix the missing consideration of cluster-id -- arm/virt: Correct timing of pause all vcpus for hot-plugged CPUs -- arm/virt: Correct timing of executing cpu_synchronize_post_init for hot-plugged cpus -- hw/acpi: Support acpi-ged to report CPU's OST info -- hw/acpi: Add ospm_status hook implementation for acpi-ged -- fix qmp command migrate-set-parameters - -* Wed Mar 22 2023 MinMin Ren - 10:6.2.0-66 -- spec: Add multiboot_dma.bin - -* Tue Dec 20 2022 yezengruan - 10:6.2.0-65 -- linux-user: Add strace output for timer_settime64() syscall -- fix qemu-core when vhost-user-net config with server mode - -* Wed Dec 14 2022 yezengruan - 10:6.2.0-64 -- target/arm: Fix kvm probe of ID_AA64ZFR0 -- migration: report migration/multiFd related thread pid to libvirt -- vhost_net: keep acked_feature only for NET_CLIENT_DRIVER_VHOST_USER - -* Mon Dec 12 2022 Qiang Wei - 10:6.2.0-63 -- Use bcond_without to control conditional build - -* Thu Dec 8 2022 Qiang Wei - 10:6.2.0-62 -- Make Ceph rbd support an optional feature. - -* Wed Dec 07 2022 yezengruan - 10:6.2.0-61 -- BuildRequires add make - -* Tue Dec 06 2022 yezengruan - 10:6.2.0-60 -- sync some bugfix patches from upstream -- fix the virtio features negotiation flaw -- fix CVE-2022-4144 - -* Tue Nov 22 2022 yezengruan - 10:6.2.0-59 -- arm/virt: Fix vcpu hotplug idx_from_topo_ids -- Revert patches related to the vSVA -- sync some bugfix patches from upstream -- add generic vDPA device support - -* Mon Nov 14 2022 weishaokun - 10:6.2.0-58 -- support io-uring by adding --enable-io-uring compilation option - -* Tue Nov 08 2022 yezengruan - 10:6.2.0-57 -- build: make check with -j - -* Mon Nov 07 2022 yuelongguang - 10:6.2.0-56 -- support rbd by adding --enable-rbd compilation option - -* Thu Nov 03 2022 yezengruan - 10:6.2.0-55 -- support dirty restraint on vCPU -- support SPR AMX in Qemu -- fix compilation errors of sw64 - -* Mon Oct 24 2022 fushanqing - 10:6.2.0-54 -- add '--enable-slirp' compilation options - -* Fri Oct 21 2022 yezengruan - 10:6.2.0-53 -- ui/vnc-clipboard: fix integer underflow in vnc_client_cut_text_ext (CVE-2022-3165) - -* Fri Sep 30 2022 wanbo - 10:6.2.0-52 -- job.c: add missing notifier initialization -- uas: add missing return -- qom: assert integer does not overflow -- pci: expose TYPE_XI03130_DOWNSTREAM name -- acpi: pcihp: pcie: set power on cap on parent slot -- hw/display/ati_2d: Fix buffer overflow in ati_2d_blt - -* Fri Sep 30 2022 zhangxinhao - 10:6.2.0-51 -- exec/memory: Extract address_space_set() from dma_memory_set() -- hw/elf_ops: clear uninitialized segment space -- vhost: also check queue state in the vhost_dev_set_log -- vhost-net: fix improper cleanup in vhost_net_start -- virtio-net: setup vhost_dev and notifiers for cvq only - -* Fri Sep 30 2022 zhangbo - 10:6.2.0-50 -- net: tulip: Restrict DMA engine to memories (CVE-2020-14394) - -* Sat Sep 03 2022 yezengruan - 10:6.2.0-49 -- hw/usb/hcd-xhci: Fix unbounded loop in xhci_ring_chain_length() (CVE-2020-14394) - -* Tue Aug 30 2022 yezengruan - 10:6.2.0-48 -- hw/scsi/lsi53c895a: Do not abort when DMA requested and no data queued -- tests/qtest: Add fuzz-lsi53c895a-test -- scsi/lsi53c895a: fix use-after-free in lsi_do_msgout (CVE-2022-0216) -- scsi/lsi53c895a: really fix use-after-free in lsi_do_msgout (CVE-2022-0216) - -* Mon Aug 29 2022 Zhang Bo - 10:6.2.0-47 -- backport nbd related patches to avoid vm crash during migration - -* Thu Aug 25 2022 yezengruan - 10:6.2.0-46 -- vhost-user: remove VirtQ notifier restore -- vhost-user: fix VirtQ notifier cleanup -- enable vDPA build params -- Provides qemu-kvm for upgrade - -* Thu Aug 11 2022 yezengruan - 2:6.2.0-45 -- numa: Enable numa for SGX EPC sections -- target/ppc: enhance error handling in kvmppc_read_int* -- fix pointer double free in func qemu_savevm_state_complete_precopy_non_iterable - -* Mon Jul 25 2022 yezengruan - 2:6.2.0-44 -- add Requires libgcc - -* Tue Jul 19 2022 cenhuilin - 2:6.2.0-43 -- softmmu Always initialize xlat in address_space_tran (CVE-2022-35414) - -* Tue Jul 12 2022 liuxiangdong - 2:6.2.0-42 -- acpi: validate hotplug selector on access -- virtiofsd: Drop membership of all supplementary groups (CVE-2022-0358) - -* Wed Jun 22 2022 yezengruan - 2:6.2.0-41 -- hw/nvme: fix CVE-2021-3929 - -* Mon Jun 20 2022 zhangziyang - 2:6.2.0-40 -- add qemu-system-riscv rpm package build - -* Thu Jun 09 2022 yezengruan - 2:6.2.0-39 -- hw/scsi/megasas: Use uint32_t for reply queue head/tail values -- dma: Let dma_memory_valid() take MemTxAttrs argument -- dma: Let dma_memory_set() take MemTxAttrs argument -- dma: Let dma_memory_rw_relaxed() take MemTxAttrs argument -- dma: Let dma_memory_rw() take MemTxAttrs argument -- dma: Let dma_memory_read/write() take MemTxAttrs argument -- dma: Let dma_memory_map() take MemTxAttrs argument -- dma: Have dma_buf_rw() take a void pointer -- dma: Have dma_buf_read() / dma_buf_write() take a void pointer -- pci: Let pci_dma_rw() take MemTxAttrs argument -- dma: Let dma_buf_rw() take MemTxAttrs argument -- dma: Let dma_buf_write() take MemTxAttrs argument -- dma: Let dma_buf_read() take MemTxAttrs argument -- dma: Let dma_buf_rw() propagate MemTxResult -- dma: Let st*_dma() take MemTxAttrs argument -- dma: Let ld*_dma() take MemTxAttrs argument -- dma: Let st*_dma() propagate MemTxResult -- dma: Let ld*_dma() propagate MemTxResult -- pci: Let st*_pci_dma() take MemTxAttrs argument -- pci: Let ld*_pci_dma() take MemTxAttrs argument -- pci: Let st*_pci_dma() propagate MemTxResult -- pci: Let ld*_pci_dma() propagate MemTxResult -- hw/audio/intel-hda: Do not ignore DMA overrun errors -- hw/audio/intel-hda: Restrict DMA engine to memories (not MMIO devices) -- tests/qtest/intel-hda-test: Add reproducer for issue #542 - -* Mon May 30 2022 yezengruan - 2:6.2.0-38 -- acpi: fix QEMU crash when started with SLIC table -- tests: acpi: whitelist expected blobs before changing them -- tests: acpi: add SLIC table test -- tests: acpi: SLIC: update expected blobs -- hw/block/fdc: Prevent end-of-track overrun (CVE-2021-3507) -- tests/qtest/fdc-test: Add a regression test for CVE-2021-3507 - -* Mon May 30 2022 zhangziyang - 2:6.2.0-37 -- add qemu-system-x86_64, qemu-system-aarch64, qemu-system-arm rpm package build - -* Thu May 26 2022 Jun Yang - 2:6.2.0-36 -- Remove unnecessary dependency of kernel package - -* Sat May 21 2022 yezengruan - 2:6.2.0-35 -- hw/intc/arm_gicv3: Check for !MEMTX_OK instead of MEMTX_ERROR (CVE-2021-3750) -- softmmu/physmem: Simplify flatview_write and address_space_access_valid -- softmmu/physmem: Introduce MemTxAttrs::memory field and MEMTX_ACCESS_ERROR - -* Tue May 10 2022 yezengruan - 2:6.2.0-34 -- display/qxl-render: fix race condition in qxl_cursor (CVE-2021-4207) -- ui/cursor: fix integer overflow in cursor_alloc (CVE-2021-4206) - -* Wed Apr 27 2022 yezengruan - 6.2.0-33 -- update the format of changelog - -* Wed Apr 27 2022 yezengruan - 6.2.0-32 -- vfio/pci: Ascend710 change to bar2 quirk - -* Fri Apr 15 2022 yezengruan - 6.2.0-31 -- vhost-vsock: detach the virqueue element in case of error (CVE-2022-26354) -- virtio-net: fix map leaking on error during receive (CVE-2022-26353) - -* Wed Mar 30 2022 yezengruan - 6.2.0-30 -- scsi-bus: fix incorrect call for blk_error_retry_reset_timeout() -- Revert "monitor: limit io error qmp event to at most once per 60s" - -* Fri Mar 25 2022 Jinhua Cao - 6.2.0-29 -- qemu-img create: 'cache' paramter only use for reg file image - -* Thu Mar 24 2022 Yan Wang - 6.2.0-28 -- spec: add hw-usb-host rpm package - -* Fri Mar 18 2022 yezengruan - 6.2.0-27 -- coro: support live patch for libcare -- add patch for sw64 support - -* Tue Mar 15 2022 jiangdawei - 6.2.0-26 -- cflags: add ftls-mode=initial-exec - -* Tue Mar 15 2022 yezengruan - 6.2.0-25 -- sw_64: Add sw64 architecture support -- update BinDir - -* Mon Mar 14 2022 jiangdawei - 6.2.0-24 -- qemu.spec: Add --enable-debug parameter to configure - -* Thu Mar 03 2022 Chen Qun - 6.2.0-23 -- tools/virtiofsd: Add rseq syscall to the seccomp allowlist - -* Thu Mar 03 2022 Chen Qun - 6.2.0-23 -- scsi-bus: fix unmatched object_unref() - -* Sat Feb 26 2022 Yan Wang - 6.2.0-22 -- pl011-reset-read-FIFO-when-UARTTIMSC-0-UARTICR-0xfff.patch -- qcow2-fix-memory-leak-in-qcow2_read_extensions.patch -- scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch -- pcie-Add-pcie-root-port-fast-plug-unplug-feature.patch -- pcie-Compat-with-devices-which-do-not-support-Link-W.patch - -* Wed Feb 23 2022 Chen Qun - 6.2.0-21 -- acpi/madt: Factor out the building of MADT GICC struct -- hw/arm/virt: Assign virt_madt_cpu_entry to acpi_ged madt_cpu hook -- arm/virt/acpi: Factor out CPPC building from DSDT CPU aml -- acpi/cpu: Prepare build_cpus_aml for arm virt -- acpi/ged: Extend ACPI GED to support CPU hotplug -- arm/cpu: assign arm_get_arch_id handler to get_arch_id hook -- tests/acpi/bios-tables-test: Allow changes to virt/DSDT file -- arm/virt: Attach ACPI CPU hotplug support to virt -- tests/acpi/bios-table-test: Update expected virt/DSDT file -- arm/virt: Add CPU hotplug framework -- arm/virt: Add CPU topology support -- test/numa: Adjust aarch64 numa test -- hw/arm/virt: Factor out some CPU init codes to pre_plug hook -- hw/arm/boot: Add manually register and trigger of CPU reset -- arm/virt/gic: Construct irqs connection from create_gic -- intc/gicv3_common: Factor out arm_gicv3_common_cpu_realize -- intc/gicv3_cpuif: Factor out gicv3_init_one_cpuif -- intc/kvm_gicv3: Factor out kvm_arm_gicv3_cpu_realize -- hw/intc/gicv3: Add CPU hotplug realize hook -- accel/kvm: Add pre-park vCPU support -- intc/gicv3: Add pre-sizing capability to GICv3 -- acpi/madt: Add pre-sizing capability to MADT GICC struct -- arm/virt: Add cpu_hotplug_enabled field -- arm/virt/acpi: Extend cpufreq to support max_cpus -- arm/virt: Pre-sizing MADT-GICC GICv3 and Pre-park KVM vCPU -- arm/virt: Start up CPU hot-plug and cold-plug - -* Mon Feb 21 2022 Chen Qun - 6.2.0-20 -- i386/cpu: fix compile error in all target configure - -* Mon Feb 21 2022 Chen Qun - 6.2.0-19 -- pl031: support rtc-timer property for pl031 - -* Mon Feb 21 2022 Chen Qun - 6.2.0-19 -- target/arm: Fix some compile errors - -* Mon Feb 21 2022 Chen Qun - 6.2.0-19 -- Revert "qmp: add command to query used memslots of vhost-net and vhost-user" - -* Thu Feb 17 2022 imxcc - 6.2.0-19 -- qapi/machine.json: Fix incorrect description for die-id -- tests/unit/test-smp-parse: Pass machine type as -- tests/unit/test-smp-parse: Split the 'generic' test in -- tests/unit/test-smp-parse: Add 'smp-with-dies' machine -- tests/unit/test-smp-parse: Add 'smp-generic-invalid' -- tests/unit/test-smp-parse: Add 'smp-generic-valid' -- tests/unit/test-smp-parse: Simplify pointer to compound -- tests/unit/test-smp-parse: Constify some pointer/struct -- hw/core: Rename smp_parse() -> -- qemu-options: Improve readability of SMP related Docs -- hw/core/machine: Introduce CPU cluster topology support -- tests/unit/test-smp-parse: Add testcases for CPU -- tests/unit/test-smp-parse: No need to explicitly zero -- tests/unit/test-smp-parse: Keep default MIN/MAX CPUs in -- hw/arm/virt: Support CPU cluster on ARM virt machine -- hw/arm/virt: Support cluster level in DT cpu-map -- hw/acpi/aml-build: Improve scalability of PPTT -- tests/acpi/bios-tables-test: Allow changes to virt/PPTT -- hw/acpi/aml-build: Support cluster level in PPTT -- tests/acpi/bios-table-test: Update expected virt/PPTT -- update BinDir -- softmmu/device_tree: Silence compiler warning with -- softmmu/device_tree: Remove redundant pointer -- hw/arm64: add vcpu cache info support -- update BinDir -- arm64: Add the cpufreq device to show cpufreq info to -- update BinDir - -* Thu Feb 17 2022 imxcc - 6.2.0-18 -- bios-tables-test: Update expected q35/SSDT.dimmpxm file -- spec: add BinDir - -* Tue Feb 15 2022 Liuxiangdong - 6.2.0-17 -- feature: disable spice protocol - -* Mon Feb 14 2022 Chen Qun - 6.2.0-16 -- log: Delete redudant qemu_log - -* Mon Feb 14 2022 Chen Qun - 6.2.0-15 -- qemu-img: add qemu-img direct create - -* Mon Feb 14 2022 eillon - 6.2.0-15 -- seabios: add check to avoid dereference NULL pointer - -* Sat Feb 12 2022 Chen Qun - 6.2.0-14 -- bugfix: irq: Avoid covering object refcount of qemu_irq - -* Sat Feb 12 2022 Chen Qun - 6.2.0-13 -- virtio-scsi: bugfix: fix qemu crash for hotplug scsi disk with dataplane -- virtio: net-tap: bugfix: del net client if net_init_tap_one failed -- virtio: bugfix: clean up callback when del virtqueue -- virtio-net: bugfix: do not delete netdev before virtio net -- virtio-net: fix max vring buf size when set ring num -- virtio: check descriptor numbers -- virtio: bugfix: add rcu_read_lock when vring_avail_idx is called -- virtio: print the guest virtio_net features that host does not support -- virtio: bugfix: check the value of caches before accessing it -- virtio-net: set the max of queue size to 4096 -- virtio-net: update the default and max of rx/tx_queue_size -- vhost-user: add unregister_savevm when vhost-user cleanup -- qemu-img: block: dont blk_make_zero if discard_zeroes false -- vhost-user: Add support reconnect vhost-user socket -- vhost-user: Set the acked_features to vm's featrue -- vhost-user: add vhost_set_mem_table when vm load_setup at destination -- vhost-user: add separate memslot counter for vhost-user -- vhost-user: quit infinite loop while used memslots is more than the backend limit -- qmp: add command to query used memslots of vhost-net and vhost-user -- vhost-user-scsi: add support for SPDK hot upgrade -- i6300esb watchdog: bugfix: Add a runstate transition - -* Sat Feb 12 2022 Chen Qun - 6.2.0-13 -- bugfix: fix some illegal memory access and memory leak -- bugfix: fix possible memory leak -- bugfix: fix eventfds may double free when vm_id reused in ivshmem -- block/mirror: fix file-system went to read-only after block-mirror -- bugfix: fix mmio information leak and ehci vm escape 0-day vulnerability -- target-i386: Fix the RES memory inc which caused by the coroutine created - -* Sat Feb 12 2022 Chen Qun - 6.2.0-13 -- log: Add log at boot & cpu init for aarch64 -- feature: Add log for each modules -- feature: Add logs for vm start and destroy - -* Sat Feb 12 2022 Chen Qun - 6.2.0-12 -- linux-headers: update against 5.10 and manual clear vfio dirty log series -- vfio: Maintain DMA mapping range for the container -- vfio/migration: Add support for manual clear vfio dirty log -- update-linux-headers: Import iommu.h -- vfio.h and iommu.h header update against 5.10 -- memory: Add new fields in IOTLBEntry -- hw/arm/smmuv3: Improve stage1 ASID invalidation -- hw/arm/smmu-common: Allow domain invalidation for NH_ALL/NSNH_ALL -- memory: Add IOMMU_ATTR_VFIO_NESTED IOMMU memory region attribute -- memory: Add IOMMU_ATTR_MSI_TRANSLATE IOMMU memory region attribute -- memory: Introduce IOMMU Memory Region inject_faults API -- iommu: Introduce generic header -- pci: introduce PCIPASIDOps to PCIDevice -- vfio: Force nested if iommu requires it -- vfio: Introduce hostwin_from_range helper -- vfio: Introduce helpers to DMA map/unmap a RAM section -- vfio: Set up nested stage mappings -- vfio: Pass stage 1 MSI bindings to the host -- vfio: Helper to get IRQ info including capabilities -- vfio/pci: Register handler for iommu fault -- vfio/pci: Set up the DMA FAULT region -- vfio/pci: Implement the DMA fault handler -- hw/arm/smmuv3: Advertise MSI_TRANSLATE attribute -- hw/arm/smmuv3: Store the PASID table GPA in the translation config -- hw/arm/smmuv3: Fill the IOTLBEntry arch_id on NH_VA invalidation -- hw/arm/smmuv3: Fill the IOTLBEntry leaf field on NH_VA invalidation -- hw/arm/smmuv3: Pass stage 1 configurations to the host -- hw/arm/smmuv3: Implement fault injection -- hw/arm/smmuv3: Allow MAP notifiers -- pci: Add return_page_response pci ops -- vfio/pci: Implement return_page_response page response callback -- vfio/common: Avoid unmap ram section at vfio_listener_region_del() in nested mode -- vfio: Introduce helpers to mark dirty pages of a RAM section -- vfio: Add vfio_prereg_listener_log_sync in nested stage -- vfio: Add vfio_prereg_listener_log_clear to re-enable mark dirty pages -- vfio: Add vfio_prereg_listener_global_log_start/stop in nested stage -- hw/arm/smmuv3: Post-load stage 1 configurations to the host -- vfio/common: Fix incorrect address alignment in vfio_dma_map_ram_section -- vfio/common: Add address alignment check in vfio_listener_region_del - -* Sat Feb 12 2022 Chen Qun - 6.2.0-11 -- log: Add some logs on VM runtime path -- qdev/monitors: Fix reundant error_setg of qdev_add_device -- bios-tables-test: Allow changes to q35/SSDT.dimmpxm file -- smbios: Add missing member of type 4 for smbios 3.0 -- net: eepro100: validate various address valuesi(CVE-2021-20255) -- pci: check bus pointer before dereference -- ide: ahci: add check to avoid null dereference (CVE-2019-12067) -- tap: return err when tap TUNGETIFF fail -- xhci: check reg to avoid OOB read -- monitor: Discard BLOCK_IO_ERROR event when VM rebooted -- monitor: limit io error qmp event to at most once per 60s - -* Sat Feb 12 2022 Chen Qun - 6.2.0-11 -- util/log: add CONFIG_DISABLE_QEMU_LOG macro - -* Sat Feb 12 2022 Yan Wang - 6.2.0-11 -- ipxe: IPv6 add support for IPv6 protocol -- u-boot: Use post increment only in inffast.c - -* Sat Feb 12 2022 jiangdongxu - 6.2.0-10 -- seabios: convert value of be16_to_cpu to u64 before shifting -- seabios: do not give back high ram -- seabios: fix memory leak when pci check -- seabios: drop yield() in smp_setup() -- seabios: increase the seabios minibiostable -- seabios: increase the seabios high mem zone size - -* Fri Feb 11 2022 Chen Qun - 6.2.0-9 -- hw/net/rocker: fix security vulnerability -- tests: Disable filemonitor testcase - -* Fri Feb 11 2022 Chen Qun - 6.2.0-8 -- hw/usb: reduce the vpcu cost of UHCI when VNC disconnect - -* Fri Feb 11 2022 Chen Qun - 6.2.0-8 -- freeclock: add qmp command to get time offset of vm in seconds -- freeclock: set rtc_date_diff for arm -- freeclock: set rtc_date_diff for X86 - -* Fri Feb 11 2022 Chen Qun - 6.2.0-8 -- target/arm: convert isar regs to array -- target/arm: parse cpu feature related options -- target/arm: register CPU features for property -- target/arm: Allow ID registers to synchronize to KVM -- target/arm: introduce CPU feature dependency mechanism -- target/arm: introduce KVM_CAP_ARM_CPU_FEATURE -- target/arm: Add CPU features to query-cpu-model-expansion -- target/arm: Add more CPU features -- target/arm: ignore evtstrm and cpuid CPU features -- target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest -- target/arm: Fix write redundant values to kvm -- target/arm: clear EL2 and EL3 only when kvm is not enabled -- target/arm: Update the ID registers of Kunpeng-920 - -* Fri Feb 11 2022 Chen Qun - 6.2.0-8 -- i386: cache passthrough: Update Intel CPUID4.EAX[25:14] based on vCPU topo -- i386: cache passthrough: Update AMD 8000_001D.EAX[25:14] based on vCPU topo - -* Fri Feb 11 2022 Chen Qun - 6.2.0-8 -- nbd/server.c: fix invalid read after client was already free -- qemu-nbd: make native as the default aio mode -- qemu-nbd: set timeout to qemu-nbd socket -- qemu-pr: fixed ioctl failed for multipath disk -- block: enable cache mode of empty cdrom -- block: disallow block jobs when there is a BDRV_O_INACTIVE flag -- scsi: cdrom: Fix crash after remote cdrom detached -- block: bugfix: disable process AIO when attach scsi disk -- block: bugfix: Don't pause vm when NOSPACE EIO happened -- scsi: bugfix: fix division by zero - -* Fri Feb 11 2022 imxcc - 6.2.0-8 -- migration: skip cache_drop for bios bootloader and -- ps2: fix oob in ps2 kbd -- Currently, while kvm and qemu can not handle some kvm -- cpu/features: fix bug for memory leakage -- monitor/qmp: drop inflight rsp if qmp client broken -- oslib-posix: optimise vm startup time for 1G hugepage - -* Fri Feb 11 2022 imxcc - 6.2.0-7 -- scsi-bus: Refactor the code that retries requests -- scsi-disk: Add support for retry on errors -- block-backend: Stop retrying when draining -- block: Add sanity check when setting retry parameters - -* Fri Feb 11 2022 imxcc - 6.2.0-7 -- vfio/pci: Ascend310 need 4Bytes quirk in bar4 -- vfio/pci: Ascend710 need 4Bytes quirk in bar0 -- vfio/pci: Ascend910 need 4Bytes quirk in bar0 - -* Fri Feb 11 2022 imxcc - 6.2.0-7 -- hugepages: hugepages files maybe leftover -- Patch0024: target-i386: Modify the VM's physical bits value set - -* Fri Feb 11 2022 Yan Wang - 6.2.0-7 -- log: disable qemu_log function for "make check V=1" - -* Fri Feb 11 2022 Yan Wang - 6.2.0-6 -- chardev/baum: disable unused brlapi - -* Fri Feb 11 2022 imxcc - 6.2.0-5 -- Revert "cpu: parse +/- feature to avoid failure" -- Revert "cpu: add Cortex-A72 processor kvm target support" -- cpu: add Cortex-A72 processor kvm target support - -* Thu Feb 10 2022 imxcc - 6.2.0-4 -- qapi/block-core: Add retry option for error action -- qapi/block-core: Add retry option for error action -- block-backend: Introduce retry timer -- block-backend: Add device specific retry callback -- block-backend: Enable retry action on errors -- block-backend: Add timeout support for retry -- block: Add error retry param setting -- virtio_blk: Add support for retry on errors -- vhost: cancel migration when vhost-user restarted -- migration: Add multi-thread compress method -- migration: Refactoring multi-thread compress migration -- migration: Add multi-thread compress ops -- migration: Add zstd support in multi-thread compression -- migration: Add compress_level sanity check -- doc: Update multi-thread compression doc - -* Wed Feb 09 2022 Chen Qun - 6.2.0-3 -- cpu: parse +/- feature to avoid failure -- cpu: add Kunpeng-920 cpu support -- cpu: add Cortex-A72 processor kvm target support -- add Phytium's CPU models: FT-2000+ and Tengyun-S2500. - -* Tue Feb 8 2022 Xiangdong Liu - 6.2.0-2 -- net/dump.c: Suppress spurious compiler warning - -* Thu Jan 27 2022 Xiangdong Liu - 6.2.0-1 +* Thu Feb 29 2024 Tao Yang - 11:8.2.0-1 - Package init diff --git a/qga-Fix-memory-leak-when-output-stream-is-unused.patch b/qga-Fix-memory-leak-when-output-stream-is-unused.patch deleted file mode 100644 index b05a65c262263afc90258847c63fcb063c43787c..0000000000000000000000000000000000000000 --- a/qga-Fix-memory-leak-when-output-stream-is-unused.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 877d97f7e7b88c9cb8754bece152dc27a2a0f47a Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 16 Oct 2023 10:22:03 +0800 -Subject: [PATCH] qga: Fix memory leak when output stream is unused - -cheery-pick from d6f67b83b81bf49b5c62e77143ed39c020e51830 - -If capture-output is requested but one of the channels goes unused (eg. -we attempt to capture stderr but the command never writes to stderr), we -can leak memory. - -guest_exec_output_watch() is (from what I understand) unconditionally -called for both streams if output capture is requested. The first call -will always pass the `p->size == p->length` check b/c both values are -0. Then GUEST_EXEC_IO_SIZE bytes will be allocated for the stream. - -But when we reap the exited process there's a `gei->err.length > 0` -check to actually free the buffer. Which does not get run if the command -doesn't write to the stream. - -Fix by making free() unconditional. - -Reviewed-by: Konstantin Kostiuk -Signed-off-by: Daniel Xu -Signed-off-by: Konstantin Kostiuk -Signed-off-by: qihao_yewu ---- - qga/commands.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/qga/commands.c b/qga/commands.c -index 80501e4a73..05f89725be 100644 ---- a/qga/commands.c -+++ b/qga/commands.c -@@ -210,16 +210,16 @@ GuestExecStatus *qmp_guest_exec_status(int64_t pid, Error **errp) - if (gei->out.length > 0) { - ges->has_out_data = true; - ges->out_data = g_base64_encode(gei->out.data, gei->out.length); -- g_free(gei->out.data); - ges->has_out_truncated = gei->out.truncated; - } -+ g_free(gei->out.data); - - if (gei->err.length > 0) { - ges->has_err_data = true; - ges->err_data = g_base64_encode(gei->err.data, gei->err.length); -- g_free(gei->err.data); - ges->has_err_truncated = gei->err.truncated; - } -+ g_free(gei->err.data); - - QTAILQ_REMOVE(&guest_exec_state.processes, gei, next); - g_free(gei); --- -2.41.0.windows.1 - diff --git a/qga-Fix-suspend-on-Linux-guests-without-systemd.patch b/qga-Fix-suspend-on-Linux-guests-without-systemd.patch deleted file mode 100644 index 309e7276a603b81cc54f9a0e38d6a5d6621a5f24..0000000000000000000000000000000000000000 --- a/qga-Fix-suspend-on-Linux-guests-without-systemd.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 9f4819201fb35b419ea21d37755c4cb62454a270 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Thu, 10 Aug 2023 13:59:53 +0800 -Subject: [PATCH] qga: Fix suspend on Linux guests without systemd - -cheery-pick from 86dcb6ab9b603450eb6d896cdc95286de2c7d561 - -Allow the Linux guest agent to attempt each of the suspend methods -(systemctl, pm-* and writing to /sys) in turn. - -Prior to this guests without systemd failed to suspend due to -`guest_suspend` returning early regardless of the return value of -`systemd_supports_mode`. - -Signed-off-by: Mark Somerville -Reviewed-by: Konstantin Kostiuk -Signed-off-by: Konstantin Kostiuk -Signed-off-by: qihao_yewu ---- - qga/commands-posix.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/qga/commands-posix.c b/qga/commands-posix.c -index 75dbaab68e..4e06271889 100644 ---- a/qga/commands-posix.c -+++ b/qga/commands-posix.c -@@ -2104,10 +2104,10 @@ static void guest_suspend(SuspendMode mode, Error **errp) - if (systemd_supports_mode(mode, &local_err)) { - mode_supported = true; - systemd_suspend(mode, &local_err); -- } - -- if (!local_err) { -- return; -+ if (!local_err) { -+ return; -+ } - } - - error_free(local_err); -@@ -2116,10 +2116,10 @@ static void guest_suspend(SuspendMode mode, Error **errp) - if (pmutils_supports_mode(mode, &local_err)) { - mode_supported = true; - pmutils_suspend(mode, &local_err); -- } - -- if (!local_err) { -- return; -+ if (!local_err) { -+ return; -+ } - } - - error_free(local_err); --- -2.41.0.windows.1 - diff --git a/qga-Improve-guest-exec-status-error-message.patch b/qga-Improve-guest-exec-status-error-message.patch deleted file mode 100644 index debbba7942c2ece1ea3f38ec47cfae531a8ace81..0000000000000000000000000000000000000000 --- a/qga-Improve-guest-exec-status-error-message.patch +++ /dev/null @@ -1,42 +0,0 @@ -From f28bc5e3a6418d8477e84b52e06dcab5db7cbf15 Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Mon, 27 Nov 2023 15:52:06 +0800 -Subject: [PATCH] qga: Improve guest-exec-status error message -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from b665165938d89c8e1f83f970d3722f507ce87acd - -When the PID passed to guest-exec-status does not exist, we report - - "Invalid parameter 'pid'" - -Improve this to - - "PID 1234 does not exist" - -Signed-off-by: Markus Armbruster -Message-ID: <20231031111059.3407803-4-armbru@redhat.com> -Reviewed-by: Konstantin Kostiuk -Reviewed-by: Philippe Mathieu-Daudé ---- - qga/commands.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/qga/commands.c b/qga/commands.c -index 05f89725be..9fe73786fc 100644 ---- a/qga/commands.c -+++ b/qga/commands.c -@@ -156,7 +156,7 @@ GuestExecStatus *qmp_guest_exec_status(int64_t pid, Error **errp) - - gei = guest_exec_info_find(pid); - if (gei == NULL) { -- error_setg(errp, QERR_INVALID_PARAMETER, "pid"); -+ error_setg(errp, "PID " PRId64 " does not exist"); - return NULL; - } - --- -2.27.0 - diff --git a/qga-vss-win32-fix-warning-for-clang-15.patch b/qga-vss-win32-fix-warning-for-clang-15.patch deleted file mode 100644 index f4dfc2cbecc8b83e8929b4d879eb25c81ec8b448..0000000000000000000000000000000000000000 --- a/qga-vss-win32-fix-warning-for-clang-15.patch +++ /dev/null @@ -1,47 +0,0 @@ -From b9212c3d72363f67d621dd4e16e507e4a677158e Mon Sep 17 00:00:00 2001 -From: qihao -Date: Tue, 27 Jun 2023 22:45:24 +0800 -Subject: [PATCH] qga/vss-win32: fix warning for clang++-15 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from a3f531cee66b12041098f7a809c2a7d6ecb6ad7d - -Reported when compiling with clang-windows-arm64. - -../qga/vss-win32/install.cpp:537:9: error: variable 'hr' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized] - if (!(ControlService(service, SERVICE_CONTROL_STOP, NULL))) { - ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -../qga/vss-win32/install.cpp:545:12: note: uninitialized use occurs here - return hr; - ^~ - -Signed-off-by: Pierrick Bouvier -Fixes: 917ebcb170 ("qga-win: Fix QGA VSS Provider service stop failure") -Reviewed-by: Konstantin Kostiuk -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Kostiantyn Kostiuk -(cherry picked from commit 0fcd574b025fccdf14d5140687cafe2bc30b634f) -Signed-off-by: Michael Tokarev -Signed-off-by: qihao_yewu ---- - qga/vss-win32/install.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp -index 40de133774..e90a03c1cf 100644 ---- a/qga/vss-win32/install.cpp -+++ b/qga/vss-win32/install.cpp -@@ -513,7 +513,7 @@ namespace _com_util - /* Stop QGA VSS provider service using Winsvc API */ - STDAPI StopService(void) - { -- HRESULT hr; -+ HRESULT hr = S_OK; - SC_HANDLE manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - SC_HANDLE service = NULL; - --- -2.41.0.windows.1 - diff --git a/qga-win-vss-requester_freeze-changes.patch b/qga-win-vss-requester_freeze-changes.patch deleted file mode 100644 index 18ee0aa8efc5e3eff5dd824c4742dc0fc71175bb..0000000000000000000000000000000000000000 --- a/qga-win-vss-requester_freeze-changes.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 977331440154d500d434258c61eb3542e01dea38 Mon Sep 17 00:00:00 2001 -From: jipengfei -Date: Tue, 4 Apr 2023 18:36:27 +0800 -Subject: [PATCH] qga/win/vss: requester_freeze changes - -Change requester_freeze so that the VSS backup type queried from the registry - -cheery-pick from 0961f929c66ceb5e9e95756bfe418b9ef34510eb - -Signed-off-by: jipengfei_yewu -Signed-off-by: Kfir Manor -Reviewed-by: Konstantin Kostiuk -Signed-off-by: Konstantin Kostiuk ---- - qga/vss-win32/requester.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp -index 940a2c8f55..418b9b6e4e 100644 ---- a/qga/vss-win32/requester.cpp -+++ b/qga/vss-win32/requester.cpp -@@ -248,6 +248,7 @@ void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset) - int num_fixed_drives = 0, i; - int num_mount_points = 0; - -+ VSS_BACKUP_TYPE vss_bt = get_vss_backup_type(); - if (vss_ctx.pVssbc) { /* already frozen */ - *num_vols = 0; - return; -@@ -294,7 +295,7 @@ void requester_freeze(int *num_vols, void *mountpoints, ErrorSet *errset) - goto out; - } - -- hr = vss_ctx.pVssbc->SetBackupState(true, true, VSS_BT_FULL, false); -+ hr = vss_ctx.pVssbc->SetBackupState(true, true, vss_bt, false); - if (FAILED(hr)) { - err_set(errset, hr, "failed to set backup state"); - goto out; --- -2.27.0 - diff --git a/qga-win32-Remove-change-action-from-MSI-installer.patch b/qga-win32-Remove-change-action-from-MSI-installer.patch deleted file mode 100644 index 3ebd4e7fd4cde1d4984b5ba1d9752a5d2a698fe2..0000000000000000000000000000000000000000 --- a/qga-win32-Remove-change-action-from-MSI-installer.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 38a72d2fbaf732d0804fefca034c24b2ad068ad1 Mon Sep 17 00:00:00 2001 -From: Konstantin Kostiuk -Date: Fri, 3 Mar 2023 21:20:07 +0200 -Subject: [PATCH] qga/win32: Remove change action from MSI installer - -Remove the 'change' button from "Programs and Features" because it does -not checks if a user is an admin or not. The installer has no components -to choose from and always installs everything. So the 'change' button is -not obviously needed but can create a security issue. - -resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2167423 -fixes: CVE-2023-0664 (part 1 of 2) - -Signed-off-by: Konstantin Kostiuk -Reviewed-by: Yan Vugenfirer -Reported-by: Brian Wiltse ---- - qga/installer/qemu-ga.wxs | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs -index 0950e8c6be..b62e709a4c 100644 ---- a/qga/installer/qemu-ga.wxs -+++ b/qga/installer/qemu-ga.wxs -@@ -58,6 +58,7 @@ - /> - - -+ - --- -2.41.0.windows.1 - diff --git a/qga-win32-Use-rundll-for-VSS-installation.patch b/qga-win32-Use-rundll-for-VSS-installation.patch deleted file mode 100644 index 36ddb7f251cfed771c67f7490cea3b3bfdaaa9bf..0000000000000000000000000000000000000000 --- a/qga-win32-Use-rundll-for-VSS-installation.patch +++ /dev/null @@ -1,99 +0,0 @@ -From bc472314a51895f67112e3ac35439df63292f101 Mon Sep 17 00:00:00 2001 -From: Konstantin Kostiuk -Date: Fri, 3 Mar 2023 21:20:08 +0200 -Subject: [PATCH] qga/win32: Use rundll for VSS installation - -The custom action uses cmd.exe to run VSS Service installation -and removal which causes an interactive command shell to spawn. -This shell can be used to execute any commands as a SYSTEM user. -Even if call qemu-ga.exe directly the interactive command shell -will be spawned as qemu-ga.exe is a console application and used -by users from the console as well as a service. - -As VSS Service runs from DLL which contains the installer and -uninstaller code, it can be run directly by rundll32.exe without -any interactive command shell. - -Add specific entry points for rundll which is just a wrapper -for COMRegister/COMUnregister functions with proper arguments. - -resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2167423 -fixes: CVE-2023-0664 (part 2 of 2) - -Signed-off-by: Konstantin Kostiuk -Reviewed-by: Yan Vugenfirer -Reported-by: Brian Wiltse ---- - qga/installer/qemu-ga.wxs | 10 +++++----- - qga/vss-win32/install.cpp | 9 +++++++++ - qga/vss-win32/qga-vss.def | 2 ++ - 3 files changed, 16 insertions(+), 5 deletions(-) - -diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs -index b62e709a4c..11b66a22e6 100644 ---- a/qga/installer/qemu-ga.wxs -+++ b/qga/installer/qemu-ga.wxs -@@ -143,22 +143,22 @@ - - - -- -+ - - - - - - -diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp -index e90a03c1cf..8b7400e4e5 100644 ---- a/qga/vss-win32/install.cpp -+++ b/qga/vss-win32/install.cpp -@@ -352,6 +352,15 @@ out: - return hr; - } - -+STDAPI_(void) CALLBACK DLLCOMRegister(HWND, HINSTANCE, LPSTR, int) -+{ -+ COMRegister(); -+} -+ -+STDAPI_(void) CALLBACK DLLCOMUnregister(HWND, HINSTANCE, LPSTR, int) -+{ -+ COMUnregister(); -+} - - static BOOL CreateRegistryKey(LPCTSTR key, LPCTSTR value, LPCTSTR data) - { -diff --git a/qga/vss-win32/qga-vss.def b/qga/vss-win32/qga-vss.def -index 927782c31b..ee97a81427 100644 ---- a/qga/vss-win32/qga-vss.def -+++ b/qga/vss-win32/qga-vss.def -@@ -1,6 +1,8 @@ - LIBRARY "QGA-PROVIDER.DLL" - - EXPORTS -+ DLLCOMRegister -+ DLLCOMUnregister - COMRegister PRIVATE - COMUnregister PRIVATE - DllCanUnloadNow PRIVATE --- -2.41.0.windows.1 - diff --git a/qmp-add-command-to-query-used-memslots-of-vhost-net-.patch b/qmp-add-command-to-query-used-memslots-of-vhost-net-.patch deleted file mode 100644 index 10d69dd73c18a4748c4afcc7f89acac49b4d3ae4..0000000000000000000000000000000000000000 --- a/qmp-add-command-to-query-used-memslots-of-vhost-net-.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 1545a60a8b78490c7dc8909b7012bca63dba63cd Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Sat, 12 Feb 2022 15:41:08 +0800 -Subject: [PATCH] qmp: add command to query used memslots of vhost-net and - vhost-user - -Signed-off-by: Jinhua Cao ---- - hw/virtio/vhost-backend.c | 2 +- - hw/virtio/vhost-user.c | 2 +- - include/hw/virtio/vhost-backend.h | 2 ++ - monitor/qmp-cmds.c | 12 ++++++++++++ - qapi/net.json | 18 ++++++++++++++++++ - qapi/pragma.json | 4 +++- - 6 files changed, 37 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c -index 2acfb750fd..d8e1710758 100644 ---- a/hw/virtio/vhost-backend.c -+++ b/hw/virtio/vhost-backend.c -@@ -300,7 +300,7 @@ static void vhost_kernel_set_used_memslots(struct vhost_dev *dev) - vhost_kernel_used_memslots = dev->mem->nregions; - } - --static unsigned int vhost_kernel_get_used_memslots(void) -+unsigned int vhost_kernel_get_used_memslots(void) - { - return vhost_kernel_used_memslots; - } -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index 176cae9244..8f69a3b850 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -2544,7 +2544,7 @@ static void vhost_user_set_used_memslots(struct vhost_dev *dev) - vhost_user_used_memslots = counter; - } - --static unsigned int vhost_user_get_used_memslots(void) -+unsigned int vhost_user_get_used_memslots(void) - { - return vhost_user_used_memslots; - } -diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h -index a64708f456..7bbc658161 100644 ---- a/include/hw/virtio/vhost-backend.h -+++ b/include/hw/virtio/vhost-backend.h -@@ -190,4 +190,6 @@ int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev, - - int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd); - -+unsigned int vhost_kernel_get_used_memslots(void); -+unsigned int vhost_user_get_used_memslots(void); - #endif /* VHOST_BACKEND_H */ -diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c -index 98868cee03..f3e80ec8a7 100644 ---- a/monitor/qmp-cmds.c -+++ b/monitor/qmp-cmds.c -@@ -36,6 +36,7 @@ - #include "qapi/qapi-commands-machine.h" - #include "qapi/qapi-commands-misc.h" - #include "qapi/qapi-commands-ui.h" -+#include "qapi/qapi-commands-net.h" - #include "qapi/type-helpers.h" - #include "qapi/qmp/qerror.h" - #include "exec/ramlist.h" -@@ -43,6 +44,7 @@ - #include "hw/acpi/acpi_dev_interface.h" - #include "hw/intc/intc.h" - #include "hw/rdma/rdma.h" -+#include "hw/virtio/vhost-backend.h" - - NameInfo *qmp_query_name(Error **errp) - { -@@ -471,3 +473,13 @@ int64_t qmp_query_rtc_date_diff(Error **errp) - { - return get_rtc_date_diff(); - } -+ -+uint32_t qmp_query_vhost_kernel_used_memslots(Error **errp) -+{ -+ return vhost_kernel_get_used_memslots(); -+} -+ -+uint32_t qmp_query_vhost_user_used_memslots(Error **errp) -+{ -+ return vhost_user_get_used_memslots(); -+} -diff --git a/qapi/net.json b/qapi/net.json -index 7fab2e7cd8..c9ff849eed 100644 ---- a/qapi/net.json -+++ b/qapi/net.json -@@ -696,3 +696,21 @@ - ## - { 'event': 'FAILOVER_NEGOTIATED', - 'data': {'device-id': 'str'} } -+ -+## -+# @query-vhost-kernel-used-memslots: -+# -+# Get vhost-kernel nic used memslots -+# -+# Since: 4.1 -+## -+{ 'command': 'query-vhost-kernel-used-memslots', 'returns': 'uint32' } -+ -+## -+# @query-vhost-user-used-memslots: -+# -+# Get vhost-user nic used memslots -+# -+# Since: 4.1 -+## -+{ 'command': 'query-vhost-user-used-memslots', 'returns': 'uint32' } -diff --git a/qapi/pragma.json b/qapi/pragma.json -index b37f6de445..d35c897acb 100644 ---- a/qapi/pragma.json -+++ b/qapi/pragma.json -@@ -27,7 +27,9 @@ - 'query-tpm-models', - 'query-tpm-types', - 'ringbuf-read', -- 'query-rtc-date-diff' ], -+ 'query-rtc-date-diff', -+ 'query-vhost-user-used-memslots', -+ 'query-vhost-kernel-used-memslots' ], - # Externally visible types whose member names may use uppercase - 'member-name-exceptions': [ # visible in: - 'ACPISlotType', # query-acpi-ospm-status --- -2.27.0 - diff --git a/qom-assert-integer-does-not-overflow.patch b/qom-assert-integer-does-not-overflow.patch deleted file mode 100644 index 6a3314d67584b901aaeb5906f0c238e489ca7006..0000000000000000000000000000000000000000 --- a/qom-assert-integer-does-not-overflow.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 7d94ca45a9c0ef8a4f1917f41496a826ecda90fb Mon Sep 17 00:00:00 2001 -From: "Michael S. Tsirkin" -Date: Fri, 25 Feb 2022 08:40:27 -0500 -Subject: [PATCH 3/6] qom: assert integer does not overflow - -QOM reference counting is not designed with an infinite amount of -references in mind, trying to take a reference in a loop without -dropping a reference will overflow the integer. - -It is generally a symptom of a reference leak (a missing deref, commonly -as part of error handling - such as one fixed here: -https://lore.kernel.org/r/20220228095058.27899-1-sgarzare%40redhat.com ). - -All this can lead to either freeing the object too early (memory -corruption) or never freeing it (memory leak). - -If we happen to dereference at just the right time (when it's wrapping -around to 0), we might eventually assert when dereferencing, but the -real problem is an extra object_ref so let's assert there to make such -issues cleaner and easier to debug. - -Some micro-benchmarking shows using fetch and add this is essentially -free on x86. - -Since multiple threads could be incrementing in parallel, we assert -around INT_MAX to make sure none of these approach the wrap around -point: this way we get a memory leak and not a memory corruption, the -former is generally easier to debug. - -Signed-off-by: Michael S. Tsirkin -Signed-off-by: wanbo ---- - qom/object.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/qom/object.c b/qom/object.c -index 4f0677cca9..5db3974f04 100644 ---- a/qom/object.c -+++ b/qom/object.c -@@ -1167,10 +1167,14 @@ GSList *object_class_get_list_sorted(const char *implements_type, - Object *object_ref(void *objptr) - { - Object *obj = OBJECT(objptr); -+ uint32_t ref; -+ - if (!obj) { - return NULL; - } -- qatomic_inc(&obj->ref); -+ ref = qatomic_fetch_inc(&obj->ref); -+ /* Assert waaay before the integer overflows */ -+ g_assert(ref < INT_MAX); - return obj; - } - --- -2.27.0 - diff --git a/qom-object-Remove-circular-include-dependency.patch b/qom-object-Remove-circular-include-dependency.patch deleted file mode 100644 index f527a3b04c15a0aa76b7cc07efe4b19c94fc5b66..0000000000000000000000000000000000000000 --- a/qom-object-Remove-circular-include-dependency.patch +++ /dev/null @@ -1,41 +0,0 @@ -From e4393667e45bdcf04150ada3840a6d87e3188d36 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 17 Nov 2023 09:13:07 +0000 -Subject: [PATCH] qom/object: Remove circular include dependency mainline - inclusion commit 5bba9bcfbb42e7c016626420e148a1bf1b080835 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -"qom/object.h" doesn't need to include itself. - -Fixes: db1015e92e04 ("Move QOM typedefs and add missing includes") -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Damien Hedde -Reviewed-by: Peter Maydell -Reviewed-by: Markus Armbruster -Message-Id: <20220509084659.52076-1-philippe.mathieu.daude@gmail.com> -Signed-off-by: Laurent Vivier - -Signed-off-by: tangbinzy ---- - include/qom/object.h | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/include/qom/object.h b/include/qom/object.h -index fae096f51c..f658e1e0a0 100644 ---- a/include/qom/object.h -+++ b/include/qom/object.h -@@ -16,7 +16,6 @@ - - #include "qapi/qapi-builtin-types.h" - #include "qemu/module.h" --#include "qom/object.h" - - struct TypeImpl; - typedef struct TypeImpl *Type; --- -2.27.0 - diff --git a/qsd-Unlink-absolute-PID-file-path.patch b/qsd-Unlink-absolute-PID-file-path.patch deleted file mode 100644 index 7c5138ad713432506c1bae7df83e78bdb9c402e8..0000000000000000000000000000000000000000 --- a/qsd-Unlink-absolute-PID-file-path.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 43668bdb7ebaa64536277d4b5b47875e58a3452a Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 21 Nov 2023 07:00:39 +0000 -Subject: [PATCH] qsd: Unlink absolute PID file path mainline inclusion commit - 9d8f8233b9fa525a7e37350fbc18877051128c5d category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -After writing the PID file, we register an atexit() handler to unlink it -when the process terminates. However, if the process has changed its -working directory in the meantime (e.g. in os_setup_post() when -daemonizing), this will not work when the PID file path was relative. -Therefore, pass the absolute path (created with realpath()) to the -unlink() call in the atexit() handler. - -(realpath() needs a path pointing to an existing file, so we cannot use -it before qemu_write_pidfile().) - -Reproducer: -$ cd /tmp -$ qemu-storage-daemon --daemonize --pidfile qsd.pid -$ file qsd.pid -qsd.pid: ASCII text -$ kill $(cat qsd.pid) -$ file qsd.pid -qsd.pid: ASCII text - -(qsd.pid should be gone after the process has terminated.) - -Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2092322 -Signed-off-by: Hanna Reitz -Message-Id: <20220609122701.17172-2-hreitz@redhat.com> -Reviewed-by: Daniel P. Berrangé - -Signed-off-by: tangbinzy ---- - storage-daemon/qemu-storage-daemon.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c -index 52cf17e8ac..f3d8c4ca11 100644 ---- a/storage-daemon/qemu-storage-daemon.c -+++ b/storage-daemon/qemu-storage-daemon.c -@@ -60,6 +60,7 @@ - #include "trace/control.h" - - static const char *pid_file; -+static char *pid_file_realpath; - static volatile bool exit_requested = false; - - void qemu_system_killed(int signal, pid_t pid) -@@ -292,7 +293,7 @@ static void process_options(int argc, char *argv[]) - - static void pid_file_cleanup(void) - { -- unlink(pid_file); -+ unlink(pid_file_realpath); - } - - static void pid_file_init(void) -@@ -308,6 +309,14 @@ static void pid_file_init(void) - exit(EXIT_FAILURE); - } - -+ pid_file_realpath = g_malloc(PATH_MAX); -+ if (!realpath(pid_file, pid_file_realpath)) { -+ error_report("cannot resolve PID file path: %s: %s", -+ pid_file, strerror(errno)); -+ unlink(pid_file); -+ exit(EXIT_FAILURE); -+ } -+ - atexit(pid_file_cleanup); - } - --- -2.27.0 - diff --git a/qtest-npcm7xx_pwm-test-Fix-memory-leak-in-mft_qom_se.patch b/qtest-npcm7xx_pwm-test-Fix-memory-leak-in-mft_qom_se.patch deleted file mode 100644 index 3da09c8d3113e398bf13c8222456c91d7fb63b14..0000000000000000000000000000000000000000 --- a/qtest-npcm7xx_pwm-test-Fix-memory-leak-in-mft_qom_se.patch +++ /dev/null @@ -1,39 +0,0 @@ -From b76d4a1a4d7d0635044cd8542564803318ac5412 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 26 Sep 2023 07:49:12 +0000 -Subject: [PATCH] qtest/npcm7xx_pwm-test: Fix memory leak in mft_qom_set - mainline inclusion commit d412597ec5a8406b2af6aa5fb7740e77c1bd3f8c category: - bugfix - ---------------------------------------------------------------- - -g_strdup_printf() allocated memory for path, we should free it with -g_free() when no longer needed. - -Signed-off-by: Miaoqian Lin -Reviewed-by: Hao Wu -Message-Id: <20220531080921.4704-1-linmq006@gmail.com> -Signed-off-by: Thomas Huth - -Signed-off-by: tangbinzy ---- - tests/qtest/npcm7xx_pwm-test.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c -index a54fd70d27..ddfc120df0 100644 ---- a/tests/qtest/npcm7xx_pwm-test.c -+++ b/tests/qtest/npcm7xx_pwm-test.c -@@ -268,6 +268,9 @@ static void mft_qom_set(QTestState *qts, int index, const char *name, - path, name, value); - /* The qom set message returns successfully. */ - g_assert_true(qdict_haskey(response, "return")); -+ -+ qobject_unref(response); -+ g_free(path); - } - - static uint32_t get_pll(uint32_t con) --- -2.41.0.windows.1 - diff --git a/replay-Fix-declaration-of-replay_read_next_clock.patch b/replay-Fix-declaration-of-replay_read_next_clock.patch deleted file mode 100644 index 5c0049f5f3d44a0fbb2964e747524ada31fb5ffa..0000000000000000000000000000000000000000 --- a/replay-Fix-declaration-of-replay_read_next_clock.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 8c499e212fedfaa4323541d97a33187ea96ba555 Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Thu, 1 Dec 2022 18:58:34 +0800 -Subject: [PATCH 08/17] replay: Fix declaration of replay_read_next_clock -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fixes the build with gcc 13: - -replay/replay-time.c:34:6: error: conflicting types for \ - 'replay_read_next_clock' due to enum/integer mismatch; \ - have 'void(ReplayClockKind)' [-Werror=enum-int-mismatch] - 34 | void replay_read_next_clock(ReplayClockKind kind) - | ^~~~~~~~~~~~~~~~~~~~~~ -In file included from ../qemu/replay/replay-time.c:14: -replay/replay-internal.h:139:6: note: previous declaration of \ - 'replay_read_next_clock' with type 'void(unsigned int)' - 139 | void replay_read_next_clock(unsigned int kind); - | ^~~~~~~~~~~~~~~~~~~~~~ - -Fixes: 8eda206e090 ("replay: recording and replaying clock ticks") -Signed-off-by: Richard Henderson -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Wilfred Mallawa -Reviewed-by: Pavel Dovgalyuk -Signed-off-by: Stefan Hajnoczi -Message-Id: <20221129010547.284051-1-richard.henderson@linaro.org> - -Signed-off-by: tangzhongrui ---- - replay/replay-internal.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/replay/replay-internal.h b/replay/replay-internal.h -index 97649ed8d7..b4238226f4 100644 ---- a/replay/replay-internal.h -+++ b/replay/replay-internal.h -@@ -141,7 +141,7 @@ bool replay_next_event_is(int event); - /*! Reads next clock value from the file. - If clock kind read from the file is different from the parameter, - the value is not used. */ --void replay_read_next_clock(unsigned int kind); -+void replay_read_next_clock(ReplayClockKind kind); - - /* Asynchronous events queue */ - --- -2.27.0 - diff --git a/replay-fix-event-queue-flush-for-qemu-shutdown.patch b/replay-fix-event-queue-flush-for-qemu-shutdown.patch deleted file mode 100644 index 0c129eedb484d01b09ad193255c9de4e15ebd3ea..0000000000000000000000000000000000000000 --- a/replay-fix-event-queue-flush-for-qemu-shutdown.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d15694ef4ae7f7ebdbdac250a8a793ab66254655 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 26 Sep 2023 08:16:21 +0000 -Subject: [PATCH] replay: fix event queue flush for qemu shutdown mainline - inclusion commit c4b8ffcbb8531206e12cf3ad92fa90f7c80ed464 category: bugfix - ---------------------------------------------------------------- - -This patch fixes event queue flush in the case of emulator -shutdown. replay_finish_events should be called when replay_mode -is not cleared. - -Signed-off-by: Pavel Dovgalyuk -Reviewed-by: Richard Henderson -Message-Id: <165364836758.688121.7959245442743676491.stgit@pasha-ThinkPad-X280> -Signed-off-by: Paolo Bonzini - -Signed-off-by: tangbinzy ---- - replay/replay.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/replay/replay.c b/replay/replay.c -index 6df2abc18c..2d3607998a 100644 ---- a/replay/replay.c -+++ b/replay/replay.c -@@ -387,9 +387,8 @@ void replay_finish(void) - g_free(replay_snapshot); - replay_snapshot = NULL; - -- replay_mode = REPLAY_MODE_NONE; -- - replay_finish_events(); -+ replay_mode = REPLAY_MODE_NONE; - } - - void replay_add_blocker(Error *reason) --- -2.41.0.windows.1 - diff --git a/revert-tcg-loongarch64-Fix-tcg_out_mov-Aborted.patch b/revert-tcg-loongarch64-Fix-tcg_out_mov-Aborted.patch deleted file mode 100644 index cf0869e44fd4e75c194d2ac4ff4b9dd241ddead9..0000000000000000000000000000000000000000 --- a/revert-tcg-loongarch64-Fix-tcg_out_mov-Aborted.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7eff40be327d0c591e4b842cd954ec5dabb75848 Mon Sep 17 00:00:00 2001 -From: xianglai li -Date: Tue, 19 Dec 2023 02:34:39 -0500 -Subject: [PATCH] revert "tcg/loongarch64: Fix tcg_out_mov() Aborted" - -openEuler loongarch64 does not support qemu tcg, -so no TCG-related patch is required for synchronization. - -Signed-off-by: xianglai li ---- - tcg/loongarch64/tcg-target.c.inc | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc -index ee7d4d728d..0b28b30002 100644 ---- a/tcg/loongarch64/tcg-target.c.inc -+++ b/tcg/loongarch64/tcg-target.c.inc -@@ -255,9 +255,6 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) - */ - tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO); - break; -- case TCG_TYPE_V128: -- tcg_out_opc_vori_b(s, ret, arg, 0); -- break; - default: - g_assert_not_reached(); - } --- -2.27.0 - diff --git a/s390x-Fix-spelling-errors.patch b/s390x-Fix-spelling-errors.patch deleted file mode 100644 index 192657105faafdd180310d2d955a0455e499040f..0000000000000000000000000000000000000000 --- a/s390x-Fix-spelling-errors.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 8f9bdcfe073479ba0170d3b01023d9a00f3b1e31 Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Thu, 7 Dec 2023 17:47:34 -0800 -Subject: [PATCH] s390x: Fix spelling errors - -mainline inclusion -commit 44ee69ea16bd0390082ed88d4e82d6cea3a18b46 -category: bugfix - ---------------------------------------------------------------- - -Fix typos (discovered with the 'codespell' utility). -Note: Though "migrateable" still seems to be a valid spelling, we change -it to "migratable" since this is the way more common spelling here. - -Message-Id: <20221111182828.282251-1-thuth@redhat.com> -Reviewed-by: Stefan Weil -Reviewed-by: Ilya Leoshkevich -Signed-off-by: Thomas Huth -Signed-off-by: zhujun2 ---- - hw/s390x/ipl.h | 2 +- - hw/s390x/s390-virtio-ccw.c | 6 +++--- - pc-bios/s390-ccw/cio.h | 2 +- - pc-bios/s390-ccw/iplb.h | 2 +- - pc-bios/s390-ccw/start.S | 2 +- - target/s390x/cpu_models.h | 4 ++-- - target/s390x/ioinst.c | 2 +- - target/s390x/tcg/excp_helper.c | 2 +- - target/s390x/tcg/fpu_helper.c | 2 +- - target/s390x/tcg/misc_helper.c | 2 +- - target/s390x/tcg/translate.c | 4 ++-- - target/s390x/tcg/translate_vx.c.inc | 6 +++--- - 12 files changed, 18 insertions(+), 18 deletions(-) - -diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h -index dfc6dfd89c..7fc86e7905 100644 ---- a/hw/s390x/ipl.h -+++ b/hw/s390x/ipl.h -@@ -140,7 +140,7 @@ void s390_ipl_clear_reset_request(void); - * have an offset of 4 + n * 8 bytes within the struct in order - * to keep it double-word aligned. - * The total size of the struct must never exceed 28 bytes. -- * This definition must be kept in sync with the defininition -+ * This definition must be kept in sync with the definition - * in pc-bios/s390-ccw/iplb.h. - */ - struct QemuIplParameters { -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 653587ea62..c84b89ba43 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -345,7 +345,7 @@ static int s390_machine_protect(S390CcwMachineState *ms) - } - - error_setg(&pv_mig_blocker, -- "protected VMs are currently not migrateable."); -+ "protected VMs are currently not migratable."); - rc = migrate_add_blocker(pv_mig_blocker, &local_err); - if (rc) { - ram_block_discard_disable(false); -@@ -434,7 +434,7 @@ static void s390_machine_reset(MachineState *machine) - break; - case S390_RESET_MODIFIED_CLEAR: - /* -- * Susbsystem reset needs to be done before we unshare memory -+ * Subsystem reset needs to be done before we unshare memory - * and lose access to VIRTIO structures in guest memory. - */ - subsystem_reset(); -@@ -447,7 +447,7 @@ static void s390_machine_reset(MachineState *machine) - break; - case S390_RESET_LOAD_NORMAL: - /* -- * Susbsystem reset needs to be done before we unshare memory -+ * Subsystem reset needs to be done before we unshare memory - * and lose access to VIRTIO structures in guest memory. - */ - subsystem_reset(); -diff --git a/pc-bios/s390-ccw/cio.h b/pc-bios/s390-ccw/cio.h -index 1e5d4e92e1..88a88adfd2 100644 ---- a/pc-bios/s390-ccw/cio.h -+++ b/pc-bios/s390-ccw/cio.h -@@ -20,7 +20,7 @@ struct pmcw { - __u32 intparm; /* interruption parameter */ - __u32 qf:1; /* qdio facility */ - __u32 w:1; -- __u32 isc:3; /* interruption sublass */ -+ __u32 isc:3; /* interruption subclass */ - __u32 res5:3; /* reserved zeros */ - __u32 ena:1; /* enabled */ - __u32 lm:2; /* limit mode */ -diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h -index 772d5c57c9..cb6ac8a880 100644 ---- a/pc-bios/s390-ccw/iplb.h -+++ b/pc-bios/s390-ccw/iplb.h -@@ -81,7 +81,7 @@ extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE))); - #define QIPL_FLAG_BM_OPTS_ZIPL 0x40 - - /* -- * This definition must be kept in sync with the defininition -+ * This definition must be kept in sync with the definition - * in hw/s390x/ipl.h - */ - struct QemuIplParameters { -diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S -index 4d5ad21653..6072906df4 100644 ---- a/pc-bios/s390-ccw/start.S -+++ b/pc-bios/s390-ccw/start.S -@@ -19,7 +19,7 @@ _start: - larl %r2, __bss_start - larl %r3, _end - slgr %r3, %r2 /* get sizeof bss */ -- ltgr %r3,%r3 /* bss emtpy? */ -+ ltgr %r3,%r3 /* bss empty? */ - jz done - aghi %r3,-1 - srlg %r4,%r3,8 /* how many 256 byte chunks? */ -diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h -index 74d1f87e4f..fb1adc8b21 100644 ---- a/target/s390x/cpu_models.h -+++ b/target/s390x/cpu_models.h -@@ -24,13 +24,13 @@ struct S390CPUDef { - uint8_t gen; /* hw generation identification */ - uint16_t type; /* cpu type identification */ - uint8_t ec_ga; /* EC GA version (on which also the BC is based) */ -- uint8_t mha_pow; /* Maximum Host Adress Power, mha = 2^pow-1 */ -+ uint8_t mha_pow; /* maximum host address power, mha = 2^pow-1 */ - uint32_t hmfai; /* hypervisor-managed facilities */ - /* base/min features, must never be changed between QEMU versions */ - S390FeatBitmap base_feat; - /* used to init base_feat from generated data */ - S390FeatInit base_init; -- /* deafault features, QEMU version specific */ -+ /* default features, QEMU version specific */ - S390FeatBitmap default_feat; - /* used to init default_feat from generated data */ - S390FeatInit default_init; -diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c -index bdae5090bc..e6347d1801 100644 ---- a/target/s390x/ioinst.c -+++ b/target/s390x/ioinst.c -@@ -285,7 +285,7 @@ void ioinst_handle_stsch(S390CPU *cpu, uint64_t reg1, uint32_t ipb, - /* - * As operand exceptions have a lower priority than access exceptions, - * we check whether the memory area is writeable (injecting the -- * access execption if it is not) first. -+ * access exception if it is not) first. - */ - if (!s390_cpu_virt_mem_check_write(cpu, addr, ar, sizeof(schib))) { - s390_program_interrupt(env, PGM_OPERAND, ra); -diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c -index 4e7648f301..6a4f7585b8 100644 ---- a/target/s390x/tcg/excp_helper.c -+++ b/target/s390x/tcg/excp_helper.c -@@ -551,7 +551,7 @@ try_deliver: - /* don't trigger a cpu_loop_exit(), use an interrupt instead */ - cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT); - } else if (cs->halted) { -- /* unhalt if we had a WAIT PSW somehwere in our injection chain */ -+ /* unhalt if we had a WAIT PSW somewhere in our injection chain */ - s390_cpu_unhalt(cpu); - } - } -diff --git a/target/s390x/tcg/fpu_helper.c b/target/s390x/tcg/fpu_helper.c -index 4067205405..be80b2373c 100644 ---- a/target/s390x/tcg/fpu_helper.c -+++ b/target/s390x/tcg/fpu_helper.c -@@ -89,7 +89,7 @@ static void handle_exceptions(CPUS390XState *env, bool XxC, uintptr_t retaddr) - /* - * invalid/divbyzero cannot coexist with other conditions. - * overflow/underflow however can coexist with inexact, we have to -- * handle it separatly. -+ * handle it separately. - */ - if (s390_exc & ~S390_IEEE_MASK_INEXACT) { - if (s390_exc & ~S390_IEEE_MASK_INEXACT & env->fpc >> 24) { -diff --git a/target/s390x/tcg/misc_helper.c b/target/s390x/tcg/misc_helper.c -index aab9c47747..7a975aaf94 100644 ---- a/target/s390x/tcg/misc_helper.c -+++ b/target/s390x/tcg/misc_helper.c -@@ -326,7 +326,7 @@ uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t r1) - /* same as machine type number in STORE CPU ID, but in EBCDIC */ - snprintf(type, ARRAY_SIZE(type), "%X", cpu->model->def->type); - ebcdic_put(sysib.sysib_111.type, type, 4); -- /* model number (not stored in STORE CPU ID for z/Architecure) */ -+ /* model number (not stored in STORE CPU ID for z/Architecture) */ - ebcdic_put(sysib.sysib_111.model, "QEMU ", 16); - ebcdic_put(sysib.sysib_111.sequence, "QEMU ", 16); - ebcdic_put(sysib.sysib_111.plant, "QEMU", 4); -diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c -index dcc249a197..62fbc90d5e 100644 ---- a/target/s390x/tcg/translate.c -+++ b/target/s390x/tcg/translate.c -@@ -434,7 +434,7 @@ static void gen_program_exception(DisasContext *s, int code) - { - TCGv_i32 tmp; - -- /* Remember what pgm exeption this was. */ -+ /* Remember what pgm exception this was. */ - tmp = tcg_const_i32(code); - tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_code)); - tcg_temp_free_i32(tmp); -@@ -490,7 +490,7 @@ static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2) - - /* - * Note that d2 is limited to 20 bits, signed. If we crop negative -- * displacements early we create larger immedate addends. -+ * displacements early we create larger immediate addends. - */ - if (b2 && x2) { - tcg_gen_add_i64(tmp, regs[b2], regs[x2]); -diff --git a/target/s390x/tcg/translate_vx.c.inc b/target/s390x/tcg/translate_vx.c.inc -index 28bf5a23b6..d1fe4df1b5 100644 ---- a/target/s390x/tcg/translate_vx.c.inc -+++ b/target/s390x/tcg/translate_vx.c.inc -@@ -797,7 +797,7 @@ static DisasJumpType op_vpk(DisasContext *s, DisasOps *o) - } - break; - case 0x94: -- /* If sources and destination dont't overlap -> fast path */ -+ /* If sources and destination don't overlap -> fast path */ - if (v1 != v2 && v1 != v3) { - const uint8_t src_es = get_field(s, m4); - const uint8_t dst_es = src_es - 1; -@@ -1793,7 +1793,7 @@ static DisasJumpType op_vmsl(DisasContext *s, DisasOps *o) - l2 = tcg_temp_new_i64(); - h2 = tcg_temp_new_i64(); - -- /* Multipy both even elements from v2 and v3 */ -+ /* Multiply both even elements from v2 and v3 */ - read_vec_element_i64(l1, get_field(s, v2), 0, ES_64); - read_vec_element_i64(h1, get_field(s, v3), 0, ES_64); - tcg_gen_mulu2_i64(l1, h1, l1, h1); -@@ -1802,7 +1802,7 @@ static DisasJumpType op_vmsl(DisasContext *s, DisasOps *o) - tcg_gen_add2_i64(l1, h1, l1, h1, l1, h1); - } - -- /* Multipy both odd elements from v2 and v3 */ -+ /* Multiply both odd elements from v2 and v3 */ - read_vec_element_i64(l2, get_field(s, v2), 1, ES_64); - read_vec_element_i64(h2, get_field(s, v3), 1, ES_64); - tcg_gen_mulu2_i64(l2, h2, l2, h2); --- -2.27.0 - diff --git a/scripts-entitlement.sh-Use-backward-compatible-cp-fl.patch b/scripts-entitlement.sh-Use-backward-compatible-cp-fl.patch deleted file mode 100644 index 6139fc97205503e47538d872a4bb89f448bf3005..0000000000000000000000000000000000000000 --- a/scripts-entitlement.sh-Use-backward-compatible-cp-fl.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 66da71e852323bf1eb7b75b93cfb13eb748ad10f Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Mon, 4 Dec 2023 10:09:12 +0800 -Subject: [PATCH] scripts/entitlement.sh: Use backward-compatible cp flags - -cherry picked from commit 4006a27c5e44734350009262efb0e2ec8da5ff09 - -Older versions of Mac OS X do not support cp -a. The cp man page indicates -that -a is equivalent to -pPR. - -Signed-off-by: Evan Miller -Message-Id: <40635C6E-059A-4146-B1E2-F6376700EE85@gmail.com> -[Leave out -R, these are files and not directories. - Paolo] -Signed-off-by: Paolo Bonzini -Signed-off-by: Luo Yifan ---- - scripts/entitlement.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/entitlement.sh b/scripts/entitlement.sh -index e2c956a3ac..0f412949ec 100755 ---- a/scripts/entitlement.sh -+++ b/scripts/entitlement.sh -@@ -15,7 +15,7 @@ ENTITLEMENT="$4" - - if $in_place; then - trap 'rm "$DST.tmp"' exit -- cp -af "$SRC" "$DST.tmp" -+ cp -pPf "$SRC" "$DST.tmp" - SRC="$DST.tmp" - else - cd "$MESON_INSTALL_DESTDIR_PREFIX" --- -2.27.0 - diff --git a/scsi-bugfix-fix-division-by-zero.patch b/scsi-bugfix-fix-division-by-zero.patch deleted file mode 100644 index 685c8d54e320562b912323497637ad1b2fd7c9c6..0000000000000000000000000000000000000000 --- a/scsi-bugfix-fix-division-by-zero.patch +++ /dev/null @@ -1,57 +0,0 @@ -From ba8fd8a3d11655da0b51148e69c01b78794a3f69 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 16:34:05 +0800 -Subject: [PATCH] scsi: bugfix: fix division by zero - -Error of PRDM disk may cause divide by zero in -scsi_read_complete(), so add LOG and assert(). - -Signed-off-by: wangjian161 ---- - hw/scsi/scsi-generic.c | 20 ++++++++++++++++++-- - 1 file changed, 18 insertions(+), 2 deletions(-) - -diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c -index 0306ccc7b1..1f51586048 100644 ---- a/hw/scsi/scsi-generic.c -+++ b/hw/scsi/scsi-generic.c -@@ -179,6 +179,10 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len) - (r->req.cmd.buf[1] & 0x01)) { - page = r->req.cmd.buf[2]; - if (page == 0xb0) { -+ if (s->blocksize == 0) { -+ qemu_log("device blocksize is 0!\n"); -+ abort(); -+ } - uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk); - uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk); - -@@ -314,11 +318,23 @@ static void scsi_read_complete(void * opaque, int ret) - /* Snoop READ CAPACITY output to set the blocksize. */ - if (r->req.cmd.buf[0] == READ_CAPACITY_10 && - (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) { -- s->blocksize = ldl_be_p(&r->buf[4]); -+ int new_blocksize = ldl_be_p(&r->buf[4]); -+ if (s->blocksize != new_blocksize) { -+ qemu_log("device id=%s type=%d: blocksize %d change to %d\n", -+ s->qdev.id ? s->qdev.id : "null", s->type, -+ s->blocksize, new_blocksize); -+ } -+ s->blocksize = new_blocksize; - s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL; - } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 && - (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { -- s->blocksize = ldl_be_p(&r->buf[8]); -+ int new_blocksize = ldl_be_p(&r->buf[8]); -+ if (s->blocksize != new_blocksize) { -+ qemu_log("device id=%s type=%d: blocksize %d change to %d\n", -+ s->qdev.id ? s->qdev.id : "null", s->type, -+ s->blocksize, new_blocksize); -+ } -+ s->blocksize = new_blocksize; - s->max_lba = ldq_be_p(&r->buf[0]); - } - blk_set_guest_block_size(s->conf.blk, s->blocksize); --- -2.27.0 - diff --git a/scsi-bus-Refactor-the-code-that-retries-requests.patch b/scsi-bus-Refactor-the-code-that-retries-requests.patch deleted file mode 100644 index 84802c483fb08d03c8e101106f33bdc0ce31461c..0000000000000000000000000000000000000000 --- a/scsi-bus-Refactor-the-code-that-retries-requests.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 391dd8f1458c8db0b848450718af5c69285e5705 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:54 +0800 -Subject: [PATCH 6/9] scsi-bus: Refactor the code that retries requests - -Move the code that retries requests from scsi_dma_restart_bh() to its own, -non-static, function. This will allow us to call it from the -retry_request_cb() of scsi-disk in a future patch. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - hw/scsi/scsi-bus.c | 16 +++++++++++----- - include/hw/scsi/scsi.h | 1 + - 2 files changed, 12 insertions(+), 5 deletions(-) - -diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c -index 77325d8cc7..5e6f891b9d 100644 ---- a/hw/scsi/scsi-bus.c -+++ b/hw/scsi/scsi-bus.c -@@ -143,14 +143,10 @@ void scsi_bus_init_named(SCSIBus *bus, size_t bus_size, DeviceState *host, - qbus_set_bus_hotplug_handler(BUS(bus)); - } - --static void scsi_dma_restart_bh(void *opaque) -+void scsi_retry_requests(SCSIDevice *s) - { -- SCSIDevice *s = opaque; - SCSIRequest *req, *next; - -- qemu_bh_delete(s->bh); -- s->bh = NULL; -- - aio_context_acquire(blk_get_aio_context(s->conf.blk)); - QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { - scsi_req_ref(req); -@@ -174,6 +170,16 @@ static void scsi_dma_restart_bh(void *opaque) - object_unref(OBJECT(s)); - } - -+static void scsi_dma_restart_bh(void *opaque) -+{ -+ SCSIDevice *s = opaque; -+ -+ qemu_bh_delete(s->bh); -+ s->bh = NULL; -+ -+ scsi_retry_requests(s); -+} -+ - void scsi_req_retry(SCSIRequest *req) - { - /* No need to save a reference, because scsi_dma_restart_bh just -diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h -index a567a5ed86..e5d90cd9dc 100644 ---- a/include/hw/scsi/scsi.h -+++ b/include/hw/scsi/scsi.h -@@ -212,6 +212,7 @@ void scsi_req_cancel_complete(SCSIRequest *req); - void scsi_req_cancel(SCSIRequest *req); - void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier); - void scsi_req_retry(SCSIRequest *req); -+void scsi_retry_requests(SCSIDevice *s); - void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); - void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense); - void scsi_device_report_change(SCSIDevice *dev, SCSISense sense); --- -2.27.0 - diff --git a/scsi-bus-fix-incorrect-call-for-blk_error_retry_rese.patch b/scsi-bus-fix-incorrect-call-for-blk_error_retry_rese.patch deleted file mode 100644 index 4f4804f16550ce3b85091a32d08f399e7b41b352..0000000000000000000000000000000000000000 --- a/scsi-bus-fix-incorrect-call-for-blk_error_retry_rese.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 3ab10a5ad9bf1cbf3b4603f5a930a7924a07ad5a Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Tue, 29 Mar 2022 12:05:56 +0800 -Subject: [PATCH 1/2] scsi-bus: fix incorrect call for - blk_error_retry_reset_timeout() - -Fix commit 52115ca0("scsi-disk: Add support for retry on errors"). -Call Stack: - ... - scsi_read_data() - scsi_do_read(r, 0) - scsi_disk_req_check_error() - blk_error_retry_reset_timeout() - blk->retry_start_time = 0; - -It will cause IO hang when storage network disconnected. Before the -storage network recovered, the upper call stack will reset the -retry_start_time, and cause the next IO operation not returned immediately. - -Signed-off-by: Yan Wang ---- - hw/scsi/scsi-disk.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index 8661932a15..a66d2b0a98 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -255,10 +255,8 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) - } - } - --static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) -+static bool scsi_disk_req_handle_error(SCSIDiskReq *r, int ret, bool acct_failed) - { -- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); -- - if (r->req.io_canceled) { - scsi_req_cancel_complete(&r->req); - return true; -@@ -268,6 +266,17 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) - return scsi_handle_rw_error(r, ret, acct_failed); - } - -+ return false; -+} -+ -+static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) -+{ -+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); -+ -+ if (r->req.io_canceled || ret < 0) { -+ return scsi_disk_req_handle_error(r, ret, acct_failed); -+ } -+ - blk_error_retry_reset_timeout(s->qdev.conf.blk); - return false; - } -@@ -418,7 +427,7 @@ static void scsi_do_read(SCSIDiskReq *r, int ret) - SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s)); - - assert (r->req.aiocb == NULL); -- if (scsi_disk_req_check_error(r, ret, false)) { -+ if (scsi_disk_req_handle_error(r, ret, false)) { - goto done; - } - -@@ -458,6 +467,9 @@ static void scsi_do_read_cb(void *opaque, int ret) - block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); - } else { - block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); -+ if (!r->req.io_canceled) { -+ blk_error_retry_reset_timeout(s->qdev.conf.blk); -+ } - } - scsi_do_read(opaque, ret); - aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); --- -2.27.0 - diff --git a/scsi-bus-fix-unmatched-object_unref.patch b/scsi-bus-fix-unmatched-object_unref.patch deleted file mode 100644 index 0cb39a07610c8da0396119e87e942b400dbdddf5..0000000000000000000000000000000000000000 --- a/scsi-bus-fix-unmatched-object_unref.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 239ffdcf42e0795b5f025f87fa19ce01642811f2 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Tue, 1 Mar 2022 20:12:12 +0800 -Subject: [PATCH] scsi-bus: fix unmatched object_unref() - -Fix commit 391dd8f1("scsi-bus: Refactor the code that retries requests"), -which split scsi_dma_restart_bh(), but the object_unref() belongs to -scsi_dma_restart_bh(). -So, we should mv object_unref() from scsi_retry_requests() to -scsi_dma_restart_bh(). - -Signed-off-by: Yan Wang ---- - hw/scsi/scsi-bus.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c -index 5e6f891b9d..9d37f490ce 100644 ---- a/hw/scsi/scsi-bus.c -+++ b/hw/scsi/scsi-bus.c -@@ -166,8 +166,6 @@ void scsi_retry_requests(SCSIDevice *s) - scsi_req_unref(req); - } - aio_context_release(blk_get_aio_context(s->conf.blk)); -- /* Drop the reference that was acquired in scsi_dma_restart_cb */ -- object_unref(OBJECT(s)); - } - - static void scsi_dma_restart_bh(void *opaque) -@@ -178,6 +176,9 @@ static void scsi_dma_restart_bh(void *opaque) - s->bh = NULL; - - scsi_retry_requests(s); -+ -+ /* Drop the reference that was acquired in scsi_dma_restart_cb */ -+ object_unref(OBJECT(s)); - } - - void scsi_req_retry(SCSIRequest *req) --- -2.27.0 - diff --git a/scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch b/scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch deleted file mode 100644 index d1147fce44d9bd2cc06e8bbd2b2da1f1ac8083af..0000000000000000000000000000000000000000 --- a/scsi-cdrom-Fix-crash-after-remote-cdrom-detached.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 77496578b22e127eb50a5a8c463e92fb3245a7e0 Mon Sep 17 00:00:00 2001 -From: WangJian -Date: Wed, 9 Feb 2022 11:42:47 +0800 -Subject: [PATCH] scsi: cdrom: Fix crash after remote cdrom detached - -There is a small window between the twice blk_is_available in -scsi_disk_emulate_command which would cause crash due to the later -assertion if the remote cdrom is detached in this window. - -So this patch replaces assertions with return to avoid qemu crash. - -Signed-off-by: wangjian161 ---- - hw/scsi/scsi-disk.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index d4914178ea..a1053f4036 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -1930,7 +1930,10 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) - memset(outbuf, 0, r->buflen); - switch (req->cmd.buf[0]) { - case TEST_UNIT_READY: -- assert(blk_is_available(s->qdev.conf.blk)); -+ if (!blk_is_available(s->qdev.conf.blk)) { -+ scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); -+ return 0; -+ } - break; - case INQUIRY: - buflen = scsi_disk_emulate_inquiry(req, outbuf); --- -2.27.0 - diff --git a/scsi-disk-Add-support-for-retry-on-errors.patch b/scsi-disk-Add-support-for-retry-on-errors.patch deleted file mode 100644 index 69f76143bc27c0ea1f121d7419b88ae2764e07dc..0000000000000000000000000000000000000000 --- a/scsi-disk-Add-support-for-retry-on-errors.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 52115ca0ad925b1d719eb46e22c455aa5839534a Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:55 +0800 -Subject: [PATCH 7/9] scsi-disk: Add support for retry on errors - -Mark failed requests as to be retried and implement retry_request_cb to -handle these requests. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - hw/scsi/scsi-disk.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index d4914178ea..d278efc701 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -246,6 +246,10 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) - scsi_req_retry(&r->req); - return true; - -+ case BLOCK_ERROR_ACTION_RETRY: -+ scsi_req_retry(&r->req); -+ return true; -+ - default: - g_assert_not_reached(); - } -@@ -253,6 +257,8 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) - - static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) - { -+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); -+ - if (r->req.io_canceled) { - scsi_req_cancel_complete(&r->req); - return true; -@@ -262,6 +268,7 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed) - return scsi_handle_rw_error(r, ret, acct_failed); - } - -+ blk_error_retry_reset_timeout(s->qdev.conf.blk); - return false; - } - -@@ -2278,6 +2285,13 @@ static void scsi_disk_resize_cb(void *opaque) - } - } - -+static void scsi_disk_retry_request(void *opaque) -+{ -+ SCSIDiskState *s = opaque; -+ -+ scsi_retry_requests(&s->qdev); -+} -+ - static void scsi_cd_change_media_cb(void *opaque, bool load, Error **errp) - { - SCSIDiskState *s = opaque; -@@ -2326,10 +2340,12 @@ static const BlockDevOps scsi_disk_removable_block_ops = { - .is_medium_locked = scsi_cd_is_medium_locked, - - .resize_cb = scsi_disk_resize_cb, -+ .retry_request_cb = scsi_disk_retry_request, - }; - - static const BlockDevOps scsi_disk_block_ops = { - .resize_cb = scsi_disk_resize_cb, -+ .retry_request_cb = scsi_disk_retry_request, - }; - - static void scsi_disk_unit_attention_reported(SCSIDevice *dev) --- -2.27.0 - diff --git a/scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch b/scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch deleted file mode 100644 index f3befe79a7e6f6b9b4513cecd5614b3aea91054e..0000000000000000000000000000000000000000 --- a/scsi-disk-define-props-in-scsi_block_disk-to-avoid-m.patch +++ /dev/null @@ -1,36 +0,0 @@ -From e026850b32231abb97d7790a04d7c94515bd1081 Mon Sep 17 00:00:00 2001 -From: Pan Nengyuan -Date: Mon, 13 Jan 2020 15:53:32 +0800 -Subject: [PATCH 3/6] scsi-disk: define props in scsi_block_disk to avoid - memleaks - -scsi_block_realize() use scsi_realize() to init some props, but -these props is not defined in scsi_block_disk_properties, so they will -not be freed. - -This patch defines these prop in scsi_block_disk_properties to avoid memleaks. - -Signed-off-by: Pan Nengyuan -Signed-off-by: Yan Wang ---- - hw/scsi/scsi-disk.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c -index d491417..1d7799d 100644 ---- a/hw/scsi/scsi-disk.c -+++ b/hw/scsi/scsi-disk.c -@@ -3107,9 +3107,7 @@ static const TypeInfo scsi_cd_info = { - - #ifdef __linux__ - static Property scsi_block_properties[] = { -- DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), -- DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk), -- DEFINE_PROP_BOOL("share-rw", SCSIDiskState, qdev.conf.share_rw, false), -+ DEFINE_SCSI_DISK_PROPERTIES(), - DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), - DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size, - DEFAULT_MAX_UNMAP_SIZE), --- -1.9.1 - diff --git a/scsi-lsi53c895a-fix-use-after-free-in-lsi_do_msgout-.patch b/scsi-lsi53c895a-fix-use-after-free-in-lsi_do_msgout-.patch deleted file mode 100644 index c617b98277d5801334492c498e1175af4b939080..0000000000000000000000000000000000000000 --- a/scsi-lsi53c895a-fix-use-after-free-in-lsi_do_msgout-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 87d97af840d61122e801a37a89e6bf48a2cbe8e2 Mon Sep 17 00:00:00 2001 -From: Mauro Matteo Cascella -Date: Tue, 5 Jul 2022 22:05:43 +0200 -Subject: [PATCH 3/4] scsi/lsi53c895a: fix use-after-free in lsi_do_msgout - (CVE-2022-0216) - -Set current_req->req to NULL to prevent reusing a free'd buffer in case of -repeated SCSI cancel requests. Thanks to Thomas Huth for suggesting the patch. - -Fixes: CVE-2022-0216 -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/972 -Signed-off-by: Mauro Matteo Cascella -Reviewed-by: Thomas Huth -Message-Id: <20220705200543.2366809-1-mcascell@redhat.com> -Signed-off-by: Paolo Bonzini ---- - hw/scsi/lsi53c895a.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c -index 4c431adb77..4c91854df9 100644 ---- a/hw/scsi/lsi53c895a.c -+++ b/hw/scsi/lsi53c895a.c -@@ -1028,8 +1028,9 @@ static void lsi_do_msgout(LSIState *s) - case 0x0d: - /* The ABORT TAG message clears the current I/O process only. */ - trace_lsi_do_msgout_abort(current_tag); -- if (current_req) { -+ if (current_req && current_req->req) { - scsi_req_cancel(current_req->req); -+ current_req->req = NULL; - } - lsi_disconnect(s); - break; --- -2.27.0 - diff --git a/scsi-lsi53c895a-really-fix-use-after-free-in-lsi_do_.patch b/scsi-lsi53c895a-really-fix-use-after-free-in-lsi_do_.patch deleted file mode 100644 index 637a78e1fbde6f28daa8aa8b7fbfbc459f1651f4..0000000000000000000000000000000000000000 --- a/scsi-lsi53c895a-really-fix-use-after-free-in-lsi_do_.patch +++ /dev/null @@ -1,141 +0,0 @@ -From b0a1db1428e8d92693a323b9d479764071d08247 Mon Sep 17 00:00:00 2001 -From: Mauro Matteo Cascella -Date: Mon, 11 Jul 2022 14:33:16 +0200 -Subject: [PATCH 4/4] scsi/lsi53c895a: really fix use-after-free in - lsi_do_msgout (CVE-2022-0216) - -Set current_req to NULL, not current_req->req, to prevent reusing a free'd -buffer in case of repeated SCSI cancel requests. Also apply the fix to -CLEAR QUEUE and BUS DEVICE RESET messages as well, since they also cancel -the request. - -Thanks to Alexander Bulekov for providing a reproducer. - -Fixes: CVE-2022-0216 -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/972 -Signed-off-by: Mauro Matteo Cascella -Tested-by: Alexander Bulekov -Message-Id: <20220711123316.421279-1-mcascell@redhat.com> -Signed-off-by: Paolo Bonzini ---- - hw/scsi/lsi53c895a.c | 3 +- - tests/qtest/fuzz-lsi53c895a-test.c | 75 ++++++++++++++++++++++++++++++ - 2 files changed, 77 insertions(+), 1 deletion(-) - -diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c -index 4c91854df9..b9c9eb0dac 100644 ---- a/hw/scsi/lsi53c895a.c -+++ b/hw/scsi/lsi53c895a.c -@@ -1030,7 +1030,7 @@ static void lsi_do_msgout(LSIState *s) - trace_lsi_do_msgout_abort(current_tag); - if (current_req && current_req->req) { - scsi_req_cancel(current_req->req); -- current_req->req = NULL; -+ current_req = NULL; - } - lsi_disconnect(s); - break; -@@ -1056,6 +1056,7 @@ static void lsi_do_msgout(LSIState *s) - /* clear the current I/O process */ - if (s->current) { - scsi_req_cancel(s->current->req); -+ current_req = NULL; - } - - /* As the current implemented devices scsi_disk and scsi_generic -diff --git a/tests/qtest/fuzz-lsi53c895a-test.c b/tests/qtest/fuzz-lsi53c895a-test.c -index ba5d468970..0f968024c8 100644 ---- a/tests/qtest/fuzz-lsi53c895a-test.c -+++ b/tests/qtest/fuzz-lsi53c895a-test.c -@@ -8,6 +8,79 @@ - #include "qemu/osdep.h" - #include "libqos/libqtest.h" - -+/* -+ * This used to trigger a UAF in lsi_do_msgout() -+ * https://gitlab.com/qemu-project/qemu/-/issues/972 -+ */ -+static void test_lsi_do_msgout_cancel_req(void) -+{ -+ QTestState *s; -+ -+ if (sizeof(void *) == 4) { -+ g_test_skip("memory size too big for 32-bit build"); -+ return; -+ } -+ -+ s = qtest_init("-M q35 -m 4G -display none -nodefaults " -+ "-device lsi53c895a,id=scsi " -+ "-device scsi-hd,drive=disk0 " -+ "-drive file=null-co://,id=disk0,if=none,format=raw"); -+ -+ qtest_outl(s, 0xcf8, 0x80000810); -+ qtest_outl(s, 0xcf8, 0xc000); -+ qtest_outl(s, 0xcf8, 0x80000810); -+ qtest_outw(s, 0xcfc, 0x7); -+ qtest_outl(s, 0xcf8, 0x80000810); -+ qtest_outl(s, 0xcfc, 0xc000); -+ qtest_outl(s, 0xcf8, 0x80000804); -+ qtest_outw(s, 0xcfc, 0x05); -+ qtest_writeb(s, 0x69736c10, 0x08); -+ qtest_writeb(s, 0x69736c13, 0x58); -+ qtest_writeb(s, 0x69736c1a, 0x01); -+ qtest_writeb(s, 0x69736c1b, 0x06); -+ qtest_writeb(s, 0x69736c22, 0x01); -+ qtest_writeb(s, 0x69736c23, 0x07); -+ qtest_writeb(s, 0x69736c2b, 0x02); -+ qtest_writeb(s, 0x69736c48, 0x08); -+ qtest_writeb(s, 0x69736c4b, 0x58); -+ qtest_writeb(s, 0x69736c52, 0x04); -+ qtest_writeb(s, 0x69736c53, 0x06); -+ qtest_writeb(s, 0x69736c5b, 0x02); -+ qtest_outl(s, 0xc02d, 0x697300); -+ qtest_writeb(s, 0x5a554662, 0x01); -+ qtest_writeb(s, 0x5a554663, 0x07); -+ qtest_writeb(s, 0x5a55466a, 0x10); -+ qtest_writeb(s, 0x5a55466b, 0x22); -+ qtest_writeb(s, 0x5a55466c, 0x5a); -+ qtest_writeb(s, 0x5a55466d, 0x5a); -+ qtest_writeb(s, 0x5a55466e, 0x34); -+ qtest_writeb(s, 0x5a55466f, 0x5a); -+ qtest_writeb(s, 0x5a345a5a, 0x77); -+ qtest_writeb(s, 0x5a345a5b, 0x55); -+ qtest_writeb(s, 0x5a345a5c, 0x51); -+ qtest_writeb(s, 0x5a345a5d, 0x27); -+ qtest_writeb(s, 0x27515577, 0x41); -+ qtest_outl(s, 0xc02d, 0x5a5500); -+ qtest_writeb(s, 0x364001d0, 0x08); -+ qtest_writeb(s, 0x364001d3, 0x58); -+ qtest_writeb(s, 0x364001da, 0x01); -+ qtest_writeb(s, 0x364001db, 0x26); -+ qtest_writeb(s, 0x364001dc, 0x0d); -+ qtest_writeb(s, 0x364001dd, 0xae); -+ qtest_writeb(s, 0x364001de, 0x41); -+ qtest_writeb(s, 0x364001df, 0x5a); -+ qtest_writeb(s, 0x5a41ae0d, 0xf8); -+ qtest_writeb(s, 0x5a41ae0e, 0x36); -+ qtest_writeb(s, 0x5a41ae0f, 0xd7); -+ qtest_writeb(s, 0x5a41ae10, 0x36); -+ qtest_writeb(s, 0x36d736f8, 0x0c); -+ qtest_writeb(s, 0x36d736f9, 0x80); -+ qtest_writeb(s, 0x36d736fa, 0x0d); -+ qtest_outl(s, 0xc02d, 0x364000); -+ -+ qtest_quit(s); -+} -+ - /* - * This used to trigger the assert in lsi_do_dma() - * https://bugs.launchpad.net/qemu/+bug/697510 -@@ -46,6 +119,8 @@ int main(int argc, char **argv) - if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { - qtest_add_func("fuzz/lsi53c895a/lsi_do_dma_empty_queue", - test_lsi_do_dma_empty_queue); -+ qtest_add_func("fuzz/lsi53c895a/lsi_do_msgout_cancel_req", -+ test_lsi_do_msgout_cancel_req); - } - - return g_test_run(); --- -2.27.0 - diff --git a/seabios-add-check-to-avoid-dereference-NULL-pointer.patch b/seabios-add-check-to-avoid-dereference-NULL-pointer.patch deleted file mode 100644 index 6c94c4681c2a74df31ea77ed2a83c5d775b1d429..0000000000000000000000000000000000000000 --- a/seabios-add-check-to-avoid-dereference-NULL-pointer.patch +++ /dev/null @@ -1,36 +0,0 @@ -From e6b133311a7a5a618b48c6f38e3c3bb9e9a395c9 Mon Sep 17 00:00:00 2001 -From: eillon -Date: Mon, 14 Feb 2022 15:35:28 +0800 -Subject: [PATCH] seabios: add check to avoid dereference NULL pointer - -alloc_find_lowest() may return NULL, check it. - -Signed-off-by: eillon ---- - roms/seabios/src/malloc.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/roms/seabios/src/malloc.c b/roms/seabios/src/malloc.c -index 5827a6523..99fa3b7e0 100644 ---- a/roms/seabios/src/malloc.c -+++ b/roms/seabios/src/malloc.c -@@ -544,10 +544,12 @@ malloc_prepboot(void) - - // Clear unused f-seg ram. - struct allocinfo_s *info = alloc_find_lowest(&ZoneFSeg); -- u32 size = info->range_end - info->range_start; -- memset(memremap(info->range_start, size), 0, size); -- dprintf(1, "Space available for UMB: %x-%x, %x-%x\n" -- , RomEnd, base, info->range_start, info->range_end); -+ if (info) { -+ u32 size = info->range_end - info->range_start; -+ memset(memremap(info->range_start, size), 0, size); -+ dprintf(1, "Space available for UMB: %x-%x, %x-%x\n" -+ , RomEnd, base, info->range_start, info->range_end); -+ } - - // We should not give back unused high ram, to support some special - // guest OS, like oracle linux series. --- -2.27.0 - diff --git a/seabios-convert-value-of-be16_to_cpu-to-u64-before-s.patch b/seabios-convert-value-of-be16_to_cpu-to-u64-before-s.patch deleted file mode 100644 index be0218f935178a0cd5ad9bfdbef24199acdbba2f..0000000000000000000000000000000000000000 --- a/seabios-convert-value-of-be16_to_cpu-to-u64-before-s.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c2ec0efb903e27f83cb9a54041764f76e2e1d390 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Fri, 11 Feb 2022 16:12:21 +0800 -Subject: [PATCH 1/6] seabios: convert value of be16_to_cpu to u64 before - shifting - -be16_to_cpu(scsi_lun->lun[i]) is 16 bits and left shifting by more than 16 will have undefined behaviour. -convert it to u64 before shifting. - -Signed-off-by: liuxiangdong -Signed-off-by: jiangdongxu ---- - roms/seabios/src/hw/blockcmd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/roms/seabios/src/hw/blockcmd.c b/roms/seabios/src/hw/blockcmd.c -index 6b6fea9707..af6d33544f 100644 ---- a/roms/seabios/src/hw/blockcmd.c -+++ b/roms/seabios/src/hw/blockcmd.c -@@ -210,7 +210,7 @@ static u64 scsilun2u64(struct scsi_lun *scsi_lun) - int i; - u64 ret = 0; - for (i = 0; i < ARRAY_SIZE(scsi_lun->lun); i++) -- ret |= be16_to_cpu(scsi_lun->lun[i]) << (16 * i); -+ ret |= (u64)be16_to_cpu(scsi_lun->lun[i]) << (16 * i); - return ret; - } - --- -2.27.0 - diff --git a/seabios-do-not-give-back-high-ram.patch b/seabios-do-not-give-back-high-ram.patch deleted file mode 100644 index df40892f44b00f51ba244ae5d8af14e69c99e7e5..0000000000000000000000000000000000000000 --- a/seabios-do-not-give-back-high-ram.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 74f052de33cb14d7a1656079a53102a7cbbb6e75 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Fri, 11 Feb 2022 16:16:05 +0800 -Subject: [PATCH 2/6] seabios: do not give back high ram - -Oracle 6 and 7 series virtual machines will use the high ram returned by -sebios. Since these high ram will not be initialized before kernel used, -this will cause a system exception. This patch removes the logic for -returning high ram, making the virtual machine will not use this part -of the memory, thus avoiding this kernel bug. - -Signed-off-by: wangxin -Signed-off-by: Fangyi -Signed-off-by: jiangdongxu ---- - roms/seabios/src/malloc.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/roms/seabios/src/malloc.c b/roms/seabios/src/malloc.c -index 3733855caf..5827a6523a 100644 ---- a/roms/seabios/src/malloc.c -+++ b/roms/seabios/src/malloc.c -@@ -549,6 +549,9 @@ malloc_prepboot(void) - dprintf(1, "Space available for UMB: %x-%x, %x-%x\n" - , RomEnd, base, info->range_start, info->range_end); - -+ // We should not give back unused high ram, to support some special -+ // guest OS, like oracle linux series. -+#ifdef HIGH_MEM_BACK - // Give back unused high ram. - info = alloc_find_lowest(&ZoneHigh); - if (info) { -@@ -556,6 +559,7 @@ malloc_prepboot(void) - e820_add(info->range_start, giveback, E820_RAM); - dprintf(1, "Returned %d bytes of ZoneHigh\n", giveback); - } -+#endif - - calcRamSize(); - } --- -2.27.0 - diff --git a/seabios-drop-yield-in-smp_setup.patch b/seabios-drop-yield-in-smp_setup.patch deleted file mode 100644 index 1c55aa0da4c4eecf6eeeb5b0d9dc5451d99672e6..0000000000000000000000000000000000000000 --- a/seabios-drop-yield-in-smp_setup.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1a8defda890d6fe3efe2238cff1ef2ae6ca8928c Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Fri, 11 Feb 2022 16:31:25 +0800 -Subject: [PATCH 4/6] seabios: drop yield() in smp_setup() - -Fix SeaBIOS stuck problem becuase SeaBIOS open hardware interrupt -by invoking yield(). That's dangerous and unnecessary. Let's drop -it, and make the processing of setup smp more security in SeaBIOS. - -Signed-off-by: liuxiangdong -Signed-off-by: jiangdongxu ---- - roms/seabios/src/fw/smp.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/roms/seabios/src/fw/smp.c b/roms/seabios/src/fw/smp.c -index 46d1da1784..e5e407be0c 100644 ---- a/roms/seabios/src/fw/smp.c -+++ b/roms/seabios/src/fw/smp.c -@@ -149,6 +149,7 @@ smp_scan(void) - - // Wait for other CPUs to process the SIPI. - u16 expected_cpus_count = qemu_get_present_cpus_count(); -+ dprintf(1,"expected_cpus_count=%d\n", expected_cpus_count); - while (expected_cpus_count != CountCPUs) - asm volatile( - // Release lock and allow other processors to use the stack. -@@ -160,7 +161,7 @@ smp_scan(void) - " jc 1b\n" - : "+m" (SMPLock), "+m" (SMPStack) - : : "cc", "memory"); -- yield(); -+ dprintf(1, "finish smp\n"); - - // Restore memory. - *(u64*)BUILD_AP_BOOT_ADDR = old; --- -2.27.0 - diff --git a/seabios-fix-memory-leak-when-pci-check.patch b/seabios-fix-memory-leak-when-pci-check.patch deleted file mode 100644 index 01d1ea06864f719c1bcd057b05506a546e9de4bc..0000000000000000000000000000000000000000 --- a/seabios-fix-memory-leak-when-pci-check.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 73cb83af0649f958bb31b5b76f46c164c6f2952c Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Fri, 11 Feb 2022 16:28:55 +0800 -Subject: [PATCH 3/6] seabios: fix memory leak when pci check - -fix code memory leak when pci check failed -free busses memory when pci_bios_check_devices function returns error in pci_setup() - -Signed-off-by: liuxiangodng -Signed-off-by: jiangdongxu ---- - roms/seabios/src/fw/pciinit.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/roms/seabios/src/fw/pciinit.c b/roms/seabios/src/fw/pciinit.c -index d25931bb05..9df35d05d1 100644 ---- a/roms/seabios/src/fw/pciinit.c -+++ b/roms/seabios/src/fw/pciinit.c -@@ -1171,8 +1171,11 @@ pci_setup(void) - return; - } - memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1)); -- if (pci_bios_check_devices(busses)) -+ if (pci_bios_check_devices(busses)) { -+ dprintf(1, "pci_bios_check_devices(busses) failed!\n"); -+ free(busses); - return; -+ } - - dprintf(1, "=== PCI new allocation pass #2 ===\n"); - pci_bios_map_devices(busses); --- -2.27.0 - diff --git a/seabios-increase-the-seabios-high-mem-zone-size.patch b/seabios-increase-the-seabios-high-mem-zone-size.patch deleted file mode 100644 index 01c16d1db2827e6948158e9bcac0823467668554..0000000000000000000000000000000000000000 --- a/seabios-increase-the-seabios-high-mem-zone-size.patch +++ /dev/null @@ -1,34 +0,0 @@ -From bf72a9439d06fe35e3c7246b60e1c5b7b8058459 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Fri, 11 Feb 2022 16:34:23 +0800 -Subject: [PATCH 6/6] seabios: increase the seabios high mem zone size - -In terms of version and specification, under the maximum configuration -specification of the number of vcpus, virtio blocks and other features, -there exists bottleneck in seabios high_mem_zone, which results in the -memory application failure and causes the vm to fail to start. - -Increase BUILD_MAX_HIGHTABLE to 512k. - -Signed-off-by: liuxiangdong -Signed-off-by: jiangdongxu ---- - roms/seabios/src/config.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/roms/seabios/src/config.h b/roms/seabios/src/config.h -index 93c8dbc2d5..9abd43474e 100644 ---- a/roms/seabios/src/config.h -+++ b/roms/seabios/src/config.h -@@ -17,7 +17,7 @@ - // Maximum number of map entries in the e820 map - #define BUILD_MAX_E820 32 - // Space to reserve in high-memory for tables --#define BUILD_MAX_HIGHTABLE (256*1024) -+#define BUILD_MAX_HIGHTABLE (512*1024) - // Largest supported externaly facing drive id - #define BUILD_MAX_EXTDRIVE 16 - // Number of bytes the smbios may be and still live in the f-segment --- -2.27.0 - diff --git a/seabios-increase-the-seabios-minibiostable.patch b/seabios-increase-the-seabios-minibiostable.patch deleted file mode 100644 index bd3cfa461ecc6b436b43ac55775ece42b62d4aea..0000000000000000000000000000000000000000 --- a/seabios-increase-the-seabios-minibiostable.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 764113a4a24e1d842a45fb62fc09279c87057616 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Fri, 11 Feb 2022 16:33:04 +0800 -Subject: [PATCH 5/6] seabios: increase the seabios minibiostable - -Increase the BUILD_MIN_BIOSTABLE to 4096; -support 25 virtio-blk(data) + 1 virtio-scsi(sys) + 1 virtio-net - -Increase the BUILD_MIN_BIOSTABLE to 5120; -support 18 virtio-scsi while vm starts with IDE boot disk - -Signed-off-by: liuxiangdong -Signed-off-by: jiangdongxu ---- - roms/seabios/scripts/layoutrom.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/roms/seabios/scripts/layoutrom.py b/roms/seabios/scripts/layoutrom.py -index abebf0211f..e2732db8f9 100755 ---- a/roms/seabios/scripts/layoutrom.py -+++ b/roms/seabios/scripts/layoutrom.py -@@ -66,7 +66,7 @@ def setSectionsStart(sections, endaddr, minalign=1, segoffset=0): - BUILD_ROM_START = 0xc0000 - BUILD_LOWRAM_END = 0xa0000 - # Space to reserve in f-segment for dynamic allocations --BUILD_MIN_BIOSTABLE = 2048 -+BUILD_MIN_BIOSTABLE = 5120 - - # Layout the 16bit code. This ensures sections with fixed offset - # requirements are placed in the correct location. It also places the --- -2.27.0 - diff --git a/semihosting-config-Merge-semihosting-config-option-g.patch b/semihosting-config-Merge-semihosting-config-option-g.patch deleted file mode 100644 index c7c9e59be4b675152c4379ab50661eda348147ce..0000000000000000000000000000000000000000 --- a/semihosting-config-Merge-semihosting-config-option-g.patch +++ /dev/null @@ -1,54 +0,0 @@ -From ff7918646e3c696d13732fb22f032d7d78c34fe1 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 6 Nov 2023 08:15:13 +0000 -Subject: [PATCH] semihosting/config: Merge --semihosting-config option groups - mainline inclusion commit 90c072e063737e9e8f431489bbd334452f89056e category: - bugfix - ---------------------------------------------------------------- - -Currently we mishandle the --semihosting-config option if the -user specifies it on the command line more than once. For -example with: - --semihosting-config target=gdb --semihosting-config arg=foo,arg=bar - -the function qemu_semihosting_config_options() is called twice, once -for each argument. But that function expects to be called only once, -and it always unconditionally sets the semihosting.enabled, -semihost_chardev and semihosting.target variables. This means that -if any of those options were set anywhere except the last ---semihosting-config option on the command line, those settings are -ignored. In the example above, 'target=gdb' in the first option is -overridden by an implied default 'target=auto' in the second. - -The QemuOptsList machinery has a flag for handling this kind of -"option group is setting global state": by setting - .merge_lists = true; -we make the machinery merge all the --semihosting-config arguments -the user passes into a single set of options and call our -qemu_semihosting_config_options() just once. - -Signed-off-by: Peter Maydell -Reviewed-by: Luc Michel -Message-id: 20220526190053.521505-3-peter.maydell@linaro.org - -Signed-off-by: tangbinzy ---- - semihosting/config.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/semihosting/config.c b/semihosting/config.c -index 137171b717..ba3e310a61 100644 ---- a/semihosting/config.c -+++ b/semihosting/config.c -@@ -27,6 +27,7 @@ - - QemuOptsList qemu_semihosting_config_opts = { - .name = "semihosting-config", -+ .merge_lists = true, - .implied_opt_name = "enable", - .head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head), - .desc = { --- -2.27.0 - diff --git a/semihosting-fix-memleak-at-semihosting_arg_fallback.patch b/semihosting-fix-memleak-at-semihosting_arg_fallback.patch deleted file mode 100644 index ccee1a5bb1ca43518d5376480569873626a121b1..0000000000000000000000000000000000000000 --- a/semihosting-fix-memleak-at-semihosting_arg_fallback.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 47a24e233e335025ed37ab0ba4a4e728719a2ad3 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 6 Nov 2023 18:14:06 +0800 -Subject: [PATCH] semihosting: fix memleak at semihosting_arg_fallback -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 2eb71a0c20a6a77be128a76c1ef8fb5dc7028a8b - -We duplicate "cmd" as strtok may modify its argument, but we forgot -to free it later. Furthermore, add_semihosting_arg doesn't take -responsibility for this memory either (it strdup's the argument). - -Signed-off-by: Matheus Tavares Bernardino -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <03d81c56bfc3d08224e4106efca5949d8894cfa5.1697801632.git.quic_mathbern@quicinc.com> -Reviewed-by: Richard Henderson -Signed-off-by: Alex Bennée -Message-Id: <20231029145033.592566-18-alex.bennee@linaro.org> -Signed-off-by: qihao_yewu ---- - semihosting/config.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/semihosting/config.c b/semihosting/config.c -index 137171b717..303338f647 100644 ---- a/semihosting/config.c -+++ b/semihosting/config.c -@@ -109,12 +109,13 @@ static int add_semihosting_arg(void *opaque, - void semihosting_arg_fallback(const char *file, const char *cmd) - { - char *cmd_token; -+ g_autofree char *cmd_dup = g_strdup(cmd); - - /* argv[0] */ - add_semihosting_arg(&semihosting, "arg", file, NULL); - - /* split -append and initialize argv[1..n] */ -- cmd_token = strtok(g_strdup(cmd), " "); -+ cmd_token = strtok(cmd_dup, " "); - while (cmd_token) { - add_semihosting_arg(&semihosting, "arg", cmd_token, NULL); - cmd_token = strtok(NULL, " "); --- -2.27.0 - diff --git a/shadow_dev-introduce-shadow-dev-for-virtio-net-devic.patch b/shadow_dev-introduce-shadow-dev-for-virtio-net-devic.patch deleted file mode 100644 index ef1164d6ca802901261df0e6e46f6b55d5c60db9..0000000000000000000000000000000000000000 --- a/shadow_dev-introduce-shadow-dev-for-virtio-net-devic.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 0a6c08bd3a16543b8021c8b65a45f7ebb701a9aa Mon Sep 17 00:00:00 2001 -From: Dongxu Sun -Date: Fri, 15 Dec 2023 17:44:54 +0800 -Subject: [PATCH] shadow_dev: introduce shadow dev for virtio-net device - -for virtio net devices, create the shadow device for vlpi -bypass inject supported. - -Signed-off-by: Wang Haibin -Signed-off-by: Yu Zenghui -Signed-off-by: Chen Qun -Signed-off-by: KunKun Jiang -Signed-off-by: Dongxu Sun ---- - hw/virtio/virtio-pci.c | 32 ++++++++++++++++++++++++++ - include/sysemu/kvm.h | 5 +++++ - linux-headers/linux/kvm.h | 13 +++++++++++ - target/arm/kvm.c | 47 +++++++++++++++++++++++++++++++++++++++ - 4 files changed, 97 insertions(+) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 82706b8b32..6b45683280 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -873,18 +873,44 @@ undo: - } - return ret; - } -+ -+#ifdef __aarch64__ -+int __attribute__((weak)) kvm_create_shadow_device(PCIDevice *dev) -+{ -+ return 0; -+} -+ -+int __attribute__((weak)) kvm_delete_shadow_device(PCIDevice *dev) -+{ -+ return 0; -+} -+#endif -+ - static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs) - { - int queue_no; - int ret = 0; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - -+#ifdef __aarch64__ -+ if (!strcmp(vdev->name, "virtio-net")) { -+ kvm_create_shadow_device(&proxy->pci_dev); -+ } -+#endif -+ - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - return -1; - } - ret = kvm_virtio_pci_vector_use_one(proxy, queue_no); - } -+ -+#ifdef __aarch64__ -+ if (!strcmp(vdev->name, "virtio-net") && ret != 0) { -+ kvm_delete_shadow_device(&proxy->pci_dev); -+ } -+#endif -+ - return ret; - } - -@@ -927,6 +953,12 @@ static void kvm_virtio_pci_vector_vq_release(VirtIOPCIProxy *proxy, int nvqs) - } - kvm_virtio_pci_vector_release_one(proxy, queue_no); - } -+ -+#ifdef __aarch64__ -+ if (!strcmp(vdev->name, "virtio-net")) { -+ kvm_delete_shadow_device(&proxy->pci_dev); -+ } -+#endif - } - - static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy) -diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h -index 1ec9432493..9f52d08ce0 100644 ---- a/include/sysemu/kvm.h -+++ b/include/sysemu/kvm.h -@@ -553,4 +553,9 @@ bool kvm_arch_cpu_check_are_resettable(void); - bool kvm_dirty_ring_enabled(void); - - uint32_t kvm_dirty_ring_size(void); -+ -+#ifdef __aarch64__ -+int kvm_create_shadow_device(PCIDevice *dev); -+int kvm_delete_shadow_device(PCIDevice *dev); -+#endif - #endif -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index 2008fbc173..cd0885f523 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1127,6 +1127,8 @@ struct kvm_ppc_resize_hpt { - - #define KVM_CAP_ARM_CPU_FEATURE 555 - -+#define KVM_CAP_ARM_VIRT_MSI_BYPASS 799 -+ - #ifdef KVM_CAP_IRQ_ROUTING - - struct kvm_irq_routing_irqchip { -@@ -1431,6 +1433,17 @@ struct kvm_s390_ucas_mapping { - #define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config) - #define KVM_SET_CLOCK _IOW(KVMIO, 0x7b, struct kvm_clock_data) - #define KVM_GET_CLOCK _IOR(KVMIO, 0x7c, struct kvm_clock_data) -+ -+#ifdef __aarch64__ -+struct kvm_master_dev_info -+{ -+ __u32 nvectors; /* number of msi vectors */ -+ struct kvm_msi msi[0]; -+}; -+#define KVM_CREATE_SHADOW_DEV _IOW(KVMIO, 0xf0, struct kvm_master_dev_info) -+#define KVM_DEL_SHADOW_DEV _IOW(KVMIO, 0xf1, __u32) -+#endif -+ - /* Available with KVM_CAP_PIT_STATE2 */ - #define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2) - #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) -diff --git a/target/arm/kvm.c b/target/arm/kvm.c -index 22ac5bcb97..38d80adfb7 100644 ---- a/target/arm/kvm.c -+++ b/target/arm/kvm.c -@@ -27,6 +27,8 @@ - #include "trace.h" - #include "internals.h" - #include "hw/pci/pci.h" -+#include "hw/pci/msi.h" -+#include "hw/pci/msix.h" - #include "exec/memattrs.h" - #include "exec/address-spaces.h" - #include "hw/boards.h" -@@ -1075,6 +1077,51 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, - return 0; - } - -+int kvm_create_shadow_device(PCIDevice *dev) -+{ -+ KVMState *s = kvm_state; -+ struct kvm_master_dev_info *mdi; -+ MSIMessage msg; -+ uint32_t vector, nvectors = msix_nr_vectors_allocated(dev); -+ uint32_t request_id; -+ int ret; -+ -+ if (!kvm_vm_check_extension(s, KVM_CAP_ARM_VIRT_MSI_BYPASS) || !nvectors) { -+ return 0; -+ } -+ -+ mdi = g_malloc0(sizeof(uint32_t) + sizeof(struct kvm_msi) * nvectors); -+ mdi->nvectors = nvectors; -+ request_id = pci_requester_id(dev); -+ -+ for (vector = 0; vector < nvectors; vector++) { -+ msg = msix_get_message(dev, vector); -+ mdi->msi[vector].address_lo = extract64(msg.address, 0, 32); -+ mdi->msi[vector].address_hi = extract64(msg.address, 32, 32); -+ mdi->msi[vector].data = le32_to_cpu(msg.data); -+ mdi->msi[vector].flags = KVM_MSI_VALID_DEVID; -+ mdi->msi[vector].devid = request_id; -+ memset(mdi->msi[vector].pad, 0, sizeof(mdi->msi[vector].pad)); -+ } -+ -+ ret = kvm_vm_ioctl(s, KVM_CREATE_SHADOW_DEV, mdi); -+ g_free(mdi); -+ return ret; -+} -+ -+int kvm_delete_shadow_device(PCIDevice *dev) -+{ -+ KVMState *s = kvm_state; -+ uint32_t request_id, nvectors = msix_nr_vectors_allocated(dev); -+ -+ if (!kvm_vm_check_extension(s, KVM_CAP_ARM_VIRT_MSI_BYPASS) || !nvectors) { -+ return 0; -+ } -+ -+ request_id = pci_requester_id(dev); -+ return kvm_vm_ioctl(s, KVM_DEL_SHADOW_DEV, &request_id); -+} -+ - int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, - int vector, PCIDevice *dev) - { --- -2.27.0 - diff --git a/smbios-Add-missing-member-of-type-4-for-smbios-3.0.patch b/smbios-Add-missing-member-of-type-4-for-smbios-3.0.patch deleted file mode 100644 index f1f9e91b6c6fa36fe8e362c1001c6ef3c68af72c..0000000000000000000000000000000000000000 --- a/smbios-Add-missing-member-of-type-4-for-smbios-3.0.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 937e22eda2480a64095928ee8df0d37b3313bb64 Mon Sep 17 00:00:00 2001 -From: Ying Fang -Date: Tue, 14 Apr 2020 14:53:44 +0800 -Subject: [PATCH] smbios: Add missing member of type 4 for smbios 3.0 - -According to smbios 3.0 spec, for processor information (type 4), -it adds three new members (Core Count 2, Core enabled 2, thread count 2) for 3.0, Without this three members, we can not get correct cpu frequency from dmi, -Because it will failed to check the length of Processor Infomation in DMI. - -The corresponding codes in kernel is like: - if (dm->type == DMI_ENTRY_PROCESSOR && - dm->length >= DMI_ENTRY_PROCESSOR_MIN_LENGTH) { - u16 val = (u16)get_unaligned((const u16 *) - (dmi_data + DMI_PROCESSOR_MAX_SPEED)); - *mhz = val > *mhz ? val : *mhz; - } - -Signed-off-by: zhanghailiang -Signed-off-by: Yan Wang ---- - hw/smbios/smbios.c | 4 +++- - include/hw/firmware/smbios.h | 3 +++ - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index 7397e56737..66be9aee09 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -688,7 +688,9 @@ static void smbios_build_type_4_table(MachineState *ms, unsigned instance) - t->thread_count = ms->smp.threads; - t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */ - t->processor_family2 = cpu_to_le16(0x01); /* Other */ -- -+ t->corecount2 = 0; -+ t->enabledcorecount2 = 0; -+ t->threadcount2 = 0; - SMBIOS_BUILD_TABLE_POST; - smbios_type4_count++; - } -diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h -index 5a0dd0c8cf..5a696cf75a 100644 ---- a/include/hw/firmware/smbios.h -+++ b/include/hw/firmware/smbios.h -@@ -193,6 +193,9 @@ struct smbios_type_4 { - uint8_t thread_count; - uint16_t processor_characteristics; - uint16_t processor_family2; -+ uint16_t corecount2; -+ uint16_t enabledcorecount2; -+ uint16_t threadcount2; - } QEMU_PACKED; - - /* SMBIOS type 11 - OEM strings */ --- -2.27.0 - diff --git a/softmmu-Always-initialize-xlat-in-address_space_tran.patch b/softmmu-Always-initialize-xlat-in-address_space_tran.patch deleted file mode 100644 index f23ad768e77109f831f6637d5b30cc6c2c059395..0000000000000000000000000000000000000000 --- a/softmmu-Always-initialize-xlat-in-address_space_tran.patch +++ /dev/null @@ -1,68 +0,0 @@ -From e6b719bf79d00dddde0b0371075a41890a8f95a4 Mon Sep 17 00:00:00 2001 -From: cenhuilin -Date: Tue, 19 Jul 2022 09:53:31 +0000 -Subject: [PATCH] softmmu Always initialize xlat in - address_space_translate_for_iotlb - -The bug is an uninitialized memory read, along the translate_fail -path, which results in garbage being read from iotlb_to_section, -which can lead to a crash in io_readx/io_writex. - -The bug may be fixed by writing any value with zero -in ~TARGET_PAGE_MASK, so that the call to iotlb_to_section using -the xlat'ed address returns io_mem_unassigned, as desired by the -translate_fail path. - -It is most useful to record the original physical page address, -which will eventually be logged by memory_region_access_valid -when the access is rejected by unassigned_mem_accepts. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1065 -Signed-off-by: Richard Henderson -Reviewed-by: Peter Maydell -Message-Id: <20220621153829.366423-1-richard.henderson@linaro.org> ---- - softmmu/physmem.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/softmmu/physmem.c b/softmmu/physmem.c -index ae26f7290..be39a49ce 100644 ---- a/softmmu/physmem.c -+++ b/softmmu/physmem.c -@@ -668,7 +668,7 @@ void tcg_iommu_init_notifier_list(CPUState *cpu) - - /* Called from RCU critical section */ - MemoryRegionSection * --address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, -+address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr, - hwaddr *xlat, hwaddr *plen, - MemTxAttrs attrs, int *prot) - { -@@ -677,6 +677,7 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, - IOMMUMemoryRegionClass *imrc; - IOMMUTLBEntry iotlb; - int iommu_idx; -+ hwaddr addr = orig_addr; - AddressSpaceDispatch *d = - qatomic_rcu_read(&cpu->cpu_ases[asidx].memory_dispatch); - -@@ -721,6 +722,16 @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, - return section; - - translate_fail: -+ /* -+ * We should be given a page-aligned address -- certainly -+ * tlb_set_page_with_attrs() does so. The page offset of xlat -+ * is used to index sections[], and PHYS_SECTION_UNASSIGNED = 0. -+ * The page portion of xlat will be logged by memory_region_access_valid() -+ * when this memory access is rejected, so use the original untranslated -+ * physical address. -+ */ -+ assert((orig_addr & ~TARGET_PAGE_MASK) == 0); -+ *xlat = orig_addr; - return &d->map.sections[PHYS_SECTION_UNASSIGNED]; - } - --- -2.33.0 - diff --git a/softmmu-device_tree-Remove-redundant-pointer-assignm.patch b/softmmu-device_tree-Remove-redundant-pointer-assignm.patch deleted file mode 100644 index c98a0588cbc31d5ff36d2e5216c8fd6d3f50d508..0000000000000000000000000000000000000000 --- a/softmmu-device_tree-Remove-redundant-pointer-assignm.patch +++ /dev/null @@ -1,58 +0,0 @@ -From ebf1ac6c0ead3d6fbc32466028c286588333c1ea Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Tue, 11 Jan 2022 11:27:58 +0800 -Subject: [PATCH 22/24] softmmu/device_tree: Remove redundant pointer - assignment - -The pointer assignment "const char *p = path;" in function -qemu_fdt_add_path is unnecessary. Let's remove it and just -use the "path" passed in. No functional change. - -Suggested-by: Richard Henderson -Signed-off-by: Yanan Wang -Reviewed-by: Andrew Jones -Reviewed-by: Alistair Francis -Reviewed-by: Thomas Huth -Message-id: 20220111032758.27804-1-wangyanan55@huawei.com -Signed-off-by: Alistair Francis ---- - softmmu/device_tree.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c -index 9e96f5ecd5..8897c79ea4 100644 ---- a/softmmu/device_tree.c -+++ b/softmmu/device_tree.c -@@ -556,7 +556,6 @@ int qemu_fdt_add_subnode(void *fdt, const char *name) - int qemu_fdt_add_path(void *fdt, const char *path) - { - const char *name; -- const char *p = path; - int namelen, retval; - int parent = 0; - -@@ -565,9 +564,9 @@ int qemu_fdt_add_path(void *fdt, const char *path) - } - - do { -- name = p + 1; -- p = strchr(name, '/'); -- namelen = p != NULL ? p - name : strlen(name); -+ name = path + 1; -+ path = strchr(name, '/'); -+ namelen = path != NULL ? path - name : strlen(name); - - retval = fdt_subnode_offset_namelen(fdt, parent, name, namelen); - if (retval < 0 && retval != -FDT_ERR_NOTFOUND) { -@@ -584,7 +583,7 @@ int qemu_fdt_add_path(void *fdt, const char *path) - } - - parent = retval; -- } while (p); -+ } while (path); - - return retval; - } --- -2.27.0 - diff --git a/softmmu-device_tree-Silence-compiler-warning-with-en.patch b/softmmu-device_tree-Silence-compiler-warning-with-en.patch deleted file mode 100644 index 68030155312cb20beca50b0e133e4c4b2ab536f4..0000000000000000000000000000000000000000 --- a/softmmu-device_tree-Silence-compiler-warning-with-en.patch +++ /dev/null @@ -1,60 +0,0 @@ -From ecc0eb93e8856321ad940a85970f0db14ab9f146 Mon Sep 17 00:00:00 2001 -From: Thomas Huth -Date: Fri, 7 Jan 2022 14:38:44 +0100 -Subject: [PATCH 21/24] softmmu/device_tree: Silence compiler warning with - --enable-sanitizers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If I configure my build with --enable-sanitizers, my GCC (v8.5.0) -complains: - -.../softmmu/device_tree.c: In function ‘qemu_fdt_add_path’: -.../softmmu/device_tree.c:560:18: error: ‘retval’ may be used uninitialized - in this function [-Werror=maybe-uninitialized] - int namelen, retval; - ^~~~~~ - -It's a false warning since the while loop is always executed at least -once (p has to be non-NULL, otherwise the derefence in the if-statement -earlier will crash). Thus let's switch to a do-while loop here instead -to make the compiler happy in all cases. - -Signed-off-by: Thomas Huth -Reviewed-by: Andrew Jones -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Richard Henderson -Reviewed-by: Alistair Francis -Reviewed-by: Yanan Wang -Message-id: 20220107133844.145039-1-thuth@redhat.com -Signed-off-by: Alistair Francis ---- - softmmu/device_tree.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c -index 3965c834ca..9e96f5ecd5 100644 ---- a/softmmu/device_tree.c -+++ b/softmmu/device_tree.c -@@ -564,7 +564,7 @@ int qemu_fdt_add_path(void *fdt, const char *path) - return -1; - } - -- while (p) { -+ do { - name = p + 1; - p = strchr(name, '/'); - namelen = p != NULL ? p - name : strlen(name); -@@ -584,7 +584,7 @@ int qemu_fdt_add_path(void *fdt, const char *path) - } - - parent = retval; -- } -+ } while (p); - - return retval; - } --- -2.27.0 - diff --git a/softmmu-dirtylimit-Add-parameter-check-for-hmp-set_v.patch b/softmmu-dirtylimit-Add-parameter-check-for-hmp-set_v.patch deleted file mode 100644 index 4fd759bc1aa684caf0add0e45c4ba4ac31885bd2..0000000000000000000000000000000000000000 --- a/softmmu-dirtylimit-Add-parameter-check-for-hmp-set_v.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 381500cc0b96e85165ae0314839c34976a4da1b2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Fri, 18 Nov 2022 10:08:54 +0800 -Subject: [PATCH] softmmu/dirtylimit: Add parameter check for hmp - "set_vcpu_dirty_limit" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -dirty_rate paraemter of hmp command "set_vcpu_dirty_limit" is invalid -if less than 0, so add parameter check for it. - -Note that this patch also delete the unsolicited help message and -clean up the code. - -Signed-off-by: Hyman Huang(黄勇) -Reviewed-by: Markus Armbruster -Reviewed-by: Peter Xu -Reviewed-by: Juan Quintela -Message-Id: <168618975839.6361.17407633874747688653-1@git.sr.ht> -Signed-off-by: Juan Quintela ---- - softmmu/dirtylimit.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c -index 8d98cb7f2c..5041c230d0 100644 ---- a/softmmu/dirtylimit.c -+++ b/softmmu/dirtylimit.c -@@ -515,14 +515,15 @@ void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict) - int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1); - Error *err = NULL; - -- qmp_set_vcpu_dirty_limit(!!(cpu_index != -1), cpu_index, dirty_rate, &err); -- if (err) { -- hmp_handle_error(mon, err); -- return; -+ if (dirty_rate < 0) { -+ error_setg(&err, "invalid dirty page limit %" PRId64, dirty_rate); -+ goto out; - } - -- monitor_printf(mon, "[Please use 'info vcpu_dirty_limit' to query " -- "dirty limit for virtual CPU]\n"); -+ qmp_set_vcpu_dirty_limit(!!(cpu_index != -1), cpu_index, dirty_rate, &err); -+ -+out: -+ hmp_handle_error(mon, err); - } - - static struct DirtyLimitInfo *dirtylimit_query_vcpu(int cpu_index) --- -2.41.0.windows.1 - diff --git a/softmmu-dirtylimit-Implement-dirty-page-rate-limit.patch b/softmmu-dirtylimit-Implement-dirty-page-rate-limit.patch deleted file mode 100644 index 3c56ed3cc3540f9d738fe3754d34cc5c1f44d6e4..0000000000000000000000000000000000000000 --- a/softmmu-dirtylimit-Implement-dirty-page-rate-limit.patch +++ /dev/null @@ -1,435 +0,0 @@ -From 39d9c1f6de01abf003980f4c2fe3c08f9e6cd60c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Sun, 26 Jun 2022 01:38:36 +0800 -Subject: [PATCH] softmmu/dirtylimit: Implement dirty page rate limit -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Implement dirtyrate calculation periodically basing on -dirty-ring and throttle virtual CPU until it reachs the quota -dirty page rate given by user. - -Introduce qmp commands "set-vcpu-dirty-limit", -"cancel-vcpu-dirty-limit", "query-vcpu-dirty-limit" -to enable, disable, query dirty page limit for virtual CPU. - -Meanwhile, introduce corresponding hmp commands -"set_vcpu_dirty_limit", "cancel_vcpu_dirty_limit", -"info vcpu_dirty_limit" so the feature can be more usable. - -"query-vcpu-dirty-limit" success depends on enabling dirty -page rate limit, so just add it to the list of skipped -command to ensure qmp-cmd-test run successfully. - -Signed-off-by: Hyman Huang(黄勇) -Acked-by: Markus Armbruster -Reviewed-by: Peter Xu -Message-Id: <4143f26706d413dd29db0b672fe58b3d3fbe34bc.1656177590.git.huangy81@chinatelecom.cn> -Signed-off-by: Dr. David Alan Gilbert ---- - hmp-commands-info.hx | 13 +++ - hmp-commands.hx | 32 ++++++ - include/monitor/hmp.h | 3 + - qapi/migration.json | 80 +++++++++++++++ - softmmu/dirtylimit.c | 194 +++++++++++++++++++++++++++++++++++++ - tests/qtest/qmp-cmd-test.c | 2 + - 6 files changed, 324 insertions(+) - -diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx -index 407a1da800..5dd3001af0 100644 ---- a/hmp-commands-info.hx -+++ b/hmp-commands-info.hx -@@ -863,6 +863,19 @@ SRST - Display the vcpu dirty rate information. - ERST - -+ { -+ .name = "vcpu_dirty_limit", -+ .args_type = "", -+ .params = "", -+ .help = "show dirty page limit information of all vCPU", -+ .cmd = hmp_info_vcpu_dirty_limit, -+ }, -+ -+SRST -+ ``info vcpu_dirty_limit`` -+ Display the vcpu dirty page limit information. -+ERST -+ - #if defined(TARGET_I386) - { - .name = "sgx", -diff --git a/hmp-commands.hx b/hmp-commands.hx -index 70a9136ac2..5bedee2d49 100644 ---- a/hmp-commands.hx -+++ b/hmp-commands.hx -@@ -1744,3 +1744,35 @@ ERST - "\n\t\t\t -b to specify dirty bitmap as method of calculation)", - .cmd = hmp_calc_dirty_rate, - }, -+ -+SRST -+``set_vcpu_dirty_limit`` -+ Set dirty page rate limit on virtual CPU, the information about all the -+ virtual CPU dirty limit status can be observed with ``info vcpu_dirty_limit`` -+ command. -+ERST -+ -+ { -+ .name = "set_vcpu_dirty_limit", -+ .args_type = "dirty_rate:l,cpu_index:l?", -+ .params = "dirty_rate [cpu_index]", -+ .help = "set dirty page rate limit, use cpu_index to set limit" -+ "\n\t\t\t\t\t on a specified virtual cpu", -+ .cmd = hmp_set_vcpu_dirty_limit, -+ }, -+ -+SRST -+``cancel_vcpu_dirty_limit`` -+ Cancel dirty page rate limit on virtual CPU, the information about all the -+ virtual CPU dirty limit status can be observed with ``info vcpu_dirty_limit`` -+ command. -+ERST -+ -+ { -+ .name = "cancel_vcpu_dirty_limit", -+ .args_type = "cpu_index:l?", -+ .params = "[cpu_index]", -+ .help = "cancel dirty page rate limit, use cpu_index to cancel" -+ "\n\t\t\t\t\t limit on a specified virtual cpu", -+ .cmd = hmp_cancel_vcpu_dirty_limit, -+ }, -diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h -index 96d014826a..478820e54f 100644 ---- a/include/monitor/hmp.h -+++ b/include/monitor/hmp.h -@@ -131,6 +131,9 @@ void hmp_replay_delete_break(Monitor *mon, const QDict *qdict); - void hmp_replay_seek(Monitor *mon, const QDict *qdict); - void hmp_info_dirty_rate(Monitor *mon, const QDict *qdict); - void hmp_calc_dirty_rate(Monitor *mon, const QDict *qdict); -+void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict); -+void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict); -+void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict); - void hmp_human_readable_text_helper(Monitor *mon, - HumanReadableText *(*qmp_handler)(Error **)); - -diff --git a/qapi/migration.json b/qapi/migration.json -index d4ebc5f028..fee266017d 100644 ---- a/qapi/migration.json -+++ b/qapi/migration.json -@@ -1874,6 +1874,86 @@ - ## - { 'command': 'query-dirty-rate', 'returns': 'DirtyRateInfo' } - -+## -+# @DirtyLimitInfo: -+# -+# Dirty page rate limit information of a virtual CPU. -+# -+# @cpu-index: index of a virtual CPU. -+# -+# @limit-rate: upper limit of dirty page rate (MB/s) for a virtual -+# CPU, 0 means unlimited. -+# -+# @current-rate: current dirty page rate (MB/s) for a virtual CPU. -+# -+# Since: 6.2 -+# -+## -+{ 'struct': 'DirtyLimitInfo', -+ 'data': { 'cpu-index': 'int', -+ 'limit-rate': 'uint64', -+ 'current-rate': 'uint64' } } -+ -+## -+# @set-vcpu-dirty-limit: -+# -+# Set the upper limit of dirty page rate for virtual CPUs. -+# -+# Requires KVM with accelerator property "dirty-ring-size" set. -+# A virtual CPU's dirty page rate is a measure of its memory load. -+# To observe dirty page rates, use @calc-dirty-rate. -+# -+# @cpu-index: index of a virtual CPU, default is all. -+# -+# @dirty-rate: upper limit of dirty page rate (MB/s) for virtual CPUs. -+# -+# Since: 6.2 -+# -+# Example: -+# {"execute": "set-vcpu-dirty-limit"} -+# "arguments": { "dirty-rate": 200, -+# "cpu-index": 1 } } -+# -+## -+{ 'command': 'set-vcpu-dirty-limit', -+ 'data': { '*cpu-index': 'int', -+ 'dirty-rate': 'uint64' } } -+ -+## -+# @cancel-vcpu-dirty-limit: -+# -+# Cancel the upper limit of dirty page rate for virtual CPUs. -+# -+# Cancel the dirty page limit for the vCPU which has been set with -+# set-vcpu-dirty-limit command. Note that this command requires -+# support from dirty ring, same as the "set-vcpu-dirty-limit". -+# -+# @cpu-index: index of a virtual CPU, default is all. -+# -+# Since: 6.2 -+# -+# Example: -+# {"execute": "cancel-vcpu-dirty-limit"} -+# "arguments": { "cpu-index": 1 } } -+# -+## -+{ 'command': 'cancel-vcpu-dirty-limit', -+ 'data': { '*cpu-index': 'int'} } -+ -+## -+# @query-vcpu-dirty-limit: -+# -+# Returns information about virtual CPU dirty page rate limits, if any. -+# -+# Since: 6.2 -+# -+# Example: -+# {"execute": "query-vcpu-dirty-limit"} -+# -+## -+{ 'command': 'query-vcpu-dirty-limit', -+ 'returns': [ 'DirtyLimitInfo' ] } -+ - ## - # @snapshot-save: - # -diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c -index e5a4f970bd..8d98cb7f2c 100644 ---- a/softmmu/dirtylimit.c -+++ b/softmmu/dirtylimit.c -@@ -14,8 +14,12 @@ - #include "qapi/error.h" - #include "qemu/main-loop.h" - #include "qapi/qapi-commands-migration.h" -+#include "qapi/qmp/qdict.h" -+#include "qapi/error.h" - #include "sysemu/dirtyrate.h" - #include "sysemu/dirtylimit.h" -+#include "monitor/hmp.h" -+#include "monitor/monitor.h" - #include "exec/memory.h" - #include "hw/boards.h" - #include "sysemu/kvm.h" -@@ -405,3 +409,193 @@ void dirtylimit_vcpu_execute(CPUState *cpu) - usleep(cpu->throttle_us_per_full); - } - } -+ -+static void dirtylimit_init(void) -+{ -+ dirtylimit_state_initialize(); -+ dirtylimit_change(true); -+ vcpu_dirty_rate_stat_initialize(); -+ vcpu_dirty_rate_stat_start(); -+} -+ -+static void dirtylimit_cleanup(void) -+{ -+ vcpu_dirty_rate_stat_stop(); -+ vcpu_dirty_rate_stat_finalize(); -+ dirtylimit_change(false); -+ dirtylimit_state_finalize(); -+} -+ -+void qmp_cancel_vcpu_dirty_limit(bool has_cpu_index, -+ int64_t cpu_index, -+ Error **errp) -+{ -+ if (!kvm_enabled() || !kvm_dirty_ring_enabled()) { -+ return; -+ } -+ -+ if (has_cpu_index && !dirtylimit_vcpu_index_valid(cpu_index)) { -+ error_setg(errp, "incorrect cpu index specified"); -+ return; -+ } -+ -+ if (!dirtylimit_in_service()) { -+ return; -+ } -+ -+ dirtylimit_state_lock(); -+ -+ if (has_cpu_index) { -+ dirtylimit_set_vcpu(cpu_index, 0, false); -+ } else { -+ dirtylimit_set_all(0, false); -+ } -+ -+ if (!dirtylimit_state->limited_nvcpu) { -+ dirtylimit_cleanup(); -+ } -+ -+ dirtylimit_state_unlock(); -+} -+ -+void hmp_cancel_vcpu_dirty_limit(Monitor *mon, const QDict *qdict) -+{ -+ int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1); -+ Error *err = NULL; -+ -+ qmp_cancel_vcpu_dirty_limit(!!(cpu_index != -1), cpu_index, &err); -+ if (err) { -+ hmp_handle_error(mon, err); -+ return; -+ } -+ -+ monitor_printf(mon, "[Please use 'info vcpu_dirty_limit' to query " -+ "dirty limit for virtual CPU]\n"); -+} -+ -+void qmp_set_vcpu_dirty_limit(bool has_cpu_index, -+ int64_t cpu_index, -+ uint64_t dirty_rate, -+ Error **errp) -+{ -+ if (!kvm_enabled() || !kvm_dirty_ring_enabled()) { -+ error_setg(errp, "dirty page limit feature requires KVM with" -+ " accelerator property 'dirty-ring-size' set'"); -+ return; -+ } -+ -+ if (has_cpu_index && !dirtylimit_vcpu_index_valid(cpu_index)) { -+ error_setg(errp, "incorrect cpu index specified"); -+ return; -+ } -+ -+ if (!dirty_rate) { -+ qmp_cancel_vcpu_dirty_limit(has_cpu_index, cpu_index, errp); -+ return; -+ } -+ -+ dirtylimit_state_lock(); -+ -+ if (!dirtylimit_in_service()) { -+ dirtylimit_init(); -+ } -+ -+ if (has_cpu_index) { -+ dirtylimit_set_vcpu(cpu_index, dirty_rate, true); -+ } else { -+ dirtylimit_set_all(dirty_rate, true); -+ } -+ -+ dirtylimit_state_unlock(); -+} -+ -+void hmp_set_vcpu_dirty_limit(Monitor *mon, const QDict *qdict) -+{ -+ int64_t dirty_rate = qdict_get_int(qdict, "dirty_rate"); -+ int64_t cpu_index = qdict_get_try_int(qdict, "cpu_index", -1); -+ Error *err = NULL; -+ -+ qmp_set_vcpu_dirty_limit(!!(cpu_index != -1), cpu_index, dirty_rate, &err); -+ if (err) { -+ hmp_handle_error(mon, err); -+ return; -+ } -+ -+ monitor_printf(mon, "[Please use 'info vcpu_dirty_limit' to query " -+ "dirty limit for virtual CPU]\n"); -+} -+ -+static struct DirtyLimitInfo *dirtylimit_query_vcpu(int cpu_index) -+{ -+ DirtyLimitInfo *info = NULL; -+ -+ info = g_malloc0(sizeof(*info)); -+ info->cpu_index = cpu_index; -+ info->limit_rate = dirtylimit_vcpu_get_state(cpu_index)->quota; -+ info->current_rate = vcpu_dirty_rate_get(cpu_index); -+ -+ return info; -+} -+ -+static struct DirtyLimitInfoList *dirtylimit_query_all(void) -+{ -+ int i, index; -+ DirtyLimitInfo *info = NULL; -+ DirtyLimitInfoList *head = NULL, **tail = &head; -+ -+ dirtylimit_state_lock(); -+ -+ if (!dirtylimit_in_service()) { -+ dirtylimit_state_unlock(); -+ return NULL; -+ } -+ -+ for (i = 0; i < dirtylimit_state->max_cpus; i++) { -+ index = dirtylimit_state->states[i].cpu_index; -+ if (dirtylimit_vcpu_get_state(index)->enabled) { -+ info = dirtylimit_query_vcpu(index); -+ QAPI_LIST_APPEND(tail, info); -+ } -+ } -+ -+ dirtylimit_state_unlock(); -+ -+ return head; -+} -+ -+struct DirtyLimitInfoList *qmp_query_vcpu_dirty_limit(Error **errp) -+{ -+ if (!dirtylimit_in_service()) { -+ return NULL; -+ } -+ -+ return dirtylimit_query_all(); -+} -+ -+void hmp_info_vcpu_dirty_limit(Monitor *mon, const QDict *qdict) -+{ -+ DirtyLimitInfoList *limit, *head, *info = NULL; -+ Error *err = NULL; -+ -+ if (!dirtylimit_in_service()) { -+ monitor_printf(mon, "Dirty page limit not enabled!\n"); -+ return; -+ } -+ -+ info = qmp_query_vcpu_dirty_limit(&err); -+ if (err) { -+ hmp_handle_error(mon, err); -+ return; -+ } -+ -+ head = info; -+ for (limit = head; limit != NULL; limit = limit->next) { -+ monitor_printf(mon, "vcpu[%"PRIi64"], limit rate %"PRIi64 " (MB/s)," -+ " current rate %"PRIi64 " (MB/s)\n", -+ limit->value->cpu_index, -+ limit->value->limit_rate, -+ limit->value->current_rate); -+ } -+ -+ g_free(info); -+} -diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c -index 7f103ea3fd..4b216a0435 100644 ---- a/tests/qtest/qmp-cmd-test.c -+++ b/tests/qtest/qmp-cmd-test.c -@@ -110,6 +110,8 @@ static bool query_is_ignored(const char *cmd) - "query-sev-capabilities", - "query-sgx", - "query-sgx-capabilities", -+ /* Success depends on enabling dirty page rate limit */ -+ "query-vcpu-dirty-limit", - NULL - }; - int i; --- -2.27.0 - diff --git a/softmmu-dirtylimit-Implement-vCPU-dirtyrate-calculat.patch b/softmmu-dirtylimit-Implement-vCPU-dirtyrate-calculat.patch deleted file mode 100644 index f408a51eaf1dcad88e045d160fc0d142b7fcf2ec..0000000000000000000000000000000000000000 --- a/softmmu-dirtylimit-Implement-vCPU-dirtyrate-calculat.patch +++ /dev/null @@ -1,214 +0,0 @@ -From 1c1049bda8e91cc6015c32fc7cc9d0f16ad46b58 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Sun, 26 Jun 2022 01:38:33 +0800 -Subject: [PATCH 1/3] softmmu/dirtylimit: Implement vCPU dirtyrate calculation - periodically -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce the third method GLOBAL_DIRTY_LIMIT of dirty -tracking for calculate dirtyrate periodly for dirty page -rate limit. - -Add dirtylimit.c to implement dirtyrate calculation periodly, -which will be used for dirty page rate limit. - -Add dirtylimit.h to export util functions for dirty page rate -limit implementation. - -Signed-off-by: Hyman Huang(黄勇) -Reviewed-by: Peter Xu -Message-Id: <5d0d641bffcb9b1c4cc3e323b6dfecb36050d948.1656177590.git.huangy81@chinatelecom.cn> -Signed-off-by: Dr. David Alan Gilbert ---- - include/exec/memory.h | 5 +- - include/sysemu/dirtylimit.h | 22 +++++++ - softmmu/dirtylimit.c | 116 ++++++++++++++++++++++++++++++++++++ - softmmu/meson.build | 1 + - 4 files changed, 143 insertions(+), 1 deletion(-) - create mode 100644 include/sysemu/dirtylimit.h - create mode 100644 softmmu/dirtylimit.c - -diff --git a/include/exec/memory.h b/include/exec/memory.h -index 3e84d62e40..4326d74b95 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 0000000000..da459f03d6 ---- /dev/null -+++ b/include/sysemu/dirtylimit.h -@@ -0,0 +1,22 @@ -+/* -+ * Dirty page rate limit common functions -+ * -+ * Copyright (c) 2022 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_TIME_MS 1000 /* 1000ms */ -+ -+int64_t vcpu_dirty_rate_get(int cpu_index); -+void vcpu_dirty_rate_stat_start(void); -+void vcpu_dirty_rate_stat_stop(void); -+void vcpu_dirty_rate_stat_initialize(void); -+void vcpu_dirty_rate_stat_finalize(void); -+#endif -diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c -new file mode 100644 -index 0000000000..ebdc064c9d ---- /dev/null -+++ b/softmmu/dirtylimit.c -@@ -0,0 +1,116 @@ -+/* -+ * Dirty page rate limit implementation code -+ * -+ * Copyright (c) 2022 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. -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qemu/main-loop.h" -+#include "qapi/qapi-commands-migration.h" -+#include "sysemu/dirtyrate.h" -+#include "sysemu/dirtylimit.h" -+#include "exec/memory.h" -+#include "hw/boards.h" -+ -+struct { -+ VcpuStat stat; -+ bool running; -+ QemuThread thread; -+} *vcpu_dirty_rate_stat; -+ -+static void vcpu_dirty_rate_stat_collect(void) -+{ -+ VcpuStat stat; -+ int i = 0; -+ -+ /* calculate vcpu dirtyrate */ -+ vcpu_calculate_dirtyrate(DIRTYLIMIT_CALC_TIME_MS, -+ &stat, -+ GLOBAL_DIRTY_LIMIT, -+ false); -+ -+ for (i = 0; i < stat.nvcpu; i++) { -+ vcpu_dirty_rate_stat->stat.rates[i].id = i; -+ vcpu_dirty_rate_stat->stat.rates[i].dirty_rate = -+ stat.rates[i].dirty_rate; -+ } -+ -+ free(stat.rates); -+} -+ -+static void *vcpu_dirty_rate_stat_thread(void *opaque) -+{ -+ rcu_register_thread(); -+ -+ /* start log sync */ -+ global_dirty_log_change(GLOBAL_DIRTY_LIMIT, true); -+ -+ while (qatomic_read(&vcpu_dirty_rate_stat->running)) { -+ vcpu_dirty_rate_stat_collect(); -+ } -+ -+ /* stop log sync */ -+ global_dirty_log_change(GLOBAL_DIRTY_LIMIT, false); -+ -+ rcu_unregister_thread(); -+ return NULL; -+} -+ -+int64_t vcpu_dirty_rate_get(int cpu_index) -+{ -+ DirtyRateVcpu *rates = vcpu_dirty_rate_stat->stat.rates; -+ return qatomic_read_i64(&rates[cpu_index].dirty_rate); -+} -+ -+void vcpu_dirty_rate_stat_start(void) -+{ -+ if (qatomic_read(&vcpu_dirty_rate_stat->running)) { -+ return; -+ } -+ -+ qatomic_set(&vcpu_dirty_rate_stat->running, 1); -+ qemu_thread_create(&vcpu_dirty_rate_stat->thread, -+ "dirtyrate-stat", -+ vcpu_dirty_rate_stat_thread, -+ NULL, -+ QEMU_THREAD_JOINABLE); -+} -+ -+void vcpu_dirty_rate_stat_stop(void) -+{ -+ qatomic_set(&vcpu_dirty_rate_stat->running, 0); -+ qemu_mutex_unlock_iothread(); -+ qemu_thread_join(&vcpu_dirty_rate_stat->thread); -+ qemu_mutex_lock_iothread(); -+} -+ -+void vcpu_dirty_rate_stat_initialize(void) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ int max_cpus = ms->smp.max_cpus; -+ -+ vcpu_dirty_rate_stat = -+ g_malloc0(sizeof(*vcpu_dirty_rate_stat)); -+ -+ vcpu_dirty_rate_stat->stat.nvcpu = max_cpus; -+ vcpu_dirty_rate_stat->stat.rates = -+ g_malloc0(sizeof(DirtyRateVcpu) * max_cpus); -+ -+ vcpu_dirty_rate_stat->running = false; -+} -+ -+void vcpu_dirty_rate_stat_finalize(void) -+{ -+ free(vcpu_dirty_rate_stat->stat.rates); -+ vcpu_dirty_rate_stat->stat.rates = NULL; -+ -+ free(vcpu_dirty_rate_stat); -+ vcpu_dirty_rate_stat = NULL; -+} -diff --git a/softmmu/meson.build b/softmmu/meson.build -index d8e03018ab..95029a5db2 100644 ---- a/softmmu/meson.build -+++ b/softmmu/meson.build -@@ -15,6 +15,7 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files( - 'vl.c', - 'cpu-timers.c', - 'runstate-action.c', -+ 'dirtylimit.c', - )]) - - specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: [files( --- -2.27.0 - diff --git a/softmmu-dirtylimit-Implement-virtual-CPU-throttle.patch b/softmmu-dirtylimit-Implement-virtual-CPU-throttle.patch deleted file mode 100644 index b515a73e3d7430643550213812c20982a3433760..0000000000000000000000000000000000000000 --- a/softmmu-dirtylimit-Implement-virtual-CPU-throttle.patch +++ /dev/null @@ -1,469 +0,0 @@ -From 7b6ab56e68fb5031ea13b82743415413b1e70e71 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Sun, 26 Jun 2022 01:38:35 +0800 -Subject: [PATCH 3/3] softmmu/dirtylimit: Implement virtual CPU throttle -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Setup a negative feedback system when vCPU thread -handling KVM_EXIT_DIRTY_RING_FULL exit by introducing -throttle_us_per_full field in struct CPUState. Sleep -throttle_us_per_full microseconds to throttle vCPU -if dirtylimit is in service. - -Signed-off-by: Hyman Huang(黄勇) -Reviewed-by: Peter Xu -Message-Id: <977e808e03a1cef5151cae75984658b6821be618.1656177590.git.huangy81@chinatelecom.cn> -Signed-off-by: Dr. David Alan Gilbert ---- - accel/kvm/kvm-all.c | 20 ++- - include/hw/core/cpu.h | 6 + - include/sysemu/dirtylimit.h | 15 ++ - softmmu/dirtylimit.c | 291 ++++++++++++++++++++++++++++++++++++ - softmmu/trace-events | 7 + - 5 files changed, 338 insertions(+), 1 deletion(-) - -diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c -index d0c4310507..946ccb260b 100644 ---- a/accel/kvm/kvm-all.c -+++ b/accel/kvm/kvm-all.c -@@ -45,6 +45,7 @@ - #include "qemu/guest-random.h" - #include "sysemu/hw_accel.h" - #include "kvm-cpus.h" -+#include "sysemu/dirtylimit.h" - - #include "hw/boards.h" - -@@ -493,6 +494,7 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp) - cpu->kvm_state = s; - cpu->vcpu_dirty = true; - cpu->dirty_pages = 0; -+ cpu->throttle_us_per_full = 0; - - mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0); - if (mmap_size < 0) { -@@ -1486,6 +1488,11 @@ static void *kvm_dirty_ring_reaper_thread(void *data) - */ - sleep(1); - -+ /* keep sleeping so that dirtylimit not be interfered by reaper */ -+ if (dirtylimit_in_service()) { -+ continue; -+ } -+ - trace_kvm_dirty_ring_reaper("wakeup"); - r->reaper_state = KVM_DIRTY_RING_REAPER_REAPING; - -@@ -2965,8 +2972,19 @@ int kvm_cpu_exec(CPUState *cpu) - */ - trace_kvm_dirty_ring_full(cpu->cpu_index); - qemu_mutex_lock_iothread(); -- kvm_dirty_ring_reap(kvm_state, NULL); -+ /* -+ * We throttle vCPU by making it sleep once it exit from kernel -+ * due to dirty ring full. In the dirtylimit scenario, reaping -+ * all vCPUs after a single vCPU dirty ring get full result in -+ * the miss of sleep, so just reap the ring-fulled vCPU. -+ */ -+ if (dirtylimit_in_service()) { -+ kvm_dirty_ring_reap(kvm_state, cpu); -+ } else { -+ kvm_dirty_ring_reap(kvm_state, NULL); -+ } - qemu_mutex_unlock_iothread(); -+ dirtylimit_vcpu_execute(cpu); - ret = 0; - break; - case KVM_EXIT_SYSTEM_EVENT: -diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h -index e948e81f1a..9631c1e2f6 100644 ---- a/include/hw/core/cpu.h -+++ b/include/hw/core/cpu.h -@@ -411,6 +411,12 @@ struct CPUState { - */ - bool throttle_thread_scheduled; - -+ /* -+ * Sleep throttle_us_per_full microseconds once dirty ring is full -+ * if dirty page rate limit is enabled. -+ */ -+ int64_t throttle_us_per_full; -+ - bool ignore_memory_transaction_failures; - - struct hax_vcpu_state *hax_vcpu; -diff --git a/include/sysemu/dirtylimit.h b/include/sysemu/dirtylimit.h -index da459f03d6..8d2c1f3a6b 100644 ---- a/include/sysemu/dirtylimit.h -+++ b/include/sysemu/dirtylimit.h -@@ -19,4 +19,19 @@ void vcpu_dirty_rate_stat_start(void); - void vcpu_dirty_rate_stat_stop(void); - void vcpu_dirty_rate_stat_initialize(void); - void vcpu_dirty_rate_stat_finalize(void); -+ -+void dirtylimit_state_lock(void); -+void dirtylimit_state_unlock(void); -+void dirtylimit_state_initialize(void); -+void dirtylimit_state_finalize(void); -+bool dirtylimit_in_service(void); -+bool dirtylimit_vcpu_index_valid(int cpu_index); -+void dirtylimit_process(void); -+void dirtylimit_change(bool start); -+void dirtylimit_set_vcpu(int cpu_index, -+ uint64_t quota, -+ bool enable); -+void dirtylimit_set_all(uint64_t quota, -+ bool enable); -+void dirtylimit_vcpu_execute(CPUState *cpu); - #endif -diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c -index ebdc064c9d..e5a4f970bd 100644 ---- a/softmmu/dirtylimit.c -+++ b/softmmu/dirtylimit.c -@@ -18,6 +18,26 @@ - #include "sysemu/dirtylimit.h" - #include "exec/memory.h" - #include "hw/boards.h" -+#include "sysemu/kvm.h" -+#include "trace.h" -+ -+/* -+ * Dirtylimit stop working if dirty page rate error -+ * value less than DIRTYLIMIT_TOLERANCE_RANGE -+ */ -+#define DIRTYLIMIT_TOLERANCE_RANGE 25 /* MB/s */ -+/* -+ * Plus or minus vcpu sleep time linearly if dirty -+ * page rate error value percentage over -+ * DIRTYLIMIT_LINEAR_ADJUSTMENT_PCT. -+ * Otherwise, plus or minus a fixed vcpu sleep time. -+ */ -+#define DIRTYLIMIT_LINEAR_ADJUSTMENT_PCT 50 -+/* -+ * Max vcpu sleep time percentage during a cycle -+ * composed of dirty ring full and sleep time. -+ */ -+#define DIRTYLIMIT_THROTTLE_PCT_MAX 99 - - struct { - VcpuStat stat; -@@ -25,6 +45,30 @@ struct { - QemuThread thread; - } *vcpu_dirty_rate_stat; - -+typedef struct VcpuDirtyLimitState { -+ int cpu_index; -+ bool enabled; -+ /* -+ * Quota dirty page rate, unit is MB/s -+ * zero if not enabled. -+ */ -+ uint64_t quota; -+} VcpuDirtyLimitState; -+ -+struct { -+ VcpuDirtyLimitState *states; -+ /* Max cpus number configured by user */ -+ int max_cpus; -+ /* Number of vcpu under dirtylimit */ -+ int limited_nvcpu; -+} *dirtylimit_state; -+ -+/* protect dirtylimit_state */ -+static QemuMutex dirtylimit_mutex; -+ -+/* dirtylimit thread quit if dirtylimit_quit is true */ -+static bool dirtylimit_quit; -+ - static void vcpu_dirty_rate_stat_collect(void) - { - VcpuStat stat; -@@ -54,6 +98,9 @@ static void *vcpu_dirty_rate_stat_thread(void *opaque) - - while (qatomic_read(&vcpu_dirty_rate_stat->running)) { - vcpu_dirty_rate_stat_collect(); -+ if (dirtylimit_in_service()) { -+ dirtylimit_process(); -+ } - } - - /* stop log sync */ -@@ -86,9 +133,11 @@ void vcpu_dirty_rate_stat_start(void) - void vcpu_dirty_rate_stat_stop(void) - { - qatomic_set(&vcpu_dirty_rate_stat->running, 0); -+ dirtylimit_state_unlock(); - qemu_mutex_unlock_iothread(); - qemu_thread_join(&vcpu_dirty_rate_stat->thread); - qemu_mutex_lock_iothread(); -+ dirtylimit_state_lock(); - } - - void vcpu_dirty_rate_stat_initialize(void) -@@ -114,3 +163,245 @@ void vcpu_dirty_rate_stat_finalize(void) - free(vcpu_dirty_rate_stat); - vcpu_dirty_rate_stat = NULL; - } -+ -+void dirtylimit_state_lock(void) -+{ -+ qemu_mutex_lock(&dirtylimit_mutex); -+} -+ -+void dirtylimit_state_unlock(void) -+{ -+ qemu_mutex_unlock(&dirtylimit_mutex); -+} -+ -+static void -+__attribute__((__constructor__)) dirtylimit_mutex_init(void) -+{ -+ qemu_mutex_init(&dirtylimit_mutex); -+} -+ -+static inline VcpuDirtyLimitState *dirtylimit_vcpu_get_state(int cpu_index) -+{ -+ return &dirtylimit_state->states[cpu_index]; -+} -+ -+void dirtylimit_state_initialize(void) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ int max_cpus = ms->smp.max_cpus; -+ int i; -+ -+ dirtylimit_state = g_malloc0(sizeof(*dirtylimit_state)); -+ -+ dirtylimit_state->states = -+ g_malloc0(sizeof(VcpuDirtyLimitState) * max_cpus); -+ -+ for (i = 0; i < max_cpus; i++) { -+ dirtylimit_state->states[i].cpu_index = i; -+ } -+ -+ dirtylimit_state->max_cpus = max_cpus; -+ trace_dirtylimit_state_initialize(max_cpus); -+} -+ -+void dirtylimit_state_finalize(void) -+{ -+ free(dirtylimit_state->states); -+ dirtylimit_state->states = NULL; -+ -+ free(dirtylimit_state); -+ dirtylimit_state = NULL; -+ -+ trace_dirtylimit_state_finalize(); -+} -+ -+bool dirtylimit_in_service(void) -+{ -+ return !!dirtylimit_state; -+} -+ -+bool dirtylimit_vcpu_index_valid(int cpu_index) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ -+ return !(cpu_index < 0 || -+ cpu_index >= ms->smp.max_cpus); -+} -+ -+static inline int64_t dirtylimit_dirty_ring_full_time(uint64_t dirtyrate) -+{ -+ static uint64_t max_dirtyrate; -+ uint32_t dirty_ring_size = kvm_dirty_ring_size(); -+ uint64_t dirty_ring_size_meory_MB = -+ dirty_ring_size * TARGET_PAGE_SIZE >> 20; -+ -+ if (max_dirtyrate < dirtyrate) { -+ max_dirtyrate = dirtyrate; -+ } -+ -+ return dirty_ring_size_meory_MB * 1000000 / max_dirtyrate; -+} -+ -+static inline bool dirtylimit_done(uint64_t quota, -+ uint64_t current) -+{ -+ uint64_t min, max; -+ -+ min = MIN(quota, current); -+ max = MAX(quota, current); -+ -+ return ((max - min) <= DIRTYLIMIT_TOLERANCE_RANGE) ? true : false; -+} -+ -+static inline bool -+dirtylimit_need_linear_adjustment(uint64_t quota, -+ uint64_t current) -+{ -+ uint64_t min, max; -+ -+ min = MIN(quota, current); -+ max = MAX(quota, current); -+ -+ return ((max - min) * 100 / max) > DIRTYLIMIT_LINEAR_ADJUSTMENT_PCT; -+} -+ -+static void dirtylimit_set_throttle(CPUState *cpu, -+ uint64_t quota, -+ uint64_t current) -+{ -+ int64_t ring_full_time_us = 0; -+ uint64_t sleep_pct = 0; -+ uint64_t throttle_us = 0; -+ -+ if (current == 0) { -+ cpu->throttle_us_per_full = 0; -+ return; -+ } -+ -+ ring_full_time_us = dirtylimit_dirty_ring_full_time(current); -+ -+ if (dirtylimit_need_linear_adjustment(quota, current)) { -+ if (quota < current) { -+ sleep_pct = (current - quota) * 100 / current; -+ throttle_us = -+ ring_full_time_us * sleep_pct / (double)(100 - sleep_pct); -+ cpu->throttle_us_per_full += throttle_us; -+ } else { -+ sleep_pct = (quota - current) * 100 / quota; -+ throttle_us = -+ ring_full_time_us * sleep_pct / (double)(100 - sleep_pct); -+ cpu->throttle_us_per_full -= throttle_us; -+ } -+ -+ trace_dirtylimit_throttle_pct(cpu->cpu_index, -+ sleep_pct, -+ throttle_us); -+ } else { -+ if (quota < current) { -+ cpu->throttle_us_per_full += ring_full_time_us / 10; -+ } else { -+ cpu->throttle_us_per_full -= ring_full_time_us / 10; -+ } -+ } -+ -+ /* -+ * TODO: in the big kvm_dirty_ring_size case (eg: 65536, or other scenario), -+ * current dirty page rate may never reach the quota, we should stop -+ * increasing sleep time? -+ */ -+ cpu->throttle_us_per_full = MIN(cpu->throttle_us_per_full, -+ ring_full_time_us * DIRTYLIMIT_THROTTLE_PCT_MAX); -+ -+ cpu->throttle_us_per_full = MAX(cpu->throttle_us_per_full, 0); -+} -+ -+static void dirtylimit_adjust_throttle(CPUState *cpu) -+{ -+ uint64_t quota = 0; -+ uint64_t current = 0; -+ int cpu_index = cpu->cpu_index; -+ -+ quota = dirtylimit_vcpu_get_state(cpu_index)->quota; -+ current = vcpu_dirty_rate_get(cpu_index); -+ -+ if (!dirtylimit_done(quota, current)) { -+ dirtylimit_set_throttle(cpu, quota, current); -+ } -+ -+ return; -+} -+ -+void dirtylimit_process(void) -+{ -+ CPUState *cpu; -+ -+ if (!qatomic_read(&dirtylimit_quit)) { -+ dirtylimit_state_lock(); -+ -+ if (!dirtylimit_in_service()) { -+ dirtylimit_state_unlock(); -+ return; -+ } -+ -+ CPU_FOREACH(cpu) { -+ if (!dirtylimit_vcpu_get_state(cpu->cpu_index)->enabled) { -+ continue; -+ } -+ dirtylimit_adjust_throttle(cpu); -+ } -+ dirtylimit_state_unlock(); -+ } -+} -+ -+void dirtylimit_change(bool start) -+{ -+ if (start) { -+ qatomic_set(&dirtylimit_quit, 0); -+ } else { -+ qatomic_set(&dirtylimit_quit, 1); -+ } -+} -+ -+void dirtylimit_set_vcpu(int cpu_index, -+ uint64_t quota, -+ bool enable) -+{ -+ trace_dirtylimit_set_vcpu(cpu_index, quota); -+ -+ if (enable) { -+ dirtylimit_state->states[cpu_index].quota = quota; -+ if (!dirtylimit_vcpu_get_state(cpu_index)->enabled) { -+ dirtylimit_state->limited_nvcpu++; -+ } -+ } else { -+ dirtylimit_state->states[cpu_index].quota = 0; -+ if (dirtylimit_state->states[cpu_index].enabled) { -+ dirtylimit_state->limited_nvcpu--; -+ } -+ } -+ -+ dirtylimit_state->states[cpu_index].enabled = enable; -+} -+ -+void dirtylimit_set_all(uint64_t quota, -+ bool enable) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ int max_cpus = ms->smp.max_cpus; -+ int i; -+ -+ for (i = 0; i < max_cpus; i++) { -+ dirtylimit_set_vcpu(i, quota, enable); -+ } -+} -+ -+void dirtylimit_vcpu_execute(CPUState *cpu) -+{ -+ if (dirtylimit_in_service() && -+ dirtylimit_vcpu_get_state(cpu->cpu_index)->enabled && -+ cpu->throttle_us_per_full) { -+ trace_dirtylimit_vcpu_execute(cpu->cpu_index, -+ cpu->throttle_us_per_full); -+ usleep(cpu->throttle_us_per_full); -+ } -+} -diff --git a/softmmu/trace-events b/softmmu/trace-events -index 9c88887b3c..22606dc27b 100644 ---- a/softmmu/trace-events -+++ b/softmmu/trace-events -@@ -31,3 +31,10 @@ runstate_set(int current_state, const char *current_state_str, int new_state, co - system_wakeup_request(int reason) "reason=%d" - qemu_system_shutdown_request(int reason) "reason=%d" - qemu_system_powerdown_request(void) "" -+ -+#dirtylimit.c -+dirtylimit_state_initialize(int max_cpus) "dirtylimit state initialize: max cpus %d" -+dirtylimit_state_finalize(void) -+dirtylimit_throttle_pct(int cpu_index, uint64_t pct, int64_t time_us) "CPU[%d] throttle percent: %" PRIu64 ", throttle adjust time %"PRIi64 " us" -+dirtylimit_set_vcpu(int cpu_index, uint64_t quota) "CPU[%d] set dirty page rate limit %"PRIu64 -+dirtylimit_vcpu_execute(int cpu_index, int64_t sleep_time_us) "CPU[%d] sleep %"PRIi64 " us" --- -2.27.0 - diff --git a/softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch b/softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch deleted file mode 100644 index 0d8e64d5df525714eb4d6ca0c31e141d67af7772..0000000000000000000000000000000000000000 --- a/softmmu-physmem-Introduce-MemTxAttrs-memory-field-an.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 96a6c8fa67298d52ccc27a0ac5bdddd6c42068cb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Wed, 15 Dec 2021 19:24:21 +0100 -Subject: [PATCH 3/3] softmmu/physmem: Introduce MemTxAttrs::memory field and - MEMTX_ACCESS_ERROR -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add the 'memory' bit to the memory attributes to restrict bus -controller accesses to memories. - -Introduce flatview_access_allowed() to check bus permission -before running any bus transaction. - -Have read/write accessors return MEMTX_ACCESS_ERROR if an access is -restricted. - -There is no change for the default case where 'memory' is not set. - -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211215182421.418374-4-philmd@redhat.com> -Reviewed-by: Richard Henderson -Reviewed-by: Stefan Hajnoczi -[thuth: Replaced MEMTX_BUS_ERROR with MEMTX_ACCESS_ERROR, remove "inline"] -Signed-off-by: Thomas Huth ---- - include/exec/memattrs.h | 9 +++++++++ - softmmu/physmem.c | 44 +++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 51 insertions(+), 2 deletions(-) - -diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h -index 95f2d20d55..9fb98bc1ef 100644 ---- a/include/exec/memattrs.h -+++ b/include/exec/memattrs.h -@@ -35,6 +35,14 @@ typedef struct MemTxAttrs { - unsigned int secure:1; - /* Memory access is usermode (unprivileged) */ - unsigned int user:1; -+ /* -+ * Bus interconnect and peripherals can access anything (memories, -+ * devices) by default. By setting the 'memory' bit, bus transaction -+ * are restricted to "normal" memories (per the AMBA documentation) -+ * versus devices. Access to devices will be logged and rejected -+ * (see MEMTX_ACCESS_ERROR). -+ */ -+ unsigned int memory:1; - /* Requester ID (for MSI for example) */ - unsigned int requester_id:16; - /* Invert endianness for this page */ -@@ -66,6 +74,7 @@ typedef struct MemTxAttrs { - #define MEMTX_OK 0 - #define MEMTX_ERROR (1U << 0) /* device returned an error */ - #define MEMTX_DECODE_ERROR (1U << 1) /* nothing at that address */ -+#define MEMTX_ACCESS_ERROR (1U << 2) /* access denied */ - typedef uint32_t MemTxResult; - - #endif -diff --git a/softmmu/physmem.c b/softmmu/physmem.c -index 049e7b1454..ae26f72909 100644 ---- a/softmmu/physmem.c -+++ b/softmmu/physmem.c -@@ -41,6 +41,7 @@ - #include "qemu/config-file.h" - #include "qemu/error-report.h" - #include "qemu/qemu-print.h" -+#include "qemu/log.h" - #include "exec/memory.h" - #include "exec/ioport.h" - #include "sysemu/dma.h" -@@ -2767,6 +2768,33 @@ static bool prepare_mmio_access(MemoryRegion *mr) - return release_lock; - } - -+/** -+ * flatview_access_allowed -+ * @mr: #MemoryRegion to be accessed -+ * @attrs: memory transaction attributes -+ * @addr: address within that memory region -+ * @len: the number of bytes to access -+ * -+ * Check if a memory transaction is allowed. -+ * -+ * Returns: true if transaction is allowed, false if denied. -+ */ -+static bool flatview_access_allowed(MemoryRegion *mr, MemTxAttrs attrs, -+ hwaddr addr, hwaddr len) -+{ -+ if (likely(!attrs.memory)) { -+ return true; -+ } -+ if (memory_region_is_ram(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)); -+ return false; -+} -+ - /* Called within RCU critical section. */ - static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, - MemTxAttrs attrs, -@@ -2781,7 +2809,10 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, - const uint8_t *buf = ptr; - - for (;;) { -- if (!memory_access_is_direct(mr, true)) { -+ if (!flatview_access_allowed(mr, attrs, addr1, l)) { -+ result |= MEMTX_ACCESS_ERROR; -+ /* Keep going. */ -+ } else if (!memory_access_is_direct(mr, true)) { - release_lock |= prepare_mmio_access(mr); - l = memory_access_size(mr, l, addr1); - /* XXX: could force current_cpu to NULL to avoid -@@ -2826,6 +2857,9 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, - - l = len; - mr = flatview_translate(fv, addr, &addr1, &l, true, attrs); -+ if (!flatview_access_allowed(mr, attrs, addr, len)) { -+ return MEMTX_ACCESS_ERROR; -+ } - return flatview_write_continue(fv, addr, attrs, buf, len, - addr1, l, mr); - } -@@ -2844,7 +2878,10 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, - - fuzz_dma_read_cb(addr, len, mr); - for (;;) { -- if (!memory_access_is_direct(mr, false)) { -+ if (!flatview_access_allowed(mr, attrs, addr1, l)) { -+ result |= MEMTX_ACCESS_ERROR; -+ /* Keep going. */ -+ } else if (!memory_access_is_direct(mr, false)) { - /* I/O case */ - release_lock |= prepare_mmio_access(mr); - l = memory_access_size(mr, l, addr1); -@@ -2887,6 +2924,9 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr, - - l = len; - mr = flatview_translate(fv, addr, &addr1, &l, false, attrs); -+ if (!flatview_access_allowed(mr, attrs, addr, len)) { -+ return MEMTX_ACCESS_ERROR; -+ } - return flatview_read_continue(fv, addr, attrs, buf, len, - addr1, l, mr); - } --- -2.27.0 - diff --git a/softmmu-physmem-Simplify-flatview_write-and-address_.patch b/softmmu-physmem-Simplify-flatview_write-and-address_.patch deleted file mode 100644 index 833fa849ba5afd9a7990aa611fadb47db9bb1267..0000000000000000000000000000000000000000 --- a/softmmu-physmem-Simplify-flatview_write-and-address_.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 105c54fca54e73f17abe244b457872926e43f8a2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Wed, 15 Dec 2021 19:24:20 +0100 -Subject: [PATCH 2/3] softmmu/physmem: Simplify flatview_write and - address_space_access_valid -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove unuseful local 'result' variables. - -Reviewed-by: Peter Xu -Reviewed-by: David Hildenbrand -Reviewed-by: Alexander Bulekov -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211215182421.418374-3-philmd@redhat.com> -Signed-off-by: Thomas Huth ---- - softmmu/physmem.c | 11 +++-------- - 1 file changed, 3 insertions(+), 8 deletions(-) - -diff --git a/softmmu/physmem.c b/softmmu/physmem.c -index 3b9a61448c..049e7b1454 100644 ---- a/softmmu/physmem.c -+++ b/softmmu/physmem.c -@@ -2823,14 +2823,11 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, - hwaddr l; - hwaddr addr1; - MemoryRegion *mr; -- MemTxResult result = MEMTX_OK; - - l = len; - mr = flatview_translate(fv, addr, &addr1, &l, true, attrs); -- result = flatview_write_continue(fv, addr, attrs, buf, len, -- addr1, l, mr); -- -- return result; -+ return flatview_write_continue(fv, addr, attrs, buf, len, -+ addr1, l, mr); - } - - /* Called within RCU critical section. */ -@@ -3127,12 +3124,10 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs) - { - FlatView *fv; -- bool result; - - RCU_READ_LOCK_GUARD(); - fv = address_space_to_flatview(as); -- result = flatview_access_valid(fv, addr, len, is_write, attrs); -- return result; -+ return flatview_access_valid(fv, addr, len, is_write, attrs); - } - - static hwaddr --- -2.27.0 - diff --git a/spapr-pci-Correct-does-not-support-hotplugging-error.patch b/spapr-pci-Correct-does-not-support-hotplugging-error.patch deleted file mode 100644 index cb82a76b8f5921ec0e6db32fe1ddc787c2325243..0000000000000000000000000000000000000000 --- a/spapr-pci-Correct-does-not-support-hotplugging-error.patch +++ /dev/null @@ -1,45 +0,0 @@ -From f647bc67bcdbfc2dd1cb1f1ba1abdb2b04c5c10f Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Mon, 27 Nov 2023 16:19:33 +0800 -Subject: [PATCH] spapr/pci: Correct "does not support hotplugging error - messages - -cherry picked from db8227a68addb9db6392001c7e02d406282ea462 - -When dynamic-reconfiguration is off, hot plug / unplug can fail with -"Bus 'spapr-pci-host-bridge' does not support hotplugging". -spapr-pci-host-bridge is a device, not a bus. Report the name of the -bus it provides instead: 'pci.0'. - -Signed-off-by: Markus Armbruster -Message-ID: <20231031111059.3407803-2-armbru@redhat.com> -Reviewed-by: Daniel Henrique Barboza ---- - hw/ppc/spapr_pci.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c -index d3367e8578..3b518f1be9 100644 ---- a/hw/ppc/spapr_pci.c -+++ b/hw/ppc/spapr_pci.c -@@ -1554,7 +1554,7 @@ static void spapr_pci_pre_plug(HotplugHandler *plug_handler, - */ - if (plugged_dev->hotplugged) { - error_setg(errp, QERR_BUS_NO_HOTPLUG, -- object_get_typename(OBJECT(phb))); -+ phb->parent_obj.bus->qbus.name); - return; - } - } -@@ -1677,7 +1677,7 @@ static void spapr_pci_unplug_request(HotplugHandler *plug_handler, - - if (!phb->dr_enabled) { - error_setg(errp, QERR_BUS_NO_HOTPLUG, -- object_get_typename(OBJECT(phb))); -+ phb->parent_obj.bus->qbus.name); - return; - } - --- -2.27.0 - diff --git a/sphinx-change-default-language-to-en.patch b/sphinx-change-default-language-to-en.patch deleted file mode 100644 index 77f2b2af213566c273c942fe6d9f18b56c352d3e..0000000000000000000000000000000000000000 --- a/sphinx-change-default-language-to-en.patch +++ /dev/null @@ -1,38 +0,0 @@ -From a6861159f23833f878be833e2c0c37060ac14513 Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:57:47 -0800 -Subject: [PATCH] sphinx: change default language to 'en' - -cherry picked from commit ba1a6723f58640ba281bc952abc255e97c70bad5 - -Fixes the following Sphinx warning (treated as error) starting -with 5.0 release: - -Warning, treated as error: -Invalid configuration value found: 'language = None'. Update your configuration to a valid langauge code. Falling back to 'en' (English). - -Signed-off-by: Martin Liska -Message-id: e91e51ee-48ac-437e-6467-98b56ee40042@suse.cz -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell -Signed-off-by: Wanghe Xiao ---- - docs/conf.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/docs/conf.py b/docs/conf.py -index 763e7d2434..84b593e12a 100644 ---- a/docs/conf.py -+++ b/docs/conf.py -@@ -120,7 +120,7 @@ - # - # This is also used if you do content translation via gettext catalogs. - # Usually you set "language" from the command line for these cases. --language = None -+language = 'en' - - # List of patterns, relative to source directory, that match files and - # directories to ignore when looking for source files. --- -2.27.0 - diff --git a/sw_64-Add-sw64-architecture-support.patch b/sw_64-Add-sw64-architecture-support.patch deleted file mode 100644 index 4bffadfbd69453b5c58bc32e821ed88148d809e1..0000000000000000000000000000000000000000 --- a/sw_64-Add-sw64-architecture-support.patch +++ /dev/null @@ -1,18277 +0,0 @@ -From d74713d8e656e8d0f7a5200122119802e639ff49 Mon Sep 17 00:00:00 2001 -From: Lu Feifei -Date: Mon, 14 Mar 2022 11:04:02 +0800 -Subject: [PATCH] sw_64: Add sw64 architecture support - -Signed-off-by: Lu Feifei ---- - configs/devices/sw64-softmmu/default.mak | 10 + - configs/targets/sw64-softmmu.mak | 8 + - configure | 7 + - disas.c | 2 + - disas/meson.build | 1 + - disas/sw64.c | 1242 +++++++ - hw/Kconfig | 1 + - hw/meson.build | 1 + - hw/rtc/sun4v-rtc.c | 11 + - hw/sw64/Kconfig | 11 + - hw/sw64/Makefile.objs | 1 + - hw/sw64/core.h | 25 + - hw/sw64/core3.c | 182 ++ - hw/sw64/core3_board.c | 493 +++ - hw/sw64/meson.build | 10 + - hw/sw64/sw64_iommu.c | 567 ++++ - hw/sw64/trace-events | 3 + - include/disas/dis-asm.h | 4 + - include/elf.h | 44 + - include/hw/sw64/sw64_iommu.h | 105 + - include/qemu/atomic.h | 2 + - include/qemu/timer.h | 10 + - include/sysemu/arch_init.h | 1 + - linux-headers/asm-sw64/kvm.h | 122 + - linux-headers/asm-sw64/unistd.h | 380 +++ - linux-user/meson.build | 1 + - linux-user/sw64/cpu_loop.c | 108 + - linux-user/sw64/signal.c | 273 ++ - linux-user/sw64/sockbits.h | 1 + - linux-user/sw64/syscall_nr.h | 471 +++ - linux-user/sw64/target_cpu.h | 38 + - linux-user/sw64/target_elf.h | 14 + - linux-user/sw64/target_fcntl.h | 11 + - linux-user/sw64/target_signal.h | 98 + - linux-user/sw64/target_structs.h | 47 + - linux-user/sw64/target_syscall.h | 121 + - linux-user/sw64/termbits.h | 265 ++ - meson.build | 12 +- - pc-bios/core3-hmcode | Bin 0 -> 225904 bytes - pc-bios/core3-reset | Bin 0 -> 5032 bytes - pc-bios/core4-hmcode | Bin 0 -> 243040 bytes - pc-bios/meson.build | 3 + - pc-bios/uefi-bios-sw | Bin 0 -> 3145728 bytes - qapi/machine.json | 2 +- - softmmu/qdev-monitor.c | 3 +- - target/Kconfig | 1 + - target/meson.build | 1 + - target/sw64/Kconfig | 2 + - target/sw64/Makefile.objs | 4 + - target/sw64/cpu-param.h | 24 + - target/sw64/cpu-qom.h | 47 + - target/sw64/cpu.c | 457 +++ - target/sw64/cpu.h | 406 +++ - target/sw64/exception.c | 76 + - target/sw64/float_helper.c | 846 +++++ - target/sw64/helper.c | 349 ++ - target/sw64/helper.h | 127 + - target/sw64/int_helper.c | 118 + - target/sw64/kvm.c | 215 ++ - target/sw64/kvm_sw64.h | 47 + - target/sw64/machine.c | 18 + - target/sw64/meson.build | 19 + - target/sw64/profile.c | 2342 +++++++++++++ - target/sw64/profile.h | 541 +++ - target/sw64/simd_helper.c | 1058 ++++++ - target/sw64/translate.c | 3798 ++++++++++++++++++++++ - target/sw64/translate.h | 60 + - tcg/sw64/tcg-target-con-set.h | 39 + - tcg/sw64/tcg-target-con-str.h | 28 + - tcg/sw64/tcg-target.c.inc | 2109 ++++++++++++ - tcg/sw64/tcg-target.h | 123 + - tcg/sw64/tcg-target.opc.h | 15 + - 72 files changed, 17578 insertions(+), 3 deletions(-) - create mode 100644 configs/devices/sw64-softmmu/default.mak - create mode 100644 configs/targets/sw64-softmmu.mak - create mode 100755 disas/sw64.c - create mode 100644 hw/sw64/Kconfig - create mode 100644 hw/sw64/Makefile.objs - create mode 100644 hw/sw64/core.h - create mode 100644 hw/sw64/core3.c - create mode 100644 hw/sw64/core3_board.c - create mode 100644 hw/sw64/meson.build - create mode 100644 hw/sw64/sw64_iommu.c - create mode 100644 hw/sw64/trace-events - create mode 100644 include/hw/sw64/sw64_iommu.h - create mode 100644 linux-headers/asm-sw64/kvm.h - create mode 100644 linux-headers/asm-sw64/unistd.h - create mode 100644 linux-user/sw64/cpu_loop.c - create mode 100644 linux-user/sw64/signal.c - create mode 100644 linux-user/sw64/sockbits.h - create mode 100644 linux-user/sw64/syscall_nr.h - create mode 100644 linux-user/sw64/target_cpu.h - create mode 100644 linux-user/sw64/target_elf.h - create mode 100644 linux-user/sw64/target_fcntl.h - create mode 100644 linux-user/sw64/target_signal.h - create mode 100644 linux-user/sw64/target_structs.h - create mode 100644 linux-user/sw64/target_syscall.h - create mode 100644 linux-user/sw64/termbits.h - create mode 100755 pc-bios/core3-hmcode - create mode 100755 pc-bios/core3-reset - create mode 100755 pc-bios/core4-hmcode - create mode 100755 pc-bios/uefi-bios-sw - create mode 100644 target/sw64/Kconfig - create mode 100644 target/sw64/Makefile.objs - create mode 100644 target/sw64/cpu-param.h - create mode 100644 target/sw64/cpu-qom.h - create mode 100644 target/sw64/cpu.c - create mode 100644 target/sw64/cpu.h - create mode 100644 target/sw64/exception.c - create mode 100644 target/sw64/float_helper.c - create mode 100644 target/sw64/helper.c - create mode 100644 target/sw64/helper.h - create mode 100644 target/sw64/int_helper.c - create mode 100644 target/sw64/kvm.c - create mode 100644 target/sw64/kvm_sw64.h - create mode 100644 target/sw64/machine.c - create mode 100644 target/sw64/meson.build - create mode 100644 target/sw64/profile.c - create mode 100644 target/sw64/profile.h - create mode 100644 target/sw64/simd_helper.c - create mode 100644 target/sw64/translate.c - create mode 100644 target/sw64/translate.h - create mode 100755 tcg/sw64/tcg-target-con-set.h - create mode 100755 tcg/sw64/tcg-target-con-str.h - create mode 100755 tcg/sw64/tcg-target.c.inc - create mode 100755 tcg/sw64/tcg-target.h - create mode 100755 tcg/sw64/tcg-target.opc.h - -diff --git a/configs/devices/sw64-softmmu/default.mak b/configs/devices/sw64-softmmu/default.mak -new file mode 100644 -index 0000000000..0b4d56b43e ---- /dev/null -+++ b/configs/devices/sw64-softmmu/default.mak -@@ -0,0 +1,10 @@ -+# Default configuration for sw64-softmmu -+ -+# Uncomment the following lines to disable these optional devices: -+# -+#CONFIG_PCI_DEVICES=n -+#CONFIG_TEST_DEVICES=n -+ -+# Boards: -+# -+CONFIG_CORE3=y -diff --git a/configs/targets/sw64-softmmu.mak b/configs/targets/sw64-softmmu.mak -new file mode 100644 -index 0000000000..37cc2e05a6 ---- /dev/null -+++ b/configs/targets/sw64-softmmu.mak -@@ -0,0 +1,8 @@ -+# Default configuration for sw64-softmmu -+ -+# Boards: -+# -+TARGET_ARCH=sw64 -+TARGET_BASE_ARCH=sw64 -+TARGET_ABI_DIR=sw64 -+TARGET_SUPPORTS_MTTCG=y -diff --git a/configure b/configure -index 48c21775f3..9569d7a3d0 100755 ---- a/configure -+++ b/configure -@@ -612,6 +612,9 @@ case "$cpu" in - sparc|sun4[cdmuv]) - cpu="sparc" - ;; -+ sw_64) -+ cpu="sw64" -+ ;; - *) - # This will result in either an error or falling back to TCI later - ARCH=unknown -@@ -3268,6 +3271,10 @@ alpha) - # Ensure there's only a single GP - QEMU_CFLAGS="-msmall-data $QEMU_CFLAGS" - ;; -+sw*) -+ # Ensure there's only a single GP -+ QEMU_CFLAGS="-msmall-data $QEMU_CFLAGS" -+;; - esac - - if test "$gprof" = "yes" ; then -diff --git a/disas.c b/disas.c -index 3dab4482d1..897de1d9a9 100644 ---- a/disas.c -+++ b/disas.c -@@ -207,6 +207,8 @@ static void initialize_debug_host(CPUDebug *s) - s->info.cap_insn_split = 6; - #elif defined(__hppa__) - s->info.print_insn = print_insn_hppa; -+#elif defined(__sw_64__) -+ s->info.print_insn = print_insn_sw_64; - #endif - } - -diff --git a/disas/meson.build b/disas/meson.build -index 449f99e1de..5c5daa69a7 100644 ---- a/disas/meson.build -+++ b/disas/meson.build -@@ -20,4 +20,5 @@ common_ss.add(when: 'CONFIG_S390_DIS', if_true: files('s390.c')) - common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c')) - common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c')) - common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c')) -+common_ss.add(when: 'CONFIG_SW64_DIS', if_true: files('sw64.c')) - common_ss.add(when: capstone, if_true: files('capstone.c')) -diff --git a/disas/sw64.c b/disas/sw64.c -new file mode 100755 -index 0000000000..c5bd578e07 ---- /dev/null -+++ b/disas/sw64.c -@@ -0,0 +1,1242 @@ -+/* -+ * sw_64-dis.c -- Disassemble Sw_64 CORE3 instructions -+ * -+ * This file is part of libopcodes. -+ * -+ * This library is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 3, or (at your option) -+ * any later version. -+ * -+ * It is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -+ * License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this file; see the file COPYING. If not, write to the Free -+ * Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA -+ * 02110-1301, USA. -+ */ -+ -+#include "qemu/osdep.h" -+#include "disas/dis-asm.h" -+ -+#undef MAX -+ -+struct sw_64_opcode { -+ /* The opcode name. */ -+ const char *name; -+ -+ /* The opcode itself. Those bits which will be filled in with -+ operands are zeroes. */ -+ unsigned opcode; -+ -+ /* The opcode mask. This is used by the disassembler. This is a -+ mask containing ones indicating those bits which must match the -+ opcode field, and zeroes indicating those bits which need not -+ match (and are presumably filled in by operands). */ -+ unsigned mask; -+ -+ /* One bit flags for the opcode. These are primarily used to -+ indicate specific processors and environments support the -+ instructions. The defined values are listed below. */ -+ unsigned flags; -+ -+ /* An array of operand codes. Each code is an index into the -+ operand table. They appear in the order which the operands must -+ appear in assembly code, and are terminated by a zero. */ -+ unsigned char operands[5]; -+}; -+ -+/* The table itself is sorted by major opcode number, and is otherwise -+ in the order in which the disassembler should consider -+ instructions. */ -+extern const struct sw_64_opcode sw_64_opcodes[]; -+extern const unsigned sw_64_num_opcodes; -+ -+/* Values defined for the flags field of a struct sw_64_opcode. */ -+ -+/* CPU Availability */ -+#define SW_OPCODE_BASE 0x0001 /* Base architecture insns. */ -+#define SW_OPCODE_CORE3 0x0002 /* Core3 private insns. */ -+#define SW_LITOP(i) (((i) >> 26) & 0x3D) -+ -+#define SW_OPCODE_NOHM (~(SW_OPCODE_BASE|SW_OPCODE_CORE3)) -+ -+/* A macro to extract the major opcode from an instruction. */ -+#define SW_OP(i) (((i) >> 26) & 0x3F) -+ -+/* The total number of major opcodes. */ -+#define SW_NOPS 0x40 -+ -+/* The operands table is an array of struct sw_64_operand. */ -+ -+struct sw_64_operand { -+ /* The number of bits in the operand. */ -+ unsigned int bits : 5; -+ -+ /* How far the operand is left shifted in the instruction. */ -+ unsigned int shift : 5; -+ -+ /* The default relocation type for this operand. */ -+ signed int default_reloc : 16; -+ -+ /* One bit syntax flags. */ -+ unsigned int flags : 16; -+ -+ /* Insertion function. This is used by the assembler. To insert an -+ operand value into an instruction, check this field. -+ -+ If it is NULL, execute -+ i |= (op & ((1 << o->bits) - 1)) << o->shift; -+ (i is the instruction which we are filling in, o is a pointer to -+ this structure, and op is the opcode value; this assumes twos -+ complement arithmetic). -+ -+ If this field is not NULL, then simply call it with the -+ instruction and the operand value. It will return the new value -+ of the instruction. If the ERRMSG argument is not NULL, then if -+ the operand value is illegal, *ERRMSG will be set to a warning -+ string (the operand will be inserted in any case). If the -+ operand value is legal, *ERRMSG will be unchanged (most operands -+ can accept any value). */ -+ unsigned (*insert) (unsigned instruction, int op, const char **errmsg); -+ -+ /* Extraction function. This is used by the disassembler. To -+ extract this operand type from an instruction, check this field. -+ -+ If it is NULL, compute -+ op = ((i) >> o->shift) & ((1 << o->bits) - 1); -+ if ((o->flags & SW_OPERAND_SIGNED) != 0 -+ && (op & (1 << (o->bits - 1))) != 0) -+ op -= 1 << o->bits; -+ (i is the instruction, o is a pointer to this structure, and op -+ is the result; this assumes twos complement arithmetic). -+ -+ If this field is not NULL, then simply call it with the -+ instruction value. It will return the value of the operand. If -+ the INVALID argument is not NULL, *INVALID will be set to -+ non-zero if this operand type can not actually be extracted from -+ this operand (i.e., the instruction does not match). If the -+ operand is valid, *INVALID will not be changed. */ -+ int (*extract) (unsigned instruction, int *invalid); -+}; -+ -+/* Elements in the table are retrieved by indexing with values from -+ the operands field of the sw_64_opcodes table. */ -+ -+extern const struct sw_64_operand sw_64_operands[]; -+extern const unsigned sw_64_num_operands; -+/* Values defined for the flags field of a struct sw_64_operand. */ -+ -+/* Mask for selecting the type for typecheck purposes */ -+#define SW_OPERAND_TYPECHECK_MASK \ -+ (SW_OPERAND_PARENS | SW_OPERAND_COMMA | SW_OPERAND_IR | \ -+ SW_OPERAND_FPR | SW_OPERAND_RELATIVE | SW_OPERAND_SIGNED | \ -+ SW_OPERAND_UNSIGNED) -+ -+/* This operand does not actually exist in the assembler input. This -+ is used to support extended mnemonics, for which two operands fields -+ are identical. The assembler should call the insert function with -+ any op value. The disassembler should call the extract function, -+ ignore the return value, and check the value placed in the invalid -+ argument. */ -+#define SW_OPERAND_FAKE 01 -+ -+/* The operand should be wrapped in parentheses rather than separated -+ from the previous by a comma. This is used for the load and store -+ instructions which want their operands to look like "Ra,disp(Rb)". */ -+#define SW_OPERAND_PARENS 02 -+ -+/* Used in combination with PARENS, this supresses the supression of -+ the comma. This is used for "jmp Ra,(Rb),hint". */ -+#define SW_OPERAND_COMMA 04 -+ -+/* This operand names an integer register. */ -+#define SW_OPERAND_IR 010 -+ -+/* This operand names a floating point register. */ -+#define SW_OPERAND_FPR 020 -+ -+/* This operand is a relative branch displacement. The disassembler -+ prints these symbolically if possible. */ -+#define SW_OPERAND_RELATIVE 040 -+ -+/* This operand takes signed values. */ -+#define SW_OPERAND_SIGNED 0100 -+ -+/* This operand takes unsigned values. This exists primarily so that -+ a flags value of 0 can be treated as end-of-arguments. */ -+#define SW_OPERAND_UNSIGNED 0200 -+ -+/* Supress overflow detection on this field. This is used for hints. */ -+#define SW_OPERAND_NOOVERFLOW 0400 -+ -+/* Mask for optional argument default value. */ -+#define SW_OPERAND_OPTIONAL_MASK 07000 -+ -+/* This operand defaults to zero. This is used for jump hints. */ -+#define SW_OPERAND_DEFAULT_ZERO 01000 -+ -+/* This operand should default to the first (real) operand and is used -+ in conjunction with SW_OPERAND_OPTIONAL. This allows -+ "and $0,3,$0" to be written as "and $0,3", etc. I don't like -+ it, but it's what DEC does. */ -+#define SW_OPERAND_DEFAULT_FIRST 02000 -+ -+/* Similarly, this operand should default to the second (real) operand. -+ This allows "negl $0" instead of "negl $0,$0". */ -+#define SW_OPERAND_DEFAULT_SECOND 04000 -+ -+/* Register common names */ -+ -+#define SW_REG_V0 0 -+#define SW_REG_T0 1 -+#define SW_REG_T1 2 -+#define SW_REG_T2 3 -+#define SW_REG_T3 4 -+#define SW_REG_T4 5 -+#define SW_REG_T5 6 -+#define SW_REG_T6 7 -+#define SW_REG_T7 8 -+#define SW_REG_S0 9 -+#define SW_REG_S1 10 -+#define SW_REG_S2 11 -+#define SW_REG_S3 12 -+#define SW_REG_S4 13 -+#define SW_REG_S5 14 -+#define SW_REG_FP 15 -+#define SW_REG_A0 16 -+#define SW_REG_A1 17 -+#define SW_REG_A2 18 -+#define SW_REG_A3 19 -+#define SW_REG_A4 20 -+#define SW_REG_A5 21 -+#define SW_REG_T8 22 -+#define SW_REG_T9 23 -+#define SW_REG_T10 24 -+#define SW_REG_T11 25 -+#define SW_REG_RA 26 -+#define SW_REG_PV 27 -+#define SW_REG_T12 27 -+#define SW_REG_AT 28 -+#define SW_REG_GP 29 -+#define SW_REG_SP 30 -+#define SW_REG_ZERO 31 -+ -+enum bfd_reloc_code_real { -+ BFD_RELOC_23_PCREL_S2, -+ BFD_RELOC_SW_64_HINT -+}; -+ -+static unsigned insert_rba(unsigned insn, int value ATTRIBUTE_UNUSED, -+ const char **errmsg ATTRIBUTE_UNUSED) -+{ -+ return insn | (((insn >> 21) & 0x1f) << 16); -+} -+ -+static int extract_rba(unsigned insn, int *invalid) -+{ -+ if (invalid != (int *) NULL -+ && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f)) -+ *invalid = 1; -+ return 0; -+} -+ -+/* The same for the RC field. */ -+static unsigned insert_rca(unsigned insn, int value ATTRIBUTE_UNUSED, -+ const char **errmsg ATTRIBUTE_UNUSED) -+{ -+ return insn | ((insn >> 21) & 0x1f); -+} -+ -+static unsigned insert_rdc(unsigned insn, int value ATTRIBUTE_UNUSED, -+ const char **errmsg ATTRIBUTE_UNUSED) -+{ -+ return insn | ((insn >> 5) & 0x1f); -+} -+ -+static int extract_rdc(unsigned insn, int *invalid) -+{ -+ if (invalid != (int *) NULL -+ && ((insn >> 5) & 0x1f) != (insn & 0x1f)) -+ *invalid = 1; -+ return 0; -+} -+ -+static int extract_rca(unsigned insn, int *invalid) -+{ -+ if (invalid != (int *) NULL -+ && ((insn >> 21) & 0x1f) != (insn & 0x1f)) -+ *invalid = 1; -+ return 0; -+} -+ -+/* Fake arguments in which the registers must be set to ZERO. */ -+static unsigned insert_za(unsigned insn, int value ATTRIBUTE_UNUSED, -+ const char **errmsg ATTRIBUTE_UNUSED) -+{ -+ return insn | (31 << 21); -+} -+ -+static int extract_za(unsigned insn, int *invalid) -+{ -+ if (invalid != (int *) NULL && ((insn >> 21) & 0x1f) != 31) -+ *invalid = 1; -+ return 0; -+} -+ -+static unsigned insert_zb(unsigned insn, int value ATTRIBUTE_UNUSED, -+ const char **errmsg ATTRIBUTE_UNUSED) -+{ -+ return insn | (31 << 16); -+} -+ -+static int extract_zb(unsigned insn, int *invalid) -+{ -+ if (invalid != (int *) NULL && ((insn >> 16) & 0x1f) != 31) -+ *invalid = 1; -+ return 0; -+} -+ -+static unsigned insert_zc(unsigned insn, int value ATTRIBUTE_UNUSED, -+ const char **errmsg ATTRIBUTE_UNUSED) -+{ -+ return insn | 31; -+} -+ -+static int extract_zc(unsigned insn, int *invalid) -+{ -+ if (invalid != (int *) NULL && (insn & 0x1f) != 31) -+ *invalid = 1; -+ return 0; -+} -+ -+ -+/* The displacement field of a Branch format insn. */ -+ -+static unsigned insert_bdisp(unsigned insn, int value, const char **errmsg) -+{ -+ if (errmsg != (const char **)NULL && (value & 3)) -+ *errmsg = "branch operand unaligned"; -+ return insn | ((value / 4) & 0x1FFFFF); -+} -+ -+static int extract_bdisp(unsigned insn, int *invalid ATTRIBUTE_UNUSED) -+{ -+ return 4 * (((insn & 0x1FFFFF) ^ 0x100000) - 0x100000); -+} -+ -+static unsigned insert_bdisp26(unsigned insn, int value, const char **errmsg) -+{ -+ if (errmsg != (const char **)NULL && (value & 3)) -+ *errmsg = "branch operand unaligned"; -+ return insn | ((value / 4) & 0x3FFFFFF); -+} -+ -+static int extract_bdisp26(unsigned insn, int *invalid ATTRIBUTE_UNUSED) -+{ -+ return 4 * (((insn & 0x3FFFFFF) ^ 0x2000000) - 0x2000000); -+} -+ -+/* The hint field of a JMP/JSR insn. */ -+/* sw use 16 bits hint disp. */ -+static unsigned insert_jhint(unsigned insn, int value, const char **errmsg) -+{ -+ if (errmsg != (const char **)NULL && (value & 3)) -+ *errmsg = "jump hint unaligned"; -+ return insn | ((value / 4) & 0xFFFF); -+} -+ -+static int extract_jhint(unsigned insn, int *invalid ATTRIBUTE_UNUSED) -+{ -+ return 4 * (((insn & 0xFFFF) ^ 0x8000) - 0x8000); -+} -+ -+/* The hint field of an CORE3 HW_JMP/JSR insn. */ -+ -+static unsigned insert_sw4hwjhint(unsigned insn, int value, const char **errmsg) -+{ -+ if (errmsg != (const char **)NULL && (value & 3)) -+ *errmsg = "jump hint unaligned"; -+ return insn | ((value / 4) & 0x1FFF); -+} -+ -+static int extract_sw4hwjhint(unsigned insn, int *invalid ATTRIBUTE_UNUSED) -+{ -+ return 4 * (((insn & 0x1FFF) ^ 0x1000) - 0x1000); -+} -+ -+/* The operands table. */ -+ -+const struct sw_64_operand sw_64_operands[] = { -+ /* The fields are bits, shift, insert, extract, flags */ -+ /* The zero index is used to indicate end-of-list */ -+#define UNUSED 0 -+ { 0, 0, 0, 0, 0, 0 }, -+ -+ /* The plain integer register fields. */ -+#define RA (UNUSED + 1) -+ { 5, 21, 0, SW_OPERAND_IR, 0, 0 }, -+#define RB (RA + 1) -+ { 5, 16, 0, SW_OPERAND_IR, 0, 0 }, -+#define RC (RB + 1) -+ { 5, 0, 0, SW_OPERAND_IR, 0, 0 }, -+ -+ /* The plain fp register fields. */ -+#define FA (RC + 1) -+ { 5, 21, 0, SW_OPERAND_FPR, 0, 0 }, -+#define FB (FA + 1) -+ { 5, 16, 0, SW_OPERAND_FPR, 0, 0 }, -+#define FC (FB + 1) -+ { 5, 0, 0, SW_OPERAND_FPR, 0, 0 }, -+ -+ /* The integer registers when they are ZERO. */ -+#define ZA (FC + 1) -+ { 5, 21, 0, SW_OPERAND_FAKE, insert_za, extract_za }, -+#define ZB (ZA + 1) -+ { 5, 16, 0, SW_OPERAND_FAKE, insert_zb, extract_zb }, -+#define ZC (ZB + 1) -+ { 5, 0, 0, SW_OPERAND_FAKE, insert_zc, extract_zc }, -+ -+ /* The RB field when it needs parentheses. */ -+#define PRB (ZC + 1) -+ { 5, 16, 0, SW_OPERAND_IR | SW_OPERAND_PARENS, 0, 0 }, -+ -+ /* The RB field when it needs parentheses _and_ a preceding comma. */ -+#define CPRB (PRB + 1) -+ { 5, 16, 0, -+ SW_OPERAND_IR | SW_OPERAND_PARENS | SW_OPERAND_COMMA, 0, 0 }, -+ -+ /* The RB field when it must be the same as the RA field. */ -+#define RBA (CPRB + 1) -+ { 5, 16, 0, SW_OPERAND_FAKE, insert_rba, extract_rba }, -+ -+ /* The RC field when it must be the same as the RB field. */ -+#define RCA (RBA + 1) -+ { 5, 0, 0, SW_OPERAND_FAKE, insert_rca, extract_rca }, -+ -+#define RDC (RCA + 1) -+ { 5, 0, 0, SW_OPERAND_FAKE, insert_rdc, extract_rdc }, -+ -+ /* The RC field when it can *default* to RA. */ -+#define DRC1 (RDC + 1) -+ { 5, 0, 0, -+ SW_OPERAND_IR | SW_OPERAND_DEFAULT_FIRST, 0, 0 }, -+ -+ /* The RC field when it can *default* to RB. */ -+#define DRC2 (DRC1 + 1) -+ { 5, 0, 0, -+ SW_OPERAND_IR | SW_OPERAND_DEFAULT_SECOND, 0, 0 }, -+ -+ /* The FC field when it can *default* to RA. */ -+#define DFC1 (DRC2 + 1) -+ { 5, 0, 0, -+ SW_OPERAND_FPR | SW_OPERAND_DEFAULT_FIRST, 0, 0 }, -+ -+ /* The FC field when it can *default* to RB. */ -+#define DFC2 (DFC1 + 1) -+ { 5, 0, 0, -+ SW_OPERAND_FPR | SW_OPERAND_DEFAULT_SECOND, 0, 0 }, -+ -+ /* The unsigned 8-bit literal of Operate format insns. */ -+#define LIT (DFC2 + 1) -+ { 8, 13, -LIT, SW_OPERAND_UNSIGNED, 0, 0 }, -+ -+ /* The signed 16-bit displacement of Memory format insns. From here -+ we can't tell what relocation should be used, so don't use a default. */ -+#define MDISP (LIT + 1) -+ { 16, 0, -MDISP, SW_OPERAND_SIGNED, 0, 0 }, -+ -+ /* The signed "23-bit" aligned displacement of Branch format insns. */ -+#define BDISP (MDISP + 1) -+ { 21, 0, BFD_RELOC_23_PCREL_S2, -+ SW_OPERAND_RELATIVE, insert_bdisp, extract_bdisp }, -+ -+ /* The 26-bit hmcode function for sys_call and sys_call / b. */ -+#define HMFN (BDISP + 1) -+ { 25, 0, -HMFN, SW_OPERAND_UNSIGNED, 0, 0 }, -+ -+ /* sw jsr/ret insntructions has no function bits. */ -+ /* The optional signed "16-bit" aligned displacement of the JMP/JSR hint. */ -+#define JMPHINT (HMFN + 1) -+ { 16, 0, BFD_RELOC_SW_64_HINT, -+ SW_OPERAND_RELATIVE | SW_OPERAND_DEFAULT_ZERO | SW_OPERAND_NOOVERFLOW, -+ insert_jhint, extract_jhint }, -+ -+ /* The optional hint to RET/JSR_COROUTINE. */ -+#define RETHINT (JMPHINT + 1) -+ { 16, 0, -RETHINT, -+ SW_OPERAND_UNSIGNED | SW_OPERAND_DEFAULT_ZERO, 0, 0 }, -+ -+ /* The 12-bit displacement for the core3 hw_{ld,st} (pal1b/pal1f) insns. */ -+#define HWDISP (RETHINT + 1) -+ { 12, 0, -HWDISP, SW_OPERAND_SIGNED, 0, 0 }, -+ -+ /* The 16-bit combined index/scoreboard mask for the core3 -+ hw_m[ft]pr (pal19/pal1d) insns. */ -+#define HWINDEX (HWDISP + 1) -+ { 16, 0, -HWINDEX, SW_OPERAND_UNSIGNED, 0, 0 }, -+ -+ /* The 13-bit branch hint for the core3 hw_jmp/jsr (pal1e) insn. */ -+#define HWJMPHINT (HWINDEX + 1) -+ { 8, 0, -HWJMPHINT, -+ SW_OPERAND_RELATIVE | SW_OPERAND_DEFAULT_ZERO | SW_OPERAND_NOOVERFLOW, -+ insert_sw4hwjhint, extract_sw4hwjhint }, -+ -+ /* for the third operand of ternary operands integer insn. */ -+#define R3 (HWJMPHINT + 1) -+ { 5, 5, 0, SW_OPERAND_IR, 0, 0 }, -+ /* The plain fp register fields */ -+#define F3 (R3 + 1) -+ { 5, 5, 0, SW_OPERAND_FPR, 0, 0 }, -+ /* sw simd settle instruction lit */ -+#define FMALIT (F3 + 1) -+ { 5, 5, -FMALIT, SW_OPERAND_UNSIGNED, 0, 0 }, //V1.1 -+#define LMDISP (FMALIT + 1) -+ { 15, 0, -LMDISP, SW_OPERAND_UNSIGNED, 0, 0 }, -+#define RPIINDEX (LMDISP + 1) -+ { 8, 0, -RPIINDEX, SW_OPERAND_UNSIGNED, 0, 0 }, -+#define ATMDISP (RPIINDEX + 1) -+ { 12, 0, -ATMDISP, SW_OPERAND_SIGNED, 0, 0 }, -+#define DISP13 (ATMDISP + 1) -+ { 13, 13, -DISP13, SW_OPERAND_SIGNED, 0, 0}, -+#define BDISP26 (DISP13 + 1) -+ { 26, 0, 222, -+ SW_OPERAND_RELATIVE, insert_bdisp26, extract_bdisp26 }, -+#define DPFTH (BDISP26 + 1) -+ { 5, 21, -DPFTH, SW_OPERAND_UNSIGNED, 0, 0} -+}; -+ -+const unsigned sw_64_num_operands = sizeof(sw_64_operands) / sizeof(*sw_64_operands); -+ -+/* Macros used to form opcodes. */ -+ -+/* The main opcode. */ -+#define OP(x) (((x) & 0x3F) << 26) -+#define OP_MASK 0xFC000000 -+ -+/* Branch format instructions. */ -+#define BRA_(oo) OP(oo) -+#define BRA_MASK OP_MASK -+#define BRA(oo) BRA_(oo), BRA_MASK -+ -+#ifdef HUANGLM20171113 -+/* Floating point format instructions. */ -+#define FP_(oo,fff) (OP(oo) | (((fff) & 0x7FF) << 5)) -+#define FP_MASK (OP_MASK | 0xFFE0) -+#define FP(oo,fff) FP_(oo,fff), FP_MASK -+ -+#else -+/* Floating point format instructions. */ -+#define FP_(oo,fff) (OP(oo) | (((fff) & 0xFF) << 5)) -+#define FP_MASK (OP_MASK | 0x1FE0) -+#define FP(oo,fff) FP_(oo,fff), FP_MASK -+ -+#define FMA_(oo,fff) (OP(oo) | (((fff) & 0x3F) << 10 )) -+#define FMA_MASK (OP_MASK | 0xFC00) -+#define FMA(oo,fff) FMA_(oo,fff), FMA_MASK -+#endif -+ -+/* Memory format instructions. */ -+#define MEM_(oo) OP(oo) -+#define MEM_MASK OP_MASK -+#define MEM(oo) MEM_(oo), MEM_MASK -+ -+/* Memory/Func Code format instructions. */ -+#define MFC_(oo,ffff) (OP(oo) | ((ffff) & 0xFFFF)) -+#define MFC_MASK (OP_MASK | 0xFFFF) -+#define MFC(oo,ffff) MFC_(oo,ffff), MFC_MASK -+ -+/* Memory/Branch format instructions. */ -+#define MBR_(oo,h) (OP(oo) | (((h) & 3) << 14)) -+#define MBR_MASK (OP_MASK | 0xC000) -+#define MBR(oo,h) MBR_(oo,h), MBR_MASK -+ -+/* Now sw Operate format instructions is different with SW1. */ -+#define OPR_(oo,ff) (OP(oo) | (((ff) & 0xFF) << 5)) -+#define OPRL_(oo,ff) (OPR_((oo), (ff)) ) -+#define OPR_MASK (OP_MASK | 0x1FE0) -+#define OPR(oo,ff) OPR_(oo,ff), OPR_MASK -+#define OPRL(oo,ff) OPRL_(oo,ff), OPR_MASK -+ -+/* sw ternary operands Operate format instructions. */ -+#define TOPR_(oo,ff) (OP(oo) | (((ff) & 0x07) << 10)) -+#define TOPRL_(oo,ff) (TOPR_((oo), (ff))) -+#define TOPR_MASK (OP_MASK | 0x1C00) -+#define TOPR(oo,ff) TOPR_(oo,ff), TOPR_MASK -+#define TOPRL(oo,ff) TOPRL_(oo,ff), TOPR_MASK -+ -+/* sw atom instructions. */ -+#define ATMEM_(oo,h) (OP(oo) | (((h) & 0xF) << 12)) -+#define ATMEM_MASK (OP_MASK | 0xF000) -+#define ATMEM(oo,h) ATMEM_(oo,h), ATMEM_MASK -+ -+/* sw privilege instructions. */ -+#define PRIRET_(oo,h) (OP(oo) | (((h) & 0x1) << 20)) -+#define PRIRET_MASK (OP_MASK | 0x100000) -+#define PRIRET(oo,h) PRIRET_(oo,h), PRIRET_MASK -+ -+/* sw rpi_rcsr,rpi_wcsr. */ -+#define CSR_(oo,ff) (OP(oo) | (((ff) & 0xFF) << 8)) -+#define CSR_MASK (OP_MASK | 0xFF00) -+#define CSR(oo,ff) CSR_(oo,ff), CSR_MASK -+ -+#define PCD_(oo,ff) (OP(oo) | (ff << 25)) -+#define PCD_MASK OP_MASK -+#define PCD(oo,ff) PCD_(oo,ff), PCD_MASK -+ -+/* Hardware memory (hw_{ld,st}) instructions. */ -+#define HWMEM_(oo,f) (OP(oo) | (((f) & 0xF) << 12)) -+#define HWMEM_MASK (OP_MASK | 0xF000) -+#define HWMEM(oo,f) HWMEM_(oo,f), HWMEM_MASK -+ -+#define LOGX_(oo,ff) (OP(oo) | (((ff) & 0x3F) << 10)) -+#define LOGX_MASK (0xF0000000) -+#define LOGX(oo,ff) LOGX_(oo,ff), LOGX_MASK -+ -+/* Abbreviations for instruction subsets. */ -+#define BASE SW_OPCODE_BASE -+#define CORE3 SW_OPCODE_CORE3 -+ -+/* Common combinations of arguments. */ -+#define ARG_NONE { 0 } -+#define ARG_BRA { RA, BDISP } -+#define ARG_FBRA { FA, BDISP } -+#define ARG_FP { FA, FB, DFC1 } -+#define ARG_FPZ1 { ZA, FB, DFC1 } -+#define ARG_MEM { RA, MDISP, PRB } -+#define ARG_FMEM { FA, MDISP, PRB } -+#define ARG_OPR { RA, RB, DRC1 } -+ -+#define ARG_OPRCAS { RA, RB, RC } -+ -+#define ARG_OPRL { RA, LIT, DRC1 } -+#define ARG_OPRZ1 { ZA, RB, DRC1 } -+#define ARG_OPRLZ1 { ZA, LIT, RC } -+#define ARG_PCD { HMFN } -+#define ARG_HWMEM { RA, HWDISP, PRB } -+#define ARG_FPL { FA,LIT, DFC1 } -+#define ARG_FMA { FA,FB,F3, DFC1 } -+#define ARG_PREFETCH { ZA, MDISP, PRB } -+#define ARG_TOPR { RA, RB,R3, DRC1 } -+#define ARG_TOPRL { RA, LIT, R3,DRC1 } -+#define ARG_FMAL { FA,FB,FMALIT, DFC1 } -+#define ARG_ATMEM { RA, ATMDISP, PRB } -+#define ARG_VUAMEM { FA, ATMDISP, PRB } -+#define ARG_OPRLZ3 { RA, LIT, ZC } -+ -+#define ARG_DISP13 {DISP13, RC} -+ -+/* The opcode table. -+ -+ The format of the opcode table is: -+ -+ NAME OPCODE MASK { OPERANDS } -+ -+ NAME is the name of the instruction. -+ -+ OPCODE is the instruction opcode. -+ -+ MASK is the opcode mask; this is used to tell the disassembler -+ which bits in the actual opcode must match OPCODE. -+ -+ OPERANDS is the list of operands. -+ -+ The preceding macros merge the text of the OPCODE and MASK fields. -+ -+ The disassembler reads the table in order and prints the first -+ instruction which matches, so this table is sorted to put more -+ specific instructions before more general instructions. -+ -+ Otherwise, it is sorted by major opcode and minor function code. -+ */ -+ -+const struct sw_64_opcode sw_64_opcodes[] = { -+ { "sys_call/b", PCD(0x00,0x00), BASE, ARG_PCD }, -+ { "sys_call", PCD(0x00,0x01), BASE, ARG_PCD }, -+ -+ { "call", MEM(0x01), BASE, { RA, CPRB, JMPHINT } }, -+ { "ret", MEM(0x02), BASE, { RA, CPRB, RETHINT } }, -+ { "jmp", MEM(0x03), BASE, { RA, CPRB, JMPHINT } }, -+ { "br", BRA(0x04), BASE, { ZA, BDISP } }, -+ { "br", BRA(0x04), BASE, ARG_BRA }, -+ { "bsr", BRA(0x05), BASE, ARG_BRA }, -+ { "memb", MFC(0x06,0x0000), BASE, ARG_NONE }, -+ { "imemb", MFC(0x06,0x0001), BASE, ARG_NONE }, -+ { "rtc", MFC(0x06,0x0020), BASE, { RA, ZB } }, -+ { "rtc", MFC(0x06,0x0020), BASE, { RA, RB } }, -+ { "rcid", MFC(0x06,0x0040), BASE, { RA , ZB} }, -+ { "halt", MFC(0x06,0x0080), BASE, { ZA, ZB } }, -+ { "rd_f", MFC(0x06,0x1000), CORE3, { RA, ZB } }, -+ { "wr_f", MFC(0x06,0x1020), CORE3, { RA, ZB } }, -+ { "rtid", MFC(0x06,0x1040), BASE, { RA } }, -+ { "pri_rcsr", CSR(0x06,0xFE), CORE3, { RA, RPIINDEX ,ZB } }, -+ { "pri_wcsr", CSR(0x06,0xFF), CORE3, { RA, RPIINDEX ,ZB } }, -+ { "pri_ret", PRIRET(0x07,0x0), BASE, { RA } }, -+ { "pri_ret/b", PRIRET(0x07,0x1), BASE, { RA } }, -+ { "lldw", ATMEM(0x08,0x0), BASE, ARG_ATMEM }, -+ { "lldl", ATMEM(0x08,0x1), BASE, ARG_ATMEM }, -+ { "ldw_inc", ATMEM(0x08,0x2), CORE3, ARG_ATMEM }, -+ { "ldl_inc", ATMEM(0x08,0x3), CORE3, ARG_ATMEM }, -+ { "ldw_dec", ATMEM(0x08,0x4), CORE3, ARG_ATMEM }, -+ { "ldl_dec", ATMEM(0x08,0x5), CORE3, ARG_ATMEM }, -+ { "ldw_set", ATMEM(0x08,0x6), CORE3, ARG_ATMEM }, -+ { "ldl_set", ATMEM(0x08,0x7), CORE3, ARG_ATMEM }, -+ { "lstw", ATMEM(0x08,0x8), BASE, ARG_ATMEM }, -+ { "lstl", ATMEM(0x08,0x9), BASE, ARG_ATMEM }, -+ { "ldw_nc", ATMEM(0x08,0xA), BASE, ARG_ATMEM }, -+ { "ldl_nc", ATMEM(0x08,0xB), BASE, ARG_ATMEM }, -+ { "ldd_nc", ATMEM(0x08,0xC), BASE, ARG_VUAMEM }, -+ { "stw_nc", ATMEM(0x08,0xD), BASE, ARG_ATMEM }, -+ { "stl_nc", ATMEM(0x08,0xE), BASE, ARG_ATMEM }, -+ { "std_nc", ATMEM(0x08,0xF), BASE, ARG_VUAMEM }, -+ { "fillcs", MEM(0x09), BASE, ARG_PREFETCH }, -+ { "ldwe", MEM(0x09), BASE, ARG_FMEM }, -+ { "e_fillcs", MEM(0x0A), BASE, ARG_PREFETCH }, -+ { "ldse", MEM(0x0A), BASE, ARG_FMEM }, -+ { "fillcs_e", MEM(0x0B), BASE, ARG_PREFETCH }, -+ { "ldde", MEM(0x0B), BASE, ARG_FMEM }, -+ { "vlds", MEM(0x0C), BASE, ARG_FMEM }, -+ { "vldd", MEM(0x0D), BASE, ARG_FMEM }, -+ { "vsts", MEM(0x0E), BASE, ARG_FMEM }, -+ { "vstd", MEM(0x0F), BASE, ARG_FMEM }, -+ { "addw", OPR(0x10,0x00), BASE, ARG_OPR }, -+ { "addw", OPRL(0x12,0x00), BASE, ARG_OPRL }, -+ { "subw", OPR(0x10,0x01), BASE, ARG_OPR }, -+ { "subw", OPRL(0x12,0x01), BASE, ARG_OPRL }, -+ { "s4addw", OPR(0x10,0x02), BASE, ARG_OPR }, -+ { "s4addw", OPRL(0x12,0x02), BASE, ARG_OPRL }, -+ { "s4subw", OPR(0x10,0x03), BASE, ARG_OPR }, -+ { "s4subw", OPRL(0x12,0x03), BASE, ARG_OPRL }, -+ { "s8addw", OPR(0x10,0x04), BASE, ARG_OPR }, -+ { "s8addw", OPRL(0x12,0x04), BASE, ARG_OPRL }, -+ { "s8subw", OPR(0x10,0x05), BASE, ARG_OPR }, -+ { "s8subw", OPRL(0x12,0x05), BASE, ARG_OPRL }, -+ { "addl", OPR(0x10,0x08), BASE, ARG_OPR }, -+ { "addl", OPRL(0x12,0x08), BASE, ARG_OPRL }, -+ { "subl", OPR(0x10,0x09), BASE, ARG_OPR }, -+ { "subl", OPRL(0x12,0x09), BASE, ARG_OPRL }, -+ { "s4addl", OPR(0x10,0x0A), BASE, ARG_OPR }, -+ { "s4addl", OPRL(0x12,0x0A), BASE, ARG_OPRL }, -+ { "s4subl", OPR(0x10,0x0B), BASE, ARG_OPR }, -+ { "s4subl", OPRL(0x12,0x0B), BASE, ARG_OPRL }, -+ { "s8addl", OPR(0x10,0x0C), BASE, ARG_OPR }, -+ { "s8addl", OPRL(0x12,0x0C), BASE, ARG_OPRL }, -+ { "s8subl", OPR(0x10,0x0D), BASE, ARG_OPR }, -+ { "s8subl", OPRL(0x12,0x0D), BASE, ARG_OPRL }, -+ { "mulw", OPR(0x10,0x10), BASE, ARG_OPR }, -+ { "mulw", OPRL(0x12,0x10), BASE, ARG_OPRL }, -+ { "mull", OPR(0x10,0x18), BASE, ARG_OPR }, -+ { "mull", OPRL(0x12,0x18), BASE, ARG_OPRL }, -+ { "umulh", OPR(0x10,0x19), BASE, ARG_OPR }, -+ { "umulh", OPRL(0x12,0x19), BASE, ARG_OPRL }, -+ { "cmpeq", OPR(0x10,0x28), BASE, ARG_OPR }, -+ { "cmpeq", OPRL(0x12,0x28), BASE, ARG_OPRL }, -+ { "cmplt", OPR(0x10,0x29), BASE, ARG_OPR }, -+ { "cmplt", OPRL(0x12,0x29), BASE, ARG_OPRL }, -+ { "cmple", OPR(0x10,0x2A), BASE, ARG_OPR }, -+ { "cmple", OPRL(0x12,0x2A), BASE, ARG_OPRL }, -+ { "cmpult", OPR(0x10,0x2B), BASE, ARG_OPR }, -+ { "cmpult", OPRL(0x12,0x2B), BASE, ARG_OPRL }, -+ { "cmpule", OPR(0x10,0x2C), BASE, ARG_OPR }, -+ { "cmpule", OPRL(0x12,0x2C), BASE, ARG_OPRL }, -+ -+ { "and", OPR(0x10,0x38), BASE, ARG_OPR }, -+ { "and", OPRL(0x12,0x38),BASE, ARG_OPRL }, -+ { "bic", OPR(0x10,0x39), BASE, ARG_OPR }, -+ { "bic", OPRL(0x12,0x39),BASE, ARG_OPRL }, -+ { "bis", OPR(0x10,0x3A), BASE, ARG_OPR }, -+ { "bis", OPRL(0x12,0x3A),BASE, ARG_OPRL }, -+ { "ornot", OPR(0x10,0x3B), BASE, ARG_OPR }, -+ { "ornot", OPRL(0x12,0x3B),BASE, ARG_OPRL }, -+ { "xor", OPR(0x10,0x3C), BASE, ARG_OPR }, -+ { "xor", OPRL(0x12,0x3C),BASE, ARG_OPRL }, -+ { "eqv", OPR(0x10,0x3D), BASE, ARG_OPR }, -+ { "eqv", OPRL(0x12,0x3D),BASE, ARG_OPRL }, -+ { "inslb", OPR(0x10,0x40), BASE, ARG_OPR }, -+ { "inslb", OPRL(0x12,0x40),BASE, ARG_OPRL }, -+ { "inslh", OPR(0x10,0x41), BASE, ARG_OPR }, -+ { "inslh", OPRL(0x12,0x41),BASE, ARG_OPRL }, -+ { "inslw", OPR(0x10,0x42), BASE, ARG_OPR }, -+ { "inslw", OPRL(0x12,0x42),BASE, ARG_OPRL }, -+ { "insll", OPR(0x10,0x43), BASE, ARG_OPR }, -+ { "insll", OPRL(0x12,0x43),BASE, ARG_OPRL }, -+ { "inshb", OPR(0x10,0x44), BASE, ARG_OPR }, -+ { "inshb", OPRL(0x12,0x44),BASE, ARG_OPRL }, -+ { "inshh", OPR(0x10,0x45), BASE, ARG_OPR }, -+ { "inshh", OPRL(0x12,0x45),BASE, ARG_OPRL }, -+ { "inshw", OPR(0x10,0x46), BASE, ARG_OPR }, -+ { "inshw", OPRL(0x12,0x46),BASE, ARG_OPRL }, -+ { "inshl", OPR(0x10,0x47), BASE, ARG_OPR }, -+ { "inshl", OPRL(0x12,0x47),BASE, ARG_OPRL }, -+ -+ { "sll", OPR(0x10,0x48), BASE, ARG_OPR }, -+ { "sll", OPRL(0x12,0x48),BASE, ARG_OPRL }, -+ { "srl", OPR(0x10,0x49), BASE, ARG_OPR }, -+ { "srl", OPRL(0x12,0x49),BASE, ARG_OPRL }, -+ { "sra", OPR(0x10,0x4A), BASE, ARG_OPR }, -+ { "sra", OPRL(0x12,0x4A),BASE, ARG_OPRL }, -+ { "extlb", OPR(0x10,0x50), BASE, ARG_OPR }, -+ { "extlb", OPRL(0x12,0x50),BASE, ARG_OPRL }, -+ { "extlh", OPR(0x10,0x51), BASE, ARG_OPR }, -+ { "extlh", OPRL(0x12,0x51),BASE, ARG_OPRL }, -+ { "extlw", OPR(0x10,0x52), BASE, ARG_OPR }, -+ { "extlw", OPRL(0x12,0x52),BASE, ARG_OPRL }, -+ { "extll", OPR(0x10,0x53), BASE, ARG_OPR }, -+ { "extll", OPRL(0x12,0x53),BASE, ARG_OPRL }, -+ { "exthb", OPR(0x10,0x54), BASE, ARG_OPR }, -+ { "exthb", OPRL(0x12,0x54),BASE, ARG_OPRL }, -+ { "exthh", OPR(0x10,0x55), BASE, ARG_OPR }, -+ { "exthh", OPRL(0x12,0x55),BASE, ARG_OPRL }, -+ { "exthw", OPR(0x10,0x56), BASE, ARG_OPR }, -+ { "exthw", OPRL(0x12,0x56),BASE, ARG_OPRL }, -+ { "exthl", OPR(0x10,0x57), BASE, ARG_OPR }, -+ { "exthl", OPRL(0x12,0x57),BASE, ARG_OPRL }, -+ { "ctpop", OPR(0x10,0x58), BASE, ARG_OPRZ1 }, -+ { "ctlz", OPR(0x10,0x59), BASE, ARG_OPRZ1 }, -+ { "cttz", OPR(0x10,0x5A), BASE, ARG_OPRZ1 }, -+ { "masklb", OPR(0x10,0x60), BASE, ARG_OPR }, -+ { "masklb", OPRL(0x12,0x60),BASE, ARG_OPRL }, -+ { "masklh", OPR(0x10,0x61), BASE, ARG_OPR }, -+ { "masklh", OPRL(0x12,0x61),BASE, ARG_OPRL }, -+ { "masklw", OPR(0x10,0x62), BASE, ARG_OPR }, -+ { "masklw", OPRL(0x12,0x62),BASE, ARG_OPRL }, -+ { "maskll", OPR(0x10,0x63), BASE, ARG_OPR }, -+ { "maskll", OPRL(0x12,0x63),BASE, ARG_OPRL }, -+ { "maskhb", OPR(0x10,0x64), BASE, ARG_OPR }, -+ { "maskhb", OPRL(0x12,0x64),BASE, ARG_OPRL }, -+ { "maskhh", OPR(0x10,0x65), BASE, ARG_OPR }, -+ { "maskhh", OPRL(0x12,0x65),BASE, ARG_OPRL }, -+ { "maskhw", OPR(0x10,0x66), BASE, ARG_OPR }, -+ { "maskhw", OPRL(0x12,0x66),BASE, ARG_OPRL }, -+ { "maskhl", OPR(0x10,0x67), BASE, ARG_OPR }, -+ { "maskhl", OPRL(0x12,0x67),BASE, ARG_OPRL }, -+ { "zap", OPR(0x10,0x68), BASE, ARG_OPR }, -+ { "zap", OPRL(0x12,0x68),BASE, ARG_OPRL }, -+ { "zapnot", OPR(0x10,0x69), BASE, ARG_OPR }, -+ { "zapnot", OPRL(0x12,0x69),BASE, ARG_OPRL }, -+ { "sextb", OPR(0x10,0x6A), BASE, ARG_OPRZ1}, -+ { "sextb", OPRL(0x12,0x6A),BASE, ARG_OPRLZ1 }, -+ { "sexth", OPR(0x10,0x6B), BASE, ARG_OPRZ1 }, -+ { "sexth", OPRL(0x12,0x6B),BASE, ARG_OPRLZ1 }, -+ { "cmpgeb", OPR(0x10,0x6C), BASE, ARG_OPR }, -+ { "cmpgeb", OPRL(0x12,0x6C),BASE, ARG_OPRL }, -+ { "fimovs", OPR(0x10,0x70), BASE, { FA, ZB, RC } }, -+ { "fimovd", OPR(0x10,0x78), BASE, { FA, ZB, RC } }, -+ { "seleq", TOPR(0x11,0x0), BASE, ARG_TOPR }, -+ { "seleq", TOPRL(0x13,0x0),BASE, ARG_TOPRL }, -+ { "selge", TOPR(0x11,0x1), BASE, ARG_TOPR }, -+ { "selge", TOPRL(0x13,0x1),BASE, ARG_TOPRL }, -+ { "selgt", TOPR(0x11,0x2), BASE, ARG_TOPR }, -+ { "selgt", TOPRL(0x13,0x2),BASE, ARG_TOPRL }, -+ { "selle", TOPR(0x11,0x3), BASE, ARG_TOPR }, -+ { "selle", TOPRL(0x13,0x3),BASE, ARG_TOPRL }, -+ { "sellt", TOPR(0x11,0x4), BASE, ARG_TOPR }, -+ { "sellt", TOPRL(0x13,0x4),BASE, ARG_TOPRL }, -+ { "selne", TOPR(0x11,0x5), BASE, ARG_TOPR }, -+ { "selne", TOPRL(0x13,0x5),BASE, ARG_TOPRL }, -+ { "sellbc", TOPR(0x11,0x6), BASE, ARG_TOPR }, -+ { "sellbc", TOPRL(0x13,0x6),BASE, ARG_TOPRL }, -+ { "sellbs", TOPR(0x11,0x7), BASE, ARG_TOPR }, -+ { "sellbs", TOPRL(0x13,0x7),BASE, ARG_TOPRL }, -+ { "vlog", LOGX(0x14,0x00), BASE, ARG_FMA }, -+ -+ { "fadds", FP(0x18,0x00), BASE, ARG_FP }, -+ { "faddd", FP(0x18,0x01), BASE, ARG_FP }, -+ { "fsubs", FP(0x18,0x02), BASE, ARG_FP }, -+ { "fsubd", FP(0x18,0x03), BASE, ARG_FP }, -+ { "fmuls", FP(0x18,0x04), BASE, ARG_FP }, -+ { "fmuld", FP(0x18,0x05), BASE, ARG_FP }, -+ { "fdivs", FP(0x18,0x06), BASE, ARG_FP }, -+ { "fdivd", FP(0x18,0x07), BASE, ARG_FP }, -+ { "fsqrts", FP(0x18,0x08), BASE, ARG_FPZ1 }, -+ { "fsqrtd", FP(0x18,0x09), BASE, ARG_FPZ1 }, -+ { "fcmpeq", FP(0x18,0x10), BASE, ARG_FP }, -+ { "fcmple", FP(0x18,0x11), BASE, ARG_FP }, -+ { "fcmplt", FP(0x18,0x12), BASE, ARG_FP }, -+ { "fcmpun", FP(0x18,0x13), BASE, ARG_FP }, -+ -+ { "fcvtsd", FP(0x18,0x20), BASE, ARG_FPZ1 }, -+ { "fcvtds", FP(0x18,0x21), BASE, ARG_FPZ1 }, -+ { "fcvtdl_g", FP(0x18,0x22), BASE, ARG_FPZ1 }, -+ { "fcvtdl_p", FP(0x18,0x23), BASE, ARG_FPZ1 }, -+ { "fcvtdl_z", FP(0x18,0x24), BASE, ARG_FPZ1 }, -+ { "fcvtdl_n", FP(0x18,0x25), BASE, ARG_FPZ1 }, -+ { "fcvtdl", FP(0x18,0x27), BASE, ARG_FPZ1 }, -+ { "fcvtwl", FP(0x18,0x28), BASE, ARG_FPZ1 }, -+ { "fcvtlw", FP(0x18,0x29), BASE, ARG_FPZ1 }, -+ { "fcvtls", FP(0x18,0x2d), BASE, ARG_FPZ1 }, -+ { "fcvtld", FP(0x18,0x2f), BASE, ARG_FPZ1 }, -+ { "fcpys", FP(0x18,0x30), BASE, ARG_FP }, -+ { "fcpyse", FP(0x18,0x31), BASE, ARG_FP }, -+ { "fcpysn", FP(0x18,0x32), BASE, ARG_FP }, -+ { "ifmovs", FP(0x18,0x40), BASE, { RA, ZB, FC } }, -+ { "ifmovd", FP(0x18,0x41), BASE, { RA, ZB, FC } }, -+ { "rfpcr", FP(0x18,0x50), BASE, { FA, RBA, RCA } }, -+ { "wfpcr", FP(0x18,0x51), BASE, { FA, RBA, RCA } }, -+ { "setfpec0", FP(0x18,0x54), BASE, ARG_NONE }, -+ { "setfpec1", FP(0x18,0x55), BASE, ARG_NONE }, -+ { "setfpec2", FP(0x18,0x56), BASE, ARG_NONE }, -+ { "setfpec3", FP(0x18,0x57), BASE, ARG_NONE }, -+ { "fmas", FMA(0x19,0x00), BASE, ARG_FMA }, -+ { "fmad", FMA(0x19,0x01), BASE, ARG_FMA }, -+ { "fmss", FMA(0x19,0x02), BASE, ARG_FMA }, -+ { "fmsd", FMA(0x19,0x03), BASE, ARG_FMA }, -+ { "fnmas", FMA(0x19,0x04), BASE, ARG_FMA }, -+ { "fnmad", FMA(0x19,0x05), BASE, ARG_FMA }, -+ { "fnmss", FMA(0x19,0x06), BASE, ARG_FMA }, -+ { "fnmsd", FMA(0x19,0x07), BASE, ARG_FMA }, -+ { "fseleq", FMA(0x19,0x10), BASE, ARG_FMA }, -+ { "fselne", FMA(0x19,0x11), BASE, ARG_FMA }, -+ { "fsellt", FMA(0x19,0x12), BASE, ARG_FMA }, -+ { "fselle", FMA(0x19,0x13), BASE, ARG_FMA }, -+ { "fselgt", FMA(0x19,0x14), BASE, ARG_FMA }, -+ { "fselge", FMA(0x19,0x15), BASE, ARG_FMA }, -+ { "vaddw", FP(0x1A,0x00), BASE, ARG_FP }, -+ { "vaddw", FP(0x1A,0x20), BASE, ARG_FPL }, -+ { "vsubw", FP(0x1A,0x01), BASE, ARG_FP }, -+ { "vsubw", FP(0x1A,0x21), BASE, ARG_FPL }, -+ { "vcmpgew", FP(0x1A,0x02), BASE, ARG_FP }, -+ { "vcmpgew", FP(0x1A,0x22), BASE, ARG_FPL }, -+ { "vcmpeqw", FP(0x1A,0x03), BASE, ARG_FP }, -+ { "vcmpeqw", FP(0x1A,0x23), BASE, ARG_FPL }, -+ { "vcmplew", FP(0x1A,0x04), BASE, ARG_FP }, -+ { "vcmplew", FP(0x1A,0x24), BASE, ARG_FPL }, -+ { "vcmpltw", FP(0x1A,0x05), BASE, ARG_FP }, -+ { "vcmpltw", FP(0x1A,0x25), BASE, ARG_FPL }, -+ { "vcmpulew", FP(0x1A,0x06), BASE, ARG_FP }, -+ { "vcmpulew", FP(0x1A,0x26), BASE, ARG_FPL }, -+ { "vcmpultw", FP(0x1A,0x07), BASE, ARG_FP }, -+ { "vcmpultw", FP(0x1A,0x27), BASE, ARG_FPL }, -+ -+ { "vsllw", FP(0x1A,0x08), BASE, ARG_FP }, -+ { "vsllw", FP(0x1A,0x28), BASE, ARG_FPL }, -+ { "vsrlw", FP(0x1A,0x09), BASE, ARG_FP }, -+ { "vsrlw", FP(0x1A,0x29), BASE, ARG_FPL }, -+ { "vsraw", FP(0x1A,0x0A), BASE, ARG_FP }, -+ { "vsraw", FP(0x1A,0x2A), BASE, ARG_FPL }, -+ { "vrolw", FP(0x1A,0x0B), BASE, ARG_FP }, -+ { "vrolw", FP(0x1A,0x2B), BASE, ARG_FPL }, -+ { "sllow", FP(0x1A,0x0C), BASE, ARG_FP }, -+ { "sllow", FP(0x1A,0x2C), BASE, ARG_FPL }, -+ { "srlow", FP(0x1A,0x0D), BASE, ARG_FP }, -+ { "srlow", FP(0x1A,0x2D), BASE, ARG_FPL }, -+ { "vaddl", FP(0x1A,0x0E), BASE, ARG_FP }, -+ { "vaddl", FP(0x1A,0x2E), BASE, ARG_FPL }, -+ { "vsubl", FP(0x1A,0x0F), BASE, ARG_FP }, -+ { "vsubl", FP(0x1A,0x2F), BASE, ARG_FPL }, -+ { "ctpopow", FP(0x1A,0x18), BASE, { FA, ZB, DFC1 } }, -+ { "ctlzow", FP(0x1A,0x19), BASE, { FA, ZB, DFC1 } }, -+ { "vucaddw", FP(0x1A,0x40), BASE, ARG_FP }, -+ { "vucaddw", FP(0x1A,0x60), BASE, ARG_FPL }, -+ { "vucsubw", FP(0x1A,0x41), BASE, ARG_FP }, -+ { "vucsubw", FP(0x1A,0x61), BASE, ARG_FPL }, -+ { "vucaddh", FP(0x1A,0x42), BASE, ARG_FP }, -+ { "vucaddh", FP(0x1A,0x62), BASE, ARG_FPL }, -+ { "vucsubh", FP(0x1A,0x43), BASE, ARG_FP }, -+ { "vucsubh", FP(0x1A,0x63), BASE, ARG_FPL }, -+ { "vucaddb", FP(0x1A,0x44), BASE, ARG_FP }, -+ { "vucaddb", FP(0x1A,0x64), BASE, ARG_FPL }, -+ { "vucsubb", FP(0x1A,0x45), BASE, ARG_FP }, -+ { "vucsubb", FP(0x1A,0x65), BASE, ARG_FPL }, -+ { "vadds", FP(0x1A,0x80), BASE, ARG_FP }, -+ { "vaddd", FP(0x1A,0x81), BASE, ARG_FP }, -+ { "vsubs", FP(0x1A,0x82), BASE, ARG_FP }, -+ { "vsubd", FP(0x1A,0x83), BASE, ARG_FP }, -+ { "vmuls", FP(0x1A,0x84), BASE, ARG_FP }, -+ { "vmuld", FP(0x1A,0x85), BASE, ARG_FP }, -+ { "vdivs", FP(0x1A,0x86), BASE, ARG_FP }, -+ { "vdivd", FP(0x1A,0x87), BASE, ARG_FP }, -+ { "vsqrts", FP(0x1A,0x88), BASE, ARG_FPZ1 }, -+ { "vsqrtd", FP(0x1A,0x89), BASE, ARG_FPZ1 }, -+ { "vfcmpeq", FP(0x1A,0x8C), BASE, ARG_FP }, -+ { "vfcmple", FP(0x1A,0x8D), BASE, ARG_FP }, -+ { "vfcmplt", FP(0x1A,0x8E), BASE, ARG_FP }, -+ { "vfcmpun", FP(0x1A,0x8F), BASE, ARG_FP }, -+ { "vcpys", FP(0x1A,0x90), BASE, ARG_FP }, -+ { "vcpyse", FP(0x1A,0x91), BASE, ARG_FP }, -+ { "vcpysn", FP(0x1A,0x92), BASE, ARG_FP }, -+ { "vmas", FMA(0x1B,0x00), BASE, ARG_FMA }, -+ { "vmad", FMA(0x1B,0x01), BASE, ARG_FMA }, -+ { "vmss", FMA(0x1B,0x02), BASE, ARG_FMA }, -+ { "vmsd", FMA(0x1B,0x03), BASE, ARG_FMA }, -+ { "vnmas", FMA(0x1B,0x04), BASE, ARG_FMA }, -+ { "vnmad", FMA(0x1B,0x05), BASE, ARG_FMA }, -+ { "vnmss", FMA(0x1B,0x06), BASE, ARG_FMA }, -+ { "vnmsd", FMA(0x1B,0x07), BASE, ARG_FMA }, -+ { "vfseleq", FMA(0x1B,0x10), BASE, ARG_FMA }, -+ { "vfsellt", FMA(0x1B,0x12), BASE, ARG_FMA }, -+ { "vfselle", FMA(0x1B,0x13), BASE, ARG_FMA }, -+ { "vseleqw", FMA(0x1B,0x18), BASE, ARG_FMA }, -+ { "vseleqw", FMA(0x1B,0x38), BASE, ARG_FMAL }, -+ { "vsellbcw", FMA(0x1B,0x19), BASE, ARG_FMA }, -+ { "vsellbcw", FMA(0x1B,0x39), BASE, ARG_FMAL }, -+ { "vselltw", FMA(0x1B,0x1A), BASE, ARG_FMA }, -+ { "vselltw", FMA(0x1B,0x3A), BASE, ARG_FMAL }, -+ { "vsellew", FMA(0x1B,0x1B), BASE, ARG_FMA }, -+ { "vsellew", FMA(0x1B,0x3B), BASE, ARG_FMAL }, -+ { "vinsw", FMA(0x1B,0x20), BASE, ARG_FMAL }, -+ { "vinsf", FMA(0x1B,0x21), BASE, ARG_FMAL }, -+ { "vextw", FMA(0x1B,0x22), BASE, { FA, FMALIT, DFC1 }}, -+ { "vextf", FMA(0x1B,0x23), BASE, { FA, FMALIT, DFC1 }}, -+ { "vcpyw", FMA(0x1B,0x24), BASE, { FA, DFC1 }}, -+ { "vcpyf", FMA(0x1B,0x25), BASE, { FA, DFC1 }}, -+ { "vconw", FMA(0x1B,0x26), BASE, ARG_FMA }, -+ { "vshfw", FMA(0x1B,0x27), BASE, ARG_FMA }, -+ { "vcons", FMA(0x1B,0x28), BASE, ARG_FMA }, -+ { "vcond", FMA(0x1B,0x29), BASE, ARG_FMA }, -+ { "vldw_u", ATMEM(0x1C,0x0), BASE, ARG_VUAMEM }, -+ { "vstw_u", ATMEM(0x1C,0x1), BASE, ARG_VUAMEM }, -+ { "vlds_u", ATMEM(0x1C,0x2), BASE, ARG_VUAMEM }, -+ { "vsts_u", ATMEM(0x1C,0x3), BASE, ARG_VUAMEM }, -+ { "vldd_u", ATMEM(0x1C,0x4), BASE, ARG_VUAMEM }, -+ { "vstd_u", ATMEM(0x1C,0x5), BASE, ARG_VUAMEM }, -+ { "vstw_ul", ATMEM(0x1C,0x8), BASE, ARG_VUAMEM }, -+ { "vstw_uh", ATMEM(0x1C,0x9), BASE, ARG_VUAMEM }, -+ { "vsts_ul", ATMEM(0x1C,0xA), BASE, ARG_VUAMEM }, -+ { "vsts_uh", ATMEM(0x1C,0xB), BASE, ARG_VUAMEM }, -+ { "vstd_ul", ATMEM(0x1C,0xC), BASE, ARG_VUAMEM }, -+ { "vstd_uh", ATMEM(0x1C,0xD), BASE, ARG_VUAMEM }, -+ { "vldd_nc", ATMEM(0x1C,0xE), BASE, ARG_VUAMEM }, -+ { "vstd_nc", ATMEM(0x1C,0xF), BASE, ARG_VUAMEM }, -+ -+ { "flushd", MEM(0x20), BASE, ARG_PREFETCH }, -+ { "ldbu", MEM(0x20), BASE, ARG_MEM }, -+ { "evictdg", MEM(0x21), BASE, ARG_PREFETCH }, -+ { "ldhu", MEM(0x21), BASE, ARG_MEM }, -+ { "s_fillcs", MEM(0x22), BASE, ARG_PREFETCH }, -+ { "ldw", MEM(0x22), BASE, ARG_MEM }, -+ { "s_fillde", MEM(0x23), BASE, ARG_PREFETCH }, -+ { "ldl", MEM(0x23), BASE, ARG_MEM }, -+ { "evictdl", MEM(0x24), BASE, ARG_PREFETCH }, -+ { "ldl_u", MEM(0x24), BASE, ARG_MEM }, -+ { "pri_ldw/p", HWMEM(0x25,0x0), BASE, ARG_HWMEM }, -+ { "pri_ldw/v", HWMEM(0x25,0x8), BASE, ARG_HWMEM }, -+ { "pri_ldl/p", HWMEM(0x25,0x1), BASE, ARG_HWMEM }, -+ { "pri_ldl/v", HWMEM(0x25,0x9), BASE, ARG_HWMEM }, -+ { "fillde", MEM(0x26), BASE, ARG_PREFETCH }, -+ { "flds", MEM(0x26), BASE, ARG_FMEM }, -+ { "fillde_e", MEM(0x27), BASE, ARG_PREFETCH }, -+ { "fldd", MEM(0x27), BASE, ARG_FMEM }, -+ -+ { "stb", MEM(0x28), BASE, ARG_MEM }, -+ { "sth", MEM(0x29), BASE, ARG_MEM }, -+ { "stw", MEM(0x2A), BASE, ARG_MEM }, -+ { "stl", MEM(0x2B), BASE, ARG_MEM }, -+ { "stl_u", MEM(0x2C), BASE, ARG_MEM }, -+ { "pri_stw/p", HWMEM(0x2D,0x0), BASE, ARG_HWMEM }, -+ { "pri_stw/v", HWMEM(0x2D,0x8), BASE, ARG_HWMEM }, -+ { "pri_stl/p", HWMEM(0x2D,0x1), BASE, ARG_HWMEM }, -+ { "pri_stl/v", HWMEM(0x2D,0x9), BASE, ARG_HWMEM }, -+ { "fsts", MEM(0x2E), BASE, ARG_FMEM }, -+ { "fstd", MEM(0x2F), BASE, ARG_FMEM }, -+ { "beq", BRA(0x30), BASE, ARG_BRA }, -+ { "bne", BRA(0x31), BASE, ARG_BRA }, -+ { "blt", BRA(0x32), BASE, ARG_BRA }, -+ { "ble", BRA(0x33), BASE, ARG_BRA }, -+ { "bgt", BRA(0x34), BASE, ARG_BRA }, -+ { "bge", BRA(0x35), BASE, ARG_BRA }, -+ { "blbc", BRA(0x36), BASE, ARG_BRA }, -+ { "blbs", BRA(0x37), BASE, ARG_BRA }, -+ -+ { "fbeq", BRA(0x38), BASE, ARG_FBRA }, -+ { "fbne", BRA(0x39), BASE, ARG_FBRA }, -+ { "fblt", BRA(0x3A), BASE, ARG_FBRA }, -+ { "fble", BRA(0x3B), BASE, ARG_FBRA }, -+ { "fbgt", BRA(0x3C), BASE, ARG_FBRA }, -+ { "fbge", BRA(0x3D), BASE, ARG_FBRA }, -+ { "ldi", MEM(0x3E), BASE, ARG_MEM }, -+ { "ldih", MEM(0x3F), BASE, ARG_MEM }, -+}; -+ -+const unsigned sw_64_num_opcodes = sizeof(sw_64_opcodes) / sizeof(*sw_64_opcodes); -+ -+/* OSF register names. */ -+ -+static const char * const osf_regnames[64] = { -+ "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", -+ "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp", -+ "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9", -+ "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero", -+ "$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" -+}; -+ -+/* VMS register names. */ -+ -+static const char * const vms_regnames[64] = { -+ "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", "AI", "RA", "PV", "AT", "FP", "SP", "RZ", -+ "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", "FZ" -+}; -+ -+int print_insn_sw_64(bfd_vma memaddr, struct disassemble_info *info) -+{ -+ static const struct sw_64_opcode *opcode_index[SW_NOPS + 1]; -+ const char * const * regnames; -+ const struct sw_64_opcode *opcode, *opcode_end; -+ const unsigned char *opindex; -+ unsigned insn, op, isa_mask; -+ int need_comma; -+ -+ /* Initialize the majorop table the first time through */ -+ if (!opcode_index[0]) { -+ opcode = sw_64_opcodes; -+ opcode_end = opcode + sw_64_num_opcodes; -+ -+ for (op = 0; op < SW_NOPS; ++op) { -+ opcode_index[op] = opcode; -+ if ((SW_LITOP (opcode->opcode) != 0x10) && (SW_LITOP (opcode->opcode) != 0x11)) { -+ while (opcode < opcode_end && op == SW_OP (opcode->opcode)) -+ ++opcode; -+ } else { -+ while (opcode < opcode_end && op == SW_LITOP (opcode->opcode)) -+ ++opcode; -+ } -+ } -+ opcode_index[op] = opcode; -+ } -+ -+ if (info->flavour == bfd_target_evax_flavour) -+ regnames = vms_regnames; -+ else -+ regnames = osf_regnames; -+ isa_mask = SW_OPCODE_NOHM; -+ switch (info->mach) { -+ case bfd_mach_sw_64_core3: -+ isa_mask |= SW_OPCODE_BASE | SW_OPCODE_CORE3; -+ break; -+ } -+ -+ /* Read the insn into a host word */ -+ { -+ bfd_byte buffer[4]; -+ int 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); -+ } -+ -+ /* Get the major opcode of the instruction. */ -+ if ((SW_LITOP (insn) == 0x10) || (SW_LITOP (insn) == 0x11)) -+ op = SW_LITOP (insn); -+ else if ((SW_OP(insn) & 0x3C) == 0x14 ) -+ op = 0x14; -+ else -+ op = SW_OP (insn); -+ -+ /* Find the first match in the opcode table. */ -+ opcode_end = opcode_index[op + 1]; -+ for (opcode = opcode_index[op]; opcode < opcode_end; ++opcode) { -+ if ((insn ^ opcode->opcode) & opcode->mask) -+ continue; -+ -+ if (!(opcode->flags & isa_mask)) -+ continue; -+ -+ /* Make two passes over the operands. First see if any of them -+ have extraction functions, and, if they do, make sure the -+ instruction is valid. */ -+ { -+ int invalid = 0; -+ for (opindex = opcode->operands; *opindex != 0; opindex++) { -+ const struct sw_64_operand *operand = sw_64_operands + *opindex; -+ if (operand->extract) -+ (*operand->extract) (insn, &invalid); -+ } -+ if (invalid) -+ continue; -+ } -+ -+ /* The instruction is valid. */ -+ goto found; -+ } -+ -+ /* No instruction found */ -+ (*info->fprintf_func) (info->stream, ".long %#08x", insn); -+ -+ return 4; -+ -+found: -+ if (!strncmp("sys_call",opcode->name,8)) { -+ if (insn & (0x1 << 25)) -+ (*info->fprintf_func) (info->stream, "%s", "sys_call"); -+ else -+ (*info->fprintf_func) (info->stream, "%s", "sys_call/b"); -+ } else -+ (*info->fprintf_func) (info->stream, "%s", opcode->name); -+ -+ /* get zz[7:6] and zz[5:0] to form truth for vlog */ -+ if (!strcmp(opcode->name, "vlog")) -+ { -+ unsigned int truth; -+ char tr[4]; -+ truth=(SW_OP(insn) & 3) << 6; -+ truth = truth | ((insn & 0xFC00) >> 10); -+ sprintf(tr,"%x",truth); -+ (*info->fprintf_func) (info->stream, "%s", tr); -+ } -+ if (opcode->operands[0] != 0) -+ (*info->fprintf_func) (info->stream, "\t"); -+ -+ /* Now extract and print the operands. */ -+ need_comma = 0; -+ for (opindex = opcode->operands; *opindex != 0; opindex++) { -+ const struct sw_64_operand *operand = sw_64_operands + *opindex; -+ int value; -+ -+ /* Operands that are marked FAKE are simply ignored. We -+ already made sure that the extract function considered -+ the instruction to be valid. */ -+ if ((operand->flags & SW_OPERAND_FAKE) != 0) -+ continue; -+ -+ /* Extract the value from the instruction. */ -+ if (operand->extract) -+ value = (*operand->extract) (insn, (int *) NULL); -+ else { -+ value = (insn >> operand->shift) & ((1 << operand->bits) - 1); -+ if (operand->flags & SW_OPERAND_SIGNED) { -+ int signbit = 1 << (operand->bits - 1); -+ value = (value ^ signbit) - signbit; -+ } -+ } -+ -+ if (need_comma && -+ ((operand->flags & (SW_OPERAND_PARENS | SW_OPERAND_COMMA)) -+ != SW_OPERAND_PARENS)) { -+ (*info->fprintf_func) (info->stream, ","); -+ } -+ if (operand->flags & SW_OPERAND_PARENS) -+ (*info->fprintf_func) (info->stream, "("); -+ -+ /* Print the operand as directed by the flags. */ -+ if (operand->flags & SW_OPERAND_IR) -+ (*info->fprintf_func) (info->stream, "%s", regnames[value]); -+ else if (operand->flags & SW_OPERAND_FPR) -+ (*info->fprintf_func) (info->stream, "%s", regnames[value + 32]); -+ else if (operand->flags & SW_OPERAND_RELATIVE) -+ (*info->print_address_func) (memaddr + 4 + value, info); -+ else if (operand->flags & SW_OPERAND_SIGNED) -+ (*info->fprintf_func) (info->stream, "%d", value); -+ else -+ (*info->fprintf_func) (info->stream, "%#x", value); -+ -+ if (operand->flags & SW_OPERAND_PARENS) -+ (*info->fprintf_func) (info->stream, ")"); -+ need_comma = 1; -+ } -+ -+ return 4; -+} -diff --git a/hw/Kconfig b/hw/Kconfig -index ad20cce0a9..5f3957be0f 100644 ---- a/hw/Kconfig -+++ b/hw/Kconfig -@@ -63,6 +63,7 @@ source sparc/Kconfig - source sparc64/Kconfig - source tricore/Kconfig - source xtensa/Kconfig -+source sw64/Kconfig - - # Symbols used by multiple targets - config TEST_DEVICES -diff --git a/hw/meson.build b/hw/meson.build -index b3366c888e..f39c1f7e70 100644 ---- a/hw/meson.build -+++ b/hw/meson.build -@@ -62,5 +62,6 @@ subdir('s390x') - subdir('sh4') - subdir('sparc') - subdir('sparc64') -+subdir('sw64') - subdir('tricore') - subdir('xtensa') -diff --git a/hw/rtc/sun4v-rtc.c b/hw/rtc/sun4v-rtc.c -index e037acd1b5..58a0cff483 100644 ---- a/hw/rtc/sun4v-rtc.c -+++ b/hw/rtc/sun4v-rtc.c -@@ -32,10 +32,17 @@ static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr, - unsigned size) - { - uint64_t val = get_clock_realtime() / NANOSECONDS_PER_SECOND; -+#if defined(__sw_64__) -+ if (addr & 4ULL) { -+ /* accessing the high 32 bits */ -+ val >>= 32; -+ } -+#else - if (!(addr & 4ULL)) { - /* accessing the high 32 bits */ - val >>= 32; - } -+#endif - trace_sun4v_rtc_read(addr, val); - return val; - } -@@ -49,7 +56,11 @@ static void sun4v_rtc_write(void *opaque, hwaddr addr, - static const MemoryRegionOps sun4v_rtc_ops = { - .read = sun4v_rtc_read, - .write = sun4v_rtc_write, -+#if defined(__sw_64__) -+ .endianness = DEVICE_LITTLE_ENDIAN, -+#else - .endianness = DEVICE_NATIVE_ENDIAN, -+#endif - }; - - void sun4v_rtc_init(hwaddr addr) -diff --git a/hw/sw64/Kconfig b/hw/sw64/Kconfig -new file mode 100644 -index 0000000000..2bf19e8234 ---- /dev/null -+++ b/hw/sw64/Kconfig -@@ -0,0 +1,11 @@ -+config CORE3 -+ bool -+ imply PCI_DEVICES -+ imply TEST_DEVICES -+ imply E1000_PCI -+ select PCI_EXPRESS -+ select SUN4V_RTC -+ select VIRTIO_MMIO -+ select SERIAL -+ select IDE_CMD646 -+ select VIRTIO_VGA -diff --git a/hw/sw64/Makefile.objs b/hw/sw64/Makefile.objs -new file mode 100644 -index 0000000000..73add9a91d ---- /dev/null -+++ b/hw/sw64/Makefile.objs -@@ -0,0 +1 @@ -+obj-y += core3.o core3_board.o -diff --git a/hw/sw64/core.h b/hw/sw64/core.h -new file mode 100644 -index 0000000000..4923382229 ---- /dev/null -+++ b/hw/sw64/core.h -@@ -0,0 +1,25 @@ -+#ifndef HW_SW64_SYS_H -+#define HW_SW64_SYS_H -+ -+typedef struct boot_params { -+ unsigned long initrd_size; /* size of initrd */ -+ unsigned long initrd_start; /* logical address of initrd */ -+ unsigned long dtb_start; /* logical address of dtb */ -+ unsigned long efi_systab; /* logical address of EFI system table */ -+ unsigned long efi_memmap; /* logical address of EFI memory map */ -+ unsigned long efi_memmap_size; /* size of EFI memory map */ -+ unsigned long efi_memdesc_size; /* size of an EFI memory map descriptor */ -+ unsigned long efi_memdesc_version; /* memory descriptor version */ -+ unsigned long cmdline; /* logical address of cmdline */ -+} BOOT_PARAMS; -+ -+void core3_board_init(SW64CPU *cpus[4], MemoryRegion *ram); -+#endif -+ -+#define MAX_CPUS 64 -+ -+#ifdef CONFIG_KVM -+#define MAX_CPUS_CORE3 64 -+#else -+#define MAX_CPUS_CORE3 32 -+#endif -diff --git a/hw/sw64/core3.c b/hw/sw64/core3.c -new file mode 100644 -index 0000000000..dbe4ed6fa1 ---- /dev/null -+++ b/hw/sw64/core3.c -@@ -0,0 +1,182 @@ -+/* -+ * QEMU CORE3 hardware system emulator. -+ * -+ * Copyright (c) 2021 Lu Feifei -+ * -+ * This work is licensed under the GNU GPL license version 2 or later. -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu-common.h" -+#include "qemu/datadir.h" -+#include "cpu.h" -+#include "hw/hw.h" -+#include "elf.h" -+#include "hw/loader.h" -+#include "hw/boards.h" -+#include "qemu/error-report.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/kvm.h" -+#include "sysemu/reset.h" -+#include "hw/ide.h" -+#include "hw/char/serial.h" -+#include "qemu/cutils.h" -+#include "ui/console.h" -+#include "core.h" -+#include "hw/boards.h" -+#include "sysemu/numa.h" -+ -+static uint64_t cpu_sw64_virt_to_phys(void *opaque, uint64_t addr) -+{ -+ return addr &= ~0xffffffff80000000 ; -+} -+ -+static CpuInstanceProperties -+sw64_cpu_index_to_props(MachineState *ms, unsigned cpu_index) -+{ -+ MachineClass *mc = MACHINE_GET_CLASS(ms); -+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); -+ -+ assert(cpu_index < possible_cpus->len); -+ return possible_cpus->cpus[cpu_index].props; -+} -+ -+static int64_t sw64_get_default_cpu_node_id(const MachineState *ms, int idx) -+{ -+ int nb_numa_nodes = ms->numa_state->num_nodes; -+ return idx % nb_numa_nodes; -+} -+ -+static const CPUArchIdList *sw64_possible_cpu_arch_ids(MachineState *ms) -+{ -+ int i; -+ unsigned int max_cpus = ms->smp.max_cpus; -+ -+ if (ms->possible_cpus) { -+ /* -+ * make sure that max_cpus hasn't changed since the first use, i.e. -+ * -smp hasn't been parsed after it -+ */ -+ assert(ms->possible_cpus->len == max_cpus); -+ return ms->possible_cpus; -+ } -+ -+ ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + -+ sizeof(CPUArchId) * max_cpus); -+ ms->possible_cpus->len = max_cpus; -+ for (i = 0; i < ms->possible_cpus->len; i++) { -+ ms->possible_cpus->cpus[i].type = ms->cpu_type; -+ ms->possible_cpus->cpus[i].vcpus_count = 1; -+ ms->possible_cpus->cpus[i].arch_id = i; -+ ms->possible_cpus->cpus[i].props.has_thread_id = true; -+ ms->possible_cpus->cpus[i].props.core_id = i; -+ } -+ -+ return ms->possible_cpus; -+} -+ -+static void core3_cpu_reset(void *opaque) -+{ -+ SW64CPU *cpu = opaque; -+ -+ cpu_reset(CPU(cpu)); -+} -+ -+static void core3_init(MachineState *machine) -+{ -+ ram_addr_t ram_size = machine->ram_size; -+ ram_addr_t buf; -+ SW64CPU *cpus[machine->smp.max_cpus]; -+ long i, size; -+ const char *kernel_filename = machine->kernel_filename; -+ const char *kernel_cmdline = machine->kernel_cmdline; -+ char *hmcode_filename; -+ char *uefi_filename; -+ uint64_t hmcode_entry, hmcode_low, hmcode_high; -+ uint64_t kernel_entry, kernel_low, kernel_high; -+ BOOT_PARAMS *core3_boot_params = g_new0(BOOT_PARAMS, 1); -+ uint64_t param_offset; -+ -+ memset(cpus, 0, sizeof(cpus)); -+ -+ for (i = 0; i < machine->smp.cpus; ++i) { -+ cpus[i] = SW64_CPU(cpu_create(machine->cpu_type)); -+ cpus[i]->env.csr[CID] = i; -+ qemu_register_reset(core3_cpu_reset, cpus[i]); -+ } -+ core3_board_init(cpus, machine->ram); -+ if (kvm_enabled()) -+ buf = ram_size; -+ else -+ buf = ram_size | (1UL << 63); -+ -+ rom_add_blob_fixed("ram_size", (char *)&buf, 0x8, 0x2040); -+ -+ param_offset = 0x90B000UL; -+ core3_boot_params->cmdline = param_offset | 0xfff0000000000000UL; -+ rom_add_blob_fixed("core3_boot_params", (core3_boot_params), 0x48, 0x90A100); -+ -+ hmcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, kvm_enabled() ? "core3-reset":"core3-hmcode"); -+ if (hmcode_filename == NULL) { -+ if (kvm_enabled()) -+ error_report("no core3-reset provided"); -+ else -+ error_report("no core3-hmcode provided"); -+ exit(1); -+ } -+ size = load_elf(hmcode_filename, NULL, cpu_sw64_virt_to_phys, NULL, -+ &hmcode_entry, &hmcode_low, &hmcode_high, NULL, 0, EM_SW64, 0, 0); -+ if (size < 0) { -+ if (kvm_enabled()) -+ error_report("could not load core3-reset: '%s'", hmcode_filename); -+ else -+ error_report("could not load core3-hmcode: '%s'", hmcode_filename); -+ exit(1); -+ } -+ g_free(hmcode_filename); -+ -+ /* Start all cpus at the hmcode RESET entry point. */ -+ for (i = 0; i < machine->smp.cpus; ++i) { -+ cpus[i]->env.pc = hmcode_entry; -+ cpus[i]->env.hm_entry = hmcode_entry; -+ } -+ -+ if (!kernel_filename) { -+ uefi_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "uefi-bios-sw"); -+ load_image_targphys(uefi_filename, 0x2f00000UL, -1); -+ g_free(uefi_filename); -+ } else { -+ /* Load a kernel. */ -+ size = load_elf(kernel_filename, NULL, cpu_sw64_virt_to_phys, NULL, -+ &kernel_entry, &kernel_low, &kernel_high, NULL, 0, EM_SW64, 0, 0); -+ if (size < 0) { -+ error_report("could not load kernel '%s'", kernel_filename); -+ exit(1); -+ } -+ cpus[0]->env.trap_arg1 = kernel_entry; -+ if (kernel_cmdline) -+ pstrcpy_targphys("cmdline", param_offset, 0x400, kernel_cmdline); -+ } -+} -+ -+static void board_reset(MachineState *state) -+{ -+ qemu_devices_reset(); -+} -+ -+static void core3_machine_init(MachineClass *mc) -+{ -+ mc->desc = "core3 BOARD"; -+ mc->init = core3_init; -+ mc->block_default_type = IF_IDE; -+ mc->max_cpus = MAX_CPUS_CORE3; -+ mc->is_default = 0; -+ mc->reset = board_reset; -+ mc->possible_cpu_arch_ids = sw64_possible_cpu_arch_ids; -+ mc->cpu_index_to_instance_props = sw64_cpu_index_to_props; -+ mc->default_cpu_type = SW64_CPU_TYPE_NAME("core3"); -+ mc->default_ram_id = "ram"; -+ mc->get_default_cpu_node_id = sw64_get_default_cpu_node_id; -+} -+ -+DEFINE_MACHINE("core3", core3_machine_init) -diff --git a/hw/sw64/core3_board.c b/hw/sw64/core3_board.c -new file mode 100644 -index 0000000000..7853e01edb ---- /dev/null -+++ b/hw/sw64/core3_board.c -@@ -0,0 +1,493 @@ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "cpu.h" -+#include "core.h" -+#include "hw/hw.h" -+#include "hw/boards.h" -+#include "sysemu/sysemu.h" -+#include "exec/address-spaces.h" -+#include "hw/pci/pci_host.h" -+#include "hw/pci/pci.h" -+#include "hw/char/serial.h" -+#include "hw/irq.h" -+#include "net/net.h" -+#include "hw/usb.h" -+#include "hw/ide/pci.h" -+#include "hw/ide/ahci.h" -+#include "sysemu/numa.h" -+#include "sysemu/kvm.h" -+#include "hw/rtc/sun4v-rtc.h" -+#include "hw/pci/msi.h" -+#include "hw/sw64/sw64_iommu.h" -+ -+#define TYPE_SWBOARD_PCI_HOST_BRIDGE "core_board-pcihost" -+#define SWBOARD_PCI_HOST_BRIDGE(obj) \ -+ OBJECT_CHECK(BoardState, (obj), TYPE_SWBOARD_PCI_HOST_BRIDGE) -+ -+#define MAX_IDE_BUS 2 -+#define SW_PIN_TO_IRQ 16 -+ -+typedef struct SWBoard { -+ SW64CPU *cpu[MAX_CPUS_CORE3]; -+} SWBoard; -+ -+typedef struct BoardState { -+ PCIHostState parent_obj; -+ -+ SWBoard sboard; -+ uint64_t expire_time; -+} BoardState; -+ -+typedef struct TimerState { -+ void *opaque; -+ int order; -+} TimerState; -+ -+#ifndef CONFIG_KVM -+static void swboard_alarm_timer(void *opaque) -+{ -+ TimerState *ts = (TimerState *)((uintptr_t)opaque); -+ BoardState *bs = (BoardState *)((uintptr_t)ts->opaque); -+ -+ int cpu = ts->order; -+ cpu_interrupt(CPU(bs->sboard.cpu[cpu]), CPU_INTERRUPT_TIMER); -+} -+#endif -+ -+static PCIINTxRoute sw_route_intx_pin_to_irq(void *opaque, int pin) -+{ -+ PCIINTxRoute route; -+ -+ route.mode = PCI_INTX_ENABLED; -+ route.irq = SW_PIN_TO_IRQ; -+ return route; -+} -+ -+static uint64_t convert_bit(int n) -+{ -+ uint64_t ret = (1UL << n) - 1; -+ -+ if (n == 64) -+ ret = 0xffffffffffffffffUL; -+ return ret; -+} -+ -+static uint64_t mcu_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ unsigned int smp_cpus = ms->smp.cpus; -+ uint64_t ret = 0; -+ switch (addr) { -+ case 0x0000: -+ /* CG_ONLINE */ -+ { -+ int i; -+ for (i = 0; i < smp_cpus; i = i + 4) -+ ret |= (1UL << i); -+ } -+ break; -+ /*IO_START*/ -+ case 0x1300: -+ ret = 0x1; -+ break; -+ case 0x3780: -+ /* MC_ONLINE */ -+ ret = convert_bit(smp_cpus); -+ break; -+ case 0x0900: -+ /* CPUID */ -+ ret = 0; -+ break; -+ case 0x1180: -+ /* LONGTIME */ -+ ret = qemu_clock_get_ns(QEMU_CLOCK_HOST) / 80; -+ break; -+ case 0x4900: -+ /* MC_CONFIG */ -+ break; -+ case 0x0780: -+ /* CORE_ONLINE */ -+ ret = convert_bit(smp_cpus); -+ break; -+ case 0x0680: -+ /* INIT_CTL */ -+ ret = 0x000003AE00000D28; -+ break; -+ default: -+ fprintf(stderr, "Unsupported MCU addr: 0x%04lx\n", addr); -+ return -1; -+ } -+ return ret; -+} -+ -+static void mcu_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) -+{ -+#ifndef CONFIG_KVM -+#ifdef CONFIG_DUMP_PRINTK -+ uint64_t print_addr; -+ uint32_t len; -+ int i; -+ -+ if (addr == 0x40000) { -+ print_addr = val & 0x7fffffff; -+ len = (uint32_t)(val >> 32); -+ uint8_t *buf; -+ buf = malloc(len + 10); -+ memset(buf, 0, len + 10); -+ cpu_physical_memory_rw(print_addr, buf, len, 0); -+ for (i = 0; i < len; i++) -+ printf("%c", buf[i]); -+ -+ free(buf); -+ return; -+ } -+#endif -+#endif -+} -+ -+static const MemoryRegionOps mcu_ops = { -+ .read = mcu_read, -+ .write = mcu_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = -+ { -+ .min_access_size = 8, -+ .max_access_size = 8, -+ }, -+ .impl = -+ { -+ .min_access_size = 8, -+ .max_access_size = 8, -+ }, -+}; -+ -+static uint64_t intpu_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ uint64_t ret = 0; -+#ifndef CONFIG_KVM -+ switch (addr) { -+ case 0x180: -+ /* LONGTIME */ -+ ret = qemu_clock_get_ns(QEMU_CLOCK_HOST) / 32; -+ break; -+ } -+#endif -+ return ret; -+} -+ -+static void intpu_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size) -+{ -+#ifndef CONFIG_KVM -+ BoardState *bs = (BoardState *)opaque; -+ SW64CPU *cpu; -+ switch (addr) { -+ case 0x00: -+ val &= 0x1f; -+ cpu = bs->sboard.cpu[val]; -+ cpu->env.csr[II_REQ] = 0x100000; -+ cpu_interrupt(CPU(cpu),CPU_INTERRUPT_IIMAIL); -+ break; -+ default: -+ fprintf(stderr, "Unsupported IPU addr: 0x%04lx\n", addr); -+ break; -+ } -+#endif -+} -+ -+static const MemoryRegionOps intpu_ops = { -+ .read = intpu_read, -+ .write = intpu_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = -+ { -+ .min_access_size = 8, -+ .max_access_size = 8, -+ }, -+ .impl = -+ { -+ .min_access_size = 8, -+ .max_access_size = 8, -+ }, -+}; -+ -+static MemTxResult msi_read(void *opaque, hwaddr addr, -+ uint64_t *data, unsigned size, -+ MemTxAttrs attrs) -+{ -+ return MEMTX_OK; -+} -+ -+MemTxResult msi_write(void *opaque, hwaddr addr, -+ uint64_t value, unsigned size, -+ MemTxAttrs attrs) -+{ -+#ifdef CONFIG_KVM -+ int ret = 0; -+ MSIMessage msg = {}; -+ -+ msg.address = (uint64_t) addr + 0x8000fee00000; -+ msg.data = (uint32_t) value; -+ -+ ret = kvm_irqchip_send_msi(kvm_state, msg); -+ if (ret < 0) { -+ fprintf(stderr, "KVM: injection failed, MSI lost (%s)\n", -+ strerror(-ret)); -+ } -+#endif -+ return MEMTX_OK; -+} -+ -+static const MemoryRegionOps msi_ops = { -+ .read_with_attrs = msi_read, -+ .write_with_attrs = msi_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = -+ { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .impl = -+ { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+}; -+ -+static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ return 1; -+} -+ -+static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size) -+{ -+} -+ -+const MemoryRegionOps core3_pci_ignore_ops = { -+ .read = ignore_read, -+ .write = ignore_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = -+ { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .impl = -+ { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+}; -+ -+static uint64_t config_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ PCIBus *b = opaque; -+ uint32_t trans_addr = 0; -+ trans_addr |= ((addr >> 16) & 0xffff) << 8; -+ trans_addr |= (addr & 0xff); -+ return pci_data_read(b, trans_addr, size); -+} -+ -+static void config_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size) -+{ -+ PCIBus *b = opaque; -+ uint32_t trans_addr = 0; -+ trans_addr |= ((addr >> 16) & 0xffff) << 8; -+ trans_addr |= (addr & 0xff); -+ pci_data_write(b, trans_addr, val, size); -+} -+ -+const MemoryRegionOps core3_pci_config_ops = { -+ .read = config_read, -+ .write = config_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = -+ { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .impl = -+ { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+}; -+ -+static void cpu_irq_change(SW64CPU *cpu, uint64_t req) -+{ -+ if (cpu != NULL) { -+ CPUState *cs = CPU(cpu); -+ if (req) -+ cpu_interrupt(cs, CPU_INTERRUPT_HARD); -+ else -+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); -+ } -+} -+ -+static void swboard_set_irq(void *opaque, int irq, int level) -+{ -+ BoardState *bs = opaque; -+ SW64CPU *cpu; -+ int i; -+ -+ if (kvm_enabled()) { -+ if (level == 0) -+ return; -+ kvm_set_irq(kvm_state, irq, level); -+ return; -+ } -+ -+ for (i = 0; i < 1; i++) { -+ cpu = bs->sboard.cpu[i]; -+ if (cpu != NULL) { -+ CPUState *cs = CPU(cpu); -+ if (level) -+ cpu_interrupt(cs, CPU_INTERRUPT_PCIE); -+ else -+ cpu_reset_interrupt(cs, CPU_INTERRUPT_PCIE); -+ } -+ } -+} -+ -+static int swboard_map_irq(PCIDevice *d, int irq_num) -+{ -+ /* In fact,the return value is the interrupt type passed to kernel, -+ * so it must keep same with the type in do_entInt in kernel. -+ */ -+ return 16; -+} -+ -+static void serial_set_irq(void *opaque, int irq, int level) -+{ -+ BoardState *bs = (BoardState *)opaque; -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ unsigned int smp_cpus = ms->smp.cpus; -+ int i; -+ if (level == 0) -+ return; -+ if (kvm_enabled()) { -+ kvm_set_irq(kvm_state, irq, level); -+ return; -+ } -+ for (i = 0; i < smp_cpus; i++) { -+ if (bs->sboard.cpu[i]) -+ cpu_irq_change(bs->sboard.cpu[i], 1); -+ } -+} -+ -+void core3_board_init(SW64CPU *cpus[MAX_CPUS], MemoryRegion *ram) -+{ -+ DeviceState *dev; -+ BoardState *bs; -+#ifndef CONFIG_KVM -+ TimerState *ts; -+#endif -+ MemoryRegion *io_mcu = g_new(MemoryRegion, 1); -+ MemoryRegion *io_intpu = g_new(MemoryRegion, 1); -+ MemoryRegion *msi_ep = g_new(MemoryRegion, 1); -+ qemu_irq serial_irq; -+ uint64_t MB = 1024 * 1024; -+ MemoryRegion *mem_ep = g_new(MemoryRegion, 1); -+ MemoryRegion *mem_ep64 = g_new(MemoryRegion, 1); -+ MemoryRegion *conf_piu0 = g_new(MemoryRegion, 1); -+ MemoryRegion *io_ep = g_new(MemoryRegion, 1); -+ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ unsigned int smp_cpus = ms->smp.cpus; -+ -+ PCIBus *b; -+ PCIHostState *phb; -+ uint64_t GB = 1024 * MB; -+ -+ int i; -+ dev = qdev_new(TYPE_SWBOARD_PCI_HOST_BRIDGE); -+ phb = PCI_HOST_BRIDGE(dev); -+ bs = SWBOARD_PCI_HOST_BRIDGE(dev); -+ -+#ifdef CONFIG_KVM -+ if (kvm_has_gsi_routing()) -+ msi_nonbroken = true; -+#endif -+ -+ for (i = 0; i < smp_cpus; ++i) { -+ if (cpus[i] == NULL) -+ continue; -+ bs->sboard.cpu[i] = cpus[i]; -+#ifndef CONFIG_KVM -+ ts = g_new(TimerState, 1); -+ ts->opaque = (void *) ((uintptr_t)bs); -+ ts->order = i; -+ cpus[i]->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &swboard_alarm_timer, ts); -+#endif -+ } -+ memory_region_add_subregion(get_system_memory(), 0, ram); -+ -+ memory_region_init_io(io_mcu, NULL, &mcu_ops, bs, "io_mcu", 16 * MB); -+ memory_region_add_subregion(get_system_memory(), 0x803000000000ULL, io_mcu); -+ -+ memory_region_init_io(io_intpu, NULL, &intpu_ops, bs, "io_intpu", 1 * MB); -+ memory_region_add_subregion(get_system_memory(), 0x802a00000000ULL, -+ io_intpu); -+ -+ memory_region_init_io(msi_ep, NULL, &msi_ops, bs, "msi_ep", 1 * MB); -+ memory_region_add_subregion(get_system_memory(), 0x8000fee00000ULL, msi_ep); -+ -+ memory_region_init(mem_ep, OBJECT(bs), "pci0-mem", 0x890000000000ULL); -+ memory_region_add_subregion(get_system_memory(), 0x880000000000ULL, mem_ep); -+ -+ memory_region_init_alias(mem_ep64, NULL, "mem_ep64", mem_ep, 0x888000000000ULL, 1ULL << 39); -+ memory_region_add_subregion(get_system_memory(), 0x888000000000ULL, mem_ep64); -+ -+ memory_region_init_io(io_ep, OBJECT(bs), &core3_pci_ignore_ops, NULL, -+ "pci0-io-ep", 4 * GB); -+ -+ memory_region_add_subregion(get_system_memory(), 0x880100000000ULL, io_ep); -+ b = pci_register_root_bus(dev, "pcie.0", swboard_set_irq, swboard_map_irq, bs, -+ mem_ep, io_ep, 0, 537, TYPE_PCIE_BUS); -+ phb->bus = b; -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); -+ pci_bus_set_route_irq_fn(b, sw_route_intx_pin_to_irq); -+ memory_region_init_io(conf_piu0, OBJECT(bs), &core3_pci_config_ops, b, -+ "pci0-ep-conf-io", 4 * GB); -+ memory_region_add_subregion(get_system_memory(), 0x880600000000ULL, -+ conf_piu0); -+#ifdef SW64_VT_IOMMU -+ sw64_vt_iommu_init(b); -+#endif -+ for (i = 0; i < nb_nics; i++) { -+ pci_nic_init_nofail(&nd_table[i], b, "e1000", NULL); -+ } -+ -+ pci_vga_init(b); -+#define MAX_SATA_PORTS 6 -+ PCIDevice *ahci; -+ DriveInfo *hd[MAX_SATA_PORTS]; -+ ahci = pci_create_simple_multifunction(b, PCI_DEVFN(0x1f, 0), true, -+ TYPE_ICH9_AHCI); -+ g_assert(MAX_SATA_PORTS == ahci_get_num_ports(ahci)); -+ ide_drive_get(hd, ahci_get_num_ports(ahci)); -+ ahci_ide_create_devs(ahci, hd); -+ -+ serial_irq = qemu_allocate_irq(serial_set_irq, bs, 12); -+ if (serial_hd(0)) { -+ serial_mm_init(get_system_memory(), 0x3F8 + 0x880100000000ULL, 0, -+ serial_irq, (1843200 >> 4), serial_hd(0), -+ DEVICE_LITTLE_ENDIAN); -+ } -+ pci_create_simple(phb->bus, -1, "nec-usb-xhci"); -+ sun4v_rtc_init(0x804910000000ULL); -+} -+ -+static const TypeInfo swboard_pcihost_info = { -+ .name = TYPE_SWBOARD_PCI_HOST_BRIDGE, -+ .parent = TYPE_PCI_HOST_BRIDGE, -+ .instance_size = sizeof(BoardState), -+}; -+ -+static void swboard_register_types(void) -+{ -+ type_register_static(&swboard_pcihost_info); -+} -+ -+type_init(swboard_register_types) -diff --git a/hw/sw64/meson.build b/hw/sw64/meson.build -new file mode 100644 -index 0000000000..8abb18222a ---- /dev/null -+++ b/hw/sw64/meson.build -@@ -0,0 +1,10 @@ -+sw64_ss = ss.source_set() -+ -+sw64_ss.add(files('sw64_iommu.c')) -+ -+sw64_ss.add(when: 'CONFIG_CORE3', if_true: files( -+ 'core3.c', -+ 'core3_board.c', -+)) -+ -+hw_arch += {'sw64': sw64_ss} -diff --git a/hw/sw64/sw64_iommu.c b/hw/sw64/sw64_iommu.c -new file mode 100644 -index 0000000000..8ded65f213 ---- /dev/null -+++ b/hw/sw64/sw64_iommu.c -@@ -0,0 +1,567 @@ -+/* -+ * QEMU sw64 IOMMU emulation -+ * -+ * Copyright (c) 2021 Lu Feifei -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+ -+#include "qemu/osdep.h" -+#include "hw/sysbus.h" -+#include "exec/address-spaces.h" -+#include "qemu/log.h" -+#include "qapi/error.h" -+#include "hw/sw64/sw64_iommu.h" -+#include "sysemu/kvm.h" -+ -+#define IOMMU_PAGE_SHIFT 13 -+#define IOMMU_PAGE_SIZE_8K (1ULL << IOMMU_PAGE_SHIFT) -+#define IOMMU_PAGE_MASK_8K (~(IOMMU_PAGE_SIZE_8K - 1)) -+#define IOMMU_IOVA_SHIFT 16 -+#define SW64IOMMU_PTIOTLB_MAX_SIZE 256 -+ -+static MemTxResult swvt_msi_read(void *opaque, hwaddr addr, -+ uint64_t *data, unsigned size, MemTxAttrs attrs) -+{ -+ return MEMTX_OK; -+} -+ -+static MemTxResult swvt_msi_write(void *opaque, hwaddr addr, -+ uint64_t value, unsigned size, -+ MemTxAttrs attrs) -+{ -+ MemTxResult ret; -+ -+ ret = msi_write(opaque, addr, value, size, attrs); -+ -+ return ret; -+} -+ -+static const MemoryRegionOps swvt_msi_ops = { -+ .read_with_attrs = swvt_msi_read, -+ .write_with_attrs = swvt_msi_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+}; -+ -+SWVTAddressSpace *iommu_find_add_as(SW64IOMMUState *s, PCIBus *bus, int devfn) -+{ -+ uintptr_t key = (uintptr_t)bus; -+ SWVTBus *swvt_bus = g_hash_table_lookup(s->swvtbus_as_by_busptr, &key); -+ SWVTAddressSpace *swvt_dev_as; -+ char name[128]; -+ -+ if (!swvt_bus) { -+ uintptr_t *new_key = g_malloc(sizeof(*new_key)); -+ *new_key = (uintptr_t)bus; -+ /* No corresponding free() */ -+ swvt_bus = g_malloc0(sizeof(SWVTBus) + sizeof(SWVTAddressSpace *) * \ -+ PCI_DEVFN_MAX); -+ swvt_bus->bus = bus; -+ g_hash_table_insert(s->swvtbus_as_by_busptr, new_key, swvt_bus); -+ } -+ swvt_dev_as = swvt_bus->dev_as[devfn]; -+ if (!swvt_dev_as) { -+ snprintf(name, sizeof(name), "sw64_iommu_devfn_%d", devfn); -+ swvt_bus->dev_as[devfn] = swvt_dev_as = g_malloc0(sizeof(SWVTAddressSpace)); -+ -+ swvt_dev_as->bus = bus; -+ swvt_dev_as->devfn = (uint8_t)devfn; -+ swvt_dev_as->iommu_state = s; -+ -+ memory_region_init_iommu(&swvt_dev_as->iommu, sizeof(swvt_dev_as->iommu), -+ TYPE_SW64_IOMMU_MEMORY_REGION, OBJECT(s), -+ "sw64_iommu_dmar", -+ 1UL << 32); -+ memory_region_init_io(&swvt_dev_as->msi, OBJECT(s), -+ &swvt_msi_ops, s, "sw_msi", 1 * 1024 * 1024); -+ memory_region_init(&swvt_dev_as->root, OBJECT(s), -+ "swvt_root", UINT64_MAX); -+ memory_region_add_subregion_overlap(&swvt_dev_as->root, -+ 0x8000fee00000ULL, -+ &swvt_dev_as->msi, 64); -+ address_space_init(&swvt_dev_as->as, &swvt_dev_as->root, name); -+ memory_region_add_subregion_overlap(&swvt_dev_as->root, 0, -+ MEMORY_REGION(&swvt_dev_as->iommu), -+ 1); -+ } -+ -+ memory_region_set_enabled(MEMORY_REGION(&swvt_dev_as->iommu), true); -+ -+ return swvt_dev_as; -+} -+ -+/** -+ * get_pte - Get the content of a page table entry located at -+ * @base_addr[@index] -+ */ -+static int get_pte(dma_addr_t baseaddr, uint64_t *pte) -+{ -+ int ret; -+ -+ /* TODO: guarantee 64-bit single-copy atomicity */ -+ ret = dma_memory_read(&address_space_memory, baseaddr, -+ (uint8_t *)pte, sizeof(*pte)); -+ -+ if (ret != MEMTX_OK) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static bool swvt_do_iommu_translate(SWVTAddressSpace *swvt_as, PCIBus *bus, -+ uint8_t devfn, hwaddr addr, IOMMUTLBEntry *entry) -+{ -+ SW64IOMMUState *s = swvt_as->iommu_state; -+ uint8_t bus_num = pci_bus_num(bus); -+ unsigned long dtbbaseaddr, dtbbasecond; -+ unsigned long pdebaseaddr, ptebaseaddr; -+ unsigned long pte; -+ uint16_t source_id; -+ SW64DTIOTLBEntry *dtcached_entry = NULL; -+ SW64DTIOTLBKey dtkey, *new_key; -+ -+ dtcached_entry = g_hash_table_lookup(s->dtiotlb, &dtkey); -+ -+ if (unlikely(!dtcached_entry)) { -+ dtbbaseaddr = s->dtbr + (bus_num << 3); -+ -+ if (get_pte(dtbbaseaddr, &pte)) -+ goto error; -+ -+ dtbbasecond = (pte & (~(SW_IOMMU_ENTRY_VALID))) + (devfn << 3); -+ if (get_pte(dtbbasecond, &pte)) -+ goto error; -+ -+ source_id = ((bus_num & 0xffUL) << 8) | (devfn & 0xffUL); -+ dtcached_entry = g_new0(SW64DTIOTLBEntry, 1); -+ dtcached_entry->ptbase_addr = pte & (~(SW_IOMMU_ENTRY_VALID)); -+ dtcached_entry->source_id = source_id; -+ -+ new_key = g_new0(SW64DTIOTLBKey, 1); -+ new_key->source_id = source_id; -+ -+ g_hash_table_insert(s->dtiotlb, new_key, dtcached_entry); -+ } -+ -+ pdebaseaddr = dtcached_entry->ptbase_addr; -+ pdebaseaddr += ((addr >> 23) & SW_IOMMU_LEVEL1_OFFSET) << 3; -+ -+ if (get_pte(pdebaseaddr, &pte)) -+ goto error; -+ -+ ptebaseaddr = pte & (~(SW_IOMMU_ENTRY_VALID)); -+ ptebaseaddr += ((addr >> IOMMU_PAGE_SHIFT) & SW_IOMMU_LEVEL2_OFFSET) << 3; -+ -+ if (get_pte(ptebaseaddr, &pte)) -+ goto error; -+ -+ pte &= ~(SW_IOMMU_ENTRY_VALID | SW_IOMMU_GRN | SW_IOMMU_ENABLE); -+ entry->translated_addr = pte; -+ entry->addr_mask = IOMMU_PAGE_SIZE_8K - 1; -+ -+ return 0; -+ -+error: -+ entry->perm = IOMMU_NONE; -+ return -EINVAL; -+} -+ -+static void swvt_ptiotlb_inv_all(SW64IOMMUState *s) -+{ -+ g_hash_table_remove_all(s->ptiotlb); -+} -+ -+static void swvt_lookup_ptiotlb(SW64IOMMUState *s, uint16_t source_id, -+ hwaddr addr, IOMMUTLBEntry *entry) -+{ -+ SW64PTIOTLBKey ptkey; -+ -+ ptkey.source_id = source_id; -+ ptkey.iova = addr; -+ -+ entry = g_hash_table_lookup(s->ptiotlb, &ptkey); -+} -+ -+static IOMMUTLBEntry sw64_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr, -+ IOMMUAccessFlags flag, int iommu_idx) -+{ -+ SWVTAddressSpace *swvt_as = container_of(iommu, SWVTAddressSpace, iommu); -+ SW64IOMMUState *s = swvt_as->iommu_state; -+ IOMMUTLBEntry *cached_entry = NULL; -+ IOMMUTLBEntry entry = { -+ .target_as = &address_space_memory, -+ .iova = addr, -+ .translated_addr = addr, -+ .addr_mask = ~(hwaddr)0, -+ .perm = IOMMU_NONE, -+ }; -+ uint8_t bus_num = pci_bus_num(swvt_as->bus); -+ uint16_t source_id; -+ SW64PTIOTLBKey *new_ptkey; -+ hwaddr aligned_addr; -+ -+ source_id = ((bus_num & 0xffUL) << 8) | (swvt_as->devfn & 0xffUL); -+ -+ qemu_mutex_lock(&s->iommu_lock); -+ -+ aligned_addr = addr & IOMMU_PAGE_MASK_8K; -+ -+ swvt_lookup_ptiotlb(s, aligned_addr, source_id, cached_entry); -+ -+ if (cached_entry) -+ goto out; -+ -+ if (g_hash_table_size(s->ptiotlb) >= SW64IOMMU_PTIOTLB_MAX_SIZE) { -+ swvt_ptiotlb_inv_all(s); -+ } -+ -+ cached_entry = g_new0(IOMMUTLBEntry, 1); -+ -+ if (swvt_do_iommu_translate(swvt_as, swvt_as->bus, swvt_as->devfn, -+ addr, cached_entry)) { -+ g_free(cached_entry); -+ qemu_mutex_unlock(&s->iommu_lock); -+ printf("%s: detected translation failure " -+ "(busnum=%d, devfn=%#x, iova=%#lx.\n", -+ __func__, pci_bus_num(swvt_as->bus), swvt_as->devfn, -+ entry.iova); -+ entry.iova = 0; -+ entry.translated_addr = 0; -+ entry.addr_mask = 0; -+ entry.perm = IOMMU_NONE; -+ -+ return entry; -+ } else { -+ new_ptkey = g_new0(SW64PTIOTLBKey, 1); -+ new_ptkey->source_id = source_id; -+ new_ptkey->iova = aligned_addr; -+ g_hash_table_insert(s->ptiotlb, new_ptkey, cached_entry); -+ } -+ -+out: -+ qemu_mutex_unlock(&s->iommu_lock); -+ entry.perm = flag; -+ entry.translated_addr = cached_entry->translated_addr + -+ (addr & (IOMMU_PAGE_SIZE_8K - 1)); -+ entry.addr_mask = cached_entry->addr_mask; -+ -+ return entry; -+} -+ -+static void swvt_ptiotlb_inv_iova(SW64IOMMUState *s, uint16_t source_id, dma_addr_t iova) -+{ -+ SW64PTIOTLBKey key = {.source_id = source_id, .iova = iova}; -+ -+ qemu_mutex_lock(&s->iommu_lock); -+ g_hash_table_remove(s->ptiotlb, &key); -+ qemu_mutex_unlock(&s->iommu_lock); -+} -+ -+void swvt_address_space_unmap_iova(SW64IOMMUState *s, unsigned long val) -+{ -+ SWVTAddressSpace *swvt_as; -+ IOMMUNotifier *n; -+ uint16_t source_id; -+ dma_addr_t iova; -+ IOMMUTLBEvent event; -+ -+ source_id = val & 0xffff; -+ iova = (val >> IOMMU_IOVA_SHIFT) << IOMMU_PAGE_SHIFT; -+ -+ swvt_ptiotlb_inv_iova(s, source_id, iova); -+ -+ QLIST_FOREACH(swvt_as, &s->swvt_as_with_notifiers, next) { -+ uint8_t bus_num = pci_bus_num(swvt_as->bus); -+ uint16_t as_sourceid = ((bus_num & 0xffUL) << 8) | (swvt_as->devfn & 0xffUL); -+ -+ if (as_sourceid == source_id) { -+ IOMMU_NOTIFIER_FOREACH(n, &swvt_as->iommu) { -+ event.type = IOMMU_NOTIFIER_UNMAP; -+ event.entry.target_as = &address_space_memory; -+ event.entry.iova = iova & IOMMU_PAGE_MASK_8K; -+ event.entry.translated_addr = 0; -+ event.entry.perm = IOMMU_NONE; -+ event.entry.addr_mask = IOMMU_PAGE_SIZE_8K - 1; -+ -+ memory_region_notify_iommu(&swvt_as->iommu, 0, event); -+ } -+ } -+ } -+} -+ -+/* Unmap the whole range in the notifier's scope. */ -+static void swvt_address_space_unmap(SWVTAddressSpace *as, IOMMUNotifier *n) -+{ -+ IOMMUTLBEvent event; -+ hwaddr size; -+ hwaddr start = n->start; -+ hwaddr end = n->end; -+ -+ assert(start <= end); -+ size = end - start; -+ -+ event.entry.target_as = &address_space_memory; -+ /* Adjust iova for the size */ -+ event.entry.iova = n->start & ~(size - 1); -+ /* This field is meaningless for unmap */ -+ event.entry.translated_addr = 0; -+ event.entry.perm = IOMMU_NONE; -+ event.entry.addr_mask = size - 1; -+ -+ memory_region_notify_iommu_one(n, &event); -+} -+ -+void swvt_address_space_map_iova(SW64IOMMUState *s, unsigned long val) -+{ -+ SWVTAddressSpace *swvt_as; -+ IOMMUNotifier *n; -+ uint16_t source_id; -+ dma_addr_t iova; -+ IOMMUTLBEvent event; -+ int ret; -+ -+ source_id = val & 0xffff; -+ iova = (val >> IOMMU_IOVA_SHIFT) << IOMMU_PAGE_SHIFT; -+ -+ swvt_ptiotlb_inv_iova(s, source_id, iova); -+ -+ QLIST_FOREACH(swvt_as, &s->swvt_as_with_notifiers, next) { -+ uint8_t bus_num = pci_bus_num(swvt_as->bus); -+ uint16_t as_sourceid = ((bus_num & 0xffUL) << 8) | (swvt_as->devfn & 0xffUL); -+ -+ if (as_sourceid == source_id) { -+ IOMMU_NOTIFIER_FOREACH(n, &swvt_as->iommu) { -+ event.type = IOMMU_NOTIFIER_UNMAP; -+ event.entry.target_as = &address_space_memory; -+ event.entry.iova = iova & IOMMU_PAGE_MASK_8K; -+ event.entry.perm = IOMMU_RW; -+ -+ ret = swvt_do_iommu_translate(swvt_as, swvt_as->bus, -+ swvt_as->devfn, iova, &event.entry); -+ if (ret) -+ goto out; -+ -+ memory_region_notify_iommu(&swvt_as->iommu, 0, event); -+ } -+ } -+ } -+out: -+ return; -+} -+ -+void swvt_address_space_invalidate_iova(SW64IOMMUState *s, unsigned long val) -+{ -+ int map_flag; -+ -+ map_flag = val >> 36; -+ -+ if (map_flag) -+ swvt_address_space_map_iova(s, val & 0xfffffffff); -+ else -+ swvt_address_space_unmap_iova(s, val); -+ -+ return; -+} -+ -+static AddressSpace *sw64_dma_iommu(PCIBus *bus, void *opaque, int devfn) -+{ -+ SW64IOMMUState *s = opaque; -+ SWVTAddressSpace *swvt_as; -+ -+ assert(0 <= devfn && devfn < PCI_DEVFN_MAX); -+ -+ swvt_as = iommu_find_add_as(s, bus, devfn); -+ return &swvt_as->as; -+} -+ -+static uint64_t piu0_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ uint64_t ret = 0; -+ switch (addr) { -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static void piu0_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size) -+{ -+ SW64IOMMUState *s = (SW64IOMMUState *)opaque; -+ -+ switch (addr) { -+ case 0xb000: -+ /* DTBaseAddr */ -+ s->dtbr = val; -+ break; -+ case 0xb280: -+ /* PTLB_FlushVAddr */ -+ swvt_address_space_invalidate_iova(s, val); -+ break; -+ default: -+ break; -+ } -+} -+ -+const MemoryRegionOps core3_pci_piu0_ops = { -+ .read = piu0_read, -+ .write = piu0_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .impl = { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+}; -+ -+void sw64_vt_iommu_init(PCIBus *b) -+{ -+ DeviceState *dev_iommu; -+ SW64IOMMUState *s; -+ MemoryRegion *io_piu0 = g_new(MemoryRegion, 1); -+ -+ dev_iommu = qdev_new(TYPE_SW64_IOMMU); -+ s = SW64_IOMMU(dev_iommu); -+ -+ s->pci_bus = b; -+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev_iommu), &error_fatal); -+ -+ pci_setup_iommu(b, sw64_dma_iommu, dev_iommu); -+ -+ memory_region_init_io(io_piu0, OBJECT(s), &core3_pci_piu0_ops, s, -+ "pci0-piu0-io", 4 * 1024 * 1024); -+ memory_region_add_subregion(get_system_memory(), 0x880200000000ULL, -+ io_piu0); -+} -+ -+static int swvt_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu, -+ IOMMUNotifierFlag old, -+ IOMMUNotifierFlag new, -+ Error **errp) -+{ -+ SWVTAddressSpace *swvt_as = container_of(iommu, SWVTAddressSpace, iommu); -+ SW64IOMMUState *s = swvt_as->iommu_state; -+ -+ /* Update per-address-space notifier flags */ -+ swvt_as->notifier_flags = new; -+ -+ if (new & IOMMU_NOTIFIER_DEVIOTLB_UNMAP) { -+ error_setg(errp, "swvt does not support dev-iotlb yet"); -+ return -EINVAL; -+ } -+ -+ if (old == IOMMU_NOTIFIER_NONE) { -+ QLIST_INSERT_HEAD(&s->swvt_as_with_notifiers, swvt_as, next); -+ } else if (new == IOMMU_NOTIFIER_NONE) { -+ QLIST_REMOVE(swvt_as, next); -+ } -+ return 0; -+} -+ -+static void swvt_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n) -+{ -+ SWVTAddressSpace *swvt_as = container_of(iommu_mr, SWVTAddressSpace, iommu); -+ -+ /* -+ * The replay can be triggered by either a invalidation or a newly -+ * created entry. No matter what, we release existing mappings -+ * (it means flushing caches for UNMAP-only registers). -+ */ -+ swvt_address_space_unmap(swvt_as, n); -+} -+ -+/* GHashTable functions */ -+static gboolean swvt_uint64_equal(gconstpointer v1, gconstpointer v2) -+{ -+ return *((const uint64_t *)v1) == *((const uint64_t *)v2); -+} -+ -+static guint swvt_uint64_hash(gconstpointer v) -+{ -+ return (guint)*(const uint64_t *)v; -+} -+ -+static void iommu_realize(DeviceState *d, Error **errp) -+{ -+ SW64IOMMUState *s = SW64_IOMMU(d); -+ -+ QLIST_INIT(&s->swvt_as_with_notifiers); -+ qemu_mutex_init(&s->iommu_lock); -+ -+ s->dtiotlb = g_hash_table_new_full(swvt_uint64_hash, swvt_uint64_equal, -+ g_free, g_free); -+ s->ptiotlb = g_hash_table_new_full(swvt_uint64_hash, swvt_uint64_equal, -+ g_free, g_free); -+ -+ s->swvtbus_as_by_busptr = g_hash_table_new(NULL, NULL); -+} -+ -+static void iommu_reset(DeviceState *d) -+{ -+} -+ -+static void sw64_iommu_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ -+ dc->reset = iommu_reset; -+ dc->realize = iommu_realize; -+} -+ -+static void sw64_iommu_memory_region_class_init(ObjectClass *klass, void *data) -+{ -+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); -+ -+ imrc->translate = sw64_translate_iommu; -+ imrc->notify_flag_changed = swvt_iommu_notify_flag_changed; -+ imrc->replay = swvt_iommu_replay; -+} -+ -+static const TypeInfo sw64_iommu_info = { -+ .name = TYPE_SW64_IOMMU, -+ .parent = TYPE_SYS_BUS_DEVICE, -+ .instance_size = sizeof(SW64IOMMUState), -+ .class_init = sw64_iommu_class_init, -+ .class_size = sizeof(SW64IOMMUClass), -+}; -+ -+static const TypeInfo sw64_iommu_memory_region_info = { -+ .parent = TYPE_IOMMU_MEMORY_REGION, -+ .name = TYPE_SW64_IOMMU_MEMORY_REGION, -+ .class_init = sw64_iommu_memory_region_class_init, -+}; -+ -+static void sw64_iommu_register_types(void) -+{ -+ type_register_static(&sw64_iommu_info); -+ type_register_static(&sw64_iommu_memory_region_info); -+} -+ -+type_init(sw64_iommu_register_types) -diff --git a/hw/sw64/trace-events b/hw/sw64/trace-events -new file mode 100644 -index 0000000000..1aa744c984 ---- /dev/null -+++ b/hw/sw64/trace-events -@@ -0,0 +1,3 @@ -+# See docs/devel/tracing.rst for syntax documentation. -+ -+# pci.c -diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h -index 08e1beec85..4590bcc968 100644 ---- a/include/disas/dis-asm.h -+++ b/include/disas/dis-asm.h -@@ -191,6 +191,9 @@ enum bfd_architecture - #define bfd_mach_alpha_ev4 0x10 - #define bfd_mach_alpha_ev5 0x20 - #define bfd_mach_alpha_ev6 0x30 -+ bfd_arch_sw_64, /* Dec Sw_64 */ -+#define bfd_mach_sw_64 1 -+#define bfd_mach_sw_64_core3 1621 - bfd_arch_arm, /* Advanced Risc Machines ARM */ - #define bfd_mach_arm_unknown 0 - #define bfd_mach_arm_2 1 -@@ -429,6 +432,7 @@ int print_insn_h8500 (bfd_vma, disassemble_info*); - int print_insn_arm_a64 (bfd_vma, disassemble_info*); - int print_insn_alpha (bfd_vma, disassemble_info*); - disassembler_ftype arc_get_disassembler (int, int); -+int print_insn_sw_64 (bfd_vma, disassemble_info*); - int print_insn_arm (bfd_vma, disassemble_info*); - int print_insn_sparc (bfd_vma, disassemble_info*); - int print_insn_big_a29k (bfd_vma, disassemble_info*); -diff --git a/include/elf.h b/include/elf.h -index 811bf4a1cb..79c188b62f 100644 ---- a/include/elf.h -+++ b/include/elf.h -@@ -207,6 +207,8 @@ typedef struct mips_elf_abiflags_v0 { - - #define EF_AVR_MACH 0x7F /* Mask for AVR e_flags to get core type */ - -+#define EM_SW64 0x9916 /* SW64 */ -+ - /* This is the info that is needed to parse the dynamic section of the file */ - #define DT_NULL 0 - #define DT_NEEDED 1 -@@ -1417,6 +1419,48 @@ typedef struct { - #define EF_RISCV_RVE 0x0008 - #define EF_RISCV_TSO 0x0010 - -+/* -+ SW_64 ELF relocation types -+ */ -+#define EM_SW_64 0x9916 -+#define R_SW_64_NONE 0 /* No reloc */ -+#define R_SW_64_REFLONG 1 /* Direct 32 bit */ -+#define R_SW_64_REFQUAD 2 /* Direct 64 bit */ -+#define R_SW_64_GPREL32 3 /* GP relative 32 bit */ -+#define R_SW_64_LITERAL 4 /* GP relative 16 bit w/optimization */ -+#define R_SW_64_LITUSE 5 /* Optimization hint for LITERAL */ -+#define R_SW_64_GPDISP 6 /* Add displacement to GP */ -+#define R_SW_64_BRADDR 7 /* PC+4 relative 23 bit shifted */ -+#define R_SW_64_HINT 8 /* PC+4 relative 16 bit shifted */ -+#define R_SW_64_SREL16 9 /* PC relative 16 bit */ -+#define R_SW_64_SREL32 10 /* PC relative 32 bit */ -+#define R_SW_64_SREL64 11 /* PC relative 64 bit */ -+#define R_SW_64_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -+#define R_SW_64_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -+#define R_SW_64_GPREL16 19 /* GP relative 16 bit */ -+#define R_SW_64_COPY 24 /* Copy symbol at runtime */ -+#define R_SW_64_GLOB_DAT 25 /* Create GOT entry */ -+#define R_SW_64_JMP_SLOT 26 /* Create PLT entry */ -+#define R_SW_64_RELATIVE 27 /* Adjust by program base */ -+#define R_SW_64_TLS_GD_HI 28 -+#define R_SW_64_TLSGD 29 -+#define R_SW_64_TLS_LDM 30 -+#define R_SW_64_DTPMOD64 31 -+#define R_SW_64_GOTDTPREL 32 -+#define R_SW_64_DTPREL64 33 -+#define R_SW_64_DTPRELHI 34 -+#define R_SW_64_DTPRELLO 35 -+#define R_SW_64_DTPREL16 36 -+#define R_SW_64_GOTTPREL 37 -+#define R_SW_64_TPREL64 38 -+#define R_SW_64_TPRELHI 39 -+#define R_SW_64_TPRELLO 40 -+#define R_SW_64_TPREL16 41 -+/* Keep this the last entry. */ -+#define R_SW_64_NUM 46 -+/* Legal values for sh_flags field of Elf64_Shdr. */ -+#define SHF_SW_64_GPREL 0x10000000 -+ - typedef struct elf32_rel { - Elf32_Addr r_offset; - Elf32_Word r_info; -diff --git a/include/hw/sw64/sw64_iommu.h b/include/hw/sw64/sw64_iommu.h -new file mode 100644 -index 0000000000..7191876083 ---- /dev/null -+++ b/include/hw/sw64/sw64_iommu.h -@@ -0,0 +1,105 @@ -+/* -+ * Copyright (C) 2021-2025 Wuxi Institute of Advanced Technology -+ * Written by Lu Feifei -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, see . -+ */ -+ -+#ifndef HW_SW64_IOMMU_H -+#define HW_SW64_IOMMU_H -+ -+#include "hw/sysbus.h" -+#include "hw/pci/pci.h" -+ -+#define TYPE_SW64_IOMMU_MEMORY_REGION "sw64-iommu-memory-region" -+#define SW_IOMMU_ENTRY_VALID ((1UL) << 63) -+#define SW_IOMMU_LEVEL1_OFFSET 0x1ff -+#define SW_IOMMU_LEVEL2_OFFSET 0x3ff -+#define SW_IOMMU_ENABLE 3 -+#define SW_IOMMU_GRN ((0UL) << 4) -+#define SWVT_PCI_BUS_MAX 256 -+ -+typedef struct SW64IOMMUClass SW64IOMMUClass; -+typedef struct SW64IOMMUState SW64IOMMUState; -+typedef struct SWVTAddressSpace SWVTAddressSpace; -+typedef struct SW64DTIOTLBKey SW64DTIOTLBKey; -+typedef struct SW64PTIOTLBKey SW64PTIOTLBKey; -+typedef struct SW64DTIOTLBEntry SW64DTIOTLBEntry; -+typedef struct SWVTBus SWVTBus; -+ -+struct SW64DTIOTLBEntry { -+ uint16_t source_id; -+ unsigned long ptbase_addr; -+}; -+ -+struct SW64DTIOTLBKey { -+ uint16_t source_id; -+}; -+ -+struct SW64PTIOTLBKey { -+ uint16_t source_id; -+ dma_addr_t iova; -+}; -+ -+struct SWVTAddressSpace { -+ PCIBus *bus; -+ uint8_t devfn; -+ AddressSpace as; -+ IOMMUMemoryRegion iommu; -+ MemoryRegion root; -+ MemoryRegion msi; /* Interrupt region: 0xfeeXXXXX */ -+ SW64IOMMUState *iommu_state; -+ QLIST_ENTRY(SWVTAddressSpace) next; -+ /* Superset of notifier flags that this address space has */ -+ IOMMUNotifierFlag notifier_flags; -+}; -+ -+struct SWVTBus { -+ PCIBus* bus; /* A reference to the bus to provide translation for */ -+ SWVTAddressSpace *dev_as[0]; /* A table of SWVTAddressSpace objects indexed by devfn */ -+}; -+ -+struct SW64IOMMUState { -+ SysBusDevice busdev; -+ dma_addr_t dtbr; /* Current root table pointer */ -+ GHashTable *dtiotlb; /* IOTLB for device table */ -+ GHashTable *ptiotlb; /* IOTLB for page table */ -+ -+ GHashTable *swvtbus_as_by_busptr; -+ /* list of registered notifiers */ -+ QLIST_HEAD(, SWVTAddressSpace) swvt_as_with_notifiers; -+ -+ PCIBus *pci_bus; -+ QemuMutex iommu_lock; -+}; -+ -+struct SW64IOMMUClass { -+ SysBusDeviceClass parent; -+ DeviceRealize realize; -+}; -+ -+#define TYPE_SW64_IOMMU "sw64-iommu" -+#define SW64_IOMMU(obj) \ -+ OBJECT_CHECK(SW64IOMMUState, (obj), TYPE_SW64_IOMMU) -+#define SW64_IOMMU_CLASS(klass) \ -+ OBJECT_CLASS_CHECK(SW64IOMMUClass, (klass), TYPE_SW64_IOMMU) -+#define SW64_IOMMU_GET_CLASS(obj) \ -+ OBJECT_GET_CLASS(SW64IOMMUClass, (obj), TYPE_SW64_IOMMU) -+extern void sw64_vt_iommu_init(PCIBus *b); -+extern void swvt_address_space_invalidate_iova(SW64IOMMUState *s, unsigned long val); -+extern void swvt_address_space_unmap_iova(SW64IOMMUState *s, unsigned long val); -+extern void swvt_address_space_map_iova(SW64IOMMUState *s, unsigned long val); -+extern SWVTAddressSpace *iommu_find_add_as(SW64IOMMUState *s, PCIBus *bus, int devfn); -+extern MemTxResult msi_write(void *opaque, hwaddr addr, uint64_t value, unsigned size, -+ MemTxAttrs attrs); -+#endif -diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h -index 112a29910b..6141122308 100644 ---- a/include/qemu/atomic.h -+++ b/include/qemu/atomic.h -@@ -85,6 +85,8 @@ - #define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); }) - #elif defined(__alpha__) - #define smp_read_barrier_depends() asm volatile("mb":::"memory") -+#elif defined(__sw_64__) -+#define smp_read_barrier_depends() asm volatile("memb":::"memory") - #else - #define smp_read_barrier_depends() barrier() - #endif -diff --git a/include/qemu/timer.h b/include/qemu/timer.h -index d263fad9a4..e6d442abee 100644 ---- a/include/qemu/timer.h -+++ b/include/qemu/timer.h -@@ -1007,6 +1007,16 @@ static inline int64_t cpu_get_host_ticks(void) - return cur - ofs; - } - -+#elif defined(__sw_64__) -+ -+static inline int64_t cpu_get_host_ticks(void) -+{ -+ uint64_t cc; -+ -+ asm volatile("rtc %0" : "=r"(cc)); -+ return cc; -+} -+ - #else - /* The host CPU doesn't have an easily accessible cycle counter. - Just return a monotonically increasing value. This will be -diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h -index 70c579560a..1cf27baa7c 100644 ---- a/include/sysemu/arch_init.h -+++ b/include/sysemu/arch_init.h -@@ -24,6 +24,7 @@ enum { - QEMU_ARCH_RX = (1 << 20), - QEMU_ARCH_AVR = (1 << 21), - QEMU_ARCH_HEXAGON = (1 << 22), -+ QEMU_ARCH_SW64 = (1 << 23), - }; - - extern const uint32_t arch_type; -diff --git a/linux-headers/asm-sw64/kvm.h b/linux-headers/asm-sw64/kvm.h -new file mode 100644 -index 0000000000..b0ce2ca346 ---- /dev/null -+++ b/linux-headers/asm-sw64/kvm.h -@@ -0,0 +1,122 @@ -+#ifndef __LINUX_KVM_SW64_H -+#define __LINUX_KVM_SW64_H -+ -+#include -+/* -+ * for KVM_GET_REGS and KVM_SET_REGS -+ */ -+struct kvm_regs { -+ unsigned long r0; -+ unsigned long r1; -+ unsigned long r2; -+ unsigned long r3; -+ -+ unsigned long r4; -+ unsigned long r5; -+ unsigned long r6; -+ unsigned long r7; -+ -+ unsigned long r8; -+ unsigned long r9; -+ unsigned long r10; -+ unsigned long r11; -+ -+ unsigned long r12; -+ unsigned long r13; -+ unsigned long r14; -+ unsigned long r15; -+ -+ unsigned long r19; -+ unsigned long r20; -+ unsigned long r21; -+ unsigned long r22; -+ -+ unsigned long r23; -+ unsigned long r24; -+ unsigned long r25; -+ unsigned long r26; -+ -+ unsigned long r27; -+ unsigned long r28; -+ unsigned long __padding0; -+ unsigned long fpcr; -+ -+ unsigned long fp[124]; -+ /* These are saved by hmcode: */ -+ unsigned long ps; -+ unsigned long pc; -+ unsigned long gp; -+ unsigned long r16; -+ unsigned long r17; -+ unsigned long r18; -+}; -+ -+struct vcpucb { -+ unsigned long go_flag; -+ unsigned long pcbb; -+ unsigned long ksp; -+ unsigned long usp; -+ unsigned long kgp; -+ unsigned long ent_arith; -+ unsigned long ent_if; -+ unsigned long ent_int; -+ unsigned long ent_mm; -+ unsigned long ent_sys; -+ unsigned long ent_una; -+ unsigned long stack_pc; -+ unsigned long new_a0; -+ unsigned long new_a1; -+ unsigned long new_a2; -+ unsigned long whami; -+ unsigned long csr_save; -+ unsigned long wakeup_magic; -+ unsigned long host_vcpucb; -+ unsigned long upcr; -+ unsigned long vpcr; -+ unsigned long dtb_pcr; -+ unsigned long guest_ksp; -+ unsigned long guest_usp; -+ unsigned long vcpu_irq_disabled; -+ unsigned long vcpu_irq; -+ unsigned long ptbr; -+ unsigned long int_stat0; -+ unsigned long int_stat1; -+ unsigned long int_stat2; -+ unsigned long int_stat3; -+ unsigned long reset_entry; -+ unsigned long pvcpu; -+ unsigned long exit_reason; -+ unsigned long ipaddr; -+ unsigned long vcpu_irq_vector; -+}; -+ -+/* -+ * for KVM_GET_FPU and KVM_SET_FPU -+ */ -+struct kvm_fpu { -+}; -+ -+/* -+ * KVM SW_64 specific structures and definitions -+ */ -+struct kvm_debug_exit_arch { -+}; -+ -+/* for KVM_SET_GUEST_DEBUG */ -+struct kvm_guest_debug_arch { -+}; -+ -+/* definition of registers in kvm_run */ -+struct kvm_sync_regs { -+}; -+ -+/* dummy definition */ -+struct kvm_sregs { -+}; -+ -+#define KVM_SW64_VCPU_INIT _IO(KVMIO, 0xba) -+#define KVM_SW64_USE_SLAVE _IO(KVMIO, 0xbb) -+#define KVM_SW64_GET_VCB _IO(KVMIO, 0xbc) -+#define KVM_SW64_SET_VCB _IO(KVMIO, 0xbd) -+ -+#endif /* __LINUX_KVM_SW64_H */ -diff --git a/linux-headers/asm-sw64/unistd.h b/linux-headers/asm-sw64/unistd.h -new file mode 100644 -index 0000000000..affe297e73 ---- /dev/null -+++ b/linux-headers/asm-sw64/unistd.h -@@ -0,0 +1,380 @@ -+#ifndef _UAPI_ASM_SW64_UNISTD_64_H -+#define _UAPI_ASM_SW64_UNISTD_64_H -+ -+#define __NR_exit 1 -+#define __NR_fork 2 -+#define __NR_read 3 -+#define __NR_write 4 -+#define __NR_close 6 -+#define __NR_osf_wait4 7 -+#define __NR_link 9 -+#define __NR_unlink 10 -+#define __NR_chdir 12 -+#define __NR_fchdir 13 -+#define __NR_mknod 14 -+#define __NR_chmod 15 -+#define __NR_chown 16 -+#define __NR_brk 17 -+#define __NR_lseek 19 -+#define __NR_getxpid 20 -+#define __NR_osf_mount 21 -+#define __NR_umount2 22 -+#define __NR_setuid 23 -+#define __NR_getxuid 24 -+#define __NR_ptrace 26 -+#define __NR_access 33 -+#define __NR_sync 36 -+#define __NR_kill 37 -+#define __NR_setpgid 39 -+#define __NR_dup 41 -+#define __NR_pipe 42 -+#define __NR_osf_set_program_attributes 43 -+#define __NR_open 45 -+#define __NR_getxgid 47 -+#define __NR_osf_sigprocmask 48 -+#define __NR_acct 51 -+#define __NR_sigpending 52 -+#define __NR_ioctl 54 -+#define __NR_symlink 57 -+#define __NR_readlink 58 -+#define __NR_execve 59 -+#define __NR_umask 60 -+#define __NR_chroot 61 -+#define __NR_getpgrp 63 -+#define __NR_getpagesize 64 -+#define __NR_vfork 66 -+#define __NR_stat 67 -+#define __NR_lstat 68 -+#define __NR_mmap 71 -+#define __NR_munmap 73 -+#define __NR_mprotect 74 -+#define __NR_madvise 75 -+#define __NR_vhangup 76 -+#define __NR_getgroups 79 -+#define __NR_setgroups 80 -+#define __NR_setpgrp 82 -+#define __NR_osf_setitimer 83 -+#define __NR_osf_getitimer 86 -+#define __NR_gethostname 87 -+#define __NR_sethostname 88 -+#define __NR_getdtablesize 89 -+#define __NR_dup2 90 -+#define __NR_fstat 91 -+#define __NR_fcntl 92 -+#define __NR_osf_select 93 -+#define __NR_poll 94 -+#define __NR_fsync 95 -+#define __NR_setpriority 96 -+#define __NR_socket 97 -+#define __NR_connect 98 -+#define __NR_accept 99 -+#define __NR_getpriority 100 -+#define __NR_send 101 -+#define __NR_recv 102 -+#define __NR_sigreturn 103 -+#define __NR_bind 104 -+#define __NR_setsockopt 105 -+#define __NR_listen 106 -+#define __NR_sigsuspend 111 -+#define __NR_osf_sigstack 112 -+#define __NR_recvmsg 113 -+#define __NR_sendmsg 114 -+#define __NR_osf_gettimeofday 116 -+#define __NR_osf_getrusage 117 -+#define __NR_getsockopt 118 -+#define __NR_socketcall 119 -+#define __NR_readv 120 -+#define __NR_writev 121 -+#define __NR_osf_settimeofday 122 -+#define __NR_fchown 123 -+#define __NR_fchmod 124 -+#define __NR_recvfrom 125 -+#define __NR_setreuid 126 -+#define __NR_setregid 127 -+#define __NR_rename 128 -+#define __NR_truncate 129 -+#define __NR_ftruncate 130 -+#define __NR_flock 131 -+#define __NR_setgid 132 -+#define __NR_sendto 133 -+#define __NR_shutdown 134 -+#define __NR_socketpair 135 -+#define __NR_mkdir 136 -+#define __NR_rmdir 137 -+#define __NR_osf_utimes 138 -+#define __NR_getpeername 141 -+#define __NR_getrlimit 144 -+#define __NR_setrlimit 145 -+#define __NR_setsid 147 -+#define __NR_quotactl 148 -+#define __NR_getsockname 150 -+#define __NR_sigaction 156 -+#define __NR_osf_getdirentries 159 -+#define __NR_osf_statfs 160 -+#define __NR_osf_fstatfs 161 -+#define __NR_osf_getdomainname 165 -+#define __NR_setdomainname 166 -+#define __NR_bpf 170 -+#define __NR_userfaultfd 171 -+#define __NR_membarrier 172 -+#define __NR_mlock2 173 -+#define __NR_getpid 174 -+#define __NR_getppid 175 -+#define __NR_getuid 176 -+#define __NR_geteuid 177 -+#define __NR_getgid 178 -+#define __NR_getegid 179 -+#define __NR_osf_swapon 199 -+#define __NR_msgctl 200 -+#define __NR_msgget 201 -+#define __NR_msgrcv 202 -+#define __NR_msgsnd 203 -+#define __NR_semctl 204 -+#define __NR_semget 205 -+#define __NR_semop 206 -+#define __NR_osf_utsname 207 -+#define __NR_lchown 208 -+#define __NR_shmat 209 -+#define __NR_shmctl 210 -+#define __NR_shmdt 211 -+#define __NR_shmget 212 -+#define __NR_msync 217 -+#define __NR_osf_stat 224 -+#define __NR_osf_lstat 225 -+#define __NR_osf_fstat 226 -+#define __NR_osf_statfs64 227 -+#define __NR_osf_fstatfs64 228 -+#define __NR_statfs64 229 -+#define __NR_fstatfs64 230 -+#define __NR_getpgid 233 -+#define __NR_getsid 234 -+#define __NR_sigaltstack 235 -+#define __NR_osf_sysinfo 241 -+#define __NR_osf_proplist_syscall 244 -+#define __NR_osf_usleep_thread 251 -+#define __NR_sysfs 254 -+#define __NR_osf_getsysinfo 256 -+#define __NR_osf_setsysinfo 257 -+#define __NR_bdflush 300 -+#define __NR_sethae 301 -+#define __NR_mount 302 -+#define __NR_old_adjtimex 303 -+#define __NR_swapoff 304 -+#define __NR_getdents 305 -+#define __NR_create_module 306 -+#define __NR_init_module 307 -+#define __NR_delete_module 308 -+#define __NR_get_kernel_syms 309 -+#define __NR_syslog 310 -+#define __NR_reboot 311 -+#define __NR_clone 312 -+#define __NR_uselib 313 -+#define __NR_mlock 314 -+#define __NR_munlock 315 -+#define __NR_mlockall 316 -+#define __NR_munlockall 317 -+#define __NR_sysinfo 318 -+#define __NR__sysctl 319 -+#define __NR_oldumount 321 -+#define __NR_swapon 322 -+#define __NR_times 323 -+#define __NR_personality 324 -+#define __NR_setfsuid 325 -+#define __NR_setfsgid 326 -+#define __NR_ustat 327 -+#define __NR_statfs 328 -+#define __NR_fstatfs 329 -+#define __NR_sched_setparam 330 -+#define __NR_sched_getparam 331 -+#define __NR_sched_setscheduler 332 -+#define __NR_sched_getscheduler 333 -+#define __NR_sched_yield 334 -+#define __NR_sched_get_priority_max 335 -+#define __NR_sched_get_priority_min 336 -+#define __NR_sched_rr_get_interval 337 -+#define __NR_afs_syscall 338 -+#define __NR_uname 339 -+#define __NR_nanosleep 340 -+#define __NR_mremap 341 -+#define __NR_nfsservctl 342 -+#define __NR_setresuid 343 -+#define __NR_getresuid 344 -+#define __NR_pciconfig_read 345 -+#define __NR_pciconfig_write 346 -+#define __NR_query_module 347 -+#define __NR_prctl 348 -+#define __NR_pread64 349 -+#define __NR_pwrite64 350 -+#define __NR_rt_sigreturn 351 -+#define __NR_rt_sigaction 352 -+#define __NR_rt_sigprocmask 353 -+#define __NR_rt_sigpending 354 -+#define __NR_rt_sigtimedwait 355 -+#define __NR_rt_sigqueueinfo 356 -+#define __NR_rt_sigsuspend 357 -+#define __NR_select 358 -+#define __NR_gettimeofday 359 -+#define __NR_settimeofday 360 -+#define __NR_getitimer 361 -+#define __NR_setitimer 362 -+#define __NR_utimes 363 -+#define __NR_getrusage 364 -+#define __NR_wait4 365 -+#define __NR_adjtimex 366 -+#define __NR_getcwd 367 -+#define __NR_capget 368 -+#define __NR_capset 369 -+#define __NR_sendfile 370 -+#define __NR_setresgid 371 -+#define __NR_getresgid 372 -+#define __NR_dipc 373 -+#define __NR_pivot_root 374 -+#define __NR_mincore 375 -+#define __NR_pciconfig_iobase 376 -+#define __NR_getdents64 377 -+#define __NR_gettid 378 -+#define __NR_readahead 379 -+#define __NR_tkill 381 -+#define __NR_setxattr 382 -+#define __NR_lsetxattr 383 -+#define __NR_fsetxattr 384 -+#define __NR_getxattr 385 -+#define __NR_lgetxattr 386 -+#define __NR_fgetxattr 387 -+#define __NR_listxattr 388 -+#define __NR_llistxattr 389 -+#define __NR_flistxattr 390 -+#define __NR_removexattr 391 -+#define __NR_lremovexattr 392 -+#define __NR_fremovexattr 393 -+#define __NR_futex 394 -+#define __NR_sched_setaffinity 395 -+#define __NR_sched_getaffinity 396 -+#define __NR_tuxcall 397 -+#define __NR_io_setup 398 -+#define __NR_io_destroy 399 -+#define __NR_io_getevents 400 -+#define __NR_io_submit 401 -+#define __NR_io_cancel 402 -+#define __NR_io_pgetevents 403 -+#define __NR_rseq 404 -+#define __NR_exit_group 405 -+#define __NR_lookup_dcookie 406 -+#define __NR_epoll_create 407 -+#define __NR_epoll_ctl 408 -+#define __NR_epoll_wait 409 -+#define __NR_remap_file_pages 410 -+#define __NR_set_tid_address 411 -+#define __NR_restart_syscall 412 -+#define __NR_fadvise64 413 -+#define __NR_timer_create 414 -+#define __NR_timer_settime 415 -+#define __NR_timer_gettime 416 -+#define __NR_timer_getoverrun 417 -+#define __NR_timer_delete 418 -+#define __NR_clock_settime 419 -+#define __NR_clock_gettime 420 -+#define __NR_clock_getres 421 -+#define __NR_clock_nanosleep 422 -+#define __NR_semtimedop 423 -+#define __NR_tgkill 424 -+#define __NR_stat64 425 -+#define __NR_lstat64 426 -+#define __NR_fstat64 427 -+#define __NR_vserver 428 -+#define __NR_mbind 429 -+#define __NR_get_mempolicy 430 -+#define __NR_set_mempolicy 431 -+#define __NR_mq_open 432 -+#define __NR_mq_unlink 433 -+#define __NR_mq_timedsend 434 -+#define __NR_mq_timedreceive 435 -+#define __NR_mq_notify 436 -+#define __NR_mq_getsetattr 437 -+#define __NR_waitid 438 -+#define __NR_add_key 439 -+#define __NR_request_key 440 -+#define __NR_keyctl 441 -+#define __NR_ioprio_set 442 -+#define __NR_ioprio_get 443 -+#define __NR_inotify_init 444 -+#define __NR_inotify_add_watch 445 -+#define __NR_inotify_rm_watch 446 -+#define __NR_fdatasync 447 -+#define __NR_kexec_load 448 -+#define __NR_migrate_pages 449 -+#define __NR_openat 450 -+#define __NR_mkdirat 451 -+#define __NR_mknodat 452 -+#define __NR_fchownat 453 -+#define __NR_futimesat 454 -+#define __NR_fstatat64 455 -+#define __NR_unlinkat 456 -+#define __NR_renameat 457 -+#define __NR_linkat 458 -+#define __NR_symlinkat 459 -+#define __NR_readlinkat 460 -+#define __NR_fchmodat 461 -+#define __NR_faccessat 462 -+#define __NR_pselect6 463 -+#define __NR_ppoll 464 -+#define __NR_unshare 465 -+#define __NR_set_robust_list 466 -+#define __NR_get_robust_list 467 -+#define __NR_splice 468 -+#define __NR_sync_file_range 469 -+#define __NR_tee 470 -+#define __NR_vmsplice 471 -+#define __NR_move_pages 472 -+#define __NR_getcpu 473 -+#define __NR_epoll_pwait 474 -+#define __NR_utimensat 475 -+#define __NR_signalfd 476 -+#define __NR_timerfd 477 -+#define __NR_eventfd 478 -+#define __NR_recvmmsg 479 -+#define __NR_fallocate 480 -+#define __NR_timerfd_create 481 -+#define __NR_timerfd_settime 482 -+#define __NR_timerfd_gettime 483 -+#define __NR_signalfd4 484 -+#define __NR_eventfd2 485 -+#define __NR_epoll_create1 486 -+#define __NR_dup3 487 -+#define __NR_pipe2 488 -+#define __NR_inotify_init1 489 -+#define __NR_preadv 490 -+#define __NR_pwritev 491 -+#define __NR_rt_tgsigqueueinfo 492 -+#define __NR_perf_event_open 493 -+#define __NR_fanotify_init 494 -+#define __NR_fanotify_mark 495 -+#define __NR_prlimit64 496 -+#define __NR_name_to_handle_at 497 -+#define __NR_open_by_handle_at 498 -+#define __NR_clock_adjtime 499 -+#define __NR_syncfs 500 -+#define __NR_setns 501 -+#define __NR_accept4 502 -+#define __NR_sendmmsg 503 -+#define __NR_process_vm_readv 504 -+#define __NR_process_vm_writev 505 -+#define __NR_kcmp 506 -+#define __NR_finit_module 507 -+#define __NR_sched_setattr 508 -+#define __NR_sched_getattr 509 -+#define __NR_renameat2 510 -+#define __NR_getrandom 511 -+#define __NR_memfd_create 512 -+#define __NR_execveat 513 -+#define __NR_seccomp 514 -+#define __NR_copy_file_range 515 -+#define __NR_preadv2 516 -+#define __NR_pwritev2 517 -+#define __NR_statx 518 -+ -+#ifdef __KERNEL__ -+#define __NR_syscalls 519 -+#endif -+ -+#endif /* _UAPI_ASM_SW64_UNISTD_64_H */ -diff --git a/linux-user/meson.build b/linux-user/meson.build -index bf62c13e37..4f4196ed13 100644 ---- a/linux-user/meson.build -+++ b/linux-user/meson.build -@@ -37,5 +37,6 @@ subdir('ppc') - subdir('s390x') - subdir('sh4') - subdir('sparc') -+subdir('sw64') - subdir('x86_64') - subdir('xtensa') -diff --git a/linux-user/sw64/cpu_loop.c b/linux-user/sw64/cpu_loop.c -new file mode 100644 -index 0000000000..3f2fde0fba ---- /dev/null -+++ b/linux-user/sw64/cpu_loop.c -@@ -0,0 +1,108 @@ -+/* -+ * qemu user cpu loop -+ * -+ * Copyright (c) 2003-2008 Fabrice Bellard -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see . -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu.h" -+#include "cpu_loop-common.h" -+ -+void cpu_loop(CPUSW64State *env) -+{ -+ CPUState *cs = CPU(sw64_env_get_cpu(env)); -+ int trapnr; -+ target_siginfo_t info; -+ abi_long sysret; -+ -+ while (1) { -+ cpu_exec_start(cs); -+ trapnr = cpu_exec(cs); -+ cpu_exec_end(cs); -+ process_queued_cpu_work(cs); -+ -+ switch (trapnr) { -+ case EXCP_OPCDEC: -+ cpu_abort(cs, "ILLEGAL SW64 insn at line %d!", __LINE__); -+ case EXCP_CALL_SYS: -+ switch (env->error_code) { -+ case 0x83: -+ /* CALLSYS */ -+ trapnr = env->ir[IDX_V0]; -+ sysret = do_syscall(env, trapnr, -+ env->ir[IDX_A0], env->ir[IDX_A1], -+ env->ir[IDX_A2], env->ir[IDX_A3], -+ env->ir[IDX_A4], env->ir[IDX_A5], -+ 0, 0); -+ if (sysret == -TARGET_ERESTARTSYS) { -+ env->pc -= 4; -+ break; -+ } -+ if (sysret == -TARGET_QEMU_ESIGRETURN) { -+ break; -+ } -+ /* Syscall writes 0 to V0 to bypass error check, similar -+ to how this is handled internal to Linux kernel. -+ (Ab)use trapnr temporarily as boolean indicating error. */ -+ trapnr = (env->ir[IDX_V0] != 0 && sysret < 0); -+ env->ir[IDX_V0] = (trapnr ? -sysret : sysret); -+ env->ir[IDX_A3] = trapnr; -+ break; -+ default: -+ printf("UNDO sys_call %lx\n", env->error_code); -+ exit(-1); -+ } -+ break; -+ case EXCP_MMFAULT: -+ info.si_signo = TARGET_SIGSEGV; -+ info.si_errno = 0; -+ info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID -+ ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR); -+ info._sifields._sigfault._addr = env->trap_arg0; -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_ARITH: -+ info.si_signo = TARGET_SIGFPE; -+ info.si_errno = 0; -+ info.si_code = TARGET_FPE_FLTINV; -+ info._sifields._sigfault._addr = env->pc; -+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); -+ break; -+ case EXCP_INTERRUPT: -+ /* just indicate that signals should be handled asap */ -+ break; -+ default: -+ cpu_abort(cs, "UNDO"); -+ } -+ process_pending_signals (env); -+ -+ /* Most of the traps imply a transition through HMcode, which -+ implies an REI instruction has been executed. Which means -+ that RX and LOCK_ADDR should be cleared. But there are a -+ few exceptions for traps internal to QEMU. */ -+ } -+} -+ -+void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) -+{ -+ int i; -+ -+ for(i = 0; i < 28; i++) { -+ env->ir[i] = ((abi_ulong *)regs)[i]; -+ } -+ env->ir[IDX_SP] = regs->usp; -+ env->pc = regs->pc; -+} -diff --git a/linux-user/sw64/signal.c b/linux-user/sw64/signal.c -new file mode 100644 -index 0000000000..5822e808d3 ---- /dev/null -+++ b/linux-user/sw64/signal.c -@@ -0,0 +1,273 @@ -+/* -+ * Emulation of Linux signals -+ * -+ * Copyright (c) 2003 Fabrice Bellard -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see . -+ */ -+#include "qemu/osdep.h" -+#include "qemu.h" -+#include "signal-common.h" -+#include "linux-user/trace.h" -+ -+struct target_sigcontext { -+ abi_long sc_onstack; -+ abi_long sc_mask; -+ abi_long sc_pc; -+ abi_long sc_ps; -+ abi_long sc_regs[32]; -+ abi_long sc_ownedfp; -+ abi_long sc_fpregs[32]; -+ abi_ulong sc_fpcr; -+ abi_ulong sc_fp_control; -+ abi_ulong sc_reserved1; -+ abi_ulong sc_reserved2; -+ abi_ulong sc_ssize; -+ abi_ulong sc_sbase; -+ abi_ulong sc_traparg_a0; -+ abi_ulong sc_traparg_a1; -+ abi_ulong sc_traparg_a2; -+ abi_ulong sc_fp_trap_pc; -+ abi_ulong sc_fp_trigger_sum; -+ abi_ulong sc_fp_trigger_inst; -+}; -+ -+struct target_ucontext { -+ abi_ulong tuc_flags; -+ abi_ulong tuc_link; -+ abi_ulong tuc_osf_sigmask; -+ target_stack_t tuc_stack; -+ struct target_sigcontext tuc_mcontext; -+ target_sigset_t tuc_sigmask; -+}; -+ -+struct target_sigframe { -+ struct target_sigcontext sc; -+ unsigned int retcode[3]; -+}; -+ -+struct target_rt_sigframe { -+ target_siginfo_t info; -+ struct target_ucontext uc; -+ unsigned int retcode[3]; -+}; -+ -+#define INSN_MOV_R30_R16 0x47fe0410 -+#define INSN_LDI_R0 0x201f0000 -+#define INSN_CALLSYS 0x00000083 -+ -+static void setup_sigcontext(struct target_sigcontext *sc, CPUSW64State *env, -+ abi_ulong frame_addr, target_sigset_t *set) -+{ -+ int i; -+ -+ __put_user(on_sig_stack(frame_addr), &sc->sc_onstack); -+ __put_user(set->sig[0], &sc->sc_mask); -+ __put_user(env->pc, &sc->sc_pc); -+ __put_user(8, &sc->sc_ps); -+ -+ for (i = 0; i < 31; ++i) { -+ __put_user(env->ir[i], &sc->sc_regs[i]); -+ } -+ __put_user(0, &sc->sc_regs[31]); -+ -+ for (i = 0; i < 31; ++i) { -+ __put_user(env->fr[i], &sc->sc_fpregs[i]); -+ } -+ __put_user(0, &sc->sc_fpregs[31]); -+ __put_user(cpu_sw64_load_fpcr(env), &sc->sc_fpcr); -+ -+ __put_user(0, &sc->sc_traparg_a0); /* FIXME */ -+ __put_user(0, &sc->sc_traparg_a1); /* FIXME */ -+ __put_user(0, &sc->sc_traparg_a2); /* FIXME */ -+} -+ -+static void restore_sigcontext(CPUSW64State *env, -+ struct target_sigcontext *sc) -+{ -+ uint64_t fpcr; -+ int i; -+ -+ __get_user(env->pc, &sc->sc_pc); -+ -+ for (i = 0; i < 31; ++i) { -+ __get_user(env->ir[i], &sc->sc_regs[i]); -+ } -+ for (i = 0; i < 31; ++i) { -+ __get_user(env->fr[i], &sc->sc_fpregs[i]); -+ } -+ -+ __get_user(fpcr, &sc->sc_fpcr); -+ cpu_sw64_store_fpcr(env, fpcr); -+} -+ -+static inline abi_ulong get_sigframe(struct target_sigaction *sa, -+ CPUSW64State *env, -+ unsigned long framesize) -+{ -+ abi_ulong sp; -+ -+ sp = target_sigsp(get_sp_from_cpustate(env), sa); -+ -+ return (sp - framesize) & -32; -+} -+ -+void setup_frame(int sig, struct target_sigaction *ka, -+ target_sigset_t *set, CPUSW64State *env) -+{ -+ abi_ulong frame_addr, r26; -+ struct target_sigframe *frame; -+ int err = 0; -+ -+ frame_addr = get_sigframe(ka, env, sizeof(*frame)); -+ trace_user_setup_frame(env, frame_addr); -+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { -+ goto give_sigsegv; -+ } -+ -+ setup_sigcontext(&frame->sc, env, frame_addr, set); -+ -+ if (ka->sa_restorer) { -+ r26 = ka->sa_restorer; -+ } else { -+ __put_user(INSN_MOV_R30_R16, &frame->retcode[0]); -+ __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn, -+ &frame->retcode[1]); -+ __put_user(INSN_CALLSYS, &frame->retcode[2]); -+ /* imb() */ -+ r26 = frame_addr + offsetof(struct target_sigframe, retcode); -+ } -+ -+ unlock_user_struct(frame, frame_addr, 1); -+ -+ if (err) { -+give_sigsegv: -+ force_sigsegv(sig); -+ return; -+ } -+ -+ env->ir[IDX_RA] = r26; -+ env->ir[IDX_PV] = env->pc = ka->_sa_handler; -+ env->ir[IDX_A0] = sig; -+ env->ir[IDX_A1] = 0; -+ env->ir[IDX_A2] = frame_addr + offsetof(struct target_sigframe, sc); -+ env->ir[IDX_SP] = frame_addr; -+} -+ -+void setup_rt_frame(int sig, struct target_sigaction *ka, -+ target_siginfo_t *info, -+ target_sigset_t *set, CPUSW64State *env) -+{ -+ abi_ulong frame_addr, r26; -+ struct target_rt_sigframe *frame; -+ int i, err = 0; -+ -+ 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(&frame->info, info); -+ -+ __put_user(0, &frame->uc.tuc_flags); -+ __put_user(0, &frame->uc.tuc_link); -+ __put_user(set->sig[0], &frame->uc.tuc_osf_sigmask); -+ -+ target_save_altstack(&frame->uc.tuc_stack, env); -+ -+ setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set); -+ for (i = 0; i < TARGET_NSIG_WORDS; ++i) { -+ __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); -+ } -+ -+ if (ka->sa_restorer) { -+ r26 = ka->sa_restorer; -+ } else { -+ __put_user(INSN_MOV_R30_R16, &frame->retcode[0]); -+ __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn, -+ &frame->retcode[1]); -+ __put_user(INSN_CALLSYS, &frame->retcode[2]); -+ r26 = frame_addr + offsetof(struct target_sigframe, retcode); -+ } -+ -+ if (err) { -+give_sigsegv: -+ force_sigsegv(sig); -+ return; -+ } -+ -+ env->ir[IDX_RA] = r26; -+ env->ir[IDX_PV] = env->pc = ka->_sa_handler; -+ env->ir[IDX_A0] = sig; -+ env->ir[IDX_A1] = frame_addr + offsetof(struct target_rt_sigframe, info); -+ env->ir[IDX_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc); -+ env->ir[IDX_SP] = frame_addr; -+} -+ -+long do_sigreturn(CPUSW64State *env) -+{ -+ struct target_sigcontext *sc; -+ abi_ulong sc_addr = env->ir[IDX_A0]; -+ target_sigset_t target_set; -+ sigset_t set; -+ -+ if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) { -+ goto badframe; -+ } -+ -+ target_sigemptyset(&target_set); -+ __get_user(target_set.sig[0], &sc->sc_mask); -+ -+ target_to_host_sigset_internal(&set, &target_set); -+ set_sigmask(&set); -+ -+ restore_sigcontext(env, sc); -+ unlock_user_struct(sc, sc_addr, 0); -+ return -TARGET_QEMU_ESIGRETURN; -+ -+badframe: -+ force_sig(TARGET_SIGSEGV); -+ return -TARGET_QEMU_ESIGRETURN; -+} -+ -+long do_rt_sigreturn(CPUSW64State *env) -+{ -+ abi_ulong frame_addr = env->ir[IDX_A0]; -+ struct target_rt_sigframe *frame; -+ sigset_t set; -+ -+ trace_user_do_rt_sigreturn(env, frame_addr); -+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { -+ goto badframe; -+ } -+ target_to_host_sigset(&set, &frame->uc.tuc_sigmask); -+ set_sigmask(&set); -+ -+ restore_sigcontext(env, &frame->uc.tuc_mcontext); -+ if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe, -+ uc.tuc_stack), -+ 0, env->ir[IDX_SP]) == -EFAULT) { -+ goto badframe; -+ } -+ -+ 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; -+} -diff --git a/linux-user/sw64/sockbits.h b/linux-user/sw64/sockbits.h -new file mode 100644 -index 0000000000..0e4c8f012d ---- /dev/null -+++ b/linux-user/sw64/sockbits.h -@@ -0,0 +1 @@ -+#include "../generic/sockbits.h" -diff --git a/linux-user/sw64/syscall_nr.h b/linux-user/sw64/syscall_nr.h -new file mode 100644 -index 0000000000..91737af322 ---- /dev/null -+++ b/linux-user/sw64/syscall_nr.h -@@ -0,0 +1,471 @@ -+/* -+ * This file contains the system call numbers. -+ */ -+#define TARGET_NR_osf_syscall 0 /* not implemented */ -+#define TARGET_NR_exit 1 -+#define TARGET_NR_fork 2 -+#define TARGET_NR_read 3 -+#define TARGET_NR_write 4 -+#define TARGET_NR_osf_old_open 5 /* not implemented */ -+#define TARGET_NR_close 6 -+#define TARGET_NR_osf_wait4 7 -+#define TARGET_NR_osf_old_creat 8 /* not implemented */ -+#define TARGET_NR_link 9 -+#define TARGET_NR_unlink 10 -+#define TARGET_NR_osf_execve 11 /* not implemented */ -+#define TARGET_NR_chdir 12 -+#define TARGET_NR_fchdir 13 -+#define TARGET_NR_mknod 14 -+#define TARGET_NR_chmod 15 -+#define TARGET_NR_chown 16 -+#define TARGET_NR_brk 17 -+#define TARGET_NR_osf_getfsstat 18 /* not implemented */ -+#define TARGET_NR_lseek 19 -+#define TARGET_NR_getxpid 20 -+#define TARGET_NR_osf_mount 21 -+#define TARGET_NR_umount 22 -+#define TARGET_NR_setuid 23 -+#define TARGET_NR_getxuid 24 -+#define TARGET_NR_exec_with_loader 25 /* not implemented */ -+#define TARGET_NR_ptrace 26 -+#define TARGET_NR_osf_nrecvmsg 27 /* not implemented */ -+#define TARGET_NR_osf_nsendmsg 28 /* not implemented */ -+#define TARGET_NR_osf_nrecvfrom 29 /* not implemented */ -+#define TARGET_NR_osf_naccept 30 /* not implemented */ -+#define TARGET_NR_osf_ngetpeername 31 /* not implemented */ -+#define TARGET_NR_osf_ngetsockname 32 /* not implemented */ -+#define TARGET_NR_access 33 -+#define TARGET_NR_osf_chflags 34 /* not implemented */ -+#define TARGET_NR_osf_fchflags 35 /* not implemented */ -+#define TARGET_NR_sync 36 -+#define TARGET_NR_kill 37 -+#define TARGET_NR_osf_old_stat 38 /* not implemented */ -+#define TARGET_NR_setpgid 39 -+#define TARGET_NR_osf_old_lstat 40 /* not implemented */ -+#define TARGET_NR_dup 41 -+#define TARGET_NR_pipe 42 -+#define TARGET_NR_osf_set_program_attributes 43 -+#define TARGET_NR_osf_profil 44 /* not implemented */ -+#define TARGET_NR_open 45 -+#define TARGET_NR_osf_old_sigaction 46 /* not implemented */ -+#define TARGET_NR_getxgid 47 -+#define TARGET_NR_osf_sigprocmask 48 -+#define TARGET_NR_osf_getlogin 49 /* not implemented */ -+#define TARGET_NR_osf_setlogin 50 /* not implemented */ -+#define TARGET_NR_acct 51 -+#define TARGET_NR_sigpending 52 -+ -+#define TARGET_NR_ioctl 54 -+#define TARGET_NR_osf_reboot 55 /* not implemented */ -+#define TARGET_NR_osf_revoke 56 /* not implemented */ -+#define TARGET_NR_symlink 57 -+#define TARGET_NR_readlink 58 -+#define TARGET_NR_execve 59 -+#define TARGET_NR_umask 60 -+#define TARGET_NR_chroot 61 -+#define TARGET_NR_osf_old_fstat 62 /* not implemented */ -+#define TARGET_NR_getpgrp 63 -+#define TARGET_NR_getpagesize 64 -+#define TARGET_NR_osf_mremap 65 /* not implemented */ -+#define TARGET_NR_vfork 66 -+#define TARGET_NR_stat 67 -+#define TARGET_NR_lstat 68 -+#define TARGET_NR_osf_sbrk 69 /* not implemented */ -+#define TARGET_NR_osf_sstk 70 /* not implemented */ -+#define TARGET_NR_mmap 71 /* OSF/1 mmap is superset of Linux */ -+#define TARGET_NR_osf_old_vadvise 72 /* not implemented */ -+#define TARGET_NR_munmap 73 -+#define TARGET_NR_mprotect 74 -+#define TARGET_NR_madvise 75 -+#define TARGET_NR_vhangup 76 -+#define TARGET_NR_osf_kmodcall 77 /* not implemented */ -+#define TARGET_NR_osf_mincore 78 /* not implemented */ -+#define TARGET_NR_getgroups 79 -+#define TARGET_NR_setgroups 80 -+#define TARGET_NR_osf_old_getpgrp 81 /* not implemented */ -+#define TARGET_NR_setpgrp 82 /* BSD alias for setpgid */ -+#define TARGET_NR_osf_setitimer 83 -+#define TARGET_NR_osf_old_wait 84 /* not implemented */ -+#define TARGET_NR_osf_table 85 /* not implemented */ -+#define TARGET_NR_osf_getitimer 86 -+#define TARGET_NR_gethostname 87 -+#define TARGET_NR_sethostname 88 -+#define TARGET_NR_getdtablesize 89 -+#define TARGET_NR_dup2 90 -+#define TARGET_NR_fstat 91 -+#define TARGET_NR_fcntl 92 -+#define TARGET_NR_osf_select 93 -+#define TARGET_NR_poll 94 -+#define TARGET_NR_fsync 95 -+#define TARGET_NR_setpriority 96 -+#define TARGET_NR_socket 97 -+#define TARGET_NR_connect 98 -+#define TARGET_NR_accept 99 -+#define TARGET_NR_getpriority 100 -+#define TARGET_NR_send 101 -+#define TARGET_NR_recv 102 -+#define TARGET_NR_sigreturn 103 -+#define TARGET_NR_bind 104 -+#define TARGET_NR_setsockopt 105 -+#define TARGET_NR_listen 106 -+#define TARGET_NR_osf_plock 107 /* not implemented */ -+#define TARGET_NR_osf_old_sigvec 108 /* not implemented */ -+#define TARGET_NR_osf_old_sigblock 109 /* not implemented */ -+#define TARGET_NR_osf_old_sigsetmask 110 /* not implemented */ -+#define TARGET_NR_sigsuspend 111 -+#define TARGET_NR_osf_sigstack 112 -+#define TARGET_NR_recvmsg 113 -+#define TARGET_NR_sendmsg 114 -+#define TARGET_NR_osf_old_vtrace 115 /* not implemented */ -+#define TARGET_NR_osf_gettimeofday 116 -+#define TARGET_NR_osf_getrusage 117 -+#define TARGET_NR_getsockopt 118 -+ -+#define TARGET_NR_readv 120 -+#define TARGET_NR_writev 121 -+#define TARGET_NR_osf_settimeofday 122 -+#define TARGET_NR_fchown 123 -+#define TARGET_NR_fchmod 124 -+#define TARGET_NR_recvfrom 125 -+#define TARGET_NR_setreuid 126 -+#define TARGET_NR_setregid 127 -+#define TARGET_NR_rename 128 -+#define TARGET_NR_truncate 129 -+#define TARGET_NR_ftruncate 130 -+#define TARGET_NR_flock 131 -+#define TARGET_NR_setgid 132 -+#define TARGET_NR_sendto 133 -+#define TARGET_NR_shutdown 134 -+#define TARGET_NR_socketpair 135 -+#define TARGET_NR_mkdir 136 -+#define TARGET_NR_rmdir 137 -+#define TARGET_NR_osf_utimes 138 -+#define TARGET_NR_osf_old_sigreturn 139 /* not implemented */ -+#define TARGET_NR_osf_adjtime 140 /* not implemented */ -+#define TARGET_NR_getpeername 141 -+#define TARGET_NR_osf_gethostid 142 /* not implemented */ -+#define TARGET_NR_osf_sethostid 143 /* not implemented */ -+#define TARGET_NR_getrlimit 144 -+#define TARGET_NR_setrlimit 145 -+#define TARGET_NR_osf_old_killpg 146 /* not implemented */ -+#define TARGET_NR_setsid 147 -+#define TARGET_NR_quotactl 148 -+#define TARGET_NR_osf_oldquota 149 /* not implemented */ -+#define TARGET_NR_getsockname 150 -+ -+#define TARGET_NR_osf_pid_block 153 /* not implemented */ -+#define TARGET_NR_osf_pid_unblock 154 /* not implemented */ -+ -+#define TARGET_NR_sigaction 156 -+#define TARGET_NR_osf_sigwaitprim 157 /* not implemented */ -+#define TARGET_NR_osf_nfssvc 158 /* not implemented */ -+#define TARGET_NR_osf_getdirentries 159 -+#define TARGET_NR_osf_statfs 160 -+#define TARGET_NR_osf_fstatfs 161 -+ -+#define TARGET_NR_osf_asynch_daemon 163 /* not implemented */ -+#define TARGET_NR_osf_getfh 164 /* not implemented */ -+#define TARGET_NR_osf_getdomainname 165 -+#define TARGET_NR_setdomainname 166 -+ -+#define TARGET_NR_osf_exportfs 169 /* not implemented */ -+ -+#define TARGET_NR_osf_alt_plock 181 /* not implemented */ -+ -+#define TARGET_NR_osf_getmnt 184 /* not implemented */ -+ -+#define TARGET_NR_osf_alt_sigpending 187 /* not implemented */ -+#define TARGET_NR_osf_alt_setsid 188 /* not implemented */ -+ -+#define TARGET_NR_osf_swapon 199 -+#define TARGET_NR_msgctl 200 -+#define TARGET_NR_msgget 201 -+#define TARGET_NR_msgrcv 202 -+#define TARGET_NR_msgsnd 203 -+#define TARGET_NR_semctl 204 -+#define TARGET_NR_semget 205 -+#define TARGET_NR_semop 206 -+#define TARGET_NR_osf_utsname 207 -+#define TARGET_NR_lchown 208 -+#define TARGET_NR_osf_shmat 209 -+#define TARGET_NR_shmctl 210 -+#define TARGET_NR_shmdt 211 -+#define TARGET_NR_shmget 212 -+#define TARGET_NR_osf_mvalid 213 /* not implemented */ -+#define TARGET_NR_osf_getaddressconf 214 /* not implemented */ -+#define TARGET_NR_osf_msleep 215 /* not implemented */ -+#define TARGET_NR_osf_mwakeup 216 /* not implemented */ -+#define TARGET_NR_msync 217 -+#define TARGET_NR_osf_signal 218 /* not implemented */ -+#define TARGET_NR_osf_utc_gettime 219 /* not implemented */ -+#define TARGET_NR_osf_utc_adjtime 220 /* not implemented */ -+ -+#define TARGET_NR_osf_security 222 /* not implemented */ -+#define TARGET_NR_osf_kloadcall 223 /* not implemented */ -+ -+#define TARGET_NR_osf_stat 224 -+#define TARGET_NR_osf_lstat 225 -+#define TARGET_NR_osf_fstat 226 -+#define TARGET_NR_osf_statfs64 227 -+#define TARGET_NR_osf_fstatfs64 228 -+ -+#define TARGET_NR_getpgid 233 -+#define TARGET_NR_getsid 234 -+#define TARGET_NR_sigaltstack 235 -+#define TARGET_NR_osf_waitid 236 /* not implemented */ -+#define TARGET_NR_osf_priocntlset 237 /* not implemented */ -+#define TARGET_NR_osf_sigsendset 238 /* not implemented */ -+#define TARGET_NR_osf_set_speculative 239 /* not implemented */ -+#define TARGET_NR_osf_msfs_syscall 240 /* not implemented */ -+#define TARGET_NR_osf_sysinfo 241 -+#define TARGET_NR_osf_uadmin 242 /* not implemented */ -+#define TARGET_NR_osf_fuser 243 /* not implemented */ -+#define TARGET_NR_osf_proplist_syscall 244 -+#define TARGET_NR_osf_ntp_adjtime 245 /* not implemented */ -+#define TARGET_NR_osf_ntp_gettime 246 /* not implemented */ -+#define TARGET_NR_osf_pathconf 247 /* not implemented */ -+#define TARGET_NR_osf_fpathconf 248 /* not implemented */ -+ -+#define TARGET_NR_osf_uswitch 250 /* not implemented */ -+#define TARGET_NR_osf_usleep_thread 251 -+#define TARGET_NR_osf_audcntl 252 /* not implemented */ -+#define TARGET_NR_osf_audgen 253 /* not implemented */ -+#define TARGET_NR_sysfs 254 -+#define TARGET_NR_osf_subsys_info 255 /* not implemented */ -+#define TARGET_NR_osf_getsysinfo 256 -+#define TARGET_NR_osf_setsysinfo 257 -+#define TARGET_NR_osf_afs_syscall 258 /* not implemented */ -+#define TARGET_NR_osf_swapctl 259 /* not implemented */ -+#define TARGET_NR_osf_memcntl 260 /* not implemented */ -+#define TARGET_NR_osf_fdatasync 261 /* not implemented */ -+ -+/* -+ * Ignore legacy syscalls that we don't use. -+ */ -+#define TARGET_IGNORE_alarm -+#define TARGET_IGNORE_creat -+#define TARGET_IGNORE_getegid -+#define TARGET_IGNORE_geteuid -+#define TARGET_IGNORE_getgid -+#define TARGET_IGNORE_getpid -+#define TARGET_IGNORE_getppid -+#define TARGET_IGNORE_getuid -+#define TARGET_IGNORE_pause -+#define TARGET_IGNORE_time -+#define TARGET_IGNORE_utime -+#define TARGET_IGNORE_umount2 -+ -+/* -+ * Linux-specific system calls begin at 300 -+ */ -+#define TARGET_NR_bdflush 300 -+#define TARGET_NR_sethae 301 -+#define TARGET_NR_mount 302 -+#define TARGET_NR_old_adjtimex 303 -+#define TARGET_NR_swapoff 304 -+#define TARGET_NR_getdents 305 -+#define TARGET_NR_create_module 306 -+#define TARGET_NR_init_module 307 -+#define TARGET_NR_delete_module 308 -+#define TARGET_NR_get_kernel_syms 309 -+#define TARGET_NR_syslog 310 -+#define TARGET_NR_reboot 311 -+#define TARGET_NR_clone 312 -+#define TARGET_NR_uselib 313 -+#define TARGET_NR_mlock 314 -+#define TARGET_NR_munlock 315 -+#define TARGET_NR_mlockall 316 -+#define TARGET_NR_munlockall 317 -+#define TARGET_NR_sysinfo 318 -+#define TARGET_NR__sysctl 319 -+/* 320 was sysTARGETidle. */ -+#define TARGET_NR_oldumount 321 -+#define TARGET_NR_swapon 322 -+#define TARGET_NR_times 323 -+#define TARGET_NR_personality 324 -+#define TARGET_NR_setfsuid 325 -+#define TARGET_NR_setfsgid 326 -+#define TARGET_NR_ustat 327 -+#define TARGET_NR_statfs 328 -+#define TARGET_NR_fstatfs 329 -+#define TARGET_NR_sched_setparam 330 -+#define TARGET_NR_sched_getparam 331 -+#define TARGET_NR_sched_setscheduler 332 -+#define TARGET_NR_sched_getscheduler 333 -+#define TARGET_NR_sched_yield 334 -+#define TARGET_NR_sched_get_priority_max 335 -+#define TARGET_NR_sched_get_priority_min 336 -+#define TARGET_NR_sched_rr_get_interval 337 -+#define TARGET_NR_afs_syscall 338 -+#define TARGET_NR_uname 339 -+#define TARGET_NR_nanosleep 340 -+#define TARGET_NR_mremap 341 -+#define TARGET_NR_nfsservctl 342 -+#define TARGET_NR_setresuid 343 -+#define TARGET_NR_getresuid 344 -+#define TARGET_NR_pciconfig_read 345 -+#define TARGET_NR_pciconfig_write 346 -+#define TARGET_NR_query_module 347 -+#define TARGET_NR_prctl 348 -+#define TARGET_NR_pread64 349 -+#define TARGET_NR_pwrite64 350 -+#define TARGET_NR_rt_sigreturn 351 -+#define TARGET_NR_rt_sigaction 352 -+#define TARGET_NR_rt_sigprocmask 353 -+#define TARGET_NR_rt_sigpending 354 -+#define TARGET_NR_rt_sigtimedwait 355 -+#define TARGET_NR_rt_sigqueueinfo 356 -+#define TARGET_NR_rt_sigsuspend 357 -+#define TARGET_NR_select 358 -+#define TARGET_NR_gettimeofday 359 -+#define TARGET_NR_settimeofday 360 -+#define TARGET_NR_getitimer 361 -+#define TARGET_NR_setitimer 362 -+#define TARGET_NR_utimes 363 -+#define TARGET_NR_getrusage 364 -+#define TARGET_NR_wait4 365 -+#define TARGET_NR_adjtimex 366 -+#define TARGET_NR_getcwd 367 -+#define TARGET_NR_capget 368 -+#define TARGET_NR_capset 369 -+#define TARGET_NR_sendfile 370 -+#define TARGET_NR_setresgid 371 -+#define TARGET_NR_getresgid 372 -+#define TARGET_NR_dipc 373 -+#define TARGET_NR_pivot_root 374 -+#define TARGET_NR_mincore 375 -+#define TARGET_NR_pciconfig_iobase 376 -+#define TARGET_NR_getdents64 377 -+#define TARGET_NR_gettid 378 -+#define TARGET_NR_readahead 379 -+/* 380 is unused */ -+#define TARGET_NR_tkill 381 -+#define TARGET_NR_setxattr 382 -+#define TARGET_NR_lsetxattr 383 -+#define TARGET_NR_fsetxattr 384 -+#define TARGET_NR_getxattr 385 -+#define TARGET_NR_lgetxattr 386 -+#define TARGET_NR_fgetxattr 387 -+#define TARGET_NR_listxattr 388 -+#define TARGET_NR_llistxattr 389 -+#define TARGET_NR_flistxattr 390 -+#define TARGET_NR_removexattr 391 -+#define TARGET_NR_lremovexattr 392 -+#define TARGET_NR_fremovexattr 393 -+#define TARGET_NR_futex 394 -+#define TARGET_NR_sched_setaffinity 395 -+#define TARGET_NR_sched_getaffinity 396 -+#define TARGET_NR_tuxcall 397 -+#define TARGET_NR_io_setup 398 -+#define TARGET_NR_io_destroy 399 -+#define TARGET_NR_io_getevents 400 -+#define TARGET_NR_io_submit 401 -+#define TARGET_NR_io_cancel 402 -+#define TARGET_NR_exit_group 405 -+#define TARGET_NR_lookup_dcookie 406 -+#define TARGET_NR_epoll_create 407 -+#define TARGET_NR_epoll_ctl 408 -+#define TARGET_NR_epoll_wait 409 -+/* Feb 2007: These three sysTARGETepoll defines shouldn't be here but culling -+ * them would break userspace apps ... we'll kill them off in 2010 :) */ -+#define TARGET_NR_sys_epoll_create TARGET_NR_epoll_create -+#define TARGET_NR_sys_epoll_ctl TARGET_NR_epoll_ctl -+#define TARGET_NR_sys_epoll_wait TARGET_NR_epoll_wait -+#define TARGET_NR_remap_file_pages 410 -+#define TARGET_NR_set_tid_address 411 -+#define TARGET_NR_restart_syscall 412 -+#define TARGET_NR_fadvise64 413 -+#define TARGET_NR_timer_create 414 -+#define TARGET_NR_timer_settime 415 -+#define TARGET_NR_timer_gettime 416 -+#define TARGET_NR_timer_getoverrun 417 -+#define TARGET_NR_timer_delete 418 -+#define TARGET_NR_clock_settime 419 -+#define TARGET_NR_clock_gettime 420 -+#define TARGET_NR_clock_getres 421 -+#define TARGET_NR_clock_nanosleep 422 -+#define TARGET_NR_semtimedop 423 -+#define TARGET_NR_tgkill 424 -+#define TARGET_NR_stat64 425 -+#define TARGET_NR_lstat64 426 -+#define TARGET_NR_fstat64 427 -+#define TARGET_NR_vserver 428 -+#define TARGET_NR_mbind 429 -+#define TARGET_NR_get_mempolicy 430 -+#define TARGET_NR_set_mempolicy 431 -+#define TARGET_NR_mq_open 432 -+#define TARGET_NR_mq_unlink 433 -+#define TARGET_NR_mq_timedsend 434 -+#define TARGET_NR_mq_timedreceive 435 -+#define TARGET_NR_mq_notify 436 -+#define TARGET_NR_mq_getsetattr 437 -+#define TARGET_NR_waitid 438 -+#define TARGET_NR_add_key 439 -+#define TARGET_NR_request_key 440 -+#define TARGET_NR_keyctl 441 -+#define TARGET_NR_ioprio_set 442 -+#define TARGET_NR_ioprio_get 443 -+#define TARGET_NR_inotify_init 444 -+#define TARGET_NR_inotify_add_watch 445 -+#define TARGET_NR_inotify_rm_watch 446 -+#define TARGET_NR_fdatasync 447 -+#define TARGET_NR_kexec_load 448 -+#define TARGET_NR_migrate_pages 449 -+#define TARGET_NR_openat 450 -+#define TARGET_NR_mkdirat 451 -+#define TARGET_NR_mknodat 452 -+#define TARGET_NR_fchownat 453 -+#define TARGET_NR_futimesat 454 -+#define TARGET_NR_fstatat64 455 -+#define TARGET_NR_unlinkat 456 -+#define TARGET_NR_renameat 457 -+#define TARGET_NR_linkat 458 -+#define TARGET_NR_symlinkat 459 -+#define TARGET_NR_readlinkat 460 -+#define TARGET_NR_fchmodat 461 -+#define TARGET_NR_faccessat 462 -+#define TARGET_NR_pselect6 463 -+#define TARGET_NR_ppoll 464 -+#define TARGET_NR_unshare 465 -+#define TARGET_NR_set_robust_list 466 -+#define TARGET_NR_get_robust_list 467 -+#define TARGET_NR_splice 468 -+#define TARGET_NR_sync_file_range 469 -+#define TARGET_NR_tee 470 -+#define TARGET_NR_vmsplice 471 -+#define TARGET_NR_move_pages 472 -+#define TARGET_NR_getcpu 473 -+#define TARGET_NR_epoll_pwait 474 -+#define TARGET_NR_utimensat 475 -+#define TARGET_NR_signalfd 476 -+#define TARGET_NR_timerfd 477 -+#define TARGET_NR_eventfd 478 -+#define TARGET_NR_recvmmsg 479 -+#define TARGET_NR_fallocate 480 -+#define TARGET_NR_timerfd_create 481 -+#define TARGET_NR_timerfd_settime 482 -+#define TARGET_NR_timerfd_gettime 483 -+#define TARGET_NR_signalfd4 484 -+#define TARGET_NR_eventfd2 485 -+#define TARGET_NR_epoll_create1 486 -+#define TARGET_NR_dup3 487 -+#define TARGET_NR_pipe2 488 -+#define TARGET_NR_inotify_init1 489 -+#define TARGET_NR_preadv 490 -+#define TARGET_NR_pwritev 491 -+#define TARGET_NR_rt_tgsigqueueinfo 492 -+#define TARGET_NR_perf_event_open 493 -+#define TARGET_NR_fanotify_init 494 -+#define TARGET_NR_fanotify_mark 495 -+#define TARGET_NR_prlimit64 496 -+#define TARGET_NR_name_to_handle_at 497 -+#define TARGET_NR_open_by_handle_at 498 -+#define TARGET_NR_clock_adjtime 499 -+#define TARGET_NR_syncfs 500 -+#define TARGET_NR_setns 501 -+#define TARGET_NR_accept4 502 -+#define TARGET_NR_sendmmsg 503 -+#define TARGET_NR_process_vm_readv 504 -+#define TARGET_NR_process_vm_writev 505 -+#define TARGET_NR_sw_slave_rwperfmons 506 -+#define TARGET_NR_sys_get_vmflags 507 -diff --git a/linux-user/sw64/target_cpu.h b/linux-user/sw64/target_cpu.h -new file mode 100644 -index 0000000000..1b87c8ba6d ---- /dev/null -+++ b/linux-user/sw64/target_cpu.h -@@ -0,0 +1,38 @@ -+/* -+ * SW64 specific CPU ABI and functions for linux-user -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#ifndef SW64_TARGET_CPU_H -+#define SW64_TARGET_CPU_H -+ -+static inline void cpu_clone_regs(CPUSW64State *env, target_ulong newsp) -+{ -+ if (newsp) { -+ env->ir[IDX_SP] = newsp; -+ } -+ env->ir[IDX_V0] = 0; -+ env->ir[IDX_A3] = 0; -+} -+ -+static inline void cpu_set_tls(CPUSW64State *env, target_ulong newtls) -+{ -+ env->unique = newtls; -+} -+ -+static inline abi_ulong get_sp_from_cpustate(CPUSW64State *state) -+{ -+ return state->ir[IDX_SP]; -+} -+#endif -diff --git a/linux-user/sw64/target_elf.h b/linux-user/sw64/target_elf.h -new file mode 100644 -index 0000000000..be48b6dee3 ---- /dev/null -+++ b/linux-user/sw64/target_elf.h -@@ -0,0 +1,14 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation, or (at your option) any -+ * later version. See the COPYING file in the top-level directory. -+ */ -+ -+#ifndef SW64_TARGET_ELF_H -+#define SW64_TARGET_ELF_H -+static inline const char *cpu_get_model(uint32_t eflags) -+{ -+ return "any"; -+} -+#endif -diff --git a/linux-user/sw64/target_fcntl.h b/linux-user/sw64/target_fcntl.h -new file mode 100644 -index 0000000000..9721e3de39 ---- /dev/null -+++ b/linux-user/sw64/target_fcntl.h -@@ -0,0 +1,11 @@ -+/* -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation, or (at your option) any -+ * later version. See the COPYING file in the top-level directory. -+ */ -+ -+#ifndef SW64_TARGET_FCNTL_H -+#define sw64_TARGET_FCNTL_H -+#include "../generic/fcntl.h" -+#endif -diff --git a/linux-user/sw64/target_signal.h b/linux-user/sw64/target_signal.h -new file mode 100644 -index 0000000000..6393a7542f ---- /dev/null -+++ b/linux-user/sw64/target_signal.h -@@ -0,0 +1,98 @@ -+#ifndef SW64_TARGET_SIGNAL_H -+#define SW64_TARGET_SIGNAL_H -+ -+#include "cpu.h" -+ -+#define TARGET_SIGHUP 1 -+#define TARGET_SIGINT 2 -+#define TARGET_SIGQUIT 3 -+#define TARGET_SIGILL 4 -+#define TARGET_SIGTRAP 5 -+#define TARGET_SIGABRT 6 -+#define TARGET_SIGSTKFLT 7 /* actually SIGEMT */ -+#define TARGET_SIGFPE 8 -+#define TARGET_SIGKILL 9 -+#define TARGET_SIGBUS 10 -+#define TARGET_SIGSEGV 11 -+#define TARGET_SIGSYS 12 -+#define TARGET_SIGPIPE 13 -+#define TARGET_SIGALRM 14 -+#define TARGET_SIGTERM 15 -+#define TARGET_SIGURG 16 -+#define TARGET_SIGSTOP 17 -+#define TARGET_SIGTSTP 18 -+#define TARGET_SIGCONT 19 -+#define TARGET_SIGCHLD 20 -+#define TARGET_SIGTTIN 21 -+#define TARGET_SIGTTOU 22 -+#define TARGET_SIGIO 23 -+#define TARGET_SIGXCPU 24 -+#define TARGET_SIGXFSZ 25 -+#define TARGET_SIGVTALRM 26 -+#define TARGET_SIGPROF 27 -+#define TARGET_SIGWINCH 28 -+#define TARGET_SIGPWR 29 /* actually SIGINFO */ -+#define TARGET_SIGUSR1 30 -+#define TARGET_SIGUSR2 31 -+#define TARGET_SIGRTMIN 32 -+ -+#define TARGET_SIG_BLOCK 1 -+#define TARGET_SIG_UNBLOCK 2 -+#define TARGET_SIG_SETMASK 3 -+ -+/* this struct defines a stack used during syscall handling */ -+ -+typedef struct target_sigaltstack { -+ abi_ulong ss_sp; -+ int32_t ss_flags; -+ int32_t dummy; -+ abi_ulong ss_size; -+} target_stack_t; -+ -+ -+/* -+ * sigaltstack controls -+ */ -+#define TARGET_SS_ONSTACK 1 -+#define TARGET_SS_DISABLE 2 -+ -+#define TARGET_SA_ONSTACK 0x00000001 -+#define TARGET_SA_RESTART 0x00000002 -+#define TARGET_SA_NOCLDSTOP 0x00000004 -+#define TARGET_SA_NODEFER 0x00000008 -+#define TARGET_SA_RESETHAND 0x00000010 -+#define TARGET_SA_NOCLDWAIT 0x00000020 /* not supported yet */ -+#define TARGET_SA_SIGINFO 0x00000040 -+ -+#define TARGET_MINSIGSTKSZ 4096 -+#define TARGET_SIGSTKSZ 16384 -+ -+/* From . */ -+#define TARGET_GEN_INTOVF -1 /* integer overflow */ -+#define TARGET_GEN_INTDIV -2 /* integer division by zero */ -+#define TARGET_GEN_FLTOVF -3 /* fp overflow */ -+#define TARGET_GEN_FLTDIV -4 /* fp division by zero */ -+#define TARGET_GEN_FLTUND -5 /* fp underflow */ -+#define TARGET_GEN_FLTINV -6 /* invalid fp operand */ -+#define TARGET_GEN_FLTINE -7 /* inexact fp operand */ -+#define TARGET_GEN_DECOVF -8 /* decimal overflow (for COBOL??) */ -+#define TARGET_GEN_DECDIV -9 /* decimal division by zero */ -+#define TARGET_GEN_DECINV -10 /* invalid decimal operand */ -+#define TARGET_GEN_ROPRAND -11 /* reserved operand */ -+#define TARGET_GEN_ASSERTERR -12 /* assertion error */ -+#define TARGET_GEN_NULPTRERR -13 /* null pointer error */ -+#define TARGET_GEN_STKOVF -14 /* stack overflow */ -+#define TARGET_GEN_STRLENERR -15 /* string length error */ -+#define TARGET_GEN_SUBSTRERR -16 /* substring error */ -+#define TARGET_GEN_RANGERR -17 /* range error */ -+#define TARGET_GEN_SUBRNG -18 -+#define TARGET_GEN_SUBRNG1 -19 -+#define TARGET_GEN_SUBRNG2 -20 -+#define TARGET_GEN_SUBRNG3 -21 -+#define TARGET_GEN_SUBRNG4 -22 -+#define TARGET_GEN_SUBRNG5 -23 -+#define TARGET_GEN_SUBRNG6 -24 -+#define TARGET_GEN_SUBRNG7 -25 -+ -+#define TARGET_ARCH_HAS_SETUP_FRAME -+#endif /* SW64_TARGET_SIGNAL_H */ -diff --git a/linux-user/sw64/target_structs.h b/linux-user/sw64/target_structs.h -new file mode 100644 -index 0000000000..7c13dc4bac ---- /dev/null -+++ b/linux-user/sw64/target_structs.h -@@ -0,0 +1,47 @@ -+/* -+ * SW64 specific structures for linux-user -+ * -+ * Copyright (c) 2018 Lin Hainan -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ */ -+#ifndef SW64_TARGET_STRUCTS_H -+#define SW64_TARGET_STRUCTS_H -+ -+/* TODO: Maybe it should be update. now it's different from other arch */ -+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; -+}; -+ -+#endif -diff --git a/linux-user/sw64/target_syscall.h b/linux-user/sw64/target_syscall.h -new file mode 100644 -index 0000000000..c901ae95d8 ---- /dev/null -+++ b/linux-user/sw64/target_syscall.h -@@ -0,0 +1,121 @@ -+#ifndef SW64_TARGET_SYSCALL_H -+#define SW64_TARGET_SYSCALL_H -+ -+/* TODO */ -+struct target_pt_regs { -+ abi_ulong r0; -+ abi_ulong r1; -+ abi_ulong r2; -+ abi_ulong r3; -+ abi_ulong r4; -+ abi_ulong r5; -+ abi_ulong r6; -+ abi_ulong r7; -+ abi_ulong r8; -+ abi_ulong r19; -+ abi_ulong r20; -+ abi_ulong r21; -+ abi_ulong r22; -+ abi_ulong r23; -+ abi_ulong r24; -+ abi_ulong r25; -+ abi_ulong r26; -+ abi_ulong r27; -+ abi_ulong r28; -+ abi_ulong hae; -+/* JRP - These are the values provided to a0-a2 by HMcode */ -+ abi_ulong trap_a0; -+ abi_ulong trap_a1; -+ abi_ulong trap_a2; -+/* These are saved by HMcode: */ -+ abi_ulong ps; -+ abi_ulong pc; -+ abi_ulong gp; -+ abi_ulong r16; -+ abi_ulong r17; -+ abi_ulong r18; -+}; -+ -+#define TARGET_MLOCKALL_MCL_CURRENT 0x2000 -+#define TARGET_MLOCKALL_MCL_FUTURE 0x4000 -+ -+ -+#define UNAME_MACHINE "sw64" -+#define UNAME_MINIMUM_RELEASE "2.6.32" -+#undef TARGET_EOPNOTSUPP -+#define TARGET_EOPNOTSUPP 45 /* Operation not supported on transport endpoint */ -+#define SWCR_STATUS_INV0 (1UL<<17) -+#define SWCR_STATUS_DZE0 (1UL<<18) -+#define SWCR_STATUS_OVF0 (1UL<<19) -+#define SWCR_STATUS_UNF0 (1UL<<20) -+#define SWCR_STATUS_INE0 (1UL<<21) -+#define SWCR_STATUS_DNO0 (1UL<<22) -+ -+#define SWCR_STATUS_MASK0 (SWCR_STATUS_INV0 | SWCR_STATUS_DZE0 | \ -+ SWCR_STATUS_OVF0 | SWCR_STATUS_UNF0 | \ -+ SWCR_STATUS_INE0 | SWCR_STATUS_DNO0) -+ -+#define SWCR_STATUS0_TO_EXCSUM_SHIFT 16 -+ -+#define SWCR_STATUS_INV1 (1UL<<23) -+#define SWCR_STATUS_DZE1 (1UL<<24) -+#define SWCR_STATUS_OVF1 (1UL<<25) -+#define SWCR_STATUS_UNF1 (1UL<<26) -+#define SWCR_STATUS_INE1 (1UL<<27) -+#define SWCR_STATUS_DNO1 (1UL<<28) -+ -+#define SWCR_STATUS_MASK1 (SWCR_STATUS_INV1 | SWCR_STATUS_DZE1 | \ -+ SWCR_STATUS_OVF1 | SWCR_STATUS_UNF1 | \ -+ SWCR_STATUS_INE1 | SWCR_STATUS_DNO1) -+ -+#define SWCR_STATUS1_TO_EXCSUM_SHIFT 22 -+#define SWCR_STATUS_INV2 (1UL<<34) -+#define SWCR_STATUS_DZE2 (1UL<<35) -+#define SWCR_STATUS_OVF2 (1UL<<36) -+#define SWCR_STATUS_UNF2 (1UL<<37) -+#define SWCR_STATUS_INE2 (1UL<<38) -+#define SWCR_STATUS_DNO2 (1UL<<39) -+ -+#define SWCR_STATUS_MASK2 (SWCR_STATUS_INV2 | SWCR_STATUS_DZE2 | \ -+ SWCR_STATUS_OVF2 | SWCR_STATUS_UNF2 | \ -+ SWCR_STATUS_INE2 | SWCR_STATUS_DNO2) -+#define SWCR_STATUS_INV3 (1UL<<40) -+#define SWCR_STATUS_DZE3 (1UL<<41) -+#define SWCR_STATUS_OVF3 (1UL<<42) -+#define SWCR_STATUS_UNF3 (1UL<<43) -+#define SWCR_STATUS_INE3 (1UL<<44) -+#define SWCR_STATUS_DNO3 (1UL<<45) -+ -+#define SWCR_STATUS_MASK3 (SWCR_STATUS_INV3 | SWCR_STATUS_DZE3 | \ -+ SWCR_STATUS_OVF3 | SWCR_STATUS_UNF3 | \ -+ SWCR_STATUS_INE3 | SWCR_STATUS_DNO3) -+#define SWCR_TRAP_ENABLE_INV (1UL<<1) /* invalid op */ -+#define SWCR_TRAP_ENABLE_DZE (1UL<<2) /* division by zero */ -+#define SWCR_TRAP_ENABLE_OVF (1UL<<3) /* overflow */ -+#define SWCR_TRAP_ENABLE_UNF (1UL<<4) /* underflow */ -+#define SWCR_TRAP_ENABLE_INE (1UL<<5) /* inexact */ -+#define SWCR_TRAP_ENABLE_DNO (1UL<<6) /* denorm */ -+#define SWCR_TRAP_ENABLE_MASK (SWCR_TRAP_ENABLE_INV | SWCR_TRAP_ENABLE_DZE | \ -+ SWCR_TRAP_ENABLE_OVF | SWCR_TRAP_ENABLE_UNF | \ -+ SWCR_TRAP_ENABLE_INE | SWCR_TRAP_ENABLE_DNO) -+ -+/* Denorm and Underflow flushing */ -+#define SWCR_MAP_DMZ (1UL<<12) /* Map denorm inputs to zero */ -+#define SWCR_MAP_UMZ (1UL<<13) /* Map underflowed outputs to zero */ -+ -+#define SWCR_MAP_MASK (SWCR_MAP_DMZ | SWCR_MAP_UMZ) -+ -+/* status bits coming from fpcr: */ -+#define SWCR_STATUS_INV (1UL<<17) -+#define SWCR_STATUS_DZE (1UL<<18) -+#define SWCR_STATUS_OVF (1UL<<19) -+#define SWCR_STATUS_UNF (1UL<<20) -+#define SWCR_STATUS_INE (1UL<<21) -+#define SWCR_STATUS_DNO (1UL<<22) -+ -+#define SWCR_STATUS_MASK (SWCR_STATUS_INV | SWCR_STATUS_DZE | \ -+ SWCR_STATUS_OVF | SWCR_STATUS_UNF | \ -+ SWCR_STATUS_INE | SWCR_STATUS_DNO) -+#define TARGET_GSI_IEEE_FP_CONTROL 45 -+#define TARGET_SSI_IEEE_FP_CONTROL 14 -+#endif -diff --git a/linux-user/sw64/termbits.h b/linux-user/sw64/termbits.h -new file mode 100644 -index 0000000000..37dd77120c ---- /dev/null -+++ b/linux-user/sw64/termbits.h -@@ -0,0 +1,265 @@ -+typedef unsigned char target_cc_t; -+typedef unsigned int target_speed_t; -+typedef unsigned int target_tcflag_t; -+ -+#define TARGET_NCCS 19 -+struct target_termios { -+ target_tcflag_t c_iflag; /* input mode flags */ -+ target_tcflag_t c_oflag; /* output mode flags */ -+ target_tcflag_t c_cflag; /* control mode flags */ -+ target_tcflag_t c_lflag; /* local mode flags */ -+ target_cc_t c_cc[TARGET_NCCS]; /* control characters */ -+ target_cc_t c_line; /* line discipline (== c_cc[19]) */ -+ target_speed_t c_ispeed; /* input speed */ -+ target_speed_t c_ospeed; /* output speed */ -+}; -+ -+/* c_cc characters */ -+#define TARGET_VEOF 0 -+#define TARGET_VEOL 1 -+#define TARGET_VEOL2 2 -+#define TARGET_VERASE 3 -+#define TARGET_VWERASE 4 -+#define TARGET_VKILL 5 -+#define TARGET_VREPRINT 6 -+#define TARGET_VSWTC 7 -+#define TARGET_VINTR 8 -+#define TARGET_VQUIT 9 -+#define TARGET_VSUSP 10 -+#define TARGET_VSTART 12 -+#define TARGET_VSTOP 13 -+#define TARGET_VLNEXT 14 -+#define TARGET_VDISCARD 15 -+#define TARGET_VMIN 16 -+#define TARGET_VTIME 17 -+ -+/* c_iflag bits */ -+#define TARGET_IGNBRK 0000001 -+#define TARGET_BRKINT 0000002 -+#define TARGET_IGNPAR 0000004 -+#define TARGET_PARMRK 0000010 -+#define TARGET_INPCK 0000020 -+#define TARGET_ISTRIP 0000040 -+#define TARGET_INLCR 0000100 -+#define TARGET_IGNCR 0000200 -+#define TARGET_ICRNL 0000400 -+#define TARGET_IXON 0001000 -+#define TARGET_IXOFF 0002000 -+#define TARGET_IXANY 0004000 -+#define TARGET_IUCLC 0010000 -+#define TARGET_IMAXBEL 0020000 -+#define TARGET_IUTF8 0040000 -+ -+/* c_oflag bits */ -+#define TARGET_OPOST 0000001 -+#define TARGET_ONLCR 0000002 -+#define TARGET_OLCUC 0000004 -+ -+#define TARGET_OCRNL 0000010 -+#define TARGET_ONOCR 0000020 -+#define TARGET_ONLRET 0000040 -+ -+#define TARGET_OFILL 00000100 -+#define TARGET_OFDEL 00000200 -+#define TARGET_NLDLY 00001400 -+#define TARGET_NL0 00000000 -+#define TARGET_NL1 00000400 -+#define TARGET_NL2 00001000 -+#define TARGET_NL3 00001400 -+#define TARGET_TABDLY 00006000 -+#define TARGET_TAB0 00000000 -+#define TARGET_TAB1 00002000 -+#define TARGET_TAB2 00004000 -+#define TARGET_TAB3 00006000 -+#define TARGET_CRDLY 00030000 -+#define TARGET_CR0 00000000 -+#define TARGET_CR1 00010000 -+#define TARGET_CR2 00020000 -+#define TARGET_CR3 00030000 -+#define TARGET_FFDLY 00040000 -+#define TARGET_FF0 00000000 -+#define TARGET_FF1 00040000 -+#define TARGET_BSDLY 00100000 -+#define TARGET_BS0 00000000 -+#define TARGET_BS1 00100000 -+#define TARGET_VTDLY 00200000 -+#define TARGET_VT0 00000000 -+#define TARGET_VT1 00200000 -+#define TARGET_XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ -+ -+/* c_cflag bit meaning */ -+#define TARGET_CBAUD 0000037 -+#define TARGET_B0 0000000 /* hang up */ -+#define TARGET_B50 0000001 -+#define TARGET_B75 0000002 -+#define TARGET_B110 0000003 -+#define TARGET_B134 0000004 -+#define TARGET_B150 0000005 -+#define TARGET_B200 0000006 -+#define TARGET_B300 0000007 -+#define TARGET_B600 0000010 -+#define TARGET_B1200 0000011 -+#define TARGET_B1800 0000012 -+#define TARGET_B2400 0000013 -+#define TARGET_B4800 0000014 -+#define TARGET_B9600 0000015 -+#define TARGET_B19200 0000016 -+#define TARGET_B38400 0000017 -+#define TARGET_EXTA B19200 -+#define TARGET_EXTB B38400 -+#define TARGET_CBAUDEX 0000000 -+#define TARGET_B57600 00020 -+#define TARGET_B115200 00021 -+#define TARGET_B230400 00022 -+#define TARGET_B460800 00023 -+#define TARGET_B500000 00024 -+#define TARGET_B576000 00025 -+#define TARGET_B921600 00026 -+#define TARGET_B1000000 00027 -+#define TARGET_B1152000 00030 -+#define TARGET_B1500000 00031 -+#define TARGET_B2000000 00032 -+#define TARGET_B2500000 00033 -+#define TARGET_B3000000 00034 -+#define TARGET_B3500000 00035 -+#define TARGET_B4000000 00036 -+ -+#define TARGET_CSIZE 00001400 -+#define TARGET_CS5 00000000 -+#define TARGET_CS6 00000400 -+#define TARGET_CS7 00001000 -+#define TARGET_CS8 00001400 -+ -+#define TARGET_CSTOPB 00002000 -+#define TARGET_CREAD 00004000 -+#define TARGET_PARENB 00010000 -+#define TARGET_PARODD 00020000 -+#define TARGET_HUPCL 00040000 -+ -+#define TARGET_CLOCAL 00100000 -+#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ -+#define TARGET_CRTSCTS 020000000000 /* flow control */ -+ -+/* c_lflag bits */ -+#define TARGET_ISIG 0x00000080 -+#define TARGET_ICANON 0x00000100 -+#define TARGET_XCASE 0x00004000 -+#define TARGET_ECHO 0x00000008 -+#define TARGET_ECHOE 0x00000002 -+#define TARGET_ECHOK 0x00000004 -+#define TARGET_ECHONL 0x00000010 -+#define TARGET_NOFLSH 0x80000000 -+#define TARGET_TOSTOP 0x00400000 -+#define TARGET_ECHOCTL 0x00000040 -+#define TARGET_ECHOPRT 0x00000020 -+#define TARGET_ECHOKE 0x00000001 -+#define TARGET_FLUSHO 0x00800000 -+#define TARGET_PENDIN 0x20000000 -+#define TARGET_IEXTEN 0x00000400 -+ -+#define TARGET_FIOCLEX TARGET_IO('f', 1) -+#define TARGET_FIONCLEX TARGET_IO('f', 2) -+#define TARGET_FIOASYNC TARGET_IOW('f', 125, int) -+#define TARGET_FIONBIO TARGET_IOW('f', 126, int) -+#define TARGET_FIONREAD TARGET_IOR('f', 127, int) -+#define TARGET_TIOCINQ FIONREAD -+#define TARGET_FIOQSIZE TARGET_IOR('f', 128, loff_t) -+ -+#define TARGET_TIOCGETP TARGET_IOR('t', 8, struct target_sgttyb) -+#define TARGET_TIOCSETP TARGET_IOW('t', 9, struct target_sgttyb) -+#define TARGET_TIOCSETN TARGET_IOW('t', 10, struct target_sgttyb) /* TIOCSETP wo flush */ -+ -+#define TARGET_TIOCSETC TARGET_IOW('t', 17, struct target_tchars) -+#define TARGET_TIOCGETC TARGET_IOR('t', 18, struct target_tchars) -+#define TARGET_TCGETS TARGET_IOR('t', 19, struct target_termios) -+#define TARGET_TCSETS TARGET_IOW('t', 20, struct target_termios) -+#define TARGET_TCSETSW TARGET_IOW('t', 21, struct target_termios) -+#define TARGET_TCSETSF TARGET_IOW('t', 22, struct target_termios) -+ -+#define TARGET_TCGETA TARGET_IOR('t', 23, struct target_termio) -+#define TARGET_TCSETA TARGET_IOW('t', 24, struct target_termio) -+#define TARGET_TCSETAW TARGET_IOW('t', 25, struct target_termio) -+#define TARGET_TCSETAF TARGET_IOW('t', 28, struct target_termio) -+ -+#define TARGET_TCSBRK TARGET_IO('t', 29) -+#define TARGET_TCXONC TARGET_IO('t', 30) -+#define TARGET_TCFLSH TARGET_IO('t', 31) -+ -+#define TARGET_TIOCSWINSZ TARGET_IOW('t', 103, struct target_winsize) -+#define TARGET_TIOCGWINSZ TARGET_IOR('t', 104, struct target_winsize) -+#define TARGET_TIOCSTART TARGET_IO('t', 110) /* start output, like ^Q */ -+#define TARGET_TIOCSTOP TARGET_IO('t', 111) /* stop output, like ^S */ -+#define TARGET_TIOCOUTQ TARGET_IOR('t', 115, int) /* output queue size */ -+ -+#define TARGET_TIOCGLTC TARGET_IOR('t', 116, struct target_ltchars) -+#define TARGET_TIOCSLTC TARGET_IOW('t', 117, struct target_ltchars) -+#define TARGET_TIOCSPGRP TARGET_IOW('t', 118, int) -+#define TARGET_TIOCGPGRP TARGET_IOR('t', 119, int) -+ -+#define TARGET_TIOCEXCL 0x540C -+#define TARGET_TIOCNXCL 0x540D -+#define TARGET_TIOCSCTTY 0x540E -+ -+#define TARGET_TIOCSTI 0x5412 -+#define TARGET_TIOCMGET 0x5415 -+#define TARGET_TIOCMBIS 0x5416 -+#define TARGET_TIOCMBIC 0x5417 -+#define TARGET_TIOCMSET 0x5418 -+# define TARGET_TIOCM_LE 0x001 -+# define TARGET_TIOCM_DTR 0x002 -+# define TARGET_TIOCM_RTS 0x004 -+# define TARGET_TIOCM_ST 0x008 -+# define TARGET_TIOCM_SR 0x010 -+# define TARGET_TIOCM_CTS 0x020 -+# define TARGET_TIOCM_CAR 0x040 -+# define TARGET_TIOCM_RNG 0x080 -+# define TARGET_TIOCM_DSR 0x100 -+# define TARGET_TIOCM_CD TIOCM_CAR -+# define TARGET_TIOCM_RI TIOCM_RNG -+# define TARGET_TIOCM_OUT1 0x2000 -+# define TARGET_TIOCM_OUT2 0x4000 -+# define TARGET_TIOCM_LOOP 0x8000 -+ -+#define TARGET_TIOCGSOFTCAR 0x5419 -+#define TARGET_TIOCSSOFTCAR 0x541A -+#define TARGET_TIOCLINUX 0x541C -+#define TARGET_TIOCCONS 0x541D -+#define TARGET_TIOCGSERIAL 0x541E -+#define TARGET_TIOCSSERIAL 0x541F -+#define TARGET_TIOCPKT 0x5420 -+# define TARGET_TIOCPKT_DATA 0 -+# define TARGET_TIOCPKT_FLUSHREAD 1 -+# define TARGET_TIOCPKT_FLUSHWRITE 2 -+# define TARGET_TIOCPKT_STOP 4 -+# define TARGET_TIOCPKT_START 8 -+# define TARGET_TIOCPKT_NOSTOP 16 -+# define TARGET_TIOCPKT_DOSTOP 32 -+ -+ -+#define TARGET_TIOCNOTTY 0x5422 -+#define TARGET_TIOCSETD 0x5423 -+#define TARGET_TIOCGETD 0x5424 -+#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -+#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ -+#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ -+#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ -+#define TARGET_TIOCGPTN TARGET_IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ -+#define TARGET_TIOCSPTLCK TARGET_IOW('T', 0x31, int) /* Lock/unlock Pty */ -+#define TARGET_TIOCGPTPEER TARGET_IO('T', 0x41) /* Safely open the slave */ -+ -+#define TARGET_TIOCSERCONFIG 0x5453 -+#define TARGET_TIOCSERGWILD 0x5454 -+#define TARGET_TIOCSERSWILD 0x5455 -+#define TARGET_TIOCGLCKTRMIOS 0x5456 -+#define TARGET_TIOCSLCKTRMIOS 0x5457 -+#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ -+#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ -+ /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -+# define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -+#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ -+#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ -+ -+#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -+#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ -+#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ -+#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ -diff --git a/meson.build b/meson.build -index 96de1a6ef9..d0bbceffe1 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', 'sw64'] - - cpu = host_machine.cpu_family() - -@@ -65,6 +65,10 @@ if cpu in ['riscv32', 'riscv64'] - cpu = 'riscv' - endif - -+if cpu == 'sw_64' -+ cpu = 'sw64' -+endif -+ - targetos = host_machine.system() - - if cpu in ['x86', 'x86_64'] -@@ -77,6 +81,8 @@ elif cpu in ['ppc', 'ppc64'] - kvm_targets = ['ppc-softmmu', 'ppc64-softmmu'] - elif cpu in ['mips', 'mips64'] - kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] -+elif cpu == 'sw64' -+ kvm_targets = ['sw64-softmmu'] - else - kvm_targets = [] - endif -@@ -359,6 +365,8 @@ if not get_option('tcg').disabled() - tcg_arch = 'i386' - elif config_host['ARCH'] == 'ppc64' - tcg_arch = 'ppc' -+ elif config_host['ARCH'] in ['sw64'] -+ tcg_arch = 'sw64' - endif - add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, - language: ['c', 'cpp', 'objc']) -@@ -1814,6 +1822,7 @@ disassemblers = { - 'sh4' : ['CONFIG_SH4_DIS'], - 'sparc' : ['CONFIG_SPARC_DIS'], - 'xtensa' : ['CONFIG_XTENSA_DIS'], -+ 'sw64' : ['CONFIG_SW64_DIS'], - } - if link_language == 'cpp' - disassemblers += { -@@ -2466,6 +2475,7 @@ if have_system - 'hw/sparc', - 'hw/sparc64', - 'hw/ssi', -+ 'hw/sw64', - 'hw/timer', - 'hw/tpm', - 'hw/usb', -diff --git a/pc-bios/meson.build b/pc-bios/meson.build -index b40ff3f2bd..05e9065ad6 100644 ---- a/pc-bios/meson.build -+++ b/pc-bios/meson.build -@@ -38,6 +38,9 @@ blobs = files( - 'vgabios-ramfb.bin', - 'vgabios-bochs-display.bin', - 'vgabios-ati.bin', -+ 'uefi-bios-sw', -+ 'core3-reset', -+ 'core3-hmcode', - 'openbios-sparc32', - 'openbios-sparc64', - 'openbios-ppc', -diff --git a/qapi/machine.json b/qapi/machine.json -index 6822cafe2e..6ed8488255 100644 ---- a/qapi/machine.json -+++ b/qapi/machine.json -@@ -29,7 +29,7 @@ - # Since: 3.0 - ## - { 'enum' : 'SysEmuTarget', -- 'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', -+ 'data' : [ 'aarch64', 'alpha', 'sw64', 'arm', 'avr', 'cris', 'hppa', 'i386', - 'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64', - 'mips64el', 'mipsel', 'nios2', 'or1k', 'ppc', - 'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4', -diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c -index 05e1d88d99..142352b24e 100644 ---- a/softmmu/qdev-monitor.c -+++ b/softmmu/qdev-monitor.c -@@ -61,7 +61,8 @@ typedef struct QDevAlias - QEMU_ARCH_HPPA | QEMU_ARCH_I386 | \ - QEMU_ARCH_MIPS | QEMU_ARCH_PPC | \ - QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \ -- QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA) -+ QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA | \ -+ QEMU_ARCH_SW64) - #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X) - #define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K) - -diff --git a/target/Kconfig b/target/Kconfig -index ae7f24fc66..a8d6cb1e97 100644 ---- a/target/Kconfig -+++ b/target/Kconfig -@@ -17,3 +17,4 @@ source sh4/Kconfig - source sparc/Kconfig - source tricore/Kconfig - source xtensa/Kconfig -+source sw64/Kconfig -diff --git a/target/meson.build b/target/meson.build -index 2f6940255e..ec6bc97331 100644 ---- a/target/meson.build -+++ b/target/meson.build -@@ -16,5 +16,6 @@ subdir('rx') - subdir('s390x') - subdir('sh4') - subdir('sparc') -+subdir('sw64') - subdir('tricore') - subdir('xtensa') -diff --git a/target/sw64/Kconfig b/target/sw64/Kconfig -new file mode 100644 -index 0000000000..ad50b9677e ---- /dev/null -+++ b/target/sw64/Kconfig -@@ -0,0 +1,2 @@ -+config SW64 -+ bool -diff --git a/target/sw64/Makefile.objs b/target/sw64/Makefile.objs -new file mode 100644 -index 0000000000..1e549d141c ---- /dev/null -+++ b/target/sw64/Makefile.objs -@@ -0,0 +1,4 @@ -+obj-$(CONFIG_SOFTMMU) += machine.o -+obj-y += cpu.o translate.o profile.o helper.o -+obj-y += int_helper.o float_helper.o simd_helper.o helper.o exception.o -+obj-$(CONFIG_KVM) += kvm.o -diff --git a/target/sw64/cpu-param.h b/target/sw64/cpu-param.h -new file mode 100644 -index 0000000000..978a3cd572 ---- /dev/null -+++ b/target/sw64/cpu-param.h -@@ -0,0 +1,24 @@ -+/* -+ * SW64 cpu parameters for qemu. -+ * -+ * Copyright (c) 2018 Lin Hainan -+ */ -+ -+#ifndef SW64_CPU_PARAM_H -+#define SW64_CPU_PARAM_H 1 -+ -+#define TARGET_LONG_BITS 64 /* if use th-1 ,TARGET_PAGE_BITS is 12 */ -+#define TARGET_PAGE_BITS 13 -+ -+#ifdef CONFIG_USER_ONLY -+#define TARGET_VIRT_ADDR_SPACE_BITS 64 -+#else -+#define TARGET_PHYS_ADDR_SPACE_BITS 48 -+#define TARGET_VIRT_ADDR_SPACE_BITS 64 -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+#define NB_MMU_MODES 4 -+#endif -+ -+#endif -diff --git a/target/sw64/cpu-qom.h b/target/sw64/cpu-qom.h -new file mode 100644 -index 0000000000..b093c2bec8 ---- /dev/null -+++ b/target/sw64/cpu-qom.h -@@ -0,0 +1,47 @@ -+/* -+ * QEMU SW64 CPU -+ * -+ * Copyright (c) 2018 Lin Hainan -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+#ifndef QEMU_SW64_CPU_QOM -+#define QEMU_SW64_CPU_QOM -+ -+#include "hw/core/cpu.h" -+ -+#define TYPE_SW64_CPU "sw64-cpu" -+ -+#define SW64_CPU_CLASS(kclass) \ -+ OBJECT_CLASS_CHECK(SW64CPUClass, (kclass), TYPE_SW64_CPU) -+#define SW64_CPU(obj) \ -+ OBJECT_CHECK(SW64CPU, (obj), TYPE_SW64_CPU) -+#define SW64_CPU_GET_CLASS(obj) \ -+ OBJECT_GET_CLASS(SW64CPUClass, (obj), TYPE_SW64_CPU) -+ -+/** -+ * SW64CPUClass: -+ * @parent_realize: The parent class' realize handler. -+ * @parent_reset: The parent class' reset handler. -+ * -+ * An SW64 CPU model. -+ */ -+typedef struct SW64CPUClass { -+ /* private */ -+ CPUClass parent_class; -+ /* public */ -+ DeviceRealize parent_realize; -+ DeviceReset parent_reset; -+} SW64CPUClass; -+ -+typedef struct SW64CPU SW64CPU; -+#endif -diff --git a/target/sw64/cpu.c b/target/sw64/cpu.c -new file mode 100644 -index 0000000000..89c21850e1 ---- /dev/null -+++ b/target/sw64/cpu.c -@@ -0,0 +1,457 @@ -+/* -+ * QEMU SW64 CPU -+ * -+ * Copyright (c) 2018 Lin Hainan -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include "qapi/error.h" -+#include "qemu/qemu-print.h" -+#include "cpu.h" -+#include "exec/exec-all.h" -+#include "sysemu/kvm.h" -+#include "disas/dis-asm.h" -+#include "kvm_sw64.h" -+#include "sysemu/reset.h" -+#include "hw/qdev-properties.h" -+ -+ -+static void sw64_cpu_set_pc(CPUState *cs, vaddr value) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ -+ cpu->env.pc = value; -+} -+ -+static void sw64_cpu_dump_state(CPUState *cs, FILE *f, int flags) -+{ -+#ifndef CONFIG_KVM -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ int i; -+ -+ static const char ireg_names[31][4] = { -+ "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0", "s1", -+ "s2", "s3", "s4", "s5", "fp", "a0", "a1", "a2", "a3", "a4", "a5", -+ "t8", "t9", "t10", "t11", "ra", "t12", "at", "gp", "sp"}; -+ static const char freg_names[128][4] = { -+ "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", "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", "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", "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"}; -+ qemu_fprintf(f, "PC=%016" PRIx64 " SP=%016" PRIx64 "\n", env->pc, -+ env->ir[IDX_SP]); -+ for (i = 0; i < 31; i++) { -+ qemu_fprintf(f, "%s=%016" PRIx64, ireg_names[i], env->ir[i]); -+ if ((i % 4) == 3) { -+ qemu_fprintf(f, "\n"); -+ } else { -+ qemu_fprintf(f, " "); -+ } -+ } -+ qemu_fprintf(f, "\n"); -+#ifndef CONFIG_USER_ONLY -+ static const char sreg_names[10][4] = {"p1", "p2", "p4", "p5", "p6", -+ "p7", "p20", "p21", "p22", "p23"}; -+ for (i = 0; i < 10; i++) { -+ qemu_fprintf(f, "%s=%016" PRIx64, sreg_names[i], env->sr[i]); -+ if ((i % 4) == 3) { -+ qemu_fprintf(f, "\n"); -+ } else { -+ qemu_fprintf(f, " "); -+ } -+ } -+ qemu_fprintf(f, "\n"); -+#endif -+ for (i = 0; i < 32; i++) { -+ qemu_fprintf(f, "%s=%016" PRIx64, freg_names[i + 96], env->fr[i + 96]); -+ qemu_fprintf(f, " %016" PRIx64, env->fr[i + 64]); -+ qemu_fprintf(f, " %016" PRIx64, env->fr[i + 32]); -+ qemu_fprintf(f, " %016" PRIx64, env->fr[i]); -+ qemu_fprintf(f, "\n"); -+ } -+ qemu_fprintf(f, "\n"); -+#endif -+} -+ -+#ifndef CONFIG_USER_ONLY -+static void sw64_machine_cpu_reset(void *opaque) -+{ -+ SW64CPU *cpu = opaque; -+ -+ cpu_reset(CPU(cpu)); -+} -+#endif -+ -+static void sw64_cpu_realizefn(DeviceState *dev, Error **errp) -+{ -+ CPUState *cs = CPU(dev); -+ SW64CPUClass *scc = SW64_CPU_GET_CLASS(dev); -+ Error *local_err = NULL; -+ -+ cpu_exec_realizefn(cs, &local_err); -+ if (local_err != NULL) { -+ error_propagate(errp, local_err); -+ return; -+ } -+#ifndef CONFIG_USER_ONLY -+ qemu_register_reset(sw64_machine_cpu_reset, cs); -+#endif -+ -+ qemu_init_vcpu(cs); -+ -+ scc->parent_realize(dev, errp); -+} -+ -+static void sw64_cpu_disas_set_info(CPUState *cs, disassemble_info *info) -+{ -+ info->mach = bfd_mach_sw_64_core3; -+ info->print_insn = print_insn_sw_64; -+} -+ -+#include "fpu/softfloat.h" -+ -+static void core3_init(Object *obj) -+{ -+ CPUState *cs = CPU(obj); -+ CPUSW64State *env = cs->env_ptr; -+#ifdef CONFIG_USER_ONLY -+ env->fpcr = 0x680e800000000000; -+ parallel_cpus = true; -+#endif -+ set_feature(env, SW64_FEATURE_CORE3); -+} -+ -+static ObjectClass *sw64_cpu_class_by_name(const char *cpu_model) -+{ -+ ObjectClass *oc; -+ char *typename; -+ char **cpuname; -+ -+ cpuname = g_strsplit(cpu_model, ",", 1); -+ typename = g_strdup_printf(SW64_CPU_TYPE_NAME("%s"), cpu_model); -+ -+ oc = object_class_by_name(typename); -+ g_strfreev(cpuname); -+ g_free(typename); -+ -+ if (oc && object_class_dynamic_cast(oc, TYPE_SW64_CPU) && -+ !object_class_is_abstract(oc)) { -+ return oc; -+ } -+ return NULL; -+} -+ -+bool sw64_cpu_has_work(CPUState *cs) -+{ -+ /* If CPU has gotten into asleep(halt), then it may be -+ * wake up by hard interrupt, timer, ii, mail or mchk. -+ */ -+ return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER | -+ CPU_INTERRUPT_IIMAIL | CPU_INTERRUPT_MCHK); -+} -+ -+static void sw64_cpu_initfn(Object *obj) -+{ -+ CPUState *cs = CPU(obj); -+ SW64CPU *cpu = SW64_CPU(obj); -+ CPUSW64State *env = &cpu->env; -+ -+ cpu_set_cpustate_pointers(cpu); -+ -+ cs->env_ptr = env; -+#ifndef CONFIG_USER_ONLY -+ env->flags = ENV_FLAG_HM_MODE; -+#else -+ env->flags = ENV_FLAG_PS_USER; -+#endif -+ tlb_flush(cs); -+} -+ -+#ifndef CONFIG_USER_ONLY -+static void sw64_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, -+ unsigned size, MMUAccessType access_type, -+ int mmu_idx, MemTxAttrs attrs, -+ MemTxResult response, uintptr_t retaddr) -+{ -+#ifdef DEBUG_TRANS -+ if (retaddr) { -+ cpu_restore_state(cs, retaddr, true); -+ } -+ fprintf(stderr, "PC = %lx, Wrong IO addr. Hwaddr = %lx, vaddr = %lx, access_type = %d\n", -+ env->pc, physaddr, addr, access_type); -+#endif -+} -+#endif -+ -+#define a0(func) (((func & 0xFF) >> 6) & 0x1) -+#define a1(func) ((((func & 0xFF) >> 6) & 0x2) >> 1) -+ -+#define t(func) ((a0(func) ^ a1(func)) & 0x1) -+#define b0(func) (t(func) | a0(func)) -+#define b1(func) ((~t(func) & 1) | a1(func)) -+ -+#define START_SYS_CALL_ADDR(func) \ -+ (b1(func) << 14) | (b0(func) << 13) | ((func & 0x3F) << 7) -+ -+static void sw64_cpu_do_interrupt(CPUState *cs) -+{ -+ int i = cs->exception_index; -+ -+ cs->exception_index = -1; -+#if !defined(CONFIG_USER_ONLY) -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ switch (i) { -+ case EXCP_OPCDEC: -+ cpu_abort(cs, "ILLEGAL INSN"); -+ break; -+ case EXCP_CALL_SYS: -+ i = START_SYS_CALL_ADDR(env->error_code); -+ if (i <= 0x3F) { -+ i += 0x4000; -+ } else if (i >= 0x40 && i <= 0x7F) { -+ i += 0x2000; -+ } else if (i >= 0x80 && i <= 0x8F) { -+ i += 0x6000; -+ } -+ break; -+ case EXCP_ARITH: -+ env->error_code = -1; -+ env->csr[EXC_PC] = env->pc - 4; -+ env->csr[EXC_SUM] = 1; -+ i = 0xB80; -+ break; -+ case EXCP_UNALIGN: -+ i = 0xB00; -+ env->csr[EXC_PC] = env->pc - 4; -+ break; -+ case EXCP_CLK_INTERRUPT: -+ case EXCP_DEV_INTERRUPT: -+ i = 0xE80; -+ break; -+ case EXCP_MMFAULT: -+ i = 0x980; -+ env->csr[EXC_PC] = env->pc; -+ break; -+ case EXCP_IIMAIL: -+ env->csr[EXC_PC] = env->pc; -+ i = 0xE00; -+ break; -+ default: -+ break; -+ } -+ env->pc = env->hm_entry + i; -+ env->flags = ENV_FLAG_HM_MODE; -+#else -+ switch (i) { -+ case EXCP_OPCDEC: -+ cpu_abort(cs, "ILLEGAL INSN"); -+ break; -+ case EXCP_CALL_SYS: -+ default: -+ break; -+ } -+#endif -+} -+ -+#ifndef CONFIG_USER_ONLY -+static bool sw64_cpu_exec_interrupt(CPUState *cs, int interrupt_request) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ int idx = -1; -+ /* We never take interrupts while in Hardmode. */ -+ if (env->flags & ENV_FLAG_HM_MODE) -+ return false; -+ -+ if (interrupt_request & CPU_INTERRUPT_IIMAIL) { -+ idx = EXCP_IIMAIL; -+ env->csr[INT_STAT] |= 1UL << 6; -+ if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -+ return false; -+ cs->interrupt_request &= ~CPU_INTERRUPT_IIMAIL; -+ goto done; -+ } -+ -+ if (interrupt_request & CPU_INTERRUPT_TIMER) { -+ idx = EXCP_CLK_INTERRUPT; -+ env->csr[INT_STAT] |= 1UL << 4; -+ if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -+ return false; -+ cs->interrupt_request &= ~CPU_INTERRUPT_TIMER; -+ goto done; -+ } -+ -+ if (interrupt_request & CPU_INTERRUPT_HARD) { -+ idx = EXCP_DEV_INTERRUPT; -+ env->csr[INT_STAT] |= 1UL << 12; -+ if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -+ return false; -+ cs->interrupt_request &= ~CPU_INTERRUPT_HARD; -+ goto done; -+ } -+ -+ if (interrupt_request & CPU_INTERRUPT_PCIE) { -+ idx = EXCP_DEV_INTERRUPT; -+ env->csr[INT_STAT] |= 1UL << 1; -+ env->csr[INT_PCI_INT] = 0x10; -+ if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -+ return false; -+ cs->interrupt_request &= ~CPU_INTERRUPT_PCIE; -+ goto done; -+ } -+ -+done: -+ if (idx >= 0) { -+ cs->exception_index = idx; -+ env->error_code = 0; -+ env->csr[EXC_PC] = env->pc; -+ sw64_cpu_do_interrupt(cs); -+ return true; -+ } -+ return false; -+} -+#endif -+ -+static void sw64_cpu_reset(DeviceState *dev) -+{ -+ CPUState *s = CPU(dev); -+ SW64CPU *cpu = SW64_CPU(s); -+ SW64CPUClass *scc = SW64_CPU_GET_CLASS(cpu); -+ -+ scc->parent_reset(dev); -+ -+#ifndef CONFIG_USER_ONLY -+ if (kvm_enabled()) { -+ kvm_sw64_reset_vcpu(cpu); -+ } -+#endif -+} -+ -+static Property sw64_cpu_properties[] = { -+#ifdef CONFIG_USER_ONLY -+ /* apic_id = 0 by default for *-user, see commit 9886e834 */ -+ DEFINE_PROP_UINT32("cid", SW64CPU, cid, 0), -+#else -+ DEFINE_PROP_UINT32("cid", SW64CPU, cid, 0xFFFFFFFF), -+#endif -+ DEFINE_PROP_END_OF_LIST() -+}; -+ -+#ifndef CONFIG_USER_ONLY -+#include "hw/core/sysemu-cpu-ops.h" -+ -+static const struct SysemuCPUOps sw64_sysemu_ops = { -+ .get_phys_page_debug = sw64_cpu_get_phys_page_debug, -+}; -+#endif -+ -+#include "hw/core/tcg-cpu-ops.h" -+ -+static const struct TCGCPUOps sw64_tcg_ops = { -+#ifdef CONFIG_TCG -+ .initialize = sw64_translate_init, -+ .tlb_fill = sw64_cpu_tlb_fill, -+#endif /* CONFIG_TCG */ -+ -+#if !defined(CONFIG_USER_ONLY) -+ .do_unaligned_access = sw64_cpu_do_unaligned_access, -+ .cpu_exec_interrupt = sw64_cpu_exec_interrupt, -+ .do_transaction_failed = sw64_cpu_do_transaction_failed, -+#endif /* !CONFIG_USER_ONLY */ -+ .do_interrupt = sw64_cpu_do_interrupt, -+}; -+ -+static void sw64_cpu_class_init(ObjectClass *oc, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(oc); -+ CPUClass *cc = CPU_CLASS(oc); -+ SW64CPUClass *scc = SW64_CPU_CLASS(oc); -+ -+ device_class_set_parent_realize(dc, sw64_cpu_realizefn, -+ &scc->parent_realize); -+ device_class_set_parent_reset(dc, sw64_cpu_reset, &scc->parent_reset); -+ device_class_set_props(dc, sw64_cpu_properties); -+ -+ cc->class_by_name = sw64_cpu_class_by_name; -+ dc->vmsd = &vmstate_sw64_cpu; -+ cc->has_work = sw64_cpu_has_work; -+ cc->set_pc = sw64_cpu_set_pc; -+ cc->disas_set_info = sw64_cpu_disas_set_info; -+ cc->dump_state = sw64_cpu_dump_state; -+ cc->tcg_ops = &sw64_tcg_ops; -+#ifndef CONFIG_USER_ONLY -+ cc->sysemu_ops = &sw64_sysemu_ops; -+#endif -+} -+ -+static const SW64CPUInfo sw64_cpus[] = -+{ -+ { -+ .name = "core3", -+ .initfn = core3_init, -+ }, -+ { -+ .name = NULL -+ }, -+}; -+ -+static void cpu_register(const SW64CPUInfo *info) -+{ -+ TypeInfo type_info = { -+ .parent = TYPE_SW64_CPU, -+ .instance_size = sizeof(SW64CPU), -+ .instance_init = info->initfn, -+ .class_size = sizeof(SW64CPUClass), -+ .class_init = info->class_init, -+ }; -+ -+ type_info.name = g_strdup_printf("%s-" TYPE_SW64_CPU, info->name); -+ type_register(&type_info); -+ g_free((void*)type_info.name); -+} -+ -+static const TypeInfo sw64_cpu_type_info = { -+ .name = TYPE_SW64_CPU, -+ .parent = TYPE_CPU, -+ .instance_size = sizeof(SW64CPU), -+ .instance_init = sw64_cpu_initfn, -+ .abstract = true, -+ .class_size = sizeof(SW64CPUClass), -+ .class_init = sw64_cpu_class_init, -+}; -+ -+static void sw64_cpu_register_types(void) -+{ -+ const SW64CPUInfo *info = sw64_cpus; -+ -+ type_register_static(&sw64_cpu_type_info); -+ -+ while (info->name) { -+ cpu_register(info); -+ info++; -+ } -+} -+ -+type_init(sw64_cpu_register_types) -diff --git a/target/sw64/cpu.h b/target/sw64/cpu.h -new file mode 100644 -index 0000000000..5a490e2b4a ---- /dev/null -+++ b/target/sw64/cpu.h -@@ -0,0 +1,406 @@ -+/* -+ * SW64 emulation cpu definitions for qemu. -+ * -+ * Copyright (c) 2018 Lin Hainan -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ */ -+#ifndef SW64_CPU_H -+#define SW64_CPU_H -+ -+#include "cpu-qom.h" -+#include "fpu/softfloat.h" -+#include "profile.h" -+ -+/* QEMU addressing/paging config */ -+#define TARGET_PAGE_BITS 13 -+#define TARGET_LONG_BITS 64 -+#define TARGET_LEVEL_BITS 10 -+//#define ALIGNED_ONLY -+ -+#include "exec/cpu-defs.h" -+ -+/* FIXME: LOCKFIX */ -+#define SW64_FIXLOCK 1 -+ -+/* swcore processors have a weak memory model */ -+#define TCG_GUEST_DEFAULT_MO (0) -+ -+#define SOFTMMU 1 -+ -+#ifndef CONFIG_USER_ONLY -+#define MMU_MODE0_SUFFIX _phys -+#define MMU_MODE3_SUFFIX _user -+#define MMU_MODE2_SUFFIX _kernel -+#endif -+#define MMU_PHYS_IDX 0 -+#define MMU_KERNEL_IDX 2 -+#define MMU_USER_IDX 3 -+ -+/* FIXME:Bits 4 and 5 are the mmu mode. The VMS hmcode uses all 4 modes; -+ The Unix hmcode only uses bit 4. */ -+#define PS_USER_MODE 8u -+ -+#define ENV_FLAG_HM_SHIFT 0 -+#define ENV_FLAG_PS_SHIFT 8 -+#define ENV_FLAG_FEN_SHIFT 24 -+ -+#define ENV_FLAG_HM_MODE (1u << ENV_FLAG_HM_SHIFT) -+#define ENV_FLAG_PS_USER (PS_USER_MODE << ENV_FLAG_PS_SHIFT) -+#define ENV_FLAG_FEN (1u << ENV_FLAG_FEN_SHIFT) -+ -+#define MCU_CLOCK 25000000 -+ -+typedef struct CPUSW64State CPUSW64State; -+typedef CPUSW64State CPUArchState; -+typedef SW64CPU ArchCPU; -+ -+struct CPUSW64State { -+ uint64_t ir[32]; -+ uint64_t fr[128]; -+ uint64_t pc; -+ bool is_slave; -+ -+ uint64_t csr[0x100]; -+ uint64_t fpcr; -+ uint64_t fpcr_exc_enable; -+ uint8_t fpcr_round_mode; -+ uint8_t fpcr_flush_to_zero; -+ -+ float_status fp_status; -+ -+ uint64_t hm_entry; -+ -+#if !defined(CONFIG_USER_ONLY) -+ uint64_t sr[10]; /* shadow regs 1,2,4-7,20-23 */ -+#endif -+ -+ uint32_t flags; -+ uint64_t error_code; -+ uint64_t unique; -+ uint64_t lock_addr; -+ uint64_t lock_valid; -+ uint64_t lock_flag; -+ uint64_t lock_success; -+#ifdef SW64_FIXLOCK -+ uint64_t lock_value; -+#endif -+ -+ uint64_t trap_arg0; -+ uint64_t trap_arg1; -+ uint64_t trap_arg2; -+ -+ uint64_t features; -+ uint64_t insn_count[537]; -+ -+ /* reserve for slave */ -+ uint64_t ca[4]; -+ uint64_t scala_gpr[64]; -+ uint64_t vec_gpr[224]; -+ uint64_t fpcr_base; -+ uint64_t fpcr_ext; -+ uint64_t pendding_flag; -+ uint64_t pendding_status; -+ uint64_t synr_pendding_status; -+ uint64_t sync_pendding_status; -+ uint8_t vlenma_idxa; -+ uint8_t stable; -+}; -+#define SW64_FEATURE_CORE3 0x2 -+ -+static inline void set_feature(CPUSW64State *env, int feature) -+{ -+ env->features |= feature; -+} -+ -+/** -+ * SW64CPU: -+ * @env: #CPUSW64State -+ * -+ * An SW64 CPU -+ */ -+struct SW64CPU { -+ /*< private >*/ -+ CPUState parent_obj; -+ /*< public >*/ -+ CPUNegativeOffsetState neg; -+ CPUSW64State env; -+ -+ uint64_t k_regs[158]; -+ uint64_t k_vcb[36]; -+ QEMUTimer *alarm_timer; -+ target_ulong irq; -+ uint32_t cid; -+}; -+ -+enum { -+ IDX_V0 = 0, -+ IDX_T0 = 1, -+ IDX_T1 = 2, -+ IDX_T2 = 3, -+ IDX_T3 = 4, -+ IDX_T4 = 5, -+ IDX_T5 = 6, -+ IDX_T6 = 7, -+ IDX_T7 = 8, -+ IDX_S0 = 9, -+ IDX_S1 = 10, -+ IDX_S2 = 11, -+ IDX_S3 = 12, -+ IDX_S4 = 13, -+ IDX_S5 = 14, -+ IDX_S6 = 15, -+ IDX_FP = IDX_S6, -+ IDX_A0 = 16, -+ IDX_A1 = 17, -+ IDX_A2 = 18, -+ IDX_A3 = 19, -+ IDX_A4 = 20, -+ IDX_A5 = 21, -+ IDX_T8 = 22, -+ IDX_T9 = 23, -+ IDX_T10 = 24, -+ IDX_T11 = 25, -+ IDX_RA = 26, -+ IDX_T12 = 27, -+ IDX_PV = IDX_T12, -+ IDX_AT = 28, -+ IDX_GP = 29, -+ IDX_SP = 30, -+ IDX_ZERO = 31, -+}; -+ -+enum { -+ MM_K_TNV = 0x0, -+ MM_K_ACV = 0x1, -+ MM_K_FOR = 0x2, -+ MM_K_FOE = 0x3, -+ MM_K_FOW = 0x4 -+}; -+ -+enum { -+ PTE_VALID = 0x0001, -+ PTE_FOR = 0x0002, /* used for page protection (fault on read) */ -+ PTE_FOW = 0x0004, /* used for page protection (fault on write) */ -+ PTE_FOE = 0x0008, -+ PTE_KS = 0x0010, -+ PTE_PSE = 0x0040, -+ PTE_GH = 0x0060, -+ PTE_HRE = 0x0100, -+ PTE_VRE = 0x0200, -+ PTE_KRE = 0x0400, -+ PTE_URE = 0x0800, -+ PTE_HWE = 0x1000, -+ PTE_VWE = 0x2000, -+ PTE_KWE = 0x4000, -+ PTE_UWE = 0x8000 -+}; -+ -+static inline int cpu_mmu_index(CPUSW64State *env, bool ifetch) -+{ -+ int ret = env->flags & ENV_FLAG_PS_USER ? MMU_USER_IDX : MMU_KERNEL_IDX; -+ if (env->flags & ENV_FLAG_HM_MODE) { -+ ret = MMU_PHYS_IDX; -+ } -+ return ret; -+} -+ -+static inline SW64CPU *sw64_env_get_cpu(CPUSW64State *env) -+{ -+ return container_of(env, SW64CPU, env); -+} -+ -+#define ENV_GET_CPU(e) CPU(sw64_env_get_cpu(e)) -+#define ENV_OFFSET offsetof(SW64CPU, env) -+ -+#define cpu_init(cpu_model) cpu_generic_init(TYPE_SW64_CPU, cpu_model) -+ -+#define SW64_CPU_TYPE_SUFFIX "-" TYPE_SW64_CPU -+#define SW64_CPU_TYPE_NAME(name) (name SW64_CPU_TYPE_SUFFIX) -+int cpu_sw64_signal_handler(int host_signum, void *pinfo, void *puc); -+bool sw64_cpu_tlb_fill(CPUState *cs, vaddr address, int size, -+ MMUAccessType access_type, int mmu_idx, -+ bool probe, uintptr_t retaddr); -+uint64_t sw64_ldl_phys(CPUState *cs, hwaddr addr); -+hwaddr sw64_cpu_get_phys_page_debug(CPUState *cs, vaddr addr); -+void sw64_stl_phys(CPUState *cs, hwaddr addr, uint64_t val); -+uint64_t sw64_ldw_phys(CPUState *cs, hwaddr addr); -+void sw64_stw_phys(CPUState *cs, hwaddr addr, uint64_t val); -+uint64_t cpu_sw64_load_fpcr(CPUSW64State *env); -+void cpu_sw64_store_fpcr(CPUSW64State *env, uint64_t val); -+void sw64_cpu_do_unaligned_access(CPUState *cs, vaddr addr, -+ MMUAccessType access_type, int mmu_idx, -+ uintptr_t retaddr) QEMU_NORETURN; -+bool sw64_cpu_has_work(CPUState *cs); -+extern struct VMStateDescription vmstate_sw64_cpu; -+ -+/* SW64-specific interrupt pending bits */ -+#define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_EXT_0 -+#define CPU_INTERRUPT_IIMAIL CPU_INTERRUPT_TGT_EXT_1 -+#define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2 -+#define CPU_INTERRUPT_PCIE CPU_INTERRUPT_TGT_EXT_3 -+#define CPU_INTERRUPT_WAKEUP CPU_INTERRUPT_TGT_EXT_3 -+#define CPU_INTERRUPT_SLAVE CPU_INTERRUPT_TGT_EXT_4 -+ -+#define cpu_signal_handler cpu_sw64_signal_handler -+#define CPU_RESOLVING_TYPE TYPE_SW64_CPU -+ -+#define SWCSR(x, y) x = y -+enum { -+ SWCSR(ITB_TAG, 0x0), -+ SWCSR(ITB_PTE, 0x1), -+ SWCSR(ITB_IA, 0x2), -+ SWCSR(ITB_IV, 0x3), -+ SWCSR(ITB_IVP, 0x4), -+ SWCSR(ITB_IU, 0x5), -+ SWCSR(ITB_IS, 0x6), -+ SWCSR(EXC_SUM, 0xd), -+ SWCSR(EXC_PC, 0xe), -+ SWCSR(DS_STAT, 0x48), -+ SWCSR(CID, 0xc4), -+ SWCSR(TID, 0xc7), -+ -+ SWCSR(DTB_TAG, 0x40), -+ SWCSR(DTB_PTE, 0x41), -+ SWCSR(DTB_IA, 0x42), -+ SWCSR(DTB_IV, 0x43), -+ SWCSR(DTB_IVP, 0x44), -+ SWCSR(DTB_IU, 0x45), -+ SWCSR(DTB_IS, 0x46), -+ SWCSR(II_REQ, 0x82), -+ -+ SWCSR(PTBR, 0x8), -+ SWCSR(PRI_BASE, 0x10), -+ SWCSR(TIMER_CTL, 0x2a), -+ SWCSR(INT_STAT, 0x30), -+ SWCSR(INT_CLR, 0x31), -+ SWCSR(IER, 0x32), -+ SWCSR(INT_PCI_INT, 0x33), -+ SWCSR(DVA, 0x4e), -+}; -+ -+#include "exec/cpu-all.h" -+static inline void cpu_get_tb_cpu_state(CPUSW64State *env, target_ulong *pc, -+ target_ulong *cs_base, uint32_t *pflags) -+{ -+ *pc = env->pc; -+ *cs_base = 0; -+ *pflags = env->flags; -+} -+ -+void sw64_translate_init(void); -+ -+enum { -+ EXCP_NONE, -+ EXCP_HALT, -+ EXCP_IIMAIL, -+ EXCP_OPCDEC, -+ EXCP_CALL_SYS, -+ EXCP_ARITH, -+ EXCP_UNALIGN, -+#ifdef SOFTMMU -+ EXCP_MMFAULT, -+#else -+ EXCP_DTBD, -+ EXCP_DTBS_U, -+ EXCP_DTBS_K, -+ EXCP_ITB_U, -+ EXCP_ITB_K, -+#endif -+ EXCP_CLK_INTERRUPT, -+ EXCP_DEV_INTERRUPT, -+ EXCP_SLAVE, -+}; -+ -+#define CSR_SHIFT_AND_MASK(name, func, shift, bits) \ -+ name##_##func##_S = shift, \ -+ name##_##func##_V = bits, \ -+ name##_##func##_M = (1UL << bits) - 1 -+ -+#define FPCR_MASK(name) ((uint64_t)FPCR_##name##_M << FPCR_##name##_S) -+/* FPCR */ -+enum { -+ CSR_SHIFT_AND_MASK(FPCR, EXC_CTL, 0, 2), -+ CSR_SHIFT_AND_MASK(FPCR, EXC_CTL_WEN, 2, 1), -+ CSR_SHIFT_AND_MASK(FPCR, RSV0, 3, 1), -+ CSR_SHIFT_AND_MASK(FPCR, INV3, 4, 1), -+ CSR_SHIFT_AND_MASK(FPCR, ZERO0, 5, 1), -+ CSR_SHIFT_AND_MASK(FPCR, OVF3, 6, 1), -+ CSR_SHIFT_AND_MASK(FPCR, UNF3, 7, 1), -+ CSR_SHIFT_AND_MASK(FPCR, INE3, 8, 1), -+ CSR_SHIFT_AND_MASK(FPCR, ZERO1, 9, 1), -+ CSR_SHIFT_AND_MASK(FPCR, RSV1, 10, 10), -+ CSR_SHIFT_AND_MASK(FPCR, INV2, 20, 1), -+ CSR_SHIFT_AND_MASK(FPCR, ZERO2, 21, 1), -+ CSR_SHIFT_AND_MASK(FPCR, OVF2, 22, 1), -+ CSR_SHIFT_AND_MASK(FPCR, UNF2, 23, 1), -+ CSR_SHIFT_AND_MASK(FPCR, INE2, 24, 1), -+ CSR_SHIFT_AND_MASK(FPCR, ZERO3, 25, 1), -+ CSR_SHIFT_AND_MASK(FPCR, RSV2, 26, 10), -+ CSR_SHIFT_AND_MASK(FPCR, INV1, 36, 1), -+ CSR_SHIFT_AND_MASK(FPCR, ZERO4, 37, 1), -+ CSR_SHIFT_AND_MASK(FPCR, OVF1, 38, 1), -+ CSR_SHIFT_AND_MASK(FPCR, UNF1, 39, 1), -+ CSR_SHIFT_AND_MASK(FPCR, INE1, 40, 1), -+ CSR_SHIFT_AND_MASK(FPCR, ZERO5, 41, 1), -+ CSR_SHIFT_AND_MASK(FPCR, RSV3, 42, 6), -+ CSR_SHIFT_AND_MASK(FPCR, DNZ, 48, 1), -+ CSR_SHIFT_AND_MASK(FPCR, INVD, 49, 1), -+ CSR_SHIFT_AND_MASK(FPCR, DZED, 50, 1), -+ CSR_SHIFT_AND_MASK(FPCR, OVFD, 51, 1), -+ CSR_SHIFT_AND_MASK(FPCR, INV0, 52, 1), -+ CSR_SHIFT_AND_MASK(FPCR, DZE0, 53, 1), -+ CSR_SHIFT_AND_MASK(FPCR, OVF0, 54, 1), -+ CSR_SHIFT_AND_MASK(FPCR, UNF0, 55, 1), -+ CSR_SHIFT_AND_MASK(FPCR, INE0, 56, 1), -+ CSR_SHIFT_AND_MASK(FPCR, OVI0, 57, 1), -+ CSR_SHIFT_AND_MASK(FPCR, DYN, 58, 2), -+ CSR_SHIFT_AND_MASK(FPCR, UNDZ, 60, 1), -+ CSR_SHIFT_AND_MASK(FPCR, UNFD, 61, 1), -+ CSR_SHIFT_AND_MASK(FPCR, INED, 62, 1), -+ CSR_SHIFT_AND_MASK(FPCR, SUM, 63, 1), -+}; -+ -+/* Arithmetic exception (entArith) constants. */ -+#define EXC_M_SWC 1 /* Software completion */ -+#define EXC_M_INV 2 /* Invalid operation */ -+#define EXC_M_DZE 4 /* Division by zero */ -+#define EXC_M_OVF 8 /* Overflow */ -+#define EXC_M_UNF 16 /* Underflow */ -+#define EXC_M_INE 32 /* Inexact result */ -+#define EXC_M_IOV 64 /* Integer Overflow */ -+#define EXC_M_DNO 128 /* Denomal operation */ -+ -+void QEMU_NORETURN dynamic_excp(CPUSW64State *env, uintptr_t retaddr, int excp, -+ int error); -+void QEMU_NORETURN arith_excp(CPUSW64State *env, uintptr_t retaddr, int exc, -+ uint64_t mask); -+ -+#define DEBUG_ARCH -+#ifdef DEBUG_ARCH -+#define arch_assert(x) \ -+ do { \ -+ g_assert(x); /*fprintf(stderr, "+6b %d\n", __LINE__); */ \ -+ } while (0) -+#else -+#define arch_assert(x) -+#endif -+ -+typedef struct SW64CPUInfo { -+ const char *name; -+ void (*initfn)(Object *obj); -+ void (*class_init)(ObjectClass *oc, void *data); -+} SW64CPUInfo; -+#define test_feature(env, x) (env->features & (x)) -+ -+/* Slave */ -+#endif -diff --git a/target/sw64/exception.c b/target/sw64/exception.c -new file mode 100644 -index 0000000000..a2df1cd329 ---- /dev/null -+++ b/target/sw64/exception.c -@@ -0,0 +1,76 @@ -+#include "qemu/osdep.h" -+#include "qemu/timer.h" -+ -+#include "cpu.h" -+#include "exec/exec-all.h" -+#include "fpu/softfloat.h" -+#include "exec/helper-proto.h" -+#include "hw/core/cpu.h" -+ -+#ifndef CONFIG_USER_ONLY -+void QEMU_NORETURN sw64_cpu_do_unaligned_access(CPUState *cs, vaddr addr, -+ MMUAccessType access_type, -+ int mmu_idx, uintptr_t retaddr) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ uint32_t insn = 0; -+ -+ if (retaddr) { -+ cpu_restore_state(cs, retaddr, true); -+ } -+ -+ fprintf(stderr, "Error %s addr = %lx\n", __func__, addr); -+ env->csr[DVA] = addr; -+ -+ env->csr[EXC_SUM] = ((insn >> 21) & 31) << 8; /* opcode */ -+ env->csr[DS_STAT] = (insn >> 26) << 4; /* dest regno */ -+ cs->exception_index = EXCP_UNALIGN; -+ env->error_code = 0; -+ cpu_loop_exit(cs); -+} -+ -+#endif -+ -+/* This should only be called from translate, via gen_excp. -+ We expect that ENV->PC has already been updated. */ -+void QEMU_NORETURN helper_excp(CPUSW64State *env, int excp, int error) -+{ -+ SW64CPU *cpu = sw64_env_get_cpu(env); -+ CPUState *cs = CPU(cpu); -+ -+ cs->exception_index = excp; -+ env->error_code = error; -+ cpu_loop_exit(cs); -+} -+ -+/* This may be called from any of the helpers to set up EXCEPTION_INDEX. */ -+void QEMU_NORETURN dynamic_excp(CPUSW64State *env, uintptr_t retaddr, int excp, -+ int error) -+{ -+ SW64CPU *cpu = sw64_env_get_cpu(env); -+ CPUState *cs = CPU(cpu); -+ -+ cs->exception_index = excp; -+ env->error_code = error; -+ if (retaddr) { -+ /* FIXME: Not jump to another tb, but jump to next insn emu */ -+ cpu_restore_state(cs, retaddr, true); -+ /* Floating-point exceptions (our only users) point to the next PC. */ -+ env->pc += 4; -+ } -+ cpu_loop_exit(cs); -+} -+ -+void QEMU_NORETURN arith_excp(CPUSW64State *env, uintptr_t retaddr, int exc, -+ uint64_t mask) -+{ -+ env->csr[EXC_SUM] = exc; -+ dynamic_excp(env, retaddr, EXCP_ARITH, 0); -+} -+ -+ -+void helper_trace_mem(CPUSW64State *env, uint64_t addr, uint64_t val) -+{ -+ /* printf("pc = %lx: Access mem addr =%lx, val = %lx\n", env->pc, addr,val); */ -+} -diff --git a/target/sw64/float_helper.c b/target/sw64/float_helper.c -new file mode 100644 -index 0000000000..ad1c3cce48 ---- /dev/null -+++ b/target/sw64/float_helper.c -@@ -0,0 +1,846 @@ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "exec/exec-all.h" -+#include "exec/helper-proto.h" -+#include "fpu/softfloat.h" -+ -+static inline uint32_t extractFloat16Frac(float16 a) -+{ -+ return float16_val(a) & 0x3ff; -+} -+ -+/*---------------------------------------------------------------------------- -+| Returns the exponent bits of the half-precision floating-point value `a'. -+*----------------------------------------------------------------------------*/ -+ -+static inline int extractFloat16Exp(float16 a) -+{ -+ return (float16_val(a) >> 10) & 0x1f; -+} -+ -+/*---------------------------------------------------------------------------- -+| Returns the sign bit of the single-precision floating-point value `a'. -+*----------------------------------------------------------------------------*/ -+ -+static inline uint8_t extractFloat16Sign(float16 a) -+{ -+ return float16_val(a) >> 15; -+} -+ -+#define FP_STATUS (env->fp_status) -+ -+#define CONVERT_BIT(X, SRC, DST) \ -+ (SRC > DST ? (X) / (SRC / DST) & (DST) : ((X)&SRC) * (DST / SRC)) -+ -+static uint64_t soft_to_errcode_exc(CPUSW64State *env) -+{ -+ uint8_t exc = get_float_exception_flags(&FP_STATUS); -+ -+ if (unlikely(exc)) { -+ set_float_exception_flags(0, &FP_STATUS); -+ } -+ return exc; -+} -+ -+static inline uint64_t float32_to_s_int(uint32_t fi) -+{ -+ uint32_t frac = fi & 0x7fffff; -+ uint32_t sign = (fi >> 31) & 1; -+ uint32_t exp_msb = (fi >> 30) & 1; -+ uint32_t exp_low = (fi >> 23) & 0x7f; -+ uint32_t exp; -+ -+ exp = (exp_msb << 10) | exp_low; -+ if (exp_msb) { -+ if (exp_low == 0x7f) { -+ exp = 0x7ff; -+ } -+ } else { -+ if (exp_low != 0x00) { -+ exp |= 0x380; -+ } -+ } -+ -+ return (((uint64_t)sign << 63) | ((uint64_t)exp << 52) | -+ ((uint64_t)frac << 29)); -+} -+ -+static inline uint64_t float32_to_s(float32 fa) -+{ -+ CPU_FloatU a; -+ a.f = fa; -+ return float32_to_s_int(a.l); -+} -+static inline uint32_t s_to_float32_int(uint64_t a) -+{ -+ return ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff); -+} -+ -+static inline float32 s_to_float32(uint64_t a) -+{ -+ CPU_FloatU r; -+ r.l = s_to_float32_int(a); -+ return r.f; -+} -+ -+uint32_t helper_s_to_memory(uint64_t a) -+{ -+ return s_to_float32(a); -+} -+ -+uint64_t helper_memory_to_s(uint32_t a) -+{ -+ return float32_to_s(a); -+} -+ -+uint64_t helper_fcvtls(CPUSW64State *env, uint64_t a) -+{ -+ float32 fr = int64_to_float32(a, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fcvtld(CPUSW64State *env, uint64_t a) -+{ -+ float64 fr = int64_to_float64(a, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+ return (uint64_t)fr; -+} -+ -+static uint64_t do_fcvtdl(CPUSW64State *env, uint64_t a, uint64_t roundmode) -+{ -+ uint64_t frac, ret = 0; -+ uint32_t exp, sign, exc = 0; -+ int shift; -+ -+ sign = (a >> 63); -+ exp = (uint32_t)(a >> 52) & 0x7ff; -+ frac = a & 0xfffffffffffffull; -+ -+ if (exp == 0) { -+ if (unlikely(frac != 0) && !env->fp_status.flush_inputs_to_zero) { -+ goto do_underflow; -+ } -+ } else if (exp == 0x7ff) { -+ exc = float_flag_invalid; -+ } else { -+ /* Restore implicit bit. */ -+ frac |= 0x10000000000000ull; -+ -+ shift = exp - 1023 - 52; -+ if (shift >= 0) { -+ /* In this case the number is so large that we must shift -+ the fraction left. There is no rounding to do. */ -+ if (shift < 64) { -+ ret = frac << shift; -+ } -+ /* Check for overflow. Note the special case of -0x1p63. */ -+ if (shift >= 11 && a != 0xC3E0000000000000ull) { -+ exc = float_flag_inexact; -+ } -+ } else { -+ uint64_t round; -+ -+ /* In this case the number is smaller than the fraction as -+ represented by the 52 bit number. Here we must think -+ about rounding the result. Handle this by shifting the -+ fractional part of the number into the high bits of ROUND. -+ This will let us efficiently handle round-to-nearest. */ -+ shift = -shift; -+ if (shift < 63) { -+ ret = frac >> shift; -+ round = frac << (64 - shift); -+ } else { -+ /* The exponent is so small we shift out everything. -+ Leave a sticky bit for proper rounding below. */ -+ do_underflow: -+ round = 1; -+ } -+ -+ if (round) { -+ exc = float_flag_inexact; -+ switch (roundmode) { -+ case float_round_nearest_even: -+ if (round == (1ull << 63)) { -+ /* Fraction is exactly 0.5; round to even. */ -+ ret += (ret & 1); -+ } else if (round > (1ull << 63)) { -+ ret += 1; -+ } -+ break; -+ case float_round_to_zero: -+ break; -+ case float_round_up: -+ ret += 1 - sign; -+ break; -+ case float_round_down: -+ ret += sign; -+ break; -+ } -+ } -+ } -+ if (sign) { -+ ret = -ret; -+ } -+ } -+ env->error_code = exc; -+ -+ return ret; -+} -+ -+/* TODO: */ -+uint64_t helper_fris(CPUSW64State *env, uint64_t a, uint64_t roundmode) -+{ -+ uint64_t ir; -+ float32 fr; -+ -+ if (roundmode == 5) -+ roundmode = env->fpcr_round_mode; -+ ir = do_fcvtdl(env, a, roundmode); -+ fr = int64_to_float32(ir, &FP_STATUS); -+ return float32_to_s(fr); -+} -+ -+/* TODO: */ -+uint64_t helper_frid(CPUSW64State *env, uint64_t a, uint64_t roundmode) -+{ -+ if (roundmode == 5) -+ roundmode = env->fpcr_round_mode; -+ return int64_to_float64(do_fcvtdl(env, a, roundmode), &FP_STATUS); -+} -+ -+uint64_t helper_fcvtdl(CPUSW64State *env, uint64_t a, uint64_t roundmode) -+{ -+ return do_fcvtdl(env, a, roundmode); -+} -+ -+uint64_t helper_fcvtdl_dyn(CPUSW64State *env, uint64_t a) -+{ -+ uint64_t roundmode = (uint64_t)(env->fpcr_round_mode); -+ return do_fcvtdl(env, a, roundmode); -+} -+ -+uint64_t helper_fcvtsd(CPUSW64State *env, uint64_t a) -+{ -+ float32 fa; -+ float64 fr; -+ -+ fa = s_to_float32(a); -+ fr = float32_to_float64(fa, &FP_STATUS); -+ -+ return fr; -+} -+ -+uint64_t helper_fcvtds(CPUSW64State *env, uint64_t a) -+{ -+ float32 fa; -+ -+ fa = float64_to_float32((float64)a, &FP_STATUS); -+ -+ return float32_to_s(fa); -+} -+ -+uint64_t helper_fcvtwl(CPUSW64State *env, uint64_t a) -+{ -+ int32_t ret; -+ ret = (a >> 29) & 0x3fffffff; -+ ret |= ((a >> 62) & 0x3) << 30; -+ return (uint64_t)(int64_t)ret; //int32_t to int64_t as Sign-Extend -+} -+ -+uint64_t helper_fcvtlw(CPUSW64State *env, uint64_t a) -+{ -+ uint64_t ret; -+ ret = (a & 0x3fffffff) << 29; -+ ret |= ((a >> 30) & 0x3) << 62; -+ return ret; -+} -+ -+uint64_t helper_fadds(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float32 fa, fb, fr; -+ -+ fa = s_to_float32(a); -+ fb = s_to_float32(b); -+#if 1 -+ fr = float32_add(fa, fb, &FP_STATUS); -+ -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(float*)&fr = *(float*)&fb + *(float*)&fa; -+#endif -+ return float32_to_s(fr); -+} -+ -+/* Input handing without software completion. Trap for all -+ non-finite numbers. */ -+uint64_t helper_faddd(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb, fr; -+ -+ fa = (float64)a; -+ fb = (float64)b; -+#if 1 -+ fr = float64_add(fa, fb, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(double*)&fr = *(double*)&fb + *(double*)&fa; -+#endif -+ return (uint64_t)fr; -+} -+ -+uint64_t helper_fsubs(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float32 fa, fb, fr; -+ -+ fa = s_to_float32(a); -+ fb = s_to_float32(b); -+#if 1 -+ fr = float32_sub(fa, fb, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(float*)&fr = *(float*)&fa - *(float*)&fb; -+#endif -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fsubd(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb, fr; -+ -+ fa = (float64)a; -+ fb = (float64)b; -+#if 1 -+ fr = float64_sub(fa, fb, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(double*)&fr = *(double*)&fa - *(double*)&fb; -+#endif -+ return (uint64_t)fr; -+} -+ -+uint64_t helper_fmuls(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float32 fa, fb, fr; -+ -+ fa = s_to_float32(a); -+ fb = s_to_float32(b); -+#if 1 -+ fr = float32_mul(fa, fb, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(float*)&fr = *(float*)&fa * *(float*)&fb; -+#endif -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fmuld(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb, fr; -+ -+ fa = (float64)a; -+ fb = (float64)b; -+#if 1 -+ fr = float64_mul(fa, fb, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(double*)&fr = *(double*)&fa * *(double*)&fb; -+#endif -+ return (uint64_t)fr; -+} -+ -+uint64_t helper_fdivs(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float32 fa, fb, fr; -+ -+ fa = s_to_float32(a); -+ fb = s_to_float32(b); -+#if 1 -+ fr = float32_div(fa, fb, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(float*)&fr = *(float*)&fa / *(float*)&fb; -+#endif -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fdivd(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb, fr; -+ -+ fa = (float64)a; -+ fb = (float64)b; -+#if 1 -+ fr = float64_div(fa, fb, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(double*)&fr = *(double*)&fa / *(double*)&fb; -+#endif -+ -+ return (uint64_t)fr; -+} -+ -+uint64_t helper_frecs(CPUSW64State *env, uint64_t a) -+{ -+ float32 fa, fb, fr; -+ -+ fa = s_to_float32(a); -+ fb = int64_to_float32(1, &FP_STATUS); -+#if 1 -+ fr = float32_div(fb, fa, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(float*)&fr = *(float*)&fb / *(float*)&fa; -+#endif -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_frecd(CPUSW64State *env, uint64_t a) -+{ -+ float64 fa, fb, fr; -+ -+ fa = (float64)a; -+ fb = int64_to_float64(1, &FP_STATUS); -+#if 1 -+ fr = float64_div(fb, fa, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+ *(double*)&fr = *(double*)&fb / *(double*)&fa; -+#endif -+ -+ return (uint64_t)fr; -+} -+ -+uint64_t helper_fsqrts(CPUSW64State *env, uint64_t b) -+{ -+ float32 fb, fr; -+#if 1 -+ fb = s_to_float32(b); -+ fr = float32_sqrt(fb, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+#include -+ *(double*)&fr = sqrt(*(double*)&b); -+#endif -+ -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fsqrt(CPUSW64State *env, uint64_t b) -+{ -+ float64 fr; -+ -+#if 1 -+ fr = float64_sqrt(b, &FP_STATUS); -+ env->error_code = soft_to_errcode_exc(env); -+#else -+#include -+ *(double*)&fr = sqrt(*(double*)&b); -+#endif -+ -+ return (uint64_t)fr; -+} -+ -+ -+uint64_t helper_fmas(CPUSW64State *env, uint64_t a, uint64_t b, uint64_t c) -+{ -+ float32 fa, fb, fc, fr; -+ fa = s_to_float32(a); -+ fb = s_to_float32(b); -+ fc = s_to_float32(c); -+ -+ fr = float32_muladd(fa, fb, fc, 0, &FP_STATUS); -+ -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fmad(CPUSW64State *env, uint64_t a, uint64_t b, uint64_t c) -+{ -+ float64 fr; -+ -+ fr = float64_muladd(a, b, c, 0, &FP_STATUS); -+ -+ return fr; -+} -+ -+ -+uint64_t helper_fmss(CPUSW64State *env, uint64_t a, uint64_t b, uint64_t c) -+{ -+ float32 fa, fb, fc, fr; -+ fa = s_to_float32(a); -+ fb = s_to_float32(b); -+ fc = s_to_float32(c); -+ -+ fr = float32_muladd(fa, fb, fc, float_muladd_negate_c, &FP_STATUS); -+ -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fmsd(CPUSW64State *env, uint64_t a, uint64_t b, uint64_t c) -+{ -+ float64 fr; -+ -+ fr = float64_muladd(a, b, c, float_muladd_negate_c, &FP_STATUS); -+ -+ return fr; -+} -+ -+ -+uint64_t helper_fnmas(CPUSW64State *env, uint64_t a, uint64_t b, uint64_t c) -+{ -+ float32 fa, fb, fc, fr; -+ fa = s_to_float32(a); -+ fb = s_to_float32(b); -+ fc = s_to_float32(c); -+ int flag = float_muladd_negate_product; -+ -+ fr = float32_muladd(fa, fb, fc, flag, &FP_STATUS); -+ -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fnmad(CPUSW64State *env, uint64_t a, uint64_t b, uint64_t c) -+{ -+ float64 fr; -+ int flag = float_muladd_negate_product; -+ -+ fr = float64_muladd(a, b, c, flag, &FP_STATUS); -+ -+ return fr; -+} -+ -+uint64_t helper_fnmss(CPUSW64State *env, uint64_t a, uint64_t b, uint64_t c) -+{ -+ float32 fa, fb, fc, fr; -+ fa = s_to_float32(a); -+ fb = s_to_float32(b); -+ fc = s_to_float32(c); -+ int flag = float_muladd_negate_product | float_muladd_negate_c; -+ -+ fr = float32_muladd(fa, fb, fc, flag, &FP_STATUS); -+ -+ return float32_to_s(fr); -+} -+ -+uint64_t helper_fnmsd(CPUSW64State *env, uint64_t a, uint64_t b, uint64_t c) -+{ -+ float64 fr; -+ int flag = float_muladd_negate_product | float_muladd_negate_c; -+ -+ fr = float64_muladd(a, b, c, flag, &FP_STATUS); -+ -+ return fr; -+} -+uint64_t helper_load_fpcr(CPUSW64State *env) -+{ -+ return cpu_sw64_load_fpcr(env); -+} -+ -+static void update_fpcr_status_mask(CPUSW64State *env) -+{ -+ uint64_t t = 0; -+ -+ /* Don't mask the inv excp: -+ * EXC_CTL1 = 1 -+ * EXC_CTL1 = 0, input denormal, DNZ=0 -+ * EXC_CTL1 = 0, no input denormal or DNZ=1, INVD = 0 -+ */ -+ if ((env->fpcr & FPCR_MASK(EXC_CTL) & 0x2)) { -+ if (env->fpcr & FPCR_MASK(EXC_CTL) & 0x1) { -+ t |= (EXC_M_INE | EXC_M_UNF | EXC_M_IOV); -+ } else { -+ t |= EXC_M_INE; -+ } -+ } else { -+ /* INV and DNO mask */ -+ if (env->fpcr & FPCR_MASK(DNZ)) t |= EXC_M_DNO; -+ if (env->fpcr & FPCR_MASK(INVD)) t |= EXC_M_INV; -+ if (env->fpcr & FPCR_MASK(OVFD)) t |= EXC_M_OVF; -+ if (env->fpcr & FPCR_MASK(UNFD)) { -+ t |= EXC_M_UNF; -+ } -+ if (env->fpcr & FPCR_MASK(DZED)) t |= EXC_M_DZE; -+ if (env->fpcr & FPCR_MASK(INED)) t |= EXC_M_INE; -+ } -+ -+ env->fpcr_exc_enable = t; -+} -+ -+void helper_store_fpcr(CPUSW64State *env, uint64_t val) -+{ -+ uint64_t fpcr = val; -+ uint8_t ret; -+ -+ switch ((fpcr & FPCR_MASK(DYN)) >> FPCR_DYN_S) { -+ case 0x0: -+ ret = float_round_to_zero; -+ break; -+ case 0x1: -+ ret = float_round_down; -+ break; -+ case 0x2: -+ ret = float_round_nearest_even; -+ break; -+ case 0x3: -+ ret = float_round_up; -+ break; -+ default: -+ ret = float_round_nearest_even; -+ break; -+ } -+ -+ env->fpcr_round_mode = ret; -+ -+ env->fp_status.float_rounding_mode = ret; -+ -+ env->fpcr_flush_to_zero = -+ (fpcr & FPCR_MASK(UNFD)) && (fpcr & FPCR_MASK(UNDZ)); -+ env->fp_status.flush_to_zero = env->fpcr_flush_to_zero; -+ -+ /* FIXME: Now the DNZ flag does not work int C3A. */ -+ //set_flush_inputs_to_zero((val & FPCR_MASK(DNZ)) != 0? 1 : 0, &FP_STATUS); -+ -+ val &= ~0x3UL; -+ val |= env->fpcr & 0x3UL; -+ env->fpcr = val; -+ update_fpcr_status_mask(env); -+} -+ -+void helper_setfpcrx(CPUSW64State *env, uint64_t val) -+{ -+ if (env->fpcr & FPCR_MASK(EXC_CTL_WEN)) { -+ env->fpcr &= ~3UL; -+ env->fpcr |= val & 0x3; -+ update_fpcr_status_mask(env); -+ } -+} -+#ifndef CONFIG_USER_ONLY -+static uint32_t soft_to_exc_type(uint64_t exc) -+{ -+ uint32_t ret = 0; -+ -+ if (unlikely(exc)) { -+ ret |= CONVERT_BIT(exc, float_flag_invalid, EXC_M_INV); -+ ret |= CONVERT_BIT(exc, float_flag_divbyzero, EXC_M_DZE); -+ ret |= CONVERT_BIT(exc, float_flag_overflow, EXC_M_OVF); -+ ret |= CONVERT_BIT(exc, float_flag_underflow, EXC_M_UNF); -+ ret |= CONVERT_BIT(exc, float_flag_inexact, EXC_M_INE); -+ } -+ -+ return ret; -+} -+static void fp_exc_raise1(CPUSW64State *env, uintptr_t retaddr, uint64_t exc, -+ uint32_t regno) -+{ -+ if (!likely(exc)) -+ return; -+ arith_excp(env, retaddr, exc, 1ull << regno); -+} -+ -+void helper_fp_exc_raise(CPUSW64State *env, uint32_t regno) -+{ -+ uint64_t exc = env->error_code; -+ uint32_t exc_type = soft_to_exc_type(exc); -+ -+ if (exc_type) { -+ exc_type &= ~(env->fpcr_exc_enable); -+ if (exc_type) fp_exc_raise1(env, GETPC(), exc_type | EXC_M_SWC, regno); -+ } -+} -+#endif -+ -+void helper_ieee_input(CPUSW64State *env, uint64_t val) -+{ -+#ifndef CONFIG_USER_ONLY -+ uint32_t exp = (uint32_t)(val >> 52) & 0x7ff; -+ uint64_t frac = val & 0xfffffffffffffull; -+ -+ if (exp == 0x7ff) { -+ /* Infinity or NaN. */ -+ uint32_t exc_type = EXC_M_INV; -+ -+ if (exc_type) { -+ exc_type &= ~(env->fpcr_exc_enable); -+ if (exc_type) -+ fp_exc_raise1(env, GETPC(), exc_type | EXC_M_SWC, 32); -+ } -+ } -+#endif -+} -+ -+void helper_ieee_input_s(CPUSW64State *env, uint64_t val) -+{ -+ if (unlikely(2 * val - 1 < 0x1fffffffffffffull) && -+ !env->fp_status.flush_inputs_to_zero) { -+ } -+} -+ -+static inline float64 t_to_float64(uint64_t a) -+{ -+ /* Memory format is the same as float64 */ -+ CPU_DoubleU r; -+ r.ll = a; -+ return r.d; -+} -+ -+uint64_t helper_fcmpun(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb; -+ uint64_t ret = 0; -+ -+ fa = t_to_float64(a); -+ fb = t_to_float64(b); -+ -+ if (float64_unordered_quiet(fa, fb, &FP_STATUS)) { -+ ret = 0x4000000000000000ULL; -+ } -+ env->error_code = soft_to_errcode_exc(env); -+ -+ return ret; -+} -+ -+uint64_t helper_fcmpeq(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb; -+ uint64_t ret = 0; -+ -+ fa = t_to_float64(a); -+ fb = t_to_float64(b); -+ -+ if (float64_eq_quiet(fa, fb, &FP_STATUS)) { -+ ret = 0x4000000000000000ULL; -+ } -+ env->error_code = soft_to_errcode_exc(env); -+ -+ return ret; -+} -+ -+uint64_t helper_fcmple(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb; -+ uint64_t ret = 0; -+ -+ fa = t_to_float64(a); -+ fb = t_to_float64(b); -+ -+ if (float64_le_quiet(fa, fb, &FP_STATUS)) { -+ ret = 0x4000000000000000ULL; -+ } -+ env->error_code = soft_to_errcode_exc(env); -+ -+ return ret; -+} -+ -+uint64_t helper_fcmplt(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb; -+ uint64_t ret = 0; -+ -+ fa = t_to_float64(a); -+ fb = t_to_float64(b); -+ -+ if (float64_lt_quiet(fa, fb, &FP_STATUS)) { -+ ret = 0x4000000000000000ULL; -+ } -+ env->error_code = soft_to_errcode_exc(env); -+ -+ return ret; -+} -+ -+uint64_t helper_fcmpge(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb; -+ uint64_t ret = 0; -+ -+ fa = t_to_float64(a); -+ fb = t_to_float64(b); -+ -+ if (float64_le_quiet(fb, fa, &FP_STATUS)) { -+ ret = 0x4000000000000000ULL; -+ } -+ env->error_code = soft_to_errcode_exc(env); -+ -+ return ret; -+} -+ -+uint64_t helper_fcmpgt(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb; -+ uint64_t ret = 0; -+ -+ fa = t_to_float64(a); -+ fb = t_to_float64(b); -+ -+ if (float64_lt_quiet(fb, fa, &FP_STATUS)) { -+ ret = 0x4000000000000000ULL; -+ } -+ env->error_code = soft_to_errcode_exc(env); -+ -+ return ret; -+} -+ -+uint64_t helper_fcmpge_s(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb; -+ uint64_t ret = 0; -+ -+ /* Make sure va and vb is s float. */ -+ fa = float32_to_float64(s_to_float32(a), &FP_STATUS); -+ fb = float32_to_float64(s_to_float32(b), &FP_STATUS); -+ -+ if (float64_le_quiet(fb, fa, &FP_STATUS)) { -+ ret = 0x4000000000000000ULL; -+ } -+ env->error_code = soft_to_errcode_exc(env); -+ -+ return ret; -+} -+ -+uint64_t helper_fcmple_s(CPUSW64State *env, uint64_t a, uint64_t b) -+{ -+ float64 fa, fb; -+ uint64_t ret = 0; -+ -+ /* Make sure va and vb is s float. */ -+ fa = float32_to_float64(s_to_float32(a), &FP_STATUS); -+ fb = float32_to_float64(s_to_float32(b), &FP_STATUS); -+ -+ if (float64_le_quiet(fa, fb, &FP_STATUS)) { -+ ret = 0x4000000000000000ULL; -+ } -+ env->error_code = soft_to_errcode_exc(env); -+ -+ return ret; -+} -+ -+void helper_vfcvtsh(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t vc, -+ uint64_t rd) -+{ -+ uint64_t temp = 0; -+ int i; -+ for (i = 0; i < 4; i++) { -+ temp |= (uint64_t)float32_to_float16(s_to_float32(env->fr[ra + i * 32]), -+ 1, &FP_STATUS) -+ << (i * 16); -+ } -+ for (i = 0; i < 4; i++) { -+ if (i == (vc & 0x3)) { -+ env->fr[rd + i * 32] = temp; -+ } else { -+ env->fr[rd + i * 32] = env->fr[rb + i * 32]; -+ } -+ } -+} -+ -+void helper_vfcvths(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t vc, -+ uint64_t rd) -+{ -+ uint64_t temp; -+ int i; -+ -+ temp = env->fr[ra + 32 * (vc & 0x3)]; -+ for (i = 0; i < 4; i++) { -+ env->fr[rd + i * 32] = float32_to_s( -+ float16_to_float32((temp >> (i * 16)) & 0xffffUL, 1, &FP_STATUS)); -+ } -+} -diff --git a/target/sw64/helper.c b/target/sw64/helper.c -new file mode 100644 -index 0000000000..0cc0af7087 ---- /dev/null -+++ b/target/sw64/helper.c -@@ -0,0 +1,349 @@ -+/* -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/timer.h" -+ -+#include "cpu.h" -+#include "exec/exec-all.h" -+#include "fpu/softfloat.h" -+#include "exec/helper-proto.h" -+#include "hw/core/cpu.h" -+#include "exec/memattrs.h" -+ -+#if defined(CONFIG_USER_ONLY) -+bool sw64_cpu_tlb_fill(CPUState *cs, vaddr address, int size, -+ MMUAccessType access_type, int mmu_idx, -+ bool probe, uintptr_t retaddr) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ -+ cs->exception_index = EXCP_MMFAULT; -+ cpu->env.trap_arg0 = address; -+ cpu_loop_exit_restore(cs, retaddr); -+} -+#else -+static target_ulong ldq_phys_clear(CPUState *cs, target_ulong phys) -+{ -+ return ldq_phys(cs->as, phys & ~(3UL)); -+} -+ -+static int get_sw64_physical_address(CPUSW64State *env, target_ulong addr, -+ int prot_need, int mmu_idx, target_ulong *pphys, -+ int *pprot) -+{ -+ CPUState *cs = CPU(sw64_env_get_cpu(env)); -+ target_ulong phys = 0; -+ int prot = 0; -+ int ret = MM_K_ACV; -+ target_ulong L1pte, L2pte, L3pte, L4pte; -+ target_ulong pt, index, pte_pfn_s; -+ -+ if (((addr >> 28) & 0xffffffff8) == 0xffffffff8) { -+ phys = (~(0xffffffff80000000)) & addr; -+ prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ ret = -1; -+ goto exit; -+ } else if (((addr >> 32) & 0xfffff000) == 0xfffff000) { -+ goto do_pgmiss; -+ } else if (((addr >> 52) & 0xfff) == 0xfff) { -+ phys = (~(0xfff0000000000000)) & addr; -+ prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ ret = -1; -+ goto exit; -+ } -+do_pgmiss: -+ pte_pfn_s = 28; -+ pt = env->csr[PTBR]; -+ index = (addr >> (TARGET_PAGE_BITS + 3 * TARGET_LEVEL_BITS)) & ((1 << TARGET_LEVEL_BITS)-1); -+ L1pte = ldq_phys_clear(cs, pt + index * 8); -+ if ((L1pte & PTE_VALID) == 0) { -+ ret = MM_K_TNV; -+ goto exit; -+ } -+ if (((L1pte >> 1) & 1) && prot_need == 0) { -+ ret = MM_K_FOR; -+ goto exit; -+ } -+ if (((L1pte >> 2) & 1) && prot_need == 1) { -+ ret = MM_K_FOW; -+ goto exit; -+ } -+ pt = L1pte >> pte_pfn_s << TARGET_PAGE_BITS; -+ -+ index = (addr >> (TARGET_PAGE_BITS + 2 * TARGET_LEVEL_BITS)) & ((1 << TARGET_LEVEL_BITS)-1); -+ L2pte = ldq_phys_clear(cs, pt + index * 8); -+ -+ if ((L2pte & PTE_VALID) == 0) { -+ ret = MM_K_TNV; -+ goto exit; -+ } -+ if (((L2pte >> 1) & 1) && prot_need == 0) { -+ ret = MM_K_FOR; -+ goto exit; -+ } -+ if (((L2pte >> 2) & 1) && prot_need == 1) { -+ ret = MM_K_FOW; -+ goto exit; -+ } -+ -+ pt = L2pte >> pte_pfn_s << TARGET_PAGE_BITS; -+ -+ index = (addr >> (TARGET_PAGE_BITS + 1 * TARGET_LEVEL_BITS)) & ((1 << TARGET_LEVEL_BITS)-1); -+ L3pte = ldq_phys_clear(cs, pt + index * 8); -+ -+ if ((L3pte & PTE_VALID) == 0) { -+ ret = MM_K_TNV; -+ goto exit; -+ } -+ if (((L3pte >> 1) & 1) && prot_need == 0) { -+ ret = MM_K_FOR; -+ goto exit; -+ } -+ if (((L3pte >> 2) & 1) && prot_need == 1) { -+ ret = MM_K_FOW; -+ goto exit; -+ } -+ -+ pt = L3pte >> pte_pfn_s << TARGET_PAGE_BITS; -+ -+ index = (addr >> TARGET_PAGE_BITS) & ((1 << TARGET_LEVEL_BITS)-1); -+ L4pte = ldq_phys_clear(cs, pt + index * 8); -+ if ((L4pte & PTE_VALID) == 0) { -+ ret = MM_K_TNV; -+ goto exit; -+ } -+#if PAGE_READ != 1 || PAGE_WRITE != 2 || PAGE_EXEC != 4 -+#error page bits out of date -+#endif -+ -+ /* Check access violations. */ -+ if ((L4pte & PTE_FOR) == 0) { -+ prot |= PAGE_READ | PAGE_EXEC; -+ } -+ if ((L4pte & PTE_FOW) == 0) { -+ prot |= PAGE_WRITE; -+ } -+ -+ /* Check fault-on-operation violations. */ -+ prot &= ~(L4pte >> 1); -+ -+ phys = (L4pte >> pte_pfn_s << TARGET_PAGE_BITS); -+ -+ if (unlikely((prot & prot_need) == 0)) { -+ ret = (prot_need & PAGE_EXEC -+ ? MM_K_FOE -+ : prot_need & PAGE_WRITE -+ ? MM_K_FOW -+ : prot_need & PAGE_READ ? MM_K_FOR : -1); -+ goto exit; -+ } -+ -+ ret = -1; -+exit: -+ *pphys = phys; -+ *pprot = prot; -+ return ret; -+} -+ -+bool sw64_cpu_tlb_fill(CPUState *cs, vaddr address, int size, -+ MMUAccessType access_type, int mmu_idx, -+ bool probe, uintptr_t retaddr) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ target_ulong phys; -+ int prot, fail; -+ -+ if (mmu_idx == MMU_PHYS_IDX) { -+ phys = address; -+ prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ fail = 0; -+ if ((address >> 52) & 1) goto do_pgmiss; -+ goto done; -+ } -+ -+do_pgmiss: -+ fail = get_sw64_physical_address(env, address, 1 << access_type, mmu_idx, &phys, &prot); -+ if (unlikely(fail >= 0)) { -+ if (probe) { -+ return false; -+ } -+ cs->exception_index = EXCP_MMFAULT; -+ if (access_type == 2) { -+ env->csr[DS_STAT] = fail; -+ env->csr[DVA] = address & ~(3UL); -+ } else { -+ env->csr[DS_STAT] = fail | (((unsigned long)access_type + 1) << 3); -+ env->csr[DVA] = address; -+ } -+ env->error_code = access_type; -+ cpu_loop_exit_restore(cs, retaddr); -+ } -+done: -+ tlb_set_page(cs, address & TARGET_PAGE_MASK, phys & TARGET_PAGE_MASK, prot, -+ mmu_idx, TARGET_PAGE_SIZE); -+ return true; -+} -+ -+hwaddr sw64_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ target_ulong phys; -+ int prot, fail; -+ int mmu_index = cpu_mmu_index(env, 0); -+ if (mmu_index == MMU_PHYS_IDX) { -+ phys = addr; -+ prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; -+ fail = -1; -+ if ((addr >> 52) & 1) goto do_pgmiss; -+ goto done; -+ } -+do_pgmiss: -+ fail = get_sw64_physical_address(&cpu->env, addr, 1, mmu_index, &phys, &prot); -+done: -+ return (fail >= 0 ? -1 : phys); -+} -+#endif -+ -+static void update_fpcr_status_mask(CPUSW64State* env) { -+ uint64_t t = 0; -+ -+ /* Don't mask the inv excp: -+ * EXC_CTL1 = 1 -+ * EXC_CTL1 = 0, input denormal, DNZ=0 -+ * EXC_CTL1 = 0, no input denormal or DNZ=1, INVD = 0 -+ */ -+ if ((env->fpcr & FPCR_MASK(EXC_CTL) & 0x2)) { -+ if (env->fpcr & FPCR_MASK(EXC_CTL) & 0x1) { -+ t |= (EXC_M_INE | EXC_M_UNF | EXC_M_IOV); -+ } else { -+ t |= EXC_M_INE; -+ } -+ } else { -+ /* INV and DNO mask */ -+ if (env->fpcr & FPCR_MASK(DNZ)) t |= EXC_M_DNO; -+ if (env->fpcr & FPCR_MASK(INVD)) t |= EXC_M_INV; -+ if (env->fpcr & FPCR_MASK(OVFD)) t |= EXC_M_OVF; -+ if (env->fpcr & FPCR_MASK(UNFD)) { -+ t |= EXC_M_UNF; -+ } -+ if (env->fpcr & FPCR_MASK(DZED)) t |= EXC_M_DZE; -+ if (env->fpcr & FPCR_MASK(INED)) t |= EXC_M_INE; -+ } -+ -+ env->fpcr_exc_enable = t; -+} -+ -+void cpu_sw64_store_fpcr(CPUSW64State* env, uint64_t val) { -+ uint64_t fpcr = val; -+ uint8_t ret; -+ -+ switch ((fpcr & FPCR_MASK(DYN)) >> FPCR_DYN_S) { -+ case 0x0: -+ ret = float_round_to_zero; -+ break; -+ case 0x1: -+ ret = float_round_down; -+ break; -+ case 0x2: -+ ret = float_round_nearest_even; -+ break; -+ case 0x3: -+ ret = float_round_up; -+ break; -+ default: -+ ret = float_round_nearest_even; -+ break; -+ } -+ -+ env->fpcr_round_mode = ret; -+ env->fp_status.float_rounding_mode = ret; -+ -+ env->fpcr_flush_to_zero = -+ (fpcr & FPCR_MASK(UNFD)) && (fpcr & FPCR_MASK(UNDZ)); -+ env->fp_status.flush_to_zero = env->fpcr_flush_to_zero; -+ -+ val &= ~0x3UL; -+ val |= env->fpcr & 0x3UL; -+ env->fpcr = val; -+ update_fpcr_status_mask(env); -+} -+ -+uint64_t helper_read_csr(CPUSW64State *env, uint64_t index) -+{ -+ if (index == PRI_BASE) -+ return 0x10000; -+ return env->csr[index]; -+} -+ -+uint64_t helper_rtc(void) -+{ -+#ifndef CONFIG_USER_ONLY -+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) * CPUFREQ_SCALE; -+#else -+ return 0; -+#endif -+} -+ -+void helper_write_csr(CPUSW64State *env, uint64_t index, uint64_t va) -+{ -+ env->csr[index] = va; -+#ifndef CONFIG_USER_ONLY -+ CPUState *cs = &(sw64_env_get_cpu(env)->parent_obj); -+ SW64CPU *cpu = SW64_CPU(cs); -+ if ((index == DTB_IA) || (index == DTB_IV) || (index == DTB_IVP) || -+ (index == DTB_IU) || (index == DTB_IS) || (index == ITB_IA) || -+ (index == ITB_IV) || (index == ITB_IVP) || (index == ITB_IU) || -+ (index == ITB_IS) || (index == PTBR)) { -+ tlb_flush(cs); -+ } -+ if (index == INT_CLR || index == INT_PCI_INT) { -+ env->csr[INT_STAT] &= ~va; -+ } -+ -+ if (index == TIMER_CTL && env->csr[index] == 1) { -+ timer_mod(cpu->alarm_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1000000000 / 250); -+ } -+#endif -+} -+ -+uint64_t cpu_sw64_load_fpcr(CPUSW64State *env) -+{ -+ return (uint64_t)env->fpcr; -+} -+ -+void helper_tb_flush(CPUSW64State *env) -+{ -+ tb_flush(CPU(sw64_env_get_cpu(env))); -+} -+ -+void helper_cpustate_update(CPUSW64State *env, uint64_t pc) -+{ -+ switch (pc & 0x3) { -+ case 0x00: -+ env->flags = ENV_FLAG_HM_MODE; -+ break; -+ case 0x01: -+ env->flags &= ~(ENV_FLAG_PS_USER | ENV_FLAG_HM_MODE); -+ break; -+ case 0x02: -+ env->flags &= ~(ENV_FLAG_PS_USER | ENV_FLAG_HM_MODE); -+ break; -+ case 0x03: -+ env->flags = ENV_FLAG_PS_USER; -+ } -+} -diff --git a/target/sw64/helper.h b/target/sw64/helper.h -new file mode 100644 -index 0000000000..7cafa563c2 ---- /dev/null -+++ b/target/sw64/helper.h -@@ -0,0 +1,127 @@ -+ -+DEF_HELPER_FLAGS_2(zap, TCG_CALL_NO_RWG_SE, i64, i64, i64) -+DEF_HELPER_FLAGS_2(zapnot, TCG_CALL_NO_RWG_SE, i64, i64, i64) -+DEF_HELPER_FLAGS_2(cmpgeb, TCG_CALL_NO_RWG_SE, i64, i64, i64) -+DEF_HELPER_FLAGS_1(s_to_memory, TCG_CALL_NO_RWG_SE, i32, i64) -+DEF_HELPER_FLAGS_1(memory_to_s, TCG_CALL_NO_RWG_SE, i64, i32) -+DEF_HELPER_FLAGS_2(fcvtls, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_2(fcvtld, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_3(fcvtdl, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_2(fcvtdl_dyn, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_3(fris, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(frid, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_2(fcvtsd, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_2(fcvtds, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_2(fcvtwl, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_2(fcvtlw, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_5(vfcvtsh, 0, void, env, i64, i64, i64, i64) -+DEF_HELPER_FLAGS_5(vfcvths, 0, void, env, i64, i64, i64, i64) -+DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_2(frecs, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_2(frecd, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_2(fsqrt, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_4(fmas, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(fmad, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(fmss, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(fmsd, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(fnmas, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(fnmad, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(fnmss, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(fnmsd, TCG_CALL_NO_RWG, i64, env, i64, i64, i64) -+DEF_HELPER_FLAGS_0(rtc, TCG_CALL_NO_RWG, i64) -+DEF_HELPER_FLAGS_1(load_fpcr, 0, i64, env) -+DEF_HELPER_FLAGS_2(store_fpcr, 0, void, env, i64) -+DEF_HELPER_FLAGS_2(setfpcrx, 0, void, env, i64) -+DEF_HELPER_FLAGS_2(ieee_input, 0, void, env, i64) -+DEF_HELPER_FLAGS_2(ieee_input_s, 0, void, env, i64) -+DEF_HELPER_FLAGS_2(read_csr, TCG_CALL_NO_RWG, i64, env, i64) -+DEF_HELPER_FLAGS_3(write_csr, 0, void, env, i64, i64) -+DEF_HELPER_FLAGS_2(cpustate_update, 0, void, env, i64) -+DEF_HELPER_FLAGS_3(trace_mem, 0, void, env, i64, i64) -+DEF_HELPER_FLAGS_3(fcmpun, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fcmple, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fcmplt, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fcmpge, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fcmpgt, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fcmpge_s, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(fcmple_s, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_4(srlow, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(sllow, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vlogzz, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vconw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vcond, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vshfw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_2(ctlzow, 0, i64, env, i64) -+DEF_HELPER_FLAGS_4(vucaddw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucaddwi, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucsubw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucsubwi, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucaddh, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucaddhi, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucsubh, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucsubhi, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucaddb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucaddbi, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucsubb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vucsubbi, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_3(vstw, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(vsts, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_3(vstd, TCG_CALL_NO_RWG, i64, env, i64, i64) -+DEF_HELPER_FLAGS_2(v_print, 0, void, env, i64) -+DEF_HELPER_FLAGS_1(tb_flush, 0, void, env) -+DEF_HELPER_FLAGS_4(vmaxb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vminb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vmaxh, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vminh, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vmaxw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vminw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(sraow, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vsm4r, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vsm4key, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vsm3msw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vcmpueqb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vcmpugtb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vcmpueqbi, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vcmpugtbi, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vumaxb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vuminb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vumaxh, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vuminh, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vumaxw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vuminw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_5(vinsb, 0, void, env, i64, i64, i64, i64) -+DEF_HELPER_FLAGS_5(vinsh, 0, void, env, i64, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vinsectlh, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vinsectlw, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vinsectlb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_5(vshfq, 0, void, env, i64, i64, i64, i64) -+DEF_HELPER_FLAGS_4(vshfqb, 0, void, env, i64, i64, i64) -+DEF_HELPER_FLAGS_5(vsm3r, 0, void, env, i64, i64, i64, i64) -+ -+#ifndef CONFIG_USER_ONLY -+DEF_HELPER_FLAGS_2(fp_exc_raise, 0, void, env, i32) -+DEF_HELPER_FLAGS_2(pri_ldw, 0, i64, env, i64) -+DEF_HELPER_FLAGS_3(pri_stw, 0, void, env, i64, i64) -+DEF_HELPER_FLAGS_2(pri_ldl, 0, i64, env, i64) -+DEF_HELPER_FLAGS_3(pri_stl, 0, void, env, i64, i64) -+#endif -+ -+DEF_HELPER_3(excp, noreturn, env, int, int) -+//DEF_HELPER_FLAGS_3(faddh, TCG_CALL_NO_RWG, i64, env, i64, i64) -+//DEF_HELPER_FLAGS_3(fsubh, TCG_CALL_NO_RWG, i64, env, i64, i64) -+//DEF_HELPER_FLAGS_3(fmulh, TCG_CALL_NO_RWG, i64, env, i64, i64) -+#ifndef CONFIG_USER_ONLY -+/* Scale factor for core3 cpu freq, ie number of ns per tick. */ -+#define CPUFREQ_SCALE 3 -+#endif -+ -+/* SLAVE FLOAT HELPER. */ -diff --git a/target/sw64/int_helper.c b/target/sw64/int_helper.c -new file mode 100644 -index 0000000000..131182585a ---- /dev/null -+++ b/target/sw64/int_helper.c -@@ -0,0 +1,118 @@ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "exec/exec-all.h" -+#include "exec/helper-proto.h" -+#include "qemu/host-utils.h" -+#include "exec/memattrs.h" -+ -+uint64_t helper_zapnot(uint64_t val, uint64_t mskb) -+{ -+ uint64_t mask; -+ -+ mask = -(mskb & 0x01) & 0x00000000000000ffull; -+ mask |= -(mskb & 0x02) & 0x000000000000ff00ull; -+ mask |= -(mskb & 0x04) & 0x0000000000ff0000ull; -+ mask |= -(mskb & 0x08) & 0x00000000ff000000ull; -+ mask |= -(mskb & 0x10) & 0x000000ff00000000ull; -+ mask |= -(mskb & 0x20) & 0x0000ff0000000000ull; -+ mask |= -(mskb & 0x40) & 0x00ff000000000000ull; -+ mask |= -(mskb & 0x80) & 0xff00000000000000ull; -+ -+ return val & mask; -+} -+ -+uint64_t helper_zap(uint64_t val, uint64_t mask) -+{ -+ return helper_zapnot(val, ~mask); -+} -+ -+uint64_t helper_cmpgeb(uint64_t va, uint64_t vb) -+{ -+ int i; -+ uint64_t ret = 0; -+ uint64_t tmp; -+ for (i = 0; i < 64; i += 8) { -+ tmp = ((va >> i) & 0xff) + (~(vb >> i) & 0xff) + 1; -+ ret |= (tmp >> 8) << (i / 8); -+ } -+ return ret; -+} -+ -+#ifndef CONFIG_USER_ONLY -+static inline MemTxAttrs cpu_get_mem_attrs(CPUSW64State *env) -+{ -+ return ((MemTxAttrs) { .secure = 1 }); -+} -+ -+static inline AddressSpace *cpu_addressspace(CPUState *cs, MemTxAttrs attrs) -+{ -+ return cpu_get_address_space(cs, cpu_asidx_from_attrs(cs, attrs)); -+} -+ -+uint64_t sw64_ldw_phys(CPUState *cs, hwaddr addr) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ int32_t ret; -+ CPUSW64State *env = &cpu->env; -+ MemTxAttrs attrs = cpu_get_mem_attrs(env); -+ AddressSpace *as = cpu_addressspace(cs, attrs); -+ -+ ret = (int32_t)address_space_ldl(as, addr, attrs, NULL); -+ -+ return (uint64_t)(int64_t)ret; -+} -+ -+void sw64_stw_phys(CPUState *cs, hwaddr addr, uint64_t val) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ MemTxAttrs attrs = cpu_get_mem_attrs(env); -+ AddressSpace *as = cpu_addressspace(cs, attrs); -+ -+ address_space_stl(as, addr, (uint32_t)val, attrs, NULL); -+} -+ -+uint64_t sw64_ldl_phys(CPUState *cs, hwaddr addr) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ MemTxAttrs attrs = cpu_get_mem_attrs(env); -+ AddressSpace *as = cpu_addressspace(cs, attrs); -+ -+ return address_space_ldq(as, addr, attrs, NULL); -+} -+ -+void sw64_stl_phys(CPUState *cs, hwaddr addr, uint64_t val) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ MemTxAttrs attrs = cpu_get_mem_attrs(env); -+ AddressSpace *as = cpu_addressspace(cs, attrs); -+ -+ address_space_stq(as, addr, val, attrs, NULL); -+} -+ -+uint64_t helper_pri_ldw(CPUSW64State *env, uint64_t hwaddr) -+{ -+ CPUState *cs = CPU(sw64_env_get_cpu(env)); -+ return sw64_ldw_phys(cs, hwaddr); -+} -+ -+void helper_pri_stw(CPUSW64State *env, uint64_t val, uint64_t hwaddr) -+{ -+ CPUState *cs = CPU(sw64_env_get_cpu(env)); -+ sw64_stw_phys(cs, hwaddr, val); -+} -+ -+uint64_t helper_pri_ldl(CPUSW64State *env, uint64_t hwaddr) -+{ -+ CPUState *cs = CPU(sw64_env_get_cpu(env)); -+ return sw64_ldl_phys(cs, hwaddr); -+} -+ -+void helper_pri_stl(CPUSW64State *env, uint64_t val, uint64_t hwaddr) -+{ -+ CPUState *cs = CPU(sw64_env_get_cpu(env)); -+ sw64_stl_phys(cs, hwaddr, val); -+} -+#endif -diff --git a/target/sw64/kvm.c b/target/sw64/kvm.c -new file mode 100644 -index 0000000000..fc134c83fb ---- /dev/null -+++ b/target/sw64/kvm.c -@@ -0,0 +1,215 @@ -+/* -+ * SW64 implementation of KVM hooks -+ * -+ * Copyright (c) 2018 Lin Hainan -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or later. -+ * See the COPYING file in the top-level directory. -+ * -+ */ -+ -+#include "qemu/osdep.h" -+#include -+ -+#include -+ -+#include "qemu-common.h" -+#include "qemu/timer.h" -+#include "qemu/error-report.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/kvm.h" -+#include "kvm_sw64.h" -+#include "cpu.h" -+#include "exec/memattrs.h" -+#include "exec/address-spaces.h" -+#include "hw/boards.h" -+#include "qemu/log.h" -+ -+#define init_pc 0xffffffff80011000 -+const KVMCapabilityInfo kvm_arch_required_capabilities[] = { -+ KVM_CAP_LAST_INFO -+}; -+/* 50000 jump to bootlader while 2f00000 jump to bios*/ -+int kvm_sw64_vcpu_init(CPUState *cs) -+{ -+ struct kvm_regs *regs; -+ SW64CPU *cpu = SW64_CPU(cs); -+ regs = (struct kvm_regs *)cpu->k_regs; -+ regs->pc = init_pc; -+ return kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); -+} -+ -+static void kvm_sw64_host_cpu_class_init(ObjectClass *oc, void *data) -+{ -+} -+ -+static void kvm_sw64_host_cpu_initfn(Object *obj) -+{ -+} -+ -+ -+static const TypeInfo host_sw64_cpu_type_info = { -+ .name = TYPE_SW64_HOST_CPU, -+ .parent = TYPE_SW64_CPU, -+ .instance_init = kvm_sw64_host_cpu_initfn, -+ .class_init = kvm_sw64_host_cpu_class_init, -+ .class_size = sizeof(SW64HostCPUClass), -+}; -+ -+int kvm_arch_init(MachineState *ms, KVMState *s) -+{ -+ kvm_async_interrupts_allowed = true; -+ -+ type_register_static(&host_sw64_cpu_type_info); -+ -+ return 0; -+} -+ -+/* 50000 jump to bootlader while 2f00000 jump to bios*/ -+void kvm_sw64_reset_vcpu(SW64CPU *cpu) -+{ -+ CPUState *cs = CPU(cpu); -+ struct kvm_regs *regs; -+ int ret; -+ -+ regs = (struct kvm_regs *)cpu->k_regs; -+ regs->pc = init_pc; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); -+ -+ if (ret < 0) { -+ fprintf(stderr, "kvm_sw64_vcpu_init failed: %s\n", strerror(-ret)); -+ abort(); -+ } -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SW64_VCPU_INIT, NULL); -+ -+ if (ret < 0) { -+ fprintf(stderr, "kvm_sw64_vcpu_init failed: %s\n", strerror(-ret)); -+ abort(); -+ } -+} -+ -+unsigned long kvm_arch_vcpu_id(CPUState *cpu) -+{ -+ return cpu->cpu_index; -+} -+ -+#include -+int kvm_arch_init_vcpu(CPUState *cs) -+{ -+ int ret; -+ ret = kvm_sw64_vcpu_init(cs); -+ if (ret) { -+ return ret; -+ } -+ return 0; -+} -+ -+int kvm_arch_destroy_vcpu(CPUState *cs) -+{ -+ return 0; -+} -+ -+int kvm_arch_get_registers(CPUState *cs) -+{ -+ int ret; -+ SW64CPU *cpu = SW64_CPU(cs); -+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &cpu->k_regs); -+ if (ret < 0) -+ return ret; -+ return kvm_vcpu_ioctl(cs, KVM_SW64_GET_VCB, &cpu->k_vcb); -+} -+ -+int kvm_arch_put_registers(CPUState *cs, int level) -+{ -+ int ret; -+ SW64CPU *cpu = SW64_CPU(cs); -+ struct vcpucb *vcb; -+ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &cpu->k_regs); -+ if (ret < 0) -+ return ret; -+ vcb = (struct vcpucb *)cpu->k_vcb; -+ vcb->whami = kvm_arch_vcpu_id(cs); -+ fprintf(stderr,"vcpu %ld init.\n", vcb->whami); -+ return kvm_vcpu_ioctl(cs, KVM_SW64_SET_VCB, &cpu->k_vcb); -+} -+ -+int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, -+ int vector, PCIDevice *dev) -+{ -+ return -1; -+} -+ -+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, -+ uint64_t address, uint32_t data, PCIDevice *dev) -+{ -+ return 0; -+} -+ -+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) -+{ -+} -+ -+MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) -+{ -+ return MEMTXATTRS_UNSPECIFIED; -+} -+ -+ -+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) -+{ -+ return -1; -+} -+ -+bool kvm_arch_stop_on_emulation_error(CPUState *cs) -+{ -+ return true; -+} -+ -+int kvm_arch_process_async_events(CPUState *cs) -+{ -+ return 0; -+} -+ -+void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg) -+{ -+} -+ -+void kvm_arch_init_irq_routing(KVMState *s) -+{ -+ /* We know at this point that we're using the in-kernel -+ * irqchip, so we can use irqfds, and on x86 we know -+ * we can use msi via irqfd and GSI routing. -+ */ -+ kvm_msi_via_irqfd_allowed = true; -+ kvm_gsi_routing_allowed = true; -+} -+ -+int kvm_arch_irqchip_create(KVMState *s) -+{ -+ return 0; -+} -+ -+int kvm_arch_release_virq_post(int virq) -+{ -+ return -1; -+} -+ -+int kvm_arch_msi_data_to_gsi(uint32_t data) -+{ -+ return -1; -+} -+ -+ -+void kvm_sw64_register_slave(SW64CPU *cpu) -+{ -+ CPUState *cs = CPU(cpu); -+ -+ kvm_vcpu_ioctl(cs, KVM_SW64_USE_SLAVE, NULL); -+} -+ -+bool kvm_arch_cpu_check_are_resettable(void) -+{ -+ return true; -+} -diff --git a/target/sw64/kvm_sw64.h b/target/sw64/kvm_sw64.h -new file mode 100644 -index 0000000000..5ebd4ec6fd ---- /dev/null -+++ b/target/sw64/kvm_sw64.h -@@ -0,0 +1,47 @@ -+/* -+ * QEMU KVM support -- SW64 specific functions. -+ * -+ * Copyright (c) 2018 Lin Hainan -+ * -+ * 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_KVM_SW64_H -+#define QEMU_KVM_SW64_H -+ -+#include "sysemu/kvm.h" -+#include "exec/memory.h" -+#include "qemu/error-report.h" -+ -+/** -+ * kvm_sw64_vcpu_init: -+ * @cs: CPUState -+ * -+ * Initialize (or reinitialize) the VCPU by invoking the -+ * KVM_SW64_VCPU_INIT ioctl with the CPU type and feature -+ * bitmask specified in the CPUState. -+ * -+ * Returns: 0 if success else < 0 error code -+ */ -+int kvm_sw64_vcpu_init(CPUState *cs); -+void kvm_sw64_reset_vcpu(SW64CPU *cpu); -+void kvm_sw64_register_slave(SW64CPU *cpu); -+ -+#define TYPE_SW64_HOST_CPU "host-" TYPE_SW64_CPU -+#define SW64_HOST_CPU_CLASS(klass) \ -+ OBJECT_CLASS_CHECK(SW64HostCPUClass, (klass), TYPE_SW64_HOST_CPU) -+#define SW64_HOST_CPU_GET_CLASS(obj) \ -+ OBJECT_GET_CLASS(SW64HostCPUClass, (obj), TYPE_SW64_HOST_CPU) -+ -+typedef struct SW64HostCPUClass { -+ /*< private >*/ -+ SW64CPUClass parent_class; -+ /*< public >*/ -+ -+ uint64_t features; -+ uint32_t target; -+ const char *dtb_compatible; -+} SW64HostCPUClass; -+#endif -diff --git a/target/sw64/machine.c b/target/sw64/machine.c -new file mode 100644 -index 0000000000..df18d3faba ---- /dev/null -+++ b/target/sw64/machine.c -@@ -0,0 +1,18 @@ -+#include "qemu/osdep.h" -+#include "qemu-common.h" -+#include "cpu.h" -+#include "migration/vmstate.h" -+#include "migration/cpu.h" -+ -+VMStateDescription vmstate_sw64_cpu = { -+ .name = "cpu", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .fields = (VMStateField[]) { -+#ifdef CONFIG_KVM -+ VMSTATE_UINTTL_ARRAY(k_regs, SW64CPU, 158), -+ VMSTATE_UINTTL_ARRAY(k_vcb, SW64CPU, 36), -+#endif -+ VMSTATE_END_OF_LIST() -+ } -+}; -diff --git a/target/sw64/meson.build b/target/sw64/meson.build -new file mode 100644 -index 0000000000..ee49e45927 ---- /dev/null -+++ b/target/sw64/meson.build -@@ -0,0 +1,19 @@ -+sw64_ss = ss.source_set() -+sw64_ss.add(files( -+ 'cpu.c', -+ 'exception.c', -+ 'float_helper.c', -+ 'helper.c', -+ 'int_helper.c', -+ 'profile.c', -+ 'simd_helper.c', -+ 'translate.c', -+)) -+ -+sw64_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) -+ -+sw64_softmmu_ss = ss.source_set() -+sw64_softmmu_ss.add(files('machine.c')) -+ -+target_arch += {'sw64': sw64_ss} -+target_softmmu_arch += {'sw64': sw64_softmmu_ss} -diff --git a/target/sw64/profile.c b/target/sw64/profile.c -new file mode 100644 -index 0000000000..73fe077234 ---- /dev/null -+++ b/target/sw64/profile.c -@@ -0,0 +1,2342 @@ -+#include "translate.h" -+ -+const char *insn_opc[535] = { -+ "sys_call", "call", "ret", "jmp", "br", "bsr", "memb", "imemb", -+ "wmemb", "rtc", "rcid", "halt", "rd_f", "wr_f", "rtid", -+ "csrws", "csrwc", "pri_rcsr", "pri_wcsr", "pri_ret", "lldw", "lldl", -+ "ldw_inc", "ldl_inc", "ldw_dec", "ldl_dec", "ldw_set", "ldl_set", "lstw", -+ "lstl", "ldw_nc", "ldl_nc", "ldd_nc", "stw_nc", "stl_nc", "std_nc", -+ "ldwe", "ldse", "ldde", "vlds", "vldd", "vsts", "vstd", -+ "fimovs", "fimovd", "addw", "subw", "s4addw", "s4subw", "s8addw", -+ "s8subw", "addl", "subl", "s4addl", "s4subl", "s8addl", "s8subl", -+ "mulw", "divw", "udivw", "remw", "uremw", "mull", "mulh", -+ "divl", "udivl", "reml", "ureml", "addpi", "addpis", "cmpeq", -+ "cmplt", "cmple", "cmpult", "cmpule", "sbt", "cbt", "and", -+ "bic", "bis", "ornot", "xor", "eqv", "inslb", "inslh", -+ "inslw", "insll", "inshb", "inshh", "inshw", "inshl", "slll", -+ "srll", "sral", "roll", "sllw", "srlw", "sraw", "rolw", -+ "extlb", "extlh", "extlw", "extll", "exthb", "exthh", "exthw", -+ "exthl", "ctpop", "ctlz", "cttz", "revbh", "revbw", "revbl", -+ "casw", "casl", "masklb", "masklh", "masklw", "maskll", "maskhb", -+ "maskhh", "maskhw", "maskhl", "zap", "zapnot", "sextb", "sexth", -+ "seleq", "selge", "selgt", "selle", "sellt", "selne", "sellbc", -+ "sellbs", "addwi", "subwi", "s4addwi", "s4subwi", "s8addwi", "s8subwi", -+ "addli", "subli", "s4addli", "s4subli", "s8addli", "s8subli", "mulwi", -+ "divwi", "udivwi", "remwi", "uremwi", "mulli", "mulhi", "divli", -+ "udivli", "remli", "uremli", "addpii", "addpisi", "cmpeqi", "cmplti", -+ "cmplei", "cmpulti", "cmpulei", "sbti", "cbti", "andi", "bici", -+ "bisi", "ornoti", "xori", "eqvi", "inslbi", "inslhi", "inslwi", -+ "inslli", "inshbi", "inshhi", "inshwi", "inshli", "sllli", "srlli", -+ "srali", "rolli", "sllwi", "srlwi", "srawi", "rolwi", "extlbi", -+ "extlhi", "extlwi", "extlli", "exthbi", "exthhi", "exthwi", "exthli", -+ "ctpopi", "ctlzi", "cttzi", "revbhi", "revbwi", "revbli", "caswi", -+ "casli", "masklbi", "masklhi", "masklwi", "masklli", "maskhbi", "maskhhi", -+ "maskhwi", "maskhli", "zapi", "zapnoti", "sextbi", "sexthi", "cmpgebi", -+ "seleqi", "selgei", "selgti", "sellei", "sellti", "selnei", "sellbci", -+ "sellbsi", "vlogzz", "fadds", "faddd", "fsubs", "fsubd", "fmuls", -+ "fmuld", "fdivs", "fdivd", "fsqrts", "fsqrtd", "fcmpeq", "fcmple", -+ "fcmplt", "fcmpun", "fcvtsd", "fcvtds", "fcvtdl_g", "fcvtdl_p", "fcvtdl_z", -+ "fcvtdl_n", "fcvtdl", "fcvtwl", "fcvtlw", "fcvtls", "fcvtld", "fcpys", -+ "fcpyse", "fcpysn", "ifmovs", "ifmovd", "rfpcr", "wfpcr", "setfpec0", -+ "setfpec1", "setfpec2", "setfpec3", "frecs", "frecd", "fris", "fris_g", -+ "fris_p", "fris_z", "fris_n", "frid", "frid_g", "frid_p", "frid_z", -+ "frid_n", "fmas", "fmad", "fmss", "fmsd", "fnmas", "fnmad", -+ "fnmss", "fnmsd", "fseleq", "fselne", "fsellt", "fselle", "fselgt", -+ "fselge", "vaddw", "vaddwi", "vsubw", "vsubwi", "vcmpgew", "vcmpgewi", -+ "vcmpeqw", "vcmpeqwi", "vcmplew", "vcmplewi", "vcmpltw", "vcmpltwi", "vcmpulew", -+ "vcmpulewi", "vcmpultw", "vcmpultwi", "vsllw", "vsllwi", "vsrlw", "vsrlwi", -+ "vsraw", "vsrawi", "vrolw", "vrolwi", "sllow", "sllowi", "srlow", -+ "srlowi", "vaddl", "vaddli", "vsubl", "vsubli", "vsllb", "vsllbi", -+ "vsrlb", "vsrlbi", "vsrab", "vsrabi", "vrolb", "vrolbi", "vsllh", -+ "vsllhi", "vsrlh", "vsrlhi", "vsrah", "vsrahi", "vrolh", "vrolhi", -+ "ctpopow", "ctlzow", "vslll", "vsllli", "vsrll", "vsrlli", "vsral", -+ "vsrali", "vroll", "vrolli", "vmaxb", "vminb", "vucaddw", "vucaddwi", -+ "vucsubw", "vucsubwi", "vucaddh", "vucaddhi", "vucsubh", "vucsubhi", "vucaddb", -+ "vucaddbi", "vucsubb", "vucsubbi", "sraow", "sraowi", "vsumw", "vsuml", -+ "vsm4r", "vbinvw", "vcmpueqb", "vcmpugtb", "vcmpugtbi", "vsm3msw", "vmaxh", -+ "vminh", "vmaxw", "vminw", "vmaxl", "vminl", "vumaxb", "vuminb", -+ "vumaxh", "vuminh", "vumaxw", "vuminw", "vumaxl", "vuminl", "vsm4key", -+ "vadds", "vaddd", "vsubs", "vsubd", "vmuls", "vmuld", "vdivs", -+ "vdivd", "vsqrts", "vsqrtd", "vfcmpeq", "vfcmple", "vfcmplt", "vfcmpun", -+ "vcpys", "vcpyse", "vcpysn", "vsums", "vsumd", "vfcvtsd", "vfcvtds", -+ "vfcvtls", "vfcvtld", "vfcvtdl", "vfcvtdl_g", "vfcvtdl_p", "vfcvtdl_z", "vfcvtdl_n", -+ "vfris", "vfris_g", "vfris_p", "vfris_z", "vfris_n", "vfrid", "vfrid_g", -+ "vfrid_p", "vfrid_z", "vfrid_n", "vfrecs", "vfrecd", "vmaxs", "vmins", -+ "vmaxd", "vmind", "vmas", "vmad", "vmss", "vmsd", "vnmas", -+ "vnmad", "vnmss", "vnmsd", "vfseleq", "vfsellt", "vfselle", "vseleqw", -+ "vseleqwi", "vsellbcw", "vsellbcwi", "vselltw", "vselltwi", "vsellew", "vsellewi", -+ "vinsw", "vinsf", "vextw", "vextf", "vcpyw", "vcpyf", "vconw", -+ "vshfw", "vcons", "vcond", "vinsb", "vinsh", "vinsectlh", "vinsectlw", -+ "vinsectll", "vinsectlb", "vshfq", "vshfqb", "vcpyb", "vcpyh", "vsm3r", -+ "vfcvtsh", "vfcvths", "vldw_u", "vstw_u", "vlds_u", "vsts_u", "vldd_u", -+ "vstd_u", "vstw_ul", "vstw_uh", "vsts_ul", "vsts_uh", "vstd_ul", "vstd_uh", -+ "vldd_nc", "vstd_nc", "lbr", "ldbu_a", "ldhu_a", "ldw_a", "ldl_a", -+ "flds_a", "fldd_a", "stbu_a", "sthu_a", "stw_a", "stl_a", "fsts_a", -+ "fstd_a", "dpfhr", "dpfhw", "ldbu", "ldhu", "ldw", "ldl", -+ "ldl_u", "pri_ldl", "pri_ldw", "flds", "fldd", "stb", "sth", -+ "stw", "stl", "stl_u", "pri_stl", "pri_stw", "fsts", "fstd", -+ "beq", "bne", "blt", "ble", "bgt", "bge", "blbc", -+ "blbs", "fbeq", "fbne", "fblt", "fble", "fbgt", "fbge", -+ "ldih", "ldi", }; -+ -+void insn_profile(DisasContext *ctx, uint32_t insn) -+{ -+ int32_t disp16, disp26 __attribute__((unused)); -+ uint8_t opc; -+ uint16_t fn3, fn4, fn6, fn8, fn11; -+ TCGv count; -+ int index, offs; -+ -+ opc = extract32(insn, 26, 6); -+ -+ fn3 = extract32(insn, 10, 3); -+ fn6 = extract32(insn, 10, 6); -+ fn4 = extract32(insn, 12, 4); -+ fn8 = extract32(insn, 5, 8); -+ fn11 = extract32(insn, 5, 11); -+ -+ disp16 = sextract32(insn, 0, 16); -+ disp26 = sextract32(insn, 0, 26); -+ -+ index = 0; -+ switch (opc) { -+ case 0x00: -+ /* SYS_CALL */ -+ index = SYS_CALL; -+ break; -+ case 0x01: -+ /* CALL */ -+ index = CALL; -+ break; -+ case 0x02: -+ /* RET */ -+ index = RET; -+ break; -+ case 0x03: -+ /* JMP */ -+ index = JMP; -+ break; -+ case 0x04: -+ /* BR */ -+ index = BR; -+ break; -+ case 0x05: -+ /* BSR */ -+ index = BSR; -+ break; -+ case 0x06: -+ switch (disp16) { -+ case 0x0000: -+ /* MEMB */ -+ index = MEMB; -+ break; -+ case 0x0001: -+ /* IMEMB */ -+ index = IMEMB; -+ break; -+ case 0x0002: -+ /* WMEMB */ -+ index = WMEMB; -+ break; -+ case 0x0020: -+ /* RTC */ -+ index = RTC; -+ break; -+ case 0x0040: -+ /* RCID */ -+ index = RCID; -+ break; -+ case 0x0080: -+ /* HALT */ -+ index = HALT; -+ break; -+ case 0x1000: -+ /* RD_F */ -+ index = RD_F; -+ break; -+ case 0x1020: -+ /* WR_F */ -+ index = WR_F; -+ break; -+ case 0x1040: -+ /* RTID */ -+ index = RTID; -+ break; -+ default: -+ if ((disp16 & 0xFF00) == 0xFC00) { -+ /* CSRWS */ -+ index = CSRWS; -+ break; -+ } -+ if ((disp16 & 0xFF00) == 0xFD00) { -+ /* CSRWC */ -+ index = CSRWC; -+ break; -+ } -+ if ((disp16 & 0xFF00) == 0xFE00) { -+ /* PRI_RCSR */ -+ index = PRI_RCSR; -+ break; -+ } -+ if ((disp16 & 0xFF00) == 0xFF00) { -+ /* PRI_WCSR */ -+ index = PRI_WCSR; -+ break; -+ } -+ goto do_invalid; -+ } -+ break; -+ case 0x07: -+ /* PRI_RET */ -+ index = PRI_RET; -+ break; -+ case 0x08: -+ switch (fn4) { -+ case 0x0: -+ /* LLDW */ -+ index = LLDW; -+ break; -+ case 0x1: -+ /* LLDL */ -+ index = LLDL; -+ break; -+ case 0x2: -+ /* LDW_INC */ -+ index = LDW_INC; -+ break; -+ case 0x3: -+ /* LDL_INC */ -+ index = LDL_INC; -+ break; -+ case 0x4: -+ /* LDW_DEC */ -+ index = LDW_DEC; -+ break; -+ case 0x5: -+ /* LDL_DEC */ -+ index = LDL_DEC; -+ break; -+ case 0x6: -+ /* LDW_SET */ -+ index = LDW_SET; -+ break; -+ case 0x7: -+ /* LDL_SET */ -+ index = LDL_SET; -+ break; -+ case 0x8: -+ /* LSTW */ -+ index = LSTW; -+ break; -+ case 0x9: -+ /* LSTL */ -+ index = LSTL; -+ break; -+ case 0xa: -+ /* LDW_NC */ -+ index = LDW_NC; -+ break; -+ case 0xb: -+ /* LDL_NC */ -+ index = LDL_NC; -+ break; -+ case 0xc: -+ /* LDD_NC */ -+ index = LDD_NC; -+ break; -+ case 0xd: -+ /* STW_NC */ -+ index = STW_NC; -+ break; -+ case 0xe: -+ /* STL_NC */ -+ index = STL_NC; -+ break; -+ case 0xf: -+ /* STD_NC */ -+ index = STD_NC; -+ break; -+ default: -+ goto do_invalid; -+ } -+ break; -+ case 0x9: -+ /* LDWE */ -+ index = LDWE; -+ break; -+ case 0x0a: -+ /* LDSE */ -+ index = LDSE; -+ break; -+ case 0x0b: -+ /* LDDE */ -+ index = LDDE; -+ break; -+ case 0x0c: -+ /* VLDS */ -+ index = VLDS; -+ break; -+ case 0x0d: -+ /* VLDD */ -+ index = VLDD; -+ break; -+ case 0x0e: -+ /* VSTS */ -+ index = VSTS; -+ break; -+ case 0x0f: -+ /* VSTD */ -+ index = VSTD; -+ break; -+ case 0x10: -+ if (fn11 == 0x70) { -+ /* FIMOVS */ -+ index = FIMOVS; -+ } else if (fn11 == 0x78) { -+ /* FIMOVD */ -+ index = FIMOVD; -+ } else { -+ switch (fn11 & 0xff) { -+ case 0x00: -+ /* ADDW */ -+ index = ADDW; -+ break; -+ case 0x01: -+ /* SUBW */ -+ index = SUBW; -+ break; -+ case 0x02: -+ /* S4ADDW */ -+ index = S4ADDW; -+ break; -+ case 0x03: -+ /* S4SUBW */ -+ index = S4SUBW; -+ break; -+ case 0x04: -+ /* S8ADDW */ -+ index = S8ADDW; -+ break; -+ case 0x05: -+ /* S8SUBW */ -+ index = S8SUBW; -+ break; -+ -+ case 0x08: -+ /* ADDL */ -+ index = ADDL; -+ break; -+ case 0x09: -+ /* SUBL */ -+ index = SUBL; -+ break; -+ case 0x0a: -+ /* S4ADDL */ -+ index = S4ADDL; -+ break; -+ case 0x0b: -+ /* S4SUBL */ -+ index = S4SUBL; -+ break; -+ case 0x0c: -+ /* S8ADDL */ -+ index = S8ADDL; -+ break; -+ case 0x0d: -+ /* S8SUBL */ -+ index = S8SUBL; -+ break; -+ case 0x10: -+ /* MULW */ -+ index = MULW; -+ break; -+ case 0x11: -+ /* DIVW */ -+ index = DIVW; -+ break; -+ case 0x12: -+ /* UDIVW */ -+ index = UDIVW; -+ break; -+ case 0x13: -+ /* REMW */ -+ index = REMW; -+ break; -+ case 0x14: -+ /* UREMW */ -+ index = UREMW; -+ break; -+ case 0x18: -+ /* MULL */ -+ index = MULL; -+ break; -+ case 0x19: -+ /* MULH */ -+ index = MULH; -+ break; -+ case 0x1A: -+ /* DIVL */ -+ index = DIVL; -+ break; -+ case 0x1B: -+ /* UDIVL */ -+ index = UDIVL; -+ break; -+ case 0x1C: -+ /* REML */ -+ index = REML; -+ break; -+ case 0x1D: -+ /* UREML */ -+ index = UREML; -+ break; -+ case 0x1E: -+ /* ADDPI */ -+ index = ADDPI; -+ break; -+ case 0x1F: -+ /* ADDPIS */ -+ index = ADDPIS; -+ break; -+ case 0x28: -+ /* CMPEQ */ -+ index = CMPEQ; -+ break; -+ case 0x29: -+ /* CMPLT */ -+ index = CMPLT; -+ break; -+ case 0x2a: -+ /* CMPLE */ -+ index = CMPLE; -+ break; -+ case 0x2b: -+ /* CMPULT */ -+ index = CMPULT; -+ break; -+ case 0x2c: -+ /* CMPULE */ -+ index = CMPULE; -+ break; -+ case 0x2D: -+ /* SBT */ -+ index = SBT; -+ break; -+ case 0x2E: -+ /* CBT */ -+ index = CBT; -+ break; -+ case 0x38: -+ /* AND */ -+ index = AND; -+ break; -+ case 0x39: -+ /* BIC */ -+ index = BIC; -+ break; -+ case 0x3a: -+ /* BIS */ -+ index = BIS; -+ break; -+ case 0x3b: -+ /* ORNOT */ -+ index = ORNOT; -+ break; -+ case 0x3c: -+ /* XOR */ -+ index = XOR; -+ break; -+ case 0x3d: -+ /* EQV */ -+ index = EQV; -+ break; -+ case 0x40: -+ /* INSLB */ -+ index = INSLB; -+ break; -+ case 0x41: -+ /* INSLH */ -+ index = INSLH; -+ break; -+ case 0x42: -+ /* INSLW */ -+ index = INSLW; -+ break; -+ case 0x43: -+ /* INSLL */ -+ index = INSLL; -+ break; -+ case 0x44: -+ /* INSHB */ -+ index = INSHB; -+ break; -+ case 0x45: -+ /* INSHH */ -+ index = INSHH; -+ break; -+ case 0x46: -+ /* INSHW */ -+ index = INSHW; -+ break; -+ case 0x47: -+ /* INSHL */ -+ index = INSHL; -+ break; -+ case 0x48: -+ /* SLLL */ -+ index = SLLL; -+ break; -+ case 0x49: -+ /* SRLL */ -+ index = SRLL; -+ break; -+ case 0x4a: -+ /* SRAL */ -+ index = SRAL; -+ break; -+ case 0x4B: -+ /* ROLL */ -+ index = ROLL; -+ break; -+ case 0x4C: -+ /* SLLW */ -+ index = SLLW; -+ break; -+ case 0x4D: -+ /* SRLW */ -+ index = SRLW; -+ break; -+ case 0x4E: -+ /* SRAW */ -+ index = SRAW; -+ break; -+ case 0x4F: -+ /* ROLW */ -+ index = ROLW; -+ break; -+ case 0x50: -+ /* EXTLB */ -+ index = EXTLB; -+ break; -+ case 0x51: -+ /* EXTLH */ -+ index = EXTLH; -+ break; -+ case 0x52: -+ /* EXTLW */ -+ index = EXTLW; -+ break; -+ case 0x53: -+ /* EXTLL */ -+ index = EXTLL; -+ break; -+ case 0x54: -+ /* EXTHB */ -+ index = EXTHB; -+ break; -+ case 0x55: -+ /* EXTHH */ -+ index = EXTHH; -+ break; -+ case 0x56: -+ /* EXTHW */ -+ index = EXTHW; -+ break; -+ case 0x57: -+ /* EXTHL */ -+ index = EXTHL; -+ break; -+ case 0x58: -+ /* CTPOP */ -+ index = CTPOP; -+ break; -+ case 0x59: -+ /* CTLZ */ -+ index = CTLZ; -+ break; -+ case 0x5a: -+ /* CTTZ */ -+ index = CTTZ; -+ break; -+ case 0x5B: -+ /* REVBH */ -+ index = REVBH; -+ break; -+ case 0x5C: -+ /* REVBW */ -+ index = REVBW; -+ break; -+ case 0x5D: -+ /* REVBL */ -+ index = REVBL; -+ break; -+ case 0x5E: -+ /* CASW */ -+ index = CASW; -+ break; -+ case 0x5F: -+ /* CASL */ -+ index = CASL; -+ break; -+ case 0x60: -+ /* MASKLB */ -+ index = MASKLB; -+ break; -+ case 0x61: -+ /* MASKLH */ -+ index = MASKLH; -+ break; -+ case 0x62: -+ /* MASKLW */ -+ index = MASKLW; -+ break; -+ case 0x63: -+ /* MASKLL */ -+ index = MASKLL; -+ break; -+ case 0x64: -+ /* MASKHB */ -+ index = MASKHB; -+ break; -+ case 0x65: -+ /* MASKHH */ -+ index = MASKHH; -+ break; -+ case 0x66: -+ /* MASKHW */ -+ index = MASKHW; -+ break; -+ case 0x67: -+ /* MASKHL */ -+ index = MASKHL; -+ break; -+ case 0x68: -+ /* ZAP */ -+ index = ZAP; -+ break; -+ case 0x69: -+ /* ZAPNOT */ -+ index = ZAPNOT; -+ break; -+ case 0x6a: -+ /* SEXTB */ -+ index = SEXTB; -+ break; -+ case 0x6b: -+ /* SEXTH */ -+ index = SEXTH; -+ break; -+ case 0x6c: -+ /* CMPGEB*/ -+ break; -+ default: -+ break; -+ } -+ } -+ break; -+ case 0x11: -+ switch (fn3) { -+ case 0x0: -+ /* SELEQ */ -+ index = SELEQ; -+ break; -+ case 0x1: -+ /* SELGE */ -+ index = SELGE; -+ break; -+ case 0x2: -+ /* SELGT */ -+ index = SELGT; -+ break; -+ case 0x3: -+ /* SELLE */ -+ index = SELLE; -+ break; -+ case 0x4: -+ /* SELLT */ -+ index = SELLT; -+ break; -+ case 0x5: -+ /* SELNE */ -+ index = SELNE; -+ break; -+ case 0x6: -+ /* SELLBC */ -+ index = SELLBC; -+ break; -+ case 0x7: -+ /* SELLBS */ -+ index = SELLBS; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x12: -+ switch (fn8 & 0xff) { -+ case 0x00: -+ /* ADDWI */ -+ index = ADDWI; -+ break; -+ case 0x01: -+ /* SUBWI */ -+ index = SUBWI; -+ break; -+ case 0x02: -+ /* S4ADDWI */ -+ index = S4ADDWI; -+ break; -+ case 0x03: -+ /* S4SUBWI */ -+ index = S4SUBWI; -+ break; -+ case 0x04: -+ /* S8ADDWI */ -+ index = S8ADDWI; -+ break; -+ case 0x05: -+ /* S8SUBWI */ -+ index = S8SUBWI; -+ break; -+ -+ case 0x08: -+ /* ADDLI */ -+ index = ADDLI; -+ break; -+ case 0x09: -+ /* SUBLI */ -+ index = SUBLI; -+ break; -+ case 0x0a: -+ /* S4ADDLI */ -+ index = S4ADDLI; -+ break; -+ case 0x0b: -+ /* S4SUBLI */ -+ index = S4SUBLI; -+ break; -+ case 0x0c: -+ /* S8ADDLI */ -+ index = S8ADDLI; -+ break; -+ case 0x0d: -+ /* S8SUBLI */ -+ index = S8SUBLI; -+ break; -+ case 0x10: -+ /* MULWI */ -+ index = MULWI; -+ break; -+ case 0x11: -+ /* DIVWI */ -+ index = DIVWI; -+ break; -+ case 0x12: -+ /* UDIVWI */ -+ index = UDIVWI; -+ break; -+ case 0x13: -+ /* REMWI */ -+ index = REMWI; -+ break; -+ case 0x14: -+ /* UREMWI */ -+ index = UREMWI; -+ break; -+ case 0x18: -+ /* MULLI */ -+ index = MULLI; -+ break; -+ case 0x19: -+ /* MULHI */ -+ index = MULHI; -+ break; -+ case 0x1A: -+ /* DIVLI */ -+ index = DIVLI; -+ break; -+ case 0x1B: -+ /* UDIVLI */ -+ index = UDIVLI; -+ break; -+ case 0x1C: -+ /* REMLI */ -+ index = REMLI; -+ break; -+ case 0x1D: -+ /* UREMLI */ -+ index = UREMLI; -+ break; -+ case 0x1E: -+ /* ADDPII */ -+ index = ADDPII; -+ break; -+ case 0x1F: -+ /* ADDPISI */ -+ index = ADDPISI; -+ break; -+ case 0x28: -+ /* CMPEQI */ -+ index = CMPEQI; -+ break; -+ case 0x29: -+ /* CMPLTI */ -+ index = CMPLTI; -+ break; -+ case 0x2a: -+ /* CMPLEI */ -+ index = CMPLEI; -+ break; -+ case 0x2b: -+ /* CMPULTI */ -+ index = CMPULTI; -+ break; -+ case 0x2c: -+ /* CMPULEI */ -+ index = CMPULEI; -+ break; -+ case 0x2D: -+ /* SBTI */ -+ index = SBTI; -+ break; -+ case 0x2E: -+ /* CBTI */ -+ index = CBTI; -+ break; -+ case 0x38: -+ /* ANDI */ -+ index = ANDI; -+ break; -+ case 0x39: -+ /* BICI */ -+ index = BICI; -+ break; -+ case 0x3a: -+ /* BISI */ -+ index = BISI; -+ break; -+ case 0x3b: -+ /* ORNOTI */ -+ index = ORNOTI; -+ break; -+ case 0x3c: -+ /* XORI */ -+ index = XORI; -+ break; -+ case 0x3d: -+ /* EQVI */ -+ index = EQVI; -+ break; -+ case 0x40: -+ /* INSLBI */ -+ index = INSLBI; -+ break; -+ case 0x41: -+ /* INSLHI */ -+ index = INSLHI; -+ break; -+ case 0x42: -+ /* INSLWI */ -+ index = INSLWI; -+ break; -+ case 0x43: -+ /* INSLLI */ -+ index = INSLLI; -+ break; -+ case 0x44: -+ /* INSHBI */ -+ index = INSHBI; -+ break; -+ case 0x45: -+ /* INSHHI */ -+ index = INSHHI; -+ break; -+ case 0x46: -+ /* INSHWI */ -+ index = INSHWI; -+ break; -+ case 0x47: -+ /* INSHLI */ -+ index = INSHLI; -+ break; -+ case 0x48: -+ /* SLLLI */ -+ index = SLLLI; -+ break; -+ case 0x49: -+ /* SRLLI */ -+ index = SRLLI; -+ break; -+ case 0x4a: -+ /* SRALI */ -+ index = SRALI; -+ break; -+ case 0x4B: -+ /* ROLLI */ -+ index = ROLLI; -+ break; -+ case 0x4C: -+ /* SLLWI */ -+ index = SLLWI; -+ break; -+ case 0x4D: -+ /* SRLWI */ -+ index = SRLWI; -+ break; -+ case 0x4E: -+ /* SRAWI */ -+ index = SRAWI; -+ break; -+ case 0x4F: -+ /* ROLWI */ -+ index = ROLWI; -+ break; -+ case 0x50: -+ /* EXTLBI */ -+ index = EXTLBI; -+ break; -+ case 0x51: -+ /* EXTLHI */ -+ index = EXTLHI; -+ break; -+ case 0x52: -+ /* EXTLWI */ -+ index = EXTLWI; -+ break; -+ case 0x53: -+ /* EXTLLI */ -+ index = EXTLLI; -+ break; -+ case 0x54: -+ /* EXTHBI */ -+ index = EXTHBI; -+ break; -+ case 0x55: -+ /* EXTHHI */ -+ index = EXTHHI; -+ break; -+ case 0x56: -+ /* EXTHWI */ -+ index = EXTHWI; -+ break; -+ case 0x57: -+ /* EXTHLI */ -+ index = EXTHLI; -+ break; -+ case 0x58: -+ /* CTPOPI */ -+ index = CTPOPI; -+ break; -+ case 0x59: -+ /* CTLZI */ -+ index = CTLZI; -+ break; -+ case 0x5a: -+ /* CTTZI */ -+ index = CTTZI; -+ break; -+ case 0x5B: -+ /* REVBHI */ -+ index = REVBHI; -+ break; -+ case 0x5C: -+ /* REVBWI */ -+ index = REVBWI; -+ break; -+ case 0x5D: -+ /* REVBLI */ -+ index = REVBLI; -+ break; -+ case 0x5E: -+ /* CASWI */ -+ index = CASWI; -+ break; -+ case 0x5F: -+ /* CASLI */ -+ index = CASLI; -+ break; -+ case 0x60: -+ /* MASKLBI */ -+ index = MASKLBI; -+ break; -+ case 0x61: -+ /* MASKLHI */ -+ index = MASKLHI; -+ break; -+ case 0x62: -+ /* MASKLWI */ -+ index = MASKLWI; -+ break; -+ case 0x63: -+ /* MASKLLI */ -+ index = MASKLLI; -+ break; -+ case 0x64: -+ /* MASKHBI */ -+ index = MASKHBI; -+ break; -+ case 0x65: -+ /* MASKHHI */ -+ index = MASKHHI; -+ break; -+ case 0x66: -+ /* MASKHWI */ -+ index = MASKHWI; -+ break; -+ case 0x67: -+ /* MASKHLI */ -+ index = MASKHLI; -+ break; -+ case 0x68: -+ /* ZAPI */ -+ index = ZAPI; -+ break; -+ case 0x69: -+ /* ZAPNOTI */ -+ index = ZAPNOTI; -+ break; -+ case 0x6a: -+ /* SEXTBI */ -+ index = SEXTBI; -+ break; -+ case 0x6b: -+ /* SEXTHI */ -+ index = SEXTHI; -+ break; -+ case 0x6c: -+ /* CMPGEBI */ -+ index = CMPGEBI; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x13: -+ switch (fn3) { -+ case 0x0: -+ /* SELEQI */ -+ index = SELEQI; -+ break; -+ case 0x1: -+ /* SELGEI */ -+ index = SELGEI; -+ break; -+ case 0x2: -+ /* SELGTI */ -+ index = SELGTI; -+ break; -+ case 0x3: -+ /* SELLEI */ -+ index = SELLEI; -+ break; -+ case 0x4: -+ /* SELLTI */ -+ index = SELLTI; -+ break; -+ case 0x5: -+ /* SELNEI */ -+ index = SELNEI; -+ break; -+ case 0x6: -+ /* SELLBCI */ -+ index = SELLBCI; -+ break; -+ case 0x7: -+ /* SELLBSI */ -+ index = SELLBSI; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x14: -+ case 0x15: -+ case 0x16: -+ case 0x17: -+ /* VLOGZZ */ -+ index = VLOGZZ; -+ break; -+ case 0x18: -+ switch (fn8) { -+ case 0x00: -+ /* FADDS */ -+ index = FADDS; -+ break; -+ case 0x01: -+ /* FADDD */ -+ index = FADDD; -+ break; -+ case 0x02: -+ /* FSUBS */ -+ index = FSUBS; -+ break; -+ case 0x03: -+ /* FSUBD */ -+ index = FSUBD; -+ break; -+ case 0x4: -+ /* FMULS */ -+ index = FMULS; -+ break; -+ case 0x05: -+ /* FMULD */ -+ index = FMULD; -+ break; -+ case 0x06: -+ /* FDIVS */ -+ index = FDIVS; -+ break; -+ case 0x07: -+ /* FDIVD */ -+ index = FDIVD; -+ break; -+ case 0x08: -+ /* FSQRTS */ -+ index = FSQRTS; -+ break; -+ case 0x09: -+ /* FSQRTD */ -+ index = FSQRTD; -+ break; -+ case 0x10: -+ /* FCMPEQ */ -+ index = FCMPEQ; -+ break; -+ case 0x11: -+ /* FCMPLE */ -+ index = FCMPLE; -+ break; -+ case 0x12: -+ /* FCMPLT */ -+ index = FCMPLT; -+ break; -+ case 0x13: -+ /* FCMPUN */ -+ index = FCMPUN; -+ break; -+ case 0x20: -+ /* FCVTSD */ -+ index = FCVTSD; -+ break; -+ case 0x21: -+ /* FCVTDS */ -+ index = FCVTDS; -+ break; -+ case 0x22: -+ /* FCVTDL_G */ -+ index = FCVTDL_G; -+ break; -+ case 0x23: -+ /* FCVTDL_P */ -+ index = FCVTDL_P; -+ break; -+ case 0x24: -+ /* FCVTDL_Z */ -+ index = FCVTDL_Z; -+ break; -+ case 0x25: -+ /* FCVTDL_N */ -+ index = FCVTDL_N; -+ break; -+ case 0x27: -+ /* FCVTDL */ -+ index = FCVTDL; -+ break; -+ case 0x28: -+ /* FCVTWL */ -+ index = FCVTWL; -+ break; -+ case 0x29: -+ /* FCVTLW */ -+ index = FCVTLW; -+ break; -+ case 0x2d: -+ /* FCVTLS */ -+ index = FCVTLS; -+ break; -+ case 0x2f: -+ /* FCVTLD */ -+ index = FCVTLD; -+ break; -+ case 0x30: -+ /* FCPYS */ -+ index = FCPYS; -+ break; -+ case 0x31: -+ /* FCPYSE */ -+ index = FCPYSE; -+ break; -+ case 0x32: -+ /* FCPYSN */ -+ index = FCPYSN; -+ break; -+ case 0x40: -+ /* IFMOVS */ -+ index = IFMOVS; -+ break; -+ case 0x41: -+ /* IFMOVD */ -+ index = IFMOVD; -+ break; -+ case 0x50: -+ /* RFPCR */ -+ index = RFPCR; -+ break; -+ case 0x51: -+ /* WFPCR */ -+ index = WFPCR; -+ break; -+ case 0x54: -+ /* SETFPEC0 */ -+ index = SETFPEC0; -+ break; -+ case 0x55: -+ /* SETFPEC1 */ -+ index = SETFPEC1; -+ break; -+ case 0x56: -+ /* SETFPEC2 */ -+ index = SETFPEC2; -+ break; -+ case 0x57: -+ /* SETFPEC3 */ -+ index = SETFPEC3; -+ break; -+ case 0x58: -+ /* FRECS */ -+ index = FRECS; -+ break; -+ case 0x59: -+ /* FRECD */ -+ index = FRECD; -+ break; -+ case 0x5A: -+ /* FRIS */ -+ index = FRIS; -+ break; -+ case 0x5B: -+ /* FRIS_G */ -+ index = FRIS_G; -+ break; -+ case 0x5C: -+ /* FRIS_P */ -+ index = FRIS_P; -+ break; -+ case 0x5D: -+ /* FRIS_Z */ -+ index = FRIS_Z; -+ break; -+ case 0x5F: -+ /* FRIS_N */ -+ index = FRIS_N; -+ break; -+ case 0x60: -+ /* FRID */ -+ index = FRID; -+ break; -+ case 0x61: -+ /* FRID_G */ -+ index = FRID_G; -+ break; -+ case 0x62: -+ /* FRID_P */ -+ index = FRID_P; -+ break; -+ case 0x63: -+ /* FRID_Z */ -+ index = FRID_Z; -+ break; -+ case 0x64: -+ /* FRID_N */ -+ index = FRID_N; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x19: -+ switch (fn6) { -+ case 0x00: -+ /* FMAS */ -+ index = FMAS; -+ break; -+ case 0x01: -+ /* FMAD */ -+ index = FMAD; -+ break; -+ case 0x02: -+ /* FMSS */ -+ index = FMSS; -+ break; -+ case 0x03: -+ /* FMSD */ -+ index = FMSD; -+ break; -+ case 0x04: -+ /* FNMAS */ -+ index = FNMAS; -+ break; -+ case 0x05: -+ /* FNMAD */ -+ index = FNMAD; -+ break; -+ case 0x06: -+ /* FNMSS */ -+ index = FNMSS; -+ break; -+ case 0x07: -+ /* FNMSD */ -+ index = FNMSD; -+ break; -+ case 0x10: -+ /* FSELEQ */ -+ index = FSELEQ; -+ break; -+ case 0x11: -+ /* FSELNE */ -+ index = FSELNE; -+ break; -+ case 0x12: -+ /* FSELLT */ -+ index = FSELLT; -+ break; -+ case 0x13: -+ /* FSELLE */ -+ index = FSELLE; -+ break; -+ case 0x14: -+ /* FSELGT */ -+ index = FSELGT; -+ break; -+ case 0x15: -+ /* FSELGE */ -+ index = FSELGE; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x1A: -+ switch (fn8) { -+ case 0x00: -+ /* VADDW */ -+ index = VADDW; -+ break; -+ case 0x20: -+ /* VADDWI */ -+ index = VADDWI; -+ break; -+ case 0x01: -+ /* VSUBW */ -+ index = VSUBW; -+ break; -+ case 0x21: -+ /* VSUBWI */ -+ index = VSUBWI; -+ break; -+ case 0x02: -+ /* VCMPGEW */ -+ index = VCMPGEW; -+ break; -+ case 0x22: -+ /* VCMPGEWI */ -+ index = VCMPGEWI; -+ break; -+ case 0x03: -+ /* VCMPEQW */ -+ index = VCMPEQW; -+ break; -+ case 0x23: -+ /* VCMPEQWI */ -+ index = VCMPEQWI; -+ break; -+ case 0x04: -+ /* VCMPLEW */ -+ index = VCMPLEW; -+ break; -+ case 0x24: -+ /* VCMPLEWI */ -+ index = VCMPLEWI; -+ break; -+ case 0x05: -+ /* VCMPLTW */ -+ index = VCMPLTW; -+ break; -+ case 0x25: -+ /* VCMPLTWI */ -+ index = VCMPLTWI; -+ break; -+ case 0x06: -+ /* VCMPULEW */ -+ index = VCMPULEW; -+ break; -+ case 0x26: -+ /* VCMPULEWI */ -+ index = VCMPULEWI; -+ break; -+ case 0x07: -+ /* VCMPULTW */ -+ index = VCMPULTW; -+ break; -+ case 0x27: -+ /* VCMPULTWI */ -+ index = VCMPULTWI; -+ break; -+ case 0x08: -+ /* VSLLW */ -+ index = VSLLW; -+ break; -+ case 0x28: -+ /* VSLLWI */ -+ index = VSLLWI; -+ break; -+ case 0x09: -+ /* VSRLW */ -+ index = VSRLW; -+ break; -+ case 0x29: -+ /* VSRLWI */ -+ index = VSRLWI; -+ break; -+ case 0x0A: -+ /* VSRAW */ -+ index = VSRAW; -+ break; -+ case 0x2A: -+ /* VSRAWI */ -+ index = VSRAWI; -+ break; -+ case 0x0B: -+ /* VROLW */ -+ index = VROLW; -+ break; -+ case 0x2B: -+ /* VROLWI */ -+ index = VROLWI; -+ break; -+ case 0x0C: -+ /* SLLOW */ -+ index = SLLOW; -+ break; -+ case 0x2C: -+ /* SLLOWI */ -+ index = SLLOWI; -+ break; -+ case 0x0D: -+ /* SRLOW */ -+ index = SRLOW; -+ break; -+ case 0x2D: -+ /* SRLOWI */ -+ index = SRLOWI; -+ break; -+ case 0x0E: -+ /* VADDL */ -+ index = VADDL; -+ break; -+ case 0x2E: -+ /* VADDLI */ -+ index = VADDLI; -+ break; -+ case 0x0F: -+ /* VSUBL */ -+ index = VSUBL; -+ break; -+ case 0x2F: -+ /* VSUBLI */ -+ index = VSUBLI; -+ break; -+ case 0x10: -+ /* VSLLB */ -+ index = VSLLB; -+ break; -+ case 0x30: -+ /* VSLLBI */ -+ index = VSLLBI; -+ break; -+ case 0x11: -+ /* VSRLB */ -+ index = VSRLB; -+ break; -+ case 0x31: -+ /* VSRLBI */ -+ index = VSRLBI; -+ break; -+ case 0x12: -+ /* VSRAB */ -+ index = VSRAB; -+ break; -+ case 0x32: -+ /* VSRABI */ -+ index = VSRABI; -+ break; -+ case 0x13: -+ /* VROLB */ -+ index = VROLB; -+ break; -+ case 0x33: -+ /* VROLBI */ -+ index = VROLBI; -+ break; -+ case 0x14: -+ /* VSLLH */ -+ index = VSLLH; -+ break; -+ case 0x34: -+ /* VSLLHI */ -+ index = VSLLHI; -+ break; -+ case 0x15: -+ /* VSRLH */ -+ index = VSRLH; -+ break; -+ case 0x35: -+ /* VSRLHI */ -+ index = VSRLHI; -+ break; -+ case 0x16: -+ /* VSRAH */ -+ index = VSRAH; -+ break; -+ case 0x36: -+ /* VSRAHI */ -+ index = VSRAHI; -+ break; -+ case 0x17: -+ /* VROLH */ -+ index = VROLH; -+ break; -+ case 0x37: -+ /* VROLHI */ -+ index = VROLHI; -+ break; -+ case 0x18: -+ /* CTPOPOW */ -+ index = CTPOPOW; -+ break; -+ case 0x19: -+ /* CTLZOW */ -+ index = CTLZOW; -+ break; -+ case 0x1A: -+ /* VSLLL */ -+ index = VSLLL; -+ break; -+ case 0x3A: -+ /* VSLLLI */ -+ index = VSLLLI; -+ break; -+ case 0x1B: -+ /* VSRLL */ -+ index = VSRLL; -+ break; -+ case 0x3B: -+ /* VSRLLI */ -+ index = VSRLLI; -+ break; -+ case 0x1C: -+ /* VSRAL */ -+ index = VSRAL; -+ break; -+ case 0x3C: -+ /* VSRALI */ -+ index = VSRALI; -+ break; -+ case 0x1D: -+ /* VROLL */ -+ index = VROLL; -+ break; -+ case 0x3D: -+ /* VROLLI */ -+ index = VROLLI; -+ break; -+ case 0x1E: -+ /* VMAXB */ -+ index = VMAXB; -+ break; -+ case 0x1F: -+ /* VMINB */ -+ index = VMINB; -+ break; -+ case 0x40: -+ /* VUCADDW */ -+ index = VUCADDW; -+ break; -+ case 0x60: -+ /* VUCADDWI */ -+ index = VUCADDWI; -+ break; -+ case 0x41: -+ /* VUCSUBW */ -+ index = VUCSUBW; -+ break; -+ case 0x61: -+ /* VUCSUBWI */ -+ index = VUCSUBWI; -+ break; -+ case 0x42: -+ /* VUCADDH */ -+ index = VUCADDH; -+ break; -+ case 0x62: -+ /* VUCADDHI */ -+ index = VUCADDHI; -+ break; -+ case 0x43: -+ /* VUCSUBH */ -+ index = VUCSUBH; -+ break; -+ case 0x63: -+ /* VUCSUBHI */ -+ index = VUCSUBHI; -+ break; -+ case 0x44: -+ /* VUCADDB */ -+ index = VUCADDB; -+ break; -+ case 0x64: -+ /* VUCADDBI */ -+ index = VUCADDBI; -+ break; -+ case 0x45: -+ /* VUCSUBB */ -+ index = VUCSUBB; -+ break; -+ case 0x65: -+ /* VUCSUBBI */ -+ index = VUCSUBBI; -+ break; -+ case 0x46: -+ /* SRAOW */ -+ index = SRAOW; -+ break; -+ case 0x66: -+ /* SRAOWI */ -+ index = SRAOWI; -+ break; -+ case 0x47: -+ /* VSUMW */ -+ index = VSUMW; -+ break; -+ case 0x48: -+ /* VSUML */ -+ index = VSUML; -+ break; -+ case 0x49: -+ /* VSM4R */ -+ index = VSM4R; -+ break; -+ case 0x4A: -+ /* VBINVW */ -+ index = VBINVW; -+ break; -+ case 0x4B: -+ /* VCMPUEQB */ -+ index = VCMPUEQB; -+ break; -+ case 0x6B: -+ /* VCMPUEQBI*/ -+ break; -+ case 0x4C: -+ /* VCMPUGTB */ -+ index = VCMPUGTB; -+ break; -+ case 0x6C: -+ /* VCMPUGTBI */ -+ index = VCMPUGTBI; -+ break; -+ case 0x4D: -+ /* VSM3MSW */ -+ index = VSM3MSW; -+ break; -+ case 0x50: -+ /* VMAXH */ -+ index = VMAXH; -+ break; -+ case 0x51: -+ /* VMINH */ -+ index = VMINH; -+ break; -+ case 0x52: -+ /* VMAXW */ -+ index = VMAXW; -+ break; -+ case 0x53: -+ /* VMINW */ -+ index = VMINW; -+ break; -+ case 0x54: -+ /* VMAXL */ -+ index = VMAXL; -+ break; -+ case 0x55: -+ /* VMINL */ -+ index = VMINL; -+ break; -+ case 0x56: -+ /* VUMAXB */ -+ index = VUMAXB; -+ break; -+ case 0x57: -+ /* VUMINB */ -+ index = VUMINB; -+ break; -+ case 0x58: -+ /* VUMAXH */ -+ index = VUMAXH; -+ break; -+ case 0x59: -+ /* VUMINH */ -+ index = VUMINH; -+ break; -+ case 0x5A: -+ /* VUMAXW */ -+ index = VUMAXW; -+ break; -+ case 0x5B: -+ /* VUMINW */ -+ index = VUMINW; -+ break; -+ case 0x5C: -+ /* VUMAXL */ -+ index = VUMAXL; -+ break; -+ case 0x5D: -+ /* VUMINL */ -+ index = VUMINL; -+ break; -+ case 0x68: -+ /* VSM4KEY */ -+ index = VSM4KEY; -+ break; -+ case 0x80: -+ /* VADDS */ -+ index = VADDS; -+ break; -+ case 0x81: -+ /* VADDD */ -+ index = VADDD; -+ break; -+ case 0x82: -+ /* VSUBS */ -+ index = VSUBS; -+ break; -+ case 0x83: -+ /* VSUBD */ -+ index = VSUBD; -+ break; -+ case 0x84: -+ /* VMULS */ -+ index = VMULS; -+ break; -+ case 0x85: -+ /* VMULD */ -+ index = VMULD; -+ break; -+ case 0x86: -+ /* VDIVS */ -+ index = VDIVS; -+ break; -+ case 0x87: -+ /* VDIVD */ -+ index = VDIVD; -+ break; -+ case 0x88: -+ /* VSQRTS */ -+ index = VSQRTS; -+ break; -+ case 0x89: -+ /* VSQRTD */ -+ index = VSQRTD; -+ break; -+ case 0x8C: -+ /* VFCMPEQ */ -+ index = VFCMPEQ; -+ break; -+ case 0x8D: -+ /* VFCMPLE */ -+ index = VFCMPLE; -+ break; -+ case 0x8E: -+ /* VFCMPLT */ -+ index = VFCMPLT; -+ break; -+ case 0x8F: -+ /* VFCMPUN */ -+ index = VFCMPUN; -+ break; -+ case 0x90: -+ /* VCPYS */ -+ index = VCPYS; -+ break; -+ case 0x91: -+ /* VCPYSE */ -+ index = VCPYSE; -+ break; -+ case 0x92: -+ /* VCPYSN */ -+ index = VCPYSN; -+ break; -+ case 0x93: -+ /* VSUMS */ -+ index = VSUMS; -+ break; -+ case 0x94: -+ /* VSUMD */ -+ index = VSUMD; -+ break; -+ case 0x95: -+ /* VFCVTSD */ -+ index = VFCVTSD; -+ break; -+ case 0x96: -+ /* VFCVTDS */ -+ index = VFCVTDS; -+ break; -+ case 0x99: -+ /* VFCVTLS */ -+ index = VFCVTLS; -+ break; -+ case 0x9A: -+ /* VFCVTLD */ -+ index = VFCVTLD; -+ break; -+ case 0x9B: -+ /* VFCVTDL */ -+ index = VFCVTDL; -+ break; -+ case 0x9C: -+ /* VFCVTDL_G */ -+ index = VFCVTDL_G; -+ break; -+ case 0x9D: -+ /* VFCVTDL_P */ -+ index = VFCVTDL_P; -+ break; -+ case 0x9E: -+ /* VFCVTDL_Z */ -+ index = VFCVTDL_Z; -+ break; -+ case 0x9F: -+ /* VFCVTDL_N */ -+ index = VFCVTDL_N; -+ break; -+ case 0xA0: -+ /* VFRIS */ -+ index = VFRIS; -+ break; -+ case 0xA1: -+ /* VFRIS_G */ -+ index = VFRIS_G; -+ break; -+ case 0xA2: -+ /* VFRIS_P */ -+ index = VFRIS_P; -+ break; -+ case 0xA3: -+ /* VFRIS_Z */ -+ index = VFRIS_Z; -+ break; -+ case 0xA4: -+ /* VFRIS_N */ -+ index = VFRIS_N; -+ break; -+ case 0xA5: -+ /* VFRID */ -+ index = VFRID; -+ break; -+ case 0xA6: -+ /* VFRID_G */ -+ index = VFRID_G; -+ break; -+ case 0xA7: -+ /* VFRID_P */ -+ index = VFRID_P; -+ break; -+ case 0xA8: -+ /* VFRID_Z */ -+ index = VFRID_Z; -+ break; -+ case 0xA9: -+ /* VFRID_N */ -+ index = VFRID_N; -+ break; -+ case 0xAA: -+ /* VFRECS */ -+ index = VFRECS; -+ break; -+ case 0xAB: -+ /* VFRECD */ -+ index = VFRECD; -+ break; -+ case 0xAC: -+ /* VMAXS */ -+ index = VMAXS; -+ break; -+ case 0xAD: -+ /* VMINS */ -+ index = VMINS; -+ break; -+ case 0xAE: -+ /* VMAXD */ -+ index = VMAXD; -+ break; -+ case 0xAF: -+ /* VMIND */ -+ index = VMIND; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x1B: -+ switch (fn6) { -+ case 0x00: -+ /* VMAS */ -+ index = VMAS; -+ break; -+ case 0x01: -+ /* VMAD */ -+ index = VMAD; -+ break; -+ case 0x02: -+ /* VMSS */ -+ index = VMSS; -+ break; -+ case 0x03: -+ /* VMSD */ -+ index = VMSD; -+ break; -+ case 0x04: -+ /* VNMAS */ -+ index = VNMAS; -+ break; -+ case 0x05: -+ /* VNMAD */ -+ index = VNMAD; -+ break; -+ case 0x06: -+ /* VNMSS */ -+ index = VNMSS; -+ break; -+ case 0x07: -+ /* VNMSD */ -+ index = VNMSD; -+ break; -+ case 0x10: -+ /* VFSELEQ */ -+ index = VFSELEQ; -+ break; -+ case 0x12: -+ /* VFSELLT */ -+ index = VFSELLT; -+ break; -+ case 0x13: -+ /* VFSELLE */ -+ index = VFSELLE; -+ break; -+ case 0x18: -+ /* VSELEQW */ -+ index = VSELEQW; -+ break; -+ case 0x38: -+ /* VSELEQWI */ -+ index = VSELEQWI; -+ break; -+ case 0x19: -+ /* VSELLBCW */ -+ index = VSELLBCW; -+ break; -+ case 0x39: -+ /* VSELLBCWI */ -+ index = VSELLBCWI; -+ break; -+ case 0x1A: -+ /* VSELLTW */ -+ index = VSELLTW; -+ break; -+ case 0x3A: -+ /* VSELLTWI */ -+ index = VSELLTWI; -+ break; -+ case 0x1B: -+ /* VSELLEW */ -+ index = VSELLEW; -+ break; -+ case 0x3B: -+ /* VSELLEWI */ -+ index = VSELLEWI; -+ break; -+ case 0x20: -+ /* VINSW */ -+ index = VINSW; -+ break; -+ case 0x21: -+ /* VINSF */ -+ index = VINSF; -+ break; -+ case 0x22: -+ /* VEXTW */ -+ index = VEXTW; -+ break; -+ case 0x23: -+ /* VEXTF */ -+ index = VEXTF; -+ break; -+ case 0x24: -+ /* VCPYW */ -+ index = VCPYW; -+ break; -+ case 0x25: -+ /* VCPYF */ -+ index = VCPYF; -+ break; -+ case 0x26: -+ /* VCONW */ -+ index = VCONW; -+ break; -+ case 0x27: -+ /* VSHFW */ -+ index = VSHFW; -+ break; -+ case 0x28: -+ /* VCONS */ -+ index = VCONS; -+ break; -+ case 0x29: -+ /* VCOND */ -+ index = VCOND; -+ break; -+ case 0x2A: -+ /* VINSB */ -+ index = VINSB; -+ break; -+ case 0x2B: -+ /* VINSH */ -+ index = VINSH; -+ break; -+ case 0x2C: -+ /* VINSECTLH */ -+ index = VINSECTLH; -+ break; -+ case 0x2D: -+ /* VINSECTLW */ -+ index = VINSECTLW; -+ break; -+ case 0x2E: -+ /* VINSECTLL */ -+ index = VINSECTLL; -+ break; -+ case 0x2F: -+ /* VINSECTLB */ -+ index = VINSECTLB; -+ break; -+ case 0x30: -+ /* VSHFQ */ -+ index = VSHFQ; -+ break; -+ case 0x31: -+ /* VSHFQB */ -+ index = VSHFQB; -+ break; -+ case 0x32: -+ /* VCPYB */ -+ index = VCPYB; -+ break; -+ case 0x33: -+ /* VCPYH */ -+ index = VCPYH; -+ break; -+ case 0x34: -+ /* VSM3R */ -+ index = VSM3R; -+ break; -+ case 0x35: -+ /* VFCVTSH */ -+ index = VFCVTSH; -+ break; -+ case 0x36: -+ /* VFCVTHS */ -+ index = VFCVTHS; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x1C: -+ switch (fn4) { -+ case 0x0: -+ /* VLDW_U */ -+ index = VLDW_U; -+ break; -+ case 0x1: -+ /* VSTW_U */ -+ index = VSTW_U; -+ break; -+ case 0x2: -+ /* VLDS_U */ -+ index = VLDS_U; -+ break; -+ case 0x3: -+ /* VSTS_U */ -+ index = VSTS_U; -+ break; -+ case 0x4: -+ /* VLDD_U */ -+ index = VLDD_U; -+ break; -+ case 0x5: -+ /* VSTD_U */ -+ index = VSTD_U; -+ break; -+ case 0x8: -+ /* VSTW_UL */ -+ index = VSTW_UL; -+ break; -+ case 0x9: -+ /* VSTW_UH */ -+ index = VSTW_UH; -+ break; -+ case 0xa: -+ /* VSTS_UL */ -+ index = VSTS_UL; -+ break; -+ case 0xb: -+ /* VSTS_UH */ -+ index = VSTS_UH; -+ break; -+ case 0xc: -+ /* VSTD_UL */ -+ index = VSTD_UL; -+ break; -+ case 0xd: -+ /* VSTD_UH */ -+ index = VSTD_UH; -+ break; -+ case 0xe: -+ /* VLDD_NC */ -+ index = VLDD_NC; -+ break; -+ case 0xf: -+ /* VSTD_NC */ -+ index = VSTD_NC; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x1D: -+ /* LBR */ -+ index = LBR; -+ break; -+ case 0x1E: -+ switch (fn4) { -+ case 0x0: -+ /* LDBU_A */ -+ index = LDBU_A; -+ break; -+ case 0x1: -+ /* LDHU_A */ -+ index = LDHU_A; -+ break; -+ case 0x2: -+ /* LDW_A */ -+ index = LDW_A; -+ break; -+ case 0x3: -+ /* LDL_A */ -+ index = LDL_A; -+ break; -+ case 0x4: -+ /* FLDS_A */ -+ index = FLDS_A; -+ break; -+ case 0x5: -+ /* FLDD_A */ -+ index = FLDD_A; -+ break; -+ case 0x6: -+ /* STBU_A */ -+ index = STBU_A; -+ break; -+ case 0x7: -+ /* STHU_A */ -+ index = STHU_A; -+ break; -+ case 0x8: -+ /* STW_A */ -+ index = STW_A; -+ break; -+ case 0x9: -+ /* STL_A */ -+ index = STL_A; -+ break; -+ case 0xA: -+ /* FSTS_A */ -+ index = FSTS_A; -+ break; -+ case 0xB: -+ /* FSTD_A */ -+ index = FSTD_A; -+ break; -+ case 0xE: -+ /* DPFHR */ -+ index = DPFHR; -+ break; -+ case 0xF: -+ /* DPFHW */ -+ index = DPFHW; -+ break; -+ default: -+ break; -+ } -+ break; -+ case 0x20: -+ /* LDBU */ -+ index = LDBU; -+ break; -+ case 0x21: -+ /* LDHU */ -+ index = LDHU; -+ break; -+ case 0x22: -+ /* LDW */ -+ index = LDW; -+ break; -+ case 0x23: -+ /* LDL */ -+ index = LDL; -+ break; -+ case 0x24: -+ /* LDL_U */ -+ index = LDL_U; -+ break; -+ case 0x25: -+ if ((insn >> 12) & 1) { -+ /* PRI_LDL */ -+ index = PRI_LDL; -+ } else { -+ /* PRI_LDW */ -+ index = PRI_LDW; -+ } -+ break; -+ case 0x26: -+ /* FLDS */ -+ index = FLDS; -+ break; -+ case 0x27: -+ /* FLDD */ -+ index = FLDD; -+ break; -+ case 0x28: -+ /* STB */ -+ index = STB; -+ break; -+ case 0x29: -+ /* STH */ -+ index = STH; -+ break; -+ case 0x2a: -+ /* STW */ -+ index = STW; -+ break; -+ case 0x2b: -+ /* STL */ -+ index = STL; -+ break; -+ case 0x2c: -+ /* STL_U */ -+ index = STL_U; -+ break; -+ case 0x2d: -+ if ((insn >> 12) & 1) { -+ /* PRI_STL */ -+ index = PRI_STL; -+ } else { -+ /* PRI_STW */ -+ index = PRI_STW; -+ } -+ break; -+ case 0x2e: -+ /* FSTS */ -+ index = FSTS; -+ break; -+ case 0x2f: -+ /* FSTD */ -+ index = FSTD; -+ break; -+ case 0x30: -+ /* BEQ */ -+ index = BEQ; -+ break; -+ case 0x31: -+ /* BNE */ -+ index = BNE; -+ break; -+ case 0x32: -+ /* BLT */ -+ index = BLT; -+ break; -+ case 0x33: -+ /* BLE */ -+ index = BLE; -+ break; -+ case 0x34: -+ /* BGT */ -+ index = BGT; -+ break; -+ case 0x35: -+ /* BGE */ -+ index = BGE; -+ break; -+ case 0x36: -+ /* BLBC */ -+ index = BLBC; -+ break; -+ case 0x37: -+ /* BLBS */ -+ index = BLBS; -+ break; -+ case 0x38: -+ /* FBEQ */ -+ index = FBEQ; -+ break; -+ case 0x39: -+ /* FBNE */ -+ index = FBNE; -+ break; -+ case 0x3a: -+ /* FBLT */ -+ index = FBLT; -+ break; -+ case 0x3b: -+ /* FBLE */ -+ index = FBLE; -+ break; -+ case 0x3c: -+ /* FBGT */ -+ index = FBGT; -+ break; -+ case 0x3d: -+ /* FBGE */ -+ index = FBGE; -+ break; -+ case 0x3f: -+ /* LDIH */ -+ index = LDIH; -+ break; -+ case 0x3e: -+ /* LDI */ -+ index = LDI; -+ break; -+ default: -+do_invalid: -+ break; -+ } -+ count = tcg_temp_new(); -+ offs = offsetof(CPUSW64State, insn_count[index]); -+ tcg_gen_ld_i64(count, cpu_env, offs); -+ tcg_gen_addi_i64(count, count, 1); -+ tcg_gen_st_i64(count, cpu_env, offs); -+ tcg_temp_free(count); -+} -diff --git a/target/sw64/profile.h b/target/sw64/profile.h -new file mode 100644 -index 0000000000..5aca541ea7 ---- /dev/null -+++ b/target/sw64/profile.h -@@ -0,0 +1,541 @@ -+#ifndef PROFILE_H -+#define PROFILE_H -+#define SYS_CALL 0 -+#define CALL 1 -+#define RET 2 -+#define JMP 3 -+#define BR 4 -+#define BSR 5 -+#define MEMB 6 -+#define IMEMB 7 -+#define WMEMB 8 -+#define RTC 9 -+#define RCID 10 -+#define HALT 11 -+#define RD_F 12 -+#define WR_F 13 -+#define RTID 14 -+#define CSRWS 15 -+#define CSRWC 16 -+#define PRI_RCSR 17 -+#define PRI_WCSR 18 -+#define PRI_RET 19 -+#define LLDW 20 -+#define LLDL 21 -+#define LDW_INC 22 -+#define LDL_INC 23 -+#define LDW_DEC 24 -+#define LDL_DEC 25 -+#define LDW_SET 26 -+#define LDL_SET 27 -+#define LSTW 28 -+#define LSTL 29 -+#define LDW_NC 30 -+#define LDL_NC 31 -+#define LDD_NC 32 -+#define STW_NC 33 -+#define STL_NC 34 -+#define STD_NC 35 -+#define LDWE 36 -+#define LDSE 37 -+#define LDDE 38 -+#define VLDS 39 -+#define VLDD 40 -+#define VSTS 41 -+#define VSTD 42 -+#define FIMOVS 43 -+#define FIMOVD 44 -+#define ADDW 45 -+#define SUBW 46 -+#define S4ADDW 47 -+#define S4SUBW 48 -+#define S8ADDW 49 -+#define S8SUBW 50 -+#define ADDL 51 -+#define SUBL 52 -+#define S4ADDL 53 -+#define S4SUBL 54 -+#define S8ADDL 55 -+#define S8SUBL 56 -+#define MULW 57 -+#define DIVW 58 -+#define UDIVW 59 -+#define REMW 60 -+#define UREMW 61 -+#define MULL 62 -+#define MULH 63 -+#define DIVL 64 -+#define UDIVL 65 -+#define REML 66 -+#define UREML 67 -+#define ADDPI 68 -+#define ADDPIS 69 -+#define CMPEQ 70 -+#define CMPLT 71 -+#define CMPLE 72 -+#define CMPULT 73 -+#define CMPULE 74 -+#define SBT 75 -+#define CBT 76 -+#define AND 77 -+#define BIC 78 -+#define BIS 79 -+#define ORNOT 80 -+#define XOR 81 -+#define EQV 82 -+#define INSLB 83 -+#define INSLH 84 -+#define INSLW 85 -+#define INSLL 86 -+#define INSHB 87 -+#define INSHH 88 -+#define INSHW 89 -+#define INSHL 90 -+#define SLLL 91 -+#define SRLL 92 -+#define SRAL 93 -+#define ROLL 94 -+#define SLLW 95 -+#define SRLW 96 -+#define SRAW 97 -+#define ROLW 98 -+#define EXTLB 99 -+#define EXTLH 100 -+#define EXTLW 101 -+#define EXTLL 102 -+#define EXTHB 103 -+#define EXTHH 104 -+#define EXTHW 105 -+#define EXTHL 106 -+#define CTPOP 107 -+#define CTLZ 108 -+#define CTTZ 109 -+#define REVBH 110 -+#define REVBW 111 -+#define REVBL 112 -+#define CASW 113 -+#define CASL 114 -+#define MASKLB 115 -+#define MASKLH 116 -+#define MASKLW 117 -+#define MASKLL 118 -+#define MASKHB 119 -+#define MASKHH 120 -+#define MASKHW 121 -+#define MASKHL 122 -+#define ZAP 123 -+#define ZAPNOT 124 -+#define SEXTB 125 -+#define SEXTH 126 -+#define SELEQ 127 -+#define SELGE 128 -+#define SELGT 129 -+#define SELLE 130 -+#define SELLT 131 -+#define SELNE 132 -+#define SELLBC 133 -+#define SELLBS 134 -+#define ADDWI 135 -+#define SUBWI 136 -+#define S4ADDWI 137 -+#define S4SUBWI 138 -+#define S8ADDWI 139 -+#define S8SUBWI 140 -+#define ADDLI 141 -+#define SUBLI 142 -+#define S4ADDLI 143 -+#define S4SUBLI 144 -+#define S8ADDLI 145 -+#define S8SUBLI 146 -+#define MULWI 147 -+#define DIVWI 148 -+#define UDIVWI 149 -+#define REMWI 150 -+#define UREMWI 151 -+#define MULLI 152 -+#define MULHI 153 -+#define DIVLI 154 -+#define UDIVLI 155 -+#define REMLI 156 -+#define UREMLI 157 -+#define ADDPII 158 -+#define ADDPISI 159 -+#define CMPEQI 160 -+#define CMPLTI 161 -+#define CMPLEI 162 -+#define CMPULTI 163 -+#define CMPULEI 164 -+#define SBTI 165 -+#define CBTI 166 -+#define ANDI 167 -+#define BICI 168 -+#define BISI 169 -+#define ORNOTI 170 -+#define XORI 171 -+#define EQVI 172 -+#define INSLBI 173 -+#define INSLHI 174 -+#define INSLWI 175 -+#define INSLLI 176 -+#define INSHBI 177 -+#define INSHHI 178 -+#define INSHWI 179 -+#define INSHLI 180 -+#define SLLLI 181 -+#define SRLLI 182 -+#define SRALI 183 -+#define ROLLI 184 -+#define SLLWI 185 -+#define SRLWI 186 -+#define SRAWI 187 -+#define ROLWI 188 -+#define EXTLBI 189 -+#define EXTLHI 190 -+#define EXTLWI 191 -+#define EXTLLI 192 -+#define EXTHBI 193 -+#define EXTHHI 194 -+#define EXTHWI 195 -+#define EXTHLI 196 -+#define CTPOPI 197 -+#define CTLZI 198 -+#define CTTZI 199 -+#define REVBHI 200 -+#define REVBWI 201 -+#define REVBLI 202 -+#define CASWI 203 -+#define CASLI 204 -+#define MASKLBI 205 -+#define MASKLHI 206 -+#define MASKLWI 207 -+#define MASKLLI 208 -+#define MASKHBI 209 -+#define MASKHHI 210 -+#define MASKHWI 211 -+#define MASKHLI 212 -+#define ZAPI 213 -+#define ZAPNOTI 214 -+#define SEXTBI 215 -+#define SEXTHI 216 -+#define CMPGEBI 217 -+#define SELEQI 218 -+#define SELGEI 219 -+#define SELGTI 220 -+#define SELLEI 221 -+#define SELLTI 222 -+#define SELNEI 223 -+#define SELLBCI 224 -+#define SELLBSI 225 -+#define VLOGZZ 226 -+#define FADDS 227 -+#define FADDD 228 -+#define FSUBS 229 -+#define FSUBD 230 -+#define FMULS 231 -+#define FMULD 232 -+#define FDIVS 233 -+#define FDIVD 234 -+#define FSQRTS 235 -+#define FSQRTD 236 -+#define FCMPEQ 237 -+#define FCMPLE 238 -+#define FCMPLT 239 -+#define FCMPUN 240 -+#define FCVTSD 241 -+#define FCVTDS 242 -+#define FCVTDL_G 243 -+#define FCVTDL_P 244 -+#define FCVTDL_Z 245 -+#define FCVTDL_N 246 -+#define FCVTDL 247 -+#define FCVTWL 248 -+#define FCVTLW 249 -+#define FCVTLS 250 -+#define FCVTLD 251 -+#define FCPYS 252 -+#define FCPYSE 253 -+#define FCPYSN 254 -+#define IFMOVS 255 -+#define IFMOVD 256 -+#define RFPCR 257 -+#define WFPCR 258 -+#define SETFPEC0 259 -+#define SETFPEC1 260 -+#define SETFPEC2 261 -+#define SETFPEC3 262 -+#define FRECS 263 -+#define FRECD 264 -+#define FRIS 265 -+#define FRIS_G 266 -+#define FRIS_P 267 -+#define FRIS_Z 268 -+#define FRIS_N 269 -+#define FRID 270 -+#define FRID_G 271 -+#define FRID_P 272 -+#define FRID_Z 273 -+#define FRID_N 274 -+#define FMAS 275 -+#define FMAD 276 -+#define FMSS 277 -+#define FMSD 278 -+#define FNMAS 279 -+#define FNMAD 280 -+#define FNMSS 281 -+#define FNMSD 282 -+#define FSELEQ 283 -+#define FSELNE 284 -+#define FSELLT 285 -+#define FSELLE 286 -+#define FSELGT 287 -+#define FSELGE 288 -+#define VADDW 289 -+#define VADDWI 290 -+#define VSUBW 291 -+#define VSUBWI 292 -+#define VCMPGEW 293 -+#define VCMPGEWI 294 -+#define VCMPEQW 295 -+#define VCMPEQWI 296 -+#define VCMPLEW 297 -+#define VCMPLEWI 298 -+#define VCMPLTW 299 -+#define VCMPLTWI 300 -+#define VCMPULEW 301 -+#define VCMPULEWI 302 -+#define VCMPULTW 303 -+#define VCMPULTWI 304 -+#define VSLLW 305 -+#define VSLLWI 306 -+#define VSRLW 307 -+#define VSRLWI 308 -+#define VSRAW 309 -+#define VSRAWI 310 -+#define VROLW 311 -+#define VROLWI 312 -+#define SLLOW 313 -+#define SLLOWI 314 -+#define SRLOW 315 -+#define SRLOWI 316 -+#define VADDL 317 -+#define VADDLI 318 -+#define VSUBL 319 -+#define VSUBLI 320 -+#define VSLLB 321 -+#define VSLLBI 322 -+#define VSRLB 323 -+#define VSRLBI 324 -+#define VSRAB 325 -+#define VSRABI 326 -+#define VROLB 327 -+#define VROLBI 328 -+#define VSLLH 329 -+#define VSLLHI 330 -+#define VSRLH 331 -+#define VSRLHI 332 -+#define VSRAH 333 -+#define VSRAHI 334 -+#define VROLH 335 -+#define VROLHI 336 -+#define CTPOPOW 337 -+#define CTLZOW 338 -+#define VSLLL 339 -+#define VSLLLI 340 -+#define VSRLL 341 -+#define VSRLLI 342 -+#define VSRAL 343 -+#define VSRALI 344 -+#define VROLL 345 -+#define VROLLI 346 -+#define VMAXB 347 -+#define VMINB 348 -+#define VUCADDW 349 -+#define VUCADDWI 350 -+#define VUCSUBW 351 -+#define VUCSUBWI 352 -+#define VUCADDH 353 -+#define VUCADDHI 354 -+#define VUCSUBH 355 -+#define VUCSUBHI 356 -+#define VUCADDB 357 -+#define VUCADDBI 358 -+#define VUCSUBB 359 -+#define VUCSUBBI 360 -+#define SRAOW 361 -+#define SRAOWI 362 -+#define VSUMW 363 -+#define VSUML 364 -+#define VSM4R 365 -+#define VBINVW 366 -+#define VCMPUEQB 367 -+#define VCMPUGTB 368 -+#define VCMPUGTBI 369 -+#define VSM3MSW 370 -+#define VMAXH 371 -+#define VMINH 372 -+#define VMAXW 373 -+#define VMINW 374 -+#define VMAXL 375 -+#define VMINL 376 -+#define VUMAXB 377 -+#define VUMINB 378 -+#define VUMAXH 379 -+#define VUMINH 380 -+#define VUMAXW 381 -+#define VUMINW 382 -+#define VUMAXL 383 -+#define VUMINL 384 -+#define VSM4KEY 385 -+#define VADDS 386 -+#define VADDD 387 -+#define VSUBS 388 -+#define VSUBD 389 -+#define VMULS 390 -+#define VMULD 391 -+#define VDIVS 392 -+#define VDIVD 393 -+#define VSQRTS 394 -+#define VSQRTD 395 -+#define VFCMPEQ 396 -+#define VFCMPLE 397 -+#define VFCMPLT 398 -+#define VFCMPUN 399 -+#define VCPYS 400 -+#define VCPYSE 401 -+#define VCPYSN 402 -+#define VSUMS 403 -+#define VSUMD 404 -+#define VFCVTSD 405 -+#define VFCVTDS 406 -+#define VFCVTLS 407 -+#define VFCVTLD 408 -+#define VFCVTDL 409 -+#define VFCVTDL_G 410 -+#define VFCVTDL_P 411 -+#define VFCVTDL_Z 412 -+#define VFCVTDL_N 413 -+#define VFRIS 414 -+#define VFRIS_G 415 -+#define VFRIS_P 416 -+#define VFRIS_Z 417 -+#define VFRIS_N 418 -+#define VFRID 419 -+#define VFRID_G 420 -+#define VFRID_P 421 -+#define VFRID_Z 422 -+#define VFRID_N 423 -+#define VFRECS 424 -+#define VFRECD 425 -+#define VMAXS 426 -+#define VMINS 427 -+#define VMAXD 428 -+#define VMIND 429 -+#define VMAS 430 -+#define VMAD 431 -+#define VMSS 432 -+#define VMSD 433 -+#define VNMAS 434 -+#define VNMAD 435 -+#define VNMSS 436 -+#define VNMSD 437 -+#define VFSELEQ 438 -+#define VFSELLT 439 -+#define VFSELLE 440 -+#define VSELEQW 441 -+#define VSELEQWI 442 -+#define VSELLBCW 443 -+#define VSELLBCWI 444 -+#define VSELLTW 445 -+#define VSELLTWI 446 -+#define VSELLEW 447 -+#define VSELLEWI 448 -+#define VINSW 449 -+#define VINSF 450 -+#define VEXTW 451 -+#define VEXTF 452 -+#define VCPYW 453 -+#define VCPYF 454 -+#define VCONW 455 -+#define VSHFW 456 -+#define VCONS 457 -+#define VCOND 458 -+#define VINSB 459 -+#define VINSH 460 -+#define VINSECTLH 461 -+#define VINSECTLW 462 -+#define VINSECTLL 463 -+#define VINSECTLB 464 -+#define VSHFQ 465 -+#define VSHFQB 466 -+#define VCPYB 467 -+#define VCPYH 468 -+#define VSM3R 469 -+#define VFCVTSH 470 -+#define VFCVTHS 471 -+#define VLDW_U 472 -+#define VSTW_U 473 -+#define VLDS_U 474 -+#define VSTS_U 475 -+#define VLDD_U 476 -+#define VSTD_U 477 -+#define VSTW_UL 478 -+#define VSTW_UH 479 -+#define VSTS_UL 480 -+#define VSTS_UH 481 -+#define VSTD_UL 482 -+#define VSTD_UH 483 -+#define VLDD_NC 484 -+#define VSTD_NC 485 -+#define LBR 486 -+#define LDBU_A 487 -+#define LDHU_A 488 -+#define LDW_A 489 -+#define LDL_A 490 -+#define FLDS_A 491 -+#define FLDD_A 492 -+#define STBU_A 493 -+#define STHU_A 494 -+#define STW_A 495 -+#define STL_A 496 -+#define FSTS_A 497 -+#define FSTD_A 498 -+#define DPFHR 499 -+#define DPFHW 500 -+#define LDBU 501 -+#define LDHU 502 -+#define LDW 503 -+#define LDL 504 -+#define LDL_U 505 -+#define PRI_LDL 506 -+#define PRI_LDW 507 -+#define FLDS 508 -+#define FLDD 509 -+#define STB 510 -+#define STH 511 -+#define STW 512 -+#define STL 513 -+#define STL_U 514 -+#define PRI_STL 515 -+#define PRI_STW 516 -+#define FSTS 517 -+#define FSTD 518 -+#define BEQ 519 -+#define BNE 520 -+#define BLT 521 -+#define BLE 522 -+#define BGT 523 -+#define BGE 524 -+#define BLBC 525 -+#define BLBS 526 -+#define FBEQ 527 -+#define FBNE 528 -+#define FBLT 529 -+#define FBLE 530 -+#define FBGT 531 -+#define FBGE 532 -+#define LDIH 533 -+#define LDI 534 -+ -+extern const char *insn_opc[535]; -+ -+#endif -diff --git a/target/sw64/simd_helper.c b/target/sw64/simd_helper.c -new file mode 100644 -index 0000000000..13bd52de3d ---- /dev/null -+++ b/target/sw64/simd_helper.c -@@ -0,0 +1,1058 @@ -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "exec/exec-all.h" -+#include "exec/helper-proto.h" -+ -+#undef DEBUG_SIMD -+ -+static inline uint8_t *get_element_b(CPUSW64State *env, uint64_t ra, -+ int index) -+{ -+ return (uint8_t*)&env->fr[ra + (index / 8) * 32] + (index % 8); -+} -+ -+static inline uint16_t *get_element_h(CPUSW64State *env, uint64_t ra, -+ int index) -+{ -+ return (uint16_t*)&env->fr[ra + (index / 4) * 32] + (index % 4); -+} -+ -+static inline uint32_t *get_element_w(CPUSW64State *env, uint64_t ra, -+ int index) -+{ -+ return (uint32_t*)&env->fr[ra + (index / 2) * 32] + (index % 2); -+} -+ -+static inline uint64_t *get_element_l(CPUSW64State *env, uint64_t ra, -+ int index) -+{ -+ return &env->fr[ra + index * 32]; -+} -+ -+void helper_srlow(CPUSW64State *env, uint64_t ra, uint64_t rc, uint64_t shift) -+{ -+ int i; -+ int adden; -+ int dest, src; -+ adden = shift >> 6; -+ shift &= 0x3f; -+#ifdef DEBUG_SIMD -+ printf("right shift = %ld adden = %d\n", shift, adden); -+ printf("in_fr[%ld]:", ra); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[ra + 32 * i]); -+ } -+ printf("\n"); -+#endif -+ -+ for (i = 0; (i + adden) < 4; i++) { -+ dest = i * 32 + rc; -+ src = (i + adden) * 32 + ra; -+ env->fr[dest] = env->fr[src] >> shift; -+ if (((i + adden) < 3) && (shift != 0)) -+ env->fr[dest] |= (env->fr[src + 32] << (64 - shift)); -+ } -+ -+ for (; i < 4; i++) { -+ env->fr[rc + i * 32] = 0; -+ } -+#ifdef DEBUG_SIMD -+ printf("out_fr[%ld]:", rc); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[rc + 32 * i]); -+ } -+ printf("\n"); -+#endif -+} -+ -+void helper_sllow(CPUSW64State *env, uint64_t ra, uint64_t rc, uint64_t shift) -+{ -+ int i; -+ int adden; -+ int dest, src; -+ adden = shift >> 6; -+ shift &= 0x3f; -+#ifdef DEBUG_SIMD -+ printf("left shift = %ld adden = %d\n", shift, adden); -+ printf("in_fr[%ld]:", ra); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[ra + 32 * i]); -+ } -+ printf("\n"); -+#endif -+ -+ for (i = 3; (i - adden) >= 0; i--) { -+ dest = i * 32 + rc; -+ src = (i - adden) * 32 + ra; -+ env->fr[dest] = env->fr[src] << shift; -+ if (((i - adden) > 0) && (shift != 0)) -+ env->fr[dest] |= (env->fr[src - 32] >> (64 - shift)); -+ } -+ for (; i >= 0; i--) { -+ env->fr[rc + i * 32] = 0; -+ } -+#ifdef DEBUG_SIMD -+ printf("out_fr[%ld]:", rc); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[rc + 32 * i]); -+ } -+ printf("\n"); -+#endif -+} -+ -+static uint64_t do_logzz(uint64_t va, uint64_t vb, uint64_t vc, uint64_t zz) -+{ -+ int i; -+ uint64_t ret = 0; -+ int index; -+ -+ for (i = 0; i < 64; i++) { -+ index = (((va >> i) & 1) << 2) | (((vb >> i) & 1) << 1) | ((vc >> i) & 1); -+ ret |= ((zz >> index) & 1) << i; -+ } -+ -+ return ret; -+} -+ -+void helper_vlogzz(CPUSW64State *env, uint64_t args, uint64_t rd, uint64_t zz) -+{ -+ int i; -+ int ra, rb, rc; -+ ra = args >> 16; -+ rb = (args >> 8) & 0xff; -+ rc = args & 0xff; -+#ifdef DEBUG_SIMD -+ printf("zz = %lx\n", zz); -+ printf("in_fr[%d]:", ra); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[ra + 32 * i]); -+ } -+ printf("\n"); -+ printf("in_fr[%d]:", rb); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[rb + 32 * i]); -+ } -+ printf("\n"); -+ printf("in_fr[%d]:", rc); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[rc + 32 * i]); -+ } -+ printf("\n"); -+#endif -+ for (i = 0; i < 4; i++) { -+ env->fr[rd + i * 32] = do_logzz(env->fr[ra + i * 32], env->fr[rb + i * 32], -+ env->fr[rc + i * 32], zz); -+ } -+#ifdef DEBUG_SIMD -+ printf("out_fr[%ld]:", rd); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[rd + 32 * i]); -+ } -+ printf("\n"); -+#endif -+} -+ -+void helper_v_print(CPUSW64State *env, uint64_t v) -+{ -+ printf("PC[%lx]: fr[%lx]:\n", GETPC(), v); -+} -+ -+void helper_vconw(CPUSW64State *env, uint64_t args, uint64_t rd, -+ uint64_t byte4_len) -+{ -+ int ra, rb; -+ int count; -+ int i; -+ uint32_t *ptr_dst, *ptr_src; -+ uint32_t tmp[8]; -+ -+ ra = (args >> 8) & 0xff; -+ rb = args & 0xff; -+ count = 8 - byte4_len; -+ -+ for (i = 0; i < 8; i++) { -+ ptr_dst = get_element_w(env, rd, i); -+ if (i < count) { -+ ptr_src = get_element_w(env, ra, i + byte4_len); -+ } else { -+ ptr_src = get_element_w(env, rb, i - count); -+ } -+ tmp[i] = *ptr_src; -+ } -+ for (i = 0; i < 8; i++) { -+ ptr_dst = get_element_w(env, rd, i); -+ *ptr_dst = tmp[i]; -+ } -+} -+ -+void helper_vcond(CPUSW64State *env, uint64_t args, uint64_t rd, -+ uint64_t byte8_len) -+{ -+ int ra, rb; -+ int count; -+ int i; -+ uint64_t *ptr_dst, *ptr_src; -+ uint64_t tmp[8]; -+ -+ ra = (args >> 8) & 0xff; -+ rb = args & 0xff; -+ count = 4 - byte8_len; -+ -+ for (i = 0; i < 4; i++) { -+ if (i < count) { -+ ptr_src = get_element_l(env, ra, i + byte8_len); -+ } else { -+ ptr_src = get_element_l(env, rb, i - count); -+ } -+ tmp[i] = *ptr_src; -+ } -+ for (i = 0; i < 4; i++) { -+ ptr_dst = get_element_l(env, rd, i + byte8_len); -+ *ptr_dst = tmp[i]; -+ } -+} -+ -+void helper_vshfw(CPUSW64State *env, uint64_t args, uint64_t rd, uint64_t vc) -+{ -+ int ra, rb; -+ int i; -+ uint32_t *ptr_dst, *ptr_src; -+ uint32_t tmp[8]; -+ int flag, idx; -+ -+ ra = (args >> 8) & 0xff; -+ rb = args & 0xff; -+ -+ for (i = 0; i < 8; i++) { -+ flag = (vc >> (i * 4)) & 0x8; -+ idx = (vc >> (i * 4)) & 0x7; -+ if (flag == 0) { -+ ptr_src = get_element_w(env, ra, idx); -+ } else { -+ ptr_src = get_element_w(env, rb, idx); -+ } -+ tmp[i] = *ptr_src; -+ } -+ for (i = 0; i < 8; i++) { -+ ptr_dst = get_element_w(env, rd, i); -+ *ptr_dst = tmp[i]; -+ } -+} -+ -+uint64_t helper_ctlzow(CPUSW64State *env, uint64_t ra) -+{ -+ int i, j; -+ uint64_t val; -+ uint64_t ctlz = 0; -+ -+ for (j = 3; j >= 0; j--) { -+ val = env->fr[ra + 32 * j]; -+ for (i = 63; i >= 0; i--) { -+ if ((val >> i) & 1) -+ return ctlz << 29; -+ else -+ ctlz++; -+ } -+ } -+ return ctlz << 29; -+} -+ -+void helper_vucaddw(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ int a, b, c; -+ int ret; -+ int i; -+ -+ for (i = 0; i < 4; i++) { -+ a = (int)(env->fr[ra + i * 32] & 0xffffffff); -+ b = (int)(env->fr[rb + i * 32] & 0xffffffff); -+ c = a + b; -+ if ((c ^ a) < 0 && (c ^ b) < 0) { -+ if (a < 0) -+ c = 0x80000000; -+ else -+ c = 0x7fffffff; -+ } -+ ret = c; -+ -+ a = (int)(env->fr[ra + i * 32] >> 32); -+ b = (int)(env->fr[rb + i * 32] >> 32); -+ c = a + b; -+ if ((c ^ a) < 0 && (c ^ b) < 0) { -+ if (a < 0) -+ c = 0x80000000; -+ else -+ c = 0x7fffffff; -+ } -+ env->fr[rc + i * 32] = ((uint64_t)(uint32_t)c << 32) | -+ (uint64_t)(uint32_t)ret; -+ } -+} -+ -+void helper_vucaddwi(CPUSW64State *env, uint64_t ra, uint64_t vb, uint64_t rc) -+{ -+ int a, b, c; -+ int ret; -+ int i; -+ -+ b = (int)vb; -+ for (i = 0; i < 4; i++) { -+ a = (int)(env->fr[ra + i * 32] & 0xffffffff); -+ c = a + b; -+ if ((c ^ a) < 0 && (c ^ b) < 0) { -+ if (a < 0) -+ c = 0x80000000; -+ else -+ c = 0x7fffffff; -+ } -+ ret = c; -+ -+ a = (int)(env->fr[ra + i * 32] >> 32); -+ c = a + b; -+ if ((c ^ a) < 0 && (c ^ b) < 0) { -+ if (a < 0) -+ c = 0x80000000; -+ else -+ c = 0x7fffffff; -+ } -+ env->fr[rc + i * 32] = ((uint64_t)(uint32_t)c << 32) | -+ (uint64_t)(uint32_t)ret; -+ } -+} -+ -+void helper_vucsubw(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ int a, b, c; -+ int ret; -+ int i; -+ -+ for (i = 0; i < 4; i++) { -+ a = (int)(env->fr[ra + i * 32] & 0xffffffff); -+ b = (int)(env->fr[rb + i * 32] & 0xffffffff); -+ c = a - b; -+ if ((b ^ a) < 0 && (c ^ a) < 0) { -+ if (a < 0) -+ c = 0x80000000; -+ else -+ c = 0x7fffffff; -+ } -+ ret = c; -+ -+ a = (int)(env->fr[ra + i * 32] >> 32); -+ b = (int)(env->fr[rb + i * 32] >> 32); -+ c = a - b; -+ if ((b ^ a) < 0 && (c ^ a) < 0) { -+ if (a < 0) -+ c = 0x80000000; -+ else -+ c = 0x7fffffff; -+ } -+ env->fr[rc + i * 32] = ((uint64_t)(uint32_t)c << 32) | -+ (uint64_t)(uint32_t)ret; -+ } -+} -+ -+void helper_vucsubwi(CPUSW64State *env, uint64_t ra, uint64_t vb, uint64_t rc) -+{ -+ int a, b, c; -+ int ret; -+ int i; -+ -+ b = (int)vb; -+ for (i = 0; i < 4; i++) { -+ a = (int)(env->fr[ra + i * 32] & 0xffffffff); -+ c = a - b; -+ if ((b ^ a) < 0 && (c ^ a) < 0) { -+ if (a < 0) -+ c = 0x80000000; -+ else -+ c = 0x7fffffff; -+ } -+ ret = c; -+ -+ a = (int)(env->fr[ra + i * 32] >> 32); -+ c = a - b; -+ if ((b ^ a) < 0 && (c ^ a) < 0) { -+ if (a < 0) -+ c = 0x80000000; -+ else -+ c = 0x7fffffff; -+ } -+ env->fr[rc + i * 32] = ((uint64_t)(uint32_t)c << 32) | -+ (uint64_t)(uint32_t)ret; -+ } -+} -+ -+void helper_vucaddh(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ short a, b, c; -+ uint64_t ret; -+ int i, j; -+ -+ for (i = 0; i < 4; i++) { -+ ret = 0; -+ for (j = 0; j < 4; j++) { -+ a = (short)((env->fr[ra + i * 32] >> (j * 16)) & 0xffff); -+ b = (short)((env->fr[rb + i * 32] >> (j * 16)) & 0xffff); -+ c = a + b; -+ if ((c ^ a) < 0 && (c ^ b) < 0) { -+ if (a < 0) -+ c = 0x8000; -+ else -+ c = 0x7fff; -+ } -+ ret |= ((uint64_t)(uint16_t)c) << (j * 16); -+ } -+ env->fr[rc + i * 32] = ret; -+ } -+} -+ -+void helper_vucaddhi(CPUSW64State *env, uint64_t ra, uint64_t vb, uint64_t rc) -+{ -+ short a, b, c; -+ uint64_t ret; -+ int i, j; -+ -+ b = (short)vb; -+ for (i = 0; i < 4; i++) { -+ ret = 0; -+ for (j = 0; j < 4; j++) { -+ a = (short)((env->fr[ra + i * 32] >> (j * 16)) & 0xffff); -+ c = a + b; -+ if ((c ^ a) < 0 && (c ^ b) < 0) { -+ if (a < 0) -+ c = 0x8000; -+ else -+ c = 0x7fff; -+ } -+ ret |= ((uint64_t)(uint16_t)c) << (j * 16); -+ } -+ env->fr[rc + i * 32] = ret; -+ } -+} -+ -+void helper_vucsubh(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ short a, b, c; -+ uint64_t ret; -+ int i, j; -+ -+ for (i = 0; i < 4; i++) { -+ ret = 0; -+ for (j = 0; j < 4; j++) { -+ a = (short)((env->fr[ra + i * 32] >> (j * 16)) & 0xffff); -+ b = (short)((env->fr[rb + i * 32] >> (j * 16)) & 0xffff); -+ c = a - b; -+ if ((b ^ a) < 0 && (c ^ a) < 0) { -+ if (a < 0) -+ c = 0x8000; -+ else -+ c = 0x7fff; -+ } -+ ret |= ((uint64_t)(uint16_t)c) << (j * 16); -+ } -+ env->fr[rc + i * 32] = ret; -+ } -+} -+ -+void helper_vucsubhi(CPUSW64State *env, uint64_t ra, uint64_t vb, uint64_t rc) -+{ -+ short a, b, c; -+ uint64_t ret; -+ int i, j; -+ -+ b = (short)vb; -+ for (i = 0; i < 4; i++) { -+ ret = 0; -+ for (j = 0; j < 4; j++) { -+ a = (short)((env->fr[ra + i * 32] >> (j * 16)) & 0xffff); -+ c = a - b; -+ if ((b ^ a) < 0 && (c ^ a) < 0) { -+ if (a < 0) -+ c = 0x8000; -+ else -+ c = 0x7fff; -+ } -+ ret |= ((uint64_t)(uint16_t)c) << (j * 16); -+ } -+ env->fr[rc + i * 32] = ret; -+ } -+} -+ -+void helper_vucaddb(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ int8_t a, b, c; -+ uint64_t ret; -+ int i, j; -+ -+ for (i = 0; i < 4; i++) { -+ ret = 0; -+ for (j = 0; j < 8; j++) { -+ a = (int8_t)((env->fr[ra + i * 32] >> (j * 8)) & 0xff); -+ b = (int8_t)((env->fr[rb + i * 32] >> (j * 8)) & 0xff); -+ c = a + b; -+ if ((c ^ a) < 0 && (c ^ b) < 0) { -+ if (a < 0) -+ c = 0x80; -+ else -+ c = 0x7f; -+ } -+ ret |= ((uint64_t)(uint8_t)c) << (j * 8); -+ } -+ env->fr[rc + i * 32] = ret; -+ } -+} -+ -+void helper_vucaddbi(CPUSW64State *env, uint64_t ra, uint64_t vb, uint64_t rc) -+{ -+ int8_t a, b, c; -+ uint64_t ret; -+ int i, j; -+ -+ b = (int8_t)(vb & 0xff); -+ for (i = 0; i < 4; i++) { -+ ret = 0; -+ for (j = 0; j < 8; j++) { -+ a = (int8_t)((env->fr[ra + i * 32] >> (j * 8)) & 0xff); -+ c = a + b; -+ if ((c ^ a) < 0 && (c ^ b) < 0) { -+ if (a < 0) -+ c = 0x80; -+ else -+ c = 0x7f; -+ } -+ ret |= ((uint64_t)(uint8_t)c) << (j * 8); -+ } -+ env->fr[rc + i * 32] = ret; -+ } -+} -+ -+void helper_vucsubb(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ int8_t a, b, c; -+ uint64_t ret; -+ int i, j; -+ -+ for (i = 0; i < 4; i++) { -+ ret = 0; -+ for (j = 0; j < 8; j++) { -+ a = (int8_t)((env->fr[ra + i * 32] >> (j * 8)) & 0xff); -+ b = (int8_t)((env->fr[rb + i * 32] >> (j * 8)) & 0xff); -+ c = a - b; -+ if ((b ^ a) < 0 && (c ^ a) < 0) { -+ if (a < 0) -+ c = 0x80; -+ else -+ c = 0x7f; -+ } -+ ret |= ((uint64_t)(uint8_t)c) << (j * 8); -+ } -+ env->fr[rc + i * 32] = ret; -+ } -+} -+ -+void helper_vucsubbi(CPUSW64State *env, uint64_t ra, uint64_t vb, uint64_t rc) -+{ -+ int8_t a, b, c; -+ uint64_t ret; -+ int i, j; -+ -+ b = (int8_t)(vb & 0xff); -+ for (i = 0; i < 4; i++) { -+ ret = 0; -+ for (j = 0; j < 8; j++) { -+ a = (int8_t)((env->fr[ra + i * 32] >> (j * 8)) & 0xffff); -+ c = a - b; -+ if ((b ^ a) < 0 && (c ^ a) < 0) { -+ if (a < 0) -+ c = 0x80; -+ else -+ c = 0x7f; -+ } -+ ret |= ((uint64_t)(uint8_t)c) << (j * 8); -+ } -+ env->fr[rc + i * 32] = ret; -+ } -+} -+ -+uint64_t helper_vstw(CPUSW64State *env, uint64_t t0, uint64_t t1) -+{ -+ uint64_t idx, shift; -+ -+ idx = t0 + (t1 / 2) * 32; -+ shift = (t1 % 2) * 32; -+ -+ return (env->fr[idx] >> shift) & 0xffffffffUL; -+} -+ -+uint64_t helper_vsts(CPUSW64State *env, uint64_t t0, uint64_t t1) -+{ -+ uint64_t idx, val; -+ -+ idx = t0 + t1 * 32; -+ val = env->fr[idx]; -+ -+ return ((val >> 32) & 0xc0000000) | ((val >> 29) & 0x3fffffff); -+} -+ -+uint64_t helper_vstd(CPUSW64State *env, uint64_t t0, uint64_t t1) -+{ -+ uint64_t idx; -+ -+ idx = t0 + t1 * 32; -+ return env->fr[idx]; -+} -+ -+#define HELPER_VMAX(name, _suffix, type, loop) \ -+ void glue(glue(helper_, name), _suffix)(CPUSW64State *env, uint64_t ra, \ -+ uint64_t rb, uint64_t rc) \ -+ { \ -+ int i; \ -+ type *ptr_dst, *ptr_src_a, *ptr_src_b; \ -+ \ -+ for (i = 0; i < loop; i++) { \ -+ ptr_dst = (type*)glue(get_element_, _suffix)(env, rc, i); \ -+ ptr_src_a = (type*)glue(get_element_, _suffix)(env, ra, i); \ -+ ptr_src_b = (type*)glue(get_element_, _suffix)(env, rb, i); \ -+ \ -+ if (*ptr_src_a >= *ptr_src_b) { \ -+ *ptr_dst = *ptr_src_a; \ -+ } else { \ -+ *ptr_dst = *ptr_src_b; \ -+ } \ -+ } \ -+ } -+ -+#define HELPER_VMIN(name, _suffix, type, loop) \ -+ void glue(glue(helper_, name), _suffix)(CPUSW64State *env, uint64_t ra, \ -+ uint64_t rb, uint64_t rc) \ -+ { \ -+ int i; \ -+ type *ptr_dst, *ptr_src_a, *ptr_src_b; \ -+ \ -+ for (i = 0; i < loop; i++) { \ -+ ptr_dst = (type*)glue(get_element_, _suffix)(env, rc, i); \ -+ ptr_src_a = (type*)glue(get_element_, _suffix)(env, ra, i); \ -+ ptr_src_b = (type*)glue(get_element_, _suffix)(env, rb, i); \ -+ \ -+ if (*ptr_src_a <= *ptr_src_b) { \ -+ *ptr_dst = *ptr_src_a; \ -+ } else { \ -+ *ptr_dst = *ptr_src_b; \ -+ } \ -+ } \ -+ } -+ -+HELPER_VMAX(vmax, b, int8_t, 32) -+HELPER_VMIN(vmin, b, int8_t, 32) -+HELPER_VMAX(vmax, h, int16_t, 16) -+HELPER_VMIN(vmin, h, int16_t, 16) -+HELPER_VMAX(vmax, w, int32_t, 8) -+HELPER_VMIN(vmin, w, int32_t, 8) -+HELPER_VMAX(vumax, b, uint8_t, 32) -+HELPER_VMIN(vumin, b, uint8_t, 32) -+HELPER_VMAX(vumax, h, uint16_t, 16) -+HELPER_VMIN(vumin, h, uint16_t, 16) -+HELPER_VMAX(vumax, w, uint32_t, 8) -+HELPER_VMIN(vumin, w, uint32_t, 8) -+ -+void helper_sraow(CPUSW64State *env, uint64_t ra, uint64_t rc, uint64_t shift) -+{ -+ int i; -+ int adden; -+ int dest, src; -+ uint64_t sign; -+ adden = shift >> 6; -+ shift &= 0x3f; -+ sign = (uint64_t)((int64_t)env->fr[ra + 96] >> 63); -+#ifdef DEBUG_SIMD -+ printf("right shift = %ld adden = %d\n", shift, adden); -+ printf("in_fr[%ld]:", ra); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[ra + 32 * i]); -+ } -+ printf("\n"); -+#endif -+ -+ for (i = 0; (i + adden) < 4; i++) { -+ dest = i * 32 + rc; -+ src = (i + adden) * 32 + ra; -+ env->fr[dest] = env->fr[src] >> shift; -+ if (shift != 0) { -+ if (((i + adden) < 3)) -+ env->fr[dest] |= (env->fr[src + 32] << (64 - shift)); -+ else -+ env->fr[dest] |= (sign << (64 - shift)); -+ } -+ } -+ -+ for (; i < 4; i++) { -+ env->fr[rc + i * 32] = sign; -+ } -+#ifdef DEBUG_SIMD -+ printf("out_fr[%ld]:", rc); -+ for (i = 3 ; i >= 0; i--) { -+ printf("%016lx ", env->fr[rc + 32 * i]); -+ } -+ printf("\n"); -+#endif -+} -+ -+static uint16_t sm4_sbox[16][16] = { -+ { 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05 }, -+ { 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99 }, -+ { 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62 }, -+ { 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6 }, -+ { 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8 }, -+ { 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35 }, -+ { 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87 }, -+ { 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e }, -+ { 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1 }, -+ { 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3 }, -+ { 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f }, -+ { 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51 }, -+ { 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8 }, -+ { 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0 }, -+ { 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84 }, -+ { 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48 } -+}; -+ -+static uint32_t SBOX(uint32_t val) -+{ -+ int ret = 0; -+ int i; -+ int idx_x, idx_y; -+ for (i = 0; i < 4; i++) { -+ idx_x = (val >> (i * 8)) & 0xff; -+ idx_y = idx_x & 0xf; -+ idx_x = idx_x >> 4; -+ -+ ret |= (sm4_sbox[idx_x][idx_y] << (i * 8)); -+ } -+ return ret; -+} -+ -+static uint32_t rotl(uint32_t val, int shift) -+{ -+ uint64_t ret = (uint64_t)val; -+ ret = (ret << (shift & 0x1f)); -+ return (uint32_t)((ret & 0xffffffff) | (ret >> 32)); -+} -+ -+void helper_vsm4r(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ uint32_t W[12], rk[8]; -+ uint32_t temp1, temp2; -+ int i, j; -+ -+ for (i = 0; i < 8; i++) { -+ rk[i] = *get_element_w(env, rb, i); -+ } -+ for (i = 0; i < 2; i++) { -+ for (j = 0; j < 4; j++) { -+ W[j] = *get_element_w(env, ra, i * 4 + j); -+ } -+ for (j = 0; j < 8; j++) { -+ temp1 = W[j + 1] ^ W[j + 2] ^ W[j + 3] ^ rk[j]; -+ temp2 = SBOX(temp1); -+ W[j + 4] = W[j] ^ temp2 ^ rotl(temp2, 2) ^ rotl(temp2, 10) ^ rotl(temp2, 18) ^ rotl(temp2, 24); -+ } -+ -+ for (j = 0; j < 4; j++) { -+ *get_element_w(env, rc, i * 4 + j) = W[8 + j]; -+ } -+ } -+} -+ -+void helper_vcmpueqb(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ uint8_t *ptr_a, *ptr_b, *ptr_c; -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ ptr_a = get_element_b(env, ra, i); -+ ptr_b = get_element_b(env, rb, i); -+ ptr_c = get_element_b(env, rc, i); -+ -+ *ptr_c = (*ptr_a == *ptr_b) ? 1 : 0; -+ ; -+ } -+} -+ -+void helper_vcmpugtb(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ uint8_t *ptr_a, *ptr_b, *ptr_c; -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ ptr_a = get_element_b(env, ra, i); -+ ptr_b = get_element_b(env, rb, i); -+ ptr_c = get_element_b(env, rc, i); -+ -+ *ptr_c = (*ptr_a > *ptr_b) ? 1 : 0; -+ ; -+ } -+} -+ -+void helper_vcmpueqbi(CPUSW64State *env, uint64_t ra, uint64_t vb, -+ uint64_t rc) -+{ -+ uint8_t *ptr_a, *ptr_c; -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ ptr_a = get_element_b(env, ra, i); -+ ptr_c = get_element_b(env, rc, i); -+ -+ *ptr_c = (*ptr_a == vb) ? 1 : 0; -+ ; -+ } -+} -+ -+void helper_vcmpugtbi(CPUSW64State *env, uint64_t ra, uint64_t vb, -+ uint64_t rc) -+{ -+ uint8_t *ptr_a, *ptr_c; -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ ptr_a = get_element_b(env, ra, i); -+ ptr_c = get_element_b(env, rc, i); -+ -+ *ptr_c = (*ptr_a > vb) ? 1 : 0; -+ ; -+ } -+} -+ -+void helper_vsm3msw(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rc) -+{ -+ uint32_t W[24]; -+ uint32_t temp; -+ int i; -+ -+ for (i = 0; i < 8; i++) { -+ W[i + 0] = *get_element_w(env, ra, i); -+ W[i + 8] = *get_element_w(env, rb, i); -+ } -+ for (i = 16; i < 24; i++) { -+ temp = W[i - 16] ^ W[i - 9] ^ rotl(W[i - 3], 15); -+ temp = temp ^ rotl(temp, 15) ^ rotl(temp, 23) ^ rotl(W[i - 13], 7) ^ W[i - 6]; -+ W[i] = temp; -+ } -+ for (i = 0; i < 8; i++) { -+ *get_element_w(env, rc, i) = W[16 + i]; -+ } -+} -+ -+static uint32_t selck[4][8] = { -+ {0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9}, -+ {0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9}, -+ {0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299}, -+ {0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279} -+}; -+ -+void helper_vsm4key(CPUSW64State *env, uint64_t ra, uint64_t vb, uint64_t rc) -+{ -+ uint32_t K[12], *CK; -+ int i; -+ uint32_t temp1, temp2; -+ -+ for (i = 4; i < 8; i++) { -+ K[i - 4] = *get_element_w(env, ra, i); -+ } -+ CK = selck[vb]; -+ -+ for (i = 0; i < 8; i++) { -+ temp1 = K[i + 1] ^ K[i + 2] ^ K[i + 3] ^ CK[i]; -+ temp2 = SBOX(temp1); -+ K[i + 4] = K[i] ^ temp2 ^ rotl(temp2, 13) ^ rotl(temp2, 23); -+ } -+ for (i = 0; i < 8; i++) { -+ *get_element_w(env, rc, i) = K[i + 4]; -+ } -+} -+ -+void helper_vinsb(CPUSW64State *env, uint64_t va, uint64_t rb, uint64_t vc, -+ uint64_t rd) -+{ -+ int i; -+ -+ for (i = 0; i < 128; i += 32) { -+ env->fr[rd + i] = env->fr[rb + i]; -+ } -+ -+ *get_element_b(env, rd, vc) = (uint8_t)(va & 0xff); -+} -+ -+void helper_vinsh(CPUSW64State *env, uint64_t va, uint64_t rb, uint64_t vc, -+ uint64_t rd) -+{ -+ int i; -+ -+ if (vc >= 16) -+ return; -+ -+ for (i = 0; i < 128; i += 32) { -+ env->fr[rd + i] = env->fr[rb + i]; -+ } -+ -+ *get_element_h(env, rd, vc) = (uint16_t)(va & 0xffff); -+} -+ -+void helper_vinsectlh(CPUSW64State *env, uint64_t ra, uint64_t rb, -+ uint64_t rd) -+{ -+ int i; -+ uint32_t temp[8]; -+ for (i = 0; i < 8; i++) { -+ temp[i] = *get_element_h(env, ra, i) | ((uint32_t)*get_element_h(env, rb, i) << 16); -+ } -+ for (i = 0; i < 8; i++) { -+ *get_element_w(env, rd, i) = temp[i]; -+ } -+} -+void helper_vinsectlw(CPUSW64State *env, uint64_t ra, uint64_t rb, -+ uint64_t rd) -+{ -+ int i; -+ uint64_t temp[4]; -+ for (i = 0; i < 4; i++) { -+ temp[i] = *get_element_w(env, ra, i) | ((uint64_t)*get_element_w(env, rb, i) << 32); -+ } -+ for (i = 0; i < 4; i++) { -+ *get_element_l(env, rd, i) = temp[i]; -+ } -+} -+ -+void helper_vinsectlb(CPUSW64State *env, uint64_t ra, uint64_t rb, -+ uint64_t rd) -+{ -+ int i; -+ uint16_t temp[16]; -+ for (i = 0; i < 16; i++) { -+ temp[i] = *get_element_b(env, ra, i) | ((uint16_t)*get_element_b(env, rb, i) << 8); -+ } -+ for (i = 0; i < 16; i++) { -+ *get_element_h(env, rd, i) = temp[i]; -+ } -+} -+ -+void helper_vshfq(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t vc, -+ uint64_t rd) -+{ -+ int i; -+ int idx; -+ uint64_t temp[4]; -+ for (i = 0; i < 2; i++) { -+ idx = ((vc >> (i * 2)) & 1) * 64; -+ if ((vc >> (i * 2 + 1)) & 1) { -+ temp[i * 2] = env->fr[rb + idx]; -+ temp[i * 2 + 1] = env->fr[rb + idx + 32]; -+ } else { -+ temp[i * 2] = env->fr[ra + idx]; -+ temp[i * 2 + 1] = env->fr[ra + idx + 32]; -+ } -+ } -+ for (i = 0; i < 4; i++) { -+ env->fr[rd + i * 32] = temp[i]; -+ } -+} -+ -+void helper_vshfqb(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t rd) -+{ -+ int i; -+ int idx; -+ int vb; -+ uint8_t temp[32]; -+ -+ for (i = 0; i < 16; i++) { -+ vb = *get_element_b(env, rb, i); -+ if (vb >> 7) { -+ temp[i] = 0; -+ } else { -+ idx = vb & 0xf; -+ temp[i] = *get_element_b(env, ra, idx); -+ } -+ vb = *get_element_b(env, rb, i + 16); -+ if (vb >> 7) { -+ temp[i + 16] = 0; -+ } else { -+ idx = vb & 0xf; -+ temp[i + 16] = *get_element_b(env, ra, idx + 16); -+ } -+ } -+ for (i = 0; i < 4; i++) { -+ env->fr[rd + i * 32] = *((uint64_t*)temp + i); -+ } -+} -+ -+void helper_vsm3r(CPUSW64State *env, uint64_t ra, uint64_t rb, uint64_t vc, -+ uint64_t rd) -+{ -+ uint32_t W[8]; -+ uint32_t A, B, C, D, E, F, G, H, T; -+ int i; -+ uint32_t SS1, SS2, TT1, TT2, P0; -+ -+ if (vc >= 16) -+ return; -+ for (i = 0; i < 8; i++) { -+ W[i] = *get_element_w(env, ra, i); -+ } -+ A = *get_element_w(env, rb, 0); -+ B = *get_element_w(env, rb, 1); -+ C = *get_element_w(env, rb, 2); -+ D = *get_element_w(env, rb, 3); -+ E = *get_element_w(env, rb, 4); -+ F = *get_element_w(env, rb, 5); -+ G = *get_element_w(env, rb, 6); -+ H = *get_element_w(env, rb, 7); -+ -+ if (vc < 4) { -+ T = 0x79cc4519; -+ for (i = 0; i < 4; i++) { -+ SS1 = rotl(rotl(A, 12) + E + rotl(T, 4 * vc + i), 7); -+ SS2 = SS1 ^ rotl(A, 12); -+ TT1 = (A ^ B ^ C) + D + SS2 + (W[i] ^ W[i + 4]); -+ TT2 = (E ^ F ^ G) + H + SS1 + W[i]; -+ -+ P0 = TT2 ^ rotl(TT2, 9) ^ rotl(TT2, 17); -+ -+ H = G; -+ G = rotl(F, 19); -+ F = E; -+ E = P0; -+ D = C; -+ C = rotl(B, 9); -+ B = A; -+ A = TT1; -+ } -+ } else { -+ T = 0x7a879d8a; -+ for (i = 0; i < 4; i++) { -+ SS1 = rotl(rotl(A, 12) + E + rotl(T, 4 * vc + i), 7); -+ SS2 = SS1 ^ rotl(A, 12); -+ TT1 = ((A & B) | (A & C) | (B & C)) + D + SS2 + (W[i] ^ W[i + 4]); -+ TT2 = ((E & F) | ((~E) & G)) + H + SS1 + W[i]; -+ -+ P0 = TT2 ^ rotl(TT2, 9) ^ rotl(TT2, 17); -+ -+ H = G; -+ G = rotl(F, 19); -+ F = E; -+ E = P0; -+ D = C; -+ C = rotl(B, 9); -+ B = A; -+ A = TT1; -+ } -+ } -+ *get_element_w(env, rd, 0) = A; -+ *get_element_w(env, rd, 1) = B; -+ *get_element_w(env, rd, 2) = C; -+ *get_element_w(env, rd, 3) = D; -+ *get_element_w(env, rd, 4) = E; -+ *get_element_w(env, rd, 5) = F; -+ *get_element_w(env, rd, 6) = G; -+ *get_element_w(env, rd, 7) = H; -+} -diff --git a/target/sw64/translate.c b/target/sw64/translate.c -new file mode 100644 -index 0000000000..37b7e89077 ---- /dev/null -+++ b/target/sw64/translate.c -@@ -0,0 +1,3798 @@ -+#include "translate.h" -+#include "tcg/tcg.h" -+#define DEVELOP_SW64 1 -+#ifdef DEVELOP_SW64 -+ -+#define ILLEGAL(x) \ -+ do { \ -+ printf("Illegal SW64 0x%x at line %d!\n", x, __LINE__); \ -+ exit(-1); \ -+ } while (0) -+#endif -+ -+TCGv cpu_pc; -+TCGv cpu_std_ir[31]; -+TCGv cpu_fr[128]; -+TCGv cpu_lock_addr; -+TCGv cpu_lock_flag; -+TCGv cpu_lock_success; -+#ifdef SW64_FIXLOCK -+TCGv cpu_lock_value; -+#endif -+ -+#ifndef CONFIG_USER_ONLY -+TCGv cpu_hm_ir[31]; -+#endif -+ -+#include "exec/gen-icount.h" -+ -+void sw64_translate_init(void) -+{ -+#define DEF_VAR(V) \ -+ { &cpu_##V, #V, offsetof(CPUSW64State, V) } -+ -+ typedef struct { -+ TCGv* var; -+ const char* name; -+ int ofs; -+ } GlobalVar; -+ -+ static const GlobalVar vars[] = { -+ DEF_VAR(pc), DEF_VAR(lock_addr), -+ DEF_VAR(lock_flag), DEF_VAR(lock_success), -+#ifdef SW64_FIXLOCK -+ DEF_VAR(lock_value), -+#endif -+ }; -+ cpu_pc = tcg_global_mem_new_i64(cpu_env, -+ offsetof(CPUSW64State, pc), "PC"); -+ -+#undef DEF_VAR -+ -+ /* Use the symbolic register names that match the disassembler. */ -+ static const char ireg_names[31][4] = { -+ "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0", "s1", -+ "s2", "s3", "s4", "s5", "fp", "a0", "a1", "a2", "a3", "a4", "a5", -+ "t8", "t9", "t10", "t11", "ra", "t12", "at", "gp", "sp"}; -+ -+ static const char freg_names[128][4] = { -+ "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", "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", "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", "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"}; -+ -+#ifndef CONFIG_USER_ONLY -+ static const char shadow_names[10][8] = { -+ "hm_p1", "hm_p2", "hm_p4", "hm_p5", "hm_p6", -+ "hm_p7", "hm_p20", "hm_p21", "hm_p22", "hm_p23"}; -+ static const int shadow_index[10] = {1, 2, 4, 5, 6, 7, 20, 21, 22, 23}; -+#endif -+ -+ int i; -+ -+ for (i = 0; i < 31; i++) { -+ cpu_std_ir[i] = tcg_global_mem_new_i64( -+ cpu_env, offsetof(CPUSW64State, ir[i]), ireg_names[i]); -+ } -+ -+ for (i = 0; i < 128; i++) { -+ cpu_fr[i] = tcg_global_mem_new_i64( -+ cpu_env, offsetof(CPUSW64State, fr[i]), freg_names[i]); -+ } -+ for (i = 0; i < ARRAY_SIZE(vars); ++i) { -+ const GlobalVar* v = &vars[i]; -+ *v->var = tcg_global_mem_new_i64(cpu_env, v->ofs, v->name); -+ } -+#ifndef CONFIG_USER_ONLY -+ memcpy(cpu_hm_ir, cpu_std_ir, sizeof(cpu_hm_ir)); -+ for (i = 0; i < 10; i++) { -+ int r = shadow_index[i]; -+ cpu_hm_ir[r] = tcg_global_mem_new_i64( -+ cpu_env, offsetof(CPUSW64State, sr[i]), shadow_names[i]); -+ } -+#endif -+} -+ -+static bool in_superpage(DisasContext* ctx, int64_t addr) -+{ -+ return false; -+} -+ -+bool use_exit_tb(DisasContext* ctx) -+{ -+ return ((tb_cflags(ctx->base.tb) & CF_LAST_IO) || -+ ctx->base.singlestep_enabled || singlestep); -+} -+ -+bool use_goto_tb(DisasContext* ctx, uint64_t dest) -+{ -+ /* Suppress goto_tb in the case of single-steping and IO. */ -+ if (unlikely(use_exit_tb(ctx))) { -+ return false; -+ } -+ /* If the destination is in the superpage, the page perms can't change. */ -+ if (in_superpage(ctx, dest)) { -+ return true; -+ } -+/* Check for the dest on the same page as the start of the TB. */ -+#ifndef CONFIG_USER_ONLY -+ return ((ctx->base.tb->pc ^ dest) & TARGET_PAGE_MASK) == 0; -+#else -+ return true; -+#endif -+} -+ -+void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src) -+{ -+ uint64_t mzero = 1ull << 63; -+ -+ switch (cond) { -+ case TCG_COND_LE: -+ case TCG_COND_GT: -+ /* For <= or >, the -0.0 value directly compares the way we want. */ -+ tcg_gen_mov_i64(dest, src); -+ break; -+ -+ case TCG_COND_EQ: -+ case TCG_COND_NE: -+ /* For == or !=, we can simply mask off the sign bit and compare. */ -+ tcg_gen_andi_i64(dest, src, mzero - 1); -+ break; -+ -+ case TCG_COND_GE: -+ case TCG_COND_LT: -+ /* For >= or <, map -0.0 to +0.0 via comparison and mask. */ -+ tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero); -+ tcg_gen_neg_i64(dest, dest); -+ tcg_gen_and_i64(dest, dest, src); -+ break; -+ -+ default: -+ abort(); -+ } -+} -+ -+static TCGv load_zero(DisasContext *ctx) -+{ -+ if (!ctx->zero) { -+ ctx->zero = tcg_const_i64(0); -+ } -+ return ctx->zero; -+} -+ -+static void free_context_temps(DisasContext *ctx) -+{ -+ if (ctx->zero) { -+ tcg_temp_free(ctx->zero); -+ ctx->zero = NULL; -+ } -+} -+ -+static TCGv load_gir(DisasContext *ctx, unsigned reg) -+{ -+ if (likely(reg < 31)) { -+ return ctx->ir[reg]; -+ } else { -+ return load_zero(ctx); -+ } -+} -+ -+static void gen_excp_1(int exception, int error_code) -+{ -+ TCGv_i32 tmp1, tmp2; -+ -+ tmp1 = tcg_const_i32(exception); -+ tmp2 = tcg_const_i32(error_code); -+ gen_helper_excp(cpu_env, tmp1, tmp2); -+ tcg_temp_free_i32(tmp2); -+ tcg_temp_free_i32(tmp1); -+} -+ -+static DisasJumpType gen_excp(DisasContext* ctx, int exception, -+ int error_code) -+{ -+ tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); -+ gen_excp_1(exception, error_code); -+ return DISAS_NORETURN; -+} -+ -+static int i_count = 1; -+ -+static inline DisasJumpType gen_invalid(DisasContext *ctx) -+{ -+ if (i_count == 0) { -+ i_count++; -+ return DISAS_NEXT; -+ } -+ fprintf(stderr, "here %lx\n", ctx->base.pc_next); -+ return gen_excp(ctx, EXCP_OPCDEC, 0); -+} -+ -+static uint64_t zapnot_mask(uint8_t byte_mask) -+{ -+ uint64_t mask = 0; -+ int i; -+ -+ for (i = 0; i < 8; ++i) { -+ if ((byte_mask >> i) & 1) { -+ mask |= 0xffull << (i * 8); -+ } -+ } -+ return mask; -+} -+ -+static void gen_ins_l(DisasContext* ctx, TCGv vc, TCGv va, TCGv vb, -+ uint8_t byte_mask) -+{ -+ TCGv tmp = tcg_temp_new(); -+ TCGv shift = tcg_temp_new(); -+ -+ tcg_gen_andi_i64(tmp, va, zapnot_mask(byte_mask)); -+ -+ tcg_gen_andi_i64(shift, vb, 7); -+ tcg_gen_shli_i64(shift, shift, 3); -+ tcg_gen_shl_i64(vc, tmp, shift); -+ -+ tcg_temp_free(shift); -+ tcg_temp_free(tmp); -+} -+ -+static void gen_ins_h(DisasContext* ctx, TCGv vc, TCGv va, TCGv vb, -+ uint8_t byte_mask) -+{ -+ TCGv tmp = tcg_temp_new(); -+ TCGv shift = tcg_temp_new(); -+ -+ tcg_gen_andi_i64(tmp, va, zapnot_mask(byte_mask)); -+ -+ tcg_gen_shli_i64(shift, vb, 3); -+ tcg_gen_not_i64(shift, shift); -+ tcg_gen_andi_i64(shift, shift, 0x3f); -+ -+ tcg_gen_shr_i64(vc, tmp, shift); -+ tcg_gen_shri_i64(vc, vc, 1); -+ tcg_temp_free(shift); -+ tcg_temp_free(tmp); -+} -+ -+static void gen_ext_l(DisasContext* ctx, TCGv vc, TCGv va, TCGv vb, -+ uint8_t byte_mask) -+{ -+ TCGv tmp = tcg_temp_new(); -+ TCGv shift = tcg_temp_new(); -+ -+ tcg_gen_andi_i64(shift, vb, 7); -+ tcg_gen_shli_i64(shift, shift, 3); -+ tcg_gen_shr_i64(tmp, va, shift); -+ -+ tcg_gen_andi_i64(vc, tmp, zapnot_mask(byte_mask)); -+ -+ tcg_temp_free(shift); -+ tcg_temp_free(tmp); -+} -+ -+static void gen_ext_h(DisasContext* ctx, TCGv vc, TCGv va, TCGv vb, -+ uint8_t byte_mask) -+{ -+ TCGv tmp = tcg_temp_new(); -+ TCGv shift = tcg_temp_new(); -+ -+ tcg_gen_andi_i64(shift, vb, 7); -+ tcg_gen_shli_i64(shift, shift, 3); -+ tcg_gen_movi_i64(tmp, 64); -+ tcg_gen_sub_i64(shift, tmp, shift); -+ tcg_gen_shl_i64(tmp, va, shift); -+ -+ tcg_gen_andi_i64(vc, tmp, zapnot_mask(byte_mask)); -+ -+ tcg_temp_free(shift); -+ tcg_temp_free(tmp); -+} -+ -+static void gen_mask_l(DisasContext* ctx, TCGv vc, TCGv va, TCGv vb, -+ uint8_t byte_mask) -+{ -+ TCGv shift = tcg_temp_new(); -+ TCGv mask = tcg_temp_new(); -+ -+ tcg_gen_andi_i64(shift, vb, 7); -+ tcg_gen_shli_i64(shift, shift, 3); -+ tcg_gen_movi_i64(mask, zapnot_mask(byte_mask)); -+ tcg_gen_shl_i64(mask, mask, shift); -+ -+ tcg_gen_andc_i64(vc, va, mask); -+ -+ tcg_temp_free(mask); -+ tcg_temp_free(shift); -+} -+ -+static void gen_mask_h(DisasContext *ctx, TCGv vc, TCGv va, TCGv vb, -+ uint8_t byte_mask) -+{ -+ TCGv shift = tcg_temp_new(); -+ TCGv mask = tcg_temp_new(); -+ -+ /* The instruction description is as above, where the byte_mask -+ is shifted left, and then we extract bits <15:8>. This can be -+ emulated with a right-shift on the expanded byte mask. This -+ requires extra care because for an input <2:0> == 0 we need a -+ shift of 64 bits in order to generate a zero. This is done by -+ splitting the shift into two parts, the variable shift - 1 -+ followed by a constant 1 shift. The code we expand below is -+ equivalent to ~(B * 8) & 63. */ -+ -+ tcg_gen_shli_i64(shift, vb, 3); -+ tcg_gen_not_i64(shift, shift); -+ tcg_gen_andi_i64(shift, shift, 0x3f); -+ tcg_gen_movi_i64(mask, zapnot_mask(byte_mask)); -+ tcg_gen_shr_i64(mask, mask, shift); -+ tcg_gen_shri_i64(mask, mask, 1); -+ -+ tcg_gen_andc_i64(vc, va, mask); -+ -+ tcg_temp_free(mask); -+ tcg_temp_free(shift); -+} -+ -+static inline void gen_load_mem( -+ DisasContext *ctx, void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1, int flags), -+ int ra, int rb, int32_t disp16, bool fp, bool clear) -+{ -+ TCGv tmp, addr, va; -+ -+ /* LDQ_U with ra $31 is UNOP. Other various loads are forms of -+ prefetches, which we can treat as nops. No worries about -+ missed exceptions here. */ -+ if (unlikely(ra == 31)) { -+ return; -+ } -+ -+ tmp = tcg_temp_new(); -+ addr = load_gir(ctx, rb); -+ -+ if (disp16) { -+ tcg_gen_addi_i64(tmp, addr, (int64_t)disp16); -+ addr = tmp; -+ } else { -+ tcg_gen_mov_i64(tmp, addr); -+ addr = tmp; -+ } -+ if (clear) { -+ tcg_gen_andi_i64(tmp, addr, ~0x7UL); -+ addr = tmp; -+ } -+ -+ va = (fp ? cpu_fr[ra] : load_gir(ctx, ra)); -+ tcg_gen_qemu_load(va, addr, ctx->mem_idx); -+ -+ tcg_temp_free(tmp); -+} -+ -+static inline void gen_store_mem( -+ DisasContext *ctx, void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1, int flags), -+ int ra, int rb, int32_t disp16, bool fp, bool clear) -+{ -+ TCGv tmp, addr, va; -+ -+ tmp = tcg_temp_new(); -+ addr = load_gir(ctx, rb); -+ if (disp16) { -+ tcg_gen_addi_i64(tmp, addr, disp16); -+ addr = tmp; -+ } else { -+ tcg_gen_mov_i64(tmp, addr); -+ addr = tmp; -+ } -+ if (clear) { -+ tcg_gen_andi_i64(tmp, addr, ~0x7); -+ addr = tmp; -+ } -+ va = (fp ? cpu_fr[ra] : load_gir(ctx, ra)); -+ -+ tcg_gen_qemu_store(va, addr, ctx->mem_idx); -+ gen_helper_trace_mem(cpu_env, addr, va); -+ tcg_temp_free(tmp); -+} -+ -+static void cal_with_iregs_2(DisasContext *ctx, TCGv vc, TCGv va, TCGv vb, -+ int32_t disp13, uint16_t fn) -+{ -+ TCGv tmp; -+ -+ switch (fn & 0xff) { -+ case 0x00: -+ /* ADDW */ -+ tcg_gen_add_i64(vc, va, vb); -+ tcg_gen_ext32s_i64(vc, vc); -+ break; -+ case 0x01: -+ /* SUBW */ -+ tcg_gen_sub_i64(vc, va, vb); -+ tcg_gen_ext32s_i64(vc, vc); -+ break; -+ case 0x02: -+ /* S4ADDW */ -+ tmp = tcg_temp_new(); -+ tcg_gen_shli_i64(tmp, va, 2); -+ tcg_gen_add_i64(tmp, tmp, vb); -+ tcg_gen_ext32s_i64(vc, tmp); -+ tcg_temp_free(tmp); -+ break; -+ case 0x03: -+ /* S4SUBW */ -+ tmp = tcg_temp_new(); -+ tcg_gen_shli_i64(tmp, va, 2); -+ tcg_gen_sub_i64(tmp, tmp, vb); -+ tcg_gen_ext32s_i64(vc, tmp); -+ tcg_temp_free(tmp); -+ break; -+ case 0x04: -+ /* S8ADDW */ -+ tmp = tcg_temp_new(); -+ tcg_gen_shli_i64(tmp, va, 3); -+ tcg_gen_add_i64(tmp, tmp, vb); -+ tcg_gen_ext32s_i64(vc, tmp); -+ tcg_temp_free(tmp); -+ break; -+ case 0x05: -+ /* S8SUBW */ -+ tmp = tcg_temp_new(); -+ tcg_gen_shli_i64(tmp, va, 3); -+ tcg_gen_sub_i64(tmp, tmp, vb); -+ tcg_gen_ext32s_i64(vc, tmp); -+ tcg_temp_free(tmp); -+ break; -+ -+ case 0x08: -+ /* ADDL */ -+ tcg_gen_add_i64(vc, va, vb); -+ break; -+ case 0x09: -+ /* SUBL */ -+ tcg_gen_sub_i64(vc, va, vb); -+ break; -+ case 0x0a: -+ /* S4ADDL */ -+ tmp = tcg_temp_new(); -+ tcg_gen_shli_i64(tmp, va, 2); -+ tcg_gen_add_i64(vc, tmp, vb); -+ tcg_temp_free(tmp); -+ break; -+ case 0x0b: -+ /* S4SUBL */ -+ tmp = tcg_temp_new(); -+ tcg_gen_shli_i64(tmp, va, 2); -+ tcg_gen_sub_i64(vc, tmp, vb); -+ tcg_temp_free(tmp); -+ break; -+ case 0x0c: -+ /* S8ADDL */ -+ tmp = tcg_temp_new(); -+ tcg_gen_shli_i64(tmp, va, 3); -+ tcg_gen_add_i64(vc, tmp, vb); -+ tcg_temp_free(tmp); -+ break; -+ case 0x0d: -+ /* S8SUBL */ -+ tmp = tcg_temp_new(); -+ tcg_gen_shli_i64(tmp, va, 3); -+ tcg_gen_sub_i64(vc, tmp, vb); -+ tcg_temp_free(tmp); -+ break; -+ case 0x10: -+ /* MULW */ -+ tcg_gen_mul_i64(vc, va, vb); -+ tcg_gen_ext32s_i64(vc, vc); -+ break; -+ case 0x18: -+ /* MULL */ -+ tcg_gen_mul_i64(vc, va, vb); -+ break; -+ case 0x19: -+ /* MULH */ -+ tmp = tcg_temp_new(); -+ tcg_gen_mulu2_i64(tmp, vc, va, vb); -+ tcg_temp_free(tmp); -+ break; -+ case 0x28: -+ /* CMPEQ */ -+ tcg_gen_setcond_i64(TCG_COND_EQ, vc, va, vb); -+ break; -+ case 0x29: -+ /* CMPLT */ -+ tcg_gen_setcond_i64(TCG_COND_LT, vc, va, vb); -+ break; -+ case 0x2a: -+ /* CMPLE */ -+ tcg_gen_setcond_i64(TCG_COND_LE, vc, va, vb); -+ break; -+ case 0x2b: -+ /* CMPULT */ -+ tcg_gen_setcond_i64(TCG_COND_LTU, vc, va, vb); -+ break; -+ case 0x2c: -+ /* CMPULE */ -+ tcg_gen_setcond_i64(TCG_COND_LEU, vc, va, vb); -+ break; -+ case 0x38: -+ /* AND */ -+ tcg_gen_and_i64(vc, va, vb); -+ break; -+ case 0x39: -+ /* BIC */ -+ tcg_gen_andc_i64(vc, va, vb); -+ break; -+ case 0x3a: -+ /* BIS */ -+ tcg_gen_or_i64(vc, va, vb); -+ break; -+ case 0x3b: -+ /* ORNOT */ -+ tcg_gen_orc_i64(vc, va, vb); -+ break; -+ case 0x3c: -+ /* XOR */ -+ tcg_gen_xor_i64(vc, va, vb); -+ break; -+ case 0x3d: -+ /* EQV */ -+ tcg_gen_eqv_i64(vc, va, vb); -+ break; -+ case 0x40: -+ /* INSLB */ -+ gen_ins_l(ctx, vc, va, vb, 0x1); -+ break; -+ case 0x41: -+ /* INSLH */ -+ gen_ins_l(ctx, vc, va, vb, 0x3); -+ break; -+ case 0x42: -+ /* INSLW */ -+ gen_ins_l(ctx, vc, va, vb, 0xf); -+ break; -+ case 0x43: -+ /* INSLL */ -+ gen_ins_l(ctx, vc, va, vb, 0xff); -+ break; -+ case 0x44: -+ /* INSHB */ -+ gen_ins_h(ctx, vc, va, vb, 0x1); -+ break; -+ case 0x45: -+ /* INSHH */ -+ gen_ins_h(ctx, vc, va, vb, 0x3); -+ break; -+ case 0x46: -+ /* INSHW */ -+ gen_ins_h(ctx, vc, va, vb, 0xf); -+ break; -+ case 0x47: -+ /* INSHL */ -+ gen_ins_h(ctx, vc, va, vb, 0xff); -+ break; -+ case 0x48: -+ /* SLL/SLLL */ -+ tmp = tcg_temp_new(); -+ tcg_gen_andi_i64(tmp, vb, 0x3f); -+ tcg_gen_shl_i64(vc, va, tmp); -+ tcg_temp_free(tmp); -+ break; -+ case 0x49: -+ /* SRL/SRLL */ -+ tmp = tcg_temp_new(); -+ tcg_gen_andi_i64(tmp, vb, 0x3f); -+ tcg_gen_shr_i64(vc, va, tmp); -+ tcg_temp_free(tmp); -+ break; -+ case 0x4a: -+ /* SRA/SRAL */ -+ tmp = tcg_temp_new(); -+ tcg_gen_andi_i64(tmp, vb, 0x3f); -+ tcg_gen_sar_i64(vc, va, tmp); -+ tcg_temp_free(tmp); -+ break; -+ case 0x50: -+ /* EXTLB */ -+ gen_ext_l(ctx, vc, va, vb, 0x1); -+ break; -+ case 0x51: -+ /* EXTLH */ -+ gen_ext_l(ctx, vc, va, vb, 0x3); -+ break; -+ case 0x52: -+ /* EXTLW */ -+ gen_ext_l(ctx, vc, va, vb, 0xf); -+ break; -+ case 0x53: -+ /* EXTLL */ -+ gen_ext_l(ctx, vc, va, vb, 0xff); -+ break; -+ case 0x54: -+ /* EXTHB */ -+ gen_ext_h(ctx, vc, va, vb, 0x1); -+ break; -+ case 0x55: -+ /* EXTHH */ -+ gen_ext_h(ctx, vc, va, vb, 0x3); -+ break; -+ case 0x56: -+ /* EXTHW */ -+ gen_ext_h(ctx, vc, va, vb, 0xf); -+ break; -+ case 0x57: -+ /* EXTHL */ -+ gen_ext_h(ctx, vc, va, vb, 0xff); -+ break; -+ case 0x58: -+ /* CTPOP */ -+ tcg_gen_ctpop_i64(vc, vb); -+ break; -+ case 0x59: -+ /* CTLZ */ -+ tcg_gen_clzi_i64(vc, vb, 64); -+ break; -+ case 0x5a: -+ /* CTTZ */ -+ tcg_gen_ctzi_i64(vc, vb, 64); -+ break; -+ case 0x60: -+ /* MASKLB */ -+ gen_mask_l(ctx, vc, va, vb, 0x1); -+ break; -+ case 0x61: -+ /* MASKLH */ -+ gen_mask_l(ctx, vc, va, vb, 0x3); -+ break; -+ case 0x62: -+ /* MASKLW */ -+ gen_mask_l(ctx, vc, va, vb, 0xf); -+ break; -+ case 0x63: -+ /* MASKLL */ -+ gen_mask_l(ctx, vc, va, vb, 0xff); -+ break; -+ case 0x64: -+ /* MASKHB */ -+ gen_mask_h(ctx, vc, va, vb, 0x1); -+ break; -+ case 0x65: -+ /* MASKHH */ -+ gen_mask_h(ctx, vc, va, vb, 0x3); -+ break; -+ case 0x66: -+ /* MASKHW */ -+ gen_mask_h(ctx, vc, va, vb, 0xf); -+ break; -+ case 0x67: -+ /* MASKHL */ -+ gen_mask_h(ctx, vc, va, vb, 0xff); -+ break; -+ case 0x68: -+ /* ZAP */ -+ gen_helper_zap(vc, va, vb); -+ break; -+ case 0x69: -+ /* ZAPNOT */ -+ gen_helper_zapnot(vc, va, vb); -+ break; -+ case 0x6a: -+ /* SEXTB */ -+ tcg_gen_ext8s_i64(vc, vb); -+ break; -+ case 0x6b: -+ /* SEXTH */ -+ tcg_gen_ext16s_i64(vc, vb); -+ break; -+ case 0x6c: -+ /* CMPGEB*/ -+ gen_helper_cmpgeb(vc, va, vb); -+ break; -+ default: -+ ILLEGAL(fn); -+ } -+} -+ -+static void cal_with_imm_2(DisasContext *ctx, TCGv vc, TCGv va, int64_t disp, -+ uint8_t fn) -+{ -+ TCGv_i64 t0 = tcg_const_i64(disp); -+ cal_with_iregs_2(ctx, vc, va, t0, 0, fn); -+ tcg_temp_free_i64(t0); -+} -+ -+static void cal_with_iregs_3(DisasContext *ctx, TCGv vd, TCGv va, TCGv vb, -+ TCGv vc, uint8_t fn) -+{ -+ TCGv_i64 t0 = tcg_const_i64(0); -+ TCGv_i64 tmp; -+ switch (fn) { -+ case 0x0: -+ /* SELEQ */ -+ tcg_gen_movcond_i64(TCG_COND_EQ, vd, va, t0, vb, vc); -+ break; -+ case 0x1: -+ /* SELGE */ -+ tcg_gen_movcond_i64(TCG_COND_GE, vd, va, t0, vb, vc); -+ break; -+ case 0x2: -+ /* SELGT */ -+ tcg_gen_movcond_i64(TCG_COND_GT, vd, va, t0, vb, vc); -+ break; -+ case 0x3: -+ /* SELLE */ -+ tcg_gen_movcond_i64(TCG_COND_LE, vd, va, t0, vb, vc); -+ break; -+ case 0x4: -+ /* SELLT */ -+ tcg_gen_movcond_i64(TCG_COND_LT, vd, va, t0, vb, vc); -+ break; -+ case 0x5: -+ /* SELNE */ -+ tcg_gen_movcond_i64(TCG_COND_NE, vd, va, t0, vb, vc); -+ break; -+ case 0x6: -+ /* SELLBC */ -+ tmp = tcg_temp_new_i64(); -+ tcg_gen_andi_i64(tmp, va, 1); -+ tcg_gen_movcond_i64(TCG_COND_EQ, vd, tmp, t0, vb, vc); -+ tcg_temp_free_i64(tmp); -+ break; -+ case 0x7: -+ /* SELLBS */ -+ tmp = tcg_temp_new_i64(); -+ tcg_gen_andi_i64(tmp, va, 1); -+ tcg_gen_movcond_i64(TCG_COND_NE, vd, tmp, t0, vb, vc); -+ tcg_temp_free_i64(tmp); -+ break; -+ default: -+ ILLEGAL(fn); -+ break; -+ } -+ tcg_temp_free_i64(t0); -+} -+ -+static void cal_with_imm_3(DisasContext *ctx, TCGv vd, TCGv va, int32_t disp, -+ TCGv vc, uint8_t fn) -+{ -+ TCGv_i64 vb = tcg_const_i64(disp); -+ cal_with_iregs_3(ctx, vd, va, vb, vc, fn); -+ tcg_temp_free_i64(vb); -+} -+ -+static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) -+{ -+ uint64_t dest = ctx->base.pc_next + ((int64_t)disp << 2); -+ if (ra != 31) { -+ tcg_gen_movi_i64(load_gir(ctx, ra), ctx->base.pc_next & (~0x3UL)); -+ } -+ if (disp == 0) { -+ return 0; -+ } else if (use_goto_tb(ctx, dest)) { -+ tcg_gen_goto_tb(0); -+ tcg_gen_movi_i64(cpu_pc, dest); -+ tcg_gen_exit_tb(ctx->base.tb, 0); -+ return DISAS_NORETURN; -+ } else { -+ tcg_gen_movi_i64(cpu_pc, dest); -+ return DISAS_PC_UPDATED; -+ } -+} -+ -+static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, -+ TCGv cmp, int disp) -+{ -+ uint64_t dest = ctx->base.pc_next + (disp << 2); -+ TCGLabel* lab_true = gen_new_label(); -+ -+ if (use_goto_tb(ctx, dest)) { -+ tcg_gen_brcondi_i64(cond, cmp, 0, lab_true); -+ -+ tcg_gen_goto_tb(0); -+ tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); -+ tcg_gen_exit_tb(ctx->base.tb, 0); -+ -+ gen_set_label(lab_true); -+ tcg_gen_goto_tb(1); -+ tcg_gen_movi_i64(cpu_pc, dest); -+ tcg_gen_exit_tb(ctx->base.tb, 1); -+ -+ return DISAS_NORETURN; -+ } else { -+ TCGv_i64 t = tcg_const_i64(0); -+ TCGv_i64 d = tcg_const_i64(dest); -+ TCGv_i64 p = tcg_const_i64(ctx->base.pc_next); -+ -+ tcg_gen_movcond_i64(cond, cpu_pc, cmp, t, d, p); -+ -+ tcg_temp_free_i64(t); -+ tcg_temp_free_i64(d); -+ tcg_temp_free_i64(p); -+ return DISAS_PC_UPDATED; -+ } -+} -+ -+static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, uint32_t ra, -+ int32_t disp, uint64_t mask) -+{ -+ TCGv tmp = tcg_temp_new(); -+ DisasJumpType ret; -+ -+ tcg_gen_andi_i64(tmp, load_gir(ctx, ra), mask); -+ ret = gen_bcond_internal(ctx, cond, tmp, disp); -+ tcg_temp_free(tmp); -+ return ret; -+} -+ -+static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra, -+ int32_t disp) -+{ -+ TCGv cmp_tmp = tcg_temp_new(); -+ DisasJumpType ret; -+ -+ gen_fold_mzero(cond, cmp_tmp, cpu_fr[ra]); -+ ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp); -+ tcg_temp_free(cmp_tmp); -+ return ret; -+} -+ -+#ifndef CONFIG_USER_ONLY -+static void gen_qemu_pri_ldw(TCGv t0, TCGv t1, int memidx) -+{ -+ gen_helper_pri_ldw(t0, cpu_env, t1); -+} -+ -+static void gen_qemu_pri_stw(TCGv t0, TCGv t1, int memidx) -+{ -+ gen_helper_pri_stw(cpu_env, t0, t1); -+} -+ -+static void gen_qemu_pri_ldl(TCGv t0, TCGv t1, int memidx) -+{ -+ gen_helper_pri_ldl(t0, cpu_env, t1); -+} -+ -+static void gen_qemu_pri_stl(TCGv t0, TCGv t1, int memidx) -+{ -+ gen_helper_pri_stl(cpu_env, t0, t1); -+} -+#endif -+ -+static inline void gen_load_mem_simd( -+ DisasContext *ctx, void (*tcg_gen_qemu_load)(int t0, TCGv t1, int flags), -+ int ra, int rb, int32_t disp16, uint64_t mask) -+{ -+ TCGv tmp, addr; -+ -+ /* LDQ_U with ra $31 is UNOP. Other various loads are forms of -+ prefetches, which we can treat as nops. No worries about -+ missed exceptions here. */ -+ if (unlikely(ra == 31)) -+ return; -+ -+ tmp = tcg_temp_new(); -+ addr = load_gir(ctx, rb); -+ -+ if (disp16) { -+ tcg_gen_addi_i64(tmp, addr, (int64_t)disp16); -+ addr = tmp; -+ } else { -+ tcg_gen_mov_i64(tmp, addr); -+ addr = tmp; -+ } -+ -+ if (mask) { -+ tcg_gen_andi_i64(addr, addr, mask); -+ } -+ -+ tcg_gen_qemu_load(ra, addr, ctx->mem_idx); -+ // FIXME: for debug -+ -+ tcg_temp_free(tmp); -+} -+ -+static inline void gen_store_mem_simd( -+ DisasContext *ctx, void (*tcg_gen_qemu_store)(int t0, TCGv t1, int flags), -+ int ra, int rb, int32_t disp16, uint64_t mask) -+{ -+ TCGv tmp, addr; -+ -+ tmp = tcg_temp_new(); -+ addr = load_gir(ctx, rb); -+ if (disp16) { -+ tcg_gen_addi_i64(tmp, addr, (int64_t)disp16); -+ addr = tmp; -+ } else { -+ tcg_gen_mov_i64(tmp, addr); -+ addr = tmp; -+ } -+ if (mask) { -+ tcg_gen_andi_i64(addr, addr, mask); -+ } -+ // FIXME: for debug -+ tcg_gen_qemu_store(ra, addr, ctx->mem_idx); -+ -+ tcg_temp_free(tmp); -+} -+ -+static void gen_qemu_ldwe(int t0, TCGv t1, int memidx) -+{ -+ TCGv tmp = tcg_temp_new(); -+ -+ tcg_gen_qemu_ld_i64(tmp, t1, memidx, MO_ALIGN_4 | MO_LEUL); -+ tcg_gen_shli_i64(cpu_fr[t0], tmp, 32); -+ tcg_gen_or_i64(cpu_fr[t0], cpu_fr[t0], tmp); -+ tcg_gen_mov_i64(cpu_fr[t0 + 32], cpu_fr[t0]); -+ tcg_gen_mov_i64(cpu_fr[t0 + 64], cpu_fr[t0]); -+ tcg_gen_mov_i64(cpu_fr[t0 + 96], cpu_fr[t0]); -+ -+ tcg_temp_free(tmp); -+} -+ -+static void gen_qemu_vlds(int t0, TCGv t1, int memidx) -+{ -+ int i; -+ TCGv_i32 tmp32 = tcg_temp_new_i32(); -+ -+ tcg_gen_qemu_ld_i32(tmp32, t1, memidx, MO_ALIGN_4 | MO_LEUL); -+ gen_helper_memory_to_s(cpu_fr[t0], tmp32); -+ tcg_gen_addi_i64(t1, t1, 4); -+ -+ for (i = 1; i < 4; i++) { -+ tcg_gen_qemu_ld_i32(tmp32, t1, memidx, MO_LEUL); -+ gen_helper_memory_to_s(cpu_fr[t0 + i * 32], tmp32); -+ tcg_gen_addi_i64(t1, t1, 4); -+ } -+ -+ tcg_temp_free_i32(tmp32); -+} -+ -+static void gen_qemu_ldse(int t0, TCGv t1, int memidx) -+{ -+ TCGv_i32 tmp32 = tcg_temp_new_i32(); -+ TCGv tmp64 = tcg_temp_new(); -+ -+ tcg_gen_qemu_ld_i32(tmp32, t1, memidx, MO_ALIGN_4 | MO_LEUL); -+ gen_helper_memory_to_s(cpu_fr[t0], tmp32); -+ tcg_gen_mov_i64(cpu_fr[t0 + 32], cpu_fr[t0]); -+ tcg_gen_mov_i64(cpu_fr[t0 + 64], cpu_fr[t0]); -+ tcg_gen_mov_i64(cpu_fr[t0 + 96], cpu_fr[t0]); -+ -+ tcg_temp_free(tmp64); -+ tcg_temp_free_i32(tmp32); -+} -+ -+static void gen_qemu_ldde(int t0, TCGv t1, int memidx) -+{ -+ tcg_gen_qemu_ld_i64(cpu_fr[t0], t1, memidx, MO_ALIGN_4 | MO_TEQ); -+ tcg_gen_mov_i64(cpu_fr[t0 + 32], cpu_fr[t0]); -+ tcg_gen_mov_i64(cpu_fr[t0 + 64], cpu_fr[t0]); -+ tcg_gen_mov_i64(cpu_fr[t0 + 96], cpu_fr[t0]); -+} -+ -+static void gen_qemu_vldd(int t0, TCGv t1, int memidx) -+{ -+ tcg_gen_qemu_ld_i64(cpu_fr[t0], t1, memidx, MO_ALIGN_4 | MO_TEQ); -+ tcg_gen_addi_i64(t1, t1, 8); -+ tcg_gen_qemu_ld_i64(cpu_fr[t0 + 32], t1, memidx, MO_TEQ); -+ tcg_gen_addi_i64(t1, t1, 8); -+ tcg_gen_qemu_ld_i64(cpu_fr[t0 + 64], t1, memidx, MO_TEQ); -+ tcg_gen_addi_i64(t1, t1, 8); -+ tcg_gen_qemu_ld_i64(cpu_fr[t0 + 96], t1, memidx, MO_TEQ); -+} -+ -+static void gen_qemu_vsts(int t0, TCGv t1, int memidx) -+{ -+ int i; -+ TCGv_i32 tmp = tcg_temp_new_i32(); -+ -+ gen_helper_s_to_memory(tmp, cpu_fr[t0]); -+ tcg_gen_qemu_st_i32(tmp, t1, memidx, MO_ALIGN_4 | MO_LEUL); -+ tcg_gen_addi_i64(t1, t1, 4); -+ for (i = 1; i < 4; i++) { -+ gen_helper_s_to_memory(tmp, cpu_fr[t0 + 32 * i]); -+ tcg_gen_qemu_st_i32(tmp, t1, memidx, MO_LEUL); -+ tcg_gen_addi_i64(t1, t1, 4); -+ } -+ tcg_temp_free_i32(tmp); -+} -+ -+static void gen_qemu_vstd(int t0, TCGv t1, int memidx) -+{ -+ tcg_gen_qemu_st_i64(cpu_fr[t0], t1, memidx, MO_ALIGN_4 | MO_TEQ); -+ tcg_gen_addi_i64(t1, t1, 8); -+ tcg_gen_qemu_st_i64(cpu_fr[t0 + 32], t1, memidx, MO_TEQ); -+ tcg_gen_addi_i64(t1, t1, 8); -+ tcg_gen_qemu_st_i64(cpu_fr[t0 + 64], t1, memidx, MO_TEQ); -+ tcg_gen_addi_i64(t1, t1, 8); -+ tcg_gen_qemu_st_i64(cpu_fr[t0 + 96], t1, memidx, MO_TEQ); -+} -+ -+static inline void gen_qemu_fsts(TCGv t0, TCGv t1, int flags) -+{ -+ TCGv_i32 tmp = tcg_temp_new_i32(); -+ gen_helper_s_to_memory(tmp, t0); -+ tcg_gen_qemu_st_i32(tmp, t1, flags, MO_LEUL); -+ tcg_temp_free_i32(tmp); -+} -+ -+static inline void gen_qemu_flds(TCGv t0, TCGv t1, int flags) -+{ -+ TCGv_i32 tmp = tcg_temp_new_i32(); -+ tcg_gen_qemu_ld_i32(tmp, t1, flags, MO_LEUL); -+ gen_helper_memory_to_s(t0, tmp); -+ tcg_temp_free_i32(tmp); -+} -+ -+static TCGv gen_ieee_input(DisasContext *ctx, int reg, int is_cmp) -+{ -+ TCGv val; -+ -+ if (unlikely(reg == 31)) { -+ val = load_zero(ctx); -+ } else { -+ val = cpu_fr[reg]; -+#ifndef CONFIG_USER_ONLY -+ /* In system mode, raise exceptions for denormals like real -+ hardware. In user mode, proceed as if the OS completion -+ handler is handling the denormal as per spec. */ -+ gen_helper_ieee_input(cpu_env, val); -+#endif -+ } -+ return val; -+} -+ -+static void gen_fp_exc_raise(int rc) -+{ -+#ifndef CONFIG_USER_ONLY -+ TCGv_i32 reg = tcg_const_i32(rc + 32); -+ gen_helper_fp_exc_raise(cpu_env, reg); -+ tcg_temp_free_i32(reg); -+#endif -+} -+ -+static void gen_ieee_arith2(DisasContext *ctx, -+ void (*helper)(TCGv, TCGv_ptr, TCGv), int ra, -+ int rc) -+{ -+ TCGv va, vc; -+ -+ va = gen_ieee_input(ctx, ra, 0); -+ vc = cpu_fr[rc]; -+ helper(vc, cpu_env, va); -+ -+ gen_fp_exc_raise(rc); -+} -+ -+static void gen_ieee_arith3(DisasContext *ctx, -+ void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv), int ra, -+ int rb, int rc) -+{ -+ TCGv va, vb, vc; -+ -+ va = gen_ieee_input(ctx, ra, 0); -+ vb = gen_ieee_input(ctx, rb, 0); -+ vc = cpu_fr[rc]; -+ helper(vc, cpu_env, va, vb); -+ -+ gen_fp_exc_raise(rc); -+} -+ -+#define IEEE_ARITH2(name) \ -+ static inline void glue(gen_, name)(DisasContext * ctx, int ra, int rc) { \ -+ gen_ieee_arith2(ctx, gen_helper_##name, ra, rc); \ -+ } -+ -+#define IEEE_ARITH3(name) \ -+ static inline void glue(gen_, name)(DisasContext * ctx, int ra, int rb, \ -+ int rc) { \ -+ gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc); \ -+ } -+IEEE_ARITH3(fadds) -+IEEE_ARITH3(faddd) -+IEEE_ARITH3(fsubs) -+IEEE_ARITH3(fsubd) -+IEEE_ARITH3(fmuls) -+IEEE_ARITH3(fmuld) -+IEEE_ARITH3(fdivs) -+IEEE_ARITH3(fdivd) -+IEEE_ARITH2(frecs) -+IEEE_ARITH2(frecd) -+ -+static void gen_ieee_compare(DisasContext *ctx, -+ void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv), int ra, -+ int rb, int rc) -+{ -+ TCGv va, vb, vc; -+ -+ va = gen_ieee_input(ctx, ra, 1); -+ vb = gen_ieee_input(ctx, rb, 1); -+ vc = cpu_fr[rc]; -+ helper(vc, cpu_env, va, vb); -+ -+ gen_fp_exc_raise(rc); -+} -+ -+#define IEEE_CMP2(name) \ -+ static inline void glue(gen_, name)(DisasContext *ctx, int ra, int rb, \ -+ int rc) { \ -+ gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc); \ -+ } -+ -+IEEE_CMP2(fcmpun) -+IEEE_CMP2(fcmpeq) -+IEEE_CMP2(fcmplt) -+IEEE_CMP2(fcmple) -+ -+static void gen_fcvtdl(int rb, int rc, uint64_t round_mode) -+{ -+ TCGv tmp64; -+ tmp64 = tcg_temp_new_i64(); -+ tcg_gen_movi_i64(tmp64, round_mode); -+ gen_helper_fcvtdl(cpu_fr[rc], cpu_env, cpu_fr[rb], tmp64); -+ tcg_temp_free(tmp64); -+ gen_fp_exc_raise(rc); -+} -+ -+static void cal_with_fregs_2(DisasContext *ctx, uint8_t rc, uint8_t ra, -+ uint8_t rb, uint8_t fn) -+{ -+ TCGv tmp64; -+ TCGv_i32 tmp32; -+ switch (fn) { -+ case 0x00: -+ /* FADDS */ -+ gen_fadds(ctx, ra, rb, rc); -+ break; -+ case 0x01: -+ /* FADDD */ -+ gen_faddd(ctx, ra, rb, rc); -+ break; -+ case 0x02: -+ /* FSUBS */ -+ gen_fsubs(ctx, ra, rb, rc); -+ break; -+ case 0x03: -+ /* FSUBD */ -+ gen_fsubd(ctx, ra, rb, rc); -+ break; -+ case 0x4: -+ /* FMULS */ -+ gen_fmuls(ctx, ra, rb, rc); -+ break; -+ case 0x05: -+ /* FMULD */ -+ gen_fmuld(ctx, ra, rb, rc); -+ break; -+ case 0x06: -+ /* FDIVS */ -+ gen_fdivs(ctx, ra, rb, rc); -+ break; -+ case 0x07: -+ /* FDIVD */ -+ gen_fdivd(ctx, ra, rb, rc); -+ break; -+ case 0x08: -+ /* FSQRTS */ -+ gen_helper_fsqrts(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ break; -+ case 0x09: -+ /* FSQRTD */ -+ gen_helper_fsqrt(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ break; -+ case 0x10: -+ /* FCMPEQ */ -+ gen_fcmpeq(ctx, ra, rb, rc); -+ break; -+ case 0x11: -+ /* FCMPLE */ -+ gen_fcmple(ctx, ra, rb, rc); -+ break; -+ case 0x12: -+ /* FCMPLT */ -+ gen_fcmplt(ctx, ra, rb, rc); -+ break; -+ case 0x13: -+ /* FCMPUN */ -+ gen_fcmpun(ctx, ra, rb, rc); -+ break; -+ case 0x20: -+ /* FCVTSD */ -+ gen_helper_fcvtsd(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ break; -+ case 0x21: -+ /* FCVTDS */ -+ gen_helper_fcvtds(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ break; -+ case 0x22: -+ /* FCVTDL_G */ -+ gen_fcvtdl(rb, rc, 0); -+ break; -+ case 0x23: -+ /* FCVTDL_P */ -+ gen_fcvtdl(rb, rc, 2); -+ break; -+ case 0x24: -+ /* FCVTDL_Z */ -+ gen_fcvtdl(rb, rc, 3); -+ break; -+ case 0x25: -+ /* FCVTDL_N */ -+ gen_fcvtdl(rb, rc, 1); -+ break; -+ case 0x27: -+ /* FCVTDL */ -+ gen_helper_fcvtdl_dyn(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ break; -+ case 0x28: -+ /* FCVTWL */ -+ gen_helper_fcvtwl(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ tcg_gen_ext32s_i64(cpu_fr[rc], cpu_fr[rc]); -+ break; -+ case 0x29: -+ /* FCVTLW */ -+ gen_helper_fcvtlw(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ break; -+ case 0x2d: -+ /* FCVTLS */ -+ gen_helper_fcvtls(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ break; -+ case 0x2f: -+ /* FCVTLD */ -+ gen_helper_fcvtld(cpu_fr[rc], cpu_env, cpu_fr[rb]); -+ break; -+ case 0x30: -+ /* FCPYS */ -+ tmp64 = tcg_temp_new(); -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra], 63); -+ tcg_gen_shli_i64(tmp64, tmp64, 63); -+ tcg_gen_andi_i64(cpu_fr[rc], cpu_fr[rb], 0x7fffffffffffffffUL); -+ tcg_gen_or_i64(cpu_fr[rc], tmp64, cpu_fr[rc]); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x31: -+ /* FCPYSE */ -+ tmp64 = tcg_temp_new(); -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra], 52); -+ tcg_gen_shli_i64(tmp64, tmp64, 52); -+ tcg_gen_andi_i64(cpu_fr[rc], cpu_fr[rb], 0x000fffffffffffffUL); -+ tcg_gen_or_i64(cpu_fr[rc], tmp64, cpu_fr[rc]); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x32: -+ /* FCPYSN */ -+ tmp64 = tcg_temp_new(); -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra], 63); -+ tcg_gen_not_i64(tmp64, tmp64); -+ tcg_gen_shli_i64(tmp64, tmp64, 63); -+ tcg_gen_andi_i64(cpu_fr[rc], cpu_fr[rb], 0x7fffffffffffffffUL); -+ tcg_gen_or_i64(cpu_fr[rc], tmp64, cpu_fr[rc]); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x40: -+ /* IFMOVS */ -+ tmp64 = tcg_temp_new(); -+ tmp32 = tcg_temp_new_i32(); -+ tcg_gen_movi_i64(tmp64, ra); -+ tcg_gen_extrl_i64_i32(tmp32, load_gir(ctx, ra)); -+ gen_helper_memory_to_s(tmp64, tmp32); -+ tcg_gen_mov_i64(cpu_fr[rc], tmp64); -+ tcg_gen_movi_i64(tmp64, rc); -+ tcg_temp_free(tmp64); -+ tcg_temp_free_i32(tmp32); -+ break; -+ case 0x41: -+ /* IFMOVD */ -+ tcg_gen_mov_i64(cpu_fr[rc], load_gir(ctx, ra)); -+ break; -+ case 0x50: -+ /* RFPCR */ -+ gen_helper_load_fpcr(cpu_fr[ra], cpu_env); -+ break; -+ case 0x51: -+ /* WFPCR */ -+ gen_helper_store_fpcr(cpu_env, cpu_fr[ra]); -+ break; -+ case 0x54: -+ /* SETFPEC0 */ -+ tmp64 = tcg_const_i64(0); -+ gen_helper_setfpcrx(cpu_env, tmp64); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x55: -+ /* SETFPEC1 */ -+ tmp64 = tcg_const_i64(1); -+ gen_helper_setfpcrx(cpu_env, tmp64); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x56: -+ /* SETFPEC2 */ -+ tmp64 = tcg_const_i64(2); -+ gen_helper_setfpcrx(cpu_env, tmp64); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x57: -+ /* SETFPEC3 */ -+ tmp64 = tcg_const_i64(3); -+ gen_helper_setfpcrx(cpu_env, tmp64); -+ tcg_temp_free(tmp64); -+ break; -+ default: -+ fprintf(stderr, "Illegal insn func[%x]\n", fn); -+ gen_invalid(ctx); -+ break; -+ } -+} -+ -+static void cal_with_fregs_4(DisasContext *ctx, uint8_t rd, uint8_t ra, -+ uint8_t rb, uint8_t rc, uint8_t fn) -+{ -+ TCGv zero = tcg_const_i64(0); -+ TCGv va, vb, vc, vd, tmp64; -+ -+ va = cpu_fr[ra]; -+ vb = cpu_fr[rb]; -+ vc = cpu_fr[rc]; -+ vd = cpu_fr[rd]; -+ -+ switch (fn) { -+ case 0x00: -+ /* FMAS */ -+ gen_helper_fmas(vd, cpu_env, va, vb, vc); -+ break; -+ case 0x01: -+ /* FMAD */ -+ gen_helper_fmad(vd, cpu_env, va, vb, vc); -+ break; -+ case 0x02: -+ /* FMSS */ -+ gen_helper_fmss(vd, cpu_env, va, vb, vc); -+ break; -+ case 0x03: -+ /* FMSD */ -+ gen_helper_fmsd(vd, cpu_env, va, vb, vc); -+ break; -+ case 0x04: -+ /* FNMAS */ -+ gen_helper_fnmas(vd, cpu_env, va, vb, vc); -+ break; -+ case 0x05: -+ /* FNMAD */ -+ gen_helper_fnmad(vd, cpu_env, va, vb, vc); -+ break; -+ case 0x06: -+ /* FNMSS */ -+ gen_helper_fnmss(vd, cpu_env, va, vb, vc); -+ break; -+ case 0x07: -+ /* FNMSD */ -+ gen_helper_fnmsd(vd, cpu_env, va, vb, vc); -+ break; -+ case 0x10: -+ /* FSELEQ */ -+ // Maybe wrong translation. -+ tmp64 = tcg_temp_new(); -+ gen_helper_fcmpeq(tmp64, cpu_env, va, zero); -+ tcg_gen_movcond_i64(TCG_COND_EQ, vd, tmp64, zero, vc, vb); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x11: -+ /* FSELNE */ -+ tmp64 = tcg_temp_new(); -+ gen_helper_fcmpeq(tmp64, cpu_env, va, zero); -+ tcg_gen_movcond_i64(TCG_COND_EQ, vd, tmp64, zero, vb, vc); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x12: -+ /* FSELLT */ -+ tmp64 = tcg_temp_new(); -+ gen_helper_fcmplt(tmp64, cpu_env, va, zero); -+ tcg_gen_movcond_i64(TCG_COND_EQ, vd, tmp64, zero, vc, vb); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x13: -+ /* FSELLE */ -+ tmp64 = tcg_temp_new(); -+ gen_helper_fcmple(tmp64, cpu_env, va, zero); -+ tcg_gen_movcond_i64(TCG_COND_EQ, vd, tmp64, zero, vc, vb); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x14: -+ /* FSELGT */ -+ tmp64 = tcg_temp_new(); -+ gen_helper_fcmpgt(tmp64, cpu_env, va, zero); -+ tcg_gen_movcond_i64(TCG_COND_NE, vd, tmp64, zero, vb, vc); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x15: -+ /* FSELGE */ -+ tmp64 = tcg_temp_new(); -+ gen_helper_fcmpge(tmp64, cpu_env, va, zero); -+ tcg_gen_movcond_i64(TCG_COND_NE, vd, tmp64, zero, vb, vc); -+ tcg_temp_free(tmp64); -+ break; -+ default: -+ fprintf(stderr, "Illegal insn func[%x]\n", fn); -+ gen_invalid(ctx); -+ break; -+ } -+ tcg_temp_free(zero); -+} -+static inline void gen_qemu_lldw(TCGv t0, TCGv t1, int flags) -+{ -+ tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LESL); -+ tcg_gen_mov_i64(cpu_lock_addr, t1); -+#ifdef SW64_FIXLOCK -+ tcg_gen_ext32u_i64(cpu_lock_value, t0); -+#endif -+} -+ -+static inline void gen_qemu_lldl(TCGv t0, TCGv t1, int flags) -+{ -+ tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LEQ); -+ tcg_gen_mov_i64(cpu_lock_addr, t1); -+#ifdef SW64_FIXLOCK -+ tcg_gen_mov_i64(cpu_lock_value, t0); -+#endif -+} -+ -+static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb, -+ int32_t disp16, int mem_idx, -+ MemOp op) -+{ -+ TCGLabel *lab_fail, *lab_done; -+ TCGv addr; -+ -+ addr = tcg_temp_new_i64(); -+ tcg_gen_addi_i64(addr, load_gir(ctx, rb), disp16); -+ free_context_temps(ctx); -+ -+ lab_fail = gen_new_label(); -+ lab_done = gen_new_label(); -+ tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail); -+ tcg_temp_free_i64(addr); -+ tcg_gen_brcondi_i64(TCG_COND_NE, cpu_lock_flag, 0x1, lab_fail); -+#ifdef SW64_FIXLOCK -+ TCGv val = tcg_temp_new_i64(); -+ tcg_gen_atomic_cmpxchg_i64(val, cpu_lock_addr, cpu_lock_value, -+ load_gir(ctx, ra), mem_idx, op); -+ tcg_gen_setcond_i64(TCG_COND_EQ, cpu_lock_success, val, cpu_lock_value); -+ tcg_temp_free_i64(val); -+#else -+ tcg_gen_qemu_st_i64(load_gir(ctx, ra), addr, mem_idx, op); -+#endif -+ -+ tcg_gen_br(lab_done); -+ -+ gen_set_label(lab_fail); -+ tcg_gen_movi_i64(cpu_lock_success, 0); -+ gen_set_label(lab_done); -+ -+ tcg_gen_movi_i64(cpu_lock_flag, 0); -+ tcg_gen_movi_i64(cpu_lock_addr, -1); -+ return DISAS_NEXT; -+} -+ -+static DisasJumpType gen_sys_call(DisasContext *ctx, int syscode) -+{ -+ if (syscode >= 0x80 && syscode <= 0xbf) { -+ switch (syscode) { -+ case 0x86: -+ /* IMB */ -+ /* No-op inside QEMU */ -+ break; -+#ifdef CONFIG_USER_ONLY -+ case 0x9E: -+ /* RDUNIQUE */ -+ tcg_gen_ld_i64(ctx->ir[IDX_V0], cpu_env, -+ offsetof(CPUSW64State, unique)); -+ break; -+ case 0x9F: -+ /* WRUNIQUE */ -+ tcg_gen_st_i64(ctx->ir[IDX_A0], cpu_env, -+ offsetof(CPUSW64State, unique)); -+ break; -+#endif -+ default: -+ goto do_sys_call; -+ } -+ return DISAS_NEXT; -+ } -+do_sys_call: -+#ifdef CONFIG_USER_ONLY -+ return gen_excp(ctx, EXCP_CALL_SYS, syscode); -+#else -+ tcg_gen_movi_i64(cpu_hm_ir[23], ctx->base.pc_next); -+ return gen_excp(ctx, EXCP_CALL_SYS, syscode); -+#endif -+} -+ -+static void read_csr(int idx, TCGv va) -+{ -+ TCGv_i64 tmp = tcg_const_i64(idx); -+ gen_helper_read_csr(va, cpu_env, tmp); -+ tcg_temp_free_i64(tmp); -+} -+ -+static void write_csr(int idx, TCGv va, CPUSW64State *env) -+{ -+ TCGv_i64 tmp = tcg_const_i64(idx); -+ gen_helper_write_csr(cpu_env, tmp, va); -+ tcg_temp_free_i64(tmp); -+} -+ -+static inline void ldx_set(DisasContext *ctx, int ra, int rb, int32_t disp12, -+ bool bype) -+{ -+ TCGv tmp, addr, va, t1; -+ -+ /* LDQ_U with ra $31 is UNOP. Other various loads are forms of -+ prefetches, which we can treat as nops. No worries about -+ missed exceptions here. */ -+ if (unlikely(ra == 31)) { -+ return; -+ } -+ -+ tmp = tcg_temp_new(); -+ t1 = tcg_const_i64(1); -+ addr = load_gir(ctx, rb); -+ -+ tcg_gen_addi_i64(tmp, addr, disp12); -+ addr = tmp; -+ -+ va = load_gir(ctx, ra); -+ if (bype == 0) { -+ tcg_gen_atomic_xchg_i64(va, addr, t1, ctx->mem_idx, MO_TESL); -+ } else { -+ tcg_gen_atomic_xchg_i64(va, addr, t1, ctx->mem_idx, MO_TEQ); -+ } -+ -+ tcg_temp_free(tmp); -+ tcg_temp_free(t1); -+} -+ -+static inline void ldx_xxx(DisasContext *ctx, int ra, int rb, int32_t disp12, -+ bool bype, int64_t val) -+{ -+ TCGv tmp, addr, va, t; -+ -+ /* LDQ_U with ra $31 is UNOP. Other various loads are forms of -+ prefetches, which we can treat as nops. No worries about -+ missed exceptions here. */ -+ if (unlikely(ra == 31)) { -+ return; -+ } -+ -+ tmp = tcg_temp_new(); -+ t = tcg_const_i64(val); -+ addr = load_gir(ctx, rb); -+ -+ tcg_gen_addi_i64(tmp, addr, disp12); -+ addr = tmp; -+ -+ va = load_gir(ctx, ra); -+ if (bype == 0) { -+ tcg_gen_atomic_fetch_add_i64(va, addr, t, ctx->mem_idx, MO_TESL); -+ } else { -+ tcg_gen_atomic_fetch_add_i64(va, addr, t, ctx->mem_idx, MO_TEQ); -+ } -+ -+ tcg_temp_free(tmp); -+ tcg_temp_free(t); -+} -+ -+static void tcg_gen_srlow_i64(int ra, int rc, int rb) -+{ -+ TCGv va, vb, vc; -+ TCGv shift; -+ -+ va = tcg_const_i64(ra); -+ vc = tcg_const_i64(rc); -+ shift = tcg_temp_new(); -+ vb = cpu_fr[rb]; -+ tcg_gen_shri_i64(shift, vb, 29); -+ tcg_gen_andi_i64(shift, shift, 0xff); -+ -+ gen_helper_srlow(cpu_env, va, vc, shift); -+ -+ tcg_temp_free(vc); -+ tcg_temp_free(va); -+ tcg_temp_free(shift); -+} -+ -+static void tcg_gen_srlowi_i64(int ra, int rc, int disp8) -+{ -+ TCGv va, vc; -+ TCGv shift; -+ -+ va = tcg_const_i64(ra); -+ vc = tcg_const_i64(rc); -+ shift = tcg_temp_new(); -+ tcg_gen_movi_i64(shift, disp8); -+ tcg_gen_andi_i64(shift, shift, 0xff); -+ -+ gen_helper_srlow(cpu_env, va, vc, shift); -+ -+ tcg_temp_free(vc); -+ tcg_temp_free(va); -+ tcg_temp_free(shift); -+} -+ -+static void tcg_gen_sllow_i64(int ra, int rc, int rb) -+{ -+ TCGv va, vb, vc; -+ TCGv shift; -+ -+ va = tcg_const_i64(ra); -+ vc = tcg_const_i64(rc); -+ shift = tcg_temp_new(); -+ vb = cpu_fr[rb]; -+ tcg_gen_shri_i64(shift, vb, 29); -+ tcg_gen_andi_i64(shift, shift, 0xff); -+ -+ gen_helper_sllow(cpu_env, va, vc, shift); -+ -+ tcg_temp_free(vc); -+ tcg_temp_free(va); -+ tcg_temp_free(shift); -+} -+ -+static void tcg_gen_sllowi_i64(int ra, int rc, int disp8) -+{ -+ TCGv va, vc; -+ TCGv shift; -+ -+ va = tcg_const_i64(ra); -+ vc = tcg_const_i64(rc); -+ shift = tcg_temp_new(); -+ tcg_gen_movi_i64(shift, disp8); -+ tcg_gen_andi_i64(shift, shift, 0xff); -+ -+ gen_helper_sllow(cpu_env, va, vc, shift); -+ -+ tcg_temp_free(vc); -+ tcg_temp_free(va); -+ tcg_temp_free(shift); -+} -+ -+static void gen_qemu_vstw_uh(int t0, TCGv t1, int memidx) -+{ -+ TCGv byte4_len; -+ TCGv addr_start, addr_end; -+ TCGv tmp[8]; -+ TCGv ti; -+ int i; -+ -+ tmp[0] = tcg_temp_new(); -+ tmp[1] = tcg_temp_new(); -+ tmp[2] = tcg_temp_new(); -+ tmp[3] = tcg_temp_new(); -+ tmp[4] = tcg_temp_new(); -+ tmp[5] = tcg_temp_new(); -+ tmp[6] = tcg_temp_new(); -+ tmp[7] = tcg_temp_new(); -+ ti = tcg_temp_new(); -+ addr_start = tcg_temp_new(); -+ addr_end = tcg_temp_new(); -+ byte4_len = tcg_temp_new(); -+ -+ tcg_gen_shri_i64(byte4_len, t1, 2); -+ tcg_gen_andi_i64(byte4_len, byte4_len, 0x7UL); -+ tcg_gen_andi_i64(t1, t1, ~0x3UL); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_andi_i64(addr_start, t1, ~0x1fUL); -+ tcg_gen_mov_i64(addr_end, t1); -+ for (i = 7; i >= 0; i--) { -+ tcg_gen_movcond_i64(TCG_COND_GEU, t1, t1, addr_start, t1, addr_start); -+ tcg_gen_qemu_ld_i64(tmp[i], t1, memidx, MO_TEUL); -+ tcg_gen_subi_i64(t1, t1, 4); -+ tcg_gen_movi_i64(ti, i); -+ if (i % 2) -+ tcg_gen_shli_i64(tmp[i], tmp[i], 32); -+ } -+ tcg_gen_subfi_i64(byte4_len, 8, byte4_len); -+ -+ for (i = 0; i < 8; i++) { -+ tcg_gen_movi_i64(ti, i); -+ tcg_gen_movcond_i64(TCG_COND_GEU, tmp[i], ti, byte4_len, cpu_fr[t0 + (i / 2)*32], tmp[i]); -+ if (i % 2) -+ tcg_gen_shri_i64(tmp[i], tmp[i], 32); -+ else -+ tcg_gen_andi_i64(tmp[i], tmp[i], 0xffffffffUL); -+ } -+ -+ tcg_gen_subi_i64(addr_end, addr_end, 32); -+ for (i = 0; i < 8; i++) { -+ tcg_gen_movcond_i64(TCG_COND_GEU, t1, addr_end, addr_start, addr_end, addr_start); -+ tcg_gen_qemu_st_i64(tmp[i], t1, memidx, MO_TEUL); -+ tcg_gen_addi_i64(addr_end, addr_end, 4); -+ } -+ -+ tcg_temp_free(ti); -+ tcg_temp_free(addr_start); -+ tcg_temp_free(addr_end); -+ tcg_temp_free(byte4_len); -+ tcg_temp_free(tmp[0]); -+ tcg_temp_free(tmp[1]); -+ tcg_temp_free(tmp[2]); -+ tcg_temp_free(tmp[3]); -+ tcg_temp_free(tmp[4]); -+ tcg_temp_free(tmp[5]); -+ tcg_temp_free(tmp[6]); -+ tcg_temp_free(tmp[7]); -+} -+ -+static void gen_qemu_vstw_ul(int t0, TCGv t1, int memidx) -+{ -+ TCGv byte4_len; -+ TCGv addr_start, addr_end; -+ TCGv tmp[8]; -+ TCGv ti; -+ int i; -+ -+ tmp[0] = tcg_temp_new(); -+ tmp[1] = tcg_temp_new(); -+ tmp[2] = tcg_temp_new(); -+ tmp[3] = tcg_temp_new(); -+ tmp[4] = tcg_temp_new(); -+ tmp[5] = tcg_temp_new(); -+ tmp[6] = tcg_temp_new(); -+ tmp[7] = tcg_temp_new(); -+ ti = tcg_temp_new(); -+ addr_start = tcg_temp_new(); -+ addr_end = tcg_temp_new(); -+ byte4_len = tcg_temp_new(); -+ -+ tcg_gen_shri_i64(byte4_len, t1, 2); -+ tcg_gen_andi_i64(byte4_len, byte4_len, 0x7UL); -+ tcg_gen_andi_i64(t1, t1, ~0x3UL); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_mov_i64(addr_start, t1); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_addi_i64(addr_end, addr_start, 24); -+ for (i = 0; i < 8; i++) { -+ tcg_gen_movcond_i64(TCG_COND_LEU, t1, t1, addr_end, t1, addr_end); -+ tcg_gen_qemu_ld_i64(tmp[i], t1, memidx, MO_TEUL); -+ tcg_gen_addi_i64(t1, t1, 4); -+ if (i % 2) -+ tcg_gen_shli_i64(tmp[i], tmp[i], 32); -+ } -+ tcg_gen_subfi_i64(byte4_len, 8, byte4_len); -+ -+ for (i = 0; i < 8; i++) { -+ tcg_gen_movi_i64(ti, i); -+ tcg_gen_movcond_i64(TCG_COND_LTU, tmp[i], ti, byte4_len, cpu_fr[t0 + (i/2)*32], tmp[i]); -+ if (i % 2) -+ tcg_gen_shri_i64(tmp[i], tmp[i], 32); -+ else -+ tcg_gen_andi_i64(tmp[i], tmp[i], 0xffffffffUL); -+ } -+ -+ tcg_gen_addi_i64(addr_start, addr_start, 32); -+ for (i = 7; i >= 0; i--) { -+ tcg_gen_subi_i64(addr_start, addr_start, 4); -+ tcg_gen_movcond_i64(TCG_COND_LEU, t1, addr_start, addr_end, addr_start, addr_end); -+ tcg_gen_qemu_st_i64(tmp[i], t1, memidx, MO_TEUL); -+ } -+ -+ tcg_temp_free(ti); -+ tcg_temp_free(addr_start); -+ tcg_temp_free(addr_end); -+ tcg_temp_free(byte4_len); -+ tcg_temp_free(tmp[0]); -+ tcg_temp_free(tmp[1]); -+ tcg_temp_free(tmp[2]); -+ tcg_temp_free(tmp[3]); -+ tcg_temp_free(tmp[4]); -+ tcg_temp_free(tmp[5]); -+ tcg_temp_free(tmp[6]); -+ tcg_temp_free(tmp[7]); -+} -+ -+static void gen_qemu_vsts_uh(int t0, TCGv t1, int memidx) -+{ -+ TCGv byte4_len; -+ TCGv addr_start, addr_end; -+ TCGv tmp[4]; -+ TCGv ftmp; -+ TCGv ti; -+ int i; -+ -+ tmp[0] = tcg_temp_new(); -+ tmp[1] = tcg_temp_new(); -+ tmp[2] = tcg_temp_new(); -+ tmp[3] = tcg_temp_new(); -+ ti = tcg_temp_new(); -+ ftmp = tcg_temp_new(); -+ addr_start = tcg_temp_new(); -+ addr_end = tcg_temp_new(); -+ byte4_len = tcg_temp_new(); -+ -+ tcg_gen_shri_i64(byte4_len, t1, 2); -+ tcg_gen_andi_i64(byte4_len, byte4_len, 0x3UL); -+ tcg_gen_andi_i64(t1, t1, ~0x3UL); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_andi_i64(addr_start, t1, ~0xfUL); -+ tcg_gen_mov_i64(addr_end, t1); -+ for (i = 3; i >= 0; i--) { -+ tcg_gen_movcond_i64(TCG_COND_GEU, t1, t1, addr_start, t1, addr_start); -+ tcg_gen_qemu_ld_i64(tmp[i], t1, memidx, MO_TEUL); -+ tcg_gen_subi_i64(t1, t1, 4); -+ } -+ tcg_gen_subfi_i64(byte4_len, 4, byte4_len); -+ -+ for (i = 0; i < 4; i++) { -+ tcg_gen_shri_i64(ti, cpu_fr[t0 + i * 32], 62); -+ tcg_gen_shli_i64(ti, ti, 30); -+ tcg_gen_shri_i64(ftmp, cpu_fr[t0 + i * 32], 29); -+ tcg_gen_andi_i64(ftmp, ftmp, 0x3fffffffUL); -+ tcg_gen_or_i64(ftmp, ftmp, ti); -+ tcg_gen_movi_i64(ti, i); -+ tcg_gen_movcond_i64(TCG_COND_GEU, tmp[i], ti, byte4_len, ftmp, tmp[i]); -+ } -+ -+ tcg_gen_subi_i64(addr_end, addr_end, 16); -+ for (i = 0; i < 4; i++) { -+ tcg_gen_movcond_i64(TCG_COND_GEU, t1, addr_end, addr_start, addr_end, addr_start); -+ tcg_gen_qemu_st_i64(tmp[i], t1, memidx, MO_TEUL); -+ tcg_gen_addi_i64(addr_end, addr_end, 4); -+ } -+ -+ tcg_temp_free(ti); -+ tcg_temp_free(ftmp); -+ tcg_temp_free(addr_start); -+ tcg_temp_free(addr_end); -+ tcg_temp_free(byte4_len); -+ tcg_temp_free(tmp[0]); -+ tcg_temp_free(tmp[1]); -+ tcg_temp_free(tmp[2]); -+ tcg_temp_free(tmp[3]); -+} -+ -+static void gen_qemu_vsts_ul(int t0, TCGv t1, int memidx) -+{ -+ TCGv byte4_len; -+ TCGv addr_start, addr_end; -+ TCGv tmp[4]; -+ TCGv ftmp; -+ TCGv ti; -+ int i; -+ -+ tmp[0] = tcg_temp_new(); -+ tmp[1] = tcg_temp_new(); -+ tmp[2] = tcg_temp_new(); -+ tmp[3] = tcg_temp_new(); -+ ftmp = tcg_temp_new(); -+ ti = tcg_temp_new(); -+ addr_start = tcg_temp_new(); -+ addr_end = tcg_temp_new(); -+ byte4_len = tcg_temp_new(); -+ -+ tcg_gen_shri_i64(byte4_len, t1, 2); -+ tcg_gen_andi_i64(byte4_len, byte4_len, 0x3UL); -+ tcg_gen_andi_i64(t1, t1, ~0x3UL); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_mov_i64(addr_start, t1); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_addi_i64(addr_end, addr_start, 12); -+ for (i = 0; i < 4; i++) { -+ tcg_gen_movcond_i64(TCG_COND_LEU, t1, t1, addr_end, t1, addr_end); -+ tcg_gen_qemu_ld_i64(tmp[i], t1, memidx, MO_TEUL); -+ tcg_gen_addi_i64(t1, t1, 4); -+ } -+ tcg_gen_subfi_i64(byte4_len, 4, byte4_len); -+ -+ for (i = 0; i < 4; i++) { -+ tcg_gen_shri_i64(ti, cpu_fr[t0 + i * 32], 62); -+ tcg_gen_shli_i64(ti, ti, 30); -+ tcg_gen_shri_i64(ftmp, cpu_fr[t0 + i * 32], 29); -+ tcg_gen_andi_i64(ftmp, ftmp, 0x3fffffffUL); -+ tcg_gen_or_i64(ftmp, ftmp, ti); -+ tcg_gen_movi_i64(ti, i); -+ tcg_gen_movcond_i64(TCG_COND_LTU, tmp[i], ti, byte4_len, ftmp, tmp[i]); -+ } -+ -+ tcg_gen_addi_i64(addr_start, addr_start, 16); -+ for (i = 3; i >= 0; i--) { -+ tcg_gen_subi_i64(addr_start, addr_start, 4); -+ tcg_gen_movcond_i64(TCG_COND_LEU, t1, addr_start, addr_end, addr_start, addr_end); -+ tcg_gen_qemu_st_i64(tmp[i], t1, memidx, MO_TEUL); -+ } -+ -+ tcg_temp_free(ti); -+ tcg_temp_free(addr_start); -+ tcg_temp_free(addr_end); -+ tcg_temp_free(byte4_len); -+ tcg_temp_free(ftmp); -+ tcg_temp_free(tmp[0]); -+ tcg_temp_free(tmp[1]); -+ tcg_temp_free(tmp[2]); -+ tcg_temp_free(tmp[3]); -+} -+ -+static void gen_qemu_vstd_uh(int t0, TCGv t1, int memidx) -+{ -+ TCGv byte8_len; -+ TCGv addr_start, addr_end; -+ TCGv tmp[4]; -+ TCGv ti; -+ int i; -+ -+ tmp[0] = tcg_temp_new(); -+ tmp[1] = tcg_temp_new(); -+ tmp[2] = tcg_temp_new(); -+ tmp[3] = tcg_temp_new(); -+ ti = tcg_temp_new(); -+ addr_start = tcg_temp_new(); -+ addr_end = tcg_temp_new(); -+ byte8_len = tcg_temp_new(); -+ -+ tcg_gen_shri_i64(byte8_len, t1, 3); -+ tcg_gen_andi_i64(byte8_len, byte8_len, 0x3UL); -+ tcg_gen_andi_i64(t1, t1, ~0x7UL); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_andi_i64(addr_start, t1, ~0x1fUL); -+ tcg_gen_mov_i64(addr_end, t1); -+ for (i = 3; i >= 0; i--) { -+ tcg_gen_movcond_i64(TCG_COND_GEU, t1, t1, addr_start, t1, addr_start); -+ tcg_gen_qemu_ld_i64(tmp[i], t1, memidx, MO_TEQ); -+ tcg_gen_subi_i64(t1, t1, 8); -+ } -+ tcg_gen_subfi_i64(byte8_len, 4, byte8_len); -+ -+ for (i = 0; i < 4; i++) { -+ tcg_gen_movi_i64(ti, i); -+ tcg_gen_movcond_i64(TCG_COND_GEU, tmp[i], ti, byte8_len, cpu_fr[t0 + i*32], tmp[i]); -+ } -+ -+ tcg_gen_subi_i64(addr_end, addr_end, 32); -+ for (i = 0; i < 4; i++) { -+ tcg_gen_movcond_i64(TCG_COND_GEU, t1, addr_end, addr_start, addr_end, addr_start); -+ tcg_gen_qemu_st_i64(tmp[i], t1, memidx, MO_TEQ); -+ tcg_gen_addi_i64(addr_end, addr_end, 8); -+ } -+ -+ tcg_temp_free(ti); -+ tcg_temp_free(addr_start); -+ tcg_temp_free(addr_end); -+ tcg_temp_free(byte8_len); -+ tcg_temp_free(tmp[0]); -+ tcg_temp_free(tmp[1]); -+ tcg_temp_free(tmp[2]); -+ tcg_temp_free(tmp[3]); -+} -+ -+static void gen_qemu_vstd_ul(int t0, TCGv t1, int memidx) -+{ -+ TCGv byte8_len; -+ TCGv addr_start, addr_end; -+ TCGv tmp[4]; -+ TCGv ti; -+ int i; -+ -+ tmp[0] = tcg_temp_new(); -+ tmp[1] = tcg_temp_new(); -+ tmp[2] = tcg_temp_new(); -+ tmp[3] = tcg_temp_new(); -+ ti = tcg_temp_new(); -+ addr_start = tcg_temp_new(); -+ addr_end = tcg_temp_new(); -+ byte8_len = tcg_temp_new(); -+ -+ tcg_gen_shri_i64(byte8_len, t1, 3); -+ tcg_gen_andi_i64(byte8_len, byte8_len, 0x3UL); -+ tcg_gen_andi_i64(t1, t1, ~0x7UL); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_mov_i64(addr_start, t1); /* t1 = addr + byte4_len * 4 */ -+ tcg_gen_addi_i64(addr_end, addr_start, 24); -+ for (i = 0; i < 4; i++) { -+ tcg_gen_movcond_i64(TCG_COND_LEU, t1, t1, addr_end, t1, addr_end); -+ tcg_gen_qemu_ld_i64(tmp[i], t1, memidx, MO_TEQ); -+ tcg_gen_addi_i64(t1, t1, 8); -+ } -+ tcg_gen_subfi_i64(byte8_len, 4, byte8_len); -+ -+ for (i = 0; i < 4; i++) { -+ tcg_gen_movi_i64(ti, i); -+ tcg_gen_movcond_i64(TCG_COND_LTU, tmp[i], ti, byte8_len, cpu_fr[t0 + i*32], tmp[i]); -+ } -+ -+ tcg_gen_addi_i64(addr_start, addr_start, 32); -+ for (i = 3; i >= 0; i--) { -+ tcg_gen_subi_i64(addr_start, addr_start, 8); -+ tcg_gen_movcond_i64(TCG_COND_LEU, t1, addr_start, addr_end, addr_start, addr_end); -+ tcg_gen_qemu_st_i64(tmp[i], t1, memidx, MO_TEQ); -+ } -+ -+ tcg_temp_free(ti); -+ tcg_temp_free(addr_start); -+ tcg_temp_free(addr_end); -+ tcg_temp_free(byte8_len); -+ tcg_temp_free(tmp[0]); -+ tcg_temp_free(tmp[1]); -+ tcg_temp_free(tmp[2]); -+ tcg_temp_free(tmp[3]); -+} -+ -+static void tcg_gen_vcpys_i64(int ra, int rb, int rc) -+{ -+ int i; -+ TCGv tmp64 = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra + i], 63); -+ tcg_gen_shli_i64(tmp64, tmp64, 63); -+ tcg_gen_andi_i64(cpu_fr[rc + i], cpu_fr[rb + i], 0x7fffffffffffffffUL); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, cpu_fr[rc + i]); -+ } -+ tcg_temp_free(tmp64); -+} -+ -+static void tcg_gen_vcpyse_i64(int ra, int rb, int rc) -+{ -+ int i; -+ -+ TCGv tmp64 = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra + i], 52); -+ tcg_gen_shli_i64(tmp64, tmp64, 52); -+ tcg_gen_andi_i64(cpu_fr[rc + i], cpu_fr[rb + i], 0x000fffffffffffffUL); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, cpu_fr[rc + i]); -+ } -+ tcg_temp_free(tmp64); -+} -+ -+static void tcg_gen_vcpysn_i64(int ra, int rb, int rc) -+{ -+ int i; -+ TCGv tmp64 = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra + i], 63); -+ tcg_gen_not_i64(tmp64, tmp64); -+ tcg_gen_shli_i64(tmp64, tmp64, 63); -+ tcg_gen_andi_i64(cpu_fr[rc + i], cpu_fr[rb + i], 0x7fffffffffffffffUL); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, cpu_fr[rc + i]); -+ } -+ tcg_temp_free(tmp64); -+} -+ -+static void tcg_gen_vlogzz_i64(DisasContext *ctx, int opc, int ra, int rb, -+ int rc, int rd, int fn6) -+{ -+ TCGv zz; -+ TCGv args, vd; -+ zz = tcg_const_i64(((opc & 0x3) << 6) | fn6); -+ args = tcg_const_i64((ra << 16) | (rb << 8) | rc); -+ vd = tcg_const_i64(rd); -+ -+ gen_helper_vlogzz(cpu_env, args, vd, zz); -+ -+ tcg_temp_free(vd); -+ tcg_temp_free(args); -+ tcg_temp_free(zz); -+} -+ -+static void gen_qemu_vcmpxxw_i64(TCGCond cond, int ra, int rb, int rc) -+{ -+ TCGv va, vb, vc, tmp64; -+ int i; -+ -+ va = tcg_temp_new(); -+ vb = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ tmp64 = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ if ((cond >> 1) & 1) { -+ tcg_gen_ext32s_i64(va, cpu_fr[ra + i]); -+ tcg_gen_ext32s_i64(vb, cpu_fr[rb + i]); -+ } else { -+ tcg_gen_ext32u_i64(va, cpu_fr[ra + i]); -+ tcg_gen_ext32u_i64(vb, cpu_fr[rb + i]); -+ } -+ tcg_gen_setcond_i64(cond, vc, va, vb); -+ tcg_gen_mov_i64(tmp64, vc); -+ -+ tcg_gen_shri_i64(va, cpu_fr[ra + i], 32); -+ tcg_gen_shri_i64(vb, cpu_fr[rb + i], 32); -+ if ((cond >> 1) & 1) { -+ tcg_gen_ext32s_i64(va, va); -+ tcg_gen_ext32s_i64(vb, vb); -+ } else { -+ tcg_gen_ext32u_i64(va, va); -+ tcg_gen_ext32u_i64(vb, vb); -+ } -+ tcg_gen_setcond_i64(cond, vc, va, vb); -+ tcg_gen_shli_i64(vc, vc, 32); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, vc); -+ } -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ tcg_temp_free(tmp64); -+} -+ -+static void gen_qemu_vcmpxxwi_i64(TCGCond cond, int ra, int rb, int rc) -+{ -+ TCGv va, vb, vc, tmp64; -+ int i; -+ -+ va = tcg_temp_new(); -+ vb = tcg_const_i64(rb); -+ vc = tcg_temp_new(); -+ tmp64 = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ if ((cond >> 1) & 1) { -+ tcg_gen_ext32s_i64(va, cpu_fr[ra + i]); -+ } else { -+ tcg_gen_ext32u_i64(va, cpu_fr[ra + i]); -+ } -+ tcg_gen_setcond_i64(cond, vc, va, vb); -+ tcg_gen_mov_i64(tmp64, vc); -+ -+ tcg_gen_shri_i64(va, cpu_fr[ra + i], 32); -+ if ((cond >> 1) & 1) { -+ tcg_gen_ext32s_i64(va, va); -+ } else { -+ tcg_gen_ext32u_i64(va, va); -+ } -+ tcg_gen_setcond_i64(cond, vc, va, vb); -+ tcg_gen_shli_i64(vc, vc, 32); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, vc); -+ } -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ tcg_temp_free(tmp64); -+} -+ -+static void gen_qemu_vselxxw(TCGCond cond, int ra, int rb, int rc, int rd, -+ int mask) -+{ -+ int i; -+ -+ TCGv t0 = tcg_const_i64(0); -+ TCGv tmpa = tcg_temp_new(); -+ TCGv tmpb = tcg_temp_new(); -+ TCGv tmpc = tcg_temp_new(); -+ TCGv tmpd = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_ext32s_i64(tmpa, cpu_fr[ra + i]); -+ tcg_gen_ext32u_i64(tmpb, cpu_fr[rb + i]); -+ tcg_gen_ext32u_i64(tmpc, cpu_fr[rc + i]); -+ if (mask) tcg_gen_andi_i64(tmpa, tmpa, mask); -+ tcg_gen_movcond_i64(cond, tmpd, tmpa, t0, tmpb, tmpc); -+ -+ tcg_gen_andi_i64(tmpa, cpu_fr[ra + i], 0xffffffff00000000UL); -+ tcg_gen_andi_i64(tmpb, cpu_fr[rb + i], 0xffffffff00000000UL); -+ tcg_gen_andi_i64(tmpc, cpu_fr[rc + i], 0xffffffff00000000UL); -+ if (mask) tcg_gen_andi_i64(tmpa, tmpa, (uint64_t)mask << 32); -+ tcg_gen_movcond_i64(cond, cpu_fr[rd + i], tmpa, t0, tmpb, tmpc); -+ -+ tcg_gen_or_i64(cpu_fr[rd + i], cpu_fr[rd + i], tmpd); -+ } -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(tmpa); -+ tcg_temp_free(tmpb); -+ tcg_temp_free(tmpc); -+ tcg_temp_free(tmpd); -+} -+ -+static void gen_qemu_vselxxwi(TCGCond cond, int ra, int rb, int disp8, int rd, -+ int mask) -+{ -+ int i; -+ -+ TCGv t0 = tcg_const_i64(0); -+ TCGv tmpa = tcg_temp_new(); -+ TCGv tmpb = tcg_temp_new(); -+ TCGv tmpc_0 = tcg_temp_new(); -+ TCGv tmpc_1 = tcg_temp_new(); -+ TCGv tmpd = tcg_temp_new(); -+ -+ tcg_gen_movi_i64(tmpc_0, (uint64_t)(((uint64_t)disp8))); -+ tcg_gen_movi_i64(tmpc_1, (uint64_t)(((uint64_t)disp8 << 32))); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_ext32s_i64(tmpa, cpu_fr[ra + i]); -+ tcg_gen_ext32u_i64(tmpb, cpu_fr[rb + i]); -+ if (mask) tcg_gen_andi_i64(tmpa, tmpa, mask); -+ tcg_gen_movcond_i64(cond, tmpd, tmpa, t0, tmpb, tmpc_0); -+ -+ tcg_gen_andi_i64(tmpa, cpu_fr[ra + i], 0xffffffff00000000UL); -+ tcg_gen_andi_i64(tmpb, cpu_fr[rb + i], 0xffffffff00000000UL); -+ if (mask) tcg_gen_andi_i64(tmpa, tmpa, (uint64_t)mask << 32); -+ tcg_gen_movcond_i64(cond, cpu_fr[rd + i], tmpa, t0, tmpb, tmpc_1); -+ -+ tcg_gen_or_i64(cpu_fr[rd + i], cpu_fr[rd + i], tmpd); -+ } -+ -+ tcg_temp_free(t0); -+ tcg_temp_free(tmpa); -+ tcg_temp_free(tmpb); -+ tcg_temp_free(tmpc_0); -+ tcg_temp_free(tmpc_1); -+ tcg_temp_free(tmpd); -+} -+ -+DisasJumpType translate_one(DisasContextBase *dcbase, uint32_t insn, -+ CPUState *cpu) -+{ -+ int32_t disp5, disp8, disp12, disp13, disp16, disp21, disp26 __attribute__((unused)); -+ uint8_t opc, ra, rb, rc, rd; -+ uint16_t fn3, fn4, fn6, fn8, fn11; -+ int32_t i; -+ TCGv va, vb, vc, vd; -+ TCGv_i32 tmp32; -+ TCGv_i64 tmp64, tmp64_0, tmp64_1, shift; -+ TCGv_i32 tmpa, tmpb, tmpc; -+ DisasJumpType ret; -+ DisasContext* ctx = container_of(dcbase, DisasContext, base); -+ -+ opc = extract32(insn, 26, 6); -+ ra = extract32(insn, 21, 5); -+ rb = extract32(insn, 16, 5); -+ rc = extract32(insn, 0, 5); -+ rd = extract32(insn, 5, 5); -+ -+ fn3 = extract32(insn, 10, 3); -+ fn6 = extract32(insn, 10, 6); -+ fn4 = extract32(insn, 12, 4); -+ fn8 = extract32(insn, 5, 8); -+ fn11 = extract32(insn, 5, 11); -+ -+ disp5 = extract32(insn, 5, 5); -+ disp8 = extract32(insn, 13, 8); -+ disp12 = sextract32(insn, 0, 12); -+ disp13 = sextract32(insn, 13, 13); -+ disp16 = sextract32(insn, 0, 16); -+ disp21 = sextract32(insn, 0, 21); -+ disp26 = sextract32(insn, 0, 26); -+ -+ ret = DISAS_NEXT; -+ insn_profile(ctx, insn); -+ -+ switch (opc) { -+ case 0x00: -+ /* SYS_CALL */ -+ ret = gen_sys_call(ctx, insn & 0x1ffffff); -+ break; -+ case 0x01: -+ /* CALL */ -+ case 0x02: -+ /* RET */ -+ case 0x03: -+ /* JMP */ -+ vb = load_gir(ctx, rb); -+ tcg_gen_addi_i64(cpu_pc, vb, ctx->base.pc_next & 0x3); -+ if (ra != 31) { -+ tcg_gen_movi_i64(load_gir(ctx, ra), ctx->base.pc_next & (~3UL)); -+ } -+ ret = DISAS_PC_UPDATED; -+ break; -+ case 0x04: -+ /* BR */ -+ case 0x05: -+ /* BSR */ -+ ret = gen_bdirect(ctx, ra, disp21); -+ break; -+ case 0x06: -+ switch (disp16) { -+ case 0x0000: -+ /* MEMB */ -+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); -+ break; -+ case 0x0001: -+ /* IMEMB */ -+ /* No achievement in Qemu*/ -+ break; -+ case 0x0020: -+ /* RTC */ -+ if (disp16 && unlikely(ra == 31)) break; -+ va = load_gir(ctx, ra); -+ gen_helper_rtc(va); -+ break; -+ case 0x0040: -+ /* RCID */ -+ if (disp16 && unlikely(ra == 31)) break; -+ va = load_gir(ctx, ra); -+ read_csr(0xc4, va); -+ break; -+ case 0x0080: -+ /* HALT */ -+#ifndef CONFIG_USER_ONLY -+ { -+ tmp32 = tcg_const_i32(1); -+ tcg_gen_st_i32( -+ tmp32, cpu_env, -+ -offsetof(SW64CPU, env) + offsetof(CPUState, halted)); -+ tcg_temp_free_i32(tmp32); -+ } -+ ret = gen_excp(ctx, EXCP_HALTED, 0); -+#endif -+ break; -+ case 0x1000: -+ /* RD_F */ -+ if (disp16 && unlikely(ra == 31)) break; -+ va = load_gir(ctx, ra); -+ tcg_gen_mov_i64(va, cpu_lock_success); -+ break; -+ case 0x1020: -+ /* WR_F */ -+ if (disp16 && unlikely(ra == 31)) break; -+ va = load_gir(ctx, ra); -+ tcg_gen_andi_i64(cpu_lock_flag, va, 0x1); -+ break; -+ case 0x1040: -+ /* RTID */ -+ if (unlikely(ra == 31)) break; -+ va = load_gir(ctx, ra); -+ read_csr(0xc7, va); -+ break; -+ default: -+ if ((disp16 & 0xFF00) == 0xFE00) { -+ /* PRI_RCSR */ -+ if (disp16 && unlikely(ra == 31)) break; -+ va = load_gir(ctx, ra); -+ read_csr(disp16 & 0xff, va); -+ break; -+ } -+ if ((disp16 & 0xFF00) == 0xFF00) { -+ /* PRI_WCSR */ -+ va = load_gir(ctx, ra); -+ write_csr(disp16 & 0xff, va, ctx->env); -+ break; -+ } -+ goto do_invalid; -+ } -+ break; -+ case 0x07: -+ /* PRI_RET */ -+ va = load_gir(ctx, ra); -+ tcg_gen_mov_i64(cpu_pc, va); -+ gen_helper_cpustate_update(cpu_env, va); -+ ret = DISAS_PC_UPDATED_NOCHAIN; -+ break; -+ case 0x08: -+ switch (fn4) { -+ case 0x0: -+ /* LLDW */ -+ gen_load_mem(ctx, &gen_qemu_lldw, ra, rb, disp12, 0, 0); -+ break; -+ case 0x1: -+ /* LLDL */ -+ gen_load_mem(ctx, &gen_qemu_lldl, ra, rb, disp12, 0, 0); -+ break; -+ case 0x2: -+ /* LDW_INC */ -+ ldx_xxx(ctx, ra, rb, disp12, 0, 1); -+ break; -+ case 0x3: -+ /* LDL_INC */ -+ ldx_xxx(ctx, ra, rb, disp12, 1, 1); -+ break; -+ case 0x4: -+ /* LDW_DEC */ -+ ldx_xxx(ctx, ra, rb, disp12, 0, -1); -+ break; -+ case 0x5: -+ /* LDL_DEC */ -+ ldx_xxx(ctx, ra, rb, disp12, 1, -1); -+ break; -+ case 0x6: -+ /* LDW_SET */ -+ ldx_set(ctx, ra, rb, disp12, 0); -+ break; -+ case 0x7: -+ /* LDL_SET */ -+ ldx_set(ctx, ra, rb, disp12, 1); -+ break; -+ case 0x8: -+ /* LSTW */ -+ ret = gen_store_conditional(ctx, ra, rb, disp12, -+ ctx->mem_idx, MO_LEUL); -+ break; -+ case 0x9: -+ /* LSTL */ -+ ret = gen_store_conditional(ctx, ra, rb, disp12, -+ ctx->mem_idx, MO_LEQ); -+ break; -+ case 0xa: -+ /* LDW_NC */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp12, 0, -+ 0); -+ break; -+ case 0xb: -+ /* LDL_NC */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp12, 0, 0); -+ break; -+ case 0xc: -+ /* LDD_NC */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp12, 1, 0); -+ break; -+ case 0xd: -+ /* STW_NC */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp12, 0, -+ 0); -+ break; -+ case 0xe: -+ /* STL_NC */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp12, 0, -+ 0); -+ break; -+ case 0xf: -+ /* STD_NC */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp12, 1, -+ 0); -+ break; -+ default: -+ goto do_invalid; -+ } -+ break; -+ case 0x9: -+ /* LDWE */ -+ gen_load_mem_simd(ctx, &gen_qemu_ldwe, ra, rb, disp16, 0); -+ break; -+ case 0x0a: -+ /* LDSE */ -+ gen_load_mem_simd(ctx, &gen_qemu_ldse, ra, rb, disp16, 0); -+ break; -+ case 0x0b: -+ /* LDDE */ -+ gen_load_mem_simd(ctx, &gen_qemu_ldde, ra, rb, disp16, 0); -+ break; -+ case 0x0c: -+ /* VLDS */ -+ gen_load_mem_simd(ctx, &gen_qemu_vlds, ra, rb, disp16, 0); -+ break; -+ case 0x0d: -+ /* VLDD */ -+ if (unlikely(ra == 31)) break; -+ gen_load_mem_simd(ctx, &gen_qemu_vldd, ra, rb, disp16, 0); -+ break; -+ case 0x0e: -+ /* VSTS */ -+ gen_store_mem_simd(ctx, &gen_qemu_vsts, ra, rb, disp16, 0); -+ break; -+ case 0x0f: -+ /* VSTD */ -+ gen_store_mem_simd(ctx, &gen_qemu_vstd, ra, rb, disp16, 0); -+ break; -+ case 0x10: -+ if (unlikely(rc == 31)) break; -+ if (fn11 == 0x70) { -+ /* FIMOVS */ -+ va = cpu_fr[ra]; -+ vc = load_gir(ctx, rc); -+ tmp32 = tcg_temp_new_i32(); -+ gen_helper_s_to_memory(tmp32, va); -+ tcg_gen_ext_i32_i64(vc, tmp32); -+ tcg_temp_free_i32(tmp32); -+ } else if (fn11 == 0x78) { -+ /* FIMOVD */ -+ va = cpu_fr[ra]; -+ vc = load_gir(ctx, rc); -+ tcg_gen_mov_i64(vc, va); -+ } else { -+ va = load_gir(ctx, ra); -+ vb = load_gir(ctx, rb); -+ vc = load_gir(ctx, rc); -+ cal_with_iregs_2(ctx, vc, va, vb, disp13, fn11); -+ } -+ break; -+ case 0x11: -+ if (unlikely(rc == 31)) break; -+ va = load_gir(ctx, ra); -+ vb = load_gir(ctx, rb); -+ vc = load_gir(ctx, rc); -+ vd = load_gir(ctx, rd); -+ cal_with_iregs_3(ctx, vc, va, vb, vd, fn3); -+ break; -+ case 0x12: -+ if (unlikely(rc == 31)) break; -+ va = load_gir(ctx, ra); -+ vc = load_gir(ctx, rc); -+ cal_with_imm_2(ctx, vc, va, disp8, fn8); -+ break; -+ case 0x13: -+ if (rc == 31) /* Special deal */ -+ break; -+ va = load_gir(ctx, ra); -+ vc = load_gir(ctx, rc); -+ vd = load_gir(ctx, rd); -+ cal_with_imm_3(ctx, vc, va, disp8, vd, fn3); -+ break; -+ case 0x14: -+ case 0x15: -+ case 0x16: -+ case 0x17: -+ /* VLOGZZ */ -+ tcg_gen_vlogzz_i64(ctx, opc, ra, rb, rd, rc, fn6); -+ break; -+ case 0x18: -+ if (unlikely(rc == 31)) break; -+ cal_with_fregs_2(ctx, rc, ra, rb, fn8); -+ break; -+ case 0x19: -+ if (unlikely(rc == 31)) break; -+ cal_with_fregs_4(ctx, rc, ra, rb, rd, fn6); -+ break; -+ case 0x1A: -+ /* SIMD */ -+ if (unlikely(rc == 31)) break; -+ switch (fn8) { -+ case 0x00: -+ /* VADDW */ -+ tmp64 = tcg_temp_new(); -+ va = tcg_temp_new(); -+ vb = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_andi_i64(va, cpu_fr[ra + i], 0xffffffffUL); -+ tcg_gen_andi_i64(vb, cpu_fr[rb + i], 0xffffffffUL); -+ tcg_gen_add_i64(tmp64, va, vb); -+ tcg_gen_ext32u_i64(tmp64, tmp64); -+ tcg_gen_andi_i64(va, cpu_fr[ra + i], -+ 0xffffffff00000000UL); -+ tcg_gen_andi_i64(vb, cpu_fr[rb + i], -+ 0xffffffff00000000UL); -+ tcg_gen_add_i64(vc, va, vb); -+ tcg_gen_or_i64(tmp64, tmp64, vc); -+ tcg_gen_mov_i64(cpu_fr[rc + i], tmp64); -+ } -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x20: -+ /* VADDW */ -+ tmp64 = tcg_temp_new(); -+ va = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_andi_i64(va, cpu_fr[ra + i], 0xffffffffUL); -+ tcg_gen_addi_i64(tmp64, va, disp8); -+ tcg_gen_ext32u_i64(tmp64, tmp64); -+ tcg_gen_andi_i64(va, cpu_fr[ra + i], -+ 0xffffffff00000000UL); -+ tcg_gen_addi_i64(vc, va, ((uint64_t)disp8 << 32)); -+ tcg_gen_or_i64(tmp64, tmp64, vc); -+ tcg_gen_mov_i64(cpu_fr[rc + i], tmp64); -+ } -+ tcg_temp_free(va); -+ tcg_temp_free(vc); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x01: -+ /* VSUBW */ -+ tmp64 = tcg_temp_new(); -+ va = tcg_temp_new(); -+ vb = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_andi_i64(va, cpu_fr[ra + i], 0xffffffffUL); -+ tcg_gen_andi_i64(vb, cpu_fr[rb + i], 0xffffffffUL); -+ tcg_gen_sub_i64(tmp64, va, vb); -+ tcg_gen_ext32u_i64(tmp64, tmp64); -+ tcg_gen_andi_i64(va, cpu_fr[ra + i], -+ 0xffffffff00000000UL); -+ tcg_gen_andi_i64(vb, cpu_fr[rb + i], -+ 0xffffffff00000000UL); -+ tcg_gen_sub_i64(vc, va, vb); -+ tcg_gen_or_i64(tmp64, tmp64, vc); -+ tcg_gen_mov_i64(cpu_fr[rc + i], tmp64); -+ } -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x21: -+ /* VSUBW */ -+ tmp64 = tcg_temp_new(); -+ va = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_andi_i64(va, cpu_fr[ra + i], 0xffffffffUL); -+ tcg_gen_subi_i64(tmp64, va, disp8); -+ tcg_gen_ext32u_i64(tmp64, tmp64); -+ tcg_gen_andi_i64(va, cpu_fr[ra + i], -+ 0xffffffff00000000UL); -+ tcg_gen_subi_i64(vc, va, ((uint64_t)disp8 << 32)); -+ tcg_gen_or_i64(tmp64, tmp64, vc); -+ tcg_gen_mov_i64(cpu_fr[rc + i], tmp64); -+ } -+ tcg_temp_free(va); -+ tcg_temp_free(vc); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x02: -+ /* VCMPGEW */ -+ tmp64 = tcg_const_i64(0); -+ va = tcg_temp_new(); -+ vb = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_ext32s_i64(va, cpu_fr[ra + i]); -+ tcg_gen_ext32s_i64(vb, cpu_fr[rb + i]); -+ tcg_gen_setcond_i64(TCG_COND_GE, vc, va, vb); -+ tcg_gen_or_i64(tmp64, tmp64, vc); -+ tcg_gen_shri_i64(va, cpu_fr[ra + i], 32); -+ tcg_gen_shri_i64(vb, cpu_fr[rb + i], 32); -+ tcg_gen_ext32s_i64(va, va); -+ tcg_gen_ext32s_i64(vb, vb); -+ tcg_gen_setcond_i64(TCG_COND_GE, vc, va, vb); -+ tcg_gen_or_i64(tmp64, tmp64, vc); -+ } -+ tcg_gen_shli_i64(cpu_fr[rc], tmp64, 29); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x22: -+ /* VCMPGEW */ -+ tmp64 = tcg_const_i64(0); -+ va = tcg_temp_new(); -+ vb = tcg_const_i64(disp8); -+ vc = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_ext32s_i64(va, cpu_fr[ra + i]); -+ tcg_gen_setcond_i64(TCG_COND_GE, vc, va, vb); -+ tcg_gen_or_i64(tmp64, tmp64, vc); -+ tcg_gen_shri_i64(va, cpu_fr[ra + i], 32); -+ tcg_gen_ext32s_i64(va, va); -+ tcg_gen_setcond_i64(TCG_COND_GE, vc, va, vb); -+ tcg_gen_or_i64(tmp64, tmp64, vc); -+ } -+ tcg_gen_shli_i64(cpu_fr[rc], tmp64, 29); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x03: -+ /* VCMPEQW */ -+ gen_qemu_vcmpxxw_i64(TCG_COND_EQ, ra, rb, rc); -+ break; -+ case 0x23: -+ /* VCMPEQW */ -+ gen_qemu_vcmpxxwi_i64(TCG_COND_EQ, ra, disp8, rc); -+ break; -+ case 0x04: -+ /* VCMPLEW */ -+ gen_qemu_vcmpxxw_i64(TCG_COND_LE, ra, rb, rc); -+ break; -+ case 0x24: -+ /* VCMPLEW */ -+ gen_qemu_vcmpxxwi_i64(TCG_COND_LE, ra, disp8, rc); -+ break; -+ case 0x05: -+ /* VCMPLTW */ -+ gen_qemu_vcmpxxw_i64(TCG_COND_LT, ra, rb, rc); -+ break; -+ case 0x25: -+ /* VCMPLTW */ -+ gen_qemu_vcmpxxwi_i64(TCG_COND_LT, ra, disp8, rc); -+ break; -+ case 0x06: -+ /* VCMPULEW */ -+ gen_qemu_vcmpxxw_i64(TCG_COND_LEU, ra, rb, rc); -+ break; -+ case 0x26: -+ /* VCMPULEW */ -+ gen_qemu_vcmpxxwi_i64(TCG_COND_LEU, ra, disp8, rc); -+ break; -+ case 0x07: -+ /* VCMPULTW */ -+ gen_qemu_vcmpxxw_i64(TCG_COND_LTU, ra, rb, rc); -+ break; -+ case 0x27: -+ /* VCMPULTW */ -+ gen_qemu_vcmpxxwi_i64(TCG_COND_LTU, ra, disp8, rc); -+ break; -+ case 0x08: -+ /* VSLLW */ -+ tmp64 = tcg_temp_new(); -+ shift = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_shri_i64(shift, cpu_fr[rb], 29); -+ tcg_gen_andi_i64(shift, shift, 0x1fUL); -+ -+ tcg_gen_shl_i64(vc, cpu_fr[ra + i], shift); -+ tcg_gen_ext32u_i64(tmp64, vc); -+ -+ tcg_gen_andi_i64(vc, cpu_fr[ra + i], -+ 0xffffffff00000000UL); -+ tcg_gen_shl_i64(vc, vc, shift); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, vc); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(shift); -+ tcg_temp_free(vc); -+ break; -+ case 0x28: -+ /* VSLLW */ -+ tmp64 = tcg_temp_new(); -+ shift = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_movi_i64(shift, disp8 & 0x1fUL); -+ -+ tcg_gen_shl_i64(vc, cpu_fr[ra + i], shift); -+ tcg_gen_ext32u_i64(tmp64, vc); -+ -+ tcg_gen_andi_i64(vc, cpu_fr[ra + i], -+ 0xffffffff00000000UL); -+ tcg_gen_shl_i64(vc, vc, shift); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, vc); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(shift); -+ tcg_temp_free(vc); -+ break; -+ case 0x09: -+ /* VSRLW */ -+ tmp64 = tcg_temp_new(); -+ shift = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_shri_i64(shift, cpu_fr[rb], 29); -+ tcg_gen_andi_i64(shift, shift, 0x1fUL); -+ -+ tcg_gen_ext32u_i64(vc, cpu_fr[ra + i]); -+ tcg_gen_shr_i64(tmp64, vc, shift); -+ -+ tcg_gen_shr_i64(vc, cpu_fr[ra + i], shift); -+ tcg_gen_andi_i64(vc, vc, 0xffffffff00000000UL); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, vc); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(shift); -+ tcg_temp_free(vc); -+ break; -+ case 0x29: -+ /* VSRLW */ -+ tmp64 = tcg_temp_new(); -+ shift = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_movi_i64(shift, disp8 & 0x1fUL); -+ -+ tcg_gen_ext32u_i64(vc, cpu_fr[ra + i]); -+ tcg_gen_shr_i64(tmp64, vc, shift); -+ -+ tcg_gen_shr_i64(vc, cpu_fr[ra + i], shift); -+ tcg_gen_andi_i64(vc, vc, 0xffffffff00000000UL); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, vc); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(shift); -+ tcg_temp_free(vc); -+ break; -+ case 0x0A: -+ /* VSRAW */ -+ tmp64 = tcg_temp_new(); -+ shift = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_shri_i64(shift, cpu_fr[rb], 29); -+ tcg_gen_andi_i64(shift, shift, 0x1fUL); -+ -+ tcg_gen_ext32s_i64(vc, cpu_fr[ra + i]); -+ tcg_gen_sar_i64(tmp64, vc, shift); -+ -+ tcg_gen_sar_i64(vc, cpu_fr[ra + i], shift); -+ tcg_gen_andi_i64(vc, vc, 0xffffffff00000000UL); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, vc); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(shift); -+ tcg_temp_free(vc); -+ break; -+ case 0x2A: -+ /* VSRAWI */ -+ tmp64 = tcg_temp_new(); -+ shift = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_movi_i64(shift, disp8 & 0x1fUL); -+ -+ tcg_gen_ext32s_i64(vc, cpu_fr[ra + i]); -+ tcg_gen_sar_i64(tmp64, vc, shift); -+ -+ tcg_gen_sar_i64(vc, cpu_fr[ra + i], shift); -+ tcg_gen_andi_i64(vc, vc, 0xffffffff00000000UL); -+ tcg_gen_or_i64(cpu_fr[rc + i], tmp64, vc); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(shift); -+ tcg_temp_free(vc); -+ break; -+ case 0x0B: -+ /* VROLW */ -+ tmpa = tcg_temp_new_i32(); -+ tmpb = tcg_temp_new_i32(); -+ tmpc = tcg_temp_new_i32(); -+ tmp64 = tcg_temp_new(); -+ shift = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_shri_i64(shift, cpu_fr[rb], 29); -+ tcg_gen_andi_i64(shift, shift, 0x1fUL); -+ -+ tcg_gen_extrl_i64_i32(tmpa, cpu_fr[ra + i]); -+ tcg_gen_extrl_i64_i32(tmpb, shift); -+ -+ tcg_gen_rotl_i32(tmpc, tmpa, tmpb); -+ tcg_gen_extu_i32_i64(tmp64, tmpc); -+ -+ tcg_gen_extrh_i64_i32(tmpa, cpu_fr[ra + i]); -+ tcg_gen_rotl_i32(tmpc, tmpa, tmpb); -+ tcg_gen_extu_i32_i64(vc, tmpc); -+ tcg_gen_shli_i64(vc, vc, 32); -+ -+ tcg_gen_or_i64(cpu_fr[rc + i], vc, tmp64); -+ } -+ tcg_temp_free_i32(tmpa); -+ tcg_temp_free_i32(tmpb); -+ tcg_temp_free_i32(tmpc); -+ tcg_temp_free(tmp64); -+ tcg_temp_free(shift); -+ tcg_temp_free(vc); -+ break; -+ case 0x2B: -+ /* VROLW */ -+ tmpa = tcg_temp_new_i32(); -+ tmpb = tcg_temp_new_i32(); -+ tmpc = tcg_temp_new_i32(); -+ tmp64 = tcg_temp_new(); -+ shift = tcg_temp_new(); -+ vc = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_movi_i64(shift, disp8 & 0x1fUL); -+ -+ tcg_gen_extrl_i64_i32(tmpa, cpu_fr[ra + i]); -+ tcg_gen_extrl_i64_i32(tmpb, shift); -+ -+ tcg_gen_rotl_i32(tmpc, tmpa, tmpb); -+ tcg_gen_extu_i32_i64(tmp64, tmpc); -+ -+ tcg_gen_extrh_i64_i32(tmpa, cpu_fr[ra + i]); -+ tcg_gen_rotl_i32(tmpc, tmpa, tmpb); -+ tcg_gen_extu_i32_i64(vc, tmpc); -+ tcg_gen_shli_i64(vc, vc, 32); -+ -+ tcg_gen_or_i64(cpu_fr[rc + i], vc, tmp64); -+ } -+ tcg_temp_free_i32(tmpa); -+ tcg_temp_free_i32(tmpb); -+ tcg_temp_free_i32(tmpc); -+ tcg_temp_free(tmp64); -+ tcg_temp_free(shift); -+ tcg_temp_free(vc); -+ break; -+ case 0x0C: -+ /* SLLOW */ -+ tcg_gen_sllow_i64(ra, rc, rb); -+ break; -+ case 0x2C: -+ /* SLLOW */ -+ tcg_gen_sllowi_i64(ra, rc, disp8); -+ break; -+ case 0x0D: -+ /* SRLOW */ -+ tcg_gen_srlow_i64(ra, rc, rb); -+ break; -+ case 0x2D: -+ /* SRLOW */ -+ tcg_gen_srlowi_i64(ra, rc, disp8); -+ break; -+ case 0x0E: -+ /* VADDL */ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_add_i64(cpu_fr[rc + i], cpu_fr[ra + i], -+ cpu_fr[rb + i]); -+ } -+ break; -+ case 0x2E: -+ /* VADDL */ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_addi_i64(cpu_fr[rc + i], cpu_fr[ra + i], disp8); -+ } -+ break; -+ case 0x0F: -+ /* VSUBL */ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_sub_i64(cpu_fr[rc + i], cpu_fr[ra + i], -+ cpu_fr[rb + i]); -+ } -+ break; -+ case 0x2F: -+ /* VSUBL */ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_subi_i64(cpu_fr[rc + i], cpu_fr[ra + i], disp8); -+ } -+ break; -+ case 0x18: -+ /* CTPOPOW */ -+ tmp64 = tcg_const_i64(0); -+ tmp64_0 = tcg_temp_new(); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_ctpop_i64(tmp64_0, cpu_fr[ra + i]); -+ tcg_gen_add_i64(tmp64, tmp64, tmp64_0); -+ } -+ tcg_gen_shli_i64(cpu_fr[rc], tmp64, 29); -+ tcg_temp_free(tmp64); -+ tcg_temp_free(tmp64_0); -+ break; -+ case 0x19: -+ /* CTLZOW */ -+ va = tcg_const_i64(ra); -+ gen_helper_ctlzow(cpu_fr[rc], cpu_env, va); -+ tcg_temp_free(va); -+ break; -+ case 0x40: -+ /* VUCADDW */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(rb); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucaddw(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x60: -+ /* VUCADDW */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(disp8); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucaddwi(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x41: -+ /* VUCSUBW */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(rb); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucsubw(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x61: -+ /* VUCSUBW */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(disp8); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucsubwi(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x42: -+ /* VUCADDH */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(rb); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucaddh(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x62: -+ /* VUCADDH */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(disp8); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucaddhi(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x43: -+ /* VUCSUBH */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(rb); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucsubh(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x63: -+ /* VUCSUBH */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(disp8); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucsubhi(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x44: -+ /* VUCADDB */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(rb); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucaddb(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x64: -+ /* VUCADDB */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(disp8); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucaddbi(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x45: -+ /* VUCSUBB */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(rb); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucsubb(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x65: -+ /* VUCSUBB */ -+ va = tcg_const_i64(ra); -+ vb = tcg_const_i64(disp8); -+ vc = tcg_const_i64(rc); -+ gen_helper_vucsubbi(cpu_env, va, vb, vc); -+ tcg_temp_free(va); -+ tcg_temp_free(vb); -+ tcg_temp_free(vc); -+ break; -+ case 0x80: -+ /* VADDS */ -+ for (i = 0; i < 128; i += 32) -+ gen_fadds(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x81: -+ /* VADDD */ -+ for (i = 0; i < 128; i += 32) -+ gen_faddd(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x82: -+ /* VSUBS */ -+ for (i = 0; i < 128; i += 32) -+ gen_fsubs(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x83: -+ /* VSUBD */ -+ for (i = 0; i < 128; i += 32) -+ gen_fsubd(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x84: -+ /* VMULS */ -+ for (i = 0; i < 128; i += 32) -+ gen_fmuls(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x85: -+ /* VMULD */ -+ for (i = 0; i < 128; i += 32) -+ gen_fmuld(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x86: -+ /* VDIVS */ -+ for (i = 0; i < 128; i += 32) -+ gen_fdivs(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x87: -+ /* VDIVD */ -+ for (i = 0; i < 128; i += 32) -+ gen_fdivd(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x88: -+ /* VSQRTS */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fsqrts(cpu_fr[rc + i], cpu_env, -+ cpu_fr[rb + i]); -+ break; -+ case 0x89: -+ /* VSQRTD */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fsqrt(cpu_fr[rc + i], cpu_env, -+ cpu_fr[rb + i]); -+ break; -+ case 0x8C: -+ /* VFCMPEQ */ -+ for (i = 0; i < 128; i += 32) -+ gen_fcmpeq(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x8D: -+ /* VFCMPLE */ -+ for (i = 0; i < 128; i += 32) -+ gen_fcmple(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x8E: -+ /* VFCMPLT */ -+ for (i = 0; i < 128; i += 32) -+ gen_fcmplt(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x8F: -+ /* VFCMPUN */ -+ for (i = 0; i < 128; i += 32) -+ gen_fcmpun(ctx, ra + i, rb + i, rc + i); -+ break; -+ case 0x90: -+ /* VCPYS */ -+ tcg_gen_vcpys_i64(ra, rb, rc); -+ break; -+ case 0x91: -+ /* VCPYSE */ -+ tcg_gen_vcpyse_i64(ra, rb, rc); -+ break; -+ case 0x92: -+ /* VCPYSN */ -+ tcg_gen_vcpysn_i64(ra, rb, rc); -+ break; -+ case 0x93: -+ /* VSUMS */ -+ gen_fadds(ctx, ra, ra + 32, rc); -+ gen_fadds(ctx, rc, ra + 64, rc); -+ gen_fadds(ctx, rc, ra + 96, rc); -+ break; -+ case 0x94: -+ /* VSUMD */ -+ gen_faddd(ctx, ra, ra + 32, rc); -+ gen_faddd(ctx, rc, ra + 64, rc); -+ gen_faddd(ctx, rc, ra + 96, rc); -+ break; -+ default: -+ printf("ILLEGAL BELOW OPC[%x] func[%08x]\n", opc, fn8); -+ ret = gen_invalid(ctx); -+ break; -+ } -+ break; -+ case 0x1B: -+ /* SIMD */ -+ if (unlikely(rc == 31)) break; -+ switch (fn6) { -+ case 0x00: -+ /* VMAS */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fmas(cpu_fr[rc + i], cpu_env, cpu_fr[ra + i], -+ cpu_fr[rb + i], cpu_fr[rd + i]); -+ break; -+ case 0x01: -+ /* VMAD */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fmad(cpu_fr[rc + i], cpu_env, cpu_fr[ra + i], -+ cpu_fr[rb + i], cpu_fr[rd + i]); -+ break; -+ case 0x02: -+ /* VMSS */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fmss(cpu_fr[rc + i], cpu_env, cpu_fr[ra + i], -+ cpu_fr[rb + i], cpu_fr[rd + i]); -+ break; -+ case 0x03: -+ /* VMSD */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fmsd(cpu_fr[rc + i], cpu_env, cpu_fr[ra + i], -+ cpu_fr[rb + i], cpu_fr[rd + i]); -+ break; -+ case 0x04: -+ /* VNMAS */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fnmas(cpu_fr[rc + i], cpu_env, -+ cpu_fr[ra + i], cpu_fr[rb + i], -+ cpu_fr[rd + i]); -+ break; -+ case 0x05: -+ /* VNMAD */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fnmad(cpu_fr[rc + i], cpu_env, -+ cpu_fr[ra + i], cpu_fr[rb + i], -+ cpu_fr[rd + i]); -+ break; -+ case 0x06: -+ /* VNMSS */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fnmss(cpu_fr[rc + i], cpu_env, -+ cpu_fr[ra + i], cpu_fr[rb + i], -+ cpu_fr[rd + i]); -+ break; -+ case 0x07: -+ /* VNMSD */ -+ for (i = 0; i < 128; i += 32) -+ gen_helper_fnmsd(cpu_fr[rc + i], cpu_env, -+ cpu_fr[ra + i], cpu_fr[rb + i], -+ cpu_fr[rd + i]); -+ break; -+ case 0x10: -+ /* VFSELEQ */ -+ tmp64 = tcg_temp_new(); -+ tmp64_0 = tcg_const_i64(0); -+ for (i = 0; i < 128; i += 32) { -+ gen_helper_fcmpeq(tmp64, cpu_env, cpu_fr[ra + i], -+ tmp64_0); -+ tcg_gen_movcond_i64(TCG_COND_EQ, cpu_fr[rc + i], tmp64, -+ tmp64_0, cpu_fr[rd + i], -+ cpu_fr[rb + i]); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(tmp64_0); -+ break; -+ case 0x12: -+ /* VFSELLT */ -+ tmp64 = tcg_temp_new(); -+ tmp64_0 = tcg_const_i64(0); -+ tmp64_1 = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_andi_i64(tmp64, cpu_fr[ra + i], -+ 0x7fffffffffffffffUL); -+ tcg_gen_setcond_i64(TCG_COND_NE, tmp64, tmp64, -+ tmp64_0); -+ tcg_gen_shri_i64(tmp64_1, cpu_fr[ra +i], 63); -+ tcg_gen_and_i64(tmp64, tmp64_1, tmp64); -+ tcg_gen_movcond_i64(TCG_COND_EQ, cpu_fr[rc + i], tmp64, -+ tmp64_0, cpu_fr[rd + i], -+ cpu_fr[rb + i]); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(tmp64_0); -+ tcg_temp_free(tmp64_1); -+ break; -+ case 0x13: -+ /* VFSELLE */ -+ tmp64 = tcg_temp_new(); -+ tmp64_0 = tcg_const_i64(0); -+ tmp64_1 = tcg_temp_new(); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_andi_i64(tmp64, cpu_fr[ra + i], -+ 0x7fffffffffffffffUL); -+ tcg_gen_setcond_i64(TCG_COND_EQ, tmp64, tmp64, -+ tmp64_0); -+ tcg_gen_shri_i64(tmp64_1, cpu_fr[ra + i], 63); -+ tcg_gen_or_i64(tmp64, tmp64_1, tmp64); -+ tcg_gen_movcond_i64(TCG_COND_EQ, cpu_fr[rc + i], tmp64, -+ tmp64_0, cpu_fr[rd + i], -+ cpu_fr[rb + i]); -+ } -+ tcg_temp_free(tmp64); -+ tcg_temp_free(tmp64_0); -+ tcg_temp_free(tmp64_1); -+ break; -+ case 0x18: -+ /* VSELEQW */ -+ gen_qemu_vselxxw(TCG_COND_EQ, ra, rb, rd, rc, 0); -+ break; -+ case 0x38: -+ /* VSELEQW */ -+ gen_qemu_vselxxwi(TCG_COND_EQ, ra, rb, disp5, rc, 0); -+ break; -+ case 0x19: -+ /* VSELLBCW */ -+ gen_qemu_vselxxw(TCG_COND_EQ, ra, rb, rd, rc, 1); -+ break; -+ case 0x39: -+ /* VSELLBCW */ -+ gen_qemu_vselxxwi(TCG_COND_EQ, ra, rb, disp5, rc, 1); -+ break; -+ case 0x1A: -+ /* VSELLTW */ -+ gen_qemu_vselxxw(TCG_COND_LT, ra, rb, rd, rc, 0); -+ break; -+ case 0x3A: -+ /* VSELLTW */ -+ gen_qemu_vselxxwi(TCG_COND_LT, ra, rb, disp5, rc, 0); -+ break; -+ case 0x1B: -+ /* VSELLEW */ -+ gen_qemu_vselxxw(TCG_COND_LE, ra, rb, rd, rc, 0); -+ break; -+ case 0x3B: -+ /* VSELLEW */ -+ gen_qemu_vselxxwi(TCG_COND_LE, ra, rb, disp5, rc, 0); -+ break; -+ case 0x20: -+ /* VINSW */ -+ if (disp5 > 7) break; -+ tmp64 = tcg_temp_new(); -+ tmp32 = tcg_temp_new_i32(); -+ gen_helper_s_to_memory(tmp32, cpu_fr[ra]); -+ tcg_gen_extu_i32_i64(tmp64, tmp32); -+ tcg_gen_shli_i64(tmp64, tmp64, (disp5 % 2) * 32); -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_mov_i64(cpu_fr[rc + i], cpu_fr[rb + i]); -+ } -+ if (disp5 % 2) { -+ tcg_gen_andi_i64(cpu_fr[rc + (disp5 / 2) * 32], -+ cpu_fr[rc + (disp5 / 2) * 32], -+ 0xffffffffUL); -+ } else { -+ tcg_gen_andi_i64(cpu_fr[rc + (disp5 / 2) * 32], -+ cpu_fr[rc + (disp5 / 2) * 32], -+ 0xffffffff00000000UL); -+ } -+ tcg_gen_or_i64(cpu_fr[rc + (disp5 / 2) * 32], -+ cpu_fr[rc + (disp5 / 2) * 32], tmp64); -+ tcg_temp_free(tmp64); -+ tcg_temp_free_i32(tmp32); -+ break; -+ case 0x21: -+ /* VINSF */ -+ if (disp5 > 3) break; -+ tmp64 = tcg_temp_new(); -+ tcg_gen_mov_i64(tmp64, cpu_fr[ra]); -+ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_mov_i64(cpu_fr[rc + i], cpu_fr[rb + i]); -+ } -+ tcg_gen_mov_i64(cpu_fr[rc + disp5 * 32], tmp64); -+ tcg_temp_free(tmp64); -+ break; -+ case 0x22: -+ /* VEXTW */ -+ if (disp5 > 7) break; -+ tmp64 = tcg_temp_new(); -+ tmp32 = tcg_temp_new_i32(); -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra + (disp5 / 2) * 32], -+ (disp5 % 2) * 32); -+ tcg_gen_extrl_i64_i32(tmp32, tmp64); -+ gen_helper_memory_to_s(tmp64, tmp32); -+ tcg_gen_mov_i64(cpu_fr[rc], tmp64); -+ tcg_temp_free(tmp64); -+ tcg_temp_free_i32(tmp32); -+ break; -+ case 0x23: -+ /* VEXTF */ -+ if (disp5 > 3) break; -+ tcg_gen_mov_i64(cpu_fr[rc], cpu_fr[ra + disp5 * 32]); -+ break; -+ case 0x24: -+ /* VCPYW */ -+ tmp64 = tcg_temp_new(); -+ tmp64_0 = tcg_temp_new(); -+ /* FIXME: for debug -+ tcg_gen_movi_i64(tmp64, ra); -+ gen_helper_v_print(cpu_env, tmp64); -+ */ -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra], 29); -+ tcg_gen_andi_i64(tmp64_0, tmp64, 0x3fffffffUL); -+ tcg_gen_shri_i64(tmp64, cpu_fr[ra], 62); -+ tcg_gen_shli_i64(tmp64, tmp64, 30); -+ tcg_gen_or_i64(tmp64_0, tmp64, tmp64_0); -+ tcg_gen_mov_i64(tmp64, tmp64_0); -+ tcg_gen_shli_i64(tmp64, tmp64, 32); -+ tcg_gen_or_i64(tmp64_0, tmp64_0, tmp64); -+ tcg_gen_mov_i64(cpu_fr[rc], tmp64_0); -+ tcg_gen_mov_i64(cpu_fr[rc + 32], cpu_fr[rc]); -+ tcg_gen_mov_i64(cpu_fr[rc + 64], cpu_fr[rc]); -+ tcg_gen_mov_i64(cpu_fr[rc + 96], cpu_fr[rc]); -+ /* FIXME: for debug -+ tcg_gen_movi_i64(tmp64, rb); -+ gen_helper_v_print(cpu_env, tmp64); -+ tcg_gen_movi_i64(tmp64, rc); -+ gen_helper_v_print(cpu_env, tmp64); -+ */ -+ tcg_temp_free(tmp64); -+ tcg_temp_free(tmp64_0); -+ break; -+ case 0x25: -+ /* VCPYF */ -+ for (i = 0; i < 128; i += 32) { -+ tcg_gen_mov_i64(cpu_fr[rc + i], cpu_fr[ra]); -+ } -+ break; -+ case 0x26: -+ /* VCONW */ -+ tmp64 = tcg_const_i64(ra << 8 | rb); -+ tmp64_0 = tcg_temp_new(); -+ vd = tcg_const_i64(rc); -+ tcg_gen_shri_i64(tmp64_0, cpu_fr[rd], 2); -+ tcg_gen_andi_i64(tmp64_0, tmp64_0, 0x7ul); -+ gen_helper_vconw(cpu_env, tmp64, vd, tmp64_0); -+ tcg_temp_free(tmp64_0); -+ tcg_temp_free(tmp64); -+ tcg_temp_free(vd); -+ break; -+ case 0x27: -+ /* VSHFW */ -+ tmp64 = tcg_const_i64(ra << 8 | rb); -+ vd = tcg_const_i64(rc); -+ gen_helper_vshfw(cpu_env, tmp64, vd, cpu_fr[rd]); -+ tcg_temp_free(tmp64); -+ tcg_temp_free(vd); -+ break; -+ case 0x28: -+ /* VCONS */ -+ tmp64 = tcg_const_i64(ra << 8 | rb); -+ tmp64_0 = tcg_temp_new(); -+ vd = tcg_const_i64(rc); -+ tcg_gen_shri_i64(tmp64_0, cpu_fr[rd], 2); -+ tcg_gen_andi_i64(tmp64_0, tmp64_0, 0x3ul); -+ gen_helper_vcond(cpu_env, tmp64, vd, tmp64_0); -+ tcg_temp_free(tmp64_0); -+ tcg_temp_free(tmp64); -+ tcg_temp_free(vd); -+ break; -+ case 0x29: -+ /* FIXME: VCOND maybe it's wrong in the instruction book -+ * that there are no temp. */ -+ tmp64 = tcg_const_i64(ra << 8 | rb); -+ tmp64_0 = tcg_temp_new(); -+ vd = tcg_const_i64(rc); -+ tcg_gen_shri_i64(tmp64_0, cpu_fr[rd], 3); -+ tcg_gen_andi_i64(tmp64_0, tmp64_0, 0x3ul); -+ gen_helper_vcond(cpu_env, tmp64, vd, tmp64_0); -+ tcg_temp_free(tmp64_0); -+ tcg_temp_free(tmp64); -+ tcg_temp_free(vd); -+ break; -+ default: -+ printf("ILLEGAL BELOW OPC[%x] func[%08x]\n", opc, fn6); -+ ret = gen_invalid(ctx); -+ break; -+ } -+ break; -+ case 0x1C: -+ switch (fn4) { -+ case 0x0: -+ /* VLDW_U */ -+ if (unlikely(ra == 31)) break; -+ gen_load_mem_simd(ctx, &gen_qemu_vldd, ra, rb, disp12, -+ ~0x1fUL); -+ break; -+ case 0x1: -+ /* VSTW_U */ -+ gen_store_mem_simd(ctx, &gen_qemu_vstd, ra, rb, disp12, -+ ~0x1fUL); -+ break; -+ case 0x2: -+ /* VLDS_U */ -+ if (unlikely(ra == 31)) break; -+ gen_load_mem_simd(ctx, &gen_qemu_vlds, ra, rb, disp12, -+ ~0xfUL); -+ break; -+ case 0x3: -+ /* VSTS_U */ -+ gen_store_mem_simd(ctx, &gen_qemu_vsts, ra, rb, disp12, -+ ~0xfUL); -+ break; -+ case 0x4: -+ /* VLDD_U */ -+ if (unlikely(ra == 31)) break; -+ gen_load_mem_simd(ctx, &gen_qemu_vldd, ra, rb, disp12, -+ ~0x1fUL); -+ break; -+ case 0x5: -+ /* VSTD_U */ -+ gen_store_mem_simd(ctx, &gen_qemu_vstd, ra, rb, disp12, -+ ~0x1fUL); -+ break; -+ case 0x8: -+ /* VSTW_UL */ -+ gen_store_mem_simd(ctx, &gen_qemu_vstw_ul, ra, rb, disp12, -+ 0); -+ break; -+ case 0x9: -+ /* VSTW_UH */ -+ gen_store_mem_simd(ctx, &gen_qemu_vstw_uh, ra, rb, disp12, -+ 0); -+ break; -+ case 0xa: -+ /* VSTS_UL */ -+ gen_store_mem_simd(ctx, &gen_qemu_vsts_ul, ra, rb, disp12, -+ 0); -+ break; -+ case 0xb: -+ /* VSTS_UH */ -+ gen_store_mem_simd(ctx, &gen_qemu_vsts_uh, ra, rb, disp12, -+ 0); -+ break; -+ case 0xc: -+ /* VSTD_UL */ -+ gen_store_mem_simd(ctx, &gen_qemu_vstd_ul, ra, rb, disp12, -+ 0); -+ break; -+ case 0xd: -+ /* VSTD_UH */ -+ gen_store_mem_simd(ctx, &gen_qemu_vstd_uh, ra, rb, disp12, -+ 0); -+ break; -+ case 0xe: -+ /* VLDD_NC */ -+ gen_load_mem_simd(ctx, &gen_qemu_vldd, ra, rb, disp12, 0); -+ break; -+ case 0xf: -+ /* VSTD_NC */ -+ gen_store_mem_simd(ctx, &gen_qemu_vstd, ra, rb, disp12, 0); -+ break; -+ default: -+ printf("ILLEGAL BELOW OPC[%x] func[%08x]\n", opc, fn4); -+ ret = gen_invalid(ctx); -+ break; -+ } -+ break; -+ case 0x20: -+ /* LDBU */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0); -+ break; -+ case 0x21: -+ /* LDHU */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0); -+ break; -+ case 0x22: -+ /* LDW */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0); -+ break; -+ case 0x23: -+ /* LDL */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0); -+ break; -+ case 0x24: -+ /* LDL_U */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1); -+ break; -+ case 0x25: -+ /* PRI_LD */ -+#ifndef CONFIG_USER_ONLY -+ if ((insn >> 12) & 1) { -+ gen_load_mem(ctx, &gen_qemu_pri_ldl, ra, rb, disp12, 0, 1); -+ } else { -+ gen_load_mem(ctx, &gen_qemu_pri_ldw, ra, rb, disp12, 0, 1); -+ } -+#endif -+ break; -+ case 0x26: -+ /* FLDS */ -+ gen_load_mem(ctx, &gen_qemu_flds, ra, rb, disp16, 1, 0); -+ break; -+ case 0x27: -+ /* FLDD */ -+ gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0); -+ break; -+ case 0x28: -+ /* STB */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0); -+ break; -+ case 0x29: -+ /* STH */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0); -+ break; -+ case 0x2a: -+ /* STW */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0); -+ break; -+ case 0x2b: -+ /* STL */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0); -+ break; -+ case 0x2c: -+ /* STL_U */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1); -+ break; -+ case 0x2d: -+ /* PRI_ST */ -+#ifndef CONFIG_USER_ONLY -+ if ((insn >> 12) & 1) { -+ gen_store_mem(ctx, &gen_qemu_pri_stl, ra, rb, disp12, 0, 1); -+ } else { -+ gen_store_mem(ctx, &gen_qemu_pri_stw, ra, rb, disp12, 0, 1); -+ } -+#endif -+ break; -+ case 0x2e: -+ /* FSTS */ -+ gen_store_mem(ctx, &gen_qemu_fsts, ra, rb, disp16, 1, 0); -+ break; -+ case 0x2f: -+ /* FSTD */ -+ gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0); -+ break; -+ case 0x30: -+ /* BEQ */ -+ ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, (uint64_t)-1); -+ break; -+ case 0x31: -+ /* BNE */ -+ ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, (uint64_t)-1); -+ break; -+ case 0x32: -+ /* BLT */ -+ ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, (uint64_t)-1); -+ break; -+ case 0x33: -+ /* BLE */ -+ ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, (uint64_t)-1); -+ break; -+ case 0x34: -+ /* BGT */ -+ ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, (uint64_t)-1); -+ break; -+ case 0x35: -+ /* BGE */ -+ ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, (uint64_t)-1); -+ break; -+ case 0x36: -+ /* BLBC */ -+ ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1); -+ break; -+ case 0x37: -+ /* BLBS */ -+ ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1); -+ break; -+ case 0x38: -+ /* FBEQ */ -+ ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21); -+ break; -+ case 0x39: -+ /* FBNE */ -+ ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21); -+ break; -+ case 0x3a: -+ /* FBLT */ -+ ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21); -+ break; -+ case 0x3b: -+ /* FBLE */ -+ ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21); -+ break; -+ case 0x3c: -+ /* FBGT */ -+ ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21); -+ break; -+ case 0x3d: -+ /* FBGE */ -+ ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21); -+ break; -+ case 0x3f: -+ /* LDIH */ -+ disp16 = ((uint32_t)disp16) << 16; -+ if (ra == 31) break; -+ va = load_gir(ctx, ra); -+ if (rb == 31) { -+ tcg_gen_movi_i64(va, disp16); -+ } else { -+ tcg_gen_addi_i64(va, load_gir(ctx, rb), (int64_t)disp16); -+ } -+ break; -+ case 0x3e: -+ /* LDI */ -+ if (ra == 31) break; -+ va = load_gir(ctx, ra); -+ if (rb == 31) { -+ tcg_gen_movi_i64(va, disp16); -+ } else { -+ tcg_gen_addi_i64(va, load_gir(ctx, rb), (int64_t)disp16); -+ } -+ break; -+ do_invalid: -+ default: -+ printf("ILLEGAL BELOW OPC[%x] insn[%08x]\n", opc, insn); -+ ret = gen_invalid(ctx); -+ } -+ return ret; -+} -+static void sw64_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) -+{ -+ DisasContext* ctx = container_of(dcbase, DisasContext, base); -+ CPUSW64State* env = cpu->env_ptr; /*init by instance_initfn*/ -+ -+ ctx->tbflags = ctx->base.tb->flags; -+ ctx->mem_idx = cpu_mmu_index(env, false); -+#ifdef CONFIG_USER_ONLY -+ ctx->ir = cpu_std_ir; -+#else -+ ctx->ir = (ctx->tbflags & ENV_FLAG_HM_MODE ? cpu_hm_ir : cpu_std_ir); -+#endif -+ ctx->zero = NULL; -+} -+ -+static void sw64_tr_tb_start(DisasContextBase *db, CPUState *cpu) -+{ -+} -+ -+static void sw64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) -+{ -+ tcg_gen_insn_start(dcbase->pc_next); -+} -+ -+static void sw64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) -+{ -+ DisasContext *ctx = container_of(dcbase, DisasContext, base); -+ CPUSW64State *env = cpu->env_ptr; -+ uint32_t insn; -+ -+ insn = cpu_ldl_code(env, ctx->base.pc_next & (~3UL)); -+ ctx->env = env; -+ ctx->base.pc_next += 4; -+ ctx->base.is_jmp = ctx->translate_one(dcbase, insn, cpu); -+ -+ free_context_temps(ctx); -+ translator_loop_temp_check(&ctx->base); -+} -+ -+/* FIXME:Linhainan */ -+static void sw64_tr_tb_stop(DisasContextBase* dcbase, CPUState* cpu) { -+ DisasContext* ctx = container_of(dcbase, DisasContext, base); -+ -+ switch (ctx->base.is_jmp) { -+ case DISAS_NORETURN: -+ break; -+ case DISAS_TOO_MANY: -+ if (use_goto_tb(ctx, ctx->base.pc_next)) { -+ tcg_gen_goto_tb(0); -+ tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); -+ tcg_gen_exit_tb(ctx->base.tb, 0); -+ } -+ /* FALLTHRU */ -+ case DISAS_PC_STALE: -+ tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); -+ /* FALLTHRU */ -+ case DISAS_PC_UPDATED: -+ if (!use_exit_tb(ctx)) { -+ tcg_gen_lookup_and_goto_ptr(); -+ break; -+ } -+ /* FALLTHRU */ -+ case DISAS_PC_UPDATED_NOCHAIN: -+ if (ctx->base.singlestep_enabled) { -+ /* FIXME: for gdb*/ -+ cpu_loop_exit(cpu); -+ } else { -+ tcg_gen_exit_tb(NULL, 0); -+ } -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void sw64_tr_disas_log(const DisasContextBase* dcbase, CPUState* cpu) { -+ SW64CPU* sc = SW64_CPU(cpu); -+ qemu_log("IN(%d): %s\n", sc->cid, -+ lookup_symbol(dcbase->pc_first)); -+ log_target_disas(cpu, dcbase->pc_first & (~0x3UL), dcbase->tb->size); -+} -+ -+static void init_transops(CPUState *cpu, DisasContext *dc) -+{ -+ dc->translate_one = translate_one; -+} -+ -+void restore_state_to_opc(CPUSW64State* env, TranslationBlock* tb, -+ target_ulong* data) { -+ env->pc = data[0]; -+} -+ -+static const TranslatorOps sw64_trans_ops = { -+ .init_disas_context = sw64_tr_init_disas_context, -+ .tb_start = sw64_tr_tb_start, -+ .insn_start = sw64_tr_insn_start, -+ .translate_insn = sw64_tr_translate_insn, -+ .tb_stop = sw64_tr_tb_stop, -+ .disas_log = sw64_tr_disas_log, -+}; -+ -+void gen_intermediate_code(CPUState* cpu, TranslationBlock* tb, int max_insns) -+{ -+ DisasContext dc; -+ init_transops(cpu, &dc); -+ translator_loop(&sw64_trans_ops, &dc.base, cpu, tb, max_insns); -+} -diff --git a/target/sw64/translate.h b/target/sw64/translate.h -new file mode 100644 -index 0000000000..e93df0815e ---- /dev/null -+++ b/target/sw64/translate.h -@@ -0,0 +1,60 @@ -+#ifndef SW64_TRANSLATE_H -+#define SW64_TRANSLATE_H -+#include "qemu/osdep.h" -+#include "cpu.h" -+#include "sysemu/cpus.h" -+#include "disas/disas.h" -+#include "qemu/host-utils.h" -+#include "exec/exec-all.h" -+#include "exec/cpu_ldst.h" -+#include "tcg/tcg-op.h" -+#include "exec/helper-proto.h" -+#include "exec/helper-gen.h" -+#include "trace-tcg.h" -+#include "exec/translator.h" -+#include "exec/log.h" -+ -+#define DISAS_PC_UPDATED_NOCHAIN DISAS_TARGET_0 -+#define DISAS_PC_UPDATED DISAS_TARGET_1 -+#define DISAS_PC_STALE DISAS_TARGET_2 -+#define DISAS_PC_UPDATED_T DISAS_TOO_MANY -+ -+typedef struct DisasContext DisasContext; -+struct DisasContext { -+ DisasContextBase base; -+ -+ uint32_t tbflags; -+ -+ /* The set of registers active in the current context. */ -+ TCGv *ir; -+ -+ /* Accel: Temporaries for $31 and $f31 as source and destination. */ -+ TCGv zero; -+ int mem_idx; -+ CPUSW64State *env; -+ DisasJumpType (*translate_one)(DisasContextBase *dcbase, uint32_t insn, -+ CPUState *cpu); -+}; -+ -+extern TCGv cpu_pc; -+extern TCGv cpu_std_ir[31]; -+extern TCGv cpu_fr[128]; -+extern TCGv cpu_lock_addr; -+extern TCGv cpu_lock_flag; -+extern TCGv cpu_lock_success; -+#ifdef SW64_FIXLOCK -+extern TCGv cpu_lock_value; -+#endif -+#ifndef CONFIG_USER_ONLY -+extern TCGv cpu_hm_ir[31]; -+#endif -+ -+DisasJumpType translate_one(DisasContextBase *dcbase, uint32_t insn, -+ CPUState *cpu); -+DisasJumpType th1_translate_one(DisasContextBase *dcbase, uint32_t insn, -+ CPUState *cpu); -+bool use_exit_tb(DisasContext *ctx); -+bool use_goto_tb(DisasContext *ctx, uint64_t dest); -+void insn_profile(DisasContext *ctx, uint32_t insn); -+extern void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src); -+#endif -diff --git a/tcg/sw64/tcg-target-con-set.h b/tcg/sw64/tcg-target-con-set.h -new file mode 100755 -index 0000000000..71fdfdcbef ---- /dev/null -+++ b/tcg/sw64/tcg-target-con-set.h -@@ -0,0 +1,39 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Define SW_64 target-specific constraint sets. -+ * Copyright (c) 2021 Linaro -+ */ -+ -+/* -+ * C_On_Im(...) defines a constraint set with outputs and inputs. -+ * Each operand should be a sequence of constraint letters as defined by -+ * tcg-target-con-str.h; the constraint combination is inclusive or. -+ */ -+C_O0_I1(r) -+C_O0_I2(lZ, l) -+C_O0_I2(r, rA) -+C_O0_I2(rZ, r) -+C_O0_I2(w, r) -+C_O1_I1(r, l) -+C_O1_I1(r, r) -+C_O1_I1(w, r) -+C_O1_I1(w, w) -+C_O1_I1(w, wr) -+C_O1_I2(r, 0, rZ) -+C_O1_I2(r, r, r) -+C_O1_I2(r, r, rA) -+C_O1_I2(r, r, rAL) -+C_O1_I2(r, r, ri) -+C_O1_I2(r, r, rL) -+C_O1_I2(r, rZ, rZ) -+C_O1_I2(w, 0, w) -+C_O1_I2(w, w, w) -+C_O1_I2(w, w, wN) -+C_O1_I2(w, w, wO) -+C_O1_I2(w, w, wZ) -+C_O1_I3(w, w, w, w) -+C_O1_I4(r, r, rA, rZ, rZ) -+C_O2_I4(r, r, rZ, rZ, rA, rMZ) -+C_O1_I4(r, r, rU, rZ, rZ) -+C_O0_I2(r, rU) -+C_O1_I2(r, r, rU) -diff --git a/tcg/sw64/tcg-target-con-str.h b/tcg/sw64/tcg-target-con-str.h -new file mode 100755 -index 0000000000..47edb3837b ---- /dev/null -+++ b/tcg/sw64/tcg-target-con-str.h -@@ -0,0 +1,28 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Define sw_64 target-specific operand constraints. -+ * Copyright (c) 2021 Linaro -+ */ -+ -+/* -+ * Define constraint letters for register sets: -+ * REGS(letter, register_mask) -+ */ -+REGS('r', ALL_GENERAL_REGS) -+REGS('l', ALL_QLDST_REGS) -+REGS('w', ALL_VECTOR_REGS) -+ -+/* -+ * Define constraint letters for constants: -+ * CONST(letter, TCG_CT_CONST_* bit set) -+ */ -+ -+CONST('Z', TCG_CT_CONST_ZERO) -+CONST('A', TCG_CT_CONST_LONG) -+CONST('M', TCG_CT_CONST_MONE) -+CONST('O', TCG_CT_CONST_ORRI) -+CONST('W', TCG_CT_CONST_WORD) -+CONST('L', TCG_CT_CONST_LONG) -+CONST('U', TCG_CT_CONST_U8) -+CONST('S', TCG_CT_CONST_S8) -+ -diff --git a/tcg/sw64/tcg-target.c.inc b/tcg/sw64/tcg-target.c.inc -new file mode 100755 -index 0000000000..982f159e23 ---- /dev/null -+++ b/tcg/sw64/tcg-target.c.inc -@@ -0,0 +1,2109 @@ -+/* -+ * Initial TCG Implementation for sw_64 -+ * -+ */ -+ -+#include "../tcg-pool.c.inc" -+#include "qemu/bitops.h" -+ -+/* We're going to re-use TCGType in setting of the SF bit, which controls -+ the size of the operation performed. If we know the values match, it -+ makes things much cleaner. */ -+QEMU_BUILD_BUG_ON(TCG_TYPE_I32 != 0 || TCG_TYPE_I64 != 1); -+static const tcg_insn_unit *tb_ret_addr; -+ -+#ifdef CONFIG_DEBUG_TCG -+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { -+ "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", -+ "X8", "X9", "X10", "X11", "X12", "X13", "X14", "fp", -+ "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", -+ "X24", "X25", "X26", "X27", "X28", "X29", "Xsp", "X31", -+ -+ "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", -+}; -+#endif /* CONFIG_DEBUG_TCG */ -+ -+static const int tcg_target_reg_alloc_order[] = { -+ /* TCG_REG_X9 qemu saved for AREG0*/ -+ TCG_REG_X10, TCG_REG_X11, TCG_REG_X12, TCG_REG_X13, TCG_REG_X14, -+ -+ TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3, TCG_REG_X4, -+ TCG_REG_X5, TCG_REG_X6, TCG_REG_X7, TCG_REG_X8, -+ -+ TCG_REG_X22, TCG_REG_X23, TCG_REG_X24, /*TCG_REG_X25, TCG_REG_X26, TCG_REG_X27, */ -+ -+ /* TCG_REG_SP=TCG_REG_X15 saved for system*/ -+ TCG_REG_X16, TCG_REG_X17, TCG_REG_X18, TCG_REG_X19, TCG_REG_X20, TCG_REG_X21, TCG_REG_X28, /* TCG_REG_X29, TCG_REG_X30, TCG_REG_X31 */ -+ -+ /* TCG_REG_TMP=TCG_REG_X27 reserved as temporary register */ -+ /* TCG_REG_TMP2=TCG_REG_X25 reserved as temporary register */ -+ /* TCG_REG_RA=TCG_REG_X26 reserved as temporary */ -+ /* TCG_REG_GP=TCG_REG_X29 gp saved for system*/ -+ /* TCG_REG_SP=TCG_REG_X30 sp saved for system*/ -+ /* TCG_REG_ZERO=TCG_REG_X31 zero saved for system*/ -+ -+ TCG_REG_F2, TCG_REG_F3, TCG_REG_F4, TCG_REG_F5, TCG_REG_F6, TCG_REG_F7, TCG_REG_F8, TCG_REG_F9, /* f2-f9 saved registers */ -+ /* TCG_VEC_TMP=TCG_REG_F10, TCG_VEC_TMP2=TCG_REG_F11, are saved as temporary */ -+ TCG_REG_F12, TCG_REG_F13, TCG_REG_F14, TCG_REG_F15, /* f10-f15 temporary registers */ -+ -+ TCG_REG_F22, TCG_REG_F23, TCG_REG_F24, TCG_REG_F25, TCG_REG_F26, TCG_REG_F27, TCG_REG_F28, TCG_REG_F29, TCG_REG_F30, /* f22-f30 temporary registers */ -+ /* TCG_REG_F31, zero saved for system */ -+ -+ TCG_REG_F16, TCG_REG_F17, TCG_REG_F18, TCG_REG_F19, TCG_REG_F20, TCG_REG_F21, /* input args */ -+ -+ TCG_REG_F0, TCG_REG_F1, /*output args */ -+}; -+ -+static const int tcg_target_call_iarg_regs[6] = { -+ TCG_REG_X16, TCG_REG_X17, TCG_REG_X18, TCG_REG_X19, TCG_REG_X20, TCG_REG_X21, -+}; -+static const int tcg_target_call_oarg_regs[1] = { -+ TCG_REG_X0, -+}; -+ -+#define TCG_REG_TMP TCG_REG_X27 -+#define TCG_REG_TMP2 TCG_REG_X25 -+#define TCG_FLOAT_TMP TCG_REG_F10 -+#define TCG_FLOAT_TMP2 TCG_REG_F11 -+ -+#define ALL_GENERAL_REGS 0xffffffffu -+#define ALL_QLDST_REGS ALL_GENERAL_REGS -+#define PUSH_SIZE ((15-9+1+1) * 8) -+#define FRAME_SIZE \ -+ ((PUSH_SIZE \ -+ + TCG_STATIC_CALL_ARGS_SIZE \ -+ + CPU_TEMP_BUF_NLONGS * sizeof(long) \ -+ + TCG_TARGET_STACK_ALIGN - 1) \ -+ & ~(TCG_TARGET_STACK_ALIGN - 1)) -+ -+/* We encode the format of the insn into the beginning of the name, so that -+ we can have the preprocessor help "typecheck" the insn vs the output -+ function. We don't have nice names for the formats, so we use the section -+ number of the architecture reference manual in which the instruction -+ group is described. */ -+#define OPC_OP(x) ((x & 0x3f) << 26) -+#define OPC_FUNC(x) ((x & 0xff) << 5) -+#define OPC_FUNC_COMPLEX(x) ((x & 0xff) << 10) -+typedef enum { -+ OPC_NOP =0X43ff075f, -+ OPC_SYS_CALL =OPC_OP(0x00), -+ OPC_CALL =OPC_OP(0x01), -+ OPC_RET =OPC_OP(0x02), -+ OPC_JMP =OPC_OP(0x03), -+ OPC_BR =OPC_OP(0x04), -+ OPC_BSR =OPC_OP(0x05), -+ OPC_PRI_RET =OPC_OP(0x07), -+ OPC_LDWE =OPC_OP(0x09), -+ OPC_LDSE =OPC_OP(0x0A), -+ OPC_LDDE =OPC_OP(0x0B), -+ OPC_VLDS =OPC_OP(0x0C), -+ OPC_VLDD =OPC_OP(0x0D), -+ OPC_VSTS =OPC_OP(0x0E), -+ OPC_VSTD =OPC_OP(0x0F), -+ -+ OPC_LDBU =OPC_OP(0x20), -+ OPC_LDHU =OPC_OP(0x21), -+ OPC_LDW =OPC_OP(0x22), -+ OPC_LDL =OPC_OP(0x23), -+ OPC_LDL_U =OPC_OP(0x24), -+ OPC_FLDS =OPC_OP(0X26), -+ OPC_PRI_LD =OPC_OP(0x25), -+ OPC_FLDD =OPC_OP(0X27), -+ OPC_STB =OPC_OP(0X28), -+ OPC_STH =OPC_OP(0x29), -+ OPC_STW =OPC_OP(0x2a), -+ OPC_STL =OPC_OP(0x2B), -+ OPC_STL_U =OPC_OP(0x2C), -+ OPC_PRI_ST =OPC_OP(0x2D), -+ OPC_FSTS =OPC_OP(0x2E), -+ OPC_FSTD =OPC_OP(0x2F), -+ -+ OPC_BEQ =OPC_OP(0x30), -+ OPC_BNE =OPC_OP(0x31), -+ OPC_BLT =OPC_OP(0x32), -+ OPC_BLE =OPC_OP(0x33), -+ OPC_BGT =OPC_OP(0x34), -+ OPC_BGE =OPC_OP(0x35), -+ OPC_BLBC =OPC_OP(0x36), -+ OPC_BLBS =OPC_OP(0x37), -+ -+ OPC_FBEQ =OPC_OP(0x38), -+ OPC_FBNE =OPC_OP(0x39), -+ OPC_FBLT =OPC_OP(0x3A), -+ OPC_FBLE =OPC_OP(0x3B), -+ OPC_FBGT =OPC_OP(0x3C), -+ OPC_FBGE =OPC_OP(0x3D), -+ OPC_LDI =OPC_OP(0x3E), -+ OPC_LDIH =OPC_OP(0x3F), -+ -+ OPC_ADDW =(OPC_OP(0x10) | OPC_FUNC(0x0)), -+ OPC_ADDW_I =(OPC_OP(0x12) | OPC_FUNC(0x0)), -+ OPC_SUBW =(OPC_OP(0x10) | OPC_FUNC(0x1)), -+ OPC_SUBW_I =(OPC_OP(0x12) | OPC_FUNC(0x1)), -+ OPC_S4ADDW =(OPC_OP(0x10) | OPC_FUNC(0x02)), -+ OPC_S4ADDW_I =(OPC_OP(0x12) | OPC_FUNC(0x02)), -+ OPC_S4SUBW =(OPC_OP(0x10) | OPC_FUNC(0x03)), -+ OPC_S4SUBW_I =(OPC_OP(0x12) | OPC_FUNC(0x03)), -+ -+ OPC_S8ADDW =(OPC_OP(0x10) | OPC_FUNC(0x04)), -+ OPC_S8ADDW_I =(OPC_OP(0x12) | OPC_FUNC(0x04)), -+ OPC_S8SUBW =(OPC_OP(0x10) | OPC_FUNC(0x05)), -+ OPC_S8SUBW_I =(OPC_OP(0x12) | OPC_FUNC(0x05)), -+ -+ OPC_ADDL =(OPC_OP(0x10) | OPC_FUNC(0x8)), -+ OPC_ADDL_I =(OPC_OP(0x12) | OPC_FUNC(0x8)), -+ OPC_SUBL =(OPC_OP(0x10) | OPC_FUNC(0x9)), -+ OPC_SUBL_I =(OPC_OP(0x12) | OPC_FUNC(0x9)), -+ -+ OPC_S4ADDL =(OPC_OP(0x10) | OPC_FUNC(0xA)), -+ OPC_S4ADDL_I =(OPC_OP(0x12) | OPC_FUNC(0xA)), -+ OPC_S4SUBL =(OPC_OP(0x10) | OPC_FUNC(0xB)), -+ OPC_S4SUBL_I =(OPC_OP(0x12) | OPC_FUNC(0xB)), -+ -+ OPC_S8ADDL =(OPC_OP(0x10) | OPC_FUNC(0xC)), -+ OPC_S8ADDL_I =(OPC_OP(0x12) | OPC_FUNC(0xC)), -+ OPC_S8SUBL =(OPC_OP(0x10) | OPC_FUNC(0xD)), -+ OPC_S8SUBL_I =(OPC_OP(0x12) | OPC_FUNC(0xD)), -+ -+ OPC_MULW =(OPC_OP(0x10) | OPC_FUNC(0x10)), -+ OPC_MULW_I =(OPC_OP(0x12) | OPC_FUNC(0x10)), -+ OPC_MULL =(OPC_OP(0x10) | OPC_FUNC(0x18)), -+ OPC_MULL_I =(OPC_OP(0x12) | OPC_FUNC(0x18)), -+ -+ OPC_UMULH =(OPC_OP(0x10) | OPC_FUNC(0x19)), -+ OPC_UMULH_I =(OPC_OP(0x12) | OPC_FUNC(0x19)), -+ -+ OPC_CTPOP =(OPC_OP(0x10) | OPC_FUNC(0x58)), -+ OPC_CTLZ =(OPC_OP(0x10) | OPC_FUNC(0x59)), -+ OPC_CTTZ =(OPC_OP(0x10) | OPC_FUNC(0x5A)), -+ -+ OPC_ZAP =(OPC_OP(0x10) | OPC_FUNC(0x68)), -+ OPC_ZAP_I =(OPC_OP(0x12) | OPC_FUNC(0x68)), -+ OPC_ZAPNOT =(OPC_OP(0x10) | OPC_FUNC(0x69)), -+ OPC_ZAPNOT_I =(OPC_OP(0x12) | OPC_FUNC(0x69)), -+ -+ OPC_SEXTB =(OPC_OP(0x10) | OPC_FUNC(0x6A)), -+ OPC_SEXTB_I =(OPC_OP(0x12) | OPC_FUNC(0x6A)), -+ OPC_SEXTH =(OPC_OP(0x10) | OPC_FUNC(0x6B)), -+ OPC_SEXTH_I =(OPC_OP(0x12) | OPC_FUNC(0x6B)), -+ -+ OPC_CMPEQ =(OPC_OP(0x10) | OPC_FUNC(0x28)), -+ OPC_CMPEQ_I =(OPC_OP(0x12) | OPC_FUNC(0x28)), -+ -+ OPC_CMPLT =(OPC_OP(0x10) | OPC_FUNC(0x29)), -+ OPC_CMPLT_I =(OPC_OP(0x12) | OPC_FUNC(0x29)), -+ OPC_CMPLE =(OPC_OP(0x10) | OPC_FUNC(0x2A)), -+ OPC_CMPLE_I =(OPC_OP(0x12) | OPC_FUNC(0x2A)), -+ -+ OPC_CMPULT =(OPC_OP(0x10) | OPC_FUNC(0x2B)), -+ OPC_CMPULT_I =(OPC_OP(0x12) | OPC_FUNC(0x2B)), -+ OPC_CMPULE =(OPC_OP(0x10) | OPC_FUNC(0x2C)), -+ OPC_CMPULE_I =(OPC_OP(0x12) | OPC_FUNC(0x2C)), -+ -+ OPC_AND =(OPC_OP(0x10) | OPC_FUNC(0x38)), -+ OPC_BIC =(OPC_OP(0x10) | OPC_FUNC(0x39)), -+ OPC_BIS =(OPC_OP(0x10) | OPC_FUNC(0x3A)), -+ OPC_ORNOT =(OPC_OP(0x10) | OPC_FUNC(0x3B)), -+ OPC_XOR =(OPC_OP(0x10) | OPC_FUNC(0x3C)), -+ OPC_EQV =(OPC_OP(0x10) | OPC_FUNC(0x3D)), -+ -+ OPC_AND_I =(OPC_OP(0x12) | OPC_FUNC(0x38)), -+ OPC_BIC_I =(OPC_OP(0x12) | OPC_FUNC(0x39)), -+ OPC_BIS_I =(OPC_OP(0x12) | OPC_FUNC(0x3A)), -+ OPC_ORNOT_I =(OPC_OP(0x12) | OPC_FUNC(0x3B)), -+ OPC_XOR_I =(OPC_OP(0x12) | OPC_FUNC(0x3C)), -+ OPC_EQV_I =(OPC_OP(0x12) | OPC_FUNC(0x3D)), -+ -+ OPC_SLL =(OPC_OP(0x10) | OPC_FUNC(0x48)), -+ OPC_SRL =(OPC_OP(0x10) | OPC_FUNC(0x49)), -+ OPC_SRA =(OPC_OP(0x10) | OPC_FUNC(0x4A)), -+ OPC_SLL_I =(OPC_OP(0x12) | OPC_FUNC(0x48)), -+ OPC_SRL_I =(OPC_OP(0x12) | OPC_FUNC(0x49)), -+ OPC_SRA_I =(OPC_OP(0x12) | OPC_FUNC(0x4A)), -+ -+ OPC_SELEQ =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x00)), -+ OPC_SELGE =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x01)), -+ OPC_SELGT =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x02)), -+ OPC_SELLE =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x03)), -+ OPC_SELLT =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x04)), -+ OPC_SELNE =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x05)), -+ OPC_SELLBC =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x06)), -+ OPC_SELLBS =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x07)), -+ OPC_SELEQ_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x00)), -+ OPC_SELGE_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x01)), -+ OPC_SELGT_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x02)), -+ OPC_SELLE_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x03)), -+ OPC_SELLT_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x04)), -+ OPC_SELNE_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x05)), -+ OPC_SELLBC_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x06)), -+ OPC_SELLBS_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x07)), -+ -+ OPC_INS0B =(OPC_OP(0x10) | OPC_FUNC(0x40)), -+ OPC_INS1B =(OPC_OP(0x10) | OPC_FUNC(0x41)), -+ OPC_INS2B =(OPC_OP(0x10) | OPC_FUNC(0x42)), -+ OPC_INS3B =(OPC_OP(0x10) | OPC_FUNC(0x43)), -+ OPC_INS4B =(OPC_OP(0x10) | OPC_FUNC(0x44)), -+ OPC_INS5B =(OPC_OP(0x10) | OPC_FUNC(0x45)), -+ OPC_INS6B =(OPC_OP(0x10) | OPC_FUNC(0x46)), -+ OPC_INS7B =(OPC_OP(0x10) | OPC_FUNC(0x47)), -+ OPC_INS0B_I =(OPC_OP(0x12) | OPC_FUNC(0x40)), -+ OPC_INS1B_I =(OPC_OP(0x12) | OPC_FUNC(0x41)), -+ OPC_INS2B_I =(OPC_OP(0x12) | OPC_FUNC(0x42)), -+ OPC_INS3B_I =(OPC_OP(0x12) | OPC_FUNC(0x43)), -+ OPC_INS4B_I =(OPC_OP(0x12) | OPC_FUNC(0x44)), -+ OPC_INS5B_I =(OPC_OP(0x12) | OPC_FUNC(0x45)), -+ OPC_INS6B_I =(OPC_OP(0x12) | OPC_FUNC(0x46)), -+ OPC_INS7B_I =(OPC_OP(0x12) | OPC_FUNC(0x47)), -+ -+ OPC_EXT0B =(OPC_OP(0x10) | OPC_FUNC(0x50)), -+ OPC_EXT1B =(OPC_OP(0x10) | OPC_FUNC(0x51)), -+ OPC_EXT2B =(OPC_OP(0x10) | OPC_FUNC(0x52)), -+ OPC_EXT3B =(OPC_OP(0x10) | OPC_FUNC(0x53)), -+ OPC_EXT4B =(OPC_OP(0x10) | OPC_FUNC(0x54)), -+ OPC_EXT5B =(OPC_OP(0x10) | OPC_FUNC(0x55)), -+ OPC_EXT6B =(OPC_OP(0x10) | OPC_FUNC(0x56)), -+ OPC_EXT7B =(OPC_OP(0x10) | OPC_FUNC(0x57)), -+ OPC_EXT0B_I =(OPC_OP(0x12) | OPC_FUNC(0x50)), -+ OPC_EXT1B_I =(OPC_OP(0x12) | OPC_FUNC(0x51)), -+ OPC_EXT2B_I =(OPC_OP(0x12) | OPC_FUNC(0x52)), -+ OPC_EXT3B_I =(OPC_OP(0x12) | OPC_FUNC(0x53)), -+ OPC_EXT4B_I =(OPC_OP(0x12) | OPC_FUNC(0x54)), -+ OPC_EXT5B_I =(OPC_OP(0x12) | OPC_FUNC(0x55)), -+ OPC_EXT6B_I =(OPC_OP(0x12) | OPC_FUNC(0x56)), -+ OPC_EXT7B_I =(OPC_OP(0x12) | OPC_FUNC(0x57)), -+ -+ OPC_MASK0B =(OPC_OP(0x10) | OPC_FUNC(0x60)), -+ OPC_MASK1B =(OPC_OP(0x10) | OPC_FUNC(0x61)), -+ OPC_MASK2B =(OPC_OP(0x10) | OPC_FUNC(0x62)), -+ OPC_MASK3B =(OPC_OP(0x10) | OPC_FUNC(0x63)), -+ OPC_MASK4B =(OPC_OP(0x10) | OPC_FUNC(0x64)), -+ OPC_MASK5B =(OPC_OP(0x10) | OPC_FUNC(0x65)), -+ OPC_MASK6B =(OPC_OP(0x10) | OPC_FUNC(0x66)), -+ OPC_MASK7B =(OPC_OP(0x10) | OPC_FUNC(0x67)), -+ OPC_MASK0B_I =(OPC_OP(0x12) | OPC_FUNC(0x60)), -+ OPC_MASK1B_I =(OPC_OP(0x12) | OPC_FUNC(0x61)), -+ OPC_MASK2B_I =(OPC_OP(0x12) | OPC_FUNC(0x62)), -+ OPC_MASK3B_I =(OPC_OP(0x12) | OPC_FUNC(0x63)), -+ OPC_MASK4B_I =(OPC_OP(0x12) | OPC_FUNC(0x64)), -+ OPC_MASK5B_I =(OPC_OP(0x12) | OPC_FUNC(0x65)), -+ OPC_MASK6B_I =(OPC_OP(0x12) | OPC_FUNC(0x66)), -+ OPC_MASK7B_I =(OPC_OP(0x12) | OPC_FUNC(0x67)), -+ -+ OPC_CNPGEB =(OPC_OP(0x10) | OPC_FUNC(0x6C)), -+ OPC_CNPGEB_I =(OPC_OP(0x12) | OPC_FUNC(0x6C)), -+ -+ OPC_MEMB =(OPC_OP(0x06) | OPC_FUNC(0x0)), -+ OPC_RTC =(OPC_OP(0x06) | OPC_FUNC(0x20)), -+ -+ /*float insn*/ -+ OPC_RFPCR = (OPC_OP(0x18) | OPC_FUNC(0x50)), -+ OPC_WFPCR = (OPC_OP(0x18) | OPC_FUNC(0x51)), -+ OPC_SETFPEC0 = (OPC_OP(0x18) | OPC_FUNC(0x54)), -+ OPC_SETFPEC1 = (OPC_OP(0x18) | OPC_FUNC(0x55)), -+ OPC_SETFPEC2 = (OPC_OP(0x18) | OPC_FUNC(0x56)), -+ OPC_SETFPEC3 = (OPC_OP(0x18) | OPC_FUNC(0x57)), -+ -+ -+ OPC_IFMOVS = (OPC_OP(0x18) | OPC_FUNC(0x40)), -+ OPC_IFMOVD = (OPC_OP(0x18) | OPC_FUNC(0x41)), -+ OPC_FIMOVS = (OPC_OP(0x10) | OPC_FUNC(0x70)), -+ OPC_FIMOVD = (OPC_OP(0x10) | OPC_FUNC(0x78)), -+ -+ /*translate S--D*/ -+ /*translate S/D--Long*/ -+ OPC_FCVTSD = (OPC_OP(0x18) | OPC_FUNC(0x20)), -+ OPC_FCVTDS = (OPC_OP(0x18) | OPC_FUNC(0x21)), -+ OPC_FCVTDL_G = (OPC_OP(0x18) | OPC_FUNC(0x22)), -+ OPC_FCVTDL_P = (OPC_OP(0x18) | OPC_FUNC(0x23)), -+ OPC_FCVTDL_Z = (OPC_OP(0x18) | OPC_FUNC(0x24)), -+ OPC_FCVTDL_N = (OPC_OP(0x18) | OPC_FUNC(0x25)), -+ OPC_FCVTDL = (OPC_OP(0x18) | OPC_FUNC(0x27)), -+ OPC_FCVTLS = (OPC_OP(0x18) | OPC_FUNC(0x2D)), -+ OPC_FCVTLD = (OPC_OP(0x18) | OPC_FUNC(0x2F)), -+ -+ -+ OPC_FADDS = (OPC_OP(0x18) | OPC_FUNC(0x00)), -+ OPC_FADDD = (OPC_OP(0x18) | OPC_FUNC(0x01)), -+ OPC_FSUBS = (OPC_OP(0x18) | OPC_FUNC(0x02)), -+ OPC_FSUBD = (OPC_OP(0x18) | OPC_FUNC(0x03)), -+ OPC_FMULS = (OPC_OP(0x18) | OPC_FUNC(0x04)), -+ OPC_FMULD = (OPC_OP(0x18) | OPC_FUNC(0x05)), -+ OPC_FDIVS = (OPC_OP(0x18) | OPC_FUNC(0x06)), -+ OPC_FDIVD = (OPC_OP(0x18) | OPC_FUNC(0x07)), -+ OPC_FSQRTS = (OPC_OP(0x18) | OPC_FUNC(0x08)), -+ OPC_FSQRTD = (OPC_OP(0x18) | OPC_FUNC(0x09)), -+}SW_64Insn; -+ -+static void tcg_out_insn_br(TCGContext *s, SW_64Insn insn, TCGReg rd, intptr_t imm64); -+static void tcg_out_insn_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t imm16); -+static void tcg_out_insn_simpleReg(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, TCGReg rm); -+static void tcg_out_insn_simple(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, intptr_t imm64); -+static void tcg_out_insn_simpleImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, intptr_t imm64); -+static void tcg_out_insn_bitImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, unsigned long imm64); -+static void tcg_out_insn_bit(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, unsigned long imm64); -+static void tcg_out_insn_complexReg(TCGContext *s, SW_64Insn insn, TCGReg cond, TCGReg rd, TCGReg rn, TCGReg rm); -+static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,TCGReg a1,TCGReg a2, bool const_b, TCGReg v1, TCGReg v2); -+static bool reloc_pc21(tcg_insn_unit *src_rw, const tcg_insn_unit *target); -+static inline uint32_t tcg_in32(TCGContext *s); -+static void tcg_out_movr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn); -+static void tcg_out_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t offset, bool sign); -+static void tcg_out_cond_cmp(TCGContext *s, TCGCond cond, TCGReg ret, TCGArg a, TCGArg b, bool const_b); -+static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t aimm); -+static inline void tcg_out_extr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm, unsigned int m); -+static inline void tcg_out_rotl_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm); -+static inline void tcg_out_rotr_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm); -+static inline void tcg_out_rotl_Imm(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m); -+static inline void tcg_out_rotr_Imm(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m); -+static void tcg_out_cltz(TCGContext *s, SW_64Insn opc_clz, TCGType ext, TCGReg rd, TCGReg rn, TCGArg b, bool const_b); -+static inline void tcg_out_bswap16u(TCGContext *s, TCGReg rd, TCGReg rn); -+static inline void tcg_out_bswap16s(TCGContext *s, TCGReg rd, TCGReg rn); -+static inline void tcg_out_bswap32u(TCGContext *s, TCGReg rd, TCGReg rn); -+static inline void tcg_out_bswap32s(TCGContext *s, TCGReg rd, TCGReg rn); -+static inline void tcg_out_bswap64(TCGContext *s, TCGReg rd, TCGReg rn); -+static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, MemOpIdx oi); -+static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, MemOpIdx oi, TCGType ext); -+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg arg1, TCGReg arg2); -+static void tcg_out_extract(TCGContext *s, TCGReg rd, TCGReg rn, int pos, int len); -+static void tcg_out_dep(TCGContext *s, TCGReg rd, TCGReg rn, int pos, int len); -+static void tcg_out_mulsh64(TCGContext *s, TCGReg rd, TCGReg rn, TCGReg rm); -+ -+#define tcg_out_insn_jump tcg_out_insn_ldst -+#define tcg_out_insn_bitReg tcg_out_insn_simpleReg -+ -+static void tcg_target_init(TCGContext *s) -+{ -+ tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffffu; -+ tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffffu; -+ tcg_target_available_regs[TCG_TYPE_V64] = 0xffffffff00000000ull; -+ tcg_target_available_regs[TCG_TYPE_V128] = 0xffffffff00000000ull; -+ tcg_target_call_clobber_regs = -1ull; -+ -+ //sw_64 callee saved x9-x15 -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X9); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X10); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X11); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X12); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X13); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X14); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X15); -+ -+ //sw_64 callee saved f2~f9 -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F2); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F3); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F4); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F5); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F6); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F7); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F8); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F9); -+ -+ s->reserved_regs = 0; -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_FP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP); //TCG_REG_X27 -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); //TCG_REG_X25 -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); //TCG_REG_X26 -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_X29); /*sw_64 platform register */ -+ tcg_regset_set_reg(s->reserved_regs, TCG_FLOAT_TMP); /*sw_64 platform register */ -+ tcg_regset_set_reg(s->reserved_regs, TCG_FLOAT_TMP2); /*sw_64 platform register */ -+} -+ -+ -+#ifndef CONFIG_SOFTMMU -+ #define USE_GUEST_BASE guest_base != 0 -+ #define TCG_REG_GUEST_BASE TCG_REG_X14 -+#endif -+ -+ -+#define zeroExt 0 -+#define sigExt 1 -+ -+ -+static void tcg_target_qemu_prologue(TCGContext *s) -+{ -+ TCGReg r; -+ int ofs; -+ -+ /* allocate space for all saved registers */ -+ /* subl $sp,PUSH_SIZE,$sp */ -+ tcg_out_insn_simple(s, OPC_SUBL_I, OPC_SUBL, TCG_REG_SP, TCG_REG_SP, PUSH_SIZE); -+ -+ /* Push (FP, LR) */ -+ /* stl $fp,0($sp) */ -+ tcg_out_insn_ldst(s, OPC_STL, TCG_REG_FP, TCG_REG_SP, 0); -+ /* stl $26,8($sp) */ -+ tcg_out_insn_ldst(s, OPC_STL, TCG_REG_RA, TCG_REG_SP, 8); -+ -+ -+ /* Set up frame pointer for canonical unwinding. */ -+ /* TCG_REG_FP=TCG_REG_SP */ -+ tcg_out_movr(s, TCG_TYPE_I64, TCG_REG_FP, TCG_REG_SP); -+ -+ /* Store callee-preserved regs x9..x14. */ -+ for (r = TCG_REG_X9; r <= TCG_REG_X14; r += 1){ -+ ofs = (r - TCG_REG_X9 + 2) * 8; -+ tcg_out_insn_ldst(s, OPC_STL, r, TCG_REG_SP, ofs); -+ } -+ -+ /* Make stack space for TCG locals. */ -+ /* subl $sp,FRAME_SIZE-PUSH_SIZE,$sp */ -+ tcg_out_insn_simple(s, OPC_SUBL_I, OPC_SUBL, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE - PUSH_SIZE); -+ -+ /* Inform TCG about how to find TCG locals with register, offset, size. */ -+ tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, -+ CPU_TEMP_BUF_NLONGS * sizeof(long)); -+ -+#if !defined(CONFIG_SOFTMMU) -+ if (USE_GUEST_BASE) { -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_GUEST_BASE, guest_base); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_GUEST_BASE); -+ } -+#endif -+ -+ /* TCG_AREG0=tcg_target_call_iarg_regs[0], on sw, we mov $16 to $9 */ -+ tcg_out_mov(s, TCG_TYPE_I64, TCG_AREG0, tcg_target_call_iarg_regs[0]); -+ tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0); -+ -+ /* -+ * Return path for goto_ptr. Set return value to 0, a-la exit_tb, -+ * and fall through to the rest of the epilogue. -+ */ -+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, 0); -+ -+ /* TB epilogue */ -+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr); -+ -+ /* Remove TCG locals stack space. */ -+ /* addl $sp,FRAME_SIZE-PUSH_SIZE,$sp */ -+ tcg_out_insn_simple(s, OPC_ADDL_I, OPC_ADDL, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE - PUSH_SIZE); -+ -+ /* Restore registers x9..x14. */ -+ for (r = TCG_REG_X9; r <= TCG_REG_X14; r += 1) { -+ int ofs = (r - TCG_REG_X9 + 2) * 8; -+ tcg_out_insn_ldst(s, OPC_LDL, r, TCG_REG_SP, ofs); -+ } -+ -+ -+ /* Pop (FP, LR) */ -+ /* ldl $fp,0($sp) */ -+ tcg_out_insn_ldst(s, OPC_LDL, TCG_REG_FP, TCG_REG_SP, 0); -+ /* ldl $26,8($sp) */ -+ tcg_out_insn_ldst(s, OPC_LDL, TCG_REG_RA, TCG_REG_SP, 8); -+ -+ /* restore SP to previous frame. */ -+ /* addl $sp,PUSH_SIZE,$sp */ -+ tcg_out_insn_simple(s, OPC_ADDL_I, OPC_ADDL, TCG_REG_SP, TCG_REG_SP, PUSH_SIZE); -+ -+ tcg_out_insn_jump(s, OPC_RET, TCG_REG_ZERO, TCG_REG_RA, 0); -+} -+ -+static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) -+{ -+ if (ret == arg) { -+ return true; -+ } -+ switch (type) { -+ case TCG_TYPE_I32: -+ case TCG_TYPE_I64: -+ if (ret < 32 && arg < 32) { -+ tcg_out_movr(s, type, ret, arg); -+ break; -+ } else if (ret < 32) { -+ break; -+ } else if (arg < 32) { -+ break; -+ } -+ /* FALLTHRU */ -+ default: -+ g_assert_not_reached(); -+ } -+ return true; -+} -+ -+ -+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) -+{ -+ switch (op) { -+ case INDEX_op_goto_ptr: -+ return C_O0_I1(r); -+ -+ case INDEX_op_ld8u_i32: -+ case INDEX_op_ld8s_i32: -+ case INDEX_op_ld16u_i32: -+ case INDEX_op_ld16s_i32: -+ case INDEX_op_ld_i32: -+ case INDEX_op_ld8u_i64: -+ case INDEX_op_ld8s_i64: -+ case INDEX_op_ld16u_i64: -+ case INDEX_op_ld16s_i64: -+ case INDEX_op_ld32u_i64: -+ case INDEX_op_ld32s_i64: -+ case INDEX_op_ld_i64: -+ case INDEX_op_neg_i32: -+ case INDEX_op_neg_i64: -+ case INDEX_op_not_i32: -+ case INDEX_op_not_i64: -+ case INDEX_op_bswap16_i32: -+ case INDEX_op_bswap32_i32: -+ case INDEX_op_bswap16_i64: -+ case INDEX_op_bswap32_i64: -+ case INDEX_op_bswap64_i64: -+ case INDEX_op_ext8s_i32: -+ case INDEX_op_ext16s_i32: -+ case INDEX_op_ext8u_i32: -+ case INDEX_op_ext16u_i32: -+ case INDEX_op_ext8s_i64: -+ case INDEX_op_ext16s_i64: -+ case INDEX_op_ext32s_i64: -+ case INDEX_op_ext8u_i64: -+ case INDEX_op_ext16u_i64: -+ case INDEX_op_ext32u_i64: -+ case INDEX_op_ext_i32_i64: -+ case INDEX_op_extu_i32_i64: -+ case INDEX_op_extract_i32: -+ case INDEX_op_extract_i64: -+ case INDEX_op_sextract_i32: -+ case INDEX_op_sextract_i64: -+ return C_O1_I1(r, r); -+ -+ case INDEX_op_st8_i32: -+ case INDEX_op_st16_i32: -+ case INDEX_op_st_i32: -+ case INDEX_op_st8_i64: -+ case INDEX_op_st16_i64: -+ case INDEX_op_st32_i64: -+ case INDEX_op_st_i64: -+ return C_O0_I2(rZ, r); -+ -+ case INDEX_op_add_i32: -+ case INDEX_op_add_i64: -+ case INDEX_op_sub_i32: -+ case INDEX_op_sub_i64: -+ return C_O1_I2(r, r, rU);//rA -+ -+ case INDEX_op_setcond_i32: -+ case INDEX_op_setcond_i64: -+ return C_O1_I2(r, r, rU);//compare,rA -+ -+ case INDEX_op_mul_i32: -+ case INDEX_op_mul_i64: -+ case INDEX_op_div_i32: -+ case INDEX_op_div_i64: -+ case INDEX_op_divu_i32: -+ case INDEX_op_divu_i64: -+ case INDEX_op_rem_i32: -+ case INDEX_op_rem_i64: -+ case INDEX_op_remu_i32: -+ case INDEX_op_remu_i64: -+ case INDEX_op_muluh_i64: -+ case INDEX_op_mulsh_i64: -+ return C_O1_I2(r, r, r); -+ -+ case INDEX_op_and_i32: -+ case INDEX_op_and_i64: -+ case INDEX_op_or_i32: -+ case INDEX_op_or_i64: -+ case INDEX_op_xor_i32: -+ case INDEX_op_xor_i64: -+ case INDEX_op_andc_i32: -+ case INDEX_op_andc_i64: -+ case INDEX_op_orc_i32: -+ case INDEX_op_orc_i64: -+ case INDEX_op_eqv_i32: -+ case INDEX_op_eqv_i64: -+ return C_O1_I2(r, r, rU);//rL -+ -+ case INDEX_op_shl_i32: -+ case INDEX_op_shr_i32: -+ case INDEX_op_sar_i32: -+ case INDEX_op_rotl_i32: -+ case INDEX_op_rotr_i32: -+ case INDEX_op_shl_i64: -+ case INDEX_op_shr_i64: -+ case INDEX_op_sar_i64: -+ case INDEX_op_rotl_i64: -+ case INDEX_op_rotr_i64: -+ return C_O1_I2(r, r, ri); -+ -+ case INDEX_op_clz_i32: -+ case INDEX_op_clz_i64: -+ return C_O1_I2(r, r, r); //rAL -+ -+ case INDEX_op_ctz_i32: -+ case INDEX_op_ctz_i64: -+ return C_O1_I2(r, r, r);//rAL -+ -+ case INDEX_op_brcond_i32: -+ case INDEX_op_brcond_i64: -+ return C_O0_I2(r, rU);//rA -+ -+ case INDEX_op_movcond_i32: -+ case INDEX_op_movcond_i64: -+ return C_O1_I4(r, r, rU, rZ, rZ);//rA->rU -+ -+ case INDEX_op_qemu_ld_i32: -+ case INDEX_op_qemu_ld_i64: -+ return C_O1_I1(r, l); -+ -+ case INDEX_op_qemu_st_i32: -+ case INDEX_op_qemu_st_i64: -+ return C_O0_I2(lZ, l); -+ -+ case INDEX_op_deposit_i32: -+ case INDEX_op_deposit_i64: -+ return C_O1_I2(r, 0, rZ); -+ -+ case INDEX_op_extract2_i32: -+ case INDEX_op_extract2_i64: -+ return C_O1_I2(r, rZ, rZ); -+ -+ case INDEX_op_add2_i32: -+ case INDEX_op_add2_i64: -+ case INDEX_op_sub2_i32: -+ case INDEX_op_sub2_i64: -+ return C_O2_I4(r, r, rZ, rZ, rA, rMZ); -+ -+ case INDEX_op_add_vec: -+ case INDEX_op_sub_vec: -+ case INDEX_op_mul_vec: -+ case INDEX_op_xor_vec: -+ case INDEX_op_ssadd_vec: -+ case INDEX_op_sssub_vec: -+ case INDEX_op_usadd_vec: -+ case INDEX_op_ussub_vec: -+ case INDEX_op_smax_vec: -+ case INDEX_op_smin_vec: -+ case INDEX_op_umax_vec: -+ case INDEX_op_umin_vec: -+ case INDEX_op_shlv_vec: -+ case INDEX_op_shrv_vec: -+ case INDEX_op_sarv_vec: -+ return C_O1_I2(w, w, w); -+ case INDEX_op_not_vec: -+ case INDEX_op_neg_vec: -+ case INDEX_op_abs_vec: -+ case INDEX_op_shli_vec: -+ case INDEX_op_shri_vec: -+ case INDEX_op_sari_vec: -+ return C_O1_I1(w, w); -+ case INDEX_op_ld_vec: -+ case INDEX_op_dupm_vec: -+ return C_O1_I1(w, r); -+ case INDEX_op_st_vec: -+ return C_O0_I2(w, r); -+ case INDEX_op_dup_vec: -+ return C_O1_I1(w, wr); -+ case INDEX_op_or_vec: -+ case INDEX_op_andc_vec: -+ return C_O1_I2(w, w, wO); -+ case INDEX_op_and_vec: -+ case INDEX_op_orc_vec: -+ return C_O1_I2(w, w, wN); -+ case INDEX_op_cmp_vec: -+ return C_O1_I2(w, w, wZ); -+ case INDEX_op_bitsel_vec: -+ return C_O1_I3(w, w, w, w); -+ -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+ -+static void tcg_out_nop_fill(tcg_insn_unit *p, int count) -+{ -+ int i; -+ for (i = 0; i < count; ++i) { -+ p[i] = OPC_NOP; -+ } -+} -+ -+/* SW instruction format of syscall -+ * insn = opcode[31,26]:Function[25,0], -+ */ -+ -+/* SW instruction format of br(alias jump) -+ * insn = opcode[31,26]:Rd[25,21]:disp[20,0], -+ */ -+static void tcg_out_insn_br(TCGContext *s, SW_64Insn insn, TCGReg rd, intptr_t imm64) -+{ -+ tcg_debug_assert(imm64 <= 0xfffff && imm64 >= -0x100000); -+ tcg_out32(s, insn | (rd & 0x1f) << 21 | (imm64 & 0x1fffff)); -+} -+ -+ -+/* SW instruction format of (load and store) -+ * insn = opcode[31,26]:rd[25,21]:rn[20,16]:disp[15,0] -+ */ -+static void tcg_out_insn_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t imm16) -+{ -+ tcg_debug_assert(imm16 <= 0x7fff && imm16 >= -0x8000); -+ tcg_out32(s, insn | (rd & 0x1f) << 21 | (rn & 0x1f) << 16 | (imm16 & 0xffff)); -+} -+ -+ -+/* SW instruction format of simple operator for Register -+ * insn = opcode[31,26]:rn(ra)[25,21]:rn(rb)[20,16]:Zeors[15,13]:function[12,5]:rd(rc)[4,0] -+ */ -+static void tcg_out_insn_simpleReg(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, TCGReg rm) -+{ -+ tcg_out32(s, insn | (rn & 0x1f) << 21 | (rm & 0x1f) << 16 | (rd & 0x1f)); -+} -+ -+/* SW instruction format of simple operator for imm -+ * insn = opcode[31,26]:rn(ra)[25,21]:disp[20,13]:function[12,5]:rd(rc)[4,0] -+ */ -+static void tcg_out_insn_simple(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, intptr_t imm64) -+{ -+ if(imm64 <= 0x7f && imm64 >= -0x80) { -+ tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+ } -+ else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, imm64); -+ tcg_out_insn_simpleReg(s, insn_Reg, rd, rn, TCG_REG_TMP); -+ } -+} -+ -+ -+static void tcg_out_insn_simpleImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, intptr_t imm64) -+{ -+ tcg_debug_assert(imm64 <= 0x7f && imm64 >= -0x80); -+ tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+ -+} -+ -+static void tcg_out_insn_bitImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, unsigned long imm64) -+{ -+ tcg_debug_assert(imm64 <= 255); -+ tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+} -+/* sw bit operation: and bis etc */ -+static void tcg_out_insn_bit(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, unsigned long imm64) -+{ -+ if (imm64 <= 255) { -+ tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+ } -+ else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, imm64); -+ tcg_out_insn_bitReg(s, insn_Reg, rd, rn, TCG_REG_TMP); -+ } -+} -+ -+/* SW instruction format of complex operator -+ * insn = opcode[31,26]:rd[25,21]:rn[20,16],function[15,10]:rm[9,5]:rx[4,0] -+ */ -+static void tcg_out_insn_complexReg(TCGContext *s, SW_64Insn insn, TCGReg cond, TCGReg rd, TCGReg rn, TCGReg rm) -+{ -+ tcg_out32(s, insn | (cond & 0x1f) << 21 | (rn & 0x1f) << 16 | (rm & 0x1f) << 5 | (rd & 0x1f)); -+} -+ -+static bool reloc_pc21(tcg_insn_unit *src_rw, const tcg_insn_unit *target) -+{ -+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); -+ ptrdiff_t offset = target - (src_rx + 1) ; -+ -+ if (offset == sextract64(offset, 0, 21)) { -+ /* read instruction, mask away previous PC_REL21 parameter contents, -+ set the proper offset, then write back the instruction. */ -+ *src_rw = deposit32(*src_rw, 0, 21, offset); -+ return true; -+ } -+ return false; -+} -+ -+/* sw*/ -+static bool patch_reloc(tcg_insn_unit *code_ptr, int type, intptr_t value, intptr_t addend) -+{ -+ tcg_debug_assert(addend == 0); -+ switch (type) { -+ case R_SW_64_BRADDR: -+ return reloc_pc21(code_ptr, (const tcg_insn_unit *)value); -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static inline uint32_t tcg_in32(TCGContext *s) -+{ -+ uint32_t v = *(uint32_t *)s->code_ptr; -+ return v; -+} -+ -+/*SW Register to register move using ADDL*/ -+static void tcg_out_movr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn) -+{ -+ tcg_out_insn_simpleReg(s, OPC_BIS, rd, rn, TCG_REG_ZERO); -+ if (ext == TCG_TYPE_I32){ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } -+} -+ -+/*sw -+ *put imm into rd -+ */ -+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, tcg_target_long orig) -+{ -+ long l0, l1, l2=0, l3=0, extra=0; -+ tcg_target_long val = orig; -+ TCGReg rs = TCG_REG_ZERO; -+ -+ if (type == TCG_TYPE_I32) -+ val = (int32_t)val; -+ -+ l0 = (int16_t)val; -+ val = (val - l0) >> 16; -+ l1 = (int16_t)val; -+ -+ if (orig >> 31 == -1 || orig >> 31 == 0) { -+ if (l1 < 0 && orig >= 0) { -+ extra = 0x4000; -+ l1 = (int16_t)(val - 0x4000); -+ } -+ } else { -+ val = (val - l1) >> 16; -+ l2 = (int16_t)val; -+ val = (val - l2) >> 16; -+ l3 = (int16_t)val; -+ -+ if (l3) { -+ tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, l3); -+ rs = rd; -+ } -+ if (l2) { -+ tcg_out_insn_ldst(s, OPC_LDI, rd, rs, l2); -+ rs = rd; -+ } -+ if (l3 || l2) -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, rd, rd, 32); -+ } -+ -+ if (l1) { -+ tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, l1); -+ rs = rd; -+ } -+ -+ if (extra) { -+ tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, extra); -+ rs = rd; -+ } -+ -+ tcg_out_insn_ldst(s, OPC_LDI, rd, rs, l0); -+} -+ -+ -+/*sw -+* memory <=> Reg in (B H W L) bytes -+*/ -+static void tcg_out_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t offset, bool sign) -+{ -+ int16_t lo = offset; -+ if (offset != lo) { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, offset - lo); -+ if (rn != TCG_REG_ZERO) { -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_TMP, TCG_REG_TMP, rn); -+ } -+ tcg_out_insn_ldst(s, insn, rd, TCG_REG_TMP, lo); -+ } -+ else { -+ tcg_out_insn_ldst(s, insn, rd, rn, lo); -+ } -+ -+ switch (insn) { -+ case OPC_LDBU: -+ if (sign) -+ tcg_out_insn_simpleReg(s, OPC_SEXTB, rd, TCG_REG_ZERO, rd); //for micro-op:INDEX_op_ld8s_i32/64,set rd[63,8]=1 -+ break; -+ case OPC_LDHU: -+ if (sign) -+ tcg_out_insn_simpleReg(s, OPC_SEXTH, rd, TCG_REG_ZERO, rd); //for micro-op:INDEX_op_ld16s_i32/64,set rd[63,16]=1 -+ break; -+ case OPC_LDW: -+ if (!sign) -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); //for micro-op:INDEX_op_ld32u_i32/64,set rd[63,32]=0 -+ break; -+ default: -+ break; -+ } -+} -+ -+/* TCG_REG_TMP stores result_of_condition_compare */ -+static void tcg_out_cond_cmp(TCGContext *s, TCGCond cond, TCGReg ret, TCGArg a, TCGArg b, bool const_b) -+{ -+ if (const_b) { -+ switch(cond) { -+ case TCG_COND_ALWAYS: -+ case TCG_COND_NEVER: -+ break; -+ case TCG_COND_EQ: -+ case TCG_COND_NE: -+ tcg_out_insn_simple(s, OPC_CMPEQ_I, OPC_CMPEQ, ret, a, b); -+ break; -+ case TCG_COND_LT: -+ case TCG_COND_GE: -+ tcg_out_insn_simple(s, OPC_CMPLT_I, OPC_CMPLT, ret, a, b); -+ break; -+ case TCG_COND_LE: -+ case TCG_COND_GT: -+ tcg_out_insn_simple(s, OPC_CMPLE_I, OPC_CMPLE, ret, a, b); -+ break; -+ case TCG_COND_LTU: -+ case TCG_COND_GEU: -+ tcg_out_insn_simple(s, OPC_CMPULT_I, OPC_CMPULT, ret, a, b); -+ break; -+ case TCG_COND_LEU: -+ case TCG_COND_GTU: -+ tcg_out_insn_simple(s, OPC_CMPULE_I, OPC_CMPULE, ret, a, b); -+ break; -+ }//cond -+ }//if (const_b) -+ else { -+ switch(cond) { -+ case TCG_COND_ALWAYS: -+ case TCG_COND_NEVER: -+ break; -+ case TCG_COND_EQ: -+ case TCG_COND_NE: -+ tcg_out_insn_simpleReg(s, OPC_CMPEQ, ret, a, b); -+ break; -+ case TCG_COND_LT: -+ case TCG_COND_GE: -+ tcg_out_insn_simpleReg(s, OPC_CMPLT, ret, a, b); -+ break; -+ case TCG_COND_LE: -+ case TCG_COND_GT: -+ tcg_out_insn_simpleReg(s, OPC_CMPLE, ret, a, b); -+ break; -+ case TCG_COND_LTU: -+ case TCG_COND_GEU: -+ tcg_out_insn_simpleReg(s, OPC_CMPULT, ret, a, b); -+ break; -+ case TCG_COND_LEU: -+ case TCG_COND_GTU: -+ tcg_out_insn_simpleReg(s, OPC_CMPULE, ret, a, b); -+ break; -+ }//cond -+ }//else -+ switch(cond) { -+ case TCG_COND_ALWAYS: -+ case TCG_COND_NEVER: -+ case TCG_COND_EQ: -+ case TCG_COND_LT: -+ case TCG_COND_LE: -+ case TCG_COND_LTU: -+ case TCG_COND_LEU: -+ break; -+ case TCG_COND_NE: -+ case TCG_COND_GE: -+ case TCG_COND_GT: -+ case TCG_COND_GEU: -+ case TCG_COND_GTU: -+ tcg_out_insn_bitImm(s, OPC_XOR_I, ret, ret, 0x1); -+ break; -+ } -+} -+ -+/* sw -+ * step1 tcg_out_cmp() ,"eq" and "ne" in the same case with the same insn; -+ * store compare result by TCG_REG_TMP, for step2; -+ * step2: jump address with compare result. in last "switch" section, we diff qe/ne by different case with different insn. -+ */ -+static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond cond, TCGArg a, TCGArg b, bool b_const, TCGLabel *l) -+{ -+ intptr_t offset; -+ bool need_cmp; -+ -+ if (b_const && b == 0 && (cond == TCG_COND_EQ || cond == TCG_COND_NE)) { -+ need_cmp = false; -+ } else { -+ need_cmp = true; -+ tcg_out_cond_cmp(s, cond, TCG_REG_TMP, a, b, b_const); -+ } -+ -+ if (!l->has_value) { -+ tcg_out_reloc(s, s->code_ptr, R_SW_64_BRADDR, l, 0); -+ offset=0; //offset = tcg_in32(s) >> 5; br $31, 0, do not jump here! -+ } else { -+ offset = tcg_pcrel_diff(s, l->u.value_ptr) ; -+ offset = offset >> 2; -+ tcg_debug_assert(offset == sextract64(offset, 0, 21)); -+ } -+ -+ if (need_cmp) { -+ tcg_out_insn_br(s, OPC_BGT, TCG_REG_TMP, offset); //a cond b,jmp -+ } else if (cond == TCG_COND_EQ) { -+ tcg_out_insn_br(s, OPC_BEQ, a, offset); -+ } else { -+ tcg_out_insn_br(s, OPC_BNE, a, offset); -+ } -+} -+ -+/*sw -+ * contact with "tcg-target-con-str.h" -+ */ -+#define TCG_CT_CONST_ZERO 0x100 -+#define TCG_CT_CONST_LONG 0x200 -+#define TCG_CT_CONST_MONE 0x400 -+#define TCG_CT_CONST_ORRI 0x800 -+#define TCG_CT_CONST_WORD 0X1000 -+#define TCG_CT_CONST_U8 0x2000 -+#define TCG_CT_CONST_S8 0X4000 -+ -+#define ALL_GENERAL_REGS 0xffffffffu -+#define ALL_VECTOR_REGS 0xffffffff00000000ull -+ -+ -+#ifdef CONFIG_SOFTMMU -+/*sw #define ALL_QLDST_REGS */ -+#else -+ #define ALL_QLDST_REGS ALL_GENERAL_REGS -+#endif -+ -+/* sw test if a constant matches the constraint */ -+static bool tcg_target_const_match(int64_t val, TCGType type, int ct) -+{ -+ if (ct & TCG_CT_CONST) { -+ return 1; -+ } -+ if (type == TCG_TYPE_I32) { -+ val = (int32_t)val; -+ } -+ if ((ct & TCG_CT_CONST_U8) && 0 <= val && val <= 255) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_LONG)) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_MONE)) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_ORRI)) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_WORD)) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_ZERO) && val == 0) { -+ return 1; -+ } -+ return 0; -+} -+ -+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn, intptr_t ofs) -+{ -+ switch (type) { -+ case TCG_TYPE_I32: -+ tcg_out_ldst(s, OPC_LDW, rd, rn, ofs, sigExt); -+ break; -+ case TCG_TYPE_I64: -+ tcg_out_ldst(s, OPC_LDL, rd, rn, ofs, sigExt); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn, intptr_t ofs) -+{ -+ switch (type) { -+ case TCG_TYPE_I32: -+ tcg_out_insn_ldst(s, OPC_STW, rd, rn, ofs); -+ break; -+ case TCG_TYPE_I64: -+ tcg_out_insn_ldst(s, OPC_STL, rd, rn, ofs); -+ break; -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, TCGReg base, intptr_t ofs) -+{ -+ if (type <= TCG_TYPE_I64 && val == 0) { -+ tcg_out_st(s, type, TCG_REG_ZERO, base, ofs); -+ return true; -+ } -+ return false; -+} -+ -+static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t imm64) -+{ -+ if (imm64 >= 0) { -+ if(0 <=imm64 && imm64 <= 255) { -+ /* we use tcg_out_insn_bitImm because imm64 is between 0~255 */ -+ tcg_out_insn_bitImm(s, OPC_ADDL_I, rd, rn, imm64); -+ }//aimm>0 && aimm == sextract64(aim, 0, 8) -+ else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, imm64); -+ tcg_out_insn_simpleReg(s, OPC_ADDL, rd, rn, TCG_REG_TMP); -+ }//aimm>0 && aimm != sextract64(aim, 0, 8) -+ } else { -+ if(0 < -imm64 && -imm64 <= 255) { -+ /* we use tcg_out_insn_bitImm because -imm64 is between 0~255 */ -+ tcg_out_insn_bitImm(s, OPC_SUBL_I, rd, rn, -imm64); -+ }//aimm<0 && aimm == sextract64(aim, 0, 8) -+ else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, -imm64); -+ tcg_out_insn_simpleReg(s, OPC_SUBL, rd, rn, TCG_REG_TMP); -+ }//aimm<0 && aimm != sextract64(aim, 0, 8) -+ } -+} -+ -+static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target) -+{ -+ ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2; -+ tcg_debug_assert(offset == sextract64(offset, 0, 21)); -+ tcg_out_insn_br(s, OPC_BR, TCG_REG_ZERO, offset); -+} -+ -+static void tcg_out_goto_long(TCGContext *s, const tcg_insn_unit *target) -+{ -+ ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2; -+ if (0 <= offset && offset <= 0x1fffff) { -+ tcg_out_insn_br(s, OPC_BR, TCG_REG_ZERO, offset); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, (intptr_t)target); -+ tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, TCG_REG_TMP, 0); -+ } -+} -+ -+ -+/*sw -+* call subroutine -+*/ -+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target) -+{ -+ ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2; -+ if (offset == sextract64(offset, 0, 21)) { -+ tcg_out_insn_br(s, OPC_BSR, TCG_REG_RA, offset); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, (intptr_t)target); -+ tcg_out_insn_jump(s, OPC_CALL, TCG_REG_RA, TCG_REG_TMP, 0); -+ } -+} -+ -+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx, uintptr_t jmp_rw, uintptr_t addr) -+{ -+ tcg_debug_assert(0); -+ //sw not support -+} -+ -+static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l) -+{ -+ if (!l->has_value) { -+ tcg_out_reloc(s, s->code_ptr, R_SW_64_BRADDR, l, 0); -+ tcg_out_insn_br(s, OPC_BR, TCG_REG_ZERO, 0); -+ } else { -+ tcg_out_goto(s, l->u.value_ptr); -+ } -+} -+ -+/* sw -+ * resut: rd=rn(64,64-m]:rm(64-m,0] -+ * 1: rn(m,0]--->TCG_REG_TMP(64,64-m] -+ * 2: rm(64,64-m]--->rm(64-m,0] -+ * 3: rd=TCG_REG_TMP(64,64-m]:rm(64-m,0] -+ */ -+static inline void tcg_out_extr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm, unsigned int m) -+{ -+ int bits = ext ? 64 : 32; -+ int max = bits - 1; -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP, rn, bits - (m & max)); -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, rm, (m & max)); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+} -+ -+/* sw -+ * loop right shift -+ */ -+static inline void tcg_out_rotr_Imm(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) -+{ -+ int bits = ext ? 64 : 32; -+ int max = bits - 1; -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP, rn, bits - (m & max)); -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, rn, (m & max)); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+} -+ -+/* sw loop right shift -+ */ -+static inline void tcg_out_rotr_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm) -+{ -+ int bits = ext ? 64 : 32; -+ //get TCG_REG_TMP=64-[rm] -+ tcg_out_insn_simpleImm(s, OPC_SUBL_I, TCG_REG_TMP, rm, bits); -+ tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_TMP); -+ -+ tcg_out_insn_bitReg(s, OPC_SLL, TCG_REG_TMP2, rn, TCG_REG_TMP); //get rn right part to TCG_REG_TMP -+ tcg_out_insn_bitReg(s, OPC_SRL, TCG_REG_TMP, rn, rm); //get rn left part to TCG_REG_TMP -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+} -+ -+/* sw -+ * loop left shift -+ */ -+static inline void tcg_out_rotl_Imm(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) -+{ -+ int bits = ext ? 64 : 32; -+ int max = bits - 1; -+ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP, rn, bits -(m & max)); -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP2, rn, (m & max)); //get rn left part to TCG_REG_TMP -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); //get rn right part to left -+} -+ -+ -+/* sw loop left shift -+ */ -+static inline void tcg_out_rotl_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm) -+{ -+ int bits = ext ? 64 : 32; -+ tcg_out_insn_simpleImm(s, OPC_SUBL_I, TCG_REG_TMP, rm, bits); //rm = 64-rm -+ tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_TMP); -+ -+ tcg_out_insn_bitReg(s, OPC_SRL, TCG_REG_TMP2, rn, TCG_REG_TMP); //get rn left part to TCG_REG_TMP -+ tcg_out_insn_bitReg(s, OPC_SLL, TCG_REG_TMP, rn, rm); //get rn right part to left -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+} -+ -+ -+ -+static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_OP_ARGS], const int const_args[TCG_MAX_OP_ARGS]) -+{ -+ /* 99% of the time, we can signal the use of extension registers -+ by looking to see if the opcode handles 64-bit data. */ -+ TCGType ext = (tcg_op_defs[opc].flags & TCG_OPF_64BIT) != 0; -+ /* Hoist the loads of the most common arguments. */ -+ TCGArg a0 = args[0]; -+ TCGArg a1 = args[1]; -+ TCGArg a2 = args[2]; -+ int c2 = const_args[2]; -+ -+ /* Some operands are defined with "rZ" constraint, a register or -+ the zero register. These need not actually test args[I] == 0. */ -+ #define REG0(I) (const_args[I] ? TCG_REG_ZERO : (TCGReg)args[I]) -+ -+ switch (opc) { -+ case INDEX_op_exit_tb: -+ /* Reuse the zeroing that exists for goto_ptr. */ -+ if (a0 == 0) { -+ tcg_out_goto_long(s, tcg_code_gen_epilogue); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0); -+ tcg_out_goto_long(s, tb_ret_addr); -+ } -+ break; -+ -+ case INDEX_op_goto_tb: -+ if (s->tb_jmp_insn_offset != NULL) { -+ /* TCG_TARGET_HAS_direct_jump */ -+ tcg_debug_assert(0); -+ /* not support here */ -+ } else { -+ /* !TCG_TARGET_HAS_direct_jump */ -+ tcg_debug_assert(s->tb_jmp_target_addr != NULL); -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP, TCG_REG_ZERO, (uintptr_t)(s->tb_jmp_target_addr + a0)); -+ } -+ tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, TCG_REG_TMP, 0); -+ set_jmp_reset_offset(s, a0); -+ break; -+ -+ case INDEX_op_goto_ptr: -+ tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, a0, 0); -+ break; -+ -+ case INDEX_op_br: -+ tcg_out_goto_label(s, arg_label(a0)); -+ break; -+ -+ case INDEX_op_ld8u_i32: -+ case INDEX_op_ld8u_i64: -+ tcg_out_ldst(s, OPC_LDBU, a0, a1, a2, 0); -+ break; -+ case INDEX_op_ld8s_i32: -+ case INDEX_op_ld8s_i64: -+ tcg_out_ldst(s, OPC_LDBU, a0, a1, a2, 1); -+ break; -+ case INDEX_op_ld16u_i32: -+ case INDEX_op_ld16u_i64: -+ tcg_out_ldst(s, OPC_LDHU, a0, a1, a2, 0); -+ break; -+ case INDEX_op_ld16s_i32: -+ case INDEX_op_ld16s_i64: -+ tcg_out_ldst(s, OPC_LDHU, a0, a1, a2, 1); -+ break; -+ case INDEX_op_ld_i32: -+ tcg_out_ldst(s, OPC_LDW, a0, a1, a2, 1); -+ break; -+ case INDEX_op_ld32u_i64: -+ tcg_out_ldst(s, OPC_LDW, a0, a1, a2, 0); -+ break; -+ case INDEX_op_ld32s_i64: -+ tcg_out_ldst(s, OPC_LDW, a0, a1, a2, 1); -+ break; -+ case INDEX_op_ld_i64: -+ tcg_out_ldst(s, OPC_LDL, a0, a1, a2, 1); -+ break; -+ case INDEX_op_st8_i32: -+ case INDEX_op_st8_i64: -+ tcg_out_ldst(s, OPC_STB, a0, a1, a2, 0); -+ break; -+ case INDEX_op_st16_i32: -+ case INDEX_op_st16_i64: -+ tcg_out_ldst(s, OPC_STH, a0, a1, a2, 0); -+ break; -+ case INDEX_op_st_i32: -+ case INDEX_op_st32_i64: -+ tcg_out_ldst(s, OPC_STW, a0, a1, a2, 0); -+ break; -+ case INDEX_op_st_i64: -+ tcg_out_ldst(s, OPC_STL, a0, a1, a2, 0); -+ break; -+ -+ case INDEX_op_add_i32: -+ a2 = (int32_t)a2; -+ if (c2) { -+ tcg_out_addsubi(s, ext, a0, a1, a2); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_ADDL, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_add_i64: -+ if (c2) { -+ tcg_out_addsubi(s, ext, a0, a1, a2); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_ADDL, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_sub_i32: -+ a2 = (int32_t)a2; -+ if (c2) { -+ tcg_out_addsubi(s, ext, a0, a1, -a2); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_SUBL, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_sub_i64: -+ if (c2) { -+ tcg_out_addsubi(s, ext, a0, a1, -a2); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_SUBL, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_neg_i64: -+ case INDEX_op_neg_i32: -+ tcg_out_insn_bitReg(s, OPC_SUBL, a0, TCG_REG_ZERO, a1); -+ break; -+ -+ case INDEX_op_and_i32: -+ a2 = (int32_t)a2; -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_AND_I, OPC_AND, a0, a1, a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_AND, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_and_i64: -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_AND_I, OPC_AND, a0, a1, a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_AND, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_andc_i32: -+ a2 = (int32_t)a2; -+ tcg_debug_assert(0); -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_AND_I, OPC_AND, a0, a1, ~a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_BIC, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_andc_i64: -+ tcg_debug_assert(0); -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_AND_I, OPC_AND, a0, a1, ~a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_BIC, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_or_i32: -+ a2 = (int32_t)a2; -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_BIS, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_or_i64: -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_BIS, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_orc_i32: -+ a2 = (int32_t)a2; -+ tcg_debug_assert(0); -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, ~a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_ORNOT, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_orc_i64: -+ tcg_debug_assert(0); -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, ~a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_ORNOT, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_xor_i32: -+ a2 = (int32_t)a2; -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_XOR, a0, a1, a2); -+ } -+ break; -+ case INDEX_op_xor_i64: -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_XOR, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_eqv_i32: -+ a2 = (int32_t)a2; -+ tcg_debug_assert(0); -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, ~a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_EQV, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_eqv_i64: -+ tcg_debug_assert(0); -+ if (c2) { -+ tcg_out_insn_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, ~a2); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_EQV, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_not_i64: -+ case INDEX_op_not_i32: -+ tcg_out_insn_bitReg(s, OPC_ORNOT, a0, TCG_REG_ZERO, a1); -+ break; -+ -+ case INDEX_op_mul_i64: -+ case INDEX_op_mul_i32: -+ tcg_out_insn_simpleReg(s, OPC_MULL, a0, a1, a2); -+ break; -+ -+ case INDEX_op_div_i64: /* a0=a1/a2 singed divide*/ -+ case INDEX_op_div_i32: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_divu_i64: /* a0=a1/a2 unsigned divide */ -+ case INDEX_op_divu_i32: -+ tcg_debug_assert(0); -+ break; -+ -+ case INDEX_op_rem_i64: /* if a1=17,a2=4, 17/4=4...1, a0=1 */ -+ case INDEX_op_rem_i32: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_remu_i64: -+ case INDEX_op_remu_i32: -+ tcg_debug_assert(0); -+ break; -+ -+ case INDEX_op_shl_i64: -+ case INDEX_op_shl_i32: /* sw logical left*/ -+ if (c2) { -+ int bits = ext ? 64 : 32; -+ int max = bits - 1; -+ tcg_out_insn_bitImm(s, OPC_SLL_I, a0, a1, a2&max); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_SLL, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_shr_i64: -+ case INDEX_op_shr_i32: /* sw logical right */ -+ if (c2) { -+ int bits = ext ? 64 : 32; -+ int max = bits - 1; -+ tcg_out_insn_bitImm(s, OPC_SRL_I, a0, a1, a2&max); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_SRL, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_sar_i64: -+ case INDEX_op_sar_i32: /* sw arithmetic right*/ -+ if (c2) { -+ int bits = ext ? 64 : 32; -+ int max = bits - 1; -+ tcg_out_insn_bitImm(s, OPC_SRA_I, a0, a1, a2&max); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_SRA, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_rotr_i64: -+ case INDEX_op_rotr_i32: /* loop shift */ -+ if (c2) {/* loop right shift a2*/ -+ tcg_out_rotr_Imm(s, ext, a0, a1, a2); -+ } else { -+ tcg_out_rotr_Reg(s, ext, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_rotl_i64: -+ case INDEX_op_rotl_i32: /* loop shift */ -+ if (c2) {/* loop left shift a2*/ -+ tcg_out_rotl_Imm(s, ext, a0, a1, a2); -+ } else { -+ tcg_out_rotl_Reg(s, ext, a0, a1, a2); -+ } -+ break; -+ -+ case INDEX_op_clz_i64: /* counting leading zero numbers */ -+ case INDEX_op_clz_i32: -+ tcg_out_cltz(s, OPC_CTLZ, ext, a0, a1, a2, c2); -+ break; -+ case INDEX_op_ctz_i64: /* counting tailing zero numbers */ -+ case INDEX_op_ctz_i32: -+ tcg_out_cltz(s, OPC_CTTZ, ext, a0, a1, a2, c2); -+ break; -+ -+ case INDEX_op_brcond_i32: -+ a1 = (int32_t)a1; -+ tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(args[3])); -+ break; -+ -+ case INDEX_op_brcond_i64: -+ tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(args[3])); -+ break; -+ -+ case INDEX_op_setcond_i32: -+ a2 = (int32_t)a2; -+ tcg_out_setcond(s, args[3], a0, a1, a2); -+ break; -+ -+ case INDEX_op_setcond_i64: -+ tcg_out_setcond(s, args[3], a0, a1, a2); -+ break; -+ -+ case INDEX_op_movcond_i32: -+ a2 = (int32_t)a2; -+ tcg_out_movcond(s, args[5], a0, a1, a2, c2, REG0(3), REG0(4)); -+ break; -+ -+ /* FALLTHRU */ -+ case INDEX_op_movcond_i64: -+ tcg_out_movcond(s, args[5], a0, a1, a2, c2, REG0(3), REG0(4)); -+ break; -+ -+ case INDEX_op_qemu_ld_i32: -+ case INDEX_op_qemu_ld_i64: -+ tcg_out_qemu_ld(s, a0, a1, a2, ext); -+ break; -+ case INDEX_op_qemu_st_i32: -+ case INDEX_op_qemu_st_i64: -+ tcg_out_qemu_st(s, REG0(0), a1, a2); -+ break; -+ -+ case INDEX_op_bswap64_i64: /* 0x123456789abcdef--->0xefcdab8967452301 */ -+ tcg_debug_assert(0); -+ tcg_out_bswap64(s, a0, a1); -+ break; -+ case INDEX_op_bswap32_i64: /* 0x123456789abcdef--->0x67452301efcdab89 */ -+ tcg_debug_assert(0); -+ tcg_out_bswap32u(s, a0, a1); -+ break; -+ case INDEX_op_bswap32_i32: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_bswap16_i64: /* 0x123456789abcdef--->0x23016745ab89efcd */ -+ case INDEX_op_bswap16_i32: -+ tcg_debug_assert(0); -+ break; -+ -+ case INDEX_op_ext8s_i64: -+ case INDEX_op_ext8s_i32: -+ tcg_out_insn_simpleReg(s, OPC_SEXTB, a0, TCG_REG_ZERO, a1); -+ break; -+ case INDEX_op_ext16s_i64: -+ case INDEX_op_ext16s_i32: -+ tcg_out_insn_simpleReg(s, OPC_SEXTH, a0, TCG_REG_ZERO, a1); -+ break; -+ case INDEX_op_ext_i32_i64: -+ case INDEX_op_ext32s_i64: -+ tcg_out_insn_simpleReg(s, OPC_ADDW, a0, TCG_REG_ZERO, a1); -+ break; -+ case INDEX_op_ext8u_i64: -+ case INDEX_op_ext8u_i32: -+ tcg_out_insn_simpleImm(s, OPC_EXT0B_I, a0, a1, 0x0); -+ break; -+ case INDEX_op_ext16u_i64: -+ case INDEX_op_ext16u_i32: -+ tcg_out_insn_simpleImm(s, OPC_EXT1B_I, a0, a1, 0x0); -+ break; -+ case INDEX_op_extu_i32_i64: -+ case INDEX_op_ext32u_i64: -+ tcg_out_movr(s, TCG_TYPE_I32, a0, a1); -+ break; -+ -+ case INDEX_op_deposit_i64: -+ case INDEX_op_deposit_i32: -+ tcg_out_dep(s, a0, a2, args[3], args[4]); -+ break; -+ -+ case INDEX_op_extract_i64: -+ case INDEX_op_extract_i32: -+ tcg_out_extract(s, a0, a1, a2, args[3]); -+ break; -+ -+ case INDEX_op_sextract_i64: -+ case INDEX_op_sextract_i32: -+ tcg_debug_assert(0); -+ break; -+ -+ case INDEX_op_extract2_i64: -+ case INDEX_op_extract2_i32: /* extract REG0(2) right args[3] bit to REG0(1) left ,save to a0*/ -+ tcg_debug_assert(0); -+ break; -+ -+ case INDEX_op_add2_i32: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_add2_i64: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_sub2_i32: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_sub2_i64: -+ tcg_debug_assert(0); -+ break; -+ -+ case INDEX_op_muluh_i64: -+ tcg_out_insn_simpleReg(s, OPC_UMULH, a0, a1, a2); -+ break; -+ case INDEX_op_mulsh_i64: /* sw not support */ -+ tcg_out_mulsh64(s, a0, a1, a2); -+ break; -+ -+ case INDEX_op_mb: -+ break; -+ -+ case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ -+ case INDEX_op_mov_i64: -+ case INDEX_op_call: /* Always emitted via tcg_out_call. */ -+ default: -+ g_assert_not_reached(); -+ } -+ -+#undef REG0 -+} -+ -+ -+ -+/*sw -+* counting heading/tailing zero numbers -+*/ -+static void tcg_out_cltz(TCGContext *s, SW_64Insn opc_clz, TCGType ext, TCGReg rd, -+ TCGReg rn, TCGArg b, bool const_b) -+{ -+ /* cond1. b is a const, and b=64 or b=32 */ -+ if (const_b && b == (ext ? 64 : 32)) { -+ /* count rn zero numbers, and writes to rd */ -+ tcg_out_insn_simpleReg(s, opc_clz, rd, TCG_REG_ZERO, rn); -+ }else { -+ /* TCG_REG_TMP= counting rn heading/tailing zero numbers */ -+ tcg_out_insn_simpleReg(s, opc_clz, TCG_REG_TMP, TCG_REG_ZERO, rn); -+ -+ if (const_b) { -+ if (b == -1) { -+ /* cond2. b is const and b=-1 */ -+ /* if rn != 0 , rd= counting rn heading/tailing zero numbers, else rd = 0xffffffffffffffff*/ -+ tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP2, TCG_REG_ZERO, TCG_REG_ZERO); -+ tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ } -+ else if (b == 0) { -+ /* cond3. b is const and b=0 */ -+ /* if rn != 0 , rd=counting rn heading/tailing zero numbers , else rd = TCG_REG_ZERO */ -+ tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP, TCG_REG_ZERO); -+ } else { -+ /* cond4. b is const */ -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP2, b); -+ /* if rn != 0 , rd=counting rn heading/tailing zero numbers , else mov b to rd */ -+ tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ } -+ } -+ else { -+ /* if b is register */ -+ tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP, b); -+ } -+ } -+} -+ -+/*sw -+ * unsigned 16bit, ab->ba -+ */ -+static inline void tcg_out_bswap16u(TCGContext *s, TCGReg rd, TCGReg rn) -+{ -+ TCGReg TCG_TMP0 = rn; -+ TCGReg TCG_TMP1 = rd; -+ /*t1=00b0*/ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP0, 8); -+ /*t1=(0000)000a*/ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP0, TCG_TMP0, 8); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP0, TCG_TMP0, 0x1); -+ /*t1=ooba*/ -+ tcg_out_insn_simpleReg(s, OPC_BIS, TCG_TMP1, TCG_TMP1, TCG_TMP0); -+} -+ -+/*sw -+ * signed 16bit, ab->ssba -+ */ -+static inline void tcg_out_bswap16s(TCGContext *s, TCGReg rd, TCGReg rn) -+{ -+ TCGReg TCG_TMP0 = rn; -+ TCGReg TCG_TMP1 = TCG_REG_TMP; -+ TCGReg TCG_TMP2 = rn; -+ /*t1=(ssss)ssb0*/ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP0, 8); -+ tcg_out_insn_simpleImm(s, OPC_ZAP_I, TCG_TMP1, TCG_TMP1, 0x2); -+ tcg_out_insn_simpleReg(s, OPC_SEXTH, TCG_TMP1, TCG_REG_ZERO, TCG_TMP1); -+ /*t2=(0000)000a*/ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP2, TCG_TMP0, 8); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP2, TCG_TMP2, 0x1); -+ /*t2=(ssss)ssba*/ -+ tcg_out_insn_simpleReg(s, OPC_BIS, TCG_TMP1, TCG_TMP1, TCG_TMP2); -+} -+ -+ -+/*sw -+ * signed 32bit, abcd -> ssdcba -+ */ -+static inline void tcg_out_bswap32s(TCGContext *s, TCGReg rd, TCGReg rn) -+{ -+ TCGReg TCG_TMP0 = rn; -+ TCGReg TCG_TMP3 = rd; -+ TCGReg TCG_TMP1 = TCG_REG_TMP; -+ TCGReg TCG_TMP2 = TCG_REG_TMP2; -+ /*swap32 -- 32-bit swap. a0 = abcd.*/ -+ -+ /* t3 = (ssss)d000 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP3, TCG_TMP0, 24); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP3, TCG_TMP3, 0x0f); -+ tcg_out_insn_simpleReg(s, OPC_SEXTB, TCG_TMP1, TCG_REG_ZERO, TCG_TMP0); -+ tcg_out_insn_simpleImm(s, OPC_ZAP_I, TCG_TMP1, TCG_TMP1, 0x0f); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ -+ /* t1 = 000a */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 24); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x1); -+ -+ /* t2 = 00c0 */ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP2, TCG_TMP0, 0x2); -+ -+ /* t3 = (ssss)d00a */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ -+ /* t1 = 0abc */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 8); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x7); -+ -+ /* t2 = 0c00 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 8); -+ /* t1 = 00b0 */ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x2); -+ /* t3 = (ssss)dc0a */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -+ /* t3 = (ssss)dcba -- delay slot */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+} -+ -+/*sw -+ * unsigned 32bit, abcd->dcba -+ */ -+static void tcg_out_bswap32u(TCGContext *s, TCGReg rd, TCGReg rn) -+{ -+ TCGReg TCG_TMP0 = rn; -+ TCGReg TCG_TMP3 = rd; -+ TCGReg TCG_TMP1 = TCG_REG_TMP; -+ TCGReg TCG_TMP2 = TCG_REG_TMP2; -+ -+ /*bswap32u -- unsigned 32-bit swap. a0 = ....abcd.*/ -+ /* t1 = (0000)000d */ -+ tcg_out_insn_bitImm(s, OPC_AND_I, TCG_TMP1, TCG_TMP0, 0xff); -+ /* t3 = 000a */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP3, TCG_TMP0, 24); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP3, TCG_TMP3, 0x1); -+ /* t1 = (0000)d000 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP1, 24); -+ /* t2 = 00c0 */ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP2, TCG_TMP0, 0x2); -+ /* t3 = d00a */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ /* t1 = 0abc */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 8); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x7); -+ /* t2 = 0c00 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 8); -+ /* t1 = 00b0 */ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x2); -+ /* t3 = dc0a */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -+ /* t3 = dcba -- delay slot */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+} -+ -+ -+ -+/*sw -+ * swap 64bit, abcdefgh->hgfedcba -+ */ -+static void tcg_out_bswap64(TCGContext *s, TCGReg rd, TCGReg rn) -+{ -+ -+ TCGReg TCG_TMP0 = rn; -+ TCGReg TCG_TMP3 = rd; -+ TCGReg TCG_TMP1 = TCG_REG_TMP; -+ TCGReg TCG_TMP2 = TCG_REG_TMP2; -+ -+ /* bswap64 -- 64-bit swap. a0 = abcdefgh*/ -+ -+ /* t3 = h0000000 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP3, TCG_TMP0, 56); -+ /* t1 = 0000000a */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 56); -+ /* t2 = 000000g0 */ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP2, TCG_TMP0, 0x2); -+ /* t3 = h000000a */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ /* t1 = 00000abc */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 40); -+ /* t2 = 0g000000 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 40); -+ /* t1 = 000000b0 */ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x2); -+ /* t3 = hg00000a */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -+ /* t2 = 0000abcd */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP2, TCG_TMP0, 32); -+ /* t3 = hg0000ba */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ /* t1 = 000000c0 */ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP2, 0x2); -+ /* t2 = 0000000d */ -+ tcg_out_insn_bitImm(s, OPC_AND_I, TCG_TMP2, TCG_TMP2, 0xff); -+ /* t1 = 00000c00 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP1, 8); -+ /* t2 = 0000d000 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 24); -+ /* t3 = hg000cba */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ /* t1 = 00abcdef */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 16); -+ /* t3 = hg00dcba */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -+ /* t2 = 0000000f */ -+ tcg_out_insn_bitImm(s, OPC_AND_I, TCG_TMP2, TCG_TMP1, 0xff); -+ /* t1 = 000000e0 */ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x2); -+ /* t2 = 00f00000 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 40); -+ /* t1 = 000e0000 */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP1, 24); -+ /* t3 = hgf0dcba */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -+ /* t3 = hgfedcba -- delay slot */ -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ -+} -+ -+static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, MemOpIdx oi, TCGType ext) -+{ -+#ifndef CONFIG_SOFTMMU -+ MemOp memop = get_memop(oi); -+ const TCGType otype = TCG_TYPE_I64; -+ -+ if (USE_GUEST_BASE) { -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_GUEST_BASE, TCG_REG_GUEST_BASE, addr_reg); -+ tcg_out_qemu_ld_direct(s, memop, data_reg, TCG_REG_GUEST_BASE, otype, 0); -+ } else { -+ tcg_out_qemu_ld_direct(s, memop, data_reg, addr_reg, TCG_TYPE_I64, 0); -+ } -+#endif /* CONFIG_SOFTMMU */ -+ -+} -+ -+static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, -+ MemOpIdx oi) -+{ -+#ifndef CONFIG_SOFTMMU -+ MemOp memop = get_memop(oi); -+ const TCGType otype = TCG_TYPE_I64; -+ -+ if (USE_GUEST_BASE) { -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_GUEST_BASE, TCG_REG_GUEST_BASE, addr_reg); -+ tcg_out_qemu_st_direct(s, memop, data_reg, TCG_REG_GUEST_BASE, otype, 0); -+ } else { -+ tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, TCG_TYPE_I64, 0); -+ } -+#endif /* CONFIG_SOFTMMU */ -+} -+ -+ -+/*sw -+ * if cond is successful, ret=1, otherwise ret = 0 -+ */ -+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, -+ TCGReg arg1, TCGReg arg2) -+{ -+ switch(cond) { -+ case TCG_COND_EQ: -+ case TCG_COND_LT: -+ case TCG_COND_LE: -+ case TCG_COND_LTU: -+ case TCG_COND_LEU: -+ case TCG_COND_NE: -+ case TCG_COND_GE: -+ case TCG_COND_GT: -+ case TCG_COND_GEU: -+ case TCG_COND_GTU: -+ tcg_out_cond_cmp(s, cond, ret, arg1, arg2, 0); -+ break; -+ default: -+ tcg_abort(); -+ break; -+ } -+} -+/*sw -+ * cond(a1,a2), yes:v1->ret, no:v2->ret -+ */ -+static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret, -+ TCGReg a1, TCGReg a2, bool const_b, TCGReg v1, TCGReg v2) -+{ -+ tcg_out_cond_cmp(s, cond, TCG_REG_TMP, a1, a2, const_b); -+ tcg_out_insn_complexReg(s, OPC_SELLBS, TCG_REG_TMP, ret, v1, v2); -+} -+ -+ -+ -+/*sw -+ * extract rn[lsb, lsb+len-1] -> rd[0, len-1] -+ */ -+static void tcg_out_extract(TCGContext *s, TCGReg rd, TCGReg rn, int lsb, int len) -+{ -+ //get 000..111..0000 -+ tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_ZERO); -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP, TCG_REG_TMP, 64 - len); -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, lsb); -+ /* get rn[lsb, lsb+len-1]-->rd[lsb, lsb+len-1] */ -+ tcg_out_insn_bitReg(s, OPC_AND, rd, rn, TCG_REG_TMP); -+ -+ /* rd[lsb, lsb+len-1] --> rd[0, len-1] */ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, rd, rd, lsb); -+} -+ -+ -+/*sw -+ * depos: rd = rd[63:msb+1]:rn[msb,lsb]:rd[lsb-1,0] -+ * len = msb -lsb + 1 -+ */ -+static void tcg_out_dep(TCGContext *s, TCGReg rd, TCGReg rn, int lsb, int len) -+{ -+ -+ //get 000..111..0000 -+ tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_ZERO); -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP, TCG_REG_TMP, 64 - len); -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, lsb); -+ -+ /* TCG_REG_TMP2 = rn[msb,lsb] */ -+ tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP2, rn, 64-len); -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, TCG_REG_TMP2, 64-len-lsb); -+ -+ /* clear rd[msb,lsb] */ -+ tcg_out_insn_bitReg(s, OPC_BIC, rd, rd, TCG_REG_TMP); -+ /* rd = rd[63:msb+1]:rn[msb,lsb]:rd[lsb-1,0] */ -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, rd, TCG_REG_TMP2); -+} -+ -+/*sw -+ * get val_s64(rn) * val_s64(rm) -> res_128 -+ * res[127:64] -> rd -+ * warn:maybe rd=rn or rm -+ */ -+static void tcg_out_mulsh64(TCGContext *s, TCGReg rd, TCGReg rn, TCGReg rm) -+{ -+ tcg_out_insn_simpleReg(s, OPC_UMULH, TCG_REG_TMP, rn, rm); -+ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, rn, 63); -+ tcg_out_insn_complexReg(s, OPC_SELEQ, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_ZERO, rm); -+ tcg_out_insn_simpleReg(s, OPC_SUBL, TCG_REG_TMP, TCG_REG_TMP, TCG_REG_TMP2); -+ -+ tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, rm, 63); -+ tcg_out_insn_complexReg(s, OPC_SELEQ, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_ZERO, rn); -+ tcg_out_insn_simpleReg(s, OPC_SUBL, rd, TCG_REG_TMP, TCG_REG_TMP2); -+} -+ -+typedef struct { -+ DebugFrameHeader h; -+ uint8_t fde_def_cfa[4]; -+ uint8_t fde_reg_ofs[8 * 2]; -+} DebugFrame; -+ -+#define ELF_HOST_MACHINE EM_SW_64 -+/* GDB doesn't appear to require proper setting of ELF_HOST_FLAGS, -+ which is good because they're really quite complicated for SW_64. */ -+ -+static const DebugFrame debug_frame = { -+ .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */ -+ .h.cie.id = -1, -+ .h.cie.version = 1, -+ .h.cie.code_align = 1, -+ .h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */ -+ .h.cie.return_column = TCG_REG_RA, -+ -+ /* Total FDE size does not include the "len" member. */ -+ .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset), -+ -+ .fde_def_cfa = { -+ 12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */ -+ (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */ -+ (FRAME_SIZE >> 7) -+ }, -+ .fde_reg_ofs = { -+ 0x80 + 14, 1, /* DW_CFA_offset, */ -+ 0x80 + 13, 2, /* DW_CFA_offset, */ -+ 0x80 + 12, 3, /* DW_CFA_offset, */ -+ 0x80 + 11, 4, /* DW_CFA_offset, */ -+ 0x80 + 10, 5, /* DW_CFA_offset, */ -+ 0x80 + 9, 6, /* DW_CFA_offset, */ -+ 0x80 + 26, 7, /* DW_CFA_offset, ra, -24 */ -+ 0x80 + 15, 8, /* DW_CFA_offset, fp, -8 */ -+ } -+}; -+ -+void tcg_register_jit(const void *buf, size_t buf_size) -+{ -+ tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame)); -+} -diff --git a/tcg/sw64/tcg-target.h b/tcg/sw64/tcg-target.h -new file mode 100755 -index 0000000000..3093e4fece ---- /dev/null -+++ b/tcg/sw64/tcg-target.h -@@ -0,0 +1,123 @@ -+/* -+ * Initial TCG Implementation for sw_64 -+ * -+ */ -+ -+#ifndef SW_64_TCG_TARGET_H -+#define SW_64_TCG_TARGET_H -+ -+#define TCG_TARGET_INSN_UNIT_SIZE 4 -+ -+typedef enum { -+ TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3, -+ TCG_REG_X4, TCG_REG_X5, TCG_REG_X6, TCG_REG_X7, -+ TCG_REG_X8, TCG_REG_X9, TCG_REG_X10, TCG_REG_X11, -+ TCG_REG_X12, TCG_REG_X13, TCG_REG_X14, TCG_REG_X15, -+ TCG_REG_X16, TCG_REG_X17, TCG_REG_X18, TCG_REG_X19, -+ TCG_REG_X20, TCG_REG_X21, TCG_REG_X22, TCG_REG_X23, -+ TCG_REG_X24, TCG_REG_X25, TCG_REG_X26, TCG_REG_X27, -+ TCG_REG_X28, TCG_REG_X29, TCG_REG_X30, TCG_REG_X31, -+ -+ TCG_REG_F0=32, TCG_REG_F1, TCG_REG_F2, TCG_REG_F3, -+ TCG_REG_F4, TCG_REG_F5, TCG_REG_F6, TCG_REG_F7, -+ TCG_REG_F8, TCG_REG_F9, TCG_REG_F10, TCG_REG_F11, -+ TCG_REG_F12, TCG_REG_F13, TCG_REG_F14, TCG_REG_F15, -+ TCG_REG_F16, TCG_REG_F17, TCG_REG_F18, TCG_REG_F19, -+ TCG_REG_F20, TCG_REG_F21, TCG_REG_F22, TCG_REG_F23, -+ TCG_REG_F24, TCG_REG_F25, TCG_REG_F26, TCG_REG_F27, -+ TCG_REG_F28, TCG_REG_F29, TCG_REG_F30, TCG_REG_F31, -+ -+ /* Aliases. */ -+ TCG_REG_FP = TCG_REG_X15, -+ TCG_REG_RA = TCG_REG_X26, -+ TCG_REG_GP = TCG_REG_X29, -+ TCG_REG_SP = TCG_REG_X30, -+ TCG_REG_ZERO = TCG_REG_X31, -+ TCG_AREG0 = TCG_REG_X9, -+} TCGReg; -+ -+#define TCG_TARGET_NB_REGS 64 -+#define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1) -+ -+/* used for function call generation */ -+#define TCG_REG_CALL_STACK TCG_REG_SP -+#define TCG_TARGET_STACK_ALIGN 16 -+#define TCG_TARGET_CALL_ALIGN_ARGS 1 /*luo*/ -+#define TCG_TARGET_CALL_STACK_OFFSET 0 /*luo*/ -+#define TCG_TARGET_HAS_neg_i64 1 -+#define TCG_TARGET_HAS_direct_jump 0 -+#define TCG_TARGET_HAS_goto_ptr 1 -+#define TCG_TARGET_HAS_qemu_st8_i32 0 -+#define TCG_TARGET_HAS_not_i32 1 -+#define TCG_TARGET_HAS_neg_i32 1 -+#define TCG_TARGET_HAS_div_i32 1 -+#define TCG_TARGET_HAS_movcond_i32 1 -+#define TCG_TARGET_HAS_rem_i32 0 -+#define TCG_TARGET_HAS_rot_i32 1 -+#define TCG_TARGET_HAS_deposit_i32 1 -+#define TCG_TARGET_HAS_extract_i32 1 -+#define TCG_TARGET_HAS_sextract_i32 0 -+#define TCG_TARGET_HAS_extract2_i32 0 -+#define TCG_TARGET_HAS_add2_i32 0 -+#define TCG_TARGET_HAS_sub2_i32 0 -+#define TCG_TARGET_HAS_sub2_i32 0 -+#define TCG_TARGET_HAS_mulu2_i32 0 -+#define TCG_TARGET_HAS_muluh_i32 0 -+#define TCG_TARGET_HAS_muls2_i32 0 -+#define TCG_TARGET_HAS_not_i32 1 -+#define TCG_TARGET_HAS_mulsh_i32 0 -+#define TCG_TARGET_HAS_ext8s_i32 0 -+#define TCG_TARGET_HAS_ext16s_i32 0 -+#define TCG_TARGET_HAS_ext8u_i32 1 -+#define TCG_TARGET_HAS_ext16u_i32 1 -+#define TCG_TARGET_HAS_bswap16_i32 0 -+#define TCG_TARGET_HAS_bswap32_i32 0 -+#define TCG_TARGET_HAS_andc_i32 0 -+#define TCG_TARGET_HAS_eqv_i32 0 -+#define TCG_TARGET_HAS_nand_i32 0 -+#define TCG_TARGET_HAS_nor_i32 0 -+#define TCG_TARGET_HAS_clz_i32 0 -+#define TCG_TARGET_HAS_ctz_i32 0 -+#define TCG_TARGET_HAS_orc_i32 0 -+#define TCG_TARGET_HAS_ctpop_i32 0 -+#define TCG_TARGET_HAS_movcond_i64 1 -+#define TCG_TARGET_HAS_div_i64 1 -+#define TCG_TARGET_HAS_rem_i64 0 -+#define TCG_TARGET_HAS_div2_i64 0 -+#define TCG_TARGET_HAS_rot_i64 1 -+#define TCG_TARGET_HAS_deposit_i64 1 -+#define TCG_TARGET_HAS_extract_i64 1 -+#define TCG_TARGET_HAS_sextract_i64 0 -+#define TCG_TARGET_HAS_extract2_i64 0 -+#define TCG_TARGET_HAS_extrl_i64_i32 0 -+#define TCG_TARGET_HAS_extrh_i64_i32 0 -+#define TCG_TARGET_HAS_ext8s_i64 0 -+#define TCG_TARGET_HAS_ext16s_i64 0 -+#define TCG_TARGET_HAS_ext32s_i64 1 -+#define TCG_TARGET_HAS_ext8u_i64 1 -+#define TCG_TARGET_HAS_ext16u_i64 1 -+#define TCG_TARGET_HAS_ext32u_i64 1 -+#define TCG_TARGET_HAS_bswap16_i64 0 -+#define TCG_TARGET_HAS_bswap32_i64 0 -+#define TCG_TARGET_HAS_bswap64_i64 0 -+#define TCG_TARGET_HAS_not_i64 1 -+#define TCG_TARGET_HAS_andc_i64 0 -+#define TCG_TARGET_HAS_orc_i64 1 -+#define TCG_TARGET_HAS_eqv_i64 0 -+#define TCG_TARGET_HAS_nand_i64 0 -+#define TCG_TARGET_HAS_nor_i64 0 -+#define TCG_TARGET_HAS_clz_i64 1 -+#define TCG_TARGET_HAS_ctz_i64 1 -+#define TCG_TARGET_HAS_ctpop_i64 0 -+#define TCG_TARGET_HAS_add2_i64 0 -+#define TCG_TARGET_HAS_sub2_i64 0 -+#define TCG_TARGET_HAS_mulu2_i64 0 -+#define TCG_TARGET_HAS_muls2_i64 0 -+#define TCG_TARGET_HAS_muluh_i64 1 -+#define TCG_TARGET_HAS_mulsh_i64 1 -+#define TCG_TARGET_DEFAULT_MO (0) -+#define TCG_TARGET_HAS_MEMORY_BSWAP 0 -+/* optional instructions */ -+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t); -+#define TCG_TARGET_NEED_POOL_LABELS -+#endif /* SW_64_TCG_TARGET_H */ -diff --git a/tcg/sw64/tcg-target.opc.h b/tcg/sw64/tcg-target.opc.h -new file mode 100755 -index 0000000000..bce30accd9 ---- /dev/null -+++ b/tcg/sw64/tcg-target.opc.h -@@ -0,0 +1,15 @@ -+/* -+ * Copyright (c) 2019 Linaro -+ * -+ * This work is licensed under the terms of the GNU GPL, version 2 or -+ * (at your option) any later version. -+ * -+ * See the COPYING file in the top-level directory for details. -+ * -+ * Target-specific opcodes for host vector expansion. These will be -+ * emitted by tcg_expand_vec_op. For those familiar with GCC internals, -+ * consider these to be UNSPEC with names. -+ */ -+ -+DEF(aa64_sshl_vec, 1, 2, 0, IMPLVEC) -+DEF(aa64_sli_vec, 1, 2, 1, IMPLVEC) --- -2.27.0 - diff --git a/sw_64-Added-sw64-architecture-related-updates.patch b/sw_64-Added-sw64-architecture-related-updates.patch deleted file mode 100644 index dd2500908b9f79f15d8826a011992ca7d3e53a6a..0000000000000000000000000000000000000000 --- a/sw_64-Added-sw64-architecture-related-updates.patch +++ /dev/null @@ -1,6108 +0,0 @@ -From 91b0065ca578a6e494b39736f746fcddddfc2978 Mon Sep 17 00:00:00 2001 -From: Lu Feifei -Date: Wed, 26 Jul 2023 14:19:42 +0800 -Subject: [PATCH] sw_64: Added sw64 architecture related updates - -Signed-off-by: Lu Feifei ---- - configs/targets/sw64-linux-user.mak | 5 + - configs/targets/sw64-softmmu.mak | 1 + - disas/sw64.c | 41 +- - gdb-xml/sw64-core.xml | 43 + - hw/rtc/sun4v-rtc.c | 11 - - hw/sw64/Kconfig | 5 +- - hw/sw64/core3.c | 25 +- - hw/sw64/core3_board.c | 73 +- - hw/sw64/sw64_iommu.c | 11 +- - linux-headers/asm-sw64/kvm.h | 14 + - linux-user/elfload.c | 16 + - linux-user/host/sw64/host-signal.h | 46 + - linux-user/host/sw64/hostdep.h | 14 + - linux-user/sw64/cpu_loop.c | 5 +- - linux-user/sw64/meson.build | 5 + - linux-user/sw64/signal.c | 33 +- - linux-user/sw64/syscall.tbl | 488 +++++ - linux-user/sw64/syscallhdr.sh | 32 + - linux-user/sw64/target_cpu.h | 15 +- - linux-user/sw64/target_errno_defs.h | 204 ++ - linux-user/sw64/target_signal.h | 2 + - linux-user/sw64/target_syscall.h | 12 +- - linux-user/sw64/termbits.h | 1 + - linux-user/syscall_defs.h | 46 +- - pc-bios/core3-hmcode | Bin 225904 -> 227168 bytes - pc-bios/core3-reset | Bin 5032 -> 229200 bytes - pc-bios/uefi-bios-sw | Bin 3145728 -> 3145728 bytes - target/sw64/Makefile.objs | 1 + - target/sw64/cpu-param.h | 8 +- - target/sw64/cpu.c | 163 +- - target/sw64/cpu.h | 17 +- - target/sw64/gdbstub.c | 56 + - target/sw64/helper.c | 142 +- - target/sw64/kvm.c | 146 +- - target/sw64/kvm_sw64.h | 9 + - target/sw64/machine.c | 2 +- - target/sw64/meson.build | 1 + - target/sw64/translate.c | 2 +- - tcg/sw64/tcg-target.c.inc | 2839 +++++++++++++++------------ - tcg/sw64/tcg-target.h | 3 + - 40 files changed, 3043 insertions(+), 1494 deletions(-) - create mode 100644 configs/targets/sw64-linux-user.mak - create mode 100644 gdb-xml/sw64-core.xml - create mode 100644 linux-user/host/sw64/host-signal.h - create mode 100755 linux-user/host/sw64/hostdep.h - create mode 100644 linux-user/sw64/meson.build - create mode 100644 linux-user/sw64/syscall.tbl - create mode 100644 linux-user/sw64/syscallhdr.sh - create mode 100644 linux-user/sw64/target_errno_defs.h - mode change 100755 => 100644 pc-bios/core3-hmcode - create mode 100644 target/sw64/gdbstub.c - -diff --git a/configs/targets/sw64-linux-user.mak b/configs/targets/sw64-linux-user.mak -new file mode 100644 -index 0000000000..ae00665692 ---- /dev/null -+++ b/configs/targets/sw64-linux-user.mak -@@ -0,0 +1,5 @@ -+TARGET_ARCH=sw64 -+TARGET_SYSTBL_ABI=common -+TARGET_SYSTBL=syscall.tbl -+TARGET_ALIGNED_ONLY=y -+TARGET_XML_FILES= gdb-xml/sw64-core.xml -diff --git a/configs/targets/sw64-softmmu.mak b/configs/targets/sw64-softmmu.mak -index 37cc2e05a6..9cf002df8c 100644 ---- a/configs/targets/sw64-softmmu.mak -+++ b/configs/targets/sw64-softmmu.mak -@@ -6,3 +6,4 @@ TARGET_ARCH=sw64 - TARGET_BASE_ARCH=sw64 - TARGET_ABI_DIR=sw64 - TARGET_SUPPORTS_MTTCG=y -+TARGET_XML_FILES= gdb-xml/sw64-core.xml -diff --git a/disas/sw64.c b/disas/sw64.c -index c5bd578e07..16504c673a 100755 ---- a/disas/sw64.c -+++ b/disas/sw64.c -@@ -62,7 +62,7 @@ extern const unsigned sw_64_num_opcodes; - #define SW_OPCODE_CORE3 0x0002 /* Core3 private insns. */ - #define SW_LITOP(i) (((i) >> 26) & 0x3D) - --#define SW_OPCODE_NOHM (~(SW_OPCODE_BASE|SW_OPCODE_CORE3)) -+#define SW_OPCODE_NOHMCODE (~(SW_OPCODE_BASE|SW_OPCODE_CORE3)) - - /* A macro to extract the major opcode from an instruction. */ - #define SW_OP(i) (((i) >> 26) & 0x3F) -@@ -328,18 +328,6 @@ static int extract_bdisp(unsigned insn, int *invalid ATTRIBUTE_UNUSED) - return 4 * (((insn & 0x1FFFFF) ^ 0x100000) - 0x100000); - } - --static unsigned insert_bdisp26(unsigned insn, int value, const char **errmsg) --{ -- if (errmsg != (const char **)NULL && (value & 3)) -- *errmsg = "branch operand unaligned"; -- return insn | ((value / 4) & 0x3FFFFFF); --} -- --static int extract_bdisp26(unsigned insn, int *invalid ATTRIBUTE_UNUSED) --{ -- return 4 * (((insn & 0x3FFFFFF) ^ 0x2000000) - 0x2000000); --} -- - /* The hint field of a JMP/JSR insn. */ - /* sw use 16 bits hint disp. */ - static unsigned insert_jhint(unsigned insn, int value, const char **errmsg) -@@ -480,13 +468,9 @@ const struct sw_64_operand sw_64_operands[] = { - { 16, 0, -HWINDEX, SW_OPERAND_UNSIGNED, 0, 0 }, - - /* The 13-bit branch hint for the core3 hw_jmp/jsr (pal1e) insn. */ --#define HWJMPHINT (HWINDEX + 1) -- { 8, 0, -HWJMPHINT, -- SW_OPERAND_RELATIVE | SW_OPERAND_DEFAULT_ZERO | SW_OPERAND_NOOVERFLOW, -- insert_sw4hwjhint, extract_sw4hwjhint }, - - /* for the third operand of ternary operands integer insn. */ --#define R3 (HWJMPHINT + 1) -+#define R3 (HWINDEX + 1) - { 5, 5, 0, SW_OPERAND_IR, 0, 0 }, - /* The plain fp register fields */ - #define F3 (R3 + 1) -@@ -494,19 +478,10 @@ const struct sw_64_operand sw_64_operands[] = { - /* sw simd settle instruction lit */ - #define FMALIT (F3 + 1) - { 5, 5, -FMALIT, SW_OPERAND_UNSIGNED, 0, 0 }, //V1.1 --#define LMDISP (FMALIT + 1) -- { 15, 0, -LMDISP, SW_OPERAND_UNSIGNED, 0, 0 }, --#define RPIINDEX (LMDISP + 1) -+#define RPIINDEX (FMALIT + 1) - { 8, 0, -RPIINDEX, SW_OPERAND_UNSIGNED, 0, 0 }, - #define ATMDISP (RPIINDEX + 1) - { 12, 0, -ATMDISP, SW_OPERAND_SIGNED, 0, 0 }, --#define DISP13 (ATMDISP + 1) -- { 13, 13, -DISP13, SW_OPERAND_SIGNED, 0, 0}, --#define BDISP26 (DISP13 + 1) -- { 26, 0, 222, -- SW_OPERAND_RELATIVE, insert_bdisp26, extract_bdisp26 }, --#define DPFTH (BDISP26 + 1) -- { 5, 21, -DPFTH, SW_OPERAND_UNSIGNED, 0, 0} - }; - - const unsigned sw_64_num_operands = sizeof(sw_64_operands) / sizeof(*sw_64_operands); -@@ -578,7 +553,7 @@ const unsigned sw_64_num_operands = sizeof(sw_64_operands) / sizeof(*sw_64_opera - #define PRIRET_MASK (OP_MASK | 0x100000) - #define PRIRET(oo,h) PRIRET_(oo,h), PRIRET_MASK - --/* sw rpi_rcsr,rpi_wcsr. */ -+/* sw pri_rcsr,pri_wcsr. */ - #define CSR_(oo,ff) (OP(oo) | (((ff) & 0xFF) << 8)) - #define CSR_MASK (OP_MASK | 0xFF00) - #define CSR(oo,ff) CSR_(oo,ff), CSR_MASK -@@ -610,8 +585,6 @@ const unsigned sw_64_num_operands = sizeof(sw_64_operands) / sizeof(*sw_64_opera - #define ARG_FMEM { FA, MDISP, PRB } - #define ARG_OPR { RA, RB, DRC1 } - --#define ARG_OPRCAS { RA, RB, RC } -- - #define ARG_OPRL { RA, LIT, DRC1 } - #define ARG_OPRZ1 { ZA, RB, DRC1 } - #define ARG_OPRLZ1 { ZA, LIT, RC } -@@ -625,9 +598,6 @@ const unsigned sw_64_num_operands = sizeof(sw_64_operands) / sizeof(*sw_64_opera - #define ARG_FMAL { FA,FB,FMALIT, DFC1 } - #define ARG_ATMEM { RA, ATMDISP, PRB } - #define ARG_VUAMEM { FA, ATMDISP, PRB } --#define ARG_OPRLZ3 { RA, LIT, ZC } -- --#define ARG_DISP13 {DISP13, RC} - - /* The opcode table. - -@@ -662,6 +632,7 @@ const struct sw_64_opcode sw_64_opcodes[] = { - { "jmp", MEM(0x03), BASE, { RA, CPRB, JMPHINT } }, - { "br", BRA(0x04), BASE, { ZA, BDISP } }, - { "br", BRA(0x04), BASE, ARG_BRA }, -+ { "bsr", BRA(0x05), BASE, { ZA, BDISP } }, - { "bsr", BRA(0x05), BASE, ARG_BRA }, - { "memb", MFC(0x06,0x0000), BASE, ARG_NONE }, - { "imemb", MFC(0x06,0x0001), BASE, ARG_NONE }, -@@ -1110,7 +1081,7 @@ int print_insn_sw_64(bfd_vma memaddr, struct disassemble_info *info) - regnames = vms_regnames; - else - regnames = osf_regnames; -- isa_mask = SW_OPCODE_NOHM; -+ isa_mask = SW_OPCODE_NOHMCODE; - switch (info->mach) { - case bfd_mach_sw_64_core3: - isa_mask |= SW_OPCODE_BASE | SW_OPCODE_CORE3; -diff --git a/gdb-xml/sw64-core.xml b/gdb-xml/sw64-core.xml -new file mode 100644 -index 0000000000..24527c175b ---- /dev/null -+++ b/gdb-xml/sw64-core.xml -@@ -0,0 +1,43 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff --git a/hw/rtc/sun4v-rtc.c b/hw/rtc/sun4v-rtc.c -index 58a0cff483..e037acd1b5 100644 ---- a/hw/rtc/sun4v-rtc.c -+++ b/hw/rtc/sun4v-rtc.c -@@ -32,17 +32,10 @@ static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr, - unsigned size) - { - uint64_t val = get_clock_realtime() / NANOSECONDS_PER_SECOND; --#if defined(__sw_64__) -- if (addr & 4ULL) { -- /* accessing the high 32 bits */ -- val >>= 32; -- } --#else - if (!(addr & 4ULL)) { - /* accessing the high 32 bits */ - val >>= 32; - } --#endif - trace_sun4v_rtc_read(addr, val); - return val; - } -@@ -56,11 +49,7 @@ static void sun4v_rtc_write(void *opaque, hwaddr addr, - static const MemoryRegionOps sun4v_rtc_ops = { - .read = sun4v_rtc_read, - .write = sun4v_rtc_write, --#if defined(__sw_64__) -- .endianness = DEVICE_LITTLE_ENDIAN, --#else - .endianness = DEVICE_NATIVE_ENDIAN, --#endif - }; - - void sun4v_rtc_init(hwaddr addr) -diff --git a/hw/sw64/Kconfig b/hw/sw64/Kconfig -index 2bf19e8234..0dc49576a5 100644 ---- a/hw/sw64/Kconfig -+++ b/hw/sw64/Kconfig -@@ -7,5 +7,8 @@ config CORE3 - select SUN4V_RTC - select VIRTIO_MMIO - select SERIAL -- select IDE_CMD646 - select VIRTIO_VGA -+ select IDE_CMD646 -+ select ISA_BUS -+ select PCKBD -+ select MSI_NONBROKEN -diff --git a/hw/sw64/core3.c b/hw/sw64/core3.c -index dbe4ed6fa1..eceeb3bec3 100644 ---- a/hw/sw64/core3.c -+++ b/hw/sw64/core3.c -@@ -25,6 +25,10 @@ - #include "core.h" - #include "hw/boards.h" - #include "sysemu/numa.h" -+#include "qemu/uuid.h" -+#include "qemu/bswap.h" -+ -+#define VMUUID 0xFF40 - - static uint64_t cpu_sw64_virt_to_phys(void *opaque, uint64_t addr) - { -@@ -69,6 +73,7 @@ static const CPUArchIdList *sw64_possible_cpu_arch_ids(MachineState *ms) - ms->possible_cpus->cpus[i].vcpus_count = 1; - ms->possible_cpus->cpus[i].arch_id = i; - ms->possible_cpus->cpus[i].props.has_thread_id = true; -+ ms->possible_cpus->cpus[i].props.has_core_id = true; - ms->possible_cpus->cpus[i].props.core_id = i; - } - -@@ -96,6 +101,7 @@ static void core3_init(MachineState *machine) - uint64_t kernel_entry, kernel_low, kernel_high; - BOOT_PARAMS *core3_boot_params = g_new0(BOOT_PARAMS, 1); - uint64_t param_offset; -+ QemuUUID uuid_out_put; - - memset(cpus, 0, sizeof(cpus)); - -@@ -112,6 +118,9 @@ static void core3_init(MachineState *machine) - - rom_add_blob_fixed("ram_size", (char *)&buf, 0x8, 0x2040); - -+ uuid_out_put = qemu_uuid; -+ uuid_out_put = qemu_uuid_bswap(uuid_out_put); -+ pstrcpy_targphys("vm-uuid", VMUUID, 0x12, (char *)&(uuid_out_put)); - param_offset = 0x90B000UL; - core3_boot_params->cmdline = param_offset | 0xfff0000000000000UL; - rom_add_blob_fixed("core3_boot_params", (core3_boot_params), 0x48, 0x90A100); -@@ -137,13 +146,24 @@ static void core3_init(MachineState *machine) - - /* Start all cpus at the hmcode RESET entry point. */ - for (i = 0; i < machine->smp.cpus; ++i) { -- cpus[i]->env.pc = hmcode_entry; -+ if (kvm_enabled()) -+ cpus[i]->env.pc = init_pc; -+ else -+ cpus[i]->env.pc = hmcode_entry; - cpus[i]->env.hm_entry = hmcode_entry; - } - - if (!kernel_filename) { - uefi_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "uefi-bios-sw"); -- load_image_targphys(uefi_filename, 0x2f00000UL, -1); -+ if (uefi_filename == NULL) { -+ error_report("no virtual bios provided"); -+ exit(1); -+ } -+ size = load_image_targphys(uefi_filename, 0x2f00000UL, -1); -+ if (size < 0) { -+ error_report("could not load virtual bios: '%s'", uefi_filename); -+ exit(1); -+ } - g_free(uefi_filename); - } else { - /* Load a kernel. */ -@@ -170,6 +190,7 @@ static void core3_machine_init(MachineClass *mc) - mc->init = core3_init; - mc->block_default_type = IF_IDE; - mc->max_cpus = MAX_CPUS_CORE3; -+ mc->pci_allow_0_address = true; - mc->is_default = 0; - mc->reset = board_reset; - mc->possible_cpu_arch_ids = sw64_possible_cpu_arch_ids; -diff --git a/hw/sw64/core3_board.c b/hw/sw64/core3_board.c -index 7853e01edb..7f623cf773 100644 ---- a/hw/sw64/core3_board.c -+++ b/hw/sw64/core3_board.c -@@ -16,17 +16,27 @@ - #include "hw/ide/ahci.h" - #include "sysemu/numa.h" - #include "sysemu/kvm.h" --#include "hw/rtc/sun4v-rtc.h" -+#include "sysemu/cpus.h" - #include "hw/pci/msi.h" - #include "hw/sw64/sw64_iommu.h" -+#include "hw/loader.h" -+#include "hw/nvram/fw_cfg.h" - - #define TYPE_SWBOARD_PCI_HOST_BRIDGE "core_board-pcihost" - #define SWBOARD_PCI_HOST_BRIDGE(obj) \ - OBJECT_CHECK(BoardState, (obj), TYPE_SWBOARD_PCI_HOST_BRIDGE) - -+#define CORE3_MAX_CPUS_MASK 0x3ff -+#define CORE3_CORES_SHIFT 10 -+#define CORE3_CORES_MASK 0x3ff -+#define CORE3_THREADS_SHIFT 20 -+#define CORE3_THREADS_MASK 0xfff -+ - #define MAX_IDE_BUS 2 - #define SW_PIN_TO_IRQ 16 - -+#define SW_FW_CFG_P_BASE (0x804920000000ULL) -+ - typedef struct SWBoard { - SW64CPU *cpu[MAX_CPUS_CORE3]; - } SWBoard; -@@ -43,6 +53,16 @@ typedef struct TimerState { - int order; - } TimerState; - -+static void sw_create_fw_cfg(hwaddr addr) -+{ -+ MachineState *ms = MACHINE(qdev_get_machine()); -+ uint16_t smp_cpus = ms->smp.cpus; -+ FWCfgState *fw_cfg; -+ fw_cfg = fw_cfg_init_mem_wide(addr + 8, addr, 8, addr + 16, &address_space_memory); -+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, smp_cpus); -+ rom_set_fw(fw_cfg); -+} -+ - #ifndef CONFIG_KVM - static void swboard_alarm_timer(void *opaque) - { -@@ -65,10 +85,13 @@ static PCIINTxRoute sw_route_intx_pin_to_irq(void *opaque, int pin) - - static uint64_t convert_bit(int n) - { -- uint64_t ret = (1UL << n) - 1; -+ uint64_t ret; - - if (n == 64) - ret = 0xffffffffffffffffUL; -+ else -+ ret = (1UL << n) - 1; -+ - return ret; - } - -@@ -76,6 +99,9 @@ static uint64_t mcu_read(void *opaque, hwaddr addr, unsigned size) - { - MachineState *ms = MACHINE(qdev_get_machine()); - unsigned int smp_cpus = ms->smp.cpus; -+ unsigned int smp_threads = ms->smp.threads; -+ unsigned int smp_cores = ms->smp.cores; -+ unsigned int max_cpus = ms->smp.max_cpus; - uint64_t ret = 0; - switch (addr) { - case 0x0000: -@@ -86,6 +112,12 @@ static uint64_t mcu_read(void *opaque, hwaddr addr, unsigned size) - ret |= (1UL << i); - } - break; -+ case 0x0080: -+ /* SMP_INFO */ -+ ret = (smp_threads & CORE3_THREADS_MASK) << CORE3_THREADS_SHIFT; -+ ret += (smp_cores & CORE3_CORES_MASK) << CORE3_CORES_SHIFT; -+ ret += max_cpus & CORE3_MAX_CPUS_MASK; -+ break; - /*IO_START*/ - case 0x1300: - ret = 0x1; -@@ -186,7 +218,7 @@ static void intpu_write(void *opaque, hwaddr addr, uint64_t val, - val &= 0x1f; - cpu = bs->sboard.cpu[val]; - cpu->env.csr[II_REQ] = 0x100000; -- cpu_interrupt(CPU(cpu),CPU_INTERRUPT_IIMAIL); -+ cpu_interrupt(CPU(cpu),CPU_INTERRUPT_II0); - break; - default: - fprintf(stderr, "Unsupported IPU addr: 0x%04lx\n", addr); -@@ -254,6 +286,33 @@ static const MemoryRegionOps msi_ops = { - }, - }; - -+static uint64_t rtc_read(void *opaque, hwaddr addr, unsigned size) -+{ -+ uint64_t val = get_clock_realtime() / NANOSECONDS_PER_SECOND; -+ return val; -+} -+ -+static void rtc_write(void *opaque, hwaddr addr, uint64_t val, -+ unsigned size) -+{ -+} -+ -+static const MemoryRegionOps rtc_ops = { -+ .read = rtc_read, -+ .write = rtc_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+ .valid = -+ { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+ .impl = -+ { -+ .min_access_size = 1, -+ .max_access_size = 8, -+ }, -+}; -+ - static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size) - { - return 1; -@@ -392,7 +451,7 @@ void core3_board_init(SW64CPU *cpus[MAX_CPUS], MemoryRegion *ram) - MemoryRegion *mem_ep64 = g_new(MemoryRegion, 1); - MemoryRegion *conf_piu0 = g_new(MemoryRegion, 1); - MemoryRegion *io_ep = g_new(MemoryRegion, 1); -- -+ MemoryRegion *io_rtc = g_new(MemoryRegion, 1); - MachineState *ms = MACHINE(qdev_get_machine()); - unsigned int smp_cpus = ms->smp.cpus; - -@@ -452,6 +511,10 @@ void core3_board_init(SW64CPU *cpus[MAX_CPUS], MemoryRegion *ram) - "pci0-ep-conf-io", 4 * GB); - memory_region_add_subregion(get_system_memory(), 0x880600000000ULL, - conf_piu0); -+ memory_region_init_io(io_rtc, OBJECT(bs), &rtc_ops, b, -+ "sw64-rtc", 0x08ULL); -+ memory_region_add_subregion(get_system_memory(), 0x804910000000ULL, -+ io_rtc); - #ifdef SW64_VT_IOMMU - sw64_vt_iommu_init(b); - #endif -@@ -476,7 +539,7 @@ void core3_board_init(SW64CPU *cpus[MAX_CPUS], MemoryRegion *ram) - DEVICE_LITTLE_ENDIAN); - } - pci_create_simple(phb->bus, -1, "nec-usb-xhci"); -- sun4v_rtc_init(0x804910000000ULL); -+ sw_create_fw_cfg(SW_FW_CFG_P_BASE); - } - - static const TypeInfo swboard_pcihost_info = { -diff --git a/hw/sw64/sw64_iommu.c b/hw/sw64/sw64_iommu.c -index 8ded65f213..1ede2a2ce4 100644 ---- a/hw/sw64/sw64_iommu.c -+++ b/hw/sw64/sw64_iommu.c -@@ -124,7 +124,7 @@ static int get_pte(dma_addr_t baseaddr, uint64_t *pte) - - /* TODO: guarantee 64-bit single-copy atomicity */ - ret = dma_memory_read(&address_space_memory, baseaddr, -- (uint8_t *)pte, sizeof(*pte)); -+ (uint8_t *)pte, sizeof(*pte), MEMTXATTRS_UNSPECIFIED); - - if (ret != MEMTX_OK) - return -EINVAL; -@@ -195,15 +195,18 @@ static void swvt_ptiotlb_inv_all(SW64IOMMUState *s) - g_hash_table_remove_all(s->ptiotlb); - } - --static void swvt_lookup_ptiotlb(SW64IOMMUState *s, uint16_t source_id, -- hwaddr addr, IOMMUTLBEntry *entry) -+static IOMMUTLBEntry *swvt_lookup_ptiotlb(SW64IOMMUState *s, uint16_t source_id, -+ hwaddr addr) - { - SW64PTIOTLBKey ptkey; -+ IOMMUTLBEntry *entry = NULL; - - ptkey.source_id = source_id; - ptkey.iova = addr; - - entry = g_hash_table_lookup(s->ptiotlb, &ptkey); -+ -+ return entry; - } - - static IOMMUTLBEntry sw64_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr, -@@ -230,7 +233,7 @@ static IOMMUTLBEntry sw64_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr, - - aligned_addr = addr & IOMMU_PAGE_MASK_8K; - -- swvt_lookup_ptiotlb(s, aligned_addr, source_id, cached_entry); -+ cached_entry = swvt_lookup_ptiotlb(s, source_id, aligned_addr); - - if (cached_entry) - goto out; -diff --git a/linux-headers/asm-sw64/kvm.h b/linux-headers/asm-sw64/kvm.h -index b0ce2ca346..5de7014b52 100644 ---- a/linux-headers/asm-sw64/kvm.h -+++ b/linux-headers/asm-sw64/kvm.h -@@ -2,6 +2,9 @@ - #define __LINUX_KVM_SW64_H - - #include -+ -+#define __KVM_HAVE_GUEST_DEBUG -+ - /* - * for KVM_GET_REGS and KVM_SET_REGS - */ -@@ -88,6 +91,16 @@ struct vcpucb { - unsigned long exit_reason; - unsigned long ipaddr; - unsigned long vcpu_irq_vector; -+ unsigned long pri_base; -+ unsigned long stack_pc_dfault; -+ unsigned long guest_p20; -+ unsigned long guest_dfault_double; -+ unsigned long guest_irqs_pending; -+ unsigned long guest_hm_r30; -+ unsigned long migration_mark; -+ unsigned long guest_longtime; -+ unsigned long guest_longtime_offset; -+ unsigned long reserved[3]; - }; - - /* -@@ -100,6 +113,7 @@ struct kvm_fpu { - * KVM SW_64 specific structures and definitions - */ - struct kvm_debug_exit_arch { -+ unsigned long epc; - }; - - /* for KVM_SET_GUEST_DEBUG */ -diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 2625af99dd..e274c0bd33 100644 ---- a/linux-user/elfload.c -+++ b/linux-user/elfload.c -@@ -1549,6 +1549,22 @@ static inline void init_thread(struct target_pt_regs *regs, - - #endif /* TARGET_HPPA */ - -+#ifdef TARGET_SW64 -+ -+#define ELF_CLASS ELFCLASS64 -+#define ELF_ARCH EM_SW64 -+ -+#define ELF_START_MMAP (0x30000000000ULL) -+ -+static inline void init_thread(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+ regs->pc = infop->entry; -+ regs->usp = infop->start_stack; -+} -+ -+#endif /* TARGET_SW64 */ -+ - #ifdef TARGET_XTENSA - - #define ELF_START_MMAP 0x20000000 -diff --git a/linux-user/host/sw64/host-signal.h b/linux-user/host/sw64/host-signal.h -new file mode 100644 -index 0000000000..11d6e97605 ---- /dev/null -+++ b/linux-user/host/sw64/host-signal.h -@@ -0,0 +1,46 @@ -+/* -+ * host-signal.h: signal info dependent on the host architecture -+ * -+ * Copyright (c) 2023 wxiat -+ * -+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. -+ * See the COPYING file in the top-level directory. -+ */ -+ -+#ifndef SW64_HOST_SIGNAL_H -+#define SW64_HOST_SIGNAL_H -+ -+static inline uintptr_t host_signal_pc(ucontext_t *uc) -+{ -+ return uc->uc_mcontext.sc_pc; -+} -+ -+static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc) -+{ -+ uc->uc_mcontext.sc_pc = pc; -+} -+ -+static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) -+{ -+ uint32_t *pc = (uint32_t *)host_signal_pc(uc); -+ uint32_t insn = *pc; -+ -+ /* XXX: need kernel patch to get write flag faster */ -+ switch (insn >> 26) { -+ case 0x0d: /* stw */ -+ case 0x0e: /* stb */ -+ case 0x0f: /* stq_u */ -+ case 0x24: /* stf */ -+ case 0x25: /* stg */ -+ case 0x26: /* sts */ -+ case 0x27: /* stt */ -+ case 0x2c: /* stl */ -+ case 0x2d: /* stq */ -+ case 0x2e: /* stl_c */ -+ case 0x2f: /* stq_c */ -+ return true; -+ } -+ return false; -+} -+ -+#endif -diff --git a/linux-user/host/sw64/hostdep.h b/linux-user/host/sw64/hostdep.h -new file mode 100755 -index 0000000000..b30ac70100 ---- /dev/null -+++ b/linux-user/host/sw64/hostdep.h -@@ -0,0 +1,14 @@ -+/* -+ * hostdep.h : things which are dependent on the host architecture -+ * -+ * * Written by Wang Yuanheng -+ * -+ * Copyright (C) 2023 wxiat -+ * -+ * 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 SW_64_HOSTDEP_H -+#define SW_64_HOSTDEP_H -+#endif -diff --git a/linux-user/sw64/cpu_loop.c b/linux-user/sw64/cpu_loop.c -index 3f2fde0fba..389b753401 100644 ---- a/linux-user/sw64/cpu_loop.c -+++ b/linux-user/sw64/cpu_loop.c -@@ -18,8 +18,11 @@ - */ - - #include "qemu/osdep.h" -+#include "qemu-common.h" - #include "qemu.h" -+#include "user-internals.h" - #include "cpu_loop-common.h" -+#include "signal-common.h" - - void cpu_loop(CPUSW64State *env) - { -@@ -89,7 +92,7 @@ void cpu_loop(CPUSW64State *env) - } - process_pending_signals (env); - -- /* Most of the traps imply a transition through HMcode, which -+ /* Most of the traps imply a transition through hmcode, which - implies an REI instruction has been executed. Which means - that RX and LOCK_ADDR should be cleared. But there are a - few exceptions for traps internal to QEMU. */ -diff --git a/linux-user/sw64/meson.build b/linux-user/sw64/meson.build -new file mode 100644 -index 0000000000..eda0056782 ---- /dev/null -+++ b/linux-user/sw64/meson.build -@@ -0,0 +1,5 @@ -+syscall_nr_generators += { -+ 'sw64': generator(sh, -+ arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ], -+ output: '@BASENAME@_nr.h') -+} -diff --git a/linux-user/sw64/signal.c b/linux-user/sw64/signal.c -index 5822e808d3..572e192a95 100644 ---- a/linux-user/sw64/signal.c -+++ b/linux-user/sw64/signal.c -@@ -18,6 +18,7 @@ - */ - #include "qemu/osdep.h" - #include "qemu.h" -+#include "user-internals.h" - #include "signal-common.h" - #include "linux-user/trace.h" - -@@ -138,8 +139,8 @@ void setup_frame(int sig, struct target_sigaction *ka, - - setup_sigcontext(&frame->sc, env, frame_addr, set); - -- if (ka->sa_restorer) { -- r26 = ka->sa_restorer; -+ if (ka->ka_restorer) { -+ r26 = ka->ka_restorer; - } else { - __put_user(INSN_MOV_R30_R16, &frame->retcode[0]); - __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn, -@@ -192,8 +193,8 @@ void setup_rt_frame(int sig, struct target_sigaction *ka, - __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]); - } - -- if (ka->sa_restorer) { -- r26 = ka->sa_restorer; -+ if (ka->ka_restorer) { -+ r26 = ka->ka_restorer; - } else { - __put_user(INSN_MOV_R30_R16, &frame->retcode[0]); - __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn, -@@ -256,11 +257,7 @@ long do_rt_sigreturn(CPUSW64State *env) - set_sigmask(&set); - - restore_sigcontext(env, &frame->uc.tuc_mcontext); -- if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe, -- uc.tuc_stack), -- 0, env->ir[IDX_SP]) == -EFAULT) { -- goto badframe; -- } -+ target_restore_altstack(&frame->uc.tuc_stack, env); - - unlock_user_struct(frame, frame_addr, 0); - return -TARGET_QEMU_ESIGRETURN; -@@ -271,3 +268,21 @@ badframe: - force_sig(TARGET_SIGSEGV); - return -TARGET_QEMU_ESIGRETURN; - } -+ -+void setup_sigtramp(abi_ulong sigtramp_page) -+{ -+ uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 6 * 4, 0); -+ assert(tramp != NULL); -+ -+ default_sigreturn = sigtramp_page; -+ __put_user(INSN_MOV_R30_R16, &tramp[0]); -+ __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn, &tramp[1]); -+ __put_user(INSN_CALLSYS, &tramp[2]); -+ -+ default_rt_sigreturn = sigtramp_page + 3 * 4; -+ __put_user(INSN_MOV_R30_R16, &tramp[3]); -+ __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn, &tramp[4]); -+ __put_user(INSN_CALLSYS, &tramp[5]); -+ -+ unlock_user(tramp, sigtramp_page, 6 * 4); -+} -diff --git a/linux-user/sw64/syscall.tbl b/linux-user/sw64/syscall.tbl -new file mode 100644 -index 0000000000..d007c7bb07 ---- /dev/null -+++ b/linux-user/sw64/syscall.tbl -@@ -0,0 +1,488 @@ -+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note -+# -+# system call numbers and entry vectors for sw64 -+# -+# The format is: -+# -+# -+# The is always "common" for this file -+# -+0 common osf_syscall sw64_syscall_zero -+1 common exit sys_exit -+2 common fork sw64_fork -+3 common read sys_read -+4 common write sys_write -+5 common osf_old_open sys_ni_syscall -+6 common close sys_close -+7 common osf_wait4 sys_osf_wait4 -+8 common osf_old_creat sys_ni_syscall -+9 common link sys_link -+10 common unlink sys_unlink -+11 common osf_execve sys_ni_syscall -+12 common chdir sys_chdir -+13 common fchdir sys_fchdir -+14 common mknod sys_mknod -+15 common chmod sys_chmod -+16 common chown sys_chown -+17 common brk sys_osf_brk -+18 common osf_getfsstat sys_ni_syscall -+19 common lseek sys_lseek -+20 common getxpid sys_getxpid -+21 common osf_mount sys_osf_mount -+22 common umount2 sys_umount -+23 common setuid sys_setuid -+24 common getxuid sys_getxuid -+25 common exec_with_loader sys_ni_syscall -+26 common ptrace sys_ptrace -+27 common osf_nrecvmsg sys_ni_syscall -+28 common osf_nsendmsg sys_ni_syscall -+29 common osf_nrecvfrom sys_ni_syscall -+30 common osf_naccept sys_ni_syscall -+31 common osf_ngetpeername sys_ni_syscall -+32 common osf_ngetsockname sys_ni_syscall -+33 common access sys_access -+34 common osf_chflags sys_ni_syscall -+35 common osf_fchflags sys_ni_syscall -+36 common sync sys_sync -+37 common kill sys_kill -+38 common osf_old_stat sys_ni_syscall -+39 common setpgid sys_setpgid -+40 common osf_old_lstat sys_ni_syscall -+41 common dup sys_dup -+42 common pipe sys_sw64_pipe -+43 common osf_set_program_attributes sys_osf_set_program_attributes -+44 common osf_profil sys_ni_syscall -+45 common open sys_open -+46 common osf_old_sigaction sys_ni_syscall -+47 common getxgid sys_getxgid -+48 common osf_sigprocmask sys_osf_sigprocmask -+49 common osf_getlogin sys_ni_syscall -+50 common osf_setlogin sys_ni_syscall -+51 common acct sys_acct -+52 common sigpending sys_sigpending -+54 common ioctl sys_ioctl -+55 common osf_reboot sys_ni_syscall -+56 common osf_revoke sys_ni_syscall -+57 common symlink sys_symlink -+58 common readlink sys_readlink -+59 common execve sys_execve -+60 common umask sys_umask -+61 common chroot sys_chroot -+62 common osf_old_fstat sys_ni_syscall -+63 common getpgrp sys_getpgrp -+64 common getpagesize sys_getpagesize -+65 common osf_mremap sys_ni_syscall -+66 common vfork sw64_vfork -+67 common stat sys_newstat -+68 common lstat sys_newlstat -+69 common osf_sbrk sys_ni_syscall -+70 common osf_sstk sys_ni_syscall -+71 common mmap sys_osf_mmap -+72 common osf_old_vadvise sys_ni_syscall -+73 common munmap sys_munmap -+74 common mprotect sys_mprotect -+75 common madvise sys_madvise -+76 common vhangup sys_vhangup -+77 common osf_kmodcall sys_ni_syscall -+78 common osf_mincore sys_ni_syscall -+79 common getgroups sys_getgroups -+80 common setgroups sys_setgroups -+81 common osf_old_getpgrp sys_ni_syscall -+82 common setpgrp sys_setpgid -+83 common osf_setitimer compat_sys_setitimer -+84 common osf_old_wait sys_ni_syscall -+85 common osf_table sys_ni_syscall -+86 common osf_getitimer compat_sys_getitimer -+87 common gethostname sys_gethostname -+88 common sethostname sys_sethostname -+89 common getdtablesize sys_getdtablesize -+90 common dup2 sys_dup2 -+91 common fstat sys_newfstat -+92 common fcntl sys_fcntl -+93 common osf_select sys_osf_select -+94 common poll sys_poll -+95 common fsync sys_fsync -+96 common setpriority sys_setpriority -+97 common socket sys_socket -+98 common connect sys_connect -+99 common accept sys_accept -+100 common getpriority sys_osf_getpriority -+101 common send sys_send -+102 common recv sys_recv -+103 common sigreturn sys_sigreturn -+104 common bind sys_bind -+105 common setsockopt sys_setsockopt -+106 common listen sys_listen -+107 common osf_plock sys_ni_syscall -+108 common osf_old_sigvec sys_ni_syscall -+109 common osf_old_sigblock sys_ni_syscall -+110 common osf_old_sigsetmask sys_ni_syscall -+111 common sigsuspend sys_sigsuspend -+112 common osf_sigstack sys_osf_sigstack -+113 common recvmsg sys_recvmsg -+114 common sendmsg sys_sendmsg -+115 common osf_old_vtrace sys_ni_syscall -+116 common osf_gettimeofday sys_osf_gettimeofday -+117 common osf_getrusage sys_osf_getrusage -+118 common getsockopt sys_getsockopt -+120 common readv sys_osf_readv -+121 common writev sys_osf_writev -+122 common osf_settimeofday sys_osf_settimeofday -+123 common fchown sys_fchown -+124 common fchmod sys_fchmod -+125 common recvfrom sys_recvfrom -+126 common setreuid sys_setreuid -+127 common setregid sys_setregid -+128 common rename sys_rename -+129 common truncate sys_truncate -+130 common ftruncate sys_ftruncate -+131 common flock sys_flock -+132 common setgid sys_setgid -+133 common sendto sys_sendto -+134 common shutdown sys_shutdown -+135 common socketpair sys_socketpair -+136 common mkdir sys_mkdir -+137 common rmdir sys_rmdir -+138 common osf_utimes sys_osf_utimes -+139 common osf_old_sigreturn sys_ni_syscall -+140 common osf_adjtime sys_ni_syscall -+141 common getpeername sys_getpeername -+142 common osf_gethostid sys_ni_syscall -+143 common osf_sethostid sys_ni_syscall -+144 common getrlimit sys_getrlimit -+145 common setrlimit sys_setrlimit -+146 common osf_old_killpg sys_ni_syscall -+147 common setsid sys_setsid -+148 common quotactl sys_quotactl -+149 common osf_oldquota sys_ni_syscall -+150 common getsockname sys_getsockname -+153 common osf_pid_block sys_ni_syscall -+154 common osf_pid_unblock sys_ni_syscall -+156 common sigaction sys_osf_sigaction -+157 common osf_sigwaitprim sys_ni_syscall -+158 common osf_nfssvc sys_ni_syscall -+159 common osf_getdirentries sys_osf_getdirentries -+160 common osf_statfs sys_osf_statfs -+161 common osf_fstatfs sys_osf_fstatfs -+163 common osf_asynch_daemon sys_ni_syscall -+164 common osf_getfh sys_ni_syscall -+165 common osf_getdomainname sys_osf_getdomainname -+166 common setdomainname sys_setdomainname -+169 common osf_exportfs sys_ni_syscall -+181 common osf_alt_plock sys_ni_syscall -+184 common osf_getmnt sys_ni_syscall -+187 common osf_alt_sigpending sys_ni_syscall -+188 common osf_alt_setsid sys_ni_syscall -+199 common osf_swapon sys_swapon -+200 common msgctl sys_old_msgctl -+201 common msgget sys_msgget -+202 common msgrcv sys_msgrcv -+203 common msgsnd sys_msgsnd -+204 common semctl sys_old_semctl -+205 common semget sys_semget -+206 common semop sys_semop -+207 common osf_utsname sys_osf_utsname -+208 common lchown sys_lchown -+209 common shmat sys_shmat -+210 common shmctl sys_old_shmctl -+211 common shmdt sys_shmdt -+212 common shmget sys_shmget -+213 common osf_mvalid sys_ni_syscall -+214 common osf_getaddressconf sys_ni_syscall -+215 common osf_msleep sys_ni_syscall -+216 common osf_mwakeup sys_ni_syscall -+217 common msync sys_msync -+218 common osf_signal sys_ni_syscall -+219 common osf_utc_gettime sys_ni_syscall -+220 common osf_utc_adjtime sys_ni_syscall -+222 common osf_security sys_ni_syscall -+223 common osf_kloadcall sys_ni_syscall -+224 common osf_stat sys_osf_stat -+225 common osf_lstat sys_osf_lstat -+226 common osf_fstat sys_osf_fstat -+227 common osf_statfs64 sys_osf_statfs64 -+228 common osf_fstatfs64 sys_osf_fstatfs64 -+233 common getpgid sys_getpgid -+234 common getsid sys_getsid -+235 common sigaltstack sys_sigaltstack -+236 common osf_waitid sys_ni_syscall -+237 common osf_priocntlset sys_ni_syscall -+238 common osf_sigsendset sys_ni_syscall -+239 common osf_set_speculative sys_ni_syscall -+240 common osf_msfs_syscall sys_ni_syscall -+241 common osf_sysinfo sys_osf_sysinfo -+242 common osf_uadmin sys_ni_syscall -+243 common osf_fuser sys_ni_syscall -+244 common osf_proplist_syscall sys_osf_proplist_syscall -+245 common osf_ntp_adjtime sys_ni_syscall -+246 common osf_ntp_gettime sys_ni_syscall -+247 common osf_pathconf sys_ni_syscall -+248 common osf_fpathconf sys_ni_syscall -+250 common osf_uswitch sys_ni_syscall -+251 common osf_usleep_thread sys_osf_usleep_thread -+252 common osf_audcntl sys_ni_syscall -+253 common osf_audgen sys_ni_syscall -+254 common sysfs sys_sysfs -+255 common osf_subsys_info sys_ni_syscall -+256 common osf_getsysinfo sys_osf_getsysinfo -+257 common osf_setsysinfo sys_osf_setsysinfo -+258 common osf_afs_syscall sys_ni_syscall -+259 common osf_swapctl sys_ni_syscall -+260 common osf_memcntl sys_ni_syscall -+261 common osf_fdatasync sys_ni_syscall -+300 common bdflush sys_bdflush -+301 common sethae sys_sethae -+302 common mount sys_mount -+303 common old_adjtimex sys_old_adjtimex -+304 common swapoff sys_swapoff -+305 common getdents sys_getdents -+306 common create_module sys_ni_syscall -+307 common init_module sys_init_module -+308 common delete_module sys_delete_module -+309 common get_kernel_syms sys_ni_syscall -+310 common syslog sys_syslog -+311 common reboot sys_reboot -+312 common clone sw64_clone -+313 common uselib sys_uselib -+314 common mlock sys_mlock -+315 common munlock sys_munlock -+316 common mlockall sys_mlockall -+317 common munlockall sys_munlockall -+318 common sysinfo sys_sysinfo -+319 common _sysctl sys_ni_syscall -+# 320 was sys_idle -+321 common oldumount sys_oldumount -+322 common swapon sys_swapon -+323 common times sys_times -+324 common personality sys_personality -+325 common setfsuid sys_setfsuid -+326 common setfsgid sys_setfsgid -+327 common ustat sys_ustat -+328 common statfs sys_statfs -+329 common fstatfs sys_fstatfs -+330 common sched_setparam sys_sched_setparam -+331 common sched_getparam sys_sched_getparam -+332 common sched_setscheduler sys_sched_setscheduler -+333 common sched_getscheduler sys_sched_getscheduler -+334 common sched_yield sys_sched_yield -+335 common sched_get_priority_max sys_sched_get_priority_max -+336 common sched_get_priority_min sys_sched_get_priority_min -+337 common sched_rr_get_interval sys_sched_rr_get_interval -+338 common afs_syscall sys_ni_syscall -+339 common uname sys_newuname -+340 common nanosleep sys_nanosleep -+341 common mremap sys_mremap -+342 common nfsservctl sys_ni_syscall -+343 common setresuid sys_setresuid -+344 common getresuid sys_getresuid -+345 common pciconfig_read sys_pciconfig_read -+346 common pciconfig_write sys_pciconfig_write -+347 common query_module sys_ni_syscall -+348 common prctl sys_prctl -+349 common pread64 sys_pread64 -+350 common pwrite64 sys_pwrite64 -+351 common rt_sigreturn sys_rt_sigreturn -+352 common rt_sigaction sys_rt_sigaction -+353 common rt_sigprocmask sys_rt_sigprocmask -+354 common rt_sigpending sys_rt_sigpending -+355 common rt_sigtimedwait sys_rt_sigtimedwait -+356 common rt_sigqueueinfo sys_rt_sigqueueinfo -+357 common rt_sigsuspend sys_rt_sigsuspend -+358 common select sys_select -+359 common gettimeofday sys_gettimeofday -+360 common settimeofday sys_settimeofday -+361 common getitimer sys_getitimer -+362 common setitimer sys_setitimer -+363 common utimes sys_utimes -+364 common getrusage sys_getrusage -+365 common wait4 sys_wait4 -+366 common adjtimex sys_adjtimex -+367 common getcwd sys_getcwd -+368 common capget sys_capget -+369 common capset sys_capset -+370 common sendfile sys_sendfile64 -+371 common setresgid sys_setresgid -+372 common getresgid sys_getresgid -+373 common dipc sys_ni_syscall -+374 common pivot_root sys_pivot_root -+375 common mincore sys_mincore -+376 common pciconfig_iobase sys_pciconfig_iobase -+377 common getdents64 sys_getdents64 -+378 common gettid sys_gettid -+379 common readahead sys_readahead -+# 380 is unused -+381 common tkill sys_tkill -+382 common setxattr sys_setxattr -+383 common lsetxattr sys_lsetxattr -+384 common fsetxattr sys_fsetxattr -+385 common getxattr sys_getxattr -+386 common lgetxattr sys_lgetxattr -+387 common fgetxattr sys_fgetxattr -+388 common listxattr sys_listxattr -+389 common llistxattr sys_llistxattr -+390 common flistxattr sys_flistxattr -+391 common removexattr sys_removexattr -+392 common lremovexattr sys_lremovexattr -+393 common fremovexattr sys_fremovexattr -+394 common futex sys_futex -+395 common sched_setaffinity sys_sched_setaffinity -+396 common sched_getaffinity sys_sched_getaffinity -+397 common tuxcall sys_ni_syscall -+398 common io_setup sys_io_setup -+399 common io_destroy sys_io_destroy -+400 common io_getevents sys_io_getevents -+401 common io_submit sys_io_submit -+402 common io_cancel sys_io_cancel -+405 common exit_group sys_exit_group -+406 common lookup_dcookie sys_lookup_dcookie -+407 common epoll_create sys_epoll_create -+408 common epoll_ctl sys_epoll_ctl -+409 common epoll_wait sys_epoll_wait -+410 common remap_file_pages sys_remap_file_pages -+411 common set_tid_address sys_set_tid_address -+412 common restart_syscall sys_restart_syscall -+413 common fadvise64 sys_fadvise64 -+414 common timer_create sys_timer_create -+415 common timer_settime sys_timer_settime -+416 common timer_gettime sys_timer_gettime -+417 common timer_getoverrun sys_timer_getoverrun -+418 common timer_delete sys_timer_delete -+419 common clock_settime sys_clock_settime -+420 common clock_gettime sys_clock_gettime -+421 common clock_getres sys_clock_getres -+422 common clock_nanosleep sys_clock_nanosleep -+423 common semtimedop sys_semtimedop -+424 common tgkill sys_tgkill -+425 common stat64 sys_stat64 -+426 common lstat64 sys_lstat64 -+427 common fstat64 sys_fstat64 -+428 common vserver sys_ni_syscall -+429 common mbind sys_ni_syscall -+430 common get_mempolicy sys_ni_syscall -+431 common set_mempolicy sys_ni_syscall -+432 common mq_open sys_mq_open -+433 common mq_unlink sys_mq_unlink -+434 common mq_timedsend sys_mq_timedsend -+435 common mq_timedreceive sys_mq_timedreceive -+436 common mq_notify sys_mq_notify -+437 common mq_getsetattr sys_mq_getsetattr -+438 common waitid sys_waitid -+439 common add_key sys_add_key -+440 common request_key sys_request_key -+441 common keyctl sys_keyctl -+442 common ioprio_set sys_ioprio_set -+443 common ioprio_get sys_ioprio_get -+444 common inotify_init sys_inotify_init -+445 common inotify_add_watch sys_inotify_add_watch -+446 common inotify_rm_watch sys_inotify_rm_watch -+447 common fdatasync sys_fdatasync -+448 common kexec_load sys_kexec_load -+449 common migrate_pages sys_migrate_pages -+450 common openat sys_openat -+451 common mkdirat sys_mkdirat -+452 common mknodat sys_mknodat -+453 common fchownat sys_fchownat -+454 common futimesat sys_futimesat -+455 common fstatat64 sys_fstatat64 -+456 common unlinkat sys_unlinkat -+457 common renameat sys_renameat -+458 common linkat sys_linkat -+459 common symlinkat sys_symlinkat -+460 common readlinkat sys_readlinkat -+461 common fchmodat sys_fchmodat -+462 common faccessat sys_faccessat -+463 common pselect6 sys_pselect6 -+464 common ppoll sys_ppoll -+465 common unshare sys_unshare -+466 common set_robust_list sys_set_robust_list -+467 common get_robust_list sys_get_robust_list -+468 common splice sys_splice -+469 common sync_file_range sys_sync_file_range -+470 common tee sys_tee -+471 common vmsplice sys_vmsplice -+472 common move_pages sys_move_pages -+473 common getcpu sys_getcpu -+474 common epoll_pwait sys_epoll_pwait -+475 common utimensat sys_utimensat -+476 common signalfd sys_signalfd -+477 common timerfd sys_ni_syscall -+478 common eventfd sys_eventfd -+479 common recvmmsg sys_recvmmsg -+480 common fallocate sys_fallocate -+481 common timerfd_create sys_timerfd_create -+482 common timerfd_settime sys_timerfd_settime -+483 common timerfd_gettime sys_timerfd_gettime -+484 common signalfd4 sys_signalfd4 -+485 common eventfd2 sys_eventfd2 -+486 common epoll_create1 sys_epoll_create1 -+487 common dup3 sys_dup3 -+488 common pipe2 sys_pipe2 -+489 common inotify_init1 sys_inotify_init1 -+490 common preadv sys_preadv -+491 common pwritev sys_pwritev -+492 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo -+493 common perf_event_open sys_perf_event_open -+494 common fanotify_init sys_fanotify_init -+495 common fanotify_mark sys_fanotify_mark -+496 common prlimit64 sys_prlimit64 -+497 common name_to_handle_at sys_name_to_handle_at -+498 common open_by_handle_at sys_open_by_handle_at -+499 common clock_adjtime sys_clock_adjtime -+500 common syncfs sys_syncfs -+501 common setns sys_setns -+502 common accept4 sys_accept4 -+503 common sendmmsg sys_sendmmsg -+504 common process_vm_readv sys_process_vm_readv -+505 common process_vm_writev sys_process_vm_writev -+506 common kcmp sys_kcmp -+507 common finit_module sys_finit_module -+508 common sched_setattr sys_sched_setattr -+509 common sched_getattr sys_sched_getattr -+510 common renameat2 sys_renameat2 -+511 common getrandom sys_getrandom -+512 common memfd_create sys_memfd_create -+513 common execveat sys_execveat -+514 common seccomp sys_seccomp -+515 common bpf sys_bpf -+516 common userfaultfd sys_userfaultfd -+517 common membarrier sys_membarrier -+518 common mlock2 sys_mlock2 -+519 common copy_file_range sys_copy_file_range -+520 common preadv2 sys_preadv2 -+521 common pwritev2 sys_pwritev2 -+522 common statx sys_statx -+523 common io_pgetevents sys_io_pgetevents -+524 common pkey_mprotect sys_pkey_mprotect -+525 common pkey_alloc sys_pkey_alloc -+526 common pkey_free sys_pkey_free -+527 common rseq sys_rseq -+528 common statfs64 sys_statfs64 -+529 common fstatfs64 sys_fstatfs64 -+530 common getegid sys_getegid -+531 common geteuid sys_geteuid -+532 common getppid sys_getppid -+# all other architectures have common numbers for new syscall, sw64 -+# is the exception. -+534 common pidfd_send_signal sys_pidfd_send_signal -+535 common io_uring_setup sys_io_uring_setup -+536 common io_uring_enter sys_io_uring_enter -+537 common io_uring_register sys_io_uring_register -+538 common open_tree sys_open_tree -+539 common move_mount sys_move_mount -+540 common fsopen sys_fsopen -+541 common fsconfig sys_fsconfig -+542 common fsmount sys_fsmount -+543 common fspick sys_fspick -+544 common pidfd_open sys_pidfd_open -+# 545 reserved for clone3 -+546 common close_range sys_close_range -+547 common openat2 sys_openat2 -+548 common pidfd_getfd sys_pidfd_getfd -+549 common faccessat2 sys_faccessat2 -+550 common process_madvise sys_process_madvise -+551 common epoll_pwait2 sys_epoll_pwait2 -+552 common mount_setattr sys_mount_setattr -+# 553 reserved for quotactl_path -+554 common landlock_create_ruleset sys_landlock_create_ruleset -+555 common landlock_add_rule sys_landlock_add_rule -+556 common landlock_restrict_self sys_landlock_restrict_self -diff --git a/linux-user/sw64/syscallhdr.sh b/linux-user/sw64/syscallhdr.sh -new file mode 100644 -index 0000000000..46c166d8ae ---- /dev/null -+++ b/linux-user/sw64/syscallhdr.sh -@@ -0,0 +1,32 @@ -+#!/bin/sh -+# SPDX-License-Identifier: GPL-2.0 -+ -+in="$1" -+out="$2" -+my_abis=`echo "($3)" | tr ',' '|'` -+prefix="$4" -+offset="$5" -+ -+fileguard=LINUX_USER_SW64_`basename "$out" | sed \ -+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -+ -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'` -+grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | ( -+ printf "#ifndef %s\n" "${fileguard}" -+ printf "#define %s\n" "${fileguard}" -+ printf "\n" -+ -+ nxt=0 -+ while read nr abi name entry ; do -+ if [ -z "$offset" ]; then -+ printf "#define TARGET_NR_%s%s\t%s\n" \ -+ "${prefix}" "${name}" "${nr}" -+ else -+ printf "#define TARGET_NR_%s%s\t(%s + %s)\n" \ -+ "${prefix}" "${name}" "${offset}" "${nr}" -+ fi -+ nxt=$((nr+1)) -+ done -+ -+ printf "\n" -+ printf "#endif /* %s */" "${fileguard}" -+) > "$out" -diff --git a/linux-user/sw64/target_cpu.h b/linux-user/sw64/target_cpu.h -index 1b87c8ba6d..63afa699c3 100644 ---- a/linux-user/sw64/target_cpu.h -+++ b/linux-user/sw64/target_cpu.h -@@ -17,13 +17,26 @@ - #ifndef SW64_TARGET_CPU_H - #define SW64_TARGET_CPU_H - --static inline void cpu_clone_regs(CPUSW64State *env, target_ulong newsp) -+static inline void cpu_clone_regs_child(CPUSW64State *env, target_ulong newsp, unsigned flags) - { - if (newsp) { - env->ir[IDX_SP] = newsp; - } - env->ir[IDX_V0] = 0; - env->ir[IDX_A3] = 0; -+ env->ir[IDX_A4] = 1; /* OSF/1 secondary return: child */ -+} -+ -+static inline void cpu_clone_regs_parent(CPUSW64State *env, unsigned flags) -+{ -+ /* -+ * OSF/1 secondary return: parent -+ * Note that the kernel does not do this if SETTLS, because the -+ * settls argument register is still live after copy_thread. -+ */ -+ if (!(flags & CLONE_SETTLS)) { -+ env->ir[IDX_A4] = 0; -+ } - } - - static inline void cpu_set_tls(CPUSW64State *env, target_ulong newtls) -diff --git a/linux-user/sw64/target_errno_defs.h b/linux-user/sw64/target_errno_defs.h -new file mode 100644 -index 0000000000..fd637f5bc9 ---- /dev/null -+++ b/linux-user/sw64/target_errno_defs.h -@@ -0,0 +1,204 @@ -+#ifndef sw64_TARGET_ERRNO_DEFS_H -+#define sw64_TARGET_ERRNO_DEFS_H -+ -+#include "../generic/target_errno_defs.h" -+ -+/* -+ * Generic target errno overridden with definitions taken -+ * from asm-sw64/errno.h -+ */ -+#undef TARGET_EWOULDBLOCK -+#define TARGET_EWOULDBLOCK TARGET_EAGAIN -+#undef TARGET_EDEADLK -+#define TARGET_EDEADLK 11 -+#undef TARGET_EAGAIN -+#define TARGET_EAGAIN 35 -+#undef TARGET_EINPROGRESS -+#define TARGET_EINPROGRESS 36 -+#undef TARGET_EALREADY -+#define TARGET_EALREADY 37 -+#undef TARGET_ENOTSOCK -+#define TARGET_ENOTSOCK 38 -+#undef TARGET_EDESTADDRREQ -+#define TARGET_EDESTADDRREQ 39 -+#undef TARGET_EMSGSIZE -+#define TARGET_EMSGSIZE 40 -+#undef TARGET_EPROTOTYPE -+#define TARGET_EPROTOTYPE 41 -+#undef TARGET_ENOPROTOOPT -+#define TARGET_ENOPROTOOPT 42 -+#undef TARGET_EPROTONOSUPPORT -+#define TARGET_EPROTONOSUPPORT 43 -+#undef TARGET_ESOCKTNOSUPPORT -+#define TARGET_ESOCKTNOSUPPORT 44 -+#undef TARGET_EOPNOTSUPP -+#define TARGET_EOPNOTSUPP 45 -+#undef TARGET_EPFNOSUPPORT -+#define TARGET_EPFNOSUPPORT 46 -+#undef TARGET_EAFNOSUPPORT -+#define TARGET_EAFNOSUPPORT 47 -+#undef TARGET_EADDRINUSE -+#define TARGET_EADDRINUSE 48 -+#undef TARGET_EADDRNOTAVAIL -+#define TARGET_EADDRNOTAVAIL 49 -+#undef TARGET_ENETDOWN -+#define TARGET_ENETDOWN 50 -+#undef TARGET_ENETUNREACH -+#define TARGET_ENETUNREACH 51 -+#undef TARGET_ENETRESET -+#define TARGET_ENETRESET 52 -+#undef TARGET_ECONNABORTED -+#define TARGET_ECONNABORTED 53 -+#undef TARGET_ECONNRESET -+#define TARGET_ECONNRESET 54 -+#undef TARGET_ENOBUFS -+#define TARGET_ENOBUFS 55 -+#undef TARGET_EISCONN -+#define TARGET_EISCONN 56 -+#undef TARGET_ENOTCONN -+#define TARGET_ENOTCONN 57 -+#undef TARGET_ESHUTDOWN -+#define TARGET_ESHUTDOWN 58 -+#undef TARGET_ETOOMANYREFS -+#define TARGET_ETOOMANYREFS 59 -+#undef TARGET_ETIMEDOUT -+#define TARGET_ETIMEDOUT 60 -+#undef TARGET_ECONNREFUSED -+#define TARGET_ECONNREFUSED 61 -+#undef TARGET_ELOOP -+#define TARGET_ELOOP 62 -+#undef TARGET_ENAMETOOLONG -+#define TARGET_ENAMETOOLONG 63 -+#undef TARGET_EHOSTDOWN -+#define TARGET_EHOSTDOWN 64 -+#undef TARGET_EHOSTUNREACH -+#define TARGET_EHOSTUNREACH 65 -+#undef TARGET_ENOTEMPTY -+#define TARGET_ENOTEMPTY 66 -+/* Unused 67 */ -+#undef TARGET_EUSERS -+#define TARGET_EUSERS 68 -+#undef TARGET_EDQUOT -+#define TARGET_EDQUOT 69 -+#undef TARGET_ESTALE -+#define TARGET_ESTALE 70 -+#undef TARGET_EREMOTE -+#define TARGET_EREMOTE 71 -+/* Unused 72-76 */ -+#undef TARGET_ENOLCK -+#define TARGET_ENOLCK 77 -+#undef TARGET_ENOSYS -+#define TARGET_ENOSYS 78 -+/* Unused 79 */ -+#undef TARGET_ENOMSG -+#define TARGET_ENOMSG 80 -+#undef TARGET_EIDRM -+#define TARGET_EIDRM 81 -+#undef TARGET_ENOSR -+#define TARGET_ENOSR 82 -+#undef TARGET_ETIME -+#define TARGET_ETIME 83 -+#undef TARGET_EBADMSG -+#define TARGET_EBADMSG 84 -+#undef TARGET_EPROTO -+#define TARGET_EPROTO 85 -+#undef TARGET_ENODATA -+#define TARGET_ENODATA 86 -+#undef TARGET_ENOSTR -+#define TARGET_ENOSTR 87 -+#undef TARGET_ECHRNG -+#define TARGET_ECHRNG 88 -+#undef TARGET_EL2NSYNC -+#define TARGET_EL2NSYNC 89 -+#undef TARGET_EL3HLT -+#define TARGET_EL3HLT 90 -+#undef TARGET_EL3RST -+#define TARGET_EL3RST 91 -+#undef TARGET_ENOPKG -+#define TARGET_ENOPKG 92 -+#undef TARGET_ELNRNG -+#define TARGET_ELNRNG 93 -+#undef TARGET_EUNATCH -+#define TARGET_EUNATCH 94 -+#undef TARGET_ENOCSI -+#define TARGET_ENOCSI 95 -+#undef TARGET_EL2HLT -+#define TARGET_EL2HLT 96 -+#undef TARGET_EBADE -+#define TARGET_EBADE 97 -+#undef TARGET_EBADR -+#define TARGET_EBADR 98 -+#undef TARGET_EXFULL -+#define TARGET_EXFULL 99 -+#undef TARGET_ENOANO -+#define TARGET_ENOANO 100 -+#undef TARGET_EBADRQC -+#define TARGET_EBADRQC 101 -+#undef TARGET_EBADSLT -+#define TARGET_EBADSLT 102 -+/* Unused 103 */ -+#undef TARGET_EBFONT -+#define TARGET_EBFONT 104 -+#undef TARGET_ENONET -+#define TARGET_ENONET 105 -+#undef TARGET_ENOLINK -+#define TARGET_ENOLINK 106 -+#undef TARGET_EADV -+#define TARGET_EADV 107 -+#undef TARGET_ESRMNT -+#define TARGET_ESRMNT 108 -+#undef TARGET_ECOMM -+#define TARGET_ECOMM 109 -+#undef TARGET_EMULTIHOP -+#define TARGET_EMULTIHOP 110 -+#undef TARGET_EDOTDOT -+#define TARGET_EDOTDOT 111 -+#undef TARGET_EOVERFLOW -+#define TARGET_EOVERFLOW 112 -+#undef TARGET_ENOTUNIQ -+#define TARGET_ENOTUNIQ 113 -+#undef TARGET_EBADFD -+#define TARGET_EBADFD 114 -+#undef TARGET_EREMCHG -+#define TARGET_EREMCHG 115 -+#undef TARGET_EILSEQ -+#define TARGET_EILSEQ 116 -+/* Same as default 117-121 */ -+#undef TARGET_ELIBACC -+#define TARGET_ELIBACC 122 -+#undef TARGET_ELIBBAD -+#define TARGET_ELIBBAD 123 -+#undef TARGET_ELIBSCN -+#define TARGET_ELIBSCN 124 -+#undef TARGET_ELIBMAX -+#define TARGET_ELIBMAX 125 -+#undef TARGET_ELIBEXEC -+#define TARGET_ELIBEXEC 126 -+#undef TARGET_ERESTART -+#define TARGET_ERESTART 127 -+#undef TARGET_ESTRPIPE -+#define TARGET_ESTRPIPE 128 -+#undef TARGET_ENOMEDIUM -+#define TARGET_ENOMEDIUM 129 -+#undef TARGET_EMEDIUMTYPE -+#define TARGET_EMEDIUMTYPE 130 -+#undef TARGET_ECANCELED -+#define TARGET_ECANCELED 131 -+#undef TARGET_ENOKEY -+#define TARGET_ENOKEY 132 -+#undef TARGET_EKEYEXPIRED -+#define TARGET_EKEYEXPIRED 133 -+#undef TARGET_EKEYREVOKED -+#define TARGET_EKEYREVOKED 134 -+#undef TARGET_EKEYREJECTED -+#define TARGET_EKEYREJECTED 135 -+#undef TARGET_EOWNERDEAD -+#define TARGET_EOWNERDEAD 136 -+#undef TARGET_ENOTRECOVERABLE -+#define TARGET_ENOTRECOVERABLE 137 -+#undef TARGET_ERFKILL -+#define TARGET_ERFKILL 138 -+#undef TARGET_EHWPOISON -+#define TARGET_EHWPOISON 139 -+ -+#endif -diff --git a/linux-user/sw64/target_signal.h b/linux-user/sw64/target_signal.h -index 6393a7542f..8cc1693b05 100644 ---- a/linux-user/sw64/target_signal.h -+++ b/linux-user/sw64/target_signal.h -@@ -95,4 +95,6 @@ typedef struct target_sigaltstack { - #define TARGET_GEN_SUBRNG7 -25 - - #define TARGET_ARCH_HAS_SETUP_FRAME -+#define TARGET_ARCH_HAS_KA_RESTORER -+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1 - #endif /* SW64_TARGET_SIGNAL_H */ -diff --git a/linux-user/sw64/target_syscall.h b/linux-user/sw64/target_syscall.h -index c901ae95d8..418905110c 100644 ---- a/linux-user/sw64/target_syscall.h -+++ b/linux-user/sw64/target_syscall.h -@@ -23,22 +23,26 @@ struct target_pt_regs { - abi_ulong r27; - abi_ulong r28; - abi_ulong hae; --/* JRP - These are the values provided to a0-a2 by HMcode */ -+/* JRP - These are the values provided to a0-a2 by hmcode */ - abi_ulong trap_a0; - abi_ulong trap_a1; - abi_ulong trap_a2; --/* These are saved by HMcode: */ -+/* These are saved by hmcode: */ - abi_ulong ps; - abi_ulong pc; - abi_ulong gp; - abi_ulong r16; - abi_ulong r17; - abi_ulong r18; -+/* Those is needed by qemu to temporary store the user stack pointer */ -+ abi_ulong usp; -+ abi_ulong unique; - }; - --#define TARGET_MLOCKALL_MCL_CURRENT 0x2000 --#define TARGET_MLOCKALL_MCL_FUTURE 0x4000 - -+#define TARGET_MCL_CURRENT 0x2000 -+#define TARGET_MCL_FUTURE 0x4000 -+#define TARGET_MCL_ONFAULT 0x8000 - - #define UNAME_MACHINE "sw64" - #define UNAME_MINIMUM_RELEASE "2.6.32" -diff --git a/linux-user/sw64/termbits.h b/linux-user/sw64/termbits.h -index 37dd77120c..5c40efcb20 100644 ---- a/linux-user/sw64/termbits.h -+++ b/linux-user/sw64/termbits.h -@@ -156,6 +156,7 @@ struct target_termios { - #define TARGET_FLUSHO 0x00800000 - #define TARGET_PENDIN 0x20000000 - #define TARGET_IEXTEN 0x00000400 -+#define TARGET_EXTPROC 0x10000000 - - #define TARGET_FIOCLEX TARGET_IO('f', 1) - #define TARGET_FIONCLEX TARGET_IO('f', 2) -diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h -index 04ca5fe7a0..a04f399278 100644 ---- a/linux-user/syscall_defs.h -+++ b/linux-user/syscall_defs.h -@@ -85,7 +85,7 @@ - - #elif defined(TARGET_PPC) || defined(TARGET_ALPHA) || \ - defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) || \ -- defined(TARGET_MIPS) -+ defined(TARGET_MIPS) || defined(TARGET_SW64) - - #define TARGET_IOC_SIZEBITS 13 - #define TARGET_IOC_DIRBITS 3 -@@ -2270,6 +2270,50 @@ struct target_stat { - int __unused[2]; - }; - -+#elif defined(TARGET_SW64) -+ -+struct target_stat { -+ unsigned int st_dev; -+ unsigned int st_ino; -+ unsigned int st_mode; -+ unsigned int st_nlink; -+ unsigned int st_uid; -+ unsigned int st_gid; -+ unsigned int st_rdev; -+ abi_long st_size; -+ abi_ulong target_st_atime; -+ abi_ulong target_st_mtime; -+ abi_ulong target_st_ctime; -+ unsigned int st_blksize; -+ unsigned int st_blocks; -+ unsigned int st_flags; -+ unsigned int st_gen; -+}; -+ -+#define TARGET_HAS_STRUCT_STAT64 -+struct target_stat64 { -+ abi_ulong st_dev; -+ abi_ulong st_ino; -+ abi_ulong st_rdev; -+ abi_long st_size; -+ abi_ulong st_blocks; -+ -+ unsigned int st_mode; -+ unsigned int st_uid; -+ unsigned int st_gid; -+ unsigned int st_blksize; -+ unsigned int st_nlink; -+ unsigned int __pad0; -+ -+ abi_ulong target_st_atime; -+ abi_ulong target_st_atime_nsec; -+ abi_ulong target_st_mtime; -+ abi_ulong target_st_mtime_nsec; -+ abi_ulong target_st_ctime; -+ abi_ulong target_st_ctime_nsec; -+ abi_long __unused[3]; -+}; -+ - #else - #error unsupported CPU - #endif -diff --git a/target/sw64/Makefile.objs b/target/sw64/Makefile.objs -index 1e549d141c..c702eaa26d 100644 ---- a/target/sw64/Makefile.objs -+++ b/target/sw64/Makefile.objs -@@ -2,3 +2,4 @@ obj-$(CONFIG_SOFTMMU) += machine.o - obj-y += cpu.o translate.o profile.o helper.o - obj-y += int_helper.o float_helper.o simd_helper.o helper.o exception.o - obj-$(CONFIG_KVM) += kvm.o -+obj-y += gdbstub.o -diff --git a/target/sw64/cpu-param.h b/target/sw64/cpu-param.h -index 978a3cd572..464cfb3dc1 100644 ---- a/target/sw64/cpu-param.h -+++ b/target/sw64/cpu-param.h -@@ -7,18 +7,12 @@ - #ifndef SW64_CPU_PARAM_H - #define SW64_CPU_PARAM_H 1 - --#define TARGET_LONG_BITS 64 /* if use th-1 ,TARGET_PAGE_BITS is 12 */ -+#define TARGET_LONG_BITS 64 - #define TARGET_PAGE_BITS 13 - --#ifdef CONFIG_USER_ONLY - #define TARGET_VIRT_ADDR_SPACE_BITS 64 --#else - #define TARGET_PHYS_ADDR_SPACE_BITS 48 --#define TARGET_VIRT_ADDR_SPACE_BITS 64 --#endif - --#ifndef CONFIG_USER_ONLY - #define NB_MMU_MODES 4 --#endif - - #endif -diff --git a/target/sw64/cpu.c b/target/sw64/cpu.c -index 89c21850e1..8987361346 100644 ---- a/target/sw64/cpu.c -+++ b/target/sw64/cpu.c -@@ -26,7 +26,6 @@ - #include "sysemu/reset.h" - #include "hw/qdev-properties.h" - -- - static void sw64_cpu_set_pc(CPUState *cs, vaddr value) - { - SW64CPU *cpu = SW64_CPU(cs); -@@ -36,7 +35,6 @@ static void sw64_cpu_set_pc(CPUState *cs, vaddr value) - - static void sw64_cpu_dump_state(CPUState *cs, FILE *f, int flags) - { --#ifndef CONFIG_KVM - SW64CPU *cpu = SW64_CPU(cs); - CPUSW64State *env = &cpu->env; - int i; -@@ -91,7 +89,6 @@ static void sw64_cpu_dump_state(CPUState *cs, FILE *f, int flags) - qemu_fprintf(f, "\n"); - } - qemu_fprintf(f, "\n"); --#endif - } - - #ifndef CONFIG_USER_ONLY -@@ -137,7 +134,6 @@ static void core3_init(Object *obj) - CPUSW64State *env = cs->env_ptr; - #ifdef CONFIG_USER_ONLY - env->fpcr = 0x680e800000000000; -- parallel_cpus = true; - #endif - set_feature(env, SW64_FEATURE_CORE3); - } -@@ -168,7 +164,7 @@ bool sw64_cpu_has_work(CPUState *cs) - * wake up by hard interrupt, timer, ii, mail or mchk. - */ - return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER | -- CPU_INTERRUPT_IIMAIL | CPU_INTERRUPT_MCHK); -+ CPU_INTERRUPT_II0| CPU_INTERRUPT_MCHK); - } - - static void sw64_cpu_initfn(Object *obj) -@@ -204,136 +200,6 @@ static void sw64_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr - } - #endif - --#define a0(func) (((func & 0xFF) >> 6) & 0x1) --#define a1(func) ((((func & 0xFF) >> 6) & 0x2) >> 1) -- --#define t(func) ((a0(func) ^ a1(func)) & 0x1) --#define b0(func) (t(func) | a0(func)) --#define b1(func) ((~t(func) & 1) | a1(func)) -- --#define START_SYS_CALL_ADDR(func) \ -- (b1(func) << 14) | (b0(func) << 13) | ((func & 0x3F) << 7) -- --static void sw64_cpu_do_interrupt(CPUState *cs) --{ -- int i = cs->exception_index; -- -- cs->exception_index = -1; --#if !defined(CONFIG_USER_ONLY) -- SW64CPU *cpu = SW64_CPU(cs); -- CPUSW64State *env = &cpu->env; -- switch (i) { -- case EXCP_OPCDEC: -- cpu_abort(cs, "ILLEGAL INSN"); -- break; -- case EXCP_CALL_SYS: -- i = START_SYS_CALL_ADDR(env->error_code); -- if (i <= 0x3F) { -- i += 0x4000; -- } else if (i >= 0x40 && i <= 0x7F) { -- i += 0x2000; -- } else if (i >= 0x80 && i <= 0x8F) { -- i += 0x6000; -- } -- break; -- case EXCP_ARITH: -- env->error_code = -1; -- env->csr[EXC_PC] = env->pc - 4; -- env->csr[EXC_SUM] = 1; -- i = 0xB80; -- break; -- case EXCP_UNALIGN: -- i = 0xB00; -- env->csr[EXC_PC] = env->pc - 4; -- break; -- case EXCP_CLK_INTERRUPT: -- case EXCP_DEV_INTERRUPT: -- i = 0xE80; -- break; -- case EXCP_MMFAULT: -- i = 0x980; -- env->csr[EXC_PC] = env->pc; -- break; -- case EXCP_IIMAIL: -- env->csr[EXC_PC] = env->pc; -- i = 0xE00; -- break; -- default: -- break; -- } -- env->pc = env->hm_entry + i; -- env->flags = ENV_FLAG_HM_MODE; --#else -- switch (i) { -- case EXCP_OPCDEC: -- cpu_abort(cs, "ILLEGAL INSN"); -- break; -- case EXCP_CALL_SYS: -- default: -- break; -- } --#endif --} -- --#ifndef CONFIG_USER_ONLY --static bool sw64_cpu_exec_interrupt(CPUState *cs, int interrupt_request) --{ -- SW64CPU *cpu = SW64_CPU(cs); -- CPUSW64State *env = &cpu->env; -- int idx = -1; -- /* We never take interrupts while in Hardmode. */ -- if (env->flags & ENV_FLAG_HM_MODE) -- return false; -- -- if (interrupt_request & CPU_INTERRUPT_IIMAIL) { -- idx = EXCP_IIMAIL; -- env->csr[INT_STAT] |= 1UL << 6; -- if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -- return false; -- cs->interrupt_request &= ~CPU_INTERRUPT_IIMAIL; -- goto done; -- } -- -- if (interrupt_request & CPU_INTERRUPT_TIMER) { -- idx = EXCP_CLK_INTERRUPT; -- env->csr[INT_STAT] |= 1UL << 4; -- if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -- return false; -- cs->interrupt_request &= ~CPU_INTERRUPT_TIMER; -- goto done; -- } -- -- if (interrupt_request & CPU_INTERRUPT_HARD) { -- idx = EXCP_DEV_INTERRUPT; -- env->csr[INT_STAT] |= 1UL << 12; -- if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -- return false; -- cs->interrupt_request &= ~CPU_INTERRUPT_HARD; -- goto done; -- } -- -- if (interrupt_request & CPU_INTERRUPT_PCIE) { -- idx = EXCP_DEV_INTERRUPT; -- env->csr[INT_STAT] |= 1UL << 1; -- env->csr[INT_PCI_INT] = 0x10; -- if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -- return false; -- cs->interrupt_request &= ~CPU_INTERRUPT_PCIE; -- goto done; -- } -- --done: -- if (idx >= 0) { -- cs->exception_index = idx; -- env->error_code = 0; -- env->csr[EXC_PC] = env->pc; -- sw64_cpu_do_interrupt(cs); -- return true; -- } -- return false; --} --#endif -- - static void sw64_cpu_reset(DeviceState *dev) - { - CPUState *s = CPU(dev); -@@ -370,17 +236,15 @@ static const struct SysemuCPUOps sw64_sysemu_ops = { - #include "hw/core/tcg-cpu-ops.h" - - static const struct TCGCPUOps sw64_tcg_ops = { --#ifdef CONFIG_TCG - .initialize = sw64_translate_init, -- .tlb_fill = sw64_cpu_tlb_fill, --#endif /* CONFIG_TCG */ - --#if !defined(CONFIG_USER_ONLY) -+#ifndef CONFIG_USER_ONLY -+ .tlb_fill = sw64_cpu_tlb_fill, - .do_unaligned_access = sw64_cpu_do_unaligned_access, - .cpu_exec_interrupt = sw64_cpu_exec_interrupt, - .do_transaction_failed = sw64_cpu_do_transaction_failed, --#endif /* !CONFIG_USER_ONLY */ - .do_interrupt = sw64_cpu_do_interrupt, -+#endif /* !CONFIG_USER_ONLY */ - }; - - static void sw64_cpu_class_init(ObjectClass *oc, void *data) -@@ -389,21 +253,26 @@ static void sw64_cpu_class_init(ObjectClass *oc, void *data) - CPUClass *cc = CPU_CLASS(oc); - SW64CPUClass *scc = SW64_CPU_CLASS(oc); - -- device_class_set_parent_realize(dc, sw64_cpu_realizefn, -- &scc->parent_realize); -- device_class_set_parent_reset(dc, sw64_cpu_reset, &scc->parent_reset); -- device_class_set_props(dc, sw64_cpu_properties); -+ device_class_set_parent_realize(dc, sw64_cpu_realizefn, &scc->parent_realize); -+ device_class_set_parent_reset(dc, sw64_cpu_reset, &scc->parent_reset); -+ device_class_set_props(dc, sw64_cpu_properties); - - cc->class_by_name = sw64_cpu_class_by_name; -+#ifndef CONFIG_USER_ONLY - dc->vmsd = &vmstate_sw64_cpu; -+ cc->sysemu_ops = &sw64_sysemu_ops; -+#endif - cc->has_work = sw64_cpu_has_work; - cc->set_pc = sw64_cpu_set_pc; - cc->disas_set_info = sw64_cpu_disas_set_info; - cc->dump_state = sw64_cpu_dump_state; -+ -+ cc->gdb_read_register = sw64_cpu_gdb_read_register; -+ cc->gdb_write_register = sw64_cpu_gdb_write_register; -+ cc->gdb_num_core_regs = 67; -+ cc->gdb_core_xml_file = "sw64-core.xml"; -+ - cc->tcg_ops = &sw64_tcg_ops; --#ifndef CONFIG_USER_ONLY -- cc->sysemu_ops = &sw64_sysemu_ops; --#endif - } - - static const SW64CPUInfo sw64_cpus[] = -diff --git a/target/sw64/cpu.h b/target/sw64/cpu.h -index 5a490e2b4a..4e14891e84 100644 ---- a/target/sw64/cpu.h -+++ b/target/sw64/cpu.h -@@ -60,6 +60,8 @@ - - #define MCU_CLOCK 25000000 - -+#define init_pc 0xffffffff80011100 -+ - typedef struct CPUSW64State CPUSW64State; - typedef CPUSW64State CPUArchState; - typedef SW64CPU ArchCPU; -@@ -136,7 +138,7 @@ struct SW64CPU { - CPUSW64State env; - - uint64_t k_regs[158]; -- uint64_t k_vcb[36]; -+ uint64_t k_vcb[48]; - QEMUTimer *alarm_timer; - target_ulong irq; - uint32_t cid; -@@ -227,6 +229,8 @@ static inline SW64CPU *sw64_env_get_cpu(CPUSW64State *env) - #define SW64_CPU_TYPE_SUFFIX "-" TYPE_SW64_CPU - #define SW64_CPU_TYPE_NAME(name) (name SW64_CPU_TYPE_SUFFIX) - int cpu_sw64_signal_handler(int host_signum, void *pinfo, void *puc); -+int sw64_cpu_gdb_read_register(CPUState *cs, uint8_t *buf, int reg); -+int sw64_cpu_gdb_write_register(CPUState *cs, uint8_t *buf, int reg); - bool sw64_cpu_tlb_fill(CPUState *cs, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr); -@@ -236,6 +240,10 @@ void sw64_stl_phys(CPUState *cs, hwaddr addr, uint64_t val); - uint64_t sw64_ldw_phys(CPUState *cs, hwaddr addr); - void sw64_stw_phys(CPUState *cs, hwaddr addr, uint64_t val); - uint64_t cpu_sw64_load_fpcr(CPUSW64State *env); -+#ifndef CONFIG_USER_ONLY -+void sw64_cpu_do_interrupt(CPUState *cs); -+bool sw64_cpu_exec_interrupt(CPUState *cpu, int int_req); -+#endif - void cpu_sw64_store_fpcr(CPUSW64State *env, uint64_t val); - void sw64_cpu_do_unaligned_access(CPUState *cs, vaddr addr, - MMUAccessType access_type, int mmu_idx, -@@ -245,7 +253,7 @@ extern struct VMStateDescription vmstate_sw64_cpu; - - /* SW64-specific interrupt pending bits */ - #define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_EXT_0 --#define CPU_INTERRUPT_IIMAIL CPU_INTERRUPT_TGT_EXT_1 -+#define CPU_INTERRUPT_II0 CPU_INTERRUPT_TGT_EXT_1 - #define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2 - #define CPU_INTERRUPT_PCIE CPU_INTERRUPT_TGT_EXT_3 - #define CPU_INTERRUPT_WAKEUP CPU_INTERRUPT_TGT_EXT_3 -@@ -281,11 +289,14 @@ enum { - SWCSR(PTBR, 0x8), - SWCSR(PRI_BASE, 0x10), - SWCSR(TIMER_CTL, 0x2a), -+ SWCSR(TIMER_TH, 0x2b), - SWCSR(INT_STAT, 0x30), - SWCSR(INT_CLR, 0x31), - SWCSR(IER, 0x32), - SWCSR(INT_PCI_INT, 0x33), - SWCSR(DVA, 0x4e), -+ SWCSR(SOFT_CID, 0xc9), -+ SWCSR(SHTCLOCK, 0xca), - }; - - #include "exec/cpu-all.h" -@@ -302,7 +313,7 @@ void sw64_translate_init(void); - enum { - EXCP_NONE, - EXCP_HALT, -- EXCP_IIMAIL, -+ EXCP_II0, - EXCP_OPCDEC, - EXCP_CALL_SYS, - EXCP_ARITH, -diff --git a/target/sw64/gdbstub.c b/target/sw64/gdbstub.c -new file mode 100644 -index 0000000000..da4d39d215 ---- /dev/null -+++ b/target/sw64/gdbstub.c -@@ -0,0 +1,56 @@ -+/* -+ * SW64 gdb server stub -+ * -+ * Copyright (c) 2023 Lu Feifei -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, see . -+ */ -+#include "qemu/osdep.h" -+#include "qemu-common.h" -+#include "cpu.h" -+#include "exec/gdbstub.h" -+ -+int sw64_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ -+ if (n < 31) { -+ return gdb_get_regl(mem_buf, env->ir[n]); -+ } else if (n == 31) { -+ return gdb_get_regl(mem_buf, 0); -+ } else if (n == 64) { -+ return gdb_get_regl(mem_buf, env->pc); -+ } -+ return 0; -+} -+ -+int sw64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ -+ if (n < 31) { -+ env->ir[n] = ldtul_p(mem_buf); -+ return sizeof(target_ulong); -+ } else if (n == 31) { -+ /* discard writes to r31 */ -+ return sizeof(target_ulong); -+ } else if (n == 64) { -+ env->pc = ldtul_p(mem_buf); -+ return sizeof(target_ulong); -+ } -+ -+ return 0; -+} -diff --git a/target/sw64/helper.c b/target/sw64/helper.c -index 0cc0af7087..e317c08f0a 100644 ---- a/target/sw64/helper.c -+++ b/target/sw64/helper.c -@@ -23,18 +23,7 @@ - #include "hw/core/cpu.h" - #include "exec/memattrs.h" - --#if defined(CONFIG_USER_ONLY) --bool sw64_cpu_tlb_fill(CPUState *cs, vaddr address, int size, -- MMUAccessType access_type, int mmu_idx, -- bool probe, uintptr_t retaddr) --{ -- SW64CPU *cpu = SW64_CPU(cs); -- -- cs->exception_index = EXCP_MMFAULT; -- cpu->env.trap_arg0 = address; -- cpu_loop_exit_restore(cs, retaddr); --} --#else -+#ifndef CONFIG_USER_ONLY - static target_ulong ldq_phys_clear(CPUState *cs, target_ulong phys) - { - return ldq_phys(cs->as, phys & ~(3UL)); -@@ -49,7 +38,7 @@ static int get_sw64_physical_address(CPUSW64State *env, target_ulong addr, - int prot = 0; - int ret = MM_K_ACV; - target_ulong L1pte, L2pte, L3pte, L4pte; -- target_ulong pt, index, pte_pfn_s; -+ target_ulong pt = 0, index = 0, pte_pfn_s = 0; - - if (((addr >> 28) & 0xffffffff8) == 0xffffffff8) { - phys = (~(0xffffffff80000000)) & addr; -@@ -217,6 +206,124 @@ do_pgmiss: - done: - return (fail >= 0 ? -1 : phys); - } -+ -+#define a0(func) (((func & 0xFF) >> 6) & 0x1) -+#define a1(func) ((((func & 0xFF) >> 6) & 0x2) >> 1) -+ -+#define t(func) ((a0(func) ^ a1(func)) & 0x1) -+#define b0(func) (t(func) | a0(func)) -+#define b1(func) ((~t(func) & 1) | a1(func)) -+ -+#define START_SYS_CALL_ADDR(func) \ -+ (b1(func) << 14) | (b0(func) << 13) | ((func & 0x3F) << 7) -+ -+void sw64_cpu_do_interrupt(CPUState *cs) -+{ -+ int i = cs->exception_index; -+ -+ cs->exception_index = -1; -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ switch (i) { -+ case EXCP_OPCDEC: -+ cpu_abort(cs, "ILLEGAL INSN"); -+ break; -+ case EXCP_CALL_SYS: -+ i = START_SYS_CALL_ADDR(env->error_code); -+ if (i <= 0x3F) { -+ i += 0x4000; -+ } else if (i >= 0x40 && i <= 0x7F) { -+ i += 0x2000; -+ } else if (i >= 0x80 && i <= 0x8F) { -+ i += 0x6000; -+ } -+ break; -+ case EXCP_ARITH: -+ env->error_code = -1; -+ env->csr[EXC_PC] = env->pc - 4; -+ env->csr[EXC_SUM] = 1; -+ i = 0xB80; -+ break; -+ case EXCP_UNALIGN: -+ i = 0xB00; -+ env->csr[EXC_PC] = env->pc - 4; -+ break; -+ case EXCP_CLK_INTERRUPT: -+ case EXCP_DEV_INTERRUPT: -+ i = 0xE80; -+ break; -+ case EXCP_MMFAULT: -+ i = 0x980; -+ env->csr[EXC_PC] = env->pc; -+ break; -+ case EXCP_II0: -+ env->csr[EXC_PC] = env->pc; -+ i = 0xE00; -+ break; -+ default: -+ break; -+ } -+ env->pc = env->hm_entry + i; -+ env->flags = ENV_FLAG_HM_MODE; -+} -+ -+bool sw64_cpu_exec_interrupt(CPUState *cs, int interrupt_request) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ int idx = -1; -+ /* We never take interrupts while in PALmode. */ -+ if (env->flags & ENV_FLAG_HM_MODE) -+ return false; -+ -+ if (interrupt_request & CPU_INTERRUPT_II0) { -+ idx = EXCP_II0; -+ env->csr[INT_STAT] |= 1UL << 6; -+ if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -+ return false; -+ cs->interrupt_request &= ~CPU_INTERRUPT_II0; -+ goto done; -+ } -+ -+ if (interrupt_request & CPU_INTERRUPT_TIMER) { -+ idx = EXCP_CLK_INTERRUPT; -+ env->csr[INT_STAT] |= 1UL << 4; -+ if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -+ return false; -+ cs->interrupt_request &= ~CPU_INTERRUPT_TIMER; -+ goto done; -+ } -+ -+ if (interrupt_request & CPU_INTERRUPT_HARD) { -+ idx = EXCP_DEV_INTERRUPT; -+ env->csr[INT_STAT] |= 1UL << 12; -+ if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -+ return false; -+ cs->interrupt_request &= ~CPU_INTERRUPT_HARD; -+ goto done; -+ } -+ -+ if (interrupt_request & CPU_INTERRUPT_PCIE) { -+ idx = EXCP_DEV_INTERRUPT; -+ env->csr[INT_STAT] |= 1UL << 1; -+ env->csr[INT_PCI_INT] = 0x10; -+ if ((env->csr[IER] & env->csr[INT_STAT]) == 0) -+ return false; -+ cs->interrupt_request &= ~CPU_INTERRUPT_PCIE; -+ goto done; -+ } -+ -+done: -+ if (idx >= 0) { -+ cs->exception_index = idx; -+ env->error_code = 0; -+ env->csr[EXC_PC] = env->pc; -+ sw64_cpu_do_interrupt(cs); -+ return true; -+ } -+ -+ return false; -+} - #endif - - static void update_fpcr_status_mask(CPUSW64State* env) { -@@ -286,7 +393,9 @@ void cpu_sw64_store_fpcr(CPUSW64State* env, uint64_t val) { - uint64_t helper_read_csr(CPUSW64State *env, uint64_t index) - { - if (index == PRI_BASE) -- return 0x10000; -+ env->csr[index] = 0x10000; -+ if (index == SHTCLOCK) -+ env->csr[index] = qemu_clock_get_ns(QEMU_CLOCK_HOST) / 40; - return env->csr[index]; - } - -@@ -311,9 +420,12 @@ void helper_write_csr(CPUSW64State *env, uint64_t index, uint64_t va) - (index == ITB_IS) || (index == PTBR)) { - tlb_flush(cs); - } -- if (index == INT_CLR || index == INT_PCI_INT) { -+ if (index == INT_CLR) { - env->csr[INT_STAT] &= ~va; - } -+ if ((index == TIMER_CTL) && (va == 1)) { -+ timer_mod(cpu->alarm_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + env->csr[TIMER_TH]); -+ } - - if (index == TIMER_CTL && env->csr[index] == 1) { - timer_mod(cpu->alarm_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1000000000 / 250); -diff --git a/target/sw64/kvm.c b/target/sw64/kvm.c -index fc134c83fb..c38db7cabe 100644 ---- a/target/sw64/kvm.c -+++ b/target/sw64/kvm.c -@@ -25,7 +25,6 @@ - #include "hw/boards.h" - #include "qemu/log.h" - --#define init_pc 0xffffffff80011000 - const KVMCapabilityInfo kvm_arch_required_capabilities[] = { - KVM_CAP_LAST_INFO - }; -@@ -71,6 +70,7 @@ void kvm_sw64_reset_vcpu(SW64CPU *cpu) - CPUState *cs = CPU(cpu); - struct kvm_regs *regs; - int ret; -+ struct vcpucb *vcb; - - regs = (struct kvm_regs *)cpu->k_regs; - regs->pc = init_pc; -@@ -82,6 +82,9 @@ void kvm_sw64_reset_vcpu(SW64CPU *cpu) - abort(); - } - -+ vcb = (struct vcpucb *)cpu->k_vcb; -+ vcb->vcpu_irq_disabled = 1; -+ - ret = kvm_vcpu_ioctl(cs, KVM_SW64_VCPU_INIT, NULL); - - if (ret < 0) { -@@ -113,12 +116,38 @@ int kvm_arch_destroy_vcpu(CPUState *cs) - - int kvm_arch_get_registers(CPUState *cs) - { -- int ret; -+ int ret, i; - SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ - ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &cpu->k_regs); - if (ret < 0) - return ret; -- return kvm_vcpu_ioctl(cs, KVM_SW64_GET_VCB, &cpu->k_vcb); -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_SW64_GET_VCB, &cpu->k_vcb); -+ if (ret < 0) -+ return ret; -+ -+ for (i = 0; i < 16; i++) -+ env->ir[i] = cpu->k_regs[i]; -+ -+ env->ir[16] = cpu->k_regs[155]; -+ env->ir[17] = cpu->k_regs[156]; -+ env->ir[18] = cpu->k_regs[157]; -+ -+ for (i = 19; i < 29; i++) -+ env->ir[i] = cpu->k_regs[i-3]; -+ -+ env->ir[29] = cpu->k_regs[154]; -+ -+ if (cpu->k_regs[152] >> 3) -+ env->ir[30] = cpu->k_vcb[3]; /* usp */ -+ else -+ env->ir[30] = cpu->k_vcb[2]; /* ksp */ -+ -+ env->pc = cpu->k_regs[153]; -+ -+ return 0; - } - - int kvm_arch_put_registers(CPUState *cs, int level) -@@ -126,15 +155,88 @@ int kvm_arch_put_registers(CPUState *cs, int level) - int ret; - SW64CPU *cpu = SW64_CPU(cs); - struct vcpucb *vcb; -+ -+ if (level == KVM_PUT_RUNTIME_STATE) { -+ int i; -+ CPUSW64State *env = &cpu->env; -+ -+ for (i = 0; i < 16; i++) -+ cpu->k_regs[i] = env->ir[i]; -+ -+ for (i = 19; i < 29; i++) -+ cpu->k_regs[i-3] = env->ir[i]; -+ -+ cpu->k_regs[155] = env->ir[16]; -+ cpu->k_regs[156] = env->ir[17]; -+ cpu->k_regs[157] = env->ir[18]; -+ -+ cpu->k_regs[154] = env->ir[29]; -+ -+ if (cpu->k_regs[152] >> 3) -+ cpu->k_vcb[3] = env->ir[30]; /* usp */ -+ else -+ cpu->k_vcb[2] = env->ir[30]; /* ksp */ -+ -+ cpu->k_regs[153] = env->pc; -+ } -+ - ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &cpu->k_regs); - if (ret < 0) - return ret; - vcb = (struct vcpucb *)cpu->k_vcb; - vcb->whami = kvm_arch_vcpu_id(cs); - fprintf(stderr,"vcpu %ld init.\n", vcb->whami); -+ -+ if (level == KVM_PUT_RESET_STATE) -+ vcb->pcbb = 0; -+ - return kvm_vcpu_ioctl(cs, KVM_SW64_SET_VCB, &cpu->k_vcb); - } - -+static const uint32_t brk_insn = 0x00000080; -+ -+int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) -+{ -+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || -+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) -+{ -+ static uint32_t brk; -+ -+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || -+ brk != brk_insn || -+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+int kvm_arch_insert_hw_breakpoint(target_ulong addr, -+ target_ulong len, int type) -+{ -+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); -+ return -EINVAL; -+} -+ -+int kvm_arch_remove_hw_breakpoint(target_ulong addr, -+ target_ulong len, int type) -+{ -+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); -+ return -EINVAL; -+} -+ -+void kvm_arch_remove_all_hw_breakpoints(void) -+{ -+ qemu_log_mask(LOG_UNIMP, "%s: not implemented\n", __func__); -+} -+ - int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, - int vector, PCIDevice *dev) - { -@@ -156,10 +258,42 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) - return MEMTXATTRS_UNSPECIFIED; - } - -+bool kvm_sw64_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit) -+{ -+ SW64CPU *cpu = SW64_CPU(cs); -+ CPUSW64State *env = &cpu->env; -+ -+ /* Ensure PC is synchronised */ -+ kvm_cpu_synchronize_state(cs); -+ -+ if (cs->singlestep_enabled) { -+ return true; -+ } else if (kvm_find_sw_breakpoint(cs, debug_exit->epc)) { -+ return true; -+ } else { -+ error_report("%s: unhandled debug exit (%"PRIx64", %"PRIx64")", -+ __func__, env->pc, debug_exit->epc); -+ } -+ -+ return false; -+} - - int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) - { -- return -1; -+ int ret = 0; -+ -+ switch (run->exit_reason) { -+ case KVM_EXIT_DEBUG: -+ if (kvm_sw64_handle_debug(cs, &run->debug.arch)) { -+ ret = EXCP_DEBUG; -+ } /* otherwise return to guest */ -+ break; -+ default: -+ qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n", -+ __func__, run->exit_reason); -+ break; -+ } -+ return ret; - } - - bool kvm_arch_stop_on_emulation_error(CPUState *cs) -@@ -213,3 +347,7 @@ bool kvm_arch_cpu_check_are_resettable(void) - { - return true; - } -+ -+void kvm_arch_accel_class_init(ObjectClass *oc) -+{ -+} -diff --git a/target/sw64/kvm_sw64.h b/target/sw64/kvm_sw64.h -index 5ebd4ec6fd..81dd760008 100644 ---- a/target/sw64/kvm_sw64.h -+++ b/target/sw64/kvm_sw64.h -@@ -44,4 +44,13 @@ typedef struct SW64HostCPUClass { - uint32_t target; - const char *dtb_compatible; - } SW64HostCPUClass; -+ -+/** -+ * kvm_sw64_handle_debug: -+ * @cs: CPUState -+ * @debug_exit: debug part of the KVM exit structure -+ * -+ * Returns: TRUE if the debug exception was handled. -+ */ -+bool kvm_sw64_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit); - #endif -diff --git a/target/sw64/machine.c b/target/sw64/machine.c -index df18d3faba..93b1968ad8 100644 ---- a/target/sw64/machine.c -+++ b/target/sw64/machine.c -@@ -11,7 +11,7 @@ VMStateDescription vmstate_sw64_cpu = { - .fields = (VMStateField[]) { - #ifdef CONFIG_KVM - VMSTATE_UINTTL_ARRAY(k_regs, SW64CPU, 158), -- VMSTATE_UINTTL_ARRAY(k_vcb, SW64CPU, 36), -+ VMSTATE_UINTTL_ARRAY(k_vcb, SW64CPU, 48), - #endif - VMSTATE_END_OF_LIST() - } -diff --git a/target/sw64/meson.build b/target/sw64/meson.build -index ee49e45927..332f2c2ee6 100644 ---- a/target/sw64/meson.build -+++ b/target/sw64/meson.build -@@ -4,6 +4,7 @@ sw64_ss.add(files( - 'exception.c', - 'float_helper.c', - 'helper.c', -+ 'gdbstub.c', - 'int_helper.c', - 'profile.c', - 'simd_helper.c', -diff --git a/target/sw64/translate.c b/target/sw64/translate.c -index 37b7e89077..1e725b9294 100644 ---- a/target/sw64/translate.c -+++ b/target/sw64/translate.c -@@ -2298,7 +2298,7 @@ DisasJumpType translate_one(DisasContextBase *dcbase, uint32_t insn, - /* RCID */ - if (disp16 && unlikely(ra == 31)) break; - va = load_gir(ctx, ra); -- read_csr(0xc4, va); -+ read_csr(0xc9, va); - break; - case 0x0080: - /* HALT */ -diff --git a/tcg/sw64/tcg-target.c.inc b/tcg/sw64/tcg-target.c.inc -index 982f159e23..da938a7382 100755 ---- a/tcg/sw64/tcg-target.c.inc -+++ b/tcg/sw64/tcg-target.c.inc -@@ -10,7 +10,6 @@ - the size of the operation performed. If we know the values match, it - makes things much cleaner. */ - QEMU_BUILD_BUG_ON(TCG_TYPE_I32 != 0 || TCG_TYPE_I64 != 1); --static const tcg_insn_unit *tb_ret_addr; - - #ifdef CONFIG_DEBUG_TCG - static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { -@@ -33,13 +32,14 @@ static const int tcg_target_reg_alloc_order[] = { - TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3, TCG_REG_X4, - TCG_REG_X5, TCG_REG_X6, TCG_REG_X7, TCG_REG_X8, - -- TCG_REG_X22, TCG_REG_X23, TCG_REG_X24, /*TCG_REG_X25, TCG_REG_X26, TCG_REG_X27, */ -+ TCG_REG_X22, TCG_REG_X23, /* TCG_REG_X24, TCG_REG_X25, TCG_REG_X26, TCG_REG_X27, */ - - /* TCG_REG_SP=TCG_REG_X15 saved for system*/ - TCG_REG_X16, TCG_REG_X17, TCG_REG_X18, TCG_REG_X19, TCG_REG_X20, TCG_REG_X21, TCG_REG_X28, /* TCG_REG_X29, TCG_REG_X30, TCG_REG_X31 */ - - /* TCG_REG_TMP=TCG_REG_X27 reserved as temporary register */ - /* TCG_REG_TMP2=TCG_REG_X25 reserved as temporary register */ -+ /* TCG_REG_TMP3=TCG_REG_X24 reserved as temporary register */ - /* TCG_REG_RA=TCG_REG_X26 reserved as temporary */ - /* TCG_REG_GP=TCG_REG_X29 gp saved for system*/ - /* TCG_REG_SP=TCG_REG_X30 sp saved for system*/ -@@ -66,27 +66,103 @@ static const int tcg_target_call_oarg_regs[1] = { - - #define TCG_REG_TMP TCG_REG_X27 - #define TCG_REG_TMP2 TCG_REG_X25 -+#define TCG_REG_TMP3 TCG_REG_X24 - #define TCG_FLOAT_TMP TCG_REG_F10 - #define TCG_FLOAT_TMP2 TCG_REG_F11 - -+#define REG0(I) (const_args[I] ? TCG_REG_ZERO : (TCGReg)args[I]) -+#define tcg_out_insn_jump tcg_out_insn_ldst -+#define tcg_out_insn_bitReg tcg_out_insn_simpleReg -+#define zeroExt 0 -+#define sigExt 1 -+#define noPara 0//represent this parament of function isnot needed. -+ -+#ifndef CONFIG_SOFTMMU -+#define USE_GUEST_BASE (guest_base != 0 || TARGET_LONG_BITS == 32) -+#define TCG_REG_GUEST_BASE TCG_REG_X14 -+#endif -+ -+static bool reloc_pc21(tcg_insn_unit *src_rw, const tcg_insn_unit *target) -+{ -+ const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); -+ ptrdiff_t offset = target - src_rx -1; -+ -+ if (offset == sextract64(offset, 0, 21)) { -+ /* read instruction, mask away previous PC_REL21 parameter contents, -+ set the proper offset, then write back the instruction. */ -+ *src_rw = deposit32(*src_rw, 0, 21, offset); -+ return true; -+ } -+ return false; -+} -+ -+static bool patch_reloc(tcg_insn_unit *code_ptr, int type, intptr_t value, intptr_t addend) -+{ -+ tcg_debug_assert(addend == 0); -+ switch (type) { -+ case R_SW_64_BRADDR: -+ value = value; -+ return reloc_pc21(code_ptr, (const tcg_insn_unit *)value); -+ default: -+ g_assert_not_reached(); -+ } -+} -+ -+/* -+* contact with "tcg-target-con-str.h" -+*/ -+#define TCG_CT_CONST_ZERO 0x100 -+#define TCG_CT_CONST_LONG 0x200 -+#define TCG_CT_CONST_MONE 0x400 -+#define TCG_CT_CONST_ORRI 0x800 -+#define TCG_CT_CONST_WORD 0X1000 -+#define TCG_CT_CONST_U8 0x2000 -+#define TCG_CT_CONST_S8 0X4000 -+ - #define ALL_GENERAL_REGS 0xffffffffu -+#define ALL_VECTOR_REGS 0xffffffff00000000ull -+ -+#ifdef CONFIG_SOFTMMU -+#define ALL_QLDST_REGS \ -+ (ALL_GENERAL_REGS & ~((1 << TCG_REG_X0) | (1 << TCG_REG_X1) | \ -+ (1 << TCG_REG_X2) | (1 << TCG_REG_X3))) -+#else - #define ALL_QLDST_REGS ALL_GENERAL_REGS --#define PUSH_SIZE ((15-9+1+1) * 8) --#define FRAME_SIZE \ -- ((PUSH_SIZE \ -- + TCG_STATIC_CALL_ARGS_SIZE \ -- + CPU_TEMP_BUF_NLONGS * sizeof(long) \ -- + TCG_TARGET_STACK_ALIGN - 1) \ -- & ~(TCG_TARGET_STACK_ALIGN - 1)) -- --/* We encode the format of the insn into the beginning of the name, so that -- we can have the preprocessor help "typecheck" the insn vs the output -- function. We don't have nice names for the formats, so we use the section -- number of the architecture reference manual in which the instruction -- group is described. */ --#define OPC_OP(x) ((x & 0x3f) << 26) --#define OPC_FUNC(x) ((x & 0xff) << 5) --#define OPC_FUNC_COMPLEX(x) ((x & 0xff) << 10) -+#endif -+ -+/* sw test if a constant matches the constraint */ -+static bool tcg_target_const_match(tcg_target_long val, TCGType type, int ct) -+{ -+ if (ct & TCG_CT_CONST) { -+ return 1; -+ } -+ if (type == TCG_TYPE_I32) { -+ val = (int32_t)val; -+ } -+ if ((ct & TCG_CT_CONST_U8) && 0 <= val && val <= 255) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_LONG)) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_MONE)) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_ORRI)) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_WORD)) { -+ return 1; -+ } -+ if ((ct & TCG_CT_CONST_ZERO) && val == 0) { -+ return 1; -+ } -+ return 0; -+} -+ -+#define OPC_OP(x) (((x) & 0x3f) << 26) -+#define OPC_FUNC(x) (((x) & 0xff) << 5) -+#define OPC_FUNC_COMPLEX(x) (((x) & 0xff) << 10) - typedef enum { - OPC_NOP =0X43ff075f, - OPC_SYS_CALL =OPC_OP(0x00), -@@ -103,7 +179,7 @@ typedef enum { - OPC_VLDD =OPC_OP(0x0D), - OPC_VSTS =OPC_OP(0x0E), - OPC_VSTD =OPC_OP(0x0F), -- -+ - OPC_LDBU =OPC_OP(0x20), - OPC_LDHU =OPC_OP(0x21), - OPC_LDW =OPC_OP(0x22), -@@ -120,7 +196,7 @@ typedef enum { - OPC_PRI_ST =OPC_OP(0x2D), - OPC_FSTS =OPC_OP(0x2E), - OPC_FSTD =OPC_OP(0x2F), -- -+ - OPC_BEQ =OPC_OP(0x30), - OPC_BNE =OPC_OP(0x31), - OPC_BLT =OPC_OP(0x32), -@@ -129,7 +205,7 @@ typedef enum { - OPC_BGE =OPC_OP(0x35), - OPC_BLBC =OPC_OP(0x36), - OPC_BLBS =OPC_OP(0x37), -- -+ - OPC_FBEQ =OPC_OP(0x38), - OPC_FBNE =OPC_OP(0x39), - OPC_FBLT =OPC_OP(0x3A), -@@ -138,7 +214,7 @@ typedef enum { - OPC_FBGE =OPC_OP(0x3D), - OPC_LDI =OPC_OP(0x3E), - OPC_LDIH =OPC_OP(0x3F), -- -+ - OPC_ADDW =(OPC_OP(0x10) | OPC_FUNC(0x0)), - OPC_ADDW_I =(OPC_OP(0x12) | OPC_FUNC(0x0)), - OPC_SUBW =(OPC_OP(0x10) | OPC_FUNC(0x1)), -@@ -147,62 +223,62 @@ typedef enum { - OPC_S4ADDW_I =(OPC_OP(0x12) | OPC_FUNC(0x02)), - OPC_S4SUBW =(OPC_OP(0x10) | OPC_FUNC(0x03)), - OPC_S4SUBW_I =(OPC_OP(0x12) | OPC_FUNC(0x03)), -- -+ - OPC_S8ADDW =(OPC_OP(0x10) | OPC_FUNC(0x04)), - OPC_S8ADDW_I =(OPC_OP(0x12) | OPC_FUNC(0x04)), - OPC_S8SUBW =(OPC_OP(0x10) | OPC_FUNC(0x05)), - OPC_S8SUBW_I =(OPC_OP(0x12) | OPC_FUNC(0x05)), -- -+ - OPC_ADDL =(OPC_OP(0x10) | OPC_FUNC(0x8)), - OPC_ADDL_I =(OPC_OP(0x12) | OPC_FUNC(0x8)), - OPC_SUBL =(OPC_OP(0x10) | OPC_FUNC(0x9)), - OPC_SUBL_I =(OPC_OP(0x12) | OPC_FUNC(0x9)), -- -+ - OPC_S4ADDL =(OPC_OP(0x10) | OPC_FUNC(0xA)), - OPC_S4ADDL_I =(OPC_OP(0x12) | OPC_FUNC(0xA)), - OPC_S4SUBL =(OPC_OP(0x10) | OPC_FUNC(0xB)), - OPC_S4SUBL_I =(OPC_OP(0x12) | OPC_FUNC(0xB)), -- -+ - OPC_S8ADDL =(OPC_OP(0x10) | OPC_FUNC(0xC)), - OPC_S8ADDL_I =(OPC_OP(0x12) | OPC_FUNC(0xC)), - OPC_S8SUBL =(OPC_OP(0x10) | OPC_FUNC(0xD)), - OPC_S8SUBL_I =(OPC_OP(0x12) | OPC_FUNC(0xD)), -- -+ - OPC_MULW =(OPC_OP(0x10) | OPC_FUNC(0x10)), - OPC_MULW_I =(OPC_OP(0x12) | OPC_FUNC(0x10)), - OPC_MULL =(OPC_OP(0x10) | OPC_FUNC(0x18)), - OPC_MULL_I =(OPC_OP(0x12) | OPC_FUNC(0x18)), -- -+ - OPC_UMULH =(OPC_OP(0x10) | OPC_FUNC(0x19)), - OPC_UMULH_I =(OPC_OP(0x12) | OPC_FUNC(0x19)), -- -+ - OPC_CTPOP =(OPC_OP(0x10) | OPC_FUNC(0x58)), - OPC_CTLZ =(OPC_OP(0x10) | OPC_FUNC(0x59)), - OPC_CTTZ =(OPC_OP(0x10) | OPC_FUNC(0x5A)), -- -+ - OPC_ZAP =(OPC_OP(0x10) | OPC_FUNC(0x68)), - OPC_ZAP_I =(OPC_OP(0x12) | OPC_FUNC(0x68)), - OPC_ZAPNOT =(OPC_OP(0x10) | OPC_FUNC(0x69)), - OPC_ZAPNOT_I =(OPC_OP(0x12) | OPC_FUNC(0x69)), -- -+ - OPC_SEXTB =(OPC_OP(0x10) | OPC_FUNC(0x6A)), - OPC_SEXTB_I =(OPC_OP(0x12) | OPC_FUNC(0x6A)), - OPC_SEXTH =(OPC_OP(0x10) | OPC_FUNC(0x6B)), - OPC_SEXTH_I =(OPC_OP(0x12) | OPC_FUNC(0x6B)), -- -+ - OPC_CMPEQ =(OPC_OP(0x10) | OPC_FUNC(0x28)), - OPC_CMPEQ_I =(OPC_OP(0x12) | OPC_FUNC(0x28)), -- -+ - OPC_CMPLT =(OPC_OP(0x10) | OPC_FUNC(0x29)), - OPC_CMPLT_I =(OPC_OP(0x12) | OPC_FUNC(0x29)), - OPC_CMPLE =(OPC_OP(0x10) | OPC_FUNC(0x2A)), - OPC_CMPLE_I =(OPC_OP(0x12) | OPC_FUNC(0x2A)), -- -+ - OPC_CMPULT =(OPC_OP(0x10) | OPC_FUNC(0x2B)), - OPC_CMPULT_I =(OPC_OP(0x12) | OPC_FUNC(0x2B)), - OPC_CMPULE =(OPC_OP(0x10) | OPC_FUNC(0x2C)), - OPC_CMPULE_I =(OPC_OP(0x12) | OPC_FUNC(0x2C)), -- -+ - OPC_AND =(OPC_OP(0x10) | OPC_FUNC(0x38)), - OPC_BIC =(OPC_OP(0x10) | OPC_FUNC(0x39)), - OPC_BIS =(OPC_OP(0x10) | OPC_FUNC(0x3A)), -@@ -216,14 +292,14 @@ typedef enum { - OPC_ORNOT_I =(OPC_OP(0x12) | OPC_FUNC(0x3B)), - OPC_XOR_I =(OPC_OP(0x12) | OPC_FUNC(0x3C)), - OPC_EQV_I =(OPC_OP(0x12) | OPC_FUNC(0x3D)), -- -+ - OPC_SLL =(OPC_OP(0x10) | OPC_FUNC(0x48)), - OPC_SRL =(OPC_OP(0x10) | OPC_FUNC(0x49)), - OPC_SRA =(OPC_OP(0x10) | OPC_FUNC(0x4A)), - OPC_SLL_I =(OPC_OP(0x12) | OPC_FUNC(0x48)), - OPC_SRL_I =(OPC_OP(0x12) | OPC_FUNC(0x49)), - OPC_SRA_I =(OPC_OP(0x12) | OPC_FUNC(0x4A)), -- -+ - OPC_SELEQ =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x00)), - OPC_SELGE =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x01)), - OPC_SELGT =(OPC_OP(0x11) | OPC_FUNC_COMPLEX(0x02)), -@@ -240,7 +316,7 @@ typedef enum { - OPC_SELNE_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x05)), - OPC_SELLBC_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x06)), - OPC_SELLBS_I =(OPC_OP(0x13) | OPC_FUNC_COMPLEX(0x07)), -- -+ - OPC_INS0B =(OPC_OP(0x10) | OPC_FUNC(0x40)), - OPC_INS1B =(OPC_OP(0x10) | OPC_FUNC(0x41)), - OPC_INS2B =(OPC_OP(0x10) | OPC_FUNC(0x42)), -@@ -258,39 +334,39 @@ typedef enum { - OPC_INS6B_I =(OPC_OP(0x12) | OPC_FUNC(0x46)), - OPC_INS7B_I =(OPC_OP(0x12) | OPC_FUNC(0x47)), - -- OPC_EXT0B =(OPC_OP(0x10) | OPC_FUNC(0x50)), -- OPC_EXT1B =(OPC_OP(0x10) | OPC_FUNC(0x51)), -- OPC_EXT2B =(OPC_OP(0x10) | OPC_FUNC(0x52)), -- OPC_EXT3B =(OPC_OP(0x10) | OPC_FUNC(0x53)), -- OPC_EXT4B =(OPC_OP(0x10) | OPC_FUNC(0x54)), -- OPC_EXT5B =(OPC_OP(0x10) | OPC_FUNC(0x55)), -- OPC_EXT6B =(OPC_OP(0x10) | OPC_FUNC(0x56)), -- OPC_EXT7B =(OPC_OP(0x10) | OPC_FUNC(0x57)), -- OPC_EXT0B_I =(OPC_OP(0x12) | OPC_FUNC(0x50)), -- OPC_EXT1B_I =(OPC_OP(0x12) | OPC_FUNC(0x51)), -- OPC_EXT2B_I =(OPC_OP(0x12) | OPC_FUNC(0x52)), -- OPC_EXT3B_I =(OPC_OP(0x12) | OPC_FUNC(0x53)), -- OPC_EXT4B_I =(OPC_OP(0x12) | OPC_FUNC(0x54)), -- OPC_EXT5B_I =(OPC_OP(0x12) | OPC_FUNC(0x55)), -- OPC_EXT6B_I =(OPC_OP(0x12) | OPC_FUNC(0x56)), -- OPC_EXT7B_I =(OPC_OP(0x12) | OPC_FUNC(0x57)), -+ OPC_EXTLB =(OPC_OP(0x10) | OPC_FUNC(0x50)), -+ OPC_EXTLH =(OPC_OP(0x10) | OPC_FUNC(0x51)), -+ OPC_EXTLW =(OPC_OP(0x10) | OPC_FUNC(0x52)), -+ OPC_EXTLL =(OPC_OP(0x10) | OPC_FUNC(0x53)), -+ OPC_EXTHB =(OPC_OP(0x10) | OPC_FUNC(0x54)), -+ OPC_EXTHH =(OPC_OP(0x10) | OPC_FUNC(0x55)), -+ OPC_EXTHW =(OPC_OP(0x10) | OPC_FUNC(0x56)), -+ OPC_EXTHL =(OPC_OP(0x10) | OPC_FUNC(0x57)), -+ OPC_EXTLB_I =(OPC_OP(0x12) | OPC_FUNC(0x50)), -+ OPC_EXTLH_I =(OPC_OP(0x12) | OPC_FUNC(0x51)), -+ OPC_EXTLW_I =(OPC_OP(0x12) | OPC_FUNC(0x52)), -+ OPC_EXTLL_I =(OPC_OP(0x12) | OPC_FUNC(0x53)), -+ OPC_EXTHB_I =(OPC_OP(0x12) | OPC_FUNC(0x54)), -+ OPC_EXTHH_I =(OPC_OP(0x12) | OPC_FUNC(0x55)), -+ OPC_EXTHW_I =(OPC_OP(0x12) | OPC_FUNC(0x56)), -+ OPC_EXTHL_I =(OPC_OP(0x12) | OPC_FUNC(0x57)), - -- OPC_MASK0B =(OPC_OP(0x10) | OPC_FUNC(0x60)), -- OPC_MASK1B =(OPC_OP(0x10) | OPC_FUNC(0x61)), -- OPC_MASK2B =(OPC_OP(0x10) | OPC_FUNC(0x62)), -- OPC_MASK3B =(OPC_OP(0x10) | OPC_FUNC(0x63)), -- OPC_MASK4B =(OPC_OP(0x10) | OPC_FUNC(0x64)), -- OPC_MASK5B =(OPC_OP(0x10) | OPC_FUNC(0x65)), -- OPC_MASK6B =(OPC_OP(0x10) | OPC_FUNC(0x66)), -- OPC_MASK7B =(OPC_OP(0x10) | OPC_FUNC(0x67)), -- OPC_MASK0B_I =(OPC_OP(0x12) | OPC_FUNC(0x60)), -- OPC_MASK1B_I =(OPC_OP(0x12) | OPC_FUNC(0x61)), -- OPC_MASK2B_I =(OPC_OP(0x12) | OPC_FUNC(0x62)), -- OPC_MASK3B_I =(OPC_OP(0x12) | OPC_FUNC(0x63)), -- OPC_MASK4B_I =(OPC_OP(0x12) | OPC_FUNC(0x64)), -- OPC_MASK5B_I =(OPC_OP(0x12) | OPC_FUNC(0x65)), -- OPC_MASK6B_I =(OPC_OP(0x12) | OPC_FUNC(0x66)), -- OPC_MASK7B_I =(OPC_OP(0x12) | OPC_FUNC(0x67)), -+ OPC_MASKLB =(OPC_OP(0x10) | OPC_FUNC(0x60)), -+ OPC_MASKLH =(OPC_OP(0x10) | OPC_FUNC(0x61)), -+ OPC_MASKLW =(OPC_OP(0x10) | OPC_FUNC(0x62)), -+ OPC_MASKLL =(OPC_OP(0x10) | OPC_FUNC(0x63)), -+ OPC_MASKHB =(OPC_OP(0x10) | OPC_FUNC(0x64)), -+ OPC_MASKHH =(OPC_OP(0x10) | OPC_FUNC(0x65)), -+ OPC_MASKHW =(OPC_OP(0x10) | OPC_FUNC(0x66)), -+ OPC_MASKHL =(OPC_OP(0x10) | OPC_FUNC(0x67)), -+ OPC_MASKLB_I =(OPC_OP(0x12) | OPC_FUNC(0x60)), -+ OPC_MASKLH_I =(OPC_OP(0x12) | OPC_FUNC(0x61)), -+ OPC_MASKLW_I =(OPC_OP(0x12) | OPC_FUNC(0x62)), -+ OPC_MASKLL_I =(OPC_OP(0x12) | OPC_FUNC(0x63)), -+ OPC_MASKHB_I =(OPC_OP(0x12) | OPC_FUNC(0x64)), -+ OPC_MASKHH_I =(OPC_OP(0x12) | OPC_FUNC(0x65)), -+ OPC_MASKHW_I =(OPC_OP(0x12) | OPC_FUNC(0x66)), -+ OPC_MASKHL_I =(OPC_OP(0x12) | OPC_FUNC(0x67)), - - OPC_CNPGEB =(OPC_OP(0x10) | OPC_FUNC(0x6C)), - OPC_CNPGEB_I =(OPC_OP(0x12) | OPC_FUNC(0x6C)), -@@ -337,168 +413,162 @@ typedef enum { - OPC_FSQRTD = (OPC_OP(0x18) | OPC_FUNC(0x09)), - }SW_64Insn; - --static void tcg_out_insn_br(TCGContext *s, SW_64Insn insn, TCGReg rd, intptr_t imm64); --static void tcg_out_insn_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t imm16); --static void tcg_out_insn_simpleReg(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, TCGReg rm); --static void tcg_out_insn_simple(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, intptr_t imm64); --static void tcg_out_insn_simpleImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, intptr_t imm64); --static void tcg_out_insn_bitImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, unsigned long imm64); --static void tcg_out_insn_bit(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, unsigned long imm64); --static void tcg_out_insn_complexReg(TCGContext *s, SW_64Insn insn, TCGReg cond, TCGReg rd, TCGReg rn, TCGReg rm); --static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,TCGReg a1,TCGReg a2, bool const_b, TCGReg v1, TCGReg v2); --static bool reloc_pc21(tcg_insn_unit *src_rw, const tcg_insn_unit *target); --static inline uint32_t tcg_in32(TCGContext *s); --static void tcg_out_movr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn); --static void tcg_out_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t offset, bool sign); --static void tcg_out_cond_cmp(TCGContext *s, TCGCond cond, TCGReg ret, TCGArg a, TCGArg b, bool const_b); --static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t aimm); --static inline void tcg_out_extr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm, unsigned int m); --static inline void tcg_out_rotl_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm); --static inline void tcg_out_rotr_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm); --static inline void tcg_out_rotl_Imm(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m); --static inline void tcg_out_rotr_Imm(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m); --static void tcg_out_cltz(TCGContext *s, SW_64Insn opc_clz, TCGType ext, TCGReg rd, TCGReg rn, TCGArg b, bool const_b); --static inline void tcg_out_bswap16u(TCGContext *s, TCGReg rd, TCGReg rn); --static inline void tcg_out_bswap16s(TCGContext *s, TCGReg rd, TCGReg rn); --static inline void tcg_out_bswap32u(TCGContext *s, TCGReg rd, TCGReg rn); --static inline void tcg_out_bswap32s(TCGContext *s, TCGReg rd, TCGReg rn); --static inline void tcg_out_bswap64(TCGContext *s, TCGReg rd, TCGReg rn); --static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, MemOpIdx oi); --static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, MemOpIdx oi, TCGType ext); --static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg arg1, TCGReg arg2); --static void tcg_out_extract(TCGContext *s, TCGReg rd, TCGReg rn, int pos, int len); --static void tcg_out_dep(TCGContext *s, TCGReg rd, TCGReg rn, int pos, int len); --static void tcg_out_mulsh64(TCGContext *s, TCGReg rd, TCGReg rn, TCGReg rm); -- --#define tcg_out_insn_jump tcg_out_insn_ldst --#define tcg_out_insn_bitReg tcg_out_insn_simpleReg -+static inline uint32_t tcg_in32(TCGContext *s) -+{ -+ uint32_t v = *(uint32_t *)s->code_ptr; -+ return v; -+} - --static void tcg_target_init(TCGContext *s) -+/* -+ * SW instruction format of br(alias jump) -+ * insn = opcode[31,26]:Rd[25,21]:disp[20,0], -+ */ -+static void tcg_out_insn_br(TCGContext *s, SW_64Insn insn, TCGReg rd, intptr_t imm64) - { -- tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffffu; -- tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffffu; -- tcg_target_available_regs[TCG_TYPE_V64] = 0xffffffff00000000ull; -- tcg_target_available_regs[TCG_TYPE_V128] = 0xffffffff00000000ull; -- tcg_target_call_clobber_regs = -1ull; -- -- //sw_64 callee saved x9-x15 -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X9); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X10); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X11); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X12); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X13); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X14); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X15); -- -- //sw_64 callee saved f2~f9 -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F2); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F3); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F4); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F5); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F6); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F7); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F8); -- tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F9); -+ tcg_debug_assert(imm64 <= 0xfffff && imm64 >= -0x100000); -+ tcg_out32(s, insn | (rd & 0x1f) << 21 | (imm64 & 0x1fffff)); -+} - -- s->reserved_regs = 0; -- tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); -- tcg_regset_set_reg(s->reserved_regs, TCG_REG_FP); -- tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP); //TCG_REG_X27 -- tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); //TCG_REG_X25 -- tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); //TCG_REG_X26 -- tcg_regset_set_reg(s->reserved_regs, TCG_REG_X29); /*sw_64 platform register */ -- tcg_regset_set_reg(s->reserved_regs, TCG_FLOAT_TMP); /*sw_64 platform register */ -- tcg_regset_set_reg(s->reserved_regs, TCG_FLOAT_TMP2); /*sw_64 platform register */ -+/* -+ * SW instruction format of (load and store) -+ * insn = opcode[31,26]:rd[25,21]:rn[20,16]:disp[15,0] -+ */ -+static void tcg_out_insn_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t imm16) -+{ -+ tcg_debug_assert(imm16 <= 0x7fff && imm16 >= -0x8000); -+ tcg_out32(s, insn | (rd & 0x1f) << 21 | (rn & 0x1f) << 16 | (imm16 & 0xffff)); - } - -+/* -+ * SW instruction format of simple operator for Register -+ * insn = opcode[31,26]:rn(ra)[25,21]:rn(rb)[20,16]:Zeors[15,13]:function[12,5]:rd(rc)[4,0] -+ */ -+static void tcg_out_insn_simpleReg(TCGContext *s, SW_64Insn insn,TCGReg rd, TCGReg rn, TCGReg rm) -+{ -+ tcg_out32(s, insn | (rn & 0x1f) << 21 | (rm & 0x1f) << 16 | (rd & 0x1f)); -+} - --#ifndef CONFIG_SOFTMMU -- #define USE_GUEST_BASE guest_base != 0 -- #define TCG_REG_GUEST_BASE TCG_REG_X14 --#endif -+/* -+ * SW instruction format of simple operator for imm -+ * insn = opcode[31,26]:rn(ra)[25,21]:disp[20,13]:function[12,5]:rd(rc)[4,0] -+ */ -+static void tcg_out_simple(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, intptr_t imm64) -+{ -+ if (imm64 <= 0x7f && imm64 >= -0x80) { -+ tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP3, imm64); -+ tcg_out_insn_simpleReg(s, insn_Reg, rd, rn, TCG_REG_TMP3); -+ } -+} - -+static void tcg_out_insn_simpleImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, unsigned long imm64) -+{ -+ tcg_debug_assert(imm64 <= 255); -+ tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+} - --#define zeroExt 0 --#define sigExt 1 -+/* -+ * sw bit operation: and bis etc -+ */ -+static void tcg_out_bit(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, unsigned long imm64) -+{ -+ if (imm64 <= 255) { -+ tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, imm64); -+ tcg_out_insn_bitReg(s, insn_Reg, rd, rn, TCG_REG_TMP); -+ } -+} - -+/* -+ * SW instruction format of complex operator -+ * insn = opcode[31,26]:rd[25,21]:rn[20,16],function[15,10]:rm[9,5]:rx[4,0] -+ */ -+static void tcg_out_insn_complexReg(TCGContext *s, SW_64Insn insn, TCGReg cond, TCGReg rd, TCGReg rn, TCGReg rm) -+{ -+ tcg_out32(s, insn | (cond & 0x1f) << 21 | (rn & 0x1f) << 16 | (rm & 0x1f) << 5 | (rd & 0x1f)); -+} - --static void tcg_target_qemu_prologue(TCGContext *s) -+static void tcg_out_insn_complexImm(TCGContext *s, SW_64Insn insn, TCGReg cond, TCGReg rd, intptr_t imm8, TCGReg rm) - { -- TCGReg r; -- int ofs; -- -- /* allocate space for all saved registers */ -- /* subl $sp,PUSH_SIZE,$sp */ -- tcg_out_insn_simple(s, OPC_SUBL_I, OPC_SUBL, TCG_REG_SP, TCG_REG_SP, PUSH_SIZE); -- -- /* Push (FP, LR) */ -- /* stl $fp,0($sp) */ -- tcg_out_insn_ldst(s, OPC_STL, TCG_REG_FP, TCG_REG_SP, 0); -- /* stl $26,8($sp) */ -- tcg_out_insn_ldst(s, OPC_STL, TCG_REG_RA, TCG_REG_SP, 8); -+ tcg_out32(s, insn | (cond & 0x1f) << 21 | (imm8 & 0xff) << 13 | (rm & 0x1f) << 5 | (rd & 0x1f)); -+} - -+static void tcg_out_movr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn) -+{ -+ if (ext == TCG_TYPE_I64) { -+ tcg_out_insn_simpleReg(s, OPC_BIS, rd, rn, TCG_REG_ZERO); -+ } else { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rn, 0xf); -+ } -+} - -- /* Set up frame pointer for canonical unwinding. */ -- /* TCG_REG_FP=TCG_REG_SP */ -- tcg_out_movr(s, TCG_TYPE_I64, TCG_REG_FP, TCG_REG_SP); -+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, tcg_target_long orig) -+{ -+ tcg_target_long l0=0, l1=0, l2=0, l3=0, extra=0; -+ tcg_target_long val = orig; -+ TCGReg rs = TCG_REG_ZERO; - -- /* Store callee-preserved regs x9..x14. */ -- for (r = TCG_REG_X9; r <= TCG_REG_X14; r += 1){ -- ofs = (r - TCG_REG_X9 + 2) * 8; -- tcg_out_insn_ldst(s, OPC_STL, r, TCG_REG_SP, ofs); -+ if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) { -+ val = (int32_t)val;//val64bit - } - -- /* Make stack space for TCG locals. */ -- /* subl $sp,FRAME_SIZE-PUSH_SIZE,$sp */ -- tcg_out_insn_simple(s, OPC_SUBL_I, OPC_SUBL, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE - PUSH_SIZE); -+ if (orig == (int16_t)orig) { -+ tcg_out_insn_ldst(s, OPC_LDI, rd, TCG_REG_ZERO, (int16_t)orig); -+ return; -+ } - -- /* Inform TCG about how to find TCG locals with register, offset, size. */ -- tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, -- CPU_TEMP_BUF_NLONGS * sizeof(long)); -+ if (orig == (uint8_t)orig) { -+ tcg_out_insn_simpleImm(s, OPC_BIS_I, rd, TCG_REG_ZERO, (uint8_t)orig); -+ return; -+ } - --#if !defined(CONFIG_SOFTMMU) -- if (USE_GUEST_BASE) { -- tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_GUEST_BASE, guest_base); -- tcg_regset_set_reg(s->reserved_regs, TCG_REG_GUEST_BASE); -+ if (type == TCG_TYPE_I32) { -+ val = (int32_t)val; - } --#endif -- -- /* TCG_AREG0=tcg_target_call_iarg_regs[0], on sw, we mov $16 to $9 */ -- tcg_out_mov(s, TCG_TYPE_I64, TCG_AREG0, tcg_target_call_iarg_regs[0]); -- tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0); - -- /* -- * Return path for goto_ptr. Set return value to 0, a-la exit_tb, -- * and fall through to the rest of the epilogue. -- */ -- tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); -- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, 0); -+ l0 = (int16_t)val; -+ val = (val - l0) >> 16; -+ l1 = (int16_t)val; - -- /* TB epilogue */ -- tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr); -+ if (orig >> 31 == -1 || orig >> 31 == 0) { -+ if (l1 < 0 && orig >= 0) { -+ extra = 0x4000; -+ l1 = (int16_t)(val - 0x4000); -+ } -+ } else { -+ val = (val - l1) >> 16; -+ l2 = (int16_t)val; -+ val = (val - l2) >> 16; -+ l3 = (int16_t)val; - -- /* Remove TCG locals stack space. */ -- /* addl $sp,FRAME_SIZE-PUSH_SIZE,$sp */ -- tcg_out_insn_simple(s, OPC_ADDL_I, OPC_ADDL, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE - PUSH_SIZE); -+ if (l3) { -+ tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, l3); -+ rs = rd; -+ } -+ if (l2) { -+ tcg_out_insn_ldst(s, OPC_LDI, rd, rs, l2); -+ rs = rd; -+ } -+ if (l3 || l2) -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, rd, rd, 32); -+ } - -- /* Restore registers x9..x14. */ -- for (r = TCG_REG_X9; r <= TCG_REG_X14; r += 1) { -- int ofs = (r - TCG_REG_X9 + 2) * 8; -- tcg_out_insn_ldst(s, OPC_LDL, r, TCG_REG_SP, ofs); -+ if (l1) { -+ tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, l1); -+ rs = rd; - } - -- -- /* Pop (FP, LR) */ -- /* ldl $fp,0($sp) */ -- tcg_out_insn_ldst(s, OPC_LDL, TCG_REG_FP, TCG_REG_SP, 0); -- /* ldl $26,8($sp) */ -- tcg_out_insn_ldst(s, OPC_LDL, TCG_REG_RA, TCG_REG_SP, 8); -- -- /* restore SP to previous frame. */ -- /* addl $sp,PUSH_SIZE,$sp */ -- tcg_out_insn_simple(s, OPC_ADDL_I, OPC_ADDL, TCG_REG_SP, TCG_REG_SP, PUSH_SIZE); -- -- tcg_out_insn_jump(s, OPC_RET, TCG_REG_ZERO, TCG_REG_RA, 0); -+ if (extra) { -+ tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, extra); -+ rs = rd; -+ } -+ -+ tcg_out_insn_ldst(s, OPC_LDI, rd, rs, l0); -+ if (type == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } - } - - static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) -@@ -513,614 +583,541 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) - tcg_out_movr(s, type, ret, arg); - break; - } else if (ret < 32) { -+ tcg_debug_assert(0); - break; - } else if (arg < 32) { -+ tcg_debug_assert(0); - break; - } - /* FALLTHRU */ -+ case TCG_TYPE_V64: -+ case TCG_TYPE_V128: -+ tcg_debug_assert(0); -+ break; - default: - g_assert_not_reached(); - } - return true; - } - -+static inline void tcg_out_sxt(TCGContext *s, TCGType ext, MemOp s_bits, -+ TCGReg rd, TCGReg rn) -+{ -+ /* -+ * Using ALIASes SXTB, SXTH, SXTW, of SBFM Xd, Xn, #0, #7|15|31 -+ * int bits = (8 << s_bits) - 1; -+ * tcg_out_sbfm(s, ext, rd, rn, 0, bits); -+ */ -+ switch (s_bits) { -+ case MO_8: -+ tcg_out_insn_simpleReg(s, OPC_SEXTB, rd, TCG_REG_ZERO, rn); -+ break; -+ case MO_16: -+ tcg_out_insn_simpleReg(s, OPC_SEXTH, rd, TCG_REG_ZERO, rn); -+ break; -+ case MO_32: -+ tcg_out_insn_simpleReg(s, OPC_ADDW, rd, rn, TCG_REG_ZERO); -+ break; -+ default: -+ tcg_debug_assert(0); -+ break; -+ } -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } -+} - --static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) -+/* -+ * counting heading/tailing zero numbers -+ */ -+static void tcg_out_ctz64(TCGContext *s, SW_64Insn opc, TCGReg rd, TCGReg rn, TCGArg b, bool const_b) - { -- switch (op) { -- case INDEX_op_goto_ptr: -- return C_O0_I1(r); -+ if (const_b && b == 64) { -+ if (opc == OPC_CTLZ) { -+ tcg_out_insn_simpleReg(s, OPC_CTLZ, rd, TCG_REG_ZERO, rn); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_CTTZ, rd, TCG_REG_ZERO, rn); -+ } -+ } else { -+ if (opc == OPC_CTLZ) { -+ tcg_out_insn_simpleReg(s, OPC_CTLZ, TCG_REG_TMP2, TCG_REG_ZERO, rn); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_CTTZ, TCG_REG_TMP2, TCG_REG_ZERO, rn); -+ } -+ if (const_b) { -+ if (b == -1) { -+ tcg_out_insn_bitReg(s, OPC_ORNOT, rd, TCG_REG_ZERO, TCG_REG_ZERO); -+ tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP2, rd); -+ } else if (b == 0) { -+ tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP2, TCG_REG_ZERO); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I64, rd, b); -+ tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP2, rd); -+ } -+ } else { -+ tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP2, b); -+ } -+ } -+} - -- case INDEX_op_ld8u_i32: -- case INDEX_op_ld8s_i32: -- case INDEX_op_ld16u_i32: -- case INDEX_op_ld16s_i32: -- case INDEX_op_ld_i32: -- case INDEX_op_ld8u_i64: -- case INDEX_op_ld8s_i64: -- case INDEX_op_ld16u_i64: -- case INDEX_op_ld16s_i64: -- case INDEX_op_ld32u_i64: -- case INDEX_op_ld32s_i64: -- case INDEX_op_ld_i64: -- case INDEX_op_neg_i32: -- case INDEX_op_neg_i64: -- case INDEX_op_not_i32: -- case INDEX_op_not_i64: -- case INDEX_op_bswap16_i32: -- case INDEX_op_bswap32_i32: -- case INDEX_op_bswap16_i64: -- case INDEX_op_bswap32_i64: -- case INDEX_op_bswap64_i64: -- case INDEX_op_ext8s_i32: -- case INDEX_op_ext16s_i32: -- case INDEX_op_ext8u_i32: -- case INDEX_op_ext16u_i32: -- case INDEX_op_ext8s_i64: -- case INDEX_op_ext16s_i64: -- case INDEX_op_ext32s_i64: -- case INDEX_op_ext8u_i64: -- case INDEX_op_ext16u_i64: -- case INDEX_op_ext32u_i64: -- case INDEX_op_ext_i32_i64: -- case INDEX_op_extu_i32_i64: -- case INDEX_op_extract_i32: -- case INDEX_op_extract_i64: -- case INDEX_op_sextract_i32: -- case INDEX_op_sextract_i64: -- return C_O1_I1(r, r); -+/* -+ * counting heading/tailing zero numbers -+ */ -+static void tcg_out_ctz32(TCGContext *s, SW_64Insn opc, TCGReg rd, TCGReg rn, TCGArg b, bool const_b) -+{ -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_REG_TMP, rn, 0xf); - -- case INDEX_op_st8_i32: -- case INDEX_op_st16_i32: -- case INDEX_op_st_i32: -- case INDEX_op_st8_i64: -- case INDEX_op_st16_i64: -- case INDEX_op_st32_i64: -- case INDEX_op_st_i64: -- return C_O0_I2(rZ, r); -+ if (const_b && b == 32) { -+ if (opc == OPC_CTLZ) { -+ tcg_out_insn_simpleReg(s, OPC_CTLZ, rd, TCG_REG_ZERO, TCG_REG_TMP); -+ tcg_out_insn_simpleImm(s, OPC_SUBW_I, rd, rd, 32); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_CTTZ, rd, TCG_REG_ZERO, TCG_REG_TMP); -+ tcg_out_insn_complexImm(s, OPC_SELEQ_I, TCG_REG_TMP, rd, 32, rd); -+ } -+ } else { -+ if (opc == OPC_CTLZ) { -+ tcg_out_insn_simpleReg(s, OPC_CTLZ, TCG_REG_TMP2, TCG_REG_ZERO, TCG_REG_TMP); -+ tcg_out_insn_simpleImm(s, OPC_SUBW_I, TCG_REG_TMP2, TCG_REG_TMP2, 32); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_CTTZ, TCG_REG_TMP2, TCG_REG_ZERO, TCG_REG_TMP); -+ tcg_out_insn_complexImm(s, OPC_SELEQ_I, TCG_REG_TMP, TCG_REG_TMP2, 32, TCG_REG_TMP2); -+ } -+ if (const_b) { -+ if (b == -1) { -+ tcg_out_insn_bitReg(s, OPC_ORNOT, rd, TCG_REG_ZERO, TCG_REG_ZERO); -+ tcg_out_insn_complexReg(s, OPC_SELNE, TCG_REG_TMP, rd, TCG_REG_TMP2, rd); -+ } else if (b == 0) { -+ tcg_out_insn_complexReg(s, OPC_SELNE, TCG_REG_TMP, rd, TCG_REG_TMP2, TCG_REG_ZERO); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I32, rd, b); -+ tcg_out_insn_complexReg(s, OPC_SELNE, TCG_REG_TMP, rd, TCG_REG_TMP2, rd); -+ } -+ } else { -+ tcg_out_insn_complexReg(s, OPC_SELNE, TCG_REG_TMP, rd, TCG_REG_TMP2, b); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } -+ } -+} - -- case INDEX_op_add_i32: -- case INDEX_op_add_i64: -- case INDEX_op_sub_i32: -- case INDEX_op_sub_i64: -- return C_O1_I2(r, r, rU);//rA -+/* -+ * memory protect for order of (ld and st) -+ */ -+static void tcg_out_mb(TCGContext *s) -+{ -+ tcg_out32(s, OPC_MEMB); -+} - -- case INDEX_op_setcond_i32: -- case INDEX_op_setcond_i64: -- return C_O1_I2(r, r, rU);//compare,rA -+static inline void tcg_out_bswap16(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn) -+{ -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP2, rn, 1); - -- case INDEX_op_mul_i32: -- case INDEX_op_mul_i64: -- case INDEX_op_div_i32: -- case INDEX_op_div_i64: -- case INDEX_op_divu_i32: -- case INDEX_op_divu_i64: -- case INDEX_op_rem_i32: -- case INDEX_op_rem_i64: -- case INDEX_op_remu_i32: -- case INDEX_op_remu_i64: -- case INDEX_op_muluh_i64: -- case INDEX_op_mulsh_i64: -- return C_O1_I2(r, r, r); -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 0); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 8); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- case INDEX_op_and_i32: -- case INDEX_op_and_i64: -- case INDEX_op_or_i32: -- case INDEX_op_or_i64: -- case INDEX_op_xor_i32: -- case INDEX_op_xor_i64: -- case INDEX_op_andc_i32: -- case INDEX_op_andc_i64: -- case INDEX_op_orc_i32: -- case INDEX_op_orc_i64: -- case INDEX_op_eqv_i32: -- case INDEX_op_eqv_i64: -- return C_O1_I2(r, r, rU);//rL -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 3); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 16); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- case INDEX_op_shl_i32: -- case INDEX_op_shr_i32: -- case INDEX_op_sar_i32: -- case INDEX_op_rotl_i32: -- case INDEX_op_rotr_i32: -- case INDEX_op_shl_i64: -- case INDEX_op_shr_i64: -- case INDEX_op_sar_i64: -- case INDEX_op_rotl_i64: -- case INDEX_op_rotr_i64: -- return C_O1_I2(r, r, ri); -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 2); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 24); - -- case INDEX_op_clz_i32: -- case INDEX_op_clz_i64: -- return C_O1_I2(r, r, r); //rAL -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP2, TCG_REG_TMP); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- case INDEX_op_ctz_i32: -- case INDEX_op_ctz_i64: -- return C_O1_I2(r, r, r);//rAL -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 5); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 32); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- case INDEX_op_brcond_i32: -- case INDEX_op_brcond_i64: -- return C_O0_I2(r, rU);//rA -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 4); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 40); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- case INDEX_op_movcond_i32: -- case INDEX_op_movcond_i64: -- return C_O1_I4(r, r, rU, rZ, rZ);//rA->rU -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 7); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 48); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- case INDEX_op_qemu_ld_i32: -- case INDEX_op_qemu_ld_i64: -- return C_O1_I1(r, l); -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 6); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 56); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP2, TCG_REG_TMP); -+ } -+} - -- case INDEX_op_qemu_st_i32: -- case INDEX_op_qemu_st_i64: -- return C_O0_I2(lZ, l); -+static void tcg_out_bswap32(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn) -+{ -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP2, rn, 3); - -- case INDEX_op_deposit_i32: -- case INDEX_op_deposit_i64: -- return C_O1_I2(r, 0, rZ); -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 2); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 8); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- case INDEX_op_extract2_i32: -- case INDEX_op_extract2_i64: -- return C_O1_I2(r, rZ, rZ); -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 1); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 16); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- case INDEX_op_add2_i32: -- case INDEX_op_add2_i64: -- case INDEX_op_sub2_i32: -- case INDEX_op_sub2_i64: -- return C_O2_I4(r, r, rZ, rZ, rA, rMZ); -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 0); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 24); - -- case INDEX_op_add_vec: -- case INDEX_op_sub_vec: -- case INDEX_op_mul_vec: -- case INDEX_op_xor_vec: -- case INDEX_op_ssadd_vec: -- case INDEX_op_sssub_vec: -- case INDEX_op_usadd_vec: -- case INDEX_op_ussub_vec: -- case INDEX_op_smax_vec: -- case INDEX_op_smin_vec: -- case INDEX_op_umax_vec: -- case INDEX_op_umin_vec: -- case INDEX_op_shlv_vec: -- case INDEX_op_shrv_vec: -- case INDEX_op_sarv_vec: -- return C_O1_I2(w, w, w); -- case INDEX_op_not_vec: -- case INDEX_op_neg_vec: -- case INDEX_op_abs_vec: -- case INDEX_op_shli_vec: -- case INDEX_op_shri_vec: -- case INDEX_op_sari_vec: -- return C_O1_I1(w, w); -- case INDEX_op_ld_vec: -- case INDEX_op_dupm_vec: -- return C_O1_I1(w, r); -- case INDEX_op_st_vec: -- return C_O0_I2(w, r); -- case INDEX_op_dup_vec: -- return C_O1_I1(w, wr); -- case INDEX_op_or_vec: -- case INDEX_op_andc_vec: -- return C_O1_I2(w, w, wO); -- case INDEX_op_and_vec: -- case INDEX_op_orc_vec: -- return C_O1_I2(w, w, wN); -- case INDEX_op_cmp_vec: -- return C_O1_I2(w, w, wZ); -- case INDEX_op_bitsel_vec: -- return C_O1_I3(w, w, w, w); -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP2, TCG_REG_TMP); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -- default: -- g_assert_not_reached(); -- } --} -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 7); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 32); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 6); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 40); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - --static void tcg_out_nop_fill(tcg_insn_unit *p, int count) --{ -- int i; -- for (i = 0; i < count; ++i) { -- p[i] = OPC_NOP; -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 5); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 48); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); -+ -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 4); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 56); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP2, TCG_REG_TMP); - } - } - --/* SW instruction format of syscall -- * insn = opcode[31,26]:Function[25,0], -- */ -- --/* SW instruction format of br(alias jump) -- * insn = opcode[31,26]:Rd[25,21]:disp[20,0], -- */ --static void tcg_out_insn_br(TCGContext *s, SW_64Insn insn, TCGReg rd, intptr_t imm64) -+static void tcg_out_bswap64(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn) - { -- tcg_debug_assert(imm64 <= 0xfffff && imm64 >= -0x100000); -- tcg_out32(s, insn | (rd & 0x1f) << 21 | (imm64 & 0x1fffff)); --} -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP2, rn, 7); - -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 6); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 8); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - --/* SW instruction format of (load and store) -- * insn = opcode[31,26]:rd[25,21]:rn[20,16]:disp[15,0] -- */ --static void tcg_out_insn_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t imm16) --{ -- tcg_debug_assert(imm16 <= 0x7fff && imm16 >= -0x8000); -- tcg_out32(s, insn | (rd & 0x1f) << 21 | (rn & 0x1f) << 16 | (imm16 & 0xffff)); --} -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 5); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 16); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 4); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 24); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); - --/* SW instruction format of simple operator for Register -- * insn = opcode[31,26]:rn(ra)[25,21]:rn(rb)[20,16]:Zeors[15,13]:function[12,5]:rd(rc)[4,0] -- */ --static void tcg_out_insn_simpleReg(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, TCGReg rm) --{ -- tcg_out32(s, insn | (rn & 0x1f) << 21 | (rm & 0x1f) << 16 | (rd & 0x1f)); -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 3); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 32); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); -+ -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 2); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 40); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); -+ -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 1); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 48); -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP); -+ -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, TCG_REG_TMP, rn, 0); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, 56); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP2, TCG_REG_TMP); - } - --/* SW instruction format of simple operator for imm -- * insn = opcode[31,26]:rn(ra)[25,21]:disp[20,13]:function[12,5]:rd(rc)[4,0] -- */ --static void tcg_out_insn_simple(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, intptr_t imm64) -+static void tcg_out_extract(TCGContext *s, TCGReg rd, TCGReg rn, int lsb, int len) - { -- if(imm64 <= 0x7f && imm64 >= -0x80) { -- tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -- } -- else { -- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, imm64); -- tcg_out_insn_simpleReg(s, insn_Reg, rd, rn, TCG_REG_TMP); -- } --} -+ //get 000..111..0000 -+ tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_ZERO); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP, TCG_REG_TMP, 64 - len); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, lsb); -+ /* get rn[lsb, lsb+len-1]-->rd[lsb, lsb+len-1] */ -+ tcg_out_insn_bitReg(s, OPC_AND, rd, rn, TCG_REG_TMP); - -+ /* rd[lsb, lsb+len-1] --> rd[0, len-1] */ -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, rd, rd, lsb); -+} - --static void tcg_out_insn_simpleImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, intptr_t imm64) -+static void tcg_out_dep(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, int lsb, int len) - { -- tcg_debug_assert(imm64 <= 0x7f && imm64 >= -0x80); -- tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+ tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_ZERO); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP, TCG_REG_TMP, 64 - len); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, lsb); -+ -+ /* TCG_REG_TMP2 = rn[msb,lsb] */ -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP2, rn, 64-len); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP2, TCG_REG_TMP2, 64-len-lsb); - -+ /* clear rd[msb,lsb] */ -+ tcg_out_insn_bitReg(s, OPC_BIC, rd, rd, TCG_REG_TMP); -+ /* rd = rd[63:msb+1]:rn[msb,lsb]:rd[lsb-1,0] */ -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, rd, TCG_REG_TMP2); -+ -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } - } - --static void tcg_out_insn_bitImm(TCGContext *s, SW_64Insn insn_Imm, TCGReg rd, TCGReg rn, unsigned long imm64) -+static void tcg_out_mulsh64(TCGContext *s, TCGReg rd, TCGReg rn, TCGReg rm) - { -- tcg_debug_assert(imm64 <= 255); -- tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -+ tcg_out_insn_simpleReg(s, OPC_UMULH, TCG_REG_TMP, rn, rm); -+ -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP2, rn, 63); -+ tcg_out_insn_complexReg(s, OPC_SELEQ, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_ZERO, rm); -+ tcg_out_insn_simpleReg(s, OPC_SUBL, TCG_REG_TMP, TCG_REG_TMP, TCG_REG_TMP2); -+ -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP2, rm, 63); -+ tcg_out_insn_complexReg(s, OPC_SELEQ, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_ZERO, rn); -+ tcg_out_insn_simpleReg(s, OPC_SUBL, rd, TCG_REG_TMP, TCG_REG_TMP2); - } --/* sw bit operation: and bis etc */ --static void tcg_out_insn_bit(TCGContext *s, SW_64Insn insn_Imm, SW_64Insn insn_Reg, TCGReg rd, TCGReg rn, unsigned long imm64) -+ -+static void tcg_out_sar(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGArg a2, bool c2) - { -- if (imm64 <= 255) { -- tcg_out32(s, insn_Imm | (rn & 0x1f) << 21 | (imm64 & 0xff) << 13 | (rd & 0x1f)); -- } -- else { -- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, imm64); -- tcg_out_insn_bitReg(s, insn_Reg, rd, rn, TCG_REG_TMP); -+ unsigned int bits = ext ? 64 : 32; -+ unsigned int max = bits - 1; -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_simpleReg(s, OPC_ADDW, TCG_REG_TMP, rn, TCG_REG_ZERO); -+ -+ if (c2) { -+ tcg_out_insn_simpleImm(s, OPC_SRA_I, rd, TCG_REG_TMP, a2 & max); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_SRA, rd, TCG_REG_TMP, a2); -+ } -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } else { -+ if (c2) { -+ tcg_out_insn_simpleImm(s, OPC_SRA_I, rd, rn, a2 & max); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_SRA, rd, rn, a2); -+ } - } - } - --/* SW instruction format of complex operator -- * insn = opcode[31,26]:rd[25,21]:rn[20,16],function[15,10]:rm[9,5]:rx[4,0] -+/* -+ * memory <=> Reg in (B H W L) bytes - */ --static void tcg_out_insn_complexReg(TCGContext *s, SW_64Insn insn, TCGReg cond, TCGReg rd, TCGReg rn, TCGReg rm) --{ -- tcg_out32(s, insn | (cond & 0x1f) << 21 | (rn & 0x1f) << 16 | (rm & 0x1f) << 5 | (rd & 0x1f)); --} -- --static bool reloc_pc21(tcg_insn_unit *src_rw, const tcg_insn_unit *target) -+static void tcg_out_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t offset, bool sign) - { -- const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw); -- ptrdiff_t offset = target - (src_rx + 1) ; -+ if (offset != sextract64(offset, 0, 15)) { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP2, offset); -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_TMP2, TCG_REG_TMP2, rn); -+ tcg_out_insn_ldst(s, insn, rd, TCG_REG_TMP2, 0); -+ } else { -+ tcg_out_insn_ldst(s, insn, rd, rn, offset); -+ } - -- if (offset == sextract64(offset, 0, 21)) { -- /* read instruction, mask away previous PC_REL21 parameter contents, -- set the proper offset, then write back the instruction. */ -- *src_rw = deposit32(*src_rw, 0, 21, offset); -- return true; -+ switch (insn) { -+ case OPC_LDBU: -+ if (sign) -+ tcg_out_insn_simpleReg(s, OPC_SEXTB, rd, TCG_REG_ZERO, rd); -+ break; -+ case OPC_LDHU: -+ if (sign) -+ tcg_out_insn_simpleReg(s, OPC_SEXTH, rd, TCG_REG_ZERO, rd); -+ break; -+ case OPC_LDW: -+ if (!sign) -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ break; -+ default: -+ break; - } -- return false; - } - --/* sw*/ --static bool patch_reloc(tcg_insn_unit *code_ptr, int type, intptr_t value, intptr_t addend) -+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn, intptr_t ofs) - { -- tcg_debug_assert(addend == 0); - switch (type) { -- case R_SW_64_BRADDR: -- return reloc_pc21(code_ptr, (const tcg_insn_unit *)value); -+ case TCG_TYPE_I32: -+ tcg_out_ldst(s, OPC_LDW, rd, rn, ofs, zeroExt); -+ break; -+ case TCG_TYPE_I64: -+ tcg_out_ldst(s, OPC_LDL, rd, rn, ofs, sigExt); -+ break; -+ case TCG_TYPE_V64: -+ case TCG_TYPE_V128: -+ tcg_debug_assert(0); -+ break; - default: - g_assert_not_reached(); - } - } - --static inline uint32_t tcg_in32(TCGContext *s) -+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg rd,TCGReg rn, intptr_t ofs) - { -- uint32_t v = *(uint32_t *)s->code_ptr; -- return v; --} -- --/*SW Register to register move using ADDL*/ --static void tcg_out_movr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn) --{ -- tcg_out_insn_simpleReg(s, OPC_BIS, rd, rn, TCG_REG_ZERO); -- if (ext == TCG_TYPE_I32){ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ switch (type) { -+ case TCG_TYPE_I32: -+ tcg_out_ldst(s, OPC_STW, rd, rn, ofs, noPara); -+ break; -+ case TCG_TYPE_I64: -+ tcg_out_ldst(s, OPC_STL, rd, rn, ofs, noPara); -+ break; -+ case TCG_TYPE_V64: -+ case TCG_TYPE_V128: -+ tcg_debug_assert(0); -+ break; -+ default: -+ g_assert_not_reached(); - } - } - --/*sw -- *put imm into rd -- */ --static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, tcg_target_long orig) -+static void tcg_out_cond_cmp(TCGContext *s, TCGType ext, TCGCond cond, TCGReg ret, TCGArg a, tcg_target_long b, bool const_b) - { -- long l0, l1, l2=0, l3=0, extra=0; -- tcg_target_long val = orig; -- TCGReg rs = TCG_REG_ZERO; -- -- if (type == TCG_TYPE_I32) -- val = (int32_t)val; -- -- l0 = (int16_t)val; -- val = (val - l0) >> 16; -- l1 = (int16_t)val; -- -- if (orig >> 31 == -1 || orig >> 31 == 0) { -- if (l1 < 0 && orig >= 0) { -- extra = 0x4000; -- l1 = (int16_t)(val - 0x4000); -- } -- } else { -- val = (val - l1) >> 16; -- l2 = (int16_t)val; -- val = (val - l2) >> 16; -- l3 = (int16_t)val; -- -- if (l3) { -- tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, l3); -- rs = rd; -- } -- if (l2) { -- tcg_out_insn_ldst(s, OPC_LDI, rd, rs, l2); -- rs = rd; -- } -- if (l3 || l2) -- tcg_out_insn_simpleImm(s, OPC_SLL_I, rd, rd, 32); -- } -- -- if (l1) { -- tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, l1); -- rs = rd; -+ if (const_b && (b < 0 || b > 0xff)) { -+ tcg_out_movi(s, ext, TCG_REG_TMP2, b); -+ b = TCG_REG_TMP2; -+ const_b = 0; - } -- -- if (extra) { -- tcg_out_insn_ldst(s, OPC_LDIH, rd, rs, extra); -- rs = rd; -- } -- -- tcg_out_insn_ldst(s, OPC_LDI, rd, rs, l0); --} - -- --/*sw --* memory <=> Reg in (B H W L) bytes --*/ --static void tcg_out_ldst(TCGContext *s, SW_64Insn insn, TCGReg rd, TCGReg rn, intptr_t offset, bool sign) --{ -- int16_t lo = offset; -- if (offset != lo) { -- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, offset - lo); -- if (rn != TCG_REG_ZERO) { -- tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_TMP, TCG_REG_TMP, rn); -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_simpleReg(s, OPC_ADDW, a, a, TCG_REG_ZERO); -+ if (!const_b) { -+ tcg_out_insn_simpleReg(s, OPC_ADDW, b, b, TCG_REG_ZERO); -+ } else { -+ b = (int32_t)b; - } -- tcg_out_insn_ldst(s, insn, rd, TCG_REG_TMP, lo); -- } -- else { -- tcg_out_insn_ldst(s, insn, rd, rn, lo); - } - -- switch (insn) { -- case OPC_LDBU: -- if (sign) -- tcg_out_insn_simpleReg(s, OPC_SEXTB, rd, TCG_REG_ZERO, rd); //for micro-op:INDEX_op_ld8s_i32/64,set rd[63,8]=1 -- break; -- case OPC_LDHU: -- if (sign) -- tcg_out_insn_simpleReg(s, OPC_SEXTH, rd, TCG_REG_ZERO, rd); //for micro-op:INDEX_op_ld16s_i32/64,set rd[63,16]=1 -- break; -- case OPC_LDW: -- if (!sign) -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); //for micro-op:INDEX_op_ld32u_i32/64,set rd[63,32]=0 -- break; -- default: -- break; -- } --} -- --/* TCG_REG_TMP stores result_of_condition_compare */ --static void tcg_out_cond_cmp(TCGContext *s, TCGCond cond, TCGReg ret, TCGArg a, TCGArg b, bool const_b) --{ - if (const_b) { -- switch(cond) { -- case TCG_COND_ALWAYS: -- case TCG_COND_NEVER: -- break; -- case TCG_COND_EQ: -- case TCG_COND_NE: -- tcg_out_insn_simple(s, OPC_CMPEQ_I, OPC_CMPEQ, ret, a, b); -- break; -- case TCG_COND_LT: -- case TCG_COND_GE: -- tcg_out_insn_simple(s, OPC_CMPLT_I, OPC_CMPLT, ret, a, b); -- break; -- case TCG_COND_LE: -- case TCG_COND_GT: -- tcg_out_insn_simple(s, OPC_CMPLE_I, OPC_CMPLE, ret, a, b); -- break; -- case TCG_COND_LTU: -- case TCG_COND_GEU: -- tcg_out_insn_simple(s, OPC_CMPULT_I, OPC_CMPULT, ret, a, b); -- break; -- case TCG_COND_LEU: -- case TCG_COND_GTU: -- tcg_out_insn_simple(s, OPC_CMPULE_I, OPC_CMPULE, ret, a, b); -- break; -- }//cond -- }//if (const_b) -- else { -- switch(cond) { -- case TCG_COND_ALWAYS: -- case TCG_COND_NEVER: -- break; -- case TCG_COND_EQ: -- case TCG_COND_NE: -- tcg_out_insn_simpleReg(s, OPC_CMPEQ, ret, a, b); -- break; -- case TCG_COND_LT: -- case TCG_COND_GE: -- tcg_out_insn_simpleReg(s, OPC_CMPLT, ret, a, b); -- break; -- case TCG_COND_LE: -- case TCG_COND_GT: -- tcg_out_insn_simpleReg(s, OPC_CMPLE, ret, a, b); -- break; -- case TCG_COND_LTU: -- case TCG_COND_GEU: -- tcg_out_insn_simpleReg(s, OPC_CMPULT, ret, a, b); -- break; -- case TCG_COND_LEU: -- case TCG_COND_GTU: -- tcg_out_insn_simpleReg(s, OPC_CMPULE, ret, a, b); -- break; -- }//cond -- }//else -- switch(cond) { -- case TCG_COND_ALWAYS: -- case TCG_COND_NEVER: -+ switch (cond) { - case TCG_COND_EQ: -+ case TCG_COND_NE: -+ tcg_out_insn_simpleImm(s, OPC_CMPEQ_I, ret, a, b); -+ break; - case TCG_COND_LT: -+ case TCG_COND_GE: -+ tcg_out_insn_simpleImm(s, OPC_CMPLT_I, ret, a, b); -+ break; - case TCG_COND_LE: -+ case TCG_COND_GT: -+ tcg_out_insn_simpleImm(s, OPC_CMPLE_I, ret, a, b); -+ break; - case TCG_COND_LTU: -+ case TCG_COND_GEU: -+ tcg_out_insn_simpleImm(s, OPC_CMPULT_I, ret, a, b); -+ break; - case TCG_COND_LEU: -+ case TCG_COND_GTU: -+ tcg_out_insn_simpleImm(s, OPC_CMPULE_I, ret, a, b); - break; -- case TCG_COND_NE: -- case TCG_COND_GE: -- case TCG_COND_GT: -- case TCG_COND_GEU: -- case TCG_COND_GTU: -- tcg_out_insn_bitImm(s, OPC_XOR_I, ret, ret, 0x1); -+ default: -+ tcg_debug_assert(0); -+ break; -+ } -+ } else { -+ switch (cond) { -+ case TCG_COND_EQ: -+ case TCG_COND_NE: -+ tcg_out_insn_simpleReg(s, OPC_CMPEQ, ret, a, b); - break; -+ case TCG_COND_LT: -+ case TCG_COND_GE: -+ tcg_out_insn_simpleReg(s, OPC_CMPLT, ret, a, b); -+ break; -+ case TCG_COND_LE: -+ case TCG_COND_GT: -+ tcg_out_insn_simpleReg(s, OPC_CMPLE, ret, a, b); -+ break; -+ case TCG_COND_LTU: -+ case TCG_COND_GEU: -+ tcg_out_insn_simpleReg(s, OPC_CMPULT, ret, a, b); -+ break; -+ case TCG_COND_LEU: -+ case TCG_COND_GTU: -+ tcg_out_insn_simpleReg(s, OPC_CMPULE, ret, a, b); -+ break; -+ default: -+ tcg_debug_assert(0); -+ break; -+ } -+ } -+ -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a, a, 0xf); -+ if (!const_b) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, b, b, 0xf); -+ } -+ } -+ -+ switch (cond) { -+ case TCG_COND_NE: -+ case TCG_COND_GE: -+ case TCG_COND_GT: -+ case TCG_COND_GEU: -+ case TCG_COND_GTU: -+ tcg_out_insn_simpleImm(s, OPC_XOR_I, ret, ret, 0x1); -+ break; -+ case TCG_COND_ALWAYS: -+ case TCG_COND_NEVER: -+ tcg_debug_assert(0); -+ break; -+ default: -+ break; - } - } - --/* sw -+/* - * step1 tcg_out_cmp() ,"eq" and "ne" in the same case with the same insn; - * store compare result by TCG_REG_TMP, for step2; - * step2: jump address with compare result. in last "switch" section, we diff qe/ne by different case with different insn. - */ --static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond cond, TCGArg a, TCGArg b, bool b_const, TCGLabel *l) -+static void tcg_out_brcond(TCGContext *s, TCGType ext, TCGCond cond, TCGArg a, tcg_target_long b, bool b_const, TCGLabel *l) - { - intptr_t offset; - bool need_cmp; - - if (b_const && b == 0 && (cond == TCG_COND_EQ || cond == TCG_COND_NE)) { - need_cmp = false; -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_REG_TMP, a, 0xf); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_BIS, TCG_REG_TMP, a, TCG_REG_ZERO); -+ } - } else { - need_cmp = true; -- tcg_out_cond_cmp(s, cond, TCG_REG_TMP, a, b, b_const); -+ tcg_out_cond_cmp(s, ext, cond, TCG_REG_TMP, a, b, b_const); - } - - if (!l->has_value) { - tcg_out_reloc(s, s->code_ptr, R_SW_64_BRADDR, l, 0); -- offset=0; //offset = tcg_in32(s) >> 5; br $31, 0, do not jump here! -+ offset=0; //offset = tcg_in32(s) >> 5;//luo br $31, 0, do not jump here! - } else { -- offset = tcg_pcrel_diff(s, l->u.value_ptr) ; -- offset = offset >> 2; -+ offset = tcg_pcrel_diff(s, l->u.value_ptr); -+ offset = offset - 4; -+ offset = offset >> 2; - tcg_debug_assert(offset == sextract64(offset, 0, 21)); - } - - if (need_cmp) { -- tcg_out_insn_br(s, OPC_BGT, TCG_REG_TMP, offset); //a cond b,jmp -+ tcg_out_insn_br(s, OPC_BGT, TCG_REG_TMP, offset); - } else if (cond == TCG_COND_EQ) { -- tcg_out_insn_br(s, OPC_BEQ, a, offset); -+ tcg_out_insn_br(s, OPC_BEQ, TCG_REG_TMP, offset); - } else { -- tcg_out_insn_br(s, OPC_BNE, a, offset); -- } --} -- --/*sw -- * contact with "tcg-target-con-str.h" -- */ --#define TCG_CT_CONST_ZERO 0x100 --#define TCG_CT_CONST_LONG 0x200 --#define TCG_CT_CONST_MONE 0x400 --#define TCG_CT_CONST_ORRI 0x800 --#define TCG_CT_CONST_WORD 0X1000 --#define TCG_CT_CONST_U8 0x2000 --#define TCG_CT_CONST_S8 0X4000 -- --#define ALL_GENERAL_REGS 0xffffffffu --#define ALL_VECTOR_REGS 0xffffffff00000000ull -- -- --#ifdef CONFIG_SOFTMMU --/*sw #define ALL_QLDST_REGS */ --#else -- #define ALL_QLDST_REGS ALL_GENERAL_REGS --#endif -- --/* sw test if a constant matches the constraint */ --static bool tcg_target_const_match(int64_t val, TCGType type, int ct) --{ -- if (ct & TCG_CT_CONST) { -- return 1; -- } -- if (type == TCG_TYPE_I32) { -- val = (int32_t)val; -- } -- if ((ct & TCG_CT_CONST_U8) && 0 <= val && val <= 255) { -- return 1; -- } -- if ((ct & TCG_CT_CONST_LONG)) { -- return 1; -- } -- if ((ct & TCG_CT_CONST_MONE)) { -- return 1; -- } -- if ((ct & TCG_CT_CONST_ORRI)) { -- return 1; -- } -- if ((ct & TCG_CT_CONST_WORD)) { -- return 1; -- } -- if ((ct & TCG_CT_CONST_ZERO) && val == 0) { -- return 1; -+ tcg_out_insn_br(s, OPC_BNE, TCG_REG_TMP, offset); - } -- return 0; - } - --static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn, intptr_t ofs) -+static void tcg_out_setcond(TCGContext *s, TCGType ext, TCGCond cond, TCGReg ret, -+ TCGReg a, tcg_target_long b, bool const_b) - { -- switch (type) { -- case TCG_TYPE_I32: -- tcg_out_ldst(s, OPC_LDW, rd, rn, ofs, sigExt); -- break; -- case TCG_TYPE_I64: -- tcg_out_ldst(s, OPC_LDL, rd, rn, ofs, sigExt); -+ switch (cond) { -+ case TCG_COND_EQ: -+ case TCG_COND_LT: -+ case TCG_COND_LE: -+ case TCG_COND_LTU: -+ case TCG_COND_LEU: -+ case TCG_COND_NE: -+ case TCG_COND_GE: -+ case TCG_COND_GT: -+ case TCG_COND_GEU: -+ case TCG_COND_GTU: -+ tcg_out_cond_cmp(s, ext, cond, ret, a, b, const_b); - break; - default: -- g_assert_not_reached(); -+ tcg_abort(); -+ break; - } - } - --static void tcg_out_st(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn, intptr_t ofs) -+static void tcg_out_movcond(TCGContext *s, TCGType ext, TCGCond cond, TCGReg ret, -+ TCGReg a1, tcg_target_long a2, bool const_b, TCGReg v1, TCGReg v2) - { -- switch (type) { -- case TCG_TYPE_I32: -- tcg_out_insn_ldst(s, OPC_STW, rd, rn, ofs); -- break; -- case TCG_TYPE_I64: -- tcg_out_insn_ldst(s, OPC_STL, rd, rn, ofs); -- break; -- default: -- g_assert_not_reached(); -- } -+ tcg_out_cond_cmp(s, ext, cond, TCG_REG_TMP, a1, a2, const_b); -+ tcg_out_insn_complexReg(s, OPC_SELLBS, TCG_REG_TMP, ret, v1, v2); - } - --static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, TCGReg base, intptr_t ofs) -+static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,TCGReg base, intptr_t ofs) - { - if (type <= TCG_TYPE_I64 && val == 0) { - tcg_out_st(s, type, TCG_REG_ZERO, base, ofs); -@@ -1129,66 +1126,123 @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, TCGReg b - return false; - } - --static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t imm64) -+static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,TCGReg rn, int64_t imm64) - { -- if (imm64 >= 0) { -- if(0 <=imm64 && imm64 <= 255) { -- /* we use tcg_out_insn_bitImm because imm64 is between 0~255 */ -- tcg_out_insn_bitImm(s, OPC_ADDL_I, rd, rn, imm64); -- }//aimm>0 && aimm == sextract64(aim, 0, 8) -- else { -- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, imm64); -- tcg_out_insn_simpleReg(s, OPC_ADDL, rd, rn, TCG_REG_TMP); -- }//aimm>0 && aimm != sextract64(aim, 0, 8) -+ if (ext == TCG_TYPE_I64) { -+ if (imm64 >= 0) { -+ if (0 <=imm64 && imm64 <= 255) { -+ /* we use tcg_out_insn_simpleImm because imm64 is between 0~255 */ -+ tcg_out_insn_simpleImm(s, OPC_ADDL_I, rd, rn, imm64); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, imm64); -+ tcg_out_insn_simpleReg(s, OPC_ADDL, rd, rn, TCG_REG_TMP); -+ } -+ } else { -+ if (0 < -imm64 && -imm64 <= 255) { -+ /* we use tcg_out_insn_simpleImm because -imm64 is between 0~255 */ -+ tcg_out_insn_simpleImm(s, OPC_SUBL_I, rd, rn, -imm64); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, -imm64); -+ tcg_out_insn_simpleReg(s, OPC_SUBL, rd, rn, TCG_REG_TMP); -+ } -+ } - } else { -- if(0 < -imm64 && -imm64 <= 255) { -- /* we use tcg_out_insn_bitImm because -imm64 is between 0~255 */ -- tcg_out_insn_bitImm(s, OPC_SUBL_I, rd, rn, -imm64); -- }//aimm<0 && aimm == sextract64(aim, 0, 8) -- else { -- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, -imm64); -- tcg_out_insn_simpleReg(s, OPC_SUBL, rd, rn, TCG_REG_TMP); -- }//aimm<0 && aimm != sextract64(aim, 0, 8) -+ if (imm64 >= 0) { -+ if (0 <=imm64 && imm64 <= 255) { -+ /* we use tcg_out_insn_simpleImm because imm64 is between 0~255 */ -+ tcg_out_insn_simpleImm(s, OPC_ADDW_I, rd, rn, imm64); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, imm64); -+ tcg_out_insn_simpleReg(s, OPC_ADDW, rd, rn, TCG_REG_TMP); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } -+ } else { -+ if (0 < -imm64 && -imm64 <= 255) { -+ /* we use tcg_out_insn_simpleImm because -imm64 is between 0~255 */ -+ tcg_out_insn_simpleImm(s, OPC_SUBW_I, rd, rn, -imm64); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } else { -+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, -imm64); -+ tcg_out_insn_simpleReg(s, OPC_SUBW, rd, rn, TCG_REG_TMP); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } -+ } - } - } - - static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target) - { -- ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2; -+ ptrdiff_t offset = (tcg_pcrel_diff(s, target) - 4) >> 2; - tcg_debug_assert(offset == sextract64(offset, 0, 21)); - tcg_out_insn_br(s, OPC_BR, TCG_REG_ZERO, offset); - } - - static void tcg_out_goto_long(TCGContext *s, const tcg_insn_unit *target) - { -- ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2; -- if (0 <= offset && offset <= 0x1fffff) { -+ ptrdiff_t offset = (tcg_pcrel_diff(s, target) - 4) >> 2; -+ if (offset == sextract64(offset, 0 ,21)) { - tcg_out_insn_br(s, OPC_BR, TCG_REG_ZERO, offset); - } else { - tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, (intptr_t)target); -- tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, TCG_REG_TMP, 0); -+ tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, TCG_REG_TMP, noPara); - } - } - -- --/*sw --* call subroutine --*/ - static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target) - { -- ptrdiff_t offset = tcg_pcrel_diff(s, target) >> 2; -+ ptrdiff_t offset = (tcg_pcrel_diff(s, target) - 4) >> 2; - if (offset == sextract64(offset, 0, 21)) { - tcg_out_insn_br(s, OPC_BSR, TCG_REG_RA, offset); - } else { - tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, (intptr_t)target); -- tcg_out_insn_jump(s, OPC_CALL, TCG_REG_RA, TCG_REG_TMP, 0); -+ tcg_out_insn_jump(s, OPC_CALL, TCG_REG_RA, TCG_REG_TMP, noPara); -+ } -+} -+ -+static void modify_direct_addr(uintptr_t addr, uintptr_t jmp_rw, uintptr_t jmp_rx) -+{ -+ tcg_target_long l0=0, l1=0; -+ tcg_target_long val = addr; -+ TCGReg rs = TCG_REG_ZERO; -+ TCGReg rd = TCG_REG_TMP; -+ tcg_insn_unit i_nop=0, i1=0, i2=0; -+ uint64_t pair = 0; -+ i_nop = OPC_NOP; -+ uintptr_t jmp = jmp_rw; -+ -+ l0 = (int16_t)val; -+ val = (val - l0) >> 16; -+ l1 = (int16_t)val; -+ if (l1) { -+ i1 = OPC_LDIH | (rd & 0x1f) << 21 | (rs & 0x1f) << 16 | (l1 & 0xffff); -+ } else { -+ i1 = i_nop; - } -+ i2 = OPC_LDI | (rd & 0x1f) << 21 | (rs & 0x1f) << 16 | (l0 & 0xffff); -+ pair = (uint64_t)i1 << 32 | i2; -+ qatomic_set((uint64_t *)jmp, pair); -+ flush_idcache_range(jmp_rx, jmp_rw, 8); - } - - void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx, uintptr_t jmp_rw, uintptr_t addr) - { -- tcg_debug_assert(0); -- //sw not support -+ tcg_insn_unit i1, i2; -+ uint64_t pair; -+ -+ ptrdiff_t offset = addr - jmp_rx -4; -+ -+ if (offset == sextract64(offset, 0, 21)) { -+ i1 = OPC_BR | (TCG_REG_ZERO & 0x1f) << 21| ((offset >> 2) & 0x1fffff); -+ i2 = OPC_NOP; -+ pair = (uint64_t)i2 << 32 | i1; -+ qatomic_set((uint64_t *)jmp_rw, pair); -+ flush_idcache_range(jmp_rx, jmp_rw, 8); -+ } else if (offset == sextract64(offset, 0, 32)) { -+ modify_direct_addr(addr, jmp_rw, jmp_rx); -+ } else { -+ tcg_debug_assert("tb_target"); -+ } - } - - static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l) -@@ -1201,8 +1255,8 @@ static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l) - } - } - --/* sw -- * resut: rd=rn(64,64-m]:rm(64-m,0] -+/* -+ * result: rd=rn(64,64-m]:rm(64-m,0] - * 1: rn(m,0]--->TCG_REG_TMP(64,64-m] - * 2: rm(64,64-m]--->rm(64-m,0] - * 3: rd=TCG_REG_TMP(64,64-m]:rm(64-m,0] -@@ -1211,84 +1265,442 @@ static inline void tcg_out_extr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn - { - int bits = ext ? 64 : 32; - int max = bits - 1; -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP, rn, bits - (m & max)); -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, rm, (m & max)); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, rn, bits - (m & max)); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP2, rm, (m & max)); - tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); - } - --/* sw -- * loop right shift -- */ - static inline void tcg_out_rotr_Imm(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) - { -- int bits = ext ? 64 : 32; -- int max = bits - 1; -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP, rn, bits - (m & max)); -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, rn, (m & max)); -- tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ unsigned int bits = ext ? 64 : 32; -+ unsigned int max = bits - 1; -+ if (ext == TCG_TYPE_I64) { -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, rn, bits - (m & max)); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP2, rn, (m & max)); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ } else { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rn, 0xf); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP, rd, bits - (m & max)); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP2, rd, (m & max)); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } - } - --/* sw loop right shift -- */ - static inline void tcg_out_rotr_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm) - { -- int bits = ext ? 64 : 32; -- //get TCG_REG_TMP=64-[rm] -+ unsigned int bits = ext ? 64 : 32; - tcg_out_insn_simpleImm(s, OPC_SUBL_I, TCG_REG_TMP, rm, bits); -- tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_TMP); -+ tcg_out_insn_bitReg(s, OPC_SUBL, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_TMP); - -- tcg_out_insn_bitReg(s, OPC_SLL, TCG_REG_TMP2, rn, TCG_REG_TMP); //get rn right part to TCG_REG_TMP -- tcg_out_insn_bitReg(s, OPC_SRL, TCG_REG_TMP, rn, rm); //get rn left part to TCG_REG_TMP -- tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ if (ext == TCG_TYPE_I64) { -+ tcg_out_insn_bitReg(s, OPC_SLL, TCG_REG_TMP2, rn, TCG_REG_TMP); -+ tcg_out_insn_bitReg(s, OPC_SRL, TCG_REG_TMP, rn, rm); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ } else { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rn, 0xf); -+ tcg_out_insn_bitReg(s, OPC_SLL, TCG_REG_TMP2, rd, TCG_REG_TMP); -+ tcg_out_insn_bitReg(s, OPC_SRL, TCG_REG_TMP, rd, rm); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } - } - --/* sw -- * loop left shift -- */ - static inline void tcg_out_rotl_Imm(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) - { -- int bits = ext ? 64 : 32; -- int max = bits - 1; -+ unsigned int bits = ext ? 64 : 32; -+ unsigned int max = bits - 1; -+ -+ if (ext == TCG_TYPE_I64) { -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP, rn, bits -(m & max)); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP2, rn, (m & max)); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ } else { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rn, 0xf); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP, rd, bits -(m & max)); -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, TCG_REG_TMP2, rd, (m & max)); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } -+} -+ -+static inline void tcg_out_rotl_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm) -+{ -+ unsigned int bits = ext ? 64 : 32; -+ tcg_out_insn_simpleImm(s, OPC_SUBL_I, TCG_REG_TMP, rm, bits); -+ tcg_out_insn_bitReg(s, OPC_SUBL, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_TMP); -+ -+ if (ext == TCG_TYPE_I64) { -+ tcg_out_insn_bitReg(s, OPC_SRL, TCG_REG_TMP2, rn, TCG_REG_TMP); -+ tcg_out_insn_bitReg(s, OPC_SLL, TCG_REG_TMP, rn, rm); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ } else { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rn, 0xf); -+ tcg_out_insn_bitReg(s, OPC_SRL, TCG_REG_TMP2, rd, TCG_REG_TMP); -+ tcg_out_insn_bitReg(s, OPC_SLL, TCG_REG_TMP, rd, rm); -+ tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, rd, rd, 0xf); -+ } -+} -+ -+#ifdef CONFIG_SOFTMMU -+#include "../tcg-ldst.c.inc" -+ -+static void * const qemu_ld_helpers[(MO_SIZE | MO_BSWAP) + 1] = { -+ [MO_UB] = helper_ret_ldub_mmu, -+ [MO_LEUW] = helper_le_lduw_mmu, -+ [MO_LEUL] = helper_le_ldul_mmu, -+ [MO_LEQ] = helper_le_ldq_mmu, -+ [MO_BEUW] = helper_be_lduw_mmu, -+ [MO_BEUL] = helper_be_ldul_mmu, -+ [MO_BEQ] = helper_be_ldq_mmu, -+}; -+ -+static void * const qemu_st_helpers[(MO_SIZE | MO_BSWAP) + 1] = { -+ [MO_UB] = helper_ret_stb_mmu, -+ [MO_LEUW] = helper_le_stw_mmu, -+ [MO_LEUL] = helper_le_stl_mmu, -+ [MO_LEQ] = helper_le_stq_mmu, -+ [MO_BEUW] = helper_be_stw_mmu, -+ [MO_BEUL] = helper_be_stl_mmu, -+ [MO_BEQ] = helper_be_stq_mmu, -+}; -+ -+static inline void tcg_out_adr(TCGContext *s, TCGReg rd, const void *target) -+{ -+ ptrdiff_t offset = tcg_pcrel_diff(s, target); -+ tcg_debug_assert(offset == sextract64(offset, 0, 21)); -+ tcg_out_insn_br(s, OPC_BR, rd, 0); -+ tcg_out_insn_simpleImm(s, OPC_SUBL_I, rd, rd, 4); -+ if (offset >= 0) { -+ tcg_out_simple(s, OPC_ADDL_I, OPC_ADDL, rd, rd, offset); -+ } else { -+ tcg_out_simple(s, OPC_SUBL_I, OPC_SUBL, rd, rd, -offset); -+ } -+} -+ -+static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) -+{ -+ MemOpIdx oi = lb->oi; -+ MemOp opc = get_memop(oi); -+ MemOp size = opc & MO_SIZE; -+ -+ if (!reloc_pc21(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { -+ return false; -+ } -+ -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X16, TCG_AREG0); -+ tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X17, lb->addrlo_reg); -+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X18, oi); -+ tcg_out_adr(s, TCG_REG_X19, lb->raddr); -+ tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]); -+ if (opc & MO_SIGN) { -+ tcg_out_sxt(s, lb->type, size, lb->datalo_reg, TCG_REG_X0); -+ } else { -+ tcg_out_mov(s, size == MO_64, lb->datalo_reg, TCG_REG_X0); -+ } -+ -+ tcg_out_goto(s, lb->raddr); -+ return true; -+} -+ -+static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) -+{ -+ MemOpIdx oi = lb->oi; -+ MemOp opc = get_memop(oi); -+ MemOp size = opc & MO_SIZE; -+ -+ if (!reloc_pc21(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { -+ return false; -+ } -+ -+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X16, TCG_AREG0); -+ tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X17, lb->addrlo_reg); -+ tcg_out_mov(s, size == MO_64, TCG_REG_X18, lb->datalo_reg); -+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X19, oi); -+ tcg_out_adr(s, TCG_REG_X20, lb->raddr); -+ tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]); -+ tcg_out_goto(s, lb->raddr); -+ return true; -+} - -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP, rn, bits -(m & max)); -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP2, rn, (m & max)); //get rn left part to TCG_REG_TMP -- tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); //get rn right part to left -+static void add_qemu_ldst_label(TCGContext *s, bool is_ld, MemOpIdx oi, -+ TCGType ext, TCGReg data_reg, TCGReg addr_reg, -+ tcg_insn_unit *raddr, tcg_insn_unit *label_ptr) -+{ -+ TCGLabelQemuLdst *label = new_ldst_label(s); -+ -+ label->is_ld = is_ld; -+ label->oi = oi; -+ label->type = ext; -+ label->datalo_reg = data_reg; -+ label->addrlo_reg = addr_reg; -+ label->raddr = tcg_splitwx_to_rx(raddr); -+ label->label_ptr[0] = label_ptr; - } - -+/* We expect to use a 7-bit scaled negative offset from ENV. */ -+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); -+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -512); -+ -+/* These offsets are built into the LDP below. */ -+QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0); -+QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, table) != 8); - --/* sw loop left shift -+/* -+ * Load and compare a TLB entry, emitting the conditional jump to the -+ * slow path for the failure case, which will be patched later when finalizing -+ * the slow path. Generated code returns the host addend in X1, -+ * clobbers X0,X2,X3,TMP. - */ --static inline void tcg_out_rotl_Reg(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm) -+static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc, -+ tcg_insn_unit **label_ptr, int mem_index, -+ bool is_read) -+{ -+ unsigned a_bits = get_alignment_bits(opc); -+ unsigned s_bits = opc & MO_SIZE; -+ unsigned a_mask = (1u << a_bits) - 1; -+ unsigned s_mask = (1u << s_bits) - 1; -+ TCGReg x3; -+ TCGType mask_type; -+ uint64_t compare_mask; -+ -+ mask_type = (TARGET_PAGE_BITS + CPU_TLB_DYN_MAX_BITS > 32 -+ ? TCG_TYPE_I64 : TCG_TYPE_I32); -+ -+ /* Load env_tlb(env)->f[mmu_idx].{mask,table} into {x0,x1}. */ -+ tcg_out_insn_ldst(s, OPC_LDL, TCG_REG_X0, TCG_AREG0, TLB_MASK_TABLE_OFS(mem_index)); -+ tcg_out_insn_ldst(s, OPC_LDL, TCG_REG_X1, TCG_AREG0, TLB_MASK_TABLE_OFS(mem_index)+8); -+ -+ /* Extract the TLB index from the address into X0. */ -+ if (mask_type == TCG_TYPE_I64) { -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); -+ tcg_out_insn_bitReg(s, OPC_AND, TCG_REG_X0, TCG_REG_X0, TCG_REG_TMP); -+ } else { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_REG_TMP, addr_reg, 0xf); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, TCG_REG_TMP, TCG_REG_TMP, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); -+ tcg_out_insn_bitReg(s, OPC_AND, TCG_REG_X0, TCG_REG_X0, TCG_REG_TMP); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_REG_X0, TCG_REG_X0, 0xf); -+ } -+ /* Add the tlb_table pointer, creating the CPUTLBEntry address into X1. */ -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_X1, TCG_REG_X1, TCG_REG_X0); -+ -+ /* Load the tlb comparator into X0, and the fast path addend into X1. */ -+ tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_X0, TCG_REG_X1, is_read -+ ? offsetof(CPUTLBEntry, addr_read) -+ : offsetof(CPUTLBEntry, addr_write)); -+ tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_X1, TCG_REG_X1, -+ offsetof(CPUTLBEntry, addend)); -+ -+ /* For aligned accesses, we check the first byte and include the alignment -+ bits within the address. For unaligned access, we check that we don't -+ cross pages using the address of the last byte of the access. */ -+ if (a_bits >= s_bits) { -+ x3 = addr_reg; -+ } else { -+ if (s_mask >= a_mask) { -+ tcg_out_simple(s, OPC_ADDL_I, OPC_ADDL, TCG_REG_X3, addr_reg, s_mask - a_mask); -+ } else { -+ tcg_out_simple(s, OPC_SUBL_I, OPC_SUBL, TCG_REG_X3, addr_reg, a_mask - s_mask); -+ } -+ -+ if (TARGET_LONG_BITS != 64) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_REG_X3, TCG_REG_X3, 0xf); -+ } -+ x3 = TCG_REG_X3; -+ } -+ compare_mask = (uint64_t)TARGET_PAGE_MASK | a_mask; -+ -+ /* Store the page mask part of the address into X3. */ -+ tcg_out_bit(s, OPC_AND_I, OPC_AND, TCG_REG_X3, x3, compare_mask); -+ if (TARGET_LONG_BITS != 64) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_REG_X3, TCG_REG_X3, 0xf); -+ } -+ -+ /* Perform the address comparison. */ -+ tcg_out_cond_cmp(s, TARGET_LONG_BITS == 64, TCG_COND_NE, TCG_REG_TMP, TCG_REG_X0, TCG_REG_X3, 0); -+ -+ /* If not equal, we jump to the slow path. */ -+ *label_ptr = s->code_ptr; -+ tcg_out_insn_br(s, OPC_BGT, TCG_REG_TMP, 0); -+} -+ -+#endif /* CONFIG_SOFTMMU */ -+ -+static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp memop, TCGType ext, -+ TCGReg data_r, TCGReg addr_r, -+ TCGType otype, TCGReg off_r) -+{ -+ if (otype == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_REG_TMP, off_r, 0xf); -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_TMP, addr_r, TCG_REG_TMP); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_TMP, addr_r, off_r); -+ } -+ -+ const MemOp bswap = memop & MO_BSWAP; -+ -+ switch (memop & MO_SSIZE) { -+ case MO_UB: -+ tcg_out_ldst(s, OPC_LDBU, data_r, TCG_REG_TMP, 0, zeroExt); -+ break; -+ case MO_SB: -+ tcg_out_ldst(s, OPC_LDBU, data_r, TCG_REG_TMP, 0, sigExt); -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, data_r, data_r, 0xf); -+ } -+ break; -+ case MO_UW: -+ tcg_out_ldst(s, OPC_LDHU, data_r, TCG_REG_TMP, 0, zeroExt); -+ if (bswap) { -+ tcg_out_bswap16(s, ext, data_r, data_r); -+ } -+ break; -+ case MO_SW: -+ if (bswap) { -+ tcg_out_ldst(s, OPC_LDHU, data_r, TCG_REG_TMP, 0, zeroExt); -+ tcg_out_bswap16(s, ext, data_r, data_r); -+ tcg_out_insn_simpleReg(s, OPC_SEXTH, data_r, TCG_REG_ZERO, data_r); -+ } else { -+ tcg_out_ldst(s, OPC_LDHU, data_r, TCG_REG_TMP, 0, sigExt); -+ } -+ -+ if (ext == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, data_r, data_r, 0xf); -+ } -+ break; -+ case MO_UL: -+ tcg_out_ldst(s, OPC_LDW, data_r, TCG_REG_TMP, 0, zeroExt); -+ if (bswap) { -+ tcg_out_bswap32(s, ext, data_r, data_r); -+ } -+ break; -+ case MO_SL: -+ if (bswap) { -+ tcg_out_ldst(s, OPC_LDW, data_r, TCG_REG_TMP, 0, zeroExt); -+ tcg_out_bswap32(s, ext, data_r, data_r); -+ tcg_out_insn_simpleReg(s, OPC_ADDW, data_r, data_r, TCG_REG_ZERO); -+ } else { -+ tcg_out_ldst(s, OPC_LDW, data_r, TCG_REG_TMP, 0, sigExt); -+ } -+ break; -+ case MO_Q: -+ tcg_out_ldst(s, OPC_LDL, data_r, TCG_REG_TMP, 0, zeroExt); -+ if (bswap) { -+ tcg_out_bswap64(s, ext, data_r, data_r); -+ } -+ break; -+ default: -+ tcg_abort(); -+ } -+} -+ -+static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, MemOpIdx oi, TCGType ext) -+{ -+ MemOp memop = get_memop(oi); -+ const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64: TCG_TYPE_I32; -+#ifdef CONFIG_SOFTMMU -+ unsigned mem_index = get_mmuidx(oi); -+ tcg_insn_unit *label_ptr; -+ -+ tcg_out_tlb_read(s, addr_reg, memop, &label_ptr, mem_index, 1); -+ tcg_out_qemu_ld_direct(s, memop, ext, data_reg, -+ TCG_REG_X1, otype, addr_reg); -+ add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg, -+ s->code_ptr, label_ptr); -+#else /* !CONFIG_SOFTMMU */ -+ if (USE_GUEST_BASE) { -+ tcg_out_qemu_ld_direct(s, memop, ext, data_reg, TCG_REG_GUEST_BASE, otype, addr_reg); -+ } else { -+ tcg_out_qemu_ld_direct(s, memop, ext, data_reg, addr_reg, TCG_TYPE_I64, TCG_REG_ZERO); -+ } -+#endif /* CONFIG_SOFTMMU */ -+} -+ -+static void tcg_out_qemu_st_direct(TCGContext *s, MemOp memop, -+ TCGReg data_r, TCGReg addr_r, -+ TCGType otype, TCGReg off_r) - { -- int bits = ext ? 64 : 32; -- tcg_out_insn_simpleImm(s, OPC_SUBL_I, TCG_REG_TMP, rm, bits); //rm = 64-rm -- tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_TMP); -+ if (otype == TCG_TYPE_I32) { -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_REG_TMP, off_r, 0xf); -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_TMP, addr_r, TCG_REG_TMP); -+ } else { -+ tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_TMP, addr_r, off_r); -+ } -+ -+ const MemOp bswap = memop & MO_BSWAP; - -- tcg_out_insn_bitReg(s, OPC_SRL, TCG_REG_TMP2, rn, TCG_REG_TMP); //get rn left part to TCG_REG_TMP -- tcg_out_insn_bitReg(s, OPC_SLL, TCG_REG_TMP, rn, rm); //get rn right part to left -- tcg_out_insn_bitReg(s, OPC_BIS, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ switch (memop & MO_SIZE) { -+ case MO_8: -+ tcg_out_ldst(s, OPC_STB, data_r, TCG_REG_TMP, 0, 0); -+ break; -+ case MO_16: -+ if (bswap && data_r != TCG_REG_ZERO) { -+ tcg_out_bswap16(s, TCG_TYPE_I32, TCG_REG_TMP3, data_r); -+ data_r = TCG_REG_TMP3; -+ } -+ tcg_out_ldst(s, OPC_STH, data_r, TCG_REG_TMP, 0, 0); -+ break; -+ case MO_32: -+ if (bswap && data_r != TCG_REG_ZERO) { -+ tcg_out_bswap32(s, TCG_TYPE_I32, TCG_REG_TMP3, data_r); -+ data_r = TCG_REG_TMP3; -+ } -+ tcg_out_ldst(s, OPC_STW, data_r, TCG_REG_TMP, 0, 0); -+ break; -+ case MO_64: -+ if (bswap && data_r != TCG_REG_ZERO) { -+ tcg_out_bswap64(s, TCG_TYPE_I64, TCG_REG_TMP3, data_r); -+ data_r = TCG_REG_TMP3; -+ } -+ tcg_out_ldst(s, OPC_STL, data_r, TCG_REG_TMP, 0, 0); -+ break; -+ default: -+ tcg_abort(); -+ } - } - -+static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, -+ MemOpIdx oi) -+{ -+ MemOp memop = get_memop(oi); -+ const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64: TCG_TYPE_I32; -+#ifdef CONFIG_SOFTMMU -+ unsigned mem_index = get_mmuidx(oi); -+ tcg_insn_unit *label_ptr; -+ -+ tcg_out_tlb_read(s, addr_reg, memop, &label_ptr, mem_index, 0); -+ tcg_out_qemu_st_direct(s, memop, data_reg, TCG_REG_X1, otype, addr_reg); -+ add_qemu_ldst_label(s, false, oi, (memop & MO_SIZE)== MO_64, data_reg, addr_reg, s->code_ptr, label_ptr); -+#else /* !CONFIG_SOFTMMU */ -+ if (USE_GUEST_BASE) { -+ tcg_out_qemu_st_direct(s, memop, data_reg, TCG_REG_GUEST_BASE, otype, addr_reg); -+ } else { -+ tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, TCG_TYPE_I64, TCG_REG_ZERO); -+ } -+#endif /* CONFIG_SOFTMMU */ -+} - -+static const tcg_insn_unit *tb_ret_addr; - --static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_OP_ARGS], const int const_args[TCG_MAX_OP_ARGS]) -+static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_OP_ARGS], -+ const int const_args[TCG_MAX_OP_ARGS]) - { - /* 99% of the time, we can signal the use of extension registers -- by looking to see if the opcode handles 64-bit data. */ -+ * by looking to see if the opcode handles 64-bit data. */ - TCGType ext = (tcg_op_defs[opc].flags & TCG_OPF_64BIT) != 0; -- /* Hoist the loads of the most common arguments. */ -+ /* Hoist the loads of the most common arguments. */ - TCGArg a0 = args[0]; - TCGArg a1 = args[1]; - TCGArg a2 = args[2]; - int c2 = const_args[2]; - - /* Some operands are defined with "rZ" constraint, a register or -- the zero register. These need not actually test args[I] == 0. */ -- #define REG0(I) (const_args[I] ? TCG_REG_ZERO : (TCGReg)args[I]) -+ * the zero register. These need not actually test args[I] == 0. */ - - switch (opc) { - case INDEX_op_exit_tb: -- /* Reuse the zeroing that exists for goto_ptr. */ -+ /* Reuse the zeroing that exists for goto_ptr. */ - if (a0 == 0) { - tcg_out_goto_long(s, tcg_code_gen_epilogue); - } else { -@@ -1296,34 +1708,39 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_O - tcg_out_goto_long(s, tb_ret_addr); - } - break; -- - case INDEX_op_goto_tb: - if (s->tb_jmp_insn_offset != NULL) { - /* TCG_TARGET_HAS_direct_jump */ -- tcg_debug_assert(0); -- /* not support here */ -+ /* Ensure that ADRP+ADD are 8-byte aligned so that an atomic -+ write can be used to patch the target address. */ -+ if ((uintptr_t)s->code_ptr & 7) { -+ tcg_out32(s, OPC_NOP); -+ } -+ s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s); -+ tcg_out32(s, OPC_NOP); -+ tcg_out32(s, OPC_NOP); - } else { - /* !TCG_TARGET_HAS_direct_jump */ - tcg_debug_assert(s->tb_jmp_target_addr != NULL); - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP, TCG_REG_ZERO, (uintptr_t)(s->tb_jmp_target_addr + a0)); - } -- tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, TCG_REG_TMP, 0); -+ tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, TCG_REG_TMP, noPara); - set_jmp_reset_offset(s, a0); - break; -- - case INDEX_op_goto_ptr: -- tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, a0, 0); -+ tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, a0, noPara); - break; -- - case INDEX_op_br: - tcg_out_goto_label(s, arg_label(a0)); - break; -- - case INDEX_op_ld8u_i32: - case INDEX_op_ld8u_i64: - tcg_out_ldst(s, OPC_LDBU, a0, a1, a2, 0); - break; - case INDEX_op_ld8s_i32: -+ tcg_out_ldst(s, OPC_LDBU, a0, a1, a2, 1); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ break; - case INDEX_op_ld8s_i64: - tcg_out_ldst(s, OPC_LDBU, a0, a1, a2, 1); - break; -@@ -1332,11 +1749,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_O - tcg_out_ldst(s, OPC_LDHU, a0, a1, a2, 0); - break; - case INDEX_op_ld16s_i32: -+ tcg_out_ldst(s, OPC_LDHU, a0, a1, a2, 1); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ break; - case INDEX_op_ld16s_i64: - tcg_out_ldst(s, OPC_LDHU, a0, a1, a2, 1); - break; - case INDEX_op_ld_i32: -- tcg_out_ldst(s, OPC_LDW, a0, a1, a2, 1); -+ tcg_out_ldst(s, OPC_LDW, a0, a1, a2, 0); - break; - case INDEX_op_ld32u_i64: - tcg_out_ldst(s, OPC_LDW, a0, a1, a2, 0); -@@ -1349,26 +1769,26 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_O - break; - case INDEX_op_st8_i32: - case INDEX_op_st8_i64: -- tcg_out_ldst(s, OPC_STB, a0, a1, a2, 0); -+ tcg_out_ldst(s, OPC_STB, REG0(0), a1, a2, 0); - break; - case INDEX_op_st16_i32: - case INDEX_op_st16_i64: -- tcg_out_ldst(s, OPC_STH, a0, a1, a2, 0); -+ tcg_out_ldst(s, OPC_STH, REG0(0), a1, a2, 0); - break; - case INDEX_op_st_i32: - case INDEX_op_st32_i64: -- tcg_out_ldst(s, OPC_STW, a0, a1, a2, 0); -+ tcg_out_ldst(s, OPC_STW, REG0(0), a1, a2, 0); - break; - case INDEX_op_st_i64: -- tcg_out_ldst(s, OPC_STL, a0, a1, a2, 0); -+ tcg_out_ldst(s, OPC_STL, REG0(0), a1, a2, 0); - break; -- - case INDEX_op_add_i32: - a2 = (int32_t)a2; - if (c2) { - tcg_out_addsubi(s, ext, a0, a1, a2); - } else { -- tcg_out_insn_simpleReg(s, OPC_ADDL, a0, a1, a2); -+ tcg_out_insn_simpleReg(s, OPC_ADDW, a0, a1, a2); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); - } - break; - case INDEX_op_add_i64: -@@ -1378,13 +1798,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_O - tcg_out_insn_simpleReg(s, OPC_ADDL, a0, a1, a2); - } - break; -- - case INDEX_op_sub_i32: - a2 = (int32_t)a2; - if (c2) { - tcg_out_addsubi(s, ext, a0, a1, -a2); - } else { -- tcg_out_insn_simpleReg(s, OPC_SUBL, a0, a1, a2); -+ tcg_out_insn_simpleReg(s, OPC_SUBW, a0, a1, a2); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); - } - break; - case INDEX_op_sub_i64: -@@ -1394,230 +1814,207 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_O - tcg_out_insn_simpleReg(s, OPC_SUBL, a0, a1, a2); - } - break; -- -- case INDEX_op_neg_i64: - case INDEX_op_neg_i32: -+ tcg_out_insn_bitReg(s, OPC_SUBW, a0, TCG_REG_ZERO, a1); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ break; -+ case INDEX_op_neg_i64: - tcg_out_insn_bitReg(s, OPC_SUBL, a0, TCG_REG_ZERO, a1); - break; -- - case INDEX_op_and_i32: -- a2 = (int32_t)a2; - if (c2) { -- tcg_out_insn_bit(s, OPC_AND_I, OPC_AND, a0, a1, a2); -+ a2 = (int32_t)a2; -+ tcg_out_bit(s, OPC_AND_I, OPC_AND, a0, a1, a2); - } else { - tcg_out_insn_bitReg(s, OPC_AND, a0, a1, a2); - } -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); - break; - case INDEX_op_and_i64: - if (c2) { -- tcg_out_insn_bit(s, OPC_AND_I, OPC_AND, a0, a1, a2); -+ tcg_out_bit(s, OPC_AND_I, OPC_AND, a0, a1, a2); - } else { - tcg_out_insn_bitReg(s, OPC_AND, a0, a1, a2); - } - break; - case INDEX_op_andc_i32: -- a2 = (int32_t)a2; -- tcg_debug_assert(0); -- if (c2) { -- tcg_out_insn_bit(s, OPC_AND_I, OPC_AND, a0, a1, ~a2); -- } else { -- tcg_out_insn_bitReg(s, OPC_BIC, a0, a1, a2); -- } -- break; - case INDEX_op_andc_i64: - tcg_debug_assert(0); -- if (c2) { -- tcg_out_insn_bit(s, OPC_AND_I, OPC_AND, a0, a1, ~a2); -- } else { -- tcg_out_insn_bitReg(s, OPC_BIC, a0, a1, a2); -- } - break; -- - case INDEX_op_or_i32: -- a2 = (int32_t)a2; - if (c2) { -- tcg_out_insn_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, a2); -+ a2 = (int32_t)a2; -+ tcg_out_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, a2); - } else { - tcg_out_insn_bitReg(s, OPC_BIS, a0, a1, a2); - } -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); - break; - case INDEX_op_or_i64: - if (c2) { -- tcg_out_insn_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, a2); -+ tcg_out_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, a2); - } else { - tcg_out_insn_bitReg(s, OPC_BIS, a0, a1, a2); - } - break; -- - case INDEX_op_orc_i32: -- a2 = (int32_t)a2; -- tcg_debug_assert(0); - if (c2) { -- tcg_out_insn_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, ~a2); -+ a2 = (int32_t)a2; -+ tcg_out_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, ~a2); - } else { - tcg_out_insn_bitReg(s, OPC_ORNOT, a0, a1, a2); - } -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); - break; - case INDEX_op_orc_i64: -- tcg_debug_assert(0); - if (c2) { -- tcg_out_insn_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, ~a2); -+ tcg_out_bit(s, OPC_BIS_I, OPC_BIS, a0, a1, ~a2); - } else { - tcg_out_insn_bitReg(s, OPC_ORNOT, a0, a1, a2); - } - break; -- - case INDEX_op_xor_i32: -- a2 = (int32_t)a2; - if (c2) { -- tcg_out_insn_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, a2); -+ a2 = (int32_t)a2; -+ tcg_out_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, a2); - } else { - tcg_out_insn_bitReg(s, OPC_XOR, a0, a1, a2); - } -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); - break; - case INDEX_op_xor_i64: - if (c2) { -- tcg_out_insn_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, a2); -+ tcg_out_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, a2); - } else { - tcg_out_insn_bitReg(s, OPC_XOR, a0, a1, a2); - } - break; -- - case INDEX_op_eqv_i32: -- a2 = (int32_t)a2; -- tcg_debug_assert(0); -- if (c2) { -- tcg_out_insn_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, ~a2); -- } else { -- tcg_out_insn_bitReg(s, OPC_EQV, a0, a1, a2); -- } -- break; -- - case INDEX_op_eqv_i64: - tcg_debug_assert(0); -- if (c2) { -- tcg_out_insn_bit(s, OPC_XOR_I, OPC_XOR, a0, a1, ~a2); -- } else { -- tcg_out_insn_bitReg(s, OPC_EQV, a0, a1, a2); -- } - break; -- -- case INDEX_op_not_i64: - case INDEX_op_not_i32: - tcg_out_insn_bitReg(s, OPC_ORNOT, a0, TCG_REG_ZERO, a1); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ break; -+ case INDEX_op_not_i64: -+ tcg_out_insn_bitReg(s, OPC_ORNOT, a0, TCG_REG_ZERO, a1); - break; -- -- case INDEX_op_mul_i64: - case INDEX_op_mul_i32: -- tcg_out_insn_simpleReg(s, OPC_MULL, a0, a1, a2); -+ tcg_out_insn_simpleReg(s, OPC_MULL, a0, a1, a2); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ break; -+ case INDEX_op_mul_i64: -+ tcg_out_insn_simpleReg(s, OPC_MULL, a0, a1, a2); - break; -- -- case INDEX_op_div_i64: /* a0=a1/a2 singed divide*/ - case INDEX_op_div_i32: -+ case INDEX_op_div_i64: - tcg_debug_assert(0); - break; -- case INDEX_op_divu_i64: /* a0=a1/a2 unsigned divide */ - case INDEX_op_divu_i32: -+ case INDEX_op_divu_i64: - tcg_debug_assert(0); - break; -- -- case INDEX_op_rem_i64: /* if a1=17,a2=4, 17/4=4...1, a0=1 */ - case INDEX_op_rem_i32: -+ case INDEX_op_rem_i64: - tcg_debug_assert(0); - break; -- case INDEX_op_remu_i64: - case INDEX_op_remu_i32: -+ case INDEX_op_remu_i64: - tcg_debug_assert(0); - break; -- -- case INDEX_op_shl_i64: - case INDEX_op_shl_i32: /* sw logical left*/ - if (c2) { -- int bits = ext ? 64 : 32; -- int max = bits - 1; -- tcg_out_insn_bitImm(s, OPC_SLL_I, a0, a1, a2&max); -+ unsigned int bits = ext ? 64 : 32; -+ unsigned int max = bits - 1; -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, a0, a1, a2&max); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ } else { -+ tcg_out_insn_bitReg(s, OPC_SLL, a0, a1, a2); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ } -+ break; -+ case INDEX_op_shl_i64: -+ if (c2) { -+ unsigned int bits = ext ? 64 : 32; -+ unsigned int max = bits - 1; -+ tcg_out_insn_simpleImm(s, OPC_SLL_I, a0, a1, a2&max); - } else { - tcg_out_insn_bitReg(s, OPC_SLL, a0, a1, a2); - } - break; -- -- case INDEX_op_shr_i64: - case INDEX_op_shr_i32: /* sw logical right */ -+ a2 = (int32_t)a2; - if (c2) { - int bits = ext ? 64 : 32; - int max = bits - 1; -- tcg_out_insn_bitImm(s, OPC_SRL_I, a0, a1, a2&max); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, a0, a1, a2&max); - } else { - tcg_out_insn_bitReg(s, OPC_SRL, a0, a1, a2); - } - break; -- -- case INDEX_op_sar_i64: -- case INDEX_op_sar_i32: /* sw arithmetic right*/ -+ case INDEX_op_shr_i64: - if (c2) { - int bits = ext ? 64 : 32; - int max = bits - 1; -- tcg_out_insn_bitImm(s, OPC_SRA_I, a0, a1, a2&max); -+ tcg_out_insn_simpleImm(s, OPC_SRL_I, a0, a1, a2&max); - } else { -- tcg_out_insn_bitReg(s, OPC_SRA, a0, a1, a2); -+ tcg_out_insn_bitReg(s, OPC_SRL, a0, a1, a2); - } - break; -- -- case INDEX_op_rotr_i64: -+ case INDEX_op_sar_i32: -+ a2 = (int32_t)a2; -+ tcg_out_sar(s, ext, a0, a1, a2, c2); -+ break; -+ case INDEX_op_sar_i64: /* sw arithmetic right*/ -+ tcg_out_sar(s, ext, a0, a1, a2, c2); -+ break; - case INDEX_op_rotr_i32: /* loop shift */ -+ case INDEX_op_rotr_i64: - if (c2) {/* loop right shift a2*/ - tcg_out_rotr_Imm(s, ext, a0, a1, a2); - } else { - tcg_out_rotr_Reg(s, ext, a0, a1, a2); - } - break; -- -- case INDEX_op_rotl_i64: - case INDEX_op_rotl_i32: /* loop shift */ -+ case INDEX_op_rotl_i64: /* sw */ - if (c2) {/* loop left shift a2*/ - tcg_out_rotl_Imm(s, ext, a0, a1, a2); - } else { - tcg_out_rotl_Reg(s, ext, a0, a1, a2); - } - break; -- -- case INDEX_op_clz_i64: /* counting leading zero numbers */ - case INDEX_op_clz_i32: -- tcg_out_cltz(s, OPC_CTLZ, ext, a0, a1, a2, c2); -+ tcg_out_ctz32(s, OPC_CTLZ, a0, a1, a2, c2); -+ break; -+ case INDEX_op_clz_i64: /* counting leading zero numbers */ -+ tcg_out_ctz64(s, OPC_CTLZ, a0, a1, a2, c2); - break; -- case INDEX_op_ctz_i64: /* counting tailing zero numbers */ - case INDEX_op_ctz_i32: -- tcg_out_cltz(s, OPC_CTTZ, ext, a0, a1, a2, c2); -+ tcg_out_ctz32(s, OPC_CTTZ, a0, a1, a2, c2); - break; -- -- case INDEX_op_brcond_i32: -- a1 = (int32_t)a1; -- tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(args[3])); -+ case INDEX_op_ctz_i64: /* counting tailing zero numbers */ -+ tcg_out_ctz64(s, OPC_CTTZ, a0, a1, a2, c2); - break; -- -+ case INDEX_op_brcond_i32: - case INDEX_op_brcond_i64: - tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(args[3])); - break; -- - case INDEX_op_setcond_i32: - a2 = (int32_t)a2; -- tcg_out_setcond(s, args[3], a0, a1, a2); -+ tcg_out_setcond(s, ext, args[3], a0, a1, a2, c2); - break; -- - case INDEX_op_setcond_i64: -- tcg_out_setcond(s, args[3], a0, a1, a2); -+ tcg_out_setcond(s, ext, args[3], a0, a1, a2, c2); - break; -- - case INDEX_op_movcond_i32: - a2 = (int32_t)a2; -- tcg_out_movcond(s, args[5], a0, a1, a2, c2, REG0(3), REG0(4)); -+ tcg_out_movcond(s, ext, args[5], a0, a1, a2, c2, REG0(3), REG0(4)); - break; -- -- /* FALLTHRU */ - case INDEX_op_movcond_i64: -- tcg_out_movcond(s, args[5], a0, a1, a2, c2, REG0(3), REG0(4)); -+ tcg_out_movcond(s, ext, args[5], a0, a1, a2, c2, REG0(3), REG0(4)); - break; -- - case INDEX_op_qemu_ld_i32: - case INDEX_op_qemu_ld_i64: - tcg_out_qemu_ld(s, a0, a1, a2, ext); -@@ -1626,443 +2023,399 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg args[TCG_MAX_O - case INDEX_op_qemu_st_i64: - tcg_out_qemu_st(s, REG0(0), a1, a2); - break; -- -- case INDEX_op_bswap64_i64: /* 0x123456789abcdef--->0xefcdab8967452301 */ -- tcg_debug_assert(0); -- tcg_out_bswap64(s, a0, a1); -- break; -- case INDEX_op_bswap32_i64: /* 0x123456789abcdef--->0x67452301efcdab89 */ -- tcg_debug_assert(0); -- tcg_out_bswap32u(s, a0, a1); -+ case INDEX_op_bswap64_i64: -+ tcg_out_bswap64(s, ext, a0, a1); - break; - case INDEX_op_bswap32_i32: -- tcg_debug_assert(0); -+ case INDEX_op_bswap32_i64: -+ tcg_out_bswap32(s, ext, a0, a1); - break; -- case INDEX_op_bswap16_i64: /* 0x123456789abcdef--->0x23016745ab89efcd */ - case INDEX_op_bswap16_i32: -- tcg_debug_assert(0); -+ case INDEX_op_bswap16_i64: -+ tcg_out_bswap16(s, ext, a0, a1); - break; -- -- case INDEX_op_ext8s_i64: - case INDEX_op_ext8s_i32: -+ tcg_out_insn_simpleReg(s, OPC_SEXTB, a0, TCG_REG_ZERO, a1); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ break; -+ case INDEX_op_ext8s_i64: - tcg_out_insn_simpleReg(s, OPC_SEXTB, a0, TCG_REG_ZERO, a1); - break; -- case INDEX_op_ext16s_i64: - case INDEX_op_ext16s_i32: -+ tcg_out_insn_simpleReg(s, OPC_SEXTH, a0, TCG_REG_ZERO, a1); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a0, 0xf); -+ break; -+ case INDEX_op_ext16s_i64: - tcg_out_insn_simpleReg(s, OPC_SEXTH, a0, TCG_REG_ZERO, a1); - break; - case INDEX_op_ext_i32_i64: - case INDEX_op_ext32s_i64: - tcg_out_insn_simpleReg(s, OPC_ADDW, a0, TCG_REG_ZERO, a1); - break; -- case INDEX_op_ext8u_i64: - case INDEX_op_ext8u_i32: -- tcg_out_insn_simpleImm(s, OPC_EXT0B_I, a0, a1, 0x0); -+ case INDEX_op_ext8u_i64: -+ tcg_out_insn_simpleImm(s, OPC_EXTLB_I, a0, a1, 0x0); - break; -- case INDEX_op_ext16u_i64: - case INDEX_op_ext16u_i32: -- tcg_out_insn_simpleImm(s, OPC_EXT1B_I, a0, a1, 0x0); -+ case INDEX_op_ext16u_i64: -+ tcg_out_insn_simpleImm(s, OPC_EXTLH_I, a0, a1, 0x0); - break; - case INDEX_op_extu_i32_i64: - case INDEX_op_ext32u_i64: -- tcg_out_movr(s, TCG_TYPE_I32, a0, a1); -+ tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, a0, a1, 0xf); - break; -- -- case INDEX_op_deposit_i64: - case INDEX_op_deposit_i32: -- tcg_out_dep(s, a0, a2, args[3], args[4]); -+ case INDEX_op_deposit_i64: -+ tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]); - break; -- -- case INDEX_op_extract_i64: - case INDEX_op_extract_i32: -+ case INDEX_op_extract_i64: - tcg_out_extract(s, a0, a1, a2, args[3]); - break; -- -- case INDEX_op_sextract_i64: - case INDEX_op_sextract_i32: -+ case INDEX_op_sextract_i64: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_extract2_i32: /* extract REG0(2) right args[3] bit to REG0(1) left ,save to a0*/ -+ case INDEX_op_extract2_i64: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_add2_i32: -+ case INDEX_op_add2_i64: -+ tcg_debug_assert(0); -+ break; -+ case INDEX_op_sub2_i32: -+ case INDEX_op_sub2_i64: - tcg_debug_assert(0); - break; -+ case INDEX_op_muluh_i64: -+ tcg_out_insn_simpleReg(s, OPC_UMULH, a0, a1, a2); -+ break; -+ case INDEX_op_mulsh_i64: -+ tcg_out_mulsh64(s, a0, a1, a2); -+ break; -+ case INDEX_op_mb: -+ tcg_out_mb(s); -+ break; -+ case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ -+ break; -+ case INDEX_op_mov_i64: -+ break; -+ case INDEX_op_call: /* Always emitted via tcg_out_call. */ -+ default: -+ g_assert_not_reached(); -+ } -+#undef REG0 -+} - -+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) -+{ -+ switch (op) { -+ case INDEX_op_goto_ptr: -+ return C_O0_I1(r); -+ case INDEX_op_ld8u_i32: -+ case INDEX_op_ld8s_i32: -+ case INDEX_op_ld16u_i32: -+ case INDEX_op_ld16s_i32: -+ case INDEX_op_ld_i32: -+ case INDEX_op_ld8u_i64: -+ case INDEX_op_ld8s_i64: -+ case INDEX_op_ld16u_i64: -+ case INDEX_op_ld16s_i64: -+ case INDEX_op_ld32u_i64: -+ case INDEX_op_ld32s_i64: -+ case INDEX_op_ld_i64: -+ case INDEX_op_neg_i32: -+ case INDEX_op_neg_i64: -+ case INDEX_op_not_i32: -+ case INDEX_op_not_i64: -+ case INDEX_op_bswap16_i32: -+ case INDEX_op_bswap32_i32: -+ case INDEX_op_bswap16_i64: -+ case INDEX_op_bswap32_i64: -+ case INDEX_op_bswap64_i64: -+ case INDEX_op_ext8s_i32: -+ case INDEX_op_ext16s_i32: -+ case INDEX_op_ext8u_i32: -+ case INDEX_op_ext16u_i32: -+ case INDEX_op_ext8s_i64: -+ case INDEX_op_ext16s_i64: -+ case INDEX_op_ext32s_i64: -+ case INDEX_op_ext8u_i64: -+ case INDEX_op_ext16u_i64: -+ case INDEX_op_ext32u_i64: -+ case INDEX_op_ext_i32_i64: -+ case INDEX_op_extu_i32_i64: -+ case INDEX_op_extract_i32: -+ case INDEX_op_extract_i64: -+ case INDEX_op_sextract_i32: -+ case INDEX_op_sextract_i64: -+ return C_O1_I1(r, r); -+ case INDEX_op_st8_i32: -+ case INDEX_op_st16_i32: -+ case INDEX_op_st_i32: -+ case INDEX_op_st8_i64: -+ case INDEX_op_st16_i64: -+ case INDEX_op_st32_i64: -+ case INDEX_op_st_i64: -+ return C_O0_I2(rZ, r); -+ case INDEX_op_add_i32: -+ case INDEX_op_add_i64: -+ case INDEX_op_sub_i32: -+ case INDEX_op_sub_i64: -+ return C_O1_I2(r, r, rU); -+ case INDEX_op_setcond_i32: -+ case INDEX_op_setcond_i64: -+ return C_O1_I2(r, r, rU); -+ case INDEX_op_mul_i32: -+ case INDEX_op_mul_i64: -+ case INDEX_op_div_i32: -+ case INDEX_op_div_i64: -+ case INDEX_op_divu_i32: -+ case INDEX_op_divu_i64: -+ case INDEX_op_rem_i32: -+ case INDEX_op_rem_i64: -+ case INDEX_op_remu_i32: -+ case INDEX_op_remu_i64: -+ case INDEX_op_muluh_i64: -+ case INDEX_op_mulsh_i64: -+ return C_O1_I2(r, r, r); -+ case INDEX_op_and_i32: -+ case INDEX_op_and_i64: -+ case INDEX_op_or_i32: -+ case INDEX_op_or_i64: -+ case INDEX_op_xor_i32: -+ case INDEX_op_xor_i64: -+ case INDEX_op_andc_i32: -+ case INDEX_op_andc_i64: -+ case INDEX_op_orc_i32: -+ case INDEX_op_orc_i64: -+ case INDEX_op_eqv_i32: -+ case INDEX_op_eqv_i64: -+ return C_O1_I2(r, r, rU); -+ case INDEX_op_shl_i32: -+ case INDEX_op_shr_i32: -+ case INDEX_op_sar_i32: -+ case INDEX_op_rotl_i32: -+ case INDEX_op_rotr_i32: -+ case INDEX_op_shl_i64: -+ case INDEX_op_shr_i64: -+ case INDEX_op_sar_i64: -+ case INDEX_op_rotl_i64: -+ case INDEX_op_rotr_i64: -+ return C_O1_I2(r, r, ri); -+ case INDEX_op_clz_i32: -+ case INDEX_op_clz_i64: -+ return C_O1_I2(r, r, r); -+ case INDEX_op_ctz_i32: -+ case INDEX_op_ctz_i64: -+ return C_O1_I2(r, r, r); -+ case INDEX_op_brcond_i32: -+ case INDEX_op_brcond_i64: -+ return C_O0_I2(r, rU); -+ case INDEX_op_movcond_i32: -+ case INDEX_op_movcond_i64: -+ return C_O1_I4(r, r, rU, rZ, rZ); -+ case INDEX_op_qemu_ld_i32: -+ case INDEX_op_qemu_ld_i64: -+ return C_O1_I1(r, l); -+ case INDEX_op_qemu_st_i32: -+ case INDEX_op_qemu_st_i64: -+ return C_O0_I2(lZ, l); -+ case INDEX_op_deposit_i32: -+ case INDEX_op_deposit_i64: -+ return C_O1_I2(r, 0, rZ); -+ case INDEX_op_extract2_i32: - case INDEX_op_extract2_i64: -- case INDEX_op_extract2_i32: /* extract REG0(2) right args[3] bit to REG0(1) left ,save to a0*/ -- tcg_debug_assert(0); -- break; -- -+ return C_O1_I2(r, rZ, rZ); - case INDEX_op_add2_i32: -- tcg_debug_assert(0); -- break; - case INDEX_op_add2_i64: -- tcg_debug_assert(0); -- break; - case INDEX_op_sub2_i32: -- tcg_debug_assert(0); -- break; - case INDEX_op_sub2_i64: -- tcg_debug_assert(0); -- break; -- -- case INDEX_op_muluh_i64: -- tcg_out_insn_simpleReg(s, OPC_UMULH, a0, a1, a2); -- break; -- case INDEX_op_mulsh_i64: /* sw not support */ -- tcg_out_mulsh64(s, a0, a1, a2); -- break; -- -- case INDEX_op_mb: -- break; -- -- case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ -- case INDEX_op_mov_i64: -- case INDEX_op_call: /* Always emitted via tcg_out_call. */ -+ return C_O2_I4(r, r, rZ, rZ, rA, rMZ); -+ case INDEX_op_add_vec: -+ case INDEX_op_sub_vec: -+ case INDEX_op_mul_vec: -+ case INDEX_op_xor_vec: -+ case INDEX_op_ssadd_vec: -+ case INDEX_op_sssub_vec: -+ case INDEX_op_usadd_vec: -+ case INDEX_op_ussub_vec: -+ case INDEX_op_smax_vec: -+ case INDEX_op_smin_vec: -+ case INDEX_op_umax_vec: -+ case INDEX_op_umin_vec: -+ case INDEX_op_shlv_vec: -+ case INDEX_op_shrv_vec: -+ case INDEX_op_sarv_vec: -+ return C_O1_I2(w, w, w); -+ case INDEX_op_not_vec: -+ case INDEX_op_neg_vec: -+ case INDEX_op_abs_vec: -+ case INDEX_op_shli_vec: -+ case INDEX_op_shri_vec: -+ case INDEX_op_sari_vec: -+ return C_O1_I1(w, w); -+ case INDEX_op_ld_vec: -+ case INDEX_op_dupm_vec: -+ return C_O1_I1(w, r); -+ case INDEX_op_st_vec: -+ return C_O0_I2(w, r); -+ case INDEX_op_dup_vec: -+ return C_O1_I1(w, wr); -+ case INDEX_op_or_vec: -+ case INDEX_op_andc_vec: -+ return C_O1_I2(w, w, wO); -+ case INDEX_op_and_vec: -+ case INDEX_op_orc_vec: -+ return C_O1_I2(w, w, wN); -+ case INDEX_op_cmp_vec: -+ return C_O1_I2(w, w, wZ); -+ case INDEX_op_bitsel_vec: -+ return C_O1_I3(w, w, w, w); - default: - g_assert_not_reached(); - } -- --#undef REG0 - } - - -- --/*sw --* counting heading/tailing zero numbers --*/ --static void tcg_out_cltz(TCGContext *s, SW_64Insn opc_clz, TCGType ext, TCGReg rd, -- TCGReg rn, TCGArg b, bool const_b) --{ -- /* cond1. b is a const, and b=64 or b=32 */ -- if (const_b && b == (ext ? 64 : 32)) { -- /* count rn zero numbers, and writes to rd */ -- tcg_out_insn_simpleReg(s, opc_clz, rd, TCG_REG_ZERO, rn); -- }else { -- /* TCG_REG_TMP= counting rn heading/tailing zero numbers */ -- tcg_out_insn_simpleReg(s, opc_clz, TCG_REG_TMP, TCG_REG_ZERO, rn); -- -- if (const_b) { -- if (b == -1) { -- /* cond2. b is const and b=-1 */ -- /* if rn != 0 , rd= counting rn heading/tailing zero numbers, else rd = 0xffffffffffffffff*/ -- tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP2, TCG_REG_ZERO, TCG_REG_ZERO); -- tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP, TCG_REG_TMP2); -- } -- else if (b == 0) { -- /* cond3. b is const and b=0 */ -- /* if rn != 0 , rd=counting rn heading/tailing zero numbers , else rd = TCG_REG_ZERO */ -- tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP, TCG_REG_ZERO); -- } else { -- /* cond4. b is const */ -- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP2, b); -- /* if rn != 0 , rd=counting rn heading/tailing zero numbers , else mov b to rd */ -- tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP, TCG_REG_TMP2); -- } -- } -- else { -- /* if b is register */ -- tcg_out_insn_complexReg(s, OPC_SELNE, rn, rd, TCG_REG_TMP, b); -- } -- } --} -- --/*sw -- * unsigned 16bit, ab->ba -- */ --static inline void tcg_out_bswap16u(TCGContext *s, TCGReg rd, TCGReg rn) -+static void tcg_target_init(TCGContext *s) - { -- TCGReg TCG_TMP0 = rn; -- TCGReg TCG_TMP1 = rd; -- /*t1=00b0*/ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP0, 8); -- /*t1=(0000)000a*/ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP0, TCG_TMP0, 8); -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP0, TCG_TMP0, 0x1); -- /*t1=ooba*/ -- tcg_out_insn_simpleReg(s, OPC_BIS, TCG_TMP1, TCG_TMP1, TCG_TMP0); --} -+ tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffffu; -+ tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffffu; -+ tcg_target_available_regs[TCG_TYPE_V64] = 0xffffffff00000000ull; -+ tcg_target_available_regs[TCG_TYPE_V128] = 0xffffffff00000000ull; -+ tcg_target_call_clobber_regs = -1ull; - --/*sw -- * signed 16bit, ab->ssba -- */ --static inline void tcg_out_bswap16s(TCGContext *s, TCGReg rd, TCGReg rn) --{ -- TCGReg TCG_TMP0 = rn; -- TCGReg TCG_TMP1 = TCG_REG_TMP; -- TCGReg TCG_TMP2 = rn; -- /*t1=(ssss)ssb0*/ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP0, 8); -- tcg_out_insn_simpleImm(s, OPC_ZAP_I, TCG_TMP1, TCG_TMP1, 0x2); -- tcg_out_insn_simpleReg(s, OPC_SEXTH, TCG_TMP1, TCG_REG_ZERO, TCG_TMP1); -- /*t2=(0000)000a*/ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP2, TCG_TMP0, 8); -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP2, TCG_TMP2, 0x1); -- /*t2=(ssss)ssba*/ -- tcg_out_insn_simpleReg(s, OPC_BIS, TCG_TMP1, TCG_TMP1, TCG_TMP2); --} -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X9); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X10); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X11); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X12); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X13); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X14); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_X15); - -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F2); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F3); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F4); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F5); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F6); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F7); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F8); -+ tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_F9); - --/*sw -- * signed 32bit, abcd -> ssdcba -- */ --static inline void tcg_out_bswap32s(TCGContext *s, TCGReg rd, TCGReg rn) --{ -- TCGReg TCG_TMP0 = rn; -- TCGReg TCG_TMP3 = rd; -- TCGReg TCG_TMP1 = TCG_REG_TMP; -- TCGReg TCG_TMP2 = TCG_REG_TMP2; -- /*swap32 -- 32-bit swap. a0 = abcd.*/ -- -- /* t3 = (ssss)d000 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP3, TCG_TMP0, 24); -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP3, TCG_TMP3, 0x0f); -- tcg_out_insn_simpleReg(s, OPC_SEXTB, TCG_TMP1, TCG_REG_ZERO, TCG_TMP0); -- tcg_out_insn_simpleImm(s, OPC_ZAP_I, TCG_TMP1, TCG_TMP1, 0x0f); -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -- -- /* t1 = 000a */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 24); -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x1); -- -- /* t2 = 00c0 */ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP2, TCG_TMP0, 0x2); -- -- /* t3 = (ssss)d00a */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -- -- /* t1 = 0abc */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 8); -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x7); -- -- /* t2 = 0c00 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 8); -- /* t1 = 00b0 */ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x2); -- /* t3 = (ssss)dc0a */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -- /* t3 = (ssss)dcba -- delay slot */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ s->reserved_regs = 0; -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_FP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP3); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_X29); -+ tcg_regset_set_reg(s->reserved_regs, TCG_FLOAT_TMP); -+ tcg_regset_set_reg(s->reserved_regs, TCG_FLOAT_TMP2); - } - --/*sw -- * unsigned 32bit, abcd->dcba -- */ --static void tcg_out_bswap32u(TCGContext *s, TCGReg rd, TCGReg rn) --{ -- TCGReg TCG_TMP0 = rn; -- TCGReg TCG_TMP3 = rd; -- TCGReg TCG_TMP1 = TCG_REG_TMP; -- TCGReg TCG_TMP2 = TCG_REG_TMP2; -- -- /*bswap32u -- unsigned 32-bit swap. a0 = ....abcd.*/ -- /* t1 = (0000)000d */ -- tcg_out_insn_bitImm(s, OPC_AND_I, TCG_TMP1, TCG_TMP0, 0xff); -- /* t3 = 000a */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP3, TCG_TMP0, 24); -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP3, TCG_TMP3, 0x1); -- /* t1 = (0000)d000 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP1, 24); -- /* t2 = 00c0 */ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP2, TCG_TMP0, 0x2); -- /* t3 = d00a */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -- /* t1 = 0abc */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 8); -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x7); -- /* t2 = 0c00 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 8); -- /* t1 = 00b0 */ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x2); -- /* t3 = dc0a */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -- /* t3 = dcba -- delay slot */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); --} -+ -+#define PUSH_SIZE ((15-9+1+1) * 8) -+#define FRAME_SIZE \ -+ ((PUSH_SIZE \ -+ + TCG_STATIC_CALL_ARGS_SIZE \ -+ + CPU_TEMP_BUF_NLONGS * sizeof(long) \ -+ + TCG_TARGET_STACK_ALIGN - 1) \ -+ & ~(TCG_TARGET_STACK_ALIGN - 1)) - - -+/* We're expecting a 2 byte uleb128 encoded value. */ -+QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14)); - --/*sw -- * swap 64bit, abcdefgh->hgfedcba -- */ --static void tcg_out_bswap64(TCGContext *s, TCGReg rd, TCGReg rn) -+/* We're expecting to use a single ADDI insn. */ -+QEMU_BUILD_BUG_ON(FRAME_SIZE - PUSH_SIZE > 0xfff); -+ -+static void tcg_target_qemu_prologue(TCGContext *s) - { -+ TCGReg r; -+ int ofs; - -- TCGReg TCG_TMP0 = rn; -- TCGReg TCG_TMP3 = rd; -- TCGReg TCG_TMP1 = TCG_REG_TMP; -- TCGReg TCG_TMP2 = TCG_REG_TMP2; -- -- /* bswap64 -- 64-bit swap. a0 = abcdefgh*/ -- -- /* t3 = h0000000 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP3, TCG_TMP0, 56); -- /* t1 = 0000000a */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 56); -- /* t2 = 000000g0 */ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP2, TCG_TMP0, 0x2); -- /* t3 = h000000a */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -- /* t1 = 00000abc */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 40); -- /* t2 = 0g000000 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 40); -- /* t1 = 000000b0 */ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x2); -- /* t3 = hg00000a */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -- /* t2 = 0000abcd */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP2, TCG_TMP0, 32); -- /* t3 = hg0000ba */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -- /* t1 = 000000c0 */ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP2, 0x2); -- /* t2 = 0000000d */ -- tcg_out_insn_bitImm(s, OPC_AND_I, TCG_TMP2, TCG_TMP2, 0xff); -- /* t1 = 00000c00 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP1, 8); -- /* t2 = 0000d000 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 24); -- /* t3 = hg000cba */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -- /* t1 = 00abcdef */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_TMP1, TCG_TMP0, 16); -- /* t3 = hg00dcba */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -- /* t2 = 0000000f */ -- tcg_out_insn_bitImm(s, OPC_AND_I, TCG_TMP2, TCG_TMP1, 0xff); -- /* t1 = 000000e0 */ -- tcg_out_insn_simpleImm(s, OPC_ZAPNOT_I, TCG_TMP1, TCG_TMP1, 0x2); -- /* t2 = 00f00000 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP2, TCG_TMP2, 40); -- /* t1 = 000e0000 */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_TMP1, TCG_TMP1, 24); -- /* t3 = hgf0dcba */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP2); -- /* t3 = hgfedcba -- delay slot */ -- tcg_out_insn_bitReg(s, OPC_BIS, TCG_TMP3, TCG_TMP3, TCG_TMP1); -+ /* allocate space for all saved registers */ -+ /* subl $sp,PUSH_SIZE,$sp */ -+ tcg_out_simple(s, OPC_SUBL_I, OPC_SUBL, TCG_REG_SP, TCG_REG_SP, PUSH_SIZE); - --} -+ /* Push (FP, LR) */ -+ /* stl $fp,0($sp) */ -+ tcg_out_insn_ldst(s, OPC_STL, TCG_REG_FP, TCG_REG_SP, 0); -+ /* stl $26,8($sp) */ -+ tcg_out_insn_ldst(s, OPC_STL, TCG_REG_RA, TCG_REG_SP, 8); - --static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, MemOpIdx oi, TCGType ext) --{ --#ifndef CONFIG_SOFTMMU -- MemOp memop = get_memop(oi); -- const TCGType otype = TCG_TYPE_I64; - -- if (USE_GUEST_BASE) { -- tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_GUEST_BASE, TCG_REG_GUEST_BASE, addr_reg); -- tcg_out_qemu_ld_direct(s, memop, data_reg, TCG_REG_GUEST_BASE, otype, 0); -- } else { -- tcg_out_qemu_ld_direct(s, memop, data_reg, addr_reg, TCG_TYPE_I64, 0); -+ /* Set up frame pointer for canonical unwinding. */ -+ /* TCG_REG_FP=TCG_REG_SP */ -+ tcg_out_movr(s, TCG_TYPE_I64, TCG_REG_FP, TCG_REG_SP); -+ -+ /* Store callee-preserved regs x9..x14. */ -+ for (r = TCG_REG_X9; r <= TCG_REG_X14; r += 1){ -+ ofs = (r - TCG_REG_X9 + 2) * 8; -+ tcg_out_insn_ldst(s, OPC_STL, r, TCG_REG_SP, ofs); - } --#endif /* CONFIG_SOFTMMU */ - --} -+ /* Make stack space for TCG locals. */ -+ /* subl $sp,FRAME_SIZE-PUSH_SIZE,$sp */ -+ tcg_out_simple(s, OPC_SUBL_I, OPC_SUBL, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE - PUSH_SIZE); - --static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, -- MemOpIdx oi) --{ --#ifndef CONFIG_SOFTMMU -- MemOp memop = get_memop(oi); -- const TCGType otype = TCG_TYPE_I64; -+ /* Inform TCG about how to find TCG locals with register, offset, size. */ -+ tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, -+ CPU_TEMP_BUF_NLONGS * sizeof(long)); - -+#ifndef CONFIG_SOFTMMU - if (USE_GUEST_BASE) { -- tcg_out_insn_simpleReg(s, OPC_ADDL, TCG_REG_GUEST_BASE, TCG_REG_GUEST_BASE, addr_reg); -- tcg_out_qemu_st_direct(s, memop, data_reg, TCG_REG_GUEST_BASE, otype, 0); -- } else { -- tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, TCG_TYPE_I64, 0); -+ tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_GUEST_BASE, guest_base); -+ tcg_regset_set_reg(s->reserved_regs, TCG_REG_GUEST_BASE); - } --#endif /* CONFIG_SOFTMMU */ --} -- -- --/*sw -- * if cond is successful, ret=1, otherwise ret = 0 -- */ --static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, -- TCGReg arg1, TCGReg arg2) --{ -- switch(cond) { -- case TCG_COND_EQ: -- case TCG_COND_LT: -- case TCG_COND_LE: -- case TCG_COND_LTU: -- case TCG_COND_LEU: -- case TCG_COND_NE: -- case TCG_COND_GE: -- case TCG_COND_GT: -- case TCG_COND_GEU: -- case TCG_COND_GTU: -- tcg_out_cond_cmp(s, cond, ret, arg1, arg2, 0); -- break; -- default: -- tcg_abort(); -- break; -- } --} --/*sw -- * cond(a1,a2), yes:v1->ret, no:v2->ret -- */ --static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret, -- TCGReg a1, TCGReg a2, bool const_b, TCGReg v1, TCGReg v2) --{ -- tcg_out_cond_cmp(s, cond, TCG_REG_TMP, a1, a2, const_b); -- tcg_out_insn_complexReg(s, OPC_SELLBS, TCG_REG_TMP, ret, v1, v2); --} -- -- -+#endif - --/*sw -- * extract rn[lsb, lsb+len-1] -> rd[0, len-1] -- */ --static void tcg_out_extract(TCGContext *s, TCGReg rd, TCGReg rn, int lsb, int len) --{ -- //get 000..111..0000 -- tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_ZERO); -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP, TCG_REG_TMP, 64 - len); -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, lsb); -- /* get rn[lsb, lsb+len-1]-->rd[lsb, lsb+len-1] */ -- tcg_out_insn_bitReg(s, OPC_AND, rd, rn, TCG_REG_TMP); -+ /* TCG_AREG0=tcg_target_call_iarg_regs[0], on sw, we mov $16 to $9 */ -+ tcg_out_mov(s, TCG_TYPE_I64, TCG_AREG0, tcg_target_call_iarg_regs[0]); -+ tcg_out_insn_jump(s, OPC_JMP, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], noPara); - -- /* rd[lsb, lsb+len-1] --> rd[0, len-1] */ -- tcg_out_insn_bitImm(s, OPC_SRL_I, rd, rd, lsb); --} -+ /* -+ * Return path for goto_ptr. Set return value to 0, a-la exit_tb, -+ * and fall through to the rest of the epilogue. -+ */ -+ tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr); -+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, 0); - -+ /* TB epilogue */ -+ tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr); - --/*sw -- * depos: rd = rd[63:msb+1]:rn[msb,lsb]:rd[lsb-1,0] -- * len = msb -lsb + 1 -- */ --static void tcg_out_dep(TCGContext *s, TCGReg rd, TCGReg rn, int lsb, int len) --{ -+ /* Remove TCG locals stack space. */ -+ /* addl $sp,FRAME_SIZE-PUSH_SIZE,$sp */ -+ tcg_out_simple(s, OPC_ADDL_I, OPC_ADDL, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE - PUSH_SIZE); - -- //get 000..111..0000 -- tcg_out_insn_bitReg(s, OPC_ORNOT, TCG_REG_TMP, TCG_REG_ZERO, TCG_REG_ZERO); -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP, TCG_REG_TMP, 64 - len); -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP, TCG_REG_TMP, lsb); -+ /* Restore registers x9..x14. */ -+ for (r = TCG_REG_X9; r <= TCG_REG_X14; r += 1) { -+ int ofs = (r - TCG_REG_X9 + 2) * 8; -+ tcg_out_insn_ldst(s, OPC_LDL, r, TCG_REG_SP, ofs); -+ } - -- /* TCG_REG_TMP2 = rn[msb,lsb] */ -- tcg_out_insn_bitImm(s, OPC_SLL_I, TCG_REG_TMP2, rn, 64-len); -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, TCG_REG_TMP2, 64-len-lsb); -+ /* Pop (FP, LR) */ -+ /* ldl $fp,0($sp) */ -+ tcg_out_insn_ldst(s, OPC_LDL, TCG_REG_FP, TCG_REG_SP, 0); -+ /* ldl $26,8($sp) */ -+ tcg_out_insn_ldst(s, OPC_LDL, TCG_REG_RA, TCG_REG_SP, 8); - -- /* clear rd[msb,lsb] */ -- tcg_out_insn_bitReg(s, OPC_BIC, rd, rd, TCG_REG_TMP); -- /* rd = rd[63:msb+1]:rn[msb,lsb]:rd[lsb-1,0] */ -- tcg_out_insn_bitReg(s, OPC_BIS, rd, rd, TCG_REG_TMP2); -+ /* restore SP to previous frame. */ -+ /* addl $sp,PUSH_SIZE,$sp */ -+ tcg_out_simple(s, OPC_ADDL_I, OPC_ADDL, TCG_REG_SP, TCG_REG_SP, PUSH_SIZE); -+ -+ tcg_out_insn_jump(s, OPC_RET, TCG_REG_ZERO, TCG_REG_RA, noPara); - } - --/*sw -- * get val_s64(rn) * val_s64(rm) -> res_128 -- * res[127:64] -> rd -- * warn:maybe rd=rn or rm -- */ --static void tcg_out_mulsh64(TCGContext *s, TCGReg rd, TCGReg rn, TCGReg rm) -+static void tcg_out_nop_fill(tcg_insn_unit *p, int count) - { -- tcg_out_insn_simpleReg(s, OPC_UMULH, TCG_REG_TMP, rn, rm); -- -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, rn, 63); -- tcg_out_insn_complexReg(s, OPC_SELEQ, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_ZERO, rm); -- tcg_out_insn_simpleReg(s, OPC_SUBL, TCG_REG_TMP, TCG_REG_TMP, TCG_REG_TMP2); -- -- tcg_out_insn_bitImm(s, OPC_SRL_I, TCG_REG_TMP2, rm, 63); -- tcg_out_insn_complexReg(s, OPC_SELEQ, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_ZERO, rn); -- tcg_out_insn_simpleReg(s, OPC_SUBL, rd, TCG_REG_TMP, TCG_REG_TMP2); -+ int i; -+ for (i = 0; i < count; ++i) { -+ p[i] = OPC_NOP; -+ } - } - - typedef struct { -@@ -2071,9 +2424,11 @@ typedef struct { - uint8_t fde_reg_ofs[8 * 2]; - } DebugFrame; - -+/* -+ * GDB doesn't appear to require proper setting of ELF_HOST_FLAGS, -+ * which is good because they're really quite complicated for SW64. -+ */ - #define ELF_HOST_MACHINE EM_SW_64 --/* GDB doesn't appear to require proper setting of ELF_HOST_FLAGS, -- which is good because they're really quite complicated for SW_64. */ - - static const DebugFrame debug_frame = { - .h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */ -diff --git a/tcg/sw64/tcg-target.h b/tcg/sw64/tcg-target.h -index 3093e4fece..91681a0c75 100755 ---- a/tcg/sw64/tcg-target.h -+++ b/tcg/sw64/tcg-target.h -@@ -119,5 +119,8 @@ typedef enum { - #define TCG_TARGET_HAS_MEMORY_BSWAP 0 - /* optional instructions */ - void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t); -+#ifdef CONFIG_SOFTMMU -+#define TCG_TARGET_NEED_LDST_LABELS -+#endif - #define TCG_TARGET_NEED_POOL_LABELS - #endif /* SW_64_TCG_TARGET_H */ --- -2.41.0.windows.1 - diff --git a/tap-return-err-when-tap-TUNGETIFF-fail.patch b/tap-return-err-when-tap-TUNGETIFF-fail.patch deleted file mode 100644 index f74fa19abc42f16414dad411c06590d66c612922..0000000000000000000000000000000000000000 --- a/tap-return-err-when-tap-TUNGETIFF-fail.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 48a38f409a25f26605d65346c8ed9403c4b36c80 Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Thu, 10 Feb 2022 10:28:59 +0800 -Subject: [PATCH] tap: return err when tap TUNGETIFF fail - -When hotplug ovs kernel netcard, even tap TUNGETIFF failed, -the hotplug would go on and would lead to qemu assert. -The failure should lead to the free_fail. - -Signed-off-by: miaoyubo -Signed-off-by: Yan Wang ---- - net/tap.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/net/tap.c b/net/tap.c -index f716be3e3f..c5cbeaa7a2 100644 ---- a/net/tap.c -+++ b/net/tap.c -@@ -900,6 +900,7 @@ int net_init_tap(const Netdev *netdev, const char *name, - if (i == 0) { - vnet_hdr = tap_probe_vnet_hdr(fd, errp); - if (vnet_hdr < 0) { -+ ret = -1; - goto free_fail; - } - } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) { --- -2.27.0 - diff --git a/target-arm-Add-CPU-features-to-query-cpu-model-expan.patch b/target-arm-Add-CPU-features-to-query-cpu-model-expan.patch deleted file mode 100644 index 3bb8d6a46f4c0d762f2590250931e6347629c30a..0000000000000000000000000000000000000000 --- a/target-arm-Add-CPU-features-to-query-cpu-model-expan.patch +++ /dev/null @@ -1,90 +0,0 @@ -From e6dd7faeea77206d7e6589cbb54ad43926457052 Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Thu, 6 Aug 2020 16:14:58 +0800 -Subject: [PATCH] target/arm: Add CPU features to query-cpu-model-expansion - -Add CPU features to the result of query-cpu-model-expansion so that -other applications (such as libvirt) can know the supported CPU -features. - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/cpu.c | 27 +++++++++++++++++++++++++++ - target/arm/cpu.h | 2 ++ - target/arm/monitor.c | 2 ++ - 3 files changed, 31 insertions(+) - -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index 3024f4a3f5..2d6a26336f 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -25,6 +25,8 @@ - #include "qemu/module.h" - #include "qapi/error.h" - #include "qapi/visitor.h" -+#include "qapi/qmp/qdict.h" -+#include "qom/qom-qobject.h" - #include "cpu.h" - #ifdef CONFIG_TCG - #include "hw/core/tcg-cpu-ops.h" -@@ -1580,6 +1582,31 @@ static const CPUFeatureDep feature_dependencies[] = { - }, - }; - -+void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features) -+{ -+ Object *obj = OBJECT(cpu); -+ const char *name; -+ ObjectProperty *prop; -+ bool is_32bit = !arm_feature(&cpu->env, ARM_FEATURE_AARCH64); -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(cpu_features); ++i) { -+ if (is_32bit != cpu_features[i].is_32bit) { -+ continue; -+ } -+ -+ name = cpu_features[i].name; -+ prop = object_property_find(obj, name); -+ if (prop) { -+ QObject *value; -+ -+ assert(prop->get); -+ value = object_property_get_qobject(obj, name, &error_abort); -+ qdict_put_obj(features, name, value); -+ } -+ } -+} -+ - static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) - { -diff --git a/target/arm/cpu.h b/target/arm/cpu.h -index 3dda33f347..947897d5ac 100644 ---- a/target/arm/cpu.h -+++ b/target/arm/cpu.h -@@ -4398,4 +4398,6 @@ static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id) - #define cpu_isar_feature(name, cpu) \ - ({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); }) - -+void arm_cpu_features_to_dict(ARMCPU *cpu, QDict *features); -+ - #endif -diff --git a/target/arm/monitor.c b/target/arm/monitor.c -index 80c64fa355..4c6f1181d9 100644 ---- a/target/arm/monitor.c -+++ b/target/arm/monitor.c -@@ -217,6 +217,8 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, - } - } - -+ arm_cpu_features_to_dict(ARM_CPU(obj), qdict_out); -+ - if (!qdict_size(qdict_out)) { - qobject_unref(qdict_out); - } else { --- -2.27.0 - diff --git a/target-arm-Add-missing-FEAT_TLBIOS-instructions.patch b/target-arm-Add-missing-FEAT_TLBIOS-instructions.patch deleted file mode 100644 index 44483e199daf5ed6f16ba1d77e8ce72aa86ec3af..0000000000000000000000000000000000000000 --- a/target-arm-Add-missing-FEAT_TLBIOS-instructions.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 1ac38ad4f16bf8fe4cabf1e41036f36ad08cf14f Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 23 Nov 2022 15:07:57 +0000 -Subject: [PATCH 14/29] target/arm: Add missing FEAT_TLBIOS instructions - -mainline inclusion -commit b7469ef92a8034b32031ba22b84fb14046f9770e -category: bugfix - ------------------------------------------------------------- - -Some of the instructions added by the FEAT_TLBIOS extension were forgotten -when the extension was originally added to QEMU. - -Fixes: 7113d618505b ("target/arm: Add support for FEAT_TLBIOS") -Signed-off-by: Idan Horowitz -Reviewed-by: Richard Henderson -Message-id: 20211231103928.1455657-1-idan.horowitz@gmail.com -Signed-off-by: Peter Maydell - -Signed-off-by: tangbinzy ---- - target/arm/helper.c | 32 ++++++++++++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - -diff --git a/target/arm/helper.c b/target/arm/helper.c -index 80737a8d7b..1854c65863 100644 ---- a/target/arm/helper.c -+++ b/target/arm/helper.c -@@ -6998,18 +6998,42 @@ static const ARMCPRegInfo tlbios_reginfo[] = { - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vmalle1is_write }, -+ { .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64, -+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1, -+ .access = PL1_W, .type = ARM_CP_NO_RAW, -+ .writefn = tlbi_aa64_vae1is_write }, - { .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2, - .access = PL1_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_vmalle1is_write }, -+ { .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64, -+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3, -+ .access = PL1_W, .type = ARM_CP_NO_RAW, -+ .writefn = tlbi_aa64_vae1is_write }, -+ { .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64, -+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5, -+ .access = PL1_W, .type = ARM_CP_NO_RAW, -+ .writefn = tlbi_aa64_vae1is_write }, -+ { .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64, -+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7, -+ .access = PL1_W, .type = ARM_CP_NO_RAW, -+ .writefn = tlbi_aa64_vae1is_write }, - { .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle2is_write }, -+ { .name = "TLBI_VAE2OS", .state = ARM_CP_STATE_AA64, -+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 1, -+ .access = PL2_W, .type = ARM_CP_NO_RAW, -+ .writefn = tlbi_aa64_vae2is_write }, - { .name = "TLBI_ALLE1OS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 4, - .access = PL2_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle1is_write }, -+ { .name = "TLBI_VALE2OS", .state = ARM_CP_STATE_AA64, -+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 5, -+ .access = PL2_W, .type = ARM_CP_NO_RAW, -+ .writefn = tlbi_aa64_vae2is_write }, - { .name = "TLBI_VMALLS12E1OS", .state = ARM_CP_STATE_AA64, - .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 6, - .access = PL2_W, .type = ARM_CP_NO_RAW, -@@ -7030,6 +7054,14 @@ static const ARMCPRegInfo tlbios_reginfo[] = { - .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 0, - .access = PL3_W, .type = ARM_CP_NO_RAW, - .writefn = tlbi_aa64_alle3is_write }, -+ { .name = "TLBI_VAE3OS", .state = ARM_CP_STATE_AA64, -+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 1, -+ .access = PL3_W, .type = ARM_CP_NO_RAW, -+ .writefn = tlbi_aa64_vae3is_write }, -+ { .name = "TLBI_VALE3OS", .state = ARM_CP_STATE_AA64, -+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 5, -+ .access = PL3_W, .type = ARM_CP_NO_RAW, -+ .writefn = tlbi_aa64_vae3is_write }, - REGINFO_SENTINEL - }; - --- -2.27.0 - diff --git a/target-arm-Add-more-CPU-features.patch b/target-arm-Add-more-CPU-features.patch deleted file mode 100644 index 4b8c01d5038e29505e5b4d19d4467e5054de792a..0000000000000000000000000000000000000000 --- a/target-arm-Add-more-CPU-features.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 85d5b46d8225c5875b8b3ff68967d46bcde9a549 Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Tue, 11 Aug 2020 10:28:10 +0800 -Subject: [PATCH] target/arm: Add more CPU features - -Add i8mm, bf16, and dgh CPU features for AArch64. - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/cpu.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index 2d6a26336f..1c1647a0a8 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -1309,6 +1309,9 @@ static struct CPUFeatureInfo cpu_features[] = { - FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true), - FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true), - FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true), -+ FIELD_INFO("i8mm", ID_AA64ISAR1, I8MM, false, 1, 0, false), -+ FIELD_INFO("bf16", ID_AA64ISAR1, BF16, false, 1, 0, false), -+ FIELD_INFO("dgh", ID_AA64ISAR1, DGH, false, 1, 0, false), - - FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true), - FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true), --- -2.27.0 - diff --git a/target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch b/target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch deleted file mode 100644 index 84645718d5fb1bcc3179bdf28f61d9d954d2dc9e..0000000000000000000000000000000000000000 --- a/target-arm-Allow-ID-registers-to-synchronize-to-KVM.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0272c52e36ab95389e665ca19b129178b0b46eac Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Thu, 6 Aug 2020 16:14:40 +0800 -Subject: [PATCH] target/arm: Allow ID registers to synchronize to KVM - -There are 2 steps to synchronize the values of system registers from -CPU state to KVM: -1. write to the values of system registers from CPU state to - (index,value) list by write_cpustate_to_list; -2. write the values in (index,value) list to KVM by - write_list_to_kvmstate; - -In step 1, the values of constant system registers are not allowed to -write to (index,value) list. However, a constant system register is -CONSTANT for guest but not for QEMU, which means, QEMU can set/modify -the value of constant system registers that is different from phsical -registers when startup. But if KVM is enabled, guest can not read the -values of the system registers which QEMU set unless they can be written -to (index,value) list. And why not try to write to KVM if kvm_sync is -true? - -At the moment we call write_cpustate_to_list, all ID registers are -contant, including ID_PFR1_EL1 and ID_AA64PFR0_EL1 because GIC has been -initialized. Hence, let's give all ID registers a chance to write to -KVM. If the write is successful, then write to (index,value) list. - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/helper.c | 31 ++++++++++++++++++++----------- - target/arm/kvm.c | 38 ++++++++++++++++++++++++++++++++++++++ - target/arm/kvm_arm.h | 3 +++ - 3 files changed, 61 insertions(+), 11 deletions(-) - -diff --git a/target/arm/helper.c b/target/arm/helper.c -index b8ea1dc1f6..79f77705c3 100644 ---- a/target/arm/helper.c -+++ b/target/arm/helper.c -@@ -35,6 +35,7 @@ - #include "exec/cpu_ldst.h" - #include "semihosting/common-semi.h" - #endif -+#include "kvm_arm.h" - - #define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */ - #define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */ -@@ -149,30 +150,38 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync) - ok = false; - continue; - } -- if (ri->type & ARM_CP_NO_RAW) { -+ /* -+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2), -+ * where 1<=crm<8, 0<=op2<8. Let's give ID registers a chance to -+ * synchronize to kvm. -+ */ -+ if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync && -+ ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && ri->crm > 0)) { - continue; - } - - newval = read_raw_cp_reg(&cpu->env, ri); - if (kvm_sync) { -- /* -- * Only sync if the previous list->cpustate sync succeeded. -- * Rather than tracking the success/failure state for every -- * item in the list, we just recheck "does the raw write we must -- * have made in write_list_to_cpustate() read back OK" here. -- */ -- uint64_t oldval = cpu->cpreg_values[i]; -+ /* Only sync if we can sync to KVM successfully. */ -+ uint64_t oldval; -+ uint64_t kvmval; - -+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) { -+ continue; -+ } - if (oldval == newval) { - continue; - } - -- write_raw_cp_reg(&cpu->env, ri, oldval); -- if (read_raw_cp_reg(&cpu->env, ri) != oldval) { -+ if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) { -+ continue; -+ } -+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) || -+ kvmval != newval) { - continue; - } - -- write_raw_cp_reg(&cpu->env, ri, newval); -+ kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval); - } - cpu->cpreg_values[i] = newval; - } -diff --git a/target/arm/kvm.c b/target/arm/kvm.c -index bbf1ce7ba3..59d556724f 100644 ---- a/target/arm/kvm.c -+++ b/target/arm/kvm.c -@@ -514,6 +514,44 @@ out: - return ret; - } - -+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target) -+{ -+ uint32_t v32; -+ int ret; -+ -+ switch (regidx & KVM_REG_SIZE_MASK) { -+ case KVM_REG_SIZE_U32: -+ ret = kvm_get_one_reg(CPU(cpu), regidx, &v32); -+ if (ret == 0) { -+ *target = v32; -+ } -+ return ret; -+ case KVM_REG_SIZE_U64: -+ return kvm_get_one_reg(CPU(cpu), regidx, target); -+ default: -+ return -1; -+ } -+} -+ -+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source) -+{ -+ uint32_t v32; -+ -+ switch (regidx & KVM_REG_SIZE_MASK) { -+ case KVM_REG_SIZE_U32: -+ v32 = *source; -+ if (v32 != *source) { -+ error_report("the value of source is too large"); -+ return -1; -+ } -+ return kvm_set_one_reg(CPU(cpu), regidx, &v32); -+ case KVM_REG_SIZE_U64: -+ return kvm_set_one_reg(CPU(cpu), regidx, source); -+ default: -+ return -1; -+ } -+} -+ - bool write_kvmstate_to_list(ARMCPU *cpu) - { - CPUState *cs = CPU(cpu); -diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h -index b7f78b5215..f8e0e64363 100644 ---- a/target/arm/kvm_arm.h -+++ b/target/arm/kvm_arm.h -@@ -528,4 +528,7 @@ static inline const char *its_class_name(void) - } - } - -+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target); -+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source); -+ - #endif --- -2.27.0 - diff --git a/target-arm-Copy-the-entire-vector-in-DO_ZIP.patch b/target-arm-Copy-the-entire-vector-in-DO_ZIP.patch deleted file mode 100644 index 328c224b6a2bb5f6c59b5a5db50126332d041083..0000000000000000000000000000000000000000 --- a/target-arm-Copy-the-entire-vector-in-DO_ZIP.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5386c69970911a73c705068b72048437b1c27df0 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Tue, 22 Nov 2022 17:52:53 +0800 -Subject: [PATCH 04/29] target/arm: Copy the entire vector in DO_ZIP - -With odd_ofs set, we weren't copying enough data. -Fixes: 09eb6d7025d1 ("target/arm: Move sve zip high_ofs into simd_data") - -Reported-by: Idan Horowitz -Signed-off-by: Richard Henderson -Signed-off-by: jianchunfu ---- - target/arm/sve_helper.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c -index 07be55b7e1..03d58cabc8 100644 ---- a/target/arm/sve_helper.c -+++ b/target/arm/sve_helper.c -@@ -3387,10 +3387,10 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \ - /* We produce output faster than we consume input. \ - Therefore we must be mindful of possible overlap. */ \ - if (unlikely((vn - vd) < (uintptr_t)oprsz)) { \ -- vn = memcpy(&tmp_n, vn, oprsz_2); \ -+ vn = memcpy(&tmp_n, vn, oprsz); \ - } \ - if (unlikely((vm - vd) < (uintptr_t)oprsz)) { \ -- vm = memcpy(&tmp_m, vm, oprsz_2); \ -+ vm = memcpy(&tmp_m, vm, oprsz); \ - } \ - for (i = 0; i < oprsz_2; i += sizeof(TYPE)) { \ - *(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + H(i)); \ --- -2.27.0 - diff --git a/target-arm-Don-t-set-syndrome-ISS-for-loads-and-stor.patch b/target-arm-Don-t-set-syndrome-ISS-for-loads-and-stor.patch deleted file mode 100644 index 4fe6a0cd77d1839db5c46f6b149bc4b996cc8672..0000000000000000000000000000000000000000 --- a/target-arm-Don-t-set-syndrome-ISS-for-loads-and-stor.patch +++ /dev/null @@ -1,51 +0,0 @@ -From dd5bf5817259ea414f40b25f4aef3864eddb9706 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 27 Nov 2023 03:24:57 +0000 -Subject: [PATCH] target/arm: Don't set syndrome ISS for loads and stores with - writeback mainline inclusion commit 53ae2fdef1f5661cbaa2ea571c517f98e6041cb8 - category: bugfix - ---------------------------------------------------------------- - -The architecture requires that for faults on loads and stores which -do writeback, the syndrome information does not have the ISS -instruction syndrome information (i.e. ISV is 0). We got this wrong -for the load and store instructions covered by disas_ldst_reg_imm9(). -Calculate iss_valid correctly so that if the insn is a writeback one -it is false. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1057 -Signed-off-by: Peter Maydell -Reviewed-by: Richard Henderson -Message-id: 20220715123323.1550983-1-peter.maydell@linaro.org - -Signed-off-by: tangbinzy ---- - target/arm/translate-a64.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c -index cec672f229..549a671bea 100644 ---- a/target/arm/translate-a64.c -+++ b/target/arm/translate-a64.c -@@ -3039,7 +3039,7 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn, - bool is_store = false; - bool is_extended = false; - bool is_unpriv = (idx == 2); -- bool iss_valid = !is_vector; -+ bool iss_valid; - bool post_index; - bool writeback; - int memidx; -@@ -3092,6 +3092,8 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn, - g_assert_not_reached(); - } - -+ iss_valid = !is_vector && !writeback; -+ - if (rn == 31) { - gen_check_sp_alignment(s); - } --- -2.27.0 - diff --git a/target-arm-Fix-some-compile-errors.patch b/target-arm-Fix-some-compile-errors.patch deleted file mode 100644 index 2a0e1e9dda1b6552e33a9a5b93806e3c1d0d9305..0000000000000000000000000000000000000000 --- a/target-arm-Fix-some-compile-errors.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 6a5a391c9c6f6c0cd105ce3495acc10868bad884 Mon Sep 17 00:00:00 2001 -From: Dongxu Sun -Date: Tue, 15 Feb 2022 14:40:48 +0800 -Subject: [PATCH] target/arm: Fix some compile errors - -fix compile errors like: - "implicit declaration of function 'kvm_arm_cpu_feature_supported'"; - "undefined reference to 'kvm_arm_get_one_reg'" - "undefined reference to 'kvm_arm_set_one_reg'" - "'kvmval' may be used uninitialized" - "'oldval' may be used uninitialized" - -Signed-off-by: Dongxu Sun ---- - target/arm/helper.c | 4 ++-- - target/arm/kvm_arm.h | 23 ++++++++++++++++++++--- - 2 files changed, 22 insertions(+), 5 deletions(-) - -diff --git a/target/arm/helper.c b/target/arm/helper.c -index 1dd5d64d96..80737a8d7b 100644 ---- a/target/arm/helper.c -+++ b/target/arm/helper.c -@@ -168,8 +168,8 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync) - if (kvm_sync) { - if (is_id_reg(ri)) { - /* Only sync if we can sync to KVM successfully. */ -- uint64_t oldval; -- uint64_t kvmval; -+ uint64_t oldval = 0; -+ uint64_t kvmval = 0; - - if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) { - continue; -diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h -index 82145607ec..8b644b3924 100644 ---- a/target/arm/kvm_arm.h -+++ b/target/arm/kvm_arm.h -@@ -377,6 +377,9 @@ void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa); - - int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level); - -+int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target); -+int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source); -+ - #else - - /* -@@ -403,6 +406,11 @@ static inline bool kvm_arm_steal_time_supported(void) - return false; - } - -+static inline bool kvm_arm_cpu_feature_supported(void) -+{ -+ return false; -+} -+ - /* - * These functions should never actually be called without KVM support. - */ -@@ -451,6 +459,18 @@ static inline void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) - g_assert_not_reached(); - } - -+static inline int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, -+ uint64_t *target) -+{ -+ g_assert_not_reached(); -+} -+ -+static inline int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, -+ uint64_t *source) -+{ -+ g_assert_not_reached(); -+} -+ - #endif - - static inline const char *gic_class_name(void) -@@ -535,7 +555,4 @@ static inline const char *its_class_name(void) - } - } - --int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target); --int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source); -- - #endif --- -2.27.0 - diff --git a/target-arm-Fix-write-redundant-values-to-kvm.patch b/target-arm-Fix-write-redundant-values-to-kvm.patch deleted file mode 100644 index db03f8b6710f725610022f78d7b5c33a27ff3acc..0000000000000000000000000000000000000000 --- a/target-arm-Fix-write-redundant-values-to-kvm.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 9680adfba5ca871f69a6fbd15b92571fc2a52d78 Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Wed, 9 Dec 2020 19:35:08 +0800 -Subject: [PATCH] target/arm: Fix write redundant values to kvm - -After modifying the value of a ID register, we'd better to try to write -it to KVM so that we can known the value is acceptable for KVM. -Because it may modify the registers' values of KVM, it's not suitable -for other registers. - -(cherry-picked from a0d7a9de807639fcfcbe1fe037cb8772d459a9cf) -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/helper.c | 73 ++++++++++++++++++++++++++++++--------------- - 1 file changed, 49 insertions(+), 24 deletions(-) - -diff --git a/target/arm/helper.c b/target/arm/helper.c -index 4c7b4cadfa..1dd5d64d96 100644 ---- a/target/arm/helper.c -+++ b/target/arm/helper.c -@@ -134,6 +134,16 @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri) - return true; - } - -+static bool is_id_reg(const ARMCPRegInfo *ri) -+{ -+ /* -+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2), -+ * where 1<=crm<8, 0<=op2<8. -+ */ -+ return ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && -+ ri->crm > 0 && ri->crm < 8; -+} -+ - bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync) - { - /* Write the coprocessor state from cpu->env to the (index,value) list. */ -@@ -150,38 +160,53 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync) - ok = false; - continue; - } -- /* -- * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2), -- * where 1<=crm<8, 0<=op2<8. Let's give ID registers a chance to -- * synchronize to kvm. -- */ -- if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync && -- ri->opc0 == 3 && ri->opc1 == 0 && ri->crn == 0 && ri->crm > 0)) { -+ if ((ri->type & ARM_CP_NO_RAW) && !(kvm_sync && is_id_reg(ri))) { - continue; - } - - newval = read_raw_cp_reg(&cpu->env, ri); - if (kvm_sync) { -- /* Only sync if we can sync to KVM successfully. */ -- uint64_t oldval; -- uint64_t kvmval; -+ if (is_id_reg(ri)) { -+ /* Only sync if we can sync to KVM successfully. */ -+ uint64_t oldval; -+ uint64_t kvmval; - -- if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) { -- continue; -- } -- if (oldval == newval) { -- continue; -- } -+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &oldval)) { -+ continue; -+ } -+ if (oldval == newval) { -+ continue; -+ } - -- if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) { -- continue; -- } -- if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) || -- kvmval != newval) { -- continue; -- } -+ if (kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &newval)) { -+ continue; -+ } -+ if (kvm_arm_get_one_reg(cpu, cpu->cpreg_indexes[i], &kvmval) || -+ kvmval != newval) { -+ continue; -+ } -+ -+ kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval); -+ } else { -+ /* -+ * Only sync if the previous list->cpustate sync succeeded. -+ * Rather than tracking the success/failure state for every -+ * item in the list, we just recheck "does the raw write we must -+ * have made in write_list_to_cpustate() read back OK" here. -+ */ -+ uint64_t oldval = cpu->cpreg_values[i]; -+ -+ if (oldval == newval) { -+ continue; -+ } - -- kvm_arm_set_one_reg(cpu, cpu->cpreg_indexes[i], &oldval); -+ write_raw_cp_reg(&cpu->env, ri, oldval); -+ if (read_raw_cp_reg(&cpu->env, ri) != oldval) { -+ continue; -+ } -+ -+ write_raw_cp_reg(&cpu->env, ri, newval); -+ } - } - cpu->cpreg_values[i] = newval; - } --- -2.27.0 - diff --git a/target-arm-Move-sve-probe-inside-kvm-4.15-branch.patch b/target-arm-Move-sve-probe-inside-kvm-4.15-branch.patch deleted file mode 100644 index 3ee1d63cd2268f958971f09f45c1c361020aee09..0000000000000000000000000000000000000000 --- a/target-arm-Move-sve-probe-inside-kvm-4.15-branch.patch +++ /dev/null @@ -1,54 +0,0 @@ -From d52674bfb6241316e436c8fe40dd5312950194dd Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Mon, 1 Aug 2022 16:21:18 +0100 -Subject: [PATCH 3/5] target/arm: Move sve probe inside kvm >= 4.15 branch - -The test for the IF block indicates no ID registers are exposed, much -less host support for SVE. Move the SVE probe into the ELSE block. - -Signed-off-by: Richard Henderson -Message-id: 20220726045828.53697-4-richard.henderson@linaro.org -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell -Signed-off-by: Kunkun Jiang ---- - target/arm/kvm64.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - -diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c -index 5b15d0582d..0f67b8ba96 100644 ---- a/target/arm/kvm64.c -+++ b/target/arm/kvm64.c -@@ -654,18 +654,18 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - dbgdidr |= (1 << 15); /* RES1 bit */ - ahcf->isar.regs[DBGDIDR] = dbgdidr; - } -- } - -- if (sve_supported) { -- /* -- * There is a range of kernels between kernel commit 73433762fcae -- * and f81cb2c3ad41 which have a bug where the kernel doesn't expose -- * SYS_ID_AA64ZFR0_EL1 via the ONE_REG API unless the VM has enabled -- * SVE support, which resulted in an error rather than RAZ. -- * So only read the register if we set KVM_ARM_VCPU_SVE above. -- */ -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64ZFR0], -- ARM64_SYS_REG(3, 0, 0, 4, 4)); -+ if (sve_supported) { -+ /* -+ * There is a range of kernels between kernel commit 73433762fcae -+ * and f81cb2c3ad41 which have a bug where the kernel doesn't -+ * expose SYS_ID_AA64ZFR0_EL1 via the ONE_REG API unless the VM has -+ * enabled SVE support, which resulted in an error rather than RAZ. -+ * So only read the register if we set KVM_ARM_VCPU_SVE above. -+ */ -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64ZFR0], -+ ARM64_SYS_REG(3, 0, 0, 4, 4)); -+ } - } - - kvm_arm_destroy_scratch_host_vcpu(fdarray); --- -2.27.0 - diff --git a/target-arm-Set-KVM_ARM_VCPU_SVE-while-probing-the-ho.patch b/target-arm-Set-KVM_ARM_VCPU_SVE-while-probing-the-ho.patch deleted file mode 100644 index e00097e947a4a8e6aba91a545ef0a527c5f65535..0000000000000000000000000000000000000000 --- a/target-arm-Set-KVM_ARM_VCPU_SVE-while-probing-the-ho.patch +++ /dev/null @@ -1,79 +0,0 @@ -From c9b226f4a56bb13d4f0924ea3ce4b334e65e6db2 Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Mon, 1 Aug 2022 16:21:18 +0100 -Subject: [PATCH 2/5] target/arm: Set KVM_ARM_VCPU_SVE while probing the host - -Because we weren't setting this flag, our probe of ID_AA64ZFR0 -was always returning zero. This also obviates the adjustment -of ID_AA64PFR0, which had sanitized the SVE field. - -The effects of the bug are not visible, because the only thing that -ID_AA64ZFR0 is used for within qemu at present is tcg translation. -The other tests for SVE within KVM are via ID_AA64PFR0.SVE. - -Reported-by: Zenghui Yu -Signed-off-by: Richard Henderson -Message-id: 20220726045828.53697-3-richard.henderson@linaro.org -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell -Signed-off-by: Kunkun Jiang ---- - target/arm/kvm64.c | 26 ++++++++++++++------------ - 1 file changed, 14 insertions(+), 12 deletions(-) - -diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c -index b7e34a4580..5b15d0582d 100644 ---- a/target/arm/kvm64.c -+++ b/target/arm/kvm64.c -@@ -501,7 +501,6 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - int fdarray[3]; - bool sve_supported; - uint64_t features = 0; -- uint64_t t; - int err; - - /* Old kernels may not know about the PREFERRED_TARGET ioctl: however -@@ -521,6 +520,15 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - */ - struct kvm_vcpu_init init = { .target = -1, }; - -+ /* -+ * Ask for SVE if supported, so that we can query ID_AA64ZFR0, -+ * which is otherwise RAZ. -+ */ -+ sve_supported = kvm_arm_sve_supported(); -+ if (sve_supported) { -+ init.features[0] |= 1 << KVM_ARM_VCPU_SVE; -+ } -+ - if (!kvm_arm_create_scratch_host_vcpu(cpus_to_try, fdarray, &init)) { - return false; - } -@@ -648,19 +656,13 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - } - } - -- sve_supported = kvm_arm_sve_supported(); -- -- /* Add feature bits that can't appear until after VCPU init. */ - if (sve_supported) { -- t = ahcf->isar.regs[ID_AA64PFR0]; -- t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1); -- ahcf->isar.regs[ID_AA64PFR0] = t; -- - /* -- * Before v5.1, KVM did not support SVE and did not expose -- * ID_AA64ZFR0_EL1 even as RAZ. After v5.1, KVM still does -- * not expose the register to "user" requests like this -- * unless the host supports SVE. -+ * There is a range of kernels between kernel commit 73433762fcae -+ * and f81cb2c3ad41 which have a bug where the kernel doesn't expose -+ * SYS_ID_AA64ZFR0_EL1 via the ONE_REG API unless the VM has enabled -+ * SVE support, which resulted in an error rather than RAZ. -+ * So only read the register if we set KVM_ARM_VCPU_SVE above. - */ - err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64ZFR0], - ARM64_SYS_REG(3, 0, 0, 4, 4)); --- -2.27.0 - diff --git a/target-arm-Update-the-ID-registers-of-Kunpeng-920.patch b/target-arm-Update-the-ID-registers-of-Kunpeng-920.patch deleted file mode 100644 index b632a31c8a51205849560417d40db9ce0a8c5c39..0000000000000000000000000000000000000000 --- a/target-arm-Update-the-ID-registers-of-Kunpeng-920.patch +++ /dev/null @@ -1,58 +0,0 @@ -From e2cb8b57278357c0a42cf7722b8c28b6f8d7585c Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Sat, 19 Sep 2020 09:04:45 +0800 -Subject: [PATCH] target/arm: Update the ID registers of Kunpeng-920 - -The values of some ID registers in Kunpeng-920 are not exactly correct. -Let's update them. The values are read from Kunpeng-920 by calling -read_sysreg_s. - -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/cpu64.c | 27 +++++++++++++++++++++++++-- - 1 file changed, 25 insertions(+), 2 deletions(-) - -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 287e7ac91c..3ec788fc29 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -262,10 +262,33 @@ static void aarch64_kunpeng_920_initfn(Object *obj) - - cpu->midr = 0x480fd010; - cpu->ctr = 0x84448004; -- cpu->isar.regs[ID_AA64PFR0] = 0x11001111; -+ cpu->isar.regs[ID_ISAR0] = 0; -+ cpu->isar.regs[ID_ISAR1] = 0; -+ cpu->isar.regs[ID_ISAR2] = 0; -+ cpu->isar.regs[ID_ISAR3] = 0; -+ cpu->isar.regs[ID_ISAR4] = 0; -+ cpu->isar.regs[ID_ISAR5] = 0; -+ cpu->isar.regs[ID_MMFR0] = 0; -+ cpu->isar.regs[ID_MMFR1] = 0; -+ cpu->isar.regs[ID_MMFR2] = 0; -+ cpu->isar.regs[ID_MMFR3] = 0; -+ cpu->isar.regs[ID_MMFR4] = 0; -+ cpu->isar.regs[MVFR0] = 0; -+ cpu->isar.regs[MVFR1] = 0; -+ cpu->isar.regs[MVFR2] = 0; -+ cpu->isar.regs[ID_DFR0] = 0; -+ cpu->isar.regs[MVFR2] = 0; -+ cpu->isar.regs[MVFR2] = 0; -+ cpu->isar.regs[MVFR2] = 0; -+ cpu->isar.regs[ID_PFR0] = 0; -+ cpu->isar.regs[ID_PFR1] = 0; -+ cpu->isar.regs[ID_AA64PFR0] = 0x0000010011111111; - cpu->isar.regs[ID_AA64DFR0] = 0x110305408; -- cpu->isar.regs[ID_AA64ISAR0] = 0x10211120; -+ cpu->isar.regs[ID_AA64ISAR0] = 0x0001100010211120; -+ cpu->isar.regs[ID_AA64ISAR1] = 0x00011001; - cpu->isar.regs[ID_AA64MMFR0] = 0x101125; -+ cpu->isar.regs[ID_AA64MMFR1] = 0x10211122; -+ cpu->isar.regs[ID_AA64MMFR2] = 0x00001011; - } - - void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) --- -2.27.0 - diff --git a/target-arm-Use-kvm_arm_sve_supported-in-kvm_arm_get_.patch b/target-arm-Use-kvm_arm_sve_supported-in-kvm_arm_get_.patch deleted file mode 100644 index 9c5a9a3273233deef37fd3679a3ab578671a9686..0000000000000000000000000000000000000000 --- a/target-arm-Use-kvm_arm_sve_supported-in-kvm_arm_get_.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 110206cee2cf58b6ce4119e230b142192f7b52ac Mon Sep 17 00:00:00 2001 -From: Richard Henderson -Date: Mon, 1 Aug 2022 16:21:17 +0100 -Subject: [PATCH 1/5] target/arm: Use kvm_arm_sve_supported in - kvm_arm_get_host_cpu_features - -Indication for support for SVE will not depend on whether we -perform the query on the main kvm_state or the temp vcpu. - -Signed-off-by: Richard Henderson -Message-id: 20220726045828.53697-2-richard.henderson@linaro.org -Reviewed-by: Peter Maydell -Signed-off-by: Peter Maydell -Signed-off-by: Kunkun Jiang ---- - target/arm/kvm64.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c -index b34a87fd24..b7e34a4580 100644 ---- a/target/arm/kvm64.c -+++ b/target/arm/kvm64.c -@@ -648,7 +648,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - } - } - -- sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0; -+ sve_supported = kvm_arm_sve_supported(); - - /* Add feature bits that can't appear until after VCPU init. */ - if (sve_supported) { --- -2.27.0 - diff --git a/target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch b/target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch deleted file mode 100644 index a8d5ac0be9b6943904393406d3104f1a7a9353e1..0000000000000000000000000000000000000000 --- a/target-arm-clear-EL2-and-EL3-only-when-kvm-is-not-en.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 20bd52038a960e0c959af38a5d3d7a6601db8e8b Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Mon, 21 Sep 2020 22:14:20 +0800 -Subject: [PATCH] target/arm: clear EL2 and EL3 only when kvm is not enabled - -When has_el2 and has_el3 are disabled, which is the default value for -virt machine, QEMU will clear the corresponding field in ID_PFR1_EL1 and -ID_AA64PFR0_EL1 to not expose EL3 and EL2 to guest. Because KVM doesn't -support to emulate ID registers in AArch64 before, it will not take -effect. Hence, clear EL2 and EL3 only when kvm is not enabled for -backwards compatibility. - -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/cpu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index 1c1647a0a8..65163f5135 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -2283,7 +2283,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - } - } - -- if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3) { -+ if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3 && !kvm_enabled()) { - /* If the has_el3 CPU property is disabled then we need to disable the - * feature. - */ -@@ -2324,7 +2324,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - cpu->pmceid1 = 0; - } - -- if (!arm_feature(env, ARM_FEATURE_EL2)) { -+ if (!arm_feature(env, ARM_FEATURE_EL2) && !kvm_enabled()) { - /* Disable the hypervisor feature bits in the processor feature - * registers if we don't have EL2. These are id_pfr1[15:12] and - * id_aa64pfr0_el1[11:8]. --- -2.27.0 - diff --git a/target-arm-convert-isar-regs-to-array.patch b/target-arm-convert-isar-regs-to-array.patch deleted file mode 100644 index 14e9a0865434bed3b0bba3038a3fb1540bbb29b8..0000000000000000000000000000000000000000 --- a/target-arm-convert-isar-regs-to-array.patch +++ /dev/null @@ -1,2781 +0,0 @@ -From bd8514594f0226b4599019ff123321138bb04d39 Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Thu, 6 Aug 2020 16:14:25 +0800 -Subject: [PATCH] target/arm: convert isar regs to array - -The isar in ARMCPU is a struct, each field of which represents an ID -register. It's not convenient for us to support CPU feature in AArch64. -So let's change it to an array first and add an enum as the index of the -array for convenience. Since we will never access high 32-bits of ID -registers in AArch32, it's harmless to change the ID registers in -AArch32 to 64-bits. - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - hw/intc/armv7m_nvic.c | 32 +-- - target/arm/cpu.c | 105 ++++----- - target/arm/cpu.h | 298 ++++++++++++------------ - target/arm/cpu64.c | 234 +++++++++---------- - target/arm/cpu_tcg.c | 503 +++++++++++++++++++++-------------------- - target/arm/helper.c | 64 +++--- - target/arm/hvf/hvf.c | 20 +- - target/arm/internals.h | 14 +- - target/arm/kvm64.c | 81 +++---- - 9 files changed, 683 insertions(+), 668 deletions(-) - -diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c -index 13df002ce4..4b12b209b7 100644 ---- a/hw/intc/armv7m_nvic.c -+++ b/hw/intc/armv7m_nvic.c -@@ -1273,17 +1273,17 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_pfr0; -+ return cpu->isar.regs[ID_PFR0]; - case 0xd44: /* PFR1. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_pfr1; -+ return cpu->isar.regs[ID_PFR1]; - case 0xd48: /* DFR0. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_dfr0; -+ return cpu->isar.regs[ID_DFR0]; - case 0xd4c: /* AFR0. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; -@@ -1293,52 +1293,52 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_mmfr0; -+ return cpu->isar.regs[ID_MMFR0]; - case 0xd54: /* MMFR1. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_mmfr1; -+ return cpu->isar.regs[ID_MMFR1]; - case 0xd58: /* MMFR2. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_mmfr2; -+ return cpu->isar.regs[ID_MMFR2]; - case 0xd5c: /* MMFR3. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_mmfr3; -+ return cpu->isar.regs[ID_MMFR3]; - case 0xd60: /* ISAR0. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_isar0; -+ return cpu->isar.regs[ID_ISAR0]; - case 0xd64: /* ISAR1. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_isar1; -+ return cpu->isar.regs[ID_ISAR1]; - case 0xd68: /* ISAR2. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_isar2; -+ return cpu->isar.regs[ID_ISAR2]; - case 0xd6c: /* ISAR3. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_isar3; -+ return cpu->isar.regs[ID_ISAR3]; - case 0xd70: /* ISAR4. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_isar4; -+ return cpu->isar.regs[ID_ISAR4]; - case 0xd74: /* ISAR5. */ - if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { - goto bad_offset; - } -- return cpu->isar.id_isar5; -+ return cpu->isar.regs[ID_ISAR5]; - case 0xd78: /* CLIDR */ - return cpu->clidr; - case 0xd7c: /* CTR */ -@@ -1548,11 +1548,11 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) - } - return cpu->env.v7m.fpdscr[attrs.secure]; - case 0xf40: /* MVFR0 */ -- return cpu->isar.mvfr0; -+ return cpu->isar.regs[MVFR0]; - case 0xf44: /* MVFR1 */ -- return cpu->isar.mvfr1; -+ return cpu->isar.regs[MVFR1]; - case 0xf48: /* MVFR2 */ -- return cpu->isar.mvfr2; -+ return cpu->isar.regs[MVFR2]; - default: - bad_offset: - qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset); -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index a211804fd3..f1ce0474a3 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -176,9 +176,9 @@ static void arm_cpu_reset(DeviceState *dev) - g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu); - - env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; -- env->vfp.xregs[ARM_VFP_MVFR0] = cpu->isar.mvfr0; -- env->vfp.xregs[ARM_VFP_MVFR1] = cpu->isar.mvfr1; -- env->vfp.xregs[ARM_VFP_MVFR2] = cpu->isar.mvfr2; -+ env->vfp.xregs[ARM_VFP_MVFR0] = cpu->isar.regs[MVFR0]; -+ env->vfp.xregs[ARM_VFP_MVFR1] = cpu->isar.regs[MVFR1]; -+ env->vfp.xregs[ARM_VFP_MVFR2] = cpu->isar.regs[MVFR2]; - - cpu->power_state = s->start_powered_off ? PSCI_OFF : PSCI_ON; - -@@ -1520,20 +1520,20 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - uint64_t t; - uint32_t u; - -- t = cpu->isar.id_aa64isar1; -+ t = cpu->isar.regs[ID_AA64ISAR1]; - t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0); -- cpu->isar.id_aa64isar1 = t; -+ cpu->isar.regs[ID_AA64ISAR1] = t; - -- t = cpu->isar.id_aa64pfr0; -+ t = cpu->isar.regs[ID_AA64PFR0]; - t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf); -- cpu->isar.id_aa64pfr0 = t; -+ cpu->isar.regs[ID_AA64PFR0] = t; - -- u = cpu->isar.id_isar6; -+ u = cpu->isar.regs[ID_ISAR6]; - u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0); - u = FIELD_DP32(u, ID_ISAR6, BF16, 0); -- cpu->isar.id_isar6 = u; -+ cpu->isar.regs[ID_ISAR6] = u; - -- u = cpu->isar.mvfr0; -+ u = cpu->isar.regs[MVFR0]; - u = FIELD_DP32(u, MVFR0, FPSP, 0); - u = FIELD_DP32(u, MVFR0, FPDP, 0); - u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0); -@@ -1543,20 +1543,20 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - u = FIELD_DP32(u, MVFR0, FPTRAP, 0); - u = FIELD_DP32(u, MVFR0, FPSHVEC, 0); - } -- cpu->isar.mvfr0 = u; -+ cpu->isar.regs[MVFR0] = u; - -- u = cpu->isar.mvfr1; -+ u = cpu->isar.regs[MVFR1]; - u = FIELD_DP32(u, MVFR1, FPFTZ, 0); - u = FIELD_DP32(u, MVFR1, FPDNAN, 0); - u = FIELD_DP32(u, MVFR1, FPHP, 0); - if (arm_feature(env, ARM_FEATURE_M)) { - u = FIELD_DP32(u, MVFR1, FP16, 0); - } -- cpu->isar.mvfr1 = u; -+ cpu->isar.regs[MVFR1] = u; - -- u = cpu->isar.mvfr2; -+ u = cpu->isar.regs[MVFR2]; - u = FIELD_DP32(u, MVFR2, FPMISC, 0); -- cpu->isar.mvfr2 = u; -+ cpu->isar.regs[MVFR2] = u; - } - - if (!cpu->has_neon) { -@@ -1565,43 +1565,43 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - - unset_feature(env, ARM_FEATURE_NEON); - -- t = cpu->isar.id_aa64isar0; -+ t = cpu->isar.regs[ID_AA64ISAR0]; - t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0); -- cpu->isar.id_aa64isar0 = t; -+ cpu->isar.regs[ID_AA64ISAR0] = t; - -- t = cpu->isar.id_aa64isar1; -+ t = cpu->isar.regs[ID_AA64ISAR1]; - t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0); - t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 0); - t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0); -- cpu->isar.id_aa64isar1 = t; -+ cpu->isar.regs[ID_AA64ISAR1] = t; - -- t = cpu->isar.id_aa64pfr0; -+ t = cpu->isar.regs[ID_AA64PFR0]; - t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf); -- cpu->isar.id_aa64pfr0 = t; -+ cpu->isar.regs[ID_AA64PFR0] = t; - -- u = cpu->isar.id_isar5; -+ u = cpu->isar.regs[ID_ISAR5]; - u = FIELD_DP32(u, ID_ISAR5, RDM, 0); - u = FIELD_DP32(u, ID_ISAR5, VCMA, 0); -- cpu->isar.id_isar5 = u; -+ cpu->isar.regs[ID_ISAR5] = u; - -- u = cpu->isar.id_isar6; -+ u = cpu->isar.regs[ID_ISAR6]; - u = FIELD_DP32(u, ID_ISAR6, DP, 0); - u = FIELD_DP32(u, ID_ISAR6, FHM, 0); - u = FIELD_DP32(u, ID_ISAR6, BF16, 0); - u = FIELD_DP32(u, ID_ISAR6, I8MM, 0); -- cpu->isar.id_isar6 = u; -+ cpu->isar.regs[ID_ISAR6] = u; - - if (!arm_feature(env, ARM_FEATURE_M)) { -- u = cpu->isar.mvfr1; -+ u = cpu->isar.regs[MVFR1]; - u = FIELD_DP32(u, MVFR1, SIMDLS, 0); - u = FIELD_DP32(u, MVFR1, SIMDINT, 0); - u = FIELD_DP32(u, MVFR1, SIMDSP, 0); - u = FIELD_DP32(u, MVFR1, SIMDHP, 0); -- cpu->isar.mvfr1 = u; -+ cpu->isar.regs[MVFR1] = u; - -- u = cpu->isar.mvfr2; -+ u = cpu->isar.regs[MVFR2]; - u = FIELD_DP32(u, MVFR2, SIMDMISC, 0); -- cpu->isar.mvfr2 = u; -+ cpu->isar.regs[MVFR2] = u; - } - } - -@@ -1609,22 +1609,22 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - uint64_t t; - uint32_t u; - -- t = cpu->isar.id_aa64isar0; -+ t = cpu->isar.regs[ID_AA64ISAR0]; - t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0); -- cpu->isar.id_aa64isar0 = t; -+ cpu->isar.regs[ID_AA64ISAR0] = t; - -- t = cpu->isar.id_aa64isar1; -+ t = cpu->isar.regs[ID_AA64ISAR1]; - t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0); -- cpu->isar.id_aa64isar1 = t; -+ cpu->isar.regs[ID_AA64ISAR1] = t; - -- u = cpu->isar.mvfr0; -+ u = cpu->isar.regs[MVFR0]; - u = FIELD_DP32(u, MVFR0, SIMDREG, 0); -- cpu->isar.mvfr0 = u; -+ cpu->isar.regs[MVFR0] = u; - - /* Despite the name, this field covers both VFP and Neon */ -- u = cpu->isar.mvfr1; -+ u = cpu->isar.regs[MVFR1]; - u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0); -- cpu->isar.mvfr1 = u; -+ cpu->isar.regs[MVFR1] = u; - } - - if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) { -@@ -1632,19 +1632,19 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - - unset_feature(env, ARM_FEATURE_THUMB_DSP); - -- u = cpu->isar.id_isar1; -+ u = cpu->isar.regs[ID_ISAR1]; - u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1); -- cpu->isar.id_isar1 = u; -+ cpu->isar.regs[ID_ISAR1] = u; - -- u = cpu->isar.id_isar2; -+ u = cpu->isar.regs[ID_ISAR2]; - u = FIELD_DP32(u, ID_ISAR2, MULTU, 1); - u = FIELD_DP32(u, ID_ISAR2, MULTS, 1); -- cpu->isar.id_isar2 = u; -+ cpu->isar.regs[ID_ISAR2] = u; - -- u = cpu->isar.id_isar3; -+ u = cpu->isar.regs[ID_ISAR3]; - u = FIELD_DP32(u, ID_ISAR3, SIMD, 1); - u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0); -- cpu->isar.id_isar3 = u; -+ cpu->isar.regs[ID_ISAR3] = u; - } - - /* Some features automatically imply others: */ -@@ -1785,8 +1785,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - /* Disable the security extension feature bits in the processor feature - * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12]. - */ -- cpu->isar.id_pfr1 &= ~0xf0; -- cpu->isar.id_aa64pfr0 &= ~0xf000; -+ cpu->isar.regs[ID_PFR1] &= ~0xf0; -+ cpu->isar.regs[ID_AA64PFR0] &= ~0xf000; - } - - if (!cpu->has_el2) { -@@ -1809,9 +1809,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - cpu); - #endif - } else { -- cpu->isar.id_aa64dfr0 = -- FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0); -- cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0); -+ cpu->isar.regs[ID_AA64DFR0] = -+ FIELD_DP64(cpu->isar.regs[ID_AA64DFR0], ID_AA64DFR0, PMUVER, 0); -+ cpu->isar.regs[ID_DFR0] = FIELD_DP32(cpu->isar.regs[ID_DFR0], ID_DFR0, -+ PERFMON, 0); - cpu->pmceid0 = 0; - cpu->pmceid1 = 0; - } -@@ -1821,8 +1822,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - * registers if we don't have EL2. These are id_pfr1[15:12] and - * id_aa64pfr0_el1[11:8]. - */ -- cpu->isar.id_aa64pfr0 &= ~0xf00; -- cpu->isar.id_pfr1 &= ~0xf000; -+ cpu->isar.regs[ID_AA64PFR0] &= ~0xf00; -+ cpu->isar.regs[ID_PFR1] &= ~0xf000; - } - - #ifndef CONFIG_USER_ONLY -@@ -1831,8 +1832,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) - * Disable the MTE feature bits if we do not have tag-memory - * provided by the machine. - */ -- cpu->isar.id_aa64pfr1 = -- FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0); -+ cpu->isar.regs[ID_AA64PFR1] = -+ FIELD_DP64(cpu->isar.regs[ID_AA64PFR1], ID_AA64PFR1, MTE, 0); - } - #endif - -diff --git a/target/arm/cpu.h b/target/arm/cpu.h -index e33f37b70a..3dda33f347 100644 ---- a/target/arm/cpu.h -+++ b/target/arm/cpu.h -@@ -69,6 +69,41 @@ - #define ARMV7M_EXCP_PENDSV 14 - #define ARMV7M_EXCP_SYSTICK 15 - -+typedef enum CPUIDReg { -+ MIDR_EL1, -+ ID_ISAR0, -+ ID_ISAR1, -+ ID_ISAR2, -+ ID_ISAR3, -+ ID_ISAR4, -+ ID_ISAR5, -+ ID_ISAR6, -+ ID_PFR0, -+ ID_PFR1, -+ ID_PFR2, -+ ID_MMFR0, -+ ID_MMFR1, -+ ID_MMFR2, -+ ID_MMFR3, -+ ID_MMFR4, -+ ID_AA64ISAR0, -+ ID_AA64ISAR1, -+ ID_AA64PFR0, -+ ID_AA64PFR1, -+ ID_AA64MMFR0, -+ ID_AA64MMFR1, -+ ID_AA64MMFR2, -+ ID_AA64DFR0, -+ ID_AA64DFR1, -+ ID_AA64ZFR0, -+ ID_DFR0, -+ MVFR0, -+ MVFR1, -+ MVFR2, -+ DBGDIDR, -+ ID_MAX, -+} CPUIDReg; -+ - /* For M profile, some registers are banked secure vs non-secure; - * these are represented as a 2-element array where the first element - * is the non-secure copy and the second is the secure copy. -@@ -922,36 +957,7 @@ struct ARMCPU { - * field by reading the value from the KVM vCPU. - */ - struct ARMISARegisters { -- uint32_t id_isar0; -- uint32_t id_isar1; -- uint32_t id_isar2; -- uint32_t id_isar3; -- uint32_t id_isar4; -- uint32_t id_isar5; -- uint32_t id_isar6; -- uint32_t id_mmfr0; -- uint32_t id_mmfr1; -- uint32_t id_mmfr2; -- uint32_t id_mmfr3; -- uint32_t id_mmfr4; -- uint32_t id_pfr0; -- uint32_t id_pfr1; -- uint32_t id_pfr2; -- uint32_t mvfr0; -- uint32_t mvfr1; -- uint32_t mvfr2; -- uint32_t id_dfr0; -- uint32_t dbgdidr; -- uint64_t id_aa64isar0; -- uint64_t id_aa64isar1; -- uint64_t id_aa64pfr0; -- uint64_t id_aa64pfr1; -- uint64_t id_aa64mmfr0; -- uint64_t id_aa64mmfr1; -- uint64_t id_aa64mmfr2; -- uint64_t id_aa64dfr0; -- uint64_t id_aa64dfr1; -- uint64_t id_aa64zfr0; -+ uint64_t regs[ID_MAX]; - } isar; - uint64_t midr; - uint32_t revidr; -@@ -3729,103 +3735,103 @@ static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x) - */ - static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR0], ID_ISAR0, DIVIDE) != 0; - } - - static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1; -+ return FIELD_EX32(id->regs[ID_ISAR0], ID_ISAR0, DIVIDE) > 1; - } - - static inline bool isar_feature_aa32_lob(const ARMISARegisters *id) - { - /* (M-profile) low-overhead loops and branch future */ -- return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3; -+ return FIELD_EX32(id->regs[ID_ISAR0], ID_ISAR0, CMPBRANCH) >= 3; - } - - static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR1], ID_ISAR1, JAZELLE) != 0; - } - - static inline bool isar_feature_aa32_aes(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR5], ID_ISAR5, AES) != 0; - } - - static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1; -+ return FIELD_EX32(id->regs[ID_ISAR5], ID_ISAR5, AES) > 1; - } - - static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR5], ID_ISAR5, SHA1) != 0; - } - - static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR5], ID_ISAR5, SHA2) != 0; - } - - static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR5], ID_ISAR5, CRC32) != 0; - } - - static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR5], ID_ISAR5, RDM) != 0; - } - - static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR5], ID_ISAR5, VCMA) != 0; - } - - static inline bool isar_feature_aa32_jscvt(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar6, ID_ISAR6, JSCVT) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR6], ID_ISAR6, JSCVT) != 0; - } - - static inline bool isar_feature_aa32_dp(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR6], ID_ISAR6, DP) != 0; - } - - static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR6], ID_ISAR6, FHM) != 0; - } - - static inline bool isar_feature_aa32_sb(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR6], ID_ISAR6, SB) != 0; - } - - static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR6], ID_ISAR6, SPECRES) != 0; - } - - static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR6], ID_ISAR6, BF16) != 0; - } - - static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0; -+ return FIELD_EX32(id->regs[ID_ISAR6], ID_ISAR6, I8MM) != 0; - } - - static inline bool isar_feature_aa32_ras(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0; -+ return FIELD_EX32(id->regs[ID_PFR0], ID_PFR0, RAS) != 0; - } - - static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0; -+ return FIELD_EX32(id->regs[ID_PFR1], ID_PFR1, MPROGMOD) != 0; - } - - static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id) -@@ -3834,16 +3840,16 @@ static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id) - * Return true if M-profile state handling insns - * (VSCCLRM, CLRM, FPCTX access insns) are implemented - */ -- return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3; -+ return FIELD_EX32(id->regs[ID_PFR1], ID_PFR1, SECURITY) >= 3; - } - - static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id) - { - /* Sadly this is encoded differently for A-profile and M-profile */ - if (isar_feature_aa32_mprofile(id)) { -- return FIELD_EX32(id->mvfr1, MVFR1, FP16) > 0; -+ return FIELD_EX32(id->regs[MVFR1], MVFR1, FP16) > 0; - } else { -- return FIELD_EX32(id->mvfr1, MVFR1, FPHP) >= 3; -+ return FIELD_EX32(id->regs[MVFR1], MVFR1, FPHP) >= 3; - } - } - -@@ -3855,7 +3861,7 @@ static inline bool isar_feature_aa32_mve(const ARMISARegisters *id) - * else for A-profile. - */ - return isar_feature_aa32_mprofile(id) && -- FIELD_EX32(id->mvfr1, MVFR1, MVE) > 0; -+ FIELD_EX32(id->regs[MVFR1], MVFR1, MVE) > 0; - } - - static inline bool isar_feature_aa32_mve_fp(const ARMISARegisters *id) -@@ -3866,7 +3872,7 @@ static inline bool isar_feature_aa32_mve_fp(const ARMISARegisters *id) - * else for A-profile. - */ - return isar_feature_aa32_mprofile(id) && -- FIELD_EX32(id->mvfr1, MVFR1, MVE) >= 2; -+ FIELD_EX32(id->regs[MVFR1], MVFR1, MVE) >= 2; - } - - static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id) -@@ -3875,42 +3881,42 @@ static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id) - * Return true if either VFP or SIMD is implemented. - * In this case, a minimum of VFP w/ D0-D15. - */ -- return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0; -+ return FIELD_EX32(id->regs[MVFR0], MVFR0, SIMDREG) > 0; - } - - static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id) - { - /* Return true if D16-D31 are implemented */ -- return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2; -+ return FIELD_EX32(id->regs[MVFR0], MVFR0, SIMDREG) >= 2; - } - - static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id) - { -- return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0; -+ return FIELD_EX32(id->regs[MVFR0], MVFR0, FPSHVEC) > 0; - } - - static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id) - { - /* Return true if CPU supports single precision floating point, VFPv2 */ -- return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0; -+ return FIELD_EX32(id->regs[MVFR0], MVFR0, FPSP) > 0; - } - - static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id) - { - /* Return true if CPU supports single precision floating point, VFPv3 */ -- return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2; -+ return FIELD_EX32(id->regs[MVFR0], MVFR0, FPSP) >= 2; - } - - static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id) - { - /* Return true if CPU supports double precision floating point, VFPv2 */ -- return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0; -+ return FIELD_EX32(id->regs[MVFR0], MVFR0, FPDP) > 0; - } - - static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id) - { - /* Return true if CPU supports double precision floating point, VFPv3 */ -- return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2; -+ return FIELD_EX32(id->regs[MVFR0], MVFR0, FPDP) >= 2; - } - - static inline bool isar_feature_aa32_vfp(const ARMISARegisters *id) -@@ -3925,12 +3931,12 @@ static inline bool isar_feature_aa32_vfp(const ARMISARegisters *id) - */ - static inline bool isar_feature_aa32_fp16_spconv(const ARMISARegisters *id) - { -- return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 0; -+ return FIELD_EX32(id->regs[MVFR1], MVFR1, FPHP) > 0; - } - - static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id) - { -- return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1; -+ return FIELD_EX32(id->regs[MVFR1], MVFR1, FPHP) > 1; - } - - /* -@@ -3942,86 +3948,86 @@ static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id) - */ - static inline bool isar_feature_aa32_simdfmac(const ARMISARegisters *id) - { -- return FIELD_EX32(id->mvfr1, MVFR1, SIMDFMAC) != 0; -+ return FIELD_EX32(id->regs[MVFR1], MVFR1, SIMDFMAC) != 0; - } - - static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id) - { -- return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 1; -+ return FIELD_EX32(id->regs[MVFR2], MVFR2, FPMISC) >= 1; - } - - static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id) - { -- return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 2; -+ return FIELD_EX32(id->regs[MVFR2], MVFR2, FPMISC) >= 2; - } - - static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id) - { -- return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 3; -+ return FIELD_EX32(id->regs[MVFR2], MVFR2, FPMISC) >= 3; - } - - static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id) - { -- return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 4; -+ return FIELD_EX32(id->regs[MVFR2], MVFR2, FPMISC) >= 4; - } - - static inline bool isar_feature_aa32_pxn(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_mmfr0, ID_MMFR0, VMSA) >= 4; -+ return FIELD_EX32(id->regs[ID_MMFR0], ID_MMFR0, VMSA) >= 4; - } - - static inline bool isar_feature_aa32_pan(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0; -+ return FIELD_EX32(id->regs[ID_MMFR3], ID_MMFR3, PAN) != 0; - } - - static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2; -+ return FIELD_EX32(id->regs[ID_MMFR3], ID_MMFR3, PAN) >= 2; - } - - static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id) - { - /* 0xf means "non-standard IMPDEF PMU" */ -- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 && -- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf; -+ return FIELD_EX32(id->regs[ID_DFR0], ID_DFR0, PERFMON) >= 4 && -+ FIELD_EX32(id->regs[ID_DFR0], ID_DFR0, PERFMON) != 0xf; - } - - static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id) - { - /* 0xf means "non-standard IMPDEF PMU" */ -- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 && -- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf; -+ return FIELD_EX32(id->regs[ID_DFR0], ID_DFR0, PERFMON) >= 5 && -+ FIELD_EX32(id->regs[ID_DFR0], ID_DFR0, PERFMON) != 0xf; - } - - static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0; -+ return FIELD_EX32(id->regs[ID_MMFR4], ID_MMFR4, HPDS) != 0; - } - - static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0; -+ return FIELD_EX32(id->regs[ID_MMFR4], ID_MMFR4, AC2) != 0; - } - - static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0; -+ return FIELD_EX32(id->regs[ID_MMFR4], ID_MMFR4, CCIDX) != 0; - } - - static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0; -+ return FIELD_EX32(id->regs[ID_MMFR4], ID_MMFR4, XNX) != 0; - } - - static inline bool isar_feature_aa32_dit(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0; -+ return FIELD_EX32(id->regs[ID_PFR0], ID_PFR0, DIT) != 0; - } - - static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id) - { -- return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0; -+ return FIELD_EX32(id->regs[ID_PFR2], ID_PFR2, SSBS) != 0; - } - - /* -@@ -4029,92 +4035,92 @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id) - */ - static inline bool isar_feature_aa64_aes(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, AES) != 0; - } - - static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, AES) > 1; - } - - static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, SHA1) != 0; - } - - static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, SHA2) != 0; - } - - static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, SHA2) > 1; - } - - static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, CRC32) != 0; - } - - static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, ATOMIC) != 0; - } - - static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, RDM) != 0; - } - - static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, SHA3) != 0; - } - - static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, SM3) != 0; - } - - static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, SM4) != 0; - } - - static inline bool isar_feature_aa64_dp(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, DP) != 0; - } - - static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, FHM) != 0; - } - - static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, TS) != 0; - } - - static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, TS) >= 2; - } - - static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, RNDR) != 0; - } - - static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, JSCVT) != 0; - } - - static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, FCMA) != 0; - } - - static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id) -@@ -4123,7 +4129,7 @@ static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id) - * Return true if any form of pauth is enabled, as this - * predicate controls migration of the 128-bit keys. - */ -- return (id->id_aa64isar1 & -+ return (id->regs[ID_AA64ISAR1] & - (FIELD_DP64(0, ID_AA64ISAR1, APA, 0xf) | - FIELD_DP64(0, ID_AA64ISAR1, API, 0xf) | - FIELD_DP64(0, ID_AA64ISAR1, GPA, 0xf) | -@@ -4136,221 +4142,221 @@ static inline bool isar_feature_aa64_pauth_arch(const ARMISARegisters *id) - * Return true if pauth is enabled with the architected QARMA algorithm. - * QEMU will always set APA+GPA to the same value. - */ -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, APA) != 0; - } - - static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, TLB) == 2; - } - - static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR0], ID_AA64ISAR0, TLB) != 0; - } - - static inline bool isar_feature_aa64_sb(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, SB) != 0; - } - - static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, SPECRES) != 0; - } - - static inline bool isar_feature_aa64_frint(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, FRINTTS) != 0; - } - - static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, DPB) != 0; - } - - static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, DPB) >= 2; - } - - static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, BF16) != 0; - } - - static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id) - { - /* We always set the AdvSIMD and FP fields identically. */ -- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf; -+ return FIELD_EX64(id->regs[ID_AA64PFR0], ID_AA64PFR0, FP) != 0xf; - } - - static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id) - { - /* We always set the AdvSIMD and FP fields identically wrt FP16. */ -- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1; -+ return FIELD_EX64(id->regs[ID_AA64PFR0], ID_AA64PFR0, FP) == 1; - } - - static inline bool isar_feature_aa64_aa32(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL0) >= 2; -+ return FIELD_EX64(id->regs[ID_AA64PFR0], ID_AA64PFR0, EL0) >= 2; - } - - static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2; -+ return FIELD_EX64(id->regs[ID_AA64PFR0], ID_AA64PFR0, EL1) >= 2; - } - - static inline bool isar_feature_aa64_sve(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0; -+ return FIELD_EX64(id->regs[ID_AA64PFR0], ID_AA64PFR0, SVE) != 0; - } - - static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0; -+ return FIELD_EX64(id->regs[ID_AA64PFR0], ID_AA64PFR0, SEL2) != 0; - } - - static inline bool isar_feature_aa64_vh(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0; -+ return FIELD_EX64(id->regs[ID_AA64MMFR1], ID_AA64MMFR1, VH) != 0; - } - - static inline bool isar_feature_aa64_lor(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0; -+ return FIELD_EX64(id->regs[ID_AA64MMFR1], ID_AA64MMFR1, LO) != 0; - } - - static inline bool isar_feature_aa64_pan(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0; -+ return FIELD_EX64(id->regs[ID_AA64MMFR1], ID_AA64MMFR1, PAN) != 0; - } - - static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2; -+ return FIELD_EX64(id->regs[ID_AA64MMFR1], ID_AA64MMFR1, PAN) >= 2; - } - - static inline bool isar_feature_aa64_uao(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0; -+ return FIELD_EX64(id->regs[ID_AA64MMFR2], ID_AA64MMFR2, UAO) != 0; - } - - static inline bool isar_feature_aa64_st(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, ST) != 0; -+ return FIELD_EX64(id->regs[ID_AA64MMFR2], ID_AA64MMFR2, ST) != 0; - } - - static inline bool isar_feature_aa64_bti(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0; -+ return FIELD_EX64(id->regs[ID_AA64PFR1], ID_AA64PFR1, BT) != 0; - } - - static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0; -+ return FIELD_EX64(id->regs[ID_AA64PFR1], ID_AA64PFR1, MTE) != 0; - } - - static inline bool isar_feature_aa64_mte(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2; -+ return FIELD_EX64(id->regs[ID_AA64PFR1], ID_AA64PFR1, MTE) >= 2; - } - - static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 && -- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf; -+ return FIELD_EX64(id->regs[ID_AA64DFR0], ID_AA64DFR0, PMUVER) >= 4 && -+ FIELD_EX64(id->regs[ID_AA64DFR0], ID_AA64DFR0, PMUVER) != 0xf; - } - - static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 && -- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf; -+ return FIELD_EX64(id->regs[ID_AA64DFR0], ID_AA64DFR0, PMUVER) >= 5 && -+ FIELD_EX64(id->regs[ID_AA64DFR0], ID_AA64DFR0, PMUVER) != 0xf; - } - - static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, LRCPC) != 0; - } - - static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, LRCPC) >= 2; - } - - static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ISAR1], ID_AA64ISAR1, I8MM) != 0; - } - - static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0; -+ return FIELD_EX64(id->regs[ID_AA64MMFR2], ID_AA64MMFR2, CCIDX) != 0; - } - - static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0; -+ return FIELD_EX64(id->regs[ID_AA64MMFR1], ID_AA64MMFR1, XNX) != 0; - } - - static inline bool isar_feature_aa64_dit(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0; -+ return FIELD_EX64(id->regs[ID_AA64PFR0], ID_AA64PFR0, DIT) != 0; - } - - static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0; -+ return FIELD_EX64(id->regs[ID_AA64PFR1], ID_AA64PFR1, SSBS) != 0; - } - - static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, SVEVER) != 0; - } - - static inline bool isar_feature_aa64_sve2_aes(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, AES) != 0; - } - - static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) >= 2; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, AES) >= 2; - } - - static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, BITPERM) != 0; - } - - static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, BFLOAT16) != 0; - } - - static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, SHA3) != 0; - } - - static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, SM4) != 0; - } - - static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, I8MM) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, I8MM) != 0; - } - - static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F32MM) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, F32MM) != 0; - } - - static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id) - { -- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F64MM) != 0; -+ return FIELD_EX64(id->regs[ID_AA64ZFR0], ID_AA64ZFR0, F64MM) != 0; - } - - /* -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 1b56261964..96a49a3158 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -108,31 +108,31 @@ static void aarch64_a57_initfn(Object *obj) - cpu->midr = 0x411fd070; - cpu->revidr = 0x00000000; - cpu->reset_fpsid = 0x41034070; -- cpu->isar.mvfr0 = 0x10110222; -- cpu->isar.mvfr1 = 0x12111111; -- cpu->isar.mvfr2 = 0x00000043; -+ cpu->isar.regs[MVFR0] = 0x10110222; -+ cpu->isar.regs[MVFR1] = 0x12111111; -+ cpu->isar.regs[MVFR2] = 0x00000043; - cpu->ctr = 0x8444c004; - cpu->reset_sctlr = 0x00c50838; -- cpu->isar.id_pfr0 = 0x00000131; -- cpu->isar.id_pfr1 = 0x00011011; -- cpu->isar.id_dfr0 = 0x03010066; -+ cpu->isar.regs[ID_PFR0] = 0x00000131; -+ cpu->isar.regs[ID_PFR1] = 0x00011011; -+ cpu->isar.regs[ID_DFR0] = 0x03010066; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x10101105; -- cpu->isar.id_mmfr1 = 0x40000000; -- cpu->isar.id_mmfr2 = 0x01260000; -- cpu->isar.id_mmfr3 = 0x02102211; -- cpu->isar.id_isar0 = 0x02101110; -- cpu->isar.id_isar1 = 0x13112111; -- cpu->isar.id_isar2 = 0x21232042; -- cpu->isar.id_isar3 = 0x01112131; -- cpu->isar.id_isar4 = 0x00011142; -- cpu->isar.id_isar5 = 0x00011121; -- cpu->isar.id_isar6 = 0; -- cpu->isar.id_aa64pfr0 = 0x00002222; -- cpu->isar.id_aa64dfr0 = 0x10305106; -- cpu->isar.id_aa64isar0 = 0x00011120; -- cpu->isar.id_aa64mmfr0 = 0x00001124; -- cpu->isar.dbgdidr = 0x3516d000; -+ cpu->isar.regs[ID_MMFR0] = 0x10101105; -+ cpu->isar.regs[ID_MMFR1] = 0x40000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01260000; -+ cpu->isar.regs[ID_MMFR3] = 0x02102211; -+ cpu->isar.regs[ID_ISAR0] = 0x02101110; -+ cpu->isar.regs[ID_ISAR1] = 0x13112111; -+ cpu->isar.regs[ID_ISAR2] = 0x21232042; -+ cpu->isar.regs[ID_ISAR3] = 0x01112131; -+ cpu->isar.regs[ID_ISAR4] = 0x00011142; -+ cpu->isar.regs[ID_ISAR5] = 0x00011121; -+ cpu->isar.regs[ID_ISAR6] = 0; -+ cpu->isar.regs[ID_AA64PFR0] = 0x00002222; -+ cpu->isar.regs[ID_AA64DFR0] = 0x10305106; -+ cpu->isar.regs[ID_AA64ISAR0] = 0x00011120; -+ cpu->isar.regs[ID_AA64MMFR0] = 0x00001124; -+ cpu->isar.regs[DBGDIDR] = 0x3516d000; - cpu->clidr = 0x0a200023; - cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ - cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */ -@@ -161,31 +161,31 @@ static void aarch64_a53_initfn(Object *obj) - cpu->midr = 0x410fd034; - cpu->revidr = 0x00000000; - cpu->reset_fpsid = 0x41034070; -- cpu->isar.mvfr0 = 0x10110222; -- cpu->isar.mvfr1 = 0x12111111; -- cpu->isar.mvfr2 = 0x00000043; -+ cpu->isar.regs[MVFR0] = 0x10110222; -+ cpu->isar.regs[MVFR1] = 0x12111111; -+ cpu->isar.regs[MVFR2] = 0x00000043; - cpu->ctr = 0x84448004; /* L1Ip = VIPT */ - cpu->reset_sctlr = 0x00c50838; -- cpu->isar.id_pfr0 = 0x00000131; -- cpu->isar.id_pfr1 = 0x00011011; -- cpu->isar.id_dfr0 = 0x03010066; -+ cpu->isar.regs[ID_PFR0] = 0x00000131; -+ cpu->isar.regs[ID_PFR1] = 0x00011011; -+ cpu->isar.regs[ID_DFR0] = 0x03010066; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x10101105; -- cpu->isar.id_mmfr1 = 0x40000000; -- cpu->isar.id_mmfr2 = 0x01260000; -- cpu->isar.id_mmfr3 = 0x02102211; -- cpu->isar.id_isar0 = 0x02101110; -- cpu->isar.id_isar1 = 0x13112111; -- cpu->isar.id_isar2 = 0x21232042; -- cpu->isar.id_isar3 = 0x01112131; -- cpu->isar.id_isar4 = 0x00011142; -- cpu->isar.id_isar5 = 0x00011121; -- cpu->isar.id_isar6 = 0; -- cpu->isar.id_aa64pfr0 = 0x00002222; -- cpu->isar.id_aa64dfr0 = 0x10305106; -- cpu->isar.id_aa64isar0 = 0x00011120; -- cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ -- cpu->isar.dbgdidr = 0x3516d000; -+ cpu->isar.regs[ID_MMFR0] = 0x10101105; -+ cpu->isar.regs[ID_MMFR1] = 0x40000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01260000; -+ cpu->isar.regs[ID_MMFR3] = 0x02102211; -+ cpu->isar.regs[ID_ISAR0] = 0x02101110; -+ cpu->isar.regs[ID_ISAR1] = 0x13112111; -+ cpu->isar.regs[ID_ISAR2] = 0x21232042; -+ cpu->isar.regs[ID_ISAR3] = 0x01112131; -+ cpu->isar.regs[ID_ISAR4] = 0x00011142; -+ cpu->isar.regs[ID_ISAR5] = 0x00011121; -+ cpu->isar.regs[ID_ISAR6] = 0; -+ cpu->isar.regs[ID_AA64PFR0] = 0x00002222; -+ cpu->isar.regs[ID_AA64DFR0] = 0x10305106; -+ cpu->isar.regs[ID_AA64ISAR0] = 0x00011120; -+ cpu->isar.regs[ID_AA64MMFR0] = 0x00001122; /* 40 bit physical addr */ -+ cpu->isar.regs[DBGDIDR] = 0x3516d000; - cpu->clidr = 0x0a200023; - cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ - cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */ -@@ -214,30 +214,30 @@ static void aarch64_a72_initfn(Object *obj) - cpu->midr = 0x410fd083; - cpu->revidr = 0x00000000; - cpu->reset_fpsid = 0x41034080; -- cpu->isar.mvfr0 = 0x10110222; -- cpu->isar.mvfr1 = 0x12111111; -- cpu->isar.mvfr2 = 0x00000043; -+ cpu->isar.regs[MVFR0] = 0x10110222; -+ cpu->isar.regs[MVFR1] = 0x12111111; -+ cpu->isar.regs[MVFR2] = 0x00000043; - cpu->ctr = 0x8444c004; - cpu->reset_sctlr = 0x00c50838; -- cpu->isar.id_pfr0 = 0x00000131; -- cpu->isar.id_pfr1 = 0x00011011; -- cpu->isar.id_dfr0 = 0x03010066; -+ cpu->isar.regs[ID_PFR0] = 0x00000131; -+ cpu->isar.regs[ID_PFR1] = 0x00011011; -+ cpu->isar.regs[ID_DFR0] = 0x03010066; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x10201105; -- cpu->isar.id_mmfr1 = 0x40000000; -- cpu->isar.id_mmfr2 = 0x01260000; -- cpu->isar.id_mmfr3 = 0x02102211; -- cpu->isar.id_isar0 = 0x02101110; -- cpu->isar.id_isar1 = 0x13112111; -- cpu->isar.id_isar2 = 0x21232042; -- cpu->isar.id_isar3 = 0x01112131; -- cpu->isar.id_isar4 = 0x00011142; -- cpu->isar.id_isar5 = 0x00011121; -- cpu->isar.id_aa64pfr0 = 0x00002222; -- cpu->isar.id_aa64dfr0 = 0x10305106; -- cpu->isar.id_aa64isar0 = 0x00011120; -- cpu->isar.id_aa64mmfr0 = 0x00001124; -- cpu->isar.dbgdidr = 0x3516d000; -+ cpu->isar.regs[ID_MMFR0] = 0x10201105; -+ cpu->isar.regs[ID_MMFR1] = 0x40000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01260000; -+ cpu->isar.regs[ID_MMFR3] = 0x02102211; -+ cpu->isar.regs[ID_ISAR0] = 0x02101110; -+ cpu->isar.regs[ID_ISAR1] = 0x13112111; -+ cpu->isar.regs[ID_ISAR2] = 0x21232042; -+ cpu->isar.regs[ID_ISAR3] = 0x01112131; -+ cpu->isar.regs[ID_ISAR4] = 0x00011142; -+ cpu->isar.regs[ID_ISAR5] = 0x00011121; -+ cpu->isar.regs[ID_AA64PFR0] = 0x00002222; -+ cpu->isar.regs[ID_AA64DFR0] = 0x10305106; -+ cpu->isar.regs[ID_AA64ISAR0] = 0x00011120; -+ cpu->isar.regs[ID_AA64MMFR0] = 0x00001124; -+ cpu->isar.regs[DBGDIDR] = 0x3516d000; - cpu->clidr = 0x0a200023; - cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ - cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */ -@@ -262,10 +262,10 @@ static void aarch64_kunpeng_920_initfn(Object *obj) - - cpu->midr = 0x480fd010; - cpu->ctr = 0x84448004; -- cpu->isar.id_aa64pfr0 = 0x11001111; -- cpu->isar.id_aa64dfr0 = 0x110305408; -- cpu->isar.id_aa64isar0 = 0x10211120; -- cpu->isar.id_aa64mmfr0 = 0x101125; -+ cpu->isar.regs[ID_AA64PFR0] = 0x11001111; -+ cpu->isar.regs[ID_AA64DFR0] = 0x110305408; -+ cpu->isar.regs[ID_AA64ISAR0] = 0x10211120; -+ cpu->isar.regs[ID_AA64MMFR0] = 0x101125; - } - - void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) -@@ -566,9 +566,9 @@ static void cpu_arm_set_sve(Object *obj, bool value, Error **errp) - return; - } - -- t = cpu->isar.id_aa64pfr0; -+ t = cpu->isar.regs[ID_AA64PFR0]; - t = FIELD_DP64(t, ID_AA64PFR0, SVE, value); -- cpu->isar.id_aa64pfr0 = t; -+ cpu->isar.regs[ID_AA64PFR0] = t; - } - - #ifdef CONFIG_USER_ONLY -@@ -662,12 +662,12 @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) - error_append_hint(errp, "Add pauth=on to the CPU property list.\n"); - } - -- t = cpu->isar.id_aa64isar1; -+ t = cpu->isar.regs[ID_AA64ISAR1]; - t = FIELD_DP64(t, ID_AA64ISAR1, APA, arch_val); - t = FIELD_DP64(t, ID_AA64ISAR1, GPA, arch_val); - t = FIELD_DP64(t, ID_AA64ISAR1, API, impdef_val); - t = FIELD_DP64(t, ID_AA64ISAR1, GPI, impdef_val); -- cpu->isar.id_aa64isar1 = t; -+ cpu->isar.regs[ID_AA64ISAR1] = t; - } - - static Property arm_cpu_pauth_property = -@@ -736,7 +736,7 @@ static void aarch64_max_initfn(Object *obj) - t = FIELD_DP64(t, MIDR_EL1, REVISION, 0); - cpu->midr = t; - -- t = cpu->isar.id_aa64isar0; -+ t = cpu->isar.regs[ID_AA64ISAR0]; - t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */ - t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); - t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */ -@@ -751,9 +751,9 @@ static void aarch64_max_initfn(Object *obj) - t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */ - t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */ - t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); -- cpu->isar.id_aa64isar0 = t; -+ cpu->isar.regs[ID_AA64ISAR0] = t; - -- t = cpu->isar.id_aa64isar1; -+ t = cpu->isar.regs[ID_AA64ISAR1]; - t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); - t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); - t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); -@@ -763,17 +763,17 @@ static void aarch64_max_initfn(Object *obj) - t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1); - t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */ - t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); -- cpu->isar.id_aa64isar1 = t; -+ cpu->isar.regs[ID_AA64ISAR1] = t; - -- t = cpu->isar.id_aa64pfr0; -+ t = cpu->isar.regs[ID_AA64PFR0]; - t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1); - t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); - t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); - t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); - t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); -- cpu->isar.id_aa64pfr0 = t; -+ cpu->isar.regs[ID_AA64PFR0] = t; - -- t = cpu->isar.id_aa64pfr1; -+ t = cpu->isar.regs[ID_AA64PFR1]; - t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); - t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); - /* -@@ -782,28 +782,28 @@ static void aarch64_max_initfn(Object *obj) - * we do for EL2 with the virtualization=on property. - */ - t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); -- cpu->isar.id_aa64pfr1 = t; -+ cpu->isar.regs[ID_AA64PFR1] = t; - -- t = cpu->isar.id_aa64mmfr0; -+ t = cpu->isar.regs[ID_AA64MMFR0]; - t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */ -- cpu->isar.id_aa64mmfr0 = t; -+ cpu->isar.regs[ID_AA64MMFR0] = t; - -- t = cpu->isar.id_aa64mmfr1; -+ t = cpu->isar.regs[ID_AA64MMFR1]; - t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */ - t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); - t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); - t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */ - t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */ - t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */ -- cpu->isar.id_aa64mmfr1 = t; -+ cpu->isar.regs[ID_AA64MMFR1] = t; - -- t = cpu->isar.id_aa64mmfr2; -+ t = cpu->isar.regs[ID_AA64MMFR2]; - t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); - t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */ - t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */ -- cpu->isar.id_aa64mmfr2 = t; -+ cpu->isar.regs[ID_AA64MMFR2] = t; - -- t = cpu->isar.id_aa64zfr0; -+ t = cpu->isar.regs[ID_AA64ZFR0]; - t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1); - t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* PMULL */ - t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); -@@ -813,19 +813,19 @@ static void aarch64_max_initfn(Object *obj) - t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); - t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); - t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); -- cpu->isar.id_aa64zfr0 = t; -+ cpu->isar.regs[ID_AA64ZFR0] = t; - - /* Replicate the same data to the 32-bit id registers. */ -- u = cpu->isar.id_isar5; -+ u = cpu->isar.regs[ID_ISAR5]; - u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */ - u = FIELD_DP32(u, ID_ISAR5, SHA1, 1); - u = FIELD_DP32(u, ID_ISAR5, SHA2, 1); - u = FIELD_DP32(u, ID_ISAR5, CRC32, 1); - u = FIELD_DP32(u, ID_ISAR5, RDM, 1); - u = FIELD_DP32(u, ID_ISAR5, VCMA, 1); -- cpu->isar.id_isar5 = u; -+ cpu->isar.regs[ID_ISAR5] = u; - -- u = cpu->isar.id_isar6; -+ u = cpu->isar.regs[ID_ISAR6]; - u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1); - u = FIELD_DP32(u, ID_ISAR6, DP, 1); - u = FIELD_DP32(u, ID_ISAR6, FHM, 1); -@@ -833,39 +833,39 @@ static void aarch64_max_initfn(Object *obj) - u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1); - u = FIELD_DP32(u, ID_ISAR6, BF16, 1); - u = FIELD_DP32(u, ID_ISAR6, I8MM, 1); -- cpu->isar.id_isar6 = u; -+ cpu->isar.regs[ID_ISAR6] = u; - -- u = cpu->isar.id_pfr0; -+ u = cpu->isar.regs[ID_PFR0]; - u = FIELD_DP32(u, ID_PFR0, DIT, 1); -- cpu->isar.id_pfr0 = u; -+ cpu->isar.regs[ID_PFR0] = u; - -- u = cpu->isar.id_pfr2; -+ u = cpu->isar.regs[ID_PFR2]; - u = FIELD_DP32(u, ID_PFR2, SSBS, 1); -- cpu->isar.id_pfr2 = u; -+ cpu->isar.regs[ID_PFR2] = u; - -- u = cpu->isar.id_mmfr3; -+ u = cpu->isar.regs[ID_MMFR3]; - u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */ -- cpu->isar.id_mmfr3 = u; -+ cpu->isar.regs[ID_MMFR3] = u; - -- u = cpu->isar.id_mmfr4; -+ u = cpu->isar.regs[ID_MMFR4]; - u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */ - u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ - u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */ - u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */ -- cpu->isar.id_mmfr4 = u; -+ cpu->isar.regs[ID_MMFR4] = u; - -- t = cpu->isar.id_aa64dfr0; -+ t = cpu->isar.regs[ID_AA64DFR0]; - t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */ -- cpu->isar.id_aa64dfr0 = t; -+ cpu->isar.regs[ID_AA64DFR0] = t; - -- u = cpu->isar.id_dfr0; -+ u = cpu->isar.regs[ID_DFR0]; - u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */ -- cpu->isar.id_dfr0 = u; -+ cpu->isar.regs[ID_DFR0] = u; - -- u = cpu->isar.mvfr1; -+ u = cpu->isar.regs[MVFR1]; - u = FIELD_DP32(u, MVFR1, FPHP, 3); /* v8.2-FP16 */ - u = FIELD_DP32(u, MVFR1, SIMDHP, 2); /* v8.2-FP16 */ -- cpu->isar.mvfr1 = u; -+ cpu->isar.regs[MVFR1] = u; - - #ifdef CONFIG_USER_ONLY - /* For usermode -cpu max we can use a larger and more efficient DCZ -@@ -903,18 +903,18 @@ static void aarch64_a64fx_initfn(Object *obj) - cpu->revidr = 0x00000000; - cpu->ctr = 0x86668006; - cpu->reset_sctlr = 0x30000180; -- cpu->isar.id_aa64pfr0 = 0x0000000101111111; /* No RAS Extensions */ -- cpu->isar.id_aa64pfr1 = 0x0000000000000000; -- cpu->isar.id_aa64dfr0 = 0x0000000010305408; -- cpu->isar.id_aa64dfr1 = 0x0000000000000000; -+ cpu->isar.regs[ID_AA64PFR0] = 0x0000000101111111; /* No RAS Extensions */ -+ cpu->isar.regs[ID_AA64PFR1] = 0x0000000000000000; -+ cpu->isar.regs[ID_AA64DFR0] = 0x0000000010305408; -+ cpu->isar.regs[ID_AA64DFR1] = 0x0000000000000000; - cpu->id_aa64afr0 = 0x0000000000000000; - cpu->id_aa64afr1 = 0x0000000000000000; -- cpu->isar.id_aa64mmfr0 = 0x0000000000001122; -- cpu->isar.id_aa64mmfr1 = 0x0000000011212100; -- cpu->isar.id_aa64mmfr2 = 0x0000000000001011; -- cpu->isar.id_aa64isar0 = 0x0000000010211120; -- cpu->isar.id_aa64isar1 = 0x0000000000010001; -- cpu->isar.id_aa64zfr0 = 0x0000000000000000; -+ cpu->isar.regs[ID_AA64MMFR0] = 0x0000000000001122; -+ cpu->isar.regs[ID_AA64MMFR1] = 0x0000000011212100; -+ cpu->isar.regs[ID_AA64MMFR2] = 0x0000000000001011; -+ cpu->isar.regs[ID_AA64ISAR0] = 0x0000000010211120; -+ cpu->isar.regs[ID_AA64ISAR1] = 0x0000000000010001; -+ cpu->isar.regs[ID_AA64ZFR0] = 0x0000000000000000; - cpu->clidr = 0x0000000080000023; - cpu->ccsidr[0] = 0x7007e01c; /* 64KB L1 dcache */ - cpu->ccsidr[1] = 0x2007e01c; /* 64KB L1 icache */ -diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c -index 13d0e9b195..be9c3166fb 100644 ---- a/target/arm/cpu_tcg.c -+++ b/target/arm/cpu_tcg.c -@@ -65,14 +65,16 @@ static void arm926_initfn(Object *obj) - * ARMv5 does not have the ID_ISAR registers, but we can still - * set the field to indicate Jazelle support within QEMU. - */ -- cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1); -+ cpu->isar.regs[ID_ISAR1] = FIELD_DP32(cpu->isar.regs[ID_ISAR1], ID_ISAR1, -+ JAZELLE, 1); - /* - * Similarly, we need to set MVFR0 fields to enable vfp and short vector - * support even though ARMv5 doesn't have this register. - */ -- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1); -- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1); -- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1); -+ cpu->isar.regs[MVFR0] = FIELD_DP32(cpu->isar.regs[MVFR0], MVFR0, FPSHVEC, -+ 1); -+ cpu->isar.regs[MVFR0] = FIELD_DP32(cpu->isar.regs[MVFR0], MVFR0, FPSP, 1); -+ cpu->isar.regs[MVFR0] = FIELD_DP32(cpu->isar.regs[MVFR0], MVFR0, FPDP, 1); - } - - static void arm946_initfn(Object *obj) -@@ -107,14 +109,16 @@ static void arm1026_initfn(Object *obj) - * ARMv5 does not have the ID_ISAR registers, but we can still - * set the field to indicate Jazelle support within QEMU. - */ -- cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1); -+ cpu->isar.regs[ID_ISAR1] = FIELD_DP32(cpu->isar.regs[ID_ISAR1], ID_ISAR1, -+ JAZELLE, 1); - /* - * Similarly, we need to set MVFR0 fields to enable vfp and short vector - * support even though ARMv5 doesn't have this register. - */ -- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1); -- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1); -- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1); -+ cpu->isar.regs[MVFR0] = FIELD_DP32(cpu->isar.regs[MVFR0], MVFR0, FPSHVEC, -+ 1); -+ cpu->isar.regs[MVFR0] = FIELD_DP32(cpu->isar.regs[MVFR0], MVFR0, FPSP, 1); -+ cpu->isar.regs[MVFR0] = FIELD_DP32(cpu->isar.regs[MVFR0], MVFR0, FPDP, 1); - - { - /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */ -@@ -147,22 +151,22 @@ static void arm1136_r2_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); - cpu->midr = 0x4107b362; - cpu->reset_fpsid = 0x410120b4; -- cpu->isar.mvfr0 = 0x11111111; -- cpu->isar.mvfr1 = 0x00000000; -+ cpu->isar.regs[MVFR0] = 0x11111111; -+ cpu->isar.regs[MVFR1] = 0x00000000; - cpu->ctr = 0x1dd20d2; - cpu->reset_sctlr = 0x00050078; -- cpu->isar.id_pfr0 = 0x111; -- cpu->isar.id_pfr1 = 0x1; -- cpu->isar.id_dfr0 = 0x2; -+ cpu->isar.regs[ID_PFR0] = 0x111; -+ cpu->isar.regs[ID_PFR1] = 0x1; -+ cpu->isar.regs[ID_DFR0] = 0x2; - cpu->id_afr0 = 0x3; -- cpu->isar.id_mmfr0 = 0x01130003; -- cpu->isar.id_mmfr1 = 0x10030302; -- cpu->isar.id_mmfr2 = 0x01222110; -- cpu->isar.id_isar0 = 0x00140011; -- cpu->isar.id_isar1 = 0x12002111; -- cpu->isar.id_isar2 = 0x11231111; -- cpu->isar.id_isar3 = 0x01102131; -- cpu->isar.id_isar4 = 0x141; -+ cpu->isar.regs[ID_MMFR0] = 0x01130003; -+ cpu->isar.regs[ID_MMFR1] = 0x10030302; -+ cpu->isar.regs[ID_MMFR2] = 0x01222110; -+ cpu->isar.regs[ID_ISAR0] = 0x00140011; -+ cpu->isar.regs[ID_ISAR1] = 0x12002111; -+ cpu->isar.regs[ID_ISAR2] = 0x11231111; -+ cpu->isar.regs[ID_ISAR3] = 0x01102131; -+ cpu->isar.regs[ID_ISAR4] = 0x141; - cpu->reset_auxcr = 7; - } - -@@ -178,22 +182,22 @@ static void arm1136_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); - cpu->midr = 0x4117b363; - cpu->reset_fpsid = 0x410120b4; -- cpu->isar.mvfr0 = 0x11111111; -- cpu->isar.mvfr1 = 0x00000000; -+ cpu->isar.regs[MVFR0] = 0x11111111; -+ cpu->isar.regs[MVFR1] = 0x00000000; - cpu->ctr = 0x1dd20d2; - cpu->reset_sctlr = 0x00050078; -- cpu->isar.id_pfr0 = 0x111; -- cpu->isar.id_pfr1 = 0x1; -- cpu->isar.id_dfr0 = 0x2; -+ cpu->isar.regs[ID_PFR0] = 0x111; -+ cpu->isar.regs[ID_PFR1] = 0x1; -+ cpu->isar.regs[ID_DFR0] = 0x2; - cpu->id_afr0 = 0x3; -- cpu->isar.id_mmfr0 = 0x01130003; -- cpu->isar.id_mmfr1 = 0x10030302; -- cpu->isar.id_mmfr2 = 0x01222110; -- cpu->isar.id_isar0 = 0x00140011; -- cpu->isar.id_isar1 = 0x12002111; -- cpu->isar.id_isar2 = 0x11231111; -- cpu->isar.id_isar3 = 0x01102131; -- cpu->isar.id_isar4 = 0x141; -+ cpu->isar.regs[ID_MMFR0] = 0x01130003; -+ cpu->isar.regs[ID_MMFR1] = 0x10030302; -+ cpu->isar.regs[ID_MMFR2] = 0x01222110; -+ cpu->isar.regs[ID_ISAR0] = 0x00140011; -+ cpu->isar.regs[ID_ISAR1] = 0x12002111; -+ cpu->isar.regs[ID_ISAR2] = 0x11231111; -+ cpu->isar.regs[ID_ISAR3] = 0x01102131; -+ cpu->isar.regs[ID_ISAR4] = 0x141; - cpu->reset_auxcr = 7; - } - -@@ -210,22 +214,22 @@ static void arm1176_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_EL3); - cpu->midr = 0x410fb767; - cpu->reset_fpsid = 0x410120b5; -- cpu->isar.mvfr0 = 0x11111111; -- cpu->isar.mvfr1 = 0x00000000; -+ cpu->isar.regs[MVFR0] = 0x11111111; -+ cpu->isar.regs[MVFR1] = 0x00000000; - cpu->ctr = 0x1dd20d2; - cpu->reset_sctlr = 0x00050078; -- cpu->isar.id_pfr0 = 0x111; -- cpu->isar.id_pfr1 = 0x11; -- cpu->isar.id_dfr0 = 0x33; -+ cpu->isar.regs[ID_PFR0] = 0x111; -+ cpu->isar.regs[ID_PFR1] = 0x11; -+ cpu->isar.regs[ID_DFR0] = 0x33; - cpu->id_afr0 = 0; -- cpu->isar.id_mmfr0 = 0x01130003; -- cpu->isar.id_mmfr1 = 0x10030302; -- cpu->isar.id_mmfr2 = 0x01222100; -- cpu->isar.id_isar0 = 0x0140011; -- cpu->isar.id_isar1 = 0x12002111; -- cpu->isar.id_isar2 = 0x11231121; -- cpu->isar.id_isar3 = 0x01102131; -- cpu->isar.id_isar4 = 0x01141; -+ cpu->isar.regs[ID_MMFR0] = 0x01130003; -+ cpu->isar.regs[ID_MMFR1] = 0x10030302; -+ cpu->isar.regs[ID_MMFR2] = 0x01222100; -+ cpu->isar.regs[ID_ISAR0] = 0x0140011; -+ cpu->isar.regs[ID_ISAR1] = 0x12002111; -+ cpu->isar.regs[ID_ISAR2] = 0x11231121; -+ cpu->isar.regs[ID_ISAR3] = 0x01102131; -+ cpu->isar.regs[ID_ISAR4] = 0x01141; - cpu->reset_auxcr = 7; - } - -@@ -240,21 +244,21 @@ static void arm11mpcore_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); - cpu->midr = 0x410fb022; - cpu->reset_fpsid = 0x410120b4; -- cpu->isar.mvfr0 = 0x11111111; -- cpu->isar.mvfr1 = 0x00000000; -+ cpu->isar.regs[MVFR0] = 0x11111111; -+ cpu->isar.regs[MVFR1] = 0x00000000; - cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ -- cpu->isar.id_pfr0 = 0x111; -- cpu->isar.id_pfr1 = 0x1; -- cpu->isar.id_dfr0 = 0; -+ cpu->isar.regs[ID_PFR0] = 0x111; -+ cpu->isar.regs[ID_PFR1] = 0x1; -+ cpu->isar.regs[ID_DFR0] = 0; - cpu->id_afr0 = 0x2; -- cpu->isar.id_mmfr0 = 0x01100103; -- cpu->isar.id_mmfr1 = 0x10020302; -- cpu->isar.id_mmfr2 = 0x01222000; -- cpu->isar.id_isar0 = 0x00100011; -- cpu->isar.id_isar1 = 0x12002111; -- cpu->isar.id_isar2 = 0x11221011; -- cpu->isar.id_isar3 = 0x01102131; -- cpu->isar.id_isar4 = 0x141; -+ cpu->isar.regs[ID_MMFR0] = 0x01100103; -+ cpu->isar.regs[ID_MMFR1] = 0x10020302; -+ cpu->isar.regs[ID_MMFR2] = 0x01222000; -+ cpu->isar.regs[ID_ISAR0] = 0x00100011; -+ cpu->isar.regs[ID_ISAR1] = 0x12002111; -+ cpu->isar.regs[ID_ISAR2] = 0x11221011; -+ cpu->isar.regs[ID_ISAR3] = 0x01102131; -+ cpu->isar.regs[ID_ISAR4] = 0x141; - cpu->reset_auxcr = 1; - } - -@@ -278,24 +282,24 @@ static void cortex_a8_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_EL3); - cpu->midr = 0x410fc080; - cpu->reset_fpsid = 0x410330c0; -- cpu->isar.mvfr0 = 0x11110222; -- cpu->isar.mvfr1 = 0x00011111; -+ cpu->isar.regs[MVFR0] = 0x11110222; -+ cpu->isar.regs[MVFR1] = 0x00011111; - cpu->ctr = 0x82048004; - cpu->reset_sctlr = 0x00c50078; -- cpu->isar.id_pfr0 = 0x1031; -- cpu->isar.id_pfr1 = 0x11; -- cpu->isar.id_dfr0 = 0x400; -+ cpu->isar.regs[ID_PFR0] = 0x1031; -+ cpu->isar.regs[ID_PFR1] = 0x11; -+ cpu->isar.regs[ID_DFR0] = 0x400; - cpu->id_afr0 = 0; -- cpu->isar.id_mmfr0 = 0x31100003; -- cpu->isar.id_mmfr1 = 0x20000000; -- cpu->isar.id_mmfr2 = 0x01202000; -- cpu->isar.id_mmfr3 = 0x11; -- cpu->isar.id_isar0 = 0x00101111; -- cpu->isar.id_isar1 = 0x12112111; -- cpu->isar.id_isar2 = 0x21232031; -- cpu->isar.id_isar3 = 0x11112131; -- cpu->isar.id_isar4 = 0x00111142; -- cpu->isar.dbgdidr = 0x15141000; -+ cpu->isar.regs[ID_MMFR0] = 0x31100003; -+ cpu->isar.regs[ID_MMFR1] = 0x20000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01202000; -+ cpu->isar.regs[ID_MMFR3] = 0x11; -+ cpu->isar.regs[ID_ISAR0] = 0x00101111; -+ cpu->isar.regs[ID_ISAR1] = 0x12112111; -+ cpu->isar.regs[ID_ISAR2] = 0x21232031; -+ cpu->isar.regs[ID_ISAR3] = 0x11112131; -+ cpu->isar.regs[ID_ISAR4] = 0x00111142; -+ cpu->isar.regs[DBGDIDR] = 0x15141000; - cpu->clidr = (1 << 27) | (2 << 24) | 3; - cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ - cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ -@@ -352,24 +356,24 @@ static void cortex_a9_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_CBAR); - cpu->midr = 0x410fc090; - cpu->reset_fpsid = 0x41033090; -- cpu->isar.mvfr0 = 0x11110222; -- cpu->isar.mvfr1 = 0x01111111; -+ cpu->isar.regs[MVFR0] = 0x11110222; -+ cpu->isar.regs[MVFR1] = 0x01111111; - cpu->ctr = 0x80038003; - cpu->reset_sctlr = 0x00c50078; -- cpu->isar.id_pfr0 = 0x1031; -- cpu->isar.id_pfr1 = 0x11; -- cpu->isar.id_dfr0 = 0x000; -+ cpu->isar.regs[ID_PFR0] = 0x1031; -+ cpu->isar.regs[ID_PFR1] = 0x11; -+ cpu->isar.regs[ID_DFR0] = 0x000; - cpu->id_afr0 = 0; -- cpu->isar.id_mmfr0 = 0x00100103; -- cpu->isar.id_mmfr1 = 0x20000000; -- cpu->isar.id_mmfr2 = 0x01230000; -- cpu->isar.id_mmfr3 = 0x00002111; -- cpu->isar.id_isar0 = 0x00101111; -- cpu->isar.id_isar1 = 0x13112111; -- cpu->isar.id_isar2 = 0x21232041; -- cpu->isar.id_isar3 = 0x11112131; -- cpu->isar.id_isar4 = 0x00111142; -- cpu->isar.dbgdidr = 0x35141000; -+ cpu->isar.regs[ID_MMFR0] = 0x00100103; -+ cpu->isar.regs[ID_MMFR1] = 0x20000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01230000; -+ cpu->isar.regs[ID_MMFR3] = 0x00002111; -+ cpu->isar.regs[ID_ISAR0] = 0x00101111; -+ cpu->isar.regs[ID_ISAR1] = 0x13112111; -+ cpu->isar.regs[ID_ISAR2] = 0x21232041; -+ cpu->isar.regs[ID_ISAR3] = 0x11112131; -+ cpu->isar.regs[ID_ISAR4] = 0x00111142; -+ cpu->isar.regs[DBGDIDR] = 0x35141000; - cpu->clidr = (1 << 27) | (1 << 24) | 3; - cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */ - cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */ -@@ -417,28 +421,28 @@ static void cortex_a7_initfn(Object *obj) - cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7; - cpu->midr = 0x410fc075; - cpu->reset_fpsid = 0x41023075; -- cpu->isar.mvfr0 = 0x10110222; -- cpu->isar.mvfr1 = 0x11111111; -+ cpu->isar.regs[MVFR0] = 0x10110222; -+ cpu->isar.regs[MVFR1] = 0x11111111; - cpu->ctr = 0x84448003; - cpu->reset_sctlr = 0x00c50078; -- cpu->isar.id_pfr0 = 0x00001131; -- cpu->isar.id_pfr1 = 0x00011011; -- cpu->isar.id_dfr0 = 0x02010555; -+ cpu->isar.regs[ID_PFR0] = 0x00001131; -+ cpu->isar.regs[ID_PFR1] = 0x00011011; -+ cpu->isar.regs[ID_DFR0] = 0x02010555; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x10101105; -- cpu->isar.id_mmfr1 = 0x40000000; -- cpu->isar.id_mmfr2 = 0x01240000; -- cpu->isar.id_mmfr3 = 0x02102211; -+ cpu->isar.regs[ID_MMFR0] = 0x10101105; -+ cpu->isar.regs[ID_MMFR1] = 0x40000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01240000; -+ cpu->isar.regs[ID_MMFR3] = 0x02102211; - /* - * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but - * table 4-41 gives 0x02101110, which includes the arm div insns. - */ -- cpu->isar.id_isar0 = 0x02101110; -- cpu->isar.id_isar1 = 0x13112111; -- cpu->isar.id_isar2 = 0x21232041; -- cpu->isar.id_isar3 = 0x11112131; -- cpu->isar.id_isar4 = 0x10011142; -- cpu->isar.dbgdidr = 0x3515f005; -+ cpu->isar.regs[ID_ISAR0] = 0x02101110; -+ cpu->isar.regs[ID_ISAR1] = 0x13112111; -+ cpu->isar.regs[ID_ISAR2] = 0x21232041; -+ cpu->isar.regs[ID_ISAR3] = 0x11112131; -+ cpu->isar.regs[ID_ISAR4] = 0x10011142; -+ cpu->isar.regs[DBGDIDR] = 0x3515f005; - cpu->clidr = 0x0a200023; - cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ - cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ -@@ -463,24 +467,24 @@ static void cortex_a15_initfn(Object *obj) - cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15; - cpu->midr = 0x412fc0f1; - cpu->reset_fpsid = 0x410430f0; -- cpu->isar.mvfr0 = 0x10110222; -- cpu->isar.mvfr1 = 0x11111111; -+ cpu->isar.regs[MVFR0] = 0x10110222; -+ cpu->isar.regs[MVFR1] = 0x11111111; - cpu->ctr = 0x8444c004; - cpu->reset_sctlr = 0x00c50078; -- cpu->isar.id_pfr0 = 0x00001131; -- cpu->isar.id_pfr1 = 0x00011011; -- cpu->isar.id_dfr0 = 0x02010555; -+ cpu->isar.regs[ID_PFR0] = 0x00001131; -+ cpu->isar.regs[ID_PFR1] = 0x00011011; -+ cpu->isar.regs[ID_DFR0] = 0x02010555; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x10201105; -- cpu->isar.id_mmfr1 = 0x20000000; -- cpu->isar.id_mmfr2 = 0x01240000; -- cpu->isar.id_mmfr3 = 0x02102211; -- cpu->isar.id_isar0 = 0x02101110; -- cpu->isar.id_isar1 = 0x13112111; -- cpu->isar.id_isar2 = 0x21232041; -- cpu->isar.id_isar3 = 0x11112131; -- cpu->isar.id_isar4 = 0x10011142; -- cpu->isar.dbgdidr = 0x3515f021; -+ cpu->isar.regs[ID_MMFR0] = 0x10201105; -+ cpu->isar.regs[ID_MMFR1] = 0x20000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01240000; -+ cpu->isar.regs[ID_MMFR3] = 0x02102211; -+ cpu->isar.regs[ID_ISAR0] = 0x02101110; -+ cpu->isar.regs[ID_ISAR1] = 0x13112111; -+ cpu->isar.regs[ID_ISAR2] = 0x21232041; -+ cpu->isar.regs[ID_ISAR3] = 0x11112131; -+ cpu->isar.regs[ID_ISAR4] = 0x10011142; -+ cpu->isar.regs[DBGDIDR] = 0x3515f021; - cpu->clidr = 0x0a200023; - cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ - cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ -@@ -504,21 +508,21 @@ static void cortex_m0_initfn(Object *obj) - * by looking at ID register fields. We use the same values as - * for the M3. - */ -- cpu->isar.id_pfr0 = 0x00000030; -- cpu->isar.id_pfr1 = 0x00000200; -- cpu->isar.id_dfr0 = 0x00100000; -+ cpu->isar.regs[ID_PFR0] = 0x00000030; -+ cpu->isar.regs[ID_PFR1] = 0x00000200; -+ cpu->isar.regs[ID_DFR0] = 0x00100000; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x00000030; -- cpu->isar.id_mmfr1 = 0x00000000; -- cpu->isar.id_mmfr2 = 0x00000000; -- cpu->isar.id_mmfr3 = 0x00000000; -- cpu->isar.id_isar0 = 0x01141110; -- cpu->isar.id_isar1 = 0x02111000; -- cpu->isar.id_isar2 = 0x21112231; -- cpu->isar.id_isar3 = 0x01111110; -- cpu->isar.id_isar4 = 0x01310102; -- cpu->isar.id_isar5 = 0x00000000; -- cpu->isar.id_isar6 = 0x00000000; -+ cpu->isar.regs[ID_MMFR0] = 0x00000030; -+ cpu->isar.regs[ID_MMFR1] = 0x00000000; -+ cpu->isar.regs[ID_MMFR2] = 0x00000000; -+ cpu->isar.regs[ID_MMFR3] = 0x00000000; -+ cpu->isar.regs[ID_ISAR0] = 0x01141110; -+ cpu->isar.regs[ID_ISAR1] = 0x02111000; -+ cpu->isar.regs[ID_ISAR2] = 0x21112231; -+ cpu->isar.regs[ID_ISAR3] = 0x01111110; -+ cpu->isar.regs[ID_ISAR4] = 0x01310102; -+ cpu->isar.regs[ID_ISAR5] = 0x00000000; -+ cpu->isar.regs[ID_ISAR6] = 0x00000000; - } - - static void cortex_m3_initfn(Object *obj) -@@ -529,21 +533,21 @@ static void cortex_m3_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_M_MAIN); - cpu->midr = 0x410fc231; - cpu->pmsav7_dregion = 8; -- cpu->isar.id_pfr0 = 0x00000030; -- cpu->isar.id_pfr1 = 0x00000200; -- cpu->isar.id_dfr0 = 0x00100000; -+ cpu->isar.regs[ID_PFR0] = 0x00000030; -+ cpu->isar.regs[ID_PFR1] = 0x00000200; -+ cpu->isar.regs[ID_DFR0] = 0x00100000; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x00000030; -- cpu->isar.id_mmfr1 = 0x00000000; -- cpu->isar.id_mmfr2 = 0x00000000; -- cpu->isar.id_mmfr3 = 0x00000000; -- cpu->isar.id_isar0 = 0x01141110; -- cpu->isar.id_isar1 = 0x02111000; -- cpu->isar.id_isar2 = 0x21112231; -- cpu->isar.id_isar3 = 0x01111110; -- cpu->isar.id_isar4 = 0x01310102; -- cpu->isar.id_isar5 = 0x00000000; -- cpu->isar.id_isar6 = 0x00000000; -+ cpu->isar.regs[ID_MMFR0] = 0x00000030; -+ cpu->isar.regs[ID_MMFR1] = 0x00000000; -+ cpu->isar.regs[ID_MMFR2] = 0x00000000; -+ cpu->isar.regs[ID_MMFR3] = 0x00000000; -+ cpu->isar.regs[ID_ISAR0] = 0x01141110; -+ cpu->isar.regs[ID_ISAR1] = 0x02111000; -+ cpu->isar.regs[ID_ISAR2] = 0x21112231; -+ cpu->isar.regs[ID_ISAR3] = 0x01111110; -+ cpu->isar.regs[ID_ISAR4] = 0x01310102; -+ cpu->isar.regs[ID_ISAR5] = 0x00000000; -+ cpu->isar.regs[ID_ISAR6] = 0x00000000; - } - - static void cortex_m4_initfn(Object *obj) -@@ -556,24 +560,24 @@ static void cortex_m4_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); - cpu->midr = 0x410fc240; /* r0p0 */ - cpu->pmsav7_dregion = 8; -- cpu->isar.mvfr0 = 0x10110021; -- cpu->isar.mvfr1 = 0x11000011; -- cpu->isar.mvfr2 = 0x00000000; -- cpu->isar.id_pfr0 = 0x00000030; -- cpu->isar.id_pfr1 = 0x00000200; -- cpu->isar.id_dfr0 = 0x00100000; -+ cpu->isar.regs[MVFR0] = 0x10110021; -+ cpu->isar.regs[MVFR1] = 0x11000011; -+ cpu->isar.regs[MVFR2] = 0x00000000; -+ cpu->isar.regs[ID_PFR0] = 0x00000030; -+ cpu->isar.regs[ID_PFR1] = 0x00000200; -+ cpu->isar.regs[ID_DFR0] = 0x00100000; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x00000030; -- cpu->isar.id_mmfr1 = 0x00000000; -- cpu->isar.id_mmfr2 = 0x00000000; -- cpu->isar.id_mmfr3 = 0x00000000; -- cpu->isar.id_isar0 = 0x01141110; -- cpu->isar.id_isar1 = 0x02111000; -- cpu->isar.id_isar2 = 0x21112231; -- cpu->isar.id_isar3 = 0x01111110; -- cpu->isar.id_isar4 = 0x01310102; -- cpu->isar.id_isar5 = 0x00000000; -- cpu->isar.id_isar6 = 0x00000000; -+ cpu->isar.regs[ID_MMFR0] = 0x00000030; -+ cpu->isar.regs[ID_MMFR1] = 0x00000000; -+ cpu->isar.regs[ID_MMFR2] = 0x00000000; -+ cpu->isar.regs[ID_MMFR3] = 0x00000000; -+ cpu->isar.regs[ID_ISAR0] = 0x01141110; -+ cpu->isar.regs[ID_ISAR1] = 0x02111000; -+ cpu->isar.regs[ID_ISAR2] = 0x21112231; -+ cpu->isar.regs[ID_ISAR3] = 0x01111110; -+ cpu->isar.regs[ID_ISAR4] = 0x01310102; -+ cpu->isar.regs[ID_ISAR5] = 0x00000000; -+ cpu->isar.regs[ID_ISAR6] = 0x00000000; - } - - static void cortex_m7_initfn(Object *obj) -@@ -586,24 +590,24 @@ static void cortex_m7_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); - cpu->midr = 0x411fc272; /* r1p2 */ - cpu->pmsav7_dregion = 8; -- cpu->isar.mvfr0 = 0x10110221; -- cpu->isar.mvfr1 = 0x12000011; -- cpu->isar.mvfr2 = 0x00000040; -- cpu->isar.id_pfr0 = 0x00000030; -- cpu->isar.id_pfr1 = 0x00000200; -- cpu->isar.id_dfr0 = 0x00100000; -+ cpu->isar.regs[MVFR0] = 0x10110221; -+ cpu->isar.regs[MVFR1] = 0x12000011; -+ cpu->isar.regs[MVFR2] = 0x00000040; -+ cpu->isar.regs[ID_PFR0] = 0x00000030; -+ cpu->isar.regs[ID_PFR1] = 0x00000200; -+ cpu->isar.regs[ID_DFR0] = 0x00100000; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x00100030; -- cpu->isar.id_mmfr1 = 0x00000000; -- cpu->isar.id_mmfr2 = 0x01000000; -- cpu->isar.id_mmfr3 = 0x00000000; -- cpu->isar.id_isar0 = 0x01101110; -- cpu->isar.id_isar1 = 0x02112000; -- cpu->isar.id_isar2 = 0x20232231; -- cpu->isar.id_isar3 = 0x01111131; -- cpu->isar.id_isar4 = 0x01310132; -- cpu->isar.id_isar5 = 0x00000000; -- cpu->isar.id_isar6 = 0x00000000; -+ cpu->isar.regs[ID_MMFR0] = 0x00100030; -+ cpu->isar.regs[ID_MMFR1] = 0x00000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01000000; -+ cpu->isar.regs[ID_MMFR3] = 0x00000000; -+ cpu->isar.regs[ID_ISAR0] = 0x01101110; -+ cpu->isar.regs[ID_ISAR1] = 0x02112000; -+ cpu->isar.regs[ID_ISAR2] = 0x20232231; -+ cpu->isar.regs[ID_ISAR3] = 0x01111131; -+ cpu->isar.regs[ID_ISAR4] = 0x01310132; -+ cpu->isar.regs[ID_ISAR5] = 0x00000000; -+ cpu->isar.regs[ID_ISAR6] = 0x00000000; - } - - static void cortex_m33_initfn(Object *obj) -@@ -618,24 +622,24 @@ static void cortex_m33_initfn(Object *obj) - cpu->midr = 0x410fd213; /* r0p3 */ - cpu->pmsav7_dregion = 16; - cpu->sau_sregion = 8; -- cpu->isar.mvfr0 = 0x10110021; -- cpu->isar.mvfr1 = 0x11000011; -- cpu->isar.mvfr2 = 0x00000040; -- cpu->isar.id_pfr0 = 0x00000030; -- cpu->isar.id_pfr1 = 0x00000210; -- cpu->isar.id_dfr0 = 0x00200000; -+ cpu->isar.regs[MVFR0] = 0x10110021; -+ cpu->isar.regs[MVFR1] = 0x11000011; -+ cpu->isar.regs[MVFR2] = 0x00000040; -+ cpu->isar.regs[ID_PFR0] = 0x00000030; -+ cpu->isar.regs[ID_PFR1] = 0x00000210; -+ cpu->isar.regs[ID_DFR0] = 0x00200000; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x00101F40; -- cpu->isar.id_mmfr1 = 0x00000000; -- cpu->isar.id_mmfr2 = 0x01000000; -- cpu->isar.id_mmfr3 = 0x00000000; -- cpu->isar.id_isar0 = 0x01101110; -- cpu->isar.id_isar1 = 0x02212000; -- cpu->isar.id_isar2 = 0x20232232; -- cpu->isar.id_isar3 = 0x01111131; -- cpu->isar.id_isar4 = 0x01310132; -- cpu->isar.id_isar5 = 0x00000000; -- cpu->isar.id_isar6 = 0x00000000; -+ cpu->isar.regs[ID_MMFR0] = 0x00101F40; -+ cpu->isar.regs[ID_MMFR1] = 0x00000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01000000; -+ cpu->isar.regs[ID_MMFR3] = 0x00000000; -+ cpu->isar.regs[ID_ISAR0] = 0x01101110; -+ cpu->isar.regs[ID_ISAR1] = 0x02212000; -+ cpu->isar.regs[ID_ISAR2] = 0x20232232; -+ cpu->isar.regs[ID_ISAR3] = 0x01111131; -+ cpu->isar.regs[ID_ISAR4] = 0x01310132; -+ cpu->isar.regs[ID_ISAR5] = 0x00000000; -+ cpu->isar.regs[ID_ISAR6] = 0x00000000; - cpu->clidr = 0x00000000; - cpu->ctr = 0x8000c000; - } -@@ -655,24 +659,24 @@ static void cortex_m55_initfn(Object *obj) - cpu->pmsav7_dregion = 16; - cpu->sau_sregion = 8; - /* These are the MVFR* values for the FPU + full MVE configuration */ -- cpu->isar.mvfr0 = 0x10110221; -- cpu->isar.mvfr1 = 0x12100211; -- cpu->isar.mvfr2 = 0x00000040; -- cpu->isar.id_pfr0 = 0x20000030; -- cpu->isar.id_pfr1 = 0x00000230; -- cpu->isar.id_dfr0 = 0x10200000; -+ cpu->isar.regs[MVFR0] = 0x10110221; -+ cpu->isar.regs[MVFR1] = 0x12100211; -+ cpu->isar.regs[MVFR2] = 0x00000040; -+ cpu->isar.regs[ID_PFR0] = 0x20000030; -+ cpu->isar.regs[ID_PFR1] = 0x00000230; -+ cpu->isar.regs[ID_DFR0] = 0x10200000; - cpu->id_afr0 = 0x00000000; -- cpu->isar.id_mmfr0 = 0x00111040; -- cpu->isar.id_mmfr1 = 0x00000000; -- cpu->isar.id_mmfr2 = 0x01000000; -- cpu->isar.id_mmfr3 = 0x00000011; -- cpu->isar.id_isar0 = 0x01103110; -- cpu->isar.id_isar1 = 0x02212000; -- cpu->isar.id_isar2 = 0x20232232; -- cpu->isar.id_isar3 = 0x01111131; -- cpu->isar.id_isar4 = 0x01310132; -- cpu->isar.id_isar5 = 0x00000000; -- cpu->isar.id_isar6 = 0x00000000; -+ cpu->isar.regs[ID_MMFR0] = 0x00111040; -+ cpu->isar.regs[ID_MMFR1] = 0x00000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01000000; -+ cpu->isar.regs[ID_MMFR3] = 0x00000011; -+ cpu->isar.regs[ID_ISAR0] = 0x01103110; -+ cpu->isar.regs[ID_ISAR1] = 0x02212000; -+ cpu->isar.regs[ID_ISAR2] = 0x20232232; -+ cpu->isar.regs[ID_ISAR3] = 0x01111131; -+ cpu->isar.regs[ID_ISAR4] = 0x01310132; -+ cpu->isar.regs[ID_ISAR5] = 0x00000000; -+ cpu->isar.regs[ID_ISAR6] = 0x00000000; - cpu->clidr = 0x00000000; /* caches not implemented */ - cpu->ctr = 0x8303c003; - } -@@ -697,21 +701,21 @@ static void cortex_r5_initfn(Object *obj) - set_feature(&cpu->env, ARM_FEATURE_PMSA); - set_feature(&cpu->env, ARM_FEATURE_PMU); - cpu->midr = 0x411fc153; /* r1p3 */ -- cpu->isar.id_pfr0 = 0x0131; -- cpu->isar.id_pfr1 = 0x001; -- cpu->isar.id_dfr0 = 0x010400; -+ cpu->isar.regs[ID_PFR0] = 0x0131; -+ cpu->isar.regs[ID_PFR1] = 0x001; -+ cpu->isar.regs[ID_DFR0] = 0x010400; - cpu->id_afr0 = 0x0; -- cpu->isar.id_mmfr0 = 0x0210030; -- cpu->isar.id_mmfr1 = 0x00000000; -- cpu->isar.id_mmfr2 = 0x01200000; -- cpu->isar.id_mmfr3 = 0x0211; -- cpu->isar.id_isar0 = 0x02101111; -- cpu->isar.id_isar1 = 0x13112111; -- cpu->isar.id_isar2 = 0x21232141; -- cpu->isar.id_isar3 = 0x01112131; -- cpu->isar.id_isar4 = 0x0010142; -- cpu->isar.id_isar5 = 0x0; -- cpu->isar.id_isar6 = 0x0; -+ cpu->isar.regs[ID_MMFR0] = 0x0210030; -+ cpu->isar.regs[ID_MMFR1] = 0x00000000; -+ cpu->isar.regs[ID_MMFR2] = 0x01200000; -+ cpu->isar.regs[ID_MMFR3] = 0x0211; -+ cpu->isar.regs[ID_ISAR0] = 0x02101111; -+ cpu->isar.regs[ID_ISAR1] = 0x13112111; -+ cpu->isar.regs[ID_ISAR2] = 0x21232141; -+ cpu->isar.regs[ID_ISAR3] = 0x01112131; -+ cpu->isar.regs[ID_ISAR4] = 0x0010142; -+ cpu->isar.regs[ID_ISAR5] = 0x0; -+ cpu->isar.regs[ID_ISAR6] = 0x0; - cpu->mp_is_up = true; - cpu->pmsav7_dregion = 16; - define_arm_cp_regs(cpu, cortexr5_cp_reginfo); -@@ -722,8 +726,8 @@ static void cortex_r5f_initfn(Object *obj) - ARMCPU *cpu = ARM_CPU(obj); - - cortex_r5_initfn(obj); -- cpu->isar.mvfr0 = 0x10110221; -- cpu->isar.mvfr1 = 0x00000011; -+ cpu->isar.regs[MVFR0] = 0x10110221; -+ cpu->isar.regs[MVFR1] = 0x00000011; - } - - static void ti925t_initfn(Object *obj) -@@ -942,7 +946,8 @@ static void arm_max_initfn(Object *obj) - cortex_a15_initfn(obj); - - /* old-style VFP short-vector support */ -- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1); -+ cpu->isar.regs[MVFR0] = FIELD_DP32(cpu->isar.regs[MVFR0], MVFR0, FPSHVEC, -+ 1); - - #ifdef CONFIG_USER_ONLY - /* -@@ -954,16 +959,16 @@ static void arm_max_initfn(Object *obj) - { - uint32_t t; - -- t = cpu->isar.id_isar5; -+ t = cpu->isar.regs[ID_ISAR5]; - t = FIELD_DP32(t, ID_ISAR5, AES, 2); - t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); - t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); - t = FIELD_DP32(t, ID_ISAR5, CRC32, 1); - t = FIELD_DP32(t, ID_ISAR5, RDM, 1); - t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); -- cpu->isar.id_isar5 = t; -+ cpu->isar.regs[ID_ISAR5] = t; - -- t = cpu->isar.id_isar6; -+ t = cpu->isar.regs[ID_ISAR6]; - t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); - t = FIELD_DP32(t, ID_ISAR6, DP, 1); - t = FIELD_DP32(t, ID_ISAR6, FHM, 1); -@@ -971,36 +976,36 @@ static void arm_max_initfn(Object *obj) - t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); - t = FIELD_DP32(t, ID_ISAR6, BF16, 1); - t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); -- cpu->isar.id_isar6 = t; -+ cpu->isar.regs[ID_ISAR6] = t; - -- t = cpu->isar.mvfr1; -+ t = cpu->isar.regs[MVFR1]; - t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */ - t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */ -- cpu->isar.mvfr1 = t; -+ cpu->isar.regs[MVFR1] = t; - -- t = cpu->isar.mvfr2; -+ t = cpu->isar.regs[MVFR2]; - t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */ - t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */ -- cpu->isar.mvfr2 = t; -+ cpu->isar.regs[MVFR2] = t; - -- t = cpu->isar.id_mmfr3; -+ t = cpu->isar.regs[ID_MMFR3]; - t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */ -- cpu->isar.id_mmfr3 = t; -+ cpu->isar.regs[ID_MMFR3] = t; - -- t = cpu->isar.id_mmfr4; -+ t = cpu->isar.regs[ID_MMFR4]; - t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */ - t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */ - t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */ - t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */ -- cpu->isar.id_mmfr4 = t; -+ cpu->isar.regs[ID_MMFR4] = t; - -- t = cpu->isar.id_pfr0; -+ t = cpu->isar.regs[ID_PFR0]; - t = FIELD_DP32(t, ID_PFR0, DIT, 1); -- cpu->isar.id_pfr0 = t; -+ cpu->isar.regs[ID_PFR0] = t; - -- t = cpu->isar.id_pfr2; -+ t = cpu->isar.regs[ID_PFR2]; - t = FIELD_DP32(t, ID_PFR2, SSBS, 1); -- cpu->isar.id_pfr2 = t; -+ cpu->isar.regs[ID_PFR2] = t; - } - #endif /* CONFIG_USER_ONLY */ - } -diff --git a/target/arm/helper.c b/target/arm/helper.c -index 9b317899a6..b8ea1dc1f6 100644 ---- a/target/arm/helper.c -+++ b/target/arm/helper.c -@@ -6547,12 +6547,12 @@ static void define_debug_regs(ARMCPU *cpu) - * use AArch32. Given that bit 15 is RES1, if the value is 0 then - * the register must not exist for this cpu. - */ -- if (cpu->isar.dbgdidr != 0) { -+ if (cpu->isar.regs[DBGDIDR] != 0) { - ARMCPRegInfo dbgdidr = { - .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, - .opc1 = 0, .opc2 = 0, - .access = PL0_R, .accessfn = access_tda, -- .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr, -+ .type = ARM_CP_CONST, .resetvalue = cpu->isar.regs[DBGDIDR], - }; - define_one_arm_cp_reg(cpu, &dbgdidr); - } -@@ -6707,7 +6707,7 @@ static void define_pmu_regs(ARMCPU *cpu) - static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) - { - ARMCPU *cpu = env_archcpu(env); -- uint64_t pfr1 = cpu->isar.id_pfr1; -+ uint64_t pfr1 = cpu->isar.regs[ID_PFR1]; - - if (env->gicv3state) { - pfr1 |= 1 << 28; -@@ -6719,7 +6719,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) - static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) - { - ARMCPU *cpu = env_archcpu(env); -- uint64_t pfr0 = cpu->isar.id_aa64pfr0; -+ uint64_t pfr0 = cpu->isar.regs[ID_AA64PFR0]; - - if (env->gicv3state) { - pfr0 |= 1 << 24; -@@ -7501,7 +7501,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_pfr0 }, -+ .resetvalue = cpu->isar.regs[ID_PFR0] }, - /* ID_PFR1 is not a plain ARM_CP_CONST because we don't know - * the value of the GIC field until after we define these regs. - */ -@@ -7515,7 +7515,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_dfr0 }, -+ .resetvalue = cpu->isar.regs[ID_DFR0] }, - { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3, - .access = PL1_R, .type = ARM_CP_CONST, -@@ -7525,62 +7525,62 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_mmfr0 }, -+ .resetvalue = cpu->isar.regs[ID_MMFR0] }, - { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_mmfr1 }, -+ .resetvalue = cpu->isar.regs[ID_MMFR1] }, - { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_mmfr2 }, -+ .resetvalue = cpu->isar.regs[ID_MMFR2] }, - { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_mmfr3 }, -+ .resetvalue = cpu->isar.regs[ID_MMFR3] }, - { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_isar0 }, -+ .resetvalue = cpu->isar.regs[ID_ISAR0] }, - { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_isar1 }, -+ .resetvalue = cpu->isar.regs[ID_ISAR1] }, - { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_isar2 }, -+ .resetvalue = cpu->isar.regs[ID_ISAR2] }, - { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_isar3 }, -+ .resetvalue = cpu->isar.regs[ID_ISAR3] }, - { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_isar4 }, -+ .resetvalue = cpu->isar.regs[ID_ISAR4] }, - { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_isar5 }, -+ .resetvalue = cpu->isar.regs[ID_ISAR5] }, - { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_mmfr4 }, -+ .resetvalue = cpu->isar.regs[ID_MMFR4] }, - { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa32_tid3, -- .resetvalue = cpu->isar.id_isar6 }, -+ .resetvalue = cpu->isar.regs[ID_ISAR6] }, - REGINFO_SENTINEL - }; - define_arm_cp_regs(cpu, v6_idregs); -@@ -7630,7 +7630,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .access = PL1_R, - #ifdef CONFIG_USER_ONLY - .type = ARM_CP_CONST, -- .resetvalue = cpu->isar.id_aa64pfr0 -+ .resetvalue = cpu->isar.regs[ID_AA64PFR0] - #else - .type = ARM_CP_NO_RAW, - .accessfn = access_aa64_tid3, -@@ -7642,7 +7642,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64pfr1}, -+ .resetvalue = cpu->isar.regs[ID_AA64PFR1]}, - { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, -@@ -7657,7 +7657,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64zfr0 }, -+ .resetvalue = cpu->isar.regs[ID_AA64ZFR0] }, - { .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5, - .access = PL1_R, .type = ARM_CP_CONST, -@@ -7677,12 +7677,12 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64dfr0 }, -+ .resetvalue = cpu->isar.regs[ID_AA64DFR0] }, - { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64dfr1 }, -+ .resetvalue = cpu->isar.regs[ID_AA64DFR1] }, - { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, -@@ -7717,12 +7717,12 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64isar0 }, -+ .resetvalue = cpu->isar.regs[ID_AA64ISAR0] }, - { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64isar1 }, -+ .resetvalue = cpu->isar.regs[ID_AA64ISAR1] }, - { .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, -@@ -7757,17 +7757,17 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64mmfr0 }, -+ .resetvalue = cpu->isar.regs[ID_AA64MMFR0] }, - { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64mmfr1 }, -+ .resetvalue = cpu->isar.regs[ID_AA64MMFR1] }, - { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_aa64mmfr2 }, -+ .resetvalue = cpu->isar.regs[ID_AA64MMFR2] }, - { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3, - .access = PL1_R, .type = ARM_CP_CONST, -@@ -7797,17 +7797,17 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.mvfr0 }, -+ .resetvalue = cpu->isar.regs[MVFR0] }, - { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.mvfr1 }, -+ .resetvalue = cpu->isar.regs[MVFR1] }, - { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.mvfr2 }, -+ .resetvalue = cpu->isar.regs[MVFR2] }, - { .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3, - .access = PL1_R, .type = ARM_CP_CONST, -@@ -7817,7 +7817,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4, - .access = PL1_R, .type = ARM_CP_CONST, - .accessfn = access_aa64_tid3, -- .resetvalue = cpu->isar.id_pfr2 }, -+ .resetvalue = cpu->isar.regs[ID_PFR2] }, - { .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64, - .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5, - .access = PL1_R, .type = ARM_CP_CONST, -diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c -index 0dc96560d3..66ad698df1 100644 ---- a/target/arm/hvf/hvf.c -+++ b/target/arm/hvf/hvf.c -@@ -449,15 +449,15 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - int reg; - uint64_t *val; - } regs[] = { -- { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.id_aa64pfr0 }, -- { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.id_aa64pfr1 }, -- { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.id_aa64dfr0 }, -- { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 }, -- { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.id_aa64isar0 }, -- { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.id_aa64isar1 }, -- { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 }, -- { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 }, -- { HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 }, -+ { HV_SYS_REG_ID_AA64PFR0_EL1, &host_isar.regs[ID_AA64PFR0] }, -+ { HV_SYS_REG_ID_AA64PFR1_EL1, &host_isar.regs[ID_AA64PFR1] }, -+ { HV_SYS_REG_ID_AA64DFR0_EL1, &host_isar.regs[ID_AA64DFR0] }, -+ { HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.regs[ID_AA64DFR1] }, -+ { HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.regs[ID_AA64ISAR0] }, -+ { HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.regs[ID_AA64ISAR1] }, -+ { HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.regs[ID_AA64MMFR0] }, -+ { HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.regs[ID_AA64MMFR1] }, -+ { HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.regs[ID_AA64MMFR2] }, - }; - hv_vcpu_t fd; - hv_return_t r = HV_SUCCESS; -@@ -593,7 +593,7 @@ int hvf_arch_init_vcpu(CPUState *cpu) - - /* We're limited to underlying hardware caps, override internal versions */ - ret = hv_vcpu_get_sys_reg(cpu->hvf->fd, HV_SYS_REG_ID_AA64MMFR0_EL1, -- &arm_cpu->isar.id_aa64mmfr0); -+ &arm_cpu->isar.regs[ID_AA64MMFR0]); - assert_hvf_ok(ret); - - return 0; -diff --git a/target/arm/internals.h b/target/arm/internals.h -index 89f7610ebc..0ea225e480 100644 ---- a/target/arm/internals.h -+++ b/target/arm/internals.h -@@ -254,7 +254,7 @@ static inline unsigned int arm_pamax(ARMCPU *cpu) - [5] = 48, - }; - unsigned int parange = -- FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); -+ FIELD_EX64(cpu->isar.regs[ID_AA64MMFR0], ID_AA64MMFR0, PARANGE); - - /* id_aa64mmfr0 is a read-only register so values outside of the - * supported mappings can be considered an implementation error. */ -@@ -808,9 +808,9 @@ static inline uint32_t arm_debug_exception_fsr(CPUARMState *env) - static inline int arm_num_brps(ARMCPU *cpu) - { - if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { -- return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1; -+ return FIELD_EX64(cpu->isar.regs[ID_AA64DFR0], ID_AA64DFR0, BRPS) + 1; - } else { -- return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1; -+ return FIELD_EX32(cpu->isar.regs[DBGDIDR], DBGDIDR, BRPS) + 1; - } - } - -@@ -822,9 +822,9 @@ static inline int arm_num_brps(ARMCPU *cpu) - static inline int arm_num_wrps(ARMCPU *cpu) - { - if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { -- return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1; -+ return FIELD_EX64(cpu->isar.regs[ID_AA64DFR0], ID_AA64DFR0, WRPS) + 1; - } else { -- return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1; -+ return FIELD_EX32(cpu->isar.regs[DBGDIDR], DBGDIDR, WRPS) + 1; - } - } - -@@ -836,9 +836,9 @@ static inline int arm_num_wrps(ARMCPU *cpu) - static inline int arm_num_ctx_cmps(ARMCPU *cpu) - { - if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { -- return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1; -+ return FIELD_EX64(cpu->isar.regs[ID_AA64DFR0], ID_AA64DFR0, CTX_CMPS) + 1; - } else { -- return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1; -+ return FIELD_EX32(cpu->isar.regs[DBGDIDR], DBGDIDR, CTX_CMPS) + 1; - } - } - -diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c -index e790d6c9a5..4f97e516c2 100644 ---- a/target/arm/kvm64.c -+++ b/target/arm/kvm64.c -@@ -468,7 +468,7 @@ void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa) - } - } - --static int read_sys_reg32(int fd, uint32_t *pret, uint64_t id) -+static int read_sys_reg32(int fd, uint64_t *pret, uint64_t id) - { - uint64_t ret; - struct kvm_one_reg idreg = { .id = id, .addr = (uintptr_t)&ret }; -@@ -528,7 +528,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - ahcf->target = init.target; - ahcf->dtb_compatible = "arm,arm-v8"; - -- err = read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr0, -+ err = read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64PFR0], - ARM64_SYS_REG(3, 0, 0, 4, 0)); - if (unlikely(err < 0)) { - /* -@@ -547,24 +547,24 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - * ??? Either of these sounds like too much effort just - * to work around running a modern host kernel. - */ -- ahcf->isar.id_aa64pfr0 = 0x00000011; /* EL1&0, AArch64 only */ -+ ahcf->isar.regs[ID_AA64PFR0] = 0x00000011; /* EL1&0, AArch64 only */ - err = 0; - } else { -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64pfr1, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64PFR1], - ARM64_SYS_REG(3, 0, 0, 4, 1)); -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64DFR0], - ARM64_SYS_REG(3, 0, 0, 5, 0)); -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64DFR1], - ARM64_SYS_REG(3, 0, 0, 5, 1)); -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64ISAR0], - ARM64_SYS_REG(3, 0, 0, 6, 0)); -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64ISAR1], - ARM64_SYS_REG(3, 0, 0, 6, 1)); -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64MMFR0], - ARM64_SYS_REG(3, 0, 0, 7, 0)); -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64MMFR1], - ARM64_SYS_REG(3, 0, 0, 7, 1)); -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr2, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64MMFR2], - ARM64_SYS_REG(3, 0, 0, 7, 2)); - - /* -@@ -574,44 +574,44 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - * than skipping the reads and leaving 0, as we must avoid - * considering the values in every case. - */ -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr0, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_PFR0], - ARM64_SYS_REG(3, 0, 0, 1, 0)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_PFR1], - ARM64_SYS_REG(3, 0, 0, 1, 1)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_PFR2], - ARM64_SYS_REG(3, 0, 0, 3, 4)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_DFR0], - ARM64_SYS_REG(3, 0, 0, 1, 2)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_MMFR0], - ARM64_SYS_REG(3, 0, 0, 1, 4)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr1, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_MMFR1], - ARM64_SYS_REG(3, 0, 0, 1, 5)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr2, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_MMFR2], - ARM64_SYS_REG(3, 0, 0, 1, 6)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr3, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_MMFR3], - ARM64_SYS_REG(3, 0, 0, 1, 7)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar0, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_ISAR0], - ARM64_SYS_REG(3, 0, 0, 2, 0)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar1, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_ISAR1], - ARM64_SYS_REG(3, 0, 0, 2, 1)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar2, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_ISAR2], - ARM64_SYS_REG(3, 0, 0, 2, 2)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar3, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_ISAR3], - ARM64_SYS_REG(3, 0, 0, 2, 3)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar4, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_ISAR4], - ARM64_SYS_REG(3, 0, 0, 2, 4)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar5, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_ISAR5], - ARM64_SYS_REG(3, 0, 0, 2, 5)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr4, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_MMFR4], - ARM64_SYS_REG(3, 0, 0, 2, 6)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_isar6, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[ID_ISAR6], - ARM64_SYS_REG(3, 0, 0, 2, 7)); - -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr0, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[MVFR0], - ARM64_SYS_REG(3, 0, 0, 3, 0)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr1, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[MVFR1], - ARM64_SYS_REG(3, 0, 0, 3, 1)); -- err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2, -+ err |= read_sys_reg32(fdarray[2], &ahcf->isar.regs[MVFR2], - ARM64_SYS_REG(3, 0, 0, 3, 2)); - - /* -@@ -624,14 +624,17 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - * arch/arm64/kvm/sys_regs.c:trap_dbgidr() does. - * We only do this if the CPU supports AArch32 at EL1. - */ -- if (FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL1) >= 2) { -- int wrps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, WRPS); -- int brps = FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, BRPS); -+ if (FIELD_EX32(ahcf->isar.regs[ID_AA64PFR0], ID_AA64PFR0, EL1) >= 2) { -+ int wrps = FIELD_EX64(ahcf->isar.regs[ID_AA64DFR0], ID_AA64DFR0, -+ WRPS); -+ int brps = FIELD_EX64(ahcf->isar.regs[ID_AA64DFR0], ID_AA64DFR0, -+ BRPS); - int ctx_cmps = -- FIELD_EX64(ahcf->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS); -+ FIELD_EX64(ahcf->isar.regs[ID_AA64DFR0], ID_AA64DFR0, -+ CTX_CMPS); - int version = 6; /* ARMv8 debug architecture */ - bool has_el3 = -- !!FIELD_EX32(ahcf->isar.id_aa64pfr0, ID_AA64PFR0, EL3); -+ !!FIELD_EX32(ahcf->isar.regs[ID_AA64PFR0], ID_AA64PFR0, EL3); - uint32_t dbgdidr = 0; - - dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, WRPS, wrps); -@@ -641,7 +644,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, NSUHD_IMP, has_el3); - dbgdidr = FIELD_DP32(dbgdidr, DBGDIDR, SE_IMP, has_el3); - dbgdidr |= (1 << 15); /* RES1 bit */ -- ahcf->isar.dbgdidr = dbgdidr; -+ ahcf->isar.regs[DBGDIDR] = dbgdidr; - } - } - -@@ -649,9 +652,9 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - - /* Add feature bits that can't appear until after VCPU init. */ - if (sve_supported) { -- t = ahcf->isar.id_aa64pfr0; -+ t = ahcf->isar.regs[ID_AA64PFR0]; - t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1); -- ahcf->isar.id_aa64pfr0 = t; -+ ahcf->isar.regs[ID_AA64PFR0] = t; - - /* - * Before v5.1, KVM did not support SVE and did not expose -@@ -659,7 +662,7 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) - * not expose the register to "user" requests like this - * unless the host supports SVE. - */ -- err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0, -+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.regs[ID_AA64ZFR0], - ARM64_SYS_REG(3, 0, 0, 4, 4)); - } - --- -2.27.0 - diff --git a/target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch b/target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch deleted file mode 100644 index edb4ea44c77e024c9104895c149040f364c11f79..0000000000000000000000000000000000000000 --- a/target-arm-ignore-evtstrm-and-cpuid-CPU-features.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 4558dc5590b89b1252baea2734c2b3668566e5cb Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Mon, 7 Sep 2020 14:07:07 +0800 -Subject: [PATCH] target/arm: ignore evtstrm and cpuid CPU features - -evtstrm and cpuid cann't be controlled by VMM: -1. evtstrm: The generic timer is configured to generate events at a - frequency of approximately 100KHz. It's controlled by the linux - kernel config CONFIG_ARM_ARCH_TIMER_EVTSTREAM. -2. cpuid: EL0 access to certain ID registers is available. It's always - set by linux kernel after 77c97b4ee2129 ("arm64: cpufeature: Expose - CPUID registers by emulation"). -However, they are exposed by getauxval() and /proc/cpuinfo. Hence, -let's report and ignore the CPU features if someone set them. - -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/cpu64.c | 29 ++++++++++++++++++++++++++++- - 1 file changed, 28 insertions(+), 1 deletion(-) - -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 9e5179afbe..287e7ac91c 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -982,10 +982,37 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs) - return g_strdup("aarch64"); - } - -+static const char *unconfigurable_feats[] = { -+ "evtstrm", -+ "cpuid", -+ NULL -+}; -+ -+static bool is_configurable_feat(const char *name) -+{ -+ int i; -+ -+ for (i = 0; unconfigurable_feats[i]; ++i) { -+ if (g_strcmp0(unconfigurable_feats[i], name) == 0) { -+ return false; -+ } -+ } -+ -+ return true; -+} -+ - static void - cpu_add_feat_as_prop(const char *typename, const char *name, const char *val) - { -- GlobalProperty *prop = g_new0(typeof(*prop), 1); -+ GlobalProperty *prop; -+ -+ if (!is_configurable_feat(name)) { -+ info_report("CPU feature '%s' is not configurable by QEMU. Ignore it.", -+ name); -+ return; -+ } -+ -+ prop = g_new0(typeof(*prop), 1); - prop->driver = typename; - prop->property = g_strdup(name); - prop->value = g_strdup(val); --- -2.27.0 - diff --git a/target-arm-introduce-CPU-feature-dependency-mechanis.patch b/target-arm-introduce-CPU-feature-dependency-mechanis.patch deleted file mode 100644 index aecfbf8991d1fc259c2efe06cf4a32bec39ac1e0..0000000000000000000000000000000000000000 --- a/target-arm-introduce-CPU-feature-dependency-mechanis.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 632d58d1b908ee979074b589417f446c0a3be35d Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Thu, 6 Aug 2020 16:14:46 +0800 -Subject: [PATCH] target/arm: introduce CPU feature dependency mechanism - -Some CPU features are dependent on other CPU features. For example, -ID_AA64PFR0_EL1.FP field and ID_AA64PFR0_EL1.AdvSIMD must have the same -value, which means FP and ADVSIMD are dependent on each other, FPHP and -ADVSIMDHP are dependent on each other. - -This commit introduces a mechanism for CPU feature dependency in -AArch64. We build a directed graph from the CPU feature dependency -relationship, each edge from->to means the `to` CPU feature is dependent -on the `from` CPU feature. And we will automatically enable/disable CPU -feature according to the directed graph. - -For example, a, b, and c CPU features are in relationship a->b->c, which -means c is dependent on b and b is dependent on a. If c is enabled by -user, then a and b is enabled automatically. And if a is disabled by -user, then b and c is disabled automatically. - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/cpu.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 129 insertions(+) - -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index c081ecc12b..ee09642dae 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -1483,6 +1483,103 @@ static struct CPUFeatureInfo cpu_features[] = { - }, - }; - -+typedef struct CPUFeatureDep { -+ CPUFeatureInfo from, to; -+} CPUFeatureDep; -+ -+static const CPUFeatureDep feature_dependencies[] = { -+ { -+ .from = FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false), -+ .to = FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false), -+ }, -+ { -+ .from = FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false), -+ .to = FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false), -+ }, -+ { -+ .from = { -+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH, -+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1, -+ .ni_value = 0, .name = "fphp", .is_32bit = false, -+ }, -+ .to = { -+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH, -+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1, -+ .ni_value = 0, .name = "asimdhp", .is_32bit = false, -+ }, -+ }, -+ { -+ .from = { -+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH, -+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1, -+ .ni_value = 0, .name = "asimdhp", .is_32bit = false, -+ }, -+ .to = { -+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH, -+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1, -+ .ni_value = 0, .name = "fphp", .is_32bit = false, -+ }, -+ }, -+ { -+ -+ .from = FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false), -+ .to = { -+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH, -+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "pmull", .is_32bit = false, -+ }, -+ }, -+ { -+ -+ .from = FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false), -+ .to = { -+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH, -+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "sha512", .is_32bit = false, -+ }, -+ }, -+ { -+ .from = FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false), -+ .to = { -+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH, -+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false, -+ }, -+ }, -+ { -+ .from = FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false), -+ .to = FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false), -+ }, -+ { -+ .from = FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false), -+ .to = FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false), -+ }, -+ { -+ .from = FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false), -+ .to = FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false), -+ }, -+ { -+ .from = FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false), -+ .to = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false), -+ }, -+ { -+ .from = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false), -+ .to = { -+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH, -+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "sha512", .is_32bit = false, -+ }, -+ }, -+ { -+ .from = { -+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH, -+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "sha512", .is_32bit = false, -+ }, -+ .to = FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false), -+ }, -+}; -+ - static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) - { -@@ -1519,13 +1616,45 @@ static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name, - } - - if (value) { -+ if (object_property_get_bool(obj, feat->name, NULL)) { -+ return; -+ } - isar->regs[feat->reg] = deposit64(isar->regs[feat->reg], - feat->shift, feat->length, - feat->min_value); -+ /* Auto enable the features which current feature is dependent on. */ -+ for (int i = 0; i < ARRAY_SIZE(feature_dependencies); ++i) { -+ const CPUFeatureDep *d = &feature_dependencies[i]; -+ if (strcmp(d->to.name, feat->name) != 0) { -+ continue; -+ } -+ -+ object_property_set_bool(obj, d->from.name, true, &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return; -+ } -+ } - } else { -+ if (!object_property_get_bool(obj, feat->name, NULL)) { -+ return; -+ } - isar->regs[feat->reg] = deposit64(isar->regs[feat->reg], - feat->shift, feat->length, - feat->ni_value); -+ /* Auto disable the features which are dependent on current feature. */ -+ for (int i = 0; i < ARRAY_SIZE(feature_dependencies); ++i) { -+ const CPUFeatureDep *d = &feature_dependencies[i]; -+ if (strcmp(d->from.name, feat->name) != 0) { -+ continue; -+ } -+ -+ object_property_set_bool(obj, d->to.name, false, &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return; -+ } -+ } - } - } - --- -2.27.0 - diff --git a/target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch b/target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch deleted file mode 100644 index d5bc0e88ed89005c6d4cf66d4c90eafb314bc048..0000000000000000000000000000000000000000 --- a/target-arm-introduce-KVM_CAP_ARM_CPU_FEATURE.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 536aa9ecc3cb25c81c2df56230c690257189d4ef Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Thu, 6 Aug 2020 16:14:55 +0800 -Subject: [PATCH] target/arm: introduce KVM_CAP_ARM_CPU_FEATURE - -Introduce KVM_CAP_ARM_CPU_FEATURE to check whether KVM supports to set -CPU features in ARM. - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - linux-headers/linux/kvm.h | 2 ++ - target/arm/cpu.c | 5 +++++ - target/arm/kvm64.c | 14 ++++++++++++++ - target/arm/kvm_arm.h | 7 +++++++ - 4 files changed, 28 insertions(+) - -diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h -index bcaf66cc4d..5d8e42b8f8 100644 ---- a/linux-headers/linux/kvm.h -+++ b/linux-headers/linux/kvm.h -@@ -1113,6 +1113,8 @@ struct kvm_ppc_resize_hpt { - #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204 - #define KVM_CAP_ARM_MTE 205 - -+#define KVM_CAP_ARM_CPU_FEATURE 555 -+ - #ifdef KVM_CAP_IRQ_ROUTING - - struct kvm_irq_routing_irqchip { -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index ee09642dae..3024f4a3f5 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -1604,6 +1604,11 @@ static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name, - Error *local_err = NULL; - bool value; - -+ if (!kvm_arm_cpu_feature_supported()) { -+ warn_report("KVM doesn't support to set CPU feature in arm. " -+ "Setting to `%s` is ignored.", name); -+ return; -+ } - if (dev->realized) { - qdev_prop_set_after_realize(dev, name, errp); - return; -diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c -index 4f97e516c2..b34a87fd24 100644 ---- a/target/arm/kvm64.c -+++ b/target/arm/kvm64.c -@@ -827,6 +827,20 @@ static int kvm_arm_sve_set_vls(CPUState *cs) - return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); - } - -+bool kvm_arm_cpu_feature_supported(void) -+{ -+ static bool cpu_feature_initialized; -+ static bool cpu_feature_supported; -+ -+ if (!cpu_feature_initialized) { -+ cpu_feature_supported = kvm_check_extension(kvm_state, -+ KVM_CAP_ARM_CPU_FEATURE); -+ cpu_feature_initialized = true; -+ } -+ -+ return cpu_feature_supported; -+} -+ - #define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5 - - int kvm_arch_init_vcpu(CPUState *cs) -diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h -index f8e0e64363..82145607ec 100644 ---- a/target/arm/kvm_arm.h -+++ b/target/arm/kvm_arm.h -@@ -306,6 +306,13 @@ bool kvm_arm_pmu_supported(void); - */ - bool kvm_arm_sve_supported(void); - -+/** -+ * kvm_arm_cpu_feature_supported: -+ * -+ * Returns true if KVM can set CPU features and false otherwise. -+ */ -+bool kvm_arm_cpu_feature_supported(void); -+ - /** - * kvm_arm_get_max_vm_ipa_size: - * @ms: Machine state handle --- -2.27.0 - diff --git a/target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch b/target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch deleted file mode 100644 index a9be076ecc13826d1f57e1fcd525721cee216342..0000000000000000000000000000000000000000 --- a/target-arm-only-set-ID_PFR1_EL1.GIC-for-AArch32-gues.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3371917ea92265377f87692a717397267416c4aa Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Wed, 16 Sep 2020 19:40:28 +0800 -Subject: [PATCH] target/arm: only set ID_PFR1_EL1.GIC for AArch32 guest - -Some AArch64 CPU doesn't support AArch32 mode, and the values of AArch32 -registers are all 0. Hence, We'd better not to modify AArch32 registers -in AArch64 mode. - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/helper.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/arm/helper.c b/target/arm/helper.c -index 79f77705c3..4c7b4cadfa 100644 ---- a/target/arm/helper.c -+++ b/target/arm/helper.c -@@ -6718,7 +6718,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri) - ARMCPU *cpu = env_archcpu(env); - uint64_t pfr1 = cpu->isar.regs[ID_PFR1]; - -- if (env->gicv3state) { -+ if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && env->gicv3state) { - pfr1 |= 1 << 28; - } - return pfr1; --- -2.27.0 - diff --git a/target-arm-parse-cpu-feature-related-options.patch b/target-arm-parse-cpu-feature-related-options.patch deleted file mode 100644 index b90027bc6316da9de2144979f3af20cc6fdf7777..0000000000000000000000000000000000000000 --- a/target-arm-parse-cpu-feature-related-options.patch +++ /dev/null @@ -1,125 +0,0 @@ -From abd51f8d46b916efb37cb2c8face176bc83c0d5d Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Thu, 6 Aug 2020 16:14:35 +0800 -Subject: [PATCH] target/arm: parse cpu feature related options - -The implementation of CPUClass::parse_features only supports CPU -features in "feature=value" format. However, libvirt maybe send us a -CPU feature string in "+feature/-feature" format. Hence, we need to -override CPUClass::parse_features to support CPU feature string in both -"feature=value" and "+feature/-feature" format. - -The logic of AArch64CPUClass::parse_features is similar to that of -X86CPUClass::parse_features. - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/cpu64.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 83 insertions(+) - -diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c -index 96a49a3158..9e5179afbe 100644 ---- a/target/arm/cpu64.c -+++ b/target/arm/cpu64.c -@@ -982,6 +982,88 @@ static gchar *aarch64_gdb_arch_name(CPUState *cs) - return g_strdup("aarch64"); - } - -+static void -+cpu_add_feat_as_prop(const char *typename, const char *name, const char *val) -+{ -+ GlobalProperty *prop = g_new0(typeof(*prop), 1); -+ prop->driver = typename; -+ prop->property = g_strdup(name); -+ prop->value = g_strdup(val); -+ qdev_prop_register_global(prop); -+} -+ -+static gint compare_string(gconstpointer a, gconstpointer b) -+{ -+ return g_strcmp0(a, b); -+} -+ -+static GList *plus_features, *minus_features; -+ -+static void aarch64_cpu_parse_features(const char *typename, char *features, -+ Error **errp) -+{ -+ GList *l; -+ char *featurestr; /* Single 'key=value" string being parsed */ -+ static bool cpu_globals_initialized; -+ -+ if (cpu_globals_initialized) { -+ return; -+ } -+ cpu_globals_initialized = true; -+ -+ if (!features) { -+ return; -+ } -+ for (featurestr = strtok(features, ","); -+ featurestr; -+ featurestr = strtok(NULL, ",")) { -+ const char *name; -+ const char *val = NULL; -+ char *eq = NULL; -+ -+ /* Compatibility syntax: */ -+ if (featurestr[0] == '+') { -+ plus_features = g_list_append(plus_features, -+ g_strdup(featurestr + 1)); -+ continue; -+ } else if (featurestr[0] == '-') { -+ minus_features = g_list_append(minus_features, -+ g_strdup(featurestr + 1)); -+ continue; -+ } -+ -+ eq = strchr(featurestr, '='); -+ name = featurestr; -+ if (eq) { -+ *eq++ = 0; -+ val = eq; -+ } else { -+ error_setg(errp, "Unsupported property format: %s", name); -+ return; -+ } -+ -+ if (g_list_find_custom(plus_features, name, compare_string)) { -+ warn_report("Ambiguous CPU model string. " -+ "Don't mix both \"+%s\" and \"%s=%s\"", -+ name, name, val); -+ } -+ if (g_list_find_custom(minus_features, name, compare_string)) { -+ warn_report("Ambiguous CPU model string. " -+ "Don't mix both \"-%s\" and \"%s=%s\"", -+ name, name, val); -+ } -+ cpu_add_feat_as_prop(typename, name, val); -+ } -+ -+ for (l = plus_features; l; l = l->next) { -+ cpu_add_feat_as_prop(typename, l->data, "on"); -+ } -+ -+ for (l = minus_features; l; l = l->next) { -+ cpu_add_feat_as_prop(typename, l->data, "off"); -+ } -+} -+ - static void aarch64_cpu_class_init(ObjectClass *oc, void *data) - { - CPUClass *cc = CPU_CLASS(oc); -@@ -991,6 +1073,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data) - cc->gdb_num_core_regs = 34; - cc->gdb_core_xml_file = "aarch64-core.xml"; - cc->gdb_arch_name = aarch64_gdb_arch_name; -+ cc->parse_features = aarch64_cpu_parse_features; - - object_class_property_add_bool(oc, "aarch64", aarch64_cpu_get_aarch64, - aarch64_cpu_set_aarch64); --- -2.27.0 - diff --git a/target-arm-register-CPU-features-for-property.patch b/target-arm-register-CPU-features-for-property.patch deleted file mode 100644 index 3d60d68c8cd96cca6e8c22d212b81f2c8378a637..0000000000000000000000000000000000000000 --- a/target-arm-register-CPU-features-for-property.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 9fd09aabba558b39ca949ef376d05bc0779fdda6 Mon Sep 17 00:00:00 2001 -From: Peng Liang -Date: Thu, 6 Aug 2020 16:14:37 +0800 -Subject: [PATCH] target/arm: register CPU features for property - -The Arm architecture specifies a number of ID registers that are -characterized as comprising a set of 4-bit ID fields. Each ID field -identifies the presence, and possibly the level of support for, a -particular feature in an implementation of the architecture. [1] - -For most of the ID fields, there is a minimum presence value, equal to -or higher than which means the corresponding CPU feature is implemented. -Hence, we can use the minimum presence value to determine whether a CPU -feature is enabled and enable a CPU feature. - -To disable a CPU feature, setting the corresponding ID field to 0x0/0xf -(for unsigned/signed field) seems as a good idea. However, it maybe -lead to some problems. For example, ID_AA64PFR0_EL1.FP is a signed ID -field. ID_AA64PFR0_EL1.FP == 0x0 represents the implementation of FP -(floating-point) and ID_AA64PFR0_EL1.FP == 0x1 represents the -implementation of FPHP (half-precision floating-point). If -ID_AA64PFR0_EL1.FP is set to 0xf when FPHP is disabled (which is also -disable FP), guest kernel maybe stuck. Hence, we add a ni_value (means -not-implemented value) to disable a CPU feature safely. - -[1] D13.1.3 Principles of the ID scheme for fields in ID registers in - DDI.0487 - -Signed-off-by: zhanghailiang -Signed-off-by: Peng Liang -Signed-off-by: Dongxu Sun ---- - target/arm/cpu.c | 343 +++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 343 insertions(+) - -diff --git a/target/arm/cpu.c b/target/arm/cpu.c -index f1ce0474a3..c081ecc12b 100644 ---- a/target/arm/cpu.c -+++ b/target/arm/cpu.c -@@ -1211,6 +1211,347 @@ unsigned int gt_cntfrq_period_ns(ARMCPU *cpu) - NANOSECONDS_PER_SECOND / cpu->gt_cntfrq_hz : 1; - } - -+/** -+ * CPUFeatureInfo: -+ * @reg: The ID register where the ID field is in. -+ * @name: The name of the CPU feature. -+ * @length: The bit length of the ID field. -+ * @shift: The bit shift of the ID field in the ID register. -+ * @min_value: The minimum value equal to or larger than which means the CPU -+ * feature is implemented. -+ * @ni_value: Not-implemented value. It will be set to the ID field when -+ * disabling the CPU feature. Usually, it's min_value - 1. -+ * @sign: Whether the ID field is signed. -+ * @is_32bit: Whether the CPU feature is for 32-bit. -+ * -+ * In ARM, a CPU feature is described by an ID field, which is a 4-bit field in -+ * an ID register. -+ */ -+typedef struct CPUFeatureInfo { -+ CPUIDReg reg; -+ const char *name; -+ int length; -+ int shift; -+ int min_value; -+ int ni_value; -+ bool sign; -+ bool is_32bit; -+} CPUFeatureInfo; -+ -+#define FIELD_INFO(feature_name, id_reg, field, s, min_val, ni_val, is32bit) { \ -+ .reg = id_reg, \ -+ .length = R_ ## id_reg ## _ ## field ## _LENGTH, \ -+ .shift = R_ ## id_reg ## _ ## field ## _SHIFT, \ -+ .sign = s, \ -+ .min_value = min_val, \ -+ .ni_value = ni_val, \ -+ .name = feature_name, \ -+ .is_32bit = is32bit, \ -+} -+ -+static struct CPUFeatureInfo cpu_features[] = { -+ FIELD_INFO("swap", ID_ISAR0, SWAP, false, 1, 0, true), -+ FIELD_INFO("bitcount", ID_ISAR0, BITCOUNT, false, 1, 0, true), -+ FIELD_INFO("bitfield", ID_ISAR0, BITFIELD, false, 1, 0, true), -+ FIELD_INFO("cmpbranch", ID_ISAR0, CMPBRANCH, false, 1, 0, true), -+ FIELD_INFO("coproc", ID_ISAR0, COPROC, false, 1, 0, true), -+ FIELD_INFO("debug", ID_ISAR0, DEBUG, false, 1, 0, true), -+ FIELD_INFO("device", ID_ISAR0, DIVIDE, false, 1, 0, true), -+ -+ FIELD_INFO("endian", ID_ISAR1, ENDIAN, false, 1, 0, true), -+ FIELD_INFO("except", ID_ISAR1, EXCEPT, false, 1, 0, true), -+ FIELD_INFO("except_ar", ID_ISAR1, EXCEPT_AR, false, 1, 0, true), -+ FIELD_INFO("extend", ID_ISAR1, EXTEND, false, 1, 0, true), -+ FIELD_INFO("ifthen", ID_ISAR1, IFTHEN, false, 1, 0, true), -+ FIELD_INFO("immediate", ID_ISAR1, IMMEDIATE, false, 1, 0, true), -+ FIELD_INFO("interwork", ID_ISAR1, INTERWORK, false, 1, 0, true), -+ FIELD_INFO("jazelle", ID_ISAR1, JAZELLE, false, 1, 0, true), -+ -+ FIELD_INFO("loadstore", ID_ISAR2, LOADSTORE, false, 1, 0, true), -+ FIELD_INFO("memhint", ID_ISAR2, MEMHINT, false, 1, 0, true), -+ FIELD_INFO("multiaccessint", ID_ISAR2, MULTIACCESSINT, false, 1, 0, true), -+ FIELD_INFO("mult", ID_ISAR2, MULT, false, 1, 0, true), -+ FIELD_INFO("mults", ID_ISAR2, MULTS, false, 1, 0, true), -+ FIELD_INFO("multu", ID_ISAR2, MULTU, false, 1, 0, true), -+ FIELD_INFO("psr_ar", ID_ISAR2, PSR_AR, false, 1, 0, true), -+ FIELD_INFO("reversal", ID_ISAR2, REVERSAL, false, 1, 0, true), -+ -+ FIELD_INFO("saturate", ID_ISAR3, SATURATE, false, 1, 0, true), -+ FIELD_INFO("simd", ID_ISAR3, SIMD, false, 1, 0, true), -+ FIELD_INFO("svc", ID_ISAR3, SVC, false, 1, 0, true), -+ FIELD_INFO("synchprim", ID_ISAR3, SYNCHPRIM, false, 1, 0, true), -+ FIELD_INFO("tabbranch", ID_ISAR3, TABBRANCH, false, 1, 0, true), -+ FIELD_INFO("t32copy", ID_ISAR3, T32COPY, false, 1, 0, true), -+ FIELD_INFO("truenop", ID_ISAR3, TRUENOP, false, 1, 0, true), -+ FIELD_INFO("t32ee", ID_ISAR3, T32EE, false, 1, 0, true), -+ -+ FIELD_INFO("unpriv", ID_ISAR4, UNPRIV, false, 1, 0, true), -+ FIELD_INFO("withshifts", ID_ISAR4, WITHSHIFTS, false, 1, 0, true), -+ FIELD_INFO("writeback", ID_ISAR4, WRITEBACK, false, 1, 0, true), -+ FIELD_INFO("smc", ID_ISAR4, SMC, false, 1, 0, true), -+ FIELD_INFO("barrier", ID_ISAR4, BARRIER, false, 1, 0, true), -+ FIELD_INFO("synchprim_frac", ID_ISAR4, SYNCHPRIM_FRAC, false, 1, 0, true), -+ FIELD_INFO("psr_m", ID_ISAR4, PSR_M, false, 1, 0, true), -+ FIELD_INFO("swp_frac", ID_ISAR4, SWP_FRAC, false, 1, 0, true), -+ -+ FIELD_INFO("sevl", ID_ISAR5, SEVL, false, 1, 0, true), -+ FIELD_INFO("aes", ID_ISAR5, AES, false, 1, 0, true), -+ FIELD_INFO("sha1", ID_ISAR5, SHA1, false, 1, 0, true), -+ FIELD_INFO("sha2", ID_ISAR5, SHA2, false, 1, 0, true), -+ FIELD_INFO("crc32", ID_ISAR5, CRC32, false, 1, 0, true), -+ FIELD_INFO("rdm", ID_ISAR5, RDM, false, 1, 0, true), -+ FIELD_INFO("vcma", ID_ISAR5, VCMA, false, 1, 0, true), -+ -+ FIELD_INFO("jscvt", ID_ISAR6, JSCVT, false, 1, 0, true), -+ FIELD_INFO("dp", ID_ISAR6, DP, false, 1, 0, true), -+ FIELD_INFO("fhm", ID_ISAR6, FHM, false, 1, 0, true), -+ FIELD_INFO("sb", ID_ISAR6, SB, false, 1, 0, true), -+ FIELD_INFO("specres", ID_ISAR6, SPECRES, false, 1, 0, true), -+ -+ FIELD_INFO("cmaintva", ID_MMFR3, CMAINTVA, false, 1, 0, true), -+ FIELD_INFO("cmaintsw", ID_MMFR3, CMAINTSW, false, 1, 0, true), -+ FIELD_INFO("bpmaint", ID_MMFR3, BPMAINT, false, 1, 0, true), -+ FIELD_INFO("maintbcst", ID_MMFR3, MAINTBCST, false, 1, 0, true), -+ FIELD_INFO("pan", ID_MMFR3, PAN, false, 1, 0, true), -+ FIELD_INFO("cohwalk", ID_MMFR3, COHWALK, false, 1, 0, true), -+ FIELD_INFO("cmemsz", ID_MMFR3, CMEMSZ, false, 1, 0, true), -+ FIELD_INFO("supersec", ID_MMFR3, SUPERSEC, false, 1, 0, true), -+ -+ FIELD_INFO("specsei", ID_MMFR4, SPECSEI, false, 1, 0, true), -+ FIELD_INFO("ac2", ID_MMFR4, AC2, false, 1, 0, true), -+ FIELD_INFO("xnx", ID_MMFR4, XNX, false, 1, 0, true), -+ FIELD_INFO("cnp", ID_MMFR4, CNP, false, 1, 0, true), -+ FIELD_INFO("hpds", ID_MMFR4, HPDS, false, 1, 0, true), -+ FIELD_INFO("lsm", ID_MMFR4, LSM, false, 1, 0, true), -+ FIELD_INFO("ccidx", ID_MMFR4, CCIDX, false, 1, 0, true), -+ FIELD_INFO("evt", ID_MMFR4, EVT, false, 1, 0, true), -+ -+ FIELD_INFO("simdreg", MVFR0, SIMDREG, false, 1, 0, true), -+ FIELD_INFO("fpsp", MVFR0, FPSP, false, 1, 0, true), -+ FIELD_INFO("fpdp", MVFR0, FPDP, false, 1, 0, true), -+ FIELD_INFO("fptrap", MVFR0, FPTRAP, false, 1, 0, true), -+ FIELD_INFO("fpdivide", MVFR0, FPDIVIDE, false, 1, 0, true), -+ FIELD_INFO("fpsqrt", MVFR0, FPSQRT, false, 1, 0, true), -+ FIELD_INFO("fpshvec", MVFR0, FPSHVEC, false, 1, 0, true), -+ FIELD_INFO("fpround", MVFR0, FPROUND, false, 1, 0, true), -+ -+ FIELD_INFO("fpftz", MVFR1, FPFTZ, false, 1, 0, true), -+ FIELD_INFO("fpdnan", MVFR1, FPDNAN, false, 1, 0, true), -+ FIELD_INFO("simdls", MVFR1, SIMDLS, false, 1, 0, true), -+ FIELD_INFO("simdint", MVFR1, SIMDINT, false, 1, 0, true), -+ FIELD_INFO("simdsp", MVFR1, SIMDSP, false, 1, 0, true), -+ FIELD_INFO("simdhp", MVFR1, SIMDHP, false, 1, 0, true), -+ FIELD_INFO("fphp", MVFR1, FPHP, false, 1, 0, true), -+ FIELD_INFO("simdfmac", MVFR1, SIMDFMAC, false, 1, 0, true), -+ -+ FIELD_INFO("simdmisc", MVFR2, SIMDMISC, false, 1, 0, true), -+ FIELD_INFO("fpmisc", MVFR2, FPMISC, false, 1, 0, true), -+ -+ FIELD_INFO("debugver", ID_AA64DFR0, DEBUGVER, false, 1, 0, false), -+ FIELD_INFO("tracever", ID_AA64DFR0, TRACEVER, false, 1, 0, false), -+ FIELD_INFO("pmuver", ID_AA64DFR0, PMUVER, false, 1, 0, false), -+ FIELD_INFO("brps", ID_AA64DFR0, BRPS, false, 1, 0, false), -+ FIELD_INFO("wrps", ID_AA64DFR0, WRPS, false, 1, 0, false), -+ FIELD_INFO("ctx_cmps", ID_AA64DFR0, CTX_CMPS, false, 1, 0, false), -+ FIELD_INFO("pmsver", ID_AA64DFR0, PMSVER, false, 1, 0, false), -+ FIELD_INFO("doublelock", ID_AA64DFR0, DOUBLELOCK, false, 1, 0, false), -+ FIELD_INFO("tracefilt", ID_AA64DFR0, TRACEFILT, false, 1, 0, false), -+ -+ FIELD_INFO("aes", ID_AA64ISAR0, AES, false, 1, 0, false), -+ FIELD_INFO("sha1", ID_AA64ISAR0, SHA1, false, 1, 0, false), -+ FIELD_INFO("sha2", ID_AA64ISAR0, SHA2, false, 1, 0, false), -+ FIELD_INFO("crc32", ID_AA64ISAR0, CRC32, false, 1, 0, false), -+ FIELD_INFO("atomics", ID_AA64ISAR0, ATOMIC, false, 1, 0, false), -+ FIELD_INFO("asimdrdm", ID_AA64ISAR0, RDM, false, 1, 0, false), -+ FIELD_INFO("sha3", ID_AA64ISAR0, SHA3, false, 1, 0, false), -+ FIELD_INFO("sm3", ID_AA64ISAR0, SM3, false, 1, 0, false), -+ FIELD_INFO("sm4", ID_AA64ISAR0, SM4, false, 1, 0, false), -+ FIELD_INFO("asimddp", ID_AA64ISAR0, DP, false, 1, 0, false), -+ FIELD_INFO("asimdfhm", ID_AA64ISAR0, FHM, false, 1, 0, false), -+ FIELD_INFO("flagm", ID_AA64ISAR0, TS, false, 1, 0, false), -+ FIELD_INFO("tlb", ID_AA64ISAR0, TLB, false, 1, 0, false), -+ FIELD_INFO("rng", ID_AA64ISAR0, RNDR, false, 1, 0, false), -+ -+ FIELD_INFO("dcpop", ID_AA64ISAR1, DPB, false, 1, 0, false), -+ FIELD_INFO("papa", ID_AA64ISAR1, APA, false, 1, 0, false), -+ FIELD_INFO("api", ID_AA64ISAR1, API, false, 1, 0, false), -+ FIELD_INFO("jscvt", ID_AA64ISAR1, JSCVT, false, 1, 0, false), -+ FIELD_INFO("fcma", ID_AA64ISAR1, FCMA, false, 1, 0, false), -+ FIELD_INFO("lrcpc", ID_AA64ISAR1, LRCPC, false, 1, 0, false), -+ FIELD_INFO("pacg", ID_AA64ISAR1, GPA, false, 1, 0, false), -+ FIELD_INFO("gpi", ID_AA64ISAR1, GPI, false, 1, 0, false), -+ FIELD_INFO("frint", ID_AA64ISAR1, FRINTTS, false, 1, 0, false), -+ FIELD_INFO("sb", ID_AA64ISAR1, SB, false, 1, 0, false), -+ FIELD_INFO("specres", ID_AA64ISAR1, SPECRES, false, 1, 0, false), -+ -+ FIELD_INFO("el0", ID_AA64PFR0, EL0, false, 1, 0, false), -+ FIELD_INFO("el1", ID_AA64PFR0, EL1, false, 1, 0, false), -+ FIELD_INFO("el2", ID_AA64PFR0, EL2, false, 1, 0, false), -+ FIELD_INFO("el3", ID_AA64PFR0, EL3, false, 1, 0, false), -+ FIELD_INFO("fp", ID_AA64PFR0, FP, true, 0, 0xf, false), -+ FIELD_INFO("asimd", ID_AA64PFR0, ADVSIMD, true, 0, 0xf, false), -+ FIELD_INFO("gic", ID_AA64PFR0, GIC, false, 1, 0, false), -+ FIELD_INFO("ras", ID_AA64PFR0, RAS, false, 1, 0, false), -+ FIELD_INFO("sve", ID_AA64PFR0, SVE, false, 1, 0, false), -+ -+ FIELD_INFO("bti", ID_AA64PFR1, BT, false, 1, 0, false), -+ FIELD_INFO("ssbs", ID_AA64PFR1, SSBS, false, 1, 0, false), -+ FIELD_INFO("mte", ID_AA64PFR1, MTE, false, 1, 0, false), -+ FIELD_INFO("ras_frac", ID_AA64PFR1, RAS_FRAC, false, 1, 0, false), -+ -+ FIELD_INFO("parange", ID_AA64MMFR0, PARANGE, false, 1, 0, false), -+ FIELD_INFO("asidbits", ID_AA64MMFR0, ASIDBITS, false, 1, 0, false), -+ FIELD_INFO("bigend", ID_AA64MMFR0, BIGEND, false, 1, 0, false), -+ FIELD_INFO("snsmem", ID_AA64MMFR0, SNSMEM, false, 1, 0, false), -+ FIELD_INFO("bigendel0", ID_AA64MMFR0, BIGENDEL0, false, 1, 0, false), -+ FIELD_INFO("tgran16", ID_AA64MMFR0, TGRAN16, false, 1, 0, false), -+ FIELD_INFO("tgran64", ID_AA64MMFR0, TGRAN64, false, 1, 0, false), -+ FIELD_INFO("tgran4", ID_AA64MMFR0, TGRAN4, false, 1, 0, false), -+ FIELD_INFO("tgran16_2", ID_AA64MMFR0, TGRAN16_2, false, 1, 0, false), -+ FIELD_INFO("tgran64_2", ID_AA64MMFR0, TGRAN64_2, false, 1, 0, false), -+ FIELD_INFO("tgran4_2", ID_AA64MMFR0, TGRAN4_2, false, 1, 0, false), -+ FIELD_INFO("exs", ID_AA64MMFR0, EXS, false, 1, 0, false), -+ -+ FIELD_INFO("hafdbs", ID_AA64MMFR1, HAFDBS, false, 1, 0, false), -+ FIELD_INFO("vmidbits", ID_AA64MMFR1, VMIDBITS, false, 1, 0, false), -+ FIELD_INFO("vh", ID_AA64MMFR1, VH, false, 1, 0, false), -+ FIELD_INFO("hpds", ID_AA64MMFR1, HPDS, false, 1, 0, false), -+ FIELD_INFO("lo", ID_AA64MMFR1, LO, false, 1, 0, false), -+ FIELD_INFO("pan", ID_AA64MMFR1, PAN, false, 1, 0, false), -+ FIELD_INFO("specsei", ID_AA64MMFR1, SPECSEI, false, 1, 0, false), -+ FIELD_INFO("xnx", ID_AA64MMFR1, XNX, false, 1, 0, false), -+ -+ FIELD_INFO("cnp", ID_AA64MMFR2, CNP, false, 1, 0, false), -+ FIELD_INFO("uao", ID_AA64MMFR2, UAO, false, 1, 0, false), -+ FIELD_INFO("lsm", ID_AA64MMFR2, LSM, false, 1, 0, false), -+ FIELD_INFO("iesb", ID_AA64MMFR2, IESB, false, 1, 0, false), -+ FIELD_INFO("varange", ID_AA64MMFR2, VARANGE, false, 1, 0, false), -+ FIELD_INFO("ccidx", ID_AA64MMFR2, CCIDX, false, 1, 0, false), -+ FIELD_INFO("nv", ID_AA64MMFR2, NV, false, 1, 0, false), -+ FIELD_INFO("st", ID_AA64MMFR2, ST, false, 1, 0, false), -+ FIELD_INFO("uscat", ID_AA64MMFR2, AT, false, 1, 0, false), -+ FIELD_INFO("ids", ID_AA64MMFR2, IDS, false, 1, 0, false), -+ FIELD_INFO("fwb", ID_AA64MMFR2, FWB, false, 1, 0, false), -+ FIELD_INFO("ttl", ID_AA64MMFR2, TTL, false, 1, 0, false), -+ FIELD_INFO("bbm", ID_AA64MMFR2, BBM, false, 1, 0, false), -+ FIELD_INFO("evt", ID_AA64MMFR2, EVT, false, 1, 0, false), -+ FIELD_INFO("e0pd", ID_AA64MMFR2, E0PD, false, 1, 0, false), -+ -+ FIELD_INFO("copdbg", ID_DFR0, COPDBG, false, 1, 0, false), -+ FIELD_INFO("copsdbg", ID_DFR0, COPSDBG, false, 1, 0, false), -+ FIELD_INFO("mmapdbg", ID_DFR0, MMAPDBG, false, 1, 0, false), -+ FIELD_INFO("coptrc", ID_DFR0, COPTRC, false, 1, 0, false), -+ FIELD_INFO("mmaptrc", ID_DFR0, MMAPTRC, false, 1, 0, false), -+ FIELD_INFO("mprofdbg", ID_DFR0, MPROFDBG, false, 1, 0, false), -+ FIELD_INFO("perfmon", ID_DFR0, PERFMON, false, 1, 0, false), -+ FIELD_INFO("tracefilt", ID_DFR0, TRACEFILT, false, 1, 0, false), -+ -+ { -+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_FP_LENGTH, -+ .shift = R_ID_AA64PFR0_FP_SHIFT, .sign = true, .min_value = 1, -+ .ni_value = 0, .name = "fphp", .is_32bit = false, -+ }, -+ { -+ .reg = ID_AA64PFR0, .length = R_ID_AA64PFR0_ADVSIMD_LENGTH, -+ .shift = R_ID_AA64PFR0_ADVSIMD_SHIFT, .sign = true, .min_value = 1, -+ .ni_value = 0, .name = "asimdhp", .is_32bit = false, -+ }, -+ { -+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_AES_LENGTH, -+ .shift = R_ID_AA64ISAR0_AES_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "pmull", .is_32bit = false, -+ }, -+ { -+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_SHA2_LENGTH, -+ .shift = R_ID_AA64ISAR0_SHA2_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "sha512", .is_32bit = false, -+ }, -+ { -+ .reg = ID_AA64ISAR0, .length = R_ID_AA64ISAR0_TS_LENGTH, -+ .shift = R_ID_AA64ISAR0_TS_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "flagm2", .is_32bit = false, -+ }, -+ { -+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_DPB_LENGTH, -+ .shift = R_ID_AA64ISAR1_DPB_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "dcpodp", .is_32bit = false, -+ }, -+ { -+ .reg = ID_AA64ISAR1, .length = R_ID_AA64ISAR1_LRCPC_LENGTH, -+ .shift = R_ID_AA64ISAR1_LRCPC_SHIFT, .sign = false, .min_value = 2, -+ .ni_value = 1, .name = "ilrcpc", .is_32bit = false, -+ }, -+}; -+ -+static void arm_cpu_get_bit_prop(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ ARMCPU *cpu = ARM_CPU(obj); -+ CPUFeatureInfo *feat = opaque; -+ int field_value = feat->sign ? sextract64(cpu->isar.regs[feat->reg], -+ feat->shift, feat->length) : -+ extract64(cpu->isar.regs[feat->reg], -+ feat->shift, feat->length); -+ bool value = field_value >= feat->min_value; -+ -+ visit_type_bool(v, name, &value, errp); -+} -+ -+static void arm_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name, -+ void *opaque, Error **errp) -+{ -+ DeviceState *dev = DEVICE(obj); -+ ARMCPU *cpu = ARM_CPU(obj); -+ ARMISARegisters *isar = &cpu->isar; -+ CPUFeatureInfo *feat = opaque; -+ Error *local_err = NULL; -+ bool value; -+ -+ if (dev->realized) { -+ qdev_prop_set_after_realize(dev, name, errp); -+ return; -+ } -+ -+ visit_type_bool(v, name, &value, &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return; -+ } -+ -+ if (value) { -+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg], -+ feat->shift, feat->length, -+ feat->min_value); -+ } else { -+ isar->regs[feat->reg] = deposit64(isar->regs[feat->reg], -+ feat->shift, feat->length, -+ feat->ni_value); -+ } -+} -+ -+static void arm_cpu_register_feature_props(ARMCPU *cpu) -+{ -+ int i; -+ int num = ARRAY_SIZE(cpu_features); -+ ObjectProperty *op; -+ CPUARMState *env = &cpu->env; -+ -+ for (i = 0; i < num; i++) { -+ if ((arm_feature(env, ARM_FEATURE_AARCH64) && cpu_features[i].is_32bit) -+ || (!arm_feature(env, ARM_FEATURE_AARCH64) && -+ cpu_features[i].is_32bit)) { -+ continue; -+ } -+ op = object_property_find(OBJECT(cpu), cpu_features[i].name); -+ if (!op) { -+ object_property_add(OBJECT(cpu), cpu_features[i].name, "bool", -+ arm_cpu_get_bit_prop, -+ arm_cpu_set_bit_prop, -+ NULL, &cpu_features[i]); -+ } -+ } -+} -+ - void arm_cpu_post_init(Object *obj) - { - ARMCPU *cpu = ARM_CPU(obj); -@@ -1319,6 +1660,8 @@ void arm_cpu_post_init(Object *obj) - - qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property); - -+ arm_cpu_register_feature_props(cpu); -+ - if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) { - qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property); - } --- -2.27.0 - diff --git a/target-hppa-Fix-deposit-assert-from-trans_shrpw_imm.patch b/target-hppa-Fix-deposit-assert-from-trans_shrpw_imm.patch deleted file mode 100644 index ea5d8de6cd65aa554bc1c883c24a7e4118204df1..0000000000000000000000000000000000000000 --- a/target-hppa-Fix-deposit-assert-from-trans_shrpw_imm.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 8964f3516cab9ed0183407136aa9f0dae87c49e3 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 23 Nov 2022 15:38:38 -0800 -Subject: [PATCH 12/29] target/hppa: Fix deposit assert from trans_shrpw_imm -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mainline inclusion -commit 05bfd4db08608bc4c22de729780c1f74612fbc0e -category: bugfix - ----------------------------------------------- - -Because sa may be 0, - - tcg_gen_deposit_reg(dest, t0, cpu_gr[a->r1], 32 - sa, sa); - -may attempt a zero-width deposit at bit 32, which will assert -for TARGET_REGISTER_BITS == 32. - -Use the newer extract2 when possible, which itself includes the -rotri special case; otherwise mirror the code from trans_shrpw_sar, -using concat and shri. - -Cc: qemu-stable@nongnu.org -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/635 -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Richard Henderson - -Signed-off-by: tangbinzy ---- - target/hppa/translate.c | 19 ++++++++++++------- - 1 file changed, 12 insertions(+), 7 deletions(-) - -diff --git a/target/hppa/translate.c b/target/hppa/translate.c -index 3b9744deb4..952027a28e 100644 ---- a/target/hppa/translate.c -+++ b/target/hppa/translate.c -@@ -140,6 +140,7 @@ - #define tcg_gen_deposit_z_reg tcg_gen_deposit_z_i64 - #define tcg_gen_extract_reg tcg_gen_extract_i64 - #define tcg_gen_sextract_reg tcg_gen_sextract_i64 -+#define tcg_gen_extract2_reg tcg_gen_extract2_i64 - #define tcg_const_reg tcg_const_i64 - #define tcg_const_local_reg tcg_const_local_i64 - #define tcg_constant_reg tcg_constant_i64 -@@ -234,6 +235,7 @@ - #define tcg_gen_deposit_z_reg tcg_gen_deposit_z_i32 - #define tcg_gen_extract_reg tcg_gen_extract_i32 - #define tcg_gen_sextract_reg tcg_gen_sextract_i32 -+#define tcg_gen_extract2_reg tcg_gen_extract2_i32 - #define tcg_const_reg tcg_const_i32 - #define tcg_const_local_reg tcg_const_local_i32 - #define tcg_constant_reg tcg_constant_i32 -@@ -3204,19 +3206,22 @@ static bool trans_shrpw_imm(DisasContext *ctx, arg_shrpw_imm *a) - - dest = dest_gpr(ctx, a->t); - t2 = load_gpr(ctx, a->r2); -- if (a->r1 == a->r2) { -+ if (a->r1 == 0) { -+ tcg_gen_extract_reg(dest, t2, sa, 32 - sa); -+ } else if (TARGET_REGISTER_BITS == 32) { -+ tcg_gen_extract2_reg(dest, t2, cpu_gr[a->r1], sa); -+ } else if (a->r1 == a->r2) { - TCGv_i32 t32 = tcg_temp_new_i32(); - tcg_gen_trunc_reg_i32(t32, t2); - tcg_gen_rotri_i32(t32, t32, sa); - tcg_gen_extu_i32_reg(dest, t32); - tcg_temp_free_i32(t32); -- } else if (a->r1 == 0) { -- tcg_gen_extract_reg(dest, t2, sa, 32 - sa); - } else { -- TCGv_reg t0 = tcg_temp_new(); -- tcg_gen_extract_reg(t0, t2, sa, 32 - sa); -- tcg_gen_deposit_reg(dest, t0, cpu_gr[a->r1], 32 - sa, sa); -- tcg_temp_free(t0); -+ TCGv_i64 t64 = tcg_temp_new_i64(); -+ tcg_gen_concat_reg_i64(t64, t2, cpu_gr[a->r1]); -+ tcg_gen_shri_i64(t64, t64, sa); -+ tcg_gen_trunc_i64_reg(dest, t64); -+ tcg_temp_free_i64(t64); - } - save_gpr(ctx, a->t, dest); - --- -2.27.0 - diff --git a/target-i386-Add-SGX-aex-notify-and-EDECCSSA-support.patch b/target-i386-Add-SGX-aex-notify-and-EDECCSSA-support.patch deleted file mode 100644 index bf32c05515dd4bfcbc74a8de8a7b3c583133a7e1..0000000000000000000000000000000000000000 --- a/target-i386-Add-SGX-aex-notify-and-EDECCSSA-support.patch +++ /dev/null @@ -1,64 +0,0 @@ -From b4657a1cf12f3a0a650498d87f4e91aae76cc840 Mon Sep 17 00:00:00 2001 -From: Kai Huang -Date: Wed, 9 Nov 2022 15:48:34 +1300 -Subject: [PATCH] target/i386: Add SGX aex-notify and EDECCSSA support - -from mainline-v8.0.0-rc0 -commit d45f24fe7525d8a8aaa4ca6d9d214dc41819caa5 -category: feature -feature: SGX aex-notify and EDECCSSA support -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6Y4W4 - -Intel-SIG: commit d45f24fe7525 ("target/i386: Add SGX aex-notify and EDECCSSA support") - ------------------------------------------------------------ - -The new SGX Asynchronous Exit (AEX) notification mechanism (AEX-notify) -allows one enclave to receive a notification in the ERESUME after the -enclave exit due to an AEX. EDECCSSA is a new SGX user leaf function -(ENCLU[EDECCSSA]) to facilitate the AEX notification handling. - -Whether the hardware supports to create enclave with AEX-notify support -is enumerated via CPUID.(EAX=0x12,ECX=0x1):EAX[10]. The new EDECCSSA -user leaf function is enumerated via CPUID.(EAX=0x12,ECX=0x0):EAX[11]. - -Add support to allow to expose the new SGX AEX-notify feature and the -new EDECCSSA user leaf function to KVM guest. - -Link: https://lore.kernel.org/lkml/166760360549.4906.809756297092548496.tip-bot2@tip-bot2/ -Link: https://lore.kernel.org/lkml/166760360934.4906.2427175408052308969.tip-bot2@tip-bot2/ -Reviewed-by: Yang Zhong -Signed-off-by: Kai Huang -Message-Id: <20221109024834.172705-1-kai.huang@intel.com> -Signed-off-by: Paolo Bonzini -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 61cd7abcaa..df475f27d3 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1205,7 +1205,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .feat_names = { - "sgx1", "sgx2", NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, "sgx-edeccssa", - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -@@ -1245,7 +1245,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .feat_names = { - NULL, "sgx-debug", "sgx-mode64", NULL, - "sgx-provisionkey", "sgx-tokenkey", NULL, "sgx-kss", -- NULL, NULL, NULL, NULL, -+ NULL, NULL, "sgx-aex-notify", NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, --- -2.27.0 - diff --git a/target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch b/target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch deleted file mode 100644 index 0db8839a414c5e161fa4150d46bd38bc3460d7d5..0000000000000000000000000000000000000000 --- a/target-i386-Add-few-security-fix-bits-in-ARCH_CAPABI.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 732cb06c9b652cf899e9f329ad74ec3dae3d18b2 Mon Sep 17 00:00:00 2001 -From: Lei Wang -Date: Thu, 6 Jul 2023 13:49:48 +0800 -Subject: [PATCH] target/i386: Add few security fix bits in ARCH_CAPABILITIES - into SapphireRapids CPU model - -commit 3baf7ae63505eb1652d1e52d65798307fead8539 upstream. - -SapphireRapids has bit 13, 14 and 15 of MSR_IA32_ARCH_CAPABILITIES -enabled, which are related to some security fixes. - -Add version 2 of SapphireRapids CPU model with those bits enabled also. - -Intel-SIG: commit 3baf7ae63505 ("target/i386: Add few security fix bits in ARCH_CAPABILITIES into SapphireRapids CPU model") -Backport support of SapphireRapids CPU Model version 2 - -Signed-off-by: Lei Wang -Signed-off-by: Tao Su -Message-ID: <20230706054949.66556-6-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 685bfca37e..eb911b12fa 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3675,8 +3675,17 @@ static const X86CPUDefinition builtin_x86_defs[] = { - .model_id = "Intel Xeon Processor (SapphireRapids)", - .versions = (X86CPUVersionDefinition[]) { - { .version = 1 }, -- { /* end of list */ }, -- }, -+ { -+ .version = 2, -+ .props = (PropValue[]) { -+ { "sbdr-ssdp-no", "on" }, -+ { "fbsdp-no", "on" }, -+ { "psdp-no", "on" }, -+ { /* end of list */ } -+ } -+ }, -+ { /* end of list */ } -+ } - }, - { - .name = "Denverton", --- -2.41.0.windows.1 - diff --git a/target-i386-Add-new-CPU-model-GraniteRapids.patch b/target-i386-Add-new-CPU-model-GraniteRapids.patch deleted file mode 100644 index 24672e94aebfec3f6b06df7769652ea1098a2b43..0000000000000000000000000000000000000000 --- a/target-i386-Add-new-CPU-model-GraniteRapids.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 7ebcbfb9ac1d53ea46bfd86fa7f0a90a4012412e Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:49 +0800 -Subject: [PATCH] target/i386: Add new CPU model GraniteRapids - -commit 6d5e9694ef374159072984c0958c3eaab6dd1d52 upstream. - -The GraniteRapids CPU model mainly adds the following new features -based on SapphireRapids: -- PREFETCHITI CPUID.(EAX=7,ECX=1):EDX[bit 14] -- AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21] - -And adds the following security fix for corresponding vulnerabilities: -- MCDT_NO CPUID.(EAX=7,ECX=2):EDX[bit 5] -- SBDR_SSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 13] -- FBSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 14] -- PSDP_NO MSR_IA32_ARCH_CAPABILITIES[bit 15] -- PBRSB_NO MSR_IA32_ARCH_CAPABILITIES[bit 24] - -Intel-SIG: commit 6d5e9694ef37 target/i386: Add new CPU model GraniteRapids. -Backport GNR and SRF ISA into QEMU-6.2 - -Signed-off-by: Tao Su -Tested-by: Xuelian Guo -Reviewed-by: Xiaoyao Li -Message-ID: <20230706054949.66556-7-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 136 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index ee243693e3..efe0c2b46c 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -3707,6 +3707,142 @@ static const X86CPUDefinition builtin_x86_defs[] = { - { /* end of list */ } - } - }, -+ { -+ .name = "GraniteRapids", -+ .level = 0x20, -+ .vendor = CPUID_VENDOR_INTEL, -+ .family = 6, -+ .model = 173, -+ .stepping = 0, -+ /* -+ * please keep the ascending order so that we can have a clear view of -+ * bit position of each feature. -+ */ -+ .features[FEAT_1_EDX] = -+ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | -+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | -+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | -+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR | -+ CPUID_SSE | CPUID_SSE2, -+ .features[FEAT_1_ECX] = -+ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | -+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | -+ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE | -+ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES | -+ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND, -+ .features[FEAT_8000_0001_EDX] = -+ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB | -+ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM, -+ .features[FEAT_8000_0001_ECX] = -+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH, -+ .features[FEAT_8000_0008_EBX] = -+ CPUID_8000_0008_EBX_WBNOINVD, -+ .features[FEAT_7_0_EBX] = -+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE | -+ CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | -+ CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM | -+ CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | -+ CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | -+ CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT | -+ CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | CPUID_7_0_EBX_SHA_NI | -+ CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL, -+ .features[FEAT_7_0_ECX] = -+ CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | -+ CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI | -+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ | -+ CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | -+ CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 | -+ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT, -+ .features[FEAT_7_0_EDX] = -+ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE | -+ CPUID_7_0_EDX_TSX_LDTRK | CPUID_7_0_EDX_AMX_BF16 | -+ CPUID_7_0_EDX_AVX512_FP16 | CPUID_7_0_EDX_AMX_TILE | -+ CPUID_7_0_EDX_AMX_INT8 | CPUID_7_0_EDX_SPEC_CTRL | -+ CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD, -+ .features[FEAT_ARCH_CAPABILITIES] = -+ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL | -+ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO | -+ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_TAA_NO | -+ MSR_ARCH_CAP_SBDR_SSDP_NO | MSR_ARCH_CAP_FBSDP_NO | -+ MSR_ARCH_CAP_PSDP_NO | MSR_ARCH_CAP_PBRSB_NO, -+ .features[FEAT_XSAVE] = -+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | -+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES | CPUID_D_1_EAX_XFD, -+ .features[FEAT_6_EAX] = -+ CPUID_6_EAX_ARAT, -+ .features[FEAT_7_1_EAX] = -+ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_AVX512_BF16 | -+ CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC | -+ CPUID_7_1_EAX_AMX_FP16, -+ .features[FEAT_7_1_EDX] = -+ CPUID_7_1_EDX_PREFETCHITI, -+ .features[FEAT_7_2_EDX] = -+ CPUID_7_2_EDX_MCDT_NO, -+ .features[FEAT_VMX_BASIC] = -+ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS, -+ .features[FEAT_VMX_ENTRY_CTLS] = -+ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE | -+ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER, -+ .features[FEAT_VMX_EPT_VPID_CAPS] = -+ MSR_VMX_EPT_EXECONLY | -+ MSR_VMX_EPT_PAGE_WALK_LENGTH_4 | MSR_VMX_EPT_PAGE_WALK_LENGTH_5 | -+ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB | -+ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS | -+ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT | -+ MSR_VMX_EPT_INVVPID_ALL_CONTEXT | -+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS, -+ .features[FEAT_VMX_EXIT_CTLS] = -+ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS | -+ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | -+ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT | -+ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER | -+ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER, -+ .features[FEAT_VMX_MISC] = -+ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT | -+ MSR_VMX_MISC_VMWRITE_VMEXIT, -+ .features[FEAT_VMX_PINBASED_CTLS] = -+ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING | -+ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER | -+ VMX_PIN_BASED_POSTED_INTR, -+ .features[FEAT_VMX_PROCBASED_CTLS] = -+ VMX_CPU_BASED_VIRTUAL_INTR_PENDING | -+ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING | -+ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING | -+ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING | -+ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING | -+ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING | -+ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING | -+ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING | -+ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG | -+ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING | -+ VMX_CPU_BASED_PAUSE_EXITING | -+ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS, -+ .features[FEAT_VMX_SECONDARY_CTLS] = -+ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | -+ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC | -+ VMX_SECONDARY_EXEC_RDTSCP | -+ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | -+ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING | -+ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST | -+ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT | -+ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | -+ VMX_SECONDARY_EXEC_RDRAND_EXITING | -+ VMX_SECONDARY_EXEC_ENABLE_INVPCID | -+ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS | -+ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML | -+ VMX_SECONDARY_EXEC_XSAVES, -+ .features[FEAT_VMX_VMFUNC] = -+ MSR_VMX_VMFUNC_EPT_SWITCHING, -+ .xlevel = 0x80000008, -+ .model_id = "Intel Xeon Processor (GraniteRapids)", -+ .versions = (X86CPUVersionDefinition[]) { -+ { .version = 1 }, -+ { /* end of list */ }, -+ }, -+ }, - { - .name = "Denverton", - .level = 21, --- -2.27.0 - diff --git a/target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch b/target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch deleted file mode 100644 index b0b81164ab851c0f1c1838d997b52b4b0044408e..0000000000000000000000000000000000000000 --- a/target-i386-Add-new-bit-definitions-of-MSR_IA32_ARCH.patch +++ /dev/null @@ -1,43 +0,0 @@ -From cdd89390a5e8fb55515798ab4ec5ec5fd6fed32b Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:47 +0800 -Subject: [PATCH] target/i386: Add new bit definitions of - MSR_IA32_ARCH_CAPABILITIES - -commit 6c43ec3b206956a8a3008accafe9eb2dfd885190 upstream. - -Currently, bit 13, 14, 15 and 24 of MSR_IA32_ARCH_CAPABILITIES are -disclosed for fixing security issues, so add those bit definitions. - -Intel-SIG: commit 6c43ec3b2069 ("target/i386: Add new bit definitions of MSR_IA32_ARCH_CAPABILITIES") -Backport new bit definitions of MSR_IA32_ARCH_CAPABILITIES - -Signed-off-by: Tao Su -Reviewed-by: Igor Mammedov -Message-ID: <20230706054949.66556-5-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - target/i386/cpu.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index edbaba0d62..37c687d4d8 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -966,7 +966,11 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define MSR_ARCH_CAP_PSCHANGE_MC_NO (1U << 6) - #define MSR_ARCH_CAP_TSX_CTRL_MSR (1U << 7) - #define MSR_ARCH_CAP_TAA_NO (1U << 8) -+#define MSR_ARCH_CAP_SBDR_SSDP_NO (1U << 13) -+#define MSR_ARCH_CAP_FBSDP_NO (1U << 14) -+#define MSR_ARCH_CAP_PSDP_NO (1U << 15) - #define MSR_ARCH_CAP_FB_CLEAR (1U << 17) -+#define MSR_ARCH_CAP_PBRSB_NO (1U << 24) - - #define MSR_CORE_CAP_SPLIT_LOCK_DETECT (1U << 5) - --- -2.41.0.windows.1 - diff --git a/target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch b/target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch deleted file mode 100644 index 27cdfaf249c65be4ea1ac7a5c5940b3f7300bd51..0000000000000000000000000000000000000000 --- a/target-i386-Add-support-for-AMX-FP16-in-CPUID-enumer.patch +++ /dev/null @@ -1,62 +0,0 @@ -From c362956eb88558991bee59e43d7db52c8bc7e5f5 Mon Sep 17 00:00:00 2001 -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:09 +0800 -Subject: [PATCH] target/i386: Add support for AMX-FP16 in CPUID enumeration - -commit 99ed8445ea27742a4df40f51a3a5fbd6f8e76fa5 upstream. - -Latest Intel platform Granite Rapids has introduced a new instruction - -AMX-FP16, which performs dot-products of two FP16 tiles and accumulates -the results into a packed single precision tile. AMX-FP16 adds FP16 -capability and allows a FP16 GPU trained model to run faster without -loss of accuracy or added SW overhead. - -The bit definition: -CPUID.(EAX=7,ECX=1):EAX[bit 21] - -Add CPUID definition for AMX-FP16. - -Intel-SIG: commit 99ed8445ea27 target/i386: Add support for AMX-FP16 in CPUID enumeration. -Backport GNR and SRF ISA into QEMU-6.2 - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-3-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 47c2d9da80..3fc3b8041a 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, NULL, "fzrm", "fsrs", - "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, "amx-fp16", NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - }, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 4a7362ee07..c747e68a7a 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -891,6 +891,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_FSRS (1U << 11) - /* Fast Short REP CMPS/SCAS */ - #define CPUID_7_1_EAX_FSRC (1U << 12) -+/* Support Tile Computational Operations on FP16 Numbers */ -+#define CPUID_7_1_EAX_AMX_FP16 (1U << 21) - - /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ - #define CPUID_7_2_EDX_MCDT_NO (1U << 5) --- -2.27.0 - diff --git a/target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch b/target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch deleted file mode 100644 index 8b99815a4c1a33bdf4ce9d0825bf04c3a746c6e4..0000000000000000000000000000000000000000 --- a/target-i386-Add-support-for-AVX-IFMA-in-CPUID-enumer.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 8fe9899c39d86f9e0baf832744a7cfe19642a3fd Mon Sep 17 00:00:00 2001 -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:10 +0800 -Subject: [PATCH] target/i386: Add support for AVX-IFMA in CPUID enumeration - -commit a957a88416ecbec51e147cba9fe89b93f6646b3b upstream. - -AVX-IFMA is a new instruction in the latest Intel platform Sierra -Forest. This instruction packed multiplies unsigned 52-bit integers and -adds the low/high 52-bit products to Qword Accumulators. - -The bit definition: -CPUID.(EAX=7,ECX=1):EAX[bit 23] - -Add CPUID definition for AVX-IFMA. - -Intel-SIG: commit a957a88416ec target/i386: Add support for AVX-IFMA in CPUID enumeration. -Backport GNR and SRF ISA into QEMU-6.2 - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-4-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 3fc3b8041a..b19fb0cf87 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -876,7 +876,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, NULL, "fzrm", "fsrs", - "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, "amx-fp16", NULL, NULL, -+ NULL, "amx-fp16", NULL, "avx-ifma", - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - }, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index c747e68a7a..2bcc127fac 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -893,6 +893,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_FSRC (1U << 12) - /* Support Tile Computational Operations on FP16 Numbers */ - #define CPUID_7_1_EAX_AMX_FP16 (1U << 21) -+/* Support for VPMADD52[H,L]UQ */ -+#define CPUID_7_1_EAX_AVX_IFMA (1U << 23) - - /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ - #define CPUID_7_2_EDX_MCDT_NO (1U << 5) --- -2.27.0 - diff --git a/target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch b/target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch deleted file mode 100644 index 0eb1635b4d3fdc20048e7357ed1187e0dce8e058..0000000000000000000000000000000000000000 --- a/target-i386-Add-support-for-AVX-NE-CONVERT-in-CPUID-.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 165d587b52f7c8459d9a9deca389610f9165b33a Mon Sep 17 00:00:00 2001 -From: Quanxian Wang -Date: Wed, 8 Nov 2023 12:44:56 +0800 -Subject: [PATCH] target/i386: Add support for AVX-NE-CONVERT in CPUID - enumeration - -commit ecd2e6ca037d7bf3673c5478590d686d5cd6135a upstream. - -AVX-NE-CONVERT is a new set of instructions which can convert low -precision floating point like BF16/FP16 to high precision floating point -FP32, as well as convert FP32 elements to BF16. This instruction allows -the platform to have improved AI capabilities and better compatibility. - -The bit definition: -CPUID.(EAX=7,ECX=1):EDX[bit 5] - -Add CPUID definition for AVX-NE-CONVERT. - -Intel-SIG: commit ecd2e6ca037d target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration. -Backport GNR and SRF ISA into QEMU-6.2 - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-6-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index a14284a81b..d36174d689 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -911,7 +911,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { - NULL, NULL, NULL, NULL, -- "avx-vnni-int8", NULL, NULL, NULL, -+ "avx-vnni-int8", "avx-ne-convert", NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index b81d77084c..93c8bd6a13 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -898,6 +898,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_AVX_IFMA (1U << 23) - /* Support for VPDPB[SU,UU,SS]D[,S] */ - #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) -+/* AVX NE CONVERT Instructions */ -+#define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5) - - /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ - #define CPUID_7_2_EDX_MCDT_NO (1U << 5) --- -2.27.0 - diff --git a/target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch b/target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch deleted file mode 100644 index b6fc1d0e249f9faa13f70b838153db3f5dc370b7..0000000000000000000000000000000000000000 --- a/target-i386-Add-support-for-AVX-VNNI-INT8-in-CPUID-e.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 71b820dc04fbe04342d5a05be3d774c704b682ec Mon Sep 17 00:00:00 2001 -From: Quanxian Wang -Date: Wed, 8 Nov 2023 12:43:11 +0800 -Subject: [PATCH] target/i386: Add support for AVX-VNNI-INT8 in CPUID - enumeration - -commit eaaa197d5b112ea2758b54df58881a2626de3af5 upstream. - -AVX-VNNI-INT8 is a new set of instructions in the latest Intel platform -Sierra Forest, aims for the platform to have superior AI capabilities. -This instruction multiplies the individual bytes of two unsigned or -unsigned source operands, then adds and accumulates the results into the -destination dword element size operand. - -The bit definition: -CPUID.(EAX=7,ECX=1):EDX[bit 4] - -AVX-VNNI-INT8 is on a new feature bits leaf. Add a CPUID feature word -FEAT_7_1_EDX for this leaf. - -Add CPUID definition for AVX-VNNI-INT8. - -Intel-SIG: commit eaaa197d5b11 target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration. -Backport GNR and SRF ISA into QEMU-6.2 - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-5-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 22 +++++++++++++++++++++- - target/i386/cpu.h | 3 +++ - 2 files changed, 24 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index b19fb0cf87..a14284a81b 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -663,6 +663,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - #define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM - #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ - CPUID_7_1_EAX_FSRC) -+#define TCG_7_1_EDX_FEATURES 0 - #define TCG_7_2_EDX_FEATURES 0 - #define TCG_APM_FEATURES 0 - #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT -@@ -906,6 +907,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - }, - .tcg_features = TCG_7_2_EDX_FEATURES, - }, -+ [FEAT_7_1_EDX] = { -+ .type = CPUID_FEATURE_WORD, -+ .feat_names = { -+ NULL, NULL, NULL, NULL, -+ "avx-vnni-int8", NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ }, -+ .cpuid = { -+ .eax = 7, -+ .needs_ecx = true, .ecx = 1, -+ .reg = R_EDX, -+ }, -+ .tcg_features = TCG_7_1_EDX_FEATURES, -+ }, - [FEAT_8000_0007_EDX] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { -@@ -5557,9 +5577,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - } - } else if (count == 1) { - *eax = env->features[FEAT_7_1_EAX]; -+ *edx = env->features[FEAT_7_1_EDX]; - *ebx = 0; - *ecx = 0; -- *edx = 0; - } else if (count == 2) { - *edx = env->features[FEAT_7_2_EDX]; - *eax = 0; -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 2bcc127fac..b81d77084c 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -601,6 +601,7 @@ typedef enum FeatureWord { - FEAT_SGX_12_0_EAX, /* CPUID[EAX=0x12,ECX=0].EAX (SGX) */ - FEAT_SGX_12_0_EBX, /* CPUID[EAX=0x12,ECX=0].EBX (SGX MISCSELECT[31:0]) */ - FEAT_SGX_12_1_EAX, /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */ -+ FEAT_7_1_EDX, /* CPUID[EAX=7,ECX=1].EDX */ - FEAT_7_2_EDX, /* CPUID[EAX=7,ECX=2].EDX */ - FEATURE_WORDS, - } FeatureWord; -@@ -895,6 +896,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_AMX_FP16 (1U << 21) - /* Support for VPMADD52[H,L]UQ */ - #define CPUID_7_1_EAX_AVX_IFMA (1U << 23) -+/* Support for VPDPB[SU,UU,SS]D[,S] */ -+#define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) - - /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ - #define CPUID_7_2_EDX_MCDT_NO (1U << 5) --- -2.27.0 - diff --git a/target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch b/target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch deleted file mode 100644 index d1633122ee5d8dfc1129f1881de2ff4eb2beed84..0000000000000000000000000000000000000000 --- a/target-i386-Add-support-for-CMPCCXADD-in-CPUID-enume.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 25d08629eab566f5a47bf915a86e20318ee1cf08 Mon Sep 17 00:00:00 2001 -From: Jiaxi Chen -Date: Fri, 3 Mar 2023 14:59:08 +0800 -Subject: [PATCH] target/i386: Add support for CMPCCXADD in CPUID enumeration - -commit a9ce107fd0f2017af84255a9cf6542fa3eb3e214 upstream. - -CMPccXADD is a new set of instructions in the latest Intel platform -Sierra Forest. This new instruction set includes a semaphore operation -that can compare and add the operands if condition is met, which can -improve database performance. - -The bit definition: -CPUID.(EAX=7,ECX=1):EAX[bit 7] - -Add CPUID definition for CMPCCXADD. - -Intel-SIG: commit a9ce107fd0f2 target/i386: Add support for CMPCCXADD in CPUID enumeration. -Backport GNR and SRF ISA into QEMU-6.2 - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-2-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 58124071da..47c2d9da80 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -872,7 +872,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { - NULL, NULL, NULL, NULL, -- "avx-vnni", "avx512-bf16", NULL, NULL, -+ "avx-vnni", "avx512-bf16", NULL, "cmpccxadd", - NULL, NULL, "fzrm", "fsrs", - "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 37c687d4d8..4a7362ee07 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -883,6 +883,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) - /* AVX512 BFloat16 Instruction */ - #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) -+/* CMPCCXADD Instructions */ -+#define CPUID_7_1_EAX_CMPCCXADD (1U << 7) - /* Fast Zero REP MOVS */ - #define CPUID_7_1_EAX_FZRM (1U << 10) - /* Fast Short REP STOS */ --- -2.27.0 - diff --git a/target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch b/target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch deleted file mode 100644 index 0dbfc10a7f56394119868f1a33fe7f891497e035..0000000000000000000000000000000000000000 --- a/target-i386-Add-support-for-MCDT_NO-in-CPUID-enumera.patch +++ /dev/null @@ -1,112 +0,0 @@ -From a7329b80a2c8a50e53da17aa4eff0ef50aa21413 Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:45 +0800 -Subject: [PATCH] target/i386: Add support for MCDT_NO in CPUID enumeration - -commit 9dd8b71091f47bac395f543779269c14d8d93c60 upstream. - -CPUID.(EAX=7,ECX=2):EDX[bit 5] enumerates MCDT_NO. Processors enumerate -this bit as 1 do not exhibit MXCSR Configuration Dependent Timing (MCDT) -behavior and do not need to be mitigated to avoid data-dependent behavior -for certain instructions. - -Since MCDT_NO is in a new sub-leaf, add a new CPUID feature word -FEAT_7_2_EDX. Also update cpuid_level_func7 by FEAT_7_2_EDX. - -Intel-SIG: commit 9dd8b71091f4 ("target/i386: Add support for MCDT_NO in CPUID enumeration") -Backport support for MCDT_NO in CPUID enumeration - -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-ID: <20230706054949.66556-3-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ jason: resolve conflict with FEAT_7_1_EDX which not backported yet ] -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 26 ++++++++++++++++++++++++++ - target/i386/cpu.h | 4 ++++ - 2 files changed, 30 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index b878a1bf20..685bfca37e 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -663,6 +663,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - #define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM - #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ - CPUID_7_1_EAX_FSRC) -+#define TCG_7_2_EDX_FEATURES 0 - #define TCG_APM_FEATURES 0 - #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT - #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) -@@ -886,6 +887,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - }, - .tcg_features = TCG_7_1_EAX_FEATURES, - }, -+ [FEAT_7_2_EDX] = { -+ .type = CPUID_FEATURE_WORD, -+ .feat_names = { -+ NULL, NULL, NULL, NULL, -+ NULL, "mcdt-no", NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, NULL, -+ }, -+ .cpuid = { -+ .eax = 7, -+ .needs_ecx = true, .ecx = 2, -+ .reg = R_EDX, -+ }, -+ .tcg_features = TCG_7_2_EDX_FEATURES, -+ }, - [FEAT_8000_0007_EDX] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { -@@ -5531,6 +5551,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - *ebx = 0; - *ecx = 0; - *edx = 0; -+ } else if (count == 2) { -+ *edx = env->features[FEAT_7_2_EDX]; -+ *eax = 0; -+ *ebx = 0; -+ *ecx = 0; - } else { - *eax = 0; - *ebx = 0; -@@ -6361,6 +6386,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) - x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX); -+ x86_cpu_adjust_feat_level(cpu, FEAT_7_2_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0007_EDX); -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index d9aac5acd2..edbaba0d62 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -601,6 +601,7 @@ typedef enum FeatureWord { - FEAT_SGX_12_0_EAX, /* CPUID[EAX=0x12,ECX=0].EAX (SGX) */ - FEAT_SGX_12_0_EBX, /* CPUID[EAX=0x12,ECX=0].EBX (SGX MISCSELECT[31:0]) */ - FEAT_SGX_12_1_EAX, /* CPUID[EAX=0x12,ECX=1].EAX (SGX ATTRIBUTES[31:0]) */ -+ FEAT_7_2_EDX, /* CPUID[EAX=7,ECX=2].EDX */ - FEATURE_WORDS, - } FeatureWord; - -@@ -889,6 +890,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - /* Fast Short REP CMPS/SCAS */ - #define CPUID_7_1_EAX_FSRC (1U << 12) - -+/* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ -+#define CPUID_7_2_EDX_MCDT_NO (1U << 5) -+ - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) - --- -2.41.0.windows.1 - diff --git a/target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch b/target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch deleted file mode 100644 index 59053fd787257ca0e120a32b0d398f10b81f2616..0000000000000000000000000000000000000000 --- a/target-i386-Add-support-for-PREFETCHIT0-1-in-CPUID-e.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 9a56c714caaf3bf31430a769befdf92e79388dda Mon Sep 17 00:00:00 2001 -From: Quanxian Wang -Date: Wed, 8 Nov 2023 12:46:00 +0800 -Subject: [PATCH] target/i386: Add support for PREFETCHIT0/1 in CPUID - enumeration - -commit d1a1111514333e46a98b136235f71eef90d610fa upstream. - -Latest Intel platform Granite Rapids has introduced a new instruction - -PREFETCHIT0/1, which moves code to memory (cache) closer to the -processor depending on specific hints. - -The bit definition: -CPUID.(EAX=7,ECX=1):EDX[bit 14] - -Add CPUID definition for PREFETCHIT0/1. - -Intel-SIG: commit d1a111151433 target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration. -Backport GNR and SRF ISA into QEMU-6.2 - -Signed-off-by: Jiaxi Chen -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-Id: <20230303065913.1246327-7-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index d36174d689..ee243693e3 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -913,7 +913,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, NULL, NULL, NULL, - "avx-vnni-int8", "avx-ne-convert", NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, NULL, "prefetchiti", NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 93c8bd6a13..32ecec5fa7 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -900,6 +900,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EDX_AVX_VNNI_INT8 (1U << 4) - /* AVX NE CONVERT Instructions */ - #define CPUID_7_1_EDX_AVX_NE_CONVERT (1U << 5) -+/* PREFETCHIT0/1 Instructions */ -+#define CPUID_7_1_EDX_PREFETCHITI (1U << 14) - - /* Do not exhibit MXCSR Configuration Dependent Timing (MCDT) behavior */ - #define CPUID_7_2_EDX_MCDT_NO (1U << 5) --- -2.27.0 - diff --git a/target-i386-Adjust-feature-level-according-to-FEAT_7.patch b/target-i386-Adjust-feature-level-according-to-FEAT_7.patch deleted file mode 100644 index 3c238c62f69f25e0943d4d95f2f6933361564b69..0000000000000000000000000000000000000000 --- a/target-i386-Adjust-feature-level-according-to-FEAT_7.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 52d000a4043f3000f880bb5c75a298f57b8e0fe0 Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:44 +0800 -Subject: [PATCH] target/i386: Adjust feature level according to FEAT_7_1_EDX - -commit 8731336e90dea3dd04948127e775c9f087f97a4c upstream. - -If FEAT_7_1_EAX is 0 and FEAT_7_1_EDX is non-zero, as is the case -with a Granite Rapids host and -'-cpu host,-avx-vnni,-avx512-bf16,-fzrm,-fsrs,-fsrc,-amx-fp16', we can't -get CPUID_7_1 leaf even though CPUID_7_1_EDX has non-zero value. - -Update cpuid_level_func7 according to CPUID_7_1_EDX, otherwise -guest may report wrong maximum number sub-leaves in leaf 07H. - -Fixes: eaaa197d5b11 ("target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration") - -Intel-SIG: commit 8731336e90de target/i386: Adjust feature level according to FEAT_7_1_EDX. -Backport GNR and SRF ISA into QEMU-6.2 - -Cc: qemu-stable@nongnu.org -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-ID: <20230706054949.66556-2-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ Quanxian Wang: amend commit log ] -Signed-off-by: Quanxian Wang ---- - target/i386/cpu.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index efe0c2b46c..6aaa730a0d 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6551,6 +6551,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp) - x86_cpu_adjust_feat_level(cpu, FEAT_6_EAX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_0_ECX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EAX); -+ x86_cpu_adjust_feat_level(cpu, FEAT_7_1_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_7_2_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_EDX); - x86_cpu_adjust_feat_level(cpu, FEAT_8000_0001_ECX); --- -2.27.0 - diff --git a/target-i386-Allow-MCDT_NO-if-host-supports.patch b/target-i386-Allow-MCDT_NO-if-host-supports.patch deleted file mode 100644 index a95c27ea6ffc34d275cb1df8cd45420c1de83195..0000000000000000000000000000000000000000 --- a/target-i386-Allow-MCDT_NO-if-host-supports.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 6beadcde4d28a1e4ad3267b7702162ecf9d4541b Mon Sep 17 00:00:00 2001 -From: Tao Su -Date: Thu, 6 Jul 2023 13:49:46 +0800 -Subject: [PATCH] target/i386: Allow MCDT_NO if host supports - -commit ba3709feaab44631315e02cd793cfccae4c6bd2a upstream. - -MCDT_NO bit indicates HW contains the security fix and doesn't need to -be mitigated to avoid data-dependent behaviour for certain instructions. -It needs no hypervisor support. Treat it as supported regardless of what -KVM reports. - -Intel-SIG: commit ba3709feaab4 ("target/i386: Allow MCDT_NO if host supports") -Backport allowing MCDT_NO if host supports - -Signed-off-by: Tao Su -Reviewed-by: Xiaoyao Li -Message-ID: <20230706054949.66556-4-tao1.su@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - target/i386/kvm/kvm.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index d323d08dcb..55ee75e844 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -424,6 +424,10 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, - uint32_t eax; - host_cpuid(7, 1, &eax, &unused, &unused, &unused); - ret |= eax & (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC); -+ } else if (function == 7 && index == 2 && reg == R_EDX) { -+ uint32_t edx; -+ host_cpuid(7, 2, &unused, &unused, &unused, &edx); -+ ret |= edx & CPUID_7_2_EDX_MCDT_NO; - } else if (function == 0xd && index == 0 && - (reg == R_EAX || reg == R_EDX)) { - /* --- -2.41.0.windows.1 - diff --git a/target-i386-Export-GDS_NO-bit-to-guests.patch b/target-i386-Export-GDS_NO-bit-to-guests.patch deleted file mode 100644 index 5b6e5f10815daeed3d809ead15b6141330f6f877..0000000000000000000000000000000000000000 --- a/target-i386-Export-GDS_NO-bit-to-guests.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 3cea2c36571b39a6fa956abe66507c04283ad614 Mon Sep 17 00:00:00 2001 -From: Pawan Gupta -Date: Mon, 14 Aug 2023 21:54:27 -0700 -Subject: [PATCH] target/i386: Export GDS_NO bit to guests - -commit 3a2a1f97ea349745094e789e6b0768dbd92d0dcd upstream. - -Gather Data Sampling (GDS) is a side-channel attack using Gather -instructions. Some Intel processors will set ARCH_CAP_GDS_NO bit in -MSR IA32_ARCH_CAPABILITIES to report that they are not vulnerable to -GDS. - -Make this bit available to guests. - -Intel-SIG: commit 3a2a1f97ea34 ("target/i386: Export GDS_NO bit to guests") -Backport to export GDS_NO bit to guests(CVE-2022-40982). - -Closes: https://lore.kernel.org/qemu-devel/CAMGffEmG6TNq0n3+4OJAgXc8J0OevY60KHZekXCBs3LoK9vehA@mail.gmail.com/ -Reported-by: Jack Wang -Signed-off-by: Pawan Gupta -Tested-by: Jack Wang -Tested-by: Daniel Sneddon -Message-ID: -Signed-off-by: Paolo Bonzini -[ Aichun Shi: amend commit log ] -Signed-off-by: Aichun Shi ---- - target/i386/cpu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index eb911b12fa..58124071da 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1004,7 +1004,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no", - NULL, "fb-clear", NULL, NULL, - NULL, NULL, NULL, NULL, -- "pbrsb-no", NULL, NULL, NULL, -+ "pbrsb-no", NULL, "gds-no", NULL, - NULL, NULL, NULL, NULL, - }, - .msr = { --- -2.27.0 - diff --git a/target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch b/target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch deleted file mode 100644 index ac4e016198be24f07fe83f1265440b45d0cbf963..0000000000000000000000000000000000000000 --- a/target-i386-Export-MSR_ARCH_CAPABILITIES-bits-to-gue.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 93551bb8747ffc9ef26fc3ced7be310d9aa805d6 Mon Sep 17 00:00:00 2001 -From: Pawan Gupta -Date: Fri, 23 Jun 2023 13:26:25 -0700 -Subject: [PATCH] target/i386: Export MSR_ARCH_CAPABILITIES bits to guests - -commit 5bef742cc4f0e21c80a31611af7881ba811e507f upstream. - -On Intel CPUs there are certain bits in MSR_ARCH_CAPABILITIES that -indicates if the CPU is not affected by a vulnerability. Without these -bits guests may try to deploy the mitigation even if the CPU is not -affected. - -Export the bits to guests that indicate immunity to hardware -vulnerabilities. - -Intel-SIG: commit 5bef742cc4f0 ("target/i386: Export MSR_ARCH_CAPABILITIES bits to guests") -Backport exporting MSR_ARCH_CAPABILITIES bits to guests - -Signed-off-by: Pawan Gupta -Message-ID: <63d85cc76d4cdc51e6c732478b81d8f13be11e5a.1687551881.git.pawan.kumar.gupta@linux.intel.com> -Signed-off-by: Paolo Bonzini -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 8adc84b7f9..b878a1bf20 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -981,10 +981,10 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry", - "ssb-no", "mds-no", "pschange-mc-no", "tsx-ctrl", - "taa-no", NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no", - NULL, "fb-clear", NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ "pbrsb-no", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - }, - .msr = { --- -2.41.0.windows.1 - diff --git a/target-i386-Fix-sanity-check-on-max-APIC-ID-X2APIC-e.patch b/target-i386-Fix-sanity-check-on-max-APIC-ID-X2APIC-e.patch deleted file mode 100644 index d9dec7a58afd2459ee8f09d0db9a693b8dde62a1..0000000000000000000000000000000000000000 --- a/target-i386-Fix-sanity-check-on-max-APIC-ID-X2APIC-e.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 197ebfabf4319c3dff79f06822d98304df2a3110 Mon Sep 17 00:00:00 2001 -From: David Woodhouse -Date: Mon, 14 Mar 2022 14:25:41 +0000 -Subject: [PATCH] target/i386: Fix sanity check on max APIC ID / X2APIC - enablement - -from mainline-v7.1.0-rc0 -commit dc89f32d92bba795b0665f075b78d8881cf67ab3 -category: feature -feature: Optimization of IPI virtualization -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6Y34T - -Intel-SIG: commit dc89f32d92bb ("target/i386: Fix sanity check on max APIC ID / X2APIC enablement") - ------------------------------------------------- - -The check on x86ms->apic_id_limit in pc_machine_done() had two problems. - -Firstly, we need KVM to support the X2APIC API in order to allow IRQ -delivery to APICs >= 255. So we need to call/check kvm_enable_x2apic(), -which was done elsewhere in *some* cases but not all. - -Secondly, microvm needs the same check. So move it from pc_machine_done() -to x86_cpus_init() where it will work for both. - -The check in kvm_cpu_instance_init() is now redundant and can be dropped. - -Signed-off-by: David Woodhouse -Acked-by: Claudio Fontana -Message-Id: <20220314142544.150555-1-dwmw2@infradead.org> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - hw/i386/pc.c | 8 -------- - hw/i386/x86.c | 16 ++++++++++++++++ - target/i386/kvm/kvm-cpu.c | 2 +- - 3 files changed, 17 insertions(+), 9 deletions(-) - -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 4870ce0f96..c5f430f83d 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -736,14 +736,6 @@ void pc_machine_done(Notifier *notifier, void *data) - /* update FW_CFG_NB_CPUS to account for -device added CPUs */ - fw_cfg_modify_i16(x86ms->fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus); - } -- -- -- if (x86ms->apic_id_limit > 255 && !xen_enabled() && -- !kvm_irqchip_in_kernel()) { -- error_report("current -smp configuration requires kernel " -- "irqchip support."); -- exit(EXIT_FAILURE); -- } - } - - void pc_guest_info_init(PCMachineState *pcms) -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index b84840a1bb..f64639b873 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -39,6 +39,7 @@ - #include "sysemu/replay.h" - #include "sysemu/sysemu.h" - #include "sysemu/cpu-timers.h" -+#include "sysemu/xen.h" - #include "trace.h" - - #include "hw/i386/x86.h" -@@ -136,6 +137,21 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) - */ - x86ms->apic_id_limit = x86_cpu_apic_id_from_index(x86ms, - ms->smp.max_cpus - 1) + 1; -+ -+ /* -+ * Can we support APIC ID 255 or higher? -+ * -+ * Under Xen: yes. -+ * With userspace emulated lapic: no -+ * With KVM's in-kernel lapic: only if X2APIC API is enabled. -+ */ -+ if (x86ms->apic_id_limit > 255 && !xen_enabled() && -+ (!kvm_irqchip_in_kernel() || !kvm_enable_x2apic())) { -+ error_report("current -smp configuration requires kernel " -+ "irqchip and X2APIC API support."); -+ exit(EXIT_FAILURE); -+ } -+ - possible_cpus = mc->possible_cpu_arch_ids(ms); - for (i = 0; i < ms->smp.cpus; i++) { - x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, &error_fatal); -diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c -index 5eb955ce9a..7237378a7d 100644 ---- a/target/i386/kvm/kvm-cpu.c -+++ b/target/i386/kvm/kvm-cpu.c -@@ -171,7 +171,7 @@ static void kvm_cpu_instance_init(CPUState *cs) - /* only applies to builtin_x86_defs cpus */ - if (!kvm_irqchip_in_kernel()) { - x86_cpu_change_kvm_default("x2apic", "off"); -- } else if (kvm_irqchip_is_split() && kvm_enable_x2apic()) { -+ } else if (kvm_irqchip_is_split()) { - x86_cpu_change_kvm_default("kvm-msi-ext-dest-id", "on"); - } - --- -2.27.0 - diff --git a/target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch b/target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch deleted file mode 100644 index ae16318772e2e2e2ff67042f20aebc4467b56c34..0000000000000000000000000000000000000000 --- a/target-i386-Fix-the-RES-memory-inc-which-caused-by-t.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 6e070be26502e171fd5d43a128dea99f1d34429b Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 10 Feb 2022 21:41:06 +0800 -Subject: [PATCH] target-i386: Fix the RES memory inc which caused by the - coroutine created - -for better performance, change the POOL_BATCH_SIZE from 64 to 128. - -Signed-off-by: caojinhua -Signed-off-by: jiangdongxu ---- - util/qemu-coroutine.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c -index 38fb6d3084..b9586d6929 100644 ---- a/util/qemu-coroutine.c -+++ b/util/qemu-coroutine.c -@@ -21,7 +21,7 @@ - #include "block/aio.h" - - enum { -- POOL_BATCH_SIZE = 64, -+ POOL_BATCH_SIZE = 128, - }; - - /** Free list to speed up creation */ --- -2.27.0 - diff --git a/target-i386-KVM-allow-fast-string-operations-if-host.patch b/target-i386-KVM-allow-fast-string-operations-if-host.patch deleted file mode 100644 index 7015ee27a6800a4c358ca751402a2b890c5906b7..0000000000000000000000000000000000000000 --- a/target-i386-KVM-allow-fast-string-operations-if-host.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 52ee6f565f4b4a0ca3325e94dcb44ce68ca61eee Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 27 Feb 2023 10:41:46 +0100 -Subject: [PATCH] target/i386: KVM: allow fast string operations if host - supports them - -mainline inclusion -from mainline-v8.0.0-rc0 -commit 3023c9b4d1092eb27a523c08d9e78cbaec67b59b -category: feature -feature: Intel fast REP string operations support -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6ZGIX - -Intel-SIG: commit 3023c9b4d109 ("target/i386: KVM: allow fast string operations if host supports them") - -------------------------------------- - -target/i386: KVM: allow fast string operations if host supports them - -These are just a flag that documents the performance characteristic of -an instruction; it needs no hypervisor support. So include them even -if KVM does not show them. In particular, FZRM/FSRS/FSRC have only -been added very recently, but they are available on Sapphire Rapids -processors. - -Reviewed-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini -Signed-off-by: Aichun Shi ---- - target/i386/kvm/kvm.c | 17 ++++++++++++++++- - 1 file changed, 16 insertions(+), 1 deletion(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index b8257e7e5f..6fa3bd9694 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -350,7 +350,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, - { - struct kvm_cpuid2 *cpuid; - uint32_t ret = 0; -- uint32_t cpuid_1_edx; -+ uint32_t cpuid_1_edx, unused; - uint64_t bitmask; - - cpuid = get_supported_cpuid(s); -@@ -397,10 +397,20 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, - } else if (function == 6 && reg == R_EAX) { - ret |= CPUID_6_EAX_ARAT; /* safe to allow because of emulated APIC */ - } else if (function == 7 && index == 0 && reg == R_EBX) { -+ /* Not new instructions, just an optimization. */ -+ uint32_t ebx; -+ host_cpuid(7, 0, &unused, &ebx, &unused, &unused); -+ ret |= ebx & CPUID_7_0_EBX_ERMS; -+ - if (host_tsx_broken()) { - ret &= ~(CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_HLE); - } - } else if (function == 7 && index == 0 && reg == R_EDX) { -+ /* Not new instructions, just an optimization. */ -+ uint32_t edx; -+ host_cpuid(7, 0, &unused, &unused, &unused, &edx); -+ ret |= edx & CPUID_7_0_EDX_FSRM; -+ - /* - * Linux v4.17-v4.20 incorrectly return ARCH_CAPABILITIES on SVM hosts. - * We can detect the bug by checking if MSR_IA32_ARCH_CAPABILITIES is -@@ -409,6 +419,11 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, - if (!has_msr_arch_capabs) { - ret &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES; - } -+ } else if (function == 7 && index == 1 && reg == R_EAX) { -+ /* Not new instructions, just an optimization. */ -+ uint32_t eax; -+ host_cpuid(7, 1, &eax, &unused, &unused, &unused); -+ ret |= eax & (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_FSRC); - } else if (function == 0xd && index == 0 && - (reg == R_EAX || reg == R_EDX)) { - /* --- -2.27.0 - diff --git a/target-i386-Modify-the-VM-s-physical-bits-value-set-.patch b/target-i386-Modify-the-VM-s-physical-bits-value-set-.patch deleted file mode 100644 index 2a490b614796ce0d33f645039c057ca8950187be..0000000000000000000000000000000000000000 --- a/target-i386-Modify-the-VM-s-physical-bits-value-set-.patch +++ /dev/null @@ -1,116 +0,0 @@ -From a09c3928b33b0c53831bd9eeb56f8171c26057bc Mon Sep 17 00:00:00 2001 -From: Jiajie Li -Date: Tue, 8 Feb 2022 09:46:53 +0800 -Subject: [PATCH 2/2] target-i386: Modify the VM's physical bits value set - policy. - -To resolve the problem that a VM with large memory capacity fails -to be live migrated, determine whether the VM is a large memory -capacity based on the memory size (4 TB). If yes, set the bus width -of the VM address to 46 bits. If no, set the bus width to 42 bits. - -Signed-off-by: Jinhua Cao -Signed-off-by: Jiajie Li ---- - target/i386/cpu.c | 19 ++++++++++++++++++- - target/i386/cpu.h | 6 ++++++ - target/i386/host-cpu.c | 13 +++++++------ - 3 files changed, 31 insertions(+), 7 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index aa9e636800..868cf3e7e8 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6678,6 +6678,23 @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value) - cpu->env.eip = value; - } - -+/* At present, we check the vm is *LARGE* or not, i.e. whether -+ * the memory size is more than 4T or not. -+ */ -+const uint64_t large_vm_mem_size = 0x40000000000UL; -+void x86_cpu_adjuest_by_ram_size(ram_addr_t ram_size, X86CPU *cpu) -+{ -+ /* If there is not a large vm, we set the phys_bits to 42 bits, -+ * otherwise, we increase the phys_bits to 46 bits. -+ */ -+ if (ram_size < large_vm_mem_size) { -+ cpu->phys_bits = DEFAULT_VM_CPU_PHYS_BITS; -+ } else { -+ cpu->phys_bits = LARGE_VM_CPU_PHYS_BITS; -+ cpu->fill_mtrr_mask = true; -+ } -+} -+ - int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request) - { - X86CPU *cpu = X86_CPU(cs); -@@ -6862,7 +6879,7 @@ static Property x86_cpu_properties[] = { - DEFINE_PROP_UINT32("phys-bits", X86CPU, phys_bits, 0), - DEFINE_PROP_BOOL("host-phys-bits", X86CPU, host_phys_bits, false), - DEFINE_PROP_UINT8("host-phys-bits-limit", X86CPU, host_phys_bits_limit, 0), -- DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, true), -+ DEFINE_PROP_BOOL("fill-mtrr-mask", X86CPU, fill_mtrr_mask, false), - DEFINE_PROP_UINT32("level-func7", X86CPU, env.cpuid_level_func7, - UINT32_MAX), - DEFINE_PROP_UINT32("level", X86CPU, env.cpuid_level, UINT32_MAX), -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 04f2b790c9..6f777fd6ca 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -24,6 +24,7 @@ - #include "cpu-qom.h" - #include "kvm/hyperv-proto.h" - #include "exec/cpu-defs.h" -+#include "exec/cpu-common.h" - #include "qapi/qapi-types-common.h" - - /* The x86 has a strong memory model with some store-after-load re-ordering */ -@@ -1841,6 +1842,11 @@ struct X86CPU { - extern const VMStateDescription vmstate_x86_cpu; - #endif - -+#define DEFAULT_VM_CPU_PHYS_BITS 42 -+#define LARGE_VM_CPU_PHYS_BITS 46 -+ -+void x86_cpu_adjuest_by_ram_size(ram_addr_t ram_size, X86CPU *cpu); -+ - int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request); - - int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, -diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c -index 10f8aba86e..5a1bbefa36 100644 ---- a/target/i386/host-cpu.c -+++ b/target/i386/host-cpu.c -@@ -12,6 +12,7 @@ - #include "host-cpu.h" - #include "qapi/error.h" - #include "sysemu/sysemu.h" -+#include "hw/boards.h" - - /* Note: Only safe for use on x86(-64) hosts */ - static uint32_t host_cpu_phys_bits(void) -@@ -56,14 +57,14 @@ static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu) - uint32_t phys_bits = cpu->phys_bits; - static bool warned; - -- /* -- * Print a warning if the user set it to a value that's not the -- * host value. -- */ -- if (phys_bits != host_phys_bits && phys_bits != 0 && -+ /* adjust x86 cpu phys_bits according to ram_size. */ -+ x86_cpu_adjuest_by_ram_size(current_machine->ram_size, cpu); -+ -+ /* Print a warning if the host value less than the user set. */ -+ if (phys_bits > host_phys_bits && phys_bits != 0 && - !warned) { - warn_report("Host physical bits (%u)" -- " does not match phys-bits property (%u)", -+ " less than phys-bits property (%u)", - host_phys_bits, phys_bits); - warned = true; - } --- -2.27.0 - diff --git a/target-i386-Set-maximum-APIC-ID-to-KVM-prior-to-vCPU.patch b/target-i386-Set-maximum-APIC-ID-to-KVM-prior-to-vCPU.patch deleted file mode 100644 index 04d6bb61193c1b89f1886f97bcc6ef54e7cad8b7..0000000000000000000000000000000000000000 --- a/target-i386-Set-maximum-APIC-ID-to-KVM-prior-to-vCPU.patch +++ /dev/null @@ -1,95 +0,0 @@ -From db3e0a8dd430a11e8dde6aee4e1f9cca4af0e015 Mon Sep 17 00:00:00 2001 -From: Zeng Guang -Date: Thu, 25 Aug 2022 10:52:46 +0800 -Subject: [PATCH] target/i386: Set maximum APIC ID to KVM prior to vCPU - creation - -from mainline-v7.2.0-rc0 -commit 19e2a9fb9da067acba95b3be83588bda5a3f6a99 -category: feature -feature: Optimization of IPI virtualization -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6Y34T - -Intel-SIG: commit 19e2a9fb9da0 ("target/i386: Set maximum APIC ID to KVM prior to vCPU creation") - ------------------------------------------------- - -Specify maximum possible APIC ID assigned for current VM session to KVM -prior to the creation of vCPUs. By this setting, KVM can set up VM-scoped -data structure indexed by the APIC ID, e.g. Posted-Interrupt Descriptor -pointer table to support Intel IPI virtualization, with the most optimal -memory footprint. - -It can be achieved by calling KVM_ENABLE_CAP for KVM_CAP_MAX_VCPU_ID -capability once KVM has enabled it. Ignoring the return error if KVM -doesn't support this capability yet. - -Signed-off-by: Zeng Guang -Acked-by: Peter Xu -Acked-by: Michael S. Tsirkin -Message-Id: <20220825025246.26618-1-guang.zeng@intel.com> -Signed-off-by: Paolo Bonzini -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - hw/i386/x86.c | 4 ++++ - target/i386/kvm/kvm-stub.c | 5 +++++ - target/i386/kvm/kvm.c | 5 +++++ - target/i386/kvm/kvm_i386.h | 2 ++ - 4 files changed, 16 insertions(+) - -diff --git a/hw/i386/x86.c b/hw/i386/x86.c -index f64639b873..a3258d78fa 100644 ---- a/hw/i386/x86.c -+++ b/hw/i386/x86.c -@@ -152,6 +152,10 @@ void x86_cpus_init(X86MachineState *x86ms, int default_cpu_version) - exit(EXIT_FAILURE); - } - -+ if (kvm_enabled()) { -+ kvm_set_max_apic_id(x86ms->apic_id_limit); -+ } -+ - possible_cpus = mc->possible_cpu_arch_ids(ms); - for (i = 0; i < ms->smp.cpus; i++) { - x86_cpu_new(x86ms, possible_cpus->cpus[i].arch_id, &error_fatal); -diff --git a/target/i386/kvm/kvm-stub.c b/target/i386/kvm/kvm-stub.c -index f6e7e4466e..e052f1c7b0 100644 ---- a/target/i386/kvm/kvm-stub.c -+++ b/target/i386/kvm/kvm-stub.c -@@ -44,3 +44,8 @@ bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp) - { - abort(); - } -+ -+void kvm_set_max_apic_id(uint32_t max_apic_id) -+{ -+ return; -+} -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index b8257e7e5f..7212ed98a9 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -5270,3 +5270,8 @@ void kvm_arch_accel_class_init(ObjectClass *oc) - "Clock cycles without an event window " - "after which a notification VM exit occurs"); - } -+ -+void kvm_set_max_apic_id(uint32_t max_apic_id) -+{ -+ kvm_vm_enable_cap(kvm_state, KVM_CAP_MAX_VCPU_ID, 0, max_apic_id); -+} -diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h -index 4124912c20..58590138e5 100644 ---- a/target/i386/kvm/kvm_i386.h -+++ b/target/i386/kvm/kvm_i386.h -@@ -54,4 +54,6 @@ uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address); - bool kvm_enable_sgx_provisioning(KVMState *s); - void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask); - -+void kvm_set_max_apic_id(uint32_t max_apic_id); -+ - #endif --- -2.27.0 - diff --git a/target-i386-add-FSRM-to-TCG.patch b/target-i386-add-FSRM-to-TCG.patch deleted file mode 100644 index e3536ace803173dbde26d5a60a2aa30a3f95f9c3..0000000000000000000000000000000000000000 --- a/target-i386-add-FSRM-to-TCG.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 2a2b5f93c2ee2071eb32c65f925974d02c11808d Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 27 Feb 2023 10:57:09 +0100 -Subject: [PATCH] target/i386: add FSRM to TCG - -mainline inclusion -from mainline-v8.0.0-rc0 -commit c0728d4e3d23356691e4182eac54c67e1ca26618 -category: feature -feature: Intel fast REP string operations support -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I6ZGIX - -Intel-SIG: commit c0728d4e3d23 ("target/i386: add FSRM to TCG") - -------------------------------------- - -target/i386: add FSRM to TCG - -Fast short REP MOVS can be added to TCG, since a trivial translation -of string operation is a good option for short lengths. - -Reviewed-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini -Signed-off-by: Aichun Shi ---- - target/i386/cpu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 61cd7abcaa..13dcd4c720 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -660,7 +660,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - #define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | \ - /* CPUID_7_0_ECX_OSPKE is dynamic */ \ - CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS) --#define TCG_7_0_EDX_FEATURES 0 -+#define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM - #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ - CPUID_7_1_EAX_FSRC) - #define TCG_APM_FEATURES 0 --- -2.27.0 - diff --git a/target-i386-add-FZRM-FSRS-FSRC.patch b/target-i386-add-FZRM-FSRS-FSRC.patch deleted file mode 100644 index 2077add338175e88fc5cd3752be19d82c076d2ee..0000000000000000000000000000000000000000 --- a/target-i386-add-FZRM-FSRS-FSRC.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 37ef938fd9cdea1c9f87b17f49a935f729374f1d Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 27 Feb 2023 10:55:46 +0100 -Subject: [PATCH] target/i386: add FZRM, FSRS, FSRC - -These are three more markers for string operation optimizations. -They can all be added to TCG, whose string operations are more or -less as fast as they can be for short lengths. - -Reviewed-by: Xiaoyao Li -Signed-off-by: Paolo Bonzini ---- - target/i386/cpu.c | 7 ++++--- - target/i386/cpu.h | 7 +++++++ - 2 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index e3cea8397c..7122af303d 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -661,7 +661,8 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - /* CPUID_7_0_ECX_OSPKE is dynamic */ \ - CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS) - #define TCG_7_0_EDX_FEATURES 0 --#define TCG_7_1_EAX_FEATURES 0 -+#define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \ -+ CPUID_7_1_EAX_FSRC) - #define TCG_APM_FEATURES 0 - #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT - #define TCG_XSAVE_FEATURES (CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1) -@@ -871,8 +872,8 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .feat_names = { - NULL, NULL, NULL, NULL, - "avx-vnni", "avx512-bf16", NULL, NULL, -- NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, NULL, "fzrm", "fsrs", -+ "fsrc", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 4f7fa87b95..7a32dabf12 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -876,6 +876,13 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) - /* AVX512 BFloat16 Instruction */ - #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) -+/* Fast Zero REP MOVS */ -+#define CPUID_7_1_EAX_FZRM (1U << 10) -+/* Fast Short REP STOS */ -+#define CPUID_7_1_EAX_FSRS (1U << 11) -+/* Fast Short REP CMPS/SCAS */ -+#define CPUID_7_1_EAX_FSRC (1U << 12) -+ - /* XFD Extend Feature Disabled */ - #define CPUID_D_1_EAX_XFD (1U << 4) - --- -2.27.0 - diff --git a/target-i386-add-support-for-FB_CLEAR-feature.patch b/target-i386-add-support-for-FB_CLEAR-feature.patch deleted file mode 100644 index 621864375f71f8284080aba51d36ca69422836cb..0000000000000000000000000000000000000000 --- a/target-i386-add-support-for-FB_CLEAR-feature.patch +++ /dev/null @@ -1,62 +0,0 @@ -From fb84b9baa665ffa4596fd871537e0544d60e40fc Mon Sep 17 00:00:00 2001 -From: Emanuele Giuseppe Esposito -Date: Wed, 1 Feb 2023 08:57:59 -0500 -Subject: [PATCH] target/i386: add support for FB_CLEAR feature - -commit 22e1094ca82d5518c1b69aff3e87c550776ae1eb upstream. - -As reported by the Intel's doc: -"FB_CLEAR: The processor will overwrite fill buffer values as part of -MD_CLEAR operations with the VERW instruction. -On these processors, L1D_FLUSH does not overwrite fill buffer values." - -If this cpu feature is present in host, allow QEMU to choose whether to -show it to the guest too. -One disadvantage of not exposing it is that the guest will report -a non existing vulnerability in -/sys/devices/system/cpu/vulnerabilities/mmio_stale_data -because the mitigation is present only when the cpu has - (FLUSH_L1D and MD_CLEAR) or FB_CLEAR -features enabled. - -Intel-SIG: commit 22e1094ca82d ("target/i386: add support for FB_CLEAR feature") -Backport support for FB_CLEAR feature - -Signed-off-by: Emanuele Giuseppe Esposito -Message-Id: <20230201135759.555607-3-eesposit@redhat.com> -Signed-off-by: Paolo Bonzini -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 512bec3ca3..8adc84b7f9 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -982,7 +982,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - "ssb-no", "mds-no", "pschange-mc-no", "tsx-ctrl", - "taa-no", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -- NULL, NULL, NULL, NULL, -+ NULL, "fb-clear", NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 9e094ef934..d9aac5acd2 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -962,6 +962,7 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define MSR_ARCH_CAP_PSCHANGE_MC_NO (1U << 6) - #define MSR_ARCH_CAP_TSX_CTRL_MSR (1U << 7) - #define MSR_ARCH_CAP_TAA_NO (1U << 8) -+#define MSR_ARCH_CAP_FB_CLEAR (1U << 17) - - #define MSR_CORE_CAP_SPLIT_LOCK_DETECT (1U << 5) - --- -2.41.0.windows.1 - diff --git a/target-i386-add-support-for-FLUSH_L1D-feature.patch b/target-i386-add-support-for-FLUSH_L1D-feature.patch deleted file mode 100644 index 1853829386d65154b5ae8260e2bb4833314feb08..0000000000000000000000000000000000000000 --- a/target-i386-add-support-for-FLUSH_L1D-feature.patch +++ /dev/null @@ -1,61 +0,0 @@ -From dd635e4b0340a426333b466a2222e5848dfda42c Mon Sep 17 00:00:00 2001 -From: Emanuele Giuseppe Esposito -Date: Wed, 1 Feb 2023 08:57:58 -0500 -Subject: [PATCH] target/i386: add support for FLUSH_L1D feature - -commit 0e7e3bf1a552c178924867fa7c2f30ccc8a179e0 upstream. - -As reported by Intel's doc: -"L1D_FLUSH: Writeback and invalidate the L1 data cache" - -If this cpu feature is present in host, allow QEMU to choose whether to -show it to the guest too. -One disadvantage of not exposing it is that the guest will report -a non existing vulnerability in -/sys/devices/system/cpu/vulnerabilities/mmio_stale_data -because the mitigation is present only when the cpu has - (FLUSH_L1D and MD_CLEAR) or FB_CLEAR -features enabled. - -Intel-SIG: commit 0e7e3bf1a552 ("target/i386: add support for FLUSH_L1D feature") -Backport support for FLUSH_L1D feature - -Signed-off-by: Emanuele Giuseppe Esposito -Message-Id: <20230201135759.555607-2-eesposit@redhat.com> -Signed-off-by: Paolo Bonzini -[ jason: amend commit log ] -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 2 +- - target/i386/cpu.h | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 66b5eaa14e..512bec3ca3 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -858,7 +858,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - "tsx-ldtrk", NULL, NULL /* pconfig */, NULL, - NULL, NULL, "amx-bf16", "avx512-fp16", - "amx-tile", "amx-int8", "spec-ctrl", "stibp", -- NULL, "arch-capabilities", "core-capability", "ssbd", -+ "flush-l1d", "arch-capabilities", "core-capability", "ssbd", - }, - .cpuid = { - .eax = 7, -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index d0c7791a1e..9e094ef934 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -869,6 +869,8 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w, - #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) - /* Single Thread Indirect Branch Predictors */ - #define CPUID_7_0_EDX_STIBP (1U << 27) -+/* Flush L1D cache */ -+#define CPUID_7_0_EDX_FLUSH_L1D (1U << 28) - /* Arch Capabilities */ - #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29) - /* Core Capability */ --- -2.41.0.windows.1 - diff --git a/target-i386-cpu-Improve-error-message-for-property-v.patch b/target-i386-cpu-Improve-error-message-for-property-v.patch deleted file mode 100644 index 462d4877ef1b5836e15e636f41a5050972c2fdd0..0000000000000000000000000000000000000000 --- a/target-i386-cpu-Improve-error-message-for-property-v.patch +++ /dev/null @@ -1,45 +0,0 @@ -From dca8f8c8bc4466d2502bcd305fcc8e84adf992da Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Mon, 27 Nov 2023 10:20:40 +0800 -Subject: [PATCH] target/i386/cpu: Improve error message for property "vendor" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from 298d8b122056052951bda487392d8aabbfd0f3e5 - -Improve - - $ qemu-system-x86_64 -device max-x86_64-cpu,vendor=me - qemu-system-x86_64: -device max-x86_64-cpu,vendor=me: Property '.vendor' doesn't take value 'me' - -to - - qemu-system-x86_64: -device max-x86_64-cpu,vendor=0123456789abc: value of property 'vendor' must consist of exactly 12 characters - -Signed-off-by: Markus Armbruster -Message-ID: <20231031111059.3407803-8-armbru@redhat.com> -Reviewed-by: Philippe Mathieu-Daudé - -Signed-off-by: boringandboring ---- - target/i386/cpu.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 6aaa730a0d..53a7484ca8 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -4805,7 +4805,8 @@ 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, "value of property 'vendor' must consist of" -+ " exactly " stringify(CPUID_VENDOR_SZ) " characters"); - return; - } - --- -2.27.0 - diff --git a/target-i386-fix-INVD-vmexit.patch b/target-i386-fix-INVD-vmexit.patch deleted file mode 100644 index 2e9a1601a4e22d2242cb440fe38f1a35f8c6c003..0000000000000000000000000000000000000000 --- a/target-i386-fix-INVD-vmexit.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b17eea58c7497f96cb66d31b8c59fdcdb06b6c40 Mon Sep 17 00:00:00 2001 -From: jipengfei_yewu -Date: Sun, 24 Sep 2023 19:43:41 +0800 -Subject: [PATCH] target/i386: fix INVD vmexit - -Due to a typo or perhaps a brain fart, the INVD vmexit was never generated. -Fix it (but not that fixing just the typo would break both INVD and WBINVD, -due to a case of two wrongs making a right). - -cheery-pick from 4d714d1a0bf1fca9576ee53a1a5dfa3fd5ddae99 - -Signed-off-by: jipengfei_yewu -Reviewed-by: Richard Henderson -Signed-off-by: Paolo Bonzini ---- - target/i386/tcg/translate.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c -index e9e1451540..82f77b52fb 100644 ---- a/target/i386/tcg/translate.c -+++ b/target/i386/tcg/translate.c -@@ -7773,7 +7773,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) - case 0x108: /* invd */ - case 0x109: /* wbinvd */ - if (check_cpl0(s)) { -- gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD); -+ gen_svm_check_intercept(s, (b & 1) ? SVM_EXIT_WBINVD : SVM_EXIT_INVD); - /* nothing to do */ - } - break; --- -2.41.0.windows.1 - diff --git a/target-i386-kvm-do-not-access-uninitialized-variable.patch b/target-i386-kvm-do-not-access-uninitialized-variable.patch deleted file mode 100644 index 3af5ef72f25d8be2045c59315c8cd84363d90e37..0000000000000000000000000000000000000000 --- a/target-i386-kvm-do-not-access-uninitialized-variable.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 550d43a946b61bdadb418e0f8bef8b98e646276d Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 18 Mar 2022 16:23:47 +0100 -Subject: [PATCH 09/10] target/i386: kvm: do not access uninitialized variable - on older kernels - -from mainline-v7.0.0-rc1 -commit 3ec5ad40081b14af28496198b4d08dbe13386790 -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit 3ec5ad40081b ("target/i386: kvm: do not access -uninitialized variable on older kernels") - ---------------------------------------------------------- - -target/i386: kvm: do not access uninitialized variable on older kernels - -KVM support for AMX includes a new system attribute, KVM_X86_XCOMP_GUEST_SUPP. -Commit 19db68ca68 ("x86: Grant AMX permission for guest", 2022-03-15) however -did not fully consider the behavior on older kernels. First, it warns -too aggressively. Second, it invokes the KVM_GET_DEVICE_ATTR ioctl -unconditionally and then uses the "bitmask" variable, which remains -uninitialized if the ioctl fails. Third, kvm_ioctl returns -errno rather -than -1 on errors. - -While at it, explain why the ioctl is needed and KVM_GET_SUPPORTED_CPUID -is not enough. - -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/kvm/kvm.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 49fca5ea88..20e418463d 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -409,6 +409,12 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, - } - } else if (function == 0xd && index == 0 && - (reg == R_EAX || reg == R_EDX)) { -+ /* -+ * The value returned by KVM_GET_SUPPORTED_CPUID does not include -+ * features that still have to be enabled with the arch_prctl -+ * system call. QEMU needs the full value, which is retrieved -+ * with KVM_GET_DEVICE_ATTR. -+ */ - struct kvm_device_attr attr = { - .group = 0, - .attr = KVM_X86_XCOMP_GUEST_SUPP, -@@ -417,13 +423,16 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, - - bool sys_attr = kvm_check_extension(s, KVM_CAP_SYS_ATTRIBUTES); - if (!sys_attr) { -- warn_report("cannot get sys attribute capabilities %d", sys_attr); -+ return ret; - } - - int rc = kvm_ioctl(s, KVM_GET_DEVICE_ATTR, &attr); -- if (rc == -1 && (errno == ENXIO || errno == EINVAL)) { -- warn_report("KVM_GET_DEVICE_ATTR(0, KVM_X86_XCOMP_GUEST_SUPP) " -- "error: %d", rc); -+ if (rc < 0) { -+ if (rc != -ENXIO) { -+ warn_report("KVM_GET_DEVICE_ATTR(0, KVM_X86_XCOMP_GUEST_SUPP) " -+ "error: %d", rc); -+ } -+ return ret; - } - ret = (reg == R_EAX) ? bitmask : bitmask >> 32; - } else if (function == 0x80000001 && reg == R_ECX) { --- -2.27.0 - diff --git a/target-i386-kvm-fix-kvmclock_current_nsec-Assertion-.patch b/target-i386-kvm-fix-kvmclock_current_nsec-Assertion-.patch deleted file mode 100644 index 5153ba71a68b4df62b1153d9a213c454c918ef63..0000000000000000000000000000000000000000 --- a/target-i386-kvm-fix-kvmclock_current_nsec-Assertion-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f53c352a12a0785ff4e83aaeaec7245384538d6a Mon Sep 17 00:00:00 2001 -From: cmss_dx -Date: Mon, 28 Nov 2022 03:10:06 +0000 -Subject: [PATCH 29/29] target/i386/kvm: fix kvmclock_current_nsec: Assertion - `time.tsc_timestamp <= migration_tsc' failed mainline inclusion from - mainline-v7.2.0-rc2 commit c4ef867f2949bf2a2ae18a4e27cf1a34bbc8aecb category: - bugfix - --------------------------------- - -New KVM_CLOCK flags were added in the kernel.(c68dc1b577eabd5605c6c7c08f3e07ae18d30d5d) -``` -+ #define KVM_CLOCK_VALID_FLAGS \ -+ (KVM_CLOCK_TSC_STABLE | KVM_CLOCK_REALTIME | KVM_CLOCK_HOST_TSC) - - case KVM_CAP_ADJUST_CLOCK: -- r = KVM_CLOCK_TSC_STABLE; -+ r = KVM_CLOCK_VALID_FLAGS; -``` - -kvm_has_adjust_clock_stable needs to handle additional flags, -so that s->clock_is_reliable can be true and kvmclock_current_nsec doesn't need to be called. - -Signed-off-by: Ray Zhang -Message-Id: <20220922100523.2362205-1-zhanglei002@gmail.com> -Signed-off-by: Paolo Bonzini - - -Signed-off-by: cmss_dx ---- - target/i386/kvm/kvm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 20e418463d..5b15e0430b 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -151,7 +151,7 @@ bool kvm_has_adjust_clock_stable(void) - { - int ret = kvm_check_extension(kvm_state, KVM_CAP_ADJUST_CLOCK); - -- return (ret == KVM_CLOCK_TSC_STABLE); -+ return (ret & KVM_CLOCK_TSC_STABLE); - } - - bool kvm_has_adjust_clock(void) --- -2.27.0 - diff --git a/target-imx-reload-cmp-timer-outside-of-the-reload-pt.patch b/target-imx-reload-cmp-timer-outside-of-the-reload-pt.patch deleted file mode 100644 index 273989a70d9344f63702f70b1a4cbd40dc56a2fb..0000000000000000000000000000000000000000 --- a/target-imx-reload-cmp-timer-outside-of-the-reload-pt.patch +++ /dev/null @@ -1,43 +0,0 @@ -From bdd1741cf18959e70cdfc6f46bb41d9209e86315 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Thu, 24 Nov 2022 17:18:00 +0800 -Subject: [PATCH 18/29] target/imx: reload cmp timer outside of the reload - ptimer transaction - -When running seL4 tests (https://docs.sel4.systems/projects/sel4test) -on the sabrelight platform, the timer tests fail. The arm/imx6 EPIT -timer interrupt does not fire properly, instead of a e.g. second in -can take up to a minute to finally see the interrupt. -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1263 - -Signed-off-by: Axel Heider -Signed-off-by: jianchunfu ---- - hw/timer/imx_epit.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c -index ebd58254d1..a78b625d15 100644 ---- a/hw/timer/imx_epit.c -+++ b/hw/timer/imx_epit.c -@@ -275,10 +275,15 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value, - /* If IOVW bit is set then set the timer value */ - ptimer_set_count(s->timer_reload, s->lr); - } -- -+ /* -+ * Commit the change to s->timer_reload, so it can propagate. Otherwise -+ * the timer interrupt may not fire properly. The commit must happen -+ * before calling imx_epit_reload_compare_timer(), which reads -+ * s->timer_reload internally again. -+ */ -+ ptimer_transaction_commit(s->timer_reload); - imx_epit_reload_compare_timer(s); - ptimer_transaction_commit(s->timer_cmp); -- ptimer_transaction_commit(s->timer_reload); - break; - - case 3: /* CMP */ --- -2.27.0 - diff --git a/target-ppc-Fix-the-order-of-kvm_enable-judgment-abou.patch b/target-ppc-Fix-the-order-of-kvm_enable-judgment-abou.patch deleted file mode 100644 index 9485b039f10828edaa14d2d3f1a4683d4c70f25f..0000000000000000000000000000000000000000 --- a/target-ppc-Fix-the-order-of-kvm_enable-judgment-abou.patch +++ /dev/null @@ -1,57 +0,0 @@ -From ba1e022f06300e6dafc7e89a4f3fe756dc9691dd Mon Sep 17 00:00:00 2001 -From: JianChunfu -Date: Wed, 20 Sep 2023 18:58:00 +0800 -Subject: [PATCH] target/ppc: Fix the order of kvm_enable judgment about - kvmppc_set_interrupt() - -It's unnecessary for non-KVM accelerators(TCG, for example), -to call this function, so change the order of kvm_enable() judgment. -The static inline function that returns -1 directly does not work -in TCG's situation. - -Signed-off-by: JianChunfu ---- - hw/ppc/ppc.c | 8 ++++++-- - target/ppc/kvm.c | 2 +- - 2 files changed, 7 insertions(+), 3 deletions(-) - -diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c -index e8127599c9..cf90ab7805 100644 ---- a/hw/ppc/ppc.c -+++ b/hw/ppc/ppc.c -@@ -66,7 +66,9 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) - } - - if (old_pending != env->pending_interrupts) { -- kvmppc_set_interrupt(cpu, n_IRQ, level); -+ if (kvm_enabled()) { -+ kvmppc_set_interrupt(cpu, irq, level); -+ } - } - - -@@ -1461,5 +1463,7 @@ void ppc_irq_reset(PowerPCCPU *cpu) - CPUPPCState *env = &cpu->env; - - env->irq_input_state = 0; -- kvmppc_set_interrupt(cpu, PPC_INTERRUPT_EXT, 0); -+ if (kvm_enabled()) { -+ kvmppc_set_interrupt(cpu, PPC_INTERRUPT_EXT, 0); -+ } - } -diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index d73563045b..397b1e902b 100644 ---- a/target/ppc/kvm.c -+++ b/target/ppc/kvm.c -@@ -1323,7 +1323,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) - return 0; - } - -- if (!kvm_enabled() || !cap_interrupt_unset) { -+ if (!cap_interrupt_unset) { - return 0; - } - --- -2.41.0.windows.1 - diff --git a/target-ppc-Fix-tlbie.patch b/target-ppc-Fix-tlbie.patch deleted file mode 100644 index 63d3ebb86b56b9728a236cf16f1ea092c0e9ae5d..0000000000000000000000000000000000000000 --- a/target-ppc-Fix-tlbie.patch +++ /dev/null @@ -1,47 +0,0 @@ -From aba3dd63d054cd21054e295d5a9d493cb9d7a75f Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 26 Sep 2023 06:25:04 +0000 -Subject: [PATCH] target/ppc: Fix tlbie mainline inclusion commit - 4ddc104689b186c4e4ed30be59a54463501761cf category: bugfix - ---------------------------------------------------------------- - -Commit 74c4912f097bab98 changed check_tlb_flush() to use -tlb_flush_all_cpus_synced() instead of calling tlb_flush() on each -CPU. However, as side effect of this, a CPU executing a ptesync -after a tlbie will have its TLB flushed only after exiting its -current Translation Block (TB). - -This causes memory accesses to invalid pages to succeed, if they -happen to be on the same TB as the ptesync. - -To fix this, use tlb_flush_all_cpus() instead, that immediately -flushes the TLB of the CPU executing the ptesync instruction. - -Fixes: 74c4912f097bab98 ("target/ppc: Fix synchronization of mttcg with broadcast TLB flushes") -Signed-off-by: Leandro Lupori -Reviewed-by: Fabiano Rosas -Message-Id: <20220503163904.22575-1-leandro.lupori@eldorado.org.br> -Signed-off-by: Daniel Henrique Barboza - -Signed-off-by: tangbinzy ---- - target/ppc/helper_regs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c -index 99562edd57..e97d25e9ab 100644 ---- a/target/ppc/helper_regs.c -+++ b/target/ppc/helper_regs.c -@@ -288,7 +288,7 @@ void check_tlb_flush(CPUPPCState *env, bool global) - if (global && (env->tlb_need_flush & TLB_NEED_GLOBAL_FLUSH)) { - env->tlb_need_flush &= ~TLB_NEED_GLOBAL_FLUSH; - env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH; -- tlb_flush_all_cpus_synced(cs); -+ tlb_flush_all_cpus(cs); - return; - } - --- -2.41.0.windows.1 - diff --git a/target-ppc-add-error-report-when-fopen-fails-in-kvmp.patch b/target-ppc-add-error-report-when-fopen-fails-in-kvmp.patch deleted file mode 100644 index 6c0c8a19e865d1e99faf0131f33ab0896144983e..0000000000000000000000000000000000000000 --- a/target-ppc-add-error-report-when-fopen-fails-in-kvmp.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 67a8e57c784ccbce4989c39dd44c70ae7f5aeda4 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Thu, 4 Aug 2022 15:37:47 +0800 -Subject: [PATCH 5/9] target/ppc: add error report when fopen fails in - kvmppc_read_int_dt() - -Use an Error pointer to report the error back to the caller. -While we're at it, return '0' instead of '-1' on error since the -function is supposed to return an uint64_t. - -Signed-off-by: jianchunfu ---- - target/ppc/kvm.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index dc93b99189..63382256c3 100644 ---- a/target/ppc/kvm.c -+++ b/target/ppc/kvm.c -@@ -1895,7 +1895,7 @@ static int kvmppc_find_cpu_dt(char *buf, int buf_len) - return 0; - } - --static uint64_t kvmppc_read_int_dt(const char *filename) -+static uint64_t kvmppc_read_int_dt(const char *filename, Error **errp) - { - union { - uint32_t v32; -@@ -1906,7 +1906,8 @@ static uint64_t kvmppc_read_int_dt(const char *filename) - - f = fopen(filename, "rb"); - if (!f) { -- return -1; -+ error_setg_errno(errp, errno, "error opening %s", filename); -+ return 0; - } - - len = fread(&u, 1, sizeof(u), f); -@@ -1937,7 +1938,7 @@ static uint64_t kvmppc_read_int_cpu_dt(const char *propname) - } - - tmp = g_strdup_printf("%s/%s", buf, propname); -- val = kvmppc_read_int_dt(tmp); -+ val = kvmppc_read_int_dt(tmp, NULL); - g_free(tmp); - - return val; --- -2.27.0 - diff --git a/target-ppc-cpu-models-Remove-the-default-CPU-alias.patch b/target-ppc-cpu-models-Remove-the-default-CPU-alias.patch deleted file mode 100644 index 048ca97c37788c5137a63877b726accc13f9b17b..0000000000000000000000000000000000000000 --- a/target-ppc-cpu-models-Remove-the-default-CPU-alias.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 73ece819848b2ecc110ec676413d5a86ffc0f8fc Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:26:10 -0800 -Subject: [PATCH] target/ppc/cpu-models: Remove the "default" CPU alias -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 7886605961d0a9c40ada0c28dee5fa0b42a30836 - -QEMU emulates a *lot* of PowerPC-based machines - having a CPU -that is named "default" and cannot be used with most of those -machines sounds just wrong. Thus let's remove this old and confusing -alias now. - -Signed-off-by: Thomas Huth -Reviewed-by: Greg Kurz -Reviewed-by: Cédric Le Goater -Message-Id: <20220705151030.662140-1-thuth@redhat.com> -Signed-off-by: Daniel Henrique Barboza -Signed-off-by: Wanghe Xiao ---- - target/ppc/cpu-models.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c -index 4baa111713..02efc95723 100644 ---- a/target/ppc/cpu-models.c -+++ b/target/ppc/cpu-models.c -@@ -963,6 +963,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { - #endif - { "ppc32", "604" }, - { "ppc", "604" }, -- { "default", "604" }, -+ - { NULL, NULL } - }; --- -2.27.0 - diff --git a/target-ppc-enhance-error-report-in-kvmppc_read_int_c.patch b/target-ppc-enhance-error-report-in-kvmppc_read_int_c.patch deleted file mode 100644 index c05844adc531e8046ab25a139b2ea87fef59e3d2..0000000000000000000000000000000000000000 --- a/target-ppc-enhance-error-report-in-kvmppc_read_int_c.patch +++ /dev/null @@ -1,81 +0,0 @@ -From b167d664414e7d4a5a7a7058bc4c7699f6e66d48 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Thu, 4 Aug 2022 15:57:46 +0800 -Subject: [PATCH 6/9] target/ppc: enhance error report in - kvmppc_read_int_cpu_dt() - -First and foremost, the function can't return '-1' when an error occurs -because the return type is set to uint64_t. Let's fix that. -After that, the function can't simply return 0 whether an error happened -and call it a day. We must provide a way of letting callers know if the -zero return is legitimate or due to an error. -Add an Error pointer to kvmppc_read_int_cpu_dt() that will be filled -with an appropriate error, if one occurs. Callers are then free to pass -an Error pointer and handle it. - -Signed-off-by: jianchunfu ---- - target/ppc/kvm.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - -diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index 63382256c3..d64d7c5b4a 100644 ---- a/target/ppc/kvm.c -+++ b/target/ppc/kvm.c -@@ -1925,20 +1925,22 @@ static uint64_t kvmppc_read_int_dt(const char *filename, Error **errp) - - /* - * Read a CPU node property from the host device tree that's a single -- * integer (32-bit or 64-bit). Returns 0 if anything goes wrong -- * (can't find or open the property, or doesn't understand the format) -+ * integer (32-bit or 64-bit). Returns 0 and set errp if anything goes -+ * wrong (can't find or open the property, or doesn't understand the -+ * format) - */ --static uint64_t kvmppc_read_int_cpu_dt(const char *propname) -+static uint64_t kvmppc_read_int_cpu_dt(const char *propname, Error **errp) - { - char buf[PATH_MAX], *tmp; - uint64_t val; - - if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { -- return -1; -+ error_setg(errp, "Failed to read CPU property %s", propname); -+ return 0; - } - - tmp = g_strdup_printf("%s/%s", buf, propname); -- val = kvmppc_read_int_dt(tmp, NULL); -+ val = kvmppc_read_int_dt(tmp, errp); - g_free(tmp); - - return val; -@@ -1946,12 +1948,12 @@ static uint64_t kvmppc_read_int_cpu_dt(const char *propname) - - uint64_t kvmppc_get_clockfreq(void) - { -- return kvmppc_read_int_cpu_dt("clock-frequency"); -+ return kvmppc_read_int_cpu_dt("clock-frequency", NULL); - } - - static int kvmppc_get_dec_bits(void) - { -- int nr_bits = kvmppc_read_int_cpu_dt("ibm,dec-bits"); -+ int nr_bits = kvmppc_read_int_cpu_dt("ibm,dec-bits", NULL); - - if (nr_bits > 0) { - return nr_bits; -@@ -2336,8 +2338,8 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on) - static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data) - { - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); -- uint32_t dcache_size = kvmppc_read_int_cpu_dt("d-cache-size"); -- uint32_t icache_size = kvmppc_read_int_cpu_dt("i-cache-size"); -+ uint32_t dcache_size = kvmppc_read_int_cpu_dt("d-cache-size", NULL); -+ uint32_t icache_size = kvmppc_read_int_cpu_dt("i-cache-size", NULL); - - /* Now fix up the class with information we can query from the host */ - pcc->pvr = mfpvr(); --- -2.27.0 - diff --git a/target-ppc-exit-1-on-failure-in-kvmppc_get_clockfreq.patch b/target-ppc-exit-1-on-failure-in-kvmppc_get_clockfreq.patch deleted file mode 100644 index 140f2fd7f3ac3f77a78705e86a079896cc6f13ad..0000000000000000000000000000000000000000 --- a/target-ppc-exit-1-on-failure-in-kvmppc_get_clockfreq.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 584a648e0de0b0bda49e87349f2db3b2f0f87c33 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Thu, 4 Aug 2022 16:47:26 +0800 -Subject: [PATCH 8/9] target/ppc: exit(1) on failure in kvmppc_get_clockfreq() - -When running under KVM accel it is expected to have 'clock-frequency' in -the DT. Not having this attribute is too risky for both the machine -emulation and userspace. -We have a way of telling whether this error scenario might happen or not -via kvmppc_read_int_cpu_dt() now being able to report errors. From now -on, when running KVM, we will assume that 'clock-frequency' will always -be present in the DT. - -Signed-off-by: jianchunfu ---- - target/ppc/kvm.c | 17 ++++++++++++++++- - 1 file changed, 16 insertions(+), 1 deletion(-) - -diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index 1a6c6b6fa0..d73563045b 100644 ---- a/target/ppc/kvm.c -+++ b/target/ppc/kvm.c -@@ -1944,9 +1944,24 @@ static uint64_t kvmppc_read_int_cpu_dt(const char *propname, Error **errp) - return kvmppc_read_int_dt(tmp, errp); - } - -+/* -+ * Read the clock-frequency from the DT. On error (e.g. -+ * 'clock-frequency' is not present in the DT) will -+ * report an error and exit(1). -+ */ - uint64_t kvmppc_get_clockfreq(void) - { -- return kvmppc_read_int_cpu_dt("clock-frequency", NULL); -+ Error *local_err = NULL; -+ int ret; -+ -+ ret = kvmppc_read_int_cpu_dt("clock-frequency", &local_err); -+ -+ if (local_err) { -+ error_report_err(local_err); -+ exit(1); -+ } -+ -+ return ret; - } - - static int kvmppc_get_dec_bits(void) --- -2.27.0 - diff --git a/target-ppc-use-g_autofree-in-kvmppc_read_int_cpu_dt.patch b/target-ppc-use-g_autofree-in-kvmppc_read_int_cpu_dt.patch deleted file mode 100644 index 7ffb9733069ec41baa9155c92731b2ad43774253..0000000000000000000000000000000000000000 --- a/target-ppc-use-g_autofree-in-kvmppc_read_int_cpu_dt.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 02a15861235d29dcf89b61bf88fed2ec4ccee9dc Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Thu, 4 Aug 2022 16:41:35 +0800 -Subject: [PATCH 7/9] target/ppc: use g_autofree in kvmppc_read_int_cpu_dt() - -This spares us a g_free() call. Let's also not use 'val' and return the -value of kvmppc_read_int_dt() directly. - -Signed-off-by: jianchunfu ---- - target/ppc/kvm.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c -index d64d7c5b4a..1a6c6b6fa0 100644 ---- a/target/ppc/kvm.c -+++ b/target/ppc/kvm.c -@@ -1931,8 +1931,8 @@ static uint64_t kvmppc_read_int_dt(const char *filename, Error **errp) - */ - static uint64_t kvmppc_read_int_cpu_dt(const char *propname, Error **errp) - { -- char buf[PATH_MAX], *tmp; -- uint64_t val; -+ g_autofree char *tmp = NULL; -+ char buf[PATH_MAX]; - - if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { - error_setg(errp, "Failed to read CPU property %s", propname); -@@ -1940,10 +1940,8 @@ static uint64_t kvmppc_read_int_cpu_dt(const char *propname, Error **errp) - } - - tmp = g_strdup_printf("%s/%s", buf, propname); -- val = kvmppc_read_int_dt(tmp, errp); -- g_free(tmp); - -- return val; -+ return kvmppc_read_int_dt(tmp, errp); - } - - uint64_t kvmppc_get_clockfreq(void) --- -2.27.0 - diff --git a/target-riscv-pmp-fix-no-pmp-illegal-intrs.patch b/target-riscv-pmp-fix-no-pmp-illegal-intrs.patch deleted file mode 100644 index b10f7d0fef451d564ccd818b3a13ed092f86a5a9..0000000000000000000000000000000000000000 --- a/target-riscv-pmp-fix-no-pmp-illegal-intrs.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 5489264cd9583855d45fd0c21f18387b649f6e44 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 23 Nov 2022 15:26:59 +0300 -Subject: [PATCH 15/29] target/riscv/pmp: fix no pmp illegal intrs - -mainline inclusion -commit 0fbb5d2d3c9ded9fbd3f6f993974cc5e88e28912 -category: bugfix - ------------------------------------------------ - -As per the privilege specification, any access from S/U mode should fail -if no pmp region is configured and pmp is present, othwerwise access -should succeed. - -Fixes: d102f19a208 (target/riscv/pmp: Raise exception if no PMP entry is configured) -Signed-off-by: Nikita Shubin -Reviewed-by: Alistair Francis -Message-id: 20211214092659.15709-1-nikita.shubin@maquefel.me -Signed-off-by: Alistair Francis - -Signed-off-by: tangbinzy ---- - target/riscv/op_helper.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c -index ee7c24efe7..58d992e98a 100644 ---- a/target/riscv/op_helper.c -+++ b/target/riscv/op_helper.c -@@ -146,7 +146,8 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb) - uint64_t mstatus = env->mstatus; - target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP); - -- if (!pmp_get_num_rules(env) && (prev_priv != PRV_M)) { -+ if (riscv_feature(env, RISCV_FEATURE_PMP) && -+ !pmp_get_num_rules(env) && (prev_priv != PRV_M)) { - riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); - } - --- -2.27.0 - diff --git a/tcg-Reduce-tcg_assert_listed_vecop-scope.patch b/tcg-Reduce-tcg_assert_listed_vecop-scope.patch deleted file mode 100644 index 15f46f796b48121394e93f17f2073af11bbccc15..0000000000000000000000000000000000000000 --- a/tcg-Reduce-tcg_assert_listed_vecop-scope.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 61af18384a150a2c7d1f54521692a93c0e4ebacc Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Sun, 2 Jul 2023 23:37:42 +0800 -Subject: [PATCH] tcg: Reduce tcg_assert_listed_vecop() scope - - tcg_assert_listed_vecop() is only used in tcg-op-vec.c. - - Signed-off-by: Philippe Mathieu-Daud - Message-Id: <20230629091107.74384-1-philmd@linaro.org> - Reviewed-by: Richard Henderson - Signed-off-by: Richard Henderson - - Signed-off-by: Zhongrui Tang ---- - include/tcg/tcg.h | 6 ------ - tcg/tcg-op-vec.c | 6 +++--- - 2 files changed, 3 insertions(+), 9 deletions(-) - -diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h -index 42f5b500ed..0ab8e4e735 100644 ---- a/include/tcg/tcg.h -+++ b/include/tcg/tcg.h -@@ -1240,12 +1240,6 @@ uint64_t dup_const(unsigned vece, uint64_t c); - : (target_long)dup_const(VECE, C)) - #endif - --#ifdef CONFIG_DEBUG_TCG --void tcg_assert_listed_vecop(TCGOpcode); --#else --static inline void tcg_assert_listed_vecop(TCGOpcode op) { } --#endif -- - static inline const TCGOpcode *tcg_swap_vecop_list(const TCGOpcode *n) - { - #ifdef CONFIG_DEBUG_TCG -diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c -index faf30f9cdd..7c027099c4 100644 ---- a/tcg/tcg-op-vec.c -+++ b/tcg/tcg-op-vec.c -@@ -50,9 +50,9 @@ extern TCGv_i32 TCGV_HIGH_link_error(TCGv_i64); - * tcg_ctx->vec_opt_opc is non-NULL, the tcg_gen_*_vec expanders - * will validate that their opcode is present in the list. - */ --#ifdef CONFIG_DEBUG_TCG --void tcg_assert_listed_vecop(TCGOpcode op) -+static void tcg_assert_listed_vecop(TCGOpcode op) - { -+#ifdef CONFIG_DEBUG_TCG - const TCGOpcode *p = tcg_ctx->vecop_list; - if (p) { - for (; *p; ++p) { -@@ -62,8 +62,8 @@ void tcg_assert_listed_vecop(TCGOpcode op) - } - g_assert_not_reached(); - } --} - #endif -+} - - bool tcg_can_emit_vecop_list(const TCGOpcode *list, - TCGType type, unsigned vece) --- -2.41.0.windows.1 - diff --git a/tcg-loongarch64-Fix-tcg_out_mov-Aborted.patch b/tcg-loongarch64-Fix-tcg_out_mov-Aborted.patch deleted file mode 100644 index 190a5c3273ce557e8c98a0c174bdb33ec68bb21a..0000000000000000000000000000000000000000 --- a/tcg-loongarch64-Fix-tcg_out_mov-Aborted.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ea14e0f1c97b6af8db9fa7b2d0df14ef03d9acb9 Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Mon, 27 Nov 2023 14:04:58 +0800 -Subject: [PATCH] tcg/loongarch64: Fix tcg_out_mov() Aborted -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from 85d57a37be1461d599747ab86dc0acc46732dbce - -On LoongArch host, we got an Aborted from tcg_out_mov(). - -qemu-x86_64 configure with '--enable-debug'. - -> (gdb) b /home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312 -> Breakpoint 1 at 0x2576f0: file /home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc, line 312. -> (gdb) run hello -[...] -> Thread 1 "qemu-x86_64" hit Breakpoint 1, tcg_out_mov (s=0xaaaae91760 , type=TCG_TYPE_V128, ret=TCG_REG_V2, -> arg=TCG_REG_V0) at /home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312 -> 312 g_assert_not_reached(); -> (gdb) bt -> #0 tcg_out_mov (s=0xaaaae91760 , type=TCG_TYPE_V128, ret=TCG_REG_V2, arg=TCG_REG_V0) -> at /home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312 -> #1 0x000000aaaad0fee0 in tcg_reg_alloc_mov (s=0xaaaae91760 , op=0xaaaaf67c20) at ../tcg/tcg.c:4632 -> #2 0x000000aaaad142f4 in tcg_gen_code (s=0xaaaae91760 , tb=0xffe8030340 , -> pc_start=4346094) at ../tcg/tcg.c:6135 -[...] -> (gdb) c -> Continuing. -> ** -> ERROR:/home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312:tcg_out_mov: code should not be reached -> Bail out! ERROR:/home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312:tcg_out_mov: code should not be reached -> -> Thread 1 "qemu-x86_64" received signal SIGABRT, Aborted. -> 0x000000fff7b1c390 in raise () from /lib64/libc.so.6 -> (gdb) q - -Fixes: 16288ded94 ("tcg/loongarch64: Lower basic tcg vec ops to LSX") -Reviewed-by: Philippe Mathieu-Daudé -Reviewed-by: Richard Henderson -Signed-off-by: Song Gao -Message-Id: <20231120065916.374045-1-gaosong@loongson.cn> ---- - tcg/loongarch64/tcg-target.c.inc | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc -index 0b28b30002..ee7d4d728d 100644 ---- a/tcg/loongarch64/tcg-target.c.inc -+++ b/tcg/loongarch64/tcg-target.c.inc -@@ -255,6 +255,9 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) - */ - tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO); - break; -+ case TCG_TYPE_V128: -+ tcg_out_opc_vori_b(s, ret, arg, 0); -+ break; - default: - g_assert_not_reached(); - } --- -2.27.0 - diff --git a/tcg-optimize-Fix-folding-of-vector-ops.patch b/tcg-optimize-Fix-folding-of-vector-ops.patch deleted file mode 100644 index 9cfcc55b6dbf95420a1762938ba79d0138858d02..0000000000000000000000000000000000000000 --- a/tcg-optimize-Fix-folding-of-vector-ops.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 8eef73d0714c8bb5a4fc5a8b6ae007752d0061b2 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 23 Nov 2022 15:35:25 -0800 -Subject: [PATCH 13/29] tcg/optimize: Fix folding of vector ops -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mainline inclusion -commit c578ff18584666499c3141b2d770b9e36b5e9d7e -category: bugfix - ------------------------------------------------------------- - -Bitwise operations are easy to fold, because the operation is -identical regardless of element size. But add and sub need -extra element size info that is not currently propagated. - -Fixes: 2f9f08ba43d -Cc: qemu-stable@nongnu.org -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/799 -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Richard Henderson - -Signed-off-by: tangbinzy ---- - tcg/optimize.c | 49 ++++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 38 insertions(+), 11 deletions(-) - -diff --git a/tcg/optimize.c b/tcg/optimize.c -index 2397f2cf93..e573000951 100644 ---- a/tcg/optimize.c -+++ b/tcg/optimize.c -@@ -308,13 +308,13 @@ static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y) - CASE_OP_32_64(mul): - return x * y; - -- CASE_OP_32_64(and): -+ CASE_OP_32_64_VEC(and): - return x & y; - -- CASE_OP_32_64(or): -+ CASE_OP_32_64_VEC(or): - return x | y; - -- CASE_OP_32_64(xor): -+ CASE_OP_32_64_VEC(xor): - return x ^ y; - - case INDEX_op_shl_i32: -@@ -347,16 +347,16 @@ static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y) - case INDEX_op_rotl_i64: - return rol64(x, y & 63); - -- CASE_OP_32_64(not): -+ CASE_OP_32_64_VEC(not): - return ~x; - - CASE_OP_32_64(neg): - return -x; - -- CASE_OP_32_64(andc): -+ CASE_OP_32_64_VEC(andc): - return x & ~y; - -- CASE_OP_32_64(orc): -+ CASE_OP_32_64_VEC(orc): - return x | ~y; - - CASE_OP_32_64(eqv): -@@ -751,6 +751,12 @@ static bool fold_const2(OptContext *ctx, TCGOp *op) - return false; - } - -+static bool fold_commutative(OptContext *ctx, TCGOp *op) -+{ -+ swap_commutative(op->args[0], &op->args[1], &op->args[2]); -+ return false; -+} -+ - static bool fold_const2_commutative(OptContext *ctx, TCGOp *op) - { - swap_commutative(op->args[0], &op->args[1], &op->args[2]); -@@ -905,6 +911,16 @@ static bool fold_add(OptContext *ctx, TCGOp *op) - return false; - } - -+/* We cannot as yet do_constant_folding with vectors. */ -+static bool fold_add_vec(OptContext *ctx, TCGOp *op) -+{ -+ if (fold_commutative(ctx, op) || -+ fold_xi_to_x(ctx, op, 0)) { -+ return true; -+ } -+ return false; -+} -+ - static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add) - { - if (arg_is_const(op->args[2]) && arg_is_const(op->args[3]) && -@@ -1938,10 +1954,10 @@ static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op) - return false; - } - --static bool fold_sub(OptContext *ctx, TCGOp *op) -+/* We cannot as yet do_constant_folding with vectors. */ -+static bool fold_sub_vec(OptContext *ctx, TCGOp *op) - { -- if (fold_const2(ctx, op) || -- fold_xx_to_i(ctx, op, 0) || -+ if (fold_xx_to_i(ctx, op, 0) || - fold_xi_to_x(ctx, op, 0) || - fold_sub_to_neg(ctx, op)) { - return true; -@@ -1949,6 +1965,11 @@ static bool fold_sub(OptContext *ctx, TCGOp *op) - return false; - } - -+static bool fold_sub(OptContext *ctx, TCGOp *op) -+{ -+ return fold_const2(ctx, op) || fold_sub_vec(ctx, op); -+} -+ - static bool fold_sub2(OptContext *ctx, TCGOp *op) - { - return fold_addsub2(ctx, op, false); -@@ -2052,9 +2073,12 @@ void tcg_optimize(TCGContext *s) - * Sorted alphabetically by opcode as much as possible. - */ - switch (opc) { -- CASE_OP_32_64_VEC(add): -+ CASE_OP_32_64(add): - done = fold_add(&ctx, op); - break; -+ case INDEX_op_add_vec: -+ done = fold_add_vec(&ctx, op); -+ break; - CASE_OP_32_64(add2): - done = fold_add2(&ctx, op); - break; -@@ -2193,9 +2217,12 @@ void tcg_optimize(TCGContext *s) - CASE_OP_32_64(sextract): - done = fold_sextract(&ctx, op); - break; -- CASE_OP_32_64_VEC(sub): -+ CASE_OP_32_64(sub): - done = fold_sub(&ctx, op); - break; -+ case INDEX_op_sub_vec: -+ done = fold_sub_vec(&ctx, op); -+ break; - CASE_OP_32_64(sub2): - done = fold_sub2(&ctx, op); - break; --- -2.27.0 - diff --git a/tcg-tci-fix-logic-error-when-registering-helpers-via.patch b/tcg-tci-fix-logic-error-when-registering-helpers-via.patch deleted file mode 100644 index 6df462c8e0f13d4263f51a8886f66dd2c1a7845d..0000000000000000000000000000000000000000 --- a/tcg-tci-fix-logic-error-when-registering-helpers-via.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 32533b4b6ea73b69f654ae2d337b3262da36830a Mon Sep 17 00:00:00 2001 -From: cmss_dx -Date: Wed, 23 Nov 2022 06:23:16 +0000 -Subject: [PATCH 07/29] tcg/tci: fix logic error when registering helpers via - FFI mainline inclusion from mainline-v7.2.0-rc1 commit - 9dd1d56e570e5119fef2b28fda811d6891e597a8 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - --------------------------------- - -When registering helpers via FFI for TCI, the inner loop that iterates -parameters of the helper reuses (and thus pollutes) the same variable -used by the outer loop that iterates all helpers, thus made some helpers -unregistered. - -Fix this logic error by using a dedicated temporary variable for the -inner loop. - -Fixes: 22f1557 ("tcg: Build ffi data structures for helpers") -Reviewed-by: Alex Bennée -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Icenowy Zheng -Message-Id: <20221028072145.1593205-1-uwu@icenowy.me> -[rth: Move declaration of j to the for loop itself] -Signed-off-by: Richard Henderson - -Signed-off-by: cmss_dx ---- - tcg/tcg.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/tcg/tcg.c b/tcg/tcg.c -index 934aa8510b..635555001b 100644 ---- a/tcg/tcg.c -+++ b/tcg/tcg.c -@@ -632,9 +632,9 @@ static void tcg_context_init(unsigned max_cpus) - - if (nargs != 0) { - ca->cif.arg_types = ca->args; -- for (i = 0; i < nargs; ++i) { -- int typecode = extract32(typemask, (i + 1) * 3, 3); -- ca->args[i] = typecode_to_ffi[typecode]; -+ for (int j = 0; j < nargs; ++j) { -+ int typecode = extract32(typemask, (j + 1) * 3, 3); -+ ca->args[j] = typecode_to_ffi[typecode]; - } - } - --- -2.27.0 - diff --git a/test-Fix-test-crypto-secret-when-compiling-without-k.patch b/test-Fix-test-crypto-secret-when-compiling-without-k.patch deleted file mode 100644 index 6fc233b254b6e5e98f252408212e84e4aef679fa..0000000000000000000000000000000000000000 --- a/test-Fix-test-crypto-secret-when-compiling-without-k.patch +++ /dev/null @@ -1,72 +0,0 @@ -From edf3134ef2f98c7fd79f54a467631f091e52a980 Mon Sep 17 00:00:00 2001 -From: Juan Quintela -Date: Fri, 14 Apr 2023 13:42:52 +0200 -Subject: [PATCH] test: Fix test-crypto-secret when compiling without keyring - support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Linux keyring support is protected by CONFIG_KEYUTILS. -We also need CONFIG_SECRET_KEYRING. - -Signed-off-by: Juan Quintela -Message-Id: <20230414114252.1136-1-quintela@redhat.com> -Reviewed-by: Daniel P. Berrangé -Signed-off-by: Thomas Huth ---- - tests/unit/test-crypto-secret.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/tests/unit/test-crypto-secret.c b/tests/unit/test-crypto-secret.c -index 34a4aecc12..147b4af828 100644 ---- a/tests/unit/test-crypto-secret.c -+++ b/tests/unit/test-crypto-secret.c -@@ -24,7 +24,7 @@ - #include "crypto/secret.h" - #include "qapi/error.h" - #include "qemu/module.h" --#ifdef CONFIG_KEYUTILS -+#if defined(CONFIG_KEYUTILS) && defined(CONFIG_SECRET_KEYRING) - #include "crypto/secret_keyring.h" - #include - #endif -@@ -128,7 +128,7 @@ static void test_secret_indirect_emptyfile(void) - g_free(fname); - } - --#ifdef CONFIG_KEYUTILS -+#if defined(CONFIG_KEYUTILS) && defined(CONFIG_SECRET_KEYRING) - - #define DESCRIPTION "qemu_test_secret" - #define PAYLOAD "Test Payload" -@@ -268,7 +268,7 @@ static void test_secret_keyring_bad_key_access_right(void) - keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING); - } - --#endif /* CONFIG_KEYUTILS */ -+#endif /* CONFIG_KEYUTILS && CONFIG_SECRET_KEYRING */ - - static void test_secret_noconv_base64_good(void) - { -@@ -571,7 +571,7 @@ int main(int argc, char **argv) - g_test_add_func("/crypto/secret/indirect/emptyfile", - test_secret_indirect_emptyfile); - --#ifdef CONFIG_KEYUTILS -+#if defined(CONFIG_KEYUTILS) && defined(CONFIG_SECRET_KEYRING) - g_test_add_func("/crypto/secret/keyring/good", - test_secret_keyring_good); - g_test_add_func("/crypto/secret/keyring/revoked_key", -@@ -582,7 +582,7 @@ int main(int argc, char **argv) - test_secret_keyring_bad_serial_key); - g_test_add_func("/crypto/secret/keyring/bad_key_access_right", - test_secret_keyring_bad_key_access_right); --#endif /* CONFIG_KEYUTILS */ -+#endif /* CONFIG_KEYUTILS && CONFIG_SECRET_KEYRING */ - - g_test_add_func("/crypto/secret/noconv/base64/good", - test_secret_noconv_base64_good); --- -2.41.0.windows.1 - diff --git a/test-numa-Adjust-aarch64-numa-test.patch b/test-numa-Adjust-aarch64-numa-test.patch deleted file mode 100644 index cb3331439de9a93efc720dd38dd5dac9e67caae1..0000000000000000000000000000000000000000 --- a/test-numa-Adjust-aarch64-numa-test.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 1a347bf3f8e7e31cdaed265af22853d66c202090 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Thu, 23 Apr 2020 20:54:18 +0800 -Subject: [PATCH] test/numa: Adjust aarch64 numa test - -We have supported topology for arm/virt in previous patch, which -changes the meaning of "thread-id", so we must modify test case. - -Signed-off-by: Keqian Zhu ---- - tests/qtest/numa-test.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c -index 90bf68a5b3..08f28012c8 100644 ---- a/tests/qtest/numa-test.c -+++ b/tests/qtest/numa-test.c -@@ -223,17 +223,17 @@ static void aarch64_numa_cpu(const void *data) - QTestState *qts; - g_autofree char *cli = NULL; - -- cli = make_cli(data, "-machine smp.cpus=2 " -+ cli = make_cli(data, "-machine smp.cpus=2,smp.cores=2 " - "-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 " -- "-numa cpu,node-id=1,thread-id=0 " -- "-numa cpu,node-id=0,thread-id=1"); -+ "-numa cpu,node-id=1,core-id=0 " -+ "-numa cpu,node-id=0,core-id=1"); - qts = qtest_init(cli); - cpus = get_cpus(qts, &resp); - g_assert(cpus); - - while ((e = qlist_pop(cpus))) { - QDict *cpu, *props; -- int64_t thread, node; -+ int64_t core, node; - - cpu = qobject_to(QDict, e); - g_assert(qdict_haskey(cpu, "props")); -@@ -241,12 +241,12 @@ static void aarch64_numa_cpu(const void *data) - - g_assert(qdict_haskey(props, "node-id")); - node = qdict_get_int(props, "node-id"); -- g_assert(qdict_haskey(props, "thread-id")); -- thread = qdict_get_int(props, "thread-id"); -+ g_assert(qdict_haskey(props, "core-id")); -+ core = qdict_get_int(props, "core-id"); - -- if (thread == 0) { -+ if (core == 0) { - g_assert_cmpint(node, ==, 1); -- } else if (thread == 1) { -+ } else if (core == 1) { - g_assert_cmpint(node, ==, 0); - } else { - g_assert(false); --- -2.27.0 - diff --git a/test-vmstate-fix-bad-GTree-usage-use-after-free.patch b/test-vmstate-fix-bad-GTree-usage-use-after-free.patch deleted file mode 100644 index be6af283e43e28edec335125be05a013f8ed771c..0000000000000000000000000000000000000000 --- a/test-vmstate-fix-bad-GTree-usage-use-after-free.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 974fcc3a97148b1af3bebfaa6a72645837233489 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 28 Feb 2023 10:29:44 +0100 -Subject: [PATCH] test-vmstate: fix bad GTree usage, use-after-free -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -According to g_tree_foreach() documentation: -"The tree may not be modified while iterating over it (you can't -add/remove items)." - -compare_trees()/diff_tree() fail to respect this rule. -Historically GLib2 used a slice allocator for the GTree APIs -which did not immediately release the memory back to the system -allocator. As a result QEMU's use-after-free bug was not visible. -With GLib > 2.75.3 however, GLib2 has switched to using malloc -and now a SIGSEGV can be observed while running test-vmstate. - -Get rid of the node removal within the tree traversal. Also -check the trees have the same number of nodes before the actual -diff. - -Fixes: 9a85e4b8f6 ("migration: Support gtree migration") -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1518 -Signed-off-by: Marc-André Lureau -Signed-off-by: Eric Auger -Reported-by: Richard W.M. Jones -Tested-by: Richard W.M. Jones -Reviewed-by: Richard W.M. Jones -Reviewed-by: Daniel P. Berrangé -Reviewed-by: Juan Quintela -Signed-off-by: Juan Quintela ---- - tests/unit/test-vmstate.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c -index 4688c03ea7..ac47f0a44b 100644 ---- a/tests/unit/test-vmstate.c -+++ b/tests/unit/test-vmstate.c -@@ -1076,7 +1076,6 @@ static gboolean diff_tree(gpointer key, gpointer value, gpointer data) - struct match_node_data d = {tp->tree2, key, value}; - - g_tree_foreach(tp->tree2, tp->match_node, &d); -- g_tree_remove(tp->tree1, key); - return false; - } - -@@ -1085,9 +1084,9 @@ static void compare_trees(GTree *tree1, GTree *tree2, - { - struct tree_cmp_data tp = {tree1, tree2, function}; - -+ assert(g_tree_nnodes(tree1) == g_tree_nnodes(tree2)); - g_tree_foreach(tree1, diff_tree, &tp); -- assert(g_tree_nnodes(tree1) == 0); -- assert(g_tree_nnodes(tree2) == 0); -+ g_tree_destroy(g_tree_ref(tree1)); - } - - static void diff_domain(TestGTreeDomain *d1, TestGTreeDomain *d2) --- -2.41.0.windows.1 - diff --git a/tests-Add-dirty-page-rate-limit-test.patch b/tests-Add-dirty-page-rate-limit-test.patch deleted file mode 100644 index 12ae236505ebbc901c088879ca65c906412d91d9..0000000000000000000000000000000000000000 --- a/tests-Add-dirty-page-rate-limit-test.patch +++ /dev/null @@ -1,362 +0,0 @@ -From 8a0f4dcf94b280d5b7db7f604c42d088c928ac0d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Sun, 26 Jun 2022 01:38:37 +0800 -Subject: [PATCH] tests: Add dirty page rate limit test -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add dirty page rate limit test if kernel support dirty ring, - -The following qmp commands are covered by this test case: -"calc-dirty-rate", "query-dirty-rate", "set-vcpu-dirty-limit", -"cancel-vcpu-dirty-limit" and "query-vcpu-dirty-limit". - -Signed-off-by: Hyman Huang(黄勇) -Acked-by: Peter Xu -Message-Id: -Signed-off-by: Dr. David Alan Gilbert ---- - tests/qtest/migration-helpers.c | 22 +++ - tests/qtest/migration-helpers.h | 2 + - tests/qtest/migration-test.c | 256 ++++++++++++++++++++++++++++++++ - 3 files changed, 280 insertions(+) - -diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c -index 4ee26014b7..1e594f9cb1 100644 ---- a/tests/qtest/migration-helpers.c -+++ b/tests/qtest/migration-helpers.c -@@ -75,6 +75,28 @@ QDict *wait_command(QTestState *who, const char *command, ...) - return ret; - } - -+/* -+ * Execute the qmp command only -+ */ -+QDict *qmp_command(QTestState *who, const char *command, ...) -+{ -+ va_list ap; -+ QDict *resp, *ret; -+ -+ va_start(ap, command); -+ resp = qtest_vqmp(who, command, ap); -+ va_end(ap); -+ -+ g_assert(!qdict_haskey(resp, "error")); -+ g_assert(qdict_haskey(resp, "return")); -+ -+ ret = qdict_get_qdict(resp, "return"); -+ qobject_ref(ret); -+ qobject_unref(resp); -+ -+ return ret; -+} -+ - /* - * Send QMP command "migrate". - * Arguments are built from @fmt... (formatted like -diff --git a/tests/qtest/migration-helpers.h b/tests/qtest/migration-helpers.h -index d63bba9630..9bc809fb75 100644 ---- a/tests/qtest/migration-helpers.h -+++ b/tests/qtest/migration-helpers.h -@@ -22,6 +22,8 @@ QDict *wait_command_fd(QTestState *who, int fd, const char *command, ...); - GCC_FMT_ATTR(2, 3) - QDict *wait_command(QTestState *who, const char *command, ...); - -+QDict *qmp_command(QTestState *who, const char *command, ...); -+ - GCC_FMT_ATTR(3, 4) - void migrate_qmp(QTestState *who, const char *uri, const char *fmt, ...); - -diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c -index 7b42f6fd90..8fad247f6c 100644 ---- a/tests/qtest/migration-test.c -+++ b/tests/qtest/migration-test.c -@@ -23,6 +23,7 @@ - #include "qapi/qapi-visit-sockets.h" - #include "qapi/qobject-input-visitor.h" - #include "qapi/qobject-output-visitor.h" -+#include "qapi/qmp/qlist.h" - - #include "migration-helpers.h" - #include "tests/migration/migration-test.h" -@@ -42,6 +43,12 @@ static bool uffd_feature_thread_id; - /* A downtime where the test really should converge */ - #define CONVERGE_DOWNTIME 1000 - -+/* -+ * Dirtylimit stop working if dirty page rate error -+ * value less than DIRTYLIMIT_TOLERANCE_RANGE -+ */ -+#define DIRTYLIMIT_TOLERANCE_RANGE 25 /* MB/s */ -+ - #if defined(__linux__) - #include - #include -@@ -1394,6 +1401,253 @@ static void test_multifd_tcp_cancel(void) - test_migrate_end(from, to2, true); - } - -+static void calc_dirty_rate(QTestState *who, uint64_t calc_time) -+{ -+ qobject_unref(qmp_command(who, -+ "{ 'execute': 'calc-dirty-rate'," -+ "'arguments': { " -+ "'calc-time': %ld," -+ "'mode': 'dirty-ring' }}", -+ calc_time)); -+} -+ -+static QDict *query_dirty_rate(QTestState *who) -+{ -+ return qmp_command(who, "{ 'execute': 'query-dirty-rate' }"); -+} -+ -+static void dirtylimit_set_all(QTestState *who, uint64_t dirtyrate) -+{ -+ qobject_unref(qmp_command(who, -+ "{ 'execute': 'set-vcpu-dirty-limit'," -+ "'arguments': { " -+ "'dirty-rate': %ld } }", -+ dirtyrate)); -+} -+ -+static void cancel_vcpu_dirty_limit(QTestState *who) -+{ -+ qobject_unref(qmp_command(who, -+ "{ 'execute': 'cancel-vcpu-dirty-limit' }")); -+} -+ -+static QDict *query_vcpu_dirty_limit(QTestState *who) -+{ -+ QDict *rsp; -+ -+ rsp = qtest_qmp(who, "{ 'execute': 'query-vcpu-dirty-limit' }"); -+ g_assert(!qdict_haskey(rsp, "error")); -+ g_assert(qdict_haskey(rsp, "return")); -+ -+ return rsp; -+} -+ -+static bool calc_dirtyrate_ready(QTestState *who) -+{ -+ QDict *rsp_return; -+ gchar *status; -+ -+ rsp_return = query_dirty_rate(who); -+ g_assert(rsp_return); -+ -+ status = g_strdup(qdict_get_str(rsp_return, "status")); -+ g_assert(status); -+ -+ return g_strcmp0(status, "measuring"); -+} -+ -+static void wait_for_calc_dirtyrate_complete(QTestState *who, -+ int64_t time_s) -+{ -+ int max_try_count = 10000; -+ usleep(time_s * 1000000); -+ -+ while (!calc_dirtyrate_ready(who) && max_try_count--) { -+ usleep(1000); -+ } -+ -+ /* -+ * Set the timeout with 10 s(max_try_count * 1000us), -+ * if dirtyrate measurement not complete, fail test. -+ */ -+ g_assert_cmpint(max_try_count, !=, 0); -+} -+ -+static int64_t get_dirty_rate(QTestState *who) -+{ -+ QDict *rsp_return; -+ gchar *status; -+ QList *rates; -+ const QListEntry *entry; -+ QDict *rate; -+ int64_t dirtyrate; -+ -+ rsp_return = query_dirty_rate(who); -+ g_assert(rsp_return); -+ -+ status = g_strdup(qdict_get_str(rsp_return, "status")); -+ g_assert(status); -+ g_assert_cmpstr(status, ==, "measured"); -+ -+ rates = qdict_get_qlist(rsp_return, "vcpu-dirty-rate"); -+ g_assert(rates && !qlist_empty(rates)); -+ -+ entry = qlist_first(rates); -+ g_assert(entry); -+ -+ rate = qobject_to(QDict, qlist_entry_obj(entry)); -+ g_assert(rate); -+ -+ dirtyrate = qdict_get_try_int(rate, "dirty-rate", -1); -+ -+ qobject_unref(rsp_return); -+ return dirtyrate; -+} -+ -+static int64_t get_limit_rate(QTestState *who) -+{ -+ QDict *rsp_return; -+ QList *rates; -+ const QListEntry *entry; -+ QDict *rate; -+ int64_t dirtyrate; -+ -+ rsp_return = query_vcpu_dirty_limit(who); -+ g_assert(rsp_return); -+ -+ rates = qdict_get_qlist(rsp_return, "return"); -+ g_assert(rates && !qlist_empty(rates)); -+ -+ entry = qlist_first(rates); -+ g_assert(entry); -+ -+ rate = qobject_to(QDict, qlist_entry_obj(entry)); -+ g_assert(rate); -+ -+ dirtyrate = qdict_get_try_int(rate, "limit-rate", -1); -+ -+ qobject_unref(rsp_return); -+ return dirtyrate; -+} -+ -+static QTestState *dirtylimit_start_vm(void) -+{ -+ QTestState *vm = NULL; -+ g_autofree gchar *cmd = NULL; -+ const char *arch = qtest_get_arch(); -+ g_autofree char *bootpath = NULL; -+ -+ assert((strcmp(arch, "x86_64") == 0)); -+ bootpath = g_strdup_printf("%s/bootsect", tmpfs); -+ assert(sizeof(x86_bootsect) == 512); -+ init_bootfile(bootpath, x86_bootsect, sizeof(x86_bootsect)); -+ -+ cmd = g_strdup_printf("-accel kvm,dirty-ring-size=4096 " -+ "-name dirtylimit-test,debug-threads=on " -+ "-m 150M -smp 1 " -+ "-serial file:%s/vm_serial " -+ "-drive file=%s,format=raw ", -+ tmpfs, bootpath); -+ -+ vm = qtest_init(cmd); -+ return vm; -+} -+ -+static void dirtylimit_stop_vm(QTestState *vm) -+{ -+ qtest_quit(vm); -+ cleanup("bootsect"); -+ cleanup("vm_serial"); -+} -+ -+static void test_vcpu_dirty_limit(void) -+{ -+ QTestState *vm; -+ int64_t origin_rate; -+ int64_t quota_rate; -+ int64_t rate ; -+ int max_try_count = 20; -+ int hit = 0; -+ -+ /* Start vm for vcpu dirtylimit test */ -+ vm = dirtylimit_start_vm(); -+ -+ /* Wait for the first serial output from the vm*/ -+ wait_for_serial("vm_serial"); -+ -+ /* Do dirtyrate measurement with calc time equals 1s */ -+ calc_dirty_rate(vm, 1); -+ -+ /* Sleep calc time and wait for calc dirtyrate complete */ -+ wait_for_calc_dirtyrate_complete(vm, 1); -+ -+ /* Query original dirty page rate */ -+ origin_rate = get_dirty_rate(vm); -+ -+ /* VM booted from bootsect should dirty memory steadily */ -+ assert(origin_rate != 0); -+ -+ /* Setup quota dirty page rate at half of origin */ -+ quota_rate = origin_rate / 2; -+ -+ /* Set dirtylimit */ -+ dirtylimit_set_all(vm, quota_rate); -+ -+ /* -+ * Check if set-vcpu-dirty-limit and query-vcpu-dirty-limit -+ * works literally -+ */ -+ g_assert_cmpint(quota_rate, ==, get_limit_rate(vm)); -+ -+ /* Sleep a bit to check if it take effect */ -+ usleep(2000000); -+ -+ /* -+ * Check if dirtylimit take effect realistically, set the -+ * timeout with 20 s(max_try_count * 1s), if dirtylimit -+ * doesn't take effect, fail test. -+ */ -+ while (--max_try_count) { -+ calc_dirty_rate(vm, 1); -+ wait_for_calc_dirtyrate_complete(vm, 1); -+ rate = get_dirty_rate(vm); -+ -+ /* -+ * Assume hitting if current rate is less -+ * than quota rate (within accepting error) -+ */ -+ if (rate < (quota_rate + DIRTYLIMIT_TOLERANCE_RANGE)) { -+ hit = 1; -+ break; -+ } -+ } -+ -+ g_assert_cmpint(hit, ==, 1); -+ -+ hit = 0; -+ max_try_count = 20; -+ -+ /* Check if dirtylimit cancellation take effect */ -+ cancel_vcpu_dirty_limit(vm); -+ while (--max_try_count) { -+ calc_dirty_rate(vm, 1); -+ wait_for_calc_dirtyrate_complete(vm, 1); -+ rate = get_dirty_rate(vm); -+ -+ /* -+ * Assume dirtylimit be canceled if current rate is -+ * greater than quota rate (within accepting error) -+ */ -+ if (rate > (quota_rate + DIRTYLIMIT_TOLERANCE_RANGE)) { -+ hit = 1; -+ break; -+ } -+ } -+ -+ g_assert_cmpint(hit, ==, 1); -+ dirtylimit_stop_vm(vm); -+} -+ - static bool kvm_dirty_ring_supported(void) - { - #if defined(__linux__) && defined(HOST_X86_64) -@@ -1483,6 +1737,8 @@ int main(int argc, char **argv) - if (kvm_dirty_ring_supported()) { - qtest_add_func("/migration/dirty_ring", - test_precopy_unix_dirty_ring); -+ qtest_add_func("/migration/vcpu_dirty_limit", -+ test_vcpu_dirty_limit); - } - - ret = g_test_run(); --- -2.27.0 - diff --git a/tests-Disable-filemonitor-testcase.patch b/tests-Disable-filemonitor-testcase.patch deleted file mode 100644 index 6d7323635b2164ad0616805fd4eb511f6c3e986e..0000000000000000000000000000000000000000 --- a/tests-Disable-filemonitor-testcase.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 4f09a1c2aa855aab666d729defce4c7f0466cb77 Mon Sep 17 00:00:00 2001 -From: Ying Fang -Date: Thu, 10 Feb 2022 17:16:55 +0800 -Subject: [PATCH] tests: Disable filemonitor testcase - -Since filemonitor testcase requires that host kernel being a LTS version, -we cannot guarantee that on OBS system. Lets disable it by default. - -Signed-off-by: Ying Fang -Signed-off-by: Jinhao Gao ---- - tests/unit/meson.build | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/tests/unit/meson.build b/tests/unit/meson.build -index acac3622ed..c21d817874 100644 ---- a/tests/unit/meson.build -+++ b/tests/unit/meson.build -@@ -129,9 +129,6 @@ if have_system - 'test-vmstate': [migration, io], - 'test-yank': ['socket-helpers.c', qom, io, chardev] - } -- if 'CONFIG_INOTIFY1' in config_host -- tests += {'test-util-filemonitor': []} -- endif - - # Some tests: test-char, test-qdev-global-props, and test-qga, - # are not runnable under TSan due to a known issue. --- -2.27.0 - diff --git a/tests-Fix-printf-format-string-in-acpi-utils.c.patch b/tests-Fix-printf-format-string-in-acpi-utils.c.patch deleted file mode 100644 index 063584b36f2c158d596eaba750ac11870cec6ca1..0000000000000000000000000000000000000000 --- a/tests-Fix-printf-format-string-in-acpi-utils.c.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 847becf4850bc244b140644cb577e17e5ba5e732 Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Thu, 26 Oct 2023 19:52:59 -0700 -Subject: [PATCH] tests: Fix printf format string in acpi-utils.c - -Inside of acpi_fetch_table() arguments are -printed via fprintf but '%d' is used to print @flags (of type -uint). Use '%u' instead. - -Signed-off-by: zhujun2 ---- - tests/qtest/acpi-utils.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/qtest/acpi-utils.c b/tests/qtest/acpi-utils.c -index 766c48e3a6..c6f5169b80 100644 ---- a/tests/qtest/acpi-utils.c -+++ b/tests/qtest/acpi-utils.c -@@ -103,7 +103,7 @@ void acpi_fetch_table(QTestState *qts, uint8_t **aml, uint32_t *aml_len, - char *fname = NULL; - GError *error = NULL; - -- fprintf(stderr, "Invalid '%.4s'(%d)\n", *aml, *aml_len); -+ fprintf(stderr, "Invalid '%.4s'(%u)\n", *aml, *aml_len); - fd = g_file_open_tmp("malformed-XXXXXX.dat", &fname, &error); - g_assert_no_error(error); - fprintf(stderr, "Dumping invalid table into '%s'\n", fname); --- -2.41.0.windows.1 - diff --git a/tests-acpi-SLIC-update-expected-blobs.patch b/tests-acpi-SLIC-update-expected-blobs.patch deleted file mode 100644 index ba1f9bc7e69efe83c08f335cfc7ebfca03db89af..0000000000000000000000000000000000000000 --- a/tests-acpi-SLIC-update-expected-blobs.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 86392e80092e62197f51507513ee09100f9c1653 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 27 Dec 2021 14:31:20 -0500 -Subject: [PATCH 4/6] tests: acpi: SLIC: update expected blobs - -Signed-off-by: Igor Mammedov -Message-Id: <20211227193120.1084176-5-imammedo@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - tests/data/acpi/q35/FACP.slic | Bin 244 -> 244 bytes - tests/data/acpi/q35/SLIC.slic | Bin 0 -> 36 bytes - tests/qtest/bios-tables-test-allowed-diff.h | 2 -- - 3 files changed, 2 deletions(-) - -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index 49dbf8fa3e..dfb8523c8b 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1,3 +1 @@ - /* List of comma-separated changed AML files to ignore */ --"tests/data/acpi/q35/FACP.slic", --"tests/data/acpi/q35/SLIC.slic", --- -2.27.0 - diff --git a/tests-acpi-add-SLIC-table-test.patch b/tests-acpi-add-SLIC-table-test.patch deleted file mode 100644 index f0b1a6ec851f6e437043036daba8668f705301b8..0000000000000000000000000000000000000000 --- a/tests-acpi-add-SLIC-table-test.patch +++ /dev/null @@ -1,55 +0,0 @@ -From b9c96b0a111e5333857682a5dc9770cbebcbabea Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 27 Dec 2021 14:31:19 -0500 -Subject: [PATCH 3/6] tests: acpi: add SLIC table test - -When user uses '-acpitable' to add SLIC table, some ACPI -tables (FADT) will change its 'Oem ID'/'Oem Table ID' fields to -match that of SLIC. Test makes sure thati QEMU handles -those fields correctly when SLIC table is added with -'-acpitable' option. - -Signed-off-by: Igor Mammedov -Message-Id: <20211227193120.1084176-4-imammedo@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - tests/qtest/bios-tables-test.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c -index 258874167e..184937e6ca 100644 ---- a/tests/qtest/bios-tables-test.c -+++ b/tests/qtest/bios-tables-test.c -@@ -1465,6 +1465,20 @@ static void test_acpi_virt_tcg(void) - free_test_data(&data); - } - -+static void test_acpi_q35_slic(void) -+{ -+ test_data data = { -+ .machine = MACHINE_Q35, -+ .variant = ".slic", -+ }; -+ -+ test_acpi_one("-acpitable sig=SLIC,oem_id='CRASH ',oem_table_id='ME'," -+ "oem_rev=00002210,asl_compiler_id='qemu'," -+ "asl_compiler_rev=00000000,data=/dev/null", -+ &data); -+ free_test_data(&data); -+} -+ - static void test_oem_fields(test_data *data) - { - int i; -@@ -1639,6 +1653,7 @@ int main(int argc, char *argv[]) - qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic); - qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar); - } -+ qtest_add_func("acpi/q35/slic", test_acpi_q35_slic); - } else if (strcmp(arch, "aarch64") == 0) { - if (has_tcg) { - qtest_add_func("acpi/virt", test_acpi_virt_tcg); --- -2.27.0 - diff --git a/tests-acpi-bios-table-test-Update-expected-virt-DSDT.patch b/tests-acpi-bios-table-test-Update-expected-virt-DSDT.patch deleted file mode 100644 index 22b88989e27f8a8ca7d34726a68b48ba63cb2ca5..0000000000000000000000000000000000000000 --- a/tests-acpi-bios-table-test-Update-expected-virt-DSDT.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d3d158cbf6b236022794e867ac395f75fb4f6436 Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 11 Feb 2022 16:07:31 +0800 -Subject: [PATCH] tests/acpi/bios-table-test: Update expected virt/DSDT file - -Update DSDT binary and empty bios-tables-test-allowd-diff.h - -Signed-off-by: Keqian Zhu ---- - tests/data/acpi/virt/DSDT | Bin 5669 -> 5669 bytes - tests/data/acpi/virt/DSDT.memhp | Bin 7030 -> 7030 bytes - tests/data/acpi/virt/DSDT.numamem | Bin 5669 -> 5669 bytes - tests/data/acpi/virt/DSDT.pxb | Bin 8152 -> 8152 bytes - tests/qtest/bios-tables-test-allowed-diff.h | 1 - - 5 files changed, 1 deletion(-) - -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index 7b4adbc822..dfb8523c8b 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1,2 +1 @@ - /* List of comma-separated changed AML files to ignore */ --"tests/data/acpi/virt/DSDT", --- -2.27.0 - diff --git a/tests-acpi-bios-table-test-Update-expected-virt-PPTT.patch b/tests-acpi-bios-table-test-Update-expected-virt-PPTT.patch deleted file mode 100644 index 8f1de286e32e21794adfb2f054ea79278def18f4..0000000000000000000000000000000000000000 --- a/tests-acpi-bios-table-test-Update-expected-virt-PPTT.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 6f89f06e686a61acf681038ac06732facc6e7b93 Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Fri, 7 Jan 2022 16:32:32 +0800 -Subject: [PATCH 20/24] tests/acpi/bios-table-test: Update expected virt/PPTT - file - -Run ./tests/data/acpi/rebuild-expected-aml.sh from build directory -to update PPTT binary. Also empty bios-tables-test-allowed-diff.h. - -The disassembled differences between actual and expected PPTT: - - /* - * Intel ACPI Component Architecture - * AML/ASL+ Disassembler version 20200528 (64-bit version) - * Copyright (c) 2000 - 2020 Intel Corporation - * -- * Disassembly of tests/data/acpi/virt/PPTT, Tue Jan 4 12:51:11 2022 -+ * Disassembly of /tmp/aml-2ZGOF1, Tue Jan 4 12:51:11 2022 - * - * ACPI Data Table [PPTT] - * - * Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue - */ - - [000h 0000 4] Signature : "PPTT" [Processor Properties Topology Table] --[004h 0004 4] Table Length : 0000004C -+[004h 0004 4] Table Length : 00000060 - [008h 0008 1] Revision : 02 --[009h 0009 1] Checksum : A8 -+[009h 0009 1] Checksum : 48 - [00Ah 0010 6] Oem ID : "BOCHS " - [010h 0016 8] Oem Table ID : "BXPC " - [018h 0024 4] Oem Revision : 00000001 - [01Ch 0028 4] Asl Compiler ID : "BXPC" - [020h 0032 4] Asl Compiler Revision : 00000001 - - [024h 0036 1] Subtable Type : 00 [Processor Hierarchy Node] - [025h 0037 1] Length : 14 - [026h 0038 2] Reserved : 0000 - [028h 0040 4] Flags (decoded below) : 00000001 - Physical package : 1 - ACPI Processor ID valid : 0 - Processor is a thread : 0 - Node is a leaf : 0 - Identical Implementation : 0 - [02Ch 0044 4] Parent : 00000000 - [030h 0048 4] ACPI Processor ID : 00000000 - [034h 0052 4] Private Resource Number : 00000000 - - [038h 0056 1] Subtable Type : 00 [Processor Hierarchy Node] - [039h 0057 1] Length : 14 - [03Ah 0058 2] Reserved : 0000 --[03Ch 0060 4] Flags (decoded below) : 0000000A -+[03Ch 0060 4] Flags (decoded below) : 00000000 - Physical package : 0 -- ACPI Processor ID valid : 1 -+ ACPI Processor ID valid : 0 - Processor is a thread : 0 -- Node is a leaf : 1 -+ Node is a leaf : 0 - Identical Implementation : 0 - [040h 0064 4] Parent : 00000024 - [044h 0068 4] ACPI Processor ID : 00000000 - [048h 0072 4] Private Resource Number : 00000000 - --Raw Table Data: Length 76 (0x4C) -+[04Ch 0076 1] Subtable Type : 00 [Processor Hierarchy Node] -+[04Dh 0077 1] Length : 14 -+[04Eh 0078 2] Reserved : 0000 -+[050h 0080 4] Flags (decoded below) : 0000000A -+ Physical package : 0 -+ ACPI Processor ID valid : 1 -+ Processor is a thread : 0 -+ Node is a leaf : 1 -+ Identical Implementation : 0 -+[054h 0084 4] Parent : 00000038 -+[058h 0088 4] ACPI Processor ID : 00000000 -+[05Ch 0092 4] Private Resource Number : 00000000 -+ -+Raw Table Data: Length 96 (0x60) - -- 0000: 50 50 54 54 4C 00 00 00 02 A8 42 4F 43 48 53 20 // PPTTL.....BOCHS -+ 0000: 50 50 54 54 60 00 00 00 02 48 42 4F 43 48 53 20 // PPTT`....HBOCHS - 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC - 0020: 01 00 00 00 00 14 00 00 01 00 00 00 00 00 00 00 // ................ -- 0030: 00 00 00 00 00 00 00 00 00 14 00 00 0A 00 00 00 // ................ -- 0040: 24 00 00 00 00 00 00 00 00 00 00 00 // $........... -+ 0030: 00 00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 // ................ -+ 0040: 24 00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 // $............... -+ 0050: 0A 00 00 00 38 00 00 00 00 00 00 00 00 00 00 00 // ....8........... - -Signed-off-by: Yanan Wang -Reviewed-by: Ani Sinha -Message-id: 20220107083232.16256-7-wangyanan55@huawei.com -Signed-off-by: Peter Maydell ---- - tests/data/acpi/virt/PPTT | Bin 76 -> 96 bytes - tests/qtest/bios-tables-test-allowed-diff.h | 1 - - 2 files changed, 1 deletion(-) - -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index cb143a55a6..dfb8523c8b 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1,2 +1 @@ - /* List of comma-separated changed AML files to ignore */ --"tests/data/acpi/virt/PPTT", --- -2.27.0 - diff --git a/tests-acpi-bios-tables-test-Allow-changes-to-virt-DS.patch b/tests-acpi-bios-tables-test-Allow-changes-to-virt-DS.patch deleted file mode 100644 index 585df22e40a21c84d9df3e883197c42ec3868ced..0000000000000000000000000000000000000000 --- a/tests-acpi-bios-tables-test-Allow-changes-to-virt-DS.patch +++ /dev/null @@ -1,22 +0,0 @@ -From d215714b9ab38f6c9e0aacf2120b44888936a1ed Mon Sep 17 00:00:00 2001 -From: Keqian Zhu -Date: Fri, 11 Feb 2022 15:48:16 +0800 -Subject: [PATCH] tests/acpi/bios-tables-test: Allow changes to virt/DSDT file - -Let virt/DSDT as the expected file allowed to be changed. - -Signed-off-by: Keqian Zhu ---- - tests/qtest/bios-tables-test-allowed-diff.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index dfb8523c8b..7b4adbc822 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1 +1,2 @@ - /* List of comma-separated changed AML files to ignore */ -+"tests/data/acpi/virt/DSDT", --- -2.27.0 - diff --git a/tests-acpi-bios-tables-test-Allow-changes-to-virt-PP.patch b/tests-acpi-bios-tables-test-Allow-changes-to-virt-PP.patch deleted file mode 100644 index a4801e55cd027f94f9e929f5dc86dcc5780620c6..0000000000000000000000000000000000000000 --- a/tests-acpi-bios-tables-test-Allow-changes-to-virt-PP.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 225034a72c803b8e3819cec22bc6fb8bfc9e7366 Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Fri, 7 Jan 2022 16:32:30 +0800 -Subject: [PATCH 18/24] tests/acpi/bios-tables-test: Allow changes to virt/PPTT - file - -List test/data/acpi/virt/PPTT as the expected files allowed to -be changed in tests/qtest/bios-tables-test-allowed-diff.h - -Signed-off-by: Yanan Wang -Acked-by: Ani Sinha -Message-id: 20220107083232.16256-5-wangyanan55@huawei.com -Signed-off-by: Peter Maydell ---- - tests/qtest/bios-tables-test-allowed-diff.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index dfb8523c8b..cb143a55a6 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1 +1,2 @@ - /* List of comma-separated changed AML files to ignore */ -+"tests/data/acpi/virt/PPTT", --- -2.27.0 - diff --git a/tests-acpi-whitelist-expected-blobs-before-changing-.patch b/tests-acpi-whitelist-expected-blobs-before-changing-.patch deleted file mode 100644 index 075361b2af5d521616d46941d9df90827fbee30d..0000000000000000000000000000000000000000 --- a/tests-acpi-whitelist-expected-blobs-before-changing-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 83229a5034161d021ac21f7c7f921d4398d388c6 Mon Sep 17 00:00:00 2001 -From: Igor Mammedov -Date: Mon, 27 Dec 2021 14:31:18 -0500 -Subject: [PATCH 2/6] tests: acpi: whitelist expected blobs before changing - them - -Signed-off-by: Igor Mammedov -Message-Id: <20211227193120.1084176-3-imammedo@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - tests/data/acpi/q35/FACP.slic | Bin 0 -> 244 bytes - tests/data/acpi/q35/SLIC.slic | 0 - tests/qtest/bios-tables-test-allowed-diff.h | 2 ++ - 3 files changed, 2 insertions(+) - create mode 100644 tests/data/acpi/q35/FACP.slic - create mode 100644 tests/data/acpi/q35/SLIC.slic - -diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h -index dfb8523c8b..49dbf8fa3e 100644 ---- a/tests/qtest/bios-tables-test-allowed-diff.h -+++ b/tests/qtest/bios-tables-test-allowed-diff.h -@@ -1 +1,3 @@ - /* List of comma-separated changed AML files to ignore */ -+"tests/data/acpi/q35/FACP.slic", -+"tests/data/acpi/q35/SLIC.slic", --- -2.27.0 - diff --git a/tests-add-riscv-virt-machine-mapping-to-testenv.patch b/tests-add-riscv-virt-machine-mapping-to-testenv.patch deleted file mode 100644 index dc008b5bc9e86e7a8c4956668a8fc56e9399e489..0000000000000000000000000000000000000000 --- a/tests-add-riscv-virt-machine-mapping-to-testenv.patch +++ /dev/null @@ -1,39 +0,0 @@ -From f0dbc3b6101e39ce3bc5d38f34723d1c672a12e9 Mon Sep 17 00:00:00 2001 -From: laokz -Date: Mon, 13 Mar 2023 06:20:48 +0000 -Subject: [PATCH] tests: add (riscv virt) machine mapping to testenv from - v7.0.0 commit 3213bbaf5797cc405e57f122e72c1fb55d0b08ab Author: laokz - Date: Tue Mar 8 12:33:39 2022 +0800 - - tests: add (riscv virt) machine mapping to testenv - - Some qemu-iotests(040 etc) use PCI disk to do test. Without the - mapping, RISC-V flavor use spike as default machine which has no - PCI bus, causing test failure. - - Resolves: https://gitlab.com/qemu-project/qemu/-/issues/894 - - Signed-off-by: Kai Zhang - Message-Id: - Reviewed-by: Alistair Francis - Signed-off-by: Hanna Reitz ---- - tests/qemu-iotests/testenv.py | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py -index c33454fa68..26ae6945cc 100644 ---- a/tests/qemu-iotests/testenv.py -+++ b/tests/qemu-iotests/testenv.py -@@ -238,6 +238,8 @@ def __init__(self, imgfmt: str, imgproto: str, aiomode: str, - ('aarch64', 'virt'), - ('avr', 'mega2560'), - ('m68k', 'virt'), -+ ('riscv32', 'virt'), -+ ('riscv64', 'virt'), - ('rx', 'gdbsim-r5f562n8'), - ('tricore', 'tricore_testboard') - ) --- -2.27.0 - diff --git a/tests-avocado-mark-ReplayKernelNormal.test_mips64el_.patch b/tests-avocado-mark-ReplayKernelNormal.test_mips64el_.patch deleted file mode 100644 index bc8f81aed54fcb488ae3a9a1cef9edfb1aebad3a..0000000000000000000000000000000000000000 --- a/tests-avocado-mark-ReplayKernelNormal.test_mips64el_.patch +++ /dev/null @@ -1,48 +0,0 @@ -From b4d96f201027d930ef84c8751909f3770e3d21f9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alex=20Benn=C3=A9e?= -Date: Fri, 1 Dec 2023 20:10:27 +0000 -Subject: [PATCH] tests/avocado: mark ReplayKernelNormal.test_mips64el_malta as - flaky -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -I missed this when going through the recent failure logs. I can run -the test 30 times without failure locally but it seems to hang pretty -reliably on GitLab's CI infra-structure. - -Cc: Philippe Mathieu-Daudé -Signed-off-by: Alex Bennée -Reviewed-by: Philippe Mathieu-Daudé -Message-ID: <20231201201027.2689404-1-alex.bennee@linaro.org> -Signed-off-by: Philippe Mathieu-Daudé - -Signed-off-by: Zhongrui Tang ---- - tests/avocado/replay_kernel.py | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tests/avocado/replay_kernel.py b/tests/avocado/replay_kernel.py -index c68a953730..16421b3407 100644 ---- a/tests/avocado/replay_kernel.py -+++ b/tests/avocado/replay_kernel.py -@@ -113,6 +113,8 @@ def test_mips_malta(self): - - self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5) - -+ # See https://gitlab.com/qemu-project/qemu/-/issues/2013 -+ @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - def test_mips64el_malta(self): - """ - This test requires the ar tool to extract "data.tar.gz" from -@@ -128,6 +130,7 @@ def test_mips64el_malta(self): - - :avocado: tags=arch:mips64el - :avocado: tags=machine:malta -+ :avocado: tags=flaky - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20130217T032700Z/pool/main/l/linux-2.6/' --- -2.27.0 - diff --git a/tests-avocado-raspi2_initrd-Wait-for-guest-shutdown-.patch b/tests-avocado-raspi2_initrd-Wait-for-guest-shutdown-.patch deleted file mode 100644 index b8bec1abebecfc66c45f617957f90d9efae00731..0000000000000000000000000000000000000000 --- a/tests-avocado-raspi2_initrd-Wait-for-guest-shutdown-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From b30894533ec65a304c304016eaa461c23ca8d70c Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Wed, 30 Nov 2022 14:21:17 +0800 -Subject: [PATCH 02/17] tests/avocado: raspi2_initrd: Wait for guest shutdown - message before stopping - -The avocado test - tests/avocado/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd -finishes wiith - exec_command(self, 'halt') - # Wait for VM to shut down gracefully - self.vm.wait() -In theory this should be fine. In practice it runs into two bugs: - * when the test calls self.vm.wait() Avocado closes the socket - connection to the guest serial console immediately, so the - avocado logs don't have the last part of the guest output: - https://gitlab.com/qemu-project/qemu/-/issues/1265 - * when the socket is closed, a bug in the QEMU socket chardev - means that it loses any data that the guest UART has not - yet consumed. This means that the guest doesn't always read - the full 'halt' command string, so the test intermittently - fails with a timeout: - https://gitlab.com/qemu-project/qemu/-/issues/1264 -Work around both of these by waiting for the guest to print the -string that means it has completed the shutdown process. This fixes -a very long standing intermittent failure in this test. -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/636 - -Signed-off-by: Peter Maydell -Signed-off-by: jianchunfu ---- - tests/avocado/boot_linux_console.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py -index 9c618d4809..58864ec163 100644 ---- a/tests/avocado/boot_linux_console.py -+++ b/tests/avocado/boot_linux_console.py -@@ -512,7 +512,7 @@ def test_arm_raspi2_initrd(self): - 'BCM2835') - exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', - '/soc/cprman@7e101000') -- exec_command(self, 'halt') -+ exec_command_and_wait_for_pattern(self, 'halt', 'reboot: System halted') - # Wait for VM to shut down gracefully - self.vm.wait() - --- -2.27.0 - diff --git a/tests-avocado-use-new-rootfs-for-orangepi-test.patch b/tests-avocado-use-new-rootfs-for-orangepi-test.patch deleted file mode 100644 index ffd66757a43aa298d1f7b9a2b84e1a5cf692e621..0000000000000000000000000000000000000000 --- a/tests-avocado-use-new-rootfs-for-orangepi-test.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 5d2db876aa6f869dabe6f6132244c5ce2383af03 Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Thu, 1 Dec 2022 17:00:40 +0800 -Subject: [PATCH 07/17] tests/avocado: use new rootfs for orangepi test -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The old URL wasn't stable. I suspect the current URL will only be -stable for a few months so maybe we need another strategy for hosting -rootfs snapshots? - -Signed-off-by: Alex Bennée -Message-Id: <20221118113309.1057790-1-alex.bennee@linaro.org> -Signed-off-by: Thomas Huth - -Signed-off-by: tangzhongrui ---- - tests/avocado/boot_linux_console.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py -index 9c618d4809..733481c53c 100644 ---- a/tests/avocado/boot_linux_console.py -+++ b/tests/avocado/boot_linux_console.py -@@ -813,8 +813,8 @@ def test_arm_orangepi_sd(self): - dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/' -- 'kci-2019.02/armel/base/rootfs.ext2.xz') -- rootfs_hash = '692510cb625efda31640d1de0a8d60e26040f061' -+ 'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz') -+ rootfs_hash = 'fae32f337c7b87547b10f42599acf109da8b6d9a' - rootfs_path_xz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash) - rootfs_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.lzma_uncompress(rootfs_path_xz, rootfs_path) --- -2.27.0 - diff --git a/tests-qtest-Add-fuzz-lsi53c895a-test.patch b/tests-qtest-Add-fuzz-lsi53c895a-test.patch deleted file mode 100644 index 4ab7705fa9527c03a594dfc03501fc481891b725..0000000000000000000000000000000000000000 --- a/tests-qtest-Add-fuzz-lsi53c895a-test.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 32e9fb62e900e94cb2e39e6bd9717983bb259d25 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Tue, 23 Nov 2021 12:17:32 +0100 -Subject: [PATCH 2/4] tests/qtest: Add fuzz-lsi53c895a-test -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Without the previous commit, this test triggers: - - $ make check-qtest-x86_64 - [...] - Running test qtest-x86_64/fuzz-lsi53c895a-test - qemu-system-x86_64: hw/scsi/lsi53c895a.c:624: lsi_do_dma: Assertion `s->current' failed. - ERROR qtest-x86_64/fuzz-lsi53c895a-test - too few tests run (expected 1, got 0) - -Suggested-by: Alexander Bulekov -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Laurent Vivier -Message-Id: <20211123111732.83137-3-philmd@redhat.com> -Signed-off-by: Paolo Bonzini ---- - MAINTAINERS | 1 + - tests/qtest/fuzz-lsi53c895a-test.c | 52 ++++++++++++++++++++++++++++++ - tests/qtest/meson.build | 1 + - 3 files changed, 54 insertions(+) - create mode 100644 tests/qtest/fuzz-lsi53c895a-test.c - -diff --git a/MAINTAINERS b/MAINTAINERS -index 7543eb4d59..fbd6d0b174 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -1825,6 +1825,7 @@ F: hw/scsi/* - F: tests/qtest/virtio-scsi-test.c - F: tests/qtest/fuzz-virtio-scsi-test.c - F: tests/qtest/am53c974-test.c -+F: tests/qtest/fuzz-lsi53c895a-test.c - T: git https://github.com/bonzini/qemu.git scsi-next - - SSI -diff --git a/tests/qtest/fuzz-lsi53c895a-test.c b/tests/qtest/fuzz-lsi53c895a-test.c -new file mode 100644 -index 0000000000..ba5d468970 ---- /dev/null -+++ b/tests/qtest/fuzz-lsi53c895a-test.c -@@ -0,0 +1,52 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * QTest fuzzer-generated testcase for LSI53C895A device -+ * -+ * Copyright (c) Red Hat -+ */ -+ -+#include "qemu/osdep.h" -+#include "libqos/libqtest.h" -+ -+/* -+ * This used to trigger the assert in lsi_do_dma() -+ * https://bugs.launchpad.net/qemu/+bug/697510 -+ * https://bugs.launchpad.net/qemu/+bug/1905521 -+ * https://bugs.launchpad.net/qemu/+bug/1908515 -+ */ -+static void test_lsi_do_dma_empty_queue(void) -+{ -+ QTestState *s; -+ -+ s = qtest_init("-M q35 -nographic -monitor none -serial none " -+ "-drive if=none,id=drive0," -+ "file=null-co://,file.read-zeroes=on,format=raw " -+ "-device lsi53c895a,id=scsi0 " -+ "-device scsi-hd,drive=drive0," -+ "bus=scsi0.0,channel=0,scsi-id=0,lun=0"); -+ qtest_outl(s, 0xcf8, 0x80001814); -+ qtest_outl(s, 0xcfc, 0xe1068000); -+ qtest_outl(s, 0xcf8, 0x80001818); -+ qtest_outl(s, 0xcf8, 0x80001804); -+ qtest_outw(s, 0xcfc, 0x7); -+ qtest_outl(s, 0xcf8, 0x80002010); -+ -+ qtest_writeb(s, 0xe106802e, 0xff); /* Fill DSP bits 16-23 */ -+ qtest_writeb(s, 0xe106802f, 0xff); /* Fill DSP bits 24-31: trigger SCRIPT */ -+ -+ qtest_quit(s); -+} -+ -+int main(int argc, char **argv) -+{ -+ const char *arch = qtest_get_arch(); -+ -+ g_test_init(&argc, &argv, NULL); -+ -+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { -+ qtest_add_func("fuzz/lsi53c895a/lsi_do_dma_empty_queue", -+ test_lsi_do_dma_empty_queue); -+ } -+ -+ return g_test_run(); -+} -diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build -index c9d8458062..d2ce20d304 100644 ---- a/tests/qtest/meson.build -+++ b/tests/qtest/meson.build -@@ -19,6 +19,7 @@ slow_qtests = { - - qtests_generic = \ - (config_all_devices.has_key('CONFIG_MEGASAS_SCSI_PCI') ? ['fuzz-megasas-test'] : []) + \ -+ (config_all_devices.has_key('CONFIG_LSI_SCSI_PCI') ? ['fuzz-lsi53c895a-test'] : []) + \ - (config_all_devices.has_key('CONFIG_VIRTIO_SCSI') ? ['fuzz-virtio-scsi-test'] : []) + \ - (config_all_devices.has_key('CONFIG_SB16') ? ['fuzz-sb16-test'] : []) + \ - (config_all_devices.has_key('CONFIG_SDHCI_PCI') ? ['fuzz-sdcard-test'] : []) + \ --- -2.27.0 - diff --git a/tests-qtest-Fix-two-format-strings.patch b/tests-qtest-Fix-two-format-strings.patch deleted file mode 100644 index ed739b906000a35e8c5efa91a34e6fa072b7f63d..0000000000000000000000000000000000000000 --- a/tests-qtest-Fix-two-format-strings.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 00b21f96b39b892d9dff0fc7616e88e7238d54cc Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:14:16 -0800 -Subject: [PATCH] tests/qtest: Fix two format strings -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit d46e6bba55f858b829251e2f4bd7b150cdb5b1d6 - -Signed-off-by: Stefan Weil -Message-Id: <20221105115525.623059-1-sw@weilnetz.de> -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Thomas Huth -Signed-off-by: Wanghe Xiao ---- - tests/qtest/migration-test.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c -index 8fad247f6c..194c7cb661 100644 ---- a/tests/qtest/migration-test.c -+++ b/tests/qtest/migration-test.c -@@ -1406,7 +1406,7 @@ static void calc_dirty_rate(QTestState *who, uint64_t calc_time) - qobject_unref(qmp_command(who, - "{ 'execute': 'calc-dirty-rate'," - "'arguments': { " -- "'calc-time': %ld," -+ "'calc-time': %" PRIu64 "," - "'mode': 'dirty-ring' }}", - calc_time)); - } -@@ -1421,7 +1421,7 @@ static void dirtylimit_set_all(QTestState *who, uint64_t dirtyrate) - qobject_unref(qmp_command(who, - "{ 'execute': 'set-vcpu-dirty-limit'," - "'arguments': { " -- "'dirty-rate': %ld } }", -+ "'dirty-rate': %" PRIu64 " } }", - dirtyrate)); - } - --- -2.27.0 - diff --git a/tests-qtest-check-the-return-value.patch b/tests-qtest-check-the-return-value.patch deleted file mode 100644 index ada8e4a34533defdd67bfda81721393fe039afe7..0000000000000000000000000000000000000000 --- a/tests-qtest-check-the-return-value.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 53e0242318e838013504688307af44e80ab36c70 Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Tue, 21 Nov 2023 18:03:25 -0800 -Subject: [PATCH] tests/qtest: check the return value - -These variables "ret" are never referenced in the code, thus -add check logic for the "ret" - -Signed-off-by: zhujun2 ---- - tests/qtest/test-filter-mirror.c | 1 + - tests/qtest/test-filter-redirector.c | 2 ++ - tests/qtest/virtio-net-test.c | 1 + - 3 files changed, 4 insertions(+) - -diff --git a/tests/qtest/test-filter-mirror.c b/tests/qtest/test-filter-mirror.c -index bc0dee64dd..40f736734a 100644 ---- a/tests/qtest/test-filter-mirror.c -+++ b/tests/qtest/test-filter-mirror.c -@@ -71,6 +71,7 @@ static void test_mirror(void) - g_assert_cmpint(len, ==, sizeof(send_buf)); - recv_buf = g_malloc(len); - ret = qemu_recv(recv_sock[0], recv_buf, len, 0); -+ g_assert_cmpint(ret, ==, len); - g_assert_cmpstr(recv_buf, ==, send_buf); - - g_free(recv_buf); -diff --git a/tests/qtest/test-filter-redirector.c b/tests/qtest/test-filter-redirector.c -index 4269b2cdd9..f802c94f54 100644 ---- a/tests/qtest/test-filter-redirector.c -+++ b/tests/qtest/test-filter-redirector.c -@@ -133,6 +133,7 @@ static void test_redirector_tx(void) - g_assert_cmpint(len, ==, sizeof(send_buf)); - recv_buf = g_malloc(len); - ret = qemu_recv(recv_sock, recv_buf, len, 0); -+ g_assert_cmpint(ret, ==, len); - g_assert_cmpstr(recv_buf, ==, send_buf); - - g_free(recv_buf); -@@ -201,6 +202,7 @@ static void test_redirector_rx(void) - g_assert_cmpint(len, ==, sizeof(send_buf)); - recv_buf = g_malloc(len); - ret = qemu_recv(backend_sock[0], recv_buf, len, 0); -+ g_assert_cmpint(ret, ==, len); - g_assert_cmpstr(recv_buf, ==, send_buf); - - close(send_sock); -diff --git a/tests/qtest/virtio-net-test.c b/tests/qtest/virtio-net-test.c -index 8bf74e516c..aab4480fb0 100644 ---- a/tests/qtest/virtio-net-test.c -+++ b/tests/qtest/virtio-net-test.c -@@ -92,6 +92,7 @@ static void tx_test(QVirtioDevice *dev, - len = ntohl(len); - - ret = qemu_recv(socket, buffer, len, 0); -+ g_assert_cmpint(ret, ==, len); - g_assert_cmpstr(buffer, ==, "TEST"); - } - --- -2.27.0 - diff --git a/tests-qtest-fdc-test-Add-a-regression-test-for-CVE-2.patch b/tests-qtest-fdc-test-Add-a-regression-test-for-CVE-2.patch deleted file mode 100644 index d089fbbf6c9f7fc7f004463601b9ad9001fc502a..0000000000000000000000000000000000000000 --- a/tests-qtest-fdc-test-Add-a-regression-test-for-CVE-2.patch +++ /dev/null @@ -1,110 +0,0 @@ -From c3ed2f4828e29f5ac82efd6a32117e9b17180dd1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 18 Nov 2021 12:57:33 +0100 -Subject: [PATCH 6/6] tests/qtest/fdc-test: Add a regression test for - CVE-2021-3507 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add the reproducer from https://gitlab.com/qemu-project/qemu/-/issues/339 - -Without the previous commit, when running 'make check-qtest-i386' -with QEMU configured with '--enable-sanitizers' we get: - - ==4028352==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x619000062a00 at pc 0x5626d03c491a bp 0x7ffdb4199410 sp 0x7ffdb4198bc0 - READ of size 786432 at 0x619000062a00 thread T0 - #0 0x5626d03c4919 in __asan_memcpy (qemu-system-i386+0x1e65919) - #1 0x5626d1c023cc in flatview_write_continue softmmu/physmem.c:2787:13 - #2 0x5626d1bf0c0f in flatview_write softmmu/physmem.c:2822:14 - #3 0x5626d1bf0798 in address_space_write softmmu/physmem.c:2914:18 - #4 0x5626d1bf0f37 in address_space_rw softmmu/physmem.c:2924:16 - #5 0x5626d1bf14c8 in cpu_physical_memory_rw softmmu/physmem.c:2933:5 - #6 0x5626d0bd5649 in cpu_physical_memory_write include/exec/cpu-common.h:82:5 - #7 0x5626d0bd0a07 in i8257_dma_write_memory hw/dma/i8257.c:452:9 - #8 0x5626d09f825d in fdctrl_transfer_handler hw/block/fdc.c:1616:13 - #9 0x5626d0a048b4 in fdctrl_start_transfer hw/block/fdc.c:1539:13 - #10 0x5626d09f4c3e in fdctrl_write_data hw/block/fdc.c:2266:13 - #11 0x5626d09f22f7 in fdctrl_write hw/block/fdc.c:829:9 - #12 0x5626d1c20bc5 in portio_write softmmu/ioport.c:207:17 - - 0x619000062a00 is located 0 bytes to the right of 512-byte region [0x619000062800,0x619000062a00) - allocated by thread T0 here: - #0 0x5626d03c66ec in posix_memalign (qemu-system-i386+0x1e676ec) - #1 0x5626d2b988d4 in qemu_try_memalign util/oslib-posix.c:210:11 - #2 0x5626d2b98b0c in qemu_memalign util/oslib-posix.c:226:27 - #3 0x5626d09fbaf0 in fdctrl_realize_common hw/block/fdc.c:2341:20 - #4 0x5626d0a150ed in isabus_fdc_realize hw/block/fdc-isa.c:113:5 - #5 0x5626d2367935 in device_set_realized hw/core/qdev.c:531:13 - - SUMMARY: AddressSanitizer: heap-buffer-overflow (qemu-system-i386+0x1e65919) in __asan_memcpy - Shadow bytes around the buggy address: - 0x0c32800044f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c3280004500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 0x0c3280004510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 0x0c3280004520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - 0x0c3280004530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - =>0x0c3280004540:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c3280004550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c3280004560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c3280004570: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c3280004580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa - 0x0c3280004590: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd - Shadow byte legend (one shadow byte represents 8 application bytes): - Addressable: 00 - Heap left redzone: fa - Freed heap region: fd - ==4028352==ABORTING - -[ kwolf: Added snapshot=on to prevent write file lock failure ] - -Reported-by: Alexander Bulekov -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Alexander Bulekov -Signed-off-by: Kevin Wolf ---- - tests/qtest/fdc-test.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/tests/qtest/fdc-test.c b/tests/qtest/fdc-test.c -index 8f6eee84a4..6f5850354f 100644 ---- a/tests/qtest/fdc-test.c -+++ b/tests/qtest/fdc-test.c -@@ -583,6 +583,26 @@ static void test_cve_2021_20196(void) - qtest_quit(s); - } - -+static void test_cve_2021_3507(void) -+{ -+ QTestState *s; -+ -+ s = qtest_initf("-nographic -m 32M -nodefaults " -+ "-drive file=%s,format=raw,if=floppy,snapshot=on", -+ test_image); -+ qtest_outl(s, 0x9, 0x0a0206); -+ qtest_outw(s, 0x3f4, 0x1600); -+ qtest_outw(s, 0x3f4, 0x0000); -+ qtest_outw(s, 0x3f4, 0x0000); -+ qtest_outw(s, 0x3f4, 0x0000); -+ qtest_outw(s, 0x3f4, 0x0200); -+ qtest_outw(s, 0x3f4, 0x0200); -+ qtest_outw(s, 0x3f4, 0x0000); -+ qtest_outw(s, 0x3f4, 0x0000); -+ qtest_outw(s, 0x3f4, 0x0000); -+ qtest_quit(s); -+} -+ - int main(int argc, char **argv) - { - int fd; -@@ -614,6 +634,7 @@ int main(int argc, char **argv) - qtest_add_func("/fdc/read_no_dma_19", test_read_no_dma_19); - qtest_add_func("/fdc/fuzz-registers", fuzz_registers); - qtest_add_func("/fdc/fuzz/cve_2021_20196", test_cve_2021_20196); -+ qtest_add_func("/fdc/fuzz/cve_2021_3507", test_cve_2021_3507); - - ret = g_test_run(); - --- -2.27.0 - diff --git a/tests-qtest-intel-hda-test-Add-reproducer-for-issue-.patch b/tests-qtest-intel-hda-test-Add-reproducer-for-issue-.patch deleted file mode 100644 index 1ecfe2aa4ec98853e60b17d0dd3fd0bb46d5b99d..0000000000000000000000000000000000000000 --- a/tests-qtest-intel-hda-test-Add-reproducer-for-issue-.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 16c1b4c9124da1b1e5fe123c9c9df683372f64a4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Sat, 18 Dec 2021 17:09:12 +0100 -Subject: [PATCH 25/25] tests/qtest/intel-hda-test: Add reproducer for issue - #542 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Include the qtest reproducer provided by Alexander Bulekov -in https://gitlab.com/qemu-project/qemu/-/issues/542. -Without the previous commit, we get: - - $ make check-qtest-i386 - ... - Running test tests/qtest/intel-hda-test - AddressSanitizer:DEADLYSIGNAL - ================================================================= - ==1580408==ERROR: AddressSanitizer: stack-overflow on address 0x7ffc3d566fe0 - #0 0x63d297cf in address_space_translate_internal softmmu/physmem.c:356 - #1 0x63d27260 in flatview_do_translate softmmu/physmem.c:499:15 - #2 0x63d27af5 in flatview_translate softmmu/physmem.c:565:15 - #3 0x63d4ce84 in flatview_write softmmu/physmem.c:2850:10 - #4 0x63d4cb18 in address_space_write softmmu/physmem.c:2950:18 - #5 0x63d4d387 in address_space_rw softmmu/physmem.c:2960:16 - #6 0x62ae12f2 in dma_memory_rw_relaxed include/sysemu/dma.h:89:12 - #7 0x62ae104a in dma_memory_rw include/sysemu/dma.h:132:12 - #8 0x62ae6157 in dma_memory_write include/sysemu/dma.h:173:12 - #9 0x62ae5ec0 in stl_le_dma include/sysemu/dma.h:275:1 - #10 0x62ae5ba2 in stl_le_pci_dma include/hw/pci/pci.h:871:1 - #11 0x62ad59a6 in intel_hda_response hw/audio/intel-hda.c:372:12 - #12 0x62ad2afb in hda_codec_response hw/audio/intel-hda.c:107:5 - #13 0x62aec4e1 in hda_audio_command hw/audio/hda-codec.c:655:5 - #14 0x62ae05d9 in intel_hda_send_command hw/audio/intel-hda.c:307:5 - #15 0x62adff54 in intel_hda_corb_run hw/audio/intel-hda.c:342:9 - #16 0x62adc13b in intel_hda_set_corb_wp hw/audio/intel-hda.c:548:5 - #17 0x62ae5942 in intel_hda_reg_write hw/audio/intel-hda.c:977:9 - #18 0x62ada10a in intel_hda_mmio_write hw/audio/intel-hda.c:1054:5 - #19 0x63d8f383 in memory_region_write_accessor softmmu/memory.c:492:5 - #20 0x63d8ecc1 in access_with_adjusted_size softmmu/memory.c:554:18 - #21 0x63d8d5d6 in memory_region_dispatch_write softmmu/memory.c:1504:16 - #22 0x63d5e85e in flatview_write_continue softmmu/physmem.c:2812:23 - #23 0x63d4d05b in flatview_write softmmu/physmem.c:2854:12 - #24 0x63d4cb18 in address_space_write softmmu/physmem.c:2950:18 - #25 0x63d4d387 in address_space_rw softmmu/physmem.c:2960:16 - #26 0x62ae12f2 in dma_memory_rw_relaxed include/sysemu/dma.h:89:12 - #27 0x62ae104a in dma_memory_rw include/sysemu/dma.h:132:12 - #28 0x62ae6157 in dma_memory_write include/sysemu/dma.h:173:12 - #29 0x62ae5ec0 in stl_le_dma include/sysemu/dma.h:275:1 - #30 0x62ae5ba2 in stl_le_pci_dma include/hw/pci/pci.h:871:1 - #31 0x62ad59a6 in intel_hda_response hw/audio/intel-hda.c:372:12 - #32 0x62ad2afb in hda_codec_response hw/audio/intel-hda.c:107:5 - #33 0x62aec4e1 in hda_audio_command hw/audio/hda-codec.c:655:5 - #34 0x62ae05d9 in intel_hda_send_command hw/audio/intel-hda.c:307:5 - #35 0x62adff54 in intel_hda_corb_run hw/audio/intel-hda.c:342:9 - #36 0x62adc13b in intel_hda_set_corb_wp hw/audio/intel-hda.c:548:5 - #37 0x62ae5942 in intel_hda_reg_write hw/audio/intel-hda.c:977:9 - #38 0x62ada10a in intel_hda_mmio_write hw/audio/intel-hda.c:1054:5 - #39 0x63d8f383 in memory_region_write_accessor softmmu/memory.c:492:5 - #40 0x63d8ecc1 in access_with_adjusted_size softmmu/memory.c:554:18 - #41 0x63d8d5d6 in memory_region_dispatch_write softmmu/memory.c:1504:16 - #42 0x63d5e85e in flatview_write_continue softmmu/physmem.c:2812:23 - #43 0x63d4d05b in flatview_write softmmu/physmem.c:2854:12 - #44 0x63d4cb18 in address_space_write softmmu/physmem.c:2950:18 - #45 0x63d4d387 in address_space_rw softmmu/physmem.c:2960:16 - #46 0x62ae12f2 in dma_memory_rw_relaxed include/sysemu/dma.h:89:12 - #47 0x62ae104a in dma_memory_rw include/sysemu/dma.h:132:12 - #48 0x62ae6157 in dma_memory_write include/sysemu/dma.h:173:12 - ... - SUMMARY: AddressSanitizer: stack-overflow softmmu/physmem.c:356 in address_space_translate_internal - ==1580408==ABORTING - Broken pipe - Aborted (core dumped) - -Signed-off-by: Philippe Mathieu-Daudé -Acked-by: Thomas Huth -Message-Id: <20211218160912.1591633-4-philmd@redhat.com> -Signed-off-by: Thomas Huth ---- - tests/qtest/intel-hda-test.c | 34 ++++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - -diff --git a/tests/qtest/intel-hda-test.c b/tests/qtest/intel-hda-test.c -index fc25ccc33c..a58c98e4d1 100644 ---- a/tests/qtest/intel-hda-test.c -+++ b/tests/qtest/intel-hda-test.c -@@ -29,11 +29,45 @@ static void ich9_test(void) - qtest_end(); - } - -+/* -+ * https://gitlab.com/qemu-project/qemu/-/issues/542 -+ * Used to trigger: -+ * AddressSanitizer: stack-overflow -+ */ -+static void test_issue542_ich6(void) -+{ -+ QTestState *s; -+ -+ s = qtest_init("-nographic -nodefaults -M pc-q35-6.2 " -+ "-device intel-hda,id=" HDA_ID CODEC_DEVICES); -+ -+ qtest_outl(s, 0xcf8, 0x80000804); -+ qtest_outw(s, 0xcfc, 0x06); -+ qtest_bufwrite(s, 0xff0d060f, "\x03", 1); -+ qtest_bufwrite(s, 0x0, "\x12", 1); -+ qtest_bufwrite(s, 0x2, "\x2a", 1); -+ qtest_writeb(s, 0x0, 0x12); -+ qtest_writeb(s, 0x2, 0x2a); -+ qtest_outl(s, 0xcf8, 0x80000811); -+ qtest_outl(s, 0xcfc, 0x006a4400); -+ qtest_bufwrite(s, 0x6a44005a, "\x01", 1); -+ qtest_bufwrite(s, 0x6a44005c, "\x02", 1); -+ qtest_bufwrite(s, 0x6a442050, "\x00\x00\x44\x6a", 4); -+ qtest_bufwrite(s, 0x6a44204a, "\x01", 1); -+ qtest_bufwrite(s, 0x6a44204c, "\x02", 1); -+ qtest_bufwrite(s, 0x6a44005c, "\x02", 1); -+ qtest_bufwrite(s, 0x6a442050, "\x00\x00\x44\x6a", 4); -+ qtest_bufwrite(s, 0x6a44204a, "\x01", 1); -+ qtest_bufwrite(s, 0x6a44204c, "\x02", 1); -+ qtest_quit(s); -+} -+ - int main(int argc, char **argv) - { - g_test_init(&argc, &argv, NULL); - qtest_add_func("/intel-hda/ich6", ich6_test); - qtest_add_func("/intel-hda/ich9", ich9_test); -+ qtest_add_func("/intel-hda/fuzz/issue542", test_issue542_ich6); - - return g_test_run(); - } --- -2.27.0 - diff --git a/tests-qtest-libqos-e1000e-Refer-common-PCI-ID-defini.patch b/tests-qtest-libqos-e1000e-Refer-common-PCI-ID-defini.patch deleted file mode 100644 index d6dff2b8a5afd350cde232d918016532593b03bc..0000000000000000000000000000000000000000 --- a/tests-qtest-libqos-e1000e-Refer-common-PCI-ID-defini.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f2ee9b7314f8abea5634c4d92991e6b668577499 Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Mon, 5 Dec 2022 14:47:00 +0800 -Subject: [PATCH 12/17] tests/qtest/libqos/e1000e: Refer common PCI ID - definitions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is yet another minor cleanup to ease understanding and -future refactoring of the tests. - -Signed-off-by: Akihiko Odaki -Message-Id: <20221103015017.19947-1-akihiko.odaki@daynix.com> -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Thomas Huth - -Signed-off-by: tangzhongrui ---- - tests/qtest/libqos/e1000e.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c -index a451f6168f..d351136975 100644 ---- a/tests/qtest/libqos/e1000e.c -+++ b/tests/qtest/libqos/e1000e.c -@@ -26,6 +26,8 @@ - #include "malloc.h" - #include "qgraph.h" - #include "e1000e.h" -+#include "hw/net/e1000_regs.h" -+#include "hw/pci/pci_ids.h" - - #define E1000E_IMS (0x00d0) - -@@ -248,8 +250,8 @@ static void *e1000e_pci_create(void *pci_bus, QGuestAllocator *alloc, - static void e1000e_register_nodes(void) - { - QPCIAddress addr = { -- .vendor_id = 0x8086, -- .device_id = 0x10D3, -+ .vendor_id = PCI_VENDOR_ID_INTEL, -+ .device_id = E1000_DEV_ID_82574L, - }; - - /* FIXME: every test using this node needs to setup a -netdev socket,id=hs0 --- -2.27.0 - diff --git a/tests-qtest-migration-test.c-spelling-fix-bandwith.patch b/tests-qtest-migration-test.c-spelling-fix-bandwith.patch deleted file mode 100644 index 93b57eb5e4c4f498d2f37084f65ec600ac685aa3..0000000000000000000000000000000000000000 --- a/tests-qtest-migration-test.c-spelling-fix-bandwith.patch +++ /dev/null @@ -1,26 +0,0 @@ -From a13b274df192b01a2b8f3f5ca5497a330705caa3 Mon Sep 17 00:00:00 2001 -From: zhujun2 -Date: Fri, 24 Nov 2023 00:46:51 -0800 -Subject: [PATCH] tests/qtest/migration-test.c: spelling fix: bandwith - -Signed-off-by: zhujun2 ---- - tests/qtest/migration-test.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c -index 8fad247f6c..3813b15ea9 100644 ---- a/tests/qtest/migration-test.c -+++ b/tests/qtest/migration-test.c -@@ -1157,7 +1157,7 @@ static void test_migrate_auto_converge(void) - - /* - * We want the test to be stable and as fast as possible. -- * E.g., with 1Gb/s bandwith migration may pass without throttling, -+ * E.g., with 1Gb/s bandwidth migration may pass without throttling, - * so we need to decrease a bandwidth. - */ - const int64_t init_pct = 5, inc_pct = 50, max_pct = 95; --- -2.27.0 - diff --git a/tests-qtest-pflash-Clean-up-local-variable-shadowing.patch b/tests-qtest-pflash-Clean-up-local-variable-shadowing.patch deleted file mode 100644 index e33ee823b42036af2d8563e9fd81745e4594c80b..0000000000000000000000000000000000000000 --- a/tests-qtest-pflash-Clean-up-local-variable-shadowing.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 42e516ba6969b8f61d7e5e45a4f48f257fecf8e1 Mon Sep 17 00:00:00 2001 -From: dinglimin_yewu -Date: Sat, 16 Sep 2023 17:56:31 +0800 -Subject: [PATCH] tests/qtest/pflash: Clean up local variable shadowing -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry-pick from 82fdcd3e140c8d4c63f177ece554f90f2bccdf68 - -Fix: - - tests/qtest/pflash-cfi02-test.c: In function ‘test_geometry’: - tests/qtest/pflash-cfi02-test.c:409:22: warning: declaration of ‘byte_addr’ shadows a previous local [-Wshadow=compatible-local] - 409 | uint64_t byte_addr = (uint64_t)i * c->sector_len[region]; - | ^~~~~~~~~ - tests/qtest/pflash-cfi02-test.c:342:14: note: shadowed declaration is here - 342 | uint64_t byte_addr = 0; - | ^~~~~~~~~ - -Signed-off-by: Philippe Mathieu-Daudé -Message-ID: <20230904162824.85385-4-philmd@linaro.org> -Reviewed-by: Peter Maydell -Signed-off-by: Thomas Huth -Signed-off-by: dinglimin_yewu ---- - tests/qtest/pflash-cfi02-test.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/qtest/pflash-cfi02-test.c b/tests/qtest/pflash-cfi02-test.c -index 6168edc821..bd1f946fc0 100644 ---- a/tests/qtest/pflash-cfi02-test.c -+++ b/tests/qtest/pflash-cfi02-test.c -@@ -406,7 +406,7 @@ static void test_geometry(const void *opaque) - - for (int region = 0; region < nb_erase_regions; ++region) { - for (uint32_t i = 0; i < c->nb_blocs[region]; ++i) { -- uint64_t byte_addr = (uint64_t)i * c->sector_len[region]; -+ byte_addr = (uint64_t)i * c->sector_len[region]; - g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c)); - } - } --- -2.41.0.windows.1 - diff --git a/tests-tcg-Fix-target-specific-Makefile-variables-pat.patch b/tests-tcg-Fix-target-specific-Makefile-variables-pat.patch deleted file mode 100644 index 39091adf308a3a03339957a9595b93e7d4484c27..0000000000000000000000000000000000000000 --- a/tests-tcg-Fix-target-specific-Makefile-variables-pat.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 83f5dc3719af39ab442cb7fe40a4dd752a82e53a Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 17 Mar 2023 02:22:44 +0000 -Subject: [PATCH] tests/tcg: Fix target-specific Makefile variables path for - user-mode mainline inclusion commit 533b0a1a41df3d9edeb44d6dc957f04d20ca143f - category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -Commit 812b31d3f91 refactor missed to update this path. - -Fixes: 812b31d3f91 ("configs: rename default-configs to configs and reorganise") -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211226001541.3807919-1-f4bug@amsat.org> -Signed-off-by: Paolo Bonzini - -Signed-off-by: tangbinzy ---- - tests/tcg/Makefile.target | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target -index 63cf1b2573..2d6ec70156 100644 ---- a/tests/tcg/Makefile.target -+++ b/tests/tcg/Makefile.target -@@ -33,7 +33,7 @@ all: - -include ../../../config-host.mak - -include ../config-$(TARGET).mak - ifeq ($(CONFIG_USER_ONLY),y) ---include $(SRC_PATH)/default-configs/targets/$(TARGET).mak -+-include $(SRC_PATH)/configs/targets/$(TARGET)/default.mak - endif - - # for including , in command strings --- -2.27.0 - diff --git a/tests-tcg-fix-unused-variable-in-linux-test.patch b/tests-tcg-fix-unused-variable-in-linux-test.patch deleted file mode 100644 index 98796967d983d70ca356f1deba2d15a75a34cbd8..0000000000000000000000000000000000000000 --- a/tests-tcg-fix-unused-variable-in-linux-test.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 050aa274447899ecb000aa8d62d95b6c6192fc56 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Wed, 28 Jun 2023 10:08:22 +0800 -Subject: [PATCH] tests/tcg: fix unused variable in linux-test -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 2bc6c79417b89c3306b724577e775f03fe61fb2e - -The latest hexagon compiler picks up that we never consume wcount. -Given the name of the #define that rcount checks against is WCOUNT_MAX -I figured the check just got missed. - -Signed-off-by: Alex Bennée -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20221221090411.1995037-5-alex.bennee@linaro.org> -Signed-off-by: qihao_yewu ---- - tests/tcg/multiarch/linux/linux-test.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/tests/tcg/multiarch/linux/linux-test.c b/tests/tcg/multiarch/linux/linux-test.c -index 019d8175ca..78c68540ef 100644 ---- a/tests/tcg/multiarch/linux/linux-test.c -+++ b/tests/tcg/multiarch/linux/linux-test.c -@@ -354,13 +354,17 @@ static void test_pipe(void) - if (FD_ISSET(fds[0], &rfds)) { - chk_error(read(fds[0], &ch, 1)); - rcount++; -- if (rcount >= WCOUNT_MAX) -+ if (rcount >= WCOUNT_MAX) { - break; -+ } - } - if (FD_ISSET(fds[1], &wfds)) { - ch = 'a'; - chk_error(write(fds[1], &ch, 1)); - wcount++; -+ if (wcount >= WCOUNT_MAX) { -+ break; -+ } - } - } - } --- -2.41.0.windows.1 - diff --git a/tests-unit-fix-a-Wformat-truncation-warning.patch b/tests-unit-fix-a-Wformat-truncation-warning.patch deleted file mode 100644 index 40fb8d09daa1fcbfd1e12fd5013aac15a3f994c1..0000000000000000000000000000000000000000 --- a/tests-unit-fix-a-Wformat-truncation-warning.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 133b578fabea9f4cc5936da233c04463bf94b6db Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Thu, 7 Dec 2023 09:20:00 +0800 -Subject: [PATCH] tests/unit: fix a -Wformat-truncation warning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from 6a54ac2a9737057dc19aa584d823a3011717423b - -../tests/test-qobject-input-visitor.c: In function ‘test_visitor_in_list’: -../tests/test-qobject-input-visitor.c:454:49: warning: ‘%d’ directive output may be truncated writing between 1 and 10 bytes into a region of size 6 [-Wformat-truncation=] - 454 | snprintf(string, sizeof(string), "string%d", i); - | ^~ -../tests/test-qobject-input-visitor.c:454:42: note: directive argument in the range [0, 2147483606] - 454 | snprintf(string, sizeof(string), "string%d", i); - | ^~~~~~~~~~ -../tests/test-qobject-input-visitor.c:454:9: note: ‘snprintf’ output between 8 and 17 bytes into a destination of size 12 - 454 | snprintf(string, sizeof(string), "string%d", i); - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Rather than trying to be clever, since this is called 3 times during -tests, let's simply use g_strdup_printf(). - -Signed-off-by: Marc-André Lureau -Reviewed-by: Markus Armbruster -Message-id: 20220810121513.1356081-1-marcandre.lureau@redhat.com -Reviewed-by: Peter Maydell -[PMM: fixed commit message typos] -Signed-off-by: Peter Maydell -Signed-off-by: boringandboring ---- - tests/unit/test-qobject-input-visitor.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/tests/unit/test-qobject-input-visitor.c b/tests/unit/test-qobject-input-visitor.c -index 6f59a7f432..0f28d46a4a 100644 ---- a/tests/unit/test-qobject-input-visitor.c -+++ b/tests/unit/test-qobject-input-visitor.c -@@ -448,9 +448,8 @@ static void test_visitor_in_list(TestInputVisitorData *data, - g_assert(head != NULL); - - for (i = 0, item = head; item; item = item->next, i++) { -- char string[12]; -+ g_autofree char *string = g_strdup_printf("string%d", i); - -- snprintf(string, sizeof(string), "string%d", i); - g_assert_cmpstr(item->value->string, ==, string); - g_assert_cmpint(item->value->integer, ==, 42 + i); - } --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Add-smp-generic-invalid-ma.patch b/tests-unit-test-smp-parse-Add-smp-generic-invalid-ma.patch deleted file mode 100644 index 5ea0e6cd48e1d0df115b00da2711627375e7b5fd..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Add-smp-generic-invalid-ma.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 9a98659dcb37c81e69f54d8f6cbe5116ceba5a36 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Mon, 15 Nov 2021 15:44:07 +0100 -Subject: [PATCH 05/24] tests/unit/test-smp-parse: Add 'smp-generic-invalid' - machine type -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Avoid modifying the MachineClass internals by adding the -'smp-generic-invalid' machine, which inherits from TYPE_MACHINE. - -Reviewed-by: Richard Henderson -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Yanan Wang -Message-Id: <20211216132015.815493-5-philmd@redhat.com> ---- - tests/unit/test-smp-parse.c | 25 ++++++++++++++++--------- - 1 file changed, 16 insertions(+), 9 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index f66cf7bb59..47e11089e2 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -487,6 +487,17 @@ static void machine_base_class_init(ObjectClass *oc, void *data) - mc->name = g_strdup(SMP_MACHINE_NAME); - } - -+static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ -+ /* Force invalid min CPUs and max CPUs */ -+ mc->min_cpus = 2; -+ mc->max_cpus = 511; -+ -+ mc->smp_props.dies_supported = false; -+} -+ - static void machine_with_dies_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); -@@ -530,10 +541,6 @@ static void test_generic_invalid(const void *opaque) - SMPTestData *data = &(SMPTestData){}; - int i; - -- /* Force invalid min CPUs and max CPUs */ -- mc->min_cpus = 2; -- mc->max_cpus = 511; -- - for (i = 0; i < ARRAY_SIZE(data_generic_invalid); i++) { - *data = data_generic_invalid[i]; - unsupported_params_init(mc, data); -@@ -541,10 +548,6 @@ static void test_generic_invalid(const void *opaque) - smp_parse_test(ms, data, false); - } - -- /* Reset the supported min CPUs and max CPUs */ -- mc->min_cpus = MIN_CPUS; -- mc->max_cpus = MAX_CPUS; -- - object_unref(obj); - } - -@@ -606,6 +609,10 @@ static const TypeInfo smp_machine_types[] = { - .class_init = machine_base_class_init, - .class_size = sizeof(MachineClass), - .instance_size = sizeof(MachineState), -+ }, { -+ .name = MACHINE_TYPE_NAME("smp-generic-invalid"), -+ .parent = TYPE_MACHINE, -+ .class_init = machine_generic_invalid_class_init, - }, { - .name = MACHINE_TYPE_NAME("smp-with-dies"), - .parent = TYPE_MACHINE, -@@ -625,7 +632,7 @@ int main(int argc, char *argv[]) - TYPE_MACHINE, - test_generic_valid); - g_test_add_data_func("/test-smp-parse/generic/invalid", -- TYPE_MACHINE, -+ MACHINE_TYPE_NAME("smp-generic-invalid"), - test_generic_invalid); - g_test_add_data_func("/test-smp-parse/with_dies", - MACHINE_TYPE_NAME("smp-with-dies"), --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Add-smp-generic-valid-mach.patch b/tests-unit-test-smp-parse-Add-smp-generic-valid-mach.patch deleted file mode 100644 index a8b17e751a578f914102e7911b820888227dbe54..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Add-smp-generic-valid-mach.patch +++ /dev/null @@ -1,75 +0,0 @@ -From c33c7dd51eebf5ae7b7ece1e829b0a5ffdcebfe1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Mon, 15 Nov 2021 15:49:59 +0100 -Subject: [PATCH 06/24] tests/unit/test-smp-parse: Add 'smp-generic-valid' - machine type -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Keep the common TYPE_MACHINE class initialization in -machine_base_class_init(), make it abstract, and move -the non-common code to a new class: "smp-generic-valid". - -Reviewed-by: Richard Henderson -Signed-off-by: Philippe Mathieu-Daudé -Reviewed-by: Yanan Wang -Message-Id: <20211216132015.815493-6-philmd@redhat.com> ---- - tests/unit/test-smp-parse.c | 19 +++++++++++++++---- - 1 file changed, 15 insertions(+), 4 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index 47e11089e2..b20bf2c235 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -478,13 +478,19 @@ static void machine_base_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); - -+ mc->smp_props.prefer_sockets = true; -+ -+ mc->name = g_strdup(SMP_MACHINE_NAME); -+} -+ -+static void machine_generic_valid_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ - mc->min_cpus = MIN_CPUS; - mc->max_cpus = MAX_CPUS; - -- mc->smp_props.prefer_sockets = true; - mc->smp_props.dies_supported = false; -- -- mc->name = g_strdup(SMP_MACHINE_NAME); - } - - static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) -@@ -606,9 +612,14 @@ static const TypeInfo smp_machine_types[] = { - { - .name = TYPE_MACHINE, - .parent = TYPE_OBJECT, -+ .abstract = true, - .class_init = machine_base_class_init, - .class_size = sizeof(MachineClass), - .instance_size = sizeof(MachineState), -+ }, { -+ .name = MACHINE_TYPE_NAME("smp-generic-valid"), -+ .parent = TYPE_MACHINE, -+ .class_init = machine_generic_valid_class_init, - }, { - .name = MACHINE_TYPE_NAME("smp-generic-invalid"), - .parent = TYPE_MACHINE, -@@ -629,7 +640,7 @@ int main(int argc, char *argv[]) - g_test_init(&argc, &argv, NULL); - - g_test_add_data_func("/test-smp-parse/generic/valid", -- TYPE_MACHINE, -+ MACHINE_TYPE_NAME("smp-generic-valid"), - test_generic_valid); - g_test_add_data_func("/test-smp-parse/generic/invalid", - MACHINE_TYPE_NAME("smp-generic-invalid"), --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Add-smp-with-dies-machine-.patch b/tests-unit-test-smp-parse-Add-smp-with-dies-machine-.patch deleted file mode 100644 index 1d779fc274a8d8140d71c76d165fd0ca5e0644da..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Add-smp-with-dies-machine-.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 4981e75623db6ca681d13719ffcf61b0cfac3edc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Mon, 15 Nov 2021 12:39:12 +0100 -Subject: [PATCH 04/24] tests/unit/test-smp-parse: Add 'smp-with-dies' machine - type -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Avoid modifying the MachineClass internals by adding the -'smp-with-dies' machine, which inherits from TYPE_MACHINE. - -Reviewed-by: Richard Henderson -Reviewed-by: Yanan Wang -Tested-by: Yanan Wang -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211216132015.815493-4-philmd@redhat.com> ---- - tests/unit/test-smp-parse.c | 22 +++++++++++++++------- - 1 file changed, 15 insertions(+), 7 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index 425ed6b6b9..f66cf7bb59 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -487,6 +487,16 @@ static void machine_base_class_init(ObjectClass *oc, void *data) - mc->name = g_strdup(SMP_MACHINE_NAME); - } - -+static void machine_with_dies_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ -+ mc->min_cpus = MIN_CPUS; -+ mc->max_cpus = MAX_CPUS; -+ -+ mc->smp_props.dies_supported = true; -+} -+ - static void test_generic_valid(const void *opaque) - { - const char *machine_type = opaque; -@@ -548,9 +558,6 @@ static void test_with_dies(const void *opaque) - unsigned int num_dies = 2; - int i; - -- /* Force the SMP compat properties */ -- mc->smp_props.dies_supported = true; -- - for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { - *data = data_generic_valid[i]; - unsupported_params_init(mc, data); -@@ -588,9 +595,6 @@ static void test_with_dies(const void *opaque) - smp_parse_test(ms, data, false); - } - -- /* Restore the SMP compat properties */ -- mc->smp_props.dies_supported = false; -- - object_unref(obj); - } - -@@ -602,6 +606,10 @@ static const TypeInfo smp_machine_types[] = { - .class_init = machine_base_class_init, - .class_size = sizeof(MachineClass), - .instance_size = sizeof(MachineState), -+ }, { -+ .name = MACHINE_TYPE_NAME("smp-with-dies"), -+ .parent = TYPE_MACHINE, -+ .class_init = machine_with_dies_class_init, - } - }; - -@@ -620,7 +628,7 @@ int main(int argc, char *argv[]) - TYPE_MACHINE, - test_generic_invalid); - g_test_add_data_func("/test-smp-parse/with_dies", -- TYPE_MACHINE, -+ MACHINE_TYPE_NAME("smp-with-dies"), - test_with_dies); - - g_test_run(); --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Add-testcases-for-CPU-clus.patch b/tests-unit-test-smp-parse-Add-testcases-for-CPU-clus.patch deleted file mode 100644 index e9c9aefbb230a5b0fb05a8e7f9f03f2bf6592158..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Add-testcases-for-CPU-clus.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 5e8a39a560ea58308f66d47639c0d5d2e704997f Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Tue, 28 Dec 2021 17:22:11 +0800 -Subject: [PATCH 12/24] tests/unit/test-smp-parse: Add testcases for CPU - clusters -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add testcases for parsing of the four-level CPU topology hierarchy, -ie sockets/clusters/cores/threads, which will be supported on ARM -virt machines. - -Signed-off-by: Yanan Wang -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20211228092221.21068-5-wangyanan55@huawei.com> -Signed-off-by: Philippe Mathieu-Daudé ---- - tests/unit/test-smp-parse.c | 130 ++++++++++++++++++++++++++++++++++-- - 1 file changed, 123 insertions(+), 7 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index b6df8137fc..331719bbc4 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -61,6 +61,20 @@ - .has_maxcpus = hf, .maxcpus = f, \ - } - -+/* -+ * Currently a 4-level topology hierarchy is supported on ARM virt machines -+ * -sockets/clusters/cores/threads -+ */ -+#define SMP_CONFIG_WITH_CLUSTERS(ha, a, hb, b, hc, c, hd, d, he, e, hf, f) \ -+ { \ -+ .has_cpus = ha, .cpus = a, \ -+ .has_sockets = hb, .sockets = b, \ -+ .has_clusters = hc, .clusters = c, \ -+ .has_cores = hd, .cores = d, \ -+ .has_threads = he, .threads = e, \ -+ .has_maxcpus = hf, .maxcpus = f, \ -+ } -+ - /** - * @config - the given SMP configuration - * @expect_prefer_sockets - the expected parsing result for the -@@ -290,6 +304,10 @@ static const struct SMPTestData data_generic_invalid[] = { - /* config: -smp 2,dies=2 */ - .config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), - .expect_error = "dies not supported by this machine's CPU topology", -+ }, { -+ /* config: -smp 2,clusters=2 */ -+ .config = SMP_CONFIG_WITH_CLUSTERS(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), -+ .expect_error = "clusters not supported by this machine's CPU topology", - }, { - /* config: -smp 8,sockets=2,cores=4,threads=2,maxcpus=8 */ - .config = SMP_CONFIG_GENERIC(T, 8, T, 2, T, 4, T, 2, T, 8), -@@ -337,20 +355,40 @@ static const struct SMPTestData data_with_dies_invalid[] = { - }, - }; - -+static const struct SMPTestData data_with_clusters_invalid[] = { -+ { -+ /* config: -smp 16,sockets=2,clusters=2,cores=4,threads=2,maxcpus=16 */ -+ .config = SMP_CONFIG_WITH_CLUSTERS(T, 16, T, 2, T, 2, T, 4, T, 2, T, 16), -+ .expect_error = "Invalid CPU topology: " -+ "product of the hierarchy must match maxcpus: " -+ "sockets (2) * clusters (2) * cores (4) * threads (2) " -+ "!= maxcpus (16)", -+ }, { -+ /* config: -smp 34,sockets=2,clusters=2,cores=4,threads=2,maxcpus=32 */ -+ .config = SMP_CONFIG_WITH_CLUSTERS(T, 34, T, 2, T, 2, T, 4, T, 2, T, 32), -+ .expect_error = "Invalid CPU topology: " -+ "maxcpus must be equal to or greater than smp: " -+ "sockets (2) * clusters (2) * cores (4) * threads (2) " -+ "== maxcpus (32) < smp_cpus (34)", -+ }, -+}; -+ - static char *smp_config_to_string(const SMPConfiguration *config) - { - return g_strdup_printf( - "(SMPConfiguration) {\n" -- " .has_cpus = %5s, cpus = %" PRId64 ",\n" -- " .has_sockets = %5s, sockets = %" PRId64 ",\n" -- " .has_dies = %5s, dies = %" PRId64 ",\n" -- " .has_cores = %5s, cores = %" PRId64 ",\n" -- " .has_threads = %5s, threads = %" PRId64 ",\n" -- " .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n" -+ " .has_cpus = %5s, cpus = %" PRId64 ",\n" -+ " .has_sockets = %5s, sockets = %" PRId64 ",\n" -+ " .has_dies = %5s, dies = %" PRId64 ",\n" -+ " .has_clusters = %5s, clusters = %" PRId64 ",\n" -+ " .has_cores = %5s, cores = %" PRId64 ",\n" -+ " .has_threads = %5s, threads = %" PRId64 ",\n" -+ " .has_maxcpus = %5s, maxcpus = %" PRId64 ",\n" - "}", - config->has_cpus ? "true" : "false", config->cpus, - config->has_sockets ? "true" : "false", config->sockets, - config->has_dies ? "true" : "false", config->dies, -+ config->has_clusters ? "true" : "false", config->clusters, - config->has_cores ? "true" : "false", config->cores, - config->has_threads ? "true" : "false", config->threads, - config->has_maxcpus ? "true" : "false", config->maxcpus); -@@ -363,11 +401,12 @@ static char *cpu_topology_to_string(const CpuTopology *topo) - " .cpus = %u,\n" - " .sockets = %u,\n" - " .dies = %u,\n" -+ " .clusters = %u,\n" - " .cores = %u,\n" - " .threads = %u,\n" - " .max_cpus = %u,\n" - "}", -- topo->cpus, topo->sockets, topo->dies, -+ topo->cpus, topo->sockets, topo->dies, topo->clusters, - topo->cores, topo->threads, topo->max_cpus); - } - -@@ -391,6 +430,7 @@ static void check_parse(MachineState *ms, const SMPConfiguration *config, - (ms->smp.cpus == expect_topo->cpus) && - (ms->smp.sockets == expect_topo->sockets) && - (ms->smp.dies == expect_topo->dies) && -+ (ms->smp.clusters == expect_topo->clusters) && - (ms->smp.cores == expect_topo->cores) && - (ms->smp.threads == expect_topo->threads) && - (ms->smp.max_cpus == expect_topo->max_cpus)) { -@@ -472,6 +512,11 @@ static void unsupported_params_init(const MachineClass *mc, SMPTestData *data) - data->expect_prefer_sockets.dies = 1; - data->expect_prefer_cores.dies = 1; - } -+ -+ if (!mc->smp_props.clusters_supported) { -+ data->expect_prefer_sockets.clusters = 1; -+ data->expect_prefer_cores.clusters = 1; -+ } - } - - static void machine_base_class_init(ObjectClass *oc, void *data) -@@ -491,6 +536,7 @@ static void machine_generic_valid_class_init(ObjectClass *oc, void *data) - mc->max_cpus = MAX_CPUS; - - mc->smp_props.dies_supported = false; -+ mc->smp_props.clusters_supported = false; - } - - static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) -@@ -502,6 +548,7 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) - mc->max_cpus = 511; - - mc->smp_props.dies_supported = false; -+ mc->smp_props.clusters_supported = false; - } - - static void machine_with_dies_class_init(ObjectClass *oc, void *data) -@@ -512,6 +559,18 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data) - mc->max_cpus = MAX_CPUS; - - mc->smp_props.dies_supported = true; -+ mc->smp_props.clusters_supported = false; -+} -+ -+static void machine_with_clusters_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ -+ mc->min_cpus = MIN_CPUS; -+ mc->max_cpus = MAX_CPUS; -+ -+ mc->smp_props.clusters_supported = true; -+ mc->smp_props.dies_supported = false; - } - - static void test_generic_valid(const void *opaque) -@@ -607,6 +666,56 @@ static void test_with_dies(const void *opaque) - object_unref(obj); - } - -+static void test_with_clusters(const void *opaque) -+{ -+ const char *machine_type = opaque; -+ Object *obj = object_new(machine_type); -+ MachineState *ms = MACHINE(obj); -+ MachineClass *mc = MACHINE_GET_CLASS(obj); -+ SMPTestData data = {}; -+ unsigned int num_clusters = 2; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { -+ data = data_generic_valid[i]; -+ unsupported_params_init(mc, &data); -+ -+ /* when clusters parameter is omitted, it will be set as 1 */ -+ data.expect_prefer_sockets.clusters = 1; -+ data.expect_prefer_cores.clusters = 1; -+ -+ smp_parse_test(ms, &data, true); -+ -+ /* when clusters parameter is specified */ -+ data.config.has_clusters = true; -+ data.config.clusters = num_clusters; -+ if (data.config.has_cpus) { -+ data.config.cpus *= num_clusters; -+ } -+ if (data.config.has_maxcpus) { -+ data.config.maxcpus *= num_clusters; -+ } -+ -+ data.expect_prefer_sockets.clusters = num_clusters; -+ data.expect_prefer_sockets.cpus *= num_clusters; -+ data.expect_prefer_sockets.max_cpus *= num_clusters; -+ data.expect_prefer_cores.clusters = num_clusters; -+ data.expect_prefer_cores.cpus *= num_clusters; -+ data.expect_prefer_cores.max_cpus *= num_clusters; -+ -+ smp_parse_test(ms, &data, true); -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(data_with_clusters_invalid); i++) { -+ data = data_with_clusters_invalid[i]; -+ unsupported_params_init(mc, &data); -+ -+ smp_parse_test(ms, &data, false); -+ } -+ -+ object_unref(obj); -+} -+ - /* Type info of the tested machine */ - static const TypeInfo smp_machine_types[] = { - { -@@ -628,6 +737,10 @@ static const TypeInfo smp_machine_types[] = { - .name = MACHINE_TYPE_NAME("smp-with-dies"), - .parent = TYPE_MACHINE, - .class_init = machine_with_dies_class_init, -+ }, { -+ .name = MACHINE_TYPE_NAME("smp-with-clusters"), -+ .parent = TYPE_MACHINE, -+ .class_init = machine_with_clusters_class_init, - } - }; - -@@ -648,6 +761,9 @@ int main(int argc, char *argv[]) - g_test_add_data_func("/test-smp-parse/with_dies", - MACHINE_TYPE_NAME("smp-with-dies"), - test_with_dies); -+ g_test_add_data_func("/test-smp-parse/with_clusters", -+ MACHINE_TYPE_NAME("smp-with-clusters"), -+ test_with_clusters); - - g_test_run(); - --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Constify-some-pointer-stru.patch b/tests-unit-test-smp-parse-Constify-some-pointer-stru.patch deleted file mode 100644 index 85a56a425c7be042146bc96406b52e162a5544da..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Constify-some-pointer-stru.patch +++ /dev/null @@ -1,82 +0,0 @@ -From bcf4b802bd8971c0c5a255e606b15900cd47c6b6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 11 Nov 2021 10:23:06 +0100 -Subject: [PATCH 08/24] tests/unit/test-smp-parse: Constify some pointer/struct -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Declare structures const when we don't need to modify -them at runtime. - -Reviewed-by: Andrew Jones -Reviewed-by: Richard Henderson -Reviewed-by: Yanan Wang -Tested-by: Yanan Wang -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211216132015.815493-8-philmd@redhat.com> ---- - tests/unit/test-smp-parse.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index 395929b66c..0f98c9509e 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -83,7 +83,7 @@ typedef struct SMPTestData { - * then test the automatic calculation algorithm of the missing - * values in the parser. - */ --static struct SMPTestData data_generic_valid[] = { -+static const struct SMPTestData data_generic_valid[] = { - { - /* config: no configuration provided - * expect: cpus=1,sockets=1,cores=1,threads=1,maxcpus=1 */ -@@ -285,7 +285,7 @@ static struct SMPTestData data_generic_valid[] = { - }, - }; - --static struct SMPTestData data_generic_invalid[] = { -+static const struct SMPTestData data_generic_invalid[] = { - { - /* config: -smp 2,dies=2 */ - .config = SMP_CONFIG_WITH_DIES(T, 2, F, 0, T, 2, F, 0, F, 0, F, 0), -@@ -319,7 +319,7 @@ static struct SMPTestData data_generic_invalid[] = { - }, - }; - --static struct SMPTestData data_with_dies_invalid[] = { -+static const struct SMPTestData data_with_dies_invalid[] = { - { - /* config: -smp 16,sockets=2,dies=2,cores=4,threads=2,maxcpus=16 */ - .config = SMP_CONFIG_WITH_DIES(T, 16, T, 2, T, 2, T, 4, T, 2, T, 16), -@@ -356,7 +356,7 @@ static char *smp_config_to_string(SMPConfiguration *config) - config->has_maxcpus ? "true" : "false", config->maxcpus); - } - --static char *cpu_topology_to_string(CpuTopology *topo) -+static char *cpu_topology_to_string(const CpuTopology *topo) - { - return g_strdup_printf( - "(CpuTopology) {\n" -@@ -372,7 +372,7 @@ static char *cpu_topology_to_string(CpuTopology *topo) - } - - static void check_parse(MachineState *ms, SMPConfiguration *config, -- CpuTopology *expect_topo, const char *expect_err, -+ const CpuTopology *expect_topo, const char *expect_err, - bool is_valid) - { - g_autofree char *config_str = smp_config_to_string(config); -@@ -466,7 +466,7 @@ static void smp_parse_test(MachineState *ms, SMPTestData *data, bool is_valid) - } - - /* The parsed results of the unsupported parameters should be 1 */ --static void unsupported_params_init(MachineClass *mc, SMPTestData *data) -+static void unsupported_params_init(const MachineClass *mc, SMPTestData *data) - { - if (!mc->smp_props.dies_supported) { - data->expect_prefer_sockets.dies = 1; --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Keep-default-MIN-MAX-CPUs-.patch b/tests-unit-test-smp-parse-Keep-default-MIN-MAX-CPUs-.patch deleted file mode 100644 index 6e343576fdca6a1ef4713535849d6d9375c71cd9..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Keep-default-MIN-MAX-CPUs-.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 214511b1799b94cfd514a222d087bb888ed808ba Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Tue, 28 Dec 2021 17:22:13 +0800 -Subject: [PATCH 14/24] tests/unit/test-smp-parse: Keep default MIN/MAX CPUs in - machine_base_class_init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Most machine types in test-smp-parse will be OK to have the default -MIN/MAX CPUs except "smp-generic-invalid", let's keep the default -values in machine_base_class_init which will be inherited. And if -we hope a different value for a specific machine, modify it in its -own initialization function. - -Signed-off-by: Yanan Wang -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20211228092221.21068-7-wangyanan55@huawei.com> -Signed-off-by: Philippe Mathieu-Daudé ---- - tests/unit/test-smp-parse.c | 16 ++-------------- - 1 file changed, 2 insertions(+), 14 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index 72d83d1bbc..fdc39a846c 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -523,15 +523,10 @@ static void machine_base_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); - -- mc->name = g_strdup(SMP_MACHINE_NAME); --} -- --static void machine_generic_valid_class_init(ObjectClass *oc, void *data) --{ -- MachineClass *mc = MACHINE_CLASS(oc); -- - mc->min_cpus = MIN_CPUS; - mc->max_cpus = MAX_CPUS; -+ -+ mc->name = g_strdup(SMP_MACHINE_NAME); - } - - static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) -@@ -547,9 +542,6 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); - -- mc->min_cpus = MIN_CPUS; -- mc->max_cpus = MAX_CPUS; -- - mc->smp_props.dies_supported = true; - } - -@@ -557,9 +549,6 @@ static void machine_with_clusters_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); - -- mc->min_cpus = MIN_CPUS; -- mc->max_cpus = MAX_CPUS; -- - mc->smp_props.clusters_supported = true; - } - -@@ -718,7 +707,6 @@ static const TypeInfo smp_machine_types[] = { - }, { - .name = MACHINE_TYPE_NAME("smp-generic-valid"), - .parent = TYPE_MACHINE, -- .class_init = machine_generic_valid_class_init, - }, { - .name = MACHINE_TYPE_NAME("smp-generic-invalid"), - .parent = TYPE_MACHINE, --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-No-need-to-explicitly-zero.patch b/tests-unit-test-smp-parse-No-need-to-explicitly-zero.patch deleted file mode 100644 index 59157169c32a498e5ae0455aaaf6dd1312c4b17f..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-No-need-to-explicitly-zero.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 77bca7d51e99f8ba4d11635ff9f51615739f4d55 Mon Sep 17 00:00:00 2001 -From: Yanan Wang -Date: Tue, 28 Dec 2021 17:22:12 +0800 -Subject: [PATCH 13/24] tests/unit/test-smp-parse: No need to explicitly zero - MachineClass members -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The default value of the MachineClass members is 0, which -means we don't have to explicitly zero them. Also the value -of "mc->smp_props.prefer_sockets" will be taken care of by -smp_parse_test(), we don't necessarily need the statement -in machine_base_class_init() either. - -Signed-off-by: Yanan Wang -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20211228092221.21068-6-wangyanan55@huawei.com> -Signed-off-by: Philippe Mathieu-Daudé ---- - tests/unit/test-smp-parse.c | 10 ---------- - 1 file changed, 10 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index 331719bbc4..72d83d1bbc 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -523,8 +523,6 @@ static void machine_base_class_init(ObjectClass *oc, void *data) - { - MachineClass *mc = MACHINE_CLASS(oc); - -- mc->smp_props.prefer_sockets = true; -- - mc->name = g_strdup(SMP_MACHINE_NAME); - } - -@@ -534,9 +532,6 @@ static void machine_generic_valid_class_init(ObjectClass *oc, void *data) - - mc->min_cpus = MIN_CPUS; - mc->max_cpus = MAX_CPUS; -- -- mc->smp_props.dies_supported = false; -- mc->smp_props.clusters_supported = false; - } - - static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) -@@ -546,9 +541,6 @@ static void machine_generic_invalid_class_init(ObjectClass *oc, void *data) - /* Force invalid min CPUs and max CPUs */ - mc->min_cpus = 2; - mc->max_cpus = 511; -- -- mc->smp_props.dies_supported = false; -- mc->smp_props.clusters_supported = false; - } - - static void machine_with_dies_class_init(ObjectClass *oc, void *data) -@@ -559,7 +551,6 @@ static void machine_with_dies_class_init(ObjectClass *oc, void *data) - mc->max_cpus = MAX_CPUS; - - mc->smp_props.dies_supported = true; -- mc->smp_props.clusters_supported = false; - } - - static void machine_with_clusters_class_init(ObjectClass *oc, void *data) -@@ -570,7 +561,6 @@ static void machine_with_clusters_class_init(ObjectClass *oc, void *data) - mc->max_cpus = MAX_CPUS; - - mc->smp_props.clusters_supported = true; -- mc->smp_props.dies_supported = false; - } - - static void test_generic_valid(const void *opaque) --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Pass-machine-type-as-argum.patch b/tests-unit-test-smp-parse-Pass-machine-type-as-argum.patch deleted file mode 100644 index d30509c63c2344dd3d7f27352b874426505be9c6..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Pass-machine-type-as-argum.patch +++ /dev/null @@ -1,69 +0,0 @@ -From d8b2aee4fd6ccd8eb621522b647c392c1dd7955c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Mon, 15 Nov 2021 12:32:09 +0100 -Subject: [PATCH 02/24] tests/unit/test-smp-parse: Pass machine type as - argument to tests -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use g_test_add_data_func() instead of g_test_add_func() so we can -pass the machine type to the tests (we will soon have different -machine types). - -Reviewed-by: Richard Henderson -Reviewed-by: Yanan Wang -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211216132015.815493-2-philmd@redhat.com> ---- - tests/unit/test-smp-parse.c | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index b02450e25a..37c6b4981d 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -487,9 +487,10 @@ static void machine_base_class_init(ObjectClass *oc, void *data) - mc->name = g_strdup(SMP_MACHINE_NAME); - } - --static void test_generic(void) -+static void test_generic(const void *opaque) - { -- Object *obj = object_new(TYPE_MACHINE); -+ const char *machine_type = opaque; -+ Object *obj = object_new(machine_type); - MachineState *ms = MACHINE(obj); - MachineClass *mc = MACHINE_GET_CLASS(obj); - SMPTestData *data = &(SMPTestData){{ }}; -@@ -525,9 +526,10 @@ static void test_generic(void) - object_unref(obj); - } - --static void test_with_dies(void) -+static void test_with_dies(const void *opaque) - { -- Object *obj = object_new(TYPE_MACHINE); -+ const char *machine_type = opaque; -+ Object *obj = object_new(machine_type); - MachineState *ms = MACHINE(obj); - MachineClass *mc = MACHINE_GET_CLASS(obj); - SMPTestData *data = &(SMPTestData){{ }}; -@@ -599,8 +601,12 @@ int main(int argc, char *argv[]) - - g_test_init(&argc, &argv, NULL); - -- g_test_add_func("/test-smp-parse/generic", test_generic); -- g_test_add_func("/test-smp-parse/with_dies", test_with_dies); -+ g_test_add_data_func("/test-smp-parse/generic", -+ TYPE_MACHINE, -+ test_generic); -+ g_test_add_data_func("/test-smp-parse/with_dies", -+ TYPE_MACHINE, -+ test_with_dies); - - g_test_run(); - --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Simplify-pointer-to-compou.patch b/tests-unit-test-smp-parse-Simplify-pointer-to-compou.patch deleted file mode 100644 index 68cc318f4b2054ce0adf70d4d66b2a4d09ce16e0..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Simplify-pointer-to-compou.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 964965721bbed1941bf77e5a748efc1274b7c289 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Thu, 11 Nov 2021 08:58:40 +0100 -Subject: [PATCH 07/24] tests/unit/test-smp-parse: Simplify pointer to compound - literal use -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We can simply use a local variable (and pass its pointer) instead -of a pointer to a compound literal. - -Reviewed-by: Andrew Jones -Reviewed-by: Richard Henderson -Reviewed-by: Yanan Wang -Tested-by: Yanan Wang -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211216132015.815493-7-philmd@redhat.com> ---- - tests/unit/test-smp-parse.c | 66 ++++++++++++++++++------------------- - 1 file changed, 33 insertions(+), 33 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index b20bf2c235..395929b66c 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -520,19 +520,19 @@ static void test_generic_valid(const void *opaque) - Object *obj = object_new(machine_type); - MachineState *ms = MACHINE(obj); - MachineClass *mc = MACHINE_GET_CLASS(obj); -- SMPTestData *data = &(SMPTestData){{ }}; -+ SMPTestData data = {}; - int i; - - for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { -- *data = data_generic_valid[i]; -- unsupported_params_init(mc, data); -+ data = data_generic_valid[i]; -+ unsupported_params_init(mc, &data); - -- smp_parse_test(ms, data, true); -+ smp_parse_test(ms, &data, true); - - /* Unsupported parameters can be provided with their values as 1 */ -- data->config.has_dies = true; -- data->config.dies = 1; -- smp_parse_test(ms, data, true); -+ data.config.has_dies = true; -+ data.config.dies = 1; -+ smp_parse_test(ms, &data, true); - } - - object_unref(obj); -@@ -544,14 +544,14 @@ static void test_generic_invalid(const void *opaque) - Object *obj = object_new(machine_type); - MachineState *ms = MACHINE(obj); - MachineClass *mc = MACHINE_GET_CLASS(obj); -- SMPTestData *data = &(SMPTestData){}; -+ SMPTestData data = {}; - int i; - - for (i = 0; i < ARRAY_SIZE(data_generic_invalid); i++) { -- *data = data_generic_invalid[i]; -- unsupported_params_init(mc, data); -+ data = data_generic_invalid[i]; -+ unsupported_params_init(mc, &data); - -- smp_parse_test(ms, data, false); -+ smp_parse_test(ms, &data, false); - } - - object_unref(obj); -@@ -563,45 +563,45 @@ static void test_with_dies(const void *opaque) - Object *obj = object_new(machine_type); - MachineState *ms = MACHINE(obj); - MachineClass *mc = MACHINE_GET_CLASS(obj); -- SMPTestData *data = &(SMPTestData){{ }}; -+ SMPTestData data = {}; - unsigned int num_dies = 2; - int i; - - for (i = 0; i < ARRAY_SIZE(data_generic_valid); i++) { -- *data = data_generic_valid[i]; -- unsupported_params_init(mc, data); -+ data = data_generic_valid[i]; -+ unsupported_params_init(mc, &data); - - /* when dies parameter is omitted, it will be set as 1 */ -- data->expect_prefer_sockets.dies = 1; -- data->expect_prefer_cores.dies = 1; -+ data.expect_prefer_sockets.dies = 1; -+ data.expect_prefer_cores.dies = 1; - -- smp_parse_test(ms, data, true); -+ smp_parse_test(ms, &data, true); - - /* when dies parameter is specified */ -- data->config.has_dies = true; -- data->config.dies = num_dies; -- if (data->config.has_cpus) { -- data->config.cpus *= num_dies; -+ data.config.has_dies = true; -+ data.config.dies = num_dies; -+ if (data.config.has_cpus) { -+ data.config.cpus *= num_dies; - } -- if (data->config.has_maxcpus) { -- data->config.maxcpus *= num_dies; -+ if (data.config.has_maxcpus) { -+ data.config.maxcpus *= num_dies; - } - -- data->expect_prefer_sockets.dies = num_dies; -- data->expect_prefer_sockets.cpus *= num_dies; -- data->expect_prefer_sockets.max_cpus *= num_dies; -- data->expect_prefer_cores.dies = num_dies; -- data->expect_prefer_cores.cpus *= num_dies; -- data->expect_prefer_cores.max_cpus *= num_dies; -+ data.expect_prefer_sockets.dies = num_dies; -+ data.expect_prefer_sockets.cpus *= num_dies; -+ data.expect_prefer_sockets.max_cpus *= num_dies; -+ data.expect_prefer_cores.dies = num_dies; -+ data.expect_prefer_cores.cpus *= num_dies; -+ data.expect_prefer_cores.max_cpus *= num_dies; - -- smp_parse_test(ms, data, true); -+ smp_parse_test(ms, &data, true); - } - - for (i = 0; i < ARRAY_SIZE(data_with_dies_invalid); i++) { -- *data = data_with_dies_invalid[i]; -- unsupported_params_init(mc, data); -+ data = data_with_dies_invalid[i]; -+ unsupported_params_init(mc, &data); - -- smp_parse_test(ms, data, false); -+ smp_parse_test(ms, &data, false); - } - - object_unref(obj); --- -2.27.0 - diff --git a/tests-unit-test-smp-parse-Split-the-generic-test-in-.patch b/tests-unit-test-smp-parse-Split-the-generic-test-in-.patch deleted file mode 100644 index dc13f6dfd02c8d576d0674a8ce577b5ed17c6588..0000000000000000000000000000000000000000 --- a/tests-unit-test-smp-parse-Split-the-generic-test-in-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From fad259cf9996dbc4001cb94ec3c846d649401027 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= -Date: Mon, 15 Nov 2021 12:35:43 +0100 -Subject: [PATCH 03/24] tests/unit/test-smp-parse: Split the 'generic' test in - valid / invalid -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Split the 'generic' test in two tests: 'valid' and 'invalid'. -This will allow us to remove the hack which modifies the -MachineClass internal state. - -Reviewed-by: Richard Henderson -Reviewed-by: Yanan Wang -Signed-off-by: Philippe Mathieu-Daudé -Message-Id: <20211216132015.815493-3-philmd@redhat.com> ---- - tests/unit/test-smp-parse.c | 21 ++++++++++++++++++--- - 1 file changed, 18 insertions(+), 3 deletions(-) - -diff --git a/tests/unit/test-smp-parse.c b/tests/unit/test-smp-parse.c -index 37c6b4981d..425ed6b6b9 100644 ---- a/tests/unit/test-smp-parse.c -+++ b/tests/unit/test-smp-parse.c -@@ -487,7 +487,7 @@ static void machine_base_class_init(ObjectClass *oc, void *data) - mc->name = g_strdup(SMP_MACHINE_NAME); - } - --static void test_generic(const void *opaque) -+static void test_generic_valid(const void *opaque) - { - const char *machine_type = opaque; - Object *obj = object_new(machine_type); -@@ -508,6 +508,18 @@ static void test_generic(const void *opaque) - smp_parse_test(ms, data, true); - } - -+ object_unref(obj); -+} -+ -+static void test_generic_invalid(const void *opaque) -+{ -+ const char *machine_type = opaque; -+ Object *obj = object_new(machine_type); -+ MachineState *ms = MACHINE(obj); -+ MachineClass *mc = MACHINE_GET_CLASS(obj); -+ SMPTestData *data = &(SMPTestData){}; -+ int i; -+ - /* Force invalid min CPUs and max CPUs */ - mc->min_cpus = 2; - mc->max_cpus = 511; -@@ -601,9 +613,12 @@ int main(int argc, char *argv[]) - - g_test_init(&argc, &argv, NULL); - -- g_test_add_data_func("/test-smp-parse/generic", -+ g_test_add_data_func("/test-smp-parse/generic/valid", -+ TYPE_MACHINE, -+ test_generic_valid); -+ g_test_add_data_func("/test-smp-parse/generic/invalid", - TYPE_MACHINE, -- test_generic); -+ test_generic_invalid); - g_test_add_data_func("/test-smp-parse/with_dies", - TYPE_MACHINE, - test_with_dies); --- -2.27.0 - diff --git a/tests-vhost-user-test-release-mutex-on-protocol-viol.patch b/tests-vhost-user-test-release-mutex-on-protocol-viol.patch deleted file mode 100644 index 884be58c52bf4ede91fee6afdbd16b3f10bee9d7..0000000000000000000000000000000000000000 --- a/tests-vhost-user-test-release-mutex-on-protocol-viol.patch +++ /dev/null @@ -1,40 +0,0 @@ -From b09ffbe7b85f891a8f5d425e5a98298a55c8400b Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Sun, 6 Aug 2023 23:48:47 -0700 -Subject: [PATCH] tests: vhost-user-test: release mutex on protocol violation - -cherry picked from commit 9260993e27cdbbd2e829d405cc63b1faefec6088 - -chr_read() is printing an error message and returning with s->data_mutex taken. -This can potentially cause a hang. Reported by Coverity. - -Signed-off-by: Paolo Bonzini -Signed-off-by: Wanghe Xiao ---- - tests/qtest/vhost-user-test.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c -index 3d6337fb5c..d07babc06d 100644 ---- a/tests/qtest/vhost-user-test.c -+++ b/tests/qtest/vhost-user-test.c -@@ -328,7 +328,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) - if (size != msg.size) { - g_test_message("Wrong message size received %d != %d", - size, msg.size); -- return; -+ goto out; - } - } - -@@ -429,6 +429,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) - break; - } - -+out: - g_mutex_unlock(&s->data_mutex); - } - --- -2.41.0.windows.1 - diff --git a/tests-vm-use-o-IdentitiesOnly-yes-for-ssh.patch b/tests-vm-use-o-IdentitiesOnly-yes-for-ssh.patch deleted file mode 100644 index f528b6a77f8923e68da6e47f333677cac09f924c..0000000000000000000000000000000000000000 --- a/tests-vm-use-o-IdentitiesOnly-yes-for-ssh.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 09ebd704c71b855a1c5732d4e4816aa9aed3fe13 Mon Sep 17 00:00:00 2001 -From: jianchunfu -Date: Tue, 22 Nov 2022 16:47:27 +0800 -Subject: [PATCH 02/29] tests/vm: use -o IdentitiesOnly=yes for ssh - -When one has a lot of keys in ~/.ssh directory, the ssh command will -try all of them before the one specified on the command line, and this -may cause the remote ssh server to reject the connection due to too -many failed authentication attempts. -Fix by adding -o IdentitiesOnly=yes, which makes the ssh client -consider only the keys specified on the command line. - -Signed-off-by: Ilya Leoshkevich -Signed-off-by: jianchunfu ---- - tests/vm/basevm.py | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py -index 254e11c932..4003bc5fef 100644 ---- a/tests/vm/basevm.py -+++ b/tests/vm/basevm.py -@@ -228,7 +228,8 @@ def _ssh_do(self, user, cmd, check): - "-o", "UserKnownHostsFile=" + os.devnull, - "-o", - "ConnectTimeout={}".format(self._config["ssh_timeout"]), -- "-p", str(self.ssh_port), "-i", self._ssh_tmp_key_file] -+ "-p", str(self.ssh_port), "-i", self._ssh_tmp_key_file, -+ "-o", "IdentitiesOnly=yes"] - # If not in debug mode, set ssh to quiet mode to - # avoid printing the results of commands. - if not self.debug: --- -2.27.0 - diff --git a/thread-pool-optimize-scheduling-of-completion-bottom.patch b/thread-pool-optimize-scheduling-of-completion-bottom.patch deleted file mode 100644 index cd24a4ee963a6e36db6bfce81b671b57c11b01b1..0000000000000000000000000000000000000000 --- a/thread-pool-optimize-scheduling-of-completion-bottom.patch +++ /dev/null @@ -1,45 +0,0 @@ -From c84bb01c0c56cadb70a95c874b32ed85b8177504 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Tue, 26 Sep 2023 06:41:50 +0000 -Subject: [PATCH] thread-pool: optimize scheduling of completion bottom half - mainline inclusion commit 3c7b72ddca9ce85a9d1e8a98fd0996b74597b5ae category: - bugfix - ---------------------------------------------------------------- - -The completion bottom half was scheduled within the pool->lock -critical section. That actually results in worse performance, -because the worker thread can run its own small critical section -and go to sleep before the bottom half starts running. - -Note that this simple change does not produce an improvement without -changing the thread pool QemuSemaphore to a condition variable. - -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Nicolas Saenz Julienne -Message-Id: <20220514065012.1149539-2-pbonzini@redhat.com> -Signed-off-by: Paolo Bonzini - -Signed-off-by: tangbinzy ---- - util/thread-pool.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/util/thread-pool.c b/util/thread-pool.c -index d763cea505..7e9e2c178b 100644 ---- a/util/thread-pool.c -+++ b/util/thread-pool.c -@@ -108,9 +108,8 @@ static void *worker_thread(void *opaque) - smp_wmb(); - req->state = THREAD_DONE; - -- qemu_mutex_lock(&pool->lock); -- - qemu_bh_schedule(pool->completion_bh); -+ qemu_mutex_lock(&pool->lock); - } - - pool->cur_threads--; --- -2.41.0.windows.1 - diff --git a/tools-virtiofsd-Add-rseq-syscall-to-the-seccomp-allo.patch b/tools-virtiofsd-Add-rseq-syscall-to-the-seccomp-allo.patch deleted file mode 100644 index b59ef0fb1cc4fb68c6f5fd1d148e4d4cf3cd7d76..0000000000000000000000000000000000000000 --- a/tools-virtiofsd-Add-rseq-syscall-to-the-seccomp-allo.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 5ca1beec7030b5d9fea36eb4f037d4e0e6c260bd Mon Sep 17 00:00:00 2001 -From: Christian Ehrhardt -Date: Wed, 9 Feb 2022 12:14:56 +0100 -Subject: [PATCH] tools/virtiofsd: Add rseq syscall to the seccomp allowlist - -The virtiofsd currently crashes when used with glibc 2.35. -That is due to the rseq system call being added to every thread -creation [1][2]. - -[1]: https://www.efficios.com/blog/2019/02/08/linux-restartable-sequences/ -[2]: https://sourceware.org/pipermail/libc-alpha/2022-February/136040.html - -This happens not at daemon start, but when a guest connects - - /usr/lib/qemu/virtiofsd -f --socket-path=/tmp/testvfsd -o sandbox=chroot \ - -o source=/var/guests/j-virtiofs --socket-group=kvm - virtio_session_mount: Waiting for vhost-user socket connection... - # start ok, now guest will connect - virtio_session_mount: Received vhost-user socket connection - virtio_loop: Entry - fv_queue_set_started: qidx=0 started=1 - fv_queue_set_started: qidx=1 started=1 - Bad system call (core dumped) - -We have to put rseq on the seccomp allowlist to avoid that the daemon -is crashing in this case. - -Reported-by: Michael Hudson-Doyle -Signed-off-by: Christian Ehrhardt -Reviewed-by: Dr. David Alan Gilbert -Message-id: 20220209111456.3328420-1-christian.ehrhardt@canonical.com - -[Moved rseq to its alphabetically ordered position in the seccomp -allowlist. ---Stefan] -Signed-off-by: Stefan Hajnoczi -Signed-off-by: qinyu ---- - tools/virtiofsd/passthrough_seccomp.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/tools/virtiofsd/passthrough_seccomp.c b/tools/virtiofsd/passthrough_seccomp.c -index a3ce9f898d..2bc0127b69 100644 ---- a/tools/virtiofsd/passthrough_seccomp.c -+++ b/tools/virtiofsd/passthrough_seccomp.c -@@ -91,6 +91,9 @@ static const int syscall_allowlist[] = { - SCMP_SYS(renameat2), - SCMP_SYS(removexattr), - SCMP_SYS(restart_syscall), -+#ifdef __NR_rseq -+ SCMP_SYS(rseq), /* required since glibc 2.35 */ -+#endif - SCMP_SYS(rt_sigaction), - SCMP_SYS(rt_sigprocmask), - SCMP_SYS(rt_sigreturn), --- -2.27.0 - diff --git a/tpm_crb-mark-command-buffer-as-dirty-on-request-comp.patch b/tpm_crb-mark-command-buffer-as-dirty-on-request-comp.patch deleted file mode 100644 index c989e26e417cfc3e093737193cf1babca5a6f3d3..0000000000000000000000000000000000000000 --- a/tpm_crb-mark-command-buffer-as-dirty-on-request-comp.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 1e32685272ff1932b9ca022db8717720fc901d0e Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 6 Nov 2023 06:17:47 +0000 -Subject: [PATCH] tpm_crb: mark command buffer as dirty on request completion - mainline inclusion commit e37a0ef4605e5d2041785ff3fc89ca6021faf7a0 category: - bugfix - ---------------------------------------------------------------- - -At the moment, there doesn't seems to be any way to know that QEMU -made modification to the command buffer. This is potentially an issue -on Xen while migrating a guest, as modification to the buffer after -the migration as started could be ignored and not transfered to the -destination. - -Mark the memory region of the command buffer as dirty once a request -is completed. - -Signed-off-by: Anthony PERARD -Reviewed-by: Stefan Berger -Signed-off-by: Stefan Berger -Message-id: 20220411144749.47185-1-anthony.perard@citrix.com - -Signed-off-by: tangbinzy ---- - hw/tpm/tpm_crb.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c -index 58ebd1469c..c05972736a 100644 ---- a/hw/tpm/tpm_crb.c -+++ b/hw/tpm/tpm_crb.c -@@ -196,6 +196,7 @@ static void tpm_crb_request_completed(TPMIf *ti, int ret) - ARRAY_FIELD_DP32(s->regs, CRB_CTRL_STS, - tpmSts, 1); /* fatal error */ - } -+ memory_region_set_dirty(&s->cmdmem, 0, CRB_CTRL_CMD_SIZE); - } - - static enum TPMVersion tpm_crb_get_version(TPMIf *ti) --- -2.27.0 - diff --git a/tracetool-avoid-invalid-escape-in-Python-string.patch b/tracetool-avoid-invalid-escape-in-Python-string.patch deleted file mode 100644 index ffd30a2c5787f4ce7a948eafd63d42bf89cc8b92..0000000000000000000000000000000000000000 --- a/tracetool-avoid-invalid-escape-in-Python-string.patch +++ /dev/null @@ -1,38 +0,0 @@ -From cb5e4e55c489462a2ff11143a5768b5c096bf1ad Mon Sep 17 00:00:00 2001 -From: qihao -Date: Wed, 15 Nov 2023 14:49:44 +0800 -Subject: [PATCH] tracetool: avoid invalid escape in Python string -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 4d96307c5b4fac40c6ca25f38318b4b65d315de0 - -This is an error in Python 3.12; fix it by using a raw string literal. - -Cc: -Signed-off-by: Marc-André Lureau -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Stefan Hajnoczi -Message-ID: <20231108105649.60453-1-marcandre.lureau@redhat.com> -Signed-off-by: qihao_yewu ---- - scripts/tracetool/__init__.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py -index 5bc94d95cf..630e85a5d6 100644 ---- a/scripts/tracetool/__init__.py -+++ b/scripts/tracetool/__init__.py -@@ -94,7 +94,7 @@ def out(*lines, **kwargs): - def validate_type(name): - bits = name.split(" ") - for bit in bits: -- bit = re.sub("\*", "", bit) -+ bit = re.sub(r"\*", "", bit) - if bit == "": - continue - if bit == "const": --- -2.27.0 - diff --git a/trivial-typos-namesapce.patch b/trivial-typos-namesapce.patch deleted file mode 100644 index 60564e4efeb1b2667058de6897035cb5aa3dfcc0..0000000000000000000000000000000000000000 --- a/trivial-typos-namesapce.patch +++ /dev/null @@ -1,89 +0,0 @@ -From ec92a6e31bb5bf118a09bdc085e1e4f476b98f1e Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 02:48:55 -0800 -Subject: [PATCH] trivial typos: namesapce - -cherry picked from commit a0984714fb700683094a754a2320a2e150cf10a7 - -'namespace' is misspelled in a bunch of places. - -Signed-off-by: Dr. David Alan Gilbert -Reviewed-by: Klaus Jensen -Message-Id: <20220614104045.85728-3-dgilbert@redhat.com> -Signed-off-by: Laurent Vivier -Signed-off-by: Wanghe Xiao ---- - hw/9pfs/9p-xattr-user.c | 8 ++++---- - hw/acpi/nvdimm.c | 2 +- - hw/nvme/ctrl.c | 2 +- - 3 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/hw/9pfs/9p-xattr-user.c b/hw/9pfs/9p-xattr-user.c -index f2ae9582e6..535677ed60 100644 ---- a/hw/9pfs/9p-xattr-user.c -+++ b/hw/9pfs/9p-xattr-user.c -@@ -27,7 +27,7 @@ static ssize_t mp_user_getxattr(FsContext *ctx, const char *path, - { - if (strncmp(name, "user.virtfs.", 12) == 0) { - /* -- * Don't allow fetch of user.virtfs namesapce -+ * Don't allow fetch of user.virtfs namespace - * in case of mapped security - */ - errno = ENOATTR; -@@ -49,7 +49,7 @@ static ssize_t mp_user_listxattr(FsContext *ctx, const char *path, - name_size -= 12; - } else { - /* -- * Don't allow fetch of user.virtfs namesapce -+ * Don't allow fetch of user.virtfs namespace - * in case of mapped security - */ - return 0; -@@ -74,7 +74,7 @@ static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name, - { - if (strncmp(name, "user.virtfs.", 12) == 0) { - /* -- * Don't allow fetch of user.virtfs namesapce -+ * Don't allow fetch of user.virtfs namespace - * in case of mapped security - */ - errno = EACCES; -@@ -88,7 +88,7 @@ static int mp_user_removexattr(FsContext *ctx, - { - if (strncmp(name, "user.virtfs.", 12) == 0) { - /* -- * Don't allow fetch of user.virtfs namesapce -+ * Don't allow fetch of user.virtfs namespace - * in case of mapped security - */ - errno = EACCES; -diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c -index 0d43da19ea..5f85b16327 100644 ---- a/hw/acpi/nvdimm.c -+++ b/hw/acpi/nvdimm.c -@@ -476,7 +476,7 @@ struct NvdimmFuncGetLabelDataOut { - /* the size of buffer filled by QEMU. */ - uint32_t len; - uint32_t func_ret_status; /* return status code. */ -- uint8_t out_buf[]; /* the data got via Get Namesapce Label function. */ -+ uint8_t out_buf[]; /* the data got via Get Namespace Label function. */ - } QEMU_PACKED; - typedef struct NvdimmFuncGetLabelDataOut NvdimmFuncGetLabelDataOut; - QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncGetLabelDataOut) > NVDIMM_DSM_MEMORY_SIZE); -diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c -index d64dd9c361..7c9f97bdb3 100644 ---- a/hw/nvme/ctrl.c -+++ b/hw/nvme/ctrl.c -@@ -71,7 +71,7 @@ - * the SUBNQN field in the controller will report the NQN of the subsystem - * device. This also enables multi controller capability represented in - * Identify Controller data structure in CMIC (Controller Multi-path I/O and -- * Namesapce Sharing Capabilities). -+ * Namespace Sharing Capabilities). - * - * - `aerl` - * The Asynchronous Event Request Limit (AERL). Indicates the maximum number --- -2.27.0 - diff --git a/tulip-Assign-default-MAC-address-if-not-specified.patch b/tulip-Assign-default-MAC-address-if-not-specified.patch deleted file mode 100644 index 5bf830823626516e81edb9e6b9fd81c70993bf32..0000000000000000000000000000000000000000 --- a/tulip-Assign-default-MAC-address-if-not-specified.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 78b2167f1e2fadb4de930bf51c699247031c8880 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 4 Sep 2023 08:27:33 +0000 -Subject: [PATCH] tulip: Assign default MAC address if not specified mainline - inclusion commit 052c2579b89b0d87debe8b05594b5180f0fde87d category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -The MAC of the tulip card is stored in the EEPROM and at startup -tulip_fill_eeprom() is called to initialize the EEPROM with the MAC -address given on the command line, e.g.: - -device tulip,mac=00:11:22:33:44:55 - -In case the mac address was not given on the command line, -tulip_fill_eeprom() initializes the MAC in EEPROM with 00:00:00:00:00:00 -which breaks e.g. a HP-UX guest. - -Fix this problem by moving qemu_macaddr_default_if_unset() a few lines -up, so that a default mac address is assigned before tulip_fill_eeprom() -initializes the EEPROM. - -Signed-off-by: Helge Deller -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: Jason Wang - -Signed-off-by: tangbinzy ---- - hw/net/tulip.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/net/tulip.c b/hw/net/tulip.c -index 5f8badefca..b9e42c322a 100644 ---- a/hw/net/tulip.c -+++ b/hw/net/tulip.c -@@ -967,6 +967,8 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp) - pci_conf = s->dev.config; - pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */ - -+ qemu_macaddr_default_if_unset(&s->c.macaddr); -+ - s->eeprom = eeprom93xx_new(&pci_dev->qdev, 64); - tulip_fill_eeprom(s); - -@@ -981,8 +983,6 @@ static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp) - - s->irq = pci_allocate_irq(&s->dev); - -- qemu_macaddr_default_if_unset(&s->c.macaddr); -- - s->nic = qemu_new_nic(&net_tulip_info, &s->c, - object_get_typename(OBJECT(pci_dev)), - pci_dev->qdev.id, s); --- -2.41.0.windows.1 - diff --git a/uas-add-missing-return.patch b/uas-add-missing-return.patch deleted file mode 100644 index 716c54073b7548f7cb460e89da78f8fc502fa318..0000000000000000000000000000000000000000 --- a/uas-add-missing-return.patch +++ /dev/null @@ -1,35 +0,0 @@ -From da75066823387c4f24b55e21ee6c856ffa537174 Mon Sep 17 00:00:00 2001 -From: Gerd Hoffmann -Date: Fri, 10 Dec 2021 09:06:59 +0100 -Subject: [PATCH 2/6] uas: add missing return -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Otherwise we run the error handling code even for successful requests. - -Fixes: 13b250b12ad3 ("uas: add stream number sanity checks.") -Reported-by: Guenter Roeck -Signed-off-by: Gerd Hoffmann -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20211210080659.2537084-1-kraxel@redhat.com> -Signed-off-by: wanbo ---- - hw/usb/dev-uas.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c -index 599d6b52a0..c9f295e7e4 100644 ---- a/hw/usb/dev-uas.c -+++ b/hw/usb/dev-uas.c -@@ -908,6 +908,7 @@ static void usb_uas_handle_data(USBDevice *dev, USBPacket *p) - p->status = USB_RET_STALL; - break; - } -+ return; - - err_stream: - error_report("%s: invalid stream %d", __func__, p->stream); --- -2.27.0 - diff --git a/ui-cursor-fix-integer-overflow-in-cursor_alloc-CVE-2.patch b/ui-cursor-fix-integer-overflow-in-cursor_alloc-CVE-2.patch deleted file mode 100644 index a63df9c4cfb1f10a1fb19fc76c0220c7e8be406c..0000000000000000000000000000000000000000 --- a/ui-cursor-fix-integer-overflow-in-cursor_alloc-CVE-2.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 7da437c2f5440a9230e482d58d86b579221b3207 Mon Sep 17 00:00:00 2001 -From: Mauro Matteo Cascella -Date: Thu, 7 Apr 2022 10:17:12 +0200 -Subject: [PATCH 2/2] ui/cursor: fix integer overflow in cursor_alloc - (CVE-2021-4206) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Prevent potential integer overflow by limiting 'width' and 'height' to -512x512. Also change 'datasize' type to size_t. Refer to security -advisory https://starlabs.sg/advisories/22-4206/ for more information. - -Fixes: CVE-2021-4206 -Signed-off-by: Mauro Matteo Cascella -Reviewed-by: Marc-André Lureau -Message-Id: <20220407081712.345609-1-mcascell@redhat.com> -Signed-off-by: Gerd Hoffmann ---- - hw/display/qxl-render.c | 7 +++++++ - hw/display/vmware_vga.c | 2 ++ - ui/cursor.c | 8 +++++++- - 3 files changed, 16 insertions(+), 1 deletion(-) - -diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c -index 237ed293ba..ca217004bf 100644 ---- a/hw/display/qxl-render.c -+++ b/hw/display/qxl-render.c -@@ -247,6 +247,13 @@ static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor, - size_t size; - - c = cursor_alloc(cursor->header.width, cursor->header.height); -+ -+ if (!c) { -+ qxl_set_guest_bug(qxl, "%s: cursor %ux%u alloc error", __func__, -+ cursor->header.width, cursor->header.height); -+ goto fail; -+ } -+ - c->hot_x = cursor->header.hot_spot_x; - c->hot_y = cursor->header.hot_spot_y; - switch (cursor->header.type) { -diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c -index e2969a6c81..2b81d6122f 100644 ---- a/hw/display/vmware_vga.c -+++ b/hw/display/vmware_vga.c -@@ -509,6 +509,8 @@ static inline void vmsvga_cursor_define(struct vmsvga_state_s *s, - int i, pixels; - - qc = cursor_alloc(c->width, c->height); -+ assert(qc != NULL); -+ - qc->hot_x = c->hot_x; - qc->hot_y = c->hot_y; - switch (c->bpp) { -diff --git a/ui/cursor.c b/ui/cursor.c -index 1d62ddd4d0..835f0802f9 100644 ---- a/ui/cursor.c -+++ b/ui/cursor.c -@@ -46,6 +46,8 @@ static QEMUCursor *cursor_parse_xpm(const char *xpm[]) - - /* parse pixel data */ - c = cursor_alloc(width, height); -+ assert(c != NULL); -+ - for (pixel = 0, y = 0; y < height; y++, line++) { - for (x = 0; x < height; x++, pixel++) { - idx = xpm[line][x]; -@@ -91,7 +93,11 @@ QEMUCursor *cursor_builtin_left_ptr(void) - QEMUCursor *cursor_alloc(int width, int height) - { - QEMUCursor *c; -- int datasize = width * height * sizeof(uint32_t); -+ size_t datasize = width * height * sizeof(uint32_t); -+ -+ if (width > 512 || height > 512) { -+ return NULL; -+ } - - c = g_malloc0(sizeof(QEMUCursor) + datasize); - c->width = width; --- -2.27.0 - diff --git a/ui-fix-crash-on-serial-reset-during-init.patch b/ui-fix-crash-on-serial-reset-during-init.patch deleted file mode 100644 index 30aeb0cead9c1d76bea9d3c0ba716558ebb6017c..0000000000000000000000000000000000000000 --- a/ui-fix-crash-on-serial-reset-during-init.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 548991fba5792b9efebc60cd75cba656624319d4 Mon Sep 17 00:00:00 2001 -From: jipengfei -Date: Tue, 4 Apr 2023 18:11:30 +0800 -Subject: [PATCH] ui: fix crash on serial reset, during init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -For ex, when resetting the xlnx-zcu102 machine: - -(lldb) bt -* thread #1, queue = 'com.apple.main-thread', stop reason = -EXC_BAD_ACCESS (code=1, address=0x50) - * frame #0: 0x10020a740 gd_vc_send_chars(vc=0x000000000) at -gtk.c:1759:41 [opt] - frame #1: 0x100636264 qemu_chr_fe_accept_input(be=) at -char-fe.c:159:9 [opt] - frame #2: 0x1000608e0 cadence_uart_reset_hold [inlined] -uart_rx_reset(s=0x10810a960) at cadence_uart.c:158:5 [opt] - frame #3: 0x1000608d4 cadence_uart_reset_hold(obj=0x10810a960) at -cadence_uart.c:530:5 [opt] - frame #4: 0x100580ab4 resettable_phase_hold(obj=0x10810a960, -opaque=0x000000000, type=) at resettable.c:0 [opt] - frame #5: 0x10057d1b0 bus_reset_child_foreach(obj=, -cb=(resettable_phase_hold at resettable.c:162), opaque=0x000000000, -type=RESET_TYPE_COLD) at bus.c:97:13 [opt] - frame #6: 0x1005809f8 resettable_phase_hold [inlined] -resettable_child_foreach(rc=0x000060000332d2c0, obj=0x0000600002c1c180, -cb=, opaque=0x000000000, type=RESET_TYPE_COLD) at -resettable.c:96:9 [opt] - frame #7: 0x1005809d8 resettable_phase_hold(obj=0x0000600002c1c180, -opaque=0x000000000, type=RESET_TYPE_COLD) at resettable.c:173:5 [opt] - frame #8: 0x1005803a0 -resettable_assert_reset(obj=0x0000600002c1c180, type=) at -resettable.c:60:5 [opt] - frame #9: 0x10058027c resettable_reset(obj=0x0000600002c1c180, -type=RESET_TYPE_COLD) at resettable.c:45:5 [opt] - -While the chardev is created early, the VirtualConsole is associated -after, during qemu_init_displays(). - -cheery-pick from 49152ac47003ca21fc6f2a5c3e517f79649e1541 -Signed-off-by: jipengfei_yewu@cmss.chinamobile.com -Signed-off-by: Marc-André Lureau -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20230220072251.3385878-1-marcandre.lureau@redhat.com> ---- - ui/gtk.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/ui/gtk.c b/ui/gtk.c -index 428f02f2df..6d9cb42b3d 100644 ---- a/ui/gtk.c -+++ b/ui/gtk.c -@@ -1718,8 +1718,10 @@ static void gd_vc_chr_accept_input(Chardev *chr) - { - VCChardev *vcd = VC_CHARDEV(chr); - VirtualConsole *vc = vcd->console; -- -- gd_vc_send_chars(vc); -+ -+ if (vc) { -+ gd_vc_send_chars(vc); -+ } - } - - static void gd_vc_chr_set_echo(Chardev *chr, bool echo) --- -2.27.0 - diff --git a/ui-fix-crash-when-there-are-no-active_console.patch b/ui-fix-crash-when-there-are-no-active_console.patch deleted file mode 100644 index 0ed65946770fc864a1ebd499ef6bafa1e8163b3b..0000000000000000000000000000000000000000 --- a/ui-fix-crash-when-there-are-no-active_console.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 89fda5a4410099a317bd1fcef56b130d6d97a2b5 Mon Sep 17 00:00:00 2001 -From: dinglimin_yewu -Date: Sat, 16 Sep 2023 17:41:07 +0800 -Subject: [PATCH] ui: fix crash when there are no active_console -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry-pick from 48a35e12faf90a896c5aa4755812201e00d60316 - -Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. -0x0000555555888630 in dpy_ui_info_supported (con=0x0) at ../ui/console.c:812 -812 return con->hw_ops->ui_info != NULL; -(gdb) bt - -Fixes: -https://issues.redhat.com/browse/RHEL-2600 - -Signed-off-by: Marc-André Lureau -Reviewed-by: Albert Esteve -Signed-off-by: dinglimin_yewu ---- - ui/console.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/ui/console.c b/ui/console.c -index 29a3e3f0f5..d22c3def20 100644 ---- a/ui/console.c -+++ b/ui/console.c -@@ -1526,6 +1526,9 @@ bool dpy_ui_info_supported(QemuConsole *con) - con = active_console; - } - -+ if (con == NULL) { -+ return false; -+ } - return con->hw_ops->ui_info != NULL; - } - --- -2.41.0.windows.1 - diff --git a/ui-gtk-prevent-ui-lock-up-when-dpy_gl_update-called-.patch b/ui-gtk-prevent-ui-lock-up-when-dpy_gl_update-called-.patch deleted file mode 100644 index 1b658ad6cb1e68c7cf5873523c600f778daf0fec..0000000000000000000000000000000000000000 --- a/ui-gtk-prevent-ui-lock-up-when-dpy_gl_update-called-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 37625d78afdadb5e88aa4616d613f64184db41bf Mon Sep 17 00:00:00 2001 -From: Wanghe Xiao -Date: Sat, 25 Nov 2023 01:42:26 -0800 -Subject: [PATCH] ui/gtk: prevent ui lock up when dpy_gl_update called again - before current draw event occurs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 64f1359bd08060ffe7a5689fdcbaeec6d8a59980 - -A warning, "qemu: warning: console: no gl-unblock within" followed by -guest scanout lockup can happen if dpy_gl_update is called in a row -and the second call is made before gd_draw_event scheduled by the first -call is taking place. This is because draw call returns without decrementing -gl_block ref count if the dmabuf was already submitted as shown below. - -(gd_gl_area_draw/gd_egl_draw) - - if (dmabuf) { - if (!dmabuf->draw_submitted) { - return; - } else { - dmabuf->draw_submitted = false; - } - } - -So it should not schedule any redundant draw event in case draw_submitted is -already set in gd_egl_fluch/gd_gl_area_scanout_flush. - -Cc: Gerd Hoffmann -Cc: Vivek Kasireddy -Signed-off-by: Dongwon Kim -Reviewed-by: Marc-André Lureau -Message-Id: <20221021192315.9110-1-dongwon.kim@intel.com> -Signed-off-by: Gerd Hoffmann -Signed-off-by: Wanghe Xiao ---- - ui/gtk-egl.c | 2 +- - ui/gtk-gl-area.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c -index 45cb67712d..0e1e5bfaaa 100644 ---- a/ui/gtk-egl.c -+++ b/ui/gtk-egl.c -@@ -340,7 +340,7 @@ void gd_egl_flush(DisplayChangeListener *dcl, - VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); - GtkWidget *area = vc->gfx.drawing_area; - -- if (vc->gfx.guest_fb.dmabuf) { -+ if (vc->gfx.guest_fb.dmabuf && !vc->gfx.guest_fb.dmabuf->draw_submitted) { - graphic_hw_gl_block(vc->gfx.dcl.con, true); - vc->gfx.guest_fb.dmabuf->draw_submitted = true; - gtk_widget_queue_draw_area(area, x, y, w, h); -diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c -index 01e4e74ee3..11e0cb4af2 100644 ---- a/ui/gtk-gl-area.c -+++ b/ui/gtk-gl-area.c -@@ -246,7 +246,7 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl, - { - VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); - -- if (vc->gfx.guest_fb.dmabuf) { -+ if (vc->gfx.guest_fb.dmabuf && !vc->gfx.guest_fb.dmabuf->draw_submitted) { - graphic_hw_gl_block(vc->gfx.dcl.con, true); - vc->gfx.guest_fb.dmabuf->draw_submitted = true; - } --- -2.27.0 - diff --git a/ui-qmp-cmds-Improve-two-error-messages.patch b/ui-qmp-cmds-Improve-two-error-messages.patch deleted file mode 100644 index 9cab96b9627fe5f75717433db4032e2d29a3efae..0000000000000000000000000000000000000000 --- a/ui-qmp-cmds-Improve-two-error-messages.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0425d773b3fa0da62be489ae6c76d1805f28f388 Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Mon, 27 Nov 2023 15:47:21 +0800 -Subject: [PATCH] ui/qmp-cmds: Improve two error messages -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from 517b0220efd421acf885eed109571a61e95b192a - -set_password with "protocol": "vnc" supports only "connected": "keep". -Any other value is rejected with - - Invalid parameter 'connected' - -Improve this to - - parameter 'connected' must be 'keep' when 'protocol' is 'vnc' - -client_migrate_info requires "port" or "tls-port". When both are -missing, it fails with - - Parameter 'port/tls-port' is missing - -Improve this to - - parameter 'port' or 'tls-port' is required - -Signed-off-by: Markus Armbruster -Message-ID: <20231031111059.3407803-5-armbru@redhat.com> -Reviewed-by: Philippe Mathieu-Daudé - -Signed-off-by: boringandboring ---- - monitor/misc.c | 2 +- - monitor/qmp-cmds.c | 3 ++- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/monitor/misc.c b/monitor/misc.c -index a3a6e47844..25a23e2290 100644 ---- a/monitor/misc.c -+++ b/monitor/misc.c -@@ -397,7 +397,7 @@ void qmp_client_migrate_info(const char *protocol, const char *hostname, - } - - if (!has_port && !has_tls_port) { -- error_setg(errp, QERR_MISSING_PARAMETER, "port/tls-port"); -+ error_setg(errp, "parameter 'port' or 'tls-port' is required"); - return; - } - -diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c -index d71beace6a..b44cca8234 100644 ---- a/monitor/qmp-cmds.c -+++ b/monitor/qmp-cmds.c -@@ -199,7 +199,8 @@ void qmp_set_password(const char *protocol, const char *password, - } else if (strcmp(protocol, "vnc") == 0) { - if (fail_if_connected || disconnect_if_connected) { - /* vnc supports "connected=keep" only */ -- error_setg(errp, QERR_INVALID_PARAMETER, "connected"); -+ error_setg(errp, "parameter 'connected' must be 'keep'" -+ " when 'protocol' is 'vnc'"); - return; - } - /* Note that setting an empty password will not disable login through --- -2.27.0 - diff --git a/ui-vnc-clipboard-fix-infinite-loop-in-inflate_buffer.patch b/ui-vnc-clipboard-fix-infinite-loop-in-inflate_buffer.patch deleted file mode 100644 index ceb609cf569c7cfb25e88cb626980bfddbf71cba..0000000000000000000000000000000000000000 --- a/ui-vnc-clipboard-fix-infinite-loop-in-inflate_buffer.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 2858029a5dbdd3fab73b1884e296daa3f3f0b1a1 Mon Sep 17 00:00:00 2001 -From: Mauro Matteo Cascella -Date: Tue, 4 Jul 2023 10:41:22 +0200 -Subject: [PATCH] ui/vnc-clipboard: fix infinite loop in inflate_buffer - (CVE-2023-3255) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -A wrong exit condition may lead to an infinite loop when inflating a -valid zlib buffer containing some extra bytes in the `inflate_buffer` -function. The bug only occurs post-authentication. Return the buffer -immediately if the end of the compressed data has been reached -(Z_STREAM_END). - -Fixes: CVE-2023-3255 -Fixes: 0bf41cab ("ui/vnc: clipboard support") -Reported-by: Kevin Denis -Signed-off-by: Mauro Matteo Cascella -Reviewed-by: Marc-André Lureau -Tested-by: Marc-André Lureau -Message-ID: <20230704084210.101822-1-mcascell@redhat.com> ---- - ui/vnc-clipboard.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - -diff --git a/ui/vnc-clipboard.c b/ui/vnc-clipboard.c -index 67284b556c..c84599cfdb 100644 ---- a/ui/vnc-clipboard.c -+++ b/ui/vnc-clipboard.c -@@ -51,8 +51,11 @@ static uint8_t *inflate_buffer(uint8_t *in, uint32_t in_len, uint32_t *size) - ret = inflate(&stream, Z_FINISH); - switch (ret) { - case Z_OK: -- case Z_STREAM_END: - break; -+ case Z_STREAM_END: -+ *size = stream.total_out; -+ inflateEnd(&stream); -+ return out; - case Z_BUF_ERROR: - out_len <<= 1; - if (out_len > (1 << 20)) { -@@ -67,11 +70,6 @@ static uint8_t *inflate_buffer(uint8_t *in, uint32_t in_len, uint32_t *size) - } - } - -- *size = stream.total_out; -- inflateEnd(&stream); -- -- return out; -- - err_end: - inflateEnd(&stream); - err: --- -2.41.0.windows.1 - diff --git a/ui-vnc-clipboard-fix-inflate_buffer.patch b/ui-vnc-clipboard-fix-inflate_buffer.patch deleted file mode 100644 index f12ff9b4c00246c040c460a53c2a4d9b70e44371..0000000000000000000000000000000000000000 --- a/ui-vnc-clipboard-fix-inflate_buffer.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 7f19287be9b468b7065073a31d35c01b2632858d Mon Sep 17 00:00:00 2001 -From: qihao -Date: Tue, 5 Dec 2023 14:10:50 +0800 -Subject: [PATCH] ui/vnc-clipboard: fix inflate_buffer -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from ebfbf394671163c14e2b24d98f3927a3151d1aff - -Commit d921fea338 ("ui/vnc-clipboard: fix infinite loop in -inflate_buffer (CVE-2023-3255)") removed this hunk, but it is still -required, because it can happen that stream.avail_in becomes zero -before coming across a return value of Z_STREAM_END in the loop. - -This fixes the host->guest direction of the clipboard with noVNC and -TigerVNC as clients. - -Fixes: d921fea338 ("ui/vnc-clipboard: fix infinite loop in inflate_buffer (CVE-2023-3255)") -Reported-by: Friedrich Weber -Signed-off-by: Fiona Ebner -Acked-by: Marc-André Lureau -Message-Id: <20231122125826.228189-1-f.ebner@proxmox.com> -Signed-off-by: qihao_yewu ---- - ui/vnc-clipboard.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/ui/vnc-clipboard.c b/ui/vnc-clipboard.c -index c84599cfdb..2bb1b07c40 100644 ---- a/ui/vnc-clipboard.c -+++ b/ui/vnc-clipboard.c -@@ -70,6 +70,11 @@ static uint8_t *inflate_buffer(uint8_t *in, uint32_t in_len, uint32_t *size) - } - } - -+ *size = stream.total_out; -+ inflateEnd(&stream); -+ -+ return out; -+ - err_end: - inflateEnd(&stream); - err: --- -2.27.0 - diff --git a/ui-vnc-clipboard-fix-integer-underflow-in-vnc_client.patch b/ui-vnc-clipboard-fix-integer-underflow-in-vnc_client.patch deleted file mode 100644 index 0fdcda62f03bc1fc1fbf418fc009c9eae5b92161..0000000000000000000000000000000000000000 --- a/ui-vnc-clipboard-fix-integer-underflow-in-vnc_client.patch +++ /dev/null @@ -1,55 +0,0 @@ -From d307040b18bfcb1393b910f1bae753d5c12a4dc7 Mon Sep 17 00:00:00 2001 -From: Mauro Matteo Cascella -Date: Sun, 25 Sep 2022 22:45:11 +0200 -Subject: [PATCH] ui/vnc-clipboard: fix integer underflow in - vnc_client_cut_text_ext - -Extended ClientCutText messages start with a 4-byte header. If len < 4, -an integer underflow occurs in vnc_client_cut_text_ext. The result is -used to decompress data in a while loop in inflate_buffer, leading to -CPU consumption and denial of service. Prevent this by checking dlen in -protocol_client_msg. - -Fixes: CVE-2022-3165 -Fixes: 0bf41cab93e5 ("ui/vnc: clipboard support") -Reported-by: TangPeng -Signed-off-by: Mauro Matteo Cascella -Message-Id: <20220925204511.1103214-1-mcascell@redhat.com> -Signed-off-by: Gerd Hoffmann ---- - ui/vnc.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/ui/vnc.c b/ui/vnc.c -index 6a05d06147..acb3629cd8 100644 ---- a/ui/vnc.c -+++ b/ui/vnc.c -@@ -2442,8 +2442,8 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) - if (len == 1) { - return 8; - } -+ uint32_t dlen = abs(read_s32(data, 4)); - if (len == 8) { -- uint32_t dlen = abs(read_s32(data, 4)); - if (dlen > (1 << 20)) { - error_report("vnc: client_cut_text msg payload has %u bytes" - " which exceeds our limit of 1MB.", dlen); -@@ -2456,8 +2456,13 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) - } - - if (read_s32(data, 4) < 0) { -- vnc_client_cut_text_ext(vs, abs(read_s32(data, 4)), -- read_u32(data, 8), data + 12); -+ if (dlen < 4) { -+ error_report("vnc: malformed payload (header less than 4 bytes)" -+ " in extended clipboard pseudo-encoding."); -+ vnc_client_error(vs); -+ break; -+ } -+ vnc_client_cut_text_ext(vs, dlen, read_u32(data, 8), data + 12); - break; - } - vnc_client_cut_text(vs, read_u32(data, 4), data + 8); --- -2.27.0 - diff --git a/update-linux-headers-Import-iommu.h.patch b/update-linux-headers-Import-iommu.h.patch deleted file mode 100644 index 5653e6a4ddd6b5cdb7a68dbef54f010d0e3a1cda..0000000000000000000000000000000000000000 --- a/update-linux-headers-Import-iommu.h.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 694acf3c321908d26ce508842b7bd076664ffbc6 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 9 May 2019 10:23:42 -0400 -Subject: [PATCH] update-linux-headers: Import iommu.h - -Update the script to import the new iommu.h uapi header. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - scripts/update-linux-headers.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh -index fea4d6eb65..acde610733 100755 ---- a/scripts/update-linux-headers.sh -+++ b/scripts/update-linux-headers.sh -@@ -144,7 +144,7 @@ done - - rm -rf "$output/linux-headers/linux" - mkdir -p "$output/linux-headers/linux" --for header in kvm.h vfio.h vfio_ccw.h vfio_zdev.h vhost.h \ -+for header in kvm.h vfio.h vfio_ccw.h vfio_zdev.h vhost.h iommu.h \ - psci.h psp-sev.h userfaultfd.h mman.h; do - cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux" - done --- -2.27.0 - diff --git a/util-Add-iova_tree_alloc_map.patch b/util-Add-iova_tree_alloc_map.patch deleted file mode 100644 index c1ab3f7cee5b07d2705e10d2ef2483c59ce78e38..0000000000000000000000000000000000000000 --- a/util-Add-iova_tree_alloc_map.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 6dac473fb3f4f98ef67c63a38b00465299519132 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:48 +0100 -Subject: [PATCH] util: Add iova_tree_alloc_map -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This iova tree function allows it to look for a hole in allocated -regions and return a totally new translation for a given translated -address. - -It's usage is mainly to allow devices to access qemu address space, -remapping guest's one into a new iova space where qemu can add chunks of -addresses. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Peter Xu -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - include/qemu/iova-tree.h | 18 ++++++ - util/iova-tree.c | 136 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 154 insertions(+) - -diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h -index 8249edd764..d066400f09 100644 ---- a/include/qemu/iova-tree.h -+++ b/include/qemu/iova-tree.h -@@ -29,6 +29,7 @@ - #define IOVA_OK (0) - #define IOVA_ERR_INVALID (-1) /* Invalid parameters */ - #define IOVA_ERR_OVERLAP (-2) /* IOVA range overlapped */ -+#define IOVA_ERR_NOMEM (-3) /* Cannot allocate */ - - typedef struct IOVATree IOVATree; - typedef struct DMAMap { -@@ -119,6 +120,23 @@ const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova); - */ - void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator); - -+/** -+ * iova_tree_alloc_map: -+ * -+ * @tree: the iova tree to allocate from -+ * @map: the new map (as translated addr & size) to allocate in the iova region -+ * @iova_begin: the minimum address of the allocation -+ * @iova_end: the maximum addressable direction of the allocation -+ * -+ * Allocates a new region of a given size, between iova_min and iova_max. -+ * -+ * Return: Same as iova_tree_insert, but cannot overlap and can return error if -+ * iova tree is out of free contiguous range. The caller gets the assigned iova -+ * in map->iova. -+ */ -+int iova_tree_alloc_map(IOVATree *tree, DMAMap *map, hwaddr iova_begin, -+ hwaddr iova_end); -+ - /** - * iova_tree_destroy: - * -diff --git a/util/iova-tree.c b/util/iova-tree.c -index 23ea35b7a4..139626b46f 100644 ---- a/util/iova-tree.c -+++ b/util/iova-tree.c -@@ -16,6 +16,40 @@ struct IOVATree { - GTree *tree; - }; - -+/* Args to pass to iova_tree_alloc foreach function. */ -+struct IOVATreeAllocArgs { -+ /* Size of the desired allocation */ -+ size_t new_size; -+ -+ /* The minimum address allowed in the allocation */ -+ hwaddr iova_begin; -+ -+ /* Map at the left of the hole, can be NULL if "this" is first one */ -+ const DMAMap *prev; -+ -+ /* Map at the right of the hole, can be NULL if "prev" is the last one */ -+ const DMAMap *this; -+ -+ /* If found, we fill in the IOVA here */ -+ hwaddr iova_result; -+ -+ /* Whether have we found a valid IOVA */ -+ bool iova_found; -+}; -+ -+/** -+ * Iterate args to the next hole -+ * -+ * @args: The alloc arguments -+ * @next: The next mapping in the tree. Can be NULL to signal the last one -+ */ -+static void iova_tree_alloc_args_iterate(struct IOVATreeAllocArgs *args, -+ const DMAMap *next) -+{ -+ args->prev = args->this; -+ args->this = next; -+} -+ - static int iova_tree_compare(gconstpointer a, gconstpointer b, gpointer data) - { - const DMAMap *m1 = a, *m2 = b; -@@ -107,6 +141,108 @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map) - return IOVA_OK; - } - -+/** -+ * Try to find an unallocated IOVA range between prev and this elements. -+ * -+ * @args: Arguments to allocation -+ * -+ * Cases: -+ * -+ * (1) !prev, !this: No entries allocated, always succeed -+ * -+ * (2) !prev, this: We're iterating at the 1st element. -+ * -+ * (3) prev, !this: We're iterating at the last element. -+ * -+ * (4) prev, this: this is the most common case, we'll try to find a hole -+ * between "prev" and "this" mapping. -+ * -+ * Note that this function assumes the last valid iova is HWADDR_MAX, but it -+ * searches linearly so it's easy to discard the result if it's not the case. -+ */ -+static void iova_tree_alloc_map_in_hole(struct IOVATreeAllocArgs *args) -+{ -+ const DMAMap *prev = args->prev, *this = args->this; -+ uint64_t hole_start, hole_last; -+ -+ if (this && this->iova + this->size < args->iova_begin) { -+ return; -+ } -+ -+ hole_start = MAX(prev ? prev->iova + prev->size + 1 : 0, args->iova_begin); -+ hole_last = this ? this->iova : HWADDR_MAX; -+ -+ if (hole_last - hole_start > args->new_size) { -+ args->iova_result = hole_start; -+ args->iova_found = true; -+ } -+} -+ -+/** -+ * Foreach dma node in the tree, compare if there is a hole with its previous -+ * node (or minimum iova address allowed) and the node. -+ * -+ * @key: Node iterating -+ * @value: Node iterating -+ * @pargs: Struct to communicate with the outside world -+ * -+ * Return: false to keep iterating, true if needs break. -+ */ -+static gboolean iova_tree_alloc_traverse(gpointer key, gpointer value, -+ gpointer pargs) -+{ -+ struct IOVATreeAllocArgs *args = pargs; -+ DMAMap *node = value; -+ -+ assert(key == value); -+ -+ iova_tree_alloc_args_iterate(args, node); -+ iova_tree_alloc_map_in_hole(args); -+ return args->iova_found; -+} -+ -+int iova_tree_alloc_map(IOVATree *tree, DMAMap *map, hwaddr iova_begin, -+ hwaddr iova_last) -+{ -+ struct IOVATreeAllocArgs args = { -+ .new_size = map->size, -+ .iova_begin = iova_begin, -+ }; -+ -+ if (unlikely(iova_last < iova_begin)) { -+ return IOVA_ERR_INVALID; -+ } -+ -+ /* -+ * Find a valid hole for the mapping -+ * -+ * Assuming low iova_begin, so no need to do a binary search to -+ * locate the first node. -+ * -+ * TODO: Replace all this with g_tree_node_first/next/last when available -+ * (from glib since 2.68). To do it with g_tree_foreach complicates the -+ * code a lot. -+ * -+ */ -+ g_tree_foreach(tree->tree, iova_tree_alloc_traverse, &args); -+ if (!args.iova_found) { -+ /* -+ * Either tree is empty or the last hole is still not checked. -+ * g_tree_foreach does not compare (last, iova_last] range, so we check -+ * it here. -+ */ -+ iova_tree_alloc_args_iterate(&args, NULL); -+ iova_tree_alloc_map_in_hole(&args); -+ } -+ -+ if (!args.iova_found || args.iova_result + map->size > iova_last) { -+ return IOVA_ERR_NOMEM; -+ } -+ -+ map->iova = args.iova_result; -+ return iova_tree_insert(tree, map); -+} -+ - void iova_tree_destroy(IOVATree *tree) - { - g_tree_destroy(tree->tree); --- -2.27.0 - diff --git a/util-Return-void-on-iova_tree_remove.patch b/util-Return-void-on-iova_tree_remove.patch deleted file mode 100644 index a38c7c3d52038de0581bc5dc0187273a530ec903..0000000000000000000000000000000000000000 --- a/util-Return-void-on-iova_tree_remove.patch +++ /dev/null @@ -1,61 +0,0 @@ -From b4c0eb3ad95c5c9a32cf87d30647d63ec9c193a9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 27 Apr 2022 17:49:31 +0200 -Subject: [PATCH] util: Return void on iova_tree_remove -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It always returns IOVA_OK so nobody uses it. - -Acked-by: Jason Wang -Reviewed-by: Peter Xu -Signed-off-by: Eugenio Pérez -Message-Id: <20220427154931.3166388-1-eperezma@redhat.com> -Signed-off-by: Laurent Vivier -Signed-off-by: fangyi ---- - include/qemu/iova-tree.h | 4 +--- - util/iova-tree.c | 4 +--- - 2 files changed, 2 insertions(+), 6 deletions(-) - -diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h -index c938fb0793..16bbfdf5f8 100644 ---- a/include/qemu/iova-tree.h -+++ b/include/qemu/iova-tree.h -@@ -72,10 +72,8 @@ int iova_tree_insert(IOVATree *tree, const DMAMap *map); - * provided. The range does not need to be exactly what has inserted, - * all the mappings that are included in the provided range will be - * removed from the tree. Here map->translated_addr is meaningless. -- * -- * Return: 0 if succeeded, or <0 if error. - */ --int iova_tree_remove(IOVATree *tree, const DMAMap *map); -+void iova_tree_remove(IOVATree *tree, const DMAMap *map); - - /** - * iova_tree_find: -diff --git a/util/iova-tree.c b/util/iova-tree.c -index 6dff29c1f6..fee530a579 100644 ---- a/util/iova-tree.c -+++ b/util/iova-tree.c -@@ -164,15 +164,13 @@ void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator) - g_tree_foreach(tree->tree, iova_tree_traverse, iterator); - } - --int iova_tree_remove(IOVATree *tree, const DMAMap *map) -+void iova_tree_remove(IOVATree *tree, const DMAMap *map) - { - const DMAMap *overlap; - - while ((overlap = iova_tree_find(tree, map))) { - g_tree_remove(tree->tree, overlap); - } -- -- return IOVA_OK; - } - - /** --- -2.27.0 - diff --git a/util-accept-iova_tree_remove_parameter-by-value.patch b/util-accept-iova_tree_remove_parameter-by-value.patch deleted file mode 100644 index 6ee105934c28c783b552eddec56e2490a9c38da8..0000000000000000000000000000000000000000 --- a/util-accept-iova_tree_remove_parameter-by-value.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 4ac2c0c847ffee0fb6aa92a9735be9448c62c107 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:20:04 +0200 -Subject: [PATCH] util: accept iova_tree_remove_parameter by value -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's convenient to call iova_tree_remove from a map returned from -iova_tree_find or iova_tree_find_iova. With the current code this is not -possible, since we will free it, and then we will try to search for it -again. - -Fix it making accepting the map by value, forcing a copy of the -argument. Not applying a fixes tag, since there is no use like that at -the moment. - -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/i386/intel_iommu.c | 6 +++--- - hw/virtio/vhost-iova-tree.c | 2 +- - hw/virtio/vhost-iova-tree.h | 2 +- - hw/virtio/vhost-vdpa.c | 6 +++--- - include/qemu/iova-tree.h | 2 +- - net/vhost-vdpa.c | 4 ++-- - util/iova-tree.c | 4 ++-- - 7 files changed, 13 insertions(+), 13 deletions(-) - -diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c -index 5b865ac08c..2d5ad84149 100644 ---- a/hw/i386/intel_iommu.c -+++ b/hw/i386/intel_iommu.c -@@ -1157,7 +1157,7 @@ static int vtd_page_walk_one(IOMMUTLBEvent *event, vtd_page_walk_info *info) - return ret; - } - /* Drop any existing mapping */ -- iova_tree_remove(as->iova_tree, &target); -+ iova_tree_remove(as->iova_tree, target); - /* Recover the correct type */ - event->type = IOMMU_NOTIFIER_MAP; - entry->perm = cache_perm; -@@ -1170,7 +1170,7 @@ static int vtd_page_walk_one(IOMMUTLBEvent *event, vtd_page_walk_info *info) - trace_vtd_page_walk_one_skip_unmap(entry->iova, entry->addr_mask); - return 0; - } -- iova_tree_remove(as->iova_tree, &target); -+ iova_tree_remove(as->iova_tree, target); - } - - trace_vtd_page_walk_one(info->domain_id, entry->iova, -@@ -3516,7 +3516,7 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n) - - map.iova = n->start; - map.size = size; -- iova_tree_remove(as->iova_tree, &map); -+ iova_tree_remove(as->iova_tree, map); - } - - static void vtd_address_space_unmap_all(IntelIOMMUState *s) -diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c -index 55fed1fefb..1339a4de8b 100644 ---- a/hw/virtio/vhost-iova-tree.c -+++ b/hw/virtio/vhost-iova-tree.c -@@ -104,7 +104,7 @@ int vhost_iova_tree_map_alloc(VhostIOVATree *tree, DMAMap *map) - * @iova_tree: The vhost iova tree - * @map: The map to remove - */ --void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map) -+void vhost_iova_tree_remove(VhostIOVATree *iova_tree, DMAMap map) - { - iova_tree_remove(iova_tree->iova_taddr_map, map); - } -diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h -index 6a4f24e0f9..4adfd79ff0 100644 ---- a/hw/virtio/vhost-iova-tree.h -+++ b/hw/virtio/vhost-iova-tree.h -@@ -22,6 +22,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_delete); - const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *iova_tree, - const DMAMap *map); - int vhost_iova_tree_map_alloc(VhostIOVATree *iova_tree, DMAMap *map); --void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map); -+void vhost_iova_tree_remove(VhostIOVATree *iova_tree, DMAMap map); - - #endif -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 02dab41c42..0f640f670b 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -242,7 +242,7 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, - - fail_map: - if (v->shadow_vqs_enabled) { -- vhost_iova_tree_remove(v->iova_tree, &mem_region); -+ vhost_iova_tree_remove(v->iova_tree, mem_region); - } - - fail: -@@ -302,7 +302,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, - return; - } - iova = result->iova; -- vhost_iova_tree_remove(v->iova_tree, result); -+ vhost_iova_tree_remove(v->iova_tree, *result); - } - vhost_vdpa_iotlb_batch_begin_once(v); - ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize)); -@@ -946,7 +946,7 @@ static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle, - needle->perm == IOMMU_RO); - if (unlikely(r != 0)) { - error_setg_errno(errp, -r, "Cannot map region to device"); -- vhost_iova_tree_remove(v->iova_tree, needle); -+ vhost_iova_tree_remove(v->iova_tree, *needle); - } - - return r == 0; -diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h -index 16bbfdf5f8..8528e5c98f 100644 ---- a/include/qemu/iova-tree.h -+++ b/include/qemu/iova-tree.h -@@ -73,7 +73,7 @@ int iova_tree_insert(IOVATree *tree, const DMAMap *map); - * all the mappings that are included in the provided range will be - * removed from the tree. Here map->translated_addr is meaningless. - */ --void iova_tree_remove(IOVATree *tree, const DMAMap *map); -+void iova_tree_remove(IOVATree *tree, DMAMap map); - - /** - * iova_tree_find: -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 0f75aa6080..8cfd086639 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -252,7 +252,7 @@ static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr) - error_report("Device cannot unmap: %s(%d)", g_strerror(r), r); - } - -- vhost_iova_tree_remove(tree, map); -+ vhost_iova_tree_remove(tree, *map); - } - - static size_t vhost_vdpa_net_cvq_cmd_len(void) -@@ -305,7 +305,7 @@ static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, - return true; - - dma_map_err: -- vhost_iova_tree_remove(v->iova_tree, &map); -+ vhost_iova_tree_remove(v->iova_tree, map); - return false; - } - -diff --git a/util/iova-tree.c b/util/iova-tree.c -index fee530a579..536789797e 100644 ---- a/util/iova-tree.c -+++ b/util/iova-tree.c -@@ -164,11 +164,11 @@ void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator) - g_tree_foreach(tree->tree, iova_tree_traverse, iterator); - } - --void iova_tree_remove(IOVATree *tree, const DMAMap *map) -+void iova_tree_remove(IOVATree *tree, DMAMap map) - { - const DMAMap *overlap; - -- while ((overlap = iova_tree_find(tree, map))) { -+ while ((overlap = iova_tree_find(tree, &map))) { - g_tree_remove(tree->tree, overlap); - } - } --- -2.27.0 - diff --git a/util-add-iova_tree_find_iova.patch b/util-add-iova_tree_find_iova.patch deleted file mode 100644 index fd935fe9927efbdb8a138985a9daa329035c599c..0000000000000000000000000000000000000000 --- a/util-add-iova_tree_find_iova.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 087ef4f1cfef58eadcb157585b70cf716c567305 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:49 +0100 -Subject: [PATCH] util: add iova_tree_find_iova -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This function does the reverse operation of iova_tree_find: To look for -a mapping that match a translated address so we can do the reverse. - -This have linear complexity instead of logarithmic, but it supports -overlapping HVA. Future developments could reduce it. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - include/qemu/iova-tree.h | 20 +++++++++++++++++++- - util/iova-tree.c | 34 ++++++++++++++++++++++++++++++++++ - 2 files changed, 53 insertions(+), 1 deletion(-) - -diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h -index d066400f09..c938fb0793 100644 ---- a/include/qemu/iova-tree.h -+++ b/include/qemu/iova-tree.h -@@ -83,7 +83,7 @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map); - * @tree: the iova tree to search from - * @map: the mapping to search - * -- * Search for a mapping in the iova tree that overlaps with the -+ * Search for a mapping in the iova tree that iova overlaps with the - * mapping range specified. Only the first found mapping will be - * returned. - * -@@ -95,6 +95,24 @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map); - */ - const DMAMap *iova_tree_find(const IOVATree *tree, const DMAMap *map); - -+/** -+ * iova_tree_find_iova: -+ * -+ * @tree: the iova tree to search from -+ * @map: the mapping to search -+ * -+ * Search for a mapping in the iova tree that translated_addr overlaps with the -+ * mapping range specified. Only the first found mapping will be -+ * returned. -+ * -+ * Return: DMAMap pointer if found, or NULL if not found. Note that -+ * the returned DMAMap pointer is maintained internally. User should -+ * only read the content but never modify or free the content. Also, -+ * user is responsible to make sure the pointer is valid (say, no -+ * concurrent deletion in progress). -+ */ -+const DMAMap *iova_tree_find_iova(const IOVATree *tree, const DMAMap *map); -+ - /** - * iova_tree_find_address: - * -diff --git a/util/iova-tree.c b/util/iova-tree.c -index 139626b46f..6dff29c1f6 100644 ---- a/util/iova-tree.c -+++ b/util/iova-tree.c -@@ -37,6 +37,11 @@ struct IOVATreeAllocArgs { - bool iova_found; - }; - -+typedef struct IOVATreeFindIOVAArgs { -+ const DMAMap *needle; -+ const DMAMap *result; -+} IOVATreeFindIOVAArgs; -+ - /** - * Iterate args to the next hole - * -@@ -81,6 +86,35 @@ const DMAMap *iova_tree_find(const IOVATree *tree, const DMAMap *map) - return g_tree_lookup(tree->tree, map); - } - -+static gboolean iova_tree_find_address_iterator(gpointer key, gpointer value, -+ gpointer data) -+{ -+ const DMAMap *map = key; -+ IOVATreeFindIOVAArgs *args = data; -+ const DMAMap *needle; -+ -+ g_assert(key == value); -+ -+ needle = args->needle; -+ if (map->translated_addr + map->size < needle->translated_addr || -+ needle->translated_addr + needle->size < map->translated_addr) { -+ return false; -+ } -+ -+ args->result = map; -+ return true; -+} -+ -+const DMAMap *iova_tree_find_iova(const IOVATree *tree, const DMAMap *map) -+{ -+ IOVATreeFindIOVAArgs args = { -+ .needle = map, -+ }; -+ -+ g_tree_foreach(tree->tree, iova_tree_find_address_iterator, &args); -+ return args.result; -+} -+ - const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova) - { - const DMAMap map = { .iova = iova, .size = 0 }; --- -2.27.0 - diff --git a/util-log-add-CONFIG_DISABLE_QEMU_LOG-macro.patch b/util-log-add-CONFIG_DISABLE_QEMU_LOG-macro.patch deleted file mode 100644 index f6940d69d12b29d8f6740cb87dec83b5eaa1356a..0000000000000000000000000000000000000000 --- a/util-log-add-CONFIG_DISABLE_QEMU_LOG-macro.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 05462305ec8b9ce5b414ede1e7e680b16d1a08ad Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Fri, 11 Feb 2022 18:20:59 +0800 -Subject: [PATCH] util/log: add CONFIG_DISABLE_QEMU_LOG macro - -Using CONFIG_DISABLE_QEMU_LOG macro to control -qemu_log function. - -Signed-off-by: Yan Wang ---- - util/log.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/util/log.c b/util/log.c -index 2ee1500bee..ed3029fe5c 100644 ---- a/util/log.c -+++ b/util/log.c -@@ -34,6 +34,12 @@ int qemu_loglevel; - static int log_append = 0; - static GArray *debug_regions; - -+#ifdef CONFIG_DISABLE_QEMU_LOG -+int qemu_log(const char *fmt, ...) -+{ -+ return 0; -+} -+#else - /* Return the number of characters emitted. */ - int qemu_log(const char *fmt, ...) - { -@@ -56,6 +62,7 @@ int qemu_log(const char *fmt, ...) - rcu_read_unlock(); - return ret; - } -+#endif - - static void __attribute__((__constructor__)) qemu_logfile_init(void) - { --- -2.27.0 - diff --git a/vdpa-Adapt-vhost_vdpa_get_vring_base-to-SVQ.patch b/vdpa-Adapt-vhost_vdpa_get_vring_base-to-SVQ.patch deleted file mode 100644 index cd93861b7c35afe0c1461f2b767acb3b6035ac3e..0000000000000000000000000000000000000000 --- a/vdpa-Adapt-vhost_vdpa_get_vring_base-to-SVQ.patch +++ /dev/null @@ -1,59 +0,0 @@ -From d42fea8a40c4a5d8909103910d86da8e674d1fb2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:52 +0100 -Subject: [PATCH] vdpa: Adapt vhost_vdpa_get_vring_base to SVQ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is needed to achieve migration, so the destination can restore its -index. - -Setting base as last used idx, so destination will see as available all -the entries that the device did not use, including the in-flight -processing ones. - -This is ok for networking, but other kinds of devices might have -problems with these retransmissions. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 8245345bcd..428137f654 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1143,8 +1143,25 @@ static int vhost_vdpa_set_vring_base(struct vhost_dev *dev, - static int vhost_vdpa_get_vring_base(struct vhost_dev *dev, - struct vhost_vring_state *ring) - { -+ struct vhost_vdpa *v = dev->opaque; - int ret; - -+ if (v->shadow_vqs_enabled) { -+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, -+ ring->index); -+ -+ /* -+ * Setting base as last used idx, so destination will see as available -+ * all the entries that the device did not use, including the in-flight -+ * processing ones. -+ * -+ * TODO: This is ok for networking, but other kinds of devices might -+ * have problems with these retransmissions. -+ */ -+ ring->num = svq->last_used_idx; -+ return 0; -+ } -+ - ret = vhost_vdpa_call(dev, VHOST_GET_VRING_BASE, ring); - trace_vhost_vdpa_get_vring_base(dev, ring->index, ring->num); - return ret; --- -2.27.0 - diff --git a/vdpa-Add-custom-IOTLB-translations-to-SVQ.patch b/vdpa-Add-custom-IOTLB-translations-to-SVQ.patch deleted file mode 100644 index 4f6c127279c478229ac54998e980f19e6270b81f..0000000000000000000000000000000000000000 --- a/vdpa-Add-custom-IOTLB-translations-to-SVQ.patch +++ /dev/null @@ -1,415 +0,0 @@ -From 649e277b6ec0d2cd798f6d43776ea38b00450db9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:51 +0100 -Subject: [PATCH] vdpa: Add custom IOTLB translations to SVQ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use translations added in VhostIOVATree in SVQ. - -Only introduce usage here, not allocation and deallocation. As with -previous patches, we use the dead code paths of shadow_vqs_enabled to -avoid commiting too many changes at once. These are impossible to take -at the moment. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 86 +++++++++++++++++--- - hw/virtio/vhost-shadow-virtqueue.h | 6 +- - hw/virtio/vhost-vdpa.c | 122 ++++++++++++++++++++++++----- - include/hw/virtio/vhost-vdpa.h | 3 + - 4 files changed, 187 insertions(+), 30 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 46e94f0861..c38b6b6ab5 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -69,7 +69,59 @@ static uint16_t vhost_svq_available_slots(const VhostShadowVirtqueue *svq) - return svq->vring.num - (svq->shadow_avail_idx - svq->shadow_used_idx); - } - --static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, -+/** -+ * Translate addresses between the qemu's virtual address and the SVQ IOVA -+ * -+ * @svq: Shadow VirtQueue -+ * @vaddr: Translated IOVA addresses -+ * @iovec: Source qemu's VA addresses -+ * @num: Length of iovec and minimum length of vaddr -+ */ -+static bool vhost_svq_translate_addr(const VhostShadowVirtqueue *svq, -+ hwaddr *addrs, const struct iovec *iovec, -+ size_t num) -+{ -+ if (num == 0) { -+ return true; -+ } -+ -+ for (size_t i = 0; i < num; ++i) { -+ DMAMap needle = { -+ .translated_addr = (hwaddr)(uintptr_t)iovec[i].iov_base, -+ .size = iovec[i].iov_len, -+ }; -+ Int128 needle_last, map_last; -+ size_t off; -+ -+ const DMAMap *map = vhost_iova_tree_find_iova(svq->iova_tree, &needle); -+ /* -+ * Map cannot be NULL since iova map contains all guest space and -+ * qemu already has a physical address mapped -+ */ -+ if (unlikely(!map)) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "Invalid address 0x%"HWADDR_PRIx" given by guest", -+ needle.translated_addr); -+ return false; -+ } -+ -+ off = needle.translated_addr - map->translated_addr; -+ addrs[i] = map->iova + off; -+ -+ needle_last = int128_add(int128_make64(needle.translated_addr), -+ int128_make64(iovec[i].iov_len)); -+ map_last = int128_make64(map->translated_addr + map->size); -+ if (unlikely(int128_gt(needle_last, map_last))) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "Guest buffer expands over iova range"); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg, - const struct iovec *iovec, size_t num, - bool more_descs, bool write) - { -@@ -88,7 +140,7 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, - } else { - descs[i].flags = flags; - } -- descs[i].addr = cpu_to_le64((hwaddr)(intptr_t)iovec[n].iov_base); -+ descs[i].addr = cpu_to_le64(sg[n]); - descs[i].len = cpu_to_le32(iovec[n].iov_len); - - last = i; -@@ -103,6 +155,8 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, - { - unsigned avail_idx; - vring_avail_t *avail = svq->vring.avail; -+ bool ok; -+ g_autofree hwaddr *sgs = g_new(hwaddr, MAX(elem->out_num, elem->in_num)); - - *head = svq->free_head; - -@@ -113,9 +167,20 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, - return false; - } - -- vhost_vring_write_descs(svq, elem->out_sg, elem->out_num, elem->in_num > 0, -- false); -- vhost_vring_write_descs(svq, elem->in_sg, elem->in_num, false, true); -+ ok = vhost_svq_translate_addr(svq, sgs, elem->out_sg, elem->out_num); -+ if (unlikely(!ok)) { -+ return false; -+ } -+ vhost_vring_write_descs(svq, sgs, elem->out_sg, elem->out_num, -+ elem->in_num > 0, false); -+ -+ -+ ok = vhost_svq_translate_addr(svq, sgs, elem->in_sg, elem->in_num); -+ if (unlikely(!ok)) { -+ return false; -+ } -+ -+ vhost_vring_write_descs(svq, sgs, elem->in_sg, elem->in_num, false, true); - - /* - * Put the entry in the available array (but don't update avail->idx until -@@ -394,9 +459,9 @@ void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd) - void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, - struct vhost_vring_addr *addr) - { -- addr->desc_user_addr = (uint64_t)(intptr_t)svq->vring.desc; -- addr->avail_user_addr = (uint64_t)(intptr_t)svq->vring.avail; -- addr->used_user_addr = (uint64_t)(intptr_t)svq->vring.used; -+ addr->desc_user_addr = (uint64_t)(uintptr_t)svq->vring.desc; -+ addr->avail_user_addr = (uint64_t)(uintptr_t)svq->vring.avail; -+ addr->used_user_addr = (uint64_t)(uintptr_t)svq->vring.used; - } - - size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq) -@@ -517,11 +582,13 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq) - * Creates vhost shadow virtqueue, and instructs the vhost device to use the - * shadow methods and file descriptors. - * -+ * @iova_tree: Tree to perform descriptors translations -+ * - * Returns the new virtqueue or NULL. - * - * In case of error, reason is reported through error_report. - */ --VhostShadowVirtqueue *vhost_svq_new(void) -+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree) - { - g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1); - int r; -@@ -542,6 +609,7 @@ VhostShadowVirtqueue *vhost_svq_new(void) - - event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND); - event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call); -+ svq->iova_tree = iova_tree; - return g_steal_pointer(&svq); - - err_init_hdev_call: -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index 38b3b91ca7..e5e24c536d 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -13,6 +13,7 @@ - #include "qemu/event_notifier.h" - #include "hw/virtio/virtio.h" - #include "standard-headers/linux/vhost_types.h" -+#include "hw/virtio/vhost-iova-tree.h" - - /* Shadow virtqueue to relay notifications */ - typedef struct VhostShadowVirtqueue { -@@ -43,6 +44,9 @@ typedef struct VhostShadowVirtqueue { - /* Virtio device */ - VirtIODevice *vdev; - -+ /* IOVA mapping */ -+ VhostIOVATree *iova_tree; -+ - /* Map for use the guest's descriptors */ - VirtQueueElement **ring_id_maps; - -@@ -75,7 +79,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, - VirtQueue *vq); - void vhost_svq_stop(VhostShadowVirtqueue *svq); - --VhostShadowVirtqueue *vhost_svq_new(void); -+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree); - - void vhost_svq_free(gpointer vq); - G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free); -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index db34f26246..8245345bcd 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -211,6 +211,21 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, - vaddr, section->readonly); - - llsize = int128_sub(llend, int128_make64(iova)); -+ if (v->shadow_vqs_enabled) { -+ DMAMap mem_region = { -+ .translated_addr = (hwaddr)(uintptr_t)vaddr, -+ .size = int128_get64(llsize) - 1, -+ .perm = IOMMU_ACCESS_FLAG(true, section->readonly), -+ }; -+ -+ int r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region); -+ if (unlikely(r != IOVA_OK)) { -+ error_report("Can't allocate a mapping (%d)", r); -+ goto fail; -+ } -+ -+ iova = mem_region.iova; -+ } - - vhost_vdpa_iotlb_batch_begin_once(v); - ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize), -@@ -263,6 +278,20 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, - - llsize = int128_sub(llend, int128_make64(iova)); - -+ if (v->shadow_vqs_enabled) { -+ const DMAMap *result; -+ const void *vaddr = memory_region_get_ram_ptr(section->mr) + -+ section->offset_within_region + -+ (iova - section->offset_within_address_space); -+ DMAMap mem_region = { -+ .translated_addr = (hwaddr)(uintptr_t)vaddr, -+ .size = int128_get64(llsize) - 1, -+ }; -+ -+ result = vhost_iova_tree_find_iova(v->iova_tree, &mem_region); -+ iova = result->iova; -+ vhost_iova_tree_remove(v->iova_tree, &mem_region); -+ } - vhost_vdpa_iotlb_batch_begin_once(v); - ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize)); - if (ret) { -@@ -372,7 +401,7 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, - - shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free); - for (unsigned n = 0; n < hdev->nvqs; ++n) { -- g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new(); -+ g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new(v->iova_tree); - - if (unlikely(!svq)) { - error_setg(errp, "Cannot create svq %u", n); -@@ -809,33 +838,70 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, - /** - * Unmap a SVQ area in the device - */ --static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr iova, -- hwaddr size) -+static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, -+ const DMAMap *needle) - { -+ const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle); -+ hwaddr size; - int r; - -- size = ROUND_UP(size, qemu_real_host_page_size); -- r = vhost_vdpa_dma_unmap(v, iova, size); -+ if (unlikely(!result)) { -+ error_report("Unable to find SVQ address to unmap"); -+ return false; -+ } -+ -+ size = ROUND_UP(result->size, qemu_real_host_page_size); -+ r = vhost_vdpa_dma_unmap(v, result->iova, size); - return r == 0; - } - - static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, - const VhostShadowVirtqueue *svq) - { -+ DMAMap needle = {}; - struct vhost_vdpa *v = dev->opaque; - struct vhost_vring_addr svq_addr; -- size_t device_size = vhost_svq_device_area_size(svq); -- size_t driver_size = vhost_svq_driver_area_size(svq); - bool ok; - - vhost_svq_get_vring_addr(svq, &svq_addr); - -- ok = vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr, driver_size); -+ needle.translated_addr = svq_addr.desc_user_addr; -+ ok = vhost_vdpa_svq_unmap_ring(v, &needle); - if (unlikely(!ok)) { - return false; - } - -- return vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr, device_size); -+ needle.translated_addr = svq_addr.used_user_addr; -+ return vhost_vdpa_svq_unmap_ring(v, &needle); -+} -+ -+/** -+ * Map the SVQ area in the device -+ * -+ * @v: Vhost-vdpa device -+ * @needle: The area to search iova -+ * @errorp: Error pointer -+ */ -+static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle, -+ Error **errp) -+{ -+ int r; -+ -+ r = vhost_iova_tree_map_alloc(v->iova_tree, needle); -+ if (unlikely(r != IOVA_OK)) { -+ error_setg(errp, "Cannot allocate iova (%d)", r); -+ return false; -+ } -+ -+ r = vhost_vdpa_dma_map(v, needle->iova, needle->size + 1, -+ (void *)(uintptr_t)needle->translated_addr, -+ needle->perm == IOMMU_RO); -+ if (unlikely(r != 0)) { -+ error_setg_errno(errp, -r, "Cannot map region to device"); -+ vhost_iova_tree_remove(v->iova_tree, needle); -+ } -+ -+ return r == 0; - } - - /** -@@ -851,28 +917,44 @@ static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev, - struct vhost_vring_addr *addr, - Error **errp) - { -+ DMAMap device_region, driver_region; -+ struct vhost_vring_addr svq_addr; - struct vhost_vdpa *v = dev->opaque; - size_t device_size = vhost_svq_device_area_size(svq); - size_t driver_size = vhost_svq_driver_area_size(svq); -- int r; -+ size_t avail_offset; -+ bool ok; - - ERRP_GUARD(); -- vhost_svq_get_vring_addr(svq, addr); -+ vhost_svq_get_vring_addr(svq, &svq_addr); - -- r = vhost_vdpa_dma_map(v, addr->desc_user_addr, driver_size, -- (void *)(uintptr_t)addr->desc_user_addr, true); -- if (unlikely(r != 0)) { -- error_setg_errno(errp, -r, "Cannot create vq driver region: "); -+ driver_region = (DMAMap) { -+ .translated_addr = svq_addr.desc_user_addr, -+ .size = driver_size - 1, -+ .perm = IOMMU_RO, -+ }; -+ ok = vhost_vdpa_svq_map_ring(v, &driver_region, errp); -+ if (unlikely(!ok)) { -+ error_prepend(errp, "Cannot create vq driver region: "); - return false; - } -+ addr->desc_user_addr = driver_region.iova; -+ avail_offset = svq_addr.avail_user_addr - svq_addr.desc_user_addr; -+ addr->avail_user_addr = driver_region.iova + avail_offset; - -- r = vhost_vdpa_dma_map(v, addr->used_user_addr, device_size, -- (void *)(intptr_t)addr->used_user_addr, false); -- if (unlikely(r != 0)) { -- error_setg_errno(errp, -r, "Cannot create vq device region: "); -+ device_region = (DMAMap) { -+ .translated_addr = svq_addr.used_user_addr, -+ .size = device_size - 1, -+ .perm = IOMMU_RW, -+ }; -+ ok = vhost_vdpa_svq_map_ring(v, &device_region, errp); -+ if (unlikely(!ok)) { -+ error_prepend(errp, "Cannot create vq device region: "); -+ vhost_vdpa_svq_unmap_ring(v, &driver_region); - } -+ addr->used_user_addr = device_region.iova; - -- return r == 0; -+ return ok; - } - - static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index 009a9f3b6b..ee8e939ad0 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -14,6 +14,7 @@ - - #include - -+#include "hw/virtio/vhost-iova-tree.h" - #include "hw/virtio/virtio.h" - #include "standard-headers/linux/vhost_types.h" - -@@ -30,6 +31,8 @@ typedef struct vhost_vdpa { - MemoryListener listener; - struct vhost_vdpa_iova_range iova_range; - bool shadow_vqs_enabled; -+ /* IOVA mapping used by the Shadow Virtqueue */ -+ VhostIOVATree *iova_tree; - GPtrArray *shadow_vqs; - struct vhost_dev *dev; - VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; --- -2.27.0 - diff --git a/vdpa-Add-device-migration-blocker.patch b/vdpa-Add-device-migration-blocker.patch deleted file mode 100644 index 85644d9cda441e30e50eff50ea69f4b411a5e21d..0000000000000000000000000000000000000000 --- a/vdpa-Add-device-migration-blocker.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 3f0eafe9e86bac9cf99176bf65a22d2dab154617 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:45 +0200 -Subject: [PATCH] vdpa: Add device migration blocker -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since the vhost-vdpa device is exposing _F_LOG, adding a migration blocker if -it uses CVQ. - -However, qemu is able to migrate simple devices with no CVQ as long as -they use SVQ. To allow it, add a placeholder error to vhost_vdpa, and -only add to vhost_dev when used. vhost_dev machinery place the migration -blocker if needed. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 15 +++++++++++++++ - include/hw/virtio/vhost-vdpa.h | 1 + - 2 files changed, 16 insertions(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 31b58aec59..5956ff4660 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -20,6 +20,7 @@ - #include "hw/virtio/vhost-shadow-virtqueue.h" - #include "hw/virtio/vhost-vdpa.h" - #include "exec/address-spaces.h" -+#include "migration/blocker.h" - #include "qemu/main-loop.h" - #include "cpu.h" - #include "trace.h" -@@ -1024,6 +1025,13 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) - return true; - } - -+ if (v->migration_blocker) { -+ int r = migrate_add_blocker(v->migration_blocker, &err); -+ if (unlikely(r < 0)) { -+ return false; -+ } -+ } -+ - for (i = 0; i < v->shadow_vqs->len; ++i) { - VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i); - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -@@ -1066,6 +1074,10 @@ err: - vhost_svq_stop(svq); - } - -+ if (v->migration_blocker) { -+ migrate_del_blocker(v->migration_blocker); -+ } -+ - return false; - } - -@@ -1085,6 +1097,9 @@ static bool vhost_vdpa_svqs_stop(struct vhost_dev *dev) - } - } - -+ if (v->migration_blocker) { -+ migrate_del_blocker(v->migration_blocker); -+ } - return true; - } - -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index 1111d85643..d10a89303e 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -35,6 +35,7 @@ typedef struct vhost_vdpa { - bool shadow_vqs_enabled; - /* IOVA mapping used by the Shadow Virtqueue */ - VhostIOVATree *iova_tree; -+ Error *migration_blocker; - GPtrArray *shadow_vqs; - const VhostShadowVirtqueueOps *shadow_vq_ops; - void *shadow_vq_ops_opaque; --- -2.27.0 - diff --git a/vdpa-Add-missing-tracing-to-batch-mapping-functions.patch b/vdpa-Add-missing-tracing-to-batch-mapping-functions.patch deleted file mode 100644 index b305d760ec0a4c0c5a8fa76e89f6ab46a9919b8a..0000000000000000000000000000000000000000 --- a/vdpa-Add-missing-tracing-to-batch-mapping-functions.patch +++ /dev/null @@ -1,58 +0,0 @@ -From d3aa8e2f948c0b3cd2cd723364fe968fd6befca9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 5 Apr 2022 08:36:28 +0200 -Subject: [PATCH] vdpa: Add missing tracing to batch mapping functions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -These functions were not traced properly. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Laurent Vivier -Reviewed-by: Stefano Garzarella -Acked-by: Jason Wang -Message-Id: <20220405063628.853745-1-eperezma@redhat.com> -Signed-off-by: Laurent Vivier -Signed-off-by: fangyi ---- - hw/virtio/trace-events | 2 ++ - hw/virtio/vhost-vdpa.c | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events -index 650e521e35..37c1555330 100644 ---- a/hw/virtio/trace-events -+++ b/hw/virtio/trace-events -@@ -25,6 +25,8 @@ vhost_user_postcopy_waker_nomatch(const char *rb, uint64_t rb_offset) "%s + 0x%" - # vhost-vdpa.c - vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8 - vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8 -+vhost_vdpa_listener_begin_batch(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8 -+vhost_vdpa_listener_commit(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8 - vhost_vdpa_listener_region_add(void *vdpa, uint64_t iova, uint64_t llend, void *vaddr, bool readonly) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64" vaddr: %p read-only: %d" - vhost_vdpa_listener_region_del(void *vdpa, uint64_t iova, uint64_t llend) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64 - vhost_vdpa_add_status(void *dev, uint8_t status) "dev: %p status: 0x%"PRIx8 -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index b66697da6e..022d70aefb 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -131,6 +131,7 @@ static void vhost_vdpa_listener_begin_batch(struct vhost_vdpa *v) - .iotlb.type = VHOST_IOTLB_BATCH_BEGIN, - }; - -+ trace_vhost_vdpa_listener_begin_batch(v, fd, msg.type, msg.iotlb.type); - if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) { - error_report("failed to write, fd=%d, errno=%d (%s)", - fd, errno, strerror(errno)); -@@ -165,6 +166,7 @@ static void vhost_vdpa_listener_commit(MemoryListener *listener) - msg.type = v->msg_type; - msg.iotlb.type = VHOST_IOTLB_BATCH_END; - -+ trace_vhost_vdpa_listener_commit(v, fd, msg.type, msg.iotlb.type); - if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) { - error_report("failed to write, fd=%d, errno=%d (%s)", - fd, errno, strerror(errno)); --- -2.27.0 - diff --git a/vdpa-Add-vhost_vdpa_net_load_mq.patch b/vdpa-Add-vhost_vdpa_net_load_mq.patch deleted file mode 100644 index 2b06bfd4aac7a1d735ddf655abed58ec1b30c19d..0000000000000000000000000000000000000000 --- a/vdpa-Add-vhost_vdpa_net_load_mq.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 6dc398327ebe7fcfe78b3df4fe9c1386bafef552 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 6 Sep 2022 17:07:16 +0200 -Subject: [PATCH] vdpa: Add vhost_vdpa_net_load_mq -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Same way as with the MAC, restore the expected number of queues at -device's start. - -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 15cd38b52e..b32fe5e68a 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -408,6 +408,28 @@ static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n) - return 0; - } - -+static int vhost_vdpa_net_load_mq(VhostVDPAState *s, -+ const VirtIONet *n) -+{ -+ struct virtio_net_ctrl_mq mq; -+ uint64_t features = n->parent_obj.guest_features; -+ ssize_t dev_written; -+ -+ if (!(features & BIT_ULL(VIRTIO_NET_F_MQ))) { -+ return 0; -+ } -+ -+ mq.virtqueue_pairs = cpu_to_le16(n->curr_queue_pairs); -+ dev_written = vhost_vdpa_net_load_cmd(s, VIRTIO_NET_CTRL_MQ, -+ VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &mq, -+ sizeof(mq)); -+ if (unlikely(dev_written < 0)) { -+ return dev_written; -+ } -+ -+ return *s->status != VIRTIO_NET_OK; -+} -+ - static int vhost_vdpa_net_load(NetClientState *nc) - { - VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); -@@ -426,6 +448,10 @@ static int vhost_vdpa_net_load(NetClientState *nc) - if (unlikely(r < 0)) { - return r; - } -+ r = vhost_vdpa_net_load_mq(s, n); -+ if (unlikely(r)) { -+ return r; -+ } - - return 0; - } --- -2.27.0 - diff --git a/vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch b/vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch deleted file mode 100644 index ad2ab280fd464dcfae6a2f2ea64fc8c5835426bd..0000000000000000000000000000000000000000 --- a/vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 8df992cbd90fb742e14ea1a90211cf535f20fbaa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:30:36 +0200 -Subject: [PATCH] vdpa: Add virtio-net mac address via CVQ at start -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is needed so the destination vdpa device see the same state a the -guest set in the source. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index b24e0919d0..561e43fa92 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -371,11 +371,51 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len, - return vhost_svq_poll(svq); - } - -+static int vhost_vdpa_net_load(NetClientState *nc) -+{ -+ VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); -+ const struct vhost_vdpa *v = &s->vhost_vdpa; -+ const VirtIONet *n; -+ uint64_t features; -+ -+ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); -+ -+ if (!v->shadow_vqs_enabled) { -+ return 0; -+ } -+ -+ n = VIRTIO_NET(v->dev->vdev); -+ features = n->parent_obj.guest_features; -+ if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) { -+ const struct virtio_net_ctrl_hdr ctrl = { -+ .class = VIRTIO_NET_CTRL_MAC, -+ .cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET, -+ }; -+ char *cursor = s->cvq_cmd_out_buffer; -+ ssize_t dev_written; -+ -+ memcpy(cursor, &ctrl, sizeof(ctrl)); -+ cursor += sizeof(ctrl); -+ memcpy(cursor, n->mac, sizeof(n->mac)); -+ -+ dev_written = vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + sizeof(n->mac), -+ sizeof(virtio_net_ctrl_ack)); -+ if (unlikely(dev_written < 0)) { -+ return dev_written; -+ } -+ -+ return *((virtio_net_ctrl_ack *)s->cvq_cmd_in_buffer) != VIRTIO_NET_OK; -+ } -+ -+ return 0; -+} -+ - static NetClientInfo net_vhost_vdpa_cvq_info = { - .type = NET_CLIENT_DRIVER_VHOST_VDPA, - .size = sizeof(VhostVDPAState), - .receive = vhost_vdpa_receive, - .start = vhost_vdpa_net_cvq_start, -+ .load = vhost_vdpa_net_load, - .stop = vhost_vdpa_net_cvq_stop, - .cleanup = vhost_vdpa_cleanup, - .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, --- -2.27.0 - diff --git a/vdpa-Add-x-svq-to-NetdevVhostVDPAOptions.patch b/vdpa-Add-x-svq-to-NetdevVhostVDPAOptions.patch deleted file mode 100644 index b97319d652678643789740cf2f42ac5baeaddd3a..0000000000000000000000000000000000000000 --- a/vdpa-Add-x-svq-to-NetdevVhostVDPAOptions.patch +++ /dev/null @@ -1,208 +0,0 @@ -From 3f278509424df64a731f69f4599460eda9a8d133 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:46 +0200 -Subject: [PATCH] vdpa: Add x-svq to NetdevVhostVDPAOptions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Finally offering the possibility to enable SVQ from the command line. - -Signed-off-by: Eugenio Pérez -Acked-by: Markus Armbruster -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++-- - qapi/net.json | 9 +++++- - 2 files changed, 77 insertions(+), 4 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 6a0fcab443..460f9674d7 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -74,6 +74,28 @@ const int vdpa_feature_bits[] = { - VHOST_INVALID_FEATURE_BIT - }; - -+/** Supported device specific feature bits with SVQ */ -+static const uint64_t vdpa_svq_device_features = -+ BIT_ULL(VIRTIO_NET_F_CSUM) | -+ BIT_ULL(VIRTIO_NET_F_GUEST_CSUM) | -+ BIT_ULL(VIRTIO_NET_F_MTU) | -+ BIT_ULL(VIRTIO_NET_F_MAC) | -+ BIT_ULL(VIRTIO_NET_F_GUEST_TSO4) | -+ BIT_ULL(VIRTIO_NET_F_GUEST_TSO6) | -+ BIT_ULL(VIRTIO_NET_F_GUEST_ECN) | -+ BIT_ULL(VIRTIO_NET_F_GUEST_UFO) | -+ BIT_ULL(VIRTIO_NET_F_HOST_TSO4) | -+ BIT_ULL(VIRTIO_NET_F_HOST_TSO6) | -+ BIT_ULL(VIRTIO_NET_F_HOST_ECN) | -+ BIT_ULL(VIRTIO_NET_F_HOST_UFO) | -+ BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) | -+ BIT_ULL(VIRTIO_NET_F_STATUS) | -+ BIT_ULL(VIRTIO_NET_F_CTRL_VQ) | -+ BIT_ULL(VIRTIO_F_ANY_LAYOUT) | -+ BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) | -+ BIT_ULL(VIRTIO_NET_F_RSC_EXT) | -+ BIT_ULL(VIRTIO_NET_F_STANDBY); -+ - VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc) - { - VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); -@@ -132,6 +154,7 @@ err_init: - static void vhost_vdpa_cleanup(NetClientState *nc) - { - VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); -+ struct vhost_dev *dev = &s->vhost_net->dev; - - /* - * If a peer NIC is attached, do not cleanup anything. -@@ -144,6 +167,9 @@ static void vhost_vdpa_cleanup(NetClientState *nc) - - qemu_vfree(s->cvq_cmd_out_buffer); - qemu_vfree(s->cvq_cmd_in_buffer); -+ if (dev->vq_index + dev->nvqs == dev->vq_index_end) { -+ g_clear_pointer(&s->vhost_vdpa.iova_tree, vhost_iova_tree_delete); -+ } - if (s->vhost_net) { - vhost_net_cleanup(s->vhost_net); - g_free(s->vhost_net); -@@ -445,7 +471,9 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - int vdpa_device_fd, - int queue_pair_index, - int nvqs, -- bool is_datapath) -+ bool is_datapath, -+ bool svq, -+ VhostIOVATree *iova_tree) - { - NetClientState *nc = NULL; - VhostVDPAState *s; -@@ -463,6 +491,8 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - - s->vhost_vdpa.device_fd = vdpa_device_fd; - s->vhost_vdpa.index = queue_pair_index; -+ s->vhost_vdpa.shadow_vqs_enabled = svq; -+ s->vhost_vdpa.iova_tree = iova_tree; - if (!is_datapath) { - s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size, - vhost_vdpa_net_cvq_cmd_page_len()); -@@ -473,6 +503,8 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - - s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops; - s->vhost_vdpa.shadow_vq_ops_opaque = s; -+ error_setg(&s->vhost_vdpa.migration_blocker, -+ "Migration disabled: vhost-vdpa uses CVQ."); - } - ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs); - if (ret) { -@@ -482,6 +514,14 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - return nc; - } - -+static int vhost_vdpa_get_iova_range(int fd, -+ struct vhost_vdpa_iova_range *iova_range) -+{ -+ int ret = ioctl(fd, VHOST_VDPA_GET_IOVA_RANGE, iova_range); -+ -+ return ret < 0 ? -errno : 0; -+} -+ - static int vhost_vdpa_get_features(int fd, uint64_t *features, Error **errp) - { - int ret = ioctl(fd, VHOST_GET_FEATURES, features); -@@ -532,6 +572,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - uint64_t features; - int vdpa_device_fd; - g_autofree NetClientState **ncs = NULL; -+ g_autoptr(VhostIOVATree) iova_tree = NULL; - NetClientState *nc; - int queue_pairs, r, i, has_cvq = 0; - -@@ -559,22 +600,45 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - return queue_pairs; - } - -+ if (opts->x_svq) { -+ struct vhost_vdpa_iova_range iova_range; -+ -+ uint64_t invalid_dev_features = -+ features & ~vdpa_svq_device_features & -+ /* Transport are all accepted at this point */ -+ ~MAKE_64BIT_MASK(VIRTIO_TRANSPORT_F_START, -+ VIRTIO_TRANSPORT_F_END - VIRTIO_TRANSPORT_F_START); -+ -+ if (invalid_dev_features) { -+ error_setg(errp, "vdpa svq does not work with features 0x%" PRIx64, -+ invalid_dev_features); -+ goto err_svq; -+ } -+ -+ vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range); -+ iova_tree = vhost_iova_tree_new(iova_range.first, iova_range.last); -+ } -+ - ncs = g_malloc0(sizeof(*ncs) * queue_pairs); - - for (i = 0; i < queue_pairs; i++) { - ncs[i] = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, -- vdpa_device_fd, i, 2, true); -+ vdpa_device_fd, i, 2, true, opts->x_svq, -+ iova_tree); - if (!ncs[i]) - goto err; - } - - if (has_cvq) { - nc = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, -- vdpa_device_fd, i, 1, false); -+ vdpa_device_fd, i, 1, false, -+ opts->x_svq, iova_tree); - if (!nc) - goto err; - } - -+ /* iova_tree ownership belongs to last NetClientState */ -+ g_steal_pointer(&iova_tree); - return 0; - - err: -@@ -583,6 +647,8 @@ err: - qemu_del_net_client(ncs[i]); - } - } -+ -+err_svq: - qemu_close(vdpa_device_fd); - - return -1; -diff --git a/qapi/net.json b/qapi/net.json -index 7fab2e7cd8..6a5460ce56 100644 ---- a/qapi/net.json -+++ b/qapi/net.json -@@ -445,12 +445,19 @@ - # @queues: number of queues to be created for multiqueue vhost-vdpa - # (default: 1) - # -+# @x-svq: Start device with (experimental) shadow virtqueue. (Since 7.1) -+# (default: false) -+# -+# Features: -+# @unstable: Member @x-svq is experimental. -+# - # Since: 5.1 - ## - { 'struct': 'NetdevVhostVDPAOptions', - 'data': { - '*vhostdev': 'str', -- '*queues': 'int' } } -+ '*queues': 'int', -+ '*x-svq': {'type': 'bool', 'features' : [ 'unstable'] } } } - - ## - # @NetClientDriver: --- -2.27.0 - diff --git a/vdpa-Allow-MQ-feature-in-SVQ.patch b/vdpa-Allow-MQ-feature-in-SVQ.patch deleted file mode 100644 index 7ebfa15a51d2cfdb0337ab5dd9ac2d1675b201b1..0000000000000000000000000000000000000000 --- a/vdpa-Allow-MQ-feature-in-SVQ.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 275135fcfb7e7c22ec84a79297ffc9c96fb82639 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 6 Sep 2022 17:07:19 +0200 -Subject: [PATCH] vdpa: Allow MQ feature in SVQ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Finally enable SVQ with MQ feature. - -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 831709a270..479abf97a7 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -93,6 +93,7 @@ static const uint64_t vdpa_svq_device_features = - BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) | - BIT_ULL(VIRTIO_NET_F_STATUS) | - BIT_ULL(VIRTIO_NET_F_CTRL_VQ) | -+ BIT_ULL(VIRTIO_NET_F_MQ) | - BIT_ULL(VIRTIO_F_ANY_LAYOUT) | - BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) | - BIT_ULL(VIRTIO_NET_F_RSC_EXT) | --- -2.27.0 - diff --git a/vdpa-Avoid-compiler-to-squash-reads-to-used-idx.patch b/vdpa-Avoid-compiler-to-squash-reads-to-used-idx.patch deleted file mode 100644 index 64e5871e3221bed882da165bad4e7e129477873d..0000000000000000000000000000000000000000 --- a/vdpa-Avoid-compiler-to-squash-reads-to-used-idx.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 853f14a29c9a31ca132647770f7d6886103b2b77 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:29 +0200 -Subject: [PATCH] vdpa: Avoid compiler to squash reads to used idx -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In the next patch we will allow busypolling of this value. The compiler -have a running path where shadow_used_idx, last_used_idx, and vring used -idx are not modified within the same thread busypolling. - -This was not an issue before since we always cleared device event -notifier before checking it, and that could act as memory barrier. -However, the busypoll needs something similar to kernel READ_ONCE. - -Let's add it here, sepparated from the polling. - -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index da1e1ce3c7..acf50a9a0b 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -326,11 +326,12 @@ static void vhost_handle_guest_kick_notifier(EventNotifier *n) - - static bool vhost_svq_more_used(VhostShadowVirtqueue *svq) - { -+ uint16_t *used_idx = &svq->vring.used->idx; - if (svq->last_used_idx != svq->shadow_used_idx) { - return true; - } - -- svq->shadow_used_idx = cpu_to_le16(svq->vring.used->idx); -+ svq->shadow_used_idx = cpu_to_le16(*(volatile uint16_t *)used_idx); - - return svq->last_used_idx != svq->shadow_used_idx; - } --- -2.27.0 - diff --git a/vdpa-Buffer-CVQ-support-on-shadow-virtqueue.patch b/vdpa-Buffer-CVQ-support-on-shadow-virtqueue.patch deleted file mode 100644 index fdbcc5d8b586708665382397e3dc48e077a68125..0000000000000000000000000000000000000000 --- a/vdpa-Buffer-CVQ-support-on-shadow-virtqueue.patch +++ /dev/null @@ -1,305 +0,0 @@ -From 31bf37b3097c1ece48b915137167bbd4bd7340aa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:43 +0200 -Subject: [PATCH] vdpa: Buffer CVQ support on shadow virtqueue -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce the control virtqueue support for vDPA shadow virtqueue. This -is needed for advanced networking features like rx filtering. - -Virtio-net control VQ copies the descriptors to qemu's VA, so we avoid -TOCTOU with the guest's or device's memory every time there is a device -model change. Otherwise, the guest could change the memory content in -the time between qemu and the device read it. - -To demonstrate command handling, VIRTIO_NET_F_CTRL_MACADDR is -implemented. If the virtio-net driver changes MAC the virtio-net device -model will be updated with the new one, and a rx filtering change event -will be raised. - -More cvq commands could be added here straightforwardly but they have -not been tested. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 214 +++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 206 insertions(+), 8 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 53a14bc756..2d928feefb 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -32,6 +32,9 @@ typedef struct VhostVDPAState { - NetClientState nc; - struct vhost_vdpa vhost_vdpa; - VHostNetState *vhost_net; -+ -+ /* Control commands shadow buffers */ -+ void *cvq_cmd_out_buffer, *cvq_cmd_in_buffer; - bool started; - } VhostVDPAState; - -@@ -138,6 +141,9 @@ static void vhost_vdpa_cleanup(NetClientState *nc) - if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) { - return; - } -+ -+ qemu_vfree(s->cvq_cmd_out_buffer); -+ qemu_vfree(s->cvq_cmd_in_buffer); - if (s->vhost_net) { - vhost_net_cleanup(s->vhost_net); - g_free(s->vhost_net); -@@ -197,24 +203,191 @@ static NetClientInfo net_vhost_vdpa_info = { - .check_peer_type = vhost_vdpa_check_peer_type, - }; - -+static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr) -+{ -+ VhostIOVATree *tree = v->iova_tree; -+ DMAMap needle = { -+ /* -+ * No need to specify size or to look for more translations since -+ * this contiguous chunk was allocated by us. -+ */ -+ .translated_addr = (hwaddr)(uintptr_t)addr, -+ }; -+ const DMAMap *map = vhost_iova_tree_find_iova(tree, &needle); -+ int r; -+ -+ if (unlikely(!map)) { -+ error_report("Cannot locate expected map"); -+ return; -+ } -+ -+ r = vhost_vdpa_dma_unmap(v, map->iova, map->size + 1); -+ if (unlikely(r != 0)) { -+ error_report("Device cannot unmap: %s(%d)", g_strerror(r), r); -+ } -+ -+ vhost_iova_tree_remove(tree, map); -+} -+ -+static size_t vhost_vdpa_net_cvq_cmd_len(void) -+{ -+ /* -+ * MAC_TABLE_SET is the ctrl command that produces the longer out buffer. -+ * In buffer is always 1 byte, so it should fit here -+ */ -+ return sizeof(struct virtio_net_ctrl_hdr) + -+ 2 * sizeof(struct virtio_net_ctrl_mac) + -+ MAC_TABLE_ENTRIES * ETH_ALEN; -+} -+ -+static size_t vhost_vdpa_net_cvq_cmd_page_len(void) -+{ -+ return ROUND_UP(vhost_vdpa_net_cvq_cmd_len(), qemu_real_host_page_size); -+} -+ -+/** Copy and map a guest buffer. */ -+static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, -+ const struct iovec *out_data, -+ size_t out_num, size_t data_len, void *buf, -+ size_t *written, bool write) -+{ -+ DMAMap map = {}; -+ int r; -+ -+ if (unlikely(!data_len)) { -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid legnth of %s buffer\n", -+ __func__, write ? "in" : "out"); -+ return false; -+ } -+ -+ *written = iov_to_buf(out_data, out_num, 0, buf, data_len); -+ map.translated_addr = (hwaddr)(uintptr_t)buf; -+ map.size = vhost_vdpa_net_cvq_cmd_page_len() - 1; -+ map.perm = write ? IOMMU_RW : IOMMU_RO, -+ r = vhost_iova_tree_map_alloc(v->iova_tree, &map); -+ if (unlikely(r != IOVA_OK)) { -+ error_report("Cannot map injected element"); -+ return false; -+ } -+ -+ r = vhost_vdpa_dma_map(v, map.iova, vhost_vdpa_net_cvq_cmd_page_len(), buf, -+ !write); -+ if (unlikely(r < 0)) { -+ goto dma_map_err; -+ } -+ -+ return true; -+ -+dma_map_err: -+ vhost_iova_tree_remove(v->iova_tree, &map); -+ return false; -+} -+ - /** -- * Forward buffer for the moment. -+ * Copy the guest element into a dedicated buffer suitable to be sent to NIC -+ * -+ * @iov: [0] is the out buffer, [1] is the in one -+ */ -+static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState *s, -+ VirtQueueElement *elem, -+ struct iovec *iov) -+{ -+ size_t in_copied; -+ bool ok; -+ -+ iov[0].iov_base = s->cvq_cmd_out_buffer; -+ ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, elem->out_sg, elem->out_num, -+ vhost_vdpa_net_cvq_cmd_len(), iov[0].iov_base, -+ &iov[0].iov_len, false); -+ if (unlikely(!ok)) { -+ return false; -+ } -+ -+ iov[1].iov_base = s->cvq_cmd_in_buffer; -+ ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, NULL, 0, -+ sizeof(virtio_net_ctrl_ack), iov[1].iov_base, -+ &in_copied, true); -+ if (unlikely(!ok)) { -+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); -+ return false; -+ } -+ -+ iov[1].iov_len = sizeof(virtio_net_ctrl_ack); -+ return true; -+} -+ -+/** -+ * Do not forward commands not supported by SVQ. Otherwise, the device could -+ * accept it and qemu would not know how to update the device model. -+ */ -+static bool vhost_vdpa_net_cvq_validate_cmd(const struct iovec *out, -+ size_t out_num) -+{ -+ struct virtio_net_ctrl_hdr ctrl; -+ size_t n; -+ -+ n = iov_to_buf(out, out_num, 0, &ctrl, sizeof(ctrl)); -+ if (unlikely(n < sizeof(ctrl))) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "%s: invalid legnth of out buffer %zu\n", __func__, n); -+ return false; -+ } -+ -+ switch (ctrl.class) { -+ case VIRTIO_NET_CTRL_MAC: -+ switch (ctrl.cmd) { -+ case VIRTIO_NET_CTRL_MAC_ADDR_SET: -+ return true; -+ default: -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mac cmd %u\n", -+ __func__, ctrl.cmd); -+ }; -+ break; -+ default: -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid control class %u\n", -+ __func__, ctrl.class); -+ }; -+ -+ return false; -+} -+ -+/** -+ * Validate and copy control virtqueue commands. -+ * -+ * Following QEMU guidelines, we offer a copy of the buffers to the device to -+ * prevent TOCTOU bugs. - */ - static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - VirtQueueElement *elem, - void *opaque) - { -- unsigned int n = elem->out_num + elem->in_num; -- g_autofree struct iovec *dev_buffers = g_new(struct iovec, n); -+ VhostVDPAState *s = opaque; - size_t in_len, dev_written; - virtio_net_ctrl_ack status = VIRTIO_NET_ERR; -- int r; -+ /* out and in buffers sent to the device */ -+ struct iovec dev_buffers[2] = { -+ { .iov_base = s->cvq_cmd_out_buffer }, -+ { .iov_base = s->cvq_cmd_in_buffer }, -+ }; -+ /* in buffer used for device model */ -+ const struct iovec in = { -+ .iov_base = &status, -+ .iov_len = sizeof(status), -+ }; -+ int r = -EINVAL; -+ bool ok; -+ -+ ok = vhost_vdpa_net_cvq_map_elem(s, elem, dev_buffers); -+ if (unlikely(!ok)) { -+ goto out; -+ } - -- memcpy(dev_buffers, elem->out_sg, elem->out_num); -- memcpy(dev_buffers + elem->out_num, elem->in_sg, elem->in_num); -+ ok = vhost_vdpa_net_cvq_validate_cmd(&dev_buffers[0], 1); -+ if (unlikely(!ok)) { -+ goto out; -+ } - -- r = vhost_svq_add(svq, &dev_buffers[0], elem->out_num, &dev_buffers[1], -- elem->in_num, elem); -+ r = vhost_svq_add(svq, &dev_buffers[0], 1, &dev_buffers[1], 1, elem); - if (unlikely(r != 0)) { - if (unlikely(r == -ENOSPC)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n", -@@ -231,6 +404,18 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - dev_written = vhost_svq_poll(svq); - if (unlikely(dev_written < sizeof(status))) { - error_report("Insufficient written data (%zu)", dev_written); -+ goto out; -+ } -+ -+ memcpy(&status, dev_buffers[1].iov_base, sizeof(status)); -+ if (status != VIRTIO_NET_OK) { -+ goto out; -+ } -+ -+ status = VIRTIO_NET_ERR; -+ virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, dev_buffers, 1); -+ if (status != VIRTIO_NET_OK) { -+ error_report("Bad CVQ processing in model"); - } - - out: -@@ -241,6 +426,12 @@ out: - } - vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status))); - g_free(elem); -+ if (dev_buffers[0].iov_base) { -+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[0].iov_base); -+ } -+ if (dev_buffers[1].iov_base) { -+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[1].iov_base); -+ } - return r; - } - -@@ -273,6 +464,13 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - s->vhost_vdpa.device_fd = vdpa_device_fd; - s->vhost_vdpa.index = queue_pair_index; - if (!is_datapath) { -+ s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size, -+ vhost_vdpa_net_cvq_cmd_page_len()); -+ memset(s->cvq_cmd_out_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len()); -+ s->cvq_cmd_in_buffer = qemu_memalign(qemu_real_host_page_size, -+ vhost_vdpa_net_cvq_cmd_page_len()); -+ memset(s->cvq_cmd_in_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len()); -+ - s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops; - s->vhost_vdpa.shadow_vq_ops_opaque = s; - } --- -2.27.0 - diff --git a/vdpa-Delete-CVQ-migration-blocker.patch b/vdpa-Delete-CVQ-migration-blocker.patch deleted file mode 100644 index 568fb20d6e0088f5695037006f1ee88ba5eca8e3..0000000000000000000000000000000000000000 --- a/vdpa-Delete-CVQ-migration-blocker.patch +++ /dev/null @@ -1,89 +0,0 @@ -From cdc1b97f133a2b79318cc10aa6d1a9b69abac78f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:30:37 +0200 -Subject: [PATCH] vdpa: Delete CVQ migration blocker -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We can restore the device state in the destination via CVQ now. Remove -the migration blocker. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 15 --------------- - include/hw/virtio/vhost-vdpa.h | 1 - - net/vhost-vdpa.c | 2 -- - 3 files changed, 18 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index d7bdc0f37c..0f07c85b91 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1035,13 +1035,6 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) - return true; - } - -- if (v->migration_blocker) { -- int r = migrate_add_blocker(v->migration_blocker, &err); -- if (unlikely(r < 0)) { -- return false; -- } -- } -- - for (i = 0; i < v->shadow_vqs->len; ++i) { - VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i); - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -@@ -1084,10 +1077,6 @@ err: - vhost_svq_stop(svq); - } - -- if (v->migration_blocker) { -- migrate_del_blocker(v->migration_blocker); -- } -- - return false; - } - -@@ -1103,10 +1092,6 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev) - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); - vhost_vdpa_svq_unmap_rings(dev, svq); - } -- -- if (v->migration_blocker) { -- migrate_del_blocker(v->migration_blocker); -- } - } - - static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index d10a89303e..1111d85643 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -35,7 +35,6 @@ typedef struct vhost_vdpa { - bool shadow_vqs_enabled; - /* IOVA mapping used by the Shadow Virtqueue */ - VhostIOVATree *iova_tree; -- Error *migration_blocker; - GPtrArray *shadow_vqs; - const VhostShadowVirtqueueOps *shadow_vq_ops; - void *shadow_vq_ops_opaque; -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 561e43fa92..b10a18aeb4 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -563,8 +563,6 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - - s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops; - s->vhost_vdpa.shadow_vq_ops_opaque = s; -- error_setg(&s->vhost_vdpa.migration_blocker, -- "Migration disabled: vhost-vdpa uses CVQ."); - } - ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs); - if (ret) { --- -2.27.0 - diff --git a/vdpa-Delete-duplicated-vdpa_feature_bits-entry.patch b/vdpa-Delete-duplicated-vdpa_feature_bits-entry.patch deleted file mode 100644 index 8a0b3658838ed87d72c63ec50928dc2a05304de1..0000000000000000000000000000000000000000 --- a/vdpa-Delete-duplicated-vdpa_feature_bits-entry.patch +++ /dev/null @@ -1,34 +0,0 @@ -From e316083c41f99c424879622c6e79452a6878b32f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 20 Oct 2022 10:00:58 +0200 -Subject: [PATCH] vdpa: Delete duplicated vdpa_feature_bits entry -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This entry was duplicated on referenced commit. Removing it. - -Fixes: 402378407dbd ("vhost-vdpa: multiqueue support") -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 479abf97a7..f4f6b8587f 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -62,7 +62,6 @@ const int vdpa_feature_bits[] = { - VIRTIO_NET_F_CTRL_RX, - VIRTIO_NET_F_CTRL_RX_EXTRA, - VIRTIO_NET_F_CTRL_VLAN, -- VIRTIO_NET_F_GUEST_ANNOUNCE, - VIRTIO_NET_F_CTRL_MAC_ADDR, - VIRTIO_NET_F_RSS, - VIRTIO_NET_F_MQ, --- -2.27.0 - diff --git a/vdpa-Export-vhost_vdpa_dma_map-and-unmap-calls.patch b/vdpa-Export-vhost_vdpa_dma_map-and-unmap-calls.patch deleted file mode 100644 index 6fade98571914a50d432284994bf526b538fcb87..0000000000000000000000000000000000000000 --- a/vdpa-Export-vhost_vdpa_dma_map-and-unmap-calls.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 4054b1e42fde8f22703d5fc9bc84a9179ee8f9f7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:40 +0200 -Subject: [PATCH] vdpa: Export vhost_vdpa_dma_map and unmap calls -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Shadow CVQ will copy buffers on qemu VA, so we avoid TOCTOU attacks from -the guest that could set a different state in qemu device model and vdpa -device. - -To do so, it needs to be able to map these new buffers to the device. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 7 +++---- - include/hw/virtio/vhost-vdpa.h | 4 ++++ - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index a8d42655f0..8e962f511d 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -73,8 +73,8 @@ static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section, - return false; - } - --static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size, -- void *vaddr, bool readonly) -+int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size, -+ void *vaddr, bool readonly) - { - struct vhost_msg_v2 msg = {}; - int fd = v->device_fd; -@@ -99,8 +99,7 @@ static int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size, - return ret; - } - --static int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, -- hwaddr size) -+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size) - { - struct vhost_msg_v2 msg = {}; - int fd = v->device_fd; -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index a29dbb3f53..7214eb47dc 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -39,4 +39,8 @@ typedef struct vhost_vdpa { - VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; - } VhostVDPA; - -+int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size, -+ void *vaddr, bool readonly); -+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size); -+ - #endif --- -2.27.0 - diff --git a/vdpa-Expose-VHOST_F_LOG_ALL-on-SVQ.patch b/vdpa-Expose-VHOST_F_LOG_ALL-on-SVQ.patch deleted file mode 100644 index 610d418620c7af70a3948e2cea25844529b3c0b4..0000000000000000000000000000000000000000 --- a/vdpa-Expose-VHOST_F_LOG_ALL-on-SVQ.patch +++ /dev/null @@ -1,120 +0,0 @@ -From a531a56bddf997f559f67fe9d3dc6d4258c82eb1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:54 +0100 -Subject: [PATCH] vdpa: Expose VHOST_F_LOG_ALL on SVQ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -SVQ is able to log the dirty bits by itself, so let's use it to not -block migration. - -Also, ignore set and clear of VHOST_F_LOG_ALL on set_features if SVQ is -enabled. Even if the device supports it, the reports would be nonsense -because SVQ memory is in the qemu region. - -The log region is still allocated. Future changes might skip that, but -this series is already long enough. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 39 ++++++++++++++++++++++++++++++---- - include/hw/virtio/vhost-vdpa.h | 1 + - 2 files changed, 36 insertions(+), 4 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 840141321a..3b5456cc0e 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -375,6 +375,16 @@ static bool vhost_vdpa_one_time_request(struct vhost_dev *dev) - return v->index != 0; - } - -+static int vhost_vdpa_get_dev_features(struct vhost_dev *dev, -+ uint64_t *features) -+{ -+ int ret; -+ -+ ret = vhost_vdpa_call(dev, VHOST_GET_FEATURES, features); -+ trace_vhost_vdpa_get_features(dev, *features); -+ return ret; -+} -+ - static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, - Error **errp) - { -@@ -387,7 +397,7 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, - return 0; - } - -- r = hdev->vhost_ops->vhost_get_features(hdev, &dev_features); -+ r = vhost_vdpa_get_dev_features(hdev, &dev_features); - if (r != 0) { - error_setg_errno(errp, -r, "Can't get vdpa device features"); - return r; -@@ -612,12 +622,29 @@ static int vhost_vdpa_set_mem_table(struct vhost_dev *dev, - static int vhost_vdpa_set_features(struct vhost_dev *dev, - uint64_t features) - { -+ struct vhost_vdpa *v = dev->opaque; - int ret; - - if (vhost_vdpa_one_time_request(dev)) { - return 0; - } - -+ if (v->shadow_vqs_enabled) { -+ if ((v->acked_features ^ features) == BIT_ULL(VHOST_F_LOG_ALL)) { -+ /* -+ * QEMU is just trying to enable or disable logging. SVQ handles -+ * this sepparately, so no need to forward this. -+ */ -+ v->acked_features = features; -+ return 0; -+ } -+ -+ v->acked_features = features; -+ -+ /* We must not ack _F_LOG if SVQ is enabled */ -+ features &= ~BIT_ULL(VHOST_F_LOG_ALL); -+ } -+ - trace_vhost_vdpa_set_features(dev, features); - ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features); - if (ret) { -@@ -1202,10 +1229,14 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev, - static int vhost_vdpa_get_features(struct vhost_dev *dev, - uint64_t *features) - { -- int ret; -+ struct vhost_vdpa *v = dev->opaque; -+ int ret = vhost_vdpa_get_dev_features(dev, features); -+ -+ if (ret == 0 && v->shadow_vqs_enabled) { -+ /* Add SVQ logging capabilities */ -+ *features |= BIT_ULL(VHOST_F_LOG_ALL); -+ } - -- ret = vhost_vdpa_call(dev, VHOST_GET_FEATURES, features); -- trace_vhost_vdpa_get_features(dev, *features); - return ret; - } - -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index ee8e939ad0..a29dbb3f53 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -30,6 +30,7 @@ typedef struct vhost_vdpa { - bool iotlb_batch_begin_sent; - MemoryListener listener; - struct vhost_vdpa_iova_range iova_range; -+ uint64_t acked_features; - bool shadow_vqs_enabled; - /* IOVA mapping used by the Shadow Virtqueue */ - VhostIOVATree *iova_tree; --- -2.27.0 - diff --git a/vdpa-Extract-get-features-part-from-vhost_vdpa_get_m.patch b/vdpa-Extract-get-features-part-from-vhost_vdpa_get_m.patch deleted file mode 100644 index 9a2f33770e657c8e2683630ed59d7c5b4cc8eef8..0000000000000000000000000000000000000000 --- a/vdpa-Extract-get-features-part-from-vhost_vdpa_get_m.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 29048bdf8848d527b39a383c7f0c4f8c60870f71 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:44 +0200 -Subject: [PATCH] vdpa: Extract get features part from - vhost_vdpa_get_max_queue_pairs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -To know the device features is needed for CVQ SVQ, so SVQ knows if it -can handle all commands or not. Extract from -vhost_vdpa_get_max_queue_pairs so we can reuse it. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 30 ++++++++++++++++++++---------- - 1 file changed, 20 insertions(+), 10 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 2d928feefb..6a0fcab443 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -482,20 +482,24 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - return nc; - } - --static int vhost_vdpa_get_max_queue_pairs(int fd, int *has_cvq, Error **errp) -+static int vhost_vdpa_get_features(int fd, uint64_t *features, Error **errp) -+{ -+ int ret = ioctl(fd, VHOST_GET_FEATURES, features); -+ if (unlikely(ret < 0)) { -+ error_setg_errno(errp, errno, -+ "Fail to query features from vhost-vDPA device"); -+ } -+ return ret; -+} -+ -+static int vhost_vdpa_get_max_queue_pairs(int fd, uint64_t features, -+ int *has_cvq, Error **errp) - { - unsigned long config_size = offsetof(struct vhost_vdpa_config, buf); - g_autofree struct vhost_vdpa_config *config = NULL; - __virtio16 *max_queue_pairs; -- uint64_t features; - int ret; - -- ret = ioctl(fd, VHOST_GET_FEATURES, &features); -- if (ret) { -- error_setg(errp, "Fail to query features from vhost-vDPA device"); -- return ret; -- } -- - if (features & (1 << VIRTIO_NET_F_CTRL_VQ)) { - *has_cvq = 1; - } else { -@@ -525,10 +529,11 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - NetClientState *peer, Error **errp) - { - const NetdevVhostVDPAOptions *opts; -+ uint64_t features; - int vdpa_device_fd; - g_autofree NetClientState **ncs = NULL; - NetClientState *nc; -- int queue_pairs, i, has_cvq = 0; -+ int queue_pairs, r, i, has_cvq = 0; - - assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); - opts = &netdev->u.vhost_vdpa; -@@ -542,7 +547,12 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - return -errno; - } - -- queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd, -+ r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp); -+ if (unlikely(r < 0)) { -+ return r; -+ } -+ -+ queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd, features, - &has_cvq, errp); - if (queue_pairs < 0) { - qemu_close(vdpa_device_fd); --- -2.27.0 - diff --git a/vdpa-Fix-bad-index-calculus-at-vhost_vdpa_get_vring_.patch b/vdpa-Fix-bad-index-calculus-at-vhost_vdpa_get_vring_.patch deleted file mode 100644 index a156e6c89539f5adcfc8593baaea0dd782b6e5f9..0000000000000000000000000000000000000000 --- a/vdpa-Fix-bad-index-calculus-at-vhost_vdpa_get_vring_.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b37494d53478957b9e126e97f03d9501888a4d83 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 12 May 2022 19:57:44 +0200 -Subject: [PATCH] vdpa: Fix bad index calculus at vhost_vdpa_get_vring_base -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fixes: 6d0b222666 ("vdpa: Adapt vhost_vdpa_get_vring_base to SVQ") - -Acked-by: Jason Wang -Signed-off-by: Eugenio Pérez -Message-Id: <20220512175747.142058-4-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 022d70aefb..3b67c9fd12 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1174,11 +1174,11 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev *dev, - struct vhost_vring_state *ring) - { - struct vhost_vdpa *v = dev->opaque; -+ int vdpa_idx = ring->index - dev->vq_index; - int ret; - - if (v->shadow_vqs_enabled) { -- VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, -- ring->index); -+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx); - - /* - * Setting base as last used idx, so destination will see as available --- -2.27.0 - diff --git a/vdpa-Fix-file-descriptor-leak-on-get-features-error.patch b/vdpa-Fix-file-descriptor-leak-on-get-features-error.patch deleted file mode 100644 index 6436bab1faf6f73d18d987e622bf2fd0be61aa2d..0000000000000000000000000000000000000000 --- a/vdpa-Fix-file-descriptor-leak-on-get-features-error.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 4077ce7f2d21dc67d18dc444165859b8496a185e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 2 Aug 2022 13:24:46 +0200 -Subject: [PATCH] vdpa: Fix file descriptor leak on get features error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -File descriptor vdpa_device_fd is not free in the case of returning -error from vhost_vdpa_get_features. Fixing it by making all errors go to -the same error path. - -Resolves: Coverity CID 1490785 -Fixes: 8170ab3f43 ("vdpa: Extract get features part from vhost_vdpa_get_max_queue_pairs") - -Signed-off-by: Eugenio Pérez -Reviewed-by: Laurent Vivier -Reviewed-by: Michael S. Tsirkin -Message-Id: <20220802112447.249436-2-eperezma@redhat.com> -Signed-off-by: Laurent Vivier -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 460f9674d7..0f75aa6080 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -574,7 +574,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - g_autofree NetClientState **ncs = NULL; - g_autoptr(VhostIOVATree) iova_tree = NULL; - NetClientState *nc; -- int queue_pairs, r, i, has_cvq = 0; -+ int queue_pairs, r, i = 0, has_cvq = 0; - - assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); - opts = &netdev->u.vhost_vdpa; -@@ -590,7 +590,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - - r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp); - if (unlikely(r < 0)) { -- return r; -+ goto err; - } - - queue_pairs = vhost_vdpa_get_max_queue_pairs(vdpa_device_fd, features, --- -2.27.0 - diff --git a/vdpa-Fix-index-calculus-at-vhost_vdpa_svqs_start.patch b/vdpa-Fix-index-calculus-at-vhost_vdpa_svqs_start.patch deleted file mode 100644 index 69f14963ab928202a072bf909fb55add1c9de1e4..0000000000000000000000000000000000000000 --- a/vdpa-Fix-index-calculus-at-vhost_vdpa_svqs_start.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 2f19a3fd1fbaca215906199ab7da7cd961b68d65 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 12 May 2022 19:57:45 +0200 -Subject: [PATCH] vdpa: Fix index calculus at vhost_vdpa_svqs_start -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With the introduction of MQ the index of the vq needs to be calculated -with the device model vq_index. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20220512175747.142058-5-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 3b67c9fd12..1360f2eaf7 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1020,7 +1020,7 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) - VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i); - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); - struct vhost_vring_addr addr = { -- .index = i, -+ .index = dev->vq_index + i, - }; - int r; - bool ok = vhost_vdpa_svq_setup(dev, svq, i, &err); --- -2.27.0 - diff --git a/vdpa-Fix-memory-listener-deletions-of-iova-tree.patch b/vdpa-Fix-memory-listener-deletions-of-iova-tree.patch deleted file mode 100644 index bba1ee0f2540ae492c4cef6d0e342196c9e1a34a..0000000000000000000000000000000000000000 --- a/vdpa-Fix-memory-listener-deletions-of-iova-tree.patch +++ /dev/null @@ -1,53 +0,0 @@ -From de9a72905ad70e256a73608c92f50c3862b8eb8e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Fri, 22 Jul 2022 10:26:30 +0200 -Subject: [PATCH] vdpa: Fix memory listener deletions of iova tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -vhost_vdpa_listener_region_del is always deleting the first iova entry -of the tree, since it's using the needle iova instead of the result's -one. - -This was detected using a vga virtual device in the VM using vdpa SVQ. -It makes some extra memory adding and deleting, so the wrong one was -mapped / unmapped. This was undetected before since all the memory was -mappend and unmapped totally without that device, but other conditions -could trigger it too: - -* mem_region was with .iova = 0, .translated_addr = (correct GPA). -* iova_tree_find_iova returned right result, but does not update - mem_region. -* iova_tree_remove always removed region with .iova = 0. Right iova were - sent to the device. -* Next map will fill the first region with .iova = 0, causing a mapping - with the same iova and device complains, if the next action is a map. -* Next unmap will cause to try to unmap again iova = 0, causing the - device to complain that no region was mapped at iova = 0. - -Fixes: 34e3c94edaef ("vdpa: Add custom IOTLB translations to SVQ") -Reported-by: Lei Yang -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 6304f174c2..d0cf7a0745 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -292,7 +292,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, - - result = vhost_iova_tree_find_iova(v->iova_tree, &mem_region); - iova = result->iova; -- vhost_iova_tree_remove(v->iova_tree, &mem_region); -+ vhost_iova_tree_remove(v->iova_tree, result); - } - vhost_vdpa_iotlb_batch_begin_once(v); - ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize)); --- -2.27.0 - diff --git a/vdpa-Fix-possible-use-after-free-for-VirtQueueElemen.patch b/vdpa-Fix-possible-use-after-free-for-VirtQueueElemen.patch deleted file mode 100644 index 925cb9efdfda400301f49446b1fb776aa3108219..0000000000000000000000000000000000000000 --- a/vdpa-Fix-possible-use-after-free-for-VirtQueueElemen.patch +++ /dev/null @@ -1,63 +0,0 @@ -From c8d132a62f026e51c2fb1f87dbf40aad8080fa9a Mon Sep 17 00:00:00 2001 -From: Hawkins Jiawei -Date: Sat, 8 Jul 2023 00:44:42 +0800 -Subject: [PATCH] vdpa: Fix possible use-after-free for VirtQueueElement -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -QEMU uses vhost_handle_guest_kick() to forward guest's available -buffers to the vdpa device in SVQ avail ring. - -In vhost_handle_guest_kick(), a `g_autofree` `elem` is used to -iterate through the available VirtQueueElements. This `elem` is -then passed to `svq->ops->avail_handler`, specifically to the -vhost_vdpa_net_handle_ctrl_avail(). If this handler fails to -process the CVQ command, vhost_handle_guest_kick() regains -ownership of the `elem`, and either frees it or requeues it. - -Yet the problem is that, vhost_vdpa_net_handle_ctrl_avail() -mistakenly frees the `elem`, even if it fails to forward the -CVQ command to vdpa device. This can result in a use-after-free -for the `elem` in vhost_handle_guest_kick(). - -This patch solves this problem by refactoring -vhost_vdpa_net_handle_ctrl_avail() to only freeing the `elem` if -it owns it. - -Fixes: bd907ae4b0 ("vdpa: manual forward CVQ buffers") -Signed-off-by: Hawkins Jiawei -Message-Id: -Reviewed-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index fd5dc8c6aa..94f74b54ae 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -658,7 +658,16 @@ out: - error_report("Bad device CVQ written length"); - } - vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status))); -- g_free(elem); -+ /* -+ * `elem` belongs to vhost_vdpa_net_handle_ctrl_avail() only when -+ * the function successfully forwards the CVQ command, indicated -+ * by a non-negative value of `dev_written`. Otherwise, it still -+ * belongs to SVQ. -+ * This function should only free the `elem` when it owns. -+ */ -+ if (dev_written >= 0) { -+ g_free(elem); -+ } - return dev_written < 0 ? dev_written : 0; - } - --- -2.27.0 - diff --git a/vdpa-Make-SVQ-vring-unmapping-return-void.patch b/vdpa-Make-SVQ-vring-unmapping-return-void.patch deleted file mode 100644 index 589898bd978c8ac58fea72bfcb8fed9830284841..0000000000000000000000000000000000000000 --- a/vdpa-Make-SVQ-vring-unmapping-return-void.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 39de24fc2b1cd16e8810b9e26cd23bb3896982a4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:20:06 +0200 -Subject: [PATCH] vdpa: Make SVQ vring unmapping return void -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Nothing actually reads the return value, but an error in cleaning some -entries could cause device stop to abort, making a restart impossible. -Better ignore explicitely the return value. - -Reported-by: Lei Yang -Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ") -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 32 ++++++++++---------------------- - 1 file changed, 10 insertions(+), 22 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 3be6988e9c..31c1b71498 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -886,7 +886,7 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, - /** - * Unmap a SVQ area in the device - */ --static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, -+static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, - const DMAMap *needle) - { - const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle); -@@ -895,38 +895,33 @@ static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, - - if (unlikely(!result)) { - error_report("Unable to find SVQ address to unmap"); -- return false; -+ return; - } - - size = ROUND_UP(result->size, qemu_real_host_page_size); - r = vhost_vdpa_dma_unmap(v, result->iova, size); - if (unlikely(r < 0)) { - error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r); -- return false; -+ return; - } - - vhost_iova_tree_remove(v->iova_tree, *result); -- return r == 0; - } - --static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, -+static void vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, - const VhostShadowVirtqueue *svq) - { - DMAMap needle = {}; - struct vhost_vdpa *v = dev->opaque; - struct vhost_vring_addr svq_addr; -- bool ok; - - vhost_svq_get_vring_addr(svq, &svq_addr); - - needle.translated_addr = svq_addr.desc_user_addr; -- ok = vhost_vdpa_svq_unmap_ring(v, &needle); -- if (unlikely(!ok)) { -- return false; -- } -+ vhost_vdpa_svq_unmap_ring(v, &needle); - - needle.translated_addr = svq_addr.used_user_addr; -- return vhost_vdpa_svq_unmap_ring(v, &needle); -+ vhost_vdpa_svq_unmap_ring(v, &needle); - } - - /** -@@ -1097,26 +1092,22 @@ err: - return false; - } - --static bool vhost_vdpa_svqs_stop(struct vhost_dev *dev) -+static void vhost_vdpa_svqs_stop(struct vhost_dev *dev) - { - struct vhost_vdpa *v = dev->opaque; - - if (!v->shadow_vqs) { -- return true; -+ return; - } - - for (unsigned i = 0; i < v->shadow_vqs->len; ++i) { - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -- bool ok = vhost_vdpa_svq_unmap_rings(dev, svq); -- if (unlikely(!ok)) { -- return false; -- } -+ vhost_vdpa_svq_unmap_rings(dev, svq); - } - - if (v->migration_blocker) { - migrate_del_blocker(v->migration_blocker); - } -- return true; - } - - static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) -@@ -1133,10 +1124,7 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) - } - vhost_vdpa_set_vring_ready(dev); - } else { -- ok = vhost_vdpa_svqs_stop(dev); -- if (unlikely(!ok)) { -- return -1; -- } -+ vhost_vdpa_svqs_stop(dev); - vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs); - } - --- -2.27.0 - diff --git a/vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch b/vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch deleted file mode 100644 index d9efa4973e7362c210a970d06dbcb3dc6ac79a8f..0000000000000000000000000000000000000000 --- a/vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch +++ /dev/null @@ -1,103 +0,0 @@ -From fdb55acf1833e6a35171b4e7e1c357f4b133e26f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 6 Sep 2022 17:07:14 +0200 -Subject: [PATCH] vdpa: Make VhostVDPAState cvq_cmd_in_buffer control ack type -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows to simplify the code. Rename to status while we're at it. - -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 23 ++++++++++++----------- - 1 file changed, 12 insertions(+), 11 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index b10a18aeb4..2700ef656f 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -34,7 +34,9 @@ typedef struct VhostVDPAState { - VHostNetState *vhost_net; - - /* Control commands shadow buffers */ -- void *cvq_cmd_out_buffer, *cvq_cmd_in_buffer; -+ void *cvq_cmd_out_buffer; -+ virtio_net_ctrl_ack *status; -+ - bool started; - } VhostVDPAState; - -@@ -166,7 +168,7 @@ static void vhost_vdpa_cleanup(NetClientState *nc) - } - - qemu_vfree(s->cvq_cmd_out_buffer); -- qemu_vfree(s->cvq_cmd_in_buffer); -+ qemu_vfree(s->status); - if (dev->vq_index + dev->nvqs == dev->vq_index_end) { - g_clear_pointer(&s->vhost_vdpa.iova_tree, vhost_iova_tree_delete); - } -@@ -318,7 +320,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc) - return r; - } - -- r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer, -+ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->status, - vhost_vdpa_net_cvq_cmd_page_len(), true); - if (unlikely(r < 0)) { - vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); -@@ -335,7 +337,7 @@ static void vhost_vdpa_net_cvq_stop(NetClientState *nc) - - if (s->vhost_vdpa.shadow_vqs_enabled) { - vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); -- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer); -+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->status); - } - } - -@@ -348,7 +350,7 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len, - .iov_len = out_len, - }; - const struct iovec in = { -- .iov_base = s->cvq_cmd_in_buffer, -+ .iov_base = s->status, - .iov_len = sizeof(virtio_net_ctrl_ack), - }; - VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0); -@@ -404,7 +406,7 @@ static int vhost_vdpa_net_load(NetClientState *nc) - return dev_written; - } - -- return *((virtio_net_ctrl_ack *)s->cvq_cmd_in_buffer) != VIRTIO_NET_OK; -+ return *s->status != VIRTIO_NET_OK; - } - - return 0; -@@ -499,8 +501,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - goto out; - } - -- memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status)); -- if (status != VIRTIO_NET_OK) { -+ if (*s->status != VIRTIO_NET_OK) { - return VIRTIO_NET_ERR; - } - -@@ -557,9 +558,9 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size, - vhost_vdpa_net_cvq_cmd_page_len()); - memset(s->cvq_cmd_out_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len()); -- s->cvq_cmd_in_buffer = qemu_memalign(qemu_real_host_page_size, -- vhost_vdpa_net_cvq_cmd_page_len()); -- memset(s->cvq_cmd_in_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len()); -+ s->status = qemu_memalign(qemu_real_host_page_size, -+ vhost_vdpa_net_cvq_cmd_page_len()); -+ memset(s->status, 0, vhost_vdpa_net_cvq_cmd_page_len()); - - s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops; - s->vhost_vdpa.shadow_vq_ops_opaque = s; --- -2.27.0 - diff --git a/vdpa-Make-ncs-autofree.patch b/vdpa-Make-ncs-autofree.patch deleted file mode 100644 index e2b8775f8fd136d35f5abca7f53fc76e7544c197..0000000000000000000000000000000000000000 --- a/vdpa-Make-ncs-autofree.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 1f1c2f74668cd1250cbd00b397dd59be92121314 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Feb 2022 20:34:15 +0100 -Subject: [PATCH] vdpa: Make ncs autofree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Simplifying memory management. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Reviewed-by: Stefano Garzarella -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20220214193415.1606752-2-eperezma@redhat.com> -Signed-off-by: Laurent Vivier -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 60b715aef1..9ba0f7bfca 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -271,7 +271,8 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - { - const NetdevVhostVDPAOptions *opts; - int vdpa_device_fd; -- NetClientState **ncs, *nc; -+ g_autofree NetClientState **ncs = NULL; -+ NetClientState *nc; - int queue_pairs, i, has_cvq = 0; - - assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); -@@ -309,7 +310,6 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - goto err; - } - -- g_free(ncs); - return 0; - - err: -@@ -317,7 +317,6 @@ err: - qemu_del_net_client(ncs[0]); - } - qemu_close(vdpa_device_fd); -- g_free(ncs); - - return -1; - } --- -2.27.0 - diff --git a/vdpa-Move-command-buffers-map-to-start-of-net-device.patch b/vdpa-Move-command-buffers-map-to-start-of-net-device.patch deleted file mode 100644 index 5b943d29176ebc67fe93c7ba35b63cbdb87b432a..0000000000000000000000000000000000000000 --- a/vdpa-Move-command-buffers-map-to-start-of-net-device.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 811a2e0b40724cc505141d4caf322030b83f86a3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:30:33 +0200 -Subject: [PATCH] vdpa: Move command buffers map to start of net device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -As this series will reuse them to restore the device state at the end of -a migration (or a device start), let's allocate only once at the device -start so we don't duplicate their map and unmap. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 123 ++++++++++++++++++++++------------------------- - 1 file changed, 58 insertions(+), 65 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 04cb08d418..882f5ee89c 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -271,29 +271,20 @@ static size_t vhost_vdpa_net_cvq_cmd_page_len(void) - return ROUND_UP(vhost_vdpa_net_cvq_cmd_len(), qemu_real_host_page_size); - } - --/** Copy and map a guest buffer. */ --static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, -- const struct iovec *out_data, -- size_t out_num, size_t data_len, void *buf, -- size_t *written, bool write) -+/** Map CVQ buffer. */ -+static int vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, void *buf, size_t size, -+ bool write) - { - DMAMap map = {}; - int r; - -- if (unlikely(!data_len)) { -- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid legnth of %s buffer\n", -- __func__, write ? "in" : "out"); -- return false; -- } -- -- *written = iov_to_buf(out_data, out_num, 0, buf, data_len); - map.translated_addr = (hwaddr)(uintptr_t)buf; -- map.size = vhost_vdpa_net_cvq_cmd_page_len() - 1; -+ map.size = size - 1; - map.perm = write ? IOMMU_RW : IOMMU_RO, - r = vhost_iova_tree_map_alloc(v->iova_tree, &map); - if (unlikely(r != IOVA_OK)) { - error_report("Cannot map injected element"); -- return false; -+ return r; - } - - r = vhost_vdpa_dma_map(v, map.iova, vhost_vdpa_net_cvq_cmd_page_len(), buf, -@@ -302,50 +293,58 @@ static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, - goto dma_map_err; - } - -- return true; -+ return 0; - - dma_map_err: - vhost_iova_tree_remove(v->iova_tree, map); -- return false; -+ return r; - } - --/** -- * Copy the guest element into a dedicated buffer suitable to be sent to NIC -- * -- * @iov: [0] is the out buffer, [1] is the in one -- */ --static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState *s, -- VirtQueueElement *elem, -- struct iovec *iov) -+static int vhost_vdpa_net_cvq_start(NetClientState *nc) - { -- size_t in_copied; -- bool ok; -+ VhostVDPAState *s; -+ int r; - -- iov[0].iov_base = s->cvq_cmd_out_buffer; -- ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, elem->out_sg, elem->out_num, -- vhost_vdpa_net_cvq_cmd_len(), iov[0].iov_base, -- &iov[0].iov_len, false); -- if (unlikely(!ok)) { -- return false; -+ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); -+ -+ s = DO_UPCAST(VhostVDPAState, nc, nc); -+ if (!s->vhost_vdpa.shadow_vqs_enabled) { -+ return 0; - } - -- iov[1].iov_base = s->cvq_cmd_in_buffer; -- ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, NULL, 0, -- sizeof(virtio_net_ctrl_ack), iov[1].iov_base, -- &in_copied, true); -- if (unlikely(!ok)) { -+ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer, -+ vhost_vdpa_net_cvq_cmd_page_len(), false); -+ if (unlikely(r < 0)) { -+ return r; -+ } -+ -+ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer, -+ vhost_vdpa_net_cvq_cmd_page_len(), true); -+ if (unlikely(r < 0)) { - vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); -- return false; - } - -- iov[1].iov_len = sizeof(virtio_net_ctrl_ack); -- return true; -+ return r; -+} -+ -+static void vhost_vdpa_net_cvq_stop(NetClientState *nc) -+{ -+ VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); -+ -+ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); -+ -+ if (s->vhost_vdpa.shadow_vqs_enabled) { -+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); -+ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer); -+ } - } - - static NetClientInfo net_vhost_vdpa_cvq_info = { - .type = NET_CLIENT_DRIVER_VHOST_VDPA, - .size = sizeof(VhostVDPAState), - .receive = vhost_vdpa_receive, -+ .start = vhost_vdpa_net_cvq_start, -+ .stop = vhost_vdpa_net_cvq_stop, - .cleanup = vhost_vdpa_cleanup, - .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, - .has_ufo = vhost_vdpa_has_ufo, -@@ -356,19 +355,17 @@ static NetClientInfo net_vhost_vdpa_cvq_info = { - * Do not forward commands not supported by SVQ. Otherwise, the device could - * accept it and qemu would not know how to update the device model. - */ --static bool vhost_vdpa_net_cvq_validate_cmd(const struct iovec *out, -- size_t out_num) -+static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len) - { - struct virtio_net_ctrl_hdr ctrl; -- size_t n; - -- n = iov_to_buf(out, out_num, 0, &ctrl, sizeof(ctrl)); -- if (unlikely(n < sizeof(ctrl))) { -+ if (unlikely(len < sizeof(ctrl))) { - qemu_log_mask(LOG_GUEST_ERROR, -- "%s: invalid legnth of out buffer %zu\n", __func__, n); -+ "%s: invalid legnth of out buffer %zu\n", __func__, len); - return false; - } - -+ memcpy(&ctrl, out_buf, sizeof(ctrl)); - switch (ctrl.class) { - case VIRTIO_NET_CTRL_MAC: - switch (ctrl.cmd) { -@@ -400,10 +397,14 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - VhostVDPAState *s = opaque; - size_t in_len, dev_written; - virtio_net_ctrl_ack status = VIRTIO_NET_ERR; -- /* out and in buffers sent to the device */ -- struct iovec dev_buffers[2] = { -- { .iov_base = s->cvq_cmd_out_buffer }, -- { .iov_base = s->cvq_cmd_in_buffer }, -+ /* Out buffer sent to both the vdpa device and the device model */ -+ struct iovec out = { -+ .iov_base = s->cvq_cmd_out_buffer, -+ }; -+ /* In buffer sent to the device */ -+ const struct iovec dev_in = { -+ .iov_base = s->cvq_cmd_in_buffer, -+ .iov_len = sizeof(virtio_net_ctrl_ack), - }; - /* in buffer used for device model */ - const struct iovec in = { -@@ -413,17 +414,15 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - int r = -EINVAL; - bool ok; - -- ok = vhost_vdpa_net_cvq_map_elem(s, elem, dev_buffers); -- if (unlikely(!ok)) { -- goto out; -- } -- -- ok = vhost_vdpa_net_cvq_validate_cmd(&dev_buffers[0], 1); -+ out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, -+ s->cvq_cmd_out_buffer, -+ vhost_vdpa_net_cvq_cmd_len()); -+ ok = vhost_vdpa_net_cvq_validate_cmd(s->cvq_cmd_out_buffer, out.iov_len); - if (unlikely(!ok)) { - goto out; - } - -- r = vhost_svq_add(svq, &dev_buffers[0], 1, &dev_buffers[1], 1, elem); -+ r = vhost_svq_add(svq, &out, 1, &dev_in, 1, elem); - if (unlikely(r != 0)) { - if (unlikely(r == -ENOSPC)) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n", -@@ -443,13 +442,13 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - goto out; - } - -- memcpy(&status, dev_buffers[1].iov_base, sizeof(status)); -+ memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status)); - if (status != VIRTIO_NET_OK) { - goto out; - } - - status = VIRTIO_NET_ERR; -- virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, dev_buffers, 1); -+ virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, &out, 1); - if (status != VIRTIO_NET_OK) { - error_report("Bad CVQ processing in model"); - } -@@ -462,12 +461,6 @@ out: - } - vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status))); - g_free(elem); -- if (dev_buffers[0].iov_base) { -- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[0].iov_base); -- } -- if (dev_buffers[1].iov_base) { -- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[1].iov_base); -- } - return r; - } - --- -2.27.0 - diff --git a/vdpa-Never-set-log_base-addr-if-SVQ-is-enabled.patch b/vdpa-Never-set-log_base-addr-if-SVQ-is-enabled.patch deleted file mode 100644 index 6778cdedec69f3291832cc0f7722ef7ee9390428..0000000000000000000000000000000000000000 --- a/vdpa-Never-set-log_base-addr-if-SVQ-is-enabled.patch +++ /dev/null @@ -1,36 +0,0 @@ -From b34bcf052293861e8b88a41dad194d0889c6692f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:53 +0100 -Subject: [PATCH] vdpa: Never set log_base addr if SVQ is enabled -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Setting the log address would make the device start reporting invalid -dirty memory because the SVQ vrings are located in qemu's memory. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 428137f654..840141321a 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1092,7 +1092,8 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) - static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base, - struct vhost_log *log) - { -- if (vhost_vdpa_one_time_request(dev)) { -+ struct vhost_vdpa *v = dev->opaque; -+ if (v->shadow_vqs_enabled || vhost_vdpa_one_time_request(dev)) { - return 0; - } - --- -2.27.0 - diff --git a/vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch b/vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch deleted file mode 100644 index be0cb96a1e6e4d7a7d2ae03d2b1da83d91f276ec..0000000000000000000000000000000000000000 --- a/vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch +++ /dev/null @@ -1,40 +0,0 @@ -From f52985fb819fbf8efb162a25096abb4c174b9f40 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:20:05 +0200 -Subject: [PATCH] vdpa: Remove SVQ vring from iova_tree at shutdown -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Although the device will be reset before usage, the right thing to do is -to clean it. - -Reported-by: Lei Yang -Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ") -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 0f640f670b..3be6988e9c 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -900,6 +900,12 @@ static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, - - size = ROUND_UP(result->size, qemu_real_host_page_size); - r = vhost_vdpa_dma_unmap(v, result->iova, size); -+ if (unlikely(r < 0)) { -+ error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r); -+ return false; -+ } -+ -+ vhost_iova_tree_remove(v->iova_tree, *result); - return r == 0; - } - --- -2.27.0 - diff --git a/vdpa-Remove-shadow-CVQ-command-check.patch b/vdpa-Remove-shadow-CVQ-command-check.patch deleted file mode 100644 index 90ef701b966ae62965a11d759621b2cb0c0a7420..0000000000000000000000000000000000000000 --- a/vdpa-Remove-shadow-CVQ-command-check.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 6cb9e17dcc07d6fc1467a585fb015991191a92da Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 20 Oct 2022 10:02:30 +0200 -Subject: [PATCH] vdpa: Remove shadow CVQ command check -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The guest will see undefined behavior if it issue not negotiate -commands, bit it is expected somehow. - -Simplify code deleting this check. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 48 ------------------------------------------------ - 1 file changed, 48 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index f4f6b8587f..c8c433002d 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -469,48 +469,6 @@ static NetClientInfo net_vhost_vdpa_cvq_info = { - .check_peer_type = vhost_vdpa_check_peer_type, - }; - --/** -- * Do not forward commands not supported by SVQ. Otherwise, the device could -- * accept it and qemu would not know how to update the device model. -- */ --static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len) --{ -- struct virtio_net_ctrl_hdr ctrl; -- -- if (unlikely(len < sizeof(ctrl))) { -- qemu_log_mask(LOG_GUEST_ERROR, -- "%s: invalid legnth of out buffer %zu\n", __func__, len); -- return false; -- } -- -- memcpy(&ctrl, out_buf, sizeof(ctrl)); -- switch (ctrl.class) { -- case VIRTIO_NET_CTRL_MAC: -- switch (ctrl.cmd) { -- case VIRTIO_NET_CTRL_MAC_ADDR_SET: -- return true; -- default: -- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mac cmd %u\n", -- __func__, ctrl.cmd); -- }; -- break; -- case VIRTIO_NET_CTRL_MQ: -- switch (ctrl.cmd) { -- case VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET: -- return true; -- default: -- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mq cmd %u\n", -- __func__, ctrl.cmd); -- }; -- break; -- default: -- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid control class %u\n", -- __func__, ctrl.class); -- }; -- -- return false; --} -- - /** - * Validate and copy control virtqueue commands. - * -@@ -534,16 +492,10 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - .iov_len = sizeof(status), - }; - ssize_t dev_written = -EINVAL; -- bool ok; - - out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, - s->cvq_cmd_out_buffer, - vhost_vdpa_net_cvq_cmd_len()); -- ok = vhost_vdpa_net_cvq_validate_cmd(s->cvq_cmd_out_buffer, out.iov_len); -- if (unlikely(!ok)) { -- goto out; -- } -- - dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); - if (unlikely(dev_written < 0)) { - goto out; --- -2.27.0 - diff --git a/vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_-new.patch b/vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_-new.patch deleted file mode 100644 index 6471c52fbb90f0a5442e4831e1350a060d0858da..0000000000000000000000000000000000000000 --- a/vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_-new.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 8f2a04c1b5790f6e00160920c3bc88801b5afc16 Mon Sep 17 00:00:00 2001 -From: Hawkins Jiawei -Date: Tue, 4 Jul 2023 11:34:34 +0800 -Subject: [PATCH] vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in - _load_mq() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -According to VirtIO standard, "The class, command and -command-specific-data are set by the driver, -and the device sets the ack byte. -There is little it can do except issue a diagnostic -if ack is not VIRTIO_NET_OK." - -Therefore, QEMU should stop sending the queued SVQ commands and -cancel the device startup if the device's ack is not VIRTIO_NET_OK. - -Yet the problem is that, vhost_vdpa_net_load_mq() returns 1 based on -`*s->status != VIRTIO_NET_OK` when the device's ack is VIRTIO_NET_ERR. -As a result, net->nc->info->load() also returns 1, this makes -vhost_net_start_one() incorrectly assume the device state is -successfully loaded by vhost_vdpa_net_load() and return 0, instead of -goto `fail` label to cancel the device startup, as vhost_net_start_one() -only cancels the device startup when net->nc->info->load() returns a -negative value. - -This patch fixes this problem by returning -EIO when the device's -ack is not VIRTIO_NET_OK. - -Fixes: f64c7cda69 ("vdpa: Add vhost_vdpa_net_load_mq") -Signed-off-by: Hawkins Jiawei -Acked-by: Jason Wang -Acked-by: Eugenio Pérez -Message-Id: -Tested-by: Lei Yang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 9af9f6554e..8192045735 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -553,8 +553,11 @@ static int vhost_vdpa_net_load_mq(VhostVDPAState *s, - if (unlikely(dev_written < 0)) { - return dev_written; - } -+ if (*s->status != VIRTIO_NET_OK) { -+ return -EIO; -+ } - -- return *s->status != VIRTIO_NET_OK; -+ return 0; - } - - static int vhost_vdpa_net_load(NetClientState *nc) --- -2.27.0 - diff --git a/vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_.patch b/vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_.patch deleted file mode 100644 index f457ca3a3a411bf462e12b49f7b521cea965c5e8..0000000000000000000000000000000000000000 --- a/vdpa-Return-EIO-if-device-ack-is-VIRTIO_NET_ERR-in-_.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 1c9d6dde6fabf6c1f6a4aeb388921a83279d3071 Mon Sep 17 00:00:00 2001 -From: Hawkins Jiawei -Date: Tue, 4 Jul 2023 11:34:33 +0800 -Subject: [PATCH] vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in - _load_mac() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -According to VirtIO standard, "The class, command and -command-specific-data are set by the driver, -and the device sets the ack byte. -There is little it can do except issue a diagnostic -if ack is not VIRTIO_NET_OK." - -Therefore, QEMU should stop sending the queued SVQ commands and -cancel the device startup if the device's ack is not VIRTIO_NET_OK. - -Yet the problem is that, vhost_vdpa_net_load_mac() returns 1 based on -`*s->status != VIRTIO_NET_OK` when the device's ack is VIRTIO_NET_ERR. -As a result, net->nc->info->load() also returns 1, this makes -vhost_net_start_one() incorrectly assume the device state is -successfully loaded by vhost_vdpa_net_load() and return 0, instead of -goto `fail` label to cancel the device startup, as vhost_net_start_one() -only cancels the device startup when net->nc->info->load() returns a -negative value. - -This patch fixes this problem by returning -EIO when the device's -ack is not VIRTIO_NET_OK. - -Fixes: f73c0c43ac ("vdpa: extract vhost_vdpa_net_load_mac from vhost_vdpa_net_load") -Signed-off-by: Hawkins Jiawei -Acked-by: Jason Wang -Acked-by: Eugenio Pérez -Message-Id: -Tested-by: Lei Yang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index afca8740bc..9af9f6554e 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -527,8 +527,9 @@ static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n) - if (unlikely(dev_written < 0)) { - return dev_written; - } -- -- return *s->status != VIRTIO_NET_OK; -+ if (*s->status != VIRTIO_NET_OK) { -+ return -EIO; -+ } - } - - return 0; --- -2.27.0 - diff --git a/vdpa-Skip-the-maps-not-in-the-iova-tree.patch b/vdpa-Skip-the-maps-not-in-the-iova-tree.patch deleted file mode 100644 index 17e13206247600b5c252e7284abe205c2c831029..0000000000000000000000000000000000000000 --- a/vdpa-Skip-the-maps-not-in-the-iova-tree.patch +++ /dev/null @@ -1,39 +0,0 @@ -From a498bc3ae687778dad2f8161ff17532432df0c1c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:20:02 +0200 -Subject: [PATCH] vdpa: Skip the maps not in the iova tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Next patch will skip the registering of dma maps that the vdpa device -rejects in the iova tree. We need to consider that here or we cause a -SIGSEGV accessing result. - -Reported-by: Lei Yang -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index d0cf7a0745..c551665f5d 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -291,6 +291,10 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, - }; - - result = vhost_iova_tree_find_iova(v->iova_tree, &mem_region); -+ if (!result) { -+ /* The memory listener map wasn't mapped */ -+ return; -+ } - iova = result->iova; - vhost_iova_tree_remove(v->iova_tree, result); - } --- -2.27.0 - diff --git a/vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch b/vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch deleted file mode 100644 index 606084cd679eae428b7b3f8e53e96d4c678aa7dd..0000000000000000000000000000000000000000 --- a/vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 1c3e4f7326031d0b689821f655a4352bb746a405 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:20:08 +0200 -Subject: [PATCH] vdpa: Use ring hwaddr at vhost_vdpa_svq_unmap_ring -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reduce code duplication. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 31c1b71498..d7bdc0f37c 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -886,10 +886,12 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, - /** - * Unmap a SVQ area in the device - */ --static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, -- const DMAMap *needle) -+static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr addr) - { -- const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle); -+ const DMAMap needle = { -+ .translated_addr = addr, -+ }; -+ const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, &needle); - hwaddr size; - int r; - -@@ -911,17 +913,14 @@ static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, - static void vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, - const VhostShadowVirtqueue *svq) - { -- DMAMap needle = {}; - struct vhost_vdpa *v = dev->opaque; - struct vhost_vring_addr svq_addr; - - vhost_svq_get_vring_addr(svq, &svq_addr); - -- needle.translated_addr = svq_addr.desc_user_addr; -- vhost_vdpa_svq_unmap_ring(v, &needle); -+ vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr); - -- needle.translated_addr = svq_addr.used_user_addr; -- vhost_vdpa_svq_unmap_ring(v, &needle); -+ vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr); - } - - /** -@@ -999,7 +998,7 @@ static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev, - ok = vhost_vdpa_svq_map_ring(v, &device_region, errp); - if (unlikely(!ok)) { - error_prepend(errp, "Cannot create vq device region: "); -- vhost_vdpa_svq_unmap_ring(v, &driver_region); -+ vhost_vdpa_svq_unmap_ring(v, driver_region.translated_addr); - } - addr->used_user_addr = device_region.iova; - --- -2.27.0 - diff --git a/vdpa-adapt-vhost_ops-callbacks-to-svq.patch b/vdpa-adapt-vhost_ops-callbacks-to-svq.patch deleted file mode 100644 index 914e13a7d9873dfb686646c7355ba4d5fd74ce54..0000000000000000000000000000000000000000 --- a/vdpa-adapt-vhost_ops-callbacks-to-svq.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 1ae2ad1afcb032dc933104da5ad922173961caf8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:46 +0100 -Subject: [PATCH] vdpa: adapt vhost_ops callbacks to svq -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -First half of the buffers forwarding part, preparing vhost-vdpa -callbacks to SVQ to offer it. QEMU cannot enable it at this moment, so -this is effectively dead code at the moment, but it helps to reduce -patch size. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 48 ++++++++++++++++++++++++++++++++++++------ - 1 file changed, 41 insertions(+), 7 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 8ee63933a8..2f0e6a9bef 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -735,6 +735,13 @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config, - return ret; - } - -+static int vhost_vdpa_set_dev_vring_base(struct vhost_dev *dev, -+ struct vhost_vring_state *ring) -+{ -+ trace_vhost_vdpa_set_vring_base(dev, ring->index, ring->num); -+ return vhost_vdpa_call(dev, VHOST_SET_VRING_BASE, ring); -+} -+ - static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev, - struct vhost_vring_file *file) - { -@@ -749,6 +756,18 @@ static int vhost_vdpa_set_vring_dev_call(struct vhost_dev *dev, - return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file); - } - -+static int vhost_vdpa_set_vring_dev_addr(struct vhost_dev *dev, -+ struct vhost_vring_addr *addr) -+{ -+ trace_vhost_vdpa_set_vring_addr(dev, addr->index, addr->flags, -+ addr->desc_user_addr, addr->used_user_addr, -+ addr->avail_user_addr, -+ addr->log_guest_addr); -+ -+ return vhost_vdpa_call(dev, VHOST_SET_VRING_ADDR, addr); -+ -+} -+ - /** - * Set the shadow virtqueue descriptors to the device - * -@@ -858,11 +877,17 @@ static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base, - static int vhost_vdpa_set_vring_addr(struct vhost_dev *dev, - struct vhost_vring_addr *addr) - { -- trace_vhost_vdpa_set_vring_addr(dev, addr->index, addr->flags, -- addr->desc_user_addr, addr->used_user_addr, -- addr->avail_user_addr, -- addr->log_guest_addr); -- return vhost_vdpa_call(dev, VHOST_SET_VRING_ADDR, addr); -+ struct vhost_vdpa *v = dev->opaque; -+ -+ if (v->shadow_vqs_enabled) { -+ /* -+ * Device vring addr was set at device start. SVQ base is handled by -+ * VirtQueue code. -+ */ -+ return 0; -+ } -+ -+ return vhost_vdpa_set_vring_dev_addr(dev, addr); - } - - static int vhost_vdpa_set_vring_num(struct vhost_dev *dev, -@@ -875,8 +900,17 @@ static int vhost_vdpa_set_vring_num(struct vhost_dev *dev, - static int vhost_vdpa_set_vring_base(struct vhost_dev *dev, - struct vhost_vring_state *ring) - { -- trace_vhost_vdpa_set_vring_base(dev, ring->index, ring->num); -- return vhost_vdpa_call(dev, VHOST_SET_VRING_BASE, ring); -+ struct vhost_vdpa *v = dev->opaque; -+ -+ if (v->shadow_vqs_enabled) { -+ /* -+ * Device vring base was set at device start. SVQ base is handled by -+ * VirtQueue code. -+ */ -+ return 0; -+ } -+ -+ return vhost_vdpa_set_dev_vring_base(dev, ring); - } - - static int vhost_vdpa_get_vring_base(struct vhost_dev *dev, --- -2.27.0 - diff --git a/vdpa-add-asid-parameter-to-vhost_vdpa_dma_map-unmap.patch b/vdpa-add-asid-parameter-to-vhost_vdpa_dma_map-unmap.patch deleted file mode 100644 index 0e6774f32e49419894ac807c6207003873990fd3..0000000000000000000000000000000000000000 --- a/vdpa-add-asid-parameter-to-vhost_vdpa_dma_map-unmap.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 657f5e7b200bec7b124ca5e2cf4d8e1b721cbfde Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:41 +0100 -Subject: [PATCH] vdpa: add asid parameter to vhost_vdpa_dma_map/unmap -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -So the caller can choose which ASID is destined. - -No need to update the batch functions as they will always be called from -memory listener updates at the moment. Memory listener updates will -always update ASID 0, as it's the passthrough ASID. - -All vhost devices's ASID are 0 at this moment. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-10-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/trace-events | 4 +-- - hw/virtio/vhost-vdpa.c | 36 ++++++++++++++------ - include/hw/virtio/vhost-vdpa.h | 14 ++++++-- - include/standard-headers/linux/vhost_types.h | 2 +- - net/vhost-vdpa.c | 6 ++-- - 5 files changed, 42 insertions(+), 20 deletions(-) - -diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events -index 35d4c00e59..edbbbeb621 100644 ---- a/hw/virtio/trace-events -+++ b/hw/virtio/trace-events -@@ -29,8 +29,8 @@ vhost_user_read(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32"" - vhost_user_write(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32"" - - # vhost-vdpa.c --vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8 --vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8 -+vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint32_t asid, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" asid: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8 -+vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint32_t asid, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" asid: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8 - vhost_vdpa_listener_begin_batch(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8 - vhost_vdpa_listener_commit(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8 - vhost_vdpa_listener_region_add(void *vdpa, uint64_t iova, uint64_t llend, void *vaddr, bool readonly) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64" vaddr: %p read-only: %d" -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 450b5effd2..f4a0878e34 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -74,22 +74,28 @@ static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section, - return false; - } - --int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size, -- void *vaddr, bool readonly) -+/* -+ * The caller must set asid = 0 if the device does not support asid. -+ * This is not an ABI break since it is set to 0 by the initializer anyway. -+ */ -+int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, -+ hwaddr size, void *vaddr, bool readonly) - { - struct vhost_msg_v2 msg = {}; - int fd = v->device_fd; - int ret = 0; - - msg.type = v->msg_type; -+ msg.asid = asid; - msg.iotlb.iova = iova; - msg.iotlb.size = size; - msg.iotlb.uaddr = (uint64_t)(uintptr_t)vaddr; - msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW; - msg.iotlb.type = VHOST_IOTLB_UPDATE; - -- trace_vhost_vdpa_dma_map(v, fd, msg.type, msg.iotlb.iova, msg.iotlb.size, -- msg.iotlb.uaddr, msg.iotlb.perm, msg.iotlb.type); -+ trace_vhost_vdpa_dma_map(v, fd, msg.type, msg.asid, msg.iotlb.iova, -+ msg.iotlb.size, msg.iotlb.uaddr, msg.iotlb.perm, -+ msg.iotlb.type); - - if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) { - error_report("failed to write, fd=%d, errno=%d (%s)", -@@ -100,18 +106,24 @@ int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size, - return ret; - } - --int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size) -+/* -+ * The caller must set asid = 0 if the device does not support asid. -+ * This is not an ABI break since it is set to 0 by the initializer anyway. -+ */ -+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, -+ hwaddr size) - { - struct vhost_msg_v2 msg = {}; - int fd = v->device_fd; - int ret = 0; - - msg.type = v->msg_type; -+ msg.asid = asid; - msg.iotlb.iova = iova; - msg.iotlb.size = size; - msg.iotlb.type = VHOST_IOTLB_INVALIDATE; - -- trace_vhost_vdpa_dma_unmap(v, fd, msg.type, msg.iotlb.iova, -+ trace_vhost_vdpa_dma_unmap(v, fd, msg.type, msg.asid, msg.iotlb.iova, - msg.iotlb.size, msg.iotlb.type); - - if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) { -@@ -231,8 +243,8 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, - } - - vhost_vdpa_iotlb_batch_begin_once(v); -- ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize), -- vaddr, section->readonly); -+ ret = vhost_vdpa_dma_map(v, VHOST_VDPA_GUEST_PA_ASID, iova, -+ int128_get64(llsize), vaddr, section->readonly); - if (ret) { - error_report("vhost vdpa map fail!"); - goto fail_map; -@@ -305,7 +317,8 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, - vhost_iova_tree_remove(v->iova_tree, *result); - } - vhost_vdpa_iotlb_batch_begin_once(v); -- ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize)); -+ ret = vhost_vdpa_dma_unmap(v, VHOST_VDPA_GUEST_PA_ASID, iova, -+ int128_get64(llsize)); - if (ret) { - error_report("vhost_vdpa dma unmap error!"); - } -@@ -872,7 +885,7 @@ static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr addr) - } - - size = ROUND_UP(result->size, qemu_real_host_page_size); -- r = vhost_vdpa_dma_unmap(v, result->iova, size); -+ r = vhost_vdpa_dma_unmap(v, v->address_space_id, result->iova, size); - if (unlikely(r < 0)) { - error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r); - return; -@@ -912,7 +925,8 @@ static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle, - return false; - } - -- r = vhost_vdpa_dma_map(v, needle->iova, needle->size + 1, -+ r = vhost_vdpa_dma_map(v, v->address_space_id, needle->iova, -+ needle->size + 1, - (void *)(uintptr_t)needle->translated_addr, - needle->perm == IOMMU_RO); - if (unlikely(r != 0)) { -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index 1111d85643..e57dfa1fd1 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -19,6 +19,12 @@ - #include "hw/virtio/virtio.h" - #include "standard-headers/linux/vhost_types.h" - -+/* -+ * ASID dedicated to map guest's addresses. If SVQ is disabled it maps GPA to -+ * qemu's IOVA. If SVQ is enabled it maps also the SVQ vring here -+ */ -+#define VHOST_VDPA_GUEST_PA_ASID 0 -+ - typedef struct VhostVDPAHostNotifier { - MemoryRegion mr; - void *addr; -@@ -29,6 +35,7 @@ typedef struct vhost_vdpa { - int index; - uint32_t msg_type; - bool iotlb_batch_begin_sent; -+ uint32_t address_space_id; - MemoryListener listener; - struct vhost_vdpa_iova_range iova_range; - uint64_t acked_features; -@@ -42,8 +49,9 @@ typedef struct vhost_vdpa { - VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; - } VhostVDPA; - --int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size, -- void *vaddr, bool readonly); --int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size); -+int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, -+ hwaddr size, void *vaddr, bool readonly); -+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, -+ hwaddr size); - - #endif -diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h -index 0bd2684a2a..fa267e39d4 100644 ---- a/include/standard-headers/linux/vhost_types.h -+++ b/include/standard-headers/linux/vhost_types.h -@@ -87,7 +87,7 @@ struct vhost_msg { - - struct vhost_msg_v2 { - uint32_t type; -- uint32_t reserved; -+ uint32_t asid; - union { - struct vhost_iotlb_msg iotlb; - uint8_t padding[64]; -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index e250d34462..cb1cc2523d 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -266,7 +266,7 @@ static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr) - return; - } - -- r = vhost_vdpa_dma_unmap(v, map->iova, map->size + 1); -+ r = vhost_vdpa_dma_unmap(v, v->address_space_id, map->iova, map->size + 1); - if (unlikely(r != 0)) { - error_report("Device cannot unmap: %s(%d)", g_strerror(r), r); - } -@@ -306,8 +306,8 @@ static int vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, void *buf, size_t size, - return r; - } - -- r = vhost_vdpa_dma_map(v, map.iova, vhost_vdpa_net_cvq_cmd_page_len(), buf, -- !write); -+ r = vhost_vdpa_dma_map(v, v->address_space_id, map.iova, -+ vhost_vdpa_net_cvq_cmd_page_len(), buf, !write); - if (unlikely(r < 0)) { - goto dma_map_err; - } --- -2.27.0 - diff --git a/vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch b/vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch deleted file mode 100644 index f06ea91d973931a3b5bc516453816c51f0664c73..0000000000000000000000000000000000000000 --- a/vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch +++ /dev/null @@ -1,53 +0,0 @@ -From a5717856457e72575a32dfc8e28ec6ba6dcf6d59 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:30:32 +0200 -Subject: [PATCH] vdpa: add net_vhost_vdpa_cvq_info NetClientInfo -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Next patches will add a new info callback to restore NIC status through -CVQ. Since only the CVQ vhost device is needed, create it with a new -NetClientInfo. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 8cfd086639..04cb08d418 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -342,6 +342,16 @@ static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState *s, - return true; - } - -+static NetClientInfo net_vhost_vdpa_cvq_info = { -+ .type = NET_CLIENT_DRIVER_VHOST_VDPA, -+ .size = sizeof(VhostVDPAState), -+ .receive = vhost_vdpa_receive, -+ .cleanup = vhost_vdpa_cleanup, -+ .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, -+ .has_ufo = vhost_vdpa_has_ufo, -+ .check_peer_type = vhost_vdpa_check_peer_type, -+}; -+ - /** - * Do not forward commands not supported by SVQ. Otherwise, the device could - * accept it and qemu would not know how to update the device model. -@@ -483,7 +493,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, - name); - } else { -- nc = qemu_new_net_control_client(&net_vhost_vdpa_info, peer, -+ nc = qemu_new_net_control_client(&net_vhost_vdpa_cvq_info, peer, - device, name); - } - snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA); --- -2.27.0 - diff --git a/vdpa-add-shadow_data-to-vhost_vdpa.patch b/vdpa-add-shadow_data-to-vhost_vdpa.patch deleted file mode 100644 index 6c457064f957298fb9263cd62cba4875d0019df4..0000000000000000000000000000000000000000 --- a/vdpa-add-shadow_data-to-vhost_vdpa.patch +++ /dev/null @@ -1,86 +0,0 @@ -From e64b1a8253b9161e16b0a7f6c3beb77fb854660d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:43 +0100 -Subject: [PATCH] vdpa: add shadow_data to vhost_vdpa -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The memory listener that thells the device how to convert GPA to qemu's -va is registered against CVQ vhost_vdpa. memory listener translations -are always ASID 0, CVQ ones are ASID 1 if supported. - -Let's tell the listener if it needs to register them on iova tree or -not. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-12-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 6 +++--- - include/hw/virtio/vhost-vdpa.h | 2 ++ - net/vhost-vdpa.c | 1 + - 3 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index f4a0878e34..6d0d85b733 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -226,7 +226,7 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, - vaddr, section->readonly); - - llsize = int128_sub(llend, int128_make64(iova)); -- if (v->shadow_vqs_enabled) { -+ if (v->shadow_data) { - int r; - - mem_region.translated_addr = (hwaddr)(uintptr_t)vaddr, -@@ -253,7 +253,7 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, - return; - - fail_map: -- if (v->shadow_vqs_enabled) { -+ if (v->shadow_data) { - vhost_iova_tree_remove(v->iova_tree, mem_region); - } - -@@ -298,7 +298,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, - - llsize = int128_sub(llend, int128_make64(iova)); - -- if (v->shadow_vqs_enabled) { -+ if (v->shadow_data) { - const DMAMap *result; - const void *vaddr = memory_region_get_ram_ptr(section->mr) + - section->offset_within_region + -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index e57dfa1fd1..45b969a311 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -40,6 +40,8 @@ typedef struct vhost_vdpa { - struct vhost_vdpa_iova_range iova_range; - uint64_t acked_features; - bool shadow_vqs_enabled; -+ /* Vdpa must send shadow addresses as IOTLB key for data queues, not GPA */ -+ bool shadow_data; - /* IOVA mapping used by the Shadow Virtqueue */ - VhostIOVATree *iova_tree; - GPtrArray *shadow_vqs; -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 7adba2c2b6..21fb89bb6b 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -580,6 +580,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - s->always_svq = svq; - s->vhost_vdpa.shadow_vqs_enabled = svq; - s->vhost_vdpa.iova_range = iova_range; -+ s->vhost_vdpa.shadow_data = svq; - s->vhost_vdpa.iova_tree = iova_tree; - if (!is_datapath) { - s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size, --- -2.27.0 - diff --git a/vdpa-add-vdpa-dev-pci-support.patch b/vdpa-add-vdpa-dev-pci-support.patch deleted file mode 100644 index 90eaa55d68fbfa7a63581cd09c2925c68c7ded92..0000000000000000000000000000000000000000 --- a/vdpa-add-vdpa-dev-pci-support.patch +++ /dev/null @@ -1,141 +0,0 @@ -From e422f956fa13298c25ac645d9d822d3ca92f8e31 Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Sat, 12 Nov 2022 22:40:11 +0800 -Subject: [PATCH 4/7] vdpa: add vdpa-dev-pci support - -Supports vdpa-dev-pci, we can use the device as follow: - --device vhost-vdpa-device-pci,vhostdev=/dev/vhost-vdpa-X - -Reviewed-by: Stefano Garzarella -Acked-by: Jason Wang -Signed-off-by: Longpeng ---- - hw/virtio/meson.build | 1 + - hw/virtio/vdpa-dev-pci.c | 102 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 103 insertions(+) - create mode 100644 hw/virtio/vdpa-dev-pci.c - -diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build -index 289e955478..8e8943e20b 100644 ---- a/hw/virtio/meson.build -+++ b/hw/virtio/meson.build -@@ -50,6 +50,7 @@ virtio_pci_ss.add(when: 'CONFIG_VIRTIO_SERIAL', if_true: files('virtio-serial-pc - virtio_pci_ss.add(when: 'CONFIG_VIRTIO_PMEM', if_true: files('virtio-pmem-pci.c')) - virtio_pci_ss.add(when: 'CONFIG_VIRTIO_IOMMU', if_true: files('virtio-iommu-pci.c')) - virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem-pci.c')) -+virtio_pci_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev-pci.c')) - - virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI', if_true: virtio_pci_ss) - -diff --git a/hw/virtio/vdpa-dev-pci.c b/hw/virtio/vdpa-dev-pci.c -new file mode 100644 -index 0000000000..5446e6b393 ---- /dev/null -+++ b/hw/virtio/vdpa-dev-pci.c -@@ -0,0 +1,102 @@ -+/* -+ * Vhost Vdpa Device PCI Bindings -+ * -+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved. -+ * -+ * Authors: -+ * Longpeng -+ * -+ * Largely based on the "vhost-user-blk-pci.c" and "vhost-user-blk.c" -+ * implemented by: -+ * Changpeng Liu -+ * -+ * This work is licensed under the terms of the GNU LGPL, version 2 or later. -+ * See the COPYING.LIB file in the top-level directory. -+ */ -+#include "qemu/osdep.h" -+#include -+#include -+#include "hw/virtio/virtio.h" -+#include "hw/virtio/vdpa-dev.h" -+#include "hw/pci/pci.h" -+#include "hw/qdev-properties.h" -+#include "qapi/error.h" -+#include "qemu/error-report.h" -+#include "qemu/module.h" -+#include "hw/virtio/virtio-pci.h" -+#include "qom/object.h" -+ -+ -+typedef struct VhostVdpaDevicePCI VhostVdpaDevicePCI; -+ -+#define TYPE_VHOST_VDPA_DEVICE_PCI "vhost-vdpa-device-pci-base" -+DECLARE_INSTANCE_CHECKER(VhostVdpaDevicePCI, VHOST_VDPA_DEVICE_PCI, -+ TYPE_VHOST_VDPA_DEVICE_PCI) -+ -+struct VhostVdpaDevicePCI { -+ VirtIOPCIProxy parent_obj; -+ VhostVdpaDevice vdev; -+}; -+ -+static void vhost_vdpa_device_pci_instance_init(Object *obj) -+{ -+ VhostVdpaDevicePCI *dev = VHOST_VDPA_DEVICE_PCI(obj); -+ -+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), -+ TYPE_VHOST_VDPA_DEVICE); -+ object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev), -+ "bootindex"); -+} -+ -+static Property vhost_vdpa_device_pci_properties[] = { -+ DEFINE_PROP_END_OF_LIST(), -+}; -+ -+static int vhost_vdpa_device_pci_post_init(VhostVdpaDevice *v, Error **errp) -+{ -+ VhostVdpaDevicePCI *dev = container_of(v, VhostVdpaDevicePCI, vdev); -+ VirtIOPCIProxy *vpci_dev = &dev->parent_obj; -+ -+ vpci_dev->class_code = virtio_pci_get_class_id(v->vdev_id); -+ vpci_dev->trans_devid = virtio_pci_get_trans_devid(v->vdev_id); -+ /* one for config vector */ -+ vpci_dev->nvectors = v->num_queues + 1; -+ -+ return 0; -+} -+ -+static void -+vhost_vdpa_device_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) -+{ -+ VhostVdpaDevicePCI *dev = VHOST_VDPA_DEVICE_PCI(vpci_dev); -+ -+ dev->vdev.post_init = vhost_vdpa_device_pci_post_init; -+ qdev_realize(DEVICE(&dev->vdev), BUS(&vpci_dev->bus), errp); -+} -+ -+static void vhost_vdpa_device_pci_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); -+ -+ set_bit(DEVICE_CATEGORY_MISC, dc->categories); -+ device_class_set_props(dc, vhost_vdpa_device_pci_properties); -+ k->realize = vhost_vdpa_device_pci_realize; -+} -+ -+static const VirtioPCIDeviceTypeInfo vhost_vdpa_device_pci_info = { -+ .base_name = TYPE_VHOST_VDPA_DEVICE_PCI, -+ .generic_name = "vhost-vdpa-device-pci", -+ .transitional_name = "vhost-vdpa-device-pci-transitional", -+ .non_transitional_name = "vhost-vdpa-device-pci-non-transitional", -+ .instance_size = sizeof(VhostVdpaDevicePCI), -+ .instance_init = vhost_vdpa_device_pci_instance_init, -+ .class_init = vhost_vdpa_device_pci_class_init, -+}; -+ -+static void vhost_vdpa_device_pci_register(void) -+{ -+ virtio_pci_types_register(&vhost_vdpa_device_pci_info); -+} -+ -+type_init(vhost_vdpa_device_pci_register); --- -2.27.0 - diff --git a/vdpa-add-vdpa-dev-support.patch b/vdpa-add-vdpa-dev-support.patch deleted file mode 100644 index b42b54b7db8df2a1d0275c5061d97ac2606dff1b..0000000000000000000000000000000000000000 --- a/vdpa-add-vdpa-dev-support.patch +++ /dev/null @@ -1,481 +0,0 @@ -From 813ab05c3e508a702457236abd40e8256312a499 Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Sat, 12 Nov 2022 22:40:10 +0800 -Subject: [PATCH 3/7] vdpa: add vdpa-dev support - -Supports vdpa-dev, we can use the deivce directly: - --M microvm -m 512m -smp 2 -kernel ... -initrd ... -device \ -vhost-vdpa-device,vhostdev=/dev/vhost-vdpa-x - -Reviewed-by: Stefano Garzarella -Acked-by: Jason Wang -Signed-off-by: Longpeng ---- - hw/virtio/Kconfig | 5 + - hw/virtio/meson.build | 1 + - hw/virtio/vdpa-dev.c | 376 +++++++++++++++++++++++++++++++++++ - include/hw/virtio/vdpa-dev.h | 43 ++++ - 4 files changed, 425 insertions(+) - create mode 100644 hw/virtio/vdpa-dev.c - create mode 100644 include/hw/virtio/vdpa-dev.h - -diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig -index c144d42f9b..724eb58a32 100644 ---- a/hw/virtio/Kconfig -+++ b/hw/virtio/Kconfig -@@ -68,3 +68,8 @@ config VHOST_USER_RNG - bool - default y - depends on VIRTIO && VHOST_USER -+ -+config VHOST_VDPA_DEV -+ bool -+ default y -+ depends on VIRTIO && VHOST_VDPA && LINUX -diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build -index 521f7d64a8..289e955478 100644 ---- a/hw/virtio/meson.build -+++ b/hw/virtio/meson.build -@@ -29,6 +29,7 @@ virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: files('vhost-user-i2c.c')) - virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_I2C'], if_true: files('vhost-user-i2c-pci.c')) - virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c')) - virtio_ss.add(when: ['CONFIG_VHOST_USER_RNG', 'CONFIG_VIRTIO_PCI'], if_true: files('vhost-user-rng-pci.c')) -+virtio_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev.c')) - - virtio_pci_ss = ss.source_set() - virtio_pci_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock-pci.c')) -diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c -new file mode 100644 -index 0000000000..42ab74c255 ---- /dev/null -+++ b/hw/virtio/vdpa-dev.c -@@ -0,0 +1,376 @@ -+/* -+ * Vhost Vdpa Device -+ * -+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved. -+ * -+ * Authors: -+ * Longpeng -+ * -+ * Largely based on the "vhost-user-blk-pci.c" and "vhost-user-blk.c" -+ * implemented by: -+ * Changpeng Liu -+ * -+ * This work is licensed under the terms of the GNU LGPL, version 2 or later. -+ * See the COPYING.LIB file in the top-level directory. -+ */ -+#include "qemu/osdep.h" -+#include -+#include -+#include "qapi/error.h" -+#include "qemu/error-report.h" -+#include "qemu/cutils.h" -+#include "hw/qdev-core.h" -+#include "hw/qdev-properties.h" -+#include "hw/qdev-properties-system.h" -+#include "hw/virtio/vhost.h" -+#include "hw/virtio/virtio.h" -+#include "hw/virtio/virtio-bus.h" -+#include "hw/virtio/virtio-access.h" -+#include "hw/virtio/vdpa-dev.h" -+#include "sysemu/sysemu.h" -+#include "sysemu/runstate.h" -+ -+static void -+vhost_vdpa_device_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq) -+{ -+ /* Nothing to do */ -+} -+ -+static uint32_t -+vhost_vdpa_device_get_u32(int fd, unsigned long int cmd, Error **errp) -+{ -+ uint32_t val = (uint32_t)-1; -+ -+ if (ioctl(fd, cmd, &val) < 0) { -+ error_setg(errp, "vhost-vdpa-device: cmd 0x%lx failed: %s", -+ cmd, strerror(errno)); -+ } -+ -+ return val; -+} -+ -+static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(dev); -+ VhostVdpaDevice *v = VHOST_VDPA_DEVICE(vdev); -+ uint16_t max_queue_size; -+ struct vhost_virtqueue *vqs; -+ int i, ret; -+ -+ if (!v->vhostdev) { -+ error_setg(errp, "vhost-vdpa-device: vhostdev are missing"); -+ return; -+ } -+ -+ v->vhostfd = qemu_open(v->vhostdev, O_RDWR, errp); -+ if (*errp) { -+ return; -+ } -+ v->vdpa.device_fd = v->vhostfd; -+ -+ v->vdev_id = vhost_vdpa_device_get_u32(v->vhostfd, -+ VHOST_VDPA_GET_DEVICE_ID, errp); -+ if (*errp) { -+ goto out; -+ } -+ -+ max_queue_size = vhost_vdpa_device_get_u32(v->vhostfd, -+ VHOST_VDPA_GET_VRING_NUM, errp); -+ if (*errp) { -+ goto out; -+ } -+ -+ if (v->queue_size > max_queue_size) { -+ error_setg(errp, "vhost-vdpa-device: invalid queue_size: %u (max:%u)", -+ v->queue_size, max_queue_size); -+ goto out; -+ } else if (!v->queue_size) { -+ v->queue_size = max_queue_size; -+ } -+ -+ v->num_queues = vhost_vdpa_device_get_u32(v->vhostfd, -+ VHOST_VDPA_GET_VQS_COUNT, errp); -+ if (*errp) { -+ goto out; -+ } -+ -+ if (!v->num_queues || v->num_queues > VIRTIO_QUEUE_MAX) { -+ error_setg(errp, "invalid number of virtqueues: %u (max:%u)", -+ v->num_queues, VIRTIO_QUEUE_MAX); -+ goto out; -+ } -+ -+ v->dev.nvqs = v->num_queues; -+ vqs = g_new0(struct vhost_virtqueue, v->dev.nvqs); -+ v->dev.vqs = vqs; -+ v->dev.vq_index = 0; -+ v->dev.vq_index_end = v->dev.nvqs; -+ v->dev.backend_features = 0; -+ v->started = false; -+ -+ ret = vhost_dev_init(&v->dev, &v->vdpa, VHOST_BACKEND_TYPE_VDPA, 0, NULL); -+ if (ret < 0) { -+ error_setg(errp, "vhost-vdpa-device: vhost initialization failed: %s", -+ strerror(-ret)); -+ goto free_vqs; -+ } -+ -+ v->config_size = vhost_vdpa_device_get_u32(v->vhostfd, -+ VHOST_VDPA_GET_CONFIG_SIZE, -+ errp); -+ if (*errp) { -+ goto vhost_cleanup; -+ } -+ -+ /* -+ * Invoke .post_init() to initialize the transport-specific fields -+ * before calling virtio_init(). -+ */ -+ if (v->post_init && v->post_init(v, errp) < 0) { -+ goto vhost_cleanup; -+ } -+ -+ v->config = g_malloc0(v->config_size); -+ -+ ret = vhost_dev_get_config(&v->dev, v->config, v->config_size, NULL); -+ if (ret < 0) { -+ error_setg(errp, "vhost-vdpa-device: get config failed"); -+ goto free_config; -+ } -+ -+ virtio_init(vdev, "vhost-vdpa", v->vdev_id, v->config_size); -+ -+ v->virtqs = g_new0(VirtQueue *, v->dev.nvqs); -+ for (i = 0; i < v->dev.nvqs; i++) { -+ v->virtqs[i] = virtio_add_queue(vdev, v->queue_size, -+ vhost_vdpa_device_dummy_handle_output); -+ } -+ -+ return; -+ -+free_config: -+ g_free(v->config); -+vhost_cleanup: -+ vhost_dev_cleanup(&v->dev); -+free_vqs: -+ g_free(vqs); -+out: -+ qemu_close(v->vhostfd); -+ v->vhostfd = -1; -+} -+ -+static void vhost_vdpa_device_unrealize(DeviceState *dev) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(dev); -+ VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -+ int i; -+ -+ virtio_set_status(vdev, 0); -+ -+ for (i = 0; i < s->num_queues; i++) { -+ virtio_delete_queue(s->virtqs[i]); -+ } -+ g_free(s->virtqs); -+ virtio_cleanup(vdev); -+ -+ g_free(s->config); -+ g_free(s->dev.vqs); -+ vhost_dev_cleanup(&s->dev); -+ qemu_close(s->vhostfd); -+ s->vhostfd = -1; -+} -+ -+static void -+vhost_vdpa_device_get_config(VirtIODevice *vdev, uint8_t *config) -+{ -+ VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -+ -+ memcpy(config, s->config, s->config_size); -+} -+ -+static void -+vhost_vdpa_device_set_config(VirtIODevice *vdev, const uint8_t *config) -+{ -+ VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -+ int ret; -+ -+ ret = vhost_dev_set_config(&s->dev, s->config, 0, s->config_size, -+ VHOST_SET_CONFIG_TYPE_MASTER); -+ if (ret) { -+ error_report("set device config space failed"); -+ return; -+ } -+} -+ -+static uint64_t vhost_vdpa_device_get_features(VirtIODevice *vdev, -+ uint64_t features, -+ Error **errp) -+{ -+ VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -+ uint64_t backend_features = s->dev.features; -+ -+ if (!virtio_has_feature(features, VIRTIO_F_IOMMU_PLATFORM)) { -+ virtio_clear_feature(&backend_features, VIRTIO_F_IOMMU_PLATFORM); -+ } -+ -+ return backend_features; -+} -+ -+static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp) -+{ -+ VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); -+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -+ int i, ret; -+ -+ if (!k->set_guest_notifiers) { -+ error_setg(errp, "binding does not support guest notifiers"); -+ return -ENOSYS; -+ } -+ -+ ret = vhost_dev_enable_notifiers(&s->dev, vdev); -+ if (ret < 0) { -+ error_setg_errno(errp, -ret, "Error enabling host notifiers"); -+ return ret; -+ } -+ -+ ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, true); -+ if (ret < 0) { -+ error_setg_errno(errp, -ret, "Error binding guest notifier"); -+ goto err_host_notifiers; -+ } -+ -+ s->dev.acked_features = vdev->guest_features; -+ -+ ret = vhost_dev_start(&s->dev, vdev); -+ if (ret < 0) { -+ error_setg_errno(errp, -ret, "Error starting vhost"); -+ goto err_guest_notifiers; -+ } -+ s->started = true; -+ -+ /* -+ * guest_notifier_mask/pending not used yet, so just unmask -+ * everything here. virtio-pci will do the right thing by -+ * enabling/disabling irqfd. -+ */ -+ for (i = 0; i < s->dev.nvqs; i++) { -+ vhost_virtqueue_mask(&s->dev, vdev, i, false); -+ } -+ -+ return ret; -+ -+err_guest_notifiers: -+ k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); -+err_host_notifiers: -+ vhost_dev_disable_notifiers(&s->dev, vdev); -+ return ret; -+} -+ -+static void vhost_vdpa_device_stop(VirtIODevice *vdev) -+{ -+ VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); -+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -+ int ret; -+ -+ if (!s->started) { -+ return; -+ } -+ s->started = false; -+ -+ if (!k->set_guest_notifiers) { -+ return; -+ } -+ -+ vhost_dev_stop(&s->dev, vdev); -+ -+ ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); -+ if (ret < 0) { -+ error_report("vhost guest notifier cleanup failed: %d", ret); -+ return; -+ } -+ -+ vhost_dev_disable_notifiers(&s->dev, vdev); -+} -+ -+static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) -+{ -+ VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -+ bool should_start = virtio_device_started(vdev, status); -+ Error *local_err = NULL; -+ int ret; -+ -+ if (!vdev->vm_running) { -+ should_start = false; -+ } -+ -+ if (s->started == should_start) { -+ return; -+ } -+ -+ if (should_start) { -+ ret = vhost_vdpa_device_start(vdev, &local_err); -+ if (ret < 0) { -+ error_reportf_err(local_err, "vhost-vdpa-device: start failed: "); -+ } -+ } else { -+ vhost_vdpa_device_stop(vdev); -+ } -+} -+ -+static Property vhost_vdpa_device_properties[] = { -+ DEFINE_PROP_STRING("vhostdev", VhostVdpaDevice, vhostdev), -+ DEFINE_PROP_UINT16("queue-size", VhostVdpaDevice, queue_size, 0), -+ DEFINE_PROP_END_OF_LIST(), -+}; -+ -+static const VMStateDescription vmstate_vhost_vdpa_device = { -+ .name = "vhost-vdpa-device", -+ .minimum_version_id = 1, -+ .version_id = 1, -+ .fields = (VMStateField[]) { -+ VMSTATE_VIRTIO_DEVICE, -+ VMSTATE_END_OF_LIST() -+ }, -+}; -+ -+static void vhost_vdpa_device_class_init(ObjectClass *klass, void *data) -+{ -+ DeviceClass *dc = DEVICE_CLASS(klass); -+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); -+ -+ device_class_set_props(dc, vhost_vdpa_device_properties); -+ dc->desc = "VDPA-based generic device assignment"; -+ dc->vmsd = &vmstate_vhost_vdpa_device; -+ set_bit(DEVICE_CATEGORY_MISC, dc->categories); -+ vdc->realize = vhost_vdpa_device_realize; -+ vdc->unrealize = vhost_vdpa_device_unrealize; -+ vdc->get_config = vhost_vdpa_device_get_config; -+ vdc->set_config = vhost_vdpa_device_set_config; -+ vdc->get_features = vhost_vdpa_device_get_features; -+ vdc->set_status = vhost_vdpa_device_set_status; -+} -+ -+static void vhost_vdpa_device_instance_init(Object *obj) -+{ -+ VhostVdpaDevice *s = VHOST_VDPA_DEVICE(obj); -+ -+ device_add_bootindex_property(obj, &s->bootindex, "bootindex", -+ NULL, DEVICE(obj)); -+} -+ -+static const TypeInfo vhost_vdpa_device_info = { -+ .name = TYPE_VHOST_VDPA_DEVICE, -+ .parent = TYPE_VIRTIO_DEVICE, -+ .instance_size = sizeof(VhostVdpaDevice), -+ .class_init = vhost_vdpa_device_class_init, -+ .instance_init = vhost_vdpa_device_instance_init, -+}; -+ -+static void register_vhost_vdpa_device_type(void) -+{ -+ type_register_static(&vhost_vdpa_device_info); -+} -+ -+type_init(register_vhost_vdpa_device_type); -diff --git a/include/hw/virtio/vdpa-dev.h b/include/hw/virtio/vdpa-dev.h -new file mode 100644 -index 0000000000..4dbf98195c ---- /dev/null -+++ b/include/hw/virtio/vdpa-dev.h -@@ -0,0 +1,43 @@ -+/* -+ * Vhost Vdpa Device -+ * -+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved. -+ * -+ * Authors: -+ * Longpeng -+ * -+ * Largely based on the "vhost-user-blk.h" implemented by: -+ * Changpeng Liu -+ * -+ * This work is licensed under the terms of the GNU LGPL, version 2 or later. -+ * See the COPYING.LIB file in the top-level directory. -+ */ -+#ifndef _VHOST_VDPA_DEVICE_H -+#define _VHOST_VDPA_DEVICE_H -+ -+#include "hw/virtio/vhost.h" -+#include "hw/virtio/vhost-vdpa.h" -+#include "qom/object.h" -+ -+ -+#define TYPE_VHOST_VDPA_DEVICE "vhost-vdpa-device" -+OBJECT_DECLARE_SIMPLE_TYPE(VhostVdpaDevice, VHOST_VDPA_DEVICE) -+ -+struct VhostVdpaDevice { -+ VirtIODevice parent_obj; -+ char *vhostdev; -+ int vhostfd; -+ int32_t bootindex; -+ uint32_t vdev_id; -+ uint32_t num_queues; -+ struct vhost_dev dev; -+ struct vhost_vdpa vdpa; -+ VirtQueue **virtqs; -+ uint8_t *config; -+ int config_size; -+ uint16_t queue_size; -+ bool started; -+ int (*post_init)(VhostVdpaDevice *v, Error **errp); -+}; -+ -+#endif --- -2.27.0 - diff --git a/vdpa-add-vhost_vdpa_net_valid_svq_features.patch b/vdpa-add-vhost_vdpa_net_valid_svq_features.patch deleted file mode 100644 index 622c8901c9170db52a54d57d8702d5a8ed6e5b21..0000000000000000000000000000000000000000 --- a/vdpa-add-vhost_vdpa_net_valid_svq_features.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 9cd4a76f615cea230ffc33d5b3666f84216f694b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:37 +0100 -Subject: [PATCH] vdpa: add vhost_vdpa_net_valid_svq_features -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It will be reused at vdpa device start so let's extract in its own -function. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-6-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 26 +++++++++++++++++--------- - 1 file changed, 17 insertions(+), 9 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index eae2ed364f..217d2545c1 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -105,6 +105,22 @@ VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc) - return s->vhost_net; - } - -+static bool vhost_vdpa_net_valid_svq_features(uint64_t features, Error **errp) -+{ -+ uint64_t invalid_dev_features = -+ features & ~vdpa_svq_device_features & -+ /* Transport are all accepted at this point */ -+ ~MAKE_64BIT_MASK(VIRTIO_TRANSPORT_F_START, -+ VIRTIO_TRANSPORT_F_END - VIRTIO_TRANSPORT_F_START); -+ -+ if (invalid_dev_features) { -+ error_setg(errp, "vdpa svq does not work with features 0x%" PRIx64, -+ invalid_dev_features); -+ } -+ -+ return !invalid_dev_features; -+} -+ - static int vhost_vdpa_net_check_device_id(struct vhost_net *net) - { - uint32_t device_id; -@@ -683,15 +699,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - if (opts->x_svq) { - struct vhost_vdpa_iova_range iova_range; - -- uint64_t invalid_dev_features = -- features & ~vdpa_svq_device_features & -- /* Transport are all accepted at this point */ -- ~MAKE_64BIT_MASK(VIRTIO_TRANSPORT_F_START, -- VIRTIO_TRANSPORT_F_END - VIRTIO_TRANSPORT_F_START); -- -- if (invalid_dev_features) { -- error_setg(errp, "vdpa svq does not work with features 0x%" PRIx64, -- invalid_dev_features); -+ if (!vhost_vdpa_net_valid_svq_features(features, errp)) { - goto err_svq; - } - --- -2.27.0 - diff --git a/vdpa-allocate-SVQ-array-unconditionally.patch b/vdpa-allocate-SVQ-array-unconditionally.patch deleted file mode 100644 index 9e8cc601130872604eb9420172d0a1e9ec0f8660..0000000000000000000000000000000000000000 --- a/vdpa-allocate-SVQ-array-unconditionally.patch +++ /dev/null @@ -1,42 +0,0 @@ -From fea179d880cd502f291cc6079b565bc059612d48 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:40 +0100 -Subject: [PATCH] vdpa: allocate SVQ array unconditionally -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -SVQ may run or not in a device depending on runtime conditions (for -example, if the device can move CVQ to its own group or not). - -Allocate the SVQ array unconditionally at startup, since its hard to -move this allocation elsewhere. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-9-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 59bfdbfc24..450b5effd2 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -535,10 +535,6 @@ static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev) - struct vhost_vdpa *v = dev->opaque; - size_t idx; - -- if (!v->shadow_vqs) { -- return; -- } -- - for (idx = 0; idx < v->shadow_vqs->len; ++idx) { - vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, idx)); - } --- -2.27.0 - diff --git a/vdpa-always-start-CVQ-in-SVQ-mode-if-possible.patch b/vdpa-always-start-CVQ-in-SVQ-mode-if-possible.patch deleted file mode 100644 index 32a59b8166f98a3176663addb05e80e51ee696bf..0000000000000000000000000000000000000000 --- a/vdpa-always-start-CVQ-in-SVQ-mode-if-possible.patch +++ /dev/null @@ -1,224 +0,0 @@ -From e2e9aeaacdb28b6c2a1bfcfef09113dc9b26a420 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:44 +0100 -Subject: [PATCH] vdpa: always start CVQ in SVQ mode if possible -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Isolate control virtqueue in its own group, allowing to intercept control -commands but letting dataplane run totally passthrough to the guest. - -Signed-off-by: Eugenio Pérez -Message-Id: <20221215113144.322011-13-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Acked-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 3 +- - include/standard-headers/linux/vhost_types.h | 5 + - linux-headers/linux/vhost.h | 14 +++ - net/vhost-vdpa.c | 110 ++++++++++++++++++- - 4 files changed, 130 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 6d0d85b733..8b44f5a7b8 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -641,7 +641,8 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) - { - uint64_t features; - uint64_t f = 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2 | -- 0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH; -+ 0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH | -+ 0x1ULL << VHOST_BACKEND_F_IOTLB_ASID; - int r; - - if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) { -diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h -index fa267e39d4..17833e320e 100644 ---- a/include/standard-headers/linux/vhost_types.h -+++ b/include/standard-headers/linux/vhost_types.h -@@ -153,4 +153,9 @@ struct vhost_vdpa_iova_range { - /* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */ - #define VHOST_NET_F_VIRTIO_NET_HDR 27 - -+/* IOTLB can accept address space identifier through V2 type of IOTLB -+ * message -+ */ -+#define VHOST_BACKEND_F_IOTLB_ASID 0x3 -+ - #endif -diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h -index 5d99e7c242..b6ded7f831 100644 ---- a/linux-headers/linux/vhost.h -+++ b/linux-headers/linux/vhost.h -@@ -157,4 +157,18 @@ - /* Get the count of all virtqueues */ - #define VHOST_VDPA_GET_VQS_COUNT _IOR(VHOST_VIRTIO, 0x80, __u32) - -+/* Get the group for a virtqueue: read index, write group in num, -+ * The virtqueue index is stored in the index field of -+ * vhost_vring_state. The group for this specific virtqueue is -+ * returned via num field of vhost_vring_state. -+ */ -+#define VHOST_VDPA_GET_VRING_GROUP _IOWR(VHOST_VIRTIO, 0x7B, \ -+ struct vhost_vring_state) -+/* Set the ASID for a virtqueue group. The group index is stored in -+ * the index field of vhost_vring_state, the ASID associated with this -+ * group is stored at num field of vhost_vring_state. -+ */ -+#define VHOST_VDPA_SET_GROUP_ASID _IOW(VHOST_VIRTIO, 0x7C, \ -+ struct vhost_vring_state) -+ - #endif -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 21fb89bb6b..24c4c2ef51 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -100,6 +100,8 @@ static const uint64_t vdpa_svq_device_features = - BIT_ULL(VIRTIO_NET_F_RSC_EXT) | - BIT_ULL(VIRTIO_NET_F_STANDBY); - -+#define VHOST_VDPA_NET_CVQ_ASID 1 -+ - VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc) - { - VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); -@@ -250,6 +252,40 @@ static NetClientInfo net_vhost_vdpa_info = { - .check_peer_type = vhost_vdpa_check_peer_type, - }; - -+static int64_t vhost_vdpa_get_vring_group(int device_fd, unsigned vq_index) -+{ -+ struct vhost_vring_state state = { -+ .index = vq_index, -+ }; -+ int r = ioctl(device_fd, VHOST_VDPA_GET_VRING_GROUP, &state); -+ -+ if (unlikely(r < 0)) { -+ error_report("Cannot get VQ %u group: %s", vq_index, -+ g_strerror(errno)); -+ return r; -+ } -+ -+ return state.num; -+} -+ -+static int vhost_vdpa_set_address_space_id(struct vhost_vdpa *v, -+ unsigned vq_group, -+ unsigned asid_num) -+{ -+ struct vhost_vring_state asid = { -+ .index = vq_group, -+ .num = asid_num, -+ }; -+ int r; -+ -+ r = ioctl(v->device_fd, VHOST_VDPA_SET_GROUP_ASID, &asid); -+ if (unlikely(r < 0)) { -+ error_report("Can't set vq group %u asid %u, errno=%d (%s)", -+ asid.index, asid.num, errno, g_strerror(errno)); -+ } -+ return r; -+} -+ - static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr) - { - VhostIOVATree *tree = v->iova_tree; -@@ -324,11 +360,75 @@ dma_map_err: - static int vhost_vdpa_net_cvq_start(NetClientState *nc) - { - VhostVDPAState *s; -- int r; -+ struct vhost_vdpa *v; -+ uint64_t backend_features; -+ int64_t cvq_group; -+ int cvq_index, r; - - assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); - - s = DO_UPCAST(VhostVDPAState, nc, nc); -+ v = &s->vhost_vdpa; -+ -+ v->shadow_data = s->always_svq; -+ v->shadow_vqs_enabled = s->always_svq; -+ s->vhost_vdpa.address_space_id = VHOST_VDPA_GUEST_PA_ASID; -+ -+ if (s->always_svq) { -+ /* SVQ is already configured for all virtqueues */ -+ goto out; -+ } -+ -+ /* -+ * If we early return in these cases SVQ will not be enabled. The migration -+ * will be blocked as long as vhost-vdpa backends will not offer _F_LOG. -+ * -+ * Calling VHOST_GET_BACKEND_FEATURES as they are not available in v->dev -+ * yet. -+ */ -+ r = ioctl(v->device_fd, VHOST_GET_BACKEND_FEATURES, &backend_features); -+ if (unlikely(r < 0)) { -+ error_report("Cannot get vdpa backend_features: %s(%d)", -+ g_strerror(errno), errno); -+ return -1; -+ } -+ if (!(backend_features & VHOST_BACKEND_F_IOTLB_ASID) || -+ !vhost_vdpa_net_valid_svq_features(v->dev->features, NULL)) { -+ return 0; -+ } -+ -+ /* -+ * Check if all the virtqueues of the virtio device are in a different vq -+ * than the last vq. VQ group of last group passed in cvq_group. -+ */ -+ cvq_index = v->dev->vq_index_end - 1; -+ cvq_group = vhost_vdpa_get_vring_group(v->device_fd, cvq_index); -+ if (unlikely(cvq_group < 0)) { -+ return cvq_group; -+ } -+ for (int i = 0; i < cvq_index; ++i) { -+ int64_t group = vhost_vdpa_get_vring_group(v->device_fd, i); -+ -+ if (unlikely(group < 0)) { -+ return group; -+ } -+ -+ if (group == cvq_group) { -+ return 0; -+ } -+ } -+ -+ r = vhost_vdpa_set_address_space_id(v, cvq_group, VHOST_VDPA_NET_CVQ_ASID); -+ if (unlikely(r < 0)) { -+ return r; -+ } -+ -+ v->iova_tree = vhost_iova_tree_new(v->iova_range.first, -+ v->iova_range.last); -+ v->shadow_vqs_enabled = true; -+ s->vhost_vdpa.address_space_id = VHOST_VDPA_NET_CVQ_ASID; -+ -+out: - if (!s->vhost_vdpa.shadow_vqs_enabled) { - return 0; - } -@@ -357,6 +457,14 @@ static void vhost_vdpa_net_cvq_stop(NetClientState *nc) - if (s->vhost_vdpa.shadow_vqs_enabled) { - vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); - vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->status); -+ if (!s->always_svq) { -+ /* -+ * If only the CVQ is shadowed we can delete this safely. -+ * If all the VQs are shadows this will be needed by the time the -+ * device is started again to register SVQ vrings and similar. -+ */ -+ g_clear_pointer(&s->vhost_vdpa.iova_tree, vhost_iova_tree_delete); -+ } - } - } - --- -2.27.0 - diff --git a/vdpa-commit-all-host-notifier-MRs-in-a-single-MR-tra.patch b/vdpa-commit-all-host-notifier-MRs-in-a-single-MR-tra.patch deleted file mode 100644 index 6c805b2df967ac61e8a1994a3bce99ca34666688..0000000000000000000000000000000000000000 --- a/vdpa-commit-all-host-notifier-MRs-in-a-single-MR-tra.patch +++ /dev/null @@ -1,79 +0,0 @@ -From aa9c65215f37fc54a280ce89a2cbfd6235e8ec9f Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Tue, 27 Dec 2022 15:20:15 +0800 -Subject: [PATCH] vdpa: commit all host notifier MRs in a single MR transaction -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows the vhost-vdpa device to batch the setup of all its MRs of -host notifiers. - -This significantly reduces the device starting time, e.g. the time spend -on setup the host notifier MRs reduce from 423ms to 32ms for a VM with -64 vCPUs and 3 vhost-vDPA generic devices (vdpa_sim_blk, 64vq per device). - -Signed-off-by: Longpeng -Message-Id: <20221227072015.3134-4-longpeng2@huawei.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Philippe Mathieu-Daudé -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 25 +++++++++++++++++++------ - 1 file changed, 19 insertions(+), 6 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index f93fac538c..2fd7af1c6b 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -522,9 +522,18 @@ static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n) - { - int i; - -+ /* -+ * Pack all the changes to the memory regions in a single -+ * transaction to avoid a few updating of the address space -+ * topology. -+ */ -+ memory_region_transaction_begin(); -+ - for (i = dev->vq_index; i < dev->vq_index + n; i++) { - vhost_vdpa_host_notifier_uninit(dev, i); - } -+ -+ memory_region_transaction_commit(); - } - - static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev) -@@ -537,17 +546,21 @@ static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev) - return; - } - -+ /* -+ * Pack all the changes to the memory regions in a single -+ * transaction to avoid a few updating of the address space -+ * topology. -+ */ -+ memory_region_transaction_begin(); -+ - for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) { - if (vhost_vdpa_host_notifier_init(dev, i)) { -- goto err; -+ vhost_vdpa_host_notifiers_uninit(dev, i - dev->vq_index); -+ break; - } - } - -- return; -- --err: -- vhost_vdpa_host_notifiers_uninit(dev, i - dev->vq_index); -- return; -+ memory_region_transaction_commit(); - } - - static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev) --- -2.27.0 - diff --git a/vdpa-correct-param-passed-in-when-unregister-save.patch b/vdpa-correct-param-passed-in-when-unregister-save.patch deleted file mode 100644 index 3b7ce2772e56b6a60dbe7847936397351efed879..0000000000000000000000000000000000000000 --- a/vdpa-correct-param-passed-in-when-unregister-save.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 9f0b9d2d71b9fa21789981d68335ee417e18b025 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 14 Dec 2023 11:22:54 +0800 -Subject: [PATCH] vdpa: correct param passed in when unregister save - -The idstr passed in the unregister_savevm function is inconsisten -with the idstr passed in when register_savevm_live registration. -Needs to be modified, otherwise migration will fail after hotunplug -all vdpa devices. - -Signed-off-by: jiangdongxu ---- - hw/virtio/vdpa-dev-mig.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c -index ee3e27f2bb..c71e71fd64 100644 ---- a/hw/virtio/vdpa-dev-mig.c -+++ b/hw/virtio/vdpa-dev-mig.c -@@ -400,6 +400,6 @@ void vdpa_migration_register(VhostVdpaDevice *vdev) - void vdpa_migration_unregister(VhostVdpaDevice *vdev) - { - remove_migration_state_change_notifier(&vdev->migration_state); -- unregister_savevm(VMSTATE_IF(&vdev->parent_obj.parent_obj), "vdpa", DEVICE(vdev)); -+ unregister_savevm(NULL, "vdpa", DEVICE(vdev)); - qemu_del_vm_change_state_handler(vdev->vmstate); - } --- -2.27.0 - diff --git a/vdpa-dev-get-iova-range-explicitly.patch b/vdpa-dev-get-iova-range-explicitly.patch deleted file mode 100644 index f9f8e1a8b67616c0e51a96ad9f09728d518487dc..0000000000000000000000000000000000000000 --- a/vdpa-dev-get-iova-range-explicitly.patch +++ /dev/null @@ -1,104 +0,0 @@ -From f5d338d28758db5066f199c35d56e0953edcc5d9 Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Sat, 24 Dec 2022 19:48:47 +0800 -Subject: [PATCH] vdpa-dev: get iova range explicitly - -In commit a585fad26b ("vdpa: request iova_range only once") we remove -GET_IOVA_RANGE form vhost_vdpa_init, the generic vdpa device will start -without iova_range populated, so the device won't work. Let's call -GET_IOVA_RANGE ioctl explicitly. - -Fixes: a585fad26b2e6ccc ("vdpa: request iova_range only once") -Signed-off-by: Longpeng -Message-Id: <20221224114848.3062-2-longpeng2@huawei.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Acked-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vdpa-dev.c | 9 +++++++++ - hw/virtio/vhost-vdpa.c | 7 +++++++ - include/hw/virtio/vhost-vdpa.h | 2 ++ - net/vhost-vdpa.c | 8 -------- - 4 files changed, 18 insertions(+), 8 deletions(-) - -diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c -index 465b08c0e3..254a213117 100644 ---- a/hw/virtio/vdpa-dev.c -+++ b/hw/virtio/vdpa-dev.c -@@ -53,6 +53,7 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) - { - VirtIODevice *vdev = VIRTIO_DEVICE(dev); - VhostVdpaDevice *v = VHOST_VDPA_DEVICE(vdev); -+ struct vhost_vdpa_iova_range iova_range; - uint16_t max_queue_size; - struct vhost_virtqueue *vqs; - int i, ret; -@@ -108,6 +109,14 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) - v->dev.backend_features = 0; - v->started = false; - -+ ret = vhost_vdpa_get_iova_range(v->vhostfd, &iova_range); -+ if (ret < 0) { -+ error_setg(errp, "vhost-vdpa-device: get iova range failed: %s", -+ strerror(-ret)); -+ goto free_vqs; -+ } -+ v->vdpa.iova_range = iova_range; -+ - ret = vhost_dev_init(&v->dev, &v->vdpa, VHOST_BACKEND_TYPE_VDPA, 0, NULL); - if (ret < 0) { - error_setg(errp, "vhost-vdpa-device: vhost initialization failed: %s", -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index c9289e2c01..f93fac538c 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -380,6 +380,13 @@ static int vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status) - return 0; - } - -+int vhost_vdpa_get_iova_range(int fd, struct vhost_vdpa_iova_range *iova_range) -+{ -+ int ret = ioctl(fd, VHOST_VDPA_GET_IOVA_RANGE, iova_range); -+ -+ return ret < 0 ? -errno : 0; -+} -+ - /* - * The use of this function is for requests that only need to be - * applied once. Typically such request occurs at the beginning -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index 45b969a311..7997f09a8d 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -51,6 +51,8 @@ typedef struct vhost_vdpa { - VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; - } VhostVDPA; - -+int vhost_vdpa_get_iova_range(int fd, struct vhost_vdpa_iova_range *iova_range); -+ - int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, - hwaddr size, void *vaddr, bool readonly); - int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 3dcf341722..3c370f2dc5 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -717,14 +717,6 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - return nc; - } - --static int vhost_vdpa_get_iova_range(int fd, -- struct vhost_vdpa_iova_range *iova_range) --{ -- int ret = ioctl(fd, VHOST_VDPA_GET_IOVA_RANGE, iova_range); -- -- return ret < 0 ? -errno : 0; --} -- - static int vhost_vdpa_get_features(int fd, uint64_t *features, Error **errp) - { - int ret = ioctl(fd, VHOST_GET_FEATURES, features); --- -2.27.0 - diff --git a/vdpa-dev-mark-the-device-as-unmigratable.patch b/vdpa-dev-mark-the-device-as-unmigratable.patch deleted file mode 100644 index 77a90515207c87acd67abc9e1861fb05a85e0bf5..0000000000000000000000000000000000000000 --- a/vdpa-dev-mark-the-device-as-unmigratable.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 90615553b0062b0c971cd1ce5b90aad4a9ea9b6a Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Sat, 12 Nov 2022 22:40:12 +0800 -Subject: [PATCH 5/7] vdpa-dev: mark the device as unmigratable - -The generic vDPA device doesn't support migration currently, so -mark it as unmigratable temporarily. - -Reviewed-by: Stefano Garzarella -Acked-by: Jason Wang -Signed-off-by: Longpeng ---- - hw/virtio/vdpa-dev.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c -index 42ab74c255..1840f0e450 100644 ---- a/hw/virtio/vdpa-dev.c -+++ b/hw/virtio/vdpa-dev.c -@@ -327,6 +327,7 @@ static Property vhost_vdpa_device_properties[] = { - - static const VMStateDescription vmstate_vhost_vdpa_device = { - .name = "vhost-vdpa-device", -+ .unmigratable = 1, - .minimum_version_id = 1, - .version_id = 1, - .fields = (VMStateField[]) { --- -2.27.0 - diff --git a/vdpa-do-not-block-migration-if-device-has-cvq-and-x-.patch b/vdpa-do-not-block-migration-if-device-has-cvq-and-x-.patch deleted file mode 100644 index 4956a0fd552ff9d71ac31bf96faa0cef548182db..0000000000000000000000000000000000000000 --- a/vdpa-do-not-block-migration-if-device-has-cvq-and-x-.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 5bd89df7b5c1448f22f37a918569d0367458591b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Fri, 2 Jun 2023 16:38:52 +0200 -Subject: [PATCH] vdpa: do not block migration if device has cvq and x-svq=on -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It was a mistake to forbid in all cases, as SVQ is already able to send -all the CVQ messages before start forwarding data vqs. It actually -caused a regression, making impossible to migrate device previously -migratable. - -Fixes: 36e4647247f2 ("vdpa: add vhost_vdpa_net_valid_svq_features") -Signed-off-by: Eugenio Pérez -Message-Id: <20230602143854.1879091-2-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Tested-by: Lei Yang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index dc1b4c4be2..cdc54a7b54 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -723,13 +723,16 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - s->vhost_vdpa.shadow_vq_ops_opaque = s; - - /* -- * TODO: We cannot migrate devices with CVQ as there is no way to set -- * the device state (MAC, MQ, etc) before starting the datapath. -+ * TODO: We cannot migrate devices with CVQ and no x-svq enabled as -+ * there is no way to set the device state (MAC, MQ, etc) before -+ * starting the datapath. - * - * Migration blocker ownership now belongs to s->vhost_vdpa. - */ -- error_setg(&s->vhost_vdpa.migration_blocker, -- "net vdpa cannot migrate with CVQ feature"); -+ if (!svq) { -+ error_setg(&s->vhost_vdpa.migration_blocker, -+ "net vdpa cannot migrate with CVQ feature"); -+ } - } - ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs); - if (ret) { --- -2.27.0 - diff --git a/vdpa-do-not-handle-VIRTIO_NET_F_GUEST_ANNOUNCE-in-vh.patch b/vdpa-do-not-handle-VIRTIO_NET_F_GUEST_ANNOUNCE-in-vh.patch deleted file mode 100644 index 1fcc058025697677234cdc705e4a27ec0458c3c9..0000000000000000000000000000000000000000 --- a/vdpa-do-not-handle-VIRTIO_NET_F_GUEST_ANNOUNCE-in-vh.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 17cd7f504c47c532eae6b8ecfc21b0e5796e08da Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 21 Dec 2022 12:50:15 +0100 -Subject: [PATCH] vdpa: do not handle VIRTIO_NET_F_GUEST_ANNOUNCE in vhost-vdpa -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -So qemu emulates it even in case the device does not support it. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221221115015.1400889-5-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 48dd9d15f6..3dcf341722 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -72,7 +72,6 @@ const int vdpa_feature_bits[] = { - VIRTIO_F_RING_PACKED, - VIRTIO_NET_F_RSS, - VIRTIO_NET_F_HASH_REPORT, -- VIRTIO_NET_F_GUEST_ANNOUNCE, - VIRTIO_NET_F_STATUS, - VHOST_INVALID_FEATURE_BIT - }; --- -2.27.0 - diff --git a/vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch b/vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch deleted file mode 100644 index e1b024471b53edc53e102e6e70226a336cb35e3b..0000000000000000000000000000000000000000 --- a/vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 556aa09e618b0fb40f038b11eafc69750c71f26e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:20:03 +0200 -Subject: [PATCH] vdpa: do not save failed dma maps in SVQ iova tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If a map fails for whatever reason, it must not be saved in the tree. -Otherwise, qemu will try to unmap it in cleanup, leaving to more errors. - -Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ") -Reported-by: Lei Yang -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index c551665f5d..02dab41c42 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -178,6 +178,7 @@ static void vhost_vdpa_listener_commit(MemoryListener *listener) - static void vhost_vdpa_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { -+ DMAMap mem_region = {}; - struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener); - hwaddr iova; - Int128 llend, llsize; -@@ -214,13 +215,13 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, - - llsize = int128_sub(llend, int128_make64(iova)); - if (v->shadow_vqs_enabled) { -- DMAMap mem_region = { -- .translated_addr = (hwaddr)(uintptr_t)vaddr, -- .size = int128_get64(llsize) - 1, -- .perm = IOMMU_ACCESS_FLAG(true, section->readonly), -- }; -+ int r; - -- int r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region); -+ mem_region.translated_addr = (hwaddr)(uintptr_t)vaddr, -+ mem_region.size = int128_get64(llsize) - 1, -+ mem_region.perm = IOMMU_ACCESS_FLAG(true, section->readonly), -+ -+ r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region); - if (unlikely(r != IOVA_OK)) { - error_report("Can't allocate a mapping (%d)", r); - goto fail; -@@ -234,11 +235,16 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, - vaddr, section->readonly); - if (ret) { - error_report("vhost vdpa map fail!"); -- goto fail; -+ goto fail_map; - } - - return; - -+fail_map: -+ if (v->shadow_vqs_enabled) { -+ vhost_iova_tree_remove(v->iova_tree, &mem_region); -+ } -+ - fail: - /* - * On the initfn path, store the first error in the container so we --- -2.27.0 - diff --git a/vdpa-don-t-suspend-resume-device-when-vdpa-device-no.patch b/vdpa-don-t-suspend-resume-device-when-vdpa-device-no.patch deleted file mode 100644 index 77e69328c28d92a81b9d25a3ab5e12724d717918..0000000000000000000000000000000000000000 --- a/vdpa-don-t-suspend-resume-device-when-vdpa-device-no.patch +++ /dev/null @@ -1,67 +0,0 @@ -From daab4fa364c508d793ed28a920d50cd76efe7633 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Tue, 19 Dec 2023 20:32:00 +0800 -Subject: [PATCH] vdpa: don't suspend/resume device when vdpa device not - started - -When vdpa device not started, we don't need to suspend vdpa device -and send vdpa device state information. Therefore, add the suspended -flag of vdpa device to distinguish whether the device is suspended and -use it to determine whether the device needs to resume in dest qemu. - -Signed-off-by: jiangdongxu ---- - hw/virtio/vdpa-dev-mig.c | 23 +++++++++++++++-------- - 1 file changed, 15 insertions(+), 8 deletions(-) - -diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c -index 4a45821892..9cd80f92eb 100644 ---- a/hw/virtio/vdpa-dev-mig.c -+++ b/hw/virtio/vdpa-dev-mig.c -@@ -296,10 +296,13 @@ static int vdpa_save_complete_precopy(QEMUFile *f, void *opaque) - int ret; - - qemu_put_be64(f, VDPA_MIG_FLAG_DEV_CONFIG_STATE); -- ret = vhost_vdpa_dev_buffer_save(hdev, f); -- if (ret) { -- error_report("Save vdpa device buffer failed: %d\n", ret); -- return ret; -+ qemu_put_be16(f, (uint16_t)vdev->suspended); -+ if (vdev->suspended) { -+ ret = vhost_vdpa_dev_buffer_save(hdev, f); -+ if (ret) { -+ error_report("Save vdpa device buffer failed: %d\n", ret); -+ return ret; -+ } - } - qemu_put_be64(f, VDPA_MIG_FLAG_END_OF_STATE); - -@@ -313,6 +316,7 @@ static int vdpa_load_state(QEMUFile *f, void *opaque, int version_id) - - int ret; - uint64_t data; -+ uint16_t suspended; - - data = qemu_get_be64(f); - while (data != VDPA_MIG_FLAG_END_OF_STATE) { -@@ -325,10 +329,13 @@ static int vdpa_load_state(QEMUFile *f, void *opaque, int version_id) - return -EINVAL; - } - } else if (data == VDPA_MIG_FLAG_DEV_CONFIG_STATE) { -- ret = vhost_vdpa_dev_buffer_load(hdev, f); -- if (ret) { -- error_report("fail to restore device buffer.\n"); -- return ret; -+ suspended = qemu_get_be16(f); -+ if (suspended) { -+ ret = vhost_vdpa_dev_buffer_load(hdev, f); -+ if (ret) { -+ error_report("fail to restore device buffer.\n"); -+ return ret; -+ } - } - } - --- -2.27.0 - diff --git a/vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch b/vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch deleted file mode 100644 index 5b2d4b509b66144b3bb4bd30346cd255f68aa19b..0000000000000000000000000000000000000000 --- a/vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch +++ /dev/null @@ -1,144 +0,0 @@ -From af761da9860bd79bd9d214c15d2d30010e73aafa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:30:34 +0200 -Subject: [PATCH] vdpa: extract vhost_vdpa_net_cvq_add from - vhost_vdpa_net_handle_ctrl_avail -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -So we can reuse it to inject state messages. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang --- -v7: -* Remove double free error - -v6: -* Do not assume in buffer sent to the device is sizeof(virtio_net_ctrl_ack) - -v5: -* Do not use an artificial !NULL VirtQueueElement -* Use only out size instead of iovec dev_buffers for these functions. - -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 59 +++++++++++++++++++++++++++++++----------------- - 1 file changed, 38 insertions(+), 21 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 882f5ee89c..b24e0919d0 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -339,6 +339,38 @@ static void vhost_vdpa_net_cvq_stop(NetClientState *nc) - } - } - -+static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len, -+ size_t in_len) -+{ -+ /* Buffers for the device */ -+ const struct iovec out = { -+ .iov_base = s->cvq_cmd_out_buffer, -+ .iov_len = out_len, -+ }; -+ const struct iovec in = { -+ .iov_base = s->cvq_cmd_in_buffer, -+ .iov_len = sizeof(virtio_net_ctrl_ack), -+ }; -+ VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0); -+ int r; -+ -+ r = vhost_svq_add(svq, &out, 1, &in, 1, NULL); -+ if (unlikely(r != 0)) { -+ if (unlikely(r == -ENOSPC)) { -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n", -+ __func__); -+ } -+ return r; -+ } -+ -+ /* -+ * We can poll here since we've had BQL from the time we sent the -+ * descriptor. Also, we need to take the answer before SVQ pulls by itself, -+ * when BQL is released -+ */ -+ return vhost_svq_poll(svq); -+} -+ - static NetClientInfo net_vhost_vdpa_cvq_info = { - .type = NET_CLIENT_DRIVER_VHOST_VDPA, - .size = sizeof(VhostVDPAState), -@@ -395,23 +427,18 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - void *opaque) - { - VhostVDPAState *s = opaque; -- size_t in_len, dev_written; -+ size_t in_len; - virtio_net_ctrl_ack status = VIRTIO_NET_ERR; - /* Out buffer sent to both the vdpa device and the device model */ - struct iovec out = { - .iov_base = s->cvq_cmd_out_buffer, - }; -- /* In buffer sent to the device */ -- const struct iovec dev_in = { -- .iov_base = s->cvq_cmd_in_buffer, -- .iov_len = sizeof(virtio_net_ctrl_ack), -- }; - /* in buffer used for device model */ - const struct iovec in = { - .iov_base = &status, - .iov_len = sizeof(status), - }; -- int r = -EINVAL; -+ ssize_t dev_written = -EINVAL; - bool ok; - - out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, -@@ -422,21 +449,11 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - goto out; - } - -- r = vhost_svq_add(svq, &out, 1, &dev_in, 1, elem); -- if (unlikely(r != 0)) { -- if (unlikely(r == -ENOSPC)) { -- qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n", -- __func__); -- } -+ dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); -+ if (unlikely(dev_written < 0)) { - goto out; - } - -- /* -- * We can poll here since we've had BQL from the time we sent the -- * descriptor. Also, we need to take the answer before SVQ pulls by itself, -- * when BQL is released -- */ -- dev_written = vhost_svq_poll(svq); - if (unlikely(dev_written < sizeof(status))) { - error_report("Insufficient written data (%zu)", dev_written); - goto out; -@@ -444,7 +461,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - - memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status)); - if (status != VIRTIO_NET_OK) { -- goto out; -+ return VIRTIO_NET_ERR; - } - - status = VIRTIO_NET_ERR; -@@ -461,7 +478,7 @@ out: - } - vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status))); - g_free(elem); -- return r; -+ return dev_written < 0 ? dev_written : 0; - } - - static const VhostShadowVirtqueueOps vhost_vdpa_net_svq_ops = { --- -2.27.0 - diff --git a/vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch b/vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch deleted file mode 100644 index 8695f98bfd06e9a19e14f0db38cb9d56fc58fc23..0000000000000000000000000000000000000000 --- a/vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 2038b0811acd3255d315354c8468bc565a51a4af Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 6 Sep 2022 17:07:15 +0200 -Subject: [PATCH] vdpa: extract vhost_vdpa_net_load_mac from - vhost_vdpa_net_load -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since there may be many commands we need to issue to load the NIC -state, let's split them in individual functions - -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 62 +++++++++++++++++++++++++++++++----------------- - 1 file changed, 40 insertions(+), 22 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 2700ef656f..15cd38b52e 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -373,12 +373,47 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len, - return vhost_svq_poll(svq); - } - -+static ssize_t vhost_vdpa_net_load_cmd(VhostVDPAState *s, uint8_t class, -+ uint8_t cmd, const void *data, -+ size_t data_size) -+{ -+ const struct virtio_net_ctrl_hdr ctrl = { -+ .class = class, -+ .cmd = cmd, -+ }; -+ -+ assert(data_size < vhost_vdpa_net_cvq_cmd_page_len() - sizeof(ctrl)); -+ -+ memcpy(s->cvq_cmd_out_buffer, &ctrl, sizeof(ctrl)); -+ memcpy(s->cvq_cmd_out_buffer + sizeof(ctrl), data, data_size); -+ -+ return vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + data_size, -+ sizeof(virtio_net_ctrl_ack)); -+} -+ -+static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n) -+{ -+ uint64_t features = n->parent_obj.guest_features; -+ if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) { -+ ssize_t dev_written = vhost_vdpa_net_load_cmd(s, VIRTIO_NET_CTRL_MAC, -+ VIRTIO_NET_CTRL_MAC_ADDR_SET, -+ n->mac, sizeof(n->mac)); -+ if (unlikely(dev_written < 0)) { -+ return dev_written; -+ } -+ -+ return *s->status != VIRTIO_NET_OK; -+ } -+ -+ return 0; -+} -+ - static int vhost_vdpa_net_load(NetClientState *nc) - { - VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); -- const struct vhost_vdpa *v = &s->vhost_vdpa; -+ struct vhost_vdpa *v = &s->vhost_vdpa; - const VirtIONet *n; -- uint64_t features; -+ int r; - - assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); - -@@ -387,26 +422,9 @@ static int vhost_vdpa_net_load(NetClientState *nc) - } - - n = VIRTIO_NET(v->dev->vdev); -- features = n->parent_obj.guest_features; -- if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) { -- const struct virtio_net_ctrl_hdr ctrl = { -- .class = VIRTIO_NET_CTRL_MAC, -- .cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET, -- }; -- char *cursor = s->cvq_cmd_out_buffer; -- ssize_t dev_written; -- -- memcpy(cursor, &ctrl, sizeof(ctrl)); -- cursor += sizeof(ctrl); -- memcpy(cursor, n->mac, sizeof(n->mac)); -- -- dev_written = vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + sizeof(n->mac), -- sizeof(virtio_net_ctrl_ack)); -- if (unlikely(dev_written < 0)) { -- return dev_written; -- } -- -- return *s->status != VIRTIO_NET_OK; -+ r = vhost_vdpa_net_load_mac(s, n); -+ if (unlikely(r < 0)) { -+ return r; - } - - return 0; --- -2.27.0 - diff --git a/vdpa-fix-VHOST_BACKEND_F_IOTLB_ASID-flag-check.patch b/vdpa-fix-VHOST_BACKEND_F_IOTLB_ASID-flag-check.patch deleted file mode 100644 index c2f2a8796d3214a54ecd7d62c069487126c11597..0000000000000000000000000000000000000000 --- a/vdpa-fix-VHOST_BACKEND_F_IOTLB_ASID-flag-check.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 404c9b2cb537a42be18a1b1aaf32df662ed951e0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 17 Jan 2023 11:53:08 +0100 -Subject: [PATCH] vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -VHOST_BACKEND_F_IOTLB_ASID is the feature bit, not the bitmask. Since -the device under test also provided VHOST_BACKEND_F_IOTLB_MSG_V2 and -VHOST_BACKEND_F_IOTLB_BATCH, this went unnoticed. - -Fixes: c1a1008685 ("vdpa: always start CVQ in SVQ mode if possible") -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index cdc54a7b54..a1b931ae2c 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -391,7 +391,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc) - g_strerror(errno), errno); - return -1; - } -- if (!(backend_features & VHOST_BACKEND_F_IOTLB_ASID) || -+ if (!(backend_features & BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID)) || - !vhost_vdpa_net_valid_svq_features(v->dev->features, NULL)) { - return 0; - } --- -2.27.0 - diff --git a/vdpa-fix-not-using-CVQ-buffer-in-case-of-error.patch b/vdpa-fix-not-using-CVQ-buffer-in-case-of-error.patch deleted file mode 100644 index 4603f6ed097c552433e845a09309a55a65fe42ec..0000000000000000000000000000000000000000 --- a/vdpa-fix-not-using-CVQ-buffer-in-case-of-error.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 5da8eddfa24d42a3ef60e111becafa29549e7100 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Fri, 2 Jun 2023 19:34:51 +0200 -Subject: [PATCH] vdpa: fix not using CVQ buffer in case of error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Bug introducing when refactoring. Otherway, the guest never received -the used buffer. - -Fixes: be4278b65fc1 ("vdpa: extract vhost_vdpa_net_cvq_add from vhost_vdpa_net_handle_ctrl_avail") -Signed-off-by: Eugenio Pérez -Message-Id: <20230602173451.1917999-1-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Acked-by: Jason Wang -Tested-by: Lei Yang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 94f74b54ae..afca8740bc 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -642,7 +642,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - } - - if (*s->status != VIRTIO_NET_OK) { -- return VIRTIO_NET_ERR; -+ goto out; - } - - status = VIRTIO_NET_ERR; --- -2.27.0 - diff --git a/vdpa-handle-VIRTIO_NET_CTRL_ANNOUNCE-in-vhost_vdpa_n.patch b/vdpa-handle-VIRTIO_NET_CTRL_ANNOUNCE-in-vhost_vdpa_n.patch deleted file mode 100644 index 7501a15d363d78f1eacb42a53db53fcf2554fab5..0000000000000000000000000000000000000000 --- a/vdpa-handle-VIRTIO_NET_CTRL_ANNOUNCE-in-vhost_vdpa_n.patch +++ /dev/null @@ -1,51 +0,0 @@ -From f6fa1b81efa3ac728a2c528b3c694d8cb5f932f1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 21 Dec 2022 12:50:14 +0100 -Subject: [PATCH] vdpa: handle VIRTIO_NET_CTRL_ANNOUNCE in - vhost_vdpa_net_handle_ctrl_avail -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since this capability is emulated by qemu shadowed CVQ cannot forward it -to the device. Process all that command within qemu. - -Signed-off-by: Eugenio Pérez -Message-Id: <20221221115015.1400889-4-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Acked-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 24c4c2ef51..48dd9d15f6 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -623,9 +623,18 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, - out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, - s->cvq_cmd_out_buffer, - vhost_vdpa_net_cvq_cmd_len()); -- dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); -- if (unlikely(dev_written < 0)) { -- goto out; -+ if (*(uint8_t *)s->cvq_cmd_out_buffer == VIRTIO_NET_CTRL_ANNOUNCE) { -+ /* -+ * Guest announce capability is emulated by qemu, so don't forward to -+ * the device. -+ */ -+ dev_written = sizeof(status); -+ *s->status = VIRTIO_NET_OK; -+ } else { -+ dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); -+ if (unlikely(dev_written < 0)) { -+ goto out; -+ } - } - - if (unlikely(dev_written < sizeof(status))) { --- -2.27.0 - diff --git a/vdpa-harden-the-error-path-if-get_iova_range-failed.patch b/vdpa-harden-the-error-path-if-get_iova_range-failed.patch deleted file mode 100644 index af79c277aebf3b147d85262bdfabd1c5115ca790..0000000000000000000000000000000000000000 --- a/vdpa-harden-the-error-path-if-get_iova_range-failed.patch +++ /dev/null @@ -1,39 +0,0 @@ -From fe4dd977b4dec6a089992566bda4b29136ed62c9 Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Sat, 24 Dec 2022 19:48:48 +0800 -Subject: [PATCH] vdpa: harden the error path if get_iova_range failed - -We should stop if the GET_IOVA_RANGE ioctl failed. - -Signed-off-by: Longpeng -Message-Id: <20221224114848.3062-3-longpeng2@huawei.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Acked-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 3c370f2dc5..fd5dc8c6aa 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -812,7 +812,13 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - return queue_pairs; - } - -- vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range); -+ r = vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range); -+ if (unlikely(r < 0)) { -+ error_setg(errp, "vhost-vdpa: get iova range failed: %s", -+ strerror(-r)); -+ goto err; -+ } -+ - if (opts->x_svq) { - if (!vhost_vdpa_net_valid_svq_features(features, errp)) { - goto err_svq; --- -2.27.0 - diff --git a/vdpa-implement-vdpa-device-migration.patch b/vdpa-implement-vdpa-device-migration.patch deleted file mode 100644 index ffc1d79586d2f3d9d24b6b1fea57c12de8b04182..0000000000000000000000000000000000000000 --- a/vdpa-implement-vdpa-device-migration.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 722147da4fb76c0ee6e75957712073a820ab1d75 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:59:56 +0800 -Subject: [PATCH] vdpa: implement vdpa device migration - -Integrate the live migration code, call the registered live -migration function, and open the vdpa live migration prototype - -Signed-off-by: libai -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vdpa-dev.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c -index 254a213117..986b5d0a78 100644 ---- a/hw/virtio/vdpa-dev.c -+++ b/hw/virtio/vdpa-dev.c -@@ -29,6 +29,8 @@ - #include "hw/virtio/vdpa-dev.h" - #include "sysemu/sysemu.h" - #include "sysemu/runstate.h" -+#include "hw/virtio/vdpa-dev-mig.h" -+#include "migration/migration.h" - - static void - vhost_vdpa_device_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq) -@@ -155,6 +157,8 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) - vhost_vdpa_device_dummy_handle_output); - } - -+ vdpa_migration_register(v); -+ - return; - - free_config: -@@ -174,6 +178,7 @@ static void vhost_vdpa_device_unrealize(DeviceState *dev) - VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); - int i; - -+ vdpa_migration_unregister(s); - virtio_set_status(vdev, 0); - - for (i = 0; i < s->num_queues; i++) { -@@ -306,6 +311,7 @@ static void vhost_vdpa_device_stop(VirtIODevice *vdev) - static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) - { - VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -+ MigrationState *ms = migrate_get_current(); - bool should_start = virtio_device_started(vdev, status); - Error *local_err = NULL; - int ret; -@@ -318,6 +324,11 @@ static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) - return; - } - -+ if (ms->state == RUN_STATE_PAUSED || -+ ms->state == RUN_STATE_RESTORE_VM) { -+ return; -+ } -+ - if (should_start) { - ret = vhost_vdpa_device_start(vdev, &local_err); - if (ret < 0) { -@@ -336,7 +347,7 @@ static Property vhost_vdpa_device_properties[] = { - - static const VMStateDescription vmstate_vhost_vdpa_device = { - .name = "vhost-vdpa-device", -- .unmigratable = 1, -+ .unmigratable = 0, - .minimum_version_id = 1, - .version_id = 1, - .fields = (VMStateField[]) { --- -2.27.0 - diff --git a/vdpa-manual-forward-CVQ-buffers.patch b/vdpa-manual-forward-CVQ-buffers.patch deleted file mode 100644 index 79e47ce9b3cd5b83abc3c77f70950f870d3a3ddc..0000000000000000000000000000000000000000 --- a/vdpa-manual-forward-CVQ-buffers.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 1fd9319e66153dc18bc4a6adfd81f1a0bc6d3a2f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:42 +0200 -Subject: [PATCH] vdpa: manual forward CVQ buffers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Do a simple forwarding of CVQ buffers, the same work SVQ could do but -through callbacks. No functional change intended. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 3 +- - include/hw/virtio/vhost-vdpa.h | 3 ++ - net/vhost-vdpa.c | 57 ++++++++++++++++++++++++++++++++++ - 3 files changed, 62 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 8e962f511d..31b58aec59 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -421,7 +421,8 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, - for (unsigned n = 0; n < hdev->nvqs; ++n) { - g_autoptr(VhostShadowVirtqueue) svq; - -- svq = vhost_svq_new(v->iova_tree, NULL, NULL); -+ svq = vhost_svq_new(v->iova_tree, v->shadow_vq_ops, -+ v->shadow_vq_ops_opaque); - if (unlikely(!svq)) { - error_setg(errp, "Cannot create svq %u", n); - return -1; -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index 7214eb47dc..1111d85643 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -15,6 +15,7 @@ - #include - - #include "hw/virtio/vhost-iova-tree.h" -+#include "hw/virtio/vhost-shadow-virtqueue.h" - #include "hw/virtio/virtio.h" - #include "standard-headers/linux/vhost_types.h" - -@@ -35,6 +36,8 @@ typedef struct vhost_vdpa { - /* IOVA mapping used by the Shadow Virtqueue */ - VhostIOVATree *iova_tree; - GPtrArray *shadow_vqs; -+ const VhostShadowVirtqueueOps *shadow_vq_ops; -+ void *shadow_vq_ops_opaque; - struct vhost_dev *dev; - VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; - } VhostVDPA; -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 7201c79116..53a14bc756 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -11,11 +11,13 @@ - - #include "qemu/osdep.h" - #include "clients.h" -+#include "hw/virtio/virtio-net.h" - #include "net/vhost_net.h" - #include "net/vhost-vdpa.h" - #include "hw/virtio/vhost-vdpa.h" - #include "qemu/config-file.h" - #include "qemu/error-report.h" -+#include "qemu/log.h" - #include "qemu/option.h" - #include "qapi/error.h" - #include -@@ -195,6 +197,57 @@ static NetClientInfo net_vhost_vdpa_info = { - .check_peer_type = vhost_vdpa_check_peer_type, - }; - -+/** -+ * Forward buffer for the moment. -+ */ -+static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, -+ VirtQueueElement *elem, -+ void *opaque) -+{ -+ unsigned int n = elem->out_num + elem->in_num; -+ g_autofree struct iovec *dev_buffers = g_new(struct iovec, n); -+ size_t in_len, dev_written; -+ virtio_net_ctrl_ack status = VIRTIO_NET_ERR; -+ int r; -+ -+ memcpy(dev_buffers, elem->out_sg, elem->out_num); -+ memcpy(dev_buffers + elem->out_num, elem->in_sg, elem->in_num); -+ -+ r = vhost_svq_add(svq, &dev_buffers[0], elem->out_num, &dev_buffers[1], -+ elem->in_num, elem); -+ if (unlikely(r != 0)) { -+ if (unlikely(r == -ENOSPC)) { -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n", -+ __func__); -+ } -+ goto out; -+ } -+ -+ /* -+ * We can poll here since we've had BQL from the time we sent the -+ * descriptor. Also, we need to take the answer before SVQ pulls by itself, -+ * when BQL is released -+ */ -+ dev_written = vhost_svq_poll(svq); -+ if (unlikely(dev_written < sizeof(status))) { -+ error_report("Insufficient written data (%zu)", dev_written); -+ } -+ -+out: -+ in_len = iov_from_buf(elem->in_sg, elem->in_num, 0, &status, -+ sizeof(status)); -+ if (unlikely(in_len < sizeof(status))) { -+ error_report("Bad device CVQ written length"); -+ } -+ vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status))); -+ g_free(elem); -+ return r; -+} -+ -+static const VhostShadowVirtqueueOps vhost_vdpa_net_svq_ops = { -+ .avail_handler = vhost_vdpa_net_handle_ctrl_avail, -+}; -+ - static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - const char *device, - const char *name, -@@ -219,6 +272,10 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - - s->vhost_vdpa.device_fd = vdpa_device_fd; - s->vhost_vdpa.index = queue_pair_index; -+ if (!is_datapath) { -+ s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops; -+ s->vhost_vdpa.shadow_vq_ops_opaque = s; -+ } - ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs); - if (ret) { - qemu_del_net_client(nc); --- -2.27.0 - diff --git a/vdpa-move-SVQ-vring-features-check-to-net.patch b/vdpa-move-SVQ-vring-features-check-to-net.patch deleted file mode 100644 index f5eca1afa7f9ec5fe6ea2b6897075cf713895c83..0000000000000000000000000000000000000000 --- a/vdpa-move-SVQ-vring-features-check-to-net.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 1d56b9b5446b79613ed1668a1afea19a9a7df875 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:39 +0100 -Subject: [PATCH] vdpa: move SVQ vring features check to net/ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The next patches will start control SVQ if possible. However, we don't -know if that will be possible at qemu boot anymore. - -Since the moved checks will be already evaluated at net/ to know if it -is ok to shadow CVQ, move them. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-8-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 32 ++------------------------------ - net/vhost-vdpa.c | 3 ++- - 2 files changed, 4 insertions(+), 31 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index c0e645ec13..59bfdbfc24 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -391,29 +391,9 @@ static int vhost_vdpa_get_dev_features(struct vhost_dev *dev, - return ret; - } - --static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, -- Error **errp) -+static void vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v) - { - g_autoptr(GPtrArray) shadow_vqs = NULL; -- uint64_t dev_features, svq_features; -- int r; -- bool ok; -- -- if (!v->shadow_vqs_enabled) { -- return 0; -- } -- -- r = vhost_vdpa_get_dev_features(hdev, &dev_features); -- if (r != 0) { -- error_setg_errno(errp, -r, "Can't get vdpa device features"); -- return r; -- } -- -- svq_features = dev_features; -- ok = vhost_svq_valid_features(svq_features, errp); -- if (unlikely(!ok)) { -- return -1; -- } - - shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free); - for (unsigned n = 0; n < hdev->nvqs; ++n) { -@@ -425,7 +405,6 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, - } - - v->shadow_vqs = g_steal_pointer(&shadow_vqs); -- return 0; - } - - static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) -@@ -450,10 +429,7 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) - dev->opaque = opaque ; - v->listener = vhost_vdpa_memory_listener; - v->msg_type = VHOST_IOTLB_MSG_V2; -- ret = vhost_vdpa_init_svq(dev, v, errp); -- if (ret) { -- goto err; -- } -+ vhost_vdpa_init_svq(dev, v); - - if (!vhost_vdpa_first_dev(dev)) { - return 0; -@@ -463,10 +439,6 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) - VIRTIO_CONFIG_S_DRIVER); - - return 0; -- --err: -- ram_block_discard_disable(false); -- return ret; - } - - static void vhost_vdpa_host_notifier_uninit(struct vhost_dev *dev, -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index be056a2553..e250d34462 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -116,9 +116,10 @@ static bool vhost_vdpa_net_valid_svq_features(uint64_t features, Error **errp) - if (invalid_dev_features) { - error_setg(errp, "vdpa svq does not work with features 0x%" PRIx64, - invalid_dev_features); -+ return false; - } - -- return !invalid_dev_features; -+ return vhost_svq_valid_features(features, errp); - } - - static int vhost_vdpa_net_check_device_id(struct vhost_net *net) --- -2.27.0 - diff --git a/vdpa-move-memory-listener-to-the-realize-stage.patch b/vdpa-move-memory-listener-to-the-realize-stage.patch deleted file mode 100644 index b762409f80c54c62452261f93903341edcbe8ff7..0000000000000000000000000000000000000000 --- a/vdpa-move-memory-listener-to-the-realize-stage.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 232ee383f3a2363bdc8f1bde873740375b5b92bb Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 16:01:16 +0800 -Subject: [PATCH] vdpa: move memory listener to the realize stage - -Move the memory listener registration of vdpa from the start stage -to the realize stage. Avoid that in the start phase, the memory -listener callback function has not yet been processed. - -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vdpa-dev.c | 4 ++++ - hw/virtio/vhost-vdpa.c | 8 -------- - 2 files changed, 4 insertions(+), 8 deletions(-) - -diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c -index 986b5d0a78..143dadc88d 100644 ---- a/hw/virtio/vdpa-dev.c -+++ b/hw/virtio/vdpa-dev.c -@@ -31,6 +31,7 @@ - #include "sysemu/runstate.h" - #include "hw/virtio/vdpa-dev-mig.h" - #include "migration/migration.h" -+#include "exec/address-spaces.h" - - static void - vhost_vdpa_device_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq) -@@ -126,6 +127,7 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) - goto free_vqs; - } - -+ memory_listener_register(&v->vdpa.listener, &address_space_memory); - v->config_size = vhost_vdpa_device_get_u32(v->vhostfd, - VHOST_VDPA_GET_CONFIG_SIZE, - errp); -@@ -164,6 +166,7 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) - free_config: - g_free(v->config); - vhost_cleanup: -+ memory_listener_unregister(&v->vdpa.listener); - vhost_dev_cleanup(&v->dev); - free_vqs: - g_free(vqs); -@@ -189,6 +192,7 @@ static void vhost_vdpa_device_unrealize(DeviceState *dev) - - g_free(s->config); - g_free(s->dev.vqs); -+ memory_listener_unregister(&s->vdpa.listener); - vhost_dev_cleanup(&s->dev); - qemu_close(s->vhostfd); - s->vhostfd = -1; -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 7688dc0eba..c7aaff7f20 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1100,7 +1100,6 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev) - - static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) - { -- struct vhost_vdpa *v = dev->opaque; - bool ok; - trace_vhost_vdpa_dev_start(dev, started); - -@@ -1121,14 +1120,11 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) - } - - if (started) { -- memory_listener_register(&v->listener, &address_space_memory); - return vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); - } else { - vhost_vdpa_reset_device(dev); - vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE | - VIRTIO_CONFIG_S_DRIVER); -- memory_listener_unregister(&v->listener); -- - return 0; - } - } -@@ -1320,7 +1316,6 @@ static unsigned int vhost_vdpa_get_used_memslots(void) - - static int vhost_vdpa_suspend_device(struct vhost_dev *dev) - { -- struct vhost_vdpa *v = dev->opaque; - int ret; - - vhost_vdpa_svqs_stop(dev); -@@ -1331,13 +1326,11 @@ static int vhost_vdpa_suspend_device(struct vhost_dev *dev) - } - - ret = vhost_vdpa_call(dev, VHOST_VDPA_SUSPEND, NULL); -- memory_listener_unregister(&v->listener); - return ret; - } - - static int vhost_vdpa_resume_device(struct vhost_dev *dev) - { -- struct vhost_vdpa *v = dev->opaque; - bool ok; - - vhost_vdpa_host_notifiers_init(dev); -@@ -1351,7 +1344,6 @@ static int vhost_vdpa_resume_device(struct vhost_dev *dev) - return 0; - } - -- memory_listener_register(&v->listener, &address_space_memory); - return vhost_vdpa_call(dev, VHOST_VDPA_RESUME, NULL); - } - --- -2.27.0 - diff --git a/vdpa-net-block-migration-if-the-device-has-CVQ.patch b/vdpa-net-block-migration-if-the-device-has-CVQ.patch deleted file mode 100644 index a700f8d40ce368ca9620863ddc179cc23f25b6f8..0000000000000000000000000000000000000000 --- a/vdpa-net-block-migration-if-the-device-has-CVQ.patch +++ /dev/null @@ -1,70 +0,0 @@ -From d97454d68f90b441d3fa19c496a7fe6916f50e31 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Fri, 3 Mar 2023 18:24:41 +0100 -Subject: [PATCH] vdpa net: block migration if the device has CVQ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Devices with CVQ need to migrate state beyond vq state. Leaving this to -future series. - -Signed-off-by: Eugenio Pérez -Message-Id: <20230303172445.1089785-11-eperezma@redhat.com> -Tested-by: Lei Yang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 1 + - include/hw/virtio/vhost-vdpa.h | 1 + - net/vhost-vdpa.c | 9 +++++++++ - 3 files changed, 11 insertions(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index f5d816f5ec..dd1ba8878c 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -450,6 +450,7 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) - v->msg_type = VHOST_IOTLB_MSG_V2; - vhost_vdpa_init_svq(dev, v); - -+ error_propagate(&dev->migration_blocker, v->migration_blocker); - if (!vhost_vdpa_first_dev(dev)) { - return 0; - } -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index 7997f09a8d..620a0f70ab 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -48,6 +48,7 @@ typedef struct vhost_vdpa { - const VhostShadowVirtqueueOps *shadow_vq_ops; - void *shadow_vq_ops_opaque; - struct vhost_dev *dev; -+ Error *migration_blocker; - VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; - } VhostVDPA; - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 8192045735..dc1b4c4be2 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -721,6 +721,15 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - - s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops; - s->vhost_vdpa.shadow_vq_ops_opaque = s; -+ -+ /* -+ * TODO: We cannot migrate devices with CVQ as there is no way to set -+ * the device state (MAC, MQ, etc) before starting the datapath. -+ * -+ * Migration blocker ownership now belongs to s->vhost_vdpa. -+ */ -+ error_setg(&s->vhost_vdpa.migration_blocker, -+ "net vdpa cannot migrate with CVQ feature"); - } - ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs); - if (ret) { --- -2.27.0 - diff --git a/vdpa-request-iova_range-only-once.patch b/vdpa-request-iova_range-only-once.patch deleted file mode 100644 index c9ce07a79a367e05fdf93ece448ef3f649c6a002..0000000000000000000000000000000000000000 --- a/vdpa-request-iova_range-only-once.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 5ff455d55b2d58a726d2557076e0f5401496de02 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:38 +0100 -Subject: [PATCH] vdpa: request iova_range only once -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently iova range is requested once per queue pair in the case of -net. Reduce the number of ioctls asking it once at initialization and -reusing that value for each vhost_vdpa. - -Signed-off-by: Eugenio Pérez -Message-Id: <20221215113144.322011-7-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Acked-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 15 --------------- - net/vhost-vdpa.c | 27 ++++++++++++++------------- - 2 files changed, 14 insertions(+), 28 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 23e715b05c..c0e645ec13 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -367,19 +367,6 @@ static int vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status) - return 0; - } - --static void vhost_vdpa_get_iova_range(struct vhost_vdpa *v) --{ -- int ret = vhost_vdpa_call(v->dev, VHOST_VDPA_GET_IOVA_RANGE, -- &v->iova_range); -- if (ret != 0) { -- v->iova_range.first = 0; -- v->iova_range.last = UINT64_MAX; -- } -- -- trace_vhost_vdpa_get_iova_range(v->dev, v->iova_range.first, -- v->iova_range.last); --} -- - /* - * The use of this function is for requests that only need to be - * applied once. Typically such request occurs at the beginning -@@ -468,8 +455,6 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) - goto err; - } - -- vhost_vdpa_get_iova_range(v); -- - if (!vhost_vdpa_first_dev(dev)) { - return 0; - } -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 217d2545c1..be056a2553 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -548,14 +548,15 @@ static const VhostShadowVirtqueueOps vhost_vdpa_net_svq_ops = { - }; - - static NetClientState *net_vhost_vdpa_init(NetClientState *peer, -- const char *device, -- const char *name, -- int vdpa_device_fd, -- int queue_pair_index, -- int nvqs, -- bool is_datapath, -- bool svq, -- VhostIOVATree *iova_tree) -+ const char *device, -+ const char *name, -+ int vdpa_device_fd, -+ int queue_pair_index, -+ int nvqs, -+ bool is_datapath, -+ bool svq, -+ struct vhost_vdpa_iova_range iova_range, -+ VhostIOVATree *iova_tree) - { - NetClientState *nc = NULL; - VhostVDPAState *s; -@@ -574,6 +575,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - s->vhost_vdpa.device_fd = vdpa_device_fd; - s->vhost_vdpa.index = queue_pair_index; - s->vhost_vdpa.shadow_vqs_enabled = svq; -+ s->vhost_vdpa.iova_range = iova_range; - s->vhost_vdpa.iova_tree = iova_tree; - if (!is_datapath) { - s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size, -@@ -653,6 +655,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - int vdpa_device_fd; - g_autofree NetClientState **ncs = NULL; - g_autoptr(VhostIOVATree) iova_tree = NULL; -+ struct vhost_vdpa_iova_range iova_range; - NetClientState *nc; - int queue_pairs, r, i = 0, has_cvq = 0; - -@@ -696,14 +699,12 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - return queue_pairs; - } - -+ vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range); - if (opts->x_svq) { -- struct vhost_vdpa_iova_range iova_range; -- - if (!vhost_vdpa_net_valid_svq_features(features, errp)) { - goto err_svq; - } - -- vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range); - iova_tree = vhost_iova_tree_new(iova_range.first, iova_range.last); - } - -@@ -712,7 +713,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - for (i = 0; i < queue_pairs; i++) { - ncs[i] = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, - vdpa_device_fd, i, 2, true, opts->x_svq, -- iova_tree); -+ iova_range, iova_tree); - if (!ncs[i]) - goto err; - } -@@ -720,7 +721,7 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - if (has_cvq) { - nc = net_vhost_vdpa_init(peer, TYPE_VHOST_VDPA, name, - vdpa_device_fd, i, 1, false, -- opts->x_svq, iova_tree); -+ opts->x_svq, iova_range, iova_tree); - if (!nc) - goto err; - } --- -2.27.0 - diff --git a/vdpa-set-vring-enable-only-if-the-vring-address-has-.patch b/vdpa-set-vring-enable-only-if-the-vring-address-has-.patch deleted file mode 100644 index f3bc7b5c071d57a7a6016280c73570cc2e1e73ab..0000000000000000000000000000000000000000 --- a/vdpa-set-vring-enable-only-if-the-vring-address-has-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 11c0e08a95c35adec07e3b40d1bd9452d7113236 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 14 Dec 2023 11:05:52 +0800 -Subject: [PATCH] vdpa: set vring enable only if the vring address has already - been set - -Currently, vhost-vdpa does not determine the status of each vring when -performing the enable operation on vring. When the vBIOS(EDK2) is running, -the driver will not enable all vrings. In this case, setting all vrings -to enable is isconsistent with the actual situation. - -Add logic when enabling vring, make a judement on the vring status. If the -vring address is not set, the vring will not enabled. - -Signed-off-by: jiangdongxu ---- - hw/virtio/vhost-vdpa.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index c7aaff7f20..36ed0c9a99 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -714,8 +714,17 @@ static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx) - static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev) - { - int i; -+ int idx; -+ hwaddr addr; -+ - trace_vhost_vdpa_set_vring_ready(dev); - for (i = 0; i < dev->nvqs; ++i) { -+ idx = vhost_vdpa_get_vq_index(dev, dev->vq_index + i); -+ addr = virtio_queue_get_desc_addr(dev->vdev, idx); -+ if (addr == 0) { -+ continue; -+ } -+ - struct vhost_vring_state state = { - .index = dev->vq_index + i, - .num = 1, --- -2.27.0 - diff --git a/vdpa-stop-all-svq-on-device-deletion.patch b/vdpa-stop-all-svq-on-device-deletion.patch deleted file mode 100644 index a6cb17e1ceb2b3c29d73c1ee89429e5f006cfa10..0000000000000000000000000000000000000000 --- a/vdpa-stop-all-svq-on-device-deletion.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 6b9c4a2607b88faf611da724ead81dc89a7b185b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 9 Feb 2023 18:00:04 +0100 -Subject: [PATCH] vdpa: stop all svq on device deletion -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Not stopping them leave the device in a bad state when virtio-net -fronted device is unplugged with device_del monitor command. - -This is not triggable in regular poweroff or qemu forces shutdown -because cleanup is called right after vhost_vdpa_dev_start(false). But -devices hot unplug does not call vdpa device cleanups. This lead to all -the vhost_vdpa devices without stop the SVQ but the last. - -Fix it and clean the code, making it symmetric with -vhost_vdpa_svqs_start. - -Fixes: dff4426fa656 ("vhost: Add Shadow VirtQueue kick forwarding capabilities") -Reported-by: Lei Yang -Signed-off-by: Eugenio Pérez -Message-Id: <20230209170004.899472-1-eperezma@redhat.com> -Tested-by: Laurent Vivier -Acked-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 17 ++--------------- - 1 file changed, 2 insertions(+), 15 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index dd1ba8878c..986fc795bf 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -692,26 +692,11 @@ static int vhost_vdpa_get_device_id(struct vhost_dev *dev, - return ret; - } - --static void vhost_vdpa_reset_svq(struct vhost_vdpa *v) --{ -- if (!v->shadow_vqs_enabled) { -- return; -- } -- -- for (unsigned i = 0; i < v->shadow_vqs->len; ++i) { -- VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -- vhost_svq_stop(svq); -- } --} -- - static int vhost_vdpa_reset_device(struct vhost_dev *dev) - { -- struct vhost_vdpa *v = dev->opaque; - int ret; - uint8_t status = 0; - -- vhost_vdpa_reset_svq(v); -- - ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status); - trace_vhost_vdpa_reset_device(dev, status); - return ret; -@@ -1103,6 +1088,8 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev) - - for (unsigned i = 0; i < v->shadow_vqs->len; ++i) { - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -+ -+ vhost_svq_stop(svq); - vhost_vdpa_svq_unmap_rings(dev, svq); - - event_notifier_cleanup(&svq->hdev_kick); --- -2.27.0 - diff --git a/vdpa-store-x-svq-parameter-in-VhostVDPAState.patch b/vdpa-store-x-svq-parameter-in-VhostVDPAState.patch deleted file mode 100644 index 96f5eae20d9c684c507cad2afd32ad0b59478cbf..0000000000000000000000000000000000000000 --- a/vdpa-store-x-svq-parameter-in-VhostVDPAState.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 7a2278d9cdd9ac2a74bb9745fdf555395ff8dcd7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:42 +0100 -Subject: [PATCH] vdpa: store x-svq parameter in VhostVDPAState -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -CVQ can be shadowed two ways: -- Device has x-svq=on parameter (current way) -- The device can isolate CVQ in its own vq group - -QEMU needs to check for the second condition dynamically, because CVQ -index is not known before the driver ack the features. Since this is -dynamic, the CVQ isolation could vary with different conditions, making -it possible to go from "not isolated group" to "isolated". - -Saving the cmdline parameter in an extra field so we never disable CVQ -SVQ in case the device was started with x-svq cmdline. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-11-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index cb1cc2523d..7adba2c2b6 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -37,6 +37,8 @@ typedef struct VhostVDPAState { - void *cvq_cmd_out_buffer; - virtio_net_ctrl_ack *status; - -+ /* The device always have SVQ enabled */ -+ bool always_svq; - bool started; - } VhostVDPAState; - -@@ -575,6 +577,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, - - s->vhost_vdpa.device_fd = vdpa_device_fd; - s->vhost_vdpa.index = queue_pair_index; -+ s->always_svq = svq; - s->vhost_vdpa.shadow_vqs_enabled = svq; - s->vhost_vdpa.iova_range = iova_range; - s->vhost_vdpa.iova_tree = iova_tree; --- -2.27.0 - diff --git a/vdpa-support-vdpa-device-suspend-resume.patch b/vdpa-support-vdpa-device-suspend-resume.patch deleted file mode 100644 index 2c94e7a3981817194eadeafebf100a7798dbdeba..0000000000000000000000000000000000000000 --- a/vdpa-support-vdpa-device-suspend-resume.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 06bb2d68ef70813167a633aa00779acf61c784b0 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Tue, 19 Dec 2023 20:18:03 +0800 -Subject: [PATCH] vdpa: support vdpa device suspend/resume - -commit a21603f7ecfa 'vhost: implement vhost_vdpa_device_suspend/resume' -only implement suspend and resume interface used for migration. The -current implementation still has bugs when suspend/resume a virtual -machine. Fix it. - -Signed-off-by: jiangdongxu ---- - hw/virtio/vdpa-dev-mig.c | 16 +++++++++++----- - hw/virtio/vdpa-dev.c | 8 +------- - include/hw/virtio/vdpa-dev.h | 1 + - 3 files changed, 13 insertions(+), 12 deletions(-) - -diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c -index c71e71fd64..4a45821892 100644 ---- a/hw/virtio/vdpa-dev-mig.c -+++ b/hw/virtio/vdpa-dev-mig.c -@@ -149,6 +149,7 @@ static int vhost_vdpa_device_suspend(VhostVdpaDevice *vdpa) - } - - vdpa->started = false; -+ vdpa->suspended = true; - - ret = vhost_dev_suspend(&vdpa->dev, vdev, false); - if (ret) { -@@ -171,6 +172,7 @@ set_guest_notifiers_fail: - } - - suspend_fail: -+ vdpa->suspended = false; - vdpa->started = true; - return ret; - } -@@ -207,6 +209,7 @@ static int vhost_vdpa_device_resume(VhostVdpaDevice *vdpa) - goto err_guest_notifiers; - } - vdpa->started = true; -+ vdpa->suspended = false; - - /* - * guest_notifier_mask/pending not used yet, so just unmask -@@ -247,7 +250,7 @@ static void vdpa_dev_vmstate_change(void *opaque, bool running, RunState state) - MigrationIncomingState *mis = migration_incoming_get_current(); - - if (!running) { -- if (ms->state == RUN_STATE_PAUSED) { -+ if (ms->state == MIGRATION_STATUS_ACTIVE || state == RUN_STATE_PAUSED) { - ret = vhost_vdpa_device_suspend(vdpa); - if (ret) { - error_report("suspend vdpa device failed: %d\n", ret); -@@ -257,16 +260,19 @@ static void vdpa_dev_vmstate_change(void *opaque, bool running, RunState state) - } - } - } else { -- if (ms->state == RUN_STATE_RESTORE_VM) { -+ if (vdpa->suspended) { - ret = vhost_vdpa_device_resume(vdpa); - if (ret) { -- error_report("migration dest resume device failed, abort!\n"); -- exit(EXIT_FAILURE); -+ error_report("vhost vdpa device resume failed: %d\n", ret); - } - } - - if (mis->state == RUN_STATE_RESTORE_VM) { -- vhost_vdpa_call(hdev, VHOST_VDPA_RESUME, NULL); -+ ret = vhost_vdpa_call(hdev, VHOST_VDPA_RESUME, NULL); -+ if (ret) { -+ error_report("migration dest resume device failed: %d\n", ret); -+ exit(EXIT_FAILURE); -+ } - /* post resume */ - mis->bh = qemu_bh_new(vdpa_dev_migration_handle_incoming_bh, - hdev); -diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c -index 143dadc88d..04d8e96a5d 100644 ---- a/hw/virtio/vdpa-dev.c -+++ b/hw/virtio/vdpa-dev.c -@@ -315,7 +315,6 @@ static void vhost_vdpa_device_stop(VirtIODevice *vdev) - static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) - { - VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); -- MigrationState *ms = migrate_get_current(); - bool should_start = virtio_device_started(vdev, status); - Error *local_err = NULL; - int ret; -@@ -324,12 +323,7 @@ static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) - should_start = false; - } - -- if (s->started == should_start) { -- return; -- } -- -- if (ms->state == RUN_STATE_PAUSED || -- ms->state == RUN_STATE_RESTORE_VM) { -+ if (s->started == should_start || s->suspended) { - return; - } - -diff --git a/include/hw/virtio/vdpa-dev.h b/include/hw/virtio/vdpa-dev.h -index 20f50c76c6..60e9c3f3fe 100644 ---- a/include/hw/virtio/vdpa-dev.h -+++ b/include/hw/virtio/vdpa-dev.h -@@ -37,6 +37,7 @@ struct VhostVdpaDevice { - int config_size; - uint16_t queue_size; - bool started; -+ bool suspended; - int (*post_init)(VhostVdpaDevice *v, Error **errp); - VMChangeStateEntry *vmstate; - Notifier migration_state; --- -2.27.0 - diff --git a/vdpa-suspend-function-return-0-when-the-vdpa-device-.patch b/vdpa-suspend-function-return-0-when-the-vdpa-device-.patch deleted file mode 100644 index 2c3c44a10a0957a8d9dcb9e74f74a8b947071a56..0000000000000000000000000000000000000000 --- a/vdpa-suspend-function-return-0-when-the-vdpa-device-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From bd3f62a0df7be244dcd7dab0632883354c476f17 Mon Sep 17 00:00:00 2001 -From: jiangdongxu -Date: Thu, 21 Dec 2023 11:03:37 +0800 -Subject: [PATCH] vdpa: suspend function return 0 when the vdpa device is - stopped - -When vhost vdpa device is stopped(vdpa->started is false), suspend -operation do nothing and return success, instead of return failure. - -The same goes for resume function. - -Signed-off-by: jiangdongxu ---- - hw/virtio/vdpa-dev-mig.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c -index 9cd80f92eb..679d37b182 100644 ---- a/hw/virtio/vdpa-dev-mig.c -+++ b/hw/virtio/vdpa-dev-mig.c -@@ -140,8 +140,8 @@ static int vhost_vdpa_device_suspend(VhostVdpaDevice *vdpa) - VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); - int ret; - -- if (!vdpa->started) { -- return -EFAULT; -+ if (!vdpa->started || vdpa->suspended) { -+ return 0; - } - - if (!k->set_guest_notifiers) { -@@ -184,6 +184,10 @@ static int vhost_vdpa_device_resume(VhostVdpaDevice *vdpa) - VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); - int i, ret; - -+ if (vdpa->started || !vdpa->suspended) { -+ return 0; -+ } -+ - if (!k->set_guest_notifiers) { - error_report("binding does not support guest notifiers\n"); - return -ENOSYS; --- -2.27.0 - diff --git a/vdpa-use-v-shadow_vqs_enabled-in-vhost_vdpa_svqs_sta.patch b/vdpa-use-v-shadow_vqs_enabled-in-vhost_vdpa_svqs_sta.patch deleted file mode 100644 index 2b22c8e5daceef0d56ccbbb9de8e621e9caed1ec..0000000000000000000000000000000000000000 --- a/vdpa-use-v-shadow_vqs_enabled-in-vhost_vdpa_svqs_sta.patch +++ /dev/null @@ -1,50 +0,0 @@ -From f2a41f2f0f16402772009efc8eac5e9a08fea0b3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:33 +0100 -Subject: [PATCH] vdpa: use v->shadow_vqs_enabled in vhost_vdpa_svqs_start & - stop -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This function used to trust in v->shadow_vqs != NULL to know if it must -start svq or not. - -This is not going to be valid anymore, as qemu is going to allocate svq -array unconditionally (but it will only start them conditionally). - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-2-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 0f07c85b91..08f92bf781 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1031,7 +1031,7 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) - Error *err = NULL; - unsigned i; - -- if (!v->shadow_vqs) { -+ if (!v->shadow_vqs_enabled) { - return true; - } - -@@ -1084,7 +1084,7 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev) - { - struct vhost_vdpa *v = dev->opaque; - -- if (!v->shadow_vqs) { -+ if (!v->shadow_vqs_enabled) { - return; - } - --- -2.27.0 - diff --git a/vdpa-validate-MQ-CVQ-commands.patch b/vdpa-validate-MQ-CVQ-commands.patch deleted file mode 100644 index 42627c177e37d5f16813ba172c191d57c7aa512a..0000000000000000000000000000000000000000 --- a/vdpa-validate-MQ-CVQ-commands.patch +++ /dev/null @@ -1,41 +0,0 @@ -From c9aa596ad26ee9fa1d4f7433485a668e3485d4ca Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 6 Sep 2022 17:07:17 +0200 -Subject: [PATCH] vdpa: validate MQ CVQ commands -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -So we are sure we can update the device model properly before sending to -the device. - -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index b32fe5e68a..831709a270 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -494,6 +494,15 @@ static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len) - __func__, ctrl.cmd); - }; - break; -+ case VIRTIO_NET_CTRL_MQ: -+ switch (ctrl.cmd) { -+ case VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET: -+ return true; -+ default: -+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mq cmd %u\n", -+ __func__, ctrl.cmd); -+ }; -+ break; - default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid control class %u\n", - __func__, ctrl.class); --- -2.27.0 - diff --git a/vfio-Add-vfio_prereg_listener_global_log_start-stop-.patch b/vfio-Add-vfio_prereg_listener_global_log_start-stop-.patch deleted file mode 100644 index 962266210c9ed50027a893c453b59313f4fedc56..0000000000000000000000000000000000000000 --- a/vfio-Add-vfio_prereg_listener_global_log_start-stop-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 287c63ab540533f1f9642e753c091caa7e6e2511 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 11 May 2021 10:08:15 +0800 -Subject: [PATCH] vfio: Add vfio_prereg_listener_global_log_start/stop in - nested stage - -In nested mode, we set up the stage 2 and stage 1 separately. In my -opinion, vfio_memory_prereg_listener is used for stage 2 and -vfio_memory_listener is used for stage 1. So it feels weird to call -the global_log_start/stop interface in vfio_memory_listener to switch -dirty tracking, although this won't cause any errors. Add -global_log_start/stop interface in vfio_memory_prereg_listener -can separate stage 2 from stage 1. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 20c820aa74..65f3979492 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1501,6 +1501,17 @@ static void vfio_listener_log_global_start(MemoryListener *listener) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); - -+ /* For nested mode, vfio_prereg_listener is used to start dirty tracking */ -+ if (container->iommu_type != VFIO_TYPE1_NESTING_IOMMU) { -+ vfio_set_dirty_page_tracking(container, true); -+ } -+} -+ -+static void vfio_prereg_listener_log_global_start(MemoryListener *listener) -+{ -+ VFIOContainer *container = -+ container_of(listener, VFIOContainer, prereg_listener); -+ - vfio_set_dirty_page_tracking(container, true); - } - -@@ -1508,6 +1519,17 @@ static void vfio_listener_log_global_stop(MemoryListener *listener) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); - -+ /* For nested mode, vfio_prereg_listener is used to stop dirty tracking */ -+ if (container->iommu_type != VFIO_TYPE1_NESTING_IOMMU) { -+ vfio_set_dirty_page_tracking(container, false); -+ } -+} -+ -+static void vfio_prereg_listener_log_global_stop(MemoryListener *listener) -+{ -+ VFIOContainer *container = -+ container_of(listener, VFIOContainer, prereg_listener); -+ - vfio_set_dirty_page_tracking(container, false); - } - -@@ -1922,6 +1944,8 @@ static const MemoryListener vfio_memory_listener = { - static MemoryListener vfio_memory_prereg_listener = { - .region_add = vfio_prereg_listener_region_add, - .region_del = vfio_prereg_listener_region_del, -+ .log_global_start = vfio_prereg_listener_log_global_start, -+ .log_global_stop = vfio_prereg_listener_log_global_stop, - .log_sync = vfio_prereg_listener_log_sync, - .log_clear = vfio_prereg_listener_log_clear, - }; --- -2.27.0 - diff --git a/vfio-Add-vfio_prereg_listener_log_clear-to-re-enable.patch b/vfio-Add-vfio_prereg_listener_log_clear-to-re-enable.patch deleted file mode 100644 index a055ed555f3a7fa213a8c16b4983a139de590ec0..0000000000000000000000000000000000000000 --- a/vfio-Add-vfio_prereg_listener_log_clear-to-re-enable.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 7086df6d90cd698a3e20cf4cf6e9a834f168cd8f Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Sat, 31 Jul 2021 09:40:24 +0800 -Subject: [PATCH] vfio: Add vfio_prereg_listener_log_clear to re-enable mark - dirty pages - -When tracking dirty pages, we just need to pay attention to stage 2 -mappings. Legacy vfio_listener_log_clear cannot be used in nested -stage. This patch adds vfio_prereg_listener_log_clear to re-enable -dirty pages in nested mode. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 40 +++++++++++++++++++++++++++++++++++++++- - 1 file changed, 39 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 2506cd57ee..20c820aa74 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1857,6 +1857,43 @@ static int vfio_physical_log_clear(VFIOContainer *container, - return ret; - } - -+static void vfio_prereg_listener_log_clear(MemoryListener *listener, -+ MemoryRegionSection *section) -+{ -+ VFIOContainer *container = -+ container_of(listener, VFIOContainer, prereg_listener); -+ -+ if (!memory_region_is_ram(section->mr)) { -+ return; -+ } -+ -+ vfio_physical_log_clear(container, section); -+} -+ -+static int vfio_clear_dirty_bitmap(VFIOContainer *container, -+ MemoryRegionSection *section) -+{ -+ if (memory_region_is_iommu(section->mr)) { -+ /* -+ * In nested mode, stage 2 (gpa->hpa) and stage 1 (giova->gpa) are -+ * set up separately. It is inappropriate to pass 'giova' to kernel -+ * to get dirty pages. We only need to focus on stage 2 mapping when -+ * marking dirty pages. -+ */ -+ if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -+ return 0; -+ } -+ -+ /* -+ * TODO: x86. With the log_clear() interface added, x86 may inplement -+ * its own method. -+ */ -+ } -+ -+ /* Here we assume that memory_region_is_ram(section->mr) == true */ -+ return vfio_physical_log_clear(container, section); -+} -+ - static void vfio_listener_log_clear(MemoryListener *listener, - MemoryRegionSection *section) - { -@@ -1868,7 +1905,7 @@ static void vfio_listener_log_clear(MemoryListener *listener, - } - - if (vfio_devices_all_dirty_tracking(container)) { -- vfio_physical_log_clear(container, section); -+ vfio_clear_dirty_bitmap(container, section); - } - } - -@@ -1886,6 +1923,7 @@ static MemoryListener vfio_memory_prereg_listener = { - .region_add = vfio_prereg_listener_region_add, - .region_del = vfio_prereg_listener_region_del, - .log_sync = vfio_prereg_listener_log_sync, -+ .log_clear = vfio_prereg_listener_log_clear, - }; - - static void vfio_listener_release(VFIOContainer *container) --- -2.27.0 - diff --git a/vfio-Add-vfio_prereg_listener_log_sync-in-nested-sta.patch b/vfio-Add-vfio_prereg_listener_log_sync-in-nested-sta.patch deleted file mode 100644 index b1df5a3801a75edaedde9968fbb8db92713dfbd5..0000000000000000000000000000000000000000 --- a/vfio-Add-vfio_prereg_listener_log_sync-in-nested-sta.patch +++ /dev/null @@ -1,74 +0,0 @@ -From f4523389bf57593484308124e06d67855bb79315 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 11 May 2021 10:08:14 +0800 -Subject: [PATCH] vfio: Add vfio_prereg_listener_log_sync in nested stage - -In nested mode, we set up the stage 2 (gpa->hpa)and stage 1 -(giova->gpa) separately by vfio_prereg_listener_region_add() -and vfio_listener_region_add(). So when marking dirty pages -we just need to pay attention to stage 2 mappings. - -Legacy vfio_listener_log_sync cannot be used in nested stage. -This patch adds vfio_prereg_listener_log_sync to mark dirty -pages in nested mode. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 6136b1ef61..2506cd57ee 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1579,6 +1579,22 @@ static int vfio_dma_sync_ram_section_dirty_bitmap(VFIOContainer *container, - int128_get64(section->size), ram_addr); - } - -+static void vfio_prereg_listener_log_sync(MemoryListener *listener, -+ MemoryRegionSection *section) -+{ -+ VFIOContainer *container = -+ container_of(listener, VFIOContainer, prereg_listener); -+ -+ if (!memory_region_is_ram(section->mr) || -+ !container->dirty_pages_supported) { -+ return; -+ } -+ -+ if (vfio_devices_all_dirty_tracking(container)) { -+ vfio_dma_sync_ram_section_dirty_bitmap(container, section); -+ } -+} -+ - typedef struct { - IOMMUNotifier n; - VFIOGuestIOMMU *giommu; -@@ -1666,6 +1682,16 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container, - if (memory_region_is_iommu(section->mr)) { - VFIOGuestIOMMU *giommu; - -+ /* -+ * In nested mode, stage 2 (gpa->hpa) and stage 1 (giova->gpa) are -+ * set up separately. It is inappropriate to pass 'giova' to kernel -+ * to get dirty pages. We only need to focus on stage 2 mapping when -+ * marking dirty pages. -+ */ -+ if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -+ return 0; -+ } -+ - QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) { - if (MEMORY_REGION(giommu->iommu) == section->mr && - giommu->n.start == section->offset_within_region) { -@@ -1859,6 +1885,7 @@ static const MemoryListener vfio_memory_listener = { - static MemoryListener vfio_memory_prereg_listener = { - .region_add = vfio_prereg_listener_region_add, - .region_del = vfio_prereg_listener_region_del, -+ .log_sync = vfio_prereg_listener_log_sync, - }; - - static void vfio_listener_release(VFIOContainer *container) --- -2.27.0 - diff --git a/vfio-Fix-vfio_get_dev_region-trace-event.patch b/vfio-Fix-vfio_get_dev_region-trace-event.patch deleted file mode 100644 index c165db9ba7e653d02893c32fb10a8adda6b255a0..0000000000000000000000000000000000000000 --- a/vfio-Fix-vfio_get_dev_region-trace-event.patch +++ /dev/null @@ -1,41 +0,0 @@ -From e2ceb2def76cc917d3165a804025e630c3bedad1 Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Wed, 2 Aug 2023 19:08:05 -0700 -Subject: [PATCH] vfio: Fix vfio_get_dev_region() trace event -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 969dae5448eaa2914be5b974f9e0311b3f95ee2c - -Simply transpose 'x8' to fix the typo and remove the ending '8' - -Fixes: e61a424f05 ("vfio: Create device specific region info helper") -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1526 -Signed-off-by: Cédric Le Goater -Reviewed-by: Philippe Mathieu-Daudé -Link: https://lore.kernel.org/r/20230303074330.2609377-1-clg@kaod.org -[aw: commit log s/revert/transpose/] -Signed-off-by: Alex Williamson - -Signed-off-by: Wanghe Xiao ---- - hw/vfio/trace-events | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 0ef1b5f4a6..f4b74a3e81 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -116,7 +116,7 @@ vfio_region_mmaps_set_enabled(const char *name, bool enabled) "Region %s mmaps e - vfio_region_unmap(const char *name, unsigned long offset, unsigned long end) "Region %s unmap [0x%lx - 0x%lx]" - vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Device %s region %d: %d sparse mmap entries" - vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]" --vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8" -+vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%08x" - vfio_dma_unmap_overflow_workaround(void) "" - - # platform.c --- -2.41.0.windows.1 - diff --git a/vfio-Force-nested-if-iommu-requires-it.patch b/vfio-Force-nested-if-iommu-requires-it.patch deleted file mode 100644 index d580ae5007f6ae7be2adb090d9e6774eeeb323db..0000000000000000000000000000000000000000 --- a/vfio-Force-nested-if-iommu-requires-it.patch +++ /dev/null @@ -1,101 +0,0 @@ -From e7eef5af743a53f0415267ebe9bba2e5f0e05816 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 28 Aug 2018 16:16:20 +0200 -Subject: [PATCH] vfio: Force nested if iommu requires it - -In case we detect the address space is translated by -a virtual IOMMU which requires HW nested paging to -integrate with VFIO, let's set up the container with -the VFIO_TYPE1_NESTING_IOMMU iommu_type. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 36 ++++++++++++++++++++++++++++-------- - 1 file changed, 28 insertions(+), 8 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 6cb91e7ffd..d7533637c9 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -2045,27 +2045,38 @@ static void vfio_put_address_space(VFIOAddressSpace *space) - * vfio_get_iommu_type - selects the richest iommu_type (v2 first) - */ - static int vfio_get_iommu_type(VFIOContainer *container, -+ bool want_nested, - Error **errp) - { -- int iommu_types[] = { VFIO_TYPE1v2_IOMMU, VFIO_TYPE1_IOMMU, -+ int iommu_types[] = { VFIO_TYPE1_NESTING_IOMMU, -+ VFIO_TYPE1v2_IOMMU, VFIO_TYPE1_IOMMU, - VFIO_SPAPR_TCE_v2_IOMMU, VFIO_SPAPR_TCE_IOMMU }; -- int i; -+ int i, ret = -EINVAL; - - for (i = 0; i < ARRAY_SIZE(iommu_types); i++) { - if (ioctl(container->fd, VFIO_CHECK_EXTENSION, iommu_types[i])) { -- return iommu_types[i]; -+ if (iommu_types[i] == VFIO_TYPE1_NESTING_IOMMU && !want_nested) { -+ continue; -+ } -+ ret = iommu_types[i]; -+ break; - } - } -- error_setg(errp, "No available IOMMU models"); -- return -EINVAL; -+ if (ret < 0) { -+ error_setg(errp, "No available IOMMU models"); -+ } else if (want_nested && ret != VFIO_TYPE1_NESTING_IOMMU) { -+ error_setg(errp, "Nested mode requested but not supported"); -+ ret = -EINVAL; -+ } -+ return ret; - } - - static int vfio_init_container(VFIOContainer *container, int group_fd, -- Error **errp) -+ bool want_nested, Error **errp) - { - int iommu_type, dirty_log_manual_clear, ret; - -- iommu_type = vfio_get_iommu_type(container, errp); -+ iommu_type = vfio_get_iommu_type(container, want_nested, errp); - if (iommu_type < 0) { - return iommu_type; - } -@@ -2177,6 +2188,14 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - VFIOContainer *container; - int ret, fd; - VFIOAddressSpace *space; -+ IOMMUMemoryRegion *iommu_mr; -+ bool nested = false; -+ -+ if (memory_region_is_iommu(as->root)) { -+ iommu_mr = IOMMU_MEMORY_REGION(as->root); -+ memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_VFIO_NESTED, -+ (void *)&nested); -+ } - - space = vfio_get_address_space(as); - -@@ -2257,7 +2276,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - QLIST_INIT(&container->vrdl_list); - QLIST_INIT(&container->dma_list); - -- ret = vfio_init_container(container, group->fd, errp); -+ ret = vfio_init_container(container, group->fd, nested, errp); - if (ret) { - goto free_container_exit; - } -@@ -2269,6 +2288,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - } - - switch (container->iommu_type) { -+ case VFIO_TYPE1_NESTING_IOMMU: - case VFIO_TYPE1v2_IOMMU: - case VFIO_TYPE1_IOMMU: - { --- -2.27.0 - diff --git a/vfio-Helper-to-get-IRQ-info-including-capabilities.patch b/vfio-Helper-to-get-IRQ-info-including-capabilities.patch deleted file mode 100644 index 3d4b1667692bf76a3c89c71cd363db5090641986..0000000000000000000000000000000000000000 --- a/vfio-Helper-to-get-IRQ-info-including-capabilities.patch +++ /dev/null @@ -1,178 +0,0 @@ -From a4336765c99a876743c0ead89997ad6f97d7b442 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 20 Jun 2019 16:39:57 +0200 -Subject: [PATCH] vfio: Helper to get IRQ info including capabilities - -As done for vfio regions, add helpers to retrieve irq info -including their optional capabilities. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 97 +++++++++++++++++++++++++++++++++++ - hw/vfio/trace-events | 1 + - include/hw/vfio/vfio-common.h | 7 +++ - 3 files changed, 105 insertions(+) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 1f78af121d..d05a485808 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1919,6 +1919,25 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, - return true; - } - -+struct vfio_info_cap_header * -+vfio_get_irq_info_cap(struct vfio_irq_info *info, uint16_t id) -+{ -+ struct vfio_info_cap_header *hdr; -+ void *ptr = info; -+ -+ if (!(info->flags & VFIO_IRQ_INFO_FLAG_CAPS)) { -+ return NULL; -+ } -+ -+ for (hdr = ptr + info->cap_offset; hdr != ptr; hdr = ptr + hdr->next) { -+ if (hdr->id == id) { -+ return hdr; -+ } -+ } -+ -+ return NULL; -+} -+ - static int vfio_setup_region_sparse_mmaps(VFIORegion *region, - struct vfio_region_info *info) - { -@@ -2887,6 +2906,33 @@ retry: - return 0; - } - -+int vfio_get_irq_info(VFIODevice *vbasedev, int index, -+ struct vfio_irq_info **info) -+{ -+ size_t argsz = sizeof(struct vfio_irq_info); -+ -+ *info = g_malloc0(argsz); -+ -+ (*info)->index = index; -+retry: -+ (*info)->argsz = argsz; -+ -+ if (ioctl(vbasedev->fd, VFIO_DEVICE_GET_IRQ_INFO, *info)) { -+ g_free(*info); -+ *info = NULL; -+ return -errno; -+ } -+ -+ if ((*info)->argsz > argsz) { -+ argsz = (*info)->argsz; -+ *info = g_realloc(*info, argsz); -+ -+ goto retry; -+ } -+ -+ return 0; -+} -+ - int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, - uint32_t subtype, struct vfio_region_info **info) - { -@@ -2922,6 +2968,42 @@ int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, - return -ENODEV; - } - -+int vfio_get_dev_irq_info(VFIODevice *vbasedev, uint32_t type, -+ uint32_t subtype, struct vfio_irq_info **info) -+{ -+ int i; -+ -+ for (i = 0; i < vbasedev->num_irqs; i++) { -+ struct vfio_info_cap_header *hdr; -+ struct vfio_irq_info_cap_type *cap_type; -+ -+ if (vfio_get_irq_info(vbasedev, i, info)) { -+ continue; -+ } -+ -+ hdr = vfio_get_irq_info_cap(*info, VFIO_IRQ_INFO_CAP_TYPE); -+ if (!hdr) { -+ g_free(*info); -+ continue; -+ } -+ -+ cap_type = container_of(hdr, struct vfio_irq_info_cap_type, header); -+ -+ trace_vfio_get_dev_irq(vbasedev->name, i, -+ cap_type->type, cap_type->subtype); -+ -+ if (cap_type->type == type && cap_type->subtype == subtype) { -+ return 0; -+ } -+ -+ g_free(*info); -+ } -+ -+ *info = NULL; -+ return -ENODEV; -+} -+ -+ - bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) - { - struct vfio_region_info *info = NULL; -@@ -2937,6 +3019,21 @@ bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) - return ret; - } - -+bool vfio_has_irq_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) -+{ -+ struct vfio_region_info *info = NULL; -+ bool ret = false; -+ -+ if (!vfio_get_region_info(vbasedev, region, &info)) { -+ if (vfio_get_region_info_cap(info, cap_type)) { -+ ret = true; -+ } -+ g_free(info); -+ } -+ -+ return ret; -+} -+ - /* - * Interfaces for IBM EEH (Enhanced Error Handling) - */ -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 35bd415d6d..f5fe201ab5 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -117,6 +117,7 @@ vfio_region_unmap(const char *name, unsigned long offset, unsigned long end) "Re - vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Device %s region %d: %d sparse mmap entries" - vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]" - vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8" -+vfio_get_dev_irq(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8" - vfio_dma_unmap_overflow_workaround(void) "" - vfio_iommu_addr_inv_iotlb(int asid, uint64_t addr, uint64_t size, uint64_t nb_granules, bool leaf) "nested IOTLB invalidate asid=%d, addr=0x%"PRIx64" granule_size=0x%"PRIx64" nb_granules=0x%"PRIx64" leaf=%d" - vfio_iommu_asid_inv_iotlb(int asid) "nested IOTLB invalidate asid=%d" -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index a838a939e4..7fdca26fa0 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -254,6 +254,13 @@ bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, - unsigned int *avail); - struct vfio_info_cap_header * - vfio_get_device_info_cap(struct vfio_device_info *info, uint16_t id); -+int vfio_get_irq_info(VFIODevice *vbasedev, int index, -+ struct vfio_irq_info **info); -+int vfio_get_dev_irq_info(VFIODevice *vbasedev, uint32_t type, -+ uint32_t subtype, struct vfio_irq_info **info); -+bool vfio_has_irq_cap(VFIODevice *vbasedev, int irq, uint16_t cap_type); -+struct vfio_info_cap_header * -+vfio_get_irq_info_cap(struct vfio_irq_info *info, uint16_t id); - #endif - extern const MemoryListener vfio_prereg_listener; - --- -2.27.0 - diff --git a/vfio-Introduce-helpers-to-DMA-map-unmap-a-RAM-sectio.patch b/vfio-Introduce-helpers-to-DMA-map-unmap-a-RAM-sectio.patch deleted file mode 100644 index fd6deffd16ce01ee2a97e4061ac358e974a49320..0000000000000000000000000000000000000000 --- a/vfio-Introduce-helpers-to-DMA-map-unmap-a-RAM-sectio.patch +++ /dev/null @@ -1,280 +0,0 @@ -From dab969657d8ff8b175856f91b035b74849cf69ba Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 30 Aug 2018 15:04:25 +0200 -Subject: [PATCH] vfio: Introduce helpers to DMA map/unmap a RAM section - -Let's introduce two helpers that allow to DMA map/unmap a RAM -section. Those helpers will be called for nested stage setup in -another call site. Also the vfio_listener_region_add/del() -structure may be clearer. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 206 +++++++++++++++++++++++++------------------ - hw/vfio/trace-events | 4 +- - 2 files changed, 123 insertions(+), 87 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index d358789f19..b3dc090840 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -922,13 +922,130 @@ hostwin_from_range(VFIOContainer *container, hwaddr iova, hwaddr end) - return NULL; - } - -+static int vfio_dma_map_ram_section(VFIOContainer *container, -+ MemoryRegionSection *section, Error **err) -+{ -+ VFIOHostDMAWindow *hostwin; -+ Int128 llend, llsize; -+ hwaddr iova, end; -+ void *vaddr; -+ int ret; -+ -+ assert(memory_region_is_ram(section->mr)); -+ -+ iova = TARGET_PAGE_ALIGN(section->offset_within_address_space); -+ llend = int128_make64(section->offset_within_address_space); -+ llend = int128_add(llend, section->size); -+ llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK)); -+ end = int128_get64(int128_sub(llend, int128_one())); -+ -+ vaddr = memory_region_get_ram_ptr(section->mr) + -+ section->offset_within_region + -+ (iova - section->offset_within_address_space); -+ -+ hostwin = hostwin_from_range(container, iova, end); -+ if (!hostwin) { -+ error_setg(err, "Container %p can't map guest IOVA region" -+ " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, container, iova, end); -+ return -EFAULT; -+ } -+ -+ trace_vfio_dma_map_ram(iova, end, vaddr); -+ -+ llsize = int128_sub(llend, int128_make64(iova)); -+ -+ if (memory_region_is_ram_device(section->mr)) { -+ hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; -+ -+ if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) { -+ trace_vfio_listener_region_add_no_dma_map( -+ memory_region_name(section->mr), -+ section->offset_within_address_space, -+ int128_getlo(section->size), -+ pgmask + 1); -+ return 0; -+ } -+ } -+ -+ ret = vfio_dma_map(container, iova, int128_get64(llsize), -+ vaddr, section->readonly); -+ if (ret) { -+ error_setg(err, "vfio_dma_map(%p, 0x%"HWADDR_PRIx", " -+ "0x%"HWADDR_PRIx", %p) = %d (%m)", -+ container, iova, int128_get64(llsize), vaddr, ret); -+ if (memory_region_is_ram_device(section->mr)) { -+ /* Allow unexpected mappings not to be fatal for RAM devices */ -+ error_report_err(*err); -+ return 0; -+ } -+ return ret; -+ } -+ return 0; -+} -+ -+static void vfio_dma_unmap_ram_section(VFIOContainer *container, -+ MemoryRegionSection *section) -+{ -+ Int128 llend, llsize; -+ hwaddr iova, end; -+ bool try_unmap = true; -+ int ret; -+ -+ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -+ llend = int128_make64(section->offset_within_address_space); -+ llend = int128_add(llend, section->size); -+ llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); -+ -+ if (int128_ge(int128_make64(iova), llend)) { -+ return; -+ } -+ end = int128_get64(int128_sub(llend, int128_one())); -+ -+ llsize = int128_sub(llend, int128_make64(iova)); -+ -+ trace_vfio_dma_unmap_ram(iova, end); -+ -+ if (memory_region_is_ram_device(section->mr)) { -+ hwaddr pgmask; -+ VFIOHostDMAWindow *hostwin = hostwin_from_range(container, iova, end); -+ -+ assert(hostwin); /* or region_add() would have failed */ -+ -+ pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; -+ try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); -+ } else if (memory_region_has_ram_discard_manager(section->mr)) { -+ vfio_unregister_ram_discard_listener(container, section); -+ /* Unregistering will trigger an unmap. */ -+ try_unmap = false; -+ } -+ -+ if (try_unmap) { -+ if (int128_eq(llsize, int128_2_64())) { -+ /* The unmap ioctl doesn't accept a full 64-bit span. */ -+ llsize = int128_rshift(llsize, 1); -+ ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -+ if (ret) { -+ error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -+ "0x%"HWADDR_PRIx") = %d (%m)", -+ container, iova, int128_get64(llsize), ret); -+ } -+ iova += int128_get64(llsize); -+ } -+ ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -+ if (ret) { -+ error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -+ "0x%"HWADDR_PRIx") = %d (%m)", -+ container, iova, int128_get64(llsize), ret); -+ } -+ } -+} -+ - static void vfio_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); - hwaddr iova, end; -- Int128 llend, llsize; -- void *vaddr; -+ Int128 llend; - int ret; - VFIOHostDMAWindow *hostwin; - Error *err = NULL; -@@ -1092,38 +1209,7 @@ static void vfio_listener_region_add(MemoryListener *listener, - return; - } - -- vaddr = memory_region_get_ram_ptr(section->mr) + -- section->offset_within_region + -- (iova - section->offset_within_address_space); -- -- trace_vfio_listener_region_add_ram(iova, end, vaddr); -- -- llsize = int128_sub(llend, int128_make64(iova)); -- -- if (memory_region_is_ram_device(section->mr)) { -- hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; -- -- if ((iova & pgmask) || (int128_get64(llsize) & pgmask)) { -- trace_vfio_listener_region_add_no_dma_map( -- memory_region_name(section->mr), -- section->offset_within_address_space, -- int128_getlo(section->size), -- pgmask + 1); -- return; -- } -- } -- -- ret = vfio_dma_map(container, iova, int128_get64(llsize), -- vaddr, section->readonly); -- if (ret) { -- error_setg(&err, "vfio_dma_map(%p, 0x%"HWADDR_PRIx", " -- "0x%"HWADDR_PRIx", %p) = %d (%m)", -- container, iova, int128_get64(llsize), vaddr, ret); -- if (memory_region_is_ram_device(section->mr)) { -- /* Allow unexpected mappings not to be fatal for RAM devices */ -- error_report_err(err); -- return; -- } -+ if (vfio_dma_map_ram_section(container, section, &err)) { - goto fail; - } - -@@ -1157,10 +1243,6 @@ static void vfio_listener_region_del(MemoryListener *listener, - MemoryRegionSection *section) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); -- hwaddr iova, end; -- Int128 llend, llsize; -- int ret; -- bool try_unmap = true; - - if (vfio_listener_skipped_section(section)) { - trace_vfio_listener_region_del_skip( -@@ -1200,53 +1282,7 @@ static void vfio_listener_region_del(MemoryListener *listener, - */ - } - -- iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -- llend = int128_make64(section->offset_within_address_space); -- llend = int128_add(llend, section->size); -- llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); -- -- if (int128_ge(int128_make64(iova), llend)) { -- return; -- } -- end = int128_get64(int128_sub(llend, int128_one())); -- -- llsize = int128_sub(llend, int128_make64(iova)); -- -- trace_vfio_listener_region_del(iova, end); -- -- if (memory_region_is_ram_device(section->mr)) { -- hwaddr pgmask; -- VFIOHostDMAWindow *hostwin = hostwin_from_range(container, iova, end); -- -- assert(hostwin); /* or region_add() would have failed */ -- -- pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; -- try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); -- } else if (memory_region_has_ram_discard_manager(section->mr)) { -- vfio_unregister_ram_discard_listener(container, section); -- /* Unregistering will trigger an unmap. */ -- try_unmap = false; -- } -- -- if (try_unmap) { -- if (int128_eq(llsize, int128_2_64())) { -- /* The unmap ioctl doesn't accept a full 64-bit span. */ -- llsize = int128_rshift(llsize, 1); -- ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -- if (ret) { -- error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -- "0x%"HWADDR_PRIx") = %d (%m)", -- container, iova, int128_get64(llsize), ret); -- } -- iova += int128_get64(llsize); -- } -- ret = vfio_dma_unmap(container, iova, int128_get64(llsize), NULL); -- if (ret) { -- error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " -- "0x%"HWADDR_PRIx") = %d (%m)", -- container, iova, int128_get64(llsize), ret); -- } -- } -+ vfio_dma_unmap_ram_section(container, section); - - memory_region_unref(section->mr); - -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 0ef1b5f4a6..a37563a315 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -99,10 +99,10 @@ vfio_iommu_map_notify(const char *op, uint64_t iova_start, uint64_t iova_end) "i - vfio_listener_region_add_skip(uint64_t start, uint64_t end) "SKIPPING region_add 0x%"PRIx64" - 0x%"PRIx64 - vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to liobn fd %d" - vfio_listener_region_add_iommu(uint64_t start, uint64_t end) "region_add [iommu] 0x%"PRIx64" - 0x%"PRIx64 --vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]" -+vfio_dma_map_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]" - vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA" - vfio_listener_region_del_skip(uint64_t start, uint64_t end) "SKIPPING region_del 0x%"PRIx64" - 0x%"PRIx64 --vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64 -+vfio_dma_unmap_ram(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64 - vfio_disconnect_container(int fd) "close container->fd=%d" - vfio_put_group(int fd) "close group->fd=%d" - vfio_get_device(const char * name, unsigned int flags, unsigned int num_regions, unsigned int num_irqs) "Device %s flags: %u, regions: %u, irqs: %u" --- -2.27.0 - diff --git a/vfio-Introduce-helpers-to-mark-dirty-pages-of-a-RAM-.patch b/vfio-Introduce-helpers-to-mark-dirty-pages-of-a-RAM-.patch deleted file mode 100644 index e77dd1d64b4bdfb606e7987df653d5e365c27c98..0000000000000000000000000000000000000000 --- a/vfio-Introduce-helpers-to-mark-dirty-pages-of-a-RAM-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 1675d767aa9bd496178b4d74e01a40dbbd97eccb Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 11 May 2021 10:08:13 +0800 -Subject: [PATCH] vfio: Introduce helpers to mark dirty pages of a RAM section - -Extract part of the code from vfio_sync_dirty_bitmap to form a -new helper, which allows to mark dirty pages of a RAM section. -This helper will be called for nested stage. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 22 ++++++++++++++-------- - 1 file changed, 14 insertions(+), 8 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index bdfcc854fe..6136b1ef61 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1566,6 +1566,19 @@ err_out: - return ret; - } - -+static int vfio_dma_sync_ram_section_dirty_bitmap(VFIOContainer *container, -+ MemoryRegionSection *section) -+{ -+ ram_addr_t ram_addr; -+ -+ ram_addr = memory_region_get_ram_addr(section->mr) + -+ section->offset_within_region; -+ -+ return vfio_get_dirty_bitmap(container, -+ REAL_HOST_PAGE_ALIGN(section->offset_within_address_space), -+ int128_get64(section->size), ram_addr); -+} -+ - typedef struct { - IOMMUNotifier n; - VFIOGuestIOMMU *giommu; -@@ -1650,8 +1663,6 @@ static int vfio_sync_ram_discard_listener_dirty_bitmap(VFIOContainer *container, - static int vfio_sync_dirty_bitmap(VFIOContainer *container, - MemoryRegionSection *section) - { -- ram_addr_t ram_addr; -- - if (memory_region_is_iommu(section->mr)) { - VFIOGuestIOMMU *giommu; - -@@ -1682,12 +1693,7 @@ static int vfio_sync_dirty_bitmap(VFIOContainer *container, - return vfio_sync_ram_discard_listener_dirty_bitmap(container, section); - } - -- ram_addr = memory_region_get_ram_addr(section->mr) + -- section->offset_within_region; -- -- return vfio_get_dirty_bitmap(container, -- REAL_HOST_PAGE_ALIGN(section->offset_within_address_space), -- int128_get64(section->size), ram_addr); -+ return vfio_dma_sync_ram_section_dirty_bitmap(container, section); - } - - static void vfio_listener_log_sync(MemoryListener *listener, --- -2.27.0 - diff --git a/vfio-Introduce-hostwin_from_range-helper.patch b/vfio-Introduce-hostwin_from_range-helper.patch deleted file mode 100644 index c8c8ab76922a95fbcfdec74b92b11dc688ce2745..0000000000000000000000000000000000000000 --- a/vfio-Introduce-hostwin_from_range-helper.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 85232739b4852f1a51dde58c9007ed0deb17c2f2 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Fri, 22 Mar 2019 18:05:23 +0100 -Subject: [PATCH] vfio: Introduce hostwin_from_range helper - -Let's introduce a hostwin_from_range() helper that returns the -hostwin encapsulating an IOVA range or NULL if none is found. - -This improves the readibility of callers and removes the usage -of hostwin_found. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 36 +++++++++++++++++------------------- - 1 file changed, 17 insertions(+), 19 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index d7533637c9..d358789f19 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -909,6 +909,19 @@ static void vfio_unregister_ram_discard_listener(VFIOContainer *container, - g_free(vrdl); - } - -+static VFIOHostDMAWindow * -+hostwin_from_range(VFIOContainer *container, hwaddr iova, hwaddr end) -+{ -+ VFIOHostDMAWindow *hostwin; -+ -+ QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -+ if (hostwin->min_iova <= iova && end <= hostwin->max_iova) { -+ return hostwin; -+ } -+ } -+ return NULL; -+} -+ - static void vfio_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { -@@ -918,7 +931,6 @@ static void vfio_listener_region_add(MemoryListener *listener, - void *vaddr; - int ret; - VFIOHostDMAWindow *hostwin; -- bool hostwin_found; - Error *err = NULL; - - if (vfio_listener_skipped_section(section)) { -@@ -1011,15 +1023,8 @@ static void vfio_listener_region_add(MemoryListener *listener, - #endif - } - -- hostwin_found = false; -- QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -- if (hostwin->min_iova <= iova && end <= hostwin->max_iova) { -- hostwin_found = true; -- break; -- } -- } -- -- if (!hostwin_found) { -+ hostwin = hostwin_from_range(container, iova, end); -+ if (!hostwin) { - error_setg(&err, "Container %p can't map guest IOVA region" - " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx, container, iova, end); - goto fail; -@@ -1211,16 +1216,9 @@ static void vfio_listener_region_del(MemoryListener *listener, - - if (memory_region_is_ram_device(section->mr)) { - hwaddr pgmask; -- VFIOHostDMAWindow *hostwin; -- bool hostwin_found = false; -+ VFIOHostDMAWindow *hostwin = hostwin_from_range(container, iova, end); - -- QLIST_FOREACH(hostwin, &container->hostwin_list, hostwin_next) { -- if (hostwin->min_iova <= iova && end <= hostwin->max_iova) { -- hostwin_found = true; -- break; -- } -- } -- assert(hostwin_found); /* or region_add() would have failed */ -+ assert(hostwin); /* or region_add() would have failed */ - - pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1; - try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); --- -2.27.0 - diff --git a/vfio-Maintain-DMA-mapping-range-for-the-container.patch b/vfio-Maintain-DMA-mapping-range-for-the-container.patch deleted file mode 100644 index ba8abb431c5606de905890d5be95e37f4d0ccf8e..0000000000000000000000000000000000000000 --- a/vfio-Maintain-DMA-mapping-range-for-the-container.patch +++ /dev/null @@ -1,191 +0,0 @@ -From ac1bf3edcd2b807cf81ada500716f13b1394d58e Mon Sep 17 00:00:00 2001 -From: Zenghui Yu -Date: Sat, 8 May 2021 17:31:04 +0800 -Subject: [PATCH] vfio: Maintain DMA mapping range for the container - -When synchronizing dirty bitmap from kernel VFIO we do it in a -per-iova-range fashion and we allocate the userspace bitmap for each of the -ioctl. This patch introduces `struct VFIODMARange` to describe a range of -the given DMA mapping with respect to a VFIO_IOMMU_MAP_DMA operation, and -make the bitmap cache of this range be persistent so that we don't need to -g_try_malloc0() every time. Note that the new structure is almost a copy of -`struct vfio_iommu_type1_dma_map` but only internally used by QEMU. - -More importantly, the cached per-iova-range dirty bitmap will be further -used when we want to add support for the CLEAR_BITMAP and this cached -bitmap will be used to guarantee we don't clear any unknown dirty bits -otherwise that can be a severe data loss issue for migration code. - -It's pretty intuitive to maintain a bitmap per container since we perform -log_sync at this granule. But I don't know how to deal with things like -memory hot-{un}plug, sparse DMA mappings, etc. Suggestions welcome. - -* yet something to-do: - - can't work with guest viommu - - no locks - - etc - -[ The idea and even the commit message are largely inherited from kvm side. - See commit 9f4bf4baa8b820c7930e23c9566c9493db7e1d25. ] - -Signed-off-by: Zenghui Yu -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 62 +++++++++++++++++++++++++++++++---- - include/hw/vfio/vfio-common.h | 9 +++++ - 2 files changed, 65 insertions(+), 6 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 080046e3f5..86ea784919 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -445,6 +445,29 @@ unmap_exit: - return ret; - } - -+static VFIODMARange *vfio_lookup_match_range(VFIOContainer *container, -+ hwaddr start_addr, hwaddr size) -+{ -+ VFIODMARange *qrange; -+ -+ QLIST_FOREACH(qrange, &container->dma_list, next) { -+ if (qrange->iova == start_addr && qrange->size == size) { -+ return qrange; -+ } -+ } -+ return NULL; -+} -+ -+static void vfio_dma_range_init_dirty_bitmap(VFIODMARange *qrange) -+{ -+ uint64_t pages, size; -+ -+ pages = REAL_HOST_PAGE_ALIGN(qrange->size) / qemu_real_host_page_size; -+ size = ROUND_UP(pages, sizeof(__u64) * BITS_PER_BYTE) / BITS_PER_BYTE; -+ -+ qrange->bitmap = g_malloc0(size); -+} -+ - /* - * DMA - Mapping and unmapping for the "type1" IOMMU interface used on x86 - */ -@@ -458,12 +481,29 @@ static int vfio_dma_unmap(VFIOContainer *container, - .iova = iova, - .size = size, - }; -+ VFIODMARange *qrange; - - if (iotlb && container->dirty_pages_supported && - vfio_devices_all_running_and_saving(container)) { - return vfio_dma_unmap_bitmap(container, iova, size, iotlb); - } - -+ /* -+ * unregister the DMA range -+ * -+ * It seems that the memory layer will give us the same section as the one -+ * used in region_add(). Otherwise it'll be complicated to manipulate the -+ * bitmap across region_{add,del}. Is there any guarantee? -+ * -+ * But there is really not such a restriction on the kernel interface -+ * (VFIO_IOMMU_DIRTY_PAGES_FLAG_{UN}MAP_DMA, etc). -+ */ -+ qrange = vfio_lookup_match_range(container, iova, size); -+ assert(qrange); -+ g_free(qrange->bitmap); -+ QLIST_REMOVE(qrange, next); -+ g_free(qrange); -+ - while (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) { - /* - * The type1 backend has an off-by-one bug in the kernel (71a7d3d78e3c -@@ -500,6 +540,14 @@ static int vfio_dma_map(VFIOContainer *container, hwaddr iova, - .iova = iova, - .size = size, - }; -+ VFIODMARange *qrange; -+ -+ qrange = g_malloc0(sizeof(*qrange)); -+ qrange->iova = iova; -+ qrange->size = size; -+ QLIST_INSERT_HEAD(&container->dma_list, qrange, next); -+ /* XXX allocate the dirty bitmap on demand */ -+ vfio_dma_range_init_dirty_bitmap(qrange); - - if (!readonly) { - map.flags |= VFIO_DMA_MAP_FLAG_WRITE; -@@ -1256,9 +1304,14 @@ static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - { - struct vfio_iommu_type1_dirty_bitmap *dbitmap; - struct vfio_iommu_type1_dirty_bitmap_get *range; -+ VFIODMARange *qrange; - uint64_t pages; - int ret; - -+ qrange = vfio_lookup_match_range(container, iova, size); -+ /* the same as vfio_dma_unmap() */ -+ assert(qrange); -+ - dbitmap = g_malloc0(sizeof(*dbitmap) + sizeof(*range)); - - dbitmap->argsz = sizeof(*dbitmap) + sizeof(*range); -@@ -1277,11 +1330,8 @@ static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - pages = REAL_HOST_PAGE_ALIGN(range->size) / qemu_real_host_page_size; - range->bitmap.size = ROUND_UP(pages, sizeof(__u64) * BITS_PER_BYTE) / - BITS_PER_BYTE; -- range->bitmap.data = g_try_malloc0(range->bitmap.size); -- if (!range->bitmap.data) { -- ret = -ENOMEM; -- goto err_out; -- } -+ -+ range->bitmap.data = (__u64 *)qrange->bitmap; - - ret = ioctl(container->fd, VFIO_IOMMU_DIRTY_PAGES, dbitmap); - if (ret) { -@@ -1297,7 +1347,6 @@ static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - trace_vfio_get_dirty_bitmap(container->fd, range->iova, range->size, - range->bitmap.size, ram_addr); - err_out: -- g_free(range->bitmap.data); - g_free(dbitmap); - - return ret; -@@ -2061,6 +2110,7 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - QLIST_INIT(&container->giommu_list); - QLIST_INIT(&container->hostwin_list); - QLIST_INIT(&container->vrdl_list); -+ QLIST_INIT(&container->dma_list); - - ret = vfio_init_container(container, group->fd, errp); - if (ret) { -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 8af11b0a76..20b9c8a1d3 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -76,6 +76,14 @@ typedef struct VFIOAddressSpace { - - struct VFIOGroup; - -+typedef struct VFIODMARange { -+ QLIST_ENTRY(VFIODMARange) next; -+ hwaddr iova; -+ size_t size; -+ void *vaddr; /* unused */ -+ unsigned long *bitmap; /* dirty bitmap cache for this range */ -+} VFIODMARange; -+ - typedef struct VFIOContainer { - VFIOAddressSpace *space; - int fd; /* /dev/vfio/vfio, empowered by the attached groups */ -@@ -93,6 +101,7 @@ typedef struct VFIOContainer { - QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; - QLIST_HEAD(, VFIOGroup) group_list; - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; -+ QLIST_HEAD(, VFIODMARange) dma_list; - QLIST_ENTRY(VFIOContainer) next; - } VFIOContainer; - --- -2.27.0 - diff --git a/vfio-Pass-stage-1-MSI-bindings-to-the-host.patch b/vfio-Pass-stage-1-MSI-bindings-to-the-host.patch deleted file mode 100644 index bed28007ce19c71e58690d3ceb7ce5c9dd87a9d4..0000000000000000000000000000000000000000 --- a/vfio-Pass-stage-1-MSI-bindings-to-the-host.patch +++ /dev/null @@ -1,262 +0,0 @@ -From 8b4fbe869f8a1f510896c86067d2e4fc3dc82eb9 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 14 Aug 2018 08:08:11 -0400 -Subject: [PATCH] vfio: Pass stage 1 MSI bindings to the host - -We register the stage1 MSI bindings when enabling the vectors -and we unregister them on msi disable. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 59 +++++++++++++++++++++++++++ - hw/vfio/pci.c | 76 ++++++++++++++++++++++++++++++++++- - hw/vfio/trace-events | 2 + - include/hw/vfio/vfio-common.h | 12 ++++++ - 4 files changed, 147 insertions(+), 2 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 58f8a43a43..1f78af121d 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -774,6 +774,65 @@ static void vfio_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - } - } - -+int vfio_iommu_set_msi_binding(VFIOContainer *container, int n, -+ IOMMUTLBEntry *iotlb) -+{ -+ struct vfio_iommu_type1_set_msi_binding ustruct; -+ VFIOMSIBinding *binding; -+ int ret; -+ -+ QLIST_FOREACH(binding, &container->msibinding_list, next) { -+ if (binding->index == n) { -+ return 0; -+ } -+ } -+ -+ ustruct.argsz = sizeof(struct vfio_iommu_type1_set_msi_binding); -+ ustruct.iova = iotlb->iova; -+ ustruct.flags = VFIO_IOMMU_BIND_MSI; -+ ustruct.gpa = iotlb->translated_addr; -+ ustruct.size = iotlb->addr_mask + 1; -+ ret = ioctl(container->fd, VFIO_IOMMU_SET_MSI_BINDING , &ustruct); -+ if (ret) { -+ error_report("%s: failed to register the stage1 MSI binding (%m)", -+ __func__); -+ return ret; -+ } -+ binding = g_new0(VFIOMSIBinding, 1); -+ binding->iova = ustruct.iova; -+ binding->gpa = ustruct.gpa; -+ binding->size = ustruct.size; -+ binding->index = n; -+ -+ QLIST_INSERT_HEAD(&container->msibinding_list, binding, next); -+ return 0; -+} -+ -+int vfio_iommu_unset_msi_binding(VFIOContainer *container, int n) -+{ -+ struct vfio_iommu_type1_set_msi_binding ustruct; -+ VFIOMSIBinding *binding, *tmp; -+ int ret; -+ -+ ustruct.argsz = sizeof(struct vfio_iommu_type1_set_msi_binding); -+ QLIST_FOREACH_SAFE(binding, &container->msibinding_list, next, tmp) { -+ if (binding->index != n) { -+ continue; -+ } -+ ustruct.flags = VFIO_IOMMU_UNBIND_MSI; -+ ustruct.iova = binding->iova; -+ ret = ioctl(container->fd, VFIO_IOMMU_SET_MSI_BINDING , &ustruct); -+ if (ret) { -+ error_report("Failed to unregister the stage1 MSI binding " -+ "for iova=0x%"PRIx64" (%m)", binding->iova); -+ } -+ QLIST_REMOVE(binding, next); -+ g_free(binding); -+ return ret; -+ } -+ return 0; -+} -+ - static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - { - VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index ae5e014e5d..99c52a0944 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -365,6 +365,65 @@ static void vfio_msi_interrupt(void *opaque) - notify(&vdev->pdev, nr); - } - -+static bool vfio_iommu_require_msi_binding(IOMMUMemoryRegion *iommu_mr) -+{ -+ bool msi_translate = false, nested = false; -+ -+ memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_MSI_TRANSLATE, -+ (void *)&msi_translate); -+ memory_region_iommu_get_attr(iommu_mr, IOMMU_ATTR_VFIO_NESTED, -+ (void *)&nested); -+ if (!nested || !msi_translate) { -+ return false; -+ } -+ return true; -+} -+ -+static int vfio_register_msi_binding(VFIOPCIDevice *vdev, -+ int vector_n, bool set) -+{ -+ VFIOContainer *container = vdev->vbasedev.group->container; -+ PCIDevice *dev = &vdev->pdev; -+ AddressSpace *as = pci_device_iommu_address_space(dev); -+ IOMMUMemoryRegionClass *imrc; -+ IOMMUMemoryRegion *iommu_mr; -+ IOMMUTLBEntry entry; -+ MSIMessage msg; -+ -+ if (as == &address_space_memory) { -+ return 0; -+ } -+ -+ iommu_mr = IOMMU_MEMORY_REGION(as->root); -+ if (!vfio_iommu_require_msi_binding(iommu_mr)) { -+ return 0; -+ } -+ -+ /* MSI doorbell address is translated by an IOMMU */ -+ -+ if (!set) { /* unregister */ -+ trace_vfio_unregister_msi_binding(vdev->vbasedev.name, vector_n); -+ -+ return vfio_iommu_unset_msi_binding(container, vector_n); -+ } -+ -+ msg = pci_get_msi_message(dev, vector_n); -+ imrc = memory_region_get_iommu_class_nocheck(iommu_mr); -+ -+ rcu_read_lock(); -+ entry = imrc->translate(iommu_mr, msg.address, IOMMU_WO, 0); -+ rcu_read_unlock(); -+ -+ if (entry.perm == IOMMU_NONE) { -+ return -ENOENT; -+ } -+ -+ trace_vfio_register_msi_binding(vdev->vbasedev.name, vector_n, -+ msg.address, entry.translated_addr); -+ -+ return vfio_iommu_set_msi_binding(container, vector_n, &entry); -+} -+ - static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) - { - struct vfio_irq_set *irq_set; -@@ -382,7 +441,7 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) - fds = (int32_t *)&irq_set->data; - - for (i = 0; i < vdev->nr_vectors; i++) { -- int fd = -1; -+ int ret, fd = -1; - - /* - * MSI vs MSI-X - The guest has direct access to MSI mask and pending -@@ -391,6 +450,12 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) - * KVM signaling path only when configured and unmasked. - */ - if (vdev->msi_vectors[i].use) { -+ ret = vfio_register_msi_binding(vdev, i, true); -+ if (ret) { -+ error_report("%s failed to register S1 MSI binding " -+ "for vector %d(%d)", vdev->vbasedev.name, i, ret); -+ goto out; -+ } - if (vdev->msi_vectors[i].virq < 0 || - (msix && msix_is_masked(&vdev->pdev, i))) { - fd = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt); -@@ -404,6 +469,7 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) - - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set); - -+out: - g_free(irq_set); - - return ret; -@@ -718,7 +784,8 @@ static void vfio_msi_disable_common(VFIOPCIDevice *vdev) - - static void vfio_msix_disable(VFIOPCIDevice *vdev) - { -- int i; -+ int ret, i; -+ - - msix_unset_vector_notifiers(&vdev->pdev); - -@@ -730,6 +797,11 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev) - if (vdev->msi_vectors[i].use) { - vfio_msix_vector_release(&vdev->pdev, i); - msix_vector_unuse(&vdev->pdev, i); -+ ret = vfio_register_msi_binding(vdev, i, false); -+ if (ret) { -+ error_report("%s: failed to unregister S1 MSI binding " -+ "for vector %d(%d)", vdev->vbasedev.name, i, ret); -+ } - } - } - -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index 20069935f5..35bd415d6d 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -120,6 +120,8 @@ vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype - vfio_dma_unmap_overflow_workaround(void) "" - vfio_iommu_addr_inv_iotlb(int asid, uint64_t addr, uint64_t size, uint64_t nb_granules, bool leaf) "nested IOTLB invalidate asid=%d, addr=0x%"PRIx64" granule_size=0x%"PRIx64" nb_granules=0x%"PRIx64" leaf=%d" - vfio_iommu_asid_inv_iotlb(int asid) "nested IOTLB invalidate asid=%d" -+vfio_register_msi_binding(const char *name, int vector, uint64_t giova, uint64_t gdb) "%s: register vector %d gIOVA=0x%"PRIx64 "-> gDB=0x%"PRIx64" stage 1 mapping" -+vfio_unregister_msi_binding(const char *name, int vector) "%s: unregister vector %d stage 1 mapping" - - # platform.c - vfio_platform_base_device_init(char *name, int groupid) "%s belongs to group #%d" -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 0234f5e1b1..a838a939e4 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -74,6 +74,14 @@ typedef struct VFIOAddressSpace { - QLIST_ENTRY(VFIOAddressSpace) list; - } VFIOAddressSpace; - -+typedef struct VFIOMSIBinding { -+ int index; -+ hwaddr iova; -+ hwaddr gpa; -+ hwaddr size; -+ QLIST_ENTRY(VFIOMSIBinding) next; -+} VFIOMSIBinding; -+ - struct VFIOGroup; - - typedef struct VFIODMARange { -@@ -103,6 +111,7 @@ typedef struct VFIOContainer { - QLIST_HEAD(, VFIOGroup) group_list; - QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; - QLIST_HEAD(, VFIODMARange) dma_list; -+ QLIST_HEAD(, VFIOMSIBinding) msibinding_list; - QLIST_ENTRY(VFIOContainer) next; - } VFIOContainer; - -@@ -222,6 +231,9 @@ VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp); - void vfio_put_group(VFIOGroup *group); - int vfio_get_device(VFIOGroup *group, const char *name, - VFIODevice *vbasedev, Error **errp); -+int vfio_iommu_set_msi_binding(VFIOContainer *container, int n, -+ IOMMUTLBEntry *entry); -+int vfio_iommu_unset_msi_binding(VFIOContainer *container, int n); - - extern const MemoryRegionOps vfio_region_ops; - typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; --- -2.27.0 - diff --git a/vfio-Set-up-nested-stage-mappings.patch b/vfio-Set-up-nested-stage-mappings.patch deleted file mode 100644 index c6d87f97be54c3c76b2890ee978723ee946146c6..0000000000000000000000000000000000000000 --- a/vfio-Set-up-nested-stage-mappings.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 96581a5ee46e89dbc9e1ebe247b00adefb1c7a41 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Wed, 29 Aug 2018 18:10:12 +0200 -Subject: [PATCH] vfio: Set up nested stage mappings - -In nested mode, legacy vfio_iommu_map_notify cannot be used as -there is no "caching" mode and we do not trap on map. - -On Intel, vfio_iommu_map_notify was used to DMA map the RAM -through the host single stage. - -With nested mode, we need to setup the stage 2 and the stage 1 -separately. This patch introduces a prereg_listener to setup -the stage 2 mapping. - -The stage 1 mapping, owned by the guest, is passed to the host -when the guest invalidates the stage 1 configuration, through -a dedicated PCIPASIDOps callback. Guest IOTLB invalidations -are cascaded downto the host through another IOMMU MR UNMAP -notifier. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 139 +++++++++++++++++++++++++++++++++++++++++-- - hw/vfio/pci.c | 21 +++++++ - hw/vfio/trace-events | 2 + - 3 files changed, 157 insertions(+), 5 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index b3dc090840..58f8a43a43 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -707,6 +707,73 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, - return true; - } - -+/* Propagate a guest IOTLB invalidation to the host (nested mode) */ -+static void vfio_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) -+{ -+ VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); -+ struct vfio_iommu_type1_cache_invalidate ustruct = {}; -+ VFIOContainer *container = giommu->container; -+ int ret; -+ -+ assert(iotlb->perm == IOMMU_NONE); -+ -+ ustruct.argsz = sizeof(ustruct); -+ ustruct.flags = 0; -+ ustruct.info.argsz = sizeof(struct iommu_cache_invalidate_info); -+ ustruct.info.version = IOMMU_CACHE_INVALIDATE_INFO_VERSION_1; -+ ustruct.info.cache = IOMMU_CACHE_INV_TYPE_IOTLB; -+ -+ switch (iotlb->granularity) { -+ case IOMMU_INV_GRAN_DOMAIN: -+ ustruct.info.granularity = IOMMU_INV_GRANU_DOMAIN; -+ break; -+ case IOMMU_INV_GRAN_PASID: -+ { -+ struct iommu_inv_pasid_info *pasid_info; -+ int archid = -1; -+ -+ pasid_info = &ustruct.info.granu.pasid_info; -+ ustruct.info.granularity = IOMMU_INV_GRANU_PASID; -+ if (iotlb->flags & IOMMU_INV_FLAGS_ARCHID) { -+ pasid_info->flags |= IOMMU_INV_ADDR_FLAGS_ARCHID; -+ archid = iotlb->arch_id; -+ } -+ pasid_info->archid = archid; -+ trace_vfio_iommu_asid_inv_iotlb(archid); -+ break; -+ } -+ case IOMMU_INV_GRAN_ADDR: -+ { -+ hwaddr start = iotlb->iova + giommu->iommu_offset; -+ struct iommu_inv_addr_info *addr_info; -+ size_t size = iotlb->addr_mask + 1; -+ int archid = -1; -+ -+ addr_info = &ustruct.info.granu.addr_info; -+ ustruct.info.granularity = IOMMU_INV_GRANU_ADDR; -+ if (iotlb->leaf) { -+ addr_info->flags |= IOMMU_INV_ADDR_FLAGS_LEAF; -+ } -+ if (iotlb->flags & IOMMU_INV_FLAGS_ARCHID) { -+ addr_info->flags |= IOMMU_INV_ADDR_FLAGS_ARCHID; -+ archid = iotlb->arch_id; -+ } -+ addr_info->archid = archid; -+ addr_info->addr = start; -+ addr_info->granule_size = size; -+ addr_info->nb_granules = 1; -+ trace_vfio_iommu_addr_inv_iotlb(archid, start, size, -+ 1, iotlb->leaf); -+ break; -+ } -+ } -+ -+ ret = ioctl(container->fd, VFIO_IOMMU_CACHE_INVALIDATE, &ustruct); -+ if (ret) { -+ error_report("%p: failed to invalidate CACHE (%d)", container, ret); -+ } -+} -+ - static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - { - VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); -@@ -1040,6 +1107,35 @@ static void vfio_dma_unmap_ram_section(VFIOContainer *container, - } - } - -+static void vfio_prereg_listener_region_add(MemoryListener *listener, -+ MemoryRegionSection *section) -+{ -+ VFIOContainer *container = -+ container_of(listener, VFIOContainer, prereg_listener); -+ Error *err = NULL; -+ -+ if (!memory_region_is_ram(section->mr)) { -+ return; -+ } -+ -+ vfio_dma_map_ram_section(container, section, &err); -+ if (err) { -+ error_report_err(err); -+ } -+} -+static void vfio_prereg_listener_region_del(MemoryListener *listener, -+ MemoryRegionSection *section) -+{ -+ VFIOContainer *container = -+ container_of(listener, VFIOContainer, prereg_listener); -+ -+ if (!memory_region_is_ram(section->mr)) { -+ return; -+ } -+ -+ vfio_dma_unmap_ram_section(container, section); -+} -+ - static void vfio_listener_region_add(MemoryListener *listener, - MemoryRegionSection *section) - { -@@ -1150,9 +1246,10 @@ static void vfio_listener_region_add(MemoryListener *listener, - memory_region_ref(section->mr); - - if (memory_region_is_iommu(section->mr)) { -+ IOMMUNotify notify; - VFIOGuestIOMMU *giommu; - IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr); -- int iommu_idx; -+ int iommu_idx, flags; - - trace_vfio_listener_region_add_iommu(iova, end); - /* -@@ -1171,8 +1268,18 @@ static void vfio_listener_region_add(MemoryListener *listener, - llend = int128_sub(llend, int128_one()); - iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr, - MEMTXATTRS_UNSPECIFIED); -- iommu_notifier_init(&giommu->n, vfio_iommu_map_notify, -- IOMMU_NOTIFIER_IOTLB_EVENTS, -+ -+ if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -+ /* IOTLB unmap notifier to propagate guest IOTLB invalidations */ -+ flags = IOMMU_NOTIFIER_UNMAP; -+ notify = vfio_iommu_unmap_notify; -+ } else { -+ /* MAP/UNMAP IOTLB notifier */ -+ flags = IOMMU_NOTIFIER_IOTLB_EVENTS; -+ notify = vfio_iommu_map_notify; -+ } -+ -+ iommu_notifier_init(&giommu->n, notify, flags, - section->offset_within_region, - int128_get64(llend), - iommu_idx); -@@ -1192,7 +1299,9 @@ static void vfio_listener_region_add(MemoryListener *listener, - goto fail; - } - QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next); -- memory_region_iommu_replay(giommu->iommu, &giommu->n); -+ if (flags & IOMMU_NOTIFIER_MAP) { -+ memory_region_iommu_replay(giommu->iommu, &giommu->n); -+ } - - return; - } -@@ -1672,10 +1781,16 @@ static const MemoryListener vfio_memory_listener = { - .log_clear = vfio_listener_log_clear, - }; - -+static MemoryListener vfio_memory_prereg_listener = { -+ .region_add = vfio_prereg_listener_region_add, -+ .region_del = vfio_prereg_listener_region_del, -+}; -+ - static void vfio_listener_release(VFIOContainer *container) - { - memory_listener_unregister(&container->listener); -- if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { -+ if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU || -+ container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { - memory_listener_unregister(&container->prereg_listener); - } - } -@@ -2351,6 +2466,20 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as, - vfio_get_iommu_info_migration(container, info); - } - g_free(info); -+ -+ if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -+ container->prereg_listener = vfio_memory_prereg_listener; -+ memory_listener_register(&container->prereg_listener, -+ &address_space_memory); -+ if (container->error) { -+ memory_listener_unregister(&container->prereg_listener); -+ ret = -1; -+ error_propagate_prepend(errp, container->error, -+ "RAM memory listener initialization failed " -+ "for container"); -+ goto free_container_exit; -+ } -+ } - break; - } - case VFIO_SPAPR_TCE_v2_IOMMU: -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 7b45353ce2..ae5e014e5d 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2797,6 +2797,25 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev) - vdev->req_enabled = false; - } - -+static int vfio_iommu_set_pasid_table(PCIBus *bus, int32_t devfn, -+ IOMMUConfig *config) -+{ -+ PCIDevice *pdev = bus->devices[devfn]; -+ VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); -+ VFIOContainer *container = vdev->vbasedev.group->container; -+ struct vfio_iommu_type1_set_pasid_table info; -+ -+ info.argsz = sizeof(info); -+ info.flags = VFIO_PASID_TABLE_FLAG_SET; -+ memcpy(&info.config, &config->pasid_cfg, sizeof(config->pasid_cfg)); -+ -+ return ioctl(container->fd, VFIO_IOMMU_SET_PASID_TABLE, &info); -+} -+ -+static PCIPASIDOps vfio_pci_pasid_ops = { -+ .set_pasid_table = vfio_iommu_set_pasid_table, -+}; -+ - static void vfio_realize(PCIDevice *pdev, Error **errp) - { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); -@@ -3108,6 +3127,8 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - vfio_register_req_notifier(vdev); - vfio_setup_resetfn_quirk(vdev); - -+ pci_setup_pasid_ops(pdev, &vfio_pci_pasid_ops); -+ - return; - - out_deregister: -diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events -index a37563a315..20069935f5 100644 ---- a/hw/vfio/trace-events -+++ b/hw/vfio/trace-events -@@ -118,6 +118,8 @@ vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Devic - vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]" - vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%0x8" - vfio_dma_unmap_overflow_workaround(void) "" -+vfio_iommu_addr_inv_iotlb(int asid, uint64_t addr, uint64_t size, uint64_t nb_granules, bool leaf) "nested IOTLB invalidate asid=%d, addr=0x%"PRIx64" granule_size=0x%"PRIx64" nb_granules=0x%"PRIx64" leaf=%d" -+vfio_iommu_asid_inv_iotlb(int asid) "nested IOTLB invalidate asid=%d" - - # platform.c - vfio_platform_base_device_init(char *name, int groupid) "%s belongs to group #%d" --- -2.27.0 - diff --git a/vfio-common-Add-address-alignment-check-in-vfio_list.patch b/vfio-common-Add-address-alignment-check-in-vfio_list.patch deleted file mode 100644 index 288f28482314f60dd0396228b35b17c0f9d67b8e..0000000000000000000000000000000000000000 --- a/vfio-common-Add-address-alignment-check-in-vfio_list.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 00c553f53657bf4bc165d859187215dba7110246 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 14 Sep 2021 14:21:46 +0800 -Subject: [PATCH] vfio/common: Add address alignment check in - vfio_listener_region_del - -Both vfio_listener_region_add and vfio_listener_region_del have -reference counting operations on ram section->mr. If the 'iova' -and 'llend' of the ram section do not pass the alignment -check, the ram section should not be mapped or unmapped. It means -that the reference counting should not be changed. - -However, the address alignment check is missing in -vfio_listener_region_del. This makes memory_region_unref will -be unconditional called and causes unintended problems in some -scenarios. - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 89c49f5508..4d45c2b625 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1411,6 +1411,8 @@ static void vfio_listener_region_del(MemoryListener *listener, - MemoryRegionSection *section) - { - VFIOContainer *container = container_of(listener, VFIOContainer, listener); -+ hwaddr iova; -+ Int128 llend; - - if (vfio_listener_skipped_section(section)) { - trace_vfio_listener_region_del_skip( -@@ -1460,6 +1462,14 @@ static void vfio_listener_region_del(MemoryListener *listener, - */ - } - -+ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); -+ llend = int128_make64(section->offset_within_address_space); -+ llend = int128_add(llend, section->size); -+ llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); -+ if (int128_ge(int128_make64(iova), llend)) { -+ return; -+ } -+ - vfio_dma_unmap_ram_section(container, section); - - memory_region_unref(section->mr); --- -2.27.0 - diff --git a/vfio-common-Avoid-unmap-ram-section-at-vfio_listener.patch b/vfio-common-Avoid-unmap-ram-section-at-vfio_listener.patch deleted file mode 100644 index 71302b2d21e9840a0591d2960452de622cd60731..0000000000000000000000000000000000000000 --- a/vfio-common-Avoid-unmap-ram-section-at-vfio_listener.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 9d7b782a0b2c5288e82f3064b4c5b7bf18887280 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Sat, 31 Jul 2021 10:02:18 +0800 -Subject: [PATCH] vfio/common: Avoid unmap ram section at - vfio_listener_region_del() in nested mode - -The ram section will be unmapped at vfio_prereg_listener_region_del() -in nested mode. So let's avoid unmap ram section at -vfio_listener_region_dev(). - -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index d05a485808..bdfcc854fe 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1441,6 +1441,16 @@ static void vfio_listener_region_del(MemoryListener *listener, - } - } - -+ /* -+ * In nested mode, stage 2 (gpa->hpa) and the stage 1 -+ * (giova->gpa) are set separately. The ram section -+ * will be unmapped in vfio_prereg_listener_region_del(). -+ * Hence it doesn't need to unmap ram section here. -+ */ -+ if (container->iommu_type == VFIO_TYPE1_NESTING_IOMMU) { -+ return; -+ } -+ - /* - * FIXME: We assume the one big unmap below is adequate to - * remove any individual page mappings in the IOMMU which --- -2.27.0 - diff --git a/vfio-common-Fix-incorrect-address-alignment-in-vfio_.patch b/vfio-common-Fix-incorrect-address-alignment-in-vfio_.patch deleted file mode 100644 index d61408e6242adbb0c7e95b4cd94ec70fcca19c22..0000000000000000000000000000000000000000 --- a/vfio-common-Fix-incorrect-address-alignment-in-vfio_.patch +++ /dev/null @@ -1,40 +0,0 @@ -From c2a4ce033db6ab74256e28da382c797a98047d4b Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Tue, 7 Sep 2021 15:14:12 +0800 -Subject: [PATCH] vfio/common: Fix incorrect address alignment in - vfio_dma_map_ram_section - -The 'iova' will be passed to host kernel for mapping with the -HPA. It is related to the host page size. So TARGET_PAGE_ALIGN -should be replaced by REAL_HOST_PAGE_ALIGN. In the case of -large granularity (64K), it may return early when map MMIO RAM -section. And because of the inconsistency with -vfio_dma_unmap_ram_section, it may cause 'assert(qrange)' -in vfio_dma_unmap. - -Signed-off-by: Kunkun Jiang -Signed-off-by: Zenghui Yu ---- - hw/vfio/common.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 65f3979492..89c49f5508 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1059,10 +1059,10 @@ static int vfio_dma_map_ram_section(VFIOContainer *container, - - assert(memory_region_is_ram(section->mr)); - -- iova = TARGET_PAGE_ALIGN(section->offset_within_address_space); -+ iova = REAL_HOST_PAGE_ALIGN(section->offset_within_address_space); - llend = int128_make64(section->offset_within_address_space); - llend = int128_add(llend, section->size); -- llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK)); -+ llend = int128_and(llend, int128_exts64(qemu_real_host_page_mask)); - end = int128_get64(int128_sub(llend, int128_one())); - - vaddr = memory_region_get_ram_ptr(section->mr) + --- -2.27.0 - diff --git a/vfio-migration-Add-support-for-manual-clear-vfio-dir.patch b/vfio-migration-Add-support-for-manual-clear-vfio-dir.patch deleted file mode 100644 index 0a5ff88f995220f5c3128eb8e56c86afeffe53e2..0000000000000000000000000000000000000000 --- a/vfio-migration-Add-support-for-manual-clear-vfio-dir.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 815258f81a660ad87272191dca4a9726cb2bf5b2 Mon Sep 17 00:00:00 2001 -From: Zenghui Yu -Date: Sat, 8 May 2021 17:31:05 +0800 -Subject: [PATCH] vfio/migration: Add support for manual clear vfio dirty log - -The new capability VFIO_DIRTY_LOG_MANUAL_CLEAR and the new ioctl -VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP_NOCLEAR and -VFIO_IOMMU_DIRTY_PAGES_FLAG_CLEAR_BITMAP have been introduced in -the kernel, tweak the userspace side to use them. - -Check if the kernel supports VFIO_DIRTY_LOG_MANUAL_CLEAR and -provide the log_clear() hook for vfio_memory_listener. If the -kernel supports it, deliever the clear message to kernel. - -Signed-off-by: Zenghui Yu -Signed-off-by: Kunkun Jiang ---- - hw/vfio/common.c | 149 +++++++++++++++++++++++++++++++++- - include/hw/vfio/vfio-common.h | 1 + - 2 files changed, 148 insertions(+), 2 deletions(-) - -diff --git a/hw/vfio/common.c b/hw/vfio/common.c -index 86ea784919..6cb91e7ffd 100644 ---- a/hw/vfio/common.c -+++ b/hw/vfio/common.c -@@ -1315,7 +1315,9 @@ static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova, - dbitmap = g_malloc0(sizeof(*dbitmap) + sizeof(*range)); - - dbitmap->argsz = sizeof(*dbitmap) + sizeof(*range); -- dbitmap->flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP; -+ dbitmap->flags = container->dirty_log_manual_clear ? -+ VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP_NOCLEAR : -+ VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP; - range = (struct vfio_iommu_type1_dirty_bitmap_get *)&dbitmap->data; - range->iova = iova; - range->size = size; -@@ -1491,6 +1493,141 @@ static void vfio_listener_log_sync(MemoryListener *listener, - } - } - -+/* -+ * I'm not sure if there's any alignment requirement for the CLEAR_BITMAP -+ * ioctl. But copy from kvm side and align {start, size} with 64 pages. -+ * -+ * I think the code can be simplified a lot if no alignment requirement. -+ */ -+#define VFIO_CLEAR_LOG_SHIFT 6 -+#define VFIO_CLEAR_LOG_ALIGN (qemu_real_host_page_size << VFIO_CLEAR_LOG_SHIFT) -+#define VFIO_CLEAR_LOG_MASK (-VFIO_CLEAR_LOG_ALIGN) -+ -+static int vfio_log_clear_one_range(VFIOContainer *container, -+ VFIODMARange *qrange, uint64_t start, uint64_t size) -+{ -+ struct vfio_iommu_type1_dirty_bitmap *dbitmap; -+ struct vfio_iommu_type1_dirty_bitmap_get *range; -+ -+ dbitmap = g_malloc0(sizeof(*dbitmap) + sizeof(*range)); -+ -+ dbitmap->argsz = sizeof(*dbitmap) + sizeof(*range); -+ dbitmap->flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_CLEAR_BITMAP; -+ range = (struct vfio_iommu_type1_dirty_bitmap_get *)&dbitmap->data; -+ -+ /* -+ * Now let's deal with the actual bitmap, which is almost the same -+ * as the kvm side. -+ */ -+ uint64_t end, bmap_start, start_delta, bmap_npages; -+ unsigned long *bmap_clear = NULL, psize = qemu_real_host_page_size; -+ int ret; -+ -+ bmap_start = start & VFIO_CLEAR_LOG_MASK; -+ start_delta = start - bmap_start; -+ bmap_start /= psize; -+ -+ bmap_npages = DIV_ROUND_UP(size + start_delta, VFIO_CLEAR_LOG_ALIGN) -+ << VFIO_CLEAR_LOG_SHIFT; -+ end = qrange->size / psize; -+ if (bmap_npages > end - bmap_start) { -+ bmap_npages = end - bmap_start; -+ } -+ start_delta /= psize; -+ -+ if (start_delta) { -+ bmap_clear = bitmap_new(bmap_npages); -+ bitmap_copy_with_src_offset(bmap_clear, qrange->bitmap, -+ bmap_start, start_delta + size / psize); -+ bitmap_clear(bmap_clear, 0, start_delta); -+ range->bitmap.data = (__u64 *)bmap_clear; -+ } else { -+ range->bitmap.data = (__u64 *)(qrange->bitmap + BIT_WORD(bmap_start)); -+ } -+ -+ range->iova = qrange->iova + bmap_start * psize; -+ range->size = bmap_npages * psize; -+ range->bitmap.size = ROUND_UP(bmap_npages, sizeof(__u64) * BITS_PER_BYTE) / -+ BITS_PER_BYTE; -+ range->bitmap.pgsize = qemu_real_host_page_size; -+ -+ ret = ioctl(container->fd, VFIO_IOMMU_DIRTY_PAGES, dbitmap); -+ if (ret) { -+ error_report("Failed to clear dirty log for iova: 0x%"PRIx64 -+ " size: 0x%"PRIx64" err: %d", (uint64_t)range->iova, -+ (uint64_t)range->size, errno); -+ goto err_out; -+ } -+ -+ bitmap_clear(qrange->bitmap, bmap_start + start_delta, size / psize); -+err_out: -+ g_free(bmap_clear); -+ g_free(dbitmap); -+ return 0; -+} -+ -+static int vfio_physical_log_clear(VFIOContainer *container, -+ MemoryRegionSection *section) -+{ -+ uint64_t start, size, offset, count; -+ VFIODMARange *qrange; -+ int ret = 0; -+ -+ if (!container->dirty_log_manual_clear) { -+ /* No need to do explicit clear */ -+ return ret; -+ } -+ -+ start = section->offset_within_address_space; -+ size = int128_get64(section->size); -+ -+ if (!size) { -+ return ret; -+ } -+ -+ QLIST_FOREACH(qrange, &container->dma_list, next) { -+ /* -+ * Discard ranges that do not overlap the section (e.g., the -+ * Memory BAR regions of the device) -+ */ -+ if (qrange->iova > start + size - 1 || -+ start > qrange->iova + qrange->size - 1) { -+ continue; -+ } -+ -+ if (start >= qrange->iova) { -+ /* The range starts before section or is aligned to it. */ -+ offset = start - qrange->iova; -+ count = MIN(qrange->size - offset, size); -+ } else { -+ /* The range starts after section. */ -+ offset = 0; -+ count = MIN(qrange->size, size - (qrange->iova - start)); -+ } -+ ret = vfio_log_clear_one_range(container, qrange, offset, count); -+ if (ret < 0) { -+ break; -+ } -+ } -+ -+ return ret; -+} -+ -+static void vfio_listener_log_clear(MemoryListener *listener, -+ MemoryRegionSection *section) -+{ -+ VFIOContainer *container = container_of(listener, VFIOContainer, listener); -+ -+ if (vfio_listener_skipped_section(section) || -+ !container->dirty_pages_supported) { -+ return; -+ } -+ -+ if (vfio_devices_all_dirty_tracking(container)) { -+ vfio_physical_log_clear(container, section); -+ } -+} -+ - static const MemoryListener vfio_memory_listener = { - .name = "vfio", - .region_add = vfio_listener_region_add, -@@ -1498,6 +1635,7 @@ static const MemoryListener vfio_memory_listener = { - .log_global_start = vfio_listener_log_global_start, - .log_global_stop = vfio_listener_log_global_stop, - .log_sync = vfio_listener_log_sync, -+ .log_clear = vfio_listener_log_clear, - }; - - static void vfio_listener_release(VFIOContainer *container) -@@ -1925,7 +2063,7 @@ static int vfio_get_iommu_type(VFIOContainer *container, - static int vfio_init_container(VFIOContainer *container, int group_fd, - Error **errp) - { -- int iommu_type, ret; -+ int iommu_type, dirty_log_manual_clear, ret; - - iommu_type = vfio_get_iommu_type(container, errp); - if (iommu_type < 0) { -@@ -1954,6 +2092,13 @@ static int vfio_init_container(VFIOContainer *container, int group_fd, - } - - container->iommu_type = iommu_type; -+ -+ dirty_log_manual_clear = ioctl(container->fd, VFIO_CHECK_EXTENSION, -+ VFIO_DIRTY_LOG_MANUAL_CLEAR); -+ if (dirty_log_manual_clear) { -+ container->dirty_log_manual_clear = dirty_log_manual_clear; -+ } -+ - return 0; - } - -diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h -index 20b9c8a1d3..0234f5e1b1 100644 ---- a/include/hw/vfio/vfio-common.h -+++ b/include/hw/vfio/vfio-common.h -@@ -93,6 +93,7 @@ typedef struct VFIOContainer { - Error *error; - bool initialized; - bool dirty_pages_supported; -+ bool dirty_log_manual_clear; - uint64_t dirty_pgsizes; - uint64_t max_dirty_bitmap_size; - unsigned long pgsizes; --- -2.27.0 - diff --git a/vfio-migration-Fix-incorrect-initialization-value-fo.patch b/vfio-migration-Fix-incorrect-initialization-value-fo.patch deleted file mode 100644 index 378fa7d74d481f1952c8f67537e2285c6a2bbaf7..0000000000000000000000000000000000000000 --- a/vfio-migration-Fix-incorrect-initialization-value-fo.patch +++ /dev/null @@ -1,37 +0,0 @@ -From d57f2527fd747d2b51ad18dc38fa9d0c25ebc8a7 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Mon, 11 Jul 2022 09:46:51 +0800 -Subject: [PATCH 2/3] vfio/migration: Fix incorrect initialization value for - parameters in VFIOMigration - -The structure VFIOMigration of a VFIODevice is allocated and initialized -in vfio_migration_init(). "device_state" and "vm_running" are initialized -to 0, indicating that VFIO device is_STOP and VM is not-running. The -initialization value is incorrect. According to the agreement, default -state of VFIO device is _RUNNING. And if a VFIO device is hot-plugged -while the VM is running, "vm_running" should be 1. This patch fixes it. - -Fixes: 02a7e71b1e5b ("vfio: Add VM state change handler to know state of VM") -Signed-off-by: Kunkun Jiang -Link: https://lore.kernel.org/r/20220711014651.1327-1-jiangkunkun@huawei.com -Signed-off-by: Alex Williamson ---- - hw/vfio/migration.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c -index ff6b45de6b..e69b5f2e42 100644 ---- a/hw/vfio/migration.c -+++ b/hw/vfio/migration.c -@@ -805,6 +805,8 @@ static int vfio_migration_init(VFIODevice *vbasedev, - } - - vbasedev->migration = g_new0(VFIOMigration, 1); -+ vbasedev->migration->device_state = VFIO_DEVICE_STATE_RUNNING; -+ vbasedev->migration->vm_running = runstate_is_running(); - - ret = vfio_region_setup(obj, vbasedev, &vbasedev->migration->region, - info->index, "migration"); --- -2.27.0 - diff --git a/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch b/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch deleted file mode 100644 index c3ea4c233b747fac21f166edb4b65717b1998cb1..0000000000000000000000000000000000000000 --- a/vfio-pci-Ascend310-need-4Bytes-quirk-in-bar4.patch +++ /dev/null @@ -1,105 +0,0 @@ -From eee7ff398496524881225d503309a9853972c5df Mon Sep 17 00:00:00 2001 -From: Binfeng Wu -Date: Tue, 8 Feb 2022 17:00:39 +0800 -Subject: [PATCH 3/5] vfio/pci: Ascend310 need 4Bytes quirk in bar4 - ---- - hw/vfio/pci-quirks.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 75 insertions(+) - -diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c -index 0cf69a8c6d..d86bcaf309 100644 ---- a/hw/vfio/pci-quirks.c -+++ b/hw/vfio/pci-quirks.c -@@ -1209,6 +1209,80 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, - return 0; - } - -+#define PCI_VENDOR_ID_HUAWEI 0x19e5 -+#define PCI_DEVICE_ID_ASCEND310 0xd100 -+#define ASCEND310_XLOADER_SIZE 4 -+#define ASCEND310_XLOADER_OFFSET 0x400 -+ -+typedef struct VFIOAscendBarQuirk { -+ struct VFIOPCIDevice *vdev; -+ pcibus_t offset; -+ uint8_t bar; -+ MemoryRegion *mem; -+} VFIOAscendBarQuirk; -+ -+static uint64_t vfio_ascend_quirk_read(void *opaque, -+ hwaddr addr, unsigned size) -+{ -+ VFIOAscendBarQuirk *quirk = opaque; -+ VFIOPCIDevice *vdev = quirk->vdev; -+ -+ qemu_log("read RO region! addr=0x%" HWADDR_PRIx ", size=%d\n", -+ addr + quirk->offset, size); -+ -+ return vfio_region_read(&vdev->bars[quirk->bar].region, -+ addr + quirk->offset, size); -+} -+ -+static void vfio_ascend_quirk_write(void *opaque, hwaddr addr, -+ uint64_t data, unsigned size) -+{ -+ VFIOAscendBarQuirk *quirk = opaque; -+ -+ qemu_log("modifying RO region is not allowed! addr=0x%" -+ HWADDR_PRIx ", data=0x%" PRIx64 ", size=%d\n", -+ addr + quirk->offset, data, size); -+} -+ -+static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { -+ .read = vfio_ascend_quirk_read, -+ .write = vfio_ascend_quirk_write, -+ .endianness = DEVICE_LITTLE_ENDIAN, -+}; -+ -+static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) -+{ -+ VFIOQuirk *quirk; -+ VFIOAscendBarQuirk *bar4_quirk; -+ -+ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 4 || -+ vdev->device_id != PCI_DEVICE_ID_ASCEND310) { -+ return; -+ } -+ -+ quirk = g_malloc0(sizeof(*quirk)); -+ quirk->nr_mem = 1; -+ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); -+ bar4_quirk = quirk->data = g_new0(typeof(*bar4_quirk), quirk->nr_mem); -+ bar4_quirk[0].vdev = vdev; -+ bar4_quirk[0].offset = ASCEND310_XLOADER_OFFSET; -+ bar4_quirk[0].bar = nr; -+ -+ /* -+ * intercept w/r to the xloader-updating register, -+ * so the vm can't enable xloader-updating -+ */ -+ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), -+ &vfio_ascend_intercept_regs_quirk, -+ &bar4_quirk[0], -+ "vfio-ascend310-bar4-intercept-regs-quirk", -+ ASCEND310_XLOADER_SIZE); -+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, -+ bar4_quirk[0].offset, -+ &quirk->mem[0], 1); -+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); -+} -+ - /* - * Common quirk probe entry points. - */ -@@ -1261,6 +1335,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) - #ifdef CONFIG_VFIO_IGD - vfio_probe_igd_bar4_quirk(vdev, nr); - #endif -+ vfio_probe_ascend310_bar4_quirk(vdev, nr); - } - - void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr) --- -2.27.0 - diff --git a/vfio-pci-Ascend710-change-to-bar2-quirk.patch b/vfio-pci-Ascend710-change-to-bar2-quirk.patch deleted file mode 100644 index 0039aaead4b93c0358021828277acf118b66e3ef..0000000000000000000000000000000000000000 --- a/vfio-pci-Ascend710-change-to-bar2-quirk.patch +++ /dev/null @@ -1,125 +0,0 @@ -From ce59c78060b5eb13026ca1cbbc046e90ea01a607 Mon Sep 17 00:00:00 2001 -From: Wu Binfeng -Date: Mon, 25 Apr 2022 15:17:48 +0800 -Subject: [PATCH] vfio/pci: Ascend710 change to bar2 quirk - -Change Ascend710's quirk regions to bar2 for internal causes. -And support Ascend710 2P format now. ---- - hw/vfio/pci-quirks.c | 64 +++++++++++++++++++++++++++++++++++--------- - 1 file changed, 51 insertions(+), 13 deletions(-) - -diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c -index 2457a61196..1222ccff0b 100644 ---- a/hw/vfio/pci-quirks.c -+++ b/hw/vfio/pci-quirks.c -@@ -1213,10 +1213,17 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, - #define PCI_DEVICE_ID_ASCEND910 0xd801 - #define PCI_DEVICE_ID_ASCEND710 0xd500 - #define PCI_DEVICE_ID_ASCEND310 0xd100 -+#define PCI_SUB_DEVICE_ID_ASCEND710_1P_MIN 0x100 -+#define PCI_SUB_DEVICE_ID_ASCEND710_1P_MAX 0x10f -+#define PCI_SUB_DEVICE_ID_ASCEND710_2P_MIN 0x110 -+#define PCI_SUB_DEVICE_ID_ASCEND710_2P_MAX 0x11f - #define ASCEND910_XLOADER_SIZE 4 - #define ASCEND910_XLOADER_OFFSET 0x80400 -+#define ASCEND710_2P_BASE (128 * 1024 * 1024) -+#define ASCEND710_1P_DEVNUM 1 -+#define ASCEND710_2P_DEVNUM 2 - #define ASCEND710_XLOADER_SIZE 4 --#define ASCEND710_XLOADER_OFFSET 0x20430 -+#define ASCEND710_XLOADER_OFFSET 0x100430 - #define ASCEND310_XLOADER_SIZE 4 - #define ASCEND310_XLOADER_OFFSET 0x400 - -@@ -1289,23 +1296,38 @@ static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) - QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); - } - --static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) -+static void vfio_probe_ascend710_bar2_quirk(VFIOPCIDevice *vdev, int nr) - { - VFIOQuirk *quirk; -- VFIOAscendBarQuirk *bar0_quirk; -+ VFIOAscendBarQuirk *bar2_quirk; -+ int sub_device_id; -+ int devnum = 0; - -- if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || -+ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2 || - vdev->device_id != PCI_DEVICE_ID_ASCEND710) { - return; - } - -+ sub_device_id = pci_get_word(vdev->pdev.config + PCI_SUBSYSTEM_ID); -+ if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND710_1P_MIN && -+ sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND710_1P_MAX) { -+ devnum = ASCEND710_1P_DEVNUM; -+ } else if (sub_device_id >= PCI_SUB_DEVICE_ID_ASCEND710_2P_MIN && -+ sub_device_id <= PCI_SUB_DEVICE_ID_ASCEND710_2P_MAX) { -+ devnum = ASCEND710_2P_DEVNUM; -+ } -+ -+ if (devnum != ASCEND710_1P_DEVNUM && devnum != ASCEND710_2P_DEVNUM) { -+ return; -+ } -+ - quirk = g_malloc0(sizeof(*quirk)); -- quirk->nr_mem = 1; -+ quirk->nr_mem = devnum; - quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); -- bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem); -- bar0_quirk[0].vdev = vdev; -- bar0_quirk[0].offset = ASCEND710_XLOADER_OFFSET; -- bar0_quirk[0].bar = nr; -+ bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem); -+ bar2_quirk[0].vdev = vdev; -+ bar2_quirk[0].offset = ASCEND710_XLOADER_OFFSET; -+ bar2_quirk[0].bar = nr; - - /* - * intercept w/r to the xloader-updating register, -@@ -1313,12 +1335,28 @@ static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) - */ - memory_region_init_io(&quirk->mem[0], OBJECT(vdev), - &vfio_ascend_intercept_regs_quirk, -- &bar0_quirk[0], -- "vfio-ascend710-bar0-intercept-regs-quirk", -+ &bar2_quirk[0], -+ "vfio-ascend710-bar2-1p-intercept-regs-quirk", - ASCEND710_XLOADER_SIZE); - memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, -- bar0_quirk[0].offset, -+ bar2_quirk[0].offset, - &quirk->mem[0], 1); -+ -+ if (devnum == ASCEND710_2P_DEVNUM) { -+ bar2_quirk[1].vdev = vdev; -+ bar2_quirk[1].offset = (ASCEND710_2P_BASE + ASCEND710_XLOADER_OFFSET); -+ bar2_quirk[1].bar = nr; -+ -+ memory_region_init_io(&quirk->mem[1], OBJECT(vdev), -+ &vfio_ascend_intercept_regs_quirk, -+ &bar2_quirk[1], -+ "vfio-ascend710-bar2-2p-intercept-regs-quirk", -+ ASCEND710_XLOADER_SIZE); -+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, -+ bar2_quirk[1].offset, -+ &quirk->mem[1], 1); -+ } -+ - QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); - } - -@@ -1408,7 +1446,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) - vfio_probe_igd_bar4_quirk(vdev, nr); - #endif - vfio_probe_ascend910_bar0_quirk(vdev, nr); -- vfio_probe_ascend710_bar0_quirk(vdev, nr); -+ vfio_probe_ascend710_bar2_quirk(vdev, nr); - vfio_probe_ascend310_bar4_quirk(vdev, nr); - } - --- -2.27.0 - diff --git a/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch b/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch deleted file mode 100644 index 93d7b2584b41a640d2b3615f7495d4734a47ac72..0000000000000000000000000000000000000000 --- a/vfio-pci-Ascend710-need-4Bytes-quirk-in-bar0.patch +++ /dev/null @@ -1,75 +0,0 @@ -From bcc63ff3975cca783308fac7517a7911c29bd7c1 Mon Sep 17 00:00:00 2001 -From: Binfeng Wu -Date: Tue, 8 Feb 2022 17:16:04 +0800 -Subject: [PATCH 4/5] vfio/pci: Ascend710 need 4Bytes quirk in bar0 - ---- - hw/vfio/pci-quirks.c | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c -index d86bcaf309..6a9fc0afc5 100644 ---- a/hw/vfio/pci-quirks.c -+++ b/hw/vfio/pci-quirks.c -@@ -1210,7 +1210,10 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, - } - - #define PCI_VENDOR_ID_HUAWEI 0x19e5 -+#define PCI_DEVICE_ID_ASCEND710 0xd500 - #define PCI_DEVICE_ID_ASCEND310 0xd100 -+#define ASCEND710_XLOADER_SIZE 4 -+#define ASCEND710_XLOADER_OFFSET 0x20430 - #define ASCEND310_XLOADER_SIZE 4 - #define ASCEND310_XLOADER_OFFSET 0x400 - -@@ -1250,6 +1253,39 @@ static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { - .endianness = DEVICE_LITTLE_ENDIAN, - }; - -+static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) -+{ -+ VFIOQuirk *quirk; -+ VFIOAscendBarQuirk *bar0_quirk; -+ -+ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || -+ vdev->device_id != PCI_DEVICE_ID_ASCEND710) { -+ return; -+ } -+ -+ quirk = g_malloc0(sizeof(*quirk)); -+ quirk->nr_mem = 1; -+ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); -+ bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem); -+ bar0_quirk[0].vdev = vdev; -+ bar0_quirk[0].offset = ASCEND710_XLOADER_OFFSET; -+ bar0_quirk[0].bar = nr; -+ -+ /* -+ * intercept w/r to the xloader-updating register, -+ * so the vm can't enable xloader-updating -+ */ -+ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), -+ &vfio_ascend_intercept_regs_quirk, -+ &bar0_quirk[0], -+ "vfio-ascend710-bar0-intercept-regs-quirk", -+ ASCEND710_XLOADER_SIZE); -+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, -+ bar0_quirk[0].offset, -+ &quirk->mem[0], 1); -+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); -+} -+ - static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr) - { - VFIOQuirk *quirk; -@@ -1335,6 +1371,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) - #ifdef CONFIG_VFIO_IGD - vfio_probe_igd_bar4_quirk(vdev, nr); - #endif -+ vfio_probe_ascend710_bar0_quirk(vdev, nr); - vfio_probe_ascend310_bar4_quirk(vdev, nr); - } - --- -2.27.0 - diff --git a/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch b/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch deleted file mode 100644 index 34b835d9b297aa8f532ff8498374dd8341d6861f..0000000000000000000000000000000000000000 --- a/vfio-pci-Ascend910-need-4Bytes-quirk-in-bar0.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 4cf7d00e43c4e90327e13afa3cbc9c7ca3657c9f Mon Sep 17 00:00:00 2001 -From: Binfeng Wu -Date: Tue, 8 Feb 2022 19:20:36 +0800 -Subject: [PATCH 5/5] vfio/pci: Ascend910 need 4Bytes quirk in bar0 - ---- - hw/vfio/pci-quirks.c | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c -index 6a9fc0afc5..2457a61196 100644 ---- a/hw/vfio/pci-quirks.c -+++ b/hw/vfio/pci-quirks.c -@@ -1210,8 +1210,11 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, - } - - #define PCI_VENDOR_ID_HUAWEI 0x19e5 -+#define PCI_DEVICE_ID_ASCEND910 0xd801 - #define PCI_DEVICE_ID_ASCEND710 0xd500 - #define PCI_DEVICE_ID_ASCEND310 0xd100 -+#define ASCEND910_XLOADER_SIZE 4 -+#define ASCEND910_XLOADER_OFFSET 0x80400 - #define ASCEND710_XLOADER_SIZE 4 - #define ASCEND710_XLOADER_OFFSET 0x20430 - #define ASCEND310_XLOADER_SIZE 4 -@@ -1253,6 +1256,39 @@ static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = { - .endianness = DEVICE_LITTLE_ENDIAN, - }; - -+static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr) -+{ -+ VFIOQuirk *quirk; -+ VFIOAscendBarQuirk *bar0_quirk; -+ -+ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 0 || -+ vdev->device_id != PCI_DEVICE_ID_ASCEND910) { -+ return; -+ } -+ -+ quirk = g_malloc0(sizeof(*quirk)); -+ quirk->nr_mem = 1; -+ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem); -+ bar0_quirk = quirk->data = g_new0(typeof(*bar0_quirk), quirk->nr_mem); -+ bar0_quirk[0].vdev = vdev; -+ bar0_quirk[0].offset = ASCEND910_XLOADER_OFFSET; -+ bar0_quirk[0].bar = nr; -+ -+ /* -+ * intercept w/r to the xloader-updating register, -+ * so the vm can't enable xloader-updating -+ */ -+ memory_region_init_io(&quirk->mem[0], OBJECT(vdev), -+ &vfio_ascend_intercept_regs_quirk, -+ &bar0_quirk[0], -+ "vfio-ascend910-bar0-intercept-regs-quirk", -+ ASCEND910_XLOADER_SIZE); -+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, -+ bar0_quirk[0].offset, -+ &quirk->mem[0], 1); -+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); -+} -+ - static void vfio_probe_ascend710_bar0_quirk(VFIOPCIDevice *vdev, int nr) - { - VFIOQuirk *quirk; -@@ -1371,6 +1407,7 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr) - #ifdef CONFIG_VFIO_IGD - vfio_probe_igd_bar4_quirk(vdev, nr); - #endif -+ vfio_probe_ascend910_bar0_quirk(vdev, nr); - vfio_probe_ascend710_bar0_quirk(vdev, nr); - vfio_probe_ascend310_bar4_quirk(vdev, nr); - } --- -2.27.0 - diff --git a/vfio-pci-Fix-a-segfault-in-vfio_realize.patch b/vfio-pci-Fix-a-segfault-in-vfio_realize.patch deleted file mode 100644 index 7ac8a6de98527eb53df815813f4fcf06907a85e2..0000000000000000000000000000000000000000 --- a/vfio-pci-Fix-a-segfault-in-vfio_realize.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 22e8d7076800d7c62e41e8c69fc01444cf00d451 Mon Sep 17 00:00:00 2001 -From: jipengfei -Date: Fri, 30 Jun 2023 21:05:23 +0800 -Subject: [PATCH] vfio/pci: Fix a segfault in vfio_realize -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The kvm irqchip notifier is only registered if the device supports -INTx, however it's unconditionally removed in vfio realize error -path. If the assigned device does not support INTx, this will cause -QEMU to crash when vfio realize fails. Change it to conditionally -remove the notifier only if the notify hook is setup. - -Before fix: -(qemu) device_add vfio-pci,host=81:11.1,id=vfio1,bus=root1,xres=1 -Connection closed by foreign host. - -After fix: -(qemu) device_add vfio-pci,host=81:11.1,id=vfio1,bus=root1,xres=1 -Error: vfio 0000:81:11.1: xres and yres properties require display=on -(qemu) - -Fixes: c5478fea27ac ("vfio/pci: Respond to KVM irqchip change notifier") - -cheery-pick from 357bd7932a136613d700ee8bc83e9165f059d1f7 - -Signed-off-by: jipengfei_yewu -Signed-off-by: Zhenzhong Duan -Reviewed-by: Cédric Le Goater -Reviewed-by: Joao Martins -Signed-off-by: Cédric Le Goater ---- - hw/vfio/pci.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 7b45353ce2..b085389ff8 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -3112,7 +3112,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - - out_deregister: - pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); -- kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); -+ if (vdev->irqchip_change_notifier.notify) { -+ kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); -+ } - out_teardown: - vfio_teardown_msi(vdev); - vfio_bars_exit(vdev); --- -2.41.0.windows.1 - diff --git a/vfio-pci-Implement-return_page_response-page-respons.patch b/vfio-pci-Implement-return_page_response-page-respons.patch deleted file mode 100644 index 21d88a363a4ddb9305b9990424a121e8ccb68623..0000000000000000000000000000000000000000 --- a/vfio-pci-Implement-return_page_response-page-respons.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 6bbf810edebdb89a6958519ee3adfb1888520231 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Fri, 6 Nov 2020 12:03:29 -0500 -Subject: [PATCH] vfio/pci: Implement return_page_response page response - callback - -This patch implements the page response path. The -response is written into the page response ring buffer and then -update header's head index is updated. This path is not used -by this series. It is introduced here as a POC for vSVA/ARM -integration. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/pci.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++ - hw/vfio/pci.h | 2 + - 2 files changed, 125 insertions(+) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index c54e62fe8f..8e24f9c7d1 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2693,6 +2693,61 @@ out: - g_free(fault_region_info); - } - -+static void vfio_init_fault_response_regions(VFIOPCIDevice *vdev, Error **errp) -+{ -+ struct vfio_region_info *fault_region_info = NULL; -+ struct vfio_region_info_cap_fault *cap_fault; -+ VFIODevice *vbasedev = &vdev->vbasedev; -+ struct vfio_info_cap_header *hdr; -+ char *fault_region_name; -+ int ret; -+ -+ ret = vfio_get_dev_region_info(&vdev->vbasedev, -+ VFIO_REGION_TYPE_NESTED, -+ VFIO_REGION_SUBTYPE_NESTED_DMA_FAULT_RESPONSE, -+ &fault_region_info); -+ if (ret) { -+ goto out; -+ } -+ -+ hdr = vfio_get_region_info_cap(fault_region_info, -+ VFIO_REGION_INFO_CAP_DMA_FAULT_RESPONSE); -+ if (!hdr) { -+ error_setg(errp, "failed to retrieve DMA FAULT RESPONSE capability"); -+ goto out; -+ } -+ cap_fault = container_of(hdr, struct vfio_region_info_cap_fault, -+ header); -+ if (cap_fault->version != 1) { -+ error_setg(errp, "Unsupported DMA FAULT RESPONSE API version %d", -+ cap_fault->version); -+ goto out; -+ } -+ -+ fault_region_name = g_strdup_printf("%s DMA FAULT RESPONSE %d", -+ vbasedev->name, -+ fault_region_info->index); -+ -+ ret = vfio_region_setup(OBJECT(vdev), vbasedev, -+ &vdev->dma_fault_response_region, -+ fault_region_info->index, -+ fault_region_name); -+ g_free(fault_region_name); -+ if (ret) { -+ error_setg_errno(errp, -ret, -+ "failed to set up the DMA FAULT RESPONSE region %d", -+ fault_region_info->index); -+ goto out; -+ } -+ -+ ret = vfio_region_mmap(&vdev->dma_fault_response_region); -+ if (ret) { -+ error_setg_errno(errp, -ret, "Failed to mmap the DMA FAULT RESPONSE queue"); -+ } -+out: -+ g_free(fault_region_info); -+} -+ - static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) - { - VFIODevice *vbasedev = &vdev->vbasedev; -@@ -2768,6 +2823,12 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) - return; - } - -+ vfio_init_fault_response_regions(vdev, &err); -+ if (err) { -+ error_propagate(errp, err); -+ return; -+ } -+ - irq_info.index = VFIO_PCI_ERR_IRQ_INDEX; - - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info); -@@ -2946,8 +3007,68 @@ static int vfio_iommu_set_pasid_table(PCIBus *bus, int32_t devfn, - return ioctl(container->fd, VFIO_IOMMU_SET_PASID_TABLE, &info); - } - -+static int vfio_iommu_return_page_response(PCIBus *bus, int32_t devfn, -+ IOMMUPageResponse *resp) -+{ -+ PCIDevice *pdev = bus->devices[devfn]; -+ VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); -+ struct iommu_page_response *response = &resp->resp; -+ struct vfio_region_dma_fault_response header; -+ struct iommu_page_response *queue; -+ char *queue_buffer = NULL; -+ ssize_t bytes; -+ -+ if (!vdev->dma_fault_response_region.mem) { -+ return -EINVAL; -+ } -+ -+ /* read the header */ -+ bytes = pread(vdev->vbasedev.fd, &header, sizeof(header), -+ vdev->dma_fault_response_region.fd_offset); -+ if (bytes != sizeof(header)) { -+ error_report("%s unable to read the fault region header (0x%lx)", -+ __func__, bytes); -+ return -1; -+ } -+ -+ /* Normally the fault queue is mmapped */ -+ queue = (struct iommu_page_response *)vdev->dma_fault_response_region.mmaps[0].mmap; -+ if (!queue) { -+ size_t queue_size = header.nb_entries * header.entry_size; -+ -+ error_report("%s: fault queue not mmapped: slower fault handling", -+ vdev->vbasedev.name); -+ -+ queue_buffer = g_malloc(queue_size); -+ bytes = pread(vdev->vbasedev.fd, queue_buffer, queue_size, -+ vdev->dma_fault_response_region.fd_offset + header.offset); -+ if (bytes != queue_size) { -+ error_report("%s unable to read the fault queue (0x%lx)", -+ __func__, bytes); -+ return -1; -+ } -+ -+ queue = (struct iommu_page_response *)queue_buffer; -+ } -+ /* deposit the new response in the queue and increment the head */ -+ memcpy(queue + header.head, response, header.entry_size); -+ -+ vdev->fault_response_head_index = -+ (vdev->fault_response_head_index + 1) % header.nb_entries; -+ bytes = pwrite(vdev->vbasedev.fd, &vdev->fault_response_head_index, 4, -+ vdev->dma_fault_response_region.fd_offset); -+ if (bytes != 4) { -+ error_report("%s unable to write the fault response region head index (0x%lx)", -+ __func__, bytes); -+ } -+ g_free(queue_buffer); -+ -+ return 0; -+} -+ - static PCIPASIDOps vfio_pci_pasid_ops = { - .set_pasid_table = vfio_iommu_set_pasid_table, -+ .return_page_response = vfio_iommu_return_page_response, - }; - - static void vfio_dma_fault_notifier_handler(void *opaque) -@@ -3411,6 +3532,7 @@ static void vfio_instance_finalize(Object *obj) - vfio_display_finalize(vdev); - vfio_bars_finalize(vdev); - vfio_region_finalize(&vdev->dma_fault_region); -+ vfio_region_finalize(&vdev->dma_fault_response_region); - g_free(vdev->emulated_config_bits); - g_free(vdev->rom); - /* -@@ -3432,6 +3554,7 @@ static void vfio_exitfn(PCIDevice *pdev) - vfio_unregister_err_notifier(vdev); - vfio_unregister_ext_irq_notifiers(vdev); - vfio_region_exit(&vdev->dma_fault_region); -+ vfio_region_exit(&vdev->dma_fault_response_region); - pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); - if (vdev->irqchip_change_notifier.notify) { - kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index 03ac8919ef..61b3bf1303 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -147,6 +147,8 @@ struct VFIOPCIDevice { - VFIOPCIExtIRQ *ext_irqs; - VFIORegion dma_fault_region; - uint32_t fault_tail_index; -+ VFIORegion dma_fault_response_region; -+ uint32_t fault_response_head_index; - int (*resetfn)(struct VFIOPCIDevice *); - uint32_t vendor_id; - uint32_t device_id; --- -2.27.0 - diff --git a/vfio-pci-Implement-the-DMA-fault-handler.patch b/vfio-pci-Implement-the-DMA-fault-handler.patch deleted file mode 100644 index 7d7349c9088662d0e38aa22c0b0ecbea3e0f7506..0000000000000000000000000000000000000000 --- a/vfio-pci-Implement-the-DMA-fault-handler.patch +++ /dev/null @@ -1,96 +0,0 @@ -From d33cc7eccb68c6a1488804c94ff5c1197ee0fc6e Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Tue, 5 Mar 2019 16:35:32 +0100 -Subject: [PATCH] vfio/pci: Implement the DMA fault handler - -Whenever the eventfd is triggered, we retrieve the DMA fault(s) -from the mmapped fault region and inject them in the iommu -memory region. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/pci.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ - hw/vfio/pci.h | 1 + - 2 files changed, 51 insertions(+) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 76bc9d3506..c54e62fe8f 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2953,10 +2953,60 @@ static PCIPASIDOps vfio_pci_pasid_ops = { - static void vfio_dma_fault_notifier_handler(void *opaque) - { - VFIOPCIExtIRQ *ext_irq = opaque; -+ VFIOPCIDevice *vdev = ext_irq->vdev; -+ PCIDevice *pdev = &vdev->pdev; -+ AddressSpace *as = pci_device_iommu_address_space(pdev); -+ IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(as->root); -+ struct vfio_region_dma_fault header; -+ struct iommu_fault *queue; -+ char *queue_buffer = NULL; -+ ssize_t bytes; - - if (!event_notifier_test_and_clear(&ext_irq->notifier)) { - return; - } -+ -+ bytes = pread(vdev->vbasedev.fd, &header, sizeof(header), -+ vdev->dma_fault_region.fd_offset); -+ if (bytes != sizeof(header)) { -+ error_report("%s unable to read the fault region header (0x%lx)", -+ __func__, bytes); -+ return; -+ } -+ -+ /* Normally the fault queue is mmapped */ -+ queue = (struct iommu_fault *)vdev->dma_fault_region.mmaps[0].mmap; -+ if (!queue) { -+ size_t queue_size = header.nb_entries * header.entry_size; -+ -+ error_report("%s: fault queue not mmapped: slower fault handling", -+ vdev->vbasedev.name); -+ -+ queue_buffer = g_malloc(queue_size); -+ bytes = pread(vdev->vbasedev.fd, queue_buffer, queue_size, -+ vdev->dma_fault_region.fd_offset + header.offset); -+ if (bytes != queue_size) { -+ error_report("%s unable to read the fault queue (0x%lx)", -+ __func__, bytes); -+ return; -+ } -+ -+ queue = (struct iommu_fault *)queue_buffer; -+ } -+ -+ while (vdev->fault_tail_index != header.head) { -+ memory_region_inject_faults(iommu_mr, 1, -+ &queue[vdev->fault_tail_index]); -+ vdev->fault_tail_index = -+ (vdev->fault_tail_index + 1) % header.nb_entries; -+ } -+ bytes = pwrite(vdev->vbasedev.fd, &vdev->fault_tail_index, 4, -+ vdev->dma_fault_region.fd_offset); -+ if (bytes != 4) { -+ error_report("%s unable to write the fault region tail index (0x%lx)", -+ __func__, bytes); -+ } -+ g_free(queue_buffer); - } - - static int vfio_register_ext_irq_handler(VFIOPCIDevice *vdev, -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index eef91065f1..03ac8919ef 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -146,6 +146,7 @@ struct VFIOPCIDevice { - EventNotifier req_notifier; - VFIOPCIExtIRQ *ext_irqs; - VFIORegion dma_fault_region; -+ uint32_t fault_tail_index; - int (*resetfn)(struct VFIOPCIDevice *); - uint32_t vendor_id; - uint32_t device_id; --- -2.27.0 - diff --git a/vfio-pci-Register-handler-for-iommu-fault.patch b/vfio-pci-Register-handler-for-iommu-fault.patch deleted file mode 100644 index 7209a807ee0911af0f6af7e01e29a9ff389944dc..0000000000000000000000000000000000000000 --- a/vfio-pci-Register-handler-for-iommu-fault.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 574455d1363e818905e05cd23ef0948e83a16a51 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 13 Dec 2018 04:39:30 -0500 -Subject: [PATCH] vfio/pci: Register handler for iommu fault - -We use the new extended IRQ VFIO_IRQ_TYPE_NESTED type and -VFIO_IRQ_SUBTYPE_DMA_FAULT subtype to set/unset -a notifier for physical DMA faults. The associated eventfd is -triggered, in nested mode, whenever a fault is detected at IOMMU -physical level. - -The actual handler will be implemented in subsequent patches. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/pci.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++- - hw/vfio/pci.h | 7 +++++ - 2 files changed, 87 insertions(+), 1 deletion(-) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 99c52a0944..37a70932c6 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2888,6 +2888,76 @@ static PCIPASIDOps vfio_pci_pasid_ops = { - .set_pasid_table = vfio_iommu_set_pasid_table, - }; - -+static void vfio_dma_fault_notifier_handler(void *opaque) -+{ -+ VFIOPCIExtIRQ *ext_irq = opaque; -+ -+ if (!event_notifier_test_and_clear(&ext_irq->notifier)) { -+ return; -+ } -+} -+ -+static int vfio_register_ext_irq_handler(VFIOPCIDevice *vdev, -+ uint32_t type, uint32_t subtype, -+ IOHandler *handler) -+{ -+ int32_t fd, ext_irq_index, index; -+ struct vfio_irq_info *irq_info; -+ Error *err = NULL; -+ EventNotifier *n; -+ int ret; -+ -+ ret = vfio_get_dev_irq_info(&vdev->vbasedev, type, subtype, &irq_info); -+ if (ret) { -+ return ret; -+ } -+ index = irq_info->index; -+ ext_irq_index = irq_info->index - VFIO_PCI_NUM_IRQS; -+ g_free(irq_info); -+ -+ vdev->ext_irqs[ext_irq_index].vdev = vdev; -+ vdev->ext_irqs[ext_irq_index].index = index; -+ n = &vdev->ext_irqs[ext_irq_index].notifier; -+ -+ ret = event_notifier_init(n, 0); -+ if (ret) { -+ error_report("vfio: Unable to init event notifier for ext irq %d(%d)", -+ ext_irq_index, ret); -+ return ret; -+ } -+ -+ fd = event_notifier_get_fd(n); -+ qemu_set_fd_handler(fd, vfio_dma_fault_notifier_handler, NULL, -+ &vdev->ext_irqs[ext_irq_index]); -+ -+ ret = vfio_set_irq_signaling(&vdev->vbasedev, index, 0, -+ VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err); -+ if (ret) { -+ error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); -+ qemu_set_fd_handler(fd, NULL, NULL, vdev); -+ event_notifier_cleanup(n); -+ } -+ return ret; -+} -+ -+static void vfio_unregister_ext_irq_notifiers(VFIOPCIDevice *vdev) -+{ -+ VFIODevice *vbasedev = &vdev->vbasedev; -+ Error *err = NULL; -+ int i; -+ -+ for (i = 0; i < vbasedev->num_irqs - VFIO_PCI_NUM_IRQS; i++) { -+ if (vfio_set_irq_signaling(vbasedev, i + VFIO_PCI_NUM_IRQS , 0, -+ VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { -+ error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); -+ } -+ qemu_set_fd_handler(event_notifier_get_fd(&vdev->ext_irqs[i].notifier), -+ NULL, NULL, vdev); -+ event_notifier_cleanup(&vdev->ext_irqs[i].notifier); -+ } -+ g_free(vdev->ext_irqs); -+} -+ - static void vfio_realize(PCIDevice *pdev, Error **errp) - { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); -@@ -2898,7 +2968,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - ssize_t len; - struct stat st; - int groupid; -- int i, ret; -+ int i, ret, nb_ext_irqs; - bool is_mdev; - - if (!vdev->vbasedev.sysfsdev) { -@@ -2986,6 +3056,11 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - goto error; - } - -+ nb_ext_irqs = vdev->vbasedev.num_irqs - VFIO_PCI_NUM_IRQS; -+ if (nb_ext_irqs > 0) { -+ vdev->ext_irqs = g_new0(VFIOPCIExtIRQ, nb_ext_irqs); -+ } -+ - vfio_populate_device(vdev, &err); - if (err) { - error_propagate(errp, err); -@@ -3197,6 +3272,9 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) - - vfio_register_err_notifier(vdev); - vfio_register_req_notifier(vdev); -+ vfio_register_ext_irq_handler(vdev, VFIO_IRQ_TYPE_NESTED, -+ VFIO_IRQ_SUBTYPE_DMA_FAULT, -+ vfio_dma_fault_notifier_handler); - vfio_setup_resetfn_quirk(vdev); - - pci_setup_pasid_ops(pdev, &vfio_pci_pasid_ops); -@@ -3239,6 +3317,7 @@ static void vfio_exitfn(PCIDevice *pdev) - - vfio_unregister_req_notifier(vdev); - vfio_unregister_err_notifier(vdev); -+ vfio_unregister_ext_irq_notifiers(vdev); - pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); - if (vdev->irqchip_change_notifier.notify) { - kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index 64777516d1..a8b06737fb 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -114,6 +114,12 @@ typedef struct VFIOMSIXInfo { - unsigned long *pending; - } VFIOMSIXInfo; - -+typedef struct VFIOPCIExtIRQ { -+ struct VFIOPCIDevice *vdev; -+ EventNotifier notifier; -+ uint32_t index; -+} VFIOPCIExtIRQ; -+ - #define TYPE_VFIO_PCI "vfio-pci" - OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI) - -@@ -138,6 +144,7 @@ struct VFIOPCIDevice { - PCIHostDeviceAddress host; - EventNotifier err_notifier; - EventNotifier req_notifier; -+ VFIOPCIExtIRQ *ext_irqs; - int (*resetfn)(struct VFIOPCIDevice *); - uint32_t vendor_id; - uint32_t device_id; --- -2.27.0 - diff --git a/vfio-pci-Set-up-the-DMA-FAULT-region.patch b/vfio-pci-Set-up-the-DMA-FAULT-region.patch deleted file mode 100644 index 9a4757dc7bbd03571a7d7e5981828ad817da5654..0000000000000000000000000000000000000000 --- a/vfio-pci-Set-up-the-DMA-FAULT-region.patch +++ /dev/null @@ -1,132 +0,0 @@ -From e701d0fef4fbb7935d6aa7d22d82eb2dcfee2431 Mon Sep 17 00:00:00 2001 -From: Eric Auger -Date: Thu, 13 Dec 2018 10:57:53 -0500 -Subject: [PATCH] vfio/pci: Set up the DMA FAULT region - -Set up the fault region which is composed of the actual fault -queue (mmappable) and a header used to handle it. The fault -queue is mmapped. - -Signed-off-by: Eric Auger -Signed-off-by: Kunkun Jiang ---- - hw/vfio/pci.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ - hw/vfio/pci.h | 1 + - 2 files changed, 65 insertions(+) - -diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c -index 37a70932c6..76bc9d3506 100644 ---- a/hw/vfio/pci.c -+++ b/hw/vfio/pci.c -@@ -2638,11 +2638,67 @@ int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp) - return 0; - } - -+static void vfio_init_fault_regions(VFIOPCIDevice *vdev, Error **errp) -+{ -+ struct vfio_region_info *fault_region_info = NULL; -+ struct vfio_region_info_cap_fault *cap_fault; -+ VFIODevice *vbasedev = &vdev->vbasedev; -+ struct vfio_info_cap_header *hdr; -+ char *fault_region_name; -+ int ret; -+ -+ ret = vfio_get_dev_region_info(&vdev->vbasedev, -+ VFIO_REGION_TYPE_NESTED, -+ VFIO_REGION_SUBTYPE_NESTED_DMA_FAULT, -+ &fault_region_info); -+ if (ret) { -+ goto out; -+ } -+ -+ hdr = vfio_get_region_info_cap(fault_region_info, -+ VFIO_REGION_INFO_CAP_DMA_FAULT); -+ if (!hdr) { -+ error_setg(errp, "failed to retrieve DMA FAULT capability"); -+ goto out; -+ } -+ cap_fault = container_of(hdr, struct vfio_region_info_cap_fault, -+ header); -+ if (cap_fault->version != 1) { -+ error_setg(errp, "Unsupported DMA FAULT API version %d", -+ cap_fault->version); -+ goto out; -+ } -+ -+ fault_region_name = g_strdup_printf("%s DMA FAULT %d", -+ vbasedev->name, -+ fault_region_info->index); -+ -+ ret = vfio_region_setup(OBJECT(vdev), vbasedev, -+ &vdev->dma_fault_region, -+ fault_region_info->index, -+ fault_region_name); -+ g_free(fault_region_name); -+ if (ret) { -+ error_setg_errno(errp, -ret, -+ "failed to set up the DMA FAULT region %d", -+ fault_region_info->index); -+ goto out; -+ } -+ -+ ret = vfio_region_mmap(&vdev->dma_fault_region); -+ if (ret) { -+ error_setg_errno(errp, -ret, "Failed to mmap the DMA FAULT queue"); -+ } -+out: -+ g_free(fault_region_info); -+} -+ - static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) - { - VFIODevice *vbasedev = &vdev->vbasedev; - struct vfio_region_info *reg_info; - struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) }; -+ Error *err = NULL; - int i, ret = -1; - - /* Sanity check device */ -@@ -2706,6 +2762,12 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) - } - } - -+ vfio_init_fault_regions(vdev, &err); -+ if (err) { -+ error_propagate(errp, err); -+ return; -+ } -+ - irq_info.index = VFIO_PCI_ERR_IRQ_INDEX; - - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info); -@@ -3298,6 +3360,7 @@ static void vfio_instance_finalize(Object *obj) - - vfio_display_finalize(vdev); - vfio_bars_finalize(vdev); -+ vfio_region_finalize(&vdev->dma_fault_region); - g_free(vdev->emulated_config_bits); - g_free(vdev->rom); - /* -@@ -3318,6 +3381,7 @@ static void vfio_exitfn(PCIDevice *pdev) - vfio_unregister_req_notifier(vdev); - vfio_unregister_err_notifier(vdev); - vfio_unregister_ext_irq_notifiers(vdev); -+ vfio_region_exit(&vdev->dma_fault_region); - pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); - if (vdev->irqchip_change_notifier.notify) { - kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); -diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h -index a8b06737fb..eef91065f1 100644 ---- a/hw/vfio/pci.h -+++ b/hw/vfio/pci.h -@@ -145,6 +145,7 @@ struct VFIOPCIDevice { - EventNotifier err_notifier; - EventNotifier req_notifier; - VFIOPCIExtIRQ *ext_irqs; -+ VFIORegion dma_fault_region; - int (*resetfn)(struct VFIOPCIDevice *); - uint32_t vendor_id; - uint32_t device_id; --- -2.27.0 - diff --git a/vfio.h-and-iommu.h-header-update-against-5.10.patch b/vfio.h-and-iommu.h-header-update-against-5.10.patch deleted file mode 100644 index 8272a6793eb1b672efe3980f4abc3ca61cb39732..0000000000000000000000000000000000000000 --- a/vfio.h-and-iommu.h-header-update-against-5.10.patch +++ /dev/null @@ -1,701 +0,0 @@ -From 36b65d7312a343cb636e6963b8262dce9420ebc6 Mon Sep 17 00:00:00 2001 -From: Kunkun Jiang -Date: Fri, 30 Jul 2021 09:15:31 +0800 -Subject: [PATCH] vfio.h and iommu.h header update against 5.10 - -Signed-off-by: Kunkun Jiang ---- - linux-headers/linux/iommu.h | 395 ++++++++++++++++++++++++++++++++++++ - linux-headers/linux/vfio.h | 220 +++++++++++++++++++- - 2 files changed, 613 insertions(+), 2 deletions(-) - create mode 100644 linux-headers/linux/iommu.h - -diff --git a/linux-headers/linux/iommu.h b/linux-headers/linux/iommu.h -new file mode 100644 -index 0000000000..773b7dc2d6 ---- /dev/null -+++ b/linux-headers/linux/iommu.h -@@ -0,0 +1,395 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * IOMMU user API definitions -+ */ -+ -+#ifndef IOMMU_H -+#define IOMMU_H -+ -+#include -+ -+#define IOMMU_FAULT_PERM_READ (1 << 0) /* read */ -+#define IOMMU_FAULT_PERM_WRITE (1 << 1) /* write */ -+#define IOMMU_FAULT_PERM_EXEC (1 << 2) /* exec */ -+#define IOMMU_FAULT_PERM_PRIV (1 << 3) /* privileged */ -+ -+/* Generic fault types, can be expanded IRQ remapping fault */ -+enum iommu_fault_type { -+ IOMMU_FAULT_DMA_UNRECOV = 1, /* unrecoverable fault */ -+ IOMMU_FAULT_PAGE_REQ, /* page request fault */ -+}; -+ -+enum iommu_fault_reason { -+ IOMMU_FAULT_REASON_UNKNOWN = 0, -+ -+ /* Could not access the PASID table (fetch caused external abort) */ -+ IOMMU_FAULT_REASON_PASID_FETCH, -+ -+ /* PASID entry is invalid or has configuration errors */ -+ IOMMU_FAULT_REASON_BAD_PASID_ENTRY, -+ -+ /* -+ * PASID is out of range (e.g. exceeds the maximum PASID -+ * supported by the IOMMU) or disabled. -+ */ -+ IOMMU_FAULT_REASON_PASID_INVALID, -+ -+ /* -+ * An external abort occurred fetching (or updating) a translation -+ * table descriptor -+ */ -+ IOMMU_FAULT_REASON_WALK_EABT, -+ -+ /* -+ * Could not access the page table entry (Bad address), -+ * actual translation fault -+ */ -+ IOMMU_FAULT_REASON_PTE_FETCH, -+ -+ /* Protection flag check failed */ -+ IOMMU_FAULT_REASON_PERMISSION, -+ -+ /* access flag check failed */ -+ IOMMU_FAULT_REASON_ACCESS, -+ -+ /* Output address of a translation stage caused Address Size fault */ -+ IOMMU_FAULT_REASON_OOR_ADDRESS, -+}; -+ -+/** -+ * struct iommu_fault_unrecoverable - Unrecoverable fault data -+ * @reason: reason of the fault, from &enum iommu_fault_reason -+ * @flags: parameters of this fault (IOMMU_FAULT_UNRECOV_* values) -+ * @pasid: Process Address Space ID -+ * @perm: requested permission access using by the incoming transaction -+ * (IOMMU_FAULT_PERM_* values) -+ * @addr: offending page address -+ * @fetch_addr: address that caused a fetch abort, if any -+ */ -+struct iommu_fault_unrecoverable { -+ __u32 reason; -+#define IOMMU_FAULT_UNRECOV_PASID_VALID (1 << 0) -+#define IOMMU_FAULT_UNRECOV_ADDR_VALID (1 << 1) -+#define IOMMU_FAULT_UNRECOV_FETCH_ADDR_VALID (1 << 2) -+ __u32 flags; -+ __u32 pasid; -+ __u32 perm; -+ __u64 addr; -+ __u64 fetch_addr; -+}; -+ -+/** -+ * struct iommu_fault_page_request - Page Request data -+ * @flags: encodes whether the corresponding fields are valid and whether this -+ * is the last page in group (IOMMU_FAULT_PAGE_REQUEST_* values). -+ * When IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID is set, the page response -+ * must have the same PASID value as the page request. When it is clear, -+ * the page response should not have a PASID. -+ * @pasid: Process Address Space ID -+ * @grpid: Page Request Group Index -+ * @perm: requested page permissions (IOMMU_FAULT_PERM_* values) -+ * @addr: page address -+ * @private_data: device-specific private information -+ */ -+struct iommu_fault_page_request { -+#define IOMMU_FAULT_PAGE_REQUEST_PASID_VALID (1 << 0) -+#define IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE (1 << 1) -+#define IOMMU_FAULT_PAGE_REQUEST_PRIV_DATA (1 << 2) -+#define IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID (1 << 3) -+ __u32 flags; -+ __u32 pasid; -+ __u32 grpid; -+ __u32 perm; -+ __u64 addr; -+ __u64 private_data[2]; -+}; -+ -+/** -+ * struct iommu_fault - Generic fault data -+ * @type: fault type from &enum iommu_fault_type -+ * @padding: reserved for future use (should be zero) -+ * @event: fault event, when @type is %IOMMU_FAULT_DMA_UNRECOV -+ * @prm: Page Request message, when @type is %IOMMU_FAULT_PAGE_REQ -+ * @padding2: sets the fault size to allow for future extensions -+ */ -+struct iommu_fault { -+ __u32 type; -+ __u32 padding; -+ union { -+ struct iommu_fault_unrecoverable event; -+ struct iommu_fault_page_request prm; -+ __u8 padding2[56]; -+ }; -+}; -+ -+/** -+ * enum iommu_page_response_code - Return status of fault handlers -+ * @IOMMU_PAGE_RESP_SUCCESS: Fault has been handled and the page tables -+ * populated, retry the access. This is "Success" in PCI PRI. -+ * @IOMMU_PAGE_RESP_FAILURE: General error. Drop all subsequent faults from -+ * this device if possible. This is "Response Failure" in PCI PRI. -+ * @IOMMU_PAGE_RESP_INVALID: Could not handle this fault, don't retry the -+ * access. This is "Invalid Request" in PCI PRI. -+ */ -+enum iommu_page_response_code { -+ IOMMU_PAGE_RESP_SUCCESS = 0, -+ IOMMU_PAGE_RESP_INVALID, -+ IOMMU_PAGE_RESP_FAILURE, -+}; -+ -+/** -+ * struct iommu_page_response - Generic page response information -+ * @argsz: User filled size of this data -+ * @version: API version of this structure -+ * @flags: encodes whether the corresponding fields are valid -+ * (IOMMU_FAULT_PAGE_RESPONSE_* values) -+ * @pasid: Process Address Space ID -+ * @grpid: Page Request Group Index -+ * @code: response code from &enum iommu_page_response_code -+ */ -+struct iommu_page_response { -+ __u32 argsz; -+#define IOMMU_PAGE_RESP_VERSION_1 1 -+ __u32 version; -+#define IOMMU_PAGE_RESP_PASID_VALID (1 << 0) -+ __u32 flags; -+ __u32 pasid; -+ __u32 grpid; -+ __u32 code; -+}; -+ -+/* defines the granularity of the invalidation */ -+enum iommu_inv_granularity { -+ IOMMU_INV_GRANU_DOMAIN, /* domain-selective invalidation */ -+ IOMMU_INV_GRANU_PASID, /* PASID-selective invalidation */ -+ IOMMU_INV_GRANU_ADDR, /* page-selective invalidation */ -+ IOMMU_INV_GRANU_NR, /* number of invalidation granularities */ -+}; -+ -+/** -+ * struct iommu_inv_addr_info - Address Selective Invalidation Structure -+ * -+ * @flags: indicates the granularity of the address-selective invalidation -+ * - If the PASID bit is set, the @pasid field is populated and the invalidation -+ * relates to cache entries tagged with this PASID and matching the address -+ * range. -+ * - If ARCHID bit is set, @archid is populated and the invalidation relates -+ * to cache entries tagged with this architecture specific ID and matching -+ * the address range. -+ * - Both PASID and ARCHID can be set as they may tag different caches. -+ * - If neither PASID or ARCHID is set, global addr invalidation applies. -+ * - The LEAF flag indicates whether only the leaf PTE caching needs to be -+ * invalidated and other paging structure caches can be preserved. -+ * @pasid: process address space ID -+ * @archid: architecture-specific ID -+ * @addr: first stage/level input address -+ * @granule_size: page/block size of the mapping in bytes -+ * @nb_granules: number of contiguous granules to be invalidated -+ */ -+struct iommu_inv_addr_info { -+#define IOMMU_INV_ADDR_FLAGS_PASID (1 << 0) -+#define IOMMU_INV_ADDR_FLAGS_ARCHID (1 << 1) -+#define IOMMU_INV_ADDR_FLAGS_LEAF (1 << 2) -+ __u32 flags; -+ __u32 archid; -+ __u64 pasid; -+ __u64 addr; -+ __u64 granule_size; -+ __u64 nb_granules; -+}; -+ -+/** -+ * struct iommu_inv_pasid_info - PASID Selective Invalidation Structure -+ * -+ * @flags: indicates the granularity of the PASID-selective invalidation -+ * - If the PASID bit is set, the @pasid field is populated and the invalidation -+ * relates to cache entries tagged with this PASID and matching the address -+ * range. -+ * - If the ARCHID bit is set, the @archid is populated and the invalidation -+ * relates to cache entries tagged with this architecture specific ID and -+ * matching the address range. -+ * - Both PASID and ARCHID can be set as they may tag different caches. -+ * - At least one of PASID or ARCHID must be set. -+ * @pasid: process address space ID -+ * @archid: architecture-specific ID -+ */ -+struct iommu_inv_pasid_info { -+#define IOMMU_INV_PASID_FLAGS_PASID (1 << 0) -+#define IOMMU_INV_PASID_FLAGS_ARCHID (1 << 1) -+ __u32 flags; -+ __u32 archid; -+ __u64 pasid; -+}; -+ -+/** -+ * struct iommu_cache_invalidate_info - First level/stage invalidation -+ * information -+ * @argsz: User filled size of this data -+ * @version: API version of this structure -+ * @cache: bitfield that allows to select which caches to invalidate -+ * @granularity: defines the lowest granularity used for the invalidation: -+ * domain > PASID > addr -+ * @padding: reserved for future use (should be zero) -+ * @pasid_info: invalidation data when @granularity is %IOMMU_INV_GRANU_PASID -+ * @addr_info: invalidation data when @granularity is %IOMMU_INV_GRANU_ADDR -+ * -+ * Not all the combinations of cache/granularity are valid: -+ * -+ * +--------------+---------------+---------------+---------------+ -+ * | type / | DEV_IOTLB | IOTLB | PASID | -+ * | granularity | | | cache | -+ * +==============+===============+===============+===============+ -+ * | DOMAIN | N/A | Y | Y | -+ * +--------------+---------------+---------------+---------------+ -+ * | PASID | Y | Y | Y | -+ * +--------------+---------------+---------------+---------------+ -+ * | ADDR | Y | Y | N/A | -+ * +--------------+---------------+---------------+---------------+ -+ * -+ * Invalidations by %IOMMU_INV_GRANU_DOMAIN don't take any argument other than -+ * @version and @cache. -+ * -+ * If multiple cache types are invalidated simultaneously, they all -+ * must support the used granularity. -+ */ -+struct iommu_cache_invalidate_info { -+ __u32 argsz; -+#define IOMMU_CACHE_INVALIDATE_INFO_VERSION_1 1 -+ __u32 version; -+/* IOMMU paging structure cache */ -+#define IOMMU_CACHE_INV_TYPE_IOTLB (1 << 0) /* IOMMU IOTLB */ -+#define IOMMU_CACHE_INV_TYPE_DEV_IOTLB (1 << 1) /* Device IOTLB */ -+#define IOMMU_CACHE_INV_TYPE_PASID (1 << 2) /* PASID cache */ -+#define IOMMU_CACHE_INV_TYPE_NR (3) -+ __u8 cache; -+ __u8 granularity; -+ __u8 padding[6]; -+ union { -+ struct iommu_inv_pasid_info pasid_info; -+ struct iommu_inv_addr_info addr_info; -+ } granu; -+}; -+ -+/** -+ * struct iommu_gpasid_bind_data_vtd - Intel VT-d specific data on device and guest -+ * SVA binding. -+ * -+ * @flags: VT-d PASID table entry attributes -+ * @pat: Page attribute table data to compute effective memory type -+ * @emt: Extended memory type -+ * -+ * Only guest vIOMMU selectable and effective options are passed down to -+ * the host IOMMU. -+ */ -+struct iommu_gpasid_bind_data_vtd { -+#define IOMMU_SVA_VTD_GPASID_SRE (1 << 0) /* supervisor request */ -+#define IOMMU_SVA_VTD_GPASID_EAFE (1 << 1) /* extended access enable */ -+#define IOMMU_SVA_VTD_GPASID_PCD (1 << 2) /* page-level cache disable */ -+#define IOMMU_SVA_VTD_GPASID_PWT (1 << 3) /* page-level write through */ -+#define IOMMU_SVA_VTD_GPASID_EMTE (1 << 4) /* extended mem type enable */ -+#define IOMMU_SVA_VTD_GPASID_CD (1 << 5) /* PASID-level cache disable */ -+#define IOMMU_SVA_VTD_GPASID_LAST (1 << 6) -+ __u64 flags; -+ __u32 pat; -+ __u32 emt; -+}; -+ -+#define IOMMU_SVA_VTD_GPASID_MTS_MASK (IOMMU_SVA_VTD_GPASID_CD | \ -+ IOMMU_SVA_VTD_GPASID_EMTE | \ -+ IOMMU_SVA_VTD_GPASID_PCD | \ -+ IOMMU_SVA_VTD_GPASID_PWT) -+ -+/** -+ * struct iommu_gpasid_bind_data - Information about device and guest PASID binding -+ * @argsz: User filled size of this data -+ * @version: Version of this data structure -+ * @format: PASID table entry format -+ * @flags: Additional information on guest bind request -+ * @gpgd: Guest page directory base of the guest mm to bind -+ * @hpasid: Process address space ID used for the guest mm in host IOMMU -+ * @gpasid: Process address space ID used for the guest mm in guest IOMMU -+ * @addr_width: Guest virtual address width -+ * @padding: Reserved for future use (should be zero) -+ * @vtd: Intel VT-d specific data -+ * -+ * Guest to host PASID mapping can be an identity or non-identity, where guest -+ * has its own PASID space. For non-identify mapping, guest to host PASID lookup -+ * is needed when VM programs guest PASID into an assigned device. VMM may -+ * trap such PASID programming then request host IOMMU driver to convert guest -+ * PASID to host PASID based on this bind data. -+ */ -+struct iommu_gpasid_bind_data { -+ __u32 argsz; -+#define IOMMU_GPASID_BIND_VERSION_1 1 -+ __u32 version; -+#define IOMMU_PASID_FORMAT_INTEL_VTD 1 -+#define IOMMU_PASID_FORMAT_LAST 2 -+ __u32 format; -+ __u32 addr_width; -+#define IOMMU_SVA_GPASID_VAL (1 << 0) /* guest PASID valid */ -+ __u64 flags; -+ __u64 gpgd; -+ __u64 hpasid; -+ __u64 gpasid; -+ __u8 padding[8]; -+ /* Vendor specific data */ -+ union { -+ struct iommu_gpasid_bind_data_vtd vtd; -+ } vendor; -+}; -+ -+/** -+ * struct iommu_pasid_smmuv3 - ARM SMMUv3 Stream Table Entry stage 1 related -+ * information -+ * @version: API version of this structure -+ * @s1fmt: STE s1fmt (format of the CD table: single CD, linear table -+ * or 2-level table) -+ * @s1dss: STE s1dss (specifies the behavior when @pasid_bits != 0 -+ * and no PASID is passed along with the incoming transaction) -+ * @padding: reserved for future use (should be zero) -+ * -+ * The PASID table is referred to as the Context Descriptor (CD) table on ARM -+ * SMMUv3. Please refer to the ARM SMMU 3.x spec (ARM IHI 0070A) for full -+ * details. -+ */ -+struct iommu_pasid_smmuv3 { -+#define PASID_TABLE_SMMUV3_CFG_VERSION_1 1 -+ __u32 version; -+ __u8 s1fmt; -+ __u8 s1dss; -+ __u8 padding[2]; -+}; -+ -+/** -+ * struct iommu_pasid_table_config - PASID table data used to bind guest PASID -+ * table to the host IOMMU -+ * @argsz: User filled size of this data -+ * @version: API version to prepare for future extensions -+ * @base_ptr: guest physical address of the PASID table -+ * @format: format of the PASID table -+ * @pasid_bits: number of PASID bits used in the PASID table -+ * @config: indicates whether the guest translation stage must -+ * be translated, bypassed or aborted. -+ * @padding: reserved for future use (should be zero) -+ * @vendor_data.smmuv3: table information when @format is -+ * %IOMMU_PASID_FORMAT_SMMUV3 -+ */ -+struct iommu_pasid_table_config { -+ __u32 argsz; -+#define PASID_TABLE_CFG_VERSION_1 1 -+ __u32 version; -+ __u64 base_ptr; -+#define IOMMU_PASID_FORMAT_SMMUV3 1 -+ __u32 format; -+ __u8 pasid_bits; -+#define IOMMU_PASID_CONFIG_TRANSLATE 1 -+#define IOMMU_PASID_CONFIG_BYPASS 2 -+#define IOMMU_PASID_CONFIG_ABORT 3 -+ __u8 config; -+ __u8 padding[2]; -+ union { -+ struct iommu_pasid_smmuv3 smmuv3; -+ } vendor_data; -+}; -+ -+#endif /* _UAPI_IOMMU_H */ -diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h -index f4ff038e8c..cf8e208fac 100644 ---- a/linux-headers/linux/vfio.h -+++ b/linux-headers/linux/vfio.h -@@ -14,6 +14,7 @@ - - #include - #include -+#include - - #define VFIO_API_VERSION 0 - -@@ -334,6 +335,7 @@ struct vfio_region_info_cap_type { - #define VFIO_REGION_TYPE_GFX (1) - #define VFIO_REGION_TYPE_CCW (2) - #define VFIO_REGION_TYPE_MIGRATION (3) -+#define VFIO_REGION_TYPE_NESTED (4) - - /* sub-types for VFIO_REGION_TYPE_PCI_* */ - -@@ -362,6 +364,10 @@ struct vfio_region_info_cap_type { - /* sub-types for VFIO_REGION_TYPE_GFX */ - #define VFIO_REGION_SUBTYPE_GFX_EDID (1) - -+/* sub-types for VFIO_REGION_TYPE_NESTED */ -+#define VFIO_REGION_SUBTYPE_NESTED_DMA_FAULT (1) -+#define VFIO_REGION_SUBTYPE_NESTED_DMA_FAULT_RESPONSE (2) -+ - /** - * struct vfio_region_gfx_edid - EDID region layout. - * -@@ -721,11 +727,30 @@ struct vfio_irq_info { - #define VFIO_IRQ_INFO_MASKABLE (1 << 1) - #define VFIO_IRQ_INFO_AUTOMASKED (1 << 2) - #define VFIO_IRQ_INFO_NORESIZE (1 << 3) -+#define VFIO_IRQ_INFO_FLAG_CAPS (1 << 4) /* Info supports caps */ - __u32 index; /* IRQ index */ - __u32 count; /* Number of IRQs within this index */ -+ __u32 cap_offset; /* Offset within info struct of first cap */ - }; - #define VFIO_DEVICE_GET_IRQ_INFO _IO(VFIO_TYPE, VFIO_BASE + 9) - -+/* -+ * The irq type capability allows IRQs unique to a specific device or -+ * class of devices to be exposed. -+ * -+ * The structures below define version 1 of this capability. -+ */ -+#define VFIO_IRQ_INFO_CAP_TYPE 3 -+ -+struct vfio_irq_info_cap_type { -+ struct vfio_info_cap_header header; -+ __u32 type; /* global per bus driver */ -+ __u32 subtype; /* type specific */ -+}; -+ -+#define VFIO_IRQ_TYPE_NESTED (1) -+#define VFIO_IRQ_SUBTYPE_DMA_FAULT (1) -+ - /** - * VFIO_DEVICE_SET_IRQS - _IOW(VFIO_TYPE, VFIO_BASE + 10, struct vfio_irq_set) - * -@@ -827,7 +852,8 @@ enum { - VFIO_PCI_MSIX_IRQ_INDEX, - VFIO_PCI_ERR_IRQ_INDEX, - VFIO_PCI_REQ_IRQ_INDEX, -- VFIO_PCI_NUM_IRQS -+ VFIO_PCI_NUM_IRQS = 5 /* Fixed user ABI, IRQ indexes >=5 use */ -+ /* device specific cap to define content */ - }; - - /* -@@ -1012,6 +1038,68 @@ struct vfio_device_feature { - */ - #define VFIO_DEVICE_FEATURE_PCI_VF_TOKEN (0) - -+/* -+ * Capability exposed by the DMA fault region -+ * @version: ABI version -+ */ -+#define VFIO_REGION_INFO_CAP_DMA_FAULT 6 -+ -+struct vfio_region_info_cap_fault { -+ struct vfio_info_cap_header header; -+ __u32 version; -+}; -+ -+/* -+ * Capability exposed by the DMA fault response region -+ * @version: ABI version -+ */ -+#define VFIO_REGION_INFO_CAP_DMA_FAULT_RESPONSE 7 -+ -+struct vfio_region_info_cap_fault_response { -+ struct vfio_info_cap_header header; -+ __u32 version; -+}; -+ -+/* -+ * DMA Fault Region Layout -+ * @tail: index relative to the start of the ring buffer at which the -+ * consumer finds the next item in the buffer -+ * @entry_size: fault ring buffer entry size in bytes -+ * @nb_entries: max capacity of the fault ring buffer -+ * @offset: ring buffer offset relative to the start of the region -+ * @head: index relative to the start of the ring buffer at which the -+ * producer (kernel) inserts items into the buffers -+ */ -+struct vfio_region_dma_fault { -+ /* Write-Only */ -+ __u32 tail; -+ /* Read-Only */ -+ __u32 entry_size; -+ __u32 nb_entries; -+ __u32 offset; -+ __u32 head; -+}; -+ -+/* -+ * DMA Fault Response Region Layout -+ * @head: index relative to the start of the ring buffer at which the -+ * producer (userspace) insert responses into the buffer -+ * @entry_size: fault ring buffer entry size in bytes -+ * @nb_entries: max capacity of the fault ring buffer -+ * @offset: ring buffer offset relative to the start of the region -+ * @tail: index relative to the start of the ring buffer at which the -+ * consumer (kernel) finds the next item in the buffer -+ */ -+struct vfio_region_dma_fault_response { -+ /* Write-Only */ -+ __u32 head; -+ /* Read-Only */ -+ __u32 entry_size; -+ __u32 nb_entries; -+ __u32 offset; -+ __u32 tail; -+}; -+ - /* -------- API for Type1 VFIO IOMMU -------- */ - - /** -@@ -1124,7 +1212,7 @@ struct vfio_iommu_type1_dma_map { - struct vfio_bitmap { - __u64 pgsize; /* page size for bitmap in bytes */ - __u64 size; /* in bytes */ -- __u64 *data; /* one bit per page */ -+ __u64 *data; /* one bit per page */ - }; - - /** -@@ -1250,6 +1338,134 @@ struct vfio_iommu_type1_dirty_bitmap_get { - - #define VFIO_IOMMU_DIRTY_PAGES _IO(VFIO_TYPE, VFIO_BASE + 17) - -+/* -+ * VFIO_IOMMU_BIND_PROCESS -+ * -+ * Allocate a PASID for a process address space, and use it to attach this -+ * process to all devices in the container. Devices can then tag their DMA -+ * traffic with the returned @pasid to perform transactions on the associated -+ * virtual address space. Mapping and unmapping buffers is performed by standard -+ * functions such as mmap and malloc. -+ * -+ * If flag is VFIO_IOMMU_BIND_PID, @pid contains the pid of a foreign process to -+ * bind. Otherwise the current task is bound. Given that the caller owns the -+ * device, setting this flag grants the caller read and write permissions on the -+ * entire address space of foreign process described by @pid. Therefore, -+ * permission to perform the bind operation on a foreign process is governed by -+ * the ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check. See man ptrace(2) -+ * for more information. -+ * -+ * On success, VFIO writes a Process Address Space ID (PASID) into @pasid. This -+ * ID is unique to a process and can be used on all devices in the container. -+ * -+ * On fork, the child inherits the device fd and can use the bonds setup by its -+ * parent. Consequently, the child has R/W access on the address spaces bound by -+ * its parent. After an execv, the device fd is closed and the child doesn't -+ * have access to the address space anymore. -+ * -+ * To remove a bond between process and container, VFIO_IOMMU_UNBIND ioctl is -+ * issued with the same parameters. If a pid was specified in VFIO_IOMMU_BIND, -+ * it should also be present for VFIO_IOMMU_UNBIND. Otherwise unbind the current -+ * task from the container. -+ */ -+struct vfio_iommu_type1_bind_process { -+ __u32 flags; -+#define VFIO_IOMMU_BIND_PID (1 << 0) -+ __u32 pasid; -+ __s32 pid; -+}; -+ -+/* -+ * Only mode supported at the moment is VFIO_IOMMU_BIND_PROCESS, which takes -+ * vfio_iommu_type1_bind_process in data. -+ */ -+struct vfio_iommu_type1_bind { -+ __u32 argsz; -+ __u32 flags; -+#define VFIO_IOMMU_BIND_PROCESS (1 << 0) -+ __u8 data[]; -+}; -+ -+/* -+ * VFIO_IOMMU_BIND - _IOWR(VFIO_TYPE, VFIO_BASE + 22, struct vfio_iommu_bind) -+ * -+ * Manage address spaces of devices in this container. Initially a TYPE1 -+ * container can only have one address space, managed with -+ * VFIO_IOMMU_MAP/UNMAP_DMA. -+ * -+ * An IOMMU of type VFIO_TYPE1_NESTING_IOMMU can be managed by both MAP/UNMAP -+ * and BIND ioctls at the same time. MAP/UNMAP acts on the stage-2 (host) page -+ * tables, and BIND manages the stage-1 (guest) page tables. Other types of -+ * IOMMU may allow MAP/UNMAP and BIND to coexist, where MAP/UNMAP controls -+ * non-PASID traffic and BIND controls PASID traffic. But this depends on the -+ * underlying IOMMU architecture and isn't guaranteed. -+ * -+ * Availability of this feature depends on the device, its bus, the underlying -+ * IOMMU and the CPU architecture. -+ * -+ * returns: 0 on success, -errno on failure. -+ */ -+#define VFIO_IOMMU_BIND _IO(VFIO_TYPE, VFIO_BASE + 22) -+ -+/* -+ * VFIO_IOMMU_UNBIND - _IOWR(VFIO_TYPE, VFIO_BASE + 23, struct vfio_iommu_bind) -+ * -+ * Undo what was done by the corresponding VFIO_IOMMU_BIND ioctl. -+ */ -+#define VFIO_IOMMU_UNBIND _IO(VFIO_TYPE, VFIO_BASE + 23) -+ -+/* -+ * VFIO_IOMMU_SET_PASID_TABLE - _IOWR(VFIO_TYPE, VFIO_BASE + 18, -+ * struct vfio_iommu_type1_set_pasid_table) -+ * -+ * The SET operation passes a PASID table to the host while the -+ * UNSET operation detaches the one currently programmed. It is -+ * allowed to "SET" the table several times without unsetting as -+ * long as the table config does not stay IOMMU_PASID_CONFIG_TRANSLATE. -+ */ -+struct vfio_iommu_type1_set_pasid_table { -+ __u32 argsz; -+ __u32 flags; -+#define VFIO_PASID_TABLE_FLAG_SET (1 << 0) -+#define VFIO_PASID_TABLE_FLAG_UNSET (1 << 1) -+ struct iommu_pasid_table_config config; /* used on SET */ -+}; -+ -+#define VFIO_IOMMU_SET_PASID_TABLE _IO(VFIO_TYPE, VFIO_BASE + 18) -+ -+/** -+ * VFIO_IOMMU_CACHE_INVALIDATE - _IOWR(VFIO_TYPE, VFIO_BASE + 19, -+ * struct vfio_iommu_type1_cache_invalidate) -+ * -+ * Propagate guest IOMMU cache invalidation to the host. -+ */ -+struct vfio_iommu_type1_cache_invalidate { -+ __u32 argsz; -+ __u32 flags; -+ struct iommu_cache_invalidate_info info; -+}; -+#define VFIO_IOMMU_CACHE_INVALIDATE _IO(VFIO_TYPE, VFIO_BASE + 19) -+ -+/** -+ * VFIO_IOMMU_SET_MSI_BINDING - _IOWR(VFIO_TYPE, VFIO_BASE + 20, -+ * struct vfio_iommu_type1_set_msi_binding) -+ * -+ * Pass a stage 1 MSI doorbell mapping to the host so that this -+ * latter can build a nested stage2 mapping. Or conversely tear -+ * down a previously bound stage 1 MSI binding. -+ */ -+struct vfio_iommu_type1_set_msi_binding { -+ __u32 argsz; -+ __u32 flags; -+#define VFIO_IOMMU_BIND_MSI (1 << 0) -+#define VFIO_IOMMU_UNBIND_MSI (1 << 1) -+ __u64 iova; /* MSI guest IOVA */ -+ /* Fields below are used on BIND */ -+ __u64 gpa; /* MSI guest physical address */ -+ __u64 size; /* size of stage1 mapping (bytes) */ -+}; -+#define VFIO_IOMMU_SET_MSI_BINDING _IO(VFIO_TYPE, VFIO_BASE + 20) -+ - /* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */ - - /* --- -2.27.0 - diff --git a/vga-avoid-crash-if-no-default-vga-card.patch b/vga-avoid-crash-if-no-default-vga-card.patch deleted file mode 100644 index 829bcae46235e3d63cbee2cfdf9c28893c6374f2..0000000000000000000000000000000000000000 --- a/vga-avoid-crash-if-no-default-vga-card.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 70b0d16c684364594443520fba504e665f167cc4 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 17 Nov 2023 09:38:56 +0000 -Subject: [PATCH] vga: avoid crash if no default vga card mainline inclusion - commit 6985d8ede92494f3b791de01e8ee9306eb6d5e4a category: bugfix - ---------------------------------------------------------------- - -QEMU in some arch will crash when executing -vga help command, because -there is no default vga model. Add check to this case and avoid crash. - -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/978 - -Signed-off-by: Guo Zhi -Reviewed-by: Thomas Huth -Tested-by: Thomas Huth -Message-Id: <20220503091724.970009-1-qtxuning1999@sjtu.edu.cn> -Signed-off-by: Laurent Vivier - -Signed-off-by: tangbinzy ---- - softmmu/vl.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/softmmu/vl.c b/softmmu/vl.c -index d8996f3d6e..e34c8a0646 100644 ---- a/softmmu/vl.c -+++ b/softmmu/vl.c -@@ -974,7 +974,8 @@ static void select_vgahw(const MachineClass *machine_class, const char *p) - - if (vga_interface_available(t) && ti->opt_name) { - printf("%-20s %s%s\n", ti->opt_name, ti->name ?: "", -- g_str_equal(ti->opt_name, def) ? " (default)" : ""); -+ (def && g_str_equal(ti->opt_name, def)) ? -+ " (default)" : ""); - } - } - exit(0); --- -2.27.0 - diff --git a/vhost-Add-SVQDescState.patch b/vhost-Add-SVQDescState.patch deleted file mode 100644 index 748d3266f8274b1ef46ac1af4952a58272447b27..0000000000000000000000000000000000000000 --- a/vhost-Add-SVQDescState.patch +++ /dev/null @@ -1,116 +0,0 @@ -From f8caeca478eb902982879ecd7fad9ffa518ad3bb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:34 +0200 -Subject: [PATCH] vhost: Add SVQDescState -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This will allow SVQ to add context to the different queue elements. - -This patch only store the actual element, no functional change intended. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 16 ++++++++-------- - hw/virtio/vhost-shadow-virtqueue.h | 8 ++++++-- - 2 files changed, 14 insertions(+), 10 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 00f5ccddfb..5ddc04e9d6 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -255,7 +255,7 @@ static int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, - return -EINVAL; - } - -- svq->ring_id_maps[qemu_head] = elem; -+ svq->desc_state[qemu_head].elem = elem; - vhost_svq_kick(svq); - return 0; - } -@@ -410,21 +410,21 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, - return NULL; - } - -- if (unlikely(!svq->ring_id_maps[used_elem.id])) { -+ if (unlikely(!svq->desc_state[used_elem.id].elem)) { - qemu_log_mask(LOG_GUEST_ERROR, - "Device %s says index %u is used, but it was not available", - svq->vdev->name, used_elem.id); - return NULL; - } - -- num = svq->ring_id_maps[used_elem.id]->in_num + -- svq->ring_id_maps[used_elem.id]->out_num; -+ num = svq->desc_state[used_elem.id].elem->in_num + -+ svq->desc_state[used_elem.id].elem->out_num; - last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id); - svq->desc_next[last_used_chain] = svq->free_head; - svq->free_head = used_elem.id; - - *len = used_elem.len; -- return g_steal_pointer(&svq->ring_id_maps[used_elem.id]); -+ return g_steal_pointer(&svq->desc_state[used_elem.id].elem); - } - - static void vhost_svq_flush(VhostShadowVirtqueue *svq, -@@ -594,7 +594,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, - memset(svq->vring.desc, 0, driver_size); - svq->vring.used = qemu_memalign(qemu_real_host_page_size, device_size); - memset(svq->vring.used, 0, device_size); -- svq->ring_id_maps = g_new0(VirtQueueElement *, svq->vring.num); -+ svq->desc_state = g_new0(SVQDescState, svq->vring.num); - svq->desc_next = g_new0(uint16_t, svq->vring.num); - for (unsigned i = 0; i < svq->vring.num - 1; i++) { - svq->desc_next[i] = cpu_to_le16(i + 1); -@@ -619,7 +619,7 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq) - - for (unsigned i = 0; i < svq->vring.num; ++i) { - g_autofree VirtQueueElement *elem = NULL; -- elem = g_steal_pointer(&svq->ring_id_maps[i]); -+ elem = g_steal_pointer(&svq->desc_state[i].elem); - if (elem) { - virtqueue_detach_element(svq->vq, elem, 0); - } -@@ -631,7 +631,7 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq) - } - svq->vq = NULL; - g_free(svq->desc_next); -- g_free(svq->ring_id_maps); -+ g_free(svq->desc_state); - qemu_vfree(svq->vring.desc); - qemu_vfree(svq->vring.used); - } -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index c132c994e9..d646c35054 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -15,6 +15,10 @@ - #include "standard-headers/linux/vhost_types.h" - #include "hw/virtio/vhost-iova-tree.h" - -+typedef struct SVQDescState { -+ VirtQueueElement *elem; -+} SVQDescState; -+ - /* Shadow virtqueue to relay notifications */ - typedef struct VhostShadowVirtqueue { - /* Shadow vring */ -@@ -47,8 +51,8 @@ typedef struct VhostShadowVirtqueue { - /* IOVA mapping */ - VhostIOVATree *iova_tree; - -- /* Map for use the guest's descriptors */ -- VirtQueueElement **ring_id_maps; -+ /* SVQ vring descriptors state */ -+ SVQDescState *desc_state; - - /* Next VirtQueue element that guest made available */ - VirtQueueElement *next_guest_avail_elem; --- -2.27.0 - diff --git a/vhost-Add-Shadow-VirtQueue-call-forwarding-capabilit.patch b/vhost-Add-Shadow-VirtQueue-call-forwarding-capabilit.patch deleted file mode 100644 index 41fe5cf437a502fd1a8b12c8646a5f2264c3c0dd..0000000000000000000000000000000000000000 --- a/vhost-Add-Shadow-VirtQueue-call-forwarding-capabilit.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 6ff532ef853499a16307e09d8bab18c57c03ecae Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:43 +0100 -Subject: [PATCH] vhost: Add Shadow VirtQueue call forwarding capabilities -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This will make qemu aware of the device used buffers, allowing it to -write the guest memory with its contents if needed. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 38 ++++++++++++++++++++++++++++++ - hw/virtio/vhost-shadow-virtqueue.h | 4 ++++ - hw/virtio/vhost-vdpa.c | 31 ++++++++++++++++++++++-- - 3 files changed, 71 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index e5da907b8e..55cb5414ef 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -26,6 +26,42 @@ static void vhost_handle_guest_kick(EventNotifier *n) - event_notifier_set(&svq->hdev_kick); - } - -+/** -+ * Forward vhost notifications -+ * -+ * @n: hdev call event notifier, the one that device set to notify svq. -+ */ -+static void vhost_svq_handle_call(EventNotifier *n) -+{ -+ VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, -+ hdev_call); -+ event_notifier_test_and_clear(n); -+ event_notifier_set(&svq->svq_call); -+} -+ -+/** -+ * Set the call notifier for the SVQ to call the guest -+ * -+ * @svq: Shadow virtqueue -+ * @call_fd: call notifier -+ * -+ * Called on BQL context. -+ */ -+void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd) -+{ -+ if (call_fd == VHOST_FILE_UNBIND) { -+ /* -+ * Fail event_notifier_set if called handling device call. -+ * -+ * SVQ still needs device notifications, since it needs to keep -+ * forwarding used buffers even with the unbind. -+ */ -+ memset(&svq->svq_call, 0, sizeof(svq->svq_call)); -+ } else { -+ event_notifier_init_fd(&svq->svq_call, call_fd); -+ } -+} -+ - /** - * Set a new file descriptor for the guest to kick the SVQ and notify for avail - * -@@ -93,6 +129,7 @@ VhostShadowVirtqueue *vhost_svq_new(void) - } - - event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND); -+ event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call); - return g_steal_pointer(&svq); - - err_init_hdev_call: -@@ -112,6 +149,7 @@ void vhost_svq_free(gpointer pvq) - VhostShadowVirtqueue *vq = pvq; - vhost_svq_stop(vq); - event_notifier_cleanup(&vq->hdev_kick); -+ event_notifier_set_handler(&vq->hdev_call, NULL); - event_notifier_cleanup(&vq->hdev_call); - g_free(vq); - } -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index 1cbc87d5d8..cbc5213579 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -28,9 +28,13 @@ typedef struct VhostShadowVirtqueue { - * So shadow virtqueue must not clean it, or we would lose VirtQueue one. - */ - EventNotifier svq_kick; -+ -+ /* Guest's call notifier, where the SVQ calls guest. */ -+ EventNotifier svq_call; - } VhostShadowVirtqueue; - - void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); -+void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd); - - void vhost_svq_stop(VhostShadowVirtqueue *svq); - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 7331c8ee04..29c720308f 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -727,6 +727,13 @@ static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev, - return vhost_vdpa_call(dev, VHOST_SET_VRING_KICK, file); - } - -+static int vhost_vdpa_set_vring_dev_call(struct vhost_dev *dev, -+ struct vhost_vring_file *file) -+{ -+ trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd); -+ return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file); -+} -+ - /** - * Set the shadow virtqueue descriptors to the device - * -@@ -734,6 +741,9 @@ static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev, - * @svq: The shadow virtqueue - * @idx: The index of the virtqueue in the vhost device - * @errp: Error -+ * -+ * Note that this function does not rewind kick file descriptor if cannot set -+ * call one. - */ - static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, - VhostShadowVirtqueue *svq, unsigned idx, -@@ -749,6 +759,14 @@ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, - r = vhost_vdpa_set_vring_dev_kick(dev, &file); - if (unlikely(r != 0)) { - error_setg_errno(errp, -r, "Can't set device kick fd"); -+ return false; -+ } -+ -+ event_notifier = &svq->hdev_call; -+ file.fd = event_notifier_get_fd(event_notifier); -+ r = vhost_vdpa_set_vring_dev_call(dev, &file); -+ if (unlikely(r != 0)) { -+ error_setg_errno(errp, -r, "Can't set device call fd"); - } - - return r == 0; -@@ -874,8 +892,17 @@ static int vhost_vdpa_set_vring_kick(struct vhost_dev *dev, - static int vhost_vdpa_set_vring_call(struct vhost_dev *dev, - struct vhost_vring_file *file) - { -- trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd); -- return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file); -+ struct vhost_vdpa *v = dev->opaque; -+ -+ if (v->shadow_vqs_enabled) { -+ int vdpa_idx = file->index - dev->vq_index; -+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx); -+ -+ vhost_svq_set_svq_call_fd(svq, file->fd); -+ return 0; -+ } else { -+ return vhost_vdpa_set_vring_dev_call(dev, file); -+ } - } - - static int vhost_vdpa_get_features(struct vhost_dev *dev, --- -2.27.0 - diff --git a/vhost-Add-Shadow-VirtQueue-kick-forwarding-capabilit.patch b/vhost-Add-Shadow-VirtQueue-kick-forwarding-capabilit.patch deleted file mode 100644 index fc8469e37fabcfeb73e5d7399cf6b2236333f4d4..0000000000000000000000000000000000000000 --- a/vhost-Add-Shadow-VirtQueue-kick-forwarding-capabilit.patch +++ /dev/null @@ -1,395 +0,0 @@ -From 41585669f68a3896d6d8a5bea868f192b30fad76 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:42 +0100 -Subject: [PATCH] vhost: Add Shadow VirtQueue kick forwarding capabilities -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -At this mode no buffer forwarding will be performed in SVQ mode: Qemu -will just forward the guest's kicks to the device. - -Host memory notifiers regions are left out for simplicity, and they will -not be addressed in this series. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 55 +++++++++++ - hw/virtio/vhost-shadow-virtqueue.h | 14 +++ - hw/virtio/vhost-vdpa.c | 144 ++++++++++++++++++++++++++++- - include/hw/virtio/vhost-vdpa.h | 4 + - 4 files changed, 215 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index c1db02c53e..e5da907b8e 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -11,6 +11,59 @@ - #include "hw/virtio/vhost-shadow-virtqueue.h" - - #include "qemu/error-report.h" -+#include "qemu/main-loop.h" -+#include "linux-headers/linux/vhost.h" -+ -+/** -+ * Forward guest notifications. -+ * -+ * @n: guest kick event notifier, the one that guest set to notify svq. -+ */ -+static void vhost_handle_guest_kick(EventNotifier *n) -+{ -+ VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, svq_kick); -+ event_notifier_test_and_clear(n); -+ event_notifier_set(&svq->hdev_kick); -+} -+ -+/** -+ * Set a new file descriptor for the guest to kick the SVQ and notify for avail -+ * -+ * @svq: The svq -+ * @svq_kick_fd: The svq kick fd -+ * -+ * Note that the SVQ will never close the old file descriptor. -+ */ -+void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd) -+{ -+ EventNotifier *svq_kick = &svq->svq_kick; -+ bool poll_stop = VHOST_FILE_UNBIND != event_notifier_get_fd(svq_kick); -+ bool poll_start = svq_kick_fd != VHOST_FILE_UNBIND; -+ -+ if (poll_stop) { -+ event_notifier_set_handler(svq_kick, NULL); -+ } -+ -+ /* -+ * event_notifier_set_handler already checks for guest's notifications if -+ * they arrive at the new file descriptor in the switch, so there is no -+ * need to explicitly check for them. -+ */ -+ if (poll_start) { -+ event_notifier_init_fd(svq_kick, svq_kick_fd); -+ event_notifier_set(svq_kick); -+ event_notifier_set_handler(svq_kick, vhost_handle_guest_kick); -+ } -+} -+ -+/** -+ * Stop the shadow virtqueue operation. -+ * @svq: Shadow Virtqueue -+ */ -+void vhost_svq_stop(VhostShadowVirtqueue *svq) -+{ -+ event_notifier_set_handler(&svq->svq_kick, NULL); -+} - - /** - * Creates vhost shadow virtqueue, and instructs the vhost device to use the -@@ -39,6 +92,7 @@ VhostShadowVirtqueue *vhost_svq_new(void) - goto err_init_hdev_call; - } - -+ event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND); - return g_steal_pointer(&svq); - - err_init_hdev_call: -@@ -56,6 +110,7 @@ err_init_hdev_kick: - void vhost_svq_free(gpointer pvq) - { - VhostShadowVirtqueue *vq = pvq; -+ vhost_svq_stop(vq); - event_notifier_cleanup(&vq->hdev_kick); - event_notifier_cleanup(&vq->hdev_call); - g_free(vq); -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index f1519e3c7b..1cbc87d5d8 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -18,8 +18,22 @@ typedef struct VhostShadowVirtqueue { - EventNotifier hdev_kick; - /* Shadow call notifier, sent to vhost */ - EventNotifier hdev_call; -+ -+ /* -+ * Borrowed virtqueue's guest to host notifier. To borrow it in this event -+ * notifier allows to recover the VhostShadowVirtqueue from the event loop -+ * easily. If we use the VirtQueue's one, we don't have an easy way to -+ * retrieve VhostShadowVirtqueue. -+ * -+ * So shadow virtqueue must not clean it, or we would lose VirtQueue one. -+ */ -+ EventNotifier svq_kick; - } VhostShadowVirtqueue; - -+void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); -+ -+void vhost_svq_stop(VhostShadowVirtqueue *svq); -+ - VhostShadowVirtqueue *vhost_svq_new(void); - - void vhost_svq_free(gpointer vq); -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 25a2f570a2..7331c8ee04 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -17,12 +17,14 @@ - #include "hw/virtio/vhost.h" - #include "hw/virtio/vhost-backend.h" - #include "hw/virtio/virtio-net.h" -+#include "hw/virtio/vhost-shadow-virtqueue.h" - #include "hw/virtio/vhost-vdpa.h" - #include "exec/address-spaces.h" - #include "qemu/main-loop.h" - #include "cpu.h" - #include "trace.h" - #include "qemu-common.h" -+#include "qapi/error.h" - - static unsigned int vhost_vdpa_used_memslots; - -@@ -344,6 +346,30 @@ static bool vhost_vdpa_one_time_request(struct vhost_dev *dev) - return v->index != 0; - } - -+static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, -+ Error **errp) -+{ -+ g_autoptr(GPtrArray) shadow_vqs = NULL; -+ -+ if (!v->shadow_vqs_enabled) { -+ return 0; -+ } -+ -+ shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free); -+ for (unsigned n = 0; n < hdev->nvqs; ++n) { -+ g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new(); -+ -+ if (unlikely(!svq)) { -+ error_setg(errp, "Cannot create svq %u", n); -+ return -1; -+ } -+ g_ptr_array_add(shadow_vqs, g_steal_pointer(&svq)); -+ } -+ -+ v->shadow_vqs = g_steal_pointer(&shadow_vqs); -+ return 0; -+} -+ - static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) - { - struct vhost_vdpa *v; -@@ -366,6 +392,10 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) - dev->opaque = opaque ; - v->listener = vhost_vdpa_memory_listener; - v->msg_type = VHOST_IOTLB_MSG_V2; -+ ret = vhost_vdpa_init_svq(dev, v, errp); -+ if (ret) { -+ goto err; -+ } - - vhost_vdpa_get_iova_range(v); - -@@ -377,6 +407,10 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) - VIRTIO_CONFIG_S_DRIVER); - - return 0; -+ -+err: -+ ram_block_discard_disable(false); -+ return ret; - } - - static void vhost_vdpa_host_notifier_uninit(struct vhost_dev *dev, -@@ -447,8 +481,14 @@ static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n) - - static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev) - { -+ struct vhost_vdpa *v = dev->opaque; - int i; - -+ if (v->shadow_vqs_enabled) { -+ /* FIXME SVQ is not compatible with host notifiers mr */ -+ return; -+ } -+ - for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) { - if (vhost_vdpa_host_notifier_init(dev, i)) { - goto err; -@@ -462,6 +502,21 @@ err: - return; - } - -+static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ size_t idx; -+ -+ if (!v->shadow_vqs) { -+ return; -+ } -+ -+ for (idx = 0; idx < v->shadow_vqs->len; ++idx) { -+ vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, idx)); -+ } -+ g_ptr_array_free(v->shadow_vqs, true); -+} -+ - static int vhost_vdpa_cleanup(struct vhost_dev *dev) - { - struct vhost_vdpa *v; -@@ -470,6 +525,7 @@ static int vhost_vdpa_cleanup(struct vhost_dev *dev) - trace_vhost_vdpa_cleanup(dev, v); - vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs); - memory_listener_unregister(&v->listener); -+ vhost_vdpa_svq_cleanup(dev); - - dev->opaque = NULL; - ram_block_discard_disable(false); -@@ -561,11 +617,26 @@ static int vhost_vdpa_get_device_id(struct vhost_dev *dev, - return ret; - } - -+static void vhost_vdpa_reset_svq(struct vhost_vdpa *v) -+{ -+ if (!v->shadow_vqs_enabled) { -+ return; -+ } -+ -+ for (unsigned i = 0; i < v->shadow_vqs->len; ++i) { -+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -+ vhost_svq_stop(svq); -+ } -+} -+ - static int vhost_vdpa_reset_device(struct vhost_dev *dev) - { -+ struct vhost_vdpa *v = dev->opaque; - int ret; - uint8_t status = 0; - -+ vhost_vdpa_reset_svq(v); -+ - ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status); - trace_vhost_vdpa_reset_device(dev, status); - return ret; -@@ -649,13 +720,74 @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config, - return ret; - } - -+static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev, -+ struct vhost_vring_file *file) -+{ -+ trace_vhost_vdpa_set_vring_kick(dev, file->index, file->fd); -+ return vhost_vdpa_call(dev, VHOST_SET_VRING_KICK, file); -+} -+ -+/** -+ * Set the shadow virtqueue descriptors to the device -+ * -+ * @dev: The vhost device model -+ * @svq: The shadow virtqueue -+ * @idx: The index of the virtqueue in the vhost device -+ * @errp: Error -+ */ -+static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, -+ VhostShadowVirtqueue *svq, unsigned idx, -+ Error **errp) -+{ -+ struct vhost_vring_file file = { -+ .index = dev->vq_index + idx, -+ }; -+ const EventNotifier *event_notifier = &svq->hdev_kick; -+ int r; -+ -+ file.fd = event_notifier_get_fd(event_notifier); -+ r = vhost_vdpa_set_vring_dev_kick(dev, &file); -+ if (unlikely(r != 0)) { -+ error_setg_errno(errp, -r, "Can't set device kick fd"); -+ } -+ -+ return r == 0; -+} -+ -+static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ Error *err = NULL; -+ unsigned i; -+ -+ if (!v->shadow_vqs) { -+ return true; -+ } -+ -+ for (i = 0; i < v->shadow_vqs->len; ++i) { -+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -+ bool ok = vhost_vdpa_svq_setup(dev, svq, i, &err); -+ if (unlikely(!ok)) { -+ error_reportf_err(err, "Cannot setup SVQ %u: ", i); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ - static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) - { - struct vhost_vdpa *v = dev->opaque; -+ bool ok; - trace_vhost_vdpa_dev_start(dev, started); - - if (started) { - vhost_vdpa_host_notifiers_init(dev); -+ ok = vhost_vdpa_svqs_start(dev); -+ if (unlikely(!ok)) { -+ return -1; -+ } - vhost_vdpa_set_vring_ready(dev); - } else { - vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs); -@@ -727,8 +859,16 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev *dev, - static int vhost_vdpa_set_vring_kick(struct vhost_dev *dev, - struct vhost_vring_file *file) - { -- trace_vhost_vdpa_set_vring_kick(dev, file->index, file->fd); -- return vhost_vdpa_call(dev, VHOST_SET_VRING_KICK, file); -+ struct vhost_vdpa *v = dev->opaque; -+ int vdpa_idx = file->index - dev->vq_index; -+ -+ if (v->shadow_vqs_enabled) { -+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx); -+ vhost_svq_set_svq_kick_fd(svq, file->fd); -+ return 0; -+ } else { -+ return vhost_vdpa_set_vring_dev_kick(dev, file); -+ } - } - - static int vhost_vdpa_set_vring_call(struct vhost_dev *dev, -diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h -index 3ce79a646d..009a9f3b6b 100644 ---- a/include/hw/virtio/vhost-vdpa.h -+++ b/include/hw/virtio/vhost-vdpa.h -@@ -12,6 +12,8 @@ - #ifndef HW_VIRTIO_VHOST_VDPA_H - #define HW_VIRTIO_VHOST_VDPA_H - -+#include -+ - #include "hw/virtio/virtio.h" - #include "standard-headers/linux/vhost_types.h" - -@@ -27,6 +29,8 @@ typedef struct vhost_vdpa { - bool iotlb_batch_begin_sent; - MemoryListener listener; - struct vhost_vdpa_iova_range iova_range; -+ bool shadow_vqs_enabled; -+ GPtrArray *shadow_vqs; - struct vhost_dev *dev; - VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; - } VhostVDPA; --- -2.27.0 - diff --git a/vhost-Add-VhostIOVATree.patch b/vhost-Add-VhostIOVATree.patch deleted file mode 100644 index 8f78f901a8c601bafb623ca546949a42ca4283e3..0000000000000000000000000000000000000000 --- a/vhost-Add-VhostIOVATree.patch +++ /dev/null @@ -1,200 +0,0 @@ -From c938dd769a872c569c3985f06c8b5854231ed74c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:50 +0100 -Subject: [PATCH] vhost: Add VhostIOVATree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This tree is able to look for a translated address from an IOVA address. - -At first glance it is similar to util/iova-tree. However, SVQ working on -devices with limited IOVA space need more capabilities, like allocating -IOVA chunks or performing reverse translations (qemu addresses to iova). - -The allocation capability, as "assign a free IOVA address to this chunk -of memory in qemu's address space" allows shadow virtqueue to create a -new address space that is not restricted by guest's addressable one, so -we can allocate shadow vqs vrings outside of it. - -It duplicates the tree so it can search efficiently in both directions, -and it will signal overlap if iova or the translated address is present -in any tree. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/meson.build | 2 +- - hw/virtio/vhost-iova-tree.c | 110 ++++++++++++++++++++++++++++++++++++ - hw/virtio/vhost-iova-tree.h | 27 +++++++++ - 3 files changed, 138 insertions(+), 1 deletion(-) - create mode 100644 hw/virtio/vhost-iova-tree.c - create mode 100644 hw/virtio/vhost-iova-tree.h - -diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build -index eb46c05a25..c2e193f56d 100644 ---- a/hw/virtio/meson.build -+++ b/hw/virtio/meson.build -@@ -11,7 +11,7 @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c')) - - virtio_ss = ss.source_set() - virtio_ss.add(files('virtio.c')) --virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c')) -+virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c', 'vhost-iova-tree.c')) - virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c')) - virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c')) - virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c')) -diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c -new file mode 100644 -index 0000000000..55fed1fefb ---- /dev/null -+++ b/hw/virtio/vhost-iova-tree.c -@@ -0,0 +1,110 @@ -+/* -+ * vhost software live migration iova tree -+ * -+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021 -+ * SPDX-FileContributor: Author: Eugenio Pérez -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#include "qemu/osdep.h" -+#include "qemu/iova-tree.h" -+#include "vhost-iova-tree.h" -+ -+#define iova_min_addr qemu_real_host_page_size -+ -+/** -+ * VhostIOVATree, able to: -+ * - Translate iova address -+ * - Reverse translate iova address (from translated to iova) -+ * - Allocate IOVA regions for translated range (linear operation) -+ */ -+struct VhostIOVATree { -+ /* First addressable iova address in the device */ -+ uint64_t iova_first; -+ -+ /* Last addressable iova address in the device */ -+ uint64_t iova_last; -+ -+ /* IOVA address to qemu memory maps. */ -+ IOVATree *iova_taddr_map; -+}; -+ -+/** -+ * Create a new IOVA tree -+ * -+ * Returns the new IOVA tree -+ */ -+VhostIOVATree *vhost_iova_tree_new(hwaddr iova_first, hwaddr iova_last) -+{ -+ VhostIOVATree *tree = g_new(VhostIOVATree, 1); -+ -+ /* Some devices do not like 0 addresses */ -+ tree->iova_first = MAX(iova_first, iova_min_addr); -+ tree->iova_last = iova_last; -+ -+ tree->iova_taddr_map = iova_tree_new(); -+ return tree; -+} -+ -+/** -+ * Delete an iova tree -+ */ -+void vhost_iova_tree_delete(VhostIOVATree *iova_tree) -+{ -+ iova_tree_destroy(iova_tree->iova_taddr_map); -+ g_free(iova_tree); -+} -+ -+/** -+ * Find the IOVA address stored from a memory address -+ * -+ * @tree: The iova tree -+ * @map: The map with the memory address -+ * -+ * Return the stored mapping, or NULL if not found. -+ */ -+const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *tree, -+ const DMAMap *map) -+{ -+ return iova_tree_find_iova(tree->iova_taddr_map, map); -+} -+ -+/** -+ * Allocate a new mapping -+ * -+ * @tree: The iova tree -+ * @map: The iova map -+ * -+ * Returns: -+ * - IOVA_OK if the map fits in the container -+ * - IOVA_ERR_INVALID if the map does not make sense (like size overflow) -+ * - IOVA_ERR_NOMEM if tree cannot allocate more space. -+ * -+ * It returns assignated iova in map->iova if return value is VHOST_DMA_MAP_OK. -+ */ -+int vhost_iova_tree_map_alloc(VhostIOVATree *tree, DMAMap *map) -+{ -+ /* Some vhost devices do not like addr 0. Skip first page */ -+ hwaddr iova_first = tree->iova_first ?: qemu_real_host_page_size; -+ -+ if (map->translated_addr + map->size < map->translated_addr || -+ map->perm == IOMMU_NONE) { -+ return IOVA_ERR_INVALID; -+ } -+ -+ /* Allocate a node in IOVA address */ -+ return iova_tree_alloc_map(tree->iova_taddr_map, map, iova_first, -+ tree->iova_last); -+} -+ -+/** -+ * Remove existing mappings from iova tree -+ * -+ * @iova_tree: The vhost iova tree -+ * @map: The map to remove -+ */ -+void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map) -+{ -+ iova_tree_remove(iova_tree->iova_taddr_map, map); -+} -diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h -new file mode 100644 -index 0000000000..6a4f24e0f9 ---- /dev/null -+++ b/hw/virtio/vhost-iova-tree.h -@@ -0,0 +1,27 @@ -+/* -+ * vhost software live migration iova tree -+ * -+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021 -+ * SPDX-FileContributor: Author: Eugenio Pérez -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#ifndef HW_VIRTIO_VHOST_IOVA_TREE_H -+#define HW_VIRTIO_VHOST_IOVA_TREE_H -+ -+#include "qemu/iova-tree.h" -+#include "exec/memory.h" -+ -+typedef struct VhostIOVATree VhostIOVATree; -+ -+VhostIOVATree *vhost_iova_tree_new(uint64_t iova_first, uint64_t iova_last); -+void vhost_iova_tree_delete(VhostIOVATree *iova_tree); -+G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_delete); -+ -+const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *iova_tree, -+ const DMAMap *map); -+int vhost_iova_tree_map_alloc(VhostIOVATree *iova_tree, DMAMap *map); -+void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map); -+ -+#endif --- -2.27.0 - diff --git a/vhost-Add-VhostShadowVirtqueue.patch b/vhost-Add-VhostShadowVirtqueue.patch deleted file mode 100644 index b4c668b4b8e1ab46fe1137540d26eebaed87f121..0000000000000000000000000000000000000000 --- a/vhost-Add-VhostShadowVirtqueue.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 6f38bfce3fc45c1c68329412d146913a155962c7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:41 +0100 -Subject: [PATCH] vhost: Add VhostShadowVirtqueue -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Vhost shadow virtqueue (SVQ) is an intermediate jump for virtqueue -notifications and buffers, allowing qemu to track them. While qemu is -forwarding the buffers and virtqueue changes, it is able to commit the -memory it's being dirtied, the same way regular qemu's VirtIO devices -do. - -This commit only exposes basic SVQ allocation and free. Next patches of -the series add functionality like notifications and buffers forwarding. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/meson.build | 2 +- - hw/virtio/vhost-shadow-virtqueue.c | 62 ++++++++++++++++++++++++++++++ - hw/virtio/vhost-shadow-virtqueue.h | 28 ++++++++++++++ - 3 files changed, 91 insertions(+), 1 deletion(-) - create mode 100644 hw/virtio/vhost-shadow-virtqueue.c - create mode 100644 hw/virtio/vhost-shadow-virtqueue.h - -diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build -index 8e8943e20b..eb46c05a25 100644 ---- a/hw/virtio/meson.build -+++ b/hw/virtio/meson.build -@@ -11,7 +11,7 @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c')) - - virtio_ss = ss.source_set() - virtio_ss.add(files('virtio.c')) --virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c')) -+virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c')) - virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c')) - virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c')) - virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c')) -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -new file mode 100644 -index 0000000000..c1db02c53e ---- /dev/null -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -0,0 +1,62 @@ -+/* -+ * vhost shadow virtqueue -+ * -+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021 -+ * SPDX-FileContributor: Author: Eugenio Pérez -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#include "qemu/osdep.h" -+#include "hw/virtio/vhost-shadow-virtqueue.h" -+ -+#include "qemu/error-report.h" -+ -+/** -+ * Creates vhost shadow virtqueue, and instructs the vhost device to use the -+ * shadow methods and file descriptors. -+ * -+ * Returns the new virtqueue or NULL. -+ * -+ * In case of error, reason is reported through error_report. -+ */ -+VhostShadowVirtqueue *vhost_svq_new(void) -+{ -+ g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1); -+ int r; -+ -+ r = event_notifier_init(&svq->hdev_kick, 0); -+ if (r != 0) { -+ error_report("Couldn't create kick event notifier: %s (%d)", -+ g_strerror(errno), errno); -+ goto err_init_hdev_kick; -+ } -+ -+ r = event_notifier_init(&svq->hdev_call, 0); -+ if (r != 0) { -+ error_report("Couldn't create call event notifier: %s (%d)", -+ g_strerror(errno), errno); -+ goto err_init_hdev_call; -+ } -+ -+ return g_steal_pointer(&svq); -+ -+err_init_hdev_call: -+ event_notifier_cleanup(&svq->hdev_kick); -+ -+err_init_hdev_kick: -+ return NULL; -+} -+ -+/** -+ * Free the resources of the shadow virtqueue. -+ * -+ * @pvq: gpointer to SVQ so it can be used by autofree functions. -+ */ -+void vhost_svq_free(gpointer pvq) -+{ -+ VhostShadowVirtqueue *vq = pvq; -+ event_notifier_cleanup(&vq->hdev_kick); -+ event_notifier_cleanup(&vq->hdev_call); -+ g_free(vq); -+} -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -new file mode 100644 -index 0000000000..f1519e3c7b ---- /dev/null -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -0,0 +1,28 @@ -+/* -+ * vhost shadow virtqueue -+ * -+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021 -+ * SPDX-FileContributor: Author: Eugenio Pérez -+ * -+ * SPDX-License-Identifier: GPL-2.0-or-later -+ */ -+ -+#ifndef VHOST_SHADOW_VIRTQUEUE_H -+#define VHOST_SHADOW_VIRTQUEUE_H -+ -+#include "qemu/event_notifier.h" -+ -+/* Shadow virtqueue to relay notifications */ -+typedef struct VhostShadowVirtqueue { -+ /* Shadow kick notifier, sent to vhost */ -+ EventNotifier hdev_kick; -+ /* Shadow call notifier, sent to vhost */ -+ EventNotifier hdev_call; -+} VhostShadowVirtqueue; -+ -+VhostShadowVirtqueue *vhost_svq_new(void); -+ -+void vhost_svq_free(gpointer vq); -+G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free); -+ -+#endif --- -2.27.0 - diff --git a/vhost-Add-svq-avail_handler-callback.patch b/vhost-Add-svq-avail_handler-callback.patch deleted file mode 100644 index b288a39d877ad5582df3642e0a591a325cc53ee8..0000000000000000000000000000000000000000 --- a/vhost-Add-svq-avail_handler-callback.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 14cc79b8bda66ace21616adccf6c2ccd65b7256a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:39 +0200 -Subject: [PATCH] vhost: Add svq avail_handler callback -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows external handlers to be aware of new buffers that the guest -places in the virtqueue. - -When this callback is defined the ownership of the guest's virtqueue -element is transferred to the callback. This means that if the user -wants to forward the descriptor it needs to manually inject it. The -callback is also free to process the command by itself and use the -element with svq_push. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 14 ++++++++++++-- - hw/virtio/vhost-shadow-virtqueue.h | 31 +++++++++++++++++++++++++++++- - hw/virtio/vhost-vdpa.c | 3 ++- - 3 files changed, 44 insertions(+), 4 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index d2676b94e0..ae443f54fe 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -305,7 +305,11 @@ static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) - break; - } - -- r = vhost_svq_add_element(svq, elem); -+ if (svq->ops) { -+ r = svq->ops->avail_handler(svq, elem, svq->ops_opaque); -+ } else { -+ r = vhost_svq_add_element(svq, elem); -+ } - if (unlikely(r != 0)) { - if (r == -ENOSPC) { - /* -@@ -684,12 +688,16 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq) - * shadow methods and file descriptors. - * - * @iova_tree: Tree to perform descriptors translations -+ * @ops: SVQ owner callbacks -+ * @ops_opaque: ops opaque pointer - * - * Returns the new virtqueue or NULL. - * - * In case of error, reason is reported through error_report. - */ --VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree) -+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree, -+ const VhostShadowVirtqueueOps *ops, -+ void *ops_opaque) - { - g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1); - int r; -@@ -711,6 +719,8 @@ VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree) - event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND); - event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call); - svq->iova_tree = iova_tree; -+ svq->ops = ops; -+ svq->ops_opaque = ops_opaque; - return g_steal_pointer(&svq); - - err_init_hdev_call: -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index cf442f7dea..d04c34a589 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -25,6 +25,27 @@ typedef struct SVQDescState { - unsigned int ndescs; - } SVQDescState; - -+typedef struct VhostShadowVirtqueue VhostShadowVirtqueue; -+ -+/** -+ * Callback to handle an avail buffer. -+ * -+ * @svq: Shadow virtqueue -+ * @elem: Element placed in the queue by the guest -+ * @vq_callback_opaque: Opaque -+ * -+ * Returns 0 if the vq is running as expected. -+ * -+ * Note that ownership of elem is transferred to the callback. -+ */ -+typedef int (*VirtQueueAvailCallback)(VhostShadowVirtqueue *svq, -+ VirtQueueElement *elem, -+ void *vq_callback_opaque); -+ -+typedef struct VhostShadowVirtqueueOps { -+ VirtQueueAvailCallback avail_handler; -+} VhostShadowVirtqueueOps; -+ - /* Shadow virtqueue to relay notifications */ - typedef struct VhostShadowVirtqueue { - /* Shadow vring */ -@@ -69,6 +90,12 @@ typedef struct VhostShadowVirtqueue { - */ - uint16_t *desc_next; - -+ /* Caller callbacks */ -+ const VhostShadowVirtqueueOps *ops; -+ -+ /* Caller callbacks opaque */ -+ void *ops_opaque; -+ - /* Next head to expose to the device */ - uint16_t shadow_avail_idx; - -@@ -102,7 +129,9 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, - VirtQueue *vq); - void vhost_svq_stop(VhostShadowVirtqueue *svq); - --VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree); -+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree, -+ const VhostShadowVirtqueueOps *ops, -+ void *ops_opaque); - - void vhost_svq_free(gpointer vq); - G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free); -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 73ff599f2b..a8d42655f0 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -420,8 +420,9 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, - - shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free); - for (unsigned n = 0; n < hdev->nvqs; ++n) { -- g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new(v->iova_tree); -+ g_autoptr(VhostShadowVirtqueue) svq; - -+ svq = vhost_svq_new(v->iova_tree, NULL, NULL); - if (unlikely(!svq)) { - error_setg(errp, "Cannot create svq %u", n); - return -1; --- -2.27.0 - diff --git a/vhost-Add-vhost_svq_valid_features-to-shadow-vq.patch b/vhost-Add-vhost_svq_valid_features-to-shadow-vq.patch deleted file mode 100644 index 53bb3be9dd255adcc401071854858cf5b1b20c8f..0000000000000000000000000000000000000000 --- a/vhost-Add-vhost_svq_valid_features-to-shadow-vq.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 2f41ff8e23ed358890fb66b6f524627a9747cc14 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:44 +0100 -Subject: [PATCH] vhost: Add vhost_svq_valid_features to shadow vq -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows SVQ to negotiate features with the guest and the device. For -the device, SVQ is a driver. While this function bypasses all -non-transport features, it needs to disable the features that SVQ does -not support when forwarding buffers. This includes packed vq layout, -indirect descriptors or event idx. - -Future changes can add support to offer more features to the guest, -since the use of VirtQueue gives this for free. This is left out at the -moment for simplicity. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 44 ++++++++++++++++++++++++++++++ - hw/virtio/vhost-shadow-virtqueue.h | 2 ++ - hw/virtio/vhost-vdpa.c | 15 ++++++++++ - 3 files changed, 61 insertions(+) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 55cb5414ef..519328445c 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -11,9 +11,53 @@ - #include "hw/virtio/vhost-shadow-virtqueue.h" - - #include "qemu/error-report.h" -+#include "qapi/error.h" - #include "qemu/main-loop.h" - #include "linux-headers/linux/vhost.h" - -+/** -+ * Validate the transport device features that both guests can use with the SVQ -+ * and SVQs can use with the device. -+ * -+ * @dev_features: The features -+ * @errp: Error pointer -+ */ -+bool vhost_svq_valid_features(uint64_t features, Error **errp) -+{ -+ bool ok = true; -+ uint64_t svq_features = features; -+ -+ for (uint64_t b = VIRTIO_TRANSPORT_F_START; b <= VIRTIO_TRANSPORT_F_END; -+ ++b) { -+ switch (b) { -+ case VIRTIO_F_ANY_LAYOUT: -+ continue; -+ -+ case VIRTIO_F_ACCESS_PLATFORM: -+ /* SVQ trust in the host's IOMMU to translate addresses */ -+ case VIRTIO_F_VERSION_1: -+ /* SVQ trust that the guest vring is little endian */ -+ if (!(svq_features & BIT_ULL(b))) { -+ svq_features |= BIT_ULL(b); -+ ok = false; -+ } -+ continue; -+ -+ default: -+ if (svq_features & BIT_ULL(b)) { -+ svq_features &= ~BIT_ULL(b); -+ ok = false; -+ } -+ } -+ } -+ -+ if (!ok) { -+ error_setg(errp, "SVQ Invalid device feature flags, offer: 0x%"PRIx64 -+ ", ok: 0x%"PRIx64, features, svq_features); -+ } -+ return ok; -+} -+ - /** - * Forward guest notifications. - * -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index cbc5213579..9e12f77201 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -33,6 +33,8 @@ typedef struct VhostShadowVirtqueue { - EventNotifier svq_call; - } VhostShadowVirtqueue; - -+bool vhost_svq_valid_features(uint64_t features, Error **errp); -+ - void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); - void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd); - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 29c720308f..8ee63933a8 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -350,11 +350,26 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, - Error **errp) - { - g_autoptr(GPtrArray) shadow_vqs = NULL; -+ uint64_t dev_features, svq_features; -+ int r; -+ bool ok; - - if (!v->shadow_vqs_enabled) { - return 0; - } - -+ r = hdev->vhost_ops->vhost_get_features(hdev, &dev_features); -+ if (r != 0) { -+ error_setg_errno(errp, -r, "Can't get vdpa device features"); -+ return r; -+ } -+ -+ svq_features = dev_features; -+ ok = vhost_svq_valid_features(svq_features, errp); -+ if (unlikely(!ok)) { -+ return -1; -+ } -+ - shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free); - for (unsigned n = 0; n < hdev->nvqs; ++n) { - g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new(); --- -2.27.0 - diff --git a/vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch b/vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch deleted file mode 100644 index e013942d9dcd70522150393094a7f72628cf620a..0000000000000000000000000000000000000000 --- a/vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 42cdf9d4b5c4ec0a6fbbebd79c21e5c39d831a48 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:20:07 +0200 -Subject: [PATCH] vhost: Always store new kick fd on vhost_svq_set_svq_kick_fd -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We can unbind twice a file descriptor if we call twice -vhost_svq_set_svq_kick_fd because of this. Since it comes from vhost and -not from SVQ, that file descriptor could be a different thing that -guest's vhost notifier. - -Likewise, it can happens the same if a guest start and stop the device -multiple times. - -Reported-by: Lei Yang -Fixes: dff4426fa6 ("vhost: Add Shadow VirtQueue kick forwarding capabilities") -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 47e831667c..1ea7b5cf59 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -601,13 +601,13 @@ void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd) - event_notifier_set_handler(svq_kick, NULL); - } - -+ event_notifier_init_fd(svq_kick, svq_kick_fd); - /* - * event_notifier_set_handler already checks for guest's notifications if - * they arrive at the new file descriptor in the switch, so there is no - * need to explicitly check for them. - */ - if (poll_start) { -- event_notifier_init_fd(svq_kick, svq_kick_fd); - event_notifier_set(svq_kick); - event_notifier_set_handler(svq_kick, vhost_handle_guest_kick_notifier); - } -@@ -655,7 +655,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, - */ - void vhost_svq_stop(VhostShadowVirtqueue *svq) - { -- event_notifier_set_handler(&svq->svq_kick, NULL); -+ vhost_svq_set_svq_kick_fd(svq, VHOST_FILE_UNBIND); - g_autofree VirtQueueElement *next_avail_elem = NULL; - - if (!svq->vq) { --- -2.27.0 - diff --git a/vhost-Check-for-queue-full-at-vhost_svq_add.patch b/vhost-Check-for-queue-full-at-vhost_svq_add.patch deleted file mode 100644 index 98f4f8e14e139abf15d0d6ead303fe14f88254a7..0000000000000000000000000000000000000000 --- a/vhost-Check-for-queue-full-at-vhost_svq_add.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 53e6a3ff0ad77689e8cfb79b2e97ca30058949a9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:32 +0200 -Subject: [PATCH] vhost: Check for queue full at vhost_svq_add -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The series need to expose vhost_svq_add with full functionality, -including checking for full queue. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 59 +++++++++++++++++------------- - 1 file changed, 33 insertions(+), 26 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index b99630acee..7104004a81 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -232,21 +232,29 @@ static void vhost_svq_kick(VhostShadowVirtqueue *svq) - * Add an element to a SVQ. - * - * The caller must check that there is enough slots for the new element. It -- * takes ownership of the element: In case of failure, it is free and the SVQ -- * is considered broken. -+ * takes ownership of the element: In case of failure not ENOSPC, it is free. -+ * -+ * Return -EINVAL if element is invalid, -ENOSPC if dev queue is full - */ --static bool vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem) -+static int vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem) - { - unsigned qemu_head; -- bool ok = vhost_svq_add_split(svq, elem, &qemu_head); -+ unsigned ndescs = elem->in_num + elem->out_num; -+ bool ok; -+ -+ if (unlikely(ndescs > vhost_svq_available_slots(svq))) { -+ return -ENOSPC; -+ } -+ -+ ok = vhost_svq_add_split(svq, elem, &qemu_head); - if (unlikely(!ok)) { - g_free(elem); -- return false; -+ return -EINVAL; - } - - svq->ring_id_maps[qemu_head] = elem; - vhost_svq_kick(svq); -- return true; -+ return 0; - } - - /** -@@ -273,7 +281,7 @@ static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) - - while (true) { - VirtQueueElement *elem; -- bool ok; -+ int r; - - if (svq->next_guest_avail_elem) { - elem = g_steal_pointer(&svq->next_guest_avail_elem); -@@ -285,25 +293,24 @@ static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) - break; - } - -- if (elem->out_num + elem->in_num > vhost_svq_available_slots(svq)) { -- /* -- * This condition is possible since a contiguous buffer in GPA -- * does not imply a contiguous buffer in qemu's VA -- * scatter-gather segments. If that happens, the buffer exposed -- * to the device needs to be a chain of descriptors at this -- * moment. -- * -- * SVQ cannot hold more available buffers if we are here: -- * queue the current guest descriptor and ignore further kicks -- * until some elements are used. -- */ -- svq->next_guest_avail_elem = elem; -- return; -- } -- -- ok = vhost_svq_add(svq, elem); -- if (unlikely(!ok)) { -- /* VQ is broken, just return and ignore any other kicks */ -+ r = vhost_svq_add(svq, elem); -+ if (unlikely(r != 0)) { -+ if (r == -ENOSPC) { -+ /* -+ * This condition is possible since a contiguous buffer in -+ * GPA does not imply a contiguous buffer in qemu's VA -+ * scatter-gather segments. If that happens, the buffer -+ * exposed to the device needs to be a chain of descriptors -+ * at this moment. -+ * -+ * SVQ cannot hold more available buffers if we are here: -+ * queue the current guest descriptor and ignore kicks -+ * until some elements are used. -+ */ -+ svq->next_guest_avail_elem = elem; -+ } -+ -+ /* VQ is full or broken, just return and ignore kicks */ - return; - } - } --- -2.27.0 - diff --git a/vhost-Decouple-vhost_svq_add-from-VirtQueueElement.patch b/vhost-Decouple-vhost_svq_add-from-VirtQueueElement.patch deleted file mode 100644 index 298fe6ac3d9c41e3ba6f6e74cad21f6c8c268053..0000000000000000000000000000000000000000 --- a/vhost-Decouple-vhost_svq_add-from-VirtQueueElement.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 1f484df7fb48cdf24e619118ddf67b8cd4e02231 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:33 +0200 -Subject: [PATCH] vhost: Decouple vhost_svq_add from VirtQueueElement -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -VirtQueueElement comes from the guest, but we're heading SVQ to be able -to modify the element presented to the device without the guest's -knowledge. - -To do so, make SVQ accept sg buffers directly, instead of using -VirtQueueElement. - -Add vhost_svq_add_element to maintain element convenience. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 33 ++++++++++++++++++++---------- - 1 file changed, 22 insertions(+), 11 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 7104004a81..00f5ccddfb 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -171,30 +171,31 @@ static bool vhost_svq_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg, - } - - static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, -- VirtQueueElement *elem, unsigned *head) -+ const struct iovec *out_sg, size_t out_num, -+ const struct iovec *in_sg, size_t in_num, -+ unsigned *head) - { - unsigned avail_idx; - vring_avail_t *avail = svq->vring.avail; - bool ok; -- g_autofree hwaddr *sgs = g_new(hwaddr, MAX(elem->out_num, elem->in_num)); -+ g_autofree hwaddr *sgs = g_new(hwaddr, MAX(out_num, in_num)); - - *head = svq->free_head; - - /* We need some descriptors here */ -- if (unlikely(!elem->out_num && !elem->in_num)) { -+ if (unlikely(!out_num && !in_num)) { - qemu_log_mask(LOG_GUEST_ERROR, - "Guest provided element with no descriptors"); - return false; - } - -- ok = vhost_svq_vring_write_descs(svq, sgs, elem->out_sg, elem->out_num, -- elem->in_num > 0, false); -+ ok = vhost_svq_vring_write_descs(svq, sgs, out_sg, out_num, in_num > 0, -+ false); - if (unlikely(!ok)) { - return false; - } - -- ok = vhost_svq_vring_write_descs(svq, sgs, elem->in_sg, elem->in_num, false, -- true); -+ ok = vhost_svq_vring_write_descs(svq, sgs, in_sg, in_num, false, true); - if (unlikely(!ok)) { - return false; - } -@@ -236,17 +237,19 @@ static void vhost_svq_kick(VhostShadowVirtqueue *svq) - * - * Return -EINVAL if element is invalid, -ENOSPC if dev queue is full - */ --static int vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem) -+static int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, -+ size_t out_num, const struct iovec *in_sg, -+ size_t in_num, VirtQueueElement *elem) - { - unsigned qemu_head; -- unsigned ndescs = elem->in_num + elem->out_num; -+ unsigned ndescs = in_num + out_num; - bool ok; - - if (unlikely(ndescs > vhost_svq_available_slots(svq))) { - return -ENOSPC; - } - -- ok = vhost_svq_add_split(svq, elem, &qemu_head); -+ ok = vhost_svq_add_split(svq, out_sg, out_num, in_sg, in_num, &qemu_head); - if (unlikely(!ok)) { - g_free(elem); - return -EINVAL; -@@ -257,6 +260,14 @@ static int vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem) - return 0; - } - -+/* Convenience wrapper to add a guest's element to SVQ */ -+static int vhost_svq_add_element(VhostShadowVirtqueue *svq, -+ VirtQueueElement *elem) -+{ -+ return vhost_svq_add(svq, elem->out_sg, elem->out_num, elem->in_sg, -+ elem->in_num, elem); -+} -+ - /** - * Forward available buffers. - * -@@ -293,7 +304,7 @@ static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) - break; - } - -- r = vhost_svq_add(svq, elem); -+ r = vhost_svq_add_element(svq, elem); - if (unlikely(r != 0)) { - if (r == -ENOSPC) { - /* --- -2.27.0 - diff --git a/vhost-Drop-unused-eventfd_add-del-hooks.patch b/vhost-Drop-unused-eventfd_add-del-hooks.patch deleted file mode 100644 index 672c23595ab84b3304a0e7b791e1c18a896db22c..0000000000000000000000000000000000000000 --- a/vhost-Drop-unused-eventfd_add-del-hooks.patch +++ /dev/null @@ -1,63 +0,0 @@ -From e1c5d60311a7b6dba60284f07fad92dfab688605 Mon Sep 17 00:00:00 2001 -From: xiaowanghe -Date: Sun, 13 Aug 2023 23:18:07 -0700 -Subject: [PATCH] vhost: Drop unused eventfd_add|del hooks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cherry picked from commit 560a997535937df2ea3716ba56bcbe38be37682f - -These hooks were introduced in: - -80a1ea3748 ("memory: move ioeventfd ops to MemoryListener", 2012-02-29) - -But they seem to be never used. Drop them. - -Cc: Richard Henderson -Signed-off-by: Peter Xu -Message-Id: <20230306193209.516011-1-peterx@redhat.com> -Reviewed-by: Philippe Mathieu-Daudé -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: Wanghe Xiao ---- - hw/virtio/vhost.c | 14 -------------- - 1 file changed, 14 deletions(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 3ac6cfde03..2d11e3c2f8 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -1268,18 +1268,6 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev, - 0, virtio_queue_get_desc_size(vdev, idx)); - } - --static void vhost_eventfd_add(MemoryListener *listener, -- MemoryRegionSection *section, -- bool match_data, uint64_t data, EventNotifier *e) --{ --} -- --static void vhost_eventfd_del(MemoryListener *listener, -- MemoryRegionSection *section, -- bool match_data, uint64_t data, EventNotifier *e) --{ --} -- - static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev, - int n, uint32_t timeout) - { -@@ -1413,8 +1401,6 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, - .log_sync = vhost_log_sync, - .log_global_start = vhost_log_global_start, - .log_global_stop = vhost_log_global_stop, -- .eventfd_add = vhost_eventfd_add, -- .eventfd_del = vhost_eventfd_del, - .priority = 10 - }; - --- -2.41.0.windows.1 - diff --git a/vhost-Expose-vhost_svq_add.patch b/vhost-Expose-vhost_svq_add.patch deleted file mode 100644 index d514ec4ee25a260514228ca2dd82bdde2626b9c5..0000000000000000000000000000000000000000 --- a/vhost-Expose-vhost_svq_add.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 9e4727140479522c62070069d552b378c73864f3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:37 +0200 -Subject: [PATCH] vhost: Expose vhost_svq_add -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows external parts of SVQ to forward custom buffers to the -device. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 6 +++--- - hw/virtio/vhost-shadow-virtqueue.h | 3 +++ - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 3b5d3bd3f3..5a85365478 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -237,9 +237,9 @@ static void vhost_svq_kick(VhostShadowVirtqueue *svq) - * - * Return -EINVAL if element is invalid, -ENOSPC if dev queue is full - */ --static int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, -- size_t out_num, const struct iovec *in_sg, -- size_t in_num, VirtQueueElement *elem) -+int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, -+ size_t out_num, const struct iovec *in_sg, size_t in_num, -+ VirtQueueElement *elem) - { - unsigned qemu_head; - unsigned ndescs = in_num + out_num; -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index d9fc1f1799..dd78f4bec2 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -86,6 +86,9 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp); - - void vhost_svq_push_elem(VhostShadowVirtqueue *svq, - const VirtQueueElement *elem, uint32_t len); -+int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, -+ size_t out_num, const struct iovec *in_sg, size_t in_num, -+ VirtQueueElement *elem); - - void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); - void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd); --- -2.27.0 - diff --git a/vhost-Fix-device-s-used-descriptor-dequeue.patch b/vhost-Fix-device-s-used-descriptor-dequeue.patch deleted file mode 100644 index f1f751e6aa5018ab2750320e29dae61a141748c9..0000000000000000000000000000000000000000 --- a/vhost-Fix-device-s-used-descriptor-dequeue.patch +++ /dev/null @@ -1,64 +0,0 @@ -From a704fb13777c6820cb8a451dbe0b082f6840f9ef Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 12 May 2022 19:57:43 +0200 -Subject: [PATCH] vhost: Fix device's used descriptor dequeue -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Only the first one of them were properly enqueued back. - -Fixes: 100890f7ca ("vhost: Shadow virtqueue buffers forwarding") - -Signed-off-by: Eugenio Pérez -Message-Id: <20220512175747.142058-3-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 6057a437df..0b394694de 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -333,12 +333,22 @@ static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq) - svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); - } - -+static uint16_t vhost_svq_last_desc_of_chain(const VhostShadowVirtqueue *svq, -+ uint16_t num, uint16_t i) -+{ -+ for (uint16_t j = 0; j < (num - 1); ++j) { -+ i = le16_to_cpu(svq->desc_next[i]); -+ } -+ -+ return i; -+} -+ - static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, - uint32_t *len) - { - const vring_used_t *used = svq->vring.used; - vring_used_elem_t used_elem; -- uint16_t last_used; -+ uint16_t last_used, last_used_chain, num; - - if (!vhost_svq_more_used(svq)) { - return NULL; -@@ -364,7 +374,10 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, - return NULL; - } - -- svq->desc_next[used_elem.id] = svq->free_head; -+ num = svq->ring_id_maps[used_elem.id]->in_num + -+ svq->ring_id_maps[used_elem.id]->out_num; -+ last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id); -+ svq->desc_next[last_used_chain] = svq->free_head; - svq->free_head = used_elem.id; - - *len = used_elem.len; --- -2.27.0 - diff --git a/vhost-Fix-element-in-vhost_svq_add-failure.patch b/vhost-Fix-element-in-vhost_svq_add-failure.patch deleted file mode 100644 index bad4669e61b347080f86c50e6fbe1e2a5c3db351..0000000000000000000000000000000000000000 --- a/vhost-Fix-element-in-vhost_svq_add-failure.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 3f2c58f4a5abda763c2d4627c7da252ecf604bbb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 12 May 2022 19:57:47 +0200 -Subject: [PATCH] vhost: Fix element in vhost_svq_add failure -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Coverity rightly reports that is not free in that case. - -Fixes: Coverity CID 1487559 -Fixes: 100890f7ca ("vhost: Shadow virtqueue buffers forwarding") - -Signed-off-by: Eugenio Pérez -Message-Id: <20220512175747.142058-7-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 0b394694de..cea2c3f8dd 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -198,11 +198,19 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, - return true; - } - -+/** -+ * Add an element to a SVQ. -+ * -+ * The caller must check that there is enough slots for the new element. It -+ * takes ownership of the element: In case of failure, it is free and the SVQ -+ * is considered broken. -+ */ - static bool vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem) - { - unsigned qemu_head; - bool ok = vhost_svq_add_split(svq, elem, &qemu_head); - if (unlikely(!ok)) { -+ g_free(elem); - return false; - } - --- -2.27.0 - diff --git a/vhost-Fix-false-positive-out-of-bounds.patch b/vhost-Fix-false-positive-out-of-bounds.patch deleted file mode 100644 index 1a6687eb5402622cc1f4d3628d923c84a0127860..0000000000000000000000000000000000000000 --- a/vhost-Fix-false-positive-out-of-bounds.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 9c38d583be2704d7cb5a40e25c9ba0227cbe70cd Mon Sep 17 00:00:00 2001 -From: Hawkins Jiawei -Date: Fri, 7 Jul 2023 23:27:31 +0800 -Subject: [PATCH] vhost: Fix false positive out-of-bounds - -QEMU uses vhost_svq_translate_addr() to translate addresses -between the QEMU's virtual address and the SVQ IOVA. In order -to validate this translation, QEMU checks whether the translated -range falls within the mapped range. - -Yet the problem is that, the value of `needle_last`, which is calculated -by `needle.translated_addr + iovec[i].iov_len`, should represent the -exclusive boundary of the translated range, rather than the last -inclusive addresses of the range. Consequently, QEMU fails the check -when the translated range matches the size of the mapped range. - -This patch solves this problem by fixing the `needle_last` value to -the last inclusive address of the translated range. - -Note that this bug cannot be triggered at the moment, because QEMU -is unable to translate such a big range due to the truncation of -the CVQ command in vhost_vdpa_net_handle_ctrl_avail(). - -Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ") -Signed-off-by: Hawkins Jiawei -Message-Id: -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 8d99edb196..8b5902a8a5 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -109,7 +109,7 @@ static bool vhost_svq_translate_addr(const VhostShadowVirtqueue *svq, - addrs[i] = map->iova + off; - - needle_last = int128_add(int128_make64(needle.translated_addr), -- int128_make64(iovec[i].iov_len)); -+ int128_makes64(iovec[i].iov_len - 1)); - map_last = int128_make64(map->translated_addr + map->size); - if (unlikely(int128_gt(needle_last, map_last))) { - qemu_log_mask(LOG_GUEST_ERROR, --- -2.27.0 - diff --git a/vhost-Get-vring-base-from-vq-not-svq.patch b/vhost-Get-vring-base-from-vq-not-svq.patch deleted file mode 100644 index d388ff1974bf5c1a4dfe4694b25feb8c657affd8..0000000000000000000000000000000000000000 --- a/vhost-Get-vring-base-from-vq-not-svq.patch +++ /dev/null @@ -1,78 +0,0 @@ -From a11196160aaf5ba1102ba324c5a7926e83548f6b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 18 Jul 2022 14:05:45 +0200 -Subject: [PATCH] vhost: Get vring base from vq, not svq -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The SVQ vring used idx usually match with the guest visible one, as long -as all the guest buffers (GPA) maps to exactly one buffer within qemu's -VA. However, as we can see in virtqueue_map_desc, a single guest buffer -could map to many buffers in SVQ vring. - -Also, its also a mistake to rewind them at the source of migration. -Since VirtQueue is able to migrate the inflight descriptors, its -responsability of the destination to perform the rewind just in case it -cannot report the inflight descriptors to the device. - -This makes easier to migrate between backends or to recover them in -vhost devices that support set in flight descriptors. - -Fixes: 6d0b22266633 ("vdpa: Adapt vhost_vdpa_get_vring_base to SVQ") -Signed-off-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 24 ++++++++++++------------ - 1 file changed, 12 insertions(+), 12 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 5956ff4660..6304f174c2 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1181,7 +1181,18 @@ static int vhost_vdpa_set_vring_base(struct vhost_dev *dev, - struct vhost_vring_state *ring) - { - struct vhost_vdpa *v = dev->opaque; -+ VirtQueue *vq = virtio_get_queue(dev->vdev, ring->index); - -+ /* -+ * vhost-vdpa devices does not support in-flight requests. Set all of them -+ * as available. -+ * -+ * TODO: This is ok for networking, but other kinds of devices might -+ * have problems with these retransmissions. -+ */ -+ while (virtqueue_rewind(vq, 1)) { -+ continue; -+ } - if (v->shadow_vqs_enabled) { - /* - * Device vring base was set at device start. SVQ base is handled by -@@ -1197,21 +1208,10 @@ static int vhost_vdpa_get_vring_base(struct vhost_dev *dev, - struct vhost_vring_state *ring) - { - struct vhost_vdpa *v = dev->opaque; -- int vdpa_idx = ring->index - dev->vq_index; - int ret; - - if (v->shadow_vqs_enabled) { -- VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx); -- -- /* -- * Setting base as last used idx, so destination will see as available -- * all the entries that the device did not use, including the in-flight -- * processing ones. -- * -- * TODO: This is ok for networking, but other kinds of devices might -- * have problems with these retransmissions. -- */ -- ring->num = svq->last_used_idx; -+ ring->num = virtio_queue_get_last_avail_idx(dev->vdev, ring->index); - return 0; - } - --- -2.27.0 - diff --git a/vhost-Move-vhost_svq_kick-call-to-vhost_svq_add.patch b/vhost-Move-vhost_svq_kick-call-to-vhost_svq_add.patch deleted file mode 100644 index 5636e942f004ab54fabbb996e44c063e794e540d..0000000000000000000000000000000000000000 --- a/vhost-Move-vhost_svq_kick-call-to-vhost_svq_add.patch +++ /dev/null @@ -1,42 +0,0 @@ -From ebce19945a9bbe3144affa6f5f4129b914e749a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:31 +0200 -Subject: [PATCH] vhost: Move vhost_svq_kick call to vhost_svq_add -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The series needs to expose vhost_svq_add with full functionality, -including kick - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 1ba863b802..b99630acee 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -245,6 +245,7 @@ static bool vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem) - } - - svq->ring_id_maps[qemu_head] = elem; -+ vhost_svq_kick(svq); - return true; - } - -@@ -305,7 +306,6 @@ static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) - /* VQ is broken, just return and ignore any other kicks */ - return; - } -- vhost_svq_kick(svq); - } - - virtio_queue_set_notification(svq->vq, true); --- -2.27.0 - diff --git a/vhost-Reorder-vhost_svq_kick.patch b/vhost-Reorder-vhost_svq_kick.patch deleted file mode 100644 index 459e354786353ab0691c2b00431f1049bc1f11af..0000000000000000000000000000000000000000 --- a/vhost-Reorder-vhost_svq_kick.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 5bf30b401a5fa16189589381d42bfc5f6cf8cf9c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:30 +0200 -Subject: [PATCH] vhost: Reorder vhost_svq_kick -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Future code needs to call it from vhost_svq_add. - -No functional change intended. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 28 ++++++++++++++-------------- - 1 file changed, 14 insertions(+), 14 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index acf50a9a0b..1ba863b802 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -214,6 +214,20 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, - return true; - } - -+static void vhost_svq_kick(VhostShadowVirtqueue *svq) -+{ -+ /* -+ * We need to expose the available array entries before checking the used -+ * flags -+ */ -+ smp_mb(); -+ if (svq->vring.used->flags & VRING_USED_F_NO_NOTIFY) { -+ return; -+ } -+ -+ event_notifier_set(&svq->hdev_kick); -+} -+ - /** - * Add an element to a SVQ. - * -@@ -234,20 +248,6 @@ static bool vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem) - return true; - } - --static void vhost_svq_kick(VhostShadowVirtqueue *svq) --{ -- /* -- * We need to expose the available array entries before checking the used -- * flags -- */ -- smp_mb(); -- if (svq->vring.used->flags & VRING_USED_F_NO_NOTIFY) { -- return; -- } -- -- event_notifier_set(&svq->hdev_kick); --} -- - /** - * Forward available buffers. - * --- -2.27.0 - diff --git a/vhost-Shadow-virtqueue-buffers-forwarding.patch b/vhost-Shadow-virtqueue-buffers-forwarding.patch deleted file mode 100644 index 5d38f7a8fd8d7d552f2e8fac7cb08438e8fd525a..0000000000000000000000000000000000000000 --- a/vhost-Shadow-virtqueue-buffers-forwarding.patch +++ /dev/null @@ -1,684 +0,0 @@ -From bb7c23fd4979edaeeedf05e05cfed0d086430500 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:47 +0100 -Subject: [PATCH] vhost: Shadow virtqueue buffers forwarding -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Initial version of shadow virtqueue that actually forward buffers. There -is no iommu support at the moment, and that will be addressed in future -patches of this series. Since all vhost-vdpa devices use forced IOMMU, -this means that SVQ is not usable at this point of the series on any -device. - -For simplicity it only supports modern devices, that expects vring -in little endian, with split ring and no event idx or indirect -descriptors. Support for them will not be added in this series. - -It reuses the VirtQueue code for the device part. The driver part is -based on Linux's virtio_ring driver, but with stripped functionality -and optimizations so it's easier to review. - -However, forwarding buffers have some particular pieces: One of the most -unexpected ones is that a guest's buffer can expand through more than -one descriptor in SVQ. While this is handled gracefully by qemu's -emulated virtio devices, it may cause unexpected SVQ queue full. This -patch also solves it by checking for this condition at both guest's -kicks and device's calls. The code may be more elegant in the future if -SVQ code runs in its own iocontext. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 351 ++++++++++++++++++++++++++++- - hw/virtio/vhost-shadow-virtqueue.h | 26 +++ - hw/virtio/vhost-vdpa.c | 155 ++++++++++++- - 3 files changed, 521 insertions(+), 11 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 573ac0d9cf..46e94f0861 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -13,6 +13,7 @@ - #include "qemu/error-report.h" - #include "qapi/error.h" - #include "qemu/main-loop.h" -+#include "qemu/log.h" - #include "linux-headers/linux/vhost.h" - - /** -@@ -59,28 +60,307 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp) - } - - /** -- * Forward guest notifications. -+ * Number of descriptors that the SVQ can make available from the guest. -+ * -+ * @svq: The svq -+ */ -+static uint16_t vhost_svq_available_slots(const VhostShadowVirtqueue *svq) -+{ -+ return svq->vring.num - (svq->shadow_avail_idx - svq->shadow_used_idx); -+} -+ -+static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, -+ const struct iovec *iovec, size_t num, -+ bool more_descs, bool write) -+{ -+ uint16_t i = svq->free_head, last = svq->free_head; -+ unsigned n; -+ uint16_t flags = write ? cpu_to_le16(VRING_DESC_F_WRITE) : 0; -+ vring_desc_t *descs = svq->vring.desc; -+ -+ if (num == 0) { -+ return; -+ } -+ -+ for (n = 0; n < num; n++) { -+ if (more_descs || (n + 1 < num)) { -+ descs[i].flags = flags | cpu_to_le16(VRING_DESC_F_NEXT); -+ } else { -+ descs[i].flags = flags; -+ } -+ descs[i].addr = cpu_to_le64((hwaddr)(intptr_t)iovec[n].iov_base); -+ descs[i].len = cpu_to_le32(iovec[n].iov_len); -+ -+ last = i; -+ i = cpu_to_le16(descs[i].next); -+ } -+ -+ svq->free_head = le16_to_cpu(descs[last].next); -+} -+ -+static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, -+ VirtQueueElement *elem, unsigned *head) -+{ -+ unsigned avail_idx; -+ vring_avail_t *avail = svq->vring.avail; -+ -+ *head = svq->free_head; -+ -+ /* We need some descriptors here */ -+ if (unlikely(!elem->out_num && !elem->in_num)) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "Guest provided element with no descriptors"); -+ return false; -+ } -+ -+ vhost_vring_write_descs(svq, elem->out_sg, elem->out_num, elem->in_num > 0, -+ false); -+ vhost_vring_write_descs(svq, elem->in_sg, elem->in_num, false, true); -+ -+ /* -+ * Put the entry in the available array (but don't update avail->idx until -+ * they do sync). -+ */ -+ avail_idx = svq->shadow_avail_idx & (svq->vring.num - 1); -+ avail->ring[avail_idx] = cpu_to_le16(*head); -+ svq->shadow_avail_idx++; -+ -+ /* Update the avail index after write the descriptor */ -+ smp_wmb(); -+ avail->idx = cpu_to_le16(svq->shadow_avail_idx); -+ -+ return true; -+} -+ -+static bool vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem) -+{ -+ unsigned qemu_head; -+ bool ok = vhost_svq_add_split(svq, elem, &qemu_head); -+ if (unlikely(!ok)) { -+ return false; -+ } -+ -+ svq->ring_id_maps[qemu_head] = elem; -+ return true; -+} -+ -+static void vhost_svq_kick(VhostShadowVirtqueue *svq) -+{ -+ /* -+ * We need to expose the available array entries before checking the used -+ * flags -+ */ -+ smp_mb(); -+ if (svq->vring.used->flags & VRING_USED_F_NO_NOTIFY) { -+ return; -+ } -+ -+ event_notifier_set(&svq->hdev_kick); -+} -+ -+/** -+ * Forward available buffers. -+ * -+ * @svq: Shadow VirtQueue -+ * -+ * Note that this function does not guarantee that all guest's available -+ * buffers are available to the device in SVQ avail ring. The guest may have -+ * exposed a GPA / GIOVA contiguous buffer, but it may not be contiguous in -+ * qemu vaddr. -+ * -+ * If that happens, guest's kick notifications will be disabled until the -+ * device uses some buffers. -+ */ -+static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) -+{ -+ /* Clear event notifier */ -+ event_notifier_test_and_clear(&svq->svq_kick); -+ -+ /* Forward to the device as many available buffers as possible */ -+ do { -+ virtio_queue_set_notification(svq->vq, false); -+ -+ while (true) { -+ VirtQueueElement *elem; -+ bool ok; -+ -+ if (svq->next_guest_avail_elem) { -+ elem = g_steal_pointer(&svq->next_guest_avail_elem); -+ } else { -+ elem = virtqueue_pop(svq->vq, sizeof(*elem)); -+ } -+ -+ if (!elem) { -+ break; -+ } -+ -+ if (elem->out_num + elem->in_num > vhost_svq_available_slots(svq)) { -+ /* -+ * This condition is possible since a contiguous buffer in GPA -+ * does not imply a contiguous buffer in qemu's VA -+ * scatter-gather segments. If that happens, the buffer exposed -+ * to the device needs to be a chain of descriptors at this -+ * moment. -+ * -+ * SVQ cannot hold more available buffers if we are here: -+ * queue the current guest descriptor and ignore further kicks -+ * until some elements are used. -+ */ -+ svq->next_guest_avail_elem = elem; -+ return; -+ } -+ -+ ok = vhost_svq_add(svq, elem); -+ if (unlikely(!ok)) { -+ /* VQ is broken, just return and ignore any other kicks */ -+ return; -+ } -+ vhost_svq_kick(svq); -+ } -+ -+ virtio_queue_set_notification(svq->vq, true); -+ } while (!virtio_queue_empty(svq->vq)); -+} -+ -+/** -+ * Handle guest's kick. - * - * @n: guest kick event notifier, the one that guest set to notify svq. - */ --static void vhost_handle_guest_kick(EventNotifier *n) -+static void vhost_handle_guest_kick_notifier(EventNotifier *n) - { - VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, svq_kick); - event_notifier_test_and_clear(n); -- event_notifier_set(&svq->hdev_kick); -+ vhost_handle_guest_kick(svq); -+} -+ -+static bool vhost_svq_more_used(VhostShadowVirtqueue *svq) -+{ -+ if (svq->last_used_idx != svq->shadow_used_idx) { -+ return true; -+ } -+ -+ svq->shadow_used_idx = cpu_to_le16(svq->vring.used->idx); -+ -+ return svq->last_used_idx != svq->shadow_used_idx; - } - - /** -- * Forward vhost notifications -+ * Enable vhost device calls after disable them. -+ * -+ * @svq: The svq -+ * -+ * It returns false if there are pending used buffers from the vhost device, -+ * avoiding the possible races between SVQ checking for more work and enabling -+ * callbacks. True if SVQ used vring has no more pending buffers. -+ */ -+static bool vhost_svq_enable_notification(VhostShadowVirtqueue *svq) -+{ -+ svq->vring.avail->flags &= ~cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); -+ /* Make sure the flag is written before the read of used_idx */ -+ smp_mb(); -+ return !vhost_svq_more_used(svq); -+} -+ -+static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq) -+{ -+ svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); -+} -+ -+static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, -+ uint32_t *len) -+{ -+ vring_desc_t *descs = svq->vring.desc; -+ const vring_used_t *used = svq->vring.used; -+ vring_used_elem_t used_elem; -+ uint16_t last_used; -+ -+ if (!vhost_svq_more_used(svq)) { -+ return NULL; -+ } -+ -+ /* Only get used array entries after they have been exposed by dev */ -+ smp_rmb(); -+ last_used = svq->last_used_idx & (svq->vring.num - 1); -+ used_elem.id = le32_to_cpu(used->ring[last_used].id); -+ used_elem.len = le32_to_cpu(used->ring[last_used].len); -+ -+ svq->last_used_idx++; -+ if (unlikely(used_elem.id >= svq->vring.num)) { -+ qemu_log_mask(LOG_GUEST_ERROR, "Device %s says index %u is used", -+ svq->vdev->name, used_elem.id); -+ return NULL; -+ } -+ -+ if (unlikely(!svq->ring_id_maps[used_elem.id])) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "Device %s says index %u is used, but it was not available", -+ svq->vdev->name, used_elem.id); -+ return NULL; -+ } -+ -+ descs[used_elem.id].next = svq->free_head; -+ svq->free_head = used_elem.id; -+ -+ *len = used_elem.len; -+ return g_steal_pointer(&svq->ring_id_maps[used_elem.id]); -+} -+ -+static void vhost_svq_flush(VhostShadowVirtqueue *svq, -+ bool check_for_avail_queue) -+{ -+ VirtQueue *vq = svq->vq; -+ -+ /* Forward as many used buffers as possible. */ -+ do { -+ unsigned i = 0; -+ -+ vhost_svq_disable_notification(svq); -+ while (true) { -+ uint32_t len; -+ g_autofree VirtQueueElement *elem = vhost_svq_get_buf(svq, &len); -+ if (!elem) { -+ break; -+ } -+ -+ if (unlikely(i >= svq->vring.num)) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "More than %u used buffers obtained in a %u size SVQ", -+ i, svq->vring.num); -+ virtqueue_fill(vq, elem, len, i); -+ virtqueue_flush(vq, i); -+ return; -+ } -+ virtqueue_fill(vq, elem, len, i++); -+ } -+ -+ virtqueue_flush(vq, i); -+ event_notifier_set(&svq->svq_call); -+ -+ if (check_for_avail_queue && svq->next_guest_avail_elem) { -+ /* -+ * Avail ring was full when vhost_svq_flush was called, so it's a -+ * good moment to make more descriptors available if possible. -+ */ -+ vhost_handle_guest_kick(svq); -+ } -+ } while (!vhost_svq_enable_notification(svq)); -+} -+ -+/** -+ * Forward used buffers. - * - * @n: hdev call event notifier, the one that device set to notify svq. -+ * -+ * Note that we are not making any buffers available in the loop, there is no -+ * way that it runs more than virtqueue size times. - */ - static void vhost_svq_handle_call(EventNotifier *n) - { - VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, - hdev_call); - event_notifier_test_and_clear(n); -- event_notifier_set(&svq->svq_call); -+ vhost_svq_flush(svq, true); - } - - /** -@@ -161,7 +441,41 @@ void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd) - if (poll_start) { - event_notifier_init_fd(svq_kick, svq_kick_fd); - event_notifier_set(svq_kick); -- event_notifier_set_handler(svq_kick, vhost_handle_guest_kick); -+ event_notifier_set_handler(svq_kick, vhost_handle_guest_kick_notifier); -+ } -+} -+ -+/** -+ * Start the shadow virtqueue operation. -+ * -+ * @svq: Shadow Virtqueue -+ * @vdev: VirtIO device -+ * @vq: Virtqueue to shadow -+ */ -+void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, -+ VirtQueue *vq) -+{ -+ size_t desc_size, driver_size, device_size; -+ -+ svq->next_guest_avail_elem = NULL; -+ svq->shadow_avail_idx = 0; -+ svq->shadow_used_idx = 0; -+ svq->last_used_idx = 0; -+ svq->vdev = vdev; -+ svq->vq = vq; -+ -+ svq->vring.num = virtio_queue_get_num(vdev, virtio_get_queue_index(vq)); -+ driver_size = vhost_svq_driver_area_size(svq); -+ device_size = vhost_svq_device_area_size(svq); -+ svq->vring.desc = qemu_memalign(qemu_real_host_page_size, driver_size); -+ desc_size = sizeof(vring_desc_t) * svq->vring.num; -+ svq->vring.avail = (void *)((char *)svq->vring.desc + desc_size); -+ memset(svq->vring.desc, 0, driver_size); -+ svq->vring.used = qemu_memalign(qemu_real_host_page_size, device_size); -+ memset(svq->vring.used, 0, device_size); -+ svq->ring_id_maps = g_new0(VirtQueueElement *, svq->vring.num); -+ for (unsigned i = 0; i < svq->vring.num - 1; i++) { -+ svq->vring.desc[i].next = cpu_to_le16(i + 1); - } - } - -@@ -172,6 +486,31 @@ void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd) - void vhost_svq_stop(VhostShadowVirtqueue *svq) - { - event_notifier_set_handler(&svq->svq_kick, NULL); -+ g_autofree VirtQueueElement *next_avail_elem = NULL; -+ -+ if (!svq->vq) { -+ return; -+ } -+ -+ /* Send all pending used descriptors to guest */ -+ vhost_svq_flush(svq, false); -+ -+ for (unsigned i = 0; i < svq->vring.num; ++i) { -+ g_autofree VirtQueueElement *elem = NULL; -+ elem = g_steal_pointer(&svq->ring_id_maps[i]); -+ if (elem) { -+ virtqueue_detach_element(svq->vq, elem, 0); -+ } -+ } -+ -+ next_avail_elem = g_steal_pointer(&svq->next_guest_avail_elem); -+ if (next_avail_elem) { -+ virtqueue_detach_element(svq->vq, next_avail_elem, 0); -+ } -+ svq->vq = NULL; -+ g_free(svq->ring_id_maps); -+ qemu_vfree(svq->vring.desc); -+ qemu_vfree(svq->vring.used); - } - - /** -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index 82cea1c3fa..38b3b91ca7 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -36,6 +36,30 @@ typedef struct VhostShadowVirtqueue { - - /* Guest's call notifier, where the SVQ calls guest. */ - EventNotifier svq_call; -+ -+ /* Virtio queue shadowing */ -+ VirtQueue *vq; -+ -+ /* Virtio device */ -+ VirtIODevice *vdev; -+ -+ /* Map for use the guest's descriptors */ -+ VirtQueueElement **ring_id_maps; -+ -+ /* Next VirtQueue element that guest made available */ -+ VirtQueueElement *next_guest_avail_elem; -+ -+ /* Next head to expose to the device */ -+ uint16_t shadow_avail_idx; -+ -+ /* Next free descriptor */ -+ uint16_t free_head; -+ -+ /* Last seen used idx */ -+ uint16_t shadow_used_idx; -+ -+ /* Next head to consume from the device */ -+ uint16_t last_used_idx; - } VhostShadowVirtqueue; - - bool vhost_svq_valid_features(uint64_t features, Error **errp); -@@ -47,6 +71,8 @@ void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, - size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq); - size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq); - -+void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, -+ VirtQueue *vq); - void vhost_svq_stop(VhostShadowVirtqueue *svq); - - VhostShadowVirtqueue *vhost_svq_new(void); -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 2f0e6a9bef..db34f26246 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -779,9 +779,9 @@ static int vhost_vdpa_set_vring_dev_addr(struct vhost_dev *dev, - * Note that this function does not rewind kick file descriptor if cannot set - * call one. - */ --static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, -- VhostShadowVirtqueue *svq, unsigned idx, -- Error **errp) -+static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, -+ VhostShadowVirtqueue *svq, unsigned idx, -+ Error **errp) - { - struct vhost_vring_file file = { - .index = dev->vq_index + idx, -@@ -793,7 +793,7 @@ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, - r = vhost_vdpa_set_vring_dev_kick(dev, &file); - if (unlikely(r != 0)) { - error_setg_errno(errp, -r, "Can't set device kick fd"); -- return false; -+ return r; - } - - event_notifier = &svq->hdev_call; -@@ -803,6 +803,95 @@ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, - error_setg_errno(errp, -r, "Can't set device call fd"); - } - -+ return r; -+} -+ -+/** -+ * Unmap a SVQ area in the device -+ */ -+static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr iova, -+ hwaddr size) -+{ -+ int r; -+ -+ size = ROUND_UP(size, qemu_real_host_page_size); -+ r = vhost_vdpa_dma_unmap(v, iova, size); -+ return r == 0; -+} -+ -+static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, -+ const VhostShadowVirtqueue *svq) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ struct vhost_vring_addr svq_addr; -+ size_t device_size = vhost_svq_device_area_size(svq); -+ size_t driver_size = vhost_svq_driver_area_size(svq); -+ bool ok; -+ -+ vhost_svq_get_vring_addr(svq, &svq_addr); -+ -+ ok = vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr, driver_size); -+ if (unlikely(!ok)) { -+ return false; -+ } -+ -+ return vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr, device_size); -+} -+ -+/** -+ * Map the shadow virtqueue rings in the device -+ * -+ * @dev: The vhost device -+ * @svq: The shadow virtqueue -+ * @addr: Assigned IOVA addresses -+ * @errp: Error pointer -+ */ -+static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev, -+ const VhostShadowVirtqueue *svq, -+ struct vhost_vring_addr *addr, -+ Error **errp) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ size_t device_size = vhost_svq_device_area_size(svq); -+ size_t driver_size = vhost_svq_driver_area_size(svq); -+ int r; -+ -+ ERRP_GUARD(); -+ vhost_svq_get_vring_addr(svq, addr); -+ -+ r = vhost_vdpa_dma_map(v, addr->desc_user_addr, driver_size, -+ (void *)(uintptr_t)addr->desc_user_addr, true); -+ if (unlikely(r != 0)) { -+ error_setg_errno(errp, -r, "Cannot create vq driver region: "); -+ return false; -+ } -+ -+ r = vhost_vdpa_dma_map(v, addr->used_user_addr, device_size, -+ (void *)(intptr_t)addr->used_user_addr, false); -+ if (unlikely(r != 0)) { -+ error_setg_errno(errp, -r, "Cannot create vq device region: "); -+ } -+ -+ return r == 0; -+} -+ -+static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, -+ VhostShadowVirtqueue *svq, unsigned idx, -+ Error **errp) -+{ -+ uint16_t vq_index = dev->vq_index + idx; -+ struct vhost_vring_state s = { -+ .index = vq_index, -+ }; -+ int r; -+ -+ r = vhost_vdpa_set_dev_vring_base(dev, &s); -+ if (unlikely(r)) { -+ error_setg_errno(errp, -r, "Cannot set vring base"); -+ return false; -+ } -+ -+ r = vhost_vdpa_svq_set_fds(dev, svq, idx, errp); - return r == 0; - } - -@@ -817,10 +906,62 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) - } - - for (i = 0; i < v->shadow_vqs->len; ++i) { -+ VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i); - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -+ struct vhost_vring_addr addr = { -+ .index = i, -+ }; -+ int r; - bool ok = vhost_vdpa_svq_setup(dev, svq, i, &err); - if (unlikely(!ok)) { -- error_reportf_err(err, "Cannot setup SVQ %u: ", i); -+ goto err; -+ } -+ -+ vhost_svq_start(svq, dev->vdev, vq); -+ ok = vhost_vdpa_svq_map_rings(dev, svq, &addr, &err); -+ if (unlikely(!ok)) { -+ goto err_map; -+ } -+ -+ /* Override vring GPA set by vhost subsystem */ -+ r = vhost_vdpa_set_vring_dev_addr(dev, &addr); -+ if (unlikely(r != 0)) { -+ error_setg_errno(&err, -r, "Cannot set device address"); -+ goto err_set_addr; -+ } -+ } -+ -+ return true; -+ -+err_set_addr: -+ vhost_vdpa_svq_unmap_rings(dev, g_ptr_array_index(v->shadow_vqs, i)); -+ -+err_map: -+ vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, i)); -+ -+err: -+ error_reportf_err(err, "Cannot setup SVQ %u: ", i); -+ for (unsigned j = 0; j < i; ++j) { -+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, j); -+ vhost_vdpa_svq_unmap_rings(dev, svq); -+ vhost_svq_stop(svq); -+ } -+ -+ return false; -+} -+ -+static bool vhost_vdpa_svqs_stop(struct vhost_dev *dev) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ -+ if (!v->shadow_vqs) { -+ return true; -+ } -+ -+ for (unsigned i = 0; i < v->shadow_vqs->len; ++i) { -+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); -+ bool ok = vhost_vdpa_svq_unmap_rings(dev, svq); -+ if (unlikely(!ok)) { - return false; - } - } -@@ -842,6 +983,10 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) - } - vhost_vdpa_set_vring_ready(dev); - } else { -+ ok = vhost_vdpa_svqs_stop(dev); -+ if (unlikely(!ok)) { -+ return -1; -+ } - vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs); - } - --- -2.27.0 - diff --git a/vhost-Track-descriptor-chain-in-private-at-SVQ.patch b/vhost-Track-descriptor-chain-in-private-at-SVQ.patch deleted file mode 100644 index dbcdb74321eecc722f2b89b20c6727d5310b0751..0000000000000000000000000000000000000000 --- a/vhost-Track-descriptor-chain-in-private-at-SVQ.patch +++ /dev/null @@ -1,104 +0,0 @@ -From de3c31598e00c4bcee42f3921f714b0928716535 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 12 May 2022 19:57:42 +0200 -Subject: [PATCH] vhost: Track descriptor chain in private at SVQ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The device could have access to modify them, and it definitely have -access when we implement packed vq. Harden SVQ maintaining a private -copy of the descriptor chain. Other fields like buffer addresses are -already maintained sepparatedly. - -Signed-off-by: Eugenio Pérez -Message-Id: <20220512175747.142058-2-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 12 +++++++----- - hw/virtio/vhost-shadow-virtqueue.h | 6 ++++++ - 2 files changed, 13 insertions(+), 5 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index c38b6b6ab5..6057a437df 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -137,6 +137,7 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg, - for (n = 0; n < num; n++) { - if (more_descs || (n + 1 < num)) { - descs[i].flags = flags | cpu_to_le16(VRING_DESC_F_NEXT); -+ descs[i].next = cpu_to_le16(svq->desc_next[i]); - } else { - descs[i].flags = flags; - } -@@ -144,10 +145,10 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg, - descs[i].len = cpu_to_le32(iovec[n].iov_len); - - last = i; -- i = cpu_to_le16(descs[i].next); -+ i = cpu_to_le16(svq->desc_next[i]); - } - -- svq->free_head = le16_to_cpu(descs[last].next); -+ svq->free_head = le16_to_cpu(svq->desc_next[last]); - } - - static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, -@@ -335,7 +336,6 @@ static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq) - static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, - uint32_t *len) - { -- vring_desc_t *descs = svq->vring.desc; - const vring_used_t *used = svq->vring.used; - vring_used_elem_t used_elem; - uint16_t last_used; -@@ -364,7 +364,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, - return NULL; - } - -- descs[used_elem.id].next = svq->free_head; -+ svq->desc_next[used_elem.id] = svq->free_head; - svq->free_head = used_elem.id; - - *len = used_elem.len; -@@ -539,8 +539,9 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, - svq->vring.used = qemu_memalign(qemu_real_host_page_size, device_size); - memset(svq->vring.used, 0, device_size); - svq->ring_id_maps = g_new0(VirtQueueElement *, svq->vring.num); -+ svq->desc_next = g_new0(uint16_t, svq->vring.num); - for (unsigned i = 0; i < svq->vring.num - 1; i++) { -- svq->vring.desc[i].next = cpu_to_le16(i + 1); -+ svq->desc_next[i] = cpu_to_le16(i + 1); - } - } - -@@ -573,6 +574,7 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq) - virtqueue_detach_element(svq->vq, next_avail_elem, 0); - } - svq->vq = NULL; -+ g_free(svq->desc_next); - g_free(svq->ring_id_maps); - qemu_vfree(svq->vring.desc); - qemu_vfree(svq->vring.used); -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index e5e24c536d..c132c994e9 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -53,6 +53,12 @@ typedef struct VhostShadowVirtqueue { - /* Next VirtQueue element that guest made available */ - VirtQueueElement *next_guest_avail_elem; - -+ /* -+ * Backup next field for each descriptor so we can recover securely, not -+ * needing to trust the device access. -+ */ -+ uint16_t *desc_next; -+ - /* Next head to expose to the device */ - uint16_t shadow_avail_idx; - --- -2.27.0 - diff --git a/vhost-Track-number-of-descs-in-SVQDescState.patch b/vhost-Track-number-of-descs-in-SVQDescState.patch deleted file mode 100644 index 1c247898e54198d1693d7a316613f05be71eba96..0000000000000000000000000000000000000000 --- a/vhost-Track-number-of-descs-in-SVQDescState.patch +++ /dev/null @@ -1,62 +0,0 @@ -From d76e2c5a5213d51dd8c48315e26c277423ade99f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:35 +0200 -Subject: [PATCH] vhost: Track number of descs in SVQDescState -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -A guest's buffer continuos on GPA may need multiple descriptors on -qemu's VA, so SVQ should track its length sepparatedly. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 4 ++-- - hw/virtio/vhost-shadow-virtqueue.h | 6 ++++++ - 2 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 5ddc04e9d6..c10c74b91f 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -256,6 +256,7 @@ static int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, - } - - svq->desc_state[qemu_head].elem = elem; -+ svq->desc_state[qemu_head].ndescs = ndescs; - vhost_svq_kick(svq); - return 0; - } -@@ -417,8 +418,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, - return NULL; - } - -- num = svq->desc_state[used_elem.id].elem->in_num + -- svq->desc_state[used_elem.id].elem->out_num; -+ num = svq->desc_state[used_elem.id].ndescs; - last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id); - svq->desc_next[last_used_chain] = svq->free_head; - svq->free_head = used_elem.id; -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index d646c35054..5c7e7cbab6 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -17,6 +17,12 @@ - - typedef struct SVQDescState { - VirtQueueElement *elem; -+ -+ /* -+ * Number of descriptors exposed to the device. May or may not match -+ * guest's -+ */ -+ unsigned int ndescs; - } SVQDescState; - - /* Shadow virtqueue to relay notifications */ --- -2.27.0 - diff --git a/vhost-add-support-for-configure-interrupt-new.patch b/vhost-add-support-for-configure-interrupt-new.patch deleted file mode 100644 index 0be96f2765e2b740fbcedab5ccd048979c1f07b4..0000000000000000000000000000000000000000 --- a/vhost-add-support-for-configure-interrupt-new.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 59957a4caee59e0c82b8d02ed1c1820db523ae64 Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:48 +0800 -Subject: [PATCH] vhost: add support for configure interrupt - -Add functions to support configure interrupt. -The configure interrupt process will start in vhost_dev_start -and stop in vhost_dev_stop. - -Also add the functions to support vhost_config_pending and -vhost_config_mask. - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-8-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 78 ++++++++++++++++++++++++++++++++++++++- - include/hw/virtio/vhost.h | 4 ++ - 2 files changed, 81 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 19ea9aef69..490c97424b 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -1627,7 +1627,68 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, - file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n); - r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file); - if (r < 0) { -- VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed"); -+ error_report("vhost_set_vring_call failed %d", -r); -+ } -+} -+ -+bool vhost_config_pending(struct vhost_dev *hdev) -+{ -+ assert(hdev->vhost_ops); -+ if ((hdev->started == false) || -+ (hdev->vhost_ops->vhost_set_config_call == NULL)) { -+ return false; -+ } -+ -+ EventNotifier *notifier = -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; -+ return event_notifier_test_and_clear(notifier); -+} -+ -+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask) -+{ -+ int fd; -+ int r; -+ EventNotifier *notifier = -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; -+ EventNotifier *config_notifier = &vdev->config_notifier; -+ assert(hdev->vhost_ops); -+ -+ if ((hdev->started == false) || -+ (hdev->vhost_ops->vhost_set_config_call == NULL)) { -+ return; -+ } -+ if (mask) { -+ assert(vdev->use_guest_notifier_mask); -+ fd = event_notifier_get_fd(notifier); -+ } else { -+ fd = event_notifier_get_fd(config_notifier); -+ } -+ r = hdev->vhost_ops->vhost_set_config_call(hdev, fd); -+ if (r < 0) { -+ error_report("vhost_set_config_call failed %d", -r); -+ } -+} -+ -+static void vhost_stop_config_intr(struct vhost_dev *dev) -+{ -+ int fd = -1; -+ assert(dev->vhost_ops); -+ if (dev->vhost_ops->vhost_set_config_call) { -+ dev->vhost_ops->vhost_set_config_call(dev, fd); -+ } -+} -+ -+static void vhost_start_config_intr(struct vhost_dev *dev) -+{ -+ int r; -+ -+ assert(dev->vhost_ops); -+ int fd = event_notifier_get_fd(&dev->vdev->config_notifier); -+ if (dev->vhost_ops->vhost_set_config_call) { -+ r = dev->vhost_ops->vhost_set_config_call(dev, fd); -+ if (!r) { -+ event_notifier_set(&dev->vdev->config_notifier); -+ } - } - } - -@@ -1867,6 +1928,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - } - } - -+ r = event_notifier_init( -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0); -+ if (r < 0) { -+ return r; -+ } -+ event_notifier_test_and_clear( -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); -+ if (!vdev->use_guest_notifier_mask) { -+ vhost_config_mask(hdev, vdev, true); -+ } - if (hdev->log_enabled) { - uint64_t log_base; - -@@ -1905,6 +1976,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - vhost_device_iotlb_miss(hdev, vq->used_phys, true); - } - } -+ vhost_start_config_intr(hdev); - return 0; - fail_start: - if (vrings) { -@@ -1934,6 +2006,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - - /* should only be called after backend is connected */ - assert(hdev->vhost_ops); -+ event_notifier_test_and_clear( -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); -+ event_notifier_test_and_clear(&vdev->config_notifier); - - trace_vhost_dev_stop(hdev, vdev->name, vrings); - -@@ -1956,6 +2031,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - } - memory_listener_unregister(&hdev->iommu_listener); - } -+ vhost_stop_config_intr(hdev); - vhost_log_put(hdev, true); - hdev->started = false; - vdev->vhost_started = false; -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index 662e0f4370..420f93e5cd 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -32,6 +32,7 @@ struct vhost_virtqueue { - unsigned long long used_phys; - unsigned used_size; - EventNotifier masked_notifier; -+ EventNotifier masked_config_notifier; - struct vhost_dev *dev; - }; - -@@ -40,6 +41,7 @@ typedef unsigned long vhost_log_chunk_t; - #define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t)) - #define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS) - #define VHOST_INVALID_FEATURE_BIT (0xff) -+#define VHOST_QUEUE_NUM_CONFIG_INR 0 - - struct vhost_log { - unsigned long long size; -@@ -163,6 +165,8 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); - * Disable direct notifications to vhost device. - */ - void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); -+bool vhost_config_pending(struct vhost_dev *hdev); -+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask); - - /** - * vhost_dev_start() - start the vhost device --- -2.27.0 - diff --git a/vhost-add-support-for-configure-interrupt.patch b/vhost-add-support-for-configure-interrupt.patch deleted file mode 100644 index d8916c37b3e8ce0b112fcbca42b9a993ee7debe3..0000000000000000000000000000000000000000 --- a/vhost-add-support-for-configure-interrupt.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 9823b7bb536cea50c9750320436511fd60b797cd Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:52 +0800 -Subject: [PATCH] vhost: add support for configure interrupt - -Add functions to support configure interrupt. -The configure interrupt process will start in vhost_dev_start -and stop in vhost_dev_stop. - -Also add the functions to support vhost_config_pending and -vhost_config_mask, for masked_config_notifier, we only -use the notifier saved in vq 0. - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-8-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 76 +++++++++++++++++++++++++++++++++++++++ - include/hw/virtio/vhost.h | 4 +++ - 2 files changed, 80 insertions(+) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 2d11e3c2f8..c3f375f276 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -1588,6 +1588,67 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, - } - } - -+bool vhost_config_pending(struct vhost_dev *hdev) -+{ -+ assert(hdev->vhost_ops); -+ if ((hdev->started == false) || -+ (hdev->vhost_ops->vhost_set_config_call == NULL)) { -+ return false; -+ } -+ -+ EventNotifier *notifier = -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; -+ return event_notifier_test_and_clear(notifier); -+} -+ -+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask) -+{ -+ int fd; -+ int r; -+ EventNotifier *notifier = -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; -+ EventNotifier *config_notifier = &vdev->config_notifier; -+ assert(hdev->vhost_ops); -+ -+ if ((hdev->started == false) || -+ (hdev->vhost_ops->vhost_set_config_call == NULL)) { -+ return; -+ } -+ if (mask) { -+ assert(vdev->use_guest_notifier_mask); -+ fd = event_notifier_get_fd(notifier); -+ } else { -+ fd = event_notifier_get_fd(config_notifier); -+ } -+ r = hdev->vhost_ops->vhost_set_config_call(hdev, fd); -+ if (r < 0) { -+ VHOST_OPS_DEBUG("vhost_set_config_call failed"); -+ } -+} -+ -+static void vhost_stop_config_intr(struct vhost_dev *dev) -+{ -+ int fd = -1; -+ assert(dev->vhost_ops); -+ if (dev->vhost_ops->vhost_set_config_call) { -+ dev->vhost_ops->vhost_set_config_call(dev, fd); -+ } -+} -+ -+static void vhost_start_config_intr(struct vhost_dev *dev) -+{ -+ int r; -+ -+ assert(dev->vhost_ops); -+ int fd = event_notifier_get_fd(&dev->vdev->config_notifier); -+ if (dev->vhost_ops->vhost_set_config_call) { -+ r = dev->vhost_ops->vhost_set_config_call(dev, fd); -+ if (!r) { -+ event_notifier_set(&dev->vdev->config_notifier); -+ } -+ } -+} -+ - uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits, - uint64_t features) - { -@@ -1800,6 +1861,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - } - } - -+ r = event_notifier_init( -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0); -+ if (r < 0) { -+ return r; -+ } -+ event_notifier_test_and_clear( -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); -+ if (!vdev->use_guest_notifier_mask) { -+ vhost_config_mask(hdev, vdev, true); -+ } - if (hdev->log_enabled) { - uint64_t log_base; - -@@ -1833,6 +1904,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - vhost_device_iotlb_miss(hdev, vq->used_phys, true); - } - } -+ vhost_start_config_intr(hdev); - return 0; - fail_log: - vhost_log_put(hdev, false); -@@ -1858,6 +1930,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) - - /* should only be called after backend is connected */ - assert(hdev->vhost_ops); -+ event_notifier_test_and_clear( -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); -+ event_notifier_test_and_clear(&vdev->config_notifier); - - if (hdev->vhost_ops->vhost_dev_start) { - hdev->vhost_ops->vhost_dev_start(hdev, false); -@@ -1875,6 +1950,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) - } - memory_listener_unregister(&hdev->iommu_listener); - } -+ vhost_stop_config_intr(hdev); - vhost_log_put(hdev, true); - hdev->started = false; - hdev->vdev = NULL; -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index 86f36f0106..2ae5c3bfd8 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -29,6 +29,7 @@ struct vhost_virtqueue { - unsigned long long used_phys; - unsigned used_size; - EventNotifier masked_notifier; -+ EventNotifier masked_config_notifier; - struct vhost_dev *dev; - }; - -@@ -37,6 +38,7 @@ typedef unsigned long vhost_log_chunk_t; - #define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t)) - #define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS) - #define VHOST_INVALID_FEATURE_BIT (0xff) -+#define VHOST_QUEUE_NUM_CONFIG_INR 0 - - struct vhost_log { - unsigned long long size; -@@ -116,6 +118,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); - void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); - int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); - void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); -+bool vhost_config_pending(struct vhost_dev *hdev); -+void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask); - - /* Test and clear masked event pending status. - * Should be called after unmask to avoid losing events. --- -2.27.0 - diff --git a/vhost-add-vhost_dev_suspend-resume_op.patch b/vhost-add-vhost_dev_suspend-resume_op.patch deleted file mode 100644 index e09763177b5fb22aba7309292ae5bfcee21b2811..0000000000000000000000000000000000000000 --- a/vhost-add-vhost_dev_suspend-resume_op.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 745bbf64b2a1e74366550bffbb68da1df2a9f378 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:13:41 +0800 -Subject: [PATCH] vhost: add vhost_dev_suspend/resume_op - -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - include/hw/virtio/vhost-backend.h | 5 +++++ - linux-headers/linux/vhost.h | 17 +++++++++++++++++ - 2 files changed, 22 insertions(+) - -diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h -index 86154dd0b2..2ca6250567 100644 ---- a/include/hw/virtio/vhost-backend.h -+++ b/include/hw/virtio/vhost-backend.h -@@ -135,6 +135,9 @@ typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev, - typedef void (*vhost_set_used_memslots_op)(struct vhost_dev *dev); - typedef unsigned int (*vhost_get_used_memslots_op)(void); - -+typedef int (*vhost_dev_suspend_op)(struct vhost_dev *dev); -+typedef int (*vhost_dev_resume_op)(struct vhost_dev *dev); -+ - typedef struct VhostOps { - VhostBackendType backend_type; - vhost_backend_init vhost_backend_init; -@@ -186,6 +189,8 @@ typedef struct VhostOps { - vhost_set_config_call_op vhost_set_config_call; - vhost_set_used_memslots_op vhost_set_used_memslots; - vhost_get_used_memslots_op vhost_get_used_memslots; -+ vhost_dev_suspend_op vhost_dev_suspend; -+ vhost_dev_resume_op vhost_dev_resume; - } VhostOps; - - int vhost_backend_update_device_iotlb(struct vhost_dev *dev, -diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h -index 65c6b49788..9b3f71b20f 100644 ---- a/linux-headers/linux/vhost.h -+++ b/linux-headers/linux/vhost.h -@@ -175,4 +175,21 @@ - #define VHOST_VDPA_SET_GROUP_ASID _IOW(VHOST_VIRTIO, 0x7C, \ - struct vhost_vring_state) - -+/* Suspend a device so it does not process virtqueue requests anymore -+ * -+ * After the return of ioctl the device must preserve all the necessary state -+ * (the virtqueue vring base plus the possible device specific states) that is -+ * required for restoring in the future. The device must not change its -+ * configuration after that point. -+ */ -+#define VHOST_VDPA_SUSPEND _IO(VHOST_VIRTIO, 0x7D) -+ -+/* Resume a device so it can resume processing virtqueue requests -+ * -+ * After the return of this ioctl the device will have restored all the -+ * necessary states and it is fully operational to continue processing the -+ * virtqueue descriptors. -+ */ -+#define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E) -+ - #endif --- -2.27.0 - diff --git a/vhost-add-vhost_svq_poll.patch b/vhost-add-vhost_svq_poll.patch deleted file mode 100644 index 90b430ab1149edec4c8bcc543bc454876839d8a2..0000000000000000000000000000000000000000 --- a/vhost-add-vhost_svq_poll.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 65869116f29f0c92a394af2308c154c855938923 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:38 +0200 -Subject: [PATCH] vhost: add vhost_svq_poll -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It allows the Shadow Control VirtQueue to wait for the device to use the -available buffers. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 27 +++++++++++++++++++++++++++ - hw/virtio/vhost-shadow-virtqueue.h | 1 + - 2 files changed, 28 insertions(+) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 5a85365478..d2676b94e0 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -484,6 +484,33 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq, - } while (!vhost_svq_enable_notification(svq)); - } - -+/** -+ * Poll the SVQ for one device used buffer. -+ * -+ * This function race with main event loop SVQ polling, so extra -+ * synchronization is needed. -+ * -+ * Return the length written by the device. -+ */ -+size_t vhost_svq_poll(VhostShadowVirtqueue *svq) -+{ -+ int64_t start_us = g_get_monotonic_time(); -+ do { -+ uint32_t len; -+ VirtQueueElement *elem = vhost_svq_get_buf(svq, &len); -+ if (elem) { -+ return len; -+ } -+ -+ if (unlikely(g_get_monotonic_time() - start_us > 10e6)) { -+ return 0; -+ } -+ -+ /* Make sure we read new used_idx */ -+ smp_rmb(); -+ } while (true); -+} -+ - /** - * Forward used buffers. - * -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index dd78f4bec2..cf442f7dea 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -89,6 +89,7 @@ void vhost_svq_push_elem(VhostShadowVirtqueue *svq, - int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, - size_t out_num, const struct iovec *in_sg, size_t in_num, - VirtQueueElement *elem); -+size_t vhost_svq_poll(VhostShadowVirtqueue *svq); - - void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); - void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd); --- -2.27.0 - diff --git a/vhost-add-vhost_svq_push_elem.patch b/vhost-add-vhost_svq_push_elem.patch deleted file mode 100644 index 395d975ad4eb6374397347f9c516609789e325b1..0000000000000000000000000000000000000000 --- a/vhost-add-vhost_svq_push_elem.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ac243c5186493f41c9ff0d60558dabb651c56983 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:36 +0200 -Subject: [PATCH] vhost: add vhost_svq_push_elem -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This function allows external SVQ users to return guest's available -buffers. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 16 ++++++++++++++++ - hw/virtio/vhost-shadow-virtqueue.h | 3 +++ - 2 files changed, 19 insertions(+) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index c10c74b91f..3b5d3bd3f3 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -427,6 +427,22 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, - return g_steal_pointer(&svq->desc_state[used_elem.id].elem); - } - -+/** -+ * Push an element to SVQ, returning it to the guest. -+ */ -+void vhost_svq_push_elem(VhostShadowVirtqueue *svq, -+ const VirtQueueElement *elem, uint32_t len) -+{ -+ virtqueue_push(svq->vq, elem, len); -+ if (svq->next_guest_avail_elem) { -+ /* -+ * Avail ring was full when vhost_svq_flush was called, so it's a -+ * good moment to make more descriptors available if possible. -+ */ -+ vhost_handle_guest_kick(svq); -+ } -+} -+ - static void vhost_svq_flush(VhostShadowVirtqueue *svq, - bool check_for_avail_queue) - { -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index 5c7e7cbab6..d9fc1f1799 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -84,6 +84,9 @@ typedef struct VhostShadowVirtqueue { - - bool vhost_svq_valid_features(uint64_t features, Error **errp); - -+void vhost_svq_push_elem(VhostShadowVirtqueue *svq, -+ const VirtQueueElement *elem, uint32_t len); -+ - void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); - void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd); - void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, --- -2.27.0 - diff --git a/vhost-allocate-SVQ-device-file-descriptors-at-device.patch b/vhost-allocate-SVQ-device-file-descriptors-at-device.patch deleted file mode 100644 index 5b85e7293d8d67c988d0cc86426ceb84d8fb9df8..0000000000000000000000000000000000000000 --- a/vhost-allocate-SVQ-device-file-descriptors-at-device.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 539c46ecb41417007840c750d364b5332cbdc5b5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:35 +0100 -Subject: [PATCH] vhost: allocate SVQ device file descriptors at device start -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The next patches will start control SVQ if possible. However, we don't -know if that will be possible at qemu boot anymore. - -Delay device file descriptors until we know it at device start. This -will avoid to create them if the device does not support SVQ. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-4-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 31 ++------------------------ - hw/virtio/vhost-vdpa.c | 35 ++++++++++++++++++++++++------ - 2 files changed, 30 insertions(+), 36 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index bc12bb42f3..47e831667c 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -692,43 +692,18 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq) - * @iova_tree: Tree to perform descriptors translations - * @ops: SVQ owner callbacks - * @ops_opaque: ops opaque pointer -- * -- * Returns the new virtqueue or NULL. -- * -- * In case of error, reason is reported through error_report. - */ - VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree, - const VhostShadowVirtqueueOps *ops, - void *ops_opaque) - { -- g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1); -- int r; -- -- r = event_notifier_init(&svq->hdev_kick, 0); -- if (r != 0) { -- error_report("Couldn't create kick event notifier: %s (%d)", -- g_strerror(errno), errno); -- goto err_init_hdev_kick; -- } -- -- r = event_notifier_init(&svq->hdev_call, 0); -- if (r != 0) { -- error_report("Couldn't create call event notifier: %s (%d)", -- g_strerror(errno), errno); -- goto err_init_hdev_call; -- } -+ VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1); - - event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND); - svq->iova_tree = iova_tree; - svq->ops = ops; - svq->ops_opaque = ops_opaque; -- return g_steal_pointer(&svq); -- --err_init_hdev_call: -- event_notifier_cleanup(&svq->hdev_kick); -- --err_init_hdev_kick: -- return NULL; -+ return svq; - } - - /** -@@ -740,7 +715,5 @@ void vhost_svq_free(gpointer pvq) - { - VhostShadowVirtqueue *vq = pvq; - vhost_svq_stop(vq); -- event_notifier_cleanup(&vq->hdev_kick); -- event_notifier_cleanup(&vq->hdev_call); - g_free(vq); - } -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 08f92bf781..23e715b05c 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -430,15 +430,11 @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v, - - shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free); - for (unsigned n = 0; n < hdev->nvqs; ++n) { -- g_autoptr(VhostShadowVirtqueue) svq; -+ VhostShadowVirtqueue *svq; - - svq = vhost_svq_new(v->iova_tree, v->shadow_vq_ops, - v->shadow_vq_ops_opaque); -- if (unlikely(!svq)) { -- error_setg(errp, "Cannot create svq %u", n); -- return -1; -- } -- g_ptr_array_add(shadow_vqs, g_steal_pointer(&svq)); -+ g_ptr_array_add(shadow_vqs, svq); - } - - v->shadow_vqs = g_steal_pointer(&shadow_vqs); -@@ -866,11 +862,23 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, - const EventNotifier *event_notifier = &svq->hdev_kick; - int r; - -+ r = event_notifier_init(&svq->hdev_kick, 0); -+ if (r != 0) { -+ error_setg_errno(errp, -r, "Couldn't create kick event notifier"); -+ goto err_init_hdev_kick; -+ } -+ -+ r = event_notifier_init(&svq->hdev_call, 0); -+ if (r != 0) { -+ error_setg_errno(errp, -r, "Couldn't create call event notifier"); -+ goto err_init_hdev_call; -+ } -+ - file.fd = event_notifier_get_fd(event_notifier); - r = vhost_vdpa_set_vring_dev_kick(dev, &file); - if (unlikely(r != 0)) { - error_setg_errno(errp, -r, "Can't set device kick fd"); -- return r; -+ goto err_init_set_dev_fd; - } - - event_notifier = &svq->hdev_call; -@@ -878,8 +886,18 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, - r = vhost_vdpa_set_vring_dev_call(dev, &file); - if (unlikely(r != 0)) { - error_setg_errno(errp, -r, "Can't set device call fd"); -+ goto err_init_set_dev_fd; - } - -+ return 0; -+ -+err_init_set_dev_fd: -+ event_notifier_set_handler(&svq->hdev_call, NULL); -+ -+err_init_hdev_call: -+ event_notifier_cleanup(&svq->hdev_kick); -+ -+err_init_hdev_kick: - return r; - } - -@@ -1091,6 +1109,9 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev) - for (unsigned i = 0; i < v->shadow_vqs->len; ++i) { - VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); - vhost_vdpa_svq_unmap_rings(dev, svq); -+ -+ event_notifier_cleanup(&svq->hdev_kick); -+ event_notifier_cleanup(&svq->hdev_call); - } - } - --- -2.27.0 - diff --git a/vhost-also-check-queue-state-in-the-vhost_dev_set_lo.patch b/vhost-also-check-queue-state-in-the-vhost_dev_set_lo.patch deleted file mode 100644 index 4299b2662d393d56a577c6a19ae9848febe31a5d..0000000000000000000000000000000000000000 --- a/vhost-also-check-queue-state-in-the-vhost_dev_set_lo.patch +++ /dev/null @@ -1,39 +0,0 @@ -From cb16f58f6db98113f9079b27e7e313c91060e6e4 Mon Sep 17 00:00:00 2001 -From: Ni Xun -Date: Thu, 9 Jun 2022 21:10:12 +0800 -Subject: [PATCH 3/5] vhost: also check queue state in the vhost_dev_set_log - error routine - -When check queue state in the vhost_dev_set_log routine, it miss the error -routine check, this patch also check queue state in error case. - -Fixes: 1e5a050f5798 ("check queue state in the vhost_dev_set_log routine") -Signed-off-by: Ni Xun -Reviewed-by: Zhigang Lu -Message-Id: -Reviewed-by: Michael S. Tsirkin -Acked-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: zhangxinhao ---- - hw/virtio/vhost.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 4c4072951c..3ac6cfde03 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -900,6 +900,10 @@ static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) - err_vq: - for (; i >= 0; --i) { - idx = dev->vhost_ops->vhost_get_vq_index(dev, dev->vq_index + i); -+ addr = virtio_queue_get_desc_addr(dev->vdev, idx); -+ if (!addr) { -+ continue; -+ } - vhost_virtqueue_set_addr(dev, dev->vqs + i, idx, - dev->log_enabled); - } --- -2.27.0 - diff --git a/vhost-cancel-migration-when-vhost-user-restarted-dur.patch b/vhost-cancel-migration-when-vhost-user-restarted-dur.patch deleted file mode 100644 index d34d1249ceb70069cd9881bf14765044dc97b3a0..0000000000000000000000000000000000000000 --- a/vhost-cancel-migration-when-vhost-user-restarted-dur.patch +++ /dev/null @@ -1,60 +0,0 @@ -From d41206e959717f68a31da4a2d875d33035baeb9f Mon Sep 17 00:00:00 2001 -From: Chuan Zheng -Date: Mon, 29 Jul 2019 16:22:12 +0800 -Subject: [PATCH 08/14] vhost: cancel migration when vhost-user restarted - during migraiton - -Qemu will abort when vhost-user process is restarted during migration -when vhost_log_global_start/stop is called. The reason is clear that -vhost_dev_set_log returns -1 because network connection is temporarily -lost. Let's cancel migraiton and report it to user in this abnormal -situation. - -Signed-off-by: Ying Fang -Reviewed-by: Gonglei ---- - hw/virtio/vhost.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 437347ad01..dafb23c481 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -25,6 +25,7 @@ - #include "hw/virtio/virtio-access.h" - #include "migration/blocker.h" - #include "migration/qemu-file-types.h" -+#include "migration/migration.h" - #include "sysemu/dma.h" - #include "sysemu/tcg.h" - #include "trace.h" -@@ -947,20 +948,24 @@ check_dev_state: - static void vhost_log_global_start(MemoryListener *listener) - { - int r; -+ Error *errp = NULL; - - r = vhost_migration_log(listener, true); - if (r < 0) { -- abort(); -+ error_setg(&errp, "Failed to start vhost migration log"); -+ migrate_fd_error(migrate_get_current(), errp); - } - } - - static void vhost_log_global_stop(MemoryListener *listener) - { - int r; -+ Error *errp = NULL; - - r = vhost_migration_log(listener, false); - if (r < 0) { -- abort(); -+ error_setg(&errp, "Failed to stop vhost migration log"); -+ migrate_fd_error(migrate_get_current(), errp); - } - } - --- -2.27.0 - diff --git a/vhost-enable-vrings-in-vhost_dev_start-for-vhost-use.patch b/vhost-enable-vrings-in-vhost_dev_start-for-vhost-use.patch deleted file mode 100644 index 51fdba4323e66287ce1408fb04885362903eb43f..0000000000000000000000000000000000000000 --- a/vhost-enable-vrings-in-vhost_dev_start-for-vhost-use.patch +++ /dev/null @@ -1,453 +0,0 @@ -From f0586baaa57c4042135b6d8f4d940da8a99e3737 Mon Sep 17 00:00:00 2001 -From: Stefano Garzarella -Date: Wed, 30 Nov 2022 11:24:36 +0000 -Subject: [PATCH] vhost: enable vrings in vhost_dev_start() for vhost-user - devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 02b61f38d3 ("hw/virtio: incorporate backend features in features") -properly negotiates VHOST_USER_F_PROTOCOL_FEATURES with the vhost-user -backend, but we forgot to enable vrings as specified in -docs/interop/vhost-user.rst: - - If ``VHOST_USER_F_PROTOCOL_FEATURES`` has not been negotiated, the - ring starts directly in the enabled state. - - If ``VHOST_USER_F_PROTOCOL_FEATURES`` has been negotiated, the ring is - initialized in a disabled state and is enabled by - ``VHOST_USER_SET_VRING_ENABLE`` with parameter 1. - -Some vhost-user front-ends already did this by calling -vhost_ops.vhost_set_vring_enable() directly: -- backends/cryptodev-vhost.c -- hw/net/virtio-net.c -- hw/virtio/vhost-user-gpio.c - -But most didn't do that, so we would leave the vrings disabled and some -backends would not work. We observed this issue with the rust version of -virtiofsd [1], which uses the event loop [2] provided by the -vhost-user-backend crate where requests are not processed if vring is -not enabled. - -Let's fix this issue by enabling the vrings in vhost_dev_start() for -vhost-user front-ends that don't already do this directly. Same thing -also in vhost_dev_stop() where we disable vrings. - -[1] https://gitlab.com/virtio-fs/virtiofsd -[2] https://github.com/rust-vmm/vhost/blob/240fc2966/crates/vhost-user-backend/src/event_loop.rs#L217 - -Fixes: 02b61f38d3 ("hw/virtio: incorporate backend features in features") -Reported-by: German Maglione -Tested-by: German Maglione -Signed-off-by: Stefano Garzarella -Acked-by: Raphael Norwitz -Message-Id: <20221123131630.52020-1-sgarzare@redhat.com> -Signed-off-by: Alex Bennée -Reviewed-by: Michael S. Tsirkin -Message-Id: <20221130112439.2527228-3-alex.bennee@linaro.org> -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - backends/cryptodev-vhost.c | 4 ++-- - backends/vhost-user.c | 4 ++-- - hw/block/vhost-user-blk.c | 4 ++-- - hw/net/vhost_net.c | 6 ++--- - hw/scsi/vhost-scsi-common.c | 4 ++-- - hw/virtio/trace-events | 4 ++-- - hw/virtio/vdpa-dev.c | 4 ++-- - hw/virtio/vhost-user-fs.c | 4 ++-- - hw/virtio/vhost-user-i2c.c | 4 ++-- - hw/virtio/vhost-user-rng.c | 4 ++-- - hw/virtio/vhost-vsock-common.c | 4 ++-- - hw/virtio/vhost.c | 44 ++++++++++++++++++++++++++++++---- - include/hw/virtio/vhost.h | 9 +++++-- - 13 files changed, 69 insertions(+), 30 deletions(-) - -diff --git a/backends/cryptodev-vhost.c b/backends/cryptodev-vhost.c -index bc13e466b4..572f87b3be 100644 ---- a/backends/cryptodev-vhost.c -+++ b/backends/cryptodev-vhost.c -@@ -94,7 +94,7 @@ cryptodev_vhost_start_one(CryptoDevBackendVhost *crypto, - goto fail_notifiers; - } - -- r = vhost_dev_start(&crypto->dev, dev); -+ r = vhost_dev_start(&crypto->dev, dev, false); - if (r < 0) { - goto fail_start; - } -@@ -111,7 +111,7 @@ static void - cryptodev_vhost_stop_one(CryptoDevBackendVhost *crypto, - VirtIODevice *dev) - { -- vhost_dev_stop(&crypto->dev, dev); -+ vhost_dev_stop(&crypto->dev, dev, false); - vhost_dev_disable_notifiers(&crypto->dev, dev); - } - -diff --git a/backends/vhost-user.c b/backends/vhost-user.c -index 10b39992d2..6632e2fe6f 100644 ---- a/backends/vhost-user.c -+++ b/backends/vhost-user.c -@@ -85,7 +85,7 @@ vhost_user_backend_start(VhostUserBackend *b) - } - - b->dev.acked_features = b->vdev->guest_features; -- ret = vhost_dev_start(&b->dev, b->vdev); -+ ret = vhost_dev_start(&b->dev, b->vdev, true); - if (ret < 0) { - error_report("Error start vhost dev"); - goto err_guest_notifiers; -@@ -120,7 +120,7 @@ vhost_user_backend_stop(VhostUserBackend *b) - return; - } - -- vhost_dev_stop(&b->dev, b->vdev); -+ vhost_dev_stop(&b->dev, b->vdev, true); - - if (k->set_guest_notifiers) { - ret = k->set_guest_notifiers(qbus->parent, -diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c -index 9bf18434c2..eddc5588fa 100644 ---- a/hw/block/vhost-user-blk.c -+++ b/hw/block/vhost-user-blk.c -@@ -167,7 +167,7 @@ static int vhost_user_blk_start(VirtIODevice *vdev, Error **errp) - goto err_guest_notifiers; - } - -- ret = vhost_dev_start(&s->dev, vdev); -+ ret = vhost_dev_start(&s->dev, vdev, true); - if (ret < 0) { - error_setg_errno(errp, -ret, "Error starting vhost"); - goto err_guest_notifiers; -@@ -207,7 +207,7 @@ static void vhost_user_blk_stop(VirtIODevice *vdev) - return; - } - -- vhost_dev_stop(&s->dev, vdev); -+ vhost_dev_stop(&s->dev, vdev, true); - - ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); - if (ret < 0) { -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index f709c060b6..c950d7e2e8 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -319,7 +319,7 @@ static int vhost_net_start_one(struct vhost_net *net, - goto fail_notifiers; - } - -- r = vhost_dev_start(&net->dev, dev); -+ r = vhost_dev_start(&net->dev, dev, false); - if (r < 0) { - goto fail_start; - } -@@ -368,7 +368,7 @@ fail: - if (net->nc->info->poll) { - net->nc->info->poll(net->nc, true); - } -- vhost_dev_stop(&net->dev, dev); -+ vhost_dev_stop(&net->dev, dev, false); - fail_start: - vhost_dev_disable_notifiers(&net->dev, dev); - fail_notifiers: -@@ -389,7 +389,7 @@ static void vhost_net_stop_one(struct vhost_net *net, - if (net->nc->info->poll) { - net->nc->info->poll(net->nc, true); - } -- vhost_dev_stop(&net->dev, dev); -+ vhost_dev_stop(&net->dev, dev, false); - if (net->nc->info->stop) { - net->nc->info->stop(net->nc); - } -diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c -index 767f827e55..18ea5dcfa1 100644 ---- a/hw/scsi/vhost-scsi-common.c -+++ b/hw/scsi/vhost-scsi-common.c -@@ -68,7 +68,7 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc) - goto err_guest_notifiers; - } - -- ret = vhost_dev_start(&vsc->dev, vdev); -+ ret = vhost_dev_start(&vsc->dev, vdev, true); - if (ret < 0) { - error_report("Error start vhost dev"); - goto err_guest_notifiers; -@@ -101,7 +101,7 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc) - VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); - int ret = 0; - -- vhost_dev_stop(&vsc->dev, vdev); -+ vhost_dev_stop(&vsc->dev, vdev, true); - - if (k->set_guest_notifiers) { - ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false); -diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events -index b8a33b2a83..35d4c00e59 100644 ---- a/hw/virtio/trace-events -+++ b/hw/virtio/trace-events -@@ -9,8 +9,8 @@ vhost_section(const char *name) "%s" - vhost_reject_section(const char *name, int d) "%s:%d" - vhost_iotlb_miss(void *dev, int step) "%p step %d" - vhost_dev_cleanup(void *dev) "%p" --vhost_dev_start(void *dev, const char *name) "%p:%s" --vhost_dev_stop(void *dev, const char *name) "%p:%s" -+vhost_dev_start(void *dev, const char *name, bool vrings) "%p:%s vrings:%d" -+vhost_dev_stop(void *dev, const char *name, bool vrings) "%p:%s vrings:%d" - - - # vhost-user.c -diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c -index 1840f0e450..465b08c0e3 100644 ---- a/hw/virtio/vdpa-dev.c -+++ b/hw/virtio/vdpa-dev.c -@@ -242,7 +242,7 @@ static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp) - - s->dev.acked_features = vdev->guest_features; - -- ret = vhost_dev_start(&s->dev, vdev); -+ ret = vhost_dev_start(&s->dev, vdev, false); - if (ret < 0) { - error_setg_errno(errp, -ret, "Error starting vhost"); - goto err_guest_notifiers; -@@ -283,7 +283,7 @@ static void vhost_vdpa_device_stop(VirtIODevice *vdev) - return; - } - -- vhost_dev_stop(&s->dev, vdev); -+ vhost_dev_stop(&s->dev, vdev, false); - - ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); - if (ret < 0) { -diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c -index 392b7d3aa1..c2739557f2 100644 ---- a/hw/virtio/vhost-user-fs.c -+++ b/hw/virtio/vhost-user-fs.c -@@ -74,7 +74,7 @@ static void vuf_start(VirtIODevice *vdev) - } - - fs->vhost_dev.acked_features = vdev->guest_features; -- ret = vhost_dev_start(&fs->vhost_dev, vdev); -+ ret = vhost_dev_start(&fs->vhost_dev, vdev, true); - if (ret < 0) { - error_report("Error starting vhost: %d", -ret); - goto err_guest_notifiers; -@@ -108,7 +108,7 @@ static void vuf_stop(VirtIODevice *vdev) - return; - } - -- vhost_dev_stop(&fs->vhost_dev, vdev); -+ vhost_dev_stop(&fs->vhost_dev, vdev, true); - - ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false); - if (ret < 0) { -diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c -index d172632bb0..dcaf471115 100644 ---- a/hw/virtio/vhost-user-i2c.c -+++ b/hw/virtio/vhost-user-i2c.c -@@ -45,7 +45,7 @@ static void vu_i2c_start(VirtIODevice *vdev) - - i2c->vhost_dev.acked_features = vdev->guest_features; - -- ret = vhost_dev_start(&i2c->vhost_dev, vdev); -+ ret = vhost_dev_start(&i2c->vhost_dev, vdev, true); - if (ret < 0) { - error_report("Error starting vhost-user-i2c: %d", -ret); - goto err_guest_notifiers; -@@ -79,7 +79,7 @@ static void vu_i2c_stop(VirtIODevice *vdev) - return; - } - -- vhost_dev_stop(&i2c->vhost_dev, vdev); -+ vhost_dev_stop(&i2c->vhost_dev, vdev, true); - - ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false); - if (ret < 0) { -diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c -index 543f3e3cef..f25b7cf624 100644 ---- a/hw/virtio/vhost-user-rng.c -+++ b/hw/virtio/vhost-user-rng.c -@@ -42,7 +42,7 @@ static void vu_rng_start(VirtIODevice *vdev) - } - - rng->vhost_dev.acked_features = vdev->guest_features; -- ret = vhost_dev_start(&rng->vhost_dev, vdev); -+ ret = vhost_dev_start(&rng->vhost_dev, vdev, true); - if (ret < 0) { - error_report("Error starting vhost-user-rng: %d", -ret); - goto err_guest_notifiers; -@@ -76,7 +76,7 @@ static void vu_rng_stop(VirtIODevice *vdev) - return; - } - -- vhost_dev_stop(&rng->vhost_dev, vdev); -+ vhost_dev_stop(&rng->vhost_dev, vdev, true); - - ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false); - if (ret < 0) { -diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c -index cd45aaf28e..42e4db4712 100644 ---- a/hw/virtio/vhost-vsock-common.c -+++ b/hw/virtio/vhost-vsock-common.c -@@ -68,7 +68,7 @@ int vhost_vsock_common_start(VirtIODevice *vdev) - } - - vvc->vhost_dev.acked_features = vdev->guest_features; -- ret = vhost_dev_start(&vvc->vhost_dev, vdev); -+ ret = vhost_dev_start(&vvc->vhost_dev, vdev, true); - if (ret < 0) { - error_report("Error starting vhost: %d", -ret); - goto err_guest_notifiers; -@@ -103,7 +103,7 @@ void vhost_vsock_common_stop(VirtIODevice *vdev) - return; - } - -- vhost_dev_stop(&vvc->vhost_dev, vdev); -+ vhost_dev_stop(&vvc->vhost_dev, vdev, true); - - ret = k->set_guest_notifiers(qbus->parent, vvc->vhost_dev.nvqs, false); - if (ret < 0) { -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 86c727d2ab..22ec9e1ef7 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -1760,15 +1760,36 @@ int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size, - return 0; - } - -+static int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable) -+{ -+ if (!hdev->vhost_ops->vhost_set_vring_enable) { -+ return 0; -+ } -+ -+ /* -+ * For vhost-user devices, if VHOST_USER_F_PROTOCOL_FEATURES has not -+ * been negotiated, the rings start directly in the enabled state, and -+ * .vhost_set_vring_enable callback will fail since -+ * VHOST_USER_SET_VRING_ENABLE is not supported. -+ */ -+ if (hdev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER && -+ !virtio_has_feature(hdev->backend_features, -+ VHOST_USER_F_PROTOCOL_FEATURES)) { -+ return 0; -+ } -+ -+ return hdev->vhost_ops->vhost_set_vring_enable(hdev, enable); -+} -+ - /* Host notifiers must be enabled at this point. */ --int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) -+int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - { - int i, r; - - /* should only be called after backend is connected */ - assert(hdev->vhost_ops); - -- trace_vhost_dev_start(hdev, vdev->name); -+ trace_vhost_dev_start(hdev, vdev->name, vrings); - - vdev->vhost_started = true; - hdev->started = true; -@@ -1813,10 +1834,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - goto fail_log; - } - } -+ if (vrings) { -+ r = vhost_dev_set_vring_enable(hdev, true); -+ if (r) { -+ goto fail_log; -+ } -+ } - if (hdev->vhost_ops->vhost_dev_start) { - r = hdev->vhost_ops->vhost_dev_start(hdev, true); - if (r) { -- goto fail_log; -+ goto fail_start; - } - } - if (vhost_dev_has_iommu(hdev) && -@@ -1831,6 +1858,10 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - } - } - return 0; -+fail_start: -+ if (vrings) { -+ vhost_dev_set_vring_enable(hdev, false); -+ } - fail_log: - vhost_log_put(hdev, false); - fail_vq: -@@ -1849,18 +1880,21 @@ fail_features: - } - - /* Host notifiers must be enabled at this point. */ --void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) -+void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - { - int i; - - /* should only be called after backend is connected */ - assert(hdev->vhost_ops); - -- trace_vhost_dev_stop(hdev, vdev->name); -+ trace_vhost_dev_stop(hdev, vdev->name, vrings); - - if (hdev->vhost_ops->vhost_dev_start) { - hdev->vhost_ops->vhost_dev_start(hdev, false); - } -+ if (vrings) { -+ vhost_dev_set_vring_enable(hdev, false); -+ } - for (i = 0; i < hdev->nvqs; ++i) { - vhost_virtqueue_stop(hdev, - vdev, -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index d7ab2579ff..662e0f4370 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -5,6 +5,9 @@ - #include "hw/virtio/virtio.h" - #include "exec/memory.h" - -+#define VHOST_F_DEVICE_IOTLB 63 -+#define VHOST_USER_F_PROTOCOL_FEATURES 30 -+ - /* Generic structures common for any vhost based device. */ - - struct vhost_inflight { -@@ -165,24 +168,26 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); - * vhost_dev_start() - start the vhost device - * @hdev: common vhost_dev structure - * @vdev: the VirtIODevice structure -+ * @vrings: true to have vrings enabled in this call - * - * Starts the vhost device. From this point VirtIO feature negotiation - * can start and the device can start processing VirtIO transactions. - * - * Return: 0 on success, < 0 on error. - */ --int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev); -+int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings); - - /** - * vhost_dev_stop() - stop the vhost device - * @hdev: common vhost_dev structure - * @vdev: the VirtIODevice structure -+ * @vrings: true to have vrings disabled in this call - * - * Stop the vhost device. After the device is stopped the notifiers - * can be disabled (@vhost_dev_disable_notifiers) and the device can - * be torn down (@vhost_dev_cleanup). - */ --void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev); -+void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings); - - /** - * DOC: vhost device configuration handling --- -2.27.0 - diff --git a/vhost-fix-null-pointer-access.patch b/vhost-fix-null-pointer-access.patch deleted file mode 100644 index 432e8a78babd183447b47c676fbfcc3988ae26b2..0000000000000000000000000000000000000000 --- a/vhost-fix-null-pointer-access.patch +++ /dev/null @@ -1,74 +0,0 @@ -From e2db610c0b0cb9130ba1ce2668a57318a416fdc4 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 14:48:18 +0800 -Subject: [PATCH] vhost: fix null pointer access - -Check vhost_get/set_used_memslots function before calling it. - -Signed-off-by: libai -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 59a12735f9..7930b37499 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -58,6 +58,10 @@ bool vhost_has_free_slot(void) - struct vhost_dev *hdev; - - QLIST_FOREACH(hdev, &vhost_devices, entry) { -+ if (!hdev->vhost_ops->vhost_get_used_memslots || -+ !hdev->vhost_ops->vhost_backend_memslots_limit) { -+ continue; -+ } - if (hdev->vhost_ops->vhost_get_used_memslots() >= - hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { - return false; -@@ -748,7 +752,9 @@ static void vhost_region_add_section(struct vhost_dev *dev, - dev->tmp_sections[dev->n_tmp_sections - 1].fv = NULL; - memory_region_ref(section->mr); - } -- dev->vhost_ops->vhost_set_used_memslots(dev); -+ if (dev->vhost_ops->vhost_set_used_memslots) { -+ dev->vhost_ops->vhost_set_used_memslots(dev); -+ } - } - - /* Used for both add and nop callbacks */ -@@ -772,7 +778,9 @@ static void vhost_region_del(MemoryListener *listener, - if (!vhost_section(dev, section)) { - return; - } -- dev->vhost_ops->vhost_set_used_memslots(dev); -+ if (dev->vhost_ops->vhost_set_used_memslots) { -+ dev->vhost_ops->vhost_set_used_memslots(dev); -+ } - } - - static void vhost_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) -@@ -1367,6 +1375,11 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq) - - static bool vhost_dev_used_memslots_is_exceeded(struct vhost_dev *hdev) - { -+ if (!hdev->vhost_ops->vhost_get_used_memslots || -+ !hdev->vhost_ops->vhost_backend_memslots_limit) { -+ goto out; -+ } -+ - if (hdev->vhost_ops->vhost_get_used_memslots() > - hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { - error_report("vhost backend memory slots limit is less" -@@ -1375,6 +1388,7 @@ static bool vhost_dev_used_memslots_is_exceeded(struct vhost_dev *hdev) - return true; - } - -+out: - used_memslots_exceeded = false; - return false; - } --- -2.27.0 - diff --git a/vhost-fix-possible-wrap-in-SVQ-descriptor-ring.patch b/vhost-fix-possible-wrap-in-SVQ-descriptor-ring.patch deleted file mode 100644 index a21d4be091bce3daa0fca77fdb2561bca92f0ac4..0000000000000000000000000000000000000000 --- a/vhost-fix-possible-wrap-in-SVQ-descriptor-ring.patch +++ /dev/null @@ -1,108 +0,0 @@ -From fdc4e7386f7fa5f0d47d6d7b582a01854073206e Mon Sep 17 00:00:00 2001 -From: Hawkins Jiawei -Date: Tue, 9 May 2023 16:48:17 +0800 -Subject: [PATCH] vhost: fix possible wrap in SVQ descriptor ring -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -QEMU invokes vhost_svq_add() when adding a guest's element -into SVQ. In vhost_svq_add(), it uses vhost_svq_available_slots() -to check whether QEMU can add the element into SVQ. If there is -enough space, then QEMU combines some out descriptors and some -in descriptors into one descriptor chain, and adds it into -`svq->vring.desc` by vhost_svq_vring_write_descs(). - -Yet the problem is that, `svq->shadow_avail_idx - svq->shadow_used_idx` -in vhost_svq_available_slots() returns the number of occupied elements, -or the number of descriptor chains, instead of the number of occupied -descriptors, which may cause wrapping in SVQ descriptor ring. - -Here is an example. In vhost_handle_guest_kick(), QEMU forwards -as many available buffers to device by virtqueue_pop() and -vhost_svq_add_element(). virtqueue_pop() returns a guest's element, -and then this element is added into SVQ by vhost_svq_add_element(), -a wrapper to vhost_svq_add(). If QEMU invokes virtqueue_pop() and -vhost_svq_add_element() `svq->vring.num` times, -vhost_svq_available_slots() thinks QEMU just ran out of slots and -everything should work fine. But in fact, virtqueue_pop() returns -`svq->vring.num` elements or descriptor chains, more than -`svq->vring.num` descriptors due to guest memory fragmentation, -and this causes wrapping in SVQ descriptor ring. - -This bug is valid even before marking the descriptors used. -If the guest memory is fragmented, SVQ must add chains -so it can try to add more descriptors than possible. - -This patch solves it by adding `num_free` field in -VhostShadowVirtqueue structure and updating this field -in vhost_svq_add() and vhost_svq_get_buf(), to record -the number of free descriptors. - -Fixes: 100890f7ca ("vhost: Shadow virtqueue buffers forwarding") -Signed-off-by: Hawkins Jiawei -Acked-by: Eugenio Pérez -Message-Id: <20230509084817.3973-1-yin31149@gmail.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Tested-by: Lei Yang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 5 ++++- - hw/virtio/vhost-shadow-virtqueue.h | 3 +++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 7d6afcb528..8d99edb196 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -66,7 +66,7 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp) - */ - static uint16_t vhost_svq_available_slots(const VhostShadowVirtqueue *svq) - { -- return svq->vring.num - (svq->shadow_avail_idx - svq->shadow_used_idx); -+ return svq->num_free; - } - - /** -@@ -255,6 +255,7 @@ int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, - return -EINVAL; - } - -+ svq->num_free -= ndescs; - svq->desc_state[qemu_head].elem = elem; - svq->desc_state[qemu_head].ndescs = ndescs; - vhost_svq_kick(svq); -@@ -426,6 +427,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, - last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id); - svq->desc_next[last_used_chain] = svq->free_head; - svq->free_head = used_elem.id; -+ svq->num_free += num; - - *len = used_elem.len; - return g_steal_pointer(&svq->desc_state[used_elem.id].elem); -@@ -636,6 +638,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, - svq->iova_tree = iova_tree; - - svq->vring.num = virtio_queue_get_num(vdev, virtio_get_queue_index(vq)); -+ svq->num_free = svq->vring.num; - driver_size = vhost_svq_driver_area_size(svq); - device_size = vhost_svq_device_area_size(svq); - svq->vring.desc = qemu_memalign(qemu_real_host_page_size, driver_size); -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index 926a4897b1..6efe051a70 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -107,6 +107,9 @@ typedef struct VhostShadowVirtqueue { - - /* Next head to consume from the device */ - uint16_t last_used_idx; -+ -+ /* Size of SVQ vring free descriptors */ -+ uint16_t num_free; - } VhostShadowVirtqueue; - - bool vhost_svq_valid_features(uint64_t features, Error **errp); --- -2.27.0 - diff --git a/vhost-fix-the-fd-leak.patch b/vhost-fix-the-fd-leak.patch deleted file mode 100644 index 2ccc1833d9488fc8a86a301efa79fa79cae4e355..0000000000000000000000000000000000000000 --- a/vhost-fix-the-fd-leak.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 2fb147eb0189ee24a74ebf784b9a682667288d3d Mon Sep 17 00:00:00 2001 -From: Li Feng -Date: Mon, 31 Jul 2023 20:10:06 +0800 -Subject: [PATCH] vhost: fix the fd leak - -When the vhost-user reconnect to the backend, the notifer should be -cleanup. Otherwise, the fd resource will be exhausted. - -Fixes: f9a09ca3ea ("vhost: add support for configure interrupt") - -Signed-off-by: Li Feng -Reviewed-by: Raphael Norwitz -Message-Id: <20230731121018.2856310-2-fengli@smartx.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Tested-by: Fiona Ebner -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 490c97424b..63ddcb3e6d 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -2009,6 +2009,8 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - event_notifier_test_and_clear( - &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); - event_notifier_test_and_clear(&vdev->config_notifier); -+ event_notifier_cleanup( -+ &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); - - trace_vhost_dev_stop(hdev, vdev->name, vrings); - --- -2.27.0 - diff --git a/vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch b/vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch deleted file mode 100644 index 9854a13c6a4c46a5c9f61daea7f0ee6be3ecc097..0000000000000000000000000000000000000000 --- a/vhost-fix-vq-dirty-bitmap-syncing-when-vIOMMU-is-ena.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 1f8330f9b4cba6ce8d88d227aeae4849c0062cf0 Mon Sep 17 00:00:00 2001 -From: Jason Wang -Date: Fri, 16 Dec 2022 11:35:52 +0800 -Subject: [PATCH] vhost: fix vq dirty bitmap syncing when vIOMMU is enabled - -When vIOMMU is enabled, the vq->used_phys is actually the IOVA not -GPA. So we need to translate it to GPA before the syncing otherwise we -may hit the following crash since IOVA could be out of the scope of -the GPA log size. This could be noted when using virtio-IOMMU with -vhost using 1G memory. - -Fixes: c471ad0e9bd46 ("vhost_net: device IOTLB support") -Cc: qemu-stable@nongnu.org -Tested-by: Lei Yang -Reported-by: Yalan Zhang -Signed-off-by: Jason Wang -Message-Id: <20221216033552.77087-1-jasowang@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 84 ++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 64 insertions(+), 20 deletions(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 8e8657fb0d..19ea9aef69 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -20,6 +20,7 @@ - #include "qemu/range.h" - #include "qemu/error-report.h" - #include "qemu/memfd.h" -+#include "qemu/log.h" - #include "standard-headers/linux/vhost_types.h" - #include "hw/virtio/virtio-bus.h" - #include "hw/virtio/virtio-access.h" -@@ -110,6 +111,24 @@ static void vhost_dev_sync_region(struct vhost_dev *dev, - } - } - -+static bool vhost_dev_has_iommu(struct vhost_dev *dev) -+{ -+ VirtIODevice *vdev = dev->vdev; -+ -+ /* -+ * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support -+ * incremental memory mapping API via IOTLB API. For platform that -+ * does not have IOMMU, there's no need to enable this feature -+ * which may cause unnecessary IOTLB miss/update transactions. -+ */ -+ if (vdev) { -+ return virtio_bus_device_iommu_enabled(vdev) && -+ virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); -+ } else { -+ return false; -+ } -+} -+ - static int vhost_sync_dirty_bitmap(struct vhost_dev *dev, - MemoryRegionSection *section, - hwaddr first, -@@ -141,8 +160,51 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev, - continue; - } - -- vhost_dev_sync_region(dev, section, start_addr, end_addr, vq->used_phys, -- range_get_last(vq->used_phys, vq->used_size)); -+ if (vhost_dev_has_iommu(dev)) { -+ IOMMUTLBEntry iotlb; -+ hwaddr used_phys = vq->used_phys, used_size = vq->used_size; -+ hwaddr phys, s, offset; -+ -+ while (used_size) { -+ rcu_read_lock(); -+ iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as, -+ used_phys, -+ true, -+ MEMTXATTRS_UNSPECIFIED); -+ rcu_read_unlock(); -+ -+ if (!iotlb.target_as) { -+ qemu_log_mask(LOG_GUEST_ERROR, "translation " -+ "failure for used_iova %"PRIx64"\n", -+ used_phys); -+ return -EINVAL; -+ } -+ -+ offset = used_phys & iotlb.addr_mask; -+ phys = iotlb.translated_addr + offset; -+ -+ /* -+ * Distance from start of used ring until last byte of -+ * IOMMU page. -+ */ -+ s = iotlb.addr_mask - offset; -+ /* -+ * Size of used ring, or of the part of it until end -+ * of IOMMU page. To avoid zero result, do the adding -+ * outside of MIN(). -+ */ -+ s = MIN(s, used_size - 1) + 1; -+ -+ vhost_dev_sync_region(dev, section, start_addr, end_addr, phys, -+ range_get_last(phys, s)); -+ used_size -= s; -+ used_phys += s; -+ } -+ } else { -+ vhost_dev_sync_region(dev, section, start_addr, -+ end_addr, vq->used_phys, -+ range_get_last(vq->used_phys, vq->used_size)); -+ } - } - return 0; - } -@@ -310,24 +372,6 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size) - dev->log_size = size; - } - --static bool vhost_dev_has_iommu(struct vhost_dev *dev) --{ -- VirtIODevice *vdev = dev->vdev; -- -- /* -- * For vhost, VIRTIO_F_IOMMU_PLATFORM means the backend support -- * incremental memory mapping API via IOTLB API. For platform that -- * does not have IOMMU, there's no need to enable this feature -- * which may cause unnecessary IOTLB miss/update transactions. -- */ -- if (vdev) { -- return virtio_bus_device_iommu_enabled(vdev) && -- virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM); -- } else { -- return false; -- } --} -- - static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr, - hwaddr *plen, bool is_write) - { --- -2.27.0 - diff --git a/vhost-implement-migration-state-notifier-for-vdpa-de.patch b/vhost-implement-migration-state-notifier-for-vdpa-de.patch deleted file mode 100644 index 246961427a2f65208c2bd25d1b3531f226484c65..0000000000000000000000000000000000000000 --- a/vhost-implement-migration-state-notifier-for-vdpa-de.patch +++ /dev/null @@ -1,78 +0,0 @@ -From ce5fa02db01263ef5188b3bb3a1367c806ddb7ce Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:55:53 +0800 -Subject: [PATCH] vhost: implement migration state notifier for vdpa device - -Signed-off-by: libai -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vdpa-dev-mig.c | 28 ++++++++++++++++++++++++++++ - include/hw/virtio/vdpa-dev.h | 1 + - 2 files changed, 29 insertions(+) - -diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c -index c0bcbda7d4..a36517b147 100644 ---- a/hw/virtio/vdpa-dev-mig.c -+++ b/hw/virtio/vdpa-dev-mig.c -@@ -344,6 +344,31 @@ static SaveVMHandlers savevm_vdpa_handlers = { - .load_setup = vdpa_load_setup, - }; - -+static void vdpa_migration_state_notifier(Notifier *notifier, void *data) -+{ -+ MigrationState *s = data; -+ VhostVdpaDevice *vdev = container_of(notifier, -+ VhostVdpaDevice, -+ migration_state); -+ struct vhost_dev *hdev = &vdev->dev; -+ int ret; -+ -+ switch (s->state) { -+ case MIGRATION_STATUS_CANCELLING: -+ case MIGRATION_STATUS_CANCELLED: -+ case MIGRATION_STATUS_FAILED: -+ ret = vhost_vdpa_set_mig_state(hdev, VDPA_DEVICE_CANCEL); -+ if (ret) { -+ error_report("Failed to set state CANCEL\n"); -+ } -+ -+ break; -+ case MIGRATION_STATUS_COMPLETED: -+ default: -+ break; -+ } -+} -+ - void vdpa_migration_register(VhostVdpaDevice *vdev) - { - vdev->vmstate = qdev_add_vm_change_state_handler(DEVICE(vdev), -@@ -351,10 +376,13 @@ void vdpa_migration_register(VhostVdpaDevice *vdev) - DEVICE(vdev)); - register_savevm_live("vdpa", -1, 1, - &savevm_vdpa_handlers, DEVICE(vdev)); -+ vdev->migration_state.notify = vdpa_migration_state_notifier; -+ add_migration_state_change_notifier(&vdev->migration_state); - } - - void vdpa_migration_unregister(VhostVdpaDevice *vdev) - { -+ remove_migration_state_change_notifier(&vdev->migration_state); - unregister_savevm(VMSTATE_IF(&vdev->parent_obj.parent_obj), "vdpa", DEVICE(vdev)); - qemu_del_vm_change_state_handler(vdev->vmstate); - } -diff --git a/include/hw/virtio/vdpa-dev.h b/include/hw/virtio/vdpa-dev.h -index 43cbcef81b..20f50c76c6 100644 ---- a/include/hw/virtio/vdpa-dev.h -+++ b/include/hw/virtio/vdpa-dev.h -@@ -39,6 +39,7 @@ struct VhostVdpaDevice { - bool started; - int (*post_init)(VhostVdpaDevice *v, Error **errp); - VMChangeStateEntry *vmstate; -+ Notifier migration_state; - }; - - #endif --- -2.27.0 - diff --git a/vhost-implement-post-resume-bh.patch b/vhost-implement-post-resume-bh.patch deleted file mode 100644 index b16606d7c30046a97dddba1bd47c86bf04bfcfbd..0000000000000000000000000000000000000000 --- a/vhost-implement-post-resume-bh.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 07fc3e07d6160508f7e6543e2fc49668607f79ad Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:57:35 +0800 -Subject: [PATCH] vhost: implement post resume bh - -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vdpa-dev-mig.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c -index a36517b147..ee3e27f2bb 100644 ---- a/hw/virtio/vdpa-dev-mig.c -+++ b/hw/virtio/vdpa-dev-mig.c -@@ -33,6 +33,7 @@ - #include "qemu/error-report.h" - #include "hw/virtio/vdpa-dev-mig.h" - #include "migration/qemu-file-types.h" -+#include "qemu/main-loop.h" - - /* - * Flags used as delimiter: -@@ -225,6 +226,18 @@ err_host_notifiers: - return ret; - } - -+static void vdpa_dev_migration_handle_incoming_bh(void *opaque) -+{ -+ struct vhost_dev *hdev = opaque; -+ int ret; -+ -+ /* Post start device, unsupport rollback if failed! */ -+ ret = vhost_vdpa_set_mig_state(hdev, VDPA_DEVICE_POST_START); -+ if (ret) { -+ error_report("Failed to set state: POST_START\n"); -+ } -+} -+ - static void vdpa_dev_vmstate_change(void *opaque, bool running, RunState state) - { - VhostVdpaDevice *vdpa = VHOST_VDPA_DEVICE(opaque); -@@ -254,6 +267,10 @@ static void vdpa_dev_vmstate_change(void *opaque, bool running, RunState state) - - if (mis->state == RUN_STATE_RESTORE_VM) { - vhost_vdpa_call(hdev, VHOST_VDPA_RESUME, NULL); -+ /* post resume */ -+ mis->bh = qemu_bh_new(vdpa_dev_migration_handle_incoming_bh, -+ hdev); -+ qemu_bh_schedule(mis->bh); - } - } - } --- -2.27.0 - diff --git a/vhost-implement-savevm_hanlder-for-vdpa-device.patch b/vhost-implement-savevm_hanlder-for-vdpa-device.patch deleted file mode 100644 index 16cacc110077ed3c5c5652dd313f953d19875de7..0000000000000000000000000000000000000000 --- a/vhost-implement-savevm_hanlder-for-vdpa-device.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 9cd596fd081bdb88b03b5e969631d8d08797c14d Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:53:28 +0800 -Subject: [PATCH] vhost: implement savevm_hanlder for vdpa device - -Signed-off-by: libai -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vdpa-dev-mig.c | 174 +++++++++++++++++++++++++++++++ - include/hw/virtio/vdpa-dev-mig.h | 13 +++ - linux-headers/linux/vhost.h | 8 ++ - 3 files changed, 195 insertions(+) - -diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c -index 64c9e245d1..c0bcbda7d4 100644 ---- a/hw/virtio/vdpa-dev-mig.c -+++ b/hw/virtio/vdpa-dev-mig.c -@@ -32,6 +32,17 @@ - #include "sysemu/runstate.h" - #include "qemu/error-report.h" - #include "hw/virtio/vdpa-dev-mig.h" -+#include "migration/qemu-file-types.h" -+ -+/* -+ * Flags used as delimiter: -+ * 0xffffffff => MSB 32-bit all 1s -+ * 0xef10 => emulated (virtual) function IO -+ * 0x0000 => 16-bits reserved for flags -+ */ -+#define VDPA_MIG_FLAG_END_OF_STATE (0xffffffffef100001ULL) -+#define VDPA_MIG_FLAG_DEV_CONFIG_STATE (0xffffffffef100002ULL) -+#define VDPA_MIG_FLAG_DEV_SETUP_STATE (0xffffffffef100003ULL) - - static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request, - void *arg) -@@ -47,6 +58,80 @@ static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request, - return ioctl(fd, request, arg); - } - -+static int vhost_vdpa_set_mig_state(struct vhost_dev *dev, uint8_t state) -+{ -+ return vhost_vdpa_call(dev, VHOST_VDPA_SET_MIG_STATE, &state); -+} -+ -+static int vhost_vdpa_dev_buffer_size(struct vhost_dev *dev, uint32_t *size) -+{ -+ return vhost_vdpa_call(dev, VHOST_GET_DEV_BUFFER_SIZE, size); -+} -+ -+static int vhost_vdpa_dev_buffer_save(struct vhost_dev *dev, QEMUFile *f) -+{ -+ struct vhost_vdpa_config *config; -+ unsigned long config_size = offsetof(struct vhost_vdpa_config, buf); -+ uint32_t buffer_size = 0; -+ int ret; -+ -+ ret = vhost_vdpa_dev_buffer_size(dev, &buffer_size); -+ if (ret) { -+ error_report("get dev buffer size failed: %d\n", ret); -+ return ret; -+ } -+ -+ qemu_put_be32(f, buffer_size); -+ -+ config = g_malloc(buffer_size + config_size); -+ config->off = 0; -+ config->len = buffer_size; -+ -+ ret = vhost_vdpa_call(dev, VHOST_GET_DEV_BUFFER, config); -+ if (ret) { -+ error_report("get dev buffer failed: %d\n", ret); -+ goto free; -+ } -+ -+ qemu_put_buffer(f, config->buf, buffer_size); -+free: -+ g_free(config); -+ -+ return ret; -+} -+ -+static int vhost_vdpa_dev_buffer_load(struct vhost_dev *dev, QEMUFile *f) -+{ -+ struct vhost_vdpa_config *config; -+ unsigned long config_size = offsetof(struct vhost_vdpa_config, buf); -+ uint32_t buffer_size, recv_size; -+ int ret; -+ -+ buffer_size = qemu_get_be32(f); -+ -+ config = g_malloc(buffer_size + config_size); -+ config->off = 0; -+ config->len = buffer_size; -+ -+ recv_size = qemu_get_buffer(f, config->buf, buffer_size); -+ if (recv_size != buffer_size) { -+ error_report("read dev mig buffer failed, buffer_size: %u, " -+ "recv_size: %u\n", buffer_size, recv_size); -+ ret = -EINVAL; -+ goto free; -+ } -+ -+ ret = vhost_vdpa_call(dev, VHOST_SET_DEV_BUFFER, config); -+ if (ret) { -+ error_report("set dev buffer failed: %d\n", ret); -+ } -+ -+free: -+ g_free(config); -+ -+ return ret; -+} -+ - static int vhost_vdpa_device_suspend(VhostVdpaDevice *vdpa) - { - VirtIODevice *vdev = VIRTIO_DEVICE(vdpa); -@@ -173,14 +258,103 @@ static void vdpa_dev_vmstate_change(void *opaque, bool running, RunState state) - } - } - -+static int vdpa_save_setup(QEMUFile *f, void *opaque) -+{ -+ qemu_put_be64(f, VDPA_MIG_FLAG_DEV_SETUP_STATE); -+ qemu_put_be64(f, VDPA_MIG_FLAG_END_OF_STATE); -+ -+ return qemu_file_get_error(f); -+} -+ -+static int vdpa_save_complete_precopy(QEMUFile *f, void *opaque) -+{ -+ VhostVdpaDevice *vdev = VHOST_VDPA_DEVICE(opaque); -+ struct vhost_dev *hdev = &vdev->dev; -+ int ret; -+ -+ qemu_put_be64(f, VDPA_MIG_FLAG_DEV_CONFIG_STATE); -+ ret = vhost_vdpa_dev_buffer_save(hdev, f); -+ if (ret) { -+ error_report("Save vdpa device buffer failed: %d\n", ret); -+ return ret; -+ } -+ qemu_put_be64(f, VDPA_MIG_FLAG_END_OF_STATE); -+ -+ return qemu_file_get_error(f); -+} -+ -+static int vdpa_load_state(QEMUFile *f, void *opaque, int version_id) -+{ -+ VhostVdpaDevice *vdev = VHOST_VDPA_DEVICE(opaque); -+ struct vhost_dev *hdev = &vdev->dev; -+ -+ int ret; -+ uint64_t data; -+ -+ data = qemu_get_be64(f); -+ while (data != VDPA_MIG_FLAG_END_OF_STATE) { -+ if (data == VDPA_MIG_FLAG_DEV_SETUP_STATE) { -+ data = qemu_get_be64(f); -+ if (data == VDPA_MIG_FLAG_END_OF_STATE) { -+ return 0; -+ } else { -+ error_report("SETUP STATE: EOS not found 0x%lx\n", data); -+ return -EINVAL; -+ } -+ } else if (data == VDPA_MIG_FLAG_DEV_CONFIG_STATE) { -+ ret = vhost_vdpa_dev_buffer_load(hdev, f); -+ if (ret) { -+ error_report("fail to restore device buffer.\n"); -+ return ret; -+ } -+ } -+ -+ ret = qemu_file_get_error(f); -+ if (ret) { -+ error_report("qemu file error: %d\n", ret); -+ return ret; -+ } -+ data = qemu_get_be64(f); -+ } -+ -+ return 0; -+} -+ -+static int vdpa_load_setup(QEMUFile *f, void *opaque) -+{ -+ VhostVdpaDevice *v = VHOST_VDPA_DEVICE(opaque); -+ struct vhost_dev *hdev = &v->dev; -+ int ret = 0; -+ -+ ret = vhost_vdpa_set_mig_state(hdev, VDPA_DEVICE_PRE_START); -+ if (ret) { -+ error_report("pre start device failed: %d\n", ret); -+ goto out; -+ } -+ -+ return qemu_file_get_error(f); -+out: -+ return ret; -+} -+ -+static SaveVMHandlers savevm_vdpa_handlers = { -+ .save_setup = vdpa_save_setup, -+ .save_live_complete_precopy = vdpa_save_complete_precopy, -+ .load_state = vdpa_load_state, -+ .load_setup = vdpa_load_setup, -+}; -+ - void vdpa_migration_register(VhostVdpaDevice *vdev) - { - vdev->vmstate = qdev_add_vm_change_state_handler(DEVICE(vdev), - vdpa_dev_vmstate_change, - DEVICE(vdev)); -+ register_savevm_live("vdpa", -1, 1, -+ &savevm_vdpa_handlers, DEVICE(vdev)); - } - - void vdpa_migration_unregister(VhostVdpaDevice *vdev) - { -+ unregister_savevm(VMSTATE_IF(&vdev->parent_obj.parent_obj), "vdpa", DEVICE(vdev)); - qemu_del_vm_change_state_handler(vdev->vmstate); - } -diff --git a/include/hw/virtio/vdpa-dev-mig.h b/include/hw/virtio/vdpa-dev-mig.h -index 89665ca747..adc1d657f7 100644 ---- a/include/hw/virtio/vdpa-dev-mig.h -+++ b/include/hw/virtio/vdpa-dev-mig.h -@@ -9,6 +9,19 @@ - - #include "hw/virtio/vdpa-dev.h" - -+enum { -+ VDPA_DEVICE_START, -+ VDPA_DEVICE_STOP, -+ VDPA_DEVICE_PRE_START, -+ VDPA_DEVICE_PRE_STOP, -+ VDPA_DEVICE_CANCEL, -+ VDPA_DEVICE_POST_START, -+ VDPA_DEVICE_START_ASYNC, -+ VDPA_DEVICE_STOP_ASYNC, -+ VDPA_DEVICE_PRE_START_ASYNC, -+ VDPA_DEVICE_QUERY_OP_STATE, -+}; -+ - void vdpa_migration_register(VhostVdpaDevice *vdev); - - void vdpa_migration_unregister(VhostVdpaDevice *vdev); -diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h -index 9b3f71b20f..457923974c 100644 ---- a/linux-headers/linux/vhost.h -+++ b/linux-headers/linux/vhost.h -@@ -192,4 +192,12 @@ - */ - #define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E) - -+/* set and get device buffer */ -+#define VHOST_GET_DEV_BUFFER _IOR(VHOST_VIRTIO, 0xb0, struct vhost_vdpa_config) -+#define VHOST_SET_DEV_BUFFER _IOW(VHOST_VIRTIO, 0xb1, struct vhost_vdpa_config) -+#define VHOST_GET_DEV_BUFFER_SIZE _IOR(VHOST_VIRTIO, 0xb3, __u32) -+ -+/* set device migtration state */ -+#define VHOST_VDPA_SET_MIG_STATE _IOW(VHOST_VIRTIO, 0xb2, __u8) -+ - #endif --- -2.27.0 - diff --git a/vhost-implement-vhost-vdpa-suspend-resume.patch b/vhost-implement-vhost-vdpa-suspend-resume.patch deleted file mode 100644 index 1a499e6cee0c8aae98d989aa1cff4ef88cafd6b9..0000000000000000000000000000000000000000 --- a/vhost-implement-vhost-vdpa-suspend-resume.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 98c74a827b742807f979fc36bca99ba0db38d295 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:22:20 +0800 -Subject: [PATCH] vhost: implement vhost-vdpa suspend/resume - -vhost-vdpa implements the vhost_dev_suspend interface, -which will be called during the shutdown phase of the -live migration source virtual machine to suspend the -device but not reset the device information. - -vhost-vdpa implements the vhost_dev_resume interface. -If the live migration fails, it will be called during -the startup phase of the source virtual machine. -Enable the device but set the status, etc. - -Signed-off-by: libai -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 44 ++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 42 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 7663d78b43..7688dc0eba 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1318,6 +1318,43 @@ static unsigned int vhost_vdpa_get_used_memslots(void) - return vhost_vdpa_used_memslots; - } - -+static int vhost_vdpa_suspend_device(struct vhost_dev *dev) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ int ret; -+ -+ vhost_vdpa_svqs_stop(dev); -+ vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs); -+ -+ if (dev->vq_index + dev->nvqs != dev->vq_index_end) { -+ return 0; -+ } -+ -+ ret = vhost_vdpa_call(dev, VHOST_VDPA_SUSPEND, NULL); -+ memory_listener_unregister(&v->listener); -+ return ret; -+} -+ -+static int vhost_vdpa_resume_device(struct vhost_dev *dev) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ bool ok; -+ -+ vhost_vdpa_host_notifiers_init(dev); -+ ok = vhost_vdpa_svqs_start(dev); -+ if (unlikely(!ok)) { -+ return -1; -+ } -+ vhost_vdpa_set_vring_ready(dev); -+ -+ if (dev->vq_index + dev->nvqs != dev->vq_index_end) { -+ return 0; -+ } -+ -+ memory_listener_register(&v->listener, &address_space_memory); -+ return vhost_vdpa_call(dev, VHOST_VDPA_RESUME, NULL); -+} -+ - static int vhost_vdpa_log_sync(struct vhost_dev *dev) - { - struct vhost_vdpa *v = dev->opaque; -@@ -1364,6 +1401,9 @@ const VhostOps vdpa_ops = { - .vhost_force_iommu = vhost_vdpa_force_iommu, - .vhost_log_sync = vhost_vdpa_log_sync, - .vhost_set_config_call = vhost_vdpa_set_config_call, -- .vhost_set_used_memslots = vhost_vdpa_set_used_memslots, -- .vhost_get_used_memslots = vhost_vdpa_get_used_memslots, -+ .vhost_set_used_memslots = vhost_vdpa_set_used_memslots, -+ .vhost_get_used_memslots = vhost_vdpa_get_used_memslots, -+ .vhost_dev_suspend = vhost_vdpa_suspend_device, -+ .vhost_dev_resume = vhost_vdpa_resume_device, -+ - }; --- -2.27.0 - diff --git a/vhost-implement-vhost_vdpa_device_suspend-resume.patch b/vhost-implement-vhost_vdpa_device_suspend-resume.patch deleted file mode 100644 index 9345bd282e10ec6383af29d23e4a78807e86fcd4..0000000000000000000000000000000000000000 --- a/vhost-implement-vhost_vdpa_device_suspend-resume.patch +++ /dev/null @@ -1,453 +0,0 @@ -From a21603f7ecfaa2fb53b2037f46ee3fb868d8c9cb Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:27:34 +0800 -Subject: [PATCH] vhost: implement vhost_vdpa_device_suspend/resume - -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/meson.build | 2 +- - hw/virtio/vdpa-dev-mig.c | 186 +++++++++++++++++++++++++++++++ - hw/virtio/vhost.c | 138 +++++++++++++++++++++++ - include/hw/virtio/vdpa-dev-mig.h | 16 +++ - include/hw/virtio/vdpa-dev.h | 1 + - include/hw/virtio/vhost.h | 4 + - migration/migration.c | 3 +- - migration/migration.h | 2 + - 8 files changed, 349 insertions(+), 3 deletions(-) - create mode 100644 hw/virtio/vdpa-dev-mig.c - create mode 100644 include/hw/virtio/vdpa-dev-mig.h - -diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build -index c2da69616f..94a030f329 100644 ---- a/hw/virtio/meson.build -+++ b/hw/virtio/meson.build -@@ -29,7 +29,7 @@ virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: files('vhost-user-i2c.c')) - virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_I2C'], if_true: files('vhost-user-i2c-pci.c')) - virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: files('vhost-user-rng.c')) - virtio_ss.add(when: ['CONFIG_VHOST_USER_RNG', 'CONFIG_VIRTIO_PCI'], if_true: files('vhost-user-rng-pci.c')) --virtio_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev.c')) -+virtio_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev.c', 'vdpa-dev-mig.c')) - - virtio_pci_ss = ss.source_set() - virtio_pci_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: files('vhost-vsock-pci.c')) -diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c -new file mode 100644 -index 0000000000..64c9e245d1 ---- /dev/null -+++ b/hw/virtio/vdpa-dev-mig.c -@@ -0,0 +1,186 @@ -+/* -+ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, see . -+ */ -+ -+#include -+#include -+#include "qemu/osdep.h" -+#include "migration/misc.h" -+#include "hw/qdev-core.h" -+#include "hw/qdev-properties.h" -+#include "hw/virtio/vhost.h" -+#include "hw/virtio/vdpa-dev.h" -+#include "hw/virtio/virtio.h" -+#include "hw/virtio/virtio-bus.h" -+#include "hw/virtio/virtio-access.h" -+#include "migration/register.h" -+#include "migration/migration.h" -+#include "qemu-common.h" -+#include "sysemu/runstate.h" -+#include "qemu/error-report.h" -+#include "hw/virtio/vdpa-dev-mig.h" -+ -+static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request, -+ void *arg) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ int fd = v->device_fd; -+ -+ if (dev->vhost_ops->backend_type != VHOST_BACKEND_TYPE_VDPA) { -+ error_report("backend type isn't VDPA. Operation not permitted!\n"); -+ return -EPERM; -+ } -+ -+ return ioctl(fd, request, arg); -+} -+ -+static int vhost_vdpa_device_suspend(VhostVdpaDevice *vdpa) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(vdpa); -+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); -+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -+ int ret; -+ -+ if (!vdpa->started) { -+ return -EFAULT; -+ } -+ -+ if (!k->set_guest_notifiers) { -+ return -EFAULT; -+ } -+ -+ vdpa->started = false; -+ -+ ret = vhost_dev_suspend(&vdpa->dev, vdev, false); -+ if (ret) { -+ goto suspend_fail; -+ } -+ -+ ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, false); -+ if (ret < 0) { -+ error_report("vhost guest notifier cleanup failed: %d\n", ret); -+ goto set_guest_notifiers_fail; -+ } -+ -+ vhost_dev_disable_notifiers(&vdpa->dev, vdev); -+ return ret; -+ -+set_guest_notifiers_fail: -+ ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, true); -+ if (ret) { -+ error_report("vhost guest notifier restore failed: %d\n", ret); -+ } -+ -+suspend_fail: -+ vdpa->started = true; -+ return ret; -+} -+ -+static int vhost_vdpa_device_resume(VhostVdpaDevice *vdpa) -+{ -+ VirtIODevice *vdev = VIRTIO_DEVICE(vdpa); -+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); -+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); -+ int i, ret; -+ -+ if (!k->set_guest_notifiers) { -+ error_report("binding does not support guest notifiers\n"); -+ return -ENOSYS; -+ } -+ -+ ret = vhost_dev_enable_notifiers(&vdpa->dev, vdev); -+ if (ret < 0) { -+ error_report("Error enabling host notifiers: %d\n", ret); -+ return ret; -+ } -+ -+ ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, true); -+ if (ret < 0) { -+ error_report("Error binding guest notifier: %d\n", ret); -+ goto err_host_notifiers; -+ } -+ -+ vdpa->dev.acked_features = vdev->guest_features; -+ -+ ret = vhost_dev_resume(&vdpa->dev, vdev, false); -+ if (ret < 0) { -+ error_report("Error starting vhost: %d\n", ret); -+ goto err_guest_notifiers; -+ } -+ vdpa->started = true; -+ -+ /* -+ * guest_notifier_mask/pending not used yet, so just unmask -+ * everything here. virtio-pci will do the right thing by -+ * enabling/disabling irqfd. -+ */ -+ for (i = 0; i < vdpa->dev.nvqs; i++) { -+ vhost_virtqueue_mask(&vdpa->dev, vdev, i, false); -+ } -+ -+ return ret; -+ -+err_guest_notifiers: -+ k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, false); -+err_host_notifiers: -+ vhost_dev_disable_notifiers(&vdpa->dev, vdev); -+ return ret; -+} -+ -+static void vdpa_dev_vmstate_change(void *opaque, bool running, RunState state) -+{ -+ VhostVdpaDevice *vdpa = VHOST_VDPA_DEVICE(opaque); -+ struct vhost_dev *hdev = &vdpa->dev; -+ int ret; -+ MigrationState *ms = migrate_get_current(); -+ MigrationIncomingState *mis = migration_incoming_get_current(); -+ -+ if (!running) { -+ if (ms->state == RUN_STATE_PAUSED) { -+ ret = vhost_vdpa_device_suspend(vdpa); -+ if (ret) { -+ error_report("suspend vdpa device failed: %d\n", ret); -+ if (ms->migration_thread_running) { -+ migrate_fd_cancel(ms); -+ } -+ } -+ } -+ } else { -+ if (ms->state == RUN_STATE_RESTORE_VM) { -+ ret = vhost_vdpa_device_resume(vdpa); -+ if (ret) { -+ error_report("migration dest resume device failed, abort!\n"); -+ exit(EXIT_FAILURE); -+ } -+ } -+ -+ if (mis->state == RUN_STATE_RESTORE_VM) { -+ vhost_vdpa_call(hdev, VHOST_VDPA_RESUME, NULL); -+ } -+ } -+} -+ -+void vdpa_migration_register(VhostVdpaDevice *vdev) -+{ -+ vdev->vmstate = qdev_add_vm_change_state_handler(DEVICE(vdev), -+ vdpa_dev_vmstate_change, -+ DEVICE(vdev)); -+} -+ -+void vdpa_migration_unregister(VhostVdpaDevice *vdev) -+{ -+ qemu_del_vm_change_state_handler(vdev->vmstate); -+} -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index d2b9278474..ed1506d3e0 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -2201,3 +2201,141 @@ bool used_memslots_is_exceeded(void) - { - return used_memslots_exceeded; - } -+ -+int vhost_dev_resume(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) -+{ -+ int i, r; -+ EventNotifier *e = &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; -+ -+ /* should only be called after backend is connected */ -+ if (!hdev->vhost_ops) { -+ error_report("Missing vhost_ops! Operation not permitted!\n"); -+ return -EPERM; -+ } -+ -+ vdev->vhost_started = true; -+ hdev->started = true; -+ hdev->vdev = vdev; -+ -+ if (vhost_dev_has_iommu(hdev)) { -+ memory_listener_register(&hdev->iommu_listener, vdev->dma_as); -+ } -+ -+ r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem); -+ if (r < 0) { -+ VHOST_OPS_DEBUG(r, "vhost_set_mem_table failed"); -+ goto fail_mem; -+ } -+ for (i = 0; i < hdev->nvqs; ++i) { -+ r = vhost_virtqueue_start(hdev, -+ vdev, -+ hdev->vqs + i, -+ hdev->vq_index + i); -+ if (r < 0) { -+ goto fail_vq; -+ } -+ } -+ -+ r = event_notifier_init(e, 0); -+ if (r < 0) { -+ return r; -+ } -+ event_notifier_test_and_clear(e); -+ if (!vdev->use_guest_notifier_mask) { -+ vhost_config_mask(hdev, vdev, true); -+ } -+ if (vrings) { -+ r = vhost_dev_set_vring_enable(hdev, true); -+ if (r) { -+ goto fail_vq; -+ } -+ } -+ if (hdev->vhost_ops->vhost_dev_resume) { -+ r = hdev->vhost_ops->vhost_dev_resume(hdev); -+ if (r) { -+ goto fail_start; -+ } -+ } -+ if (vhost_dev_has_iommu(hdev)) { -+ hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true); -+ -+ /* -+ * Update used ring information for IOTLB to work correctly, -+ * vhost-kernel code requires for this. -+ */ -+ for (i = 0; i < hdev->nvqs; ++i) { -+ struct vhost_virtqueue *vq = hdev->vqs + i; -+ vhost_device_iotlb_miss(hdev, vq->used_phys, true); -+ } -+ } -+ vhost_start_config_intr(hdev); -+ return 0; -+fail_start: -+ if (vrings) { -+ vhost_dev_set_vring_enable(hdev, false); -+ } -+fail_vq: -+ while (--i >= 0) { -+ vhost_virtqueue_stop(hdev, -+ vdev, -+ hdev->vqs + i, -+ hdev->vq_index + i); -+ } -+ -+fail_mem: -+ vdev->vhost_started = false; -+ hdev->started = false; -+ return r; -+} -+ -+int vhost_dev_suspend(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) -+{ -+ int i; -+ int ret = 0; -+ EventNotifier *e = &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; -+ -+ /* should only be called after backend is connected */ -+ if (!hdev->vhost_ops) { -+ error_report("Missing vhost_ops! Operation not permitted!\n"); -+ return -EPERM; -+ } -+ -+ event_notifier_test_and_clear(e); -+ event_notifier_test_and_clear(&vdev->config_notifier); -+ -+ if (hdev->vhost_ops->vhost_dev_suspend) { -+ ret = hdev->vhost_ops->vhost_dev_suspend(hdev); -+ if (ret) { -+ goto fail_suspend; -+ } -+ } -+ if (vrings) { -+ ret = vhost_dev_set_vring_enable(hdev, false); -+ if (ret) { -+ goto fail_suspend; -+ } -+ } -+ for (i = 0; i < hdev->nvqs; ++i) { -+ vhost_virtqueue_stop(hdev, -+ vdev, -+ hdev->vqs + i, -+ hdev->vq_index + i); -+ } -+ -+ if (vhost_dev_has_iommu(hdev)) { -+ hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false); -+ memory_listener_unregister(&hdev->iommu_listener); -+ } -+ vhost_stop_config_intr(hdev); -+ vhost_log_put(hdev, true); -+ hdev->started = false; -+ vdev->vhost_started = false; -+ hdev->vdev = NULL; -+ -+ return ret; -+ -+fail_suspend: -+ event_notifier_test_and_clear(e); -+ -+ return ret; -+} -diff --git a/include/hw/virtio/vdpa-dev-mig.h b/include/hw/virtio/vdpa-dev-mig.h -new file mode 100644 -index 0000000000..89665ca747 ---- /dev/null -+++ b/include/hw/virtio/vdpa-dev-mig.h -@@ -0,0 +1,16 @@ -+/* -+ * Vhost Vdpa Device Migration Header -+ * -+ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All Rights Reserved. -+ */ -+ -+#ifndef _VHOST_VDPA_MIGRATION_H -+#define _VHOST_VDPA_MIGRATION_H -+ -+#include "hw/virtio/vdpa-dev.h" -+ -+void vdpa_migration_register(VhostVdpaDevice *vdev); -+ -+void vdpa_migration_unregister(VhostVdpaDevice *vdev); -+ -+#endif /* _VHOST_VDPA_MIGRATION_H */ -diff --git a/include/hw/virtio/vdpa-dev.h b/include/hw/virtio/vdpa-dev.h -index 4dbf98195c..43cbcef81b 100644 ---- a/include/hw/virtio/vdpa-dev.h -+++ b/include/hw/virtio/vdpa-dev.h -@@ -38,6 +38,7 @@ struct VhostVdpaDevice { - uint16_t queue_size; - bool started; - int (*post_init)(VhostVdpaDevice *v, Error **errp); -+ VMChangeStateEntry *vmstate; - }; - - #endif -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index 0491fe1ed7..9441b4c50e 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -277,4 +277,8 @@ int vhost_dev_set_inflight(struct vhost_dev *dev, - int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size, - struct vhost_inflight *inflight); - bool used_memslots_is_exceeded(void); -+ -+int vhost_dev_resume(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings); -+int vhost_dev_suspend(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings); -+ - #endif -diff --git a/migration/migration.c b/migration/migration.c -index 2ec116f901..40e743b4e9 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -178,7 +178,6 @@ static bool migration_object_check(MigrationState *ms, Error **errp); - static int migration_maybe_pause(MigrationState *s, - int *current_active_state, - int new_state); --static void migrate_fd_cancel(MigrationState *s); - - static gint page_request_addr_cmp(gconstpointer ap, gconstpointer bp) - { -@@ -1914,7 +1913,7 @@ void migrate_fd_error(MigrationState *s, const Error *error) - migrate_set_error(s, error); - } - --static void migrate_fd_cancel(MigrationState *s) -+void migrate_fd_cancel(MigrationState *s) - { - int old_state ; - QEMUFile *f = migrate_get_current()->to_dst_file; -diff --git a/migration/migration.h b/migration/migration.h -index 4ed4f555da..a87fd54d10 100644 ---- a/migration/migration.h -+++ b/migration/migration.h -@@ -393,4 +393,6 @@ void migration_cancel(const Error *error); - - void populate_vfio_info(MigrationInfo *info); - -+void migrate_fd_cancel(MigrationState *s); -+ - #endif --- -2.27.0 - diff --git a/vhost-introduce-bytemap-for-vhost-backend-logging.patch b/vhost-introduce-bytemap-for-vhost-backend-logging.patch deleted file mode 100644 index afa3d4d1adef19e67d80318cdf628773cb0ea66d..0000000000000000000000000000000000000000 --- a/vhost-introduce-bytemap-for-vhost-backend-logging.patch +++ /dev/null @@ -1,271 +0,0 @@ -From e2f1953ad26a61e59f1d45892c6937d7454e65b5 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:09:26 +0800 -Subject: [PATCH] vhost: introduce bytemap for vhost backend logging - -As vhost backend may use bytemap for logging, when get log_size -of vhost device, check whether vhost device support VHOST_BACKEND_F_BYTEMAPLOG. -If vhost device support, use bytemap for logging. - -By the way, add log_resize func pointer check and vhost_log_sync return -value check. - -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 144 ++++++++++++++++++++++++++++++++++++-- - include/hw/virtio/vhost.h | 1 + - 2 files changed, 139 insertions(+), 6 deletions(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 7930b37499..d2b9278474 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -19,9 +19,11 @@ - #include "qemu/atomic.h" - #include "qemu/range.h" - #include "qemu/error-report.h" -+#include "cpu.h" - #include "qemu/memfd.h" - #include "qemu/log.h" - #include "standard-headers/linux/vhost_types.h" -+#include "exec/ram_addr.h" - #include "hw/virtio/virtio-bus.h" - #include "hw/virtio/virtio-access.h" - #include "migration/blocker.h" -@@ -30,6 +32,7 @@ - #include "sysemu/dma.h" - #include "sysemu/tcg.h" - #include "trace.h" -+#include "qapi/qapi-commands-migration.h" - - /* enabled until disconnected backend stabilizes */ - #define _VHOST_DEBUG 1 -@@ -45,6 +48,11 @@ - do { } while (0) - #endif - -+static inline bool vhost_bytemap_log_support(struct vhost_dev *dev) -+{ -+ return (dev->backend_cap & BIT_ULL(VHOST_BACKEND_F_BYTEMAPLOG)); -+} -+ - static struct vhost_log *vhost_log; - static struct vhost_log *vhost_log_shm; - -@@ -213,12 +221,93 @@ static int vhost_sync_dirty_bitmap(struct vhost_dev *dev, - return 0; - } - -+#define BYTES_PER_LONG (sizeof(unsigned long)) -+#define BYTE_WORD(nr) ((nr) / BYTES_PER_LONG) -+#define BYTES_TO_LONGS(nr) DIV_ROUND_UP(nr, BYTES_PER_LONG) -+ -+static inline int64_t _set_dirty_bytemap_atomic(unsigned long *bytemap, unsigned long cur_pfn) -+{ -+ char *byte_of_long = (char *)bytemap; -+ int i; -+ int64_t dirty_num = 0; -+ -+ for (i = 0; i < BYTES_PER_LONG; i++) { -+ if (byte_of_long[i]) { -+ cpu_physical_memory_set_dirty_range((cur_pfn + i) << TARGET_PAGE_BITS, -+ TARGET_PAGE_SIZE, -+ 1 << DIRTY_MEMORY_MIGRATION); -+ /* Per byte ops, no need to atomic_xchg */ -+ byte_of_long[i] = 0; -+ dirty_num++; -+ } -+ } -+ -+ return dirty_num; -+} -+ -+static inline int64_t cpu_physical_memory_set_dirty_bytemap(unsigned long *bytemap, -+ ram_addr_t start, -+ ram_addr_t pages) -+{ -+ unsigned long i; -+ unsigned long len = BYTES_TO_LONGS(pages); -+ unsigned long pfn = (start >> TARGET_PAGE_BITS) / -+ BYTES_PER_LONG * BYTES_PER_LONG; -+ int64_t dirty_mig_bits = 0; -+ -+ for (i = 0; i < len; i++) { -+ if (bytemap[i]) { -+ dirty_mig_bits += _set_dirty_bytemap_atomic(&bytemap[i], -+ pfn + BYTES_PER_LONG * i); -+ } -+ } -+ -+ return dirty_mig_bits; -+} -+ -+static int vhost_sync_dirty_bytemap(struct vhost_dev *dev, -+ MemoryRegionSection *section) -+{ -+ struct vhost_log *log = dev->log; -+ -+ ram_addr_t start = section->offset_within_region + -+ memory_region_get_ram_addr(section->mr); -+ ram_addr_t pages = int128_get64(section->size) >> TARGET_PAGE_BITS; -+ -+ hwaddr idx = BYTE_WORD( -+ section->offset_within_address_space >> TARGET_PAGE_BITS); -+ -+ return cpu_physical_memory_set_dirty_bytemap((unsigned long *)log->log + idx, -+ start, pages); -+} -+ - static void vhost_log_sync(MemoryListener *listener, - MemoryRegionSection *section) - { - struct vhost_dev *dev = container_of(listener, struct vhost_dev, - memory_listener); -- vhost_sync_dirty_bitmap(dev, section, 0x0, ~0x0ULL); -+ MigrationState *ms = migrate_get_current(); -+ -+ if (!dev->log_enabled || !dev->started) { -+ return; -+ } -+ -+ if (dev->vhost_ops->vhost_log_sync) { -+ int r = dev->vhost_ops->vhost_log_sync(dev); -+ if (r < 0) { -+ error_report("Failed to sync dirty log: 0x%x\n", r); -+ if (migration_is_running(ms->state)) { -+ qmp_migrate_cancel(NULL); -+ } -+ return; -+ } -+ } -+ -+ if (vhost_bytemap_log_support(dev)) { -+ vhost_sync_dirty_bytemap(dev, section); -+ } else { -+ vhost_sync_dirty_bitmap(dev, section, 0x0, ~0x0ULL); -+ } - } - - static void vhost_log_sync_range(struct vhost_dev *dev, -@@ -228,7 +317,11 @@ static void vhost_log_sync_range(struct vhost_dev *dev, - /* FIXME: this is N^2 in number of sections */ - for (i = 0; i < dev->n_mem_sections; ++i) { - MemoryRegionSection *section = &dev->mem_sections[i]; -- vhost_sync_dirty_bitmap(dev, section, first, last); -+ if (vhost_bytemap_log_support(dev)) { -+ vhost_sync_dirty_bytemap(dev, section); -+ } else { -+ vhost_sync_dirty_bitmap(dev, section, first, last); -+ } - } - } - -@@ -236,11 +329,19 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev) - { - uint64_t log_size = 0; - int i; -+ uint64_t vhost_log_chunk_size; -+ -+ if (vhost_bytemap_log_support(dev)) { -+ vhost_log_chunk_size = VHOST_LOG_CHUNK_BYTES; -+ } else { -+ vhost_log_chunk_size = VHOST_LOG_CHUNK; -+ } -+ - for (i = 0; i < dev->mem->nregions; ++i) { - struct vhost_memory_region *reg = dev->mem->regions + i; - uint64_t last = range_get_last(reg->guest_phys_addr, - reg->memory_size); -- log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1); -+ log_size = MAX(log_size, last / vhost_log_chunk_size + 1); - } - return log_size; - } -@@ -358,12 +459,21 @@ static bool vhost_dev_log_is_shared(struct vhost_dev *dev) - dev->vhost_ops->vhost_requires_shm_log(dev); - } - --static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size) -+static inline int vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size) - { - struct vhost_log *log = vhost_log_get(size, vhost_dev_log_is_shared(dev)); -- uint64_t log_base = (uintptr_t)log->log; -+ uint64_t log_base; -+ int log_fd; - int r; - -+ if (!log) { -+ r = -ENOMEM; -+ goto out; -+ } -+ -+ log_base = (uint64_t)log->log; -+ log_fd = log_fd; -+ - /* inform backend of log switching, this must be done before - releasing the current log, to ensure no logging is lost */ - r = dev->vhost_ops->vhost_set_log_base(dev, log_base, log); -@@ -371,9 +481,19 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size) - VHOST_OPS_DEBUG(r, "vhost_set_log_base failed"); - } - -+ if (dev->vhost_ops->vhost_set_log_size) { -+ r = dev->vhost_ops->vhost_set_log_size(dev, size, dev->log); -+ if (r < 0) { -+ VHOST_OPS_DEBUG(r, "vhost_set_log_size failed"); -+ } -+ } -+ - vhost_log_put(dev, true); - dev->log = log; - dev->log_size = size; -+ -+out: -+ return r; - } - - static void *vhost_memory_map(struct vhost_dev *dev, hwaddr addr, -@@ -990,7 +1110,11 @@ static int vhost_migration_log(MemoryListener *listener, bool enable) - } - vhost_log_put(dev, false); - } else { -- vhost_dev_log_resize(dev, vhost_get_log_size(dev)); -+ r = vhost_dev_log_resize(dev, vhost_get_log_size(dev)); -+ if ( r < 0 ) { -+ return r; -+ } -+ - r = vhost_dev_set_log(dev, true); - if (r < 0) { - goto check_dev_state; -@@ -1967,6 +2091,14 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - VHOST_OPS_DEBUG(r, "vhost_set_log_base failed"); - goto fail_log; - } -+ -+ if (hdev->vhost_ops->vhost_set_log_size) { -+ r = hdev->vhost_ops->vhost_set_log_size(hdev, hdev->log_size, hdev->log); -+ if (r < 0) { -+ VHOST_OPS_DEBUG(r, "vhost_set_log_size failed"); -+ goto fail_log; -+ } -+ } - } - if (vrings) { - r = vhost_dev_set_vring_enable(hdev, true); -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index 420f93e5cd..0491fe1ed7 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -40,6 +40,7 @@ typedef unsigned long vhost_log_chunk_t; - #define VHOST_LOG_PAGE 0x1000 - #define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t)) - #define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS) -+#define VHOST_LOG_CHUNK_BYTES (VHOST_LOG_PAGE * sizeof(vhost_log_chunk_t)) - #define VHOST_INVALID_FEATURE_BIT (0xff) - #define VHOST_QUEUE_NUM_CONFIG_INR 0 - --- -2.27.0 - diff --git a/vhost-introduce-new-VhostOps-vhost_set_config_call-new.patch b/vhost-introduce-new-VhostOps-vhost_set_config_call-new.patch deleted file mode 100644 index b1e7a94074bf8f60bba3e83339e8f541d495f74a..0000000000000000000000000000000000000000 --- a/vhost-introduce-new-VhostOps-vhost_set_config_call-new.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0e8cd86ad1cc2c67fb3bd31493b534d740c9ac28 Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:45 +0800 -Subject: [PATCH] vhost: introduce new VhostOps vhost_set_config_call - -This patch introduces new VhostOps vhost_set_config_call. -This function allows the qemu to set the config -event fd to kernel driver. - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-5-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - include/hw/virtio/vhost-backend.h | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h -index a64708f456..bd1c7dfe4f 100644 ---- a/include/hw/virtio/vhost-backend.h -+++ b/include/hw/virtio/vhost-backend.h -@@ -125,6 +125,8 @@ typedef int (*vhost_vq_get_addr_op)(struct vhost_dev *dev, - typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id); - - typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev); -+typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev, -+ int fd); - typedef void (*vhost_set_used_memslots_op)(struct vhost_dev *dev); - typedef unsigned int (*vhost_get_used_memslots_op)(void); - -@@ -173,6 +175,7 @@ typedef struct VhostOps { - vhost_vq_get_addr_op vhost_vq_get_addr; - vhost_get_device_id_op vhost_get_device_id; - vhost_force_iommu_op vhost_force_iommu; -+ vhost_set_config_call_op vhost_set_config_call; - vhost_set_used_memslots_op vhost_set_used_memslots; - vhost_get_used_memslots_op vhost_get_used_memslots; - } VhostOps; --- -2.27.0 - diff --git a/vhost-introduce-new-VhostOps-vhost_set_config_call.patch b/vhost-introduce-new-VhostOps-vhost_set_config_call.patch deleted file mode 100644 index 92b4c263fa9d297c411fae0f2ddfb1569ba141b1..0000000000000000000000000000000000000000 --- a/vhost-introduce-new-VhostOps-vhost_set_config_call.patch +++ /dev/null @@ -1,41 +0,0 @@ -From af8377d0e9437401ad30d80a27ab1fcf8252fad1 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:57 +0800 -Subject: [PATCH] vhost: introduce new VhostOps vhost_set_config_call - -This patch introduces new VhostOps vhost_set_config_call. This function allows the -vhost to set the event fd to kernel - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-5-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - include/hw/virtio/vhost-backend.h | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h -index a64708f456..bd1c7dfe4f 100644 ---- a/include/hw/virtio/vhost-backend.h -+++ b/include/hw/virtio/vhost-backend.h -@@ -125,6 +125,8 @@ typedef int (*vhost_vq_get_addr_op)(struct vhost_dev *dev, - typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id); - - typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev); -+typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev, -+ int fd); - typedef void (*vhost_set_used_memslots_op)(struct vhost_dev *dev); - typedef unsigned int (*vhost_get_used_memslots_op)(void); - -@@ -173,6 +175,7 @@ typedef struct VhostOps { - vhost_vq_get_addr_op vhost_vq_get_addr; - vhost_get_device_id_op vhost_get_device_id; - vhost_force_iommu_op vhost_force_iommu; -+ vhost_set_config_call_op vhost_set_config_call; - vhost_set_used_memslots_op vhost_set_used_memslots; - vhost_get_used_memslots_op vhost_get_used_memslots; - } VhostOps; --- -2.27.0 - diff --git a/vhost-move-descriptor-translation-to-vhost_svq_vring.patch b/vhost-move-descriptor-translation-to-vhost_svq_vring.patch deleted file mode 100644 index a45e88f8e505c993072011089f1c6902e3e49f99..0000000000000000000000000000000000000000 --- a/vhost-move-descriptor-translation-to-vhost_svq_vring.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 16fdc235caece008e3802934250f434e9ca03dd3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:26 +0200 -Subject: [PATCH] vhost: move descriptor translation to - vhost_svq_vring_write_descs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's done for both in and out descriptors so it's better placed here. - -Acked-by: Jason Wang -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 38 +++++++++++++++++++++--------- - 1 file changed, 27 insertions(+), 11 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index cea2c3f8dd..da1e1ce3c7 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -121,17 +121,35 @@ static bool vhost_svq_translate_addr(const VhostShadowVirtqueue *svq, - return true; - } - --static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg, -- const struct iovec *iovec, size_t num, -- bool more_descs, bool write) -+/** -+ * Write descriptors to SVQ vring -+ * -+ * @svq: The shadow virtqueue -+ * @sg: Cache for hwaddr -+ * @iovec: The iovec from the guest -+ * @num: iovec length -+ * @more_descs: True if more descriptors come in the chain -+ * @write: True if they are writeable descriptors -+ * -+ * Return true if success, false otherwise and print error. -+ */ -+static bool vhost_svq_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg, -+ const struct iovec *iovec, size_t num, -+ bool more_descs, bool write) - { - uint16_t i = svq->free_head, last = svq->free_head; - unsigned n; - uint16_t flags = write ? cpu_to_le16(VRING_DESC_F_WRITE) : 0; - vring_desc_t *descs = svq->vring.desc; -+ bool ok; - - if (num == 0) { -- return; -+ return true; -+ } -+ -+ ok = vhost_svq_translate_addr(svq, sg, iovec, num); -+ if (unlikely(!ok)) { -+ return false; - } - - for (n = 0; n < num; n++) { -@@ -149,6 +167,7 @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg, - } - - svq->free_head = le16_to_cpu(svq->desc_next[last]); -+ return true; - } - - static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, -@@ -168,21 +187,18 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, - return false; - } - -- ok = vhost_svq_translate_addr(svq, sgs, elem->out_sg, elem->out_num); -+ ok = vhost_svq_vring_write_descs(svq, sgs, elem->out_sg, elem->out_num, -+ elem->in_num > 0, false); - if (unlikely(!ok)) { - return false; - } -- vhost_vring_write_descs(svq, sgs, elem->out_sg, elem->out_num, -- elem->in_num > 0, false); -- - -- ok = vhost_svq_translate_addr(svq, sgs, elem->in_sg, elem->in_num); -+ ok = vhost_svq_vring_write_descs(svq, sgs, elem->in_sg, elem->in_num, false, -+ true); - if (unlikely(!ok)) { - return false; - } - -- vhost_vring_write_descs(svq, sgs, elem->in_sg, elem->in_num, false, true); -- - /* - * Put the entry in the available array (but don't update avail->idx until - * they do sync). --- -2.27.0 - diff --git a/vhost-move-iova_tree-set-to-vhost_svq_start.patch b/vhost-move-iova_tree-set-to-vhost_svq_start.patch deleted file mode 100644 index 93cccc1ad9bc1bdfaf857f92f4a5ca3a705f1a78..0000000000000000000000000000000000000000 --- a/vhost-move-iova_tree-set-to-vhost_svq_start.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 7c93447234412390e6cd3bae1d5001426287a362 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:36 +0100 -Subject: [PATCH] vhost: move iova_tree set to vhost_svq_start -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since we don't know if we will use SVQ at qemu initialization, let's -allocate iova_tree only if needed. To do so, accept it at SVQ start, not -at initialization. - -This will avoid to create it if the device does not support SVQ. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-5-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 9 ++++----- - hw/virtio/vhost-shadow-virtqueue.h | 5 ++--- - hw/virtio/vhost-vdpa.c | 5 ++--- - 3 files changed, 8 insertions(+), 11 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 1ea7b5cf59..7d6afcb528 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -619,9 +619,10 @@ void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd) - * @svq: Shadow Virtqueue - * @vdev: VirtIO device - * @vq: Virtqueue to shadow -+ * @iova_tree: Tree to perform descriptors translations - */ - void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, -- VirtQueue *vq) -+ VirtQueue *vq, VhostIOVATree *iova_tree) - { - size_t desc_size, driver_size, device_size; - -@@ -632,6 +633,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, - svq->last_used_idx = 0; - svq->vdev = vdev; - svq->vq = vq; -+ svq->iova_tree = iova_tree; - - svq->vring.num = virtio_queue_get_num(vdev, virtio_get_queue_index(vq)); - driver_size = vhost_svq_driver_area_size(svq); -@@ -689,18 +691,15 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq) - * Creates vhost shadow virtqueue, and instructs the vhost device to use the - * shadow methods and file descriptors. - * -- * @iova_tree: Tree to perform descriptors translations - * @ops: SVQ owner callbacks - * @ops_opaque: ops opaque pointer - */ --VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree, -- const VhostShadowVirtqueueOps *ops, -+VhostShadowVirtqueue *vhost_svq_new(const VhostShadowVirtqueueOps *ops, - void *ops_opaque) - { - VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1); - - event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND); -- svq->iova_tree = iova_tree; - svq->ops = ops; - svq->ops_opaque = ops_opaque; - return svq; -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index d04c34a589..926a4897b1 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -126,11 +126,10 @@ size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq); - size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq); - - void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, -- VirtQueue *vq); -+ VirtQueue *vq, VhostIOVATree *iova_tree); - void vhost_svq_stop(VhostShadowVirtqueue *svq); - --VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree, -- const VhostShadowVirtqueueOps *ops, -+VhostShadowVirtqueue *vhost_svq_new(const VhostShadowVirtqueueOps *ops, - void *ops_opaque); - - void vhost_svq_free(gpointer vq); -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 2fd7af1c6b..f5d816f5ec 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -419,8 +419,7 @@ static void vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v) - for (unsigned n = 0; n < hdev->nvqs; ++n) { - VhostShadowVirtqueue *svq; - -- svq = vhost_svq_new(v->iova_tree, v->shadow_vq_ops, -- v->shadow_vq_ops_opaque); -+ svq = vhost_svq_new(v->shadow_vq_ops, v->shadow_vq_ops_opaque); - g_ptr_array_add(shadow_vqs, svq); - } - -@@ -1060,7 +1059,7 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) - goto err; - } - -- vhost_svq_start(svq, dev->vdev, vq); -+ vhost_svq_start(svq, dev->vdev, vq, v->iova_tree); - ok = vhost_vdpa_svq_map_rings(dev, svq, &addr, &err); - if (unlikely(!ok)) { - goto err_map; --- -2.27.0 - diff --git a/vhost-net-fix-improper-cleanup-in-vhost_net_start.patch b/vhost-net-fix-improper-cleanup-in-vhost_net_start.patch deleted file mode 100644 index e2db14cec61a7b061a0027612b5d00fdbc9af420..0000000000000000000000000000000000000000 --- a/vhost-net-fix-improper-cleanup-in-vhost_net_start.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 4670dbaa57d7f034c2b5720d2a4c141a82f73025 Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Fri, 6 May 2022 19:28:15 -0700 -Subject: [PATCH 4/5] vhost-net: fix improper cleanup in vhost_net_start - -vhost_net_start() missed a corresponding stop_one() upon error from -vhost_set_vring_enable(). While at it, make the error handling for -err_start more robust. No real issue was found due to this though. - -Signed-off-by: Si-Wei Liu -Acked-by: Jason Wang -Message-Id: <1651890498-24478-5-git-send-email-si-wei.liu@oracle.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: zhangxinhao ---- - hw/net/vhost_net.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index e8a79db94d..1911ffd7ed 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -439,6 +439,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, - r = vhost_set_vring_enable(peer, peer->vring_enable); - - if (r < 0) { -+ vhost_net_stop_one(get_vhost_net(peer), dev); - goto err_start; - } - } -@@ -448,7 +449,8 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, - - err_start: - while (--i >= 0) { -- peer = qemu_get_peer(ncs , i); -+ peer = qemu_get_peer(ncs, i < data_queue_pairs ? -+ i : n->max_queue_pairs); - vhost_net_stop_one(get_vhost_net(peer), dev); - } - e = k->set_guest_notifiers(qbus->parent, total_notifiers, false); --- -2.27.0 - diff --git a/vhost-release-virtqueue-objects-in-error-path.patch b/vhost-release-virtqueue-objects-in-error-path.patch deleted file mode 100644 index 895d2b2b70ed145bd58d195a307f2d7e28438bc2..0000000000000000000000000000000000000000 --- a/vhost-release-virtqueue-objects-in-error-path.patch +++ /dev/null @@ -1,39 +0,0 @@ -From ec9c8583bee8ba140274abd3f5e8366442ceaa8e Mon Sep 17 00:00:00 2001 -From: Prasad Pandit -Date: Mon, 29 May 2023 17:13:33 +0530 -Subject: [PATCH] vhost: release virtqueue objects in error path - -vhost_dev_start function does not release virtqueue objects when -event_notifier_init() function fails. Release virtqueue objects -and log a message about function failure. - -Signed-off-by: Prasad Pandit -Message-Id: <20230529114333.31686-3-ppandit@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Fixes: f9a09ca3ea ("vhost: add support for configure interrupt") -Reviewed-by: Peter Xu -Cc: qemu-stable@nongnu.org -Acked-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 63ddcb3e6d..59a12735f9 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -1931,7 +1931,8 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) - r = event_notifier_init( - &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0); - if (r < 0) { -- return r; -+ VHOST_OPS_DEBUG(r, "event_notifier_init failed"); -+ goto fail_vq; - } - event_notifier_test_and_clear( - &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); --- -2.27.0 - diff --git a/vhost-set-SVQ-device-call-handler-at-SVQ-start.patch b/vhost-set-SVQ-device-call-handler-at-SVQ-start.patch deleted file mode 100644 index 1d95b5ce14b4849df4aea3402defa73a3107c8e3..0000000000000000000000000000000000000000 --- a/vhost-set-SVQ-device-call-handler-at-SVQ-start.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 462ece480c425ef9de419f5454ec2b7293c35e16 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Thu, 15 Dec 2022 12:31:34 +0100 -Subject: [PATCH] vhost: set SVQ device call handler at SVQ start -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -By the end of this series CVQ is shadowed as long as the features -support it. - -Since we don't know at the beginning of qemu running if this is -supported, move the event notifier handler setting to the start of the -SVQ, instead of the start of qemu run. This will avoid to create them if -the device does not support SVQ. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Message-Id: <20221215113144.322011-3-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index ae443f54fe..bc12bb42f3 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -625,6 +625,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, - { - size_t desc_size, driver_size, device_size; - -+ event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call); - svq->next_guest_avail_elem = NULL; - svq->shadow_avail_idx = 0; - svq->shadow_used_idx = 0; -@@ -681,6 +682,7 @@ void vhost_svq_stop(VhostShadowVirtqueue *svq) - g_free(svq->desc_state); - qemu_vfree(svq->vring.desc); - qemu_vfree(svq->vring.used); -+ event_notifier_set_handler(&svq->hdev_call, NULL); - } - - /** -@@ -717,7 +719,6 @@ VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree, - } - - event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND); -- event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call); - svq->iova_tree = iova_tree; - svq->ops = ops; - svq->ops_opaque = ops_opaque; -@@ -740,7 +741,6 @@ void vhost_svq_free(gpointer pvq) - VhostShadowVirtqueue *vq = pvq; - vhost_svq_stop(vq); - event_notifier_cleanup(&vq->hdev_kick); -- event_notifier_set_handler(&vq->hdev_call, NULL); - event_notifier_cleanup(&vq->hdev_call); - g_free(vq); - } --- -2.27.0 - diff --git a/vhost-stick-to-errno-error-return-convention.patch b/vhost-stick-to-errno-error-return-convention.patch deleted file mode 100644 index 2607c44617db1ebeec0f47ed42afb5948a0b54a4..0000000000000000000000000000000000000000 --- a/vhost-stick-to-errno-error-return-convention.patch +++ /dev/null @@ -1,349 +0,0 @@ -From a5d0727f516b27e39b1f223e8dcf57b4c1bf95ea Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:56 +0800 -Subject: [PATCH] vhost: stick to -errno error return convention - -The generic vhost code expects that many of the VhostOps methods in the -respective backends set errno on errors. However, none of the existing -backends actually bothers to do so. In a number of those methods errno -from the failed call is clobbered by successful later calls to some -library functions; on a few code paths the generic vhost code then -negates and returns that errno, thus making failures look as successes -to the caller. - -As a result, in certain scenarios (e.g. live migration) the device -doesn't notice the first failure and goes on through its state -transitions as if everything is ok, instead of taking recovery actions -(break and reestablish the vhost-user connection, cancel migration, etc) -before it's too late. - -To fix this, consolidate on the convention to return negated errno on -failures throughout generic vhost, and use it for error propagation. - -Signed-off-by: Roman Kagan -Message-Id: <20211111153354.18807-10-rvkagan@yandex-team.ru> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost.c | 100 +++++++++++++++++++++------------------------- - 1 file changed, 46 insertions(+), 54 deletions(-) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index c3f375f276..caa53443ab 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -34,11 +34,13 @@ - #define _VHOST_DEBUG 1 - - #ifdef _VHOST_DEBUG --#define VHOST_OPS_DEBUG(fmt, ...) \ -- do { error_report(fmt ": %s (%d)", ## __VA_ARGS__, \ -- strerror(errno), errno); } while (0) -+#define VHOST_OPS_DEBUG(retval, fmt, ...) \ -+ do { \ -+ error_report(fmt ": %s (%d)", ## __VA_ARGS__, \ -+ strerror(-retval), -retval); \ -+ } while (0) - #else --#define VHOST_OPS_DEBUG(fmt, ...) \ -+#define VHOST_OPS_DEBUG(retval, fmt, ...) \ - do { } while (0) - #endif - -@@ -300,7 +302,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev *dev, uint64_t size) - releasing the current log, to ensure no logging is lost */ - r = dev->vhost_ops->vhost_set_log_base(dev, log_base, log); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_log_base failed"); -+ VHOST_OPS_DEBUG(r, "vhost_set_log_base failed"); - } - - vhost_log_put(dev, true); -@@ -552,7 +554,7 @@ static void vhost_commit(MemoryListener *listener) - if (!dev->log_enabled) { - r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_mem_table failed"); -+ VHOST_OPS_DEBUG(r, "vhost_set_mem_table failed"); - } - goto out; - } -@@ -566,7 +568,7 @@ static void vhost_commit(MemoryListener *listener) - } - r = dev->vhost_ops->vhost_set_mem_table(dev, dev->mem); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_mem_table failed"); -+ VHOST_OPS_DEBUG(r, "vhost_set_mem_table failed"); - } - /* To log less, can only decrease log size after table update. */ - if (dev->log_size > log_size + VHOST_LOG_BUFFER) { -@@ -817,8 +819,8 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev, - if (dev->vhost_ops->vhost_vq_get_addr) { - r = dev->vhost_ops->vhost_vq_get_addr(dev, &addr, vq); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_vq_get_addr failed"); -- return -errno; -+ VHOST_OPS_DEBUG(r, "vhost_vq_get_addr failed"); -+ return r; - } - } else { - addr.desc_user_addr = (uint64_t)(unsigned long)vq->desc; -@@ -830,10 +832,9 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev, - addr.flags = enable_log ? (1 << VHOST_VRING_F_LOG) : 0; - r = dev->vhost_ops->vhost_set_vring_addr(dev, &addr); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_vring_addr failed"); -- return -errno; -+ VHOST_OPS_DEBUG(r, "vhost_set_vring_addr failed"); - } -- return 0; -+ return r; - } - - static int vhost_dev_set_features(struct vhost_dev *dev, -@@ -854,19 +855,19 @@ static int vhost_dev_set_features(struct vhost_dev *dev, - } - r = dev->vhost_ops->vhost_set_features(dev, features); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_features failed"); -+ VHOST_OPS_DEBUG(r, "vhost_set_features failed"); - goto out; - } - if (dev->vhost_ops->vhost_set_backend_cap) { - r = dev->vhost_ops->vhost_set_backend_cap(dev); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_backend_cap failed"); -+ VHOST_OPS_DEBUG(r, "vhost_set_backend_cap failed"); - goto out; - } - } - - out: -- return r < 0 ? -errno : 0; -+ return r; - } - - static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log) -@@ -1021,22 +1022,17 @@ static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev, - bool is_big_endian, - int vhost_vq_index) - { -+ int r; - struct vhost_vring_state s = { - .index = vhost_vq_index, - .num = is_big_endian - }; - -- if (!dev->vhost_ops->vhost_set_vring_endian(dev, &s)) { -- return 0; -- } -- -- VHOST_OPS_DEBUG("vhost_set_vring_endian failed"); -- if (errno == ENOTTY) { -- error_report("vhost does not support cross-endian"); -- return -ENOSYS; -+ r = dev->vhost_ops->vhost_set_vring_endian(dev, &s); -+ if (r < 0) { -+ VHOST_OPS_DEBUG(r, "vhost_set_vring_endian failed"); - } -- -- return -errno; -+ return r; - } - - static int vhost_memory_region_lookup(struct vhost_dev *hdev, -@@ -1128,15 +1124,15 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, - vq->num = state.num = virtio_queue_get_num(vdev, idx); - r = dev->vhost_ops->vhost_set_vring_num(dev, &state); - if (r) { -- VHOST_OPS_DEBUG("vhost_set_vring_num failed"); -- return -errno; -+ VHOST_OPS_DEBUG(r, "vhost_set_vring_num failed"); -+ return r; - } - - state.num = virtio_queue_get_last_avail_idx(vdev, idx); - r = dev->vhost_ops->vhost_set_vring_base(dev, &state); - if (r) { -- VHOST_OPS_DEBUG("vhost_set_vring_base failed"); -- return -errno; -+ VHOST_OPS_DEBUG(r, "vhost_set_vring_base failed"); -+ return r; - } - - if (vhost_needs_vring_endian(vdev)) { -@@ -1144,7 +1140,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, - virtio_is_big_endian(vdev), - vhost_vq_index); - if (r) { -- return -errno; -+ return r; - } - } - -@@ -1172,15 +1168,13 @@ static int vhost_virtqueue_start(struct vhost_dev *dev, - - r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled); - if (r < 0) { -- r = -errno; - goto fail_alloc; - } - - file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq)); - r = dev->vhost_ops->vhost_set_vring_kick(dev, &file); - if (r) { -- VHOST_OPS_DEBUG("vhost_set_vring_kick failed"); -- r = -errno; -+ VHOST_OPS_DEBUG(r, "vhost_set_vring_kick failed"); - goto fail_kick; - } - -@@ -1240,7 +1234,7 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev, - - r = dev->vhost_ops->vhost_get_vring_base(dev, &state); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost VQ %u ring restore failed: %d", idx, r); -+ VHOST_OPS_DEBUG(r, "vhost VQ %u ring restore failed: %d", idx, r); - /* Connection to the backend is broken, so let's sync internal - * last avail idx to the device used idx. - */ -@@ -1284,7 +1278,7 @@ static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev, - - r = dev->vhost_ops->vhost_set_vring_busyloop_timeout(dev, &state); - if (r) { -- VHOST_OPS_DEBUG("vhost_set_vring_busyloop_timeout failed"); -+ VHOST_OPS_DEBUG(r, "vhost_set_vring_busyloop_timeout failed"); - return r; - } - -@@ -1306,8 +1300,7 @@ static int vhost_virtqueue_init(struct vhost_dev *dev, - file.fd = event_notifier_get_fd(&vq->masked_notifier); - r = dev->vhost_ops->vhost_set_vring_call(dev, &file); - if (r) { -- VHOST_OPS_DEBUG("vhost_set_vring_call failed"); -- r = -errno; -+ VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed"); - goto fail_call; - } - -@@ -1584,7 +1577,7 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, - file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n); - r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_vring_call failed"); -+ VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed"); - } - } - -@@ -1622,7 +1615,7 @@ void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask) - } - r = hdev->vhost_ops->vhost_set_config_call(hdev, fd); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_config_call failed"); -+ VHOST_OPS_DEBUG(r, "vhost_set_config_call failed"); - } - } - -@@ -1687,7 +1680,7 @@ int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config, - } - - error_setg(errp, "vhost_get_config not implemented"); -- return -ENOTSUP; -+ return -ENOSYS; - } - - int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data, -@@ -1700,7 +1693,7 @@ int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data, - size, flags); - } - -- return -1; -+ return -ENOSYS; - } - - void vhost_dev_set_config_notifier(struct vhost_dev *hdev, -@@ -1729,7 +1722,7 @@ static int vhost_dev_resize_inflight(struct vhost_inflight *inflight, - - if (err) { - error_report_err(err); -- return -1; -+ return -ENOMEM; - } - - vhost_dev_free_inflight(inflight); -@@ -1762,8 +1755,9 @@ int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f) - } - - if (inflight->size != size) { -- if (vhost_dev_resize_inflight(inflight, size)) { -- return -1; -+ int ret = vhost_dev_resize_inflight(inflight, size); -+ if (ret < 0) { -+ return ret; - } - } - inflight->queue_size = qemu_get_be16(f); -@@ -1786,7 +1780,7 @@ int vhost_dev_prepare_inflight(struct vhost_dev *hdev, VirtIODevice *vdev) - - r = vhost_dev_set_features(hdev, hdev->log_enabled); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_dev_prepare_inflight failed"); -+ VHOST_OPS_DEBUG(r, "vhost_dev_prepare_inflight failed"); - return r; - } - -@@ -1801,8 +1795,8 @@ int vhost_dev_set_inflight(struct vhost_dev *dev, - if (dev->vhost_ops->vhost_set_inflight_fd && inflight->addr) { - r = dev->vhost_ops->vhost_set_inflight_fd(dev, inflight); - if (r) { -- VHOST_OPS_DEBUG("vhost_set_inflight_fd failed"); -- return -errno; -+ VHOST_OPS_DEBUG(r, "vhost_set_inflight_fd failed"); -+ return r; - } - } - -@@ -1817,8 +1811,8 @@ int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size, - if (dev->vhost_ops->vhost_get_inflight_fd) { - r = dev->vhost_ops->vhost_get_inflight_fd(dev, queue_size, inflight); - if (r) { -- VHOST_OPS_DEBUG("vhost_get_inflight_fd failed"); -- return -errno; -+ VHOST_OPS_DEBUG(r, "vhost_get_inflight_fd failed"); -+ return r; - } - } - -@@ -1847,8 +1841,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - - r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_mem_table failed"); -- r = -errno; -+ VHOST_OPS_DEBUG(r, "vhost_set_mem_table failed"); - goto fail_mem; - } - for (i = 0; i < hdev->nvqs; ++i) { -@@ -1882,8 +1875,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - hdev->log_size ? log_base : 0, - hdev->log); - if (r < 0) { -- VHOST_OPS_DEBUG("vhost_set_log_base failed"); -- r = -errno; -+ VHOST_OPS_DEBUG(r, "vhost_set_log_base failed"); - goto fail_log; - } - } -@@ -1963,7 +1955,7 @@ int vhost_net_set_backend(struct vhost_dev *hdev, - return hdev->vhost_ops->vhost_net_set_backend(hdev, file); - } - -- return -1; -+ return -ENOSYS; - } - - bool used_memslots_is_exceeded(void) --- -2.27.0 - diff --git a/vhost-user-Add-support-reconnect-vhost-user-socket.patch b/vhost-user-Add-support-reconnect-vhost-user-socket.patch deleted file mode 100644 index cbe49c282b7ba86473e412201d613b6c01040f96..0000000000000000000000000000000000000000 --- a/vhost-user-Add-support-reconnect-vhost-user-socket.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 3a223111d71307eb4fdc18f5ee46ce3d6cb57660 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Fri, 11 Feb 2022 18:05:47 +0800 -Subject: [PATCH] vhost-user: Add support reconnect vhost-user socket - -Add support reconnect vhost-user socket, the reconnect time -is set to be 3 seconds. - -Signed-off-by: Jinhua Cao ---- - chardev/char-socket.c | 19 ++++++++++++++++++- - hw/net/vhost_net.c | 4 +++- - hw/virtio/vhost-user.c | 6 ++++++ - include/chardev/char.h | 16 ++++++++++++++++ - net/vhost-user.c | 3 +++ - 5 files changed, 46 insertions(+), 2 deletions(-) - -diff --git a/chardev/char-socket.c b/chardev/char-socket.c -index 836cfa0bc2..b1e9f43ec6 100644 ---- a/chardev/char-socket.c -+++ b/chardev/char-socket.c -@@ -393,6 +393,22 @@ static GSource *tcp_chr_add_watch(Chardev *chr, GIOCondition cond) - return qio_channel_create_watch(s->ioc, cond); - } - -+static void tcp_chr_set_reconnect_time(Chardev *chr, -+ int64_t reconnect_time) -+{ -+ SocketChardev *s = SOCKET_CHARDEV(chr); -+ s->reconnect_time = reconnect_time; -+} -+ -+void qemu_chr_set_reconnect_time(Chardev *chr, int64_t reconnect_time) -+{ -+ ChardevClass *cc = CHARDEV_GET_CLASS(chr); -+ -+ if (cc->chr_set_reconnect_time) { -+ cc->chr_set_reconnect_time(chr, reconnect_time); -+ } -+} -+ - static void remove_hup_source(SocketChardev *s) - { - if (s->hup_source != NULL) { -@@ -591,7 +607,7 @@ static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len) - if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) { - qio_channel_set_blocking(s->ioc, false, NULL); - } -- if (size == 0) { -+ if (size == 0 && chr->chr_for_flag != CHR_FOR_VHOST_USER) { - /* connection closed */ - tcp_chr_disconnect(chr); - } -@@ -1585,6 +1601,7 @@ static void char_socket_class_init(ObjectClass *oc, void *data) - cc->set_msgfds = tcp_set_msgfds; - cc->chr_add_client = tcp_chr_add_client; - cc->chr_add_watch = tcp_chr_add_watch; -+ cc->chr_set_reconnect_time = tcp_chr_set_reconnect_time; - cc->chr_update_read_handler = tcp_chr_update_read_handler; - - object_class_property_add(oc, "addr", "SocketAddress", -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index 30379d2ca4..a60f7cef9a 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -376,7 +376,9 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs, - goto err_start; - } - -- if (peer->vring_enable) { -+ /* ovs needs to restore all states of vring */ -+ if (peer->vring_enable || -+ ncs[i].peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { - /* restore vring enable state */ - r = vhost_set_vring_enable(peer, peer->vring_enable); - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index c265e9e92c..fc2b1b81c9 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -1926,9 +1926,15 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque, - uint64_t features, protocol_features, ram_slots; - struct vhost_user *u; - int err; -+ Chardev *chr; - - assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER); - -+ chr = qemu_chr_fe_get_driver(((VhostUserState *)opaque)->chr); -+ if (chr) { -+ chr->chr_for_flag = CHR_FOR_VHOST_USER; -+ } -+ - u = g_new0(struct vhost_user, 1); - u->user = opaque; - u->dev = dev; -diff --git a/include/chardev/char.h b/include/chardev/char.h -index a319b5fdff..f388d4b109 100644 ---- a/include/chardev/char.h -+++ b/include/chardev/char.h -@@ -14,6 +14,8 @@ - #define IAC_SB 250 - #define IAC 255 - -+#define CHR_FOR_VHOST_USER 0x32a1 -+ - /* character device */ - typedef struct CharBackend CharBackend; - -@@ -70,6 +72,7 @@ struct Chardev { - GSource *gsource; - GMainContext *gcontext; - DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); -+ int chr_for_flag; - }; - - /** -@@ -227,6 +230,16 @@ int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all); - #define qemu_chr_write_all(s, buf, len) qemu_chr_write(s, buf, len, true) - int qemu_chr_wait_connected(Chardev *chr, Error **errp); - -+/** -+ * @qemu_chr_set_reconnect_time: -+ * -+ * Set reconnect time for char disconnect. -+ * Currently, only vhost user will call it. -+ * -+ * @reconnect_time the reconnect_time to be set -+ */ -+void qemu_chr_set_reconnect_time(Chardev *chr, int64_t reconnect_time); -+ - #define TYPE_CHARDEV "chardev" - OBJECT_DECLARE_TYPE(Chardev, ChardevClass, CHARDEV) - -@@ -306,6 +319,9 @@ struct ChardevClass { - - /* handle various events */ - void (*chr_be_event)(Chardev *s, QEMUChrEvent event); -+ -+ /* set reconnect time */ -+ void (*chr_set_reconnect_time)(Chardev *chr, int64_t reconnect_time); - }; - - Chardev *qemu_chardev_new(const char *id, const char *typename, -diff --git a/net/vhost-user.c b/net/vhost-user.c -index b1a0247b59..d1aefcb9aa 100644 ---- a/net/vhost-user.c -+++ b/net/vhost-user.c -@@ -21,6 +21,8 @@ - #include "qemu/option.h" - #include "trace.h" - -+#define VHOST_USER_RECONNECT_TIME (3) -+ - typedef struct NetVhostUserState { - NetClientState nc; - CharBackend chr; /* only queue index 0 */ -@@ -287,6 +289,7 @@ static void net_vhost_user_event(void *opaque, QEMUChrEvent event) - trace_vhost_user_event(chr->label, event); - switch (event) { - case CHR_EVENT_OPENED: -+ qemu_chr_set_reconnect_time(chr, VHOST_USER_RECONNECT_TIME); - if (vhost_user_start(queues, ncs, s->vhost_user) < 0) { - qemu_chr_fe_disconnect(&s->chr); - return; --- -2.27.0 - diff --git a/vhost-user-Fix-the-virtio-features-negotiation-flaw.patch b/vhost-user-Fix-the-virtio-features-negotiation-flaw.patch deleted file mode 100644 index 9d45f1810c80f9d28316c7a2189f3bad4f2f90fa..0000000000000000000000000000000000000000 --- a/vhost-user-Fix-the-virtio-features-negotiation-flaw.patch +++ /dev/null @@ -1,92 +0,0 @@ -From d29a94eff93b12790fe96c40412854c4cff843d2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Fri, 11 Nov 2022 19:33:26 +0800 -Subject: [PATCH 11/17] vhost-user: Fix the virtio features negotiation flaw -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch aims to fix unexpected negotiation features for -vhost-user netdev interface. - -When openvswitch reconnect Qemu after an unexpected disconnection -and Qemu therefore start the vhost_dev, acked_features field in -vhost_dev is initialized with value fetched from acked_features -field in NetVhostUserState, which should be up-to-date at that -moment but Qemu could not make it actually during the time window -of virtio features negotiation. - -So we save the acked_features right after being configured by -guest virtio driver so it can be used to restore acked_features -field in vhost_dev correctly. - -Signed-off-by: Hyman Huang(黄勇) -Signed-off-by: Guoyi Tu ---- - hw/net/vhost_net-stub.c | 5 +++++ - hw/net/vhost_net.c | 6 ++++++ - hw/net/virtio-net.c | 6 ++++++ - include/net/vhost_net.h | 1 + - 4 files changed, 18 insertions(+) - -diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c -index 89d71cfb8e..199b09952a 100644 ---- a/hw/net/vhost_net-stub.c -+++ b/hw/net/vhost_net-stub.c -@@ -101,3 +101,8 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu) - { - return 0; - } -+ -+void vhost_net_save_acked_features(NetClientState *nc) -+{ -+ -+} -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index 1911ffd7ed..a98575ffbc 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -141,6 +141,12 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net) - return net->dev.acked_features; - } - -+void vhost_net_save_acked_features(NetClientState *nc) -+{ -+ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_USER); -+ vhost_user_save_acked_features(nc); -+} -+ - static int vhost_net_get_fd(NetClientState *backend) - { - switch (backend->info->type) { -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 918a7aba89..4946b65e22 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -935,6 +935,12 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features) - continue; - } - vhost_net_ack_features(get_vhost_net(nc->peer), features); -+ -+ /* -+ * keep acked_features in NetVhostUserState up-to-date so it -+ * can't miss any features configured by guest virtio driver. -+ */ -+ vhost_net_save_acked_features(nc->peer); - } - - if (virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN)) { -diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h -index 387e913e4e..7bdbf484e4 100644 ---- a/include/net/vhost_net.h -+++ b/include/net/vhost_net.h -@@ -48,4 +48,5 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net); - - int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu); - -+void vhost_net_save_acked_features(NetClientState *nc); - #endif --- -2.27.0 - diff --git a/vhost-user-Refactor-the-chr_closed_bh.patch b/vhost-user-Refactor-the-chr_closed_bh.patch deleted file mode 100644 index 52289c54b81a605ff6778e1460dcfbcfd75ad89c..0000000000000000000000000000000000000000 --- a/vhost-user-Refactor-the-chr_closed_bh.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b8c6b11e9651c5c94d3a66c64a9d54becb625a8e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Fri, 11 Nov 2022 20:03:56 +0800 -Subject: [PATCH 10/17] vhost-user: Refactor the chr_closed_bh -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use vhost_user_save_acked_features to implemente acked features -saving. - -Signed-off-by: Hyman Huang(黄勇) -Signed-off-by: Guoyi Tu ---- - net/vhost-user.c | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/net/vhost-user.c b/net/vhost-user.c -index dca277db8c..e3680b769f 100644 ---- a/net/vhost-user.c -+++ b/net/vhost-user.c -@@ -263,11 +263,7 @@ static void chr_closed_bh(void *opaque) - s = DO_UPCAST(NetVhostUserState, nc, ncs[0]); - - for (i = queues -1; i >= 0; i--) { -- s = DO_UPCAST(NetVhostUserState, nc, ncs[i]); -- -- if (s->vhost_net) { -- s->acked_features = vhost_net_get_acked_features(s->vhost_net); -- } -+ vhost_user_save_acked_features(ncs[i]); - } - - qmp_set_link(name, false, &err); --- -2.27.0 - diff --git a/vhost-user-Refactor-vhost-acked-features-saving.patch b/vhost-user-Refactor-vhost-acked-features-saving.patch deleted file mode 100644 index da7e913638e6169309061ec0959f4a1768a9387a..0000000000000000000000000000000000000000 --- a/vhost-user-Refactor-vhost-acked-features-saving.patch +++ /dev/null @@ -1,75 +0,0 @@ -From b51c193973c5bf80f08da173dcc8eb859f0f4049 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?= - -Date: Mon, 26 Sep 2022 05:32:46 +0800 -Subject: [PATCH 09/17] vhost-user: Refactor vhost acked features saving -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Abstract vhost acked features saving into -vhost_user_save_acked_features, export it as util function. - -Signed-off-by: Hyman Huang(黄勇) -Signed-off-by: Guoyi Tu ---- - include/net/vhost-user.h | 1 + - net/vhost-user.c | 21 +++++++++++++++------ - 2 files changed, 16 insertions(+), 6 deletions(-) - -diff --git a/include/net/vhost-user.h b/include/net/vhost-user.h -index 5bcd8a6285..35bf619709 100644 ---- a/include/net/vhost-user.h -+++ b/include/net/vhost-user.h -@@ -14,5 +14,6 @@ - struct vhost_net; - struct vhost_net *vhost_user_get_vhost_net(NetClientState *nc); - uint64_t vhost_user_get_acked_features(NetClientState *nc); -+void vhost_user_save_acked_features(NetClientState *nc); - - #endif /* VHOST_USER_H */ -diff --git a/net/vhost-user.c b/net/vhost-user.c -index f910a286e4..dca277db8c 100644 ---- a/net/vhost-user.c -+++ b/net/vhost-user.c -@@ -48,10 +48,23 @@ uint64_t vhost_user_get_acked_features(NetClientState *nc) - return s->acked_features; - } - --static void vhost_user_stop(int queues, NetClientState *ncs[]) -+void vhost_user_save_acked_features(NetClientState *nc) - { - NetVhostUserState *s; -+ -+ s = DO_UPCAST(NetVhostUserState, nc, nc); -+ if (s->vhost_net) { -+ uint64_t features = vhost_net_get_acked_features(s->vhost_net); -+ if (features) { -+ s->acked_features = features; -+ } -+ } -+} -+ -+static void vhost_user_stop(int queues, NetClientState *ncs[]) -+{ - int i; -+ NetVhostUserState *s; - - for (i = 0; i < queues; i++) { - assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER); -@@ -59,11 +72,7 @@ static void vhost_user_stop(int queues, NetClientState *ncs[]) - s = DO_UPCAST(NetVhostUserState, nc, ncs[i]); - - if (s->vhost_net) { -- /* save acked features */ -- uint64_t features = vhost_net_get_acked_features(s->vhost_net); -- if (features) { -- s->acked_features = features; -- } -+ vhost_user_save_acked_features(ncs[i]); - vhost_net_cleanup(s->vhost_net); - } - } --- -2.27.0 - diff --git a/vhost-user-Set-the-acked_features-to-vm-s-featrue.patch b/vhost-user-Set-the-acked_features-to-vm-s-featrue.patch deleted file mode 100644 index 63c03535bc4e3e4e8886981205f79aff8b40f145..0000000000000000000000000000000000000000 --- a/vhost-user-Set-the-acked_features-to-vm-s-featrue.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 12af29806ba8ede96567e4df9223f0c02669727c Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Fri, 11 Feb 2022 18:49:21 +0800 -Subject: [PATCH] vhost-user: Set the acked_features to vm's featrue - -Fix the problem when vm restart, the ovs restart and lead to the net -unreachable. The soluation is set the acked_features to vm's featrue -just the same as guest virtio-net mod load. - -Signed-off-by: Jinhua Cao ---- - hw/net/vhost_net.c | 58 +++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 57 insertions(+), 1 deletion(-) - -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index a60f7cef9a..e8a79db94d 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -152,9 +152,26 @@ static int vhost_net_get_fd(NetClientState *backend) - } - } - -+static uint64_t vhost_get_mask_features(const int *feature_bits, uint64_t features) -+{ -+ const int *bit = feature_bits; -+ uint64_t out_features = 0; -+ -+ while (*bit != VHOST_INVALID_FEATURE_BIT) { -+ uint64_t bit_mask = (1ULL << *bit); -+ if (features & bit_mask) { -+ out_features |= bit_mask; -+ } -+ bit++; -+ } -+ return out_features; -+} -+ - struct vhost_net *vhost_net_init(VhostNetOptions *options) - { - int r; -+ VirtIONet *n; -+ VirtIODevice *vdev; - bool backend_kernel = options->backend_type == VHOST_BACKEND_TYPE_KERNEL; - struct vhost_net *net = g_new0(struct vhost_net, 1); - uint64_t features = 0; -@@ -180,7 +197,46 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options) - net->backend = r; - net->dev.protocol_features = 0; - } else { -- net->dev.backend_features = 0; -+ /* for ovs restart when vm start. -+ * Normal situation: -+ * 1.vm start. -+ * 2.vhost_net_init init ok, then dev.acked_features is 0x40000000. -+ * 3.guest virtio-net mod load. qemu will call virtio_net_set_features set -+ * dev.acked_features to 0x40408000. -+ * 4.feature set to ovs's vhostuser(0x40408000). -+ * 5.ovs restart. -+ * 6.vhost_user_stop will save net->dev.acked_features(0x40408000) to -+ * VhostUserState's acked_features(0x40408000). -+ * 7.restart ok. -+ * 8.vhost_net_init fun call vhost_user_get_acked_features get the save -+ * features, and set to net->dev.acked_features. -+ * Abnormal situation: -+ * 1.vm start. -+ * 2.vhost_net_init init ok, then dev.acked_features is 0x40000000. -+ * 3.ovs restart. -+ * 4.vhost_user_stop will save net->dev.acked_features(0x40000000) to -+ * VhostUserState's acked_features(0x40000000). -+ * 5.guest virtio-net mod load. qemu will call virtio_net_set_features set -+ * dev.acked_features to 0x40408000. -+ * 6.restart ok. -+ * 7.vhost_net_init fun call vhost_user_get_acked_features get the save -+ * features(0x40000000), and set to net->dev.acked_features(0x40000000). -+ * 8.feature set to ovs's vhostuser(0x40000000). -+ * -+ * in abnormal situation, qemu set the wrong features to ovs's vhostuser, -+ * then the vm's network will be down. -+ * in abnormal situation, we found it just lost the guest feartures in -+ * acked_features, so hear we set the acked_features to vm's featrue -+ * just the same as guest virtio-net mod load. -+ */ -+ if (options->net_backend->peer) { -+ n = qemu_get_nic_opaque(options->net_backend->peer); -+ vdev = VIRTIO_DEVICE(n); -+ net->dev.backend_features = vhost_get_mask_features(vhost_net_get_feature_bits(net), -+ vdev->guest_features); -+ } else { -+ net->dev.backend_features = 0; -+ } - net->dev.protocol_features = 0; - net->backend = -1; - --- -2.27.0 - diff --git a/vhost-user-Use-correct-macro-name-TARGET_PPC64.patch b/vhost-user-Use-correct-macro-name-TARGET_PPC64.patch deleted file mode 100644 index 7d469cb1fcf3b75ce98ae13836fb0b6a2780563c..0000000000000000000000000000000000000000 --- a/vhost-user-Use-correct-macro-name-TARGET_PPC64.patch +++ /dev/null @@ -1,42 +0,0 @@ -From f985f564a64e122e55a02f7a22e877f0de2de464 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 21 Aug 2023 06:55:57 +0000 -Subject: [PATCH] vhost-user: Use correct macro name TARGET_PPC64 mainline - inclusion commit 97252353c1f6ecbb54385c9272378b5788749a16 category: bugfix - ---------------------------------------------------------------- - -The correct name of the macro is TARGET_PPC64. - -Fixes: 27598393a232 ("Lift max memory slots limit imposed by vhost-user") -Reported-by: Fabiano Rosas -Signed-off-by: Murilo Opsfelder Araujo -Cc: Raphael Norwitz -Cc: Peter Turschmid -Reviewed-by: Daniel Henrique Barboza -Reviewed-by: Michael S. Tsirkin -Reviewed-by: Raphael Norwitz -Message-Id: <20220503180108.34506-1-muriloo@linux.ibm.com> -Signed-off-by: Daniel Henrique Barboza - -Signed-off-by: tangbinzy ---- - hw/virtio/vhost-user.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index 42a9e16cd9..24f80d5d18 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -52,7 +52,7 @@ - #include "hw/acpi/acpi.h" - #define VHOST_USER_MAX_RAM_SLOTS ACPI_MAX_RAM_SLOTS - --#elif defined(TARGET_PPC) || defined(TARGET_PPC_64) -+#elif defined(TARGET_PPC) || defined(TARGET_PPC64) - #include "hw/ppc/spapr.h" - #define VHOST_USER_MAX_RAM_SLOTS SPAPR_MAX_RAM_SLOTS - --- -2.41.0.windows.1 - diff --git a/vhost-user-add-separate-memslot-counter-for-vhost-us.patch b/vhost-user-add-separate-memslot-counter-for-vhost-us.patch deleted file mode 100644 index d84f83043c6570edeb16df68fbf0572906ed7c7d..0000000000000000000000000000000000000000 --- a/vhost-user-add-separate-memslot-counter-for-vhost-us.patch +++ /dev/null @@ -1,244 +0,0 @@ -From 185d7efe768229b43911504f64fccd33ad3650ef Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Fri, 11 Feb 2022 19:17:59 +0800 -Subject: [PATCH] vhost-user: add separate memslot counter for vhost-user - -Used_memslots is equal to dev->mem->nregions now, it is true for -vhost kernel, but not for vhost user, which uses the memory regions -that have file descriptor. In fact, not all of the memory regions -have file descriptor. -It is usefully in some scenarios, e.g. used_memslots is 8, and only -5 memory slots can be used by vhost user, it is failed to hot plug -a new memory RAM because vhost_has_free_slot just returned false, -but we can hot plug it safely in fact. - -Signed-off-by: Jinhua Cao ---- - hw/virtio/vhost-backend.c | 14 ++++++++++ - hw/virtio/vhost-user.c | 27 ++++++++++++++++++ - hw/virtio/vhost.c | 46 +++++++++++++++++++++++++------ - include/hw/virtio/vhost-backend.h | 4 +++ - 4 files changed, 82 insertions(+), 9 deletions(-) - -diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c -index b65f8f7e97..2acfb750fd 100644 ---- a/hw/virtio/vhost-backend.c -+++ b/hw/virtio/vhost-backend.c -@@ -20,6 +20,8 @@ - #include - #include - -+static unsigned int vhost_kernel_used_memslots; -+ - static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request, - void *arg) - { -@@ -293,6 +295,16 @@ static void vhost_kernel_set_iotlb_callback(struct vhost_dev *dev, - qemu_set_fd_handler((uintptr_t)dev->opaque, NULL, NULL, NULL); - } - -+static void vhost_kernel_set_used_memslots(struct vhost_dev *dev) -+{ -+ vhost_kernel_used_memslots = dev->mem->nregions; -+} -+ -+static unsigned int vhost_kernel_get_used_memslots(void) -+{ -+ return vhost_kernel_used_memslots; -+} -+ - const VhostOps kernel_ops = { - .backend_type = VHOST_BACKEND_TYPE_KERNEL, - .vhost_backend_init = vhost_kernel_init, -@@ -325,6 +337,8 @@ const VhostOps kernel_ops = { - #endif /* CONFIG_VHOST_VSOCK */ - .vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback, - .vhost_send_device_iotlb_msg = vhost_kernel_send_device_iotlb_msg, -+ .vhost_set_used_memslots = vhost_kernel_set_used_memslots, -+ .vhost_get_used_memslots = vhost_kernel_get_used_memslots, - }; - #endif - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index a8feea489b..176cae9244 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -234,6 +234,7 @@ static VhostUserMsg m __attribute__ ((unused)); - - /* The version of the protocol we support */ - #define VHOST_USER_VERSION (0x1) -+static unsigned int vhost_user_used_memslots; - - struct vhost_user { - struct vhost_dev *dev; -@@ -2524,6 +2525,30 @@ void vhost_user_cleanup(VhostUserState *user) - user->chr = NULL; - } - -+static void vhost_user_set_used_memslots(struct vhost_dev *dev) -+{ -+ unsigned int counter = 0; -+ int i; -+ -+ for (i = 0; i < dev->mem->nregions; ++i) { -+ struct vhost_memory_region *reg = dev->mem->regions + i; -+ ram_addr_t offset; -+ MemoryRegion *mr; -+ -+ mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr, -+ &offset); -+ if (mr && memory_region_get_fd(mr) > 0) { -+ counter++; -+ } -+ } -+ vhost_user_used_memslots = counter; -+} -+ -+static unsigned int vhost_user_get_used_memslots(void) -+{ -+ return vhost_user_used_memslots; -+} -+ - const VhostOps user_ops = { - .backend_type = VHOST_BACKEND_TYPE_USER, - .vhost_backend_init = vhost_user_backend_init, -@@ -2557,4 +2582,6 @@ const VhostOps user_ops = { - .vhost_backend_mem_section_filter = vhost_user_mem_section_filter, - .vhost_get_inflight_fd = vhost_user_get_inflight_fd, - .vhost_set_inflight_fd = vhost_user_set_inflight_fd, -+ .vhost_set_used_memslots = vhost_user_set_used_memslots, -+ .vhost_get_used_memslots = vhost_user_get_used_memslots, - }; -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index dafb23c481..e4809777bc 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -45,20 +45,20 @@ - static struct vhost_log *vhost_log; - static struct vhost_log *vhost_log_shm; - --static unsigned int used_memslots; - static QLIST_HEAD(, vhost_dev) vhost_devices = - QLIST_HEAD_INITIALIZER(vhost_devices); - - bool vhost_has_free_slot(void) - { -- unsigned int slots_limit = ~0U; - struct vhost_dev *hdev; - - QLIST_FOREACH(hdev, &vhost_devices, entry) { -- unsigned int r = hdev->vhost_ops->vhost_backend_memslots_limit(hdev); -- slots_limit = MIN(slots_limit, r); -+ if (hdev->vhost_ops->vhost_get_used_memslots() >= -+ hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { -+ return false; -+ } - } -- return slots_limit > used_memslots; -+ return true; - } - - static void vhost_dev_sync_region(struct vhost_dev *dev, -@@ -521,7 +521,6 @@ static void vhost_commit(MemoryListener *listener) - dev->n_mem_sections * sizeof dev->mem->regions[0]; - dev->mem = g_realloc(dev->mem, regions_size); - dev->mem->nregions = dev->n_mem_sections; -- used_memslots = dev->mem->nregions; - for (i = 0; i < dev->n_mem_sections; i++) { - struct vhost_memory_region *cur_vmr = dev->mem->regions + i; - struct MemoryRegionSection *mrs = dev->mem_sections + i; -@@ -697,6 +696,7 @@ static void vhost_region_add_section(struct vhost_dev *dev, - dev->tmp_sections[dev->n_tmp_sections - 1].fv = NULL; - memory_region_ref(section->mr); - } -+ dev->vhost_ops->vhost_set_used_memslots(dev); - } - - /* Used for both add and nop callbacks */ -@@ -712,6 +712,17 @@ static void vhost_region_addnop(MemoryListener *listener, - vhost_region_add_section(dev, section); - } - -+static void vhost_region_del(MemoryListener *listener, -+ MemoryRegionSection *section) -+{ -+ struct vhost_dev *dev = container_of(listener, struct vhost_dev, -+ memory_listener); -+ if (!vhost_section(dev, section)) { -+ return; -+ } -+ dev->vhost_ops->vhost_set_used_memslots(dev); -+} -+ - static void vhost_iommu_unmap_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) - { - struct vhost_iommu *iommu = container_of(n, struct vhost_iommu, n); -@@ -1319,6 +1330,18 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq) - event_notifier_cleanup(&vq->masked_notifier); - } - -+static bool vhost_dev_used_memslots_is_exceeded(struct vhost_dev *hdev) -+{ -+ if (hdev->vhost_ops->vhost_get_used_memslots() > -+ hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { -+ error_report("vhost backend memory slots limit is less" -+ " than current number of present memory slots"); -+ return true; -+ } -+ -+ return false; -+} -+ - int vhost_dev_init(struct vhost_dev *hdev, void *opaque, - VhostBackendType backend_type, uint32_t busyloop_timeout, - Error **errp) -@@ -1374,6 +1397,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, - .name = "vhost", - .begin = vhost_begin, - .commit = vhost_commit, -+ .region_del = vhost_region_del, - .region_add = vhost_region_addnop, - .region_nop = vhost_region_addnop, - .log_start = vhost_log_start, -@@ -1420,9 +1444,13 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, - memory_listener_register(&hdev->memory_listener, &address_space_memory); - QLIST_INSERT_HEAD(&vhost_devices, hdev, entry); - -- if (used_memslots > hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { -- error_setg(errp, "vhost backend memory slots limit is less" -- " than current number of present memory slots"); -+ /* -+ * If we started a VM without any vhost device, -+ * vhost_dev_used_memslots_is_exceeded will always return false for the -+ * first time vhost device hot-plug(vhost_get_used_memslots is always 0), -+ * so it needs to double check here -+ */ -+ if (vhost_dev_used_memslots_is_exceeded(hdev)) { - r = -EINVAL; - goto fail_busyloop; - } -diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h -index 81bf3109f8..a64708f456 100644 ---- a/include/hw/virtio/vhost-backend.h -+++ b/include/hw/virtio/vhost-backend.h -@@ -125,6 +125,8 @@ typedef int (*vhost_vq_get_addr_op)(struct vhost_dev *dev, - typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id); - - typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev); -+typedef void (*vhost_set_used_memslots_op)(struct vhost_dev *dev); -+typedef unsigned int (*vhost_get_used_memslots_op)(void); - - typedef struct VhostOps { - VhostBackendType backend_type; -@@ -171,6 +173,8 @@ typedef struct VhostOps { - vhost_vq_get_addr_op vhost_vq_get_addr; - vhost_get_device_id_op vhost_get_device_id; - vhost_force_iommu_op vhost_force_iommu; -+ vhost_set_used_memslots_op vhost_set_used_memslots; -+ vhost_get_used_memslots_op vhost_get_used_memslots; - } VhostOps; - - int vhost_backend_update_device_iotlb(struct vhost_dev *dev, --- -2.27.0 - diff --git a/vhost-user-add-unregister_savevm-when-vhost-user-cle.patch b/vhost-user-add-unregister_savevm-when-vhost-user-cle.patch deleted file mode 100644 index 95488a220c8d37b4fae6d3ebfc2cc016ea45f364..0000000000000000000000000000000000000000 --- a/vhost-user-add-unregister_savevm-when-vhost-user-cle.patch +++ /dev/null @@ -1,33 +0,0 @@ -From a9459c849c5484a022f67a317b72de764c84c845 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 20:21:33 +0800 -Subject: [PATCH] vhost-user: add unregister_savevm when vhost-user cleanup - -Signed-off-by: Jinhua Cao ---- - hw/virtio/vhost-user.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index bf6e50223c..c265e9e92c 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -24,6 +24,7 @@ - #include "sysemu/cryptodev.h" - #include "migration/migration.h" - #include "migration/postcopy-ram.h" -+#include "migration/register.h" - #include "trace.h" - - #include -@@ -2068,6 +2069,7 @@ static int vhost_user_backend_cleanup(struct vhost_dev *dev) - u->region_rb_len = 0; - g_free(u); - dev->opaque = 0; -+ unregister_savevm(NULL, "vhost-user", dev); - - return 0; - } --- -2.27.0 - diff --git a/vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch b/vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch deleted file mode 100644 index fcd6bbf930f6496eee95cee86459f83b979ab507..0000000000000000000000000000000000000000 --- a/vhost-user-add-vhost_set_mem_table-when-vm-load_setu.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 5c753d539a968f2127ff6e5b916cd4b38a08b40c Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Fri, 11 Feb 2022 18:59:34 +0800 -Subject: [PATCH] vhost-user: add vhost_set_mem_table when vm load_setup at - destination - -When migrate huge vm, packages lost are 90+. - -During the load_setup of the destination vm, pass the -vm mem structure to ovs, the netcard could be enabled -when the migration finish state shifting. - -Signed-off-by: Jinhua Cao ---- - hw/virtio/vhost-user.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index fc2b1b81c9..a8feea489b 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -1920,6 +1920,28 @@ static int vhost_user_postcopy_notifier(NotifierWithReturn *notifier, - return 0; - } - -+static int vhost_user_load_setup(QEMUFile *f, void *opaque) -+{ -+ struct vhost_dev *hdev = opaque; -+ int r; -+ -+ if (hdev->vhost_ops && hdev->vhost_ops->vhost_set_mem_table) { -+ r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem); -+ if (r < 0) { -+ qemu_log("error: vhost_set_mem_table failed: %s(%d)\n", -+ strerror(errno), errno); -+ return r; -+ } else { -+ qemu_log("info: vhost_set_mem_table OK\n"); -+ } -+ } -+ return 0; -+} -+ -+SaveVMHandlers savevm_vhost_user_handlers = { -+ .load_setup = vhost_user_load_setup, -+}; -+ - static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque, - Error **errp) - { -@@ -2044,6 +2066,7 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque, - - u->postcopy_notifier.notify = vhost_user_postcopy_notifier; - postcopy_add_notifier(&u->postcopy_notifier); -+ register_savevm_live("vhost-user", -1, 1, &savevm_vhost_user_handlers, dev); - - return 0; - } --- -2.27.0 - diff --git a/vhost-user-blk-fix-the-resize-crash.patch b/vhost-user-blk-fix-the-resize-crash.patch deleted file mode 100644 index 83c6cea4ed8459c0a48963f144351f5502a3d8ad..0000000000000000000000000000000000000000 --- a/vhost-user-blk-fix-the-resize-crash.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 17e6be412054ae22027a339614fca82d55e64973 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Thu, 30 Mar 2023 17:45:11 +0800 -Subject: [PATCH] vhost-user-blk: fix the resize crash - -cheery-pick from ab6075d849f4285fc730d3ae6e17418d65d09998 - -If the os is not installed and doesn't have the virtio guest driver, -the vhost dev isn't started, so the dev->vdev is NULL. - -Reproduce: mount a Win 2019 iso, go into the install ui, then resize -the virtio-blk device, qemu crash. - -Signed-off-by: qihao_yewu -Signed-off-by: Li Feng -Message-Id: <20220919121816.3252223-1-fengli@smartx.com> -Reviewed-by: Raphael Norwitz -Reviewed-by: Kevin Wolf -Signed-off-by: Kevin Wolf ---- - hw/block/vhost-user-blk.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c -index eb1264afc7..bcc3f83c4b 100644 ---- a/hw/block/vhost-user-blk.c -+++ b/hw/block/vhost-user-blk.c -@@ -95,6 +95,10 @@ static int vhost_user_blk_handle_config_change(struct vhost_dev *dev) - VHostUserBlk *s = VHOST_USER_BLK(dev->vdev); - Error *local_err = NULL; - -+ if (!dev->started) { -+ return 0; -+ } -+ - ret = vhost_dev_get_config(dev, (uint8_t *)&blkcfg, - sizeof(struct virtio_blk_config), - &local_err); --- -2.27.0 - diff --git a/vhost-user-blk-propagate-error-return-from-generic-v.patch b/vhost-user-blk-propagate-error-return-from-generic-v.patch deleted file mode 100644 index 7894db573723a59ed7e8ee70af058b0bf48eddb1..0000000000000000000000000000000000000000 --- a/vhost-user-blk-propagate-error-return-from-generic-v.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 2a4dcc55ce71f1251d0dc0ccd293866bfe4dc071 Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Mon, 4 Dec 2023 11:15:58 +0800 -Subject: [PATCH] vhost-user-blk: propagate error return from generic vhost - -cherry picked from commit fb767859345506d747876c23d181155b183f8e94 - -Fix the only callsite that doesn't propagate the error code from the -generic vhost code. - -Signed-off-by: Roman Kagan -Message-Id: <20211111153354.18807-11-rvkagan@yandex-team.ru> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Raphael Norwitz -Signed-off-by: Luo Yifan ---- - hw/block/vhost-user-blk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c -index eddc5588fa..f1a281a965 100644 ---- a/hw/block/vhost-user-blk.c -+++ b/hw/block/vhost-user-blk.c -@@ -104,7 +104,7 @@ static int vhost_user_blk_handle_config_change(struct vhost_dev *dev) - &local_err); - if (ret < 0) { - error_report_err(local_err); -- return -1; -+ return ret; - } - - /* valid for resize only */ --- -2.27.0 - diff --git a/vhost-user-blk-reconnect-on-any-error-during-realize.patch b/vhost-user-blk-reconnect-on-any-error-during-realize.patch deleted file mode 100644 index 25eaab24a154eb9e72caa7a38137c74b6b98fbdb..0000000000000000000000000000000000000000 --- a/vhost-user-blk-reconnect-on-any-error-during-realize.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a64c32378bd5a1119ea69d8c29f93b6365d3346b Mon Sep 17 00:00:00 2001 -From: Luo Yifan -Date: Mon, 4 Dec 2023 11:11:29 +0800 -Subject: [PATCH] vhost-user-blk: reconnect on any error during realize - -cherry picked from commit b7107e758f4ecdd8f07ede3f093cbbfdb623e865 - -vhost-user-blk realize only attempts to reconnect if the previous -connection attempt failed on "a problem with the connection and not an -error related to the content (which would fail again the same way in the -next attempt)". - -However this distinction is very subtle, and may be inadvertently broken -if the code changes somewhere deep down the stack and a new error gets -propagated up to here. - -OTOH now that the number of reconnection attempts is limited it seems -harmless to try reconnecting on any error. - -So relax the condition of whether to retry connecting to check for any -error. - -This patch amends a527e312b5 "vhost-user-blk: Implement reconnection -during realize". - -Signed-off-by: Roman Kagan -Message-Id: <20211111153354.18807-2-rvkagan@yandex-team.ru> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Raphael Norwitz -Signed-off-by: Luo Yifan ---- - hw/block/vhost-user-blk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c -index eddc5588fa..a2236c5239 100644 ---- a/hw/block/vhost-user-blk.c -+++ b/hw/block/vhost-user-blk.c -@@ -516,7 +516,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) - *errp = NULL; - } - ret = vhost_user_blk_realize_connect(s, errp); -- } while (ret == -EPROTO && retries--); -+ } while (ret < 0 && retries--); - - if (ret < 0) { - goto virtio_err; --- -2.27.0 - diff --git a/vhost-user-fix-VirtQ-notifier-cleanup.patch b/vhost-user-fix-VirtQ-notifier-cleanup.patch deleted file mode 100644 index 96bba60295d7dd010f5c4085abc87b9436d6c126..0000000000000000000000000000000000000000 --- a/vhost-user-fix-VirtQ-notifier-cleanup.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 0d022f741ab510b52453bb9e9e07b968e7d5e0df Mon Sep 17 00:00:00 2001 -From: Xueming Li -Date: Mon, 7 Feb 2022 15:19:29 +0800 -Subject: [PATCH 2/2] vhost-user: fix VirtQ notifier cleanup - -When vhost-user device cleanup, remove notifier MR and munmaps notifier -address in the event-handling thread, VM CPU thread writing the notifier -in concurrent fails with an error of accessing invalid address. It -happens because MR is still being referenced and accessed in another -thread while the underlying notifier mmap address is being freed and -becomes invalid. - -This patch calls RCU and munmap notifiers in the callback after the -memory flatview update finish. - -Fixes: 44866521bd6e ("vhost-user: support registering external host notifiers") -Cc: qemu-stable@nongnu.org -Signed-off-by: Xueming Li -Message-Id: <20220207071929.527149-3-xuemingl@nvidia.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit 0b0af4d62f7002b31cd7b2762b26d2fcb76bb2ba) ---- - hw/virtio/vhost-user.c | 48 ++++++++++++++++++++-------------- - include/hw/virtio/vhost-user.h | 2 ++ - 2 files changed, 31 insertions(+), 19 deletions(-) - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index 7b21e09723..42a9e16cd9 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -26,6 +26,7 @@ - #include "migration/postcopy-ram.h" - #include "migration/register.h" - #include "trace.h" -+#include "exec/ramblock.h" - - #include - #include -@@ -1145,15 +1146,26 @@ static int vhost_user_set_vring_num(struct vhost_dev *dev, - return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring); - } - --static void vhost_user_host_notifier_remove(struct vhost_dev *dev, -- int queue_idx) -+static void vhost_user_host_notifier_free(VhostUserHostNotifier *n) - { -- struct vhost_user *u = dev->opaque; -- VhostUserHostNotifier *n = &u->user->notifier[queue_idx]; -- VirtIODevice *vdev = dev->vdev; -+ assert(n && n->unmap_addr); -+ munmap(n->unmap_addr, qemu_real_host_page_size); -+ n->unmap_addr = NULL; -+} -+ -+static void vhost_user_host_notifier_remove(VhostUserState *user, -+ VirtIODevice *vdev, int queue_idx) -+{ -+ VhostUserHostNotifier *n = &user->notifier[queue_idx]; - - if (n->addr) { -- virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); -+ if (vdev) { -+ virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); -+ } -+ assert(!n->unmap_addr); -+ n->unmap_addr = n->addr; -+ n->addr = NULL; -+ call_rcu(n, vhost_user_host_notifier_free, rcu); - } - } - -@@ -1192,8 +1204,9 @@ static int vhost_user_get_vring_base(struct vhost_dev *dev, - .payload.state = *ring, - .hdr.size = sizeof(msg.payload.state), - }; -+ struct vhost_user *u = dev->opaque; - -- vhost_user_host_notifier_remove(dev, ring->index); -+ vhost_user_host_notifier_remove(u->user, dev->vdev, ring->index); - - if (vhost_user_write(dev, &msg, NULL, 0) < 0) { - return -1; -@@ -1488,12 +1501,7 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, - - n = &user->notifier[queue_idx]; - -- if (n->addr) { -- virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); -- object_unparent(OBJECT(&n->mr)); -- munmap(n->addr, page_size); -- n->addr = NULL; -- } -+ vhost_user_host_notifier_remove(user, vdev, queue_idx); - - if (area->u64 & VHOST_USER_VRING_NOFD_MASK) { - return 0; -@@ -1512,9 +1520,12 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, - - name = g_strdup_printf("vhost-user/host-notifier@%p mmaps[%d]", - user, queue_idx); -- if (!n->mr.ram) /* Don't init again after suspend. */ -+ if (!n->mr.ram) { /* Don't init again after suspend. */ - memory_region_init_ram_device_ptr(&n->mr, OBJECT(vdev), name, - page_size, addr); -+ } else { -+ n->mr.ram_block->host = addr; -+ } - g_free(name); - - if (virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true)) { -@@ -2492,17 +2503,16 @@ bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp) - void vhost_user_cleanup(VhostUserState *user) - { - int i; -+ VhostUserHostNotifier *n; - - if (!user->chr) { - return; - } - memory_region_transaction_begin(); - for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { -- if (user->notifier[i].addr) { -- object_unparent(OBJECT(&user->notifier[i].mr)); -- munmap(user->notifier[i].addr, qemu_real_host_page_size); -- user->notifier[i].addr = NULL; -- } -+ n = &user->notifier[i]; -+ vhost_user_host_notifier_remove(user, NULL, i); -+ object_unparent(OBJECT(&n->mr)); - } - memory_region_transaction_commit(); - user->chr = NULL; -diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h -index f6012b2078..e44a41bb70 100644 ---- a/include/hw/virtio/vhost-user.h -+++ b/include/hw/virtio/vhost-user.h -@@ -12,8 +12,10 @@ - #include "hw/virtio/virtio.h" - - typedef struct VhostUserHostNotifier { -+ struct rcu_head rcu; - MemoryRegion mr; - void *addr; -+ void *unmap_addr; - } VhostUserHostNotifier; - - typedef struct VhostUserState { --- -2.27.0 - diff --git a/vhost-user-fs-Back-up-vqs-before-cleaning-up-vhost_d.patch b/vhost-user-fs-Back-up-vqs-before-cleaning-up-vhost_d.patch deleted file mode 100644 index 3d9f4c575026e47dc712786fbb069fccea62c36c..0000000000000000000000000000000000000000 --- a/vhost-user-fs-Back-up-vqs-before-cleaning-up-vhost_d.patch +++ /dev/null @@ -1,43 +0,0 @@ -From d48beee81ba11b6bc5151f4f882a9fe2ff9b1d2c Mon Sep 17 00:00:00 2001 -From: dinglimin_yewu -Date: Thu, 28 Sep 2023 16:07:30 +0800 -Subject: [PATCH] vhost-user-fs: Back up vqs before cleaning up vhost_dev - -cheery-pick from 331acddc87b739c64b936ba4e58518f8491f1c6b - -vhost_dev_cleanup() clears vhost_dev so back up its vqs member to free the memory pointed by the member. - -Fixes: 98fc1ada4c ("virtio: add vhost-user-fs base device") -Signed-off-by: Akihiko Odaki -Signed-off-by: Stefan Hajnoczi -Message-Id: <20230130140225.77964-1-akihiko.odaki at daynix.com> -Signed-off-by: dinglimin_yewu ---- - hw/virtio/vhost-user-fs.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c -index c595957983..fc7dcc96ef 100644 ---- a/hw/virtio/vhost-user-fs.c -+++ b/hw/virtio/vhost-user-fs.c -@@ -258,6 +258,7 @@ static void vuf_device_unrealize(DeviceState *dev) - { - VirtIODevice *vdev = VIRTIO_DEVICE(dev); - VHostUserFS *fs = VHOST_USER_FS(dev); -+ struct vhost_virtqueue *vhost_vqs = fs->vhost_dev.vqs; - int i; - - /* This will stop vhost backend if appropriate. */ -@@ -273,8 +274,7 @@ static void vuf_device_unrealize(DeviceState *dev) - } - g_free(fs->req_vqs); - virtio_cleanup(vdev); -- g_free(fs->vhost_dev.vqs); -- fs->vhost_dev.vqs = NULL; -+ g_free(vhost_vqs); - } - - static const VMStateDescription vuf_vmstate = { --- -2.41.0.windows.1 - diff --git a/vhost-user-quit-infinite-loop-while-used-memslots-is.patch b/vhost-user-quit-infinite-loop-while-used-memslots-is.patch deleted file mode 100644 index e6990e38165989e32f2c9b443187e805edcbb23b..0000000000000000000000000000000000000000 --- a/vhost-user-quit-infinite-loop-while-used-memslots-is.patch +++ /dev/null @@ -1,88 +0,0 @@ -From f46191f24706a6200cfe607a902b3da45f57c9ad Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Fri, 11 Feb 2022 19:24:30 +0800 -Subject: [PATCH] vhost-user: quit infinite loop while used memslots is more - than the backend limit - -When used memslots is more than the backend limit, -the vhost-user netcard would attach fail and quit -infinite loop. - -Signed-off-by: Jinhua Cao ---- - hw/virtio/vhost.c | 9 +++++++++ - include/hw/virtio/vhost.h | 1 + - net/vhost-user.c | 6 ++++++ - 3 files changed, 16 insertions(+) - -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index e4809777bc..4c4072951c 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -48,6 +48,8 @@ static struct vhost_log *vhost_log_shm; - static QLIST_HEAD(, vhost_dev) vhost_devices = - QLIST_HEAD_INITIALIZER(vhost_devices); - -+bool used_memslots_exceeded; -+ - bool vhost_has_free_slot(void) - { - struct vhost_dev *hdev; -@@ -1336,9 +1338,11 @@ static bool vhost_dev_used_memslots_is_exceeded(struct vhost_dev *hdev) - hdev->vhost_ops->vhost_backend_memslots_limit(hdev)) { - error_report("vhost backend memory slots limit is less" - " than current number of present memory slots"); -+ used_memslots_exceeded = true; - return true; - } - -+ used_memslots_exceeded = false; - return false; - } - -@@ -1895,3 +1899,8 @@ int vhost_net_set_backend(struct vhost_dev *hdev, - - return -1; - } -+ -+bool used_memslots_is_exceeded(void) -+{ -+ return used_memslots_exceeded; -+} -diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h -index 58a73e7b7a..86f36f0106 100644 ---- a/include/hw/virtio/vhost.h -+++ b/include/hw/virtio/vhost.h -@@ -154,4 +154,5 @@ int vhost_dev_set_inflight(struct vhost_dev *dev, - struct vhost_inflight *inflight); - int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size, - struct vhost_inflight *inflight); -+bool used_memslots_is_exceeded(void); - #endif -diff --git a/net/vhost-user.c b/net/vhost-user.c -index d1aefcb9aa..f910a286e4 100644 ---- a/net/vhost-user.c -+++ b/net/vhost-user.c -@@ -20,6 +20,7 @@ - #include "qemu/error-report.h" - #include "qemu/option.h" - #include "trace.h" -+#include "include/hw/virtio/vhost.h" - - #define VHOST_USER_RECONNECT_TIME (3) - -@@ -369,6 +370,11 @@ static int net_vhost_user_init(NetClientState *peer, const char *device, - qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, - net_vhost_user_event, NULL, nc0->name, NULL, - true); -+ if (used_memslots_is_exceeded()) { -+ error_report("used memslots exceeded the backend limit, quit " -+ "loop"); -+ goto err; -+ } - } while (!s->started); - - assert(s->vhost_net); --- -2.27.0 - diff --git a/vhost-user-remove-VirtQ-notifier-restore.patch b/vhost-user-remove-VirtQ-notifier-restore.patch deleted file mode 100644 index fae278a626c64d38606d692ad9febf2c2866ab36..0000000000000000000000000000000000000000 --- a/vhost-user-remove-VirtQ-notifier-restore.patch +++ /dev/null @@ -1,100 +0,0 @@ -From f06e65cb747cbd32f4d12f1d880625c14a8bd9da Mon Sep 17 00:00:00 2001 -From: Xueming Li -Date: Mon, 7 Feb 2022 15:19:28 +0800 -Subject: [PATCH 1/2] vhost-user: remove VirtQ notifier restore - -Notifier set when vhost-user backend asks qemu to mmap an FD and -offset. When vhost-user backend restart or getting killed, VQ notifier -FD and mmap addresses become invalid. After backend restart, MR contains -the invalid address will be restored and fail on notifier access. - -On the other hand, qemu should munmap the notifier, release underlying -hardware resources to enable backend restart and allocate hardware -notifier resources correctly. - -Qemu shouldn't reference and use resources of disconnected backend. - -This patch removes VQ notifier restore, uses the default vhost-user -notifier to avoid invalid address access. - -After backend restart, the backend should ask qemu to install a hardware -notifier if needed. - -Fixes: 44866521bd6e ("vhost-user: support registering external host notifiers") -Cc: qemu-stable@nongnu.org -Signed-off-by: Xueming Li -Message-Id: <20220207071929.527149-2-xuemingl@nvidia.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit e867144b73b3c5009266b6df07d5ff44acfb82c3) ---- - hw/virtio/vhost-user.c | 19 +------------------ - include/hw/virtio/vhost-user.h | 1 - - 2 files changed, 1 insertion(+), 19 deletions(-) - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index 176cae9244..7b21e09723 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -1145,19 +1145,6 @@ static int vhost_user_set_vring_num(struct vhost_dev *dev, - return vhost_set_vring(dev, VHOST_USER_SET_VRING_NUM, ring); - } - --static void vhost_user_host_notifier_restore(struct vhost_dev *dev, -- int queue_idx) --{ -- struct vhost_user *u = dev->opaque; -- VhostUserHostNotifier *n = &u->user->notifier[queue_idx]; -- VirtIODevice *vdev = dev->vdev; -- -- if (n->addr && !n->set) { -- virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true); -- n->set = true; -- } --} -- - static void vhost_user_host_notifier_remove(struct vhost_dev *dev, - int queue_idx) - { -@@ -1165,17 +1152,14 @@ static void vhost_user_host_notifier_remove(struct vhost_dev *dev, - VhostUserHostNotifier *n = &u->user->notifier[queue_idx]; - VirtIODevice *vdev = dev->vdev; - -- if (n->addr && n->set) { -+ if (n->addr) { - virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, false); -- n->set = false; - } - } - - static int vhost_user_set_vring_base(struct vhost_dev *dev, - struct vhost_vring_state *ring) - { -- vhost_user_host_notifier_restore(dev, ring->index); -- - return vhost_set_vring(dev, VHOST_USER_SET_VRING_BASE, ring); - } - -@@ -1540,7 +1524,6 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, - } - - n->addr = addr; -- n->set = true; - - return 0; - } -diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h -index a9abca3288..f6012b2078 100644 ---- a/include/hw/virtio/vhost-user.h -+++ b/include/hw/virtio/vhost-user.h -@@ -14,7 +14,6 @@ - typedef struct VhostUserHostNotifier { - MemoryRegion mr; - void *addr; -- bool set; - } VhostUserHostNotifier; - - typedef struct VhostUserState { --- -2.27.0 - diff --git a/vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch b/vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch deleted file mode 100644 index 8d54935e19501bf8eda7b896bf937cd68f0b161d..0000000000000000000000000000000000000000 --- a/vhost-user-scsi-add-support-for-SPDK-hot-upgrade.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 8c52233c08fe66b2e5c79fd514d4f804aa6fe427 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Fri, 11 Feb 2022 20:13:50 +0800 -Subject: [PATCH] vhost-user-scsi: add support for SPDK hot upgrade - -In the hot upgrade scenario, the reconnection mechanism of qemu and SPDK after upgrade - -Signed-off-by: Jinhua Cao ---- - hw/scsi/vhost-user-scsi.c | 42 ++++++++++++++++++++++++++++++++++++++- - 1 file changed, 41 insertions(+), 1 deletion(-) - -diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c -index 1b2f7eed98..052740a76e 100644 ---- a/hw/scsi/vhost-user-scsi.c -+++ b/hw/scsi/vhost-user-scsi.c -@@ -29,6 +29,9 @@ - #include "hw/virtio/virtio-access.h" - #include "chardev/char-fe.h" - #include "sysemu/sysemu.h" -+#include "qemu/log.h" -+ -+#define VHOST_USER_SCSI_RECONNECT_TIME 3 - - /* Features supported by the host application */ - static const int user_feature_bits[] = { -@@ -59,7 +62,7 @@ static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) - ret = vhost_scsi_common_start(vsc); - if (ret < 0) { - error_report("unable to start vhost-user-scsi: %s", strerror(-ret)); -- exit(1); -+ return; - } - } else { - vhost_scsi_common_stop(vsc); -@@ -89,11 +92,43 @@ static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq) - { - } - -+static void vhost_user_scsi_event(void *opaque, QEMUChrEvent event) -+{ -+ int ret; -+ VHostUserSCSI *s = (VHostUserSCSI *)opaque; -+ VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); -+ VirtIODevice *vdev = VIRTIO_DEVICE(s); -+ -+ qemu_log("event:%d, vdev status:%d\n", event, vdev->status); -+ -+ /* if CHR_EVENT_CLOSED, do nothing */ -+ if (event != CHR_EVENT_OPENED) { -+ return; -+ }; -+ -+ /* if status of vdev is not DRIVER_OK, just waiting. -+ * vsc should start when status change to DRIVER_OK */ -+ if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { -+ return; -+ } -+ -+ /* vsc may not fully start because of vhost app stopping */ -+ if (vsc->dev.started) { -+ vhost_scsi_common_stop(vsc); -+ } -+ -+ ret = vhost_scsi_common_start(vsc); -+ if (ret < 0) { -+ qemu_log("unable to start vhost-user-scsi: %s\n", strerror(-ret)); -+ } -+} -+ - static void vhost_user_scsi_realize(DeviceState *dev, Error **errp) - { - VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev); - VHostUserSCSI *s = VHOST_USER_SCSI(dev); - VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); -+ Chardev *chr; - struct vhost_virtqueue *vqs = NULL; - Error *err = NULL; - int ret; -@@ -132,6 +167,11 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp) - vsc->lun = 0; - vsc->target = vs->conf.boot_tpgt; - -+ chr = qemu_chr_fe_get_driver(&vs->conf.chardev); -+ qemu_chr_set_reconnect_time(chr, VHOST_USER_SCSI_RECONNECT_TIME); -+ qemu_chr_fe_set_handlers(&vs->conf.chardev, NULL, NULL, -+ vhost_user_scsi_event, NULL, s, NULL, true); -+ - return; - - free_vhost: --- -2.27.0 - diff --git a/vhost-user-stick-to-errno-error-return-convention.patch b/vhost-user-stick-to-errno-error-return-convention.patch deleted file mode 100644 index 037c3a28415b4685ee875906dfa72d85e3c79c3b..0000000000000000000000000000000000000000 --- a/vhost-user-stick-to-errno-error-return-convention.patch +++ /dev/null @@ -1,1100 +0,0 @@ -From f6c384a73aaaa7dfc52ed3ceb8ec135f33551629 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:55 +0800 -Subject: [PATCH] vhost-user: stick to -errno error return convention - -VhostOps methods in user_ops are not very consistent in their error -returns: some return negated errno while others just -1. - -Make sure all of them consistently return negated errno. This also -helps error propagation from the functions being called inside. -Besides, this synchronizes the error return convention with the other -two vhost backends, kernel and vdpa, and will therefore allow for -consistent error propagation in the generic vhost code (in a followup -patch). - -Signed-off-by: Roman Kagan -Message-Id: <20211111153354.18807-9-rvkagan@yandex-team.ru> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-user.c | 401 +++++++++++++++++++++++------------------ - 1 file changed, 223 insertions(+), 178 deletions(-) - -diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c -index 24f80d5d18..358dc82010 100644 ---- a/hw/virtio/vhost-user.c -+++ b/hw/virtio/vhost-user.c -@@ -283,9 +283,10 @@ static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg) - - r = qemu_chr_fe_read_all(chr, p, size); - if (r != size) { -+ int saved_errno = errno; - error_report("Failed to read msg header. Read %d instead of %d." - " Original request %d.", r, size, msg->hdr.request); -- return -1; -+ return r < 0 ? -saved_errno : -EIO; - } - - /* validate received flags */ -@@ -293,7 +294,7 @@ static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg) - error_report("Failed to read msg header." - " Flags 0x%x instead of 0x%x.", msg->hdr.flags, - VHOST_USER_REPLY_MASK | VHOST_USER_VERSION); -- return -1; -+ return -EPROTO; - } - - return 0; -@@ -317,8 +318,9 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition, - uint8_t *p = (uint8_t *) msg; - int r, size; - -- if (vhost_user_read_header(dev, msg) < 0) { -- data->ret = -1; -+ r = vhost_user_read_header(dev, msg); -+ if (r < 0) { -+ data->ret = r; - goto end; - } - -@@ -327,7 +329,7 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition, - error_report("Failed to read msg header." - " Size %d exceeds the maximum %zu.", msg->hdr.size, - VHOST_USER_PAYLOAD_SIZE); -- data->ret = -1; -+ data->ret = -EPROTO; - goto end; - } - -@@ -336,9 +338,10 @@ static gboolean vhost_user_read_cb(void *do_not_use, GIOCondition condition, - size = msg->hdr.size; - r = qemu_chr_fe_read_all(chr, p, size); - if (r != size) { -+ int saved_errno = errno; - error_report("Failed to read msg payload." - " Read %d instead of %d.", r, msg->hdr.size); -- data->ret = -1; -+ data->ret = r < 0 ? -saved_errno : -EIO; - goto end; - } - } -@@ -421,24 +424,26 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg) - static int process_message_reply(struct vhost_dev *dev, - const VhostUserMsg *msg) - { -+ int ret; - VhostUserMsg msg_reply; - - if ((msg->hdr.flags & VHOST_USER_NEED_REPLY_MASK) == 0) { - return 0; - } - -- if (vhost_user_read(dev, &msg_reply) < 0) { -- return -1; -+ ret = vhost_user_read(dev, &msg_reply); -+ if (ret < 0) { -+ return ret; - } - - if (msg_reply.hdr.request != msg->hdr.request) { - error_report("Received unexpected msg type. " - "Expected %d received %d", - msg->hdr.request, msg_reply.hdr.request); -- return -1; -+ return -EPROTO; - } - -- return msg_reply.payload.u64 ? -1 : 0; -+ return msg_reply.payload.u64 ? -EIO : 0; - } - - static bool vhost_user_one_time_request(VhostUserRequest request) -@@ -475,14 +480,15 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg, - - if (qemu_chr_fe_set_msgfds(chr, fds, fd_num) < 0) { - error_report("Failed to set msg fds."); -- return -1; -+ return -EINVAL; - } - - ret = qemu_chr_fe_write_all(chr, (const uint8_t *) msg, size); - if (ret != size) { -+ int saved_errno = errno; - error_report("Failed to write msg." - " Wrote %d instead of %d.", ret, size); -- return -1; -+ return ret < 0 ? -saved_errno : -EIO; - } - - return 0; -@@ -505,6 +511,7 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base, - size_t fd_num = 0; - bool shmfd = virtio_has_feature(dev->protocol_features, - VHOST_USER_PROTOCOL_F_LOG_SHMFD); -+ int ret; - VhostUserMsg msg = { - .hdr.request = VHOST_USER_SET_LOG_BASE, - .hdr.flags = VHOST_USER_VERSION, -@@ -517,21 +524,23 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base, - fds[fd_num++] = log->fd; - } - -- if (vhost_user_write(dev, &msg, fds, fd_num) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, fds, fd_num); -+ if (ret < 0) { -+ return ret; - } - - if (shmfd) { - msg.hdr.size = 0; -- if (vhost_user_read(dev, &msg) < 0) { -- return -1; -+ ret = vhost_user_read(dev, &msg); -+ if (ret < 0) { -+ return ret; - } - - if (msg.hdr.request != VHOST_USER_SET_LOG_BASE) { - error_report("Received unexpected msg type. " - "Expected %d received %d", - VHOST_USER_SET_LOG_BASE, msg.hdr.request); -- return -1; -+ return -EPROTO; - } - } - -@@ -591,7 +600,7 @@ static int vhost_user_fill_set_mem_table_msg(struct vhost_user *u, - u->region_rb[i] = mr->ram_block; - } else if (*fd_num == VHOST_MEMORY_BASELINE_NREGIONS) { - error_report("Failed preparing vhost-user memory table msg"); -- return -1; -+ return -ENOBUFS; - } - vhost_user_fill_msg_region(®ion_buffer, reg, offset); - msg->payload.memory.regions[*fd_num] = region_buffer; -@@ -607,14 +616,14 @@ static int vhost_user_fill_set_mem_table_msg(struct vhost_user *u, - if (!*fd_num) { - error_report("Failed initializing vhost-user memory map, " - "consider using -object memory-backend-file share=on"); -- return -1; -+ return -EINVAL; - } - - msg->hdr.size = sizeof(msg->payload.memory.nregions); - msg->hdr.size += sizeof(msg->payload.memory.padding); - msg->hdr.size += *fd_num * sizeof(VhostUserMemoryRegion); - -- return 1; -+ return 0; - } - - static inline bool reg_equal(struct vhost_memory_region *shadow_reg, -@@ -744,8 +753,9 @@ static int send_remove_regions(struct vhost_dev *dev, - vhost_user_fill_msg_region(®ion_buffer, shadow_reg, 0); - msg->payload.mem_reg.region = region_buffer; - -- if (vhost_user_write(dev, msg, &fd, 1) < 0) { -- return -1; -+ ret = vhost_user_write(dev, msg, &fd, 1); -+ if (ret < 0) { -+ return ret; - } - - if (reply_supported) { -@@ -804,15 +814,17 @@ static int send_add_regions(struct vhost_dev *dev, - vhost_user_fill_msg_region(®ion_buffer, reg, offset); - msg->payload.mem_reg.region = region_buffer; - -- if (vhost_user_write(dev, msg, &fd, 1) < 0) { -- return -1; -+ ret = vhost_user_write(dev, msg, &fd, 1); -+ if (ret < 0) { -+ return ret; - } - - if (track_ramblocks) { - uint64_t reply_gpa; - -- if (vhost_user_read(dev, &msg_reply) < 0) { -- return -1; -+ ret = vhost_user_read(dev, &msg_reply); -+ if (ret < 0) { -+ return ret; - } - - reply_gpa = msg_reply.payload.mem_reg.region.guest_phys_addr; -@@ -822,7 +834,7 @@ static int send_add_regions(struct vhost_dev *dev, - "Expected %d received %d", __func__, - VHOST_USER_ADD_MEM_REG, - msg_reply.hdr.request); -- return -1; -+ return -EPROTO; - } - - /* -@@ -833,7 +845,7 @@ static int send_add_regions(struct vhost_dev *dev, - error_report("%s: Unexpected size for postcopy reply " - "%d vs %d", __func__, msg_reply.hdr.size, - msg->hdr.size); -- return -1; -+ return -EPROTO; - } - - /* Get the postcopy client base from the backend's reply. */ -@@ -849,7 +861,7 @@ static int send_add_regions(struct vhost_dev *dev, - "Got guest physical address %" PRIX64 ", expected " - "%" PRIX64, __func__, reply_gpa, - dev->mem->regions[reg_idx].guest_phys_addr); -- return -1; -+ return -EPROTO; - } - } else if (reply_supported) { - ret = process_message_reply(dev, msg); -@@ -890,6 +902,7 @@ static int vhost_user_add_remove_regions(struct vhost_dev *dev, - struct scrub_regions rem_reg[VHOST_USER_MAX_RAM_SLOTS]; - uint64_t shadow_pcb[VHOST_USER_MAX_RAM_SLOTS] = {}; - int nr_add_reg, nr_rem_reg; -+ int ret; - - msg->hdr.size = sizeof(msg->payload.mem_reg); - -@@ -897,16 +910,20 @@ static int vhost_user_add_remove_regions(struct vhost_dev *dev, - scrub_shadow_regions(dev, add_reg, &nr_add_reg, rem_reg, &nr_rem_reg, - shadow_pcb, track_ramblocks); - -- if (nr_rem_reg && send_remove_regions(dev, rem_reg, nr_rem_reg, msg, -- reply_supported) < 0) -- { -- goto err; -+ if (nr_rem_reg) { -+ ret = send_remove_regions(dev, rem_reg, nr_rem_reg, msg, -+ reply_supported); -+ if (ret < 0) { -+ goto err; -+ } - } - -- if (nr_add_reg && send_add_regions(dev, add_reg, nr_add_reg, msg, -- shadow_pcb, reply_supported, track_ramblocks) < 0) -- { -- goto err; -+ if (nr_add_reg) { -+ ret = send_add_regions(dev, add_reg, nr_add_reg, msg, shadow_pcb, -+ reply_supported, track_ramblocks); -+ if (ret < 0) { -+ goto err; -+ } - } - - if (track_ramblocks) { -@@ -921,8 +938,9 @@ static int vhost_user_add_remove_regions(struct vhost_dev *dev, - msg->hdr.size = sizeof(msg->payload.u64); - msg->payload.u64 = 0; /* OK */ - -- if (vhost_user_write(dev, msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - } - -@@ -934,7 +952,7 @@ err: - sizeof(uint64_t) * VHOST_USER_MAX_RAM_SLOTS); - } - -- return -1; -+ return ret; - } - - static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev, -@@ -947,6 +965,7 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev, - size_t fd_num = 0; - VhostUserMsg msg_reply; - int region_i, msg_i; -+ int ret; - - VhostUserMsg msg = { - .hdr.flags = VHOST_USER_VERSION, -@@ -964,29 +983,32 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev, - } - - if (config_mem_slots) { -- if (vhost_user_add_remove_regions(dev, &msg, reply_supported, -- true) < 0) { -- return -1; -+ ret = vhost_user_add_remove_regions(dev, &msg, reply_supported, true); -+ if (ret < 0) { -+ return ret; - } - } else { -- if (vhost_user_fill_set_mem_table_msg(u, dev, &msg, fds, &fd_num, -- true) < 0) { -- return -1; -+ ret = vhost_user_fill_set_mem_table_msg(u, dev, &msg, fds, &fd_num, -+ true); -+ if (ret < 0) { -+ return ret; - } - -- if (vhost_user_write(dev, &msg, fds, fd_num) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, fds, fd_num); -+ if (ret < 0) { -+ return ret; - } - -- if (vhost_user_read(dev, &msg_reply) < 0) { -- return -1; -+ ret = vhost_user_read(dev, &msg_reply); -+ if (ret < 0) { -+ return ret; - } - - if (msg_reply.hdr.request != VHOST_USER_SET_MEM_TABLE) { - error_report("%s: Received unexpected msg type." - "Expected %d received %d", __func__, - VHOST_USER_SET_MEM_TABLE, msg_reply.hdr.request); -- return -1; -+ return -EPROTO; - } - - /* -@@ -997,7 +1019,7 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev, - error_report("%s: Unexpected size for postcopy reply " - "%d vs %d", __func__, msg_reply.hdr.size, - msg.hdr.size); -- return -1; -+ return -EPROTO; - } - - memset(u->postcopy_client_bases, 0, -@@ -1027,7 +1049,7 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev, - error_report("%s: postcopy reply not fully consumed " - "%d vs %zd", - __func__, msg_i, fd_num); -- return -1; -+ return -EIO; - } - - /* -@@ -1038,8 +1060,9 @@ static int vhost_user_set_mem_table_postcopy(struct vhost_dev *dev, - /* TODO: Use this for failure cases as well with a bad value. */ - msg.hdr.size = sizeof(msg.payload.u64); - msg.payload.u64 = 0; /* OK */ -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - } - -@@ -1058,6 +1081,7 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev, - bool config_mem_slots = - virtio_has_feature(dev->protocol_features, - VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS); -+ int ret; - - if (do_postcopy) { - /* -@@ -1077,17 +1101,20 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev, - } - - if (config_mem_slots) { -- if (vhost_user_add_remove_regions(dev, &msg, reply_supported, -- false) < 0) { -- return -1; -+ ret = vhost_user_add_remove_regions(dev, &msg, reply_supported, false); -+ if (ret < 0) { -+ return ret; - } - } else { -- if (vhost_user_fill_set_mem_table_msg(u, dev, &msg, fds, &fd_num, -- false) < 0) { -- return -1; -+ ret = vhost_user_fill_set_mem_table_msg(u, dev, &msg, fds, &fd_num, -+ false); -+ if (ret < 0) { -+ return ret; - } -- if (vhost_user_write(dev, &msg, fds, fd_num) < 0) { -- return -1; -+ -+ ret = vhost_user_write(dev, &msg, fds, fd_num); -+ if (ret < 0) { -+ return ret; - } - - if (reply_supported) { -@@ -1112,14 +1139,10 @@ static int vhost_user_set_vring_endian(struct vhost_dev *dev, - - if (!cross_endian) { - error_report("vhost-user trying to send unhandled ioctl"); -- return -1; -+ return -ENOTSUP; - } - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -- } -- -- return 0; -+ return vhost_user_write(dev, &msg, NULL, 0); - } - - static int vhost_set_vring(struct vhost_dev *dev, -@@ -1133,11 +1156,7 @@ static int vhost_set_vring(struct vhost_dev *dev, - .hdr.size = sizeof(msg.payload.state), - }; - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -- } -- -- return 0; -+ return vhost_user_write(dev, &msg, NULL, 0); - } - - static int vhost_user_set_vring_num(struct vhost_dev *dev, -@@ -1180,16 +1199,25 @@ static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable) - int i; - - if (!virtio_has_feature(dev->features, VHOST_USER_F_PROTOCOL_FEATURES)) { -- return -1; -+ return -EINVAL; - } - - for (i = 0; i < dev->nvqs; ++i) { -+ int ret; - struct vhost_vring_state state = { - .index = dev->vq_index + i, - .num = enable, - }; - -- vhost_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, &state); -+ ret = vhost_set_vring(dev, VHOST_USER_SET_VRING_ENABLE, &state); -+ if (ret < 0) { -+ /* -+ * Restoring the previous state is likely infeasible, as well as -+ * proceeding regardless the error, so just bail out and hope for -+ * the device-level recovery. -+ */ -+ return ret; -+ } - } - - return 0; -@@ -1198,6 +1226,7 @@ static int vhost_user_set_vring_enable(struct vhost_dev *dev, int enable) - static int vhost_user_get_vring_base(struct vhost_dev *dev, - struct vhost_vring_state *ring) - { -+ int ret; - VhostUserMsg msg = { - .hdr.request = VHOST_USER_GET_VRING_BASE, - .hdr.flags = VHOST_USER_VERSION, -@@ -1208,23 +1237,25 @@ static int vhost_user_get_vring_base(struct vhost_dev *dev, - - vhost_user_host_notifier_remove(u->user, dev->vdev, ring->index); - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - -- if (vhost_user_read(dev, &msg) < 0) { -- return -1; -+ ret = vhost_user_read(dev, &msg); -+ if (ret < 0) { -+ return ret; - } - - if (msg.hdr.request != VHOST_USER_GET_VRING_BASE) { - error_report("Received unexpected msg type. Expected %d received %d", - VHOST_USER_GET_VRING_BASE, msg.hdr.request); -- return -1; -+ return -EPROTO; - } - - if (msg.hdr.size != sizeof(msg.payload.state)) { - error_report("Received bad msg size."); -- return -1; -+ return -EPROTO; - } - - *ring = msg.payload.state; -@@ -1251,11 +1282,7 @@ static int vhost_set_vring_file(struct vhost_dev *dev, - msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK; - } - -- if (vhost_user_write(dev, &msg, fds, fd_num) < 0) { -- return -1; -- } -- -- return 0; -+ return vhost_user_write(dev, &msg, fds, fd_num); - } - - static int vhost_user_set_vring_kick(struct vhost_dev *dev, -@@ -1273,6 +1300,7 @@ static int vhost_user_set_vring_call(struct vhost_dev *dev, - - static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64) - { -+ int ret; - VhostUserMsg msg = { - .hdr.request = request, - .hdr.flags = VHOST_USER_VERSION, -@@ -1282,23 +1310,25 @@ static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64) - return 0; - } - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - -- if (vhost_user_read(dev, &msg) < 0) { -- return -1; -+ ret = vhost_user_read(dev, &msg); -+ if (ret < 0) { -+ return ret; - } - - if (msg.hdr.request != request) { - error_report("Received unexpected msg type. Expected %d received %d", - request, msg.hdr.request); -- return -1; -+ return -EPROTO; - } - - if (msg.hdr.size != sizeof(msg.payload.u64)) { - error_report("Received bad msg size."); -- return -1; -+ return -EPROTO; - } - - *u64 = msg.payload.u64; -@@ -1336,6 +1366,7 @@ static int enforce_reply(struct vhost_dev *dev, - static int vhost_user_set_vring_addr(struct vhost_dev *dev, - struct vhost_vring_addr *addr) - { -+ int ret; - VhostUserMsg msg = { - .hdr.request = VHOST_USER_SET_VRING_ADDR, - .hdr.flags = VHOST_USER_VERSION, -@@ -1356,8 +1387,9 @@ static int vhost_user_set_vring_addr(struct vhost_dev *dev, - msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK; - } - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - - if (wait_for_reply) { -@@ -1376,6 +1408,7 @@ static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64, - .payload.u64 = u64, - .hdr.size = sizeof(msg.payload.u64), - }; -+ int ret; - - if (wait_for_reply) { - bool reply_supported = virtio_has_feature(dev->protocol_features, -@@ -1385,8 +1418,9 @@ static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64, - } - } - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - - if (wait_for_reply) { -@@ -1423,11 +1457,7 @@ static int vhost_user_set_owner(struct vhost_dev *dev) - .hdr.flags = VHOST_USER_VERSION, - }; - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -EPROTO; -- } -- -- return 0; -+ return vhost_user_write(dev, &msg, NULL, 0); - } - - static int vhost_user_get_max_memslots(struct vhost_dev *dev, -@@ -1458,26 +1488,16 @@ static int vhost_user_reset_device(struct vhost_dev *dev) - ? VHOST_USER_RESET_DEVICE - : VHOST_USER_RESET_OWNER; - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -- } -- -- return 0; -+ return vhost_user_write(dev, &msg, NULL, 0); - } - - static int vhost_user_slave_handle_config_change(struct vhost_dev *dev) - { -- int ret = -1; -- -- if (!dev->config_ops) { -- return -1; -+ if (!dev->config_ops || !dev->config_ops->vhost_dev_config_notifier) { -+ return -ENOSYS; - } - -- if (dev->config_ops->vhost_dev_config_notifier) { -- ret = dev->config_ops->vhost_dev_config_notifier(dev); -- } -- -- return ret; -+ return dev->config_ops->vhost_dev_config_notifier(dev); - } - - static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, -@@ -1496,7 +1516,7 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, - if (!virtio_has_feature(dev->protocol_features, - VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) || - vdev == NULL || queue_idx >= virtio_get_num_queues(vdev)) { -- return -1; -+ return -EINVAL; - } - - n = &user->notifier[queue_idx]; -@@ -1509,13 +1529,13 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, - - /* Sanity check. */ - if (area->size != page_size) { -- return -1; -+ return -EINVAL; - } - - addr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, - fd, area->offset); - if (addr == MAP_FAILED) { -- return -1; -+ return -EFAULT; - } - - name = g_strdup_printf("vhost-user/host-notifier@%p mmaps[%d]", -@@ -1531,7 +1551,7 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev, - if (virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true)) { - object_unparent(OBJECT(&n->mr)); - munmap(addr, page_size); -- return -1; -+ return -ENXIO; - } - - n->addr = addr; -@@ -1660,14 +1680,15 @@ static int vhost_setup_slave_channel(struct vhost_dev *dev) - } - - if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) { -+ int saved_errno = errno; - error_report("socketpair() failed"); -- return -1; -+ return -saved_errno; - } - - ioc = QIO_CHANNEL(qio_channel_socket_new_fd(sv[0], &local_err)); - if (!ioc) { - error_report_err(local_err); -- return -1; -+ return -ECONNREFUSED; - } - u->slave_ioc = ioc; - slave_update_read_handler(dev, NULL); -@@ -1774,35 +1795,38 @@ static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp) - struct vhost_user *u = dev->opaque; - CharBackend *chr = u->user->chr; - int ufd; -+ int ret; - VhostUserMsg msg = { - .hdr.request = VHOST_USER_POSTCOPY_ADVISE, - .hdr.flags = VHOST_USER_VERSION, - }; - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { - error_setg(errp, "Failed to send postcopy_advise to vhost"); -- return -1; -+ return ret; - } - -- if (vhost_user_read(dev, &msg) < 0) { -+ ret = vhost_user_read(dev, &msg); -+ if (ret < 0) { - error_setg(errp, "Failed to get postcopy_advise reply from vhost"); -- return -1; -+ return ret; - } - - if (msg.hdr.request != VHOST_USER_POSTCOPY_ADVISE) { - error_setg(errp, "Unexpected msg type. Expected %d received %d", - VHOST_USER_POSTCOPY_ADVISE, msg.hdr.request); -- return -1; -+ return -EPROTO; - } - - if (msg.hdr.size) { - error_setg(errp, "Received bad msg size."); -- return -1; -+ return -EPROTO; - } - ufd = qemu_chr_fe_get_msgfd(chr); - if (ufd < 0) { - error_setg(errp, "%s: Failed to get ufd", __func__); -- return -1; -+ return -EIO; - } - qemu_set_nonblock(ufd); - -@@ -1816,7 +1840,7 @@ static int vhost_user_postcopy_advise(struct vhost_dev *dev, Error **errp) - return 0; - #else - error_setg(errp, "Postcopy not supported on non-Linux systems"); -- return -1; -+ return -ENOSYS; - #endif - } - -@@ -1832,10 +1856,13 @@ static int vhost_user_postcopy_listen(struct vhost_dev *dev, Error **errp) - .hdr.flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK, - }; - u->postcopy_listen = true; -+ - trace_vhost_user_postcopy_listen(); -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -+ -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { - error_setg(errp, "Failed to send postcopy_listen to vhost"); -- return -1; -+ return ret; - } - - ret = process_message_reply(dev, &msg); -@@ -1860,9 +1887,11 @@ static int vhost_user_postcopy_end(struct vhost_dev *dev, Error **errp) - struct vhost_user *u = dev->opaque; - - trace_vhost_user_postcopy_end_entry(); -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -+ -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { - error_setg(errp, "Failed to send postcopy_end to vhost"); -- return -1; -+ return ret; - } - - ret = process_message_reply(dev, &msg); -@@ -2141,7 +2170,7 @@ static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr) - - return vhost_user_write(dev, &msg, NULL, 0); - } -- return -1; -+ return -ENOTSUP; - } - - static bool vhost_user_can_merge(struct vhost_dev *dev, -@@ -2162,6 +2191,7 @@ static int vhost_user_net_set_mtu(struct vhost_dev *dev, uint16_t mtu) - VhostUserMsg msg; - bool reply_supported = virtio_has_feature(dev->protocol_features, - VHOST_USER_PROTOCOL_F_REPLY_ACK); -+ int ret; - - if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_NET_MTU))) { - return 0; -@@ -2175,8 +2205,9 @@ static int vhost_user_net_set_mtu(struct vhost_dev *dev, uint16_t mtu) - msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK; - } - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - - /* If reply_ack supported, slave has to ack specified MTU is valid */ -@@ -2190,6 +2221,7 @@ static int vhost_user_net_set_mtu(struct vhost_dev *dev, uint16_t mtu) - static int vhost_user_send_device_iotlb_msg(struct vhost_dev *dev, - struct vhost_iotlb_msg *imsg) - { -+ int ret; - VhostUserMsg msg = { - .hdr.request = VHOST_USER_IOTLB_MSG, - .hdr.size = sizeof(msg.payload.iotlb), -@@ -2197,8 +2229,9 @@ static int vhost_user_send_device_iotlb_msg(struct vhost_dev *dev, - .payload.iotlb = *imsg, - }; - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -EFAULT; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - - return process_message_reply(dev, &msg); -@@ -2213,6 +2246,7 @@ static void vhost_user_set_iotlb_callback(struct vhost_dev *dev, int enabled) - static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config, - uint32_t config_len, Error **errp) - { -+ int ret; - VhostUserMsg msg = { - .hdr.request = VHOST_USER_GET_CONFIG, - .hdr.flags = VHOST_USER_VERSION, -@@ -2229,26 +2263,28 @@ static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config, - - msg.payload.config.offset = 0; - msg.payload.config.size = config_len; -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- error_setg_errno(errp, EPROTO, "vhost_get_config failed"); -- return -EPROTO; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ error_setg_errno(errp, -ret, "vhost_get_config failed"); -+ return ret; - } - -- if (vhost_user_read(dev, &msg) < 0) { -- error_setg_errno(errp, EPROTO, "vhost_get_config failed"); -- return -EPROTO; -+ ret = vhost_user_read(dev, &msg); -+ if (ret < 0) { -+ error_setg_errno(errp, -ret, "vhost_get_config failed"); -+ return ret; - } - - if (msg.hdr.request != VHOST_USER_GET_CONFIG) { - error_setg(errp, - "Received unexpected msg type. Expected %d received %d", - VHOST_USER_GET_CONFIG, msg.hdr.request); -- return -EINVAL; -+ return -EPROTO; - } - - if (msg.hdr.size != VHOST_USER_CONFIG_HDR_SIZE + config_len) { - error_setg(errp, "Received bad msg size."); -- return -EINVAL; -+ return -EPROTO; - } - - memcpy(config, msg.payload.config.region, config_len); -@@ -2259,6 +2295,7 @@ static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config, - static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data, - uint32_t offset, uint32_t size, uint32_t flags) - { -+ int ret; - uint8_t *p; - bool reply_supported = virtio_has_feature(dev->protocol_features, - VHOST_USER_PROTOCOL_F_REPLY_ACK); -@@ -2271,7 +2308,7 @@ static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data, - - if (!virtio_has_feature(dev->protocol_features, - VHOST_USER_PROTOCOL_F_CONFIG)) { -- return -1; -+ return -ENOTSUP; - } - - if (reply_supported) { -@@ -2279,7 +2316,7 @@ static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data, - } - - if (size > VHOST_USER_MAX_CONFIG_SIZE) { -- return -1; -+ return -EINVAL; - } - - msg.payload.config.offset = offset, -@@ -2288,8 +2325,9 @@ static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data, - p = msg.payload.config.region; - memcpy(p, data, size); - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - - if (reply_supported) { -@@ -2303,6 +2341,7 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev, - void *session_info, - uint64_t *session_id) - { -+ int ret; - bool crypto_session = virtio_has_feature(dev->protocol_features, - VHOST_USER_PROTOCOL_F_CRYPTO_SESSION); - CryptoDevBackendSymSessionInfo *sess_info = session_info; -@@ -2316,7 +2355,7 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev, - - if (!crypto_session) { - error_report("vhost-user trying to send unhandled ioctl"); -- return -1; -+ return -ENOTSUP; - } - - memcpy(&msg.payload.session.session_setup_data, sess_info, -@@ -2329,31 +2368,35 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev, - memcpy(&msg.payload.session.auth_key, sess_info->auth_key, - sess_info->auth_key_len); - } -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- error_report("vhost_user_write() return -1, create session failed"); -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ error_report("vhost_user_write() return %d, create session failed", -+ ret); -+ return ret; - } - -- if (vhost_user_read(dev, &msg) < 0) { -- error_report("vhost_user_read() return -1, create session failed"); -- return -1; -+ ret = vhost_user_read(dev, &msg); -+ if (ret < 0) { -+ error_report("vhost_user_read() return %d, create session failed", -+ ret); -+ return ret; - } - - if (msg.hdr.request != VHOST_USER_CREATE_CRYPTO_SESSION) { - error_report("Received unexpected msg type. Expected %d received %d", - VHOST_USER_CREATE_CRYPTO_SESSION, msg.hdr.request); -- return -1; -+ return -EPROTO; - } - - if (msg.hdr.size != sizeof(msg.payload.session)) { - error_report("Received bad msg size."); -- return -1; -+ return -EPROTO; - } - - if (msg.payload.session.session_id < 0) { - error_report("Bad session id: %" PRId64 "", - msg.payload.session.session_id); -- return -1; -+ return -EINVAL; - } - *session_id = msg.payload.session.session_id; - -@@ -2363,6 +2406,7 @@ static int vhost_user_crypto_create_session(struct vhost_dev *dev, - static int - vhost_user_crypto_close_session(struct vhost_dev *dev, uint64_t session_id) - { -+ int ret; - bool crypto_session = virtio_has_feature(dev->protocol_features, - VHOST_USER_PROTOCOL_F_CRYPTO_SESSION); - VhostUserMsg msg = { -@@ -2374,12 +2418,14 @@ vhost_user_crypto_close_session(struct vhost_dev *dev, uint64_t session_id) - - if (!crypto_session) { - error_report("vhost-user trying to send unhandled ioctl"); -- return -1; -+ return -ENOTSUP; - } - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- error_report("vhost_user_write() return -1, close session failed"); -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ error_report("vhost_user_write() return %d, close session failed", -+ ret); -+ return ret; - } - - return 0; -@@ -2401,6 +2447,7 @@ static int vhost_user_get_inflight_fd(struct vhost_dev *dev, - { - void *addr; - int fd; -+ int ret; - struct vhost_user *u = dev->opaque; - CharBackend *chr = u->user->chr; - VhostUserMsg msg = { -@@ -2416,24 +2463,26 @@ static int vhost_user_get_inflight_fd(struct vhost_dev *dev, - return 0; - } - -- if (vhost_user_write(dev, &msg, NULL, 0) < 0) { -- return -1; -+ ret = vhost_user_write(dev, &msg, NULL, 0); -+ if (ret < 0) { -+ return ret; - } - -- if (vhost_user_read(dev, &msg) < 0) { -- return -1; -+ ret = vhost_user_read(dev, &msg); -+ if (ret < 0) { -+ return ret; - } - - if (msg.hdr.request != VHOST_USER_GET_INFLIGHT_FD) { - error_report("Received unexpected msg type. " - "Expected %d received %d", - VHOST_USER_GET_INFLIGHT_FD, msg.hdr.request); -- return -1; -+ return -EPROTO; - } - - if (msg.hdr.size != sizeof(msg.payload.inflight)) { - error_report("Received bad msg size."); -- return -1; -+ return -EPROTO; - } - - if (!msg.payload.inflight.mmap_size) { -@@ -2443,7 +2492,7 @@ static int vhost_user_get_inflight_fd(struct vhost_dev *dev, - fd = qemu_chr_fe_get_msgfd(chr); - if (fd < 0) { - error_report("Failed to get mem fd"); -- return -1; -+ return -EIO; - } - - addr = mmap(0, msg.payload.inflight.mmap_size, PROT_READ | PROT_WRITE, -@@ -2452,7 +2501,7 @@ static int vhost_user_get_inflight_fd(struct vhost_dev *dev, - if (addr == MAP_FAILED) { - error_report("Failed to mmap mem fd"); - close(fd); -- return -1; -+ return -EFAULT; - } - - inflight->addr = addr; -@@ -2482,11 +2531,7 @@ static int vhost_user_set_inflight_fd(struct vhost_dev *dev, - return 0; - } - -- if (vhost_user_write(dev, &msg, &inflight->fd, 1) < 0) { -- return -1; -- } -- -- return 0; -+ return vhost_user_write(dev, &msg, &inflight->fd, 1); - } - - bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp) --- -2.27.0 - diff --git a/vhost-vdpa-add-VHOST_BACKEND_F_BYTEMAPLOG.patch b/vhost-vdpa-add-VHOST_BACKEND_F_BYTEMAPLOG.patch deleted file mode 100644 index d40dd186cc2313bcf9321399b8d12f916066b473..0000000000000000000000000000000000000000 --- a/vhost-vdpa-add-VHOST_BACKEND_F_BYTEMAPLOG.patch +++ /dev/null @@ -1,49 +0,0 @@ -From b0c67874628455a869ca1afde0de44572c70d5b9 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 14:49:53 +0800 -Subject: [PATCH] vhost-vdpa: add VHOST_BACKEND_F_BYTEMAPLOG - -support VHOST_BACKEND_F_BYTEMAPLOG to support vhost -device bytemap logging. - -Signed-off-by: libai -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 7 ++++--- - include/standard-headers/linux/vhost_types.h | 2 ++ - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 986fc795bf..e1c90cf6c2 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -660,9 +660,10 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev, - static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) - { - uint64_t features; -- uint64_t f = 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2 | -- 0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH | -- 0x1ULL << VHOST_BACKEND_F_IOTLB_ASID; -+ uint64_t f = BIT_ULL(VHOST_BACKEND_F_IOTLB_MSG_V2) | -+ BIT_ULL(VHOST_BACKEND_F_IOTLB_BATCH) | -+ BIT_ULL(VHOST_BACKEND_F_IOTLB_ASID) | -+ BIT_ULL(VHOST_BACKEND_F_BYTEMAPLOG); - int r; - - if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) { -diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h -index 17833e320e..3801d95182 100644 ---- a/include/standard-headers/linux/vhost_types.h -+++ b/include/standard-headers/linux/vhost_types.h -@@ -157,5 +157,7 @@ struct vhost_vdpa_iova_range { - * message - */ - #define VHOST_BACKEND_F_IOTLB_ASID 0x3 -+/* device can use bytemap log */ -+#define VHOST_BACKEND_F_BYTEMAPLOG 0x3f - - #endif --- -2.27.0 - diff --git a/vhost-vdpa-add-memslot-getter-setter-for-vhost-vdpa.patch b/vhost-vdpa-add-memslot-getter-setter-for-vhost-vdpa.patch deleted file mode 100644 index 5a35b3d496a14d0b69c2077d851de4fd04b247b4..0000000000000000000000000000000000000000 --- a/vhost-vdpa-add-memslot-getter-setter-for-vhost-vdpa.patch +++ /dev/null @@ -1,70 +0,0 @@ -From f32dbb81662b5c74d1a929ff8a58fec6a920a34a Mon Sep 17 00:00:00 2001 -From: Pengyuan -Date: Mon, 7 Nov 2022 10:11:06 +0800 -Subject: [PATCH 7/7] vhost-vdpa: add memslot getter/setter for vhost-vdpa - -When vhost-vdpa is used as the virtio-net-pci backend on -the ARM64 platform, a null pointer access is triggered. - -#0 0x0000000000000000 in () -#1 0x0000aaaaab63bdcc in vhost_dev_used_memslots_is_exceeded (hdev=0xaaaaac632420) at ../hw/virtio/vhost.c:1341 -#2 0x0000aaaaab63c420 in vhost_dev_init (hdev=0xaaaaac632420, opaque=0xfffff4321190, backend_type=VHOST_BACKEND_TYPE_VDPA, busyloop_timeout=0, errp=0xfffffffff210) at ../hw/virtio/vhost.c:1461 -#3 0x0000aaaaab0d6ad8 in vhost_net_init (options=0xfffffffff290) at ../hw/net/vhost_net.c:247 -#4 0x0000aaaaaaf05f40 in vhost_vdpa_add (ncs=0xfffff4321010, be=0xfffff4321190, queue_pair_index=0, nvqs=2) at ../net/vhost-vdpa.c:109 -#5 0x0000aaaaaaf06358 in net_vhost_vdpa_init (peer=0x0, device=0xaaaaaba47140 "vhost-vdpa", name=0xaaaaac63a640 "vhost-vdpa0", vdpa_device_fd=12, queue_pair_index=0, nvqs=2, is_datapath=true) at ../net/vhost-vdpa.c:214 -#6 0x0000aaaaaaf066ac in net_init_vhost_vdpa (netdev=0xaaaaac6322a0, name=0xaaaaac63a640 "vhost-vdpa0", peer=0x0, errp=0xaaaaac26ea20 ) at ../net/vhost-vdpa.c:291 -#7 0x0000aaaaaaef7f94 in net_client_init1 (netdev=0xaaaaac6322a0, is_netdev=true, errp=0xaaaaac26ea20 ) at ../net/net.c:1064 -#8 0x0000aaaaaaef8334 in net_client_init (opts=0xaaaaac32bf80, is_netdev=true, errp=0xaaaaac26ea20 ) at ../net/net.c:1162 -#9 0x0000aaaaaaef90a4 in net_init_netdev (dummy=0x0, opts=0xaaaaac32bf80, errp=0xaaaaac26ea20 ) at ../net/net.c:1494 -#10 0x0000aaaaab97aee0 in qemu_opts_foreach (list=0xaaaaac1038c0 , func=0xaaaaaaef9040 , opaque=0x0, errp=0xaaaaac26ea20 ) at ../util/qemu-option.c:1135 -#11 0x0000aaaaaaef93a4 in net_init_clients (errp=0xaaaaac26ea20 ) at ../net/net.c:1567 -#12 0x0000aaaaab586f8c in qemu_create_late_backends () at ../softmmu/vl.c:2000 -#13 0x0000aaaaab58b234 in qemu_init (argc=37, argv=0xfffffffff848, envp=0xfffffffff978) at ../softmmu/vl.c:3763 -#14 0x0000aaaaaae1f7f8 in main (argc=37, argv=0xfffffffff848, envp=0xfffffffff978) at ../softmmu/main.c:50 - -Fixes: 185d7efe768 ("vhost-user: add separate memslot counter for vhost-user") -Signed-off-by:Pengyuan Zhao ---- - hw/virtio/vhost-vdpa.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index bcaf00e09f..f285edb786 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -24,6 +24,8 @@ - #include "trace.h" - #include "qemu-common.h" - -+static unsigned int vhost_vdpa_used_memslots; -+ - /* - * Return one past the end of the end of section. Be careful with uint64_t - * conversions! -@@ -763,6 +765,16 @@ static bool vhost_vdpa_force_iommu(struct vhost_dev *dev) - return true; - } - -+static void vhost_vdpa_set_used_memslots(struct vhost_dev *dev) -+{ -+ vhost_vdpa_used_memslots = dev->mem->nregions; -+} -+ -+static unsigned int vhost_vdpa_get_used_memslots(void) -+{ -+ return vhost_vdpa_used_memslots; -+} -+ - const VhostOps vdpa_ops = { - .backend_type = VHOST_BACKEND_TYPE_VDPA, - .vhost_backend_init = vhost_vdpa_init, -@@ -795,4 +807,6 @@ const VhostOps vdpa_ops = { - .vhost_get_device_id = vhost_vdpa_get_device_id, - .vhost_vq_get_addr = vhost_vdpa_vq_get_addr, - .vhost_force_iommu = vhost_vdpa_force_iommu, -+ .vhost_set_used_memslots = vhost_vdpa_set_used_memslots, -+ .vhost_get_used_memslots = vhost_vdpa_get_used_memslots, - }; --- -2.27.0 - diff --git a/vhost-vdpa-add-migration-log-ops-for-VhostOps.patch b/vhost-vdpa-add-migration-log-ops-for-VhostOps.patch deleted file mode 100644 index 9de17d74f0dd9ef3cdd260e53f994272fff96c35..0000000000000000000000000000000000000000 --- a/vhost-vdpa-add-migration-log-ops-for-VhostOps.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 51c8cb0fa2481be78282e7ea8f24a3f97083e2fd Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Mon, 4 Dec 2023 15:04:25 +0800 -Subject: [PATCH] vhost-vdpa: add migration log ops for VhostOps - -Implement vhost_set_log_size for setting buffer size for logging. -Implement vhost_set_log_fd to specify an eventfd to signal on log write. -Implement vhost_log_sync for getting dirtymap logged by vhost backend. - -Signed-off-by: libai -Signed-off-by: jiangdongxu -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 37 +++++++++++++++++++++++++++++++ - include/hw/virtio/vhost-backend.h | 8 +++++++ - linux-headers/linux/vhost.h | 4 ++++ - 3 files changed, 49 insertions(+) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index e1c90cf6c2..7663d78b43 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -1146,6 +1146,30 @@ static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base, - return vhost_vdpa_call(dev, VHOST_SET_LOG_BASE, &base); - } - -+static int vhost_vdpa_set_log_fd(struct vhost_dev *dev, int fd, -+ struct vhost_log *log) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ if (v->shadow_vqs_enabled || !vhost_vdpa_first_dev(dev)) { -+ return 0; -+ } -+ -+ return vhost_vdpa_call(dev, VHOST_SET_LOG_FD, &fd); -+} -+ -+static int vhost_vdpa_set_log_size(struct vhost_dev *dev, uint64_t size, -+ struct vhost_log *log) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ uint64_t logsize = size * sizeof(*(log->log)); -+ -+ if (v->shadow_vqs_enabled || !vhost_vdpa_first_dev(dev)) { -+ return 0; -+ } -+ -+ return vhost_vdpa_call(dev, VHOST_SET_LOG_SIZE, &logsize); -+} -+ - static int vhost_vdpa_set_vring_addr(struct vhost_dev *dev, - struct vhost_vring_addr *addr) - { -@@ -1294,11 +1318,23 @@ static unsigned int vhost_vdpa_get_used_memslots(void) - return vhost_vdpa_used_memslots; - } - -+static int vhost_vdpa_log_sync(struct vhost_dev *dev) -+{ -+ struct vhost_vdpa *v = dev->opaque; -+ if (v->shadow_vqs_enabled || !vhost_vdpa_first_dev(dev)) { -+ return 0; -+ } -+ -+ return vhost_vdpa_call(dev, VHOST_LOG_SYNC, NULL); -+} -+ - const VhostOps vdpa_ops = { - .backend_type = VHOST_BACKEND_TYPE_VDPA, - .vhost_backend_init = vhost_vdpa_init, - .vhost_backend_cleanup = vhost_vdpa_cleanup, - .vhost_set_log_base = vhost_vdpa_set_log_base, -+ .vhost_set_log_size = vhost_vdpa_set_log_size, -+ .vhost_set_log_fd = vhost_vdpa_set_log_fd, - .vhost_set_vring_addr = vhost_vdpa_set_vring_addr, - .vhost_set_vring_num = vhost_vdpa_set_vring_num, - .vhost_set_vring_base = vhost_vdpa_set_vring_base, -@@ -1326,6 +1362,7 @@ const VhostOps vdpa_ops = { - .vhost_get_device_id = vhost_vdpa_get_device_id, - .vhost_vq_get_addr = vhost_vdpa_vq_get_addr, - .vhost_force_iommu = vhost_vdpa_force_iommu, -+ .vhost_log_sync = vhost_vdpa_log_sync, - .vhost_set_config_call = vhost_vdpa_set_config_call, - .vhost_set_used_memslots = vhost_vdpa_set_used_memslots, - .vhost_get_used_memslots = vhost_vdpa_get_used_memslots, -diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h -index bd1c7dfe4f..86154dd0b2 100644 ---- a/include/hw/virtio/vhost-backend.h -+++ b/include/hw/virtio/vhost-backend.h -@@ -53,6 +53,11 @@ typedef int (*vhost_scsi_get_abi_version_op)(struct vhost_dev *dev, - int *version); - typedef int (*vhost_set_log_base_op)(struct vhost_dev *dev, uint64_t base, - struct vhost_log *log); -+typedef int (*vhost_set_log_size_op)(struct vhost_dev *dev, uint64_t size, -+ struct vhost_log *log); -+typedef int (*vhost_set_log_fd_op)(struct vhost_dev *dev, int fd, -+ struct vhost_log *log); -+typedef int (*vhost_log_sync_op)(struct vhost_dev *dev); - typedef int (*vhost_set_mem_table_op)(struct vhost_dev *dev, - struct vhost_memory *mem); - typedef int (*vhost_set_vring_addr_op)(struct vhost_dev *dev, -@@ -141,6 +146,9 @@ typedef struct VhostOps { - vhost_scsi_clear_endpoint_op vhost_scsi_clear_endpoint; - vhost_scsi_get_abi_version_op vhost_scsi_get_abi_version; - vhost_set_log_base_op vhost_set_log_base; -+ vhost_set_log_size_op vhost_set_log_size; -+ vhost_set_log_fd_op vhost_set_log_fd; -+ vhost_log_sync_op vhost_log_sync; - vhost_set_mem_table_op vhost_set_mem_table; - vhost_set_vring_addr_op vhost_set_vring_addr; - vhost_set_vring_endian_op vhost_set_vring_endian; -diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h -index b6ded7f831..65c6b49788 100644 ---- a/linux-headers/linux/vhost.h -+++ b/linux-headers/linux/vhost.h -@@ -43,6 +43,10 @@ - * The bit is set using an atomic 32 bit operation. */ - /* Set base address for logging. */ - #define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64) -+/* Set buffer size for logging */ -+#define VHOST_SET_LOG_SIZE _IOW(VHOST_VIRTIO, 0x05, __u64) -+/* Logging sync */ -+#define VHOST_LOG_SYNC _IO(VHOST_VIRTIO, 0x06) - /* Specify an eventfd file descriptor to signal on log write. */ - #define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int) - --- -2.27.0 - diff --git a/vhost-vdpa-add-support-for-config-interrupt-new.patch b/vhost-vdpa-add-support-for-config-interrupt-new.patch deleted file mode 100644 index 9d6739558daacf62d115e06c041c2a45d4fa45dd..0000000000000000000000000000000000000000 --- a/vhost-vdpa-add-support-for-config-interrupt-new.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 1a5b6648f563f7991fba0c4cb07a3a4d05834c83 Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:46 +0800 -Subject: [PATCH] vhost-vdpa: add support for config interrupt - -Add new call back function in vhost-vdpa, The function -vhost_set_config_call can set the event fd to kernel. -This function will be called in the vhost_dev_start -and vhost_dev_stop - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-6-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/trace-events | 1 + - hw/virtio/vhost-vdpa.c | 8 ++++++++ - 2 files changed, 9 insertions(+) - -diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events -index edbbbeb621..0396518241 100644 ---- a/hw/virtio/trace-events -+++ b/hw/virtio/trace-events -@@ -61,6 +61,7 @@ vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRI - vhost_vdpa_set_owner(void *dev) "dev: %p" - vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64 - vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64 -+vhost_vdpa_set_config_call(void *dev, int fd)"dev: %p fd: %d" - - # virtio.c - virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u" -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 8b44f5a7b8..c9289e2c01 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -719,6 +719,13 @@ static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev) - return 0; - } - -+static int vhost_vdpa_set_config_call(struct vhost_dev *dev, -+ int fd) -+{ -+ trace_vhost_vdpa_set_config_call(dev, fd); -+ return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, &fd); -+} -+ - static void vhost_vdpa_dump_config(struct vhost_dev *dev, const uint8_t *config, - uint32_t config_len) - { -@@ -1311,6 +1318,7 @@ const VhostOps vdpa_ops = { - .vhost_get_device_id = vhost_vdpa_get_device_id, - .vhost_vq_get_addr = vhost_vdpa_vq_get_addr, - .vhost_force_iommu = vhost_vdpa_force_iommu, -+ .vhost_set_config_call = vhost_vdpa_set_config_call, - .vhost_set_used_memslots = vhost_vdpa_set_used_memslots, - .vhost_get_used_memslots = vhost_vdpa_get_used_memslots, - }; --- -2.27.0 - diff --git a/vhost-vdpa-add-support-for-config-interrupt.patch b/vhost-vdpa-add-support-for-config-interrupt.patch deleted file mode 100644 index f154b19ab4a31ce7f47dda01f5b2405ac3402d42..0000000000000000000000000000000000000000 --- a/vhost-vdpa-add-support-for-config-interrupt.patch +++ /dev/null @@ -1,59 +0,0 @@ -From cc9df379f703274eb600dd6af7dbacae4d457d5f Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:51 +0800 -Subject: [PATCH] vhost-vdpa: add support for config interrupt - -Add new call back function in vhost-vdpa, this function will -set the event fd to kernel. This function will be called -in the vhost_dev_start and vhost_dev_stop - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-6-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/trace-events | 1 + - hw/virtio/vhost-vdpa.c | 7 +++++++ - 2 files changed, 8 insertions(+) - -diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events -index 650e521e35..39c36ff7a6 100644 ---- a/hw/virtio/trace-events -+++ b/hw/virtio/trace-events -@@ -53,6 +53,7 @@ vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRI - vhost_vdpa_set_owner(void *dev) "dev: %p" - vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64 - vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64 -+vhost_vdpa_set_config_call(void *dev, int fd)"dev: %p fd: %d" - - # virtio.c - virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u" -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 287025ef93..b7bbd65cdd 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -728,6 +728,12 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev, - trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd); - return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file); - } -+static int vhost_vdpa_set_config_call(struct vhost_dev *dev, -+ int fd) -+{ -+ trace_vhost_vdpa_set_config_call(dev, fd); -+ return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, &fd); -+} - - static int vhost_vdpa_get_features(struct vhost_dev *dev, - uint64_t *features) -@@ -808,6 +814,7 @@ const VhostOps vdpa_ops = { - .vhost_get_device_id = vhost_vdpa_get_device_id, - .vhost_vq_get_addr = vhost_vdpa_vq_get_addr, - .vhost_force_iommu = vhost_vdpa_force_iommu, -+ .vhost_set_config_call = vhost_vdpa_set_config_call, - .vhost_set_used_memslots = vhost_vdpa_set_used_memslots, - .vhost_get_used_memslots = vhost_vdpa_get_used_memslots, - }; --- -2.27.0 - diff --git a/vhost-vdpa-allow-passing-opened-vhostfd-to-vhost-vdp.patch b/vhost-vdpa-allow-passing-opened-vhostfd-to-vhost-vdp.patch deleted file mode 100644 index c17fb9d8b40cbe3034062f1a17808de59f21a76c..0000000000000000000000000000000000000000 --- a/vhost-vdpa-allow-passing-opened-vhostfd-to-vhost-vdp.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 2feaf4260eae797c518c86d181f24eca5948b8b0 Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Sat, 8 Oct 2022 00:58:58 -0700 -Subject: [PATCH] vhost-vdpa: allow passing opened vhostfd to vhost-vdpa -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Similar to other vhost backends, vhostfd can be passed to vhost-vdpa -backend as another parameter to instantiate vhost-vdpa net client. -This would benefit the use case where only open file descriptors, as -opposed to raw vhost-vdpa device paths, are accessible from the QEMU -process. - -(qemu) netdev_add type=vhost-vdpa,vhostfd=61,id=vhost-vdpa1 - -Signed-off-by: Si-Wei Liu -Acked-by: Eugenio Pérez -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 25 ++++++++++++++++++++----- - qapi/net.json | 3 +++ - qemu-options.hx | 6 ++++-- - 3 files changed, 27 insertions(+), 7 deletions(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index c8c433002d..58225649f9 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -642,14 +642,29 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - - assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); - opts = &netdev->u.vhost_vdpa; -- if (!opts->vhostdev) { -- error_setg(errp, "vdpa character device not specified with vhostdev"); -+ if (!opts->has_vhostdev && !opts->has_vhostfd) { -+ error_setg(errp, -+ "vhost-vdpa: neither vhostdev= nor vhostfd= was specified"); - return -1; - } - -- vdpa_device_fd = qemu_open(opts->vhostdev, O_RDWR, errp); -- if (vdpa_device_fd == -1) { -- return -errno; -+ if (opts->has_vhostdev && opts->has_vhostfd) { -+ error_setg(errp, -+ "vhost-vdpa: vhostdev= and vhostfd= are mutually exclusive"); -+ return -1; -+ } -+ -+ if (opts->has_vhostdev) { -+ vdpa_device_fd = qemu_open(opts->vhostdev, O_RDWR, errp); -+ if (vdpa_device_fd == -1) { -+ return -errno; -+ } -+ } else if (opts->has_vhostfd) { -+ vdpa_device_fd = monitor_fd_param(monitor_cur(), opts->vhostfd, errp); -+ if (vdpa_device_fd == -1) { -+ error_prepend(errp, "vhost-vdpa: unable to parse vhostfd: "); -+ return -1; -+ } - } - - r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp); -diff --git a/qapi/net.json b/qapi/net.json -index 6a5460ce56..a38a7b611b 100644 ---- a/qapi/net.json -+++ b/qapi/net.json -@@ -442,6 +442,8 @@ - # @vhostdev: path of vhost-vdpa device - # (default:'/dev/vhost-vdpa-0') - # -+# @vhostfd: file descriptor of an already opened vhost vdpa device -+# - # @queues: number of queues to be created for multiqueue vhost-vdpa - # (default: 1) - # -@@ -456,6 +458,7 @@ - { 'struct': 'NetdevVhostVDPAOptions', - 'data': { - '*vhostdev': 'str', -+ '*vhostfd': 'str', - '*queues': 'int', - '*x-svq': {'type': 'bool', 'features' : [ 'unstable'] } } } - -diff --git a/qemu-options.hx b/qemu-options.hx -index e329ec58ca..e25b76771d 100644 ---- a/qemu-options.hx -+++ b/qemu-options.hx -@@ -2739,8 +2739,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, - " configure a vhost-user network, backed by a chardev 'dev'\n" - #endif - #ifdef __linux__ -- "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n" -+ "-netdev vhost-vdpa,id=str[,vhostdev=/path/to/dev][,vhostfd=h]\n" - " configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n" -+ " use 'vhostdev=/path/to/dev' to open a vhost vdpa device\n" -+ " use 'vhostfd=h' to connect to an already opened vhost vdpa device\n" - #endif - "-netdev hubport,id=str,hubid=n[,netdev=nd]\n" - " configure a hub port on the hub with ID 'n'\n", QEMU_ARCH_ALL) -@@ -3220,7 +3222,7 @@ SRST - -netdev type=vhost-user,id=net0,chardev=chr0 \ - -device virtio-net-pci,netdev=net0 - --``-netdev vhost-vdpa,vhostdev=/path/to/dev`` -+``-netdev vhost-vdpa[,vhostdev=/path/to/dev][,vhostfd=h]`` - Establish a vhost-vdpa netdev. - - vDPA device is a device that uses a datapath which complies with --- -2.27.0 - diff --git a/vhost-vdpa-backend-feature-should-set-only-once.patch b/vhost-vdpa-backend-feature-should-set-only-once.patch deleted file mode 100644 index b14e65f830247bae9abd095101515192fe70b613..0000000000000000000000000000000000000000 --- a/vhost-vdpa-backend-feature-should-set-only-once.patch +++ /dev/null @@ -1,49 +0,0 @@ -From a089328f183371ec7f7cd641f46beeeea2c9decc Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Fri, 6 May 2022 19:28:16 -0700 -Subject: [PATCH] vhost-vdpa: backend feature should set only once -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The vhost_vdpa_one_time_request() branch in -vhost_vdpa_set_backend_cap() incorrectly sends down -ioctls on vhost_dev with non-zero index. This may -end up with multiple VHOST_SET_BACKEND_FEATURES -ioctl calls sent down on the vhost-vdpa fd that is -shared between all these vhost_dev's. - -To fix it, send down ioctl only once via the first -vhost_dev with index 0. Toggle the polarity of the -vhost_vdpa_one_time_request() test should do the -trick. - -Fixes: 4d191cfdc7de ("vhost-vdpa: classify one time request") -Signed-off-by: Si-Wei Liu -Reviewed-by: Stefano Garzarella -Acked-by: Jason Wang -Acked-by: Eugenio Pérez -Message-Id: <1651890498-24478-6-git-send-email-si-wei.liu@oracle.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 1360f2eaf7..cb74d71b80 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -669,7 +669,7 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) - - features &= f; - -- if (vhost_vdpa_one_time_request(dev)) { -+ if (!vhost_vdpa_one_time_request(dev)) { - r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features); - if (r) { - return -EFAULT; --- -2.27.0 - diff --git a/vhost-vdpa-change-name-and-polarity-for-vhost_vdpa_o.patch b/vhost-vdpa-change-name-and-polarity-for-vhost_vdpa_o.patch deleted file mode 100644 index 3c67ccd022dca2b1c4cea6874cdaf3d44ad69dc9..0000000000000000000000000000000000000000 --- a/vhost-vdpa-change-name-and-polarity-for-vhost_vdpa_o.patch +++ /dev/null @@ -1,111 +0,0 @@ -From fdf8d168adeac8e91bb61d4940756af0df3b8d2c Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Fri, 6 May 2022 19:28:17 -0700 -Subject: [PATCH] vhost-vdpa: change name and polarity for - vhost_vdpa_one_time_request() - -The name vhost_vdpa_one_time_request() was confusing. No -matter whatever it returns, its typical occurrence had -always been at requests that only need to be applied once. -And the name didn't suggest what it actually checks for. -Change it to vhost_vdpa_first_dev() with polarity flipped -for better readibility of code. That way it is able to -reflect what the check is really about. - -This call is applicable to request which performs operation -only once, before queues are set up, and usually at the beginning -of the caller function. Document the requirement for it in place. - -Signed-off-by: Si-Wei Liu -Message-Id: <1651890498-24478-7-git-send-email-si-wei.liu@oracle.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Stefano Garzarella -Acked-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 23 +++++++++++++++-------- - 1 file changed, 15 insertions(+), 8 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index cb74d71b80..73ff599f2b 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -370,11 +370,18 @@ static void vhost_vdpa_get_iova_range(struct vhost_vdpa *v) - v->iova_range.last); - } - --static bool vhost_vdpa_one_time_request(struct vhost_dev *dev) -+/* -+ * The use of this function is for requests that only need to be -+ * applied once. Typically such request occurs at the beginning -+ * of operation, and before setting up queues. It should not be -+ * used for request that performs operation until all queues are -+ * set, which would need to check dev->vq_index_end instead. -+ */ -+static bool vhost_vdpa_first_dev(struct vhost_dev *dev) - { - struct vhost_vdpa *v = dev->opaque; - -- return v->index != 0; -+ return v->index == 0; - } - - static int vhost_vdpa_get_dev_features(struct vhost_dev *dev, -@@ -455,7 +462,7 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) - - vhost_vdpa_get_iova_range(v); - -- if (vhost_vdpa_one_time_request(dev)) { -+ if (!vhost_vdpa_first_dev(dev)) { - return 0; - } - -@@ -598,7 +605,7 @@ static int vhost_vdpa_memslots_limit(struct vhost_dev *dev) - static int vhost_vdpa_set_mem_table(struct vhost_dev *dev, - struct vhost_memory *mem) - { -- if (vhost_vdpa_one_time_request(dev)) { -+ if (!vhost_vdpa_first_dev(dev)) { - return 0; - } - -@@ -627,7 +634,7 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev, - struct vhost_vdpa *v = dev->opaque; - int ret; - -- if (vhost_vdpa_one_time_request(dev)) { -+ if (!vhost_vdpa_first_dev(dev)) { - return 0; - } - -@@ -669,7 +676,7 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) - - features &= f; - -- if (!vhost_vdpa_one_time_request(dev)) { -+ if (vhost_vdpa_first_dev(dev)) { - r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features); - if (r) { - return -EFAULT; -@@ -1122,7 +1129,7 @@ static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base, - struct vhost_log *log) - { - struct vhost_vdpa *v = dev->opaque; -- if (v->shadow_vqs_enabled || vhost_vdpa_one_time_request(dev)) { -+ if (v->shadow_vqs_enabled || !vhost_vdpa_first_dev(dev)) { - return 0; - } - -@@ -1244,7 +1251,7 @@ static int vhost_vdpa_get_features(struct vhost_dev *dev, - - static int vhost_vdpa_set_owner(struct vhost_dev *dev) - { -- if (vhost_vdpa_one_time_request(dev)) { -+ if (!vhost_vdpa_first_dev(dev)) { - return 0; - } - --- -2.27.0 - diff --git a/vhost-vdpa-do-not-cleanup-the-vdpa-vhost-net-structu.patch b/vhost-vdpa-do-not-cleanup-the-vdpa-vhost-net-structu.patch deleted file mode 100644 index d74d15c97f0db3359159bd532f1155d44ab025a1..0000000000000000000000000000000000000000 --- a/vhost-vdpa-do-not-cleanup-the-vdpa-vhost-net-structu.patch +++ /dev/null @@ -1,59 +0,0 @@ -From b6e32ca6cb92d6b1c5414206a262fd72cedd56bc Mon Sep 17 00:00:00 2001 -From: Ani Sinha -Date: Mon, 19 Jun 2023 12:22:09 +0530 -Subject: [PATCH] vhost-vdpa: do not cleanup the vdpa/vhost-net structures if - peer nic is present - -When a peer nic is still attached to the vdpa backend, it is too early to free -up the vhost-net and vdpa structures. If these structures are freed here, then -QEMU crashes when the guest is being shut down. The following call chain -would result in an assertion failure since the pointer returned from -vhost_vdpa_get_vhost_net() would be NULL: - -do_vm_stop() -> vm_state_notify() -> virtio_set_status() -> -virtio_net_vhost_status() -> get_vhost_net(). - -Therefore, we defer freeing up the structures until at guest shutdown -time when qemu_cleanup() calls net_cleanup() which then calls -qemu_del_net_client() which would eventually call vhost_vdpa_cleanup() -again to free up the structures. This time, the loop in net_cleanup() -ensures that vhost_vdpa_cleanup() will be called one last time when -all the peer nics are detached and freed. - -All unit tests pass with this change. - -CC: imammedo@redhat.com -CC: jusual@redhat.com -CC: mst@redhat.com -Fixes: CVE-2023-3301 -Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2128929 -Signed-off-by: Ani Sinha -Message-Id: <20230619065209.442185-1-anisinha@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - net/vhost-vdpa.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 25dd6dd975..60b715aef1 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -128,6 +128,14 @@ static void vhost_vdpa_cleanup(NetClientState *nc) - { - VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); - -+ /* -+ * If a peer NIC is attached, do not cleanup anything. -+ * Cleanup will happen as a part of qemu_cleanup() -> net_cleanup() -+ * when the guest is shutting down. -+ */ -+ if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_NIC) { -+ return; -+ } - if (s->vhost_net) { - vhost_net_cleanup(s->vhost_net); - g_free(s->vhost_net); --- -2.41.0.windows.1 - diff --git a/vhost-vdpa-fix-assert-virtio_net_get_subqueue-nc-asy.patch b/vhost-vdpa-fix-assert-virtio_net_get_subqueue-nc-asy.patch deleted file mode 100644 index b49311e91e0858283caec25d57ea59f91c0e48a3..0000000000000000000000000000000000000000 --- a/vhost-vdpa-fix-assert-virtio_net_get_subqueue-nc-asy.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0462d79e6b607799538ac96b9486b60ee6819e9f Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Tue, 8 Nov 2022 12:19:28 +0800 -Subject: [PATCH] vhost-vdpa: fix assert - !virtio_net_get_subqueue(nc)->async_tx.elem in virtio_net_reset - -The citing commit has incorrect code in vhost_vdpa_receive() that returns -zero instead of full packet size to the caller. This renders pending packets -unable to be freed so then get clogged in the tx queue forever. When device -is being reset later on, below assertion failure ensues: - -0 0x00007f86d53bb387 in raise () from /lib64/libc.so.6 -1 0x00007f86d53bca78 in abort () from /lib64/libc.so.6 -2 0x00007f86d53b41a6 in __assert_fail_base () from /lib64/libc.so.6 -3 0x00007f86d53b4252 in __assert_fail () from /lib64/libc.so.6 -4 0x000055b8f6ff6fcc in virtio_net_reset (vdev=) at /usr/src/debug/qemu/hw/net/virtio-net.c:563 -5 0x000055b8f7012fcf in virtio_reset (opaque=0x55b8faf881f0) at /usr/src/debug/qemu/hw/virtio/virtio.c:1993 -6 0x000055b8f71f0086 in virtio_bus_reset (bus=bus@entry=0x55b8faf88178) at /usr/src/debug/qemu/hw/virtio/virtio-bus.c:102 -7 0x000055b8f71f1620 in virtio_pci_reset (qdev=) at /usr/src/debug/qemu/hw/virtio/virtio-pci.c:1845 -8 0x000055b8f6fafc6c in memory_region_write_accessor (mr=, addr=, value=, - size=, shift=, mask=, attrs=...) at /usr/src/debug/qemu/memory.c:483 -9 0x000055b8f6fadce9 in access_with_adjusted_size (addr=addr@entry=20, value=value@entry=0x7f867e7fb7e8, size=size@entry=1, - access_size_min=, access_size_max=, access_fn=0x55b8f6fafc20 , - mr=0x55b8faf80a50, attrs=...) at /usr/src/debug/qemu/memory.c:544 -10 0x000055b8f6fb1d0b in memory_region_dispatch_write (mr=mr@entry=0x55b8faf80a50, addr=addr@entry=20, data=0, op=, - attrs=attrs@entry=...) at /usr/src/debug/qemu/memory.c:1470 -11 0x000055b8f6f62ada in flatview_write_continue (fv=fv@entry=0x7f86ac04cd20, addr=addr@entry=549755813908, attrs=..., - attrs@entry=..., buf=buf@entry=0x7f86d0223028
, len=len@entry=1, addr1=20, l=1, - mr=0x55b8faf80a50) at /usr/src/debug/qemu/exec.c:3266 -12 0x000055b8f6f62c8f in flatview_write (fv=0x7f86ac04cd20, addr=549755813908, attrs=..., - buf=0x7f86d0223028
, len=1) at /usr/src/debug/qemu/exec.c:3306 -13 0x000055b8f6f674cb in address_space_write (as=, addr=, attrs=..., buf=, - len=) at /usr/src/debug/qemu/exec.c:3396 -14 0x000055b8f6f67575 in address_space_rw (as=, addr=, attrs=..., attrs@entry=..., - buf=buf@entry=0x7f86d0223028
, len=, is_write=) - at /usr/src/debug/qemu/exec.c:3406 -15 0x000055b8f6fc1cc8 in kvm_cpu_exec (cpu=cpu@entry=0x55b8f9aa0e10) at /usr/src/debug/qemu/accel/kvm/kvm-all.c:2410 -16 0x000055b8f6fa5f5e in qemu_kvm_cpu_thread_fn (arg=0x55b8f9aa0e10) at /usr/src/debug/qemu/cpus.c:1318 -17 0x000055b8f7336e16 in qemu_thread_start (args=0x55b8f9ac8480) at /usr/src/debug/qemu/util/qemu-thread-posix.c:519 -18 0x00007f86d575aea5 in start_thread () from /lib64/libpthread.so.0 -19 0x00007f86d5483b2d in clone () from /lib64/libc.so.6 - -Make vhost_vdpa_receive() return the size passed in as is, so that the -caller qemu_deliver_packet_iov() would eventually propagate it back to -virtio_net_flush_tx() to release pending packets from the async_tx queue. -Which corresponds to the drop path where qemu_sendv_packet_async() returns -non-zero in virtio_net_flush_tx(). - -Fixes: 846a1e85da64 ("vdpa: Add dummy receive callback") -Cc: Eugenio Perez Martin -Signed-off-by: Si-Wei Liu -Signed-off-by: Jason Wang -Signed-off-by: Stefan Hajnoczi -Message-Id: <20221108041929.18417-2-jasowang@redhat.com> -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index c89f9d1243..eae2ed364f 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -218,7 +218,7 @@ static bool vhost_vdpa_check_peer_type(NetClientState *nc, ObjectClass *oc, - static ssize_t vhost_vdpa_receive(NetClientState *nc, const uint8_t *buf, - size_t size) - { -- return 0; -+ return size; - } - - static NetClientInfo net_vhost_vdpa_info = { --- -2.27.0 - diff --git a/vhost-vdpa-fix-improper-cleanup-in-net_init_vhost_vd.patch b/vhost-vdpa-fix-improper-cleanup-in-net_init_vhost_vd.patch deleted file mode 100644 index ecb45191573bc973eee4e3d32d9c826153f8f617..0000000000000000000000000000000000000000 --- a/vhost-vdpa-fix-improper-cleanup-in-net_init_vhost_vd.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ddd117ccb7dfc57dcd45d52d35cd71f746d81c3a Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Fri, 6 May 2022 19:28:14 -0700 -Subject: [PATCH] vhost-vdpa: fix improper cleanup in net_init_vhost_vdpa - -... such that no memory leaks on dangling net clients in case of -error. - -Signed-off-by: Si-Wei Liu -Acked-by: Jason Wang -Message-Id: <1651890498-24478-4-git-send-email-si-wei.liu@oracle.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - net/vhost-vdpa.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c -index 9ba0f7bfca..7201c79116 100644 ---- a/net/vhost-vdpa.c -+++ b/net/vhost-vdpa.c -@@ -314,7 +314,9 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, - - err: - if (i) { -- qemu_del_net_client(ncs[0]); -+ for (i--; i >= 0; i--) { -+ qemu_del_net_client(ncs[i]); -+ } - } - qemu_close(vdpa_device_fd); - --- -2.27.0 - diff --git a/vhost-vdpa-fix-typo-in-a-comment.patch b/vhost-vdpa-fix-typo-in-a-comment.patch deleted file mode 100644 index b55cff07d2d541dfadb4a338780ba6fcfec96fdf..0000000000000000000000000000000000000000 --- a/vhost-vdpa-fix-typo-in-a-comment.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 208e92b8d029d8483f994858304d49af5b6d875a Mon Sep 17 00:00:00 2001 -From: Stefano Garzarella -Date: Mon, 28 Mar 2022 17:20:22 +0200 -Subject: [PATCH] vhost-vdpa: fix typo in a comment -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Replace vpda with vdpa. - -Signed-off-by: Stefano Garzarella -Reviewed-by: Philippe Mathieu-Daudé -Message-Id: <20220328152022.73245-1-sgarzare@redhat.com> -Signed-off-by: Laurent Vivier -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index 3b5456cc0e..b66697da6e 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -301,7 +301,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, - memory_region_unref(section->mr); - } - /* -- * IOTLB API is used by vhost-vpda which requires incremental updating -+ * IOTLB API is used by vhost-vdpa which requires incremental updating - * of the mapping. So we can not use generic vhost memory listener which - * depends on the addnop(). - */ --- -2.27.0 - diff --git a/vhost-vdpa-stick-to-errno-error-return-convention.patch b/vhost-vdpa-stick-to-errno-error-return-convention.patch deleted file mode 100644 index 1ef8091e130d3ce4dd1c3b4c925980ef810c8fa5..0000000000000000000000000000000000000000 --- a/vhost-vdpa-stick-to-errno-error-return-convention.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 69fdbac8d37a02cfc91e6c849a768e58e57dd15f Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:55 +0800 -Subject: [PATCH] vhost-vdpa: stick to -errno error return convention - -Almost all VhostOps methods in vdpa_ops follow the convention of -returning negated errno on error. - -Adjust the few that don't. To that end, rework vhost_vdpa_add_status to -check if setting of the requested status bits has succeeded and return -the respective error code it hasn't, and propagate the error codes -wherever it's appropriate. - -Signed-off-by: Roman Kagan -Message-Id: <20211111153354.18807-8-rvkagan@yandex-team.ru> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-vdpa.c | 37 +++++++++++++++++++++++-------------- - 1 file changed, 23 insertions(+), 14 deletions(-) - -diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c -index b7bbd65cdd..d8fba0b714 100644 ---- a/hw/virtio/vhost-vdpa.c -+++ b/hw/virtio/vhost-vdpa.c -@@ -294,18 +294,34 @@ static int vhost_vdpa_call(struct vhost_dev *dev, unsigned long int request, - return ret < 0 ? -errno : ret; - } - --static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status) -+static int vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status) - { - uint8_t s; -+ int ret; - - trace_vhost_vdpa_add_status(dev, status); -- if (vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &s)) { -- return; -+ ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &s); -+ if (ret < 0) { -+ return ret; - } - - s |= status; - -- vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s); -+ ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &s); -+ if (ret < 0) { -+ return ret; -+ } -+ -+ if (!(s & status)) { -+ return -EIO; -+ } -+ -+ return 0; - } - - static void vhost_vdpa_get_iova_range(struct vhost_vdpa *v) -@@ -487,7 +503,7 @@ static int vhost_vdpa_set_mem_table(struct vhost_dev *dev, - } - } - if (mem->padding) { -- return -1; -+ return -EINVAL; - } - - return 0; -@@ -504,14 +520,11 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev, - - trace_vhost_vdpa_set_features(dev, features); - ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features); -- uint8_t status = 0; - if (ret) { - return ret; - } -- vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); -- vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status); - -- return !(status & VIRTIO_CONFIG_S_FEATURES_OK); -+ return vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); - } - - static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) -@@ -653,12 +666,8 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) - } - - if (started) { -- uint8_t status = 0; - memory_listener_register(&v->listener, &address_space_memory); -- vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); -- vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status); -- -- return !(status & VIRTIO_CONFIG_S_DRIVER_OK); -+ return vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); - } else { - vhost_vdpa_reset_device(dev); - vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE | --- -2.27.0 - diff --git a/vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch b/vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch deleted file mode 100644 index 019f41be808442382fe083d8bfb712e46826422a..0000000000000000000000000000000000000000 --- a/vhost-vsock-detach-the-virqueue-element-in-case-of-e.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 1362d692f9fac12d5ee37a44163c652bb58075eb Mon Sep 17 00:00:00 2001 -From: Stefano Garzarella -Date: Mon, 28 Feb 2022 10:50:58 +0100 -Subject: [PATCH 1/2] vhost-vsock: detach the virqueue element in case of error - -In vhost_vsock_common_send_transport_reset(), if an element popped from -the virtqueue is invalid, we should call virtqueue_detach_element() to -detach it from the virtqueue before freeing its memory. - -Fixes: fc0b9b0e1c ("vhost-vsock: add virtio sockets device") -Fixes: CVE-2022-26354 -Cc: qemu-stable@nongnu.org -Reported-by: VictorV -Signed-off-by: Stefano Garzarella -Message-Id: <20220228095058.27899-1-sgarzare@redhat.com> -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio/vhost-vsock-common.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c -index 3f3771274e..ed706681ac 100644 ---- a/hw/virtio/vhost-vsock-common.c -+++ b/hw/virtio/vhost-vsock-common.c -@@ -153,19 +153,23 @@ static void vhost_vsock_common_send_transport_reset(VHostVSockCommon *vvc) - if (elem->out_num) { - error_report("invalid vhost-vsock event virtqueue element with " - "out buffers"); -- goto out; -+ goto err; - } - - if (iov_from_buf(elem->in_sg, elem->in_num, 0, - &event, sizeof(event)) != sizeof(event)) { - error_report("vhost-vsock event virtqueue element is too short"); -- goto out; -+ goto err; - } - - virtqueue_push(vq, elem, sizeof(event)); - virtio_notify(VIRTIO_DEVICE(vvc), vq); - --out: -+ g_free(elem); -+ return; -+ -+err: -+ virtqueue_detach_element(vq, elem, 0); - g_free(elem); - } - --- -2.27.0 - diff --git a/vhost_net-Add-NetClientInfo-start-callback.patch b/vhost_net-Add-NetClientInfo-start-callback.patch deleted file mode 100644 index 546c4ef93974c34f24a2de1efb5732eb6e82c8fc..0000000000000000000000000000000000000000 --- a/vhost_net-Add-NetClientInfo-start-callback.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 533bcae898152213703a1f15b3d4a938292fd23f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:30:30 +0200 -Subject: [PATCH] vhost_net: Add NetClientInfo start callback -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is used by the backend to perform actions before the device is -started. - -In particular, vdpa net use it to map CVQ buffers to the device, so it -can send control commands using them. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/net/vhost_net.c | 7 +++++++ - include/net/net.h | 2 ++ - 2 files changed, 9 insertions(+) - -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index bea053a742..92df7558bf 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -307,6 +307,13 @@ static int vhost_net_start_one(struct vhost_net *net, - struct vhost_vring_file file = { }; - int r; - -+ if (net->nc->info->start) { -+ r = net->nc->info->start(net->nc); -+ if (r < 0) { -+ return r; -+ } -+ } -+ - r = vhost_dev_enable_notifiers(&net->dev, dev); - if (r < 0) { - goto fail_notifiers; -diff --git a/include/net/net.h b/include/net/net.h -index 523136c7ac..ad9e80083a 100644 ---- a/include/net/net.h -+++ b/include/net/net.h -@@ -44,6 +44,7 @@ typedef struct NICConf { - - typedef void (NetPoll)(NetClientState *, bool enable); - typedef bool (NetCanReceive)(NetClientState *); -+typedef int (NetStart)(NetClientState *); - typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t); - typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int); - typedef void (NetCleanup) (NetClientState *); -@@ -71,6 +72,7 @@ typedef struct NetClientInfo { - NetReceive *receive_raw; - NetReceiveIOV *receive_iov; - NetCanReceive *can_receive; -+ NetStart *start; - NetCleanup *cleanup; - LinkStatusChanged *link_status_changed; - QueryRxFilter *query_rx_filter; --- -2.27.0 - diff --git a/vhost_net-Add-NetClientInfo-stop-callback.patch b/vhost_net-Add-NetClientInfo-stop-callback.patch deleted file mode 100644 index 80cbd5266a278c2dc50bdcdd740f2a166b04bba2..0000000000000000000000000000000000000000 --- a/vhost_net-Add-NetClientInfo-stop-callback.patch +++ /dev/null @@ -1,59 +0,0 @@ -From d25c4237821c994e36b7a23e0a0c609993707d47 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:30:31 +0200 -Subject: [PATCH] vhost_net: Add NetClientInfo stop callback -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Used by the backend to perform actions after the device is stopped. - -In particular, vdpa net use it to unmap CVQ buffers to the device, -cleaning the actions performed in prepare(). - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/net/vhost_net.c | 3 +++ - include/net/net.h | 2 ++ - 2 files changed, 5 insertions(+) - -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index 92df7558bf..fe6932171b 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -383,6 +383,9 @@ static void vhost_net_stop_one(struct vhost_net *net, - net->nc->info->poll(net->nc, true); - } - vhost_dev_stop(&net->dev, dev); -+ if (net->nc->info->stop) { -+ net->nc->info->stop(net->nc); -+ } - vhost_dev_disable_notifiers(&net->dev, dev); - } - -diff --git a/include/net/net.h b/include/net/net.h -index ad9e80083a..476ad45b9a 100644 ---- a/include/net/net.h -+++ b/include/net/net.h -@@ -45,6 +45,7 @@ typedef struct NICConf { - typedef void (NetPoll)(NetClientState *, bool enable); - typedef bool (NetCanReceive)(NetClientState *); - typedef int (NetStart)(NetClientState *); -+typedef void (NetStop)(NetClientState *); - typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t); - typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int); - typedef void (NetCleanup) (NetClientState *); -@@ -73,6 +74,7 @@ typedef struct NetClientInfo { - NetReceiveIOV *receive_iov; - NetCanReceive *can_receive; - NetStart *start; -+ NetStop *stop; - NetCleanup *cleanup; - LinkStatusChanged *link_status_changed; - QueryRxFilter *query_rx_filter; --- -2.27.0 - diff --git a/vhost_net-add-NetClientState-load-callback.patch b/vhost_net-add-NetClientState-load-callback.patch deleted file mode 100644 index 39d93523ab27c05d093406a27c181177b4e4015d..0000000000000000000000000000000000000000 --- a/vhost_net-add-NetClientState-load-callback.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 4b0c6e40f26af49416d00b186840344b424b48ac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 23 Aug 2022 20:30:35 +0200 -Subject: [PATCH] vhost_net: add NetClientState->load() callback -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It allows per-net client operations right after device's successful -start. In particular, to load the device status. - -Vhost-vdpa net will use it to add the CVQ buffers to restore the device -status. - -Signed-off-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/net/vhost_net.c | 7 +++++++ - include/net/net.h | 2 ++ - 2 files changed, 9 insertions(+) - -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index fe6932171b..f709c060b6 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -344,6 +344,13 @@ static int vhost_net_start_one(struct vhost_net *net, - } - } - } -+ -+ if (net->nc->info->load) { -+ r = net->nc->info->load(net->nc); -+ if (r < 0) { -+ goto fail; -+ } -+ } - return 0; - fail: - file.fd = -1; -diff --git a/include/net/net.h b/include/net/net.h -index 476ad45b9a..81d0b21def 100644 ---- a/include/net/net.h -+++ b/include/net/net.h -@@ -45,6 +45,7 @@ typedef struct NICConf { - typedef void (NetPoll)(NetClientState *, bool enable); - typedef bool (NetCanReceive)(NetClientState *); - typedef int (NetStart)(NetClientState *); -+typedef int (NetLoad)(NetClientState *); - typedef void (NetStop)(NetClientState *); - typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t); - typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int); -@@ -74,6 +75,7 @@ typedef struct NetClientInfo { - NetReceiveIOV *receive_iov; - NetCanReceive *can_receive; - NetStart *start; -+ NetLoad *load; - NetStop *stop; - NetCleanup *cleanup; - LinkStatusChanged *link_status_changed; --- -2.27.0 - diff --git a/vhost_net-keep-acked_feature-only-for-NET_CLIENT_DRI.patch b/vhost_net-keep-acked_feature-only-for-NET_CLIENT_DRI.patch deleted file mode 100644 index 762aad2c4e8ff6e4cdad84c11b276d1e36e747e0..0000000000000000000000000000000000000000 --- a/vhost_net-keep-acked_feature-only-for-NET_CLIENT_DRI.patch +++ /dev/null @@ -1,38 +0,0 @@ -From fece8b3e700c30be2b6bb1239041333b3c1fc17b Mon Sep 17 00:00:00 2001 -From: liuxiangdong -Date: Mon, 5 Dec 2022 07:11:28 +0800 -Subject: [PATCH] vhost_net: keep acked_feature only for - NET_CLIENT_DRIVER_VHOST_USER - -Keep acked_features in NetVhostUserState up-to-date by function vhost_net_save_acked_features -in function virtio_net_set_features. But nc->peer->info->type maybe NET_CLIENT_DRIVER_TAP or -NET_CLIENT_DRIVER_VHOST_VDPA besides NET_CLIENT_DRIVER_VHOST_USER. - -Don't keep acked_features in other type now except NET_CLIENT_DRIVER_VHOST_USER - -Fix d29a94eff(vhost-user: Fix the virtio features negotiation flaw) - -Signed-off-by: liuxiangdong ---- - hw/net/vhost_net.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index a98575ffbc..bea053a742 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -143,8 +143,9 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net) - - void vhost_net_save_acked_features(NetClientState *nc) - { -- assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_USER); -- vhost_user_save_acked_features(nc); -+ if (nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) { -+ vhost_user_save_acked_features(nc); -+ } - } - - static int vhost_net_get_fd(NetClientState *backend) --- -2.27.0 - diff --git a/virtio-Add-vhost_svq_get_vring_addr.patch b/virtio-Add-vhost_svq_get_vring_addr.patch deleted file mode 100644 index 67f864e8cc09f12a1258bc8a3f9c31824cb6ee80..0000000000000000000000000000000000000000 --- a/virtio-Add-vhost_svq_get_vring_addr.patch +++ /dev/null @@ -1,96 +0,0 @@ -From c9b863e96be5277e775cb424cf8ea34f8f921776 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Mon, 14 Mar 2022 18:34:45 +0100 -Subject: [PATCH] virtio: Add vhost_svq_get_vring_addr -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It reports the shadow virtqueue address from qemu virtual address space. - -Since this will be different from the guest's vaddr, but the device can -access it, SVQ takes special care about its alignment & lack of garbage -data. It assumes that IOMMU will work in host_page_size ranges for that. - -Signed-off-by: Eugenio Pérez -Acked-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/virtio/vhost-shadow-virtqueue.c | 29 +++++++++++++++++++++++++++++ - hw/virtio/vhost-shadow-virtqueue.h | 9 +++++++++ - 2 files changed, 38 insertions(+) - -diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c -index 519328445c..573ac0d9cf 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.c -+++ b/hw/virtio/vhost-shadow-virtqueue.c -@@ -106,6 +106,35 @@ void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd) - } - } - -+/** -+ * Get the shadow vq vring address. -+ * @svq: Shadow virtqueue -+ * @addr: Destination to store address -+ */ -+void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, -+ struct vhost_vring_addr *addr) -+{ -+ addr->desc_user_addr = (uint64_t)(intptr_t)svq->vring.desc; -+ addr->avail_user_addr = (uint64_t)(intptr_t)svq->vring.avail; -+ addr->used_user_addr = (uint64_t)(intptr_t)svq->vring.used; -+} -+ -+size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq) -+{ -+ size_t desc_size = sizeof(vring_desc_t) * svq->vring.num; -+ size_t avail_size = offsetof(vring_avail_t, ring) + -+ sizeof(uint16_t) * svq->vring.num; -+ -+ return ROUND_UP(desc_size + avail_size, qemu_real_host_page_size); -+} -+ -+size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq) -+{ -+ size_t used_size = offsetof(vring_used_t, ring) + -+ sizeof(vring_used_elem_t) * svq->vring.num; -+ return ROUND_UP(used_size, qemu_real_host_page_size); -+} -+ - /** - * Set a new file descriptor for the guest to kick the SVQ and notify for avail - * -diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h -index 9e12f77201..82cea1c3fa 100644 ---- a/hw/virtio/vhost-shadow-virtqueue.h -+++ b/hw/virtio/vhost-shadow-virtqueue.h -@@ -11,9 +11,14 @@ - #define VHOST_SHADOW_VIRTQUEUE_H - - #include "qemu/event_notifier.h" -+#include "hw/virtio/virtio.h" -+#include "standard-headers/linux/vhost_types.h" - - /* Shadow virtqueue to relay notifications */ - typedef struct VhostShadowVirtqueue { -+ /* Shadow vring */ -+ struct vring vring; -+ - /* Shadow kick notifier, sent to vhost */ - EventNotifier hdev_kick; - /* Shadow call notifier, sent to vhost */ -@@ -37,6 +42,10 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp); - - void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); - void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd); -+void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, -+ struct vhost_vring_addr *addr); -+size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq); -+size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq); - - void vhost_svq_stop(VhostShadowVirtqueue *svq); - --- -2.27.0 - diff --git a/virtio-add-support-for-configure-interrupt-new.patch b/virtio-add-support-for-configure-interrupt-new.patch deleted file mode 100644 index 72a134791f3be49c3dda5ab63536f170626805c2..0000000000000000000000000000000000000000 --- a/virtio-add-support-for-configure-interrupt-new.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 90152f58401b828febbb060cff86330827e6befe Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:47 +0800 -Subject: [PATCH] virtio: add support for configure interrupt - -Add the functions to support the configure interrupt in virtio -The function virtio_config_guest_notifier_read will notify the -guest if there is an configure interrupt. -The function virtio_config_set_guest_notifier_fd_handler is -to set the fd hander for the notifier - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-7-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio.c | 29 +++++++++++++++++++++++++++++ - include/hw/virtio/virtio.h | 4 ++++ - 2 files changed, 33 insertions(+) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 12f4a8ab3d..e3f392fc59 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -3548,7 +3548,14 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n) - virtio_irq(vq); - } - } -+static void virtio_config_guest_notifier_read(EventNotifier *n) -+{ -+ VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier); - -+ if (event_notifier_test_and_clear(n)) { -+ virtio_notify_config(vdev); -+ } -+} - void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, - bool with_irqfd) - { -@@ -3565,6 +3572,23 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, - } - } - -+void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev, -+ bool assign, bool with_irqfd) -+{ -+ EventNotifier *n; -+ n = &vdev->config_notifier; -+ if (assign && !with_irqfd) { -+ event_notifier_set_handler(n, virtio_config_guest_notifier_read); -+ } else { -+ event_notifier_set_handler(n, NULL); -+ } -+ if (!assign) { -+ /* Test and clear notifier before closing it,*/ -+ /* in case poll callback didn't have time to run. */ -+ virtio_config_guest_notifier_read(n); -+ } -+} -+ - EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq) - { - return &vq->guest_notifier; -@@ -3638,6 +3662,11 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq) - return &vq->host_notifier; - } - -+EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev) -+{ -+ return &vdev->config_notifier; -+} -+ - void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled) - { - vq->host_notifier_enabled = enabled; -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index 91d1c3433a..43509b33ff 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -114,6 +114,7 @@ struct VirtIODevice - bool use_guest_notifier_mask; - AddressSpace *dma_as; - QLIST_HEAD(, VirtQueue) *vector_queues; -+ EventNotifier config_notifier; - }; - - struct VirtioDeviceClass { -@@ -329,6 +330,9 @@ void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx, - VirtIOHandleAIOOutput handle_output); - VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector); - VirtQueue *virtio_vector_next_queue(VirtQueue *vq); -+EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev); -+void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev, -+ bool assign, bool with_irqfd); - - static inline void virtio_add_feature(uint64_t *features, unsigned int fbit) - { --- -2.27.0 - diff --git a/virtio-add-support-for-configure-interrupt.patch b/virtio-add-support-for-configure-interrupt.patch deleted file mode 100644 index b5bc73ab8480c461ba17ba7c37155d6150d4bae9..0000000000000000000000000000000000000000 --- a/virtio-add-support-for-configure-interrupt.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 3ada114454dba1f4b8c6c30e64dfeedd41a6efc8 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:52 +0800 -Subject: [PATCH] virtio: add support for configure interrupt - -Add the functions to support the configure interrupt in virtio -The function virtio_config_guest_notifier_read will notify the -guest if there is an configure interrupt. -The function virtio_config_set_guest_notifier_fd_handler is -to set the fd hander for the notifier - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-7-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio.c | 29 +++++++++++++++++++++++++++++ - include/hw/virtio/virtio.h | 4 ++++ - 2 files changed, 33 insertions(+) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 071668e3e0..d90cabe868 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -3546,7 +3546,14 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n) - virtio_irq(vq); - } - } -+static void virtio_config_guest_notifier_read(EventNotifier *n) -+{ -+ VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier); - -+ if (event_notifier_test_and_clear(n)) { -+ virtio_notify_config(vdev); -+ } -+} - void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, - bool with_irqfd) - { -@@ -3563,6 +3570,23 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, - } - } - -+void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev, -+ bool assign, bool with_irqfd) -+{ -+ EventNotifier *n; -+ n = &vdev->config_notifier; -+ if (assign && !with_irqfd) { -+ event_notifier_set_handler(n, virtio_config_guest_notifier_read); -+ } else { -+ event_notifier_set_handler(n, NULL); -+ } -+ if (!assign) { -+ /* Test and clear notifier before closing it,*/ -+ /* in case poll callback didn't have time to run. */ -+ virtio_config_guest_notifier_read(n); -+ } -+} -+ - EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq) - { - return &vq->guest_notifier; -@@ -3636,6 +3660,11 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq) - return &vq->host_notifier; - } - -+EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev) -+{ -+ return &vdev->config_notifier; -+} -+ - void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled) - { - vq->host_notifier_enabled = enabled; -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index c113a5b864..8788ccd1f3 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -112,6 +112,7 @@ struct VirtIODevice - bool use_guest_notifier_mask; - AddressSpace *dma_as; - QLIST_HEAD(, VirtQueue) *vector_queues; -+ EventNotifier config_notifier; - }; - - struct VirtioDeviceClass { -@@ -315,11 +316,14 @@ uint16_t virtio_get_queue_index(VirtQueue *vq); - EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq); - void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, - bool with_irqfd); -+void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev, -+ bool assign, bool with_irqfd); - int virtio_device_start_ioeventfd(VirtIODevice *vdev); - int virtio_device_grab_ioeventfd(VirtIODevice *vdev); - void virtio_device_release_ioeventfd(VirtIODevice *vdev); - bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev); - EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq); -+EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev); - void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled); - void virtio_queue_host_notifier_read(EventNotifier *n); - void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx, --- -2.27.0 - diff --git a/virtio-add-vhost-support-for-virtio-devices.patch b/virtio-add-vhost-support-for-virtio-devices.patch deleted file mode 100644 index 5d9448014ff279e0442c45fcad56ea60b6ac7937..0000000000000000000000000000000000000000 --- a/virtio-add-vhost-support-for-virtio-devices.patch +++ /dev/null @@ -1,336 +0,0 @@ -From b51d5c0def1e902a716bd3896d2f1868c635c554 Mon Sep 17 00:00:00 2001 -From: Jonah Palmer -Date: Fri, 1 Apr 2022 09:23:19 -0400 -Subject: [PATCH] virtio: add vhost support for virtio devices - -This patch adds a get_vhost() callback function for VirtIODevices that -returns the device's corresponding vhost_dev structure, if the vhost -device is running. This patch also adds a vhost_started flag for -VirtIODevices. - -Previously, a VirtIODevice wouldn't be able to tell if its corresponding -vhost device was active or not. - -Signed-off-by: Jonah Palmer -Message-Id: <1648819405-25696-3-git-send-email-jonah.palmer@oracle.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/block/vhost-user-blk.c | 7 +++++++ - hw/display/vhost-user-gpu.c | 7 +++++++ - hw/input/vhost-user-input.c | 7 +++++++ - hw/net/virtio-net.c | 9 +++++++++ - hw/scsi/vhost-scsi.c | 8 ++++++++ - hw/virtio/vhost-user-fs.c | 7 +++++++ - hw/virtio/vhost-user-rng.c | 7 +++++++ - hw/virtio/vhost-vsock-common.c | 7 +++++++ - hw/virtio/vhost.c | 4 +++- - hw/virtio/virtio-crypto.c | 10 ++++++++++ - hw/virtio/virtio.c | 1 + - include/hw/virtio/virtio.h | 3 +++ - 12 files changed, 76 insertions(+), 1 deletion(-) - -diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c -index bcc3f83c4b..9bf18434c2 100644 ---- a/hw/block/vhost-user-blk.c -+++ b/hw/block/vhost-user-blk.c -@@ -573,6 +573,12 @@ static void vhost_user_blk_instance_init(Object *obj) - "/disk@0,0", DEVICE(obj)); - } - -+static struct vhost_dev *vhost_user_blk_get_vhost(VirtIODevice *vdev) -+{ -+ VHostUserBlk *s = VHOST_USER_BLK(vdev); -+ return &s->dev; -+} -+ - static const VMStateDescription vmstate_vhost_user_blk = { - .name = "vhost-user-blk", - .minimum_version_id = 1, -@@ -607,6 +613,7 @@ static void vhost_user_blk_class_init(ObjectClass *klass, void *data) - vdc->get_features = vhost_user_blk_get_features; - vdc->set_status = vhost_user_blk_set_status; - vdc->reset = vhost_user_blk_reset; -+ vdc->get_vhost = vhost_user_blk_get_vhost; - } - - static const TypeInfo vhost_user_blk_info = { -diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c -index 49df56cd14..6e93b463d6 100644 ---- a/hw/display/vhost-user-gpu.c -+++ b/hw/display/vhost-user-gpu.c -@@ -565,6 +565,12 @@ vhost_user_gpu_device_realize(DeviceState *qdev, Error **errp) - g->vhost_gpu_fd = -1; - } - -+static struct vhost_dev *vhost_user_gpu_get_vhost(VirtIODevice *vdev) -+{ -+ VhostUserGPU *g = VHOST_USER_GPU(vdev); -+ return &g->vhost->dev; -+} -+ - static Property vhost_user_gpu_properties[] = { - VIRTIO_GPU_BASE_PROPERTIES(VhostUserGPU, parent_obj.conf), - DEFINE_PROP_END_OF_LIST(), -@@ -586,6 +592,7 @@ vhost_user_gpu_class_init(ObjectClass *klass, void *data) - vdc->guest_notifier_pending = vhost_user_gpu_guest_notifier_pending; - vdc->get_config = vhost_user_gpu_get_config; - vdc->set_config = vhost_user_gpu_set_config; -+ vdc->get_vhost = vhost_user_gpu_get_vhost; - - device_class_set_props(dc, vhost_user_gpu_properties); - } -diff --git a/hw/input/vhost-user-input.c b/hw/input/vhost-user-input.c -index 273e96a7b1..43d2ff3816 100644 ---- a/hw/input/vhost-user-input.c -+++ b/hw/input/vhost-user-input.c -@@ -79,6 +79,12 @@ static void vhost_input_set_config(VirtIODevice *vdev, - virtio_notify_config(vdev); - } - -+static struct vhost_dev *vhost_input_get_vhost(VirtIODevice *vdev) -+{ -+ VHostUserInput *vhi = VHOST_USER_INPUT(vdev); -+ return &vhi->vhost->dev; -+} -+ - static const VMStateDescription vmstate_vhost_input = { - .name = "vhost-user-input", - .unmigratable = 1, -@@ -93,6 +99,7 @@ static void vhost_input_class_init(ObjectClass *klass, void *data) - dc->vmsd = &vmstate_vhost_input; - vdc->get_config = vhost_input_get_config; - vdc->set_config = vhost_input_set_config; -+ vdc->get_vhost = vhost_input_get_vhost; - vic->realize = vhost_input_realize; - vic->change_active = vhost_input_change_active; - } -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 3bd786cc22..41bb4010b0 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3644,6 +3644,14 @@ static bool dev_unplug_pending(void *opaque) - return vdc->primary_unplug_pending(dev); - } - -+static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev) -+{ -+ VirtIONet *n = VIRTIO_NET(vdev); -+ NetClientState *nc = qemu_get_queue(n->nic); -+ struct vhost_net *net = get_vhost_net(nc->peer); -+ return &net->dev; -+} -+ - static const VMStateDescription vmstate_virtio_net = { - .name = "virtio-net", - .minimum_version_id = VIRTIO_NET_VM_VERSION, -@@ -3785,6 +3793,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) - vdc->post_load = virtio_net_post_load_virtio; - vdc->vmsd = &vmstate_virtio_net_device; - vdc->primary_unplug_pending = primary_unplug_pending; -+ vdc->get_vhost = virtio_net_get_vhost; - } - - static const TypeInfo virtio_net_info = { -diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c -index 039caf2614..b0a9c45e43 100644 ---- a/hw/scsi/vhost-scsi.c -+++ b/hw/scsi/vhost-scsi.c -@@ -264,6 +264,13 @@ static void vhost_scsi_unrealize(DeviceState *dev) - virtio_scsi_common_unrealize(dev); - } - -+static struct vhost_dev *vhost_scsi_get_vhost(VirtIODevice *vdev) -+{ -+ VHostSCSI *s = VHOST_SCSI(vdev); -+ VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); -+ return &vsc->dev; -+} -+ - static Property vhost_scsi_properties[] = { - DEFINE_PROP_STRING("vhostfd", VirtIOSCSICommon, conf.vhostfd), - DEFINE_PROP_STRING("wwpn", VirtIOSCSICommon, conf.wwpn), -@@ -298,6 +305,7 @@ static void vhost_scsi_class_init(ObjectClass *klass, void *data) - vdc->get_features = vhost_scsi_common_get_features; - vdc->set_config = vhost_scsi_common_set_config; - vdc->set_status = vhost_scsi_set_status; -+ vdc->get_vhost = vhost_scsi_get_vhost; - fwc->get_dev_path = vhost_scsi_common_get_fw_dev_path; - } - -diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c -index fc7dcc96ef..392b7d3aa1 100644 ---- a/hw/virtio/vhost-user-fs.c -+++ b/hw/virtio/vhost-user-fs.c -@@ -277,6 +277,12 @@ static void vuf_device_unrealize(DeviceState *dev) - g_free(vhost_vqs); - } - -+static struct vhost_dev *vuf_get_vhost(VirtIODevice *vdev) -+{ -+ VHostUserFS *fs = VHOST_USER_FS(vdev); -+ return &fs->vhost_dev; -+} -+ - static const VMStateDescription vuf_vmstate = { - .name = "vhost-user-fs", - .unmigratable = 1, -@@ -314,6 +320,7 @@ static void vuf_class_init(ObjectClass *klass, void *data) - vdc->set_status = vuf_set_status; - vdc->guest_notifier_mask = vuf_guest_notifier_mask; - vdc->guest_notifier_pending = vuf_guest_notifier_pending; -+ vdc->get_vhost = vuf_get_vhost; - } - - static const TypeInfo vuf_info = { -diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c -index 209ee5bf9a..543f3e3cef 100644 ---- a/hw/virtio/vhost-user-rng.c -+++ b/hw/virtio/vhost-user-rng.c -@@ -247,6 +247,12 @@ static void vu_rng_device_unrealize(DeviceState *dev) - vhost_user_cleanup(&rng->vhost_user); - } - -+static struct vhost_dev *vu_rng_get_vhost(VirtIODevice *vdev) -+{ -+ VHostUserRNG *rng = VHOST_USER_RNG(vdev); -+ return &rng->vhost_dev; -+} -+ - static const VMStateDescription vu_rng_vmstate = { - .name = "vhost-user-rng", - .unmigratable = 1, -@@ -272,6 +278,7 @@ static void vu_rng_class_init(ObjectClass *klass, void *data) - vdc->set_status = vu_rng_set_status; - vdc->guest_notifier_mask = vu_rng_guest_notifier_mask; - vdc->guest_notifier_pending = vu_rng_guest_notifier_pending; -+ vdc->get_vhost = vu_rng_get_vhost; - } - - static const TypeInfo vu_rng_info = { -diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c -index ed706681ac..cd45aaf28e 100644 ---- a/hw/virtio/vhost-vsock-common.c -+++ b/hw/virtio/vhost-vsock-common.c -@@ -259,6 +259,12 @@ void vhost_vsock_common_unrealize(VirtIODevice *vdev) - virtio_cleanup(vdev); - } - -+static struct vhost_dev *vhost_vsock_common_get_vhost(VirtIODevice *vdev) -+{ -+ VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); -+ return &vvc->vhost_dev; -+} -+ - static Property vhost_vsock_common_properties[] = { - DEFINE_PROP_ON_OFF_AUTO("seqpacket", VHostVSockCommon, seqpacket, - ON_OFF_AUTO_AUTO), -@@ -274,6 +280,7 @@ static void vhost_vsock_common_class_init(ObjectClass *klass, void *data) - set_bit(DEVICE_CATEGORY_MISC, dc->categories); - vdc->guest_notifier_mask = vhost_vsock_common_guest_notifier_mask; - vdc->guest_notifier_pending = vhost_vsock_common_guest_notifier_pending; -+ vdc->get_vhost = vhost_vsock_common_get_vhost; - } - - static const TypeInfo vhost_vsock_common_info = { -diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c -index 2f9bb96d63..c1f5cb5b91 100644 ---- a/hw/virtio/vhost.c -+++ b/hw/virtio/vhost.c -@@ -1766,6 +1766,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev) - /* should only be called after backend is connected */ - assert(hdev->vhost_ops); - -+ vdev->vhost_started = true; - hdev->started = true; - hdev->vdev = vdev; - -@@ -1838,7 +1839,7 @@ fail_vq: - - fail_mem: - fail_features: -- -+ vdev->vhost_started = false; - hdev->started = false; - return r; - } -@@ -1869,6 +1870,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev) - } - vhost_log_put(hdev, true); - hdev->started = false; -+ vdev->vhost_started = false; - hdev->vdev = NULL; - } - -diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c -index 274c7b4dea..f9d849fa43 100644 ---- a/hw/virtio/virtio-crypto.c -+++ b/hw/virtio/virtio-crypto.c -@@ -966,6 +966,15 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx) - return cryptodev_vhost_virtqueue_pending(vdev, queue, idx); - } - -+static struct vhost_dev *virtio_crypto_get_vhost(VirtIODevice *vdev) -+{ -+ VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); -+ CryptoDevBackend *b = vcrypto->cryptodev; -+ CryptoDevBackendClient *cc = b->conf.peers.ccs[0]; -+ CryptoDevBackendVhost *vhost_crypto = cryptodev_get_vhost(cc, b, 0); -+ return &vhost_crypto->dev; -+} -+ - static void virtio_crypto_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); -@@ -982,6 +991,7 @@ static void virtio_crypto_class_init(ObjectClass *klass, void *data) - vdc->set_status = virtio_crypto_set_status; - vdc->guest_notifier_mask = virtio_crypto_guest_notifier_mask; - vdc->guest_notifier_pending = virtio_crypto_guest_notifier_pending; -+ vdc->get_vhost = virtio_crypto_get_vhost; - } - - static void virtio_crypto_instance_init(Object *obj) -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index c1497f59aa..12f4a8ab3d 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -3298,6 +3298,7 @@ void virtio_init(VirtIODevice *vdev, const char *name, - - vdev->start_on_kick = false; - vdev->started = false; -+ vdev->vhost_started = false; - vdev->device_id = device_id; - vdev->status = 0; - qatomic_set(&vdev->isr, 0); -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index 7472145821..223e82436f 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -22,6 +22,7 @@ - #include "standard-headers/linux/virtio_config.h" - #include "standard-headers/linux/virtio_ring.h" - #include "qom/object.h" -+#include "hw/virtio/vhost.h" - - /* A guest should never accept this. It implies negotiation is broken. */ - #define VIRTIO_F_BAD_FEATURE 30 -@@ -103,6 +104,7 @@ struct VirtIODevice - bool started; - bool start_on_kick; /* when virtio 1.0 feature has not been negotiated */ - bool disable_legacy_check; -+ bool vhost_started; - VMChangeStateEntry *vmstate; - char *bus_name; - uint8_t device_endian; -@@ -162,6 +164,7 @@ struct VirtioDeviceClass { - int (*post_load)(VirtIODevice *vdev); - const VMStateDescription *vmsd; - bool (*primary_unplug_pending)(void *opaque); -+ struct vhost_dev *(*get_vhost)(VirtIODevice *vdev); - }; - - void virtio_instance_init_common(Object *proxy_obj, void *data, --- -2.27.0 - diff --git a/virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch b/virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch deleted file mode 100644 index 39551a752e5ae493872be352cb39191a026420ad..0000000000000000000000000000000000000000 --- a/virtio-bugfix-add-rcu_read_lock-when-vring_avail_idx.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 41aa66e37d04246d48b5417c57967425ecc466a0 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 11:16:26 +0800 -Subject: [PATCH] virtio: bugfix: add rcu_read_lock when vring_avail_idx is - called - -viring_avail_idx should be called within rcu_read_lock(), -or may get NULL caches in vring_get_region_caches() and -trigger assert(). - -Signed-off-by: Jinhua Cao ---- - hw/virtio/virtio.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 007f4c9e26..0af9684881 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -2864,6 +2864,7 @@ static void check_vring_avail_num(VirtIODevice *vdev, int index) - { - uint16_t nheads; - -+ rcu_read_lock(); - /* Check it isn't doing strange things with descriptor numbers. */ - nheads = vring_avail_idx(&vdev->vq[index]) - vdev->vq[index].last_avail_idx; - if (nheads > vdev->vq[index].vring.num) { -@@ -2874,6 +2875,7 @@ static void check_vring_avail_num(VirtIODevice *vdev, int index) - vring_avail_idx(&vdev->vq[index]), - vdev->vq[index].last_avail_idx, nheads); - } -+ rcu_read_unlock(); - } - - int virtio_save(VirtIODevice *vdev, QEMUFile *f) --- -2.27.0 - diff --git a/virtio-bugfix-check-the-value-of-caches-before-acces.patch b/virtio-bugfix-check-the-value-of-caches-before-acces.patch deleted file mode 100644 index 8cead345733d1b88a88b21c45c71948e38b147b6..0000000000000000000000000000000000000000 --- a/virtio-bugfix-check-the-value-of-caches-before-acces.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 74ab61b4317f12b231fb2cbcd54a333a07efd678 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 14:37:52 +0800 -Subject: [PATCH] virtio: bugfix: check the value of caches before accessing it - -Vring caches may be NULL in check_vring_avail_num() if -virtio_reset() is called at the same time, such as when -the virtual machine starts. -So check it before accessing it in vring_avail_idx(). - -Signed-off-by: Jinhua Cao ---- - hw/virtio/virtio.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 9a2a83d507..b08fff9419 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -2863,8 +2863,19 @@ static const VMStateDescription vmstate_virtio = { - static void check_vring_avail_num(VirtIODevice *vdev, int index) - { - uint16_t nheads; -+ VRingMemoryRegionCaches *caches; - - rcu_read_lock(); -+ caches = qatomic_rcu_read(&vdev->vq[index].vring.caches); -+ if (caches == NULL) { -+ /* -+ * caches may be NULL if virtio_reset is called at the same time, -+ * such as when the virtual machine starts. -+ */ -+ rcu_read_unlock(); -+ return; -+ } -+ - /* Check it isn't doing strange things with descriptor numbers. */ - nheads = vring_avail_idx(&vdev->vq[index]) - vdev->vq[index].last_avail_idx; - if (nheads > vdev->vq[index].vring.num) { --- -2.27.0 - diff --git a/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch b/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch deleted file mode 100644 index c0e259b19742a5aef0b42e3d8cb16100e6449ae5..0000000000000000000000000000000000000000 --- a/virtio-bugfix-clean-up-callback-when-del-virtqueue.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 95d334a905e8ddaac4a8cec908dcdb03b2e5993f Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 10:17:20 +0800 -Subject: [PATCH] virtio: bugfix: clean up callback when del virtqueue - -We will access NULL pointer as follow: -1. Start a vm with multiqueue vhost-net -2. then we write VIRTIO_PCI_GUEST_FEATURES in PCI configuration to - trigger multiqueue disable in this vm which will delete the virtqueue. - In this step, the tx_bh is deleted but the callback virtio_net_handle_tx_bh - still exist. -3. Finally, we write VIRTIO_PCI_QUEUE_NOTIFY in PCI configuration to - notify the deleted virtqueue. In this way, virtio_net_handle_tx_bh - will be called and qemu will be crashed. - -Signed-off-by: Jinhua Cao ---- - hw/net/virtio-net.c | 5 ++++- - hw/virtio/virtio.c | 1 + - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index f2014d5ea0..b3a5d0b19e 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -2644,7 +2644,10 @@ static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq) - return; - } - virtio_queue_set_notification(vq, 0); -- qemu_bh_schedule(q->tx_bh); -+ -+ if (q->tx_bh) { -+ qemu_bh_schedule(q->tx_bh); -+ } - } - - static void virtio_net_tx_timer(void *opaque) -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 9b4ac58a16..ec3e96af3b 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -2417,6 +2417,7 @@ void virtio_delete_queue(VirtQueue *vq) - { - vq->vring.num = 0; - vq->vring.num_default = 0; -+ vq->vring.align = 0; - vq->handle_output = NULL; - vq->handle_aio_output = NULL; - g_free(vq->used_elems); --- -2.27.0 - diff --git a/virtio-check-descriptor-numbers.patch b/virtio-check-descriptor-numbers.patch deleted file mode 100644 index ea38103f2e17a2657060d9b72edf6470c8b0041c..0000000000000000000000000000000000000000 --- a/virtio-check-descriptor-numbers.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 9e04e1c6a7a12e3e1d0a8a7cf07f441597a1dbb7 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 11:09:36 +0800 -Subject: [PATCH] virtio: check descriptor numbers - -Check if the vring num is normal in virtio_save(), and add LOG -the vm push the wrong viring num down through writing IO Port. - -Signed-off-by: Jinhua Cao ---- - hw/virtio/virtio.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 03afa36e99..007f4c9e26 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -2860,6 +2860,22 @@ static const VMStateDescription vmstate_virtio = { - } - }; - -+static void check_vring_avail_num(VirtIODevice *vdev, int index) -+{ -+ uint16_t nheads; -+ -+ /* Check it isn't doing strange things with descriptor numbers. */ -+ nheads = vring_avail_idx(&vdev->vq[index]) - vdev->vq[index].last_avail_idx; -+ if (nheads > vdev->vq[index].vring.num) { -+ qemu_log("VQ %d size 0x%x Guest index 0x%x " -+ "inconsistent with Host index 0x%x: " -+ "delta 0x%x\n", -+ index, vdev->vq[index].vring.num, -+ vring_avail_idx(&vdev->vq[index]), -+ vdev->vq[index].last_avail_idx, nheads); -+ } -+} -+ - int virtio_save(VirtIODevice *vdev, QEMUFile *f) - { - BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); -@@ -2890,6 +2906,8 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f) - if (vdev->vq[i].vring.num == 0) - break; - -+ check_vring_avail_num(vdev, i); -+ - qemu_put_be32(f, vdev->vq[i].vring.num); - if (k->has_variable_vring_alignment) { - qemu_put_be32(f, vdev->vq[i].vring.align); --- -2.27.0 - diff --git a/virtio-crypto-verify-src-dst-buffer-length-for-sym-r.patch b/virtio-crypto-verify-src-dst-buffer-length-for-sym-r.patch deleted file mode 100644 index a449c2df4fed8f4f990ea4a3a9095c46d416f5c3..0000000000000000000000000000000000000000 --- a/virtio-crypto-verify-src-dst-buffer-length-for-sym-r.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 017c7af0d5b928c6af60f8262c62d4c570b2e55e Mon Sep 17 00:00:00 2001 -From: zhenwei pi -Date: Thu, 3 Aug 2023 10:43:13 +0800 -Subject: [PATCH] virtio-crypto: verify src&dst buffer length for sym request - -For symmetric algorithms, the length of ciphertext must be as same -as the plaintext. -The missing verification of the src_len and the dst_len in -virtio_crypto_sym_op_helper() may lead buffer overflow/divulged. - -This patch is originally written by Yiming Tao for QEMU-SECURITY, -resend it(a few changes of error message) in qemu-devel. - -Fixes: CVE-2023-3180 -Fixes: 04b9b37edda("virtio-crypto: add data queue processing handler") -Cc: Gonglei -Cc: Mauro Matteo Cascella -Cc: Yiming Tao -Signed-off-by: zhenwei pi -Message-Id: <20230803024314.29962-2-pizhenwei@bytedance.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -(cherry picked from commit 9d38a8434721a6479fe03fb5afb150ca793d3980) -Signed-off-by: Michael Tokarev ---- - hw/virtio/virtio-crypto.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c -index 54f9bbb789..274c7b4dea 100644 ---- a/hw/virtio/virtio-crypto.c -+++ b/hw/virtio/virtio-crypto.c -@@ -461,6 +461,11 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev, - return NULL; - } - -+ if (unlikely(src_len != dst_len)) { -+ virtio_error(vdev, "sym request src len is different from dst len"); -+ return NULL; -+ } -+ - max_len = (uint64_t)iv_len + aad_len + src_len + dst_len + hash_result_len; - if (unlikely(max_len > vcrypto->conf.max_size)) { - virtio_error(vdev, "virtio-crypto too big length"); --- -2.41.0.windows.1 - diff --git a/virtio-crypto-verify-src-dst-buffer-length-for-sym-request.patch b/virtio-crypto-verify-src-dst-buffer-length-for-sym-request.patch deleted file mode 100644 index 76ce5d75e24557b07aba59af4f7becd36d407a26..0000000000000000000000000000000000000000 --- a/virtio-crypto-verify-src-dst-buffer-length-for-sym-request.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 9110c9bf711a39b3c9a1bdbe2fc84f38930d3094 Mon Sep 17 00:00:00 2001 -From: zhenwei pi -Date: Thu, 3 Aug 2023 10:43:13 +0800 -Subject: [PATCH] virtio-crypto: verify src&dst buffer length for sym request - -For symmetric algorithms, the length of ciphertext must be as same -as the plaintext. -The missing verification of the src_len and the dst_len in -virtio_crypto_sym_op_helper() may lead buffer overflow/divulged. - -This patch is originally written by Yiming Tao for QEMU-SECURITY, -resend it(a few changes of error message) in qemu-devel. - -Fixes: CVE-2023-3180 -Fixes: 04b9b37edda("virtio-crypto: add data queue processing handler") -Cc: Gonglei -Cc: Mauro Matteo Cascella -Cc: Yiming Tao -Signed-off-by: zhenwei pi -Message-Id: <20230803024314.29962-2-pizhenwei@bytedance.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-crypto.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c -index 98304184cd..9f7dcc88ba 100644 ---- a/hw/virtio/virtio-crypto.c -+++ b/hw/virtio/virtio-crypto.c -@@ -466,6 +466,11 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev, - return NULL; - } - -+ if (unlikely(src_len != dst_len)) { -+ virtio_error(vdev, "sym request src len is different from dst len"); -+ return NULL; -+ } -+ - max_len = (uint64_t)iv_len + aad_len + src_len + dst_len + hash_result_len; - if (unlikely(max_len > vcrypto->conf.max_size)) { - virtio_error(vdev, "virtio-crypto too big length"); --- -2.27.0 - diff --git a/virtio-fix-enable-vhost-user-build-on-non-Linux.patch b/virtio-fix-enable-vhost-user-build-on-non-Linux.patch deleted file mode 100644 index c124baf67a3615f63340642476aeeecdc9f326b6..0000000000000000000000000000000000000000 --- a/virtio-fix-enable-vhost-user-build-on-non-Linux.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 558472cd6040b5515baaf860b5bba0c1c511d18b Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Mon, 28 Mar 2022 17:58:27 +0200 -Subject: [PATCH] virtio: fix --enable-vhost-user build on non-Linux -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The vhost-shadow-virtqueue.c build requires include files from -linux-headers/, so it cannot be built on non-Linux systems. -Fortunately it is only needed by vhost-vdpa, so move it there. - -Acked-by: Eugenio Pérez -Acked-by: Jason Wang -Signed-off-by: Paolo Bonzini -Signed-off-by: fangyi ---- - hw/virtio/meson.build | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build -index c2e193f56d..c2da69616f 100644 ---- a/hw/virtio/meson.build -+++ b/hw/virtio/meson.build -@@ -11,9 +11,9 @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c')) - - virtio_ss = ss.source_set() - virtio_ss.add(files('virtio.c')) --virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c', 'vhost-iova-tree.c')) -+virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-iova-tree.c')) - virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c')) --virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c')) -+virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-shadow-virtqueue.c', 'vhost-vdpa.c')) - virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c')) - virtio_ss.add(when: 'CONFIG_VIRTIO_CRYPTO', if_true: files('virtio-crypto.c')) - virtio_ss.add(when: ['CONFIG_VIRTIO_CRYPTO', 'CONFIG_VIRTIO_PCI'], if_true: files('virtio-crypto-pci.c')) --- -2.27.0 - diff --git a/virtio-fix-reachable-assertion-due-to-stale-value-of.patch b/virtio-fix-reachable-assertion-due-to-stale-value-of.patch deleted file mode 100644 index e070054f871114dd33a301f61d365f8a7e77d4b5..0000000000000000000000000000000000000000 --- a/virtio-fix-reachable-assertion-due-to-stale-value-of.patch +++ /dev/null @@ -1,110 +0,0 @@ -From fc3c5fc2f3ccc236a6bcb670043912ab31e99772 Mon Sep 17 00:00:00 2001 -From: wangmeiyang -Date: Fri, 26 May 2023 11:09:19 +0800 -Subject: [PATCH] virtio: fix reachable assertion due to stale value of cached - region size -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In virtqueue_{split,packed}_get_avail_bytes() descriptors are read -in a loop via MemoryRegionCache regions and calls to -vring_{split,packed}_desc_read() - these take a region cache and the -index of the descriptor to be read. - -For direct descriptors we use a cache provided by the caller, whose -size matches that of the virtqueue vring. We limit the number of -descriptors we can read by the size of that vring: - max = vq->vring.num; - ... - MemoryRegionCache *desc_cache = &caches->desc; - -For indirect descriptors, we initialize a new cache and limit the -number of descriptors by the size of the intermediate descriptor: - - len = address_space_cache_init(&indirect_desc_cache, - vdev->dma_as, - desc.addr, desc.len, false); - desc_cache = &indirect_desc_cache; - ... - max = desc.len / sizeof(VRingDesc); - -However, the first initialization of `max` is done outside the loop -where we process guest descriptors, while the second one is done -inside. This means that a sequence of an indirect descriptor followed -by a direct one will leave a stale value in `max`. If the second -descriptor's `next` field is smaller than the stale value, but -greater than the size of the virtqueue ring (and thus the cached -region), a failed assertion will be triggered in -address_space_read_cached() down the call chain. - -Fix this by initializing `max` inside the loop in both functions. - -origin commit: https://gitlab.com/qemu-project/qemu/-/commit/bbc1c327d7974261c61566cdb950cc5fa0196b41 -Signed-off-by: Meiyang Wang -Fixes: 9796d0ac8fb0 ("virtio: use address_space_map/unmap to access descriptors") -Signed-off-by: Carlos López -Message-Id: <20230302100358.3613-1-clopez@suse.de> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin ---- - hw/virtio/virtio.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index f8ab48e6bd..071668e3e0 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -983,7 +983,7 @@ static void virtqueue_split_get_avail_bytes(VirtQueue *vq, - VRingMemoryRegionCaches *caches) - { - VirtIODevice *vdev = vq->vdev; -- unsigned int max, idx; -+ unsigned int idx; - unsigned int total_bufs, in_total, out_total; - MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID; - int64_t len = 0; -@@ -992,13 +992,12 @@ static void virtqueue_split_get_avail_bytes(VirtQueue *vq, - idx = vq->last_avail_idx; - total_bufs = in_total = out_total = 0; - -- max = vq->vring.num; -- - while ((rc = virtqueue_num_heads(vq, idx)) > 0) { - MemoryRegionCache *desc_cache = &caches->desc; - unsigned int num_bufs; - VRingDesc desc; - unsigned int i; -+ unsigned int max = vq->vring.num; - - num_bufs = total_bufs; - -@@ -1120,7 +1119,7 @@ static void virtqueue_packed_get_avail_bytes(VirtQueue *vq, - VRingMemoryRegionCaches *caches) - { - VirtIODevice *vdev = vq->vdev; -- unsigned int max, idx; -+ unsigned int idx; - unsigned int total_bufs, in_total, out_total; - MemoryRegionCache *desc_cache; - MemoryRegionCache indirect_desc_cache = MEMORY_REGION_CACHE_INVALID; -@@ -1132,14 +1131,14 @@ static void virtqueue_packed_get_avail_bytes(VirtQueue *vq, - wrap_counter = vq->last_avail_wrap_counter; - total_bufs = in_total = out_total = 0; - -- max = vq->vring.num; -- - for (;;) { - unsigned int num_bufs = total_bufs; - unsigned int i = idx; - int rc; -+ unsigned int max = vq->vring.num; - - desc_cache = &caches->desc; -+ - vring_packed_desc_read(vdev, &desc, desc_cache, idx, true); - if (!is_desc_avail(desc.flags, wrap_counter)) { - break; --- -2.41.0.windows.1 - diff --git a/virtio-get-class_id-and-pci-device-id-by-the-virtio-.patch b/virtio-get-class_id-and-pci-device-id-by-the-virtio-.patch deleted file mode 100644 index 28d19266c62fca46e8e60bdb6314856e21f49ff4..0000000000000000000000000000000000000000 --- a/virtio-get-class_id-and-pci-device-id-by-the-virtio-.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 78f66113a2c3a01f0290a982f6901ba57516f47f Mon Sep 17 00:00:00 2001 -From: Longpeng -Date: Sat, 12 Nov 2022 22:40:09 +0800 -Subject: [PATCH 2/7] virtio: get class_id and pci device id by the virtio id - -Add helpers to get the "Transitional PCI Device ID" and "class_id" -of the device specified by the "Virtio Device ID". - -These helpers will be used to build the generic vDPA device later. - -Acked-by: Jason Wang -Signed-off-by: Longpeng ---- - hw/virtio/virtio-pci.c | 88 ++++++++++++++++++++++++++++++++++++++++++ - hw/virtio/virtio-pci.h | 5 +++ - 2 files changed, 93 insertions(+) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 38a5dc1ba8..21c0ec3b1b 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -19,6 +19,7 @@ - - #include "exec/memop.h" - #include "standard-headers/linux/virtio_pci.h" -+#include "standard-headers/linux/virtio_ids.h" - #include "hw/boards.h" - #include "hw/virtio/virtio.h" - #include "migration/qemu-file-types.h" -@@ -213,6 +214,90 @@ static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f) - return 0; - } - -+typedef struct VirtIOPCIIDInfo { -+ /* virtio id */ -+ uint16_t vdev_id; -+ /* pci device id for the transitional device */ -+ uint16_t trans_devid; -+ uint16_t class_id; -+} VirtIOPCIIDInfo; -+ -+static const VirtIOPCIIDInfo virtio_pci_id_info[] = { -+ { -+ .vdev_id = VIRTIO_ID_CRYPTO, -+ .class_id = PCI_CLASS_OTHERS, -+ }, { -+ .vdev_id = VIRTIO_ID_FS, -+ .class_id = PCI_CLASS_STORAGE_OTHER, -+ }, { -+ .vdev_id = VIRTIO_ID_NET, -+ .trans_devid = PCI_DEVICE_ID_VIRTIO_NET, -+ .class_id = PCI_CLASS_NETWORK_ETHERNET, -+ }, { -+ .vdev_id = VIRTIO_ID_BLOCK, -+ .trans_devid = PCI_DEVICE_ID_VIRTIO_BLOCK, -+ .class_id = PCI_CLASS_STORAGE_SCSI, -+ }, { -+ .vdev_id = VIRTIO_ID_CONSOLE, -+ .trans_devid = PCI_DEVICE_ID_VIRTIO_CONSOLE, -+ .class_id = PCI_CLASS_COMMUNICATION_OTHER, -+ }, { -+ .vdev_id = VIRTIO_ID_SCSI, -+ .trans_devid = PCI_DEVICE_ID_VIRTIO_SCSI, -+ .class_id = PCI_CLASS_STORAGE_SCSI -+ }, { -+ .vdev_id = VIRTIO_ID_9P, -+ .trans_devid = PCI_DEVICE_ID_VIRTIO_9P, -+ .class_id = PCI_BASE_CLASS_NETWORK, -+ }, { -+ .vdev_id = VIRTIO_ID_BALLOON, -+ .trans_devid = PCI_DEVICE_ID_VIRTIO_BALLOON, -+ .class_id = PCI_CLASS_OTHERS, -+ }, { -+ .vdev_id = VIRTIO_ID_RNG, -+ .trans_devid = PCI_DEVICE_ID_VIRTIO_RNG, -+ .class_id = PCI_CLASS_OTHERS, -+ }, -+}; -+ -+static const VirtIOPCIIDInfo *virtio_pci_get_id_info(uint16_t vdev_id) -+{ -+ const VirtIOPCIIDInfo *info = NULL; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(virtio_pci_id_info); i++) { -+ if (virtio_pci_id_info[i].vdev_id == vdev_id) { -+ info = &virtio_pci_id_info[i]; -+ break; -+ } -+ } -+ -+ if (!info) { -+ /* The device id is invalid or not added to the id_info yet. */ -+ error_report("Invalid virtio device(id %u)", vdev_id); -+ abort(); -+ } -+ -+ return info; -+} -+ -+/* -+ * Get the Transitional Device ID for the specific device, return -+ * zero if the device is non-transitional. -+ */ -+uint16_t virtio_pci_get_trans_devid(uint16_t device_id) -+{ -+ return virtio_pci_get_id_info(device_id)->trans_devid; -+} -+ -+/* -+ * Get the Class ID for the specific device. -+ */ -+uint16_t virtio_pci_get_class_id(uint16_t device_id) -+{ -+ return virtio_pci_get_id_info(device_id)->class_id; -+} -+ - static bool virtio_pci_ioeventfd_enabled(DeviceState *d) - { - VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); -@@ -1674,6 +1759,9 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) - * is set to PCI_SUBVENDOR_ID_REDHAT_QUMRANET by default. - */ - pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus)); -+ if (proxy->trans_devid) { -+ pci_config_set_device_id(config, proxy->trans_devid); -+ } - } else { - /* pure virtio-1.0 */ - pci_set_word(config + PCI_VENDOR_ID, -diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h -index 2446dcd9ae..d95b1a13a5 100644 ---- a/hw/virtio/virtio-pci.h -+++ b/hw/virtio/virtio-pci.h -@@ -146,6 +146,8 @@ struct VirtIOPCIProxy { - bool disable_modern; - bool ignore_backend_features; - OnOffAuto disable_legacy; -+ /* Transitional device id */ -+ uint16_t trans_devid; - uint32_t class_code; - uint32_t nvectors; - uint32_t dfselect; -@@ -179,6 +181,9 @@ static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy) - proxy->disable_modern = true; - } - -+uint16_t virtio_pci_get_trans_devid(uint16_t device_id); -+uint16_t virtio_pci_get_class_id(uint16_t device_id); -+ - /* - * virtio-input-pci: This extends VirtioPCIProxy. - */ --- -2.27.0 - diff --git a/virtio-gpu-add-a-FIXME-for-virtio_gpu_load.patch b/virtio-gpu-add-a-FIXME-for-virtio_gpu_load.patch deleted file mode 100644 index 04f60db3dc7dbb4ec256a32bd2561f82e3078bf7..0000000000000000000000000000000000000000 --- a/virtio-gpu-add-a-FIXME-for-virtio_gpu_load.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 5a69ce95a920377f1c4f0c34c6cb8073dc5dbf8d Mon Sep 17 00:00:00 2001 -From: qihao -Date: Mon, 26 Jun 2023 14:29:40 +0800 -Subject: [PATCH] virtio-gpu: add a FIXME for virtio_gpu_load() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -cheery-pick from 529969b8d03970bae5feef8c69ebf5e0f521131c - -It looks like the virtio_gpu_load() does not compute and set the offset, -the same way virtio_gpu_set_scanout() does. This probably results in -incorrect display until the scanout/framebuffer is updated again, I -guess we should fix it, although I haven't checked this yet. - -Signed-off-by: Marc-André Lureau -Message-Id: <20230515132518.1025853-1-marcandre.lureau@redhat.com> -Signed-off-by: qihao_yewu ---- - hw/display/virtio-gpu.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c -index c6dc818988..9ccc0575e3 100644 ---- a/hw/display/virtio-gpu.c -+++ b/hw/display/virtio-gpu.c -@@ -1284,6 +1284,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, - /* load & apply scanout state */ - vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1); - for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { -+ /* FIXME: should take scanout.r.{x,y} into account */ - scanout = &g->parent_obj.scanout[i]; - if (!scanout->resource_id) { - continue; --- -2.41.0.windows.1 - diff --git a/virtio-i2c-Check-notifier-helpers-for-VIRTIO_CONFIG_.patch b/virtio-i2c-Check-notifier-helpers-for-VIRTIO_CONFIG_.patch deleted file mode 100644 index 79c916cd088ad0d6dd31a1899e56af486fa22b20..0000000000000000000000000000000000000000 --- a/virtio-i2c-Check-notifier-helpers-for-VIRTIO_CONFIG_.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 7f25adf1fd99b5b8f9455537d0c6108837ee25de Mon Sep 17 00:00:00 2001 -From: Viresh Kumar -Date: Tue, 18 Apr 2023 09:24:54 +0530 -Subject: [PATCH] virtio: i2c: Check notifier helpers for VIRTIO_CONFIG_IRQ_IDX - -Since the driver doesn't support interrupts, we must return early when -index is set to VIRTIO_CONFIG_IRQ_IDX. - -Fixes: 544f0278afca ("virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX") -Signed-off-by: Viresh Kumar -Message-Id: -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/vhost-user-i2c.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c -index dcaf471115..19add4a707 100644 ---- a/hw/virtio/vhost-user-i2c.c -+++ b/hw/virtio/vhost-user-i2c.c -@@ -129,6 +129,14 @@ static void vu_i2c_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask) - { - VHostUserI2C *i2c = VHOST_USER_I2C(vdev); - -+ /* -+ * We don't support interrupts, return early if index is set to -+ * VIRTIO_CONFIG_IRQ_IDX. -+ */ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } -+ - vhost_virtqueue_mask(&i2c->vhost_dev, vdev, idx, mask); - } - -@@ -136,6 +144,14 @@ static bool vu_i2c_guest_notifier_pending(VirtIODevice *vdev, int idx) - { - VHostUserI2C *i2c = VHOST_USER_I2C(vdev); - -+ /* -+ * We don't support interrupts, return early if index is set to -+ * VIRTIO_CONFIG_IRQ_IDX. -+ */ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } -+ - return vhost_virtqueue_pending(&i2c->vhost_dev, idx); - } - --- -2.27.0 - diff --git a/virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch b/virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch deleted file mode 100644 index c46da01cb045b956501d2b571769badd1ba97452..0000000000000000000000000000000000000000 --- a/virtio-introduce-macro-IRTIO_CONFIG_IRQ_IDX.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 438e224baf7c2debab5ac109739316d9db562e2c Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:50 +0800 -Subject: [PATCH] virtio: introduce macro IRTIO_CONFIG_IRQ_IDX - -To support configure interrupt for vhost-vdpa -Introduce VIRTIO_CONFIG_IRQ_IDX -1 as configure interrupt's queue index, -Then we can reuse the functions guest_notifier_mask and guest_notifier_pending. -Add the check of queue index in these drivers, if the driver does not support -configure interrupt, the function will just return - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-2-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/display/vhost-user-gpu.c | 6 ++++++ - hw/net/virtio-net.c | 10 ++++++++-- - hw/virtio/vhost-user-fs.c | 6 ++++++ - hw/virtio/vhost-vsock-common.c | 6 ++++++ - hw/virtio/virtio-crypto.c | 6 ++++++ - include/hw/virtio/virtio.h | 3 +++ - 6 files changed, 35 insertions(+), 2 deletions(-) - -diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c -index 49df56cd14..73ad3d84c9 100644 ---- a/hw/display/vhost-user-gpu.c -+++ b/hw/display/vhost-user-gpu.c -@@ -485,6 +485,9 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx) - { - VhostUserGPU *g = VHOST_USER_GPU(vdev); - -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return vhost_virtqueue_pending(&g->vhost->dev, idx); - } - -@@ -493,6 +496,9 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask) - { - VhostUserGPU *g = VHOST_USER_GPU(vdev); - -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } - vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask); - } - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 3bd786cc22..7537f44d10 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3195,6 +3195,9 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) - VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx)); - assert(n->vhost_started); -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx); - } - -@@ -3204,8 +3207,11 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, - VirtIONet *n = VIRTIO_NET(vdev); - NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx)); - assert(n->vhost_started); -- vhost_net_virtqueue_mask(get_vhost_net(nc->peer), -- vdev, idx, mask); -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } -+ -+ vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask); - } - - static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features) -diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c -index fc7dcc96ef..90c2bc9c5d 100644 ---- a/hw/virtio/vhost-user-fs.c -+++ b/hw/virtio/vhost-user-fs.c -@@ -161,6 +161,9 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx, - { - VHostUserFS *fs = VHOST_USER_FS(vdev); - -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } - vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask); - } - -@@ -168,6 +171,9 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx) - { - VHostUserFS *fs = VHOST_USER_FS(vdev); - -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return vhost_virtqueue_pending(&fs->vhost_dev, idx); - } - -diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c -index ed706681ac..b1f0d46209 100644 ---- a/hw/virtio/vhost-vsock-common.c -+++ b/hw/virtio/vhost-vsock-common.c -@@ -125,6 +125,9 @@ static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx, - { - VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); - -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } - vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask); - } - -@@ -133,6 +136,9 @@ static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev, - { - VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); - -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return vhost_virtqueue_pending(&vvc->vhost_dev, idx); - } - -diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c -index 274c7b4dea..52ba34ef1e 100644 ---- a/hw/virtio/virtio-crypto.c -+++ b/hw/virtio/virtio-crypto.c -@@ -953,6 +953,9 @@ static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, - - assert(vcrypto->vhost_started); - -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } - cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask); - } - -@@ -963,6 +966,9 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx) - - assert(vcrypto->vhost_started); - -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return cryptodev_vhost_virtqueue_pending(vdev, queue, idx); - } - -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index 7472145821..c113a5b864 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -68,6 +68,9 @@ typedef struct VirtQueueElement - - #define VIRTIO_NO_VECTOR 0xffff - -+/* special index value used internally for config irqs */ -+#define VIRTIO_CONFIG_IRQ_IDX -1 -+ - #define TYPE_VIRTIO_DEVICE "virtio-device" - OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE) - --- -2.27.0 - diff --git a/virtio-introduce-macro-VIRTIO_CONFIG_IRQ_IDX.patch b/virtio-introduce-macro-VIRTIO_CONFIG_IRQ_IDX.patch deleted file mode 100644 index 67c848beb5cc3451c9b423a06cc98d05b41987ff..0000000000000000000000000000000000000000 --- a/virtio-introduce-macro-VIRTIO_CONFIG_IRQ_IDX.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 61630772adbe254719e312fb7704a8edd00cc72b Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:42 +0800 -Subject: [PATCH] virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX - -To support configure interrupt for vhost-vdpa -Introduce VIRTIO_CONFIG_IRQ_IDX -1 as configure interrupt's queue index, -Then we can reuse the functions guest_notifier_mask and guest_notifier_pending. -Add the check of queue index in these drivers, if the driver does not support -configure interrupt, the function will just return - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-2-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/display/vhost-user-gpu.c | 18 ++++++++++++++++++ - hw/net/virtio-net.c | 22 ++++++++++++++++++++-- - hw/virtio/vhost-user-fs.c | 18 ++++++++++++++++++ - hw/virtio/vhost-vsock-common.c | 18 ++++++++++++++++++ - hw/virtio/virtio-crypto.c | 18 ++++++++++++++++++ - include/hw/virtio/virtio.h | 3 +++ - 6 files changed, 95 insertions(+), 2 deletions(-) - -diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c -index 6e93b463d6..1c78272a83 100644 ---- a/hw/display/vhost-user-gpu.c -+++ b/hw/display/vhost-user-gpu.c -@@ -485,6 +485,15 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx) - { - VhostUserGPU *g = VHOST_USER_GPU(vdev); - -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return vhost_virtqueue_pending(&g->vhost->dev, idx); - } - -@@ -493,6 +502,15 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask) - { - VhostUserGPU *g = VHOST_USER_GPU(vdev); - -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } - vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask); - } - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 867a1e77dc..304f501da5 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3232,6 +3232,15 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) - } else { - nc = qemu_get_subqueue(n->nic, vq2q(idx)); - } -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return false -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx); - } - -@@ -3255,8 +3264,17 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, - } else { - nc = qemu_get_subqueue(n->nic, vq2q(idx)); - } -- vhost_net_virtqueue_mask(get_vhost_net(nc->peer), -- vdev, idx, mask); -+ /* -+ *Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } -+ -+ vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask); - } - - static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features) -diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c -index c2739557f2..0c6ecd3b4f 100644 ---- a/hw/virtio/vhost-user-fs.c -+++ b/hw/virtio/vhost-user-fs.c -@@ -161,6 +161,15 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx, - { - VHostUserFS *fs = VHOST_USER_FS(vdev); - -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } - vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask); - } - -@@ -168,6 +177,15 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx) - { - VHostUserFS *fs = VHOST_USER_FS(vdev); - -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return vhost_virtqueue_pending(&fs->vhost_dev, idx); - } - -diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c -index 42e4db4712..e4a8d90f4c 100644 ---- a/hw/virtio/vhost-vsock-common.c -+++ b/hw/virtio/vhost-vsock-common.c -@@ -125,6 +125,15 @@ static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx, - { - VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); - -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } - vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask); - } - -@@ -133,6 +142,15 @@ static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev, - { - VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); - -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return vhost_virtqueue_pending(&vvc->vhost_dev, idx); - } - -diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c -index f9d849fa43..98304184cd 100644 ---- a/hw/virtio/virtio-crypto.c -+++ b/hw/virtio/virtio-crypto.c -@@ -953,6 +953,15 @@ static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, - - assert(vcrypto->vhost_started); - -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return; -+ } - cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask); - } - -@@ -963,6 +972,15 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx) - - assert(vcrypto->vhost_started); - -+ /* -+ * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 -+ * as the Marco of configure interrupt's IDX, If this driver does not -+ * support, the function will return -+ */ -+ -+ if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ return false; -+ } - return cryptodev_vhost_virtqueue_pending(vdev, queue, idx); - } - -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index 223e82436f..91d1c3433a 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -69,6 +69,9 @@ typedef struct VirtQueueElement - - #define VIRTIO_NO_VECTOR 0xffff - -+/* special index value used internally for config irqs */ -+#define VIRTIO_CONFIG_IRQ_IDX -1 -+ - #define TYPE_VIRTIO_DEVICE "virtio-device" - OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE) - --- -2.27.0 - diff --git a/virtio-iommu-Fix-the-partial-copy-of-probe-request.patch b/virtio-iommu-Fix-the-partial-copy-of-probe-request.patch deleted file mode 100644 index 4ae4766bbdb40027f7ea52064293b043dc2afdd9..0000000000000000000000000000000000000000 --- a/virtio-iommu-Fix-the-partial-copy-of-probe-request.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 1e73eaa18c753157046d22e43333fd9bc711eaa9 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 17 Nov 2023 09:55:19 +0000 -Subject: [PATCH] virtio-iommu: Fix the partial copy of probe request mainline - inclusion commit 45461aace83d961e933b27519b81d17b4c690514 category: bugfix - ---------------------------------------------------------------- - -The structure of probe request doesn't include the tail, this leads -to a few field missed to be copied. Currently this isn't an issue as -those missed field belong to reserved field, just in case reserved -field will be used in the future. - -Changed 4th parameter of virtio_iommu_iov_to_req() to receive size -of device-readable part. - -Fixes: 1733eebb9e75b ("virtio-iommu: Implement RESV_MEM probe request") -Signed-off-by: Zhenzhong Duan -Message-Id: <20220623023152.3473231-1-zhenzhong.duan@intel.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: Jean-Philippe Brucker -Reviewed-by: Eric Auger - -Signed-off-by: tangbinzy ---- - hw/virtio/virtio-iommu.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c -index ed47d4cb64..ae33d93b11 100644 ---- a/hw/virtio/virtio-iommu.c -+++ b/hw/virtio/virtio-iommu.c -@@ -547,11 +547,10 @@ static int virtio_iommu_probe(VirtIOIOMMU *s, - - static int virtio_iommu_iov_to_req(struct iovec *iov, - unsigned int iov_cnt, -- void *req, size_t req_sz) -+ void *req, size_t payload_sz) - { -- size_t sz, payload_sz = req_sz - sizeof(struct virtio_iommu_req_tail); -+ size_t sz = iov_to_buf(iov, iov_cnt, 0, req, payload_sz); - -- sz = iov_to_buf(iov, iov_cnt, 0, req, payload_sz); - if (unlikely(sz != payload_sz)) { - return VIRTIO_IOMMU_S_INVAL; - } -@@ -564,7 +563,8 @@ static int virtio_iommu_handle_ ## __req(VirtIOIOMMU *s, \ - unsigned int iov_cnt) \ - { \ - struct virtio_iommu_req_ ## __req req; \ -- int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req)); \ -+ int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, \ -+ sizeof(req) - sizeof(struct virtio_iommu_req_tail));\ - \ - return ret ? ret : virtio_iommu_ ## __req(s, &req); \ - } --- -2.27.0 - diff --git a/virtio-iommu-use-after-free-fix.patch b/virtio-iommu-use-after-free-fix.patch deleted file mode 100644 index 23b4e7a93a2179046e5f624af77eaa7fa4eb5cbf..0000000000000000000000000000000000000000 --- a/virtio-iommu-use-after-free-fix.patch +++ /dev/null @@ -1,82 +0,0 @@ -From ab4228f1a5b45450490077a06094670f364b4efc Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Mon, 21 Aug 2023 06:02:21 +0000 -Subject: [PATCH] virtio-iommu: use-after-free fix mainline inclusion commit - 4bf58c7213b0ab03209a53731c71f0861c35ef91 category: bugfix -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---------------------------------------------------------------- - -A potential Use-after-free was reported in virtio_iommu_handle_command -when using virtio-iommu: - -> I find a potential Use-after-free in QEMU 6.2.0, which is in -> virtio_iommu_handle_command() (./hw/virtio/virtio-iommu.c). -> -> -> Specifically, in the loop body, the variable 'buf' allocated at line 639 can be -> freed by g_free() at line 659. However, if the execution path enters the loop -> body again and the if branch takes true at line 616, the control will directly -> jump to 'out' at line 651. At this time, 'buf' is a freed pointer, which is not -> assigned with an allocated memory but used at line 653. As a result, a UAF bug -> is triggered. -> -> -> -> 599 for (;;) { -> ... -> 615 sz = iov_to_buf(iov, iov_cnt, 0, &head, sizeof(head)); -> 616 if (unlikely(sz != sizeof(head))) { -> 617 tail.status = VIRTIO_IOMMU_S_DEVERR; -> 618 goto out; -> 619 } -> ... -> 639 buf = g_malloc0(output_size); -> ... -> 651 out: -> 652 sz = iov_from_buf(elem->in_sg, elem->in_num, 0, -> 653 buf ? buf : &tail, output_size); -> ... -> 659 g_free(buf); -> -> We can fix it by set ‘buf‘ to NULL after freeing it: -> -> -> 651 out: -> 652 sz = iov_from_buf(elem->in_sg, elem->in_num, 0, -> 653 buf ? buf : &tail, output_size); -> ... -> 659 g_free(buf); -> +++ buf = NULL; -> 660 } - -Fix as suggested by the reporter. - -Signed-off-by: Wentao Liang -Signed-off-by: Michael S. Tsirkin -Message-id: 20220407095047.50371-1-mst@redhat.com -Message-ID: <20220406040445-mutt-send-email-mst@kernel.org> -Signed-off-by: Peter Maydell - -Signed-off-by: tangbinzy ---- - hw/virtio/virtio-iommu.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c -index 1b23e8e18c..ed47d4cb64 100644 ---- a/hw/virtio/virtio-iommu.c -+++ b/hw/virtio/virtio-iommu.c -@@ -657,6 +657,7 @@ out: - virtio_notify(vdev, vq); - g_free(elem); - g_free(buf); -+ buf = NULL; - } - } - --- -2.41.0.windows.1 - diff --git a/virtio-mem-Don-t-skip-alignment-checks-when-warning-.patch b/virtio-mem-Don-t-skip-alignment-checks-when-warning-.patch deleted file mode 100644 index 39bcaf94576f5f598a8416f036c7ea1845184915..0000000000000000000000000000000000000000 --- a/virtio-mem-Don-t-skip-alignment-checks-when-warning-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d319f43f223df53ed5c9c13c5b60caaa1b952c35 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Wed, 23 Nov 2022 06:26:18 +0000 -Subject: [PATCH 08/29] virtio-mem: Don't skip alignment checks when warning - about block size mainline inclusion commit - 7656d9ce09cb1d6d76eeb2081f164a920361d1d3 category: bugfix - ---------------------------------------------------------------- - -If we warn about the block size being smaller than the default, we skip -some alignment checks. - -This can currently only fail on x86-64, when specifying a block size of -1 MiB, however, we detect the THP size of 2 MiB. - -Fixes: 228957fea3a9 ("virtio-mem: Probe THP size to determine default block size") -Cc: "Michael S. Tsirkin" -Signed-off-by: David Hildenbrand -Message-Id: <20211011173305.13778-1-david@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin - - -Signed-off-by: tangbinzy ---- - hw/virtio/virtio-mem.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c -index d5a578142b..341c3fa2c1 100644 ---- a/hw/virtio/virtio-mem.c -+++ b/hw/virtio/virtio-mem.c -@@ -733,7 +733,8 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) - warn_report("'%s' property is smaller than the default block size (%" - PRIx64 " MiB)", VIRTIO_MEM_BLOCK_SIZE_PROP, - virtio_mem_default_block_size(rb) / MiB); -- } else if (!QEMU_IS_ALIGNED(vmem->requested_size, vmem->block_size)) { -+ } -+ if (!QEMU_IS_ALIGNED(vmem->requested_size, vmem->block_size)) { - error_setg(errp, "'%s' property has to be multiples of '%s' (0x%" PRIx64 - ")", VIRTIO_MEM_REQUESTED_SIZE_PROP, - VIRTIO_MEM_BLOCK_SIZE_PROP, vmem->block_size); --- -2.27.0 - diff --git a/virtio-mmio-add-support-for-configure-interrupt-new.patch b/virtio-mmio-add-support-for-configure-interrupt-new.patch deleted file mode 100644 index c0900ca310338b13ba2c383abc3a66e7073838dd..0000000000000000000000000000000000000000 --- a/virtio-mmio-add-support-for-configure-interrupt-new.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3f5311e1a80539a9cc21905fd3134709417e3747 Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:50 +0800 -Subject: [PATCH] virtio-mmio: add support for configure interrupt - -Add configure interrupt support in virtio-mmio bus. -add function to set configure guest notifier. - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-10-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-mmio.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c -index 72da12fea5..508dd4cdb7 100644 ---- a/hw/virtio/virtio-mmio.c -+++ b/hw/virtio/virtio-mmio.c -@@ -673,7 +673,30 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign, - - return 0; - } -+static int virtio_mmio_set_config_guest_notifier(DeviceState *d, bool assign, -+ bool with_irqfd) -+{ -+ VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); -+ EventNotifier *notifier = virtio_config_get_guest_notifier(vdev); -+ int r = 0; - -+ if (assign) { -+ r = event_notifier_init(notifier, 0); -+ if (r < 0) { -+ return r; -+ } -+ virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -+ } else { -+ virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -+ event_notifier_cleanup(notifier); -+ } -+ if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) { -+ vdc->guest_notifier_mask(vdev, VIRTIO_CONFIG_IRQ_IDX, !assign); -+ } -+ return r; -+} - static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, - bool assign) - { -@@ -695,6 +718,10 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, - goto assign_error; - } - } -+ r = virtio_mmio_set_config_guest_notifier(d, assign, with_irqfd); -+ if (r < 0) { -+ goto assign_error; -+ } - - return 0; - --- -2.27.0 - diff --git a/virtio-mmio-add-support-for-configure-interrupt.patch b/virtio-mmio-add-support-for-configure-interrupt.patch deleted file mode 100644 index 0b4d42599563676d9fc6f170c359f99bb1747928..0000000000000000000000000000000000000000 --- a/virtio-mmio-add-support-for-configure-interrupt.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 89b329c73a84ca3f1376f8d8533154306bc50187 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:54 +0800 -Subject: [PATCH] virtio-mmio: add support for configure interrupt - -Add configure interrupt support for virtio-mmio bus. This -interrupt will be working while the backend is vhost-vdpa - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-10-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-mmio.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c -index 72da12fea5..809132018b 100644 ---- a/hw/virtio/virtio-mmio.c -+++ b/hw/virtio/virtio-mmio.c -@@ -673,7 +673,30 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign, - - return 0; - } -+static int virtio_mmio_set_config_guest_notifier(DeviceState *d, bool assign) -+{ -+ VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); -+ bool with_irqfd = false; -+ EventNotifier *notifier = virtio_config_get_guest_notifier(vdev); -+ int r = 0; - -+ if (assign) { -+ r = event_notifier_init(notifier, 0); -+ if (r < 0) { -+ return r; -+ } -+ virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -+ } else { -+ virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -+ event_notifier_cleanup(notifier); -+ } -+ if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) { -+ vdc->guest_notifier_mask(vdev, VIRTIO_CONFIG_IRQ_IDX, !assign); -+ } -+ return r; -+} - static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, - bool assign) - { -@@ -695,6 +718,10 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, - goto assign_error; - } - } -+ r = virtio_mmio_set_config_guest_notifier(d, assign); -+ if (r < 0) { -+ goto assign_error; -+ } - - return 0; - --- -2.27.0 - diff --git a/virtio-net-Expose-MAC_TABLE_ENTRIES.patch b/virtio-net-Expose-MAC_TABLE_ENTRIES.patch deleted file mode 100644 index 15e740579fecc5bc32e1012d7a2f15b56cb72562..0000000000000000000000000000000000000000 --- a/virtio-net-Expose-MAC_TABLE_ENTRIES.patch +++ /dev/null @@ -1,50 +0,0 @@ -From c8ee92256e06a7fec7cfff3bf18e21ec03016613 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:27 +0200 -Subject: [PATCH] virtio-net: Expose MAC_TABLE_ENTRIES -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -vhost-vdpa control virtqueue needs to know the maximum entries supported -by the virtio-net device, so we know if it is possible to apply the -filter. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/net/virtio-net.c | 1 - - include/hw/virtio/virtio-net.h | 3 +++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 512b37eb76..36d24b47bb 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -48,7 +48,6 @@ - - #define VIRTIO_NET_VM_VERSION 11 - --#define MAC_TABLE_ENTRIES 64 - #define MAX_VLAN (1 << 12) /* Per 802.1Q definition */ - - /* previously fixed value */ -diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h -index eb87032627..cce1c554f7 100644 ---- a/include/hw/virtio/virtio-net.h -+++ b/include/hw/virtio/virtio-net.h -@@ -35,6 +35,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(VirtIONet, VIRTIO_NET) - * and latency. */ - #define TX_BURST 256 - -+/* Maximum VIRTIO_NET_CTRL_MAC_TABLE_SET unicast + multicast entries. */ -+#define MAC_TABLE_ENTRIES 64 -+ - typedef struct virtio_net_conf - { - uint32_t txtimer; --- -2.27.0 - diff --git a/virtio-net-Expose-ctrl-virtqueue-logic.patch b/virtio-net-Expose-ctrl-virtqueue-logic.patch deleted file mode 100644 index fc50d2007e0a1eaa868bd59515f62f20c1a4b0e6..0000000000000000000000000000000000000000 --- a/virtio-net-Expose-ctrl-virtqueue-logic.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 4987c967fb3b9b403bde7a1103f5ea1bf20445c7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Wed, 20 Jul 2022 08:59:28 +0200 -Subject: [PATCH] virtio-net: Expose ctrl virtqueue logic -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows external vhost-net devices to modify the state of the -VirtIO device model once the vhost-vdpa device has acknowledged the -control commands. - -Signed-off-by: Eugenio Pérez -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/net/virtio-net.c | 83 ++++++++++++++++++++-------------- - include/hw/virtio/virtio-net.h | 4 ++ - 2 files changed, 53 insertions(+), 34 deletions(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 36d24b47bb..999072921d 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -1452,56 +1452,71 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, - return VIRTIO_NET_OK; - } - --static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) -+size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev, -+ const struct iovec *in_sg, unsigned in_num, -+ const struct iovec *out_sg, -+ unsigned out_num) - { - VirtIONet *n = VIRTIO_NET(vdev); - struct virtio_net_ctrl_hdr ctrl; - virtio_net_ctrl_ack status = VIRTIO_NET_ERR; -- VirtQueueElement *elem; - size_t s; - struct iovec *iov, *iov2; -- unsigned int iov_cnt; -+ -+ if (iov_size(in_sg, in_num) < sizeof(status) || -+ iov_size(out_sg, out_num) < sizeof(ctrl)) { -+ virtio_error(vdev, "virtio-net ctrl missing headers"); -+ return 0; -+ } -+ -+ iov2 = iov = g_memdup(out_sg, sizeof(struct iovec) * out_num); -+ s = iov_to_buf(iov, out_num, 0, &ctrl, sizeof(ctrl)); -+ iov_discard_front(&iov, &out_num, sizeof(ctrl)); -+ if (s != sizeof(ctrl)) { -+ status = VIRTIO_NET_ERR; -+ } else if (ctrl.class == VIRTIO_NET_CTRL_RX) { -+ status = virtio_net_handle_rx_mode(n, ctrl.cmd, iov, out_num); -+ } else if (ctrl.class == VIRTIO_NET_CTRL_MAC) { -+ status = virtio_net_handle_mac(n, ctrl.cmd, iov, out_num); -+ } else if (ctrl.class == VIRTIO_NET_CTRL_VLAN) { -+ status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, out_num); -+ } else if (ctrl.class == VIRTIO_NET_CTRL_ANNOUNCE) { -+ status = virtio_net_handle_announce(n, ctrl.cmd, iov, out_num); -+ } else if (ctrl.class == VIRTIO_NET_CTRL_MQ) { -+ status = virtio_net_handle_mq(n, ctrl.cmd, iov, out_num); -+ } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) { -+ status = virtio_net_handle_offloads(n, ctrl.cmd, iov, out_num); -+ } -+ -+ s = iov_from_buf(in_sg, in_num, 0, &status, sizeof(status)); -+ assert(s == sizeof(status)); -+ -+ g_free(iov2); -+ return sizeof(status); -+} -+ -+static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) -+{ -+ VirtQueueElement *elem; - - for (;;) { -+ size_t written; - elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); - if (!elem) { - break; - } -- if (iov_size(elem->in_sg, elem->in_num) < sizeof(status) || -- iov_size(elem->out_sg, elem->out_num) < sizeof(ctrl)) { -- virtio_error(vdev, "virtio-net ctrl missing headers"); -+ -+ written = virtio_net_handle_ctrl_iov(vdev, elem->in_sg, elem->in_num, -+ elem->out_sg, elem->out_num); -+ if (written > 0) { -+ virtqueue_push(vq, elem, written); -+ virtio_notify(vdev, vq); -+ g_free(elem); -+ } else { - virtqueue_detach_element(vq, elem, 0); - g_free(elem); - break; - } -- -- iov_cnt = elem->out_num; -- iov2 = iov = g_memdup(elem->out_sg, sizeof(struct iovec) * elem->out_num); -- s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl)); -- iov_discard_front(&iov, &iov_cnt, sizeof(ctrl)); -- if (s != sizeof(ctrl)) { -- status = VIRTIO_NET_ERR; -- } else if (ctrl.class == VIRTIO_NET_CTRL_RX) { -- status = virtio_net_handle_rx_mode(n, ctrl.cmd, iov, iov_cnt); -- } else if (ctrl.class == VIRTIO_NET_CTRL_MAC) { -- status = virtio_net_handle_mac(n, ctrl.cmd, iov, iov_cnt); -- } else if (ctrl.class == VIRTIO_NET_CTRL_VLAN) { -- status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, iov_cnt); -- } else if (ctrl.class == VIRTIO_NET_CTRL_ANNOUNCE) { -- status = virtio_net_handle_announce(n, ctrl.cmd, iov, iov_cnt); -- } else if (ctrl.class == VIRTIO_NET_CTRL_MQ) { -- status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt); -- } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) { -- status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt); -- } -- -- s = iov_from_buf(elem->in_sg, elem->in_num, 0, &status, sizeof(status)); -- assert(s == sizeof(status)); -- -- virtqueue_push(vq, elem, sizeof(status)); -- virtio_notify(vdev, vq); -- g_free(iov2); -- g_free(elem); - } - } - -diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h -index cce1c554f7..ef234ffe7e 100644 ---- a/include/hw/virtio/virtio-net.h -+++ b/include/hw/virtio/virtio-net.h -@@ -221,6 +221,10 @@ struct VirtIONet { - struct EBPFRSSContext ebpf_rss; - }; - -+size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev, -+ const struct iovec *in_sg, unsigned in_num, -+ const struct iovec *out_sg, -+ unsigned out_num); - void virtio_net_set_netclient_name(VirtIONet *n, const char *name, - const char *type); - --- -2.27.0 - diff --git a/virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch b/virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch deleted file mode 100644 index fb9f7adb5a87d2ccefcd644292ee5656da523c27..0000000000000000000000000000000000000000 --- a/virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 49c90114e00fb1cbbe25eeaee825981210c24f41 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 6 Sep 2022 17:07:18 +0200 -Subject: [PATCH] virtio-net: Update virtio-net curr_queue_pairs in vdpa - backends -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It was returned as error before. Instead of it, simply update the -corresponding field so qemu can send it in the migration data. - -Signed-off-by: Eugenio Pérez -Acked-by: Si-Wei Liu -Signed-off-by: Jason Wang -Signed-off-by: fangyi ---- - hw/net/virtio-net.c | 17 ++++++----------- - 1 file changed, 6 insertions(+), 11 deletions(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 999072921d..867a1e77dc 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -1431,19 +1431,14 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, - return VIRTIO_NET_ERR; - } - -- /* Avoid changing the number of queue_pairs for vdpa device in -- * userspace handler. A future fix is needed to handle the mq -- * change in userspace handler with vhost-vdpa. Let's disable -- * the mq handling from userspace for now and only allow get -- * done through the kernel. Ripples may be seen when falling -- * back to userspace, but without doing it qemu process would -- * crash on a recursive entry to virtio_net_set_status(). -- */ -+ n->curr_queue_pairs = queue_pairs; - if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) { -- return VIRTIO_NET_ERR; -+ /* -+ * Avoid updating the backend for a vdpa device: We're only interested -+ * in updating the device model queues. -+ */ -+ return VIRTIO_NET_OK; - } -- -- n->curr_queue_pairs = queue_pairs; - /* stop the backend before changing the number of queue_pairs to avoid handling a - * disabled queue */ - virtio_net_set_status(vdev, vdev->status); --- -2.27.0 - diff --git a/virtio-net-add-support-for-configure-interrupt-new.patch b/virtio-net-add-support-for-configure-interrupt-new.patch deleted file mode 100644 index 006222ded936cbfe789b1f914046111cf40afcb6..0000000000000000000000000000000000000000 --- a/virtio-net-add-support-for-configure-interrupt-new.patch +++ /dev/null @@ -1,102 +0,0 @@ -From e55e9f52865565415000834b4cacb741b0abb2d8 Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:49 +0800 -Subject: [PATCH] virtio-net: add support for configure interrupt - -Add functions to support configure interrupt in virtio_net -Add the functions to support vhost_net_config_pending -and vhost_net_config_mask. - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-9-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/net/vhost_net-stub.c | 9 +++++++++ - hw/net/vhost_net.c | 9 +++++++++ - hw/net/virtio-net.c | 4 ++-- - include/net/vhost_net.h | 2 ++ - 4 files changed, 22 insertions(+), 2 deletions(-) - -diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c -index 199b09952a..db171829b4 100644 ---- a/hw/net/vhost_net-stub.c -+++ b/hw/net/vhost_net-stub.c -@@ -82,6 +82,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, - { - } - -+bool vhost_net_config_pending(VHostNetState *net) -+{ -+ return false; -+} -+ -+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask) -+{ -+} -+ - int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) - { - return -1; -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index c950d7e2e8..d226dba83c 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -541,6 +541,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, - vhost_virtqueue_mask(&net->dev, dev, idx, mask); - } - -+bool vhost_net_config_pending(VHostNetState *net) -+{ -+ return vhost_config_pending(&net->dev); -+} -+ -+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask) -+{ -+ vhost_config_mask(&net->dev, dev, mask); -+} - VHostNetState *get_vhost_net(NetClientState *nc) - { - VHostNetState *vhost_net = 0; -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 304f501da5..bc26f5347a 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3239,7 +3239,7 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) - */ - - if (idx == VIRTIO_CONFIG_IRQ_IDX) { -- return false; -+ return vhost_net_config_pending(get_vhost_net(nc->peer)); - } - return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx); - } -@@ -3271,9 +3271,9 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, - */ - - if (idx == VIRTIO_CONFIG_IRQ_IDX) { -+ vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask); - return; - } -- - vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask); - } - -diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h -index 7bdbf484e4..1844f0ed46 100644 ---- a/include/net/vhost_net.h -+++ b/include/net/vhost_net.h -@@ -39,6 +39,8 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data, - bool vhost_net_virtqueue_pending(VHostNetState *net, int n); - void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, - int idx, bool mask); -+bool vhost_net_config_pending(VHostNetState *net); -+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask); - int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr); - VHostNetState *get_vhost_net(NetClientState *nc); - --- -2.27.0 - diff --git a/virtio-net-add-support-for-configure-interrupt.patch b/virtio-net-add-support-for-configure-interrupt.patch deleted file mode 100644 index 98ac5d22ed702ac7d00e9aacb1d6bed3a186c0c2..0000000000000000000000000000000000000000 --- a/virtio-net-add-support-for-configure-interrupt.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0ae5aeef8aa5bf2d32fdf393cf66c36172c3e974 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:53 +0800 -Subject: [PATCH] virtio-net: add support for configure interrupt - -Add functions to support configure interrupt in virtio_net -The functions are config_pending and config_mask, while -this input idx is VIRTIO_CONFIG_IRQ_IDX will check the -function of configure interrupt. - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-9-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/net/vhost_net.c | 9 +++++++++ - include/net/vhost_net.h | 2 ++ - 2 files changed, 11 insertions(+) - -diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c -index bea053a742..d5a92144bb 100644 ---- a/hw/net/vhost_net.c -+++ b/hw/net/vhost_net.c -@@ -524,6 +524,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, - vhost_virtqueue_mask(&net->dev, dev, idx, mask); - } - -+bool vhost_net_config_pending(VHostNetState *net) -+{ -+ return vhost_config_pending(&net->dev); -+} -+ -+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask) -+{ -+ vhost_config_mask(&net->dev, dev, mask); -+} - VHostNetState *get_vhost_net(NetClientState *nc) - { - VHostNetState *vhost_net = 0; -diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h -index 7bdbf484e4..1844f0ed46 100644 ---- a/include/net/vhost_net.h -+++ b/include/net/vhost_net.h -@@ -39,6 +39,8 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data, - bool vhost_net_virtqueue_pending(VHostNetState *net, int n); - void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, - int idx, bool mask); -+bool vhost_net_config_pending(VHostNetState *net); -+void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask); - int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr); - VHostNetState *get_vhost_net(NetClientState *nc); - --- -2.27.0 - diff --git a/virtio-net-align-ctrl_vq-index-for-non-mq-guest-for-.patch b/virtio-net-align-ctrl_vq-index-for-non-mq-guest-for-.patch deleted file mode 100644 index 2c86d6473433eab6c32a0bb6a07ca509c31729a5..0000000000000000000000000000000000000000 --- a/virtio-net-align-ctrl_vq-index-for-non-mq-guest-for-.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 9bfeaccd2adb6bc4d4e7efacc508324112e5651f Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Fri, 6 May 2022 19:28:13 -0700 -Subject: [PATCH] virtio-net: align ctrl_vq index for non-mq guest for - vhost_vdpa - -With MQ enabled vdpa device and non-MQ supporting guest e.g. -booting vdpa with mq=on over OVMF of single vqp, below assert -failure is seen: - -../hw/virtio/vhost-vdpa.c:560: vhost_vdpa_get_vq_index: Assertion `idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs' failed. - -0 0x00007f8ce3ff3387 in raise () at /lib64/libc.so.6 -1 0x00007f8ce3ff4a78 in abort () at /lib64/libc.so.6 -2 0x00007f8ce3fec1a6 in __assert_fail_base () at /lib64/libc.so.6 -3 0x00007f8ce3fec252 in () at /lib64/libc.so.6 -4 0x0000558f52d79421 in vhost_vdpa_get_vq_index (dev=, idx=) at ../hw/virtio/vhost-vdpa.c:563 -5 0x0000558f52d79421 in vhost_vdpa_get_vq_index (dev=, idx=) at ../hw/virtio/vhost-vdpa.c:558 -6 0x0000558f52d7329a in vhost_virtqueue_mask (hdev=0x558f55c01800, vdev=0x558f568f91f0, n=2, mask=) at ../hw/virtio/vhost.c:1557 -7 0x0000558f52c6b89a in virtio_pci_set_guest_notifier (d=d@entry=0x558f568f0f60, n=n@entry=2, assign=assign@entry=true, with_irqfd=with_irqfd@entry=false) - at ../hw/virtio/virtio-pci.c:974 -8 0x0000558f52c6c0d8 in virtio_pci_set_guest_notifiers (d=0x558f568f0f60, nvqs=3, assign=true) at ../hw/virtio/virtio-pci.c:1019 -9 0x0000558f52bf091d in vhost_net_start (dev=dev@entry=0x558f568f91f0, ncs=0x558f56937cd0, data_queue_pairs=data_queue_pairs@entry=1, cvq=cvq@entry=1) - at ../hw/net/vhost_net.c:361 -10 0x0000558f52d4e5e7 in virtio_net_set_status (status=, n=0x558f568f91f0) at ../hw/net/virtio-net.c:289 -11 0x0000558f52d4e5e7 in virtio_net_set_status (vdev=0x558f568f91f0, status=15 '\017') at ../hw/net/virtio-net.c:370 -12 0x0000558f52d6c4b2 in virtio_set_status (vdev=vdev@entry=0x558f568f91f0, val=val@entry=15 '\017') at ../hw/virtio/virtio.c:1945 -13 0x0000558f52c69eff in virtio_pci_common_write (opaque=0x558f568f0f60, addr=, val=, size=) at ../hw/virtio/virtio-pci.c:1292 -14 0x0000558f52d15d6e in memory_region_write_accessor (mr=0x558f568f19d0, addr=20, value=, size=1, shift=, mask=, attrs=...) - at ../softmmu/memory.c:492 -15 0x0000558f52d127de in access_with_adjusted_size (addr=addr@entry=20, value=value@entry=0x7f8cdbffe748, size=size@entry=1, access_size_min=, access_size_max=, access_fn=0x558f52d15cf0 , mr=0x558f568f19d0, attrs=...) at ../softmmu/memory.c:554 -16 0x0000558f52d157ef in memory_region_dispatch_write (mr=mr@entry=0x558f568f19d0, addr=20, data=, op=, attrs=attrs@entry=...) - at ../softmmu/memory.c:1504 -17 0x0000558f52d078e7 in flatview_write_continue (fv=fv@entry=0x7f8accbc3b90, addr=addr@entry=103079215124, attrs=..., ptr=ptr@entry=0x7f8ce6300028, len=len@entry=1, addr1=, l=, mr=0x558f568f19d0) at /home/opc/qemu-upstream/include/qemu/host-utils.h:165 -18 0x0000558f52d07b06 in flatview_write (fv=0x7f8accbc3b90, addr=103079215124, attrs=..., buf=0x7f8ce6300028, len=1) at ../softmmu/physmem.c:2822 -19 0x0000558f52d0b36b in address_space_write (as=, addr=, attrs=..., buf=buf@entry=0x7f8ce6300028, len=) - at ../softmmu/physmem.c:2914 -20 0x0000558f52d0b3da in address_space_rw (as=, addr=, attrs=..., - attrs@entry=..., buf=buf@entry=0x7f8ce6300028, len=, is_write=) at ../softmmu/physmem.c:2924 -21 0x0000558f52dced09 in kvm_cpu_exec (cpu=cpu@entry=0x558f55c2da60) at ../accel/kvm/kvm-all.c:2903 -22 0x0000558f52dcfabd in kvm_vcpu_thread_fn (arg=arg@entry=0x558f55c2da60) at ../accel/kvm/kvm-accel-ops.c:49 -23 0x0000558f52f9f04a in qemu_thread_start (args=) at ../util/qemu-thread-posix.c:556 -24 0x00007f8ce4392ea5 in start_thread () at /lib64/libpthread.so.0 -25 0x00007f8ce40bb9fd in clone () at /lib64/libc.so.6 - -The cause for the assert failure is due to that the vhost_dev index -for the ctrl vq was not aligned with actual one in use by the guest. -Upon multiqueue feature negotiation in virtio_net_set_multiqueue(), -if guest doesn't support multiqueue, the guest vq layout would shrink -to a single queue pair, consisting of 3 vqs in total (rx, tx and ctrl). -This results in ctrl_vq taking a different vhost_dev group index than -the default. We can map vq to the correct vhost_dev group by checking -if MQ is supported by guest and successfully negotiated. Since the -MQ feature is only present along with CTRL_VQ, we ensure the index -2 is only meant for the control vq while MQ is not supported by guest. - -Fixes: 22288fe ("virtio-net: vhost control virtqueue support") -Suggested-by: Jason Wang -Signed-off-by: Si-Wei Liu -Acked-by: Jason Wang -Message-Id: <1651890498-24478-3-git-send-email-si-wei.liu@oracle.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/net/virtio-net.c | 33 +++++++++++++++++++++++++++++++-- - 1 file changed, 31 insertions(+), 2 deletions(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 41bb4010b0..eed3fb5cd3 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -14,6 +14,7 @@ - #include "qemu/osdep.h" - #include "qemu/atomic.h" - #include "qemu/iov.h" -+#include "qemu/log.h" - #include "qemu/main-loop.h" - #include "qemu/module.h" - #include "hw/virtio/virtio.h" -@@ -3193,8 +3194,22 @@ static NetClientInfo net_virtio_info = { - static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) - { - VirtIONet *n = VIRTIO_NET(vdev); -- NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx)); -+ NetClientState *nc; - assert(n->vhost_started); -+ if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_MQ) && idx == 2) { -+ /* Must guard against invalid features and bogus queue index -+ * from being set by malicious guest, or penetrated through -+ * buggy migration stream. -+ */ -+ if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "%s: bogus vq index ignored\n", __func__); -+ return false; -+ } -+ nc = qemu_get_subqueue(n->nic, n->max_queue_pairs); -+ } else { -+ nc = qemu_get_subqueue(n->nic, vq2q(idx)); -+ } - return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx); - } - -@@ -3202,8 +3217,22 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, - bool mask) - { - VirtIONet *n = VIRTIO_NET(vdev); -- NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(idx)); -+ NetClientState *nc; - assert(n->vhost_started); -+ if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_MQ) && idx == 2) { -+ /* Must guard against invalid features and bogus queue index -+ * from being set by malicious guest, or penetrated through -+ * buggy migration stream. -+ */ -+ if (!virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) { -+ qemu_log_mask(LOG_GUEST_ERROR, -+ "%s: bogus vq index ignored\n", __func__); -+ return; -+ } -+ nc = qemu_get_subqueue(n->nic, n->max_queue_pairs); -+ } else { -+ nc = qemu_get_subqueue(n->nic, vq2q(idx)); -+ } - vhost_net_virtqueue_mask(get_vhost_net(nc->peer), - vdev, idx, mask); - } --- -2.27.0 - diff --git a/virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch b/virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch deleted file mode 100644 index c328f9e30cfa2bc8bcced01feb645324a452fd79..0000000000000000000000000000000000000000 --- a/virtio-net-bugfix-do-not-delete-netdev-before-virtio.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 532566ba64b60f2dd2f8ff41d670712ccafe1e98 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 10:31:38 +0800 -Subject: [PATCH] virtio-net: bugfix: do not delete netdev before virtio net - -For the vhost-user net-card, it is allow to delete its -network backend while the virtio-net device still exists. -However, when the status of the device changes in guest, -QEMU will check whether the network backend exists, otherwise -it will crash. -So do not allowed to delete the network backend directly -without delete virtio-net device. - -Signed-off-by: Jinhua Cao ---- - net/net.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/net/net.c b/net/net.c -index f0d14dbfc1..ed4b1c1740 100644 ---- a/net/net.c -+++ b/net/net.c -@@ -1202,6 +1202,12 @@ void qmp_netdev_del(const char *id, Error **errp) - return; - } - -+ if (nc->info->type == NET_CLIENT_DRIVER_VHOST_USER && nc->peer) { -+ error_setg(errp, "Device '%s' is a netdev for vhostuser," -+ "please delete the peer front-end device (virtio-net) first.", id); -+ return; -+ } -+ - qemu_del_net_client(nc); - - /* --- -2.27.0 - diff --git a/virtio-net-clear-guest_announce-feature-if-no-cvq-ba.patch b/virtio-net-clear-guest_announce-feature-if-no-cvq-ba.patch deleted file mode 100644 index 8ead12105e612e01379c51549af24a0384a9ea74..0000000000000000000000000000000000000000 --- a/virtio-net-clear-guest_announce-feature-if-no-cvq-ba.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 7c85ae20bc8a6bb2e08794d01e6f65af7626a05d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= -Date: Tue, 24 Jan 2023 17:11:59 +0100 -Subject: [PATCH] virtio-net: clear guest_announce feature if no cvq backend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since GUEST_ANNOUNCE is emulated the feature bit could be set without -backend support. This happens in the vDPA case. - -However, backend vDPA parent may not have CVQ support. This causes an -incoherent feature set, and the driver may refuse to start. This -happens in virtio-net Linux driver. - -This may be solved differently in the future. Qemu is able to emulate a -CVQ just for guest_announce purposes, helping guest to notify the new -location with vDPA devices that does not support it. However, this is -left as a TODO as it is way more complex to backport. - -Tested with vdpa_net_sim, toggling manually VIRTIO_NET_F_CTRL_VQ in the -driver and migrating it with x-svq=on. - -Fixes: 980003debddd ("vdpa: do not handle VIRTIO_NET_F_GUEST_ANNOUNCE in vhost-vdpa") -Reported-by: Dawar, Gautam -Signed-off-by: Eugenio Pérez -Message-Id: <20230124161159.2182117-1-eperezma@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Reviewed-by: David Edmondson -Reviewed-by: Gautam Dawar -Tested-by: Gautam Dawar -Tested-by: Lei Yang -Signed-off-by: fangyi ---- - hw/net/virtio-net.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index bc26f5347a..ae37b3461b 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -771,6 +771,21 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features, - features |= (1ULL << VIRTIO_NET_F_MTU); - } - -+ /* -+ * Since GUEST_ANNOUNCE is emulated the feature bit could be set without -+ * enabled. This happens in the vDPA case. -+ * -+ * Make sure the feature set is not incoherent, as the driver could refuse -+ * to start. -+ * -+ * TODO: QEMU is able to emulate a CVQ just for guest_announce purposes, -+ * helping guest to notify the new location with vDPA devices that does not -+ * support it. -+ */ -+ if (!virtio_has_feature(vdev->backend_features, VIRTIO_NET_F_CTRL_VQ)) { -+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ANNOUNCE); -+ } -+ - return features; - } - --- -2.27.0 - diff --git a/virtio-net-don-t-handle-mq-request-in-userspace-hand.patch b/virtio-net-don-t-handle-mq-request-in-userspace-hand.patch deleted file mode 100644 index 27e2366d5c734c1bc95f4f0820f7d2a7ef560662..0000000000000000000000000000000000000000 --- a/virtio-net-don-t-handle-mq-request-in-userspace-hand.patch +++ /dev/null @@ -1,97 +0,0 @@ -From f45beb1e364dc0a6d42425d716f5e31b69d7710d Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Fri, 6 May 2022 19:28:18 -0700 -Subject: [PATCH] virtio-net: don't handle mq request in userspace handler for - vhost-vdpa - -virtio_queue_host_notifier_read() tends to read pending event -left behind on ioeventfd in the vhost_net_stop() path, and -attempts to handle outstanding kicks from userspace vq handler. -However, in the ctrl_vq handler, virtio_net_handle_mq() has a -recursive call into virtio_net_set_status(), which may lead to -segmentation fault as shown in below stack trace: - -0 0x000055f800df1780 in qdev_get_parent_bus (dev=0x0) at ../hw/core/qdev.c:376 -1 0x000055f800c68ad8 in virtio_bus_device_iommu_enabled (vdev=vdev@entry=0x0) at ../hw/virtio/virtio-bus.c:331 -2 0x000055f800d70d7f in vhost_memory_unmap (dev=) at ../hw/virtio/vhost.c:318 -3 0x000055f800d70d7f in vhost_memory_unmap (dev=, buffer=0x7fc19bec5240, len=2052, is_write=1, access_len=2052) at ../hw/virtio/vhost.c:336 -4 0x000055f800d71867 in vhost_virtqueue_stop (dev=dev@entry=0x55f8037ccc30, vdev=vdev@entry=0x55f8044ec590, vq=0x55f8037cceb0, idx=0) at ../hw/virtio/vhost.c:1241 -5 0x000055f800d7406c in vhost_dev_stop (hdev=hdev@entry=0x55f8037ccc30, vdev=vdev@entry=0x55f8044ec590) at ../hw/virtio/vhost.c:1839 -6 0x000055f800bf00a7 in vhost_net_stop_one (net=0x55f8037ccc30, dev=0x55f8044ec590) at ../hw/net/vhost_net.c:315 -7 0x000055f800bf0678 in vhost_net_stop (dev=dev@entry=0x55f8044ec590, ncs=0x55f80452bae0, data_queue_pairs=data_queue_pairs@entry=7, cvq=cvq@entry=1) - at ../hw/net/vhost_net.c:423 -8 0x000055f800d4e628 in virtio_net_set_status (status=, n=0x55f8044ec590) at ../hw/net/virtio-net.c:296 -9 0x000055f800d4e628 in virtio_net_set_status (vdev=vdev@entry=0x55f8044ec590, status=15 '\017') at ../hw/net/virtio-net.c:370 -10 0x000055f800d534d8 in virtio_net_handle_ctrl (iov_cnt=, iov=, cmd=0 '\000', n=0x55f8044ec590) at ../hw/net/virtio-net.c:1408 -11 0x000055f800d534d8 in virtio_net_handle_ctrl (vdev=0x55f8044ec590, vq=0x7fc1a7e888d0) at ../hw/net/virtio-net.c:1452 -12 0x000055f800d69f37 in virtio_queue_host_notifier_read (vq=0x7fc1a7e888d0) at ../hw/virtio/virtio.c:2331 -13 0x000055f800d69f37 in virtio_queue_host_notifier_read (n=n@entry=0x7fc1a7e8894c) at ../hw/virtio/virtio.c:3575 -14 0x000055f800c688e6 in virtio_bus_cleanup_host_notifier (bus=, n=n@entry=14) at ../hw/virtio/virtio-bus.c:312 -15 0x000055f800d73106 in vhost_dev_disable_notifiers (hdev=hdev@entry=0x55f8035b51b0, vdev=vdev@entry=0x55f8044ec590) - at ../../../include/hw/virtio/virtio-bus.h:35 -16 0x000055f800bf00b2 in vhost_net_stop_one (net=0x55f8035b51b0, dev=0x55f8044ec590) at ../hw/net/vhost_net.c:316 -17 0x000055f800bf0678 in vhost_net_stop (dev=dev@entry=0x55f8044ec590, ncs=0x55f80452bae0, data_queue_pairs=data_queue_pairs@entry=7, cvq=cvq@entry=1) - at ../hw/net/vhost_net.c:423 -18 0x000055f800d4e628 in virtio_net_set_status (status=, n=0x55f8044ec590) at ../hw/net/virtio-net.c:296 -19 0x000055f800d4e628 in virtio_net_set_status (vdev=0x55f8044ec590, status=15 '\017') at ../hw/net/virtio-net.c:370 -20 0x000055f800d6c4b2 in virtio_set_status (vdev=0x55f8044ec590, val=) at ../hw/virtio/virtio.c:1945 -21 0x000055f800d11d9d in vm_state_notify (running=running@entry=false, state=state@entry=RUN_STATE_SHUTDOWN) at ../softmmu/runstate.c:333 -22 0x000055f800d04e7a in do_vm_stop (state=state@entry=RUN_STATE_SHUTDOWN, send_stop=send_stop@entry=false) at ../softmmu/cpus.c:262 -23 0x000055f800d04e99 in vm_shutdown () at ../softmmu/cpus.c:280 -24 0x000055f800d126af in qemu_cleanup () at ../softmmu/runstate.c:812 -25 0x000055f800ad5b13 in main (argc=, argv=, envp=) at ../softmmu/main.c:51 - -For now, temporarily disable handling MQ request from the ctrl_vq -userspace hanlder to avoid the recursive virtio_net_set_status() -call. Some rework is needed to allow changing the number of -queues without going through a full virtio_net_set_status cycle, -particularly for vhost-vdpa backend. - -This patch will need to be reverted as soon as future patches of -having the change of #queues handled in userspace is merged. - -Fixes: 402378407db ("vhost-vdpa: multiqueue support") -Signed-off-by: Si-Wei Liu -Acked-by: Jason Wang -Message-Id: <1651890498-24478-8-git-send-email-si-wei.liu@oracle.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/net/virtio-net.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index eed3fb5cd3..512b37eb76 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -1400,6 +1400,7 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, - { - VirtIODevice *vdev = VIRTIO_DEVICE(n); - uint16_t queue_pairs; -+ NetClientState *nc = qemu_get_queue(n->nic); - - virtio_net_disable_rss(n); - if (cmd == VIRTIO_NET_CTRL_MQ_HASH_CONFIG) { -@@ -1431,6 +1432,18 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, - return VIRTIO_NET_ERR; - } - -+ /* Avoid changing the number of queue_pairs for vdpa device in -+ * userspace handler. A future fix is needed to handle the mq -+ * change in userspace handler with vhost-vdpa. Let's disable -+ * the mq handling from userspace for now and only allow get -+ * done through the kernel. Ripples may be seen when falling -+ * back to userspace, but without doing it qemu process would -+ * crash on a recursive entry to virtio_net_set_status(). -+ */ -+ if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) { -+ return VIRTIO_NET_ERR; -+ } -+ - n->curr_queue_pairs = queue_pairs; - /* stop the backend before changing the number of queue_pairs to avoid handling a - * disabled queue */ --- -2.27.0 - diff --git a/virtio-net-fix-map-leaking-on-error-during-receive.patch b/virtio-net-fix-map-leaking-on-error-during-receive.patch deleted file mode 100644 index b8b59dc11e9416e64d8fdcce369363913c8c568f..0000000000000000000000000000000000000000 --- a/virtio-net-fix-map-leaking-on-error-during-receive.patch +++ /dev/null @@ -1,39 +0,0 @@ -From df98392ee2334462e9f1007b3c9f7a14938bd9ab Mon Sep 17 00:00:00 2001 -From: Jason Wang -Date: Tue, 8 Mar 2022 10:42:51 +0800 -Subject: [PATCH 2/2] virtio-net: fix map leaking on error during receive - -Commit bedd7e93d0196 ("virtio-net: fix use after unmap/free for sg") -tries to fix the use after free of the sg by caching the virtqueue -elements in an array and unmap them at once after receiving the -packets, But it forgot to unmap the cached elements on error which -will lead to leaking of mapping and other unexpected results. - -Fixing this by detaching the cached elements on error. This addresses -CVE-2022-26353. - -Reported-by: Victor Tom -Cc: qemu-stable@nongnu.org -Fixes: CVE-2022-26353 -Fixes: bedd7e93d0196 ("virtio-net: fix use after unmap/free for sg") -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Jason Wang ---- - hw/net/virtio-net.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index e887589a30..d33da9b7ef 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -1883,6 +1883,7 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, - - err: - for (j = 0; j < i; j++) { -+ virtqueue_detach_element(q->rx_vq, elems[j], lens[j]); - g_free(elems[j]); - } - --- -2.27.0 - diff --git a/virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch b/virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch deleted file mode 100644 index 8e2af0ce32cd04a7f50605e8d8be1cc5ac9e0ab8..0000000000000000000000000000000000000000 --- a/virtio-net-fix-max-vring-buf-size-when-set-ring-num.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 318f0eda68554af0c779e5374f16bf8cdb895fe7 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 10:48:27 +0800 -Subject: [PATCH] virtio-net: fix max vring buf size when set ring num - -Signed-off-by: Jinhua Cao ---- - hw/virtio/virtio.c | 9 +++++++-- - include/hw/virtio/virtio.h | 1 + - 2 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index ec3e96af3b..03afa36e99 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -2241,12 +2241,17 @@ void virtio_queue_set_rings(VirtIODevice *vdev, int n, hwaddr desc, - - void virtio_queue_set_num(VirtIODevice *vdev, int n, int num) - { -+ int vq_max_size = VIRTQUEUE_MAX_SIZE; -+ -+ if (!strcmp(vdev->name, "virtio-net")) { -+ vq_max_size = VIRTIO_NET_VQ_MAX_SIZE; -+ } -+ - /* Don't allow guest to flip queue between existent and - * nonexistent states, or to set it to an invalid size. - */ - if (!!num != !!vdev->vq[n].vring.num || -- num > VIRTQUEUE_MAX_SIZE || -- num < 0) { -+ num > vq_max_size || num < 0) { - return; - } - vdev->vq[n].vring.num = num; -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index 8bab9cfb75..b3749ce34b 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -49,6 +49,7 @@ size_t virtio_feature_get_config_size(const VirtIOFeature *features, - typedef struct VirtQueue VirtQueue; - - #define VIRTQUEUE_MAX_SIZE 1024 -+#define VIRTIO_NET_VQ_MAX_SIZE (4096) - - typedef struct VirtQueueElement - { --- -2.27.0 - diff --git a/virtio-net-set-the-max-of-queue-size-to-4096.patch b/virtio-net-set-the-max-of-queue-size-to-4096.patch deleted file mode 100644 index de0520ec279d7a0a3d95338c959dd3cc619b1582..0000000000000000000000000000000000000000 --- a/virtio-net-set-the-max-of-queue-size-to-4096.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 7beaecc21a8a573d43c7ad7604ac77cdf5bbf405 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Sat, 12 Feb 2022 17:22:38 +0800 -Subject: [PATCH] virtio-net: set the max of queue size to 4096 - -Signed-off-by: Jinhua Cao ---- - hw/net/virtio-net.c | 10 +++++----- - hw/virtio/virtio.c | 2 +- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 6874c88bc0..009dc9f3d1 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -637,7 +637,7 @@ static int virtio_net_max_tx_queue_size(VirtIONet *n) - return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE; - } - -- return VIRTQUEUE_MAX_SIZE; -+ return VIRTIO_NET_VQ_MAX_SIZE; - } - - static int peer_attach(VirtIONet *n, int index) -@@ -3394,23 +3394,23 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) - * help from us (using virtio 1 and up). - */ - if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE || -- n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE || -+ n->net_conf.rx_queue_size > VIRTIO_NET_VQ_MAX_SIZE || - !is_power_of_2(n->net_conf.rx_queue_size)) { - error_setg(errp, "Invalid rx_queue_size (= %" PRIu16 "), " - "must be a power of 2 between %d and %d.", - n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE, -- VIRTQUEUE_MAX_SIZE); -+ VIRTIO_NET_VQ_MAX_SIZE); - virtio_cleanup(vdev); - return; - } - - if (n->net_conf.tx_queue_size < VIRTIO_NET_TX_QUEUE_MIN_SIZE || -- n->net_conf.tx_queue_size > VIRTQUEUE_MAX_SIZE || -+ n->net_conf.tx_queue_size > VIRTIO_NET_VQ_MAX_SIZE || - !is_power_of_2(n->net_conf.tx_queue_size)) { - error_setg(errp, "Invalid tx_queue_size (= %" PRIu16 "), " - "must be a power of 2 between %d and %d", - n->net_conf.tx_queue_size, VIRTIO_NET_TX_QUEUE_MIN_SIZE, -- VIRTQUEUE_MAX_SIZE); -+ VIRTIO_NET_VQ_MAX_SIZE); - virtio_cleanup(vdev); - return; - } -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index b08fff9419..120672672e 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -2401,7 +2401,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, - break; - } - -- if (i == VIRTIO_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE) { -+ if (i == VIRTIO_QUEUE_MAX) { - qemu_log("unacceptable queue_size (%d) or num (%d)\n", - queue_size, i); - abort(); --- -2.27.0 - diff --git a/virtio-net-setup-vhost_dev-and-notifiers-for-cvq-onl.patch b/virtio-net-setup-vhost_dev-and-notifiers-for-cvq-onl.patch deleted file mode 100644 index 7a31bd47ddab62d312cb011547b12a44b33f47b9..0000000000000000000000000000000000000000 --- a/virtio-net-setup-vhost_dev-and-notifiers-for-cvq-onl.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 89409c7268be2feb85d33af1f3571c0cb62298fb Mon Sep 17 00:00:00 2001 -From: Si-Wei Liu -Date: Fri, 6 May 2022 19:28:12 -0700 -Subject: [PATCH 5/5] virtio-net: setup vhost_dev and notifiers for cvq only - when feature is negotiated - -When the control virtqueue feature is absent or not negotiated, -vhost_net_start() still tries to set up vhost_dev and install -vhost notifiers for the control virtqueue, which results in -erroneous ioctl calls with incorrect queue index sending down -to driver. Do that only when needed. - -Fixes: 22288fe ("virtio-net: vhost control virtqueue support") -Signed-off-by: Si-Wei Liu -Acked-by: Jason Wang -Message-Id: <1651890498-24478-2-git-send-email-si-wei.liu@oracle.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: zhangxinhao ---- - hw/net/virtio-net.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index d33da9b7ef..918a7aba89 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -243,7 +243,8 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status) - VirtIODevice *vdev = VIRTIO_DEVICE(n); - NetClientState *nc = qemu_get_queue(n->nic); - int queue_pairs = n->multiqueue ? n->max_queue_pairs : 1; -- int cvq = n->max_ncs - n->max_queue_pairs; -+ int cvq = virtio_vdev_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ) ? -+ n->max_ncs - n->max_queue_pairs : 0; - - if (!get_vhost_net(nc->peer)) { - return; --- -2.27.0 - diff --git a/virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch b/virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch deleted file mode 100644 index 59b7c25ecfc6ad380a607659c408f24375cdd262..0000000000000000000000000000000000000000 --- a/virtio-net-tap-bugfix-del-net-client-if-net_init_tap.patch +++ /dev/null @@ -1,76 +0,0 @@ -From cee545754b44b6283408ec6a43eb0e317c98ebb1 Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Wed, 9 Feb 2022 20:27:41 +0800 -Subject: [PATCH] virtio: net-tap: bugfix: del net client if net_init_tap_one - failed - -In net_init_tap_one(), if the net-tap initializes successful -but other actions failed during vhost-net hot-plugging, the -net-tap will remain in the net clients.causing next hot-plug -fails again. - -Signed-off-by: Jinhua Cao ---- - net/tap.c | 16 +++++++++++----- - 1 file changed, 11 insertions(+), 5 deletions(-) - -diff --git a/net/tap.c b/net/tap.c -index c5cbeaa7a2..3f79cd06c2 100644 ---- a/net/tap.c -+++ b/net/tap.c -@@ -684,7 +684,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, - tap_set_sndbuf(s->fd, tap, &err); - if (err) { - error_propagate(errp, err); -- return; -+ goto fail; - } - - if (tap->has_fd || tap->has_fds) { -@@ -726,13 +726,13 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, - } else { - warn_report_err(err); - } -- return; -+ goto fail; - } - ret = qemu_try_set_nonblock(vhostfd); - if (ret < 0) { - error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", - name, fd); -- return; -+ goto fail; - } - } else { - vhostfd = open("/dev/vhost-net", O_RDWR); -@@ -744,7 +744,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, - warn_report("tap: open vhost char device failed: %s", - strerror(errno)); - } -- return; -+ goto fail; - } - qemu_set_nonblock(vhostfd); - } -@@ -758,11 +758,17 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, - } else { - warn_report(VHOST_NET_INIT_FAILED); - } -- return; -+ goto fail; - } - } else if (vhostfdname) { - error_setg(errp, "vhostfd(s)= is not valid without vhost"); -+ goto fail; - } -+ -+ return; -+ -+fail: -+ qemu_del_net_client(&s->nc); - } - - static int get_fds(char *str, char *fds[], int max) --- -2.27.0 - diff --git a/virtio-net-update-the-default-and-max-of-rx-tx_queue.patch b/virtio-net-update-the-default-and-max-of-rx-tx_queue.patch deleted file mode 100644 index 0d849f97421772a4af00443d60c450a444f6f499..0000000000000000000000000000000000000000 --- a/virtio-net-update-the-default-and-max-of-rx-tx_queue.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 88dfb4236c735c608f8ca91cfbfb5ac424d654aa Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 17:28:49 +0800 -Subject: [PATCH] virtio-net: update the default and max of rx/tx_queue_size - -Set the max of tx_queue_size to 4096 even if the backends -are not vhost-user. - -Set the default of rx/tx_queue_size to 2048 if the backends -are vhost-user, otherwise to 4096. - -Signed-off-by: Jinhua Cao ---- - hw/net/virtio-net.c | 41 +++++++++++++++++++++++++++++++---------- - 1 file changed, 31 insertions(+), 10 deletions(-) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index 009dc9f3d1..e887589a30 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -51,12 +51,11 @@ - #define MAX_VLAN (1 << 12) /* Per 802.1Q definition */ - - /* previously fixed value */ --#define VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE 256 --#define VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE 256 -+#define VIRTIO_NET_VHOST_USER_DEFAULT_SIZE 2048 - - /* for now, only allow larger queue_pairs; with virtio-1, guest can downsize */ --#define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE --#define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE -+#define VIRTIO_NET_RX_QUEUE_MIN_SIZE 256 -+#define VIRTIO_NET_TX_QUEUE_MIN_SIZE 256 - - #define VIRTIO_NET_IP4_ADDR_SIZE 8 /* ipv4 saddr + daddr */ - -@@ -622,6 +621,28 @@ static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs, - } - } - -+static void virtio_net_set_default_queue_size(VirtIONet *n) -+{ -+ NetClientState *peer = n->nic_conf.peers.ncs[0]; -+ -+ /* Default value is 0 if not set */ -+ if (n->net_conf.rx_queue_size == 0) { -+ if (peer && peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { -+ n->net_conf.rx_queue_size = VIRTIO_NET_VHOST_USER_DEFAULT_SIZE; -+ } else { -+ n->net_conf.rx_queue_size = VIRTIO_NET_VQ_MAX_SIZE; -+ } -+ } -+ -+ if (n->net_conf.tx_queue_size == 0) { -+ if (peer && peer->info->type == NET_CLIENT_DRIVER_VHOST_USER) { -+ n->net_conf.tx_queue_size = VIRTIO_NET_VHOST_USER_DEFAULT_SIZE; -+ } else { -+ n->net_conf.tx_queue_size = VIRTIO_NET_VQ_MAX_SIZE; -+ } -+ } -+} -+ - static int virtio_net_max_tx_queue_size(VirtIONet *n) - { - NetClientState *peer = n->nic_conf.peers.ncs[0]; -@@ -630,11 +651,11 @@ static int virtio_net_max_tx_queue_size(VirtIONet *n) - * Backends other than vhost-user don't support max queue size. - */ - if (!peer) { -- return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE; -+ return VIRTIO_NET_VQ_MAX_SIZE; - } - - if (peer->info->type != NET_CLIENT_DRIVER_VHOST_USER) { -- return VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE; -+ return VIRTIO_NET_VQ_MAX_SIZE; - } - - return VIRTIO_NET_VQ_MAX_SIZE; -@@ -3388,6 +3409,8 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) - virtio_net_set_config_size(n, n->host_features); - virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size); - -+ virtio_net_set_default_queue_size(n); -+ - /* - * We set a lower limit on RX queue size to what it always was. - * Guests that want a smaller ring can always resize it without -@@ -3679,10 +3702,8 @@ static Property virtio_net_properties[] = { - TX_TIMER_INTERVAL), - DEFINE_PROP_INT32("x-txburst", VirtIONet, net_conf.txburst, TX_BURST), - DEFINE_PROP_STRING("tx", VirtIONet, net_conf.tx), -- DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size, -- VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE), -- DEFINE_PROP_UINT16("tx_queue_size", VirtIONet, net_conf.tx_queue_size, -- VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE), -+ DEFINE_PROP_UINT16("rx_queue_size", VirtIONet, net_conf.rx_queue_size, 0), -+ DEFINE_PROP_UINT16("tx_queue_size", VirtIONet, net_conf.tx_queue_size, 0), - DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0), - DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend, - true), --- -2.27.0 - diff --git a/virtio-pci-add-support-for-configure-interrupt-new.patch b/virtio-pci-add-support-for-configure-interrupt-new.patch deleted file mode 100644 index 91715da57a14a36eecc5550f7919f8d2d1b74d57..0000000000000000000000000000000000000000 --- a/virtio-pci-add-support-for-configure-interrupt-new.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 7e8f9690b0558a99001d45751754df7caf2ff32b Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:51 +0800 -Subject: [PATCH] virtio-pci: add support for configure interrupt - -Add process to handle the configure interrupt, The function's -logic is the same with vq interrupt.Add extra process to check -the configure interrupt - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-11-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 118 ++++++++++++++++++++++++++++++++++------- - hw/virtio/virtio-pci.h | 4 +- - 2 files changed, 102 insertions(+), 20 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 75be770971..82706b8b32 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -812,7 +812,8 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, - VirtQueue *vq; - - if (queue_no == VIRTIO_CONFIG_IRQ_IDX) { -- return -1; -+ *n = virtio_config_get_guest_notifier(vdev); -+ *vector = vdev->config_vector; - } else { - if (!virtio_queue_get_num(vdev, queue_no)) { - return -1; -@@ -872,7 +873,7 @@ undo: - } - return ret; - } --static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) -+static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs) - { - int queue_no; - int ret = 0; -@@ -887,6 +888,10 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - return ret; - } - -+static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy) -+{ -+ return kvm_virtio_pci_vector_use_one(proxy, VIRTIO_CONFIG_IRQ_IDX); -+} - - static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy, - int queue_no) -@@ -911,7 +916,7 @@ static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy, - kvm_virtio_pci_vq_vector_release(proxy, vector); - } - --static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) -+static void kvm_virtio_pci_vector_vq_release(VirtIOPCIProxy *proxy, int nvqs) - { - int queue_no; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -@@ -924,6 +929,11 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - } - } - -+static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy) -+{ -+ kvm_virtio_pci_vector_release_one(proxy, VIRTIO_CONFIG_IRQ_IDX); -+} -+ - static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy, - unsigned int queue_no, - unsigned int vector, -@@ -1005,9 +1015,19 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - } - vq = virtio_vector_next_queue(vq); - } -- -+ /* unmask config intr */ -+ if (vector == vdev->config_vector) { -+ n = virtio_config_get_guest_notifier(vdev); -+ ret = virtio_pci_one_vector_unmask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, -+ msg, n); -+ if (ret < 0) { -+ goto undo_config; -+ } -+ } - return 0; -- -+undo_config: -+ n = virtio_config_get_guest_notifier(vdev); -+ virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n); - undo: - vq = virtio_vector_first_queue(vdev, vector); - while (vq && unmasked >= 0) { -@@ -1041,6 +1061,11 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) - } - vq = virtio_vector_next_queue(vq); - } -+ -+ if (vector == vdev->config_vector) { -+ n = virtio_config_get_guest_notifier(vdev); -+ virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n); -+ } - } - - static void virtio_pci_vector_poll(PCIDevice *dev, -@@ -1072,6 +1097,34 @@ static void virtio_pci_vector_poll(PCIDevice *dev, - msix_set_pending(dev, vector); - } - } -+ /* poll the config intr */ -+ ret = virtio_pci_get_notifier(proxy, VIRTIO_CONFIG_IRQ_IDX, ¬ifier, -+ &vector); -+ if (ret < 0) { -+ return; -+ } -+ if (vector < vector_start || vector >= vector_end || -+ !msix_is_masked(dev, vector)) { -+ return; -+ } -+ if (k->guest_notifier_pending) { -+ if (k->guest_notifier_pending(vdev, VIRTIO_CONFIG_IRQ_IDX)) { -+ msix_set_pending(dev, vector); -+ } -+ } else if (event_notifier_test_and_clear(notifier)) { -+ msix_set_pending(dev, vector); -+ } -+} -+ -+void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq, -+ int n, bool assign, -+ bool with_irqfd) -+{ -+ if (n == VIRTIO_CONFIG_IRQ_IDX) { -+ virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -+ } else { -+ virtio_queue_set_guest_notifier_fd_handler(vq, assign, with_irqfd); -+ } - } - - static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, -@@ -1080,17 +1133,25 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, - VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); -- VirtQueue *vq = virtio_get_queue(vdev, n); -- EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); -+ VirtQueue *vq = NULL; -+ EventNotifier *notifier = NULL; -+ -+ if (n == VIRTIO_CONFIG_IRQ_IDX) { -+ notifier = virtio_config_get_guest_notifier(vdev); -+ } else { -+ vq = virtio_get_queue(vdev, n); -+ notifier = virtio_queue_get_guest_notifier(vq); -+ } - - if (assign) { - int r = event_notifier_init(notifier, 0); - if (r < 0) { - return r; - } -- virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); -+ virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, true, with_irqfd); - } else { -- virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); -+ virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, false, -+ with_irqfd); - event_notifier_cleanup(notifier); - } - -@@ -1128,10 +1189,13 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - proxy->nvqs_with_notifiers = nvqs; - - /* Must unset vector notifier while guest notifier is still assigned */ -- if ((proxy->vector_irqfd || k->guest_notifier_mask) && !assign) { -+ if ((proxy->vector_irqfd || -+ (vdev->use_guest_notifier_mask && k->guest_notifier_mask)) && -+ !assign) { - msix_unset_vector_notifiers(&proxy->pci_dev); - if (proxy->vector_irqfd) { -- kvm_virtio_pci_vector_release(proxy, nvqs); -+ kvm_virtio_pci_vector_vq_release(proxy, nvqs); -+ kvm_virtio_pci_vector_config_release(proxy); - g_free(proxy->vector_irqfd); - proxy->vector_irqfd = NULL; - } -@@ -1147,20 +1211,30 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - goto assign_error; - } - } -- -+ r = virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, assign, -+ with_irqfd); -+ if (r < 0) { -+ goto config_assign_error; -+ } - /* Must set vector notifier after guest notifier has been assigned */ -- if ((with_irqfd || k->guest_notifier_mask) && assign) { -+ if ((with_irqfd || -+ (vdev->use_guest_notifier_mask && k->guest_notifier_mask)) && -+ assign) { - if (with_irqfd) { - proxy->vector_irqfd = - g_malloc0(sizeof(*proxy->vector_irqfd) * - msix_nr_vectors_allocated(&proxy->pci_dev)); -- r = kvm_virtio_pci_vector_use(proxy, nvqs); -+ r = kvm_virtio_pci_vector_vq_use(proxy, nvqs); -+ if (r < 0) { -+ goto config_assign_error; -+ } -+ r = kvm_virtio_pci_vector_config_use(proxy); - if (r < 0) { -- goto assign_error; -+ goto config_error; - } - } -- r = msix_set_vector_notifiers(&proxy->pci_dev, -- virtio_pci_vector_unmask, -+ -+ r = msix_set_vector_notifiers(&proxy->pci_dev, virtio_pci_vector_unmask, - virtio_pci_vector_mask, - virtio_pci_vector_poll); - if (r < 0) { -@@ -1173,9 +1247,15 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - notifiers_error: - if (with_irqfd) { - assert(assign); -- kvm_virtio_pci_vector_release(proxy, nvqs); -+ kvm_virtio_pci_vector_vq_release(proxy, nvqs); - } -- -+config_error: -+ if (with_irqfd) { -+ kvm_virtio_pci_vector_config_release(proxy); -+ } -+config_assign_error: -+ virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, !assign, -+ with_irqfd); - assign_error: - /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ - assert(assign); -diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h -index d95b1a13a5..6d8e071d8d 100644 ---- a/hw/virtio/virtio-pci.h -+++ b/hw/virtio/virtio-pci.h -@@ -256,5 +256,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t); - * @fixed_queues. - */ - unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues); -- -+void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq, -+ int n, bool assign, -+ bool with_irqfd); - #endif --- -2.27.0 - diff --git a/virtio-pci-add-support-for-configure-interrupt.patch b/virtio-pci-add-support-for-configure-interrupt.patch deleted file mode 100644 index 9aa53c1c64c364e805dd0c2e7171858ea73dd2cd..0000000000000000000000000000000000000000 --- a/virtio-pci-add-support-for-configure-interrupt.patch +++ /dev/null @@ -1,218 +0,0 @@ -From ce91ab22c29c56e4e18ee2e861b65657f7bb3e90 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:54 +0800 -Subject: [PATCH] virtio-pci: add support for configure interrupt - -Add support for configure interrupt, The process is used kvm_irqfd_assign -to set the gsi to kernel. When the configure notifier was signal by -host, qemu will inject a msix interrupt to guest - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-11-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 92 ++++++++++++++++++++++++++++++++++++------ - hw/virtio/virtio-pci.h | 4 +- - 2 files changed, 83 insertions(+), 13 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 75be770971..90237f523e 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -812,7 +812,8 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, - VirtQueue *vq; - - if (queue_no == VIRTIO_CONFIG_IRQ_IDX) { -- return -1; -+ *n = virtio_config_get_guest_notifier(vdev); -+ *vector = vdev->config_vector; - } else { - if (!virtio_queue_get_num(vdev, queue_no)) { - return -1; -@@ -887,6 +888,10 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - return ret; - } - -+static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy) -+{ -+ return kvm_virtio_pci_vector_use_one(proxy, VIRTIO_CONFIG_IRQ_IDX); -+} - - static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy, - int queue_no) -@@ -924,6 +929,11 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - } - } - -+static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy) -+{ -+ kvm_virtio_pci_vector_release_one(proxy, VIRTIO_CONFIG_IRQ_IDX); -+} -+ - static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy, - unsigned int queue_no, - unsigned int vector, -@@ -1005,9 +1015,17 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - } - vq = virtio_vector_next_queue(vq); - } -- -+ /* unmask config intr */ -+ n = virtio_config_get_guest_notifier(vdev); -+ ret = virtio_pci_one_vector_unmask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, -+ msg, n); -+ if (ret < 0) { -+ goto undo_config; -+ } - return 0; -- -+undo_config: -+ n = virtio_config_get_guest_notifier(vdev); -+ virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n); - undo: - vq = virtio_vector_first_queue(vdev, vector); - while (vq && unmasked >= 0) { -@@ -1041,6 +1059,8 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) - } - vq = virtio_vector_next_queue(vq); - } -+ n = virtio_config_get_guest_notifier(vdev); -+ virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n); - } - - static void virtio_pci_vector_poll(PCIDevice *dev, -@@ -1072,6 +1092,34 @@ static void virtio_pci_vector_poll(PCIDevice *dev, - msix_set_pending(dev, vector); - } - } -+ /* poll the config intr */ -+ ret = virtio_pci_get_notifier(proxy, VIRTIO_CONFIG_IRQ_IDX, ¬ifier, -+ &vector); -+ if (ret < 0) { -+ return; -+ } -+ if (vector < vector_start || vector >= vector_end || -+ !msix_is_masked(dev, vector)) { -+ return; -+ } -+ if (k->guest_notifier_pending) { -+ if (k->guest_notifier_pending(vdev, VIRTIO_CONFIG_IRQ_IDX)) { -+ msix_set_pending(dev, vector); -+ } -+ } else if (event_notifier_test_and_clear(notifier)) { -+ msix_set_pending(dev, vector); -+ } -+} -+ -+void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq, -+ int n, bool assign, -+ bool with_irqfd) -+{ -+ if (n == VIRTIO_CONFIG_IRQ_IDX) { -+ virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); -+ } else { -+ virtio_queue_set_guest_notifier_fd_handler(vq, assign, with_irqfd); -+ } - } - - static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, -@@ -1080,17 +1128,25 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, - VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); -- VirtQueue *vq = virtio_get_queue(vdev, n); -- EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); -+ VirtQueue *vq = NULL; -+ EventNotifier *notifier = NULL; -+ -+ if (n == VIRTIO_CONFIG_IRQ_IDX) { -+ notifier = virtio_config_get_guest_notifier(vdev); -+ } else { -+ vq = virtio_get_queue(vdev, n); -+ notifier = virtio_queue_get_guest_notifier(vq); -+ } - - if (assign) { - int r = event_notifier_init(notifier, 0); - if (r < 0) { - return r; - } -- virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); -+ virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, true, with_irqfd); - } else { -- virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); -+ virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, false, -+ with_irqfd); - event_notifier_cleanup(notifier); - } - -@@ -1132,6 +1188,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - msix_unset_vector_notifiers(&proxy->pci_dev); - if (proxy->vector_irqfd) { - kvm_virtio_pci_vector_release(proxy, nvqs); -+ kvm_virtio_pci_vector_config_release(proxy); - g_free(proxy->vector_irqfd); - proxy->vector_irqfd = NULL; - } -@@ -1147,7 +1204,11 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - goto assign_error; - } - } -- -+ r = virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, assign, -+ with_irqfd); -+ if (r < 0) { -+ goto config_assign_error; -+ } - /* Must set vector notifier after guest notifier has been assigned */ - if ((with_irqfd || k->guest_notifier_mask) && assign) { - if (with_irqfd) { -@@ -1156,11 +1217,14 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) - msix_nr_vectors_allocated(&proxy->pci_dev)); - r = kvm_virtio_pci_vector_use(proxy, nvqs); - if (r < 0) { -- goto assign_error; -+ goto config_assign_error; - } - } -- r = msix_set_vector_notifiers(&proxy->pci_dev, -- virtio_pci_vector_unmask, -+ r = kvm_virtio_pci_vector_config_use(proxy); -+ if (r < 0) { -+ goto config_error; -+ } -+ r = msix_set_vector_notifiers(&proxy->pci_dev, virtio_pci_vector_unmask, - virtio_pci_vector_mask, - virtio_pci_vector_poll); - if (r < 0) { -@@ -1175,7 +1239,11 @@ notifiers_error: - assert(assign); - kvm_virtio_pci_vector_release(proxy, nvqs); - } -- -+config_error: -+ kvm_virtio_pci_vector_config_release(proxy); -+config_assign_error: -+ virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, !assign, -+ with_irqfd); - assign_error: - /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ - assert(assign); -diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h -index d95b1a13a5..6d8e071d8d 100644 ---- a/hw/virtio/virtio-pci.h -+++ b/hw/virtio/virtio-pci.h -@@ -256,5 +256,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t); - * @fixed_queues. - */ - unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues); -- -+void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq, -+ int n, bool assign, -+ bool with_irqfd); - #endif --- -2.27.0 - diff --git a/virtio-pci-decouple-notifier-from-interrupt-process-new.patch b/virtio-pci-decouple-notifier-from-interrupt-process-new.patch deleted file mode 100644 index 89380b313ddfcdfa975def97a88d3cee55819342..0000000000000000000000000000000000000000 --- a/virtio-pci-decouple-notifier-from-interrupt-process-new.patch +++ /dev/null @@ -1,259 +0,0 @@ -From e7e028565dd2620b86e884f953761b96a1ecdfdc Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:43 +0800 -Subject: [PATCH] virtio-pci: decouple notifier from interrupt process - -To reuse the notifier process. We add the virtio_pci_get_notifier -to get the notifier and vector. The INPUT for this function is IDX, -The OUTPUT is the notifier and the vector - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-3-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 88 +++++++++++++++++++++++++++--------------- - 1 file changed, 57 insertions(+), 31 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 21c0ec3b1b..85d7357f66 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -789,29 +789,41 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy, - } - - static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy, -- unsigned int queue_no, -+ EventNotifier *n, - unsigned int vector) - { - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; -- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -- VirtQueue *vq = virtio_get_queue(vdev, queue_no); -- EventNotifier *n = virtio_queue_get_guest_notifier(vq); - return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq); - } - - static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy, -- unsigned int queue_no, -+ EventNotifier *n , - unsigned int vector) - { -- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -- VirtQueue *vq = virtio_get_queue(vdev, queue_no); -- EventNotifier *n = virtio_queue_get_guest_notifier(vq); - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; - int ret; - - ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq); - assert(ret == 0); - } -+static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, -+ EventNotifier **n, unsigned int *vector) -+{ -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ VirtQueue *vq; -+ -+ if (queue_no == VIRTIO_CONFIG_IRQ_IDX) { -+ return -1; -+ } else { -+ if (!virtio_queue_get_num(vdev, queue_no)) { -+ return -1; -+ } -+ *vector = virtio_queue_vector(vdev, queue_no); -+ vq = virtio_get_queue(vdev, queue_no); -+ *n = virtio_queue_get_guest_notifier(vq); -+ } -+ return 0; -+} - - static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - { -@@ -820,12 +832,15 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - unsigned int vector; - int ret, queue_no; -- -+ EventNotifier *n; - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- vector = virtio_queue_vector(vdev, queue_no); -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; - } -@@ -837,7 +852,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - * Otherwise, delay until unmasked in the frontend. - */ - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); -+ ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); - if (ret < 0) { - kvm_virtio_pci_vq_vector_release(proxy, vector); - goto undo; -@@ -853,7 +868,11 @@ undo: - continue; - } - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); - } - kvm_virtio_pci_vq_vector_release(proxy, vector); - } -@@ -867,12 +886,16 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - unsigned int vector; - int queue_no; - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- -+ EventNotifier *n; -+ int ret ; - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- vector = virtio_queue_vector(vdev, queue_no); -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; - } -@@ -880,21 +903,20 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - * Otherwise, it was cleaned when masked in the frontend. - */ - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); - } - kvm_virtio_pci_vq_vector_release(proxy, vector); - } - } - --static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, -+static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy, - unsigned int queue_no, - unsigned int vector, -- MSIMessage msg) -+ MSIMessage msg, -+ EventNotifier *n) - { - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- VirtQueue *vq = virtio_get_queue(vdev, queue_no); -- EventNotifier *n = virtio_queue_get_guest_notifier(vq); - VirtIOIRQFD *irqfd; - int ret = 0; - -@@ -921,14 +943,15 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, - event_notifier_set(n); - } - } else { -- ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); -+ ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); - } - return ret; - } - --static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, -+static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy, - unsigned int queue_no, -- unsigned int vector) -+ unsigned int vector, -+ EventNotifier *n) - { - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -@@ -939,7 +962,7 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { - k->guest_notifier_mask(vdev, queue_no, true); - } else { -- kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); - } - } - -@@ -949,6 +972,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtQueue *vq = virtio_vector_first_queue(vdev, vector); -+ EventNotifier *n; - int ret, index, unmasked = 0; - - while (vq) { -@@ -957,7 +981,8 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - break; - } - if (index < proxy->nvqs_with_notifiers) { -- ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg); -+ n = virtio_queue_get_guest_notifier(vq); -+ ret = virtio_pci_one_vector_unmask(proxy, index, vector, msg, n); - if (ret < 0) { - goto undo; - } -@@ -973,7 +998,8 @@ undo: - while (vq && unmasked >= 0) { - index = virtio_get_queue_index(vq); - if (index < proxy->nvqs_with_notifiers) { -- virtio_pci_vq_vector_mask(proxy, index, vector); -+ n = virtio_queue_get_guest_notifier(vq); -+ virtio_pci_one_vector_mask(proxy, index, vector, n); - --unmasked; - } - vq = virtio_vector_next_queue(vq); -@@ -986,15 +1012,17 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) - VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtQueue *vq = virtio_vector_first_queue(vdev, vector); -+ EventNotifier *n; - int index; - - while (vq) { - index = virtio_get_queue_index(vq); -+ n = virtio_queue_get_guest_notifier(vq); - if (!virtio_queue_get_num(vdev, index)) { - break; - } - if (index < proxy->nvqs_with_notifiers) { -- virtio_pci_vq_vector_mask(proxy, index, vector); -+ virtio_pci_one_vector_mask(proxy, index, vector, n); - } - vq = virtio_vector_next_queue(vq); - } -@@ -1010,19 +1038,17 @@ static void virtio_pci_vector_poll(PCIDevice *dev, - int queue_no; - unsigned int vector; - EventNotifier *notifier; -- VirtQueue *vq; -+ int ret; - - for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { -- if (!virtio_queue_get_num(vdev, queue_no)) { -+ ret = virtio_pci_get_notifier(proxy, queue_no, ¬ifier, &vector); -+ if (ret < 0) { - break; - } -- vector = virtio_queue_vector(vdev, queue_no); - if (vector < vector_start || vector >= vector_end || - !msix_is_masked(dev, vector)) { - continue; - } -- vq = virtio_get_queue(vdev, queue_no); -- notifier = virtio_queue_get_guest_notifier(vq); - if (k->guest_notifier_pending) { - if (k->guest_notifier_pending(vdev, queue_no)) { - msix_set_pending(dev, vector); --- -2.27.0 - diff --git a/virtio-pci-decouple-notifier-from-interrupt-process.patch b/virtio-pci-decouple-notifier-from-interrupt-process.patch deleted file mode 100644 index 0c3d620898eab1936fde061c701def6ae7631721..0000000000000000000000000000000000000000 --- a/virtio-pci-decouple-notifier-from-interrupt-process.patch +++ /dev/null @@ -1,259 +0,0 @@ -From 22998eab50bc17b9af19e377df04d1583a7ddbda Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:50 +0800 -Subject: [PATCH] virtio-pci: decouple notifier from interrupt process - -To reuse the notifier process in configure interrupt. -Use the virtio_pci_get_notifier function to get the notifier. -the INPUT of this function is the IDX, the OUTPUT is notifier and -the vector - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-3-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 88 +++++++++++++++++++++++++++--------------- - 1 file changed, 57 insertions(+), 31 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 21c0ec3b1b..85d7357f66 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -789,29 +789,41 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy, - } - - static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy, -- unsigned int queue_no, -+ EventNotifier *n, - unsigned int vector) - { - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; -- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -- VirtQueue *vq = virtio_get_queue(vdev, queue_no); -- EventNotifier *n = virtio_queue_get_guest_notifier(vq); - return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq); - } - - static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy, -- unsigned int queue_no, -+ EventNotifier *n , - unsigned int vector) - { -- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -- VirtQueue *vq = virtio_get_queue(vdev, queue_no); -- EventNotifier *n = virtio_queue_get_guest_notifier(vq); - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; - int ret; - - ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq); - assert(ret == 0); - } -+static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, -+ EventNotifier **n, unsigned int *vector) -+{ -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ VirtQueue *vq; -+ -+ if (queue_no == VIRTIO_CONFIG_IRQ_IDX) { -+ return -1; -+ } else { -+ if (!virtio_queue_get_num(vdev, queue_no)) { -+ return -1; -+ } -+ *vector = virtio_queue_vector(vdev, queue_no); -+ vq = virtio_get_queue(vdev, queue_no); -+ *n = virtio_queue_get_guest_notifier(vq); -+ } -+ return 0; -+} - - static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - { -@@ -820,12 +832,15 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - unsigned int vector; - int ret, queue_no; -- -+ EventNotifier *n; - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- vector = virtio_queue_vector(vdev, queue_no); -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; - } -@@ -837,7 +852,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) - * Otherwise, delay until unmasked in the frontend. - */ - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); -+ ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); - if (ret < 0) { - kvm_virtio_pci_vq_vector_release(proxy, vector); - goto undo; -@@ -853,7 +868,11 @@ undo: - continue; - } - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); - } - kvm_virtio_pci_vq_vector_release(proxy, vector); - } -@@ -867,12 +886,16 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - unsigned int vector; - int queue_no; - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- -+ EventNotifier *n; -+ int ret ; - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- vector = virtio_queue_vector(vdev, queue_no); -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ break; -+ } - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; - } -@@ -880,21 +903,20 @@ static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) - * Otherwise, it was cleaned when masked in the frontend. - */ - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); - } - kvm_virtio_pci_vq_vector_release(proxy, vector); - } - } - --static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, -+static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy, - unsigned int queue_no, - unsigned int vector, -- MSIMessage msg) -+ MSIMessage msg, -+ EventNotifier *n) - { - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- VirtQueue *vq = virtio_get_queue(vdev, queue_no); -- EventNotifier *n = virtio_queue_get_guest_notifier(vq); - VirtIOIRQFD *irqfd; - int ret = 0; - -@@ -921,14 +943,15 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, - event_notifier_set(n); - } - } else { -- ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); -+ ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); - } - return ret; - } - --static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, -+static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy, - unsigned int queue_no, -- unsigned int vector) -+ unsigned int vector, -+ EventNotifier *n) - { - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -@@ -939,7 +962,7 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { - k->guest_notifier_mask(vdev, queue_no, true); - } else { -- kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); - } - } - -@@ -949,6 +972,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtQueue *vq = virtio_vector_first_queue(vdev, vector); -+ EventNotifier *n; - int ret, index, unmasked = 0; - - while (vq) { -@@ -957,7 +981,8 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, - break; - } - if (index < proxy->nvqs_with_notifiers) { -- ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg); -+ n = virtio_queue_get_guest_notifier(vq); -+ ret = virtio_pci_one_vector_unmask(proxy, index, vector, msg, n); - if (ret < 0) { - goto undo; - } -@@ -973,7 +998,8 @@ undo: - while (vq && unmasked >= 0) { - index = virtio_get_queue_index(vq); - if (index < proxy->nvqs_with_notifiers) { -- virtio_pci_vq_vector_mask(proxy, index, vector); -+ n = virtio_queue_get_guest_notifier(vq); -+ virtio_pci_one_vector_mask(proxy, index, vector, n); - --unmasked; - } - vq = virtio_vector_next_queue(vq); -@@ -986,15 +1012,17 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) - VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtQueue *vq = virtio_vector_first_queue(vdev, vector); -+ EventNotifier *n; - int index; - - while (vq) { - index = virtio_get_queue_index(vq); -+ n = virtio_queue_get_guest_notifier(vq); - if (!virtio_queue_get_num(vdev, index)) { - break; - } - if (index < proxy->nvqs_with_notifiers) { -- virtio_pci_vq_vector_mask(proxy, index, vector); -+ virtio_pci_one_vector_mask(proxy, index, vector, n); - } - vq = virtio_vector_next_queue(vq); - } -@@ -1010,19 +1038,17 @@ static void virtio_pci_vector_poll(PCIDevice *dev, - int queue_no; - unsigned int vector; - EventNotifier *notifier; -- VirtQueue *vq; -+ int ret; - - for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { -- if (!virtio_queue_get_num(vdev, queue_no)) { -+ ret = virtio_pci_get_notifier(proxy, queue_no, ¬ifier, &vector); -+ if (ret < 0) { - break; - } -- vector = virtio_queue_vector(vdev, queue_no); - if (vector < vector_start || vector >= vector_end || - !msix_is_masked(dev, vector)) { - continue; - } -- vq = virtio_get_queue(vdev, queue_no); -- notifier = virtio_queue_get_guest_notifier(vq); - if (k->guest_notifier_pending) { - if (k->guest_notifier_pending(vdev, queue_no)) { - msix_set_pending(dev, vector); --- -2.27.0 - diff --git a/virtio-pci-decouple-the-single-vector-from-the-inter-new.patch b/virtio-pci-decouple-the-single-vector-from-the-inter-new.patch deleted file mode 100644 index 1bff2796e481ac1ae801550ea65d7d9ec44a5f73..0000000000000000000000000000000000000000 --- a/virtio-pci-decouple-the-single-vector-from-the-inter-new.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 99e35c22ecd4847c652f136334c5949651e8419d Mon Sep 17 00:00:00 2001 -From: Cindy Lu -Date: Thu, 22 Dec 2022 15:04:44 +0800 -Subject: [PATCH] virtio-pci: decouple the single vector from the interrupt - process - -To reuse the interrupt process in configure interrupt -Need to decouple the single vector from the interrupt process. -We add new function kvm_virtio_pci_vector_use_one and _release_one. -These functions are used for the single vector, the whole process will -finish in the loop with vq number. - -Signed-off-by: Cindy Lu -Message-Id: <20221222070451.936503-4-lulu@redhat.com> -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 131 +++++++++++++++++++++++------------------ - 1 file changed, 73 insertions(+), 58 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 85d7357f66..75be770971 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -762,7 +762,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev, - } - - static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, -- unsigned int queue_no, - unsigned int vector) - { - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; -@@ -825,87 +824,103 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, - return 0; - } - --static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) -+static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no) - { -+ unsigned int vector; -+ int ret; -+ EventNotifier *n; - PCIDevice *dev = &proxy->pci_dev; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- unsigned int vector; -- int ret, queue_no; -- EventNotifier *n; -- for (queue_no = 0; queue_no < nvqs; queue_no++) { -- if (!virtio_queue_get_num(vdev, queue_no)) { -- break; -- } -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -- if (vector >= msix_nr_vectors_allocated(dev)) { -- continue; -- } -- ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector); -+ -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ return ret; -+ } -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ return 0; -+ } -+ ret = kvm_virtio_pci_vq_vector_use(proxy, vector); -+ if (ret < 0) { -+ goto undo; -+ } -+ /* -+ * If guest supports masking, set up irqfd now. -+ * Otherwise, delay until unmasked in the frontend. -+ */ -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); - if (ret < 0) { -+ kvm_virtio_pci_vq_vector_release(proxy, vector); - goto undo; - } -- /* If guest supports masking, set up irqfd now. -- * Otherwise, delay until unmasked in the frontend. -- */ -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); -- if (ret < 0) { -- kvm_virtio_pci_vq_vector_release(proxy, vector); -- goto undo; -- } -- } - } -- return 0; - -+ return 0; - undo: -- while (--queue_no >= 0) { -- vector = virtio_queue_vector(vdev, queue_no); -- if (vector >= msix_nr_vectors_allocated(dev)) { -- continue; -+ -+ vector = virtio_queue_vector(vdev, queue_no); -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ return ret; -+ } -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ return ret; - } -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ } -+ return ret; -+} -+static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) -+{ -+ int queue_no; -+ int ret = 0; -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ -+ for (queue_no = 0; queue_no < nvqs; queue_no++) { -+ if (!virtio_queue_get_num(vdev, queue_no)) { -+ return -1; - } -- kvm_virtio_pci_vq_vector_release(proxy, vector); -+ ret = kvm_virtio_pci_vector_use_one(proxy, queue_no); - } - return ret; - } - --static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) -+ -+static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy, -+ int queue_no) - { -- PCIDevice *dev = &proxy->pci_dev; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - unsigned int vector; -- int queue_no; -- VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - EventNotifier *n; -- int ret ; -+ int ret; -+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -+ PCIDevice *dev = &proxy->pci_dev; -+ -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ return; -+ } -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ return; -+ } -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ } -+ kvm_virtio_pci_vq_vector_release(proxy, vector); -+} -+ -+static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) -+{ -+ int queue_no; -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -- if (vector >= msix_nr_vectors_allocated(dev)) { -- continue; -- } -- /* If guest supports masking, clean up irqfd now. -- * Otherwise, it was cleaned when masked in the frontend. -- */ -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -- } -- kvm_virtio_pci_vq_vector_release(proxy, vector); -+ kvm_virtio_pci_vector_release_one(proxy, queue_no); - } - } - --- -2.27.0 - diff --git a/virtio-pci-decouple-the-single-vector-from-the-inter.patch b/virtio-pci-decouple-the-single-vector-from-the-inter.patch deleted file mode 100644 index a6989f9b42c0417ca792dfb6e16d630f044b37dc..0000000000000000000000000000000000000000 --- a/virtio-pci-decouple-the-single-vector-from-the-inter.patch +++ /dev/null @@ -1,196 +0,0 @@ -From b3223ddde84840ccc6bb2282dfc146616b85a362 Mon Sep 17 00:00:00 2001 -From: fangyi -Date: Thu, 16 Nov 2023 09:54:51 +0800 -Subject: [PATCH] virtio-pci: decouple the single vector from the interrupt - process - -To reuse the interrupt process in configure interrupt -Need to decouple the single vector from the interrupt process. Add new function -kvm_virtio_pci_vector_use_one and _release_one. These functions are use -for the single vector, the whole process will finish in a loop for the vq number. - -Signed-off-by: Cindy Lu -Message-Id: <20211104164827.21911-4-lulu@redhat.com> -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio-pci.c | 131 +++++++++++++++++++++++------------------ - 1 file changed, 73 insertions(+), 58 deletions(-) - -diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c -index 85d7357f66..75be770971 100644 ---- a/hw/virtio/virtio-pci.c -+++ b/hw/virtio/virtio-pci.c -@@ -762,7 +762,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev, - } - - static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, -- unsigned int queue_no, - unsigned int vector) - { - VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; -@@ -825,87 +824,103 @@ static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, - return 0; - } - --static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) -+static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no) - { -+ unsigned int vector; -+ int ret; -+ EventNotifier *n; - PCIDevice *dev = &proxy->pci_dev; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -- unsigned int vector; -- int ret, queue_no; -- EventNotifier *n; -- for (queue_no = 0; queue_no < nvqs; queue_no++) { -- if (!virtio_queue_get_num(vdev, queue_no)) { -- break; -- } -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -- if (vector >= msix_nr_vectors_allocated(dev)) { -- continue; -- } -- ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector); -+ -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ return ret; -+ } -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ return 0; -+ } -+ ret = kvm_virtio_pci_vq_vector_use(proxy, vector); -+ if (ret < 0) { -+ goto undo; -+ } -+ /* -+ * If guest supports masking, set up irqfd now. -+ * Otherwise, delay until unmasked in the frontend. -+ */ -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); - if (ret < 0) { -+ kvm_virtio_pci_vq_vector_release(proxy, vector); - goto undo; - } -- /* If guest supports masking, set up irqfd now. -- * Otherwise, delay until unmasked in the frontend. -- */ -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); -- if (ret < 0) { -- kvm_virtio_pci_vq_vector_release(proxy, vector); -- goto undo; -- } -- } - } -- return 0; - -+ return 0; - undo: -- while (--queue_no >= 0) { -- vector = virtio_queue_vector(vdev, queue_no); -- if (vector >= msix_nr_vectors_allocated(dev)) { -- continue; -+ -+ vector = virtio_queue_vector(vdev, queue_no); -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ return ret; -+ } -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ return ret; - } -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ } -+ return ret; -+} -+static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) -+{ -+ int queue_no; -+ int ret = 0; -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ -+ for (queue_no = 0; queue_no < nvqs; queue_no++) { -+ if (!virtio_queue_get_num(vdev, queue_no)) { -+ return -1; - } -- kvm_virtio_pci_vq_vector_release(proxy, vector); -+ ret = kvm_virtio_pci_vector_use_one(proxy, queue_no); - } - return ret; - } - --static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) -+ -+static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy, -+ int queue_no) - { -- PCIDevice *dev = &proxy->pci_dev; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - unsigned int vector; -- int queue_no; -- VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - EventNotifier *n; -- int ret ; -+ int ret; -+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); -+ PCIDevice *dev = &proxy->pci_dev; -+ -+ ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -+ if (ret < 0) { -+ return; -+ } -+ if (vector >= msix_nr_vectors_allocated(dev)) { -+ return; -+ } -+ if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -+ kvm_virtio_pci_irqfd_release(proxy, n, vector); -+ } -+ kvm_virtio_pci_vq_vector_release(proxy, vector); -+} -+ -+static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) -+{ -+ int queue_no; -+ VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); -+ - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } -- ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); -- if (ret < 0) { -- break; -- } -- if (vector >= msix_nr_vectors_allocated(dev)) { -- continue; -- } -- /* If guest supports masking, clean up irqfd now. -- * Otherwise, it was cleaned when masked in the frontend. -- */ -- if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { -- kvm_virtio_pci_irqfd_release(proxy, n, vector); -- } -- kvm_virtio_pci_vq_vector_release(proxy, vector); -+ kvm_virtio_pci_vector_release_one(proxy, queue_no); - } - } - --- -2.27.0 - diff --git a/virtio-print-the-guest-virtio_net-features-that-host.patch b/virtio-print-the-guest-virtio_net-features-that-host.patch deleted file mode 100644 index 5db0434aba861b8347915f104e313807418b01bf..0000000000000000000000000000000000000000 --- a/virtio-print-the-guest-virtio_net-features-that-host.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 8a08b3b41400e152cc1786ae5a8a53507f8e925c Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Thu, 10 Feb 2022 14:16:17 +0800 -Subject: [PATCH] virtio: print the guest virtio_net features that host does - not support - -Signed-off-by: Jinhua Cao ---- - hw/net/virtio-net.c | 41 ++++++++++++++++++++++++++++++++++++++ - hw/virtio/virtio.c | 7 +++++++ - include/hw/virtio/virtio.h | 1 + - 3 files changed, 49 insertions(+) - -diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c -index b3a5d0b19e..6874c88bc0 100644 ---- a/hw/net/virtio-net.c -+++ b/hw/net/virtio-net.c -@@ -3692,6 +3692,46 @@ static Property virtio_net_properties[] = { - DEFINE_PROP_END_OF_LIST(), - }; - -+static void virtio_net_print_features(uint64_t features) -+{ -+ Property *props = virtio_net_properties; -+ int feature_cnt = 0; -+ -+ if (!features) { -+ return; -+ } -+ printf("virtio_net_feature: "); -+ -+ for (; features && props->name; props++) { -+ /* The bitnr of property may be default(0) besides 'csum' property. */ -+ if (props->bitnr == 0 && strcmp(props->name, "csum")) { -+ continue; -+ } -+ -+ /* Features only support 64bit. */ -+ if (props->bitnr > 63) { -+ continue; -+ } -+ -+ if (virtio_has_feature(features, props->bitnr)) { -+ virtio_clear_feature(&features, props->bitnr); -+ if (feature_cnt != 0) { -+ printf(", "); -+ } -+ printf("%s", props->name); -+ feature_cnt++; -+ } -+ } -+ -+ if (features) { -+ if (feature_cnt != 0) { -+ printf(", "); -+ } -+ printf("unkown bits 0x%." PRIx64, features); -+ } -+ printf("\n"); -+} -+ - static void virtio_net_class_init(ObjectClass *klass, void *data) - { - DeviceClass *dc = DEVICE_CLASS(klass); -@@ -3706,6 +3746,7 @@ static void virtio_net_class_init(ObjectClass *klass, void *data) - vdc->set_config = virtio_net_set_config; - vdc->get_features = virtio_net_get_features; - vdc->set_features = virtio_net_set_features; -+ vdc->print_features = virtio_net_print_features; - vdc->bad_features = virtio_net_bad_features; - vdc->reset = virtio_net_reset; - vdc->set_status = virtio_net_set_status; -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index 0af9684881..9a2a83d507 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -2967,6 +2967,13 @@ static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val) - { - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - bool bad = (val & ~(vdev->host_features)) != 0; -+ uint64_t feat = val & ~(vdev->host_features); -+ -+ if (bad && k->print_features) { -+ qemu_log("error: Please check host config, "\ -+ "because host does not support required feature bits 0x%" PRIx64 "\n", feat); -+ k->print_features(feat); -+ } - - val &= vdev->host_features; - if (k->set_features) { -diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h -index b3749ce34b..7472145821 100644 ---- a/include/hw/virtio/virtio.h -+++ b/include/hw/virtio/virtio.h -@@ -127,6 +127,7 @@ struct VirtioDeviceClass { - int (*validate_features)(VirtIODevice *vdev); - void (*get_config)(VirtIODevice *vdev, uint8_t *config); - void (*set_config)(VirtIODevice *vdev, const uint8_t *config); -+ void (*print_features)(uint64_t features); - void (*reset)(VirtIODevice *vdev); - void (*set_status)(VirtIODevice *vdev, uint8_t val); - /* For transitional devices, this is a bitmap of features --- -2.27.0 - diff --git a/virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch b/virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch deleted file mode 100644 index bca7db04571d8c014d6a3b51b5c7727f2dcc3aed..0000000000000000000000000000000000000000 --- a/virtio-scsi-bugfix-fix-qemu-crash-for-hotplug-scsi-d.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 98cbb6d13484e79b6f9da064a40a281f2983be1d Mon Sep 17 00:00:00 2001 -From: Jinhua Cao -Date: Wed, 9 Feb 2022 19:58:21 +0800 -Subject: [PATCH] virtio-scsi: bugfix: fix qemu crash for hotplug scsi disk - with dataplane - -The vm will trigger a disk sweep operation after plugging -a controller who's io type is iothread. If attach a scsi -disk immediately, the sg_inqury request in vm will trigger -the assert in virtio_scsi_ctx_check(), which is called by -virtio_scsi_handle_cmd_req_prepare(). - -Add judgment in virtio_scsi_handle_cmd_req_prepare() and -return IO Error directly if the device has not been -initialized. - -Signed-off-by: Jinhua Cao ---- - hw/scsi/virtio-scsi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c -index 51fd09522a..781a37fe89 100644 ---- a/hw/scsi/virtio-scsi.c -+++ b/hw/scsi/virtio-scsi.c -@@ -638,7 +638,7 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) - req->req.cmd.tag, req->req.cmd.cdb[0]); - - d = virtio_scsi_device_get(s, req->req.cmd.lun); -- if (!d) { -+ if (!d || !d->qdev.realized) { - req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; - virtio_scsi_complete_cmd_req(req); - return -ENOENT; --- -2.27.0 - diff --git a/virtio-signal-after-wrapping-packed-used_idx.patch b/virtio-signal-after-wrapping-packed-used_idx.patch deleted file mode 100644 index 3fa3b633aef0aab471da451e04fab95af43a30e1..0000000000000000000000000000000000000000 --- a/virtio-signal-after-wrapping-packed-used_idx.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 671f0830d70c1e35deb63cc66db7ce8b713e8967 Mon Sep 17 00:00:00 2001 -From: Stefan Hajnoczi -Date: Tue, 30 Nov 2021 13:45:10 +0000 -Subject: [PATCH] virtio: signal after wrapping packed used_idx - -Packed Virtqueues wrap used_idx instead of letting it run freely like -Split Virtqueues do. If the used ring wraps more than once there is no -way to compare vq->signalled_used and vq->used_idx in -virtio_packed_should_notify() since they are modulo vq->vring.num. - -This causes the device to stop sending used buffer notifications when -when virtio_packed_should_notify() is called less than once each time -around the used ring. - -It is possible to trigger this with virtio-blk's dataplane -notify_guest_bh() irq coalescing optimization. The call to -virtio_notify_irqfd() (and virtio_packed_should_notify()) is deferred to -a BH. If the guest driver is polling it can complete and submit more -requests before the BH executes, causing the used ring to wrap more than -once. The result is that the virtio-blk device ceases to raise -interrupts and I/O hangs. - -Cc: Tiwei Bie -Cc: Jason Wang -Cc: Michael S. Tsirkin -Signed-off-by: Stefan Hajnoczi -Message-Id: <20211130134510.267382-1-stefanha@redhat.com> -Fixes: 86044b24e865fb9596ed77a4d0f3af8b90a088a1 ("virtio: basic packed virtqueue support") -Acked-by: Jason Wang -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: fangyi ---- - hw/virtio/virtio.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c -index d90cabe868..05409b84d1 100644 ---- a/hw/virtio/virtio.c -+++ b/hw/virtio/virtio.c -@@ -885,6 +885,7 @@ static void virtqueue_packed_flush(VirtQueue *vq, unsigned int count) - if (vq->used_idx >= vq->vring.num) { - vq->used_idx -= vq->vring.num; - vq->used_wrap_counter ^= 1; -+ vq->signalled_used_valid = false; - } - } - --- -2.27.0 - diff --git a/virtio-vhost-vsock-don-t-double-close-vhostfd-remove.patch b/virtio-vhost-vsock-don-t-double-close-vhostfd-remove.patch deleted file mode 100644 index b554e7a1d728a2c82ec50d51f5bf246d7945bd0f..0000000000000000000000000000000000000000 --- a/virtio-vhost-vsock-don-t-double-close-vhostfd-remove.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 1d888e71517be4a0793b5a03b4a2234c55953c8f Mon Sep 17 00:00:00 2001 -From: boringandboring -Date: Fri, 8 Dec 2023 10:02:51 +0800 -Subject: [PATCH] virtio/vhost-vsock: don't double close vhostfd, remove - redundant cleanup - -cherry picked from d731ab31196579144457c7f2fa3649338bfb21f2 - -In case of an error during initialization in vhost_dev_init, vhostfd is -closed in vhost_dev_cleanup. Remove close from err_virtio as it's both -redundant and causes a double close on vhostfd. - -Signed-off-by: Daniil Tatianin -Message-Id: <20211129125204.1108088-1-d-tatianin@yandex-team.ru> -Reviewed-by: Stefano Garzarella -Reviewed-by: Michael S. Tsirkin -Signed-off-by: Michael S. Tsirkin -Signed-off-by: boringandboring ---- - hw/virtio/vhost-vsock.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - -diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c -index 478c0c9a87..433d42d897 100644 ---- a/hw/virtio/vhost-vsock.c -+++ b/hw/virtio/vhost-vsock.c -@@ -171,6 +171,10 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp) - ret = vhost_dev_init(&vvc->vhost_dev, (void *)(uintptr_t)vhostfd, - VHOST_BACKEND_TYPE_KERNEL, 0, errp); - if (ret < 0) { -+ /* -+ * vhostfd is closed by vhost_dev_cleanup, which is called -+ * by vhost_dev_init on initialization error. -+ */ - goto err_virtio; - } - -@@ -183,15 +187,10 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp) - return; - - err_vhost_dev: -- vhost_dev_cleanup(&vvc->vhost_dev); - /* vhost_dev_cleanup() closes the vhostfd passed to vhost_dev_init() */ -- vhostfd = -1; -+ vhost_dev_cleanup(&vvc->vhost_dev); - err_virtio: - vhost_vsock_common_unrealize(vdev); -- if (vhostfd >= 0) { -- close(vhostfd); -- } -- return; - } - - static void vhost_vsock_device_unrealize(DeviceState *dev) --- -2.27.0 - diff --git a/virtio_blk-Add-support-for-retry-on-errors.patch b/virtio_blk-Add-support-for-retry-on-errors.patch deleted file mode 100644 index 1d7bd03846fe489f9aab23e1931f9d9f286e51fb..0000000000000000000000000000000000000000 --- a/virtio_blk-Add-support-for-retry-on-errors.patch +++ /dev/null @@ -1,90 +0,0 @@ -From a81122e37595fe1cc9eaa2adbbfccbfdf8f988b8 Mon Sep 17 00:00:00 2001 -From: Jiahui Cen -Date: Thu, 21 Jan 2021 15:46:53 +0800 -Subject: [PATCH 7/7] virtio_blk: Add support for retry on errors - -Insert failed requests into device's list for later retry and handle -queued requests to implement retry_request_cb. - -Signed-off-by: Jiahui Cen -Signed-off-by: Ying Fang -Signed-off-by: Alex Chen ---- - hw/block/virtio-blk.c | 21 ++++++++++++++++++--- - 1 file changed, 18 insertions(+), 3 deletions(-) - -diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c -index f139cd7cc9..c8d94a3dfb 100644 ---- a/hw/block/virtio-blk.c -+++ b/hw/block/virtio-blk.c -@@ -108,6 +108,10 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error, - block_acct_failed(blk_get_stats(s->blk), &req->acct); - } - virtio_blk_free_request(req); -+ } else if (action == BLOCK_ERROR_ACTION_RETRY) { -+ req->mr_next = NULL; -+ req->next = s->rq; -+ s->rq = req; - } - - blk_error_action(s->blk, action, is_read, error); -@@ -149,6 +153,7 @@ static void virtio_blk_rw_complete(void *opaque, int ret) - } - } - -+ blk_error_retry_reset_timeout(s->blk); - virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); - block_acct_done(blk_get_stats(s->blk), &req->acct); - virtio_blk_free_request(req); -@@ -168,6 +173,7 @@ static void virtio_blk_flush_complete(void *opaque, int ret) - } - } - -+ blk_error_retry_reset_timeout(s->blk); - virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); - block_acct_done(blk_get_stats(s->blk), &req->acct); - virtio_blk_free_request(req); -@@ -190,6 +196,7 @@ static void virtio_blk_discard_write_zeroes_complete(void *opaque, int ret) - } - } - -+ blk_error_retry_reset_timeout(s->blk); - virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); - if (is_write_zeroes) { - block_acct_done(blk_get_stats(s->blk), &req->acct); -@@ -828,12 +835,12 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) - - void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh) - { -- VirtIOBlockReq *req = s->rq; -+ VirtIOBlockReq *req; - MultiReqBuffer mrb = {}; - -- s->rq = NULL; -- - aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); -+ req = s->rq; -+ s->rq = NULL; - while (req) { - VirtIOBlockReq *next = req->next; - if (virtio_blk_handle_request(req, &mrb)) { -@@ -1138,8 +1145,16 @@ static void virtio_blk_resize(void *opaque) - aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev); - } - -+static void virtio_blk_retry_request(void *opaque) -+{ -+ VirtIOBlock *s = VIRTIO_BLK(opaque); -+ -+ virtio_blk_process_queued_requests(s, false); -+} -+ - static const BlockDevOps virtio_block_ops = { - .resize_cb = virtio_blk_resize, -+ .retry_request_cb = virtio_blk_retry_request, - }; - - static void virtio_blk_device_realize(DeviceState *dev, Error **errp) --- -2.27.0 - diff --git a/virtiofsd-Drop-membership-of-all-supplementary-group.patch b/virtiofsd-Drop-membership-of-all-supplementary-group.patch deleted file mode 100644 index cedcfc2d6760981f62b55674917f05af46933be6..0000000000000000000000000000000000000000 --- a/virtiofsd-Drop-membership-of-all-supplementary-group.patch +++ /dev/null @@ -1,101 +0,0 @@ -From fa471a127c7bacd760b6dcb9d6a8434883eedf8c Mon Sep 17 00:00:00 2001 -From: Vivek Goyal -Date: Tue, 25 Jan 2022 13:51:14 -0500 -Subject: [PATCH 2/2] virtiofsd: Drop membership of all supplementary groups - (CVE-2022-0358) - -At the start, drop membership of all supplementary groups. This is -not required. - -If we have membership of "root" supplementary group and when we switch -uid/gid using setresuid/setsgid, we still retain membership of existing -supplemntary groups. And that can allow some operations which are not -normally allowed. - -For example, if root in guest creates a dir as follows. - -$ mkdir -m 03777 test_dir - -This sets SGID on dir as well as allows unprivileged users to write into -this dir. - -And now as unprivileged user open file as follows. - -$ su test -$ fd = open("test_dir/priviledge_id", O_RDWR|O_CREAT|O_EXCL, 02755); - -This will create SGID set executable in test_dir/. - -And that's a problem because now an unpriviliged user can execute it, -get egid=0 and get access to resources owned by "root" group. This is -privilege escalation. - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2044863 -Fixes: CVE-2022-0358 -Reported-by: JIETAO XIAO -Suggested-by: Miklos Szeredi -Reviewed-by: Stefan Hajnoczi -Reviewed-by: Dr. David Alan Gilbert -Signed-off-by: Vivek Goyal -Message-Id: -Signed-off-by: Dr. David Alan Gilbert - dgilbert: Fixed missing {}'s style nit ---- - tools/virtiofsd/passthrough_ll.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c -index 64b5b4fbb1..b3d0674f6d 100644 ---- a/tools/virtiofsd/passthrough_ll.c -+++ b/tools/virtiofsd/passthrough_ll.c -@@ -54,6 +54,7 @@ - #include - #include - #include -+#include - - #include "qemu/cutils.h" - #include "passthrough_helpers.h" -@@ -1161,6 +1162,30 @@ static void lo_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) - #define OURSYS_setresuid SYS_setresuid - #endif - -+static void drop_supplementary_groups(void) -+{ -+ int ret; -+ -+ ret = getgroups(0, NULL); -+ if (ret == -1) { -+ fuse_log(FUSE_LOG_ERR, "getgroups() failed with error=%d:%s\n", -+ errno, strerror(errno)); -+ exit(1); -+ } -+ -+ if (!ret) { -+ return; -+ } -+ -+ /* Drop all supplementary groups. We should not need it */ -+ ret = setgroups(0, NULL); -+ if (ret == -1) { -+ fuse_log(FUSE_LOG_ERR, "setgroups() failed with error=%d:%s\n", -+ errno, strerror(errno)); -+ exit(1); -+ } -+} -+ - /* - * Change to uid/gid of caller so that file is created with - * ownership of caller. -@@ -3926,6 +3951,8 @@ int main(int argc, char *argv[]) - - qemu_init_exec_dir(argv[0]); - -+ drop_supplementary_groups(); -+ - pthread_mutex_init(&lo.mutex, NULL); - lo.inodes = g_hash_table_new(lo_key_hash, lo_key_equal); - lo.root.fd = -1; --- -2.27.0 - diff --git a/vnc-avoid-underflow-when-accessing-user-provided-add.patch b/vnc-avoid-underflow-when-accessing-user-provided-add.patch deleted file mode 100644 index 5d6b3acd95421e603afb782424e47291197d54b6..0000000000000000000000000000000000000000 --- a/vnc-avoid-underflow-when-accessing-user-provided-add.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 3d6a5be54f59b86db1d9513cff24ca6f7d002400 Mon Sep 17 00:00:00 2001 -From: qihao -Date: Tue, 27 Jun 2023 17:39:56 +0800 -Subject: [PATCH] vnc: avoid underflow when accessing user-provided address - -cheery-pick from bfc532703f3c4f8d2744748c440ca36ce9798ccb - -If hostlen is zero, there is a possibility that addrstr[hostlen - 1] -underflows and, if a closing bracked is there, hostlen - 2 is passed -to g_strndup() on the next line. If websocket==false then -addrstr[0] would be a colon, but if websocket==true this could in -principle happen. - -Fix it by checking hostlen. - -Reported by Coverity. - -Signed-off-by: Paolo Bonzini -(cherry picked from commit 3f9c41c5df9617510d8533cf6588172efb3df34b) -Signed-off-by: Michael Tokarev -Signed-off-by: qihao_yewu ---- - ui/vnc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ui/vnc.c b/ui/vnc.c -index 91e067ba7c..f4322a9065 100644 ---- a/ui/vnc.c -+++ b/ui/vnc.c -@@ -3761,7 +3761,7 @@ static int vnc_display_get_address(const char *addrstr, - - addr->type = SOCKET_ADDRESS_TYPE_INET; - inet = &addr->u.inet; -- if (addrstr[0] == '[' && addrstr[hostlen - 1] == ']') { -+ if (hostlen && addrstr[0] == '[' && addrstr[hostlen - 1] == ']') { - inet->host = g_strndup(addrstr + 1, hostlen - 2); - } else { - inet->host = g_strndup(addrstr, hostlen); --- -2.41.0.windows.1 - diff --git a/x86-Add-AMX-CPUIDs-enumeration.patch b/x86-Add-AMX-CPUIDs-enumeration.patch deleted file mode 100644 index ef7d5efe00c7a0fd348d12a4891e4a8a97f66a55..0000000000000000000000000000000000000000 --- a/x86-Add-AMX-CPUIDs-enumeration.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 42f96b9e73ff4a23fad56bc8fefea5e477ee95b9 Mon Sep 17 00:00:00 2001 -From: Jing Liu -Date: Wed, 16 Feb 2022 22:04:31 -0800 -Subject: [PATCH 06/10] x86: Add AMX CPUIDs enumeration - -from mainline-v7.0.0-rc0 -commit f21a48171cf3fa39532fc8553fd82e81b88b6474 -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit f21a48171cf3 ("x86: Add AMX CPUIDs enumeration") - ----------------------------------------------- - -x86: Add AMX CPUIDs enumeration - -Add AMX primary feature bits XFD and AMX_TILE to -enumerate the CPU's AMX capability. Meanwhile, add -AMX TILE and TMUL CPUID leaf and subleaves which -exist when AMX TILE is present to provide the maximum -capability of TILE and TMUL. - -Signed-off-by: Jing Liu -Signed-off-by: Yang Zhong -Message-Id: <20220217060434.52460-6-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 55 ++++++++++++++++++++++++++++++++++++++++--- - target/i386/kvm/kvm.c | 4 +++- - 2 files changed, 55 insertions(+), 4 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index da81e47dc3..1bc03d3eef 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -574,6 +574,18 @@ static CPUCacheInfo legacy_l3_cache = { - #define INTEL_PT_CYCLE_BITMAP 0x1fff /* Support 0,2^(0~11) */ - #define INTEL_PT_PSB_BITMAP (0x003f << 16) /* Support 2K,4K,8K,16K,32K,64K */ - -+/* CPUID Leaf 0x1D constants: */ -+#define INTEL_AMX_TILE_MAX_SUBLEAF 0x1 -+#define INTEL_AMX_TOTAL_TILE_BYTES 0x2000 -+#define INTEL_AMX_BYTES_PER_TILE 0x400 -+#define INTEL_AMX_BYTES_PER_ROW 0x40 -+#define INTEL_AMX_TILE_MAX_NAMES 0x8 -+#define INTEL_AMX_TILE_MAX_ROWS 0x10 -+ -+/* CPUID Leaf 0x1E constants: */ -+#define INTEL_AMX_TMUL_MAX_K 0x10 -+#define INTEL_AMX_TMUL_MAX_N 0x40 -+ - void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - uint32_t vendor2, uint32_t vendor3) - { -@@ -843,8 +855,8 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - "avx512-vp2intersect", NULL, "md-clear", NULL, - NULL, NULL, "serialize", NULL, - "tsx-ldtrk", NULL, NULL /* pconfig */, NULL, -- NULL, NULL, NULL, "avx512-fp16", -- NULL, NULL, "spec-ctrl", "stibp", -+ NULL, NULL, "amx-bf16", "avx512-fp16", -+ "amx-tile", "amx-int8", "spec-ctrl", "stibp", - NULL, "arch-capabilities", "core-capability", "ssbd", - }, - .cpuid = { -@@ -909,7 +921,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - .type = CPUID_FEATURE_WORD, - .feat_names = { - "xsaveopt", "xsavec", "xgetbv1", "xsaves", -- NULL, NULL, NULL, NULL, -+ "xfd", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, -@@ -5605,6 +5617,43 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - } - break; - } -+ case 0x1D: { -+ /* AMX TILE */ -+ *eax = 0; -+ *ebx = 0; -+ *ecx = 0; -+ *edx = 0; -+ if (!(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_AMX_TILE)) { -+ break; -+ } -+ -+ if (count == 0) { -+ /* Highest numbered palette subleaf */ -+ *eax = INTEL_AMX_TILE_MAX_SUBLEAF; -+ } else if (count == 1) { -+ *eax = INTEL_AMX_TOTAL_TILE_BYTES | -+ (INTEL_AMX_BYTES_PER_TILE << 16); -+ *ebx = INTEL_AMX_BYTES_PER_ROW | (INTEL_AMX_TILE_MAX_NAMES << 16); -+ *ecx = INTEL_AMX_TILE_MAX_ROWS; -+ } -+ break; -+ } -+ case 0x1E: { -+ /* AMX TMUL */ -+ *eax = 0; -+ *ebx = 0; -+ *ecx = 0; -+ *edx = 0; -+ if (!(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_AMX_TILE)) { -+ break; -+ } -+ -+ if (count == 0) { -+ /* Highest numbered palette subleaf */ -+ *ebx = INTEL_AMX_TMUL_MAX_K | (INTEL_AMX_TMUL_MAX_N << 8); -+ } -+ break; -+ } - case 0x40000000: - /* - * CPUID code in kvm_arch_init_vcpu() ignores stuff -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index e7f57d05a2..60ccdec5e8 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -1779,7 +1779,9 @@ int kvm_arch_init_vcpu(CPUState *cs) - c = &cpuid_data.entries[cpuid_i++]; - } - break; -- case 0x14: { -+ case 0x14: -+ case 0x1d: -+ case 0x1e: { - uint32_t times; - - c->function = i; --- -2.27.0 - diff --git a/x86-Add-AMX-XTILECFG-and-XTILEDATA-components.patch b/x86-Add-AMX-XTILECFG-and-XTILEDATA-components.patch deleted file mode 100644 index d47f7361ae550ae542fbbead7cc4f2ef15483e77..0000000000000000000000000000000000000000 --- a/x86-Add-AMX-XTILECFG-and-XTILEDATA-components.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 98f5dbc3fd8390728401528786ac94b39f0581ee Mon Sep 17 00:00:00 2001 -From: Jing Liu -Date: Wed, 16 Feb 2022 22:04:28 -0800 -Subject: [PATCH 03/10] x86: Add AMX XTILECFG and XTILEDATA components - -from mainline-v7.0.0-rc0 -commit 1f16764f7d4515bfd5e4ae0aae814fa280a7d0c8 -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit 1f16764f7d45 ("x86: Add AMX XTILECFG and XTILEDATA components") - -------------------------------------------------------------- - -x86: Add AMX XTILECFG and XTILEDATA components - -The AMX TILECFG register and the TMMx tile data registers are -saved/restored via XSAVE, respectively in state component 17 -(64 bytes) and state component 18 (8192 bytes). - -Add AMX feature bits to x86_ext_save_areas array to set -up AMX components. Add structs that define the layout of -AMX XSAVE areas and use QEMU_BUILD_BUG_ON to validate the -structs sizes. - -Signed-off-by: Jing Liu -Signed-off-by: Yang Zhong -Message-Id: <20220217060434.52460-3-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 8 ++++++++ - target/i386/cpu.h | 18 +++++++++++++++++- - 2 files changed, 25 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 532ca45015..31d63be081 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1401,6 +1401,14 @@ ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT] = { - [XSTATE_PKRU_BIT] = - { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU, - .size = sizeof(XSavePKRU) }, -+ [XSTATE_XTILE_CFG_BIT] = { -+ .feature = FEAT_7_0_EDX, .bits = CPUID_7_0_EDX_AMX_TILE, -+ .size = sizeof(XSaveXTILECFG), -+ }, -+ [XSTATE_XTILE_DATA_BIT] = { -+ .feature = FEAT_7_0_EDX, .bits = CPUID_7_0_EDX_AMX_TILE, -+ .size = sizeof(XSaveXTILEDATA) -+ }, - }; - - static uint32_t xsave_area_size(uint64_t mask) -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 52330d1112..cc431b1d76 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -538,6 +538,8 @@ typedef enum X86Seg { - #define XSTATE_ZMM_Hi256_BIT 6 - #define XSTATE_Hi16_ZMM_BIT 7 - #define XSTATE_PKRU_BIT 9 -+#define XSTATE_XTILE_CFG_BIT 17 -+#define XSTATE_XTILE_DATA_BIT 18 - - #define XSTATE_FP_MASK (1ULL << XSTATE_FP_BIT) - #define XSTATE_SSE_MASK (1ULL << XSTATE_SSE_BIT) -@@ -846,6 +848,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; - #define CPUID_7_0_EDX_TSX_LDTRK (1U << 16) - /* AVX512_FP16 instruction */ - #define CPUID_7_0_EDX_AVX512_FP16 (1U << 23) -+/* AMX tile (two-dimensional register) */ -+#define CPUID_7_0_EDX_AMX_TILE (1U << 24) - /* Speculation Control */ - #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) - /* Single Thread Indirect Branch Predictors */ -@@ -1349,6 +1353,16 @@ typedef struct XSavePKRU { - uint32_t padding; - } XSavePKRU; - -+/* Ext. save area 17: AMX XTILECFG state */ -+typedef struct XSaveXTILECFG { -+ uint8_t xtilecfg[64]; -+} XSaveXTILECFG; -+ -+/* Ext. save area 18: AMX XTILEDATA state */ -+typedef struct XSaveXTILEDATA { -+ uint8_t xtiledata[8][1024]; -+} XSaveXTILEDATA; -+ - QEMU_BUILD_BUG_ON(sizeof(XSaveAVX) != 0x100); - QEMU_BUILD_BUG_ON(sizeof(XSaveBNDREG) != 0x40); - QEMU_BUILD_BUG_ON(sizeof(XSaveBNDCSR) != 0x40); -@@ -1356,6 +1370,8 @@ QEMU_BUILD_BUG_ON(sizeof(XSaveOpmask) != 0x40); - QEMU_BUILD_BUG_ON(sizeof(XSaveZMM_Hi256) != 0x200); - QEMU_BUILD_BUG_ON(sizeof(XSaveHi16_ZMM) != 0x400); - QEMU_BUILD_BUG_ON(sizeof(XSavePKRU) != 0x8); -+QEMU_BUILD_BUG_ON(sizeof(XSaveXTILECFG) != 0x40); -+QEMU_BUILD_BUG_ON(sizeof(XSaveXTILEDATA) != 0x2000); - - typedef struct ExtSaveArea { - uint32_t feature, bits; -@@ -1363,7 +1379,7 @@ typedef struct ExtSaveArea { - uint32_t ecx; - } ExtSaveArea; - --#define XSAVE_STATE_AREA_COUNT (XSTATE_PKRU_BIT + 1) -+#define XSAVE_STATE_AREA_COUNT (XSTATE_XTILE_DATA_BIT + 1) - - extern ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT]; - --- -2.27.0 - diff --git a/x86-Add-XFD-faulting-bit-for-state-components.patch b/x86-Add-XFD-faulting-bit-for-state-components.patch deleted file mode 100644 index 4b2edc2cff0a3dc03f8f32e6a415bf8b85d20e81..0000000000000000000000000000000000000000 --- a/x86-Add-XFD-faulting-bit-for-state-components.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 52eed626a2200da02e67aa93c2a8d59cb529737b Mon Sep 17 00:00:00 2001 -From: Jing Liu -Date: Wed, 16 Feb 2022 22:04:30 -0800 -Subject: [PATCH 05/10] x86: Add XFD faulting bit for state components - -from mainline-v7.0.0-rc0 -commit 0f17f6b30f3b051f0f96ccc98c9f7f395713699f -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit 0f17f6b30f3b ("x86: Add XFD faulting bit for state -components") - -------------------------------------------------- - -x86: Add XFD faulting bit for state components - -Intel introduces XFD faulting mechanism for extended -XSAVE features to dynamically enable the features in -runtime. If CPUID (EAX=0Dh, ECX=n, n>1).ECX[2] is set -as 1, it indicates support for XFD faulting of this -state component. - -Signed-off-by: Jing Liu -Signed-off-by: Yang Zhong -Message-Id: <20220217060434.52460-5-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 3 ++- - target/i386/cpu.h | 2 ++ - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index fb6b4c86de..da81e47dc3 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -5515,7 +5515,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - const ExtSaveArea *esa = &x86_ext_save_areas[count]; - *eax = esa->size; - *ebx = esa->offset; -- *ecx = esa->ecx & ESA_FEATURE_ALIGN64_MASK; -+ *ecx = esa->ecx & -+ (ESA_FEATURE_ALIGN64_MASK | ESA_FEATURE_XFD_MASK); - } - } - break; -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 93d1c60ac1..09c725ee13 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -556,8 +556,10 @@ typedef enum X86Seg { - #define XSTATE_DYNAMIC_MASK (XSTATE_XTILE_DATA_MASK) - - #define ESA_FEATURE_ALIGN64_BIT 1 -+#define ESA_FEATURE_XFD_BIT 2 - - #define ESA_FEATURE_ALIGN64_MASK (1U << ESA_FEATURE_ALIGN64_BIT) -+#define ESA_FEATURE_XFD_MASK (1U << ESA_FEATURE_XFD_BIT) - - - /* CPUID feature words */ --- -2.27.0 - diff --git a/x86-Fix-the-64-byte-boundary-enumeration-for-extende.patch b/x86-Fix-the-64-byte-boundary-enumeration-for-extende.patch deleted file mode 100644 index e0aede1951081fc75ecb3f936e2a96412c35268b..0000000000000000000000000000000000000000 --- a/x86-Fix-the-64-byte-boundary-enumeration-for-extende.patch +++ /dev/null @@ -1,91 +0,0 @@ -From ab183c656a2bee466e7c609224cddb75b80d9d6f Mon Sep 17 00:00:00 2001 -From: Jing Liu -Date: Wed, 16 Feb 2022 22:04:27 -0800 -Subject: [PATCH 02/10] x86: Fix the 64-byte boundary enumeration for extended - state - -from mainline-v7.0.0-rc0 -commit 131266b7565bd437127bd231563572696bb27235 -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit 131266b7565b ("x86: Fix the 64-byte boundary enumeration for extended state") - ------------------------------------------------------------ - -x86: Fix the 64-byte boundary enumeration for extended state - -The extended state subleaves (EAX=0Dh, ECX=n, n>1).ECX[1] -indicate whether the extended state component locates -on the next 64-byte boundary following the preceding state -component when the compacted format of an XSAVE area is -used. - -Right now, they are all zero because no supported component -needed the bit to be set, but the upcoming AMX feature will -use it. Fix the subleaves value according to KVM's supported -cpuid. - -Signed-off-by: Jing Liu -Signed-off-by: Yang Zhong -Message-Id: <20220217060434.52460-2-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 1 + - target/i386/cpu.h | 6 ++++++ - target/i386/kvm/kvm-cpu.c | 1 + - 3 files changed, 8 insertions(+) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index d9dca1dafb..532ca45015 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -5507,6 +5507,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, - const ExtSaveArea *esa = &x86_ext_save_areas[count]; - *eax = esa->size; - *ebx = esa->offset; -+ *ecx = esa->ecx & ESA_FEATURE_ALIGN64_MASK; - } - } - break; -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index d9296a9abc..52330d1112 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -549,6 +549,11 @@ typedef enum X86Seg { - #define XSTATE_Hi16_ZMM_MASK (1ULL << XSTATE_Hi16_ZMM_BIT) - #define XSTATE_PKRU_MASK (1ULL << XSTATE_PKRU_BIT) - -+#define ESA_FEATURE_ALIGN64_BIT 1 -+ -+#define ESA_FEATURE_ALIGN64_MASK (1U << ESA_FEATURE_ALIGN64_BIT) -+ -+ - /* CPUID feature words */ - typedef enum FeatureWord { - FEAT_1_EDX, /* CPUID[1].EDX */ -@@ -1355,6 +1360,7 @@ QEMU_BUILD_BUG_ON(sizeof(XSavePKRU) != 0x8); - typedef struct ExtSaveArea { - uint32_t feature, bits; - uint32_t offset, size; -+ uint32_t ecx; - } ExtSaveArea; - - #define XSAVE_STATE_AREA_COUNT (XSTATE_PKRU_BIT + 1) -diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c -index d95028018e..ce27d3b1df 100644 ---- a/target/i386/kvm/kvm-cpu.c -+++ b/target/i386/kvm/kvm-cpu.c -@@ -104,6 +104,7 @@ static void kvm_cpu_xsave_init(void) - if (sz != 0) { - assert(esa->size == sz); - esa->offset = kvm_arch_get_supported_cpuid(s, 0xd, i, R_EBX); -+ esa->ecx = kvm_arch_get_supported_cpuid(s, 0xd, i, R_ECX); - } - } - } --- -2.27.0 - diff --git a/x86-Grant-AMX-permission-for-guest.patch b/x86-Grant-AMX-permission-for-guest.patch deleted file mode 100644 index 9ecbc461e04b66c984397ccb53cb4a99200bf1df..0000000000000000000000000000000000000000 --- a/x86-Grant-AMX-permission-for-guest.patch +++ /dev/null @@ -1,218 +0,0 @@ -From b7e588a4506ce61c13e78175c2da5b69b60af128 Mon Sep 17 00:00:00 2001 -From: Yang Zhong -Date: Wed, 16 Feb 2022 22:04:29 -0800 -Subject: [PATCH 04/10] x86: Grant AMX permission for guest - -from mainline-v7.0.0-rc0 -commit 19db68ca68a78fa033a21d419036b6e416554564 -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit 19db68ca68a7 ("x86: Grant AMX permission for guest") - --------------------------------------------------------- - -x86: Grant AMX permission for guest - -Kernel allocates 4K xstate buffer by default. For XSAVE features -which require large state component (e.g. AMX), Linux kernel -dynamically expands the xstate buffer only after the process has -acquired the necessary permissions. Those are called dynamically- -enabled XSAVE features (or dynamic xfeatures). - -There are separate permissions for native tasks and guests. - -Qemu should request the guest permissions for dynamic xfeatures -which will be exposed to the guest. This only needs to be done -once before the first vcpu is created. - -KVM implemented one new ARCH_GET_XCOMP_SUPP system attribute API to -get host side supported_xcr0 and Qemu can decide if it can request -dynamically enabled XSAVE features permission. -https://lore.kernel.org/all/20220126152210.3044876-1-pbonzini@redhat.com/ - -Suggested-by: Paolo Bonzini -Signed-off-by: Yang Zhong -Signed-off-by: Jing Liu -Message-Id: <20220217060434.52460-4-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.c | 7 +++++ - target/i386/cpu.h | 4 +++ - target/i386/kvm/kvm-cpu.c | 12 ++++---- - target/i386/kvm/kvm.c | 57 ++++++++++++++++++++++++++++++++++++++ - target/i386/kvm/kvm_i386.h | 1 + - 5 files changed, 75 insertions(+), 6 deletions(-) - -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 31d63be081..fb6b4c86de 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -6048,6 +6048,7 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) - CPUX86State *env = &cpu->env; - int i; - uint64_t mask; -+ static bool request_perm; - - if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { - env->features[FEAT_XSAVE_COMP_LO] = 0; -@@ -6063,6 +6064,12 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu) - } - } - -+ /* Only request permission for first vcpu */ -+ if (kvm_enabled() && !request_perm) { -+ kvm_request_xsave_components(cpu, mask); -+ request_perm = true; -+ } -+ - env->features[FEAT_XSAVE_COMP_LO] = mask; - env->features[FEAT_XSAVE_COMP_HI] = mask >> 32; - } -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index cc431b1d76..93d1c60ac1 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -550,6 +550,10 @@ typedef enum X86Seg { - #define XSTATE_ZMM_Hi256_MASK (1ULL << XSTATE_ZMM_Hi256_BIT) - #define XSTATE_Hi16_ZMM_MASK (1ULL << XSTATE_Hi16_ZMM_BIT) - #define XSTATE_PKRU_MASK (1ULL << XSTATE_PKRU_BIT) -+#define XSTATE_XTILE_CFG_MASK (1ULL << XSTATE_XTILE_CFG_BIT) -+#define XSTATE_XTILE_DATA_MASK (1ULL << XSTATE_XTILE_DATA_BIT) -+ -+#define XSTATE_DYNAMIC_MASK (XSTATE_XTILE_DATA_MASK) - - #define ESA_FEATURE_ALIGN64_BIT 1 - -diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c -index ce27d3b1df..a35a1bf9fe 100644 ---- a/target/i386/kvm/kvm-cpu.c -+++ b/target/i386/kvm/kvm-cpu.c -@@ -84,7 +84,7 @@ static void kvm_cpu_max_instance_init(X86CPU *cpu) - static void kvm_cpu_xsave_init(void) - { - static bool first = true; -- KVMState *s = kvm_state; -+ uint32_t eax, ebx, ecx, edx; - int i; - - if (!first) { -@@ -100,11 +100,11 @@ static void kvm_cpu_xsave_init(void) - ExtSaveArea *esa = &x86_ext_save_areas[i]; - - if (esa->size) { -- int sz = kvm_arch_get_supported_cpuid(s, 0xd, i, R_EAX); -- if (sz != 0) { -- assert(esa->size == sz); -- esa->offset = kvm_arch_get_supported_cpuid(s, 0xd, i, R_EBX); -- esa->ecx = kvm_arch_get_supported_cpuid(s, 0xd, i, R_ECX); -+ host_cpuid(0xd, i, &eax, &ebx, &ecx, &edx); -+ if (eax != 0) { -+ assert(esa->size == eax); -+ esa->offset = ebx; -+ esa->ecx = ecx; - } - } - } -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 5a698bde19..e7f57d05a2 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -17,6 +17,7 @@ - #include "qapi/error.h" - #include - #include -+#include - - #include - #include "standard-headers/asm-x86/kvm_para.h" -@@ -347,6 +348,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, - struct kvm_cpuid2 *cpuid; - uint32_t ret = 0; - uint32_t cpuid_1_edx; -+ uint64_t bitmask; - - cpuid = get_supported_cpuid(s); - -@@ -404,6 +406,25 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function, - if (!has_msr_arch_capabs) { - ret &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES; - } -+ } else if (function == 0xd && index == 0 && -+ (reg == R_EAX || reg == R_EDX)) { -+ struct kvm_device_attr attr = { -+ .group = 0, -+ .attr = KVM_X86_XCOMP_GUEST_SUPP, -+ .addr = (unsigned long) &bitmask -+ }; -+ -+ bool sys_attr = kvm_check_extension(s, KVM_CAP_SYS_ATTRIBUTES); -+ if (!sys_attr) { -+ warn_report("cannot get sys attribute capabilities %d", sys_attr); -+ } -+ -+ int rc = kvm_ioctl(s, KVM_GET_DEVICE_ATTR, &attr); -+ if (rc == -1 && (errno == ENXIO || errno == EINVAL)) { -+ warn_report("KVM_GET_DEVICE_ATTR(0, KVM_X86_XCOMP_GUEST_SUPP) " -+ "error: %d", rc); -+ } -+ ret = (reg == R_EAX) ? bitmask : bitmask >> 32; - } else if (function == 0x80000001 && reg == R_ECX) { - /* - * It's safe to enable TOPOEXT even if it's not returned by -@@ -5050,3 +5071,39 @@ bool kvm_arch_cpu_check_are_resettable(void) - { - return !sev_es_enabled(); - } -+ -+#define ARCH_REQ_XCOMP_GUEST_PERM 0x1025 -+ -+void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask) -+{ -+ KVMState *s = kvm_state; -+ uint64_t supported; -+ -+ mask &= XSTATE_DYNAMIC_MASK; -+ if (!mask) { -+ return; -+ } -+ /* -+ * Just ignore bits that are not in CPUID[EAX=0xD,ECX=0]. -+ * ARCH_REQ_XCOMP_GUEST_PERM would fail, and QEMU has warned -+ * about them already because they are not supported features. -+ */ -+ supported = kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX); -+ supported |= (uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32; -+ mask &= supported; -+ -+ while (mask) { -+ int bit = ctz64(mask); -+ int rc = syscall(SYS_arch_prctl, ARCH_REQ_XCOMP_GUEST_PERM, bit); -+ if (rc) { -+ /* -+ * Older kernel version (<5.17) do not support -+ * ARCH_REQ_XCOMP_GUEST_PERM, but also do not return -+ * any dynamic feature from kvm_arch_get_supported_cpuid. -+ */ -+ warn_report("prctl(ARCH_REQ_XCOMP_GUEST_PERM) failure " -+ "for feature bit %d", bit); -+ } -+ mask &= ~BIT_ULL(bit); -+ } -+} -diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h -index a978509d50..4124912c20 100644 ---- a/target/i386/kvm/kvm_i386.h -+++ b/target/i386/kvm/kvm_i386.h -@@ -52,5 +52,6 @@ bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp); - uint64_t kvm_swizzle_msi_ext_dest_id(uint64_t address); - - bool kvm_enable_sgx_provisioning(KVMState *s); -+void kvm_request_xsave_components(X86CPU *cpu, uint64_t mask); - - #endif --- -2.27.0 - diff --git a/x86-Support-XFD-and-AMX-xsave-data-migration.patch b/x86-Support-XFD-and-AMX-xsave-data-migration.patch deleted file mode 100644 index a33ad5b67a3367562192f4f26ca472d388c32c4c..0000000000000000000000000000000000000000 --- a/x86-Support-XFD-and-AMX-xsave-data-migration.patch +++ /dev/null @@ -1,182 +0,0 @@ -From bb1b53e5d0b67d97042ea3c33b5c4c80e33809f2 Mon Sep 17 00:00:00 2001 -From: Zeng Guang -Date: Wed, 16 Feb 2022 22:04:33 -0800 -Subject: [PATCH 08/10] x86: Support XFD and AMX xsave data migration - -from mainline-v7.0.0-rc0 -commit cdec2b753b487d9e8aab028231c35d87789ea083 -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit cdec2b753b48 ("x86: Support XFD and AMX xsave data -migration") - ------------------------------------------------- - -x86: Support XFD and AMX xsave data migration - -XFD(eXtended Feature Disable) allows to enable a -feature on xsave state while preventing specific -user threads from using the feature. - -Support save and restore XFD MSRs if CPUID.D.1.EAX[4] -enumerate to be valid. Likewise migrate the MSRs and -related xsave state necessarily. - -Signed-off-by: Zeng Guang -Signed-off-by: Wei Wang -Signed-off-by: Yang Zhong -Message-Id: <20220217060434.52460-8-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.h | 9 +++++++++ - target/i386/kvm/kvm.c | 18 +++++++++++++++++ - target/i386/machine.c | 46 +++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 73 insertions(+) - -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 74e66c352c..eaa99c302f 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -506,6 +506,9 @@ typedef enum X86Seg { - - #define MSR_VM_HSAVE_PA 0xc0010117 - -+#define MSR_IA32_XFD 0x000001c4 -+#define MSR_IA32_XFD_ERR 0x000001c5 -+ - #define MSR_IA32_BNDCFGS 0x00000d90 - #define MSR_IA32_XSS 0x00000da0 - #define MSR_IA32_UMWAIT_CONTROL 0xe1 -@@ -871,6 +874,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; - #define CPUID_7_1_EAX_AVX_VNNI (1U << 4) - /* AVX512 BFloat16 Instruction */ - #define CPUID_7_1_EAX_AVX512_BF16 (1U << 5) -+/* XFD Extend Feature Disabled */ -+#define CPUID_D_1_EAX_XFD (1U << 4) - - /* Packets which contain IP payload have LIP values */ - #define CPUID_14_0_ECX_LIP (1U << 31) -@@ -1612,6 +1617,10 @@ typedef struct CPUX86State { - uint64_t msr_rtit_cr3_match; - uint64_t msr_rtit_addrs[MAX_RTIT_ADDRS]; - -+ /* Per-VCPU XFD MSRs */ -+ uint64_t msr_xfd; -+ uint64_t msr_xfd_err; -+ - /* exception/interrupt handling */ - int error_code; - int exception_is_int; -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index b0b22dcf7c..49fca5ea88 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -3219,6 +3219,13 @@ static int kvm_put_msrs(X86CPU *cpu, int level) - env->msr_ia32_sgxlepubkeyhash[3]); - } - -+ if (env->features[FEAT_XSAVE] & CPUID_D_1_EAX_XFD) { -+ kvm_msr_entry_add(cpu, MSR_IA32_XFD, -+ env->msr_xfd); -+ kvm_msr_entry_add(cpu, MSR_IA32_XFD_ERR, -+ env->msr_xfd_err); -+ } -+ - /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see - * kvm_put_msr_feature_control. */ - } -@@ -3570,6 +3577,11 @@ static int kvm_get_msrs(X86CPU *cpu) - kvm_msr_entry_add(cpu, MSR_IA32_SGXLEPUBKEYHASH3, 0); - } - -+ if (env->features[FEAT_XSAVE] & CPUID_D_1_EAX_XFD) { -+ kvm_msr_entry_add(cpu, MSR_IA32_XFD, 0); -+ kvm_msr_entry_add(cpu, MSR_IA32_XFD_ERR, 0); -+ } -+ - ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf); - if (ret < 0) { - return ret; -@@ -3866,6 +3878,12 @@ static int kvm_get_msrs(X86CPU *cpu) - env->msr_ia32_sgxlepubkeyhash[index - MSR_IA32_SGXLEPUBKEYHASH0] = - msrs[i].data; - break; -+ case MSR_IA32_XFD: -+ env->msr_xfd = msrs[i].data; -+ break; -+ case MSR_IA32_XFD_ERR: -+ env->msr_xfd_err = msrs[i].data; -+ break; - } - } - -diff --git a/target/i386/machine.c b/target/i386/machine.c -index 83c2b91529..3977e9d8f8 100644 ---- a/target/i386/machine.c -+++ b/target/i386/machine.c -@@ -1455,6 +1455,48 @@ static const VMStateDescription vmstate_msr_intel_sgx = { - } - }; - -+static bool xfd_msrs_needed(void *opaque) -+{ -+ X86CPU *cpu = opaque; -+ CPUX86State *env = &cpu->env; -+ -+ return !!(env->features[FEAT_XSAVE] & CPUID_D_1_EAX_XFD); -+} -+ -+static const VMStateDescription vmstate_msr_xfd = { -+ .name = "cpu/msr_xfd", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .needed = xfd_msrs_needed, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT64(env.msr_xfd, X86CPU), -+ VMSTATE_UINT64(env.msr_xfd_err, X86CPU), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ -+#ifdef TARGET_X86_64 -+static bool amx_xtile_needed(void *opaque) -+{ -+ X86CPU *cpu = opaque; -+ CPUX86State *env = &cpu->env; -+ -+ return !!(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_AMX_TILE); -+} -+ -+static const VMStateDescription vmstate_amx_xtile = { -+ .name = "cpu/intel_amx_xtile", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .needed = amx_xtile_needed, -+ .fields = (VMStateField[]) { -+ VMSTATE_UINT8_ARRAY(env.xtilecfg, X86CPU, 64), -+ VMSTATE_UINT8_ARRAY(env.xtiledata, X86CPU, 8192), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+#endif -+ - const VMStateDescription vmstate_x86_cpu = { - .name = "cpu", - .version_id = 12, -@@ -1593,6 +1635,10 @@ const VMStateDescription vmstate_x86_cpu = { - #endif - &vmstate_msr_tsx_ctrl, - &vmstate_msr_intel_sgx, -+ &vmstate_msr_xfd, -+#ifdef TARGET_X86_64 -+ &vmstate_amx_xtile, -+#endif - NULL - } - }; --- -2.27.0 - diff --git a/x86-add-support-for-KVM_CAP_XSAVE2-and-AMX-state-mig.patch b/x86-add-support-for-KVM_CAP_XSAVE2-and-AMX-state-mig.patch deleted file mode 100644 index 7331af7c22560f5a921ee4b72ccd423a16b1773c..0000000000000000000000000000000000000000 --- a/x86-add-support-for-KVM_CAP_XSAVE2-and-AMX-state-mig.patch +++ /dev/null @@ -1,186 +0,0 @@ -From e98958c23ea5b15a8e84642c373336a8898cd63f Mon Sep 17 00:00:00 2001 -From: Jing Liu -Date: Wed, 16 Feb 2022 22:04:32 -0800 -Subject: [PATCH 07/10] x86: add support for KVM_CAP_XSAVE2 and AMX state - migration - -from mainline-v7.0.0-rc0 -commit e56dd3c70abb31893c61ac834109fa7a38841330 -category: feature -feature: SPR AMX support for Qemu -bugzilla: https://gitee.com/openeuler/intel-qemu/issues/I5VHOB - -Intel-SIG: commit e56dd3c70abb ("x86: add support for KVM_CAP_XSAVE2 and -AMX state migration") - -------------------------------------------------------- - -x86: add support for KVM_CAP_XSAVE2 and AMX state migration - -When dynamic xfeatures (e.g. AMX) are used by the guest, the xsave -area would be larger than 4KB. KVM_GET_XSAVE2 and KVM_SET_XSAVE -under KVM_CAP_XSAVE2 works with a xsave buffer larger than 4KB. -Always use the new ioctls under KVM_CAP_XSAVE2 when KVM supports it. - -Signed-off-by: Jing Liu -Signed-off-by: Zeng Guang -Signed-off-by: Wei Wang -Signed-off-by: Yang Zhong -Message-Id: <20220217060434.52460-7-yang.zhong@intel.com> -Signed-off-by: Paolo Bonzini -Signed-off-by: Jason Zeng ---- - target/i386/cpu.h | 4 ++++ - target/i386/kvm/kvm.c | 42 ++++++++++++++++++++++++-------------- - target/i386/xsave_helper.c | 28 +++++++++++++++++++++++++ - 3 files changed, 59 insertions(+), 15 deletions(-) - -diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 09c725ee13..74e66c352c 100644 ---- a/target/i386/cpu.h -+++ b/target/i386/cpu.h -@@ -1523,6 +1523,10 @@ typedef struct CPUX86State { - uint64_t opmask_regs[NB_OPMASK_REGS]; - YMMReg zmmh_regs[CPU_NB_REGS]; - ZMMReg hi16_zmm_regs[CPU_NB_REGS]; -+#ifdef TARGET_X86_64 -+ uint8_t xtilecfg[64]; -+ uint8_t xtiledata[8192]; -+#endif - - /* sysenter registers */ - uint32_t sysenter_cs; -diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c -index 60ccdec5e8..b0b22dcf7c 100644 ---- a/target/i386/kvm/kvm.c -+++ b/target/i386/kvm/kvm.c -@@ -123,6 +123,7 @@ static uint32_t num_architectural_pmu_gp_counters; - static uint32_t num_architectural_pmu_fixed_counters; - - static int has_xsave; -+static int has_xsave2; - static int has_xcrs; - static int has_pit_state2; - static int has_exception_payload; -@@ -1585,6 +1586,26 @@ static Error *invtsc_mig_blocker; - - #define KVM_MAX_CPUID_ENTRIES 100 - -+static void kvm_init_xsave(CPUX86State *env) -+{ -+ if (has_xsave2) { -+ env->xsave_buf_len = QEMU_ALIGN_UP(has_xsave2, 4096); -+ } else if (has_xsave) { -+ env->xsave_buf_len = sizeof(struct kvm_xsave); -+ } else { -+ return; -+ } -+ -+ env->xsave_buf = qemu_memalign(4096, env->xsave_buf_len); -+ memset(env->xsave_buf, 0, env->xsave_buf_len); -+ /* -+ * The allocated storage must be large enough for all of the -+ * possible XSAVE state components. -+ */ -+ assert(kvm_arch_get_supported_cpuid(kvm_state, 0xd, 0, R_ECX) <= -+ env->xsave_buf_len); -+} -+ - int kvm_arch_init_vcpu(CPUState *cs) - { - struct { -@@ -1614,6 +1635,8 @@ int kvm_arch_init_vcpu(CPUState *cs) - - cpuid_i = 0; - -+ has_xsave2 = kvm_check_extension(cs->kvm_state, KVM_CAP_XSAVE2); -+ - r = kvm_arch_set_tsc_khz(cs); - if (r < 0) { - return r; -@@ -2003,19 +2026,7 @@ int kvm_arch_init_vcpu(CPUState *cs) - if (r) { - goto fail; - } -- -- if (has_xsave) { -- env->xsave_buf_len = sizeof(struct kvm_xsave); -- env->xsave_buf = qemu_memalign(4096, env->xsave_buf_len); -- memset(env->xsave_buf, 0, env->xsave_buf_len); -- -- /* -- * The allocated storage must be large enough for all of the -- * possible XSAVE state components. -- */ -- assert(kvm_arch_get_supported_cpuid(kvm_state, 0xd, 0, R_ECX) -- <= env->xsave_buf_len); -- } -+ kvm_init_xsave(env); - - max_nested_state_len = kvm_max_nested_state_length(); - if (max_nested_state_len > 0) { -@@ -3263,13 +3274,14 @@ static int kvm_get_xsave(X86CPU *cpu) - { - CPUX86State *env = &cpu->env; - void *xsave = env->xsave_buf; -- int ret; -+ int type, ret; - - if (!has_xsave) { - return kvm_get_fpu(cpu); - } - -- ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_XSAVE, xsave); -+ type = has_xsave2 ? KVM_GET_XSAVE2 : KVM_GET_XSAVE; -+ ret = kvm_vcpu_ioctl(CPU(cpu), type, xsave); - if (ret < 0) { - return ret; - } -diff --git a/target/i386/xsave_helper.c b/target/i386/xsave_helper.c -index ac61a96344..996e9f3bfe 100644 ---- a/target/i386/xsave_helper.c -+++ b/target/i386/xsave_helper.c -@@ -126,6 +126,20 @@ void x86_cpu_xsave_all_areas(X86CPU *cpu, void *buf, uint32_t buflen) - - memcpy(pkru, &env->pkru, sizeof(env->pkru)); - } -+ -+ e = &x86_ext_save_areas[XSTATE_XTILE_CFG_BIT]; -+ if (e->size && e->offset) { -+ XSaveXTILECFG *tilecfg = buf + e->offset; -+ -+ memcpy(tilecfg, &env->xtilecfg, sizeof(env->xtilecfg)); -+ } -+ -+ e = &x86_ext_save_areas[XSTATE_XTILE_DATA_BIT]; -+ if (e->size && e->offset && buflen >= e->size + e->offset) { -+ XSaveXTILEDATA *tiledata = buf + e->offset; -+ -+ memcpy(tiledata, &env->xtiledata, sizeof(env->xtiledata)); -+ } - #endif - } - -@@ -247,5 +261,19 @@ void x86_cpu_xrstor_all_areas(X86CPU *cpu, const void *buf, uint32_t buflen) - pkru = buf + e->offset; - memcpy(&env->pkru, pkru, sizeof(env->pkru)); - } -+ -+ e = &x86_ext_save_areas[XSTATE_XTILE_CFG_BIT]; -+ if (e->size && e->offset) { -+ const XSaveXTILECFG *tilecfg = buf + e->offset; -+ -+ memcpy(&env->xtilecfg, tilecfg, sizeof(env->xtilecfg)); -+ } -+ -+ e = &x86_ext_save_areas[XSTATE_XTILE_DATA_BIT]; -+ if (e->size && e->offset && buflen >= e->size + e->offset) { -+ const XSaveXTILEDATA *tiledata = buf + e->offset; -+ -+ memcpy(&env->xtiledata, tiledata, sizeof(env->xtiledata)); -+ } - #endif - } --- -2.27.0 - diff --git a/xen-block-Avoid-leaks-on-new-error-path.patch b/xen-block-Avoid-leaks-on-new-error-path.patch deleted file mode 100644 index ef430bc44d9319bc08e97c4aa43255268ce6e80d..0000000000000000000000000000000000000000 --- a/xen-block-Avoid-leaks-on-new-error-path.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 67577f8a8310b1233bddfdaa1099bf6371b79d51 Mon Sep 17 00:00:00 2001 -From: tangzhongrui -Date: Thu, 3 Aug 2023 11:01:42 +0800 -Subject: [PATCH] xen-block: Avoid leaks on new error path - -Commit 189829399070 ("xen-block: Use specific blockdev driver") -introduced a new error path, without taking care of allocated -resources. - -So only allocate the qdicts after the error check, and free both -`filename` and `driver` when we are about to return and thus taking -care of both success and error path. - -Coverity only spotted the leak of qdicts (*_layer variables). - -Reported-by: Peter Maydell -Fixes: Coverity CID 1508722, 1398649 -Fixes: 189829399070 ("xen-block: Use specific blockdev driver") -Signed-off-by: Anthony PERARD -Reviewed-by: Paul Durrant -Reviewed-by: Peter Maydell -Message-Id: <20230704171819.42564-1-anthony.perard@citrix.com> -Signed-off-by: Anthony PERARD - -Signed-off-by: Zhongrui Tang ---- - hw/block/xen-block.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c -index 674953f1ad..6d90621e02 100644 ---- a/hw/block/xen-block.c -+++ b/hw/block/xen-block.c -@@ -760,14 +760,15 @@ static XenBlockDrive *xen_block_drive_create(const char *id, - drive = g_new0(XenBlockDrive, 1); - drive->id = g_strdup(id); - -- file_layer = qdict_new(); -- driver_layer = qdict_new(); -- - rc = stat(filename, &st); - if (rc) { - error_setg_errno(errp, errno, "Could not stat file '%s'", filename); - goto done; - } -+ -+ file_layer = qdict_new(); -+ driver_layer = qdict_new(); -+ - if (S_ISBLK(st.st_mode)) { - qdict_put_str(file_layer, "driver", "host_device"); - } else { -@@ -775,7 +776,6 @@ static XenBlockDrive *xen_block_drive_create(const char *id, - } - - qdict_put_str(file_layer, "filename", filename); -- g_free(filename); - - if (mode && *mode != 'w') { - qdict_put_bool(file_layer, "read-only", true); -@@ -810,7 +810,6 @@ static XenBlockDrive *xen_block_drive_create(const char *id, - qdict_put_str(file_layer, "locking", "off"); - - qdict_put_str(driver_layer, "driver", driver); -- g_free(driver); - - qdict_put(driver_layer, "file", file_layer); - -@@ -821,6 +820,8 @@ static XenBlockDrive *xen_block_drive_create(const char *id, - qobject_unref(driver_layer); - - done: -+ g_free(filename); -+ g_free(driver); - if (*errp) { - xen_block_drive_destroy(drive, NULL); - return NULL; --- -2.41.0.windows.1 - diff --git a/xen-pass-through-don-t-create-needless-register-grou.patch b/xen-pass-through-don-t-create-needless-register-grou.patch deleted file mode 100644 index 0c45f2be52dd8620f387617e0dd7a99fa55dac5d..0000000000000000000000000000000000000000 --- a/xen-pass-through-don-t-create-needless-register-grou.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 125b3c3ef9db4cda5e6f08d2f1f5b3d1fe853ef7 Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 24 Nov 2023 08:33:13 +0000 -Subject: [PATCH] xen/pass-through: don't create needless register group - mainline inclusion commit c0e86b7624cb9d6db03e0d48cf82659e5b89a6a6 category: - bugfix - ---------------------------------------------------------------- - -Currently we are creating a register group for the Intel IGD OpRegion -for every device we pass through, but the XEN_PCI_INTEL_OPREGION -register group is only valid for an Intel IGD. Add a check to make -sure the device is an Intel IGD and a check that the administrator has -enabled gfx_passthru in the xl domain configuration. Require both checks -to be true before creating the register group. Use the existing -is_igd_vga_passthrough() function to check for a graphics device from -any vendor and that the administrator enabled gfx_passthru in the xl -domain configuration, but further require that the vendor be Intel, -because only Intel IGD devices have an Intel OpRegion. These are the -same checks hvmloader and libxl do to determine if the Intel OpRegion -needs to be mapped into the guest's memory. Also, move the comment -about trapping 0xfc for the Intel OpRegion where it belongs after -applying this patch. - -Signed-off-by: Chuck Zmudzinski -Reviewed-by: Anthony PERARD -Message-Id: -Signed-off-by: Anthony PERARD - -Signed-off-by: tangbinzy ---- - hw/xen/xen_pt_config_init.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c -index e7bcbe4c4f..b9833d2fa7 100644 ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -2031,12 +2031,16 @@ void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp) - } - } - -- /* -- * By default we will trap up to 0x40 in the cfg space. -- * If an intel device is pass through we need to trap 0xfc, -- * therefore the size should be 0xff. -- */ - if (xen_pt_emu_reg_grps[i].grp_id == XEN_PCI_INTEL_OPREGION) { -+ if (!is_igd_vga_passthrough(&s->real_device) || -+ s->real_device.vendor_id != PCI_VENDOR_ID_INTEL) { -+ continue; -+ } -+ /* -+ * By default we will trap up to 0x40 in the cfg space. -+ * If an intel device is pass through we need to trap 0xfc, -+ * therefore the size should be 0xff. -+ */ - reg_grp_offset = XEN_PCI_INTEL_OPREGION; - } - --- -2.27.0 - diff --git a/xen-pass-through-merge-emulated-bits-correctly.patch b/xen-pass-through-merge-emulated-bits-correctly.patch deleted file mode 100644 index e4bc9c4a56def04713a93624c2c4c6852449bf85..0000000000000000000000000000000000000000 --- a/xen-pass-through-merge-emulated-bits-correctly.patch +++ /dev/null @@ -1,67 +0,0 @@ -From feec0d41c0737ce46860fd7b34324d41498fdb9d Mon Sep 17 00:00:00 2001 -From: tangbinzy -Date: Fri, 24 Nov 2023 08:20:17 +0000 -Subject: [PATCH] xen/pass-through: merge emulated bits correctly mainline - inclusion commit be9c61da9fc57eb7d293f380d0805ca6f46c2657 category: bugfix - ---------------------------------------------------------------- - -In xen_pt_config_reg_init(), there is an error in the merging of the -emulated data with the host value. With the current Qemu, instead of -merging the emulated bits with the host bits as defined by emu_mask, -the emulated bits are merged with the host bits as defined by the -inverse of emu_mask. In some cases, depending on the data in the -registers on the host, the way the registers are setup, and the -initial values of the emulated bits, the end result will be that -the register is initialized with the wrong value. - -To correct this error, use the XEN_PT_MERGE_VALUE macro to help ensure -the merge is done correctly. - -This correction is needed to resolve Qemu project issue #1061, which -describes the failure of Xen HVM Linux guests to boot in certain -configurations with passed through PCI devices, that is, when this error -disables instead of enables the PCI_STATUS_CAP_LIST bit of the -PCI_STATUS register of a passed through PCI device, which in turn -disables the MSI-X capability of the device in Linux guests with the end -result being that the Linux guest never completes the boot process. - -Fixes: 2e87512eccf3 ("xen/pt: Sync up the dev.config and data values") -Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1061 -Buglink: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988333 - -Signed-off-by: Chuck Zmudzinski -Reviewed-by: Anthony PERARD -Message-Id: -Signed-off-by: Anthony PERARD - -Signed-off-by: tangbinzy ---- - hw/xen/xen_pt_config_init.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c -index e7bcbe4c4f..d04c12ce3d 100644 ---- a/hw/xen/xen_pt_config_init.c -+++ b/hw/xen/xen_pt_config_init.c -@@ -1965,11 +1965,12 @@ static void xen_pt_config_reg_init(XenPCIPassthroughState *s, - - if ((data & host_mask) != (val & host_mask)) { - uint32_t new_val; -- -- /* Mask out host (including past size). */ -- new_val = val & host_mask; -- /* Merge emulated ones (excluding the non-emulated ones). */ -- new_val |= data & host_mask; -+ /* -+ * Merge the emulated bits (data) with the host bits (val) -+ * and mask out the bits past size to enable restoration -+ * of the proper value for logging below. -+ */ -+ new_val = XEN_PT_MERGE_VALUE(val, data, host_mask) & size_mask; - /* Leave intact host and emulated values past the size - even though - * we do not care as we write per reg->size granularity, but for the - * logging below lets have the proper value. */ --- -2.27.0 - diff --git a/xhci-check-reg-to-avoid-OOB-read.patch b/xhci-check-reg-to-avoid-OOB-read.patch deleted file mode 100644 index f6a4c356578e4f686ad8cb0dbbcdd24e6cd8b816..0000000000000000000000000000000000000000 --- a/xhci-check-reg-to-avoid-OOB-read.patch +++ /dev/null @@ -1,47 +0,0 @@ -From a95ada20170af0a71529c1583846e402cdbb850b Mon Sep 17 00:00:00 2001 -From: Yan Wang -Date: Thu, 10 Feb 2022 10:41:40 +0800 -Subject: [PATCH] xhci: check reg to avoid OOB read - -Add a sanity check to fix OOB read access. - -Signed-off-by: Yan Wang ---- - hw/usb/hcd-xhci.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index e01700039b..08cd63e159 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -27,6 +27,7 @@ - #include "hw/qdev-properties.h" - #include "trace.h" - #include "qapi/error.h" -+#include "qemu/log.h" - - #include "hcd-xhci.h" - -@@ -3017,14 +3018,17 @@ static void xhci_runtime_write(void *ptr, hwaddr reg, - XHCIInterrupter *intr; - int v; - -- trace_usb_xhci_runtime_write(reg, val); -- - if (reg < 0x20) { - trace_usb_xhci_unimplemented("runtime write", reg); - return; - } - v = (reg - 0x20) / 0x20; -+ if (v >= xhci->numintrs) { -+ qemu_log("intr nr out of range (%d >= %d)\n", v, xhci->numintrs); -+ return; -+ } - intr = &xhci->intr[v]; -+ trace_usb_xhci_runtime_write(reg, val); - - switch (reg & 0x1f) { - case 0x00: /* IMAN */ --- -2.27.0 -