Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
Fix race condition that can cause a crash at startup.
# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmQsVJoUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroPnWgf/SRc2eAtWtLDkIhjszkfK8TVeQzzS
# wD0pobk/8MNyj+EW/wV+/HsR3U8oNvHsAnzB4+RKd7YGhPxHwDvqC+hNm5HS8u4g
# gY+LhvwirFB7RkP0dDd4yt1BX6emylyFjUpM+QxlrwuorQ5wfRaIh77ex349rnq8
# fp8Kw53VpBWscyp3S3AYlQMRN3NGPH9JdeDtWap0AHFGA+PeBR2VCOuJ3xUJF62T
# xyacGGe3JXNUcFJVKR8PMDBO1FeJgl4Y7k0idHK/mcpOPj6HYFN3EV863XdP8Foa
# mv9h2DXRuIpFJEj//0GQAVDw+F8BFofjZaPeRNAoX+oE3I4CnZhVC5uG/w==
# =Ttdf
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 04 Apr 2023 17:47:22 BST
# gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg: issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
kvm: dirty-ring: Fix race with vcpu creation
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 0000000..93718ef
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,21 @@
+#
+# List of code-formatting clean ups the git blame can ignore
+#
+# git blame --ignore-revs-file .git-blame-ignore-revs
+#
+# or
+#
+# git config blame.ignoreRevsFile .git-blame-ignore-revs
+#
+
+# gdbstub: clean-up indents
+ad9e4585b3c7425759d3eea697afbca71d2c2082
+
+# e1000e: fix code style
+0eadd56bf53ab196a16d492d7dd31c62e1c24c32
+
+# target/riscv: coding style fixes
+8c7feddddd9218b407792120bcfda0347ed16205
+
+# replace TABs with spaces
+48805df9c22a0700fba4b3b548fafaa21726ca68
diff --git a/.gitlab-ci.d/base.yml b/.gitlab-ci.d/base.yml
index 0274228..2fbb58d 100644
--- a/.gitlab-ci.d/base.yml
+++ b/.gitlab-ci.d/base.yml
@@ -75,5 +75,5 @@
- if: '$QEMU_CI != "2" && $CI_PROJECT_NAMESPACE != "qemu-project"'
when: manual
- # Jobs can run if any jobs they depend on were successfull
+ # Jobs can run if any jobs they depend on were successful
- when: on_success
diff --git a/MAINTAINERS b/MAINTAINERS
index ef45b5e..2c2068e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -64,6 +64,20 @@
F: *
F: */
+Project policy and developer guides
+R: Alex Bennée <alex.bennee@linaro.org>
+R: Daniel P. Berrangé <berrange@redhat.com>
+R: Thomas Huth <thuth@redhat.com>
+R: Markus Armbruster <armbru@redhat.com>
+R: Philippe Mathieu-Daudé <philmd@linaro.org>
+W: https://www.qemu.org/docs/master/devel/index.html
+S: Odd Fixes
+F: docs/devel/style.rst
+F: docs/devel/code-of-conduct.rst
+F: docs/devel/conflict-resolution.rst
+F: docs/devel/submitting-a-patch.rst
+F: docs/devel/submitting-a-pull-request.rst
+
Responsible Disclosure, Reporting Security Issues
-------------------------------------------------
W: https://wiki.qemu.org/SecurityProcess
@@ -2119,7 +2133,6 @@
L: qemu-s390x@nongnu.org
virtiofs
-M: Dr. David Alan Gilbert <dgilbert@redhat.com>
M: Stefan Hajnoczi <stefanha@redhat.com>
S: Supported
F: hw/virtio/vhost-user-fs*
@@ -2863,7 +2876,7 @@
F: util/rcu.c
Human Monitor (HMP)
-M: Dr. David Alan Gilbert <dgilbert@redhat.com>
+M: Dr. David Alan Gilbert <dave@treblig.org>
S: Maintained
F: monitor/monitor-internal.h
F: monitor/misc.c
@@ -3136,7 +3149,6 @@
Migration
M: Juan Quintela <quintela@redhat.com>
-M: Dr. David Alan Gilbert <dgilbert@redhat.com>
S: Maintained
F: hw/core/vmstate-if.c
F: include/hw/vmstate-if.h
@@ -3908,3 +3920,8 @@
M: Ahmed Karaman <ahmedkhaledkaraman@gmail.com>
S: Maintained
F: scripts/performance/
+
+Code Coverage Tools
+M: Alex Bennée <alex.bennee@linaro.org>
+S: Odd Fixes
+F: scripts/coverage/
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index c815f2d..8370c92 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -257,7 +257,7 @@
if (cflags & CF_PCREL) {
/* Use acquire to ensure current load of pc from jc. */
- tb = qatomic_load_acquire(&jc->array[hash].tb);
+ tb = qatomic_load_acquire(&jc->array[hash].tb);
if (likely(tb &&
jc->array[hash].pc == pc &&
@@ -272,7 +272,7 @@
return NULL;
}
jc->array[hash].pc = pc;
- /* Use store_release on tb to ensure pc is written first. */
+ /* Ensure pc is written first. */
qatomic_store_release(&jc->array[hash].tb, tb);
} else {
/* Use rcu_read to ensure current load of pc from *tb. */
@@ -971,18 +971,27 @@
tb = tb_lookup(cpu, pc, cs_base, flags, cflags);
if (tb == NULL) {
+ CPUJumpCache *jc;
uint32_t h;
mmap_lock();
tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
mmap_unlock();
+
/*
* We add the TB in the virtual pc hash table
* for the fast lookup
*/
h = tb_jmp_cache_hash_func(pc);
- /* Use the pc value already stored in tb->pc. */
- qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
+ jc = cpu->tb_jmp_cache;
+ if (cflags & CF_PCREL) {
+ jc->array[h].pc = pc;
+ /* Ensure pc is written first. */
+ qatomic_store_release(&jc->array[h].tb, tb);
+ } else {
+ /* Use the pc value already stored in tb->pc. */
+ qatomic_set(&jc->array[h].tb, tb);
+ }
}
#ifndef CONFIG_USER_ONLY
diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
index af35e0d..58c8e64 100644
--- a/accel/tcg/tcg-accel-ops.c
+++ b/accel/tcg/tcg-accel-ops.c
@@ -59,7 +59,7 @@
cflags |= parallel ? CF_PARALLEL : 0;
cflags |= icount_enabled() ? CF_USE_ICOUNT : 0;
- cpu->tcg_cflags = cflags;
+ cpu->tcg_cflags |= cflags;
}
void tcg_cpus_destroy(CPUState *cpu)
diff --git a/block/dmg-lzfse.c b/block/dmg-lzfse.c
index 6798cf4..4ea0b9b 100644
--- a/block/dmg-lzfse.c
+++ b/block/dmg-lzfse.c
@@ -23,7 +23,12 @@
*/
#include "qemu/osdep.h"
#include "dmg.h"
+
+/* Work around a -Wstrict-prototypes warning in LZFSE headers */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-prototypes"
#include <lzfse.h>
+#pragma GCC diagnostic pop
static int dmg_uncompress_lzfse_do(char *next_in, unsigned int avail_in,
char *next_out, unsigned int avail_out)
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
index 2a66371..0760d78 100644
--- a/gdbstub/gdbstub.c
+++ b/gdbstub/gdbstub.c
@@ -1468,7 +1468,7 @@
";ReverseStep+;ReverseContinue+");
}
-#ifdef CONFIG_USER_ONLY
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX)
if (gdbserver_state.c_cpu->opaque) {
g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
}
diff --git a/gdbstub/meson.build b/gdbstub/meson.build
index bd5c5cd..cdb4d28 100644
--- a/gdbstub/meson.build
+++ b/gdbstub/meson.build
@@ -20,11 +20,13 @@
libgdb_user = static_library('gdb_user',
gdb_user_ss.sources() + genh,
name_suffix: 'fa',
- c_args: '-DCONFIG_USER_ONLY')
+ c_args: '-DCONFIG_USER_ONLY',
+ build_by_default: have_user)
libgdb_softmmu = static_library('gdb_softmmu',
gdb_softmmu_ss.sources() + genh,
- name_suffix: 'fa')
+ name_suffix: 'fa',
+ build_by_default: have_system)
gdb_user = declare_dependency(link_whole: libgdb_user)
user_ss.add(gdb_user)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 50e5141..54f6a3e 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -689,7 +689,10 @@
qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
rom_ptr_for_as(as, addr, size));
- g_free(fdt);
+ if (fdt != ms->fdt) {
+ g_free(ms->fdt);
+ ms->fdt = fdt;
+ }
return size;
diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index c3d6046..44fe4ed 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -94,6 +94,13 @@
void pmbus_send_string(PMBusDevice *pmdev, const char *data)
{
+ if (!data) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: %s: uninitialised read from 0x%02x\n",
+ __func__, DEVICE(pmdev)->canonical_path, pmdev->code);
+ return;
+ }
+
size_t len = strlen(data);
g_assert(len > 0);
g_assert(len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN);
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index b702c3f..f4bf14c 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -399,7 +399,7 @@
static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
{
- return addr & 0x1fffffffll;
+ return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
}
static int64_t load_kernel_info(void)
diff --git a/hw/pci-host/gt64120.c b/hw/pci-host/gt64120.c
index f226d03..82c15ed 100644
--- a/hw/pci-host/gt64120.c
+++ b/hw/pci-host/gt64120.c
@@ -321,9 +321,6 @@
static void gt64120_update_pci_cfgdata_mapping(GT64120State *s)
{
/* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 */
- static const MemoryRegionOps *pci_host_conf_ops[] = {
- &pci_host_conf_be_ops, &pci_host_conf_le_ops
- };
static const MemoryRegionOps *pci_host_data_ops[] = {
&pci_host_data_be_ops, &pci_host_data_le_ops
};
@@ -339,15 +336,6 @@
* - Table 16: 32-bit PCI Transaction Endianess
* - Table 158: PCI_0 Command, Offset: 0xc00
*/
- if (memory_region_is_mapped(&phb->conf_mem)) {
- memory_region_del_subregion(&s->ISD_mem, &phb->conf_mem);
- object_unparent(OBJECT(&phb->conf_mem));
- }
- memory_region_init_io(&phb->conf_mem, OBJECT(phb),
- pci_host_conf_ops[s->regs[GT_PCI0_CMD] & 1],
- s, "pci-conf-idx", 4);
- memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGADDR << 2,
- &phb->conf_mem, 1);
if (memory_region_is_mapped(&phb->data_mem)) {
memory_region_del_subregion(&s->ISD_mem, &phb->data_mem);
@@ -1208,6 +1196,12 @@
PCI_DEVFN(18, 0), TYPE_PCI_BUS);
pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
+ memory_region_init_io(&phb->conf_mem, OBJECT(phb),
+ &pci_host_conf_le_ops,
+ s, "pci-conf-idx", 4);
+ memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGADDR << 2,
+ &phb->conf_mem, 1);
+
/*
* The whole address space decoded by the GT-64120A doesn't generate
diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c
index 5529276..d4de2e7 100644
--- a/hw/ssi/xilinx_spi.c
+++ b/hw/ssi/xilinx_spi.c
@@ -156,6 +156,7 @@
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);
}
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index b96b3e5..f1370a7 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -423,32 +423,12 @@
static bool init_guest_commpage(void)
{
- ARMCPU *cpu = ARM_CPU(thread_cpu);
- abi_ptr want = HI_COMMPAGE & TARGET_PAGE_MASK;
- abi_ptr addr;
+ abi_ptr commpage = HI_COMMPAGE & -qemu_host_page_size;
+ void *want = g2h_untagged(commpage);
+ void *addr = mmap(want, qemu_host_page_size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
- /*
- * M-profile allocates maximum of 2GB address space, so can never
- * allocate the commpage. Skip it.
- */
- if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
- return true;
- }
-
- /*
- * If reserved_va does not cover the commpage, we get an assert
- * in page_set_flags. Produce an intelligent error instead.
- */
- if (reserved_va != 0 && want + TARGET_PAGE_SIZE - 1 > reserved_va) {
- error_report("Allocating guest commpage: -R 0x%" PRIx64 " too small",
- (uint64_t)reserved_va + 1);
- exit(EXIT_FAILURE);
- }
-
- addr = target_mmap(want, TARGET_PAGE_SIZE, PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
-
- if (addr == -1) {
+ if (addr == MAP_FAILED) {
perror("Allocating guest commpage");
exit(EXIT_FAILURE);
}
@@ -457,12 +437,15 @@
}
/* Set kernel helper versions; rest of page is 0. */
- put_user_u32(5, 0xffff0ffcu);
+ __put_user(5, (uint32_t *)g2h_untagged(0xffff0ffcu));
- if (target_mprotect(addr, qemu_host_page_size, PROT_READ | PROT_EXEC)) {
+ if (mprotect(addr, qemu_host_page_size, PROT_READ)) {
perror("Protecting guest commpage");
exit(EXIT_FAILURE);
}
+
+ page_set_flags(commpage, commpage | ~qemu_host_page_mask,
+ PAGE_READ | PAGE_EXEC | PAGE_VALID);
return true;
}
diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h
index a98c9bd..b965e86 100644
--- a/linux-user/mips/target_elf.h
+++ b/linux-user/mips/target_elf.h
@@ -15,6 +15,9 @@
if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
return "R5900";
}
+ if (eflags & EF_MIPS_NAN2008) {
+ return "P5600";
+ }
return "24Kf";
}
#endif
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 614a1cb..cc37054 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -61,7 +61,7 @@
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) \
|| (defined(TARGET_ARM) && defined(TARGET_ABI32)) \
- || defined(TARGET_SPARC) \
+ || (defined(TARGET_SPARC) && defined(TARGET_ABI32)) \
|| defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
/* 16 bit uid wrappers emulation */
#define USE_UID16
diff --git a/nbd/server.c b/nbd/server.c
index 848836d..3d8d0d8 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -2758,6 +2758,7 @@
}
client->tlsauthz = g_strdup(tlsauthz);
client->sioc = sioc;
+ qio_channel_set_delay(QIO_CHANNEL(sioc), false);
object_ref(OBJECT(client->sioc));
client->ioc = QIO_CHANNEL(sioc);
object_ref(OBJECT(client->ioc));
diff --git a/scripts/coverage/compare_gcov_json.py b/scripts/coverage/compare_gcov_json.py
new file mode 100755
index 0000000..1b92dc2
--- /dev/null
+++ b/scripts/coverage/compare_gcov_json.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+#
+# Compare output of two gcovr JSON reports and report differences. To
+# generate the required output first:
+# - create two build dirs with --enable-gcov
+# - run set of tests in each
+# - run make coverage-html in each
+# - run gcovr --json --exclude-unreachable-branches \
+# --print-summary -o coverage.json --root ../../ . *.p
+#
+# Author: Alex Bennée <alex.bennee@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+import argparse
+import json
+import sys
+from pathlib import Path
+
+def create_parser():
+ parser = argparse.ArgumentParser(
+ prog='compare_gcov_json',
+ description='analyse the differences in coverage between two runs')
+
+ parser.add_argument('-a', type=Path, default=None,
+ help=('First file to check'))
+
+ parser.add_argument('-b', type=Path, default=None,
+ help=('Second file to check'))
+
+ parser.add_argument('--verbose', action='store_true', default=False,
+ help=('A minimal verbosity level that prints the '
+ 'overall result of the check/wait'))
+ return parser
+
+
+# See https://gcovr.com/en/stable/output/json.html#json-format-reference
+def load_json(json_file_path: Path, verbose = False) -> dict[str, set[int]]:
+
+ with open(json_file_path) as f:
+ data = json.load(f)
+
+ root_dir = json_file_path.absolute().parent
+ covered_lines = dict()
+
+ for filecov in data["files"]:
+ file_path = Path(filecov["file"])
+
+ # account for generated files - map into src tree
+ resolved_path = Path(file_path).absolute()
+ if resolved_path.is_relative_to(root_dir):
+ file_path = resolved_path.relative_to(root_dir)
+ # print(f"remapped {resolved_path} to {file_path}")
+
+ lines = filecov["lines"]
+
+ executed_lines = set(
+ linecov["line_number"]
+ for linecov in filecov["lines"]
+ if linecov["count"] != 0 and not linecov["gcovr/noncode"]
+ )
+
+ # if this file has any coverage add it to the system
+ if len(executed_lines) > 0:
+ if verbose:
+ print(f"file {file_path} {len(executed_lines)}/{len(lines)}")
+ covered_lines[str(file_path)] = executed_lines
+
+ return covered_lines
+
+def find_missing_files(first, second):
+ """
+ Return a list of files not covered in the second set
+ """
+ missing_files = []
+ for f in sorted(first):
+ file_a = first[f]
+ try:
+ file_b = second[f]
+ except KeyError:
+ missing_files.append(f)
+
+ return missing_files
+
+def main():
+ """
+ Script entry point
+ """
+ parser = create_parser()
+ args = parser.parse_args()
+
+ if not args.a or not args.b:
+ print("We need two files to compare")
+ sys.exit(1)
+
+ first_coverage = load_json(args.a, args.verbose)
+ second_coverage = load_json(args.b, args.verbose)
+
+ first_missing = find_missing_files(first_coverage,
+ second_coverage)
+
+ second_missing = find_missing_files(second_coverage,
+ first_coverage)
+
+ a_name = args.a.parent.name
+ b_name = args.b.parent.name
+
+ print(f"{b_name} missing coverage in {len(first_missing)} files")
+ for f in first_missing:
+ print(f" {f}")
+
+ print(f"{a_name} missing coverage in {len(second_missing)} files")
+ for f in second_missing:
+ print(f" {f}")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
index ec1e07f..c1f7e8c 100644
--- a/target/arm/gdbstub64.c
+++ b/target/arm/gdbstub64.c
@@ -230,8 +230,11 @@
{
bool is_data = !(reg & 1);
bool is_high = reg & 2;
- uint64_t mask = pauth_ptr_mask(env, -is_high, is_data);
- return gdb_get_reg64(buf, mask);
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
+ ARMVAParameters param;
+
+ param = aa64_va_parameters(env, -is_high, mmu_idx, is_data);
+ return gdb_get_reg64(buf, pauth_ptr_mask(param));
}
default:
return 0;
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 673519a..c2c70d5 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1391,13 +1391,18 @@
/**
* pauth_ptr_mask:
- * @env: cpu context
- * @ptr: selects between TTBR0 and TTBR1
- * @data: selects between TBI and TBID
+ * @param: parameters defining the MMU setup
*
- * Return a mask of the bits of @ptr that contain the authentication code.
+ * Return a mask of the address bits that contain the authentication code,
+ * given the MMU config defined by @param.
*/
-uint64_t pauth_ptr_mask(CPUARMState *env, uint64_t ptr, bool data);
+static inline uint64_t pauth_ptr_mask(ARMVAParameters param)
+{
+ int bot_pac_bit = 64 - param.tsz;
+ int top_pac_bit = 64 - 8 * param.tbi;
+
+ return MAKE_64BIT_MASK(bot_pac_bit, top_pac_bit - bot_pac_bit);
+}
/* Add the cpreg definitions for debug related system registers */
void define_debug_regs(ARMCPU *cpu);
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
index 20f3473..de067fa 100644
--- a/target/arm/tcg/pauth_helper.c
+++ b/target/arm/tcg/pauth_helper.c
@@ -339,17 +339,9 @@
return pac | ext | ptr;
}
-static uint64_t pauth_ptr_mask_internal(ARMVAParameters param)
-{
- int bot_pac_bit = 64 - param.tsz;
- int top_pac_bit = 64 - 8 * param.tbi;
-
- return MAKE_64BIT_MASK(bot_pac_bit, top_pac_bit - bot_pac_bit);
-}
-
static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
{
- uint64_t mask = pauth_ptr_mask_internal(param);
+ uint64_t mask = pauth_ptr_mask(param);
/* Note that bit 55 is used whether or not the regime has 2 ranges. */
if (extract64(ptr, 55, 1)) {
@@ -359,14 +351,6 @@
}
}
-uint64_t pauth_ptr_mask(CPUARMState *env, uint64_t ptr, bool data)
-{
- ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
- ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
-
- return pauth_ptr_mask_internal(param);
-}
-
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
ARMPACKey *key, bool data, int keynumber)
{
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index 2cb9368..3c8401e 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -4623,6 +4623,12 @@
tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, over.label);
gen_exception_insn(s, 0, EXCP_UDEF, syndrome);
+ /*
+ * gen_exception_insn() will set is_jmp to DISAS_NORETURN,
+ * but since we're conditionally branching over it, we want
+ * to assume continue-to-next-instruction.
+ */
+ s->base.is_jmp = DISAS_NEXT;
set_disas_label(s, over);
}
}
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index f443b58..21d8607 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -177,7 +177,7 @@
CPULoongArchState *env = cs->env_ptr;
DisasContext *ctx = container_of(dcbase, DisasContext, base);
- ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+ ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
if (!decode(ctx, ctx->opcode)) {
qemu_log_mask(LOG_UNIMP, "Error: unknown opcode. "
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
index ccc4144..694f2b9 100644
--- a/tcg/sparc64/tcg-target.c.inc
+++ b/tcg/sparc64/tcg-target.c.inc
@@ -1445,12 +1445,12 @@
{
ptrdiff_t off = tcg_tbrel_diff(s, (void *)get_jmp_target_addr(s, which));
- /* Direct branch will be patched by tb_target_set_jmp_target. */
+ /* Load link and indirect branch. */
set_jmp_insn_offset(s, which);
- tcg_out32(s, CALL);
- /* delay slot */
- tcg_debug_assert(check_fit_ptr(off, 13));
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TB, TCG_REG_TB, off);
+ tcg_out_arithi(s, TCG_REG_G0, TCG_REG_TB, 0, JMPL);
+ /* delay slot */
+ tcg_out_nop(s);
set_jmp_reset_offset(s, which);
/*
@@ -1469,28 +1469,6 @@
void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
uintptr_t jmp_rx, uintptr_t jmp_rw)
{
- uintptr_t addr = tb->jmp_target_addr[n];
- intptr_t br_disp = (intptr_t)(addr - jmp_rx) >> 2;
- tcg_insn_unit insn;
-
- br_disp >>= 2;
- if (check_fit_ptr(br_disp, 19)) {
- /* ba,pt %icc, addr */
- insn = deposit32(INSN_OP(0) | INSN_OP2(1) | INSN_COND(COND_A)
- | BPCC_ICC | BPCC_PT, 0, 19, br_disp);
- } else if (check_fit_ptr(br_disp, 22)) {
- /* ba addr */
- insn = deposit32(INSN_OP(0) | INSN_OP2(2) | INSN_COND(COND_A),
- 0, 22, br_disp);
- } else {
- /* The code_gen_buffer can't be larger than 2GB. */
- tcg_debug_assert(check_fit_ptr(br_disp, 30));
- /* call addr */
- insn = deposit32(CALL, 0, 30, br_disp);
- }
-
- qatomic_set((uint32_t *)jmp_rw, insn);
- flush_idcache_range(jmp_rx, jmp_rw, 4);
}
static void tcg_out_op(TCGContext *s, TCGOpcode opc,
diff --git a/tests/avocado/kvm_xen_guest.py b/tests/avocado/kvm_xen_guest.py
new file mode 100644
index 0000000..5391283
--- /dev/null
+++ b/tests/avocado/kvm_xen_guest.py
@@ -0,0 +1,171 @@
+# KVM Xen guest functional tests
+#
+# Copyright © 2021 Red Hat, Inc.
+# Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Author:
+# David Woodhouse <dwmw2@infradead.org>
+# Alex Bennée <alex.bennee@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+
+from qemu.machine import machine
+
+from avocado_qemu import LinuxSSHMixIn
+from avocado_qemu import QemuSystemTest
+from avocado_qemu import wait_for_console_pattern
+
+class KVMXenGuest(QemuSystemTest, LinuxSSHMixIn):
+ """
+ :avocado: tags=arch:x86_64
+ :avocado: tags=machine:q35
+ :avocado: tags=accel:kvm
+ :avocado: tags=kvm_xen_guest
+ """
+
+ KERNEL_DEFAULT = 'printk.time=0 root=/dev/xvda console=ttyS0'
+
+ kernel_path = None
+ kernel_params = None
+
+ # Fetch assets from the kvm-xen-guest subdir of my shared test
+ # images directory on fileserver.linaro.org where you can find
+ # build instructions for how they where assembled.
+ def get_asset(self, name, sha1):
+ base_url = ('https://fileserver.linaro.org/s/'
+ 'kE4nCFLdQcoBF9t/download?'
+ 'path=%2Fkvm-xen-guest&files=' )
+ url = base_url + name
+ # use explicit name rather than failing to neatly parse the
+ # URL into a unique one
+ return self.fetch_asset(name=name, locations=(url), asset_hash=sha1)
+
+ def common_vm_setup(self):
+ # We also catch lack of KVM_XEN support if we fail to launch
+ self.require_accelerator("kvm")
+
+ self.vm.set_console()
+
+ self.vm.add_args("-accel", "kvm,xen-version=0x4000a,kernel-irqchip=split")
+ self.vm.add_args("-smp", "2")
+
+ self.kernel_path = self.get_asset("bzImage",
+ "367962983d0d32109998a70b45dcee4672d0b045")
+ self.rootfs = self.get_asset("rootfs.ext4",
+ "f1478401ea4b3fa2ea196396be44315bab2bb5e4")
+
+ def run_and_check(self):
+ self.vm.add_args('-kernel', self.kernel_path,
+ '-append', self.kernel_params,
+ '-drive', f"file={self.rootfs},if=none,format=raw,id=drv0",
+ '-device', 'xen-disk,drive=drv0,vdev=xvda',
+ '-device', 'virtio-net-pci,netdev=unet',
+ '-netdev', 'user,id=unet,hostfwd=:127.0.0.1:0-:22')
+
+ try:
+ self.vm.launch()
+ except machine.VMLaunchFailure as e:
+ if "Xen HVM guest support not present" in e.output:
+ self.cancel("KVM Xen support is not present "
+ "(need v5.12+ kernel with CONFIG_KVM_XEN)")
+ elif "Property 'kvm-accel.xen-version' not found" in e.output:
+ self.cancel("QEMU not built with CONFIG_XEN_EMU support")
+ else:
+ raise e
+
+ self.log.info('VM launched, waiting for sshd')
+ console_pattern = 'Starting dropbear sshd: OK'
+ wait_for_console_pattern(self, console_pattern, 'Oops')
+ self.log.info('sshd ready')
+ self.ssh_connect('root', '', False)
+
+ self.ssh_command('cat /proc/cmdline')
+ self.ssh_command('dmesg | grep -e "Grant table initialized"')
+
+ def test_kvm_xen_guest(self):
+ """
+ :avocado: tags=kvm_xen_guest
+ """
+
+ self.common_vm_setup()
+
+ self.kernel_params = (self.KERNEL_DEFAULT +
+ ' xen_emul_unplug=ide-disks')
+ self.run_and_check()
+ self.ssh_command('grep xen-pirq.*msi /proc/interrupts')
+
+ def test_kvm_xen_guest_nomsi(self):
+ """
+ :avocado: tags=kvm_xen_guest_nomsi
+ """
+
+ self.common_vm_setup()
+
+ self.kernel_params = (self.KERNEL_DEFAULT +
+ ' xen_emul_unplug=ide-disks pci=nomsi')
+ self.run_and_check()
+ self.ssh_command('grep xen-pirq.* /proc/interrupts')
+
+ def test_kvm_xen_guest_noapic_nomsi(self):
+ """
+ :avocado: tags=kvm_xen_guest_noapic_nomsi
+ """
+
+ self.common_vm_setup()
+
+ self.kernel_params = (self.KERNEL_DEFAULT +
+ ' xen_emul_unplug=ide-disks noapic pci=nomsi')
+ self.run_and_check()
+ self.ssh_command('grep xen-pirq /proc/interrupts')
+
+ def test_kvm_xen_guest_vapic(self):
+ """
+ :avocado: tags=kvm_xen_guest_vapic
+ """
+
+ self.common_vm_setup()
+ self.vm.add_args('-cpu', 'host,+xen-vapic')
+ self.kernel_params = (self.KERNEL_DEFAULT +
+ ' xen_emul_unplug=ide-disks')
+ self.run_and_check()
+ self.ssh_command('grep xen-pirq /proc/interrupts')
+ self.ssh_command('grep PCI-MSI /proc/interrupts')
+
+ def test_kvm_xen_guest_novector(self):
+ """
+ :avocado: tags=kvm_xen_guest_novector
+ """
+
+ self.common_vm_setup()
+ self.kernel_params = (self.KERNEL_DEFAULT +
+ ' xen_emul_unplug=ide-disks' +
+ ' xen_no_vector_callback')
+ self.run_and_check()
+ self.ssh_command('grep xen-platform-pci /proc/interrupts')
+
+ def test_kvm_xen_guest_novector_nomsi(self):
+ """
+ :avocado: tags=kvm_xen_guest_novector_nomsi
+ """
+
+ self.common_vm_setup()
+
+ self.kernel_params = (self.KERNEL_DEFAULT +
+ ' xen_emul_unplug=ide-disks pci=nomsi' +
+ ' xen_no_vector_callback')
+ self.run_and_check()
+ self.ssh_command('grep xen-platform-pci /proc/interrupts')
+
+ def test_kvm_xen_guest_novector_noapic(self):
+ """
+ :avocado: tags=kvm_xen_guest_novector_noapic
+ """
+
+ self.common_vm_setup()
+ self.kernel_params = (self.KERNEL_DEFAULT +
+ ' xen_emul_unplug=ide-disks' +
+ ' xen_no_vector_callback noapic')
+ self.run_and_check()
+ self.ssh_command('grep xen-platform-pci /proc/interrupts')
diff --git a/tests/avocado/tuxrun_baselines.py b/tests/avocado/tuxrun_baselines.py
index c3fb67f..d343376 100644
--- a/tests/avocado/tuxrun_baselines.py
+++ b/tests/avocado/tuxrun_baselines.py
@@ -270,7 +270,6 @@
"""
self.common_tuxrun(drive="driver=ide-hd,bus=ide.0,unit=0")
- @skip("QEMU currently broken") # regression against stable QEMU
def test_mips64(self):
"""
:avocado: tags=arch:mips64
diff --git a/tests/docker/dockerfiles/debian-hexagon-cross.docker b/tests/docker/dockerfiles/debian-hexagon-cross.docker
index 5308ccb..b99d99f 100644
--- a/tests/docker/dockerfiles/debian-hexagon-cross.docker
+++ b/tests/docker/dockerfiles/debian-hexagon-cross.docker
@@ -27,7 +27,7 @@
ENV TOOLCHAIN_INSTALL /opt
-ENV TOOLCHAIN_RELEASE 15.0.3
+ENV TOOLCHAIN_RELEASE 16.0.0
ENV TOOLCHAIN_BASENAME "clang+llvm-${TOOLCHAIN_RELEASE}-cross-hexagon-unknown-linux-musl"
ENV TOOLCHAIN_URL https://codelinaro.jfrog.io/artifactory/codelinaro-toolchain-for-hexagon/v${TOOLCHAIN_RELEASE}/${TOOLCHAIN_BASENAME}.tar.xz
diff --git a/tests/qemu-iotests/meson.build b/tests/qemu-iotests/meson.build
index a162f68..9735071 100644
--- a/tests/qemu-iotests/meson.build
+++ b/tests/qemu-iotests/meson.build
@@ -47,19 +47,20 @@
endif
rc = run_command(
- [qemu_iotests_check_cmd] + args + ['-n'],
+ [python, qemu_iotests_check_cmd] + args + ['-n'],
check: true,
)
foreach item: rc.stdout().strip().split()
- args = ['-tap', '-' + format, item,
+ args = [qemu_iotests_check_cmd,
+ '-tap', '-' + format, item,
'--source-dir', meson.current_source_dir(),
'--build-dir', meson.current_build_dir()]
# Some individual tests take as long as 45 seconds
# Bump the timeout to 3 minutes for some headroom
# on slow machines to minimize spurious failures
test('io-' + format + '-' + item,
- qemu_iotests_check_cmd,
+ python,
args: args,
depends: qemu_iotests_binaries,
env: qemu_iotests_env,
diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index aa54338..0b9536c 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -30,7 +30,6 @@
"git-base",
"pkgconf",
"xz",
- "python37",
"ninja-build",
# gnu tools
@@ -66,7 +65,7 @@
mkdir src build; cd src;
tar -xf /dev/rld1a;
cd ../build
- ../src/configure --python=python3.7 --disable-opengl {configure_opts};
+ ../src/configure --disable-opengl {configure_opts};
gmake --output-sync -j{jobs} {target} {verbose};
"""
poweroff = "/sbin/poweroff"