Merge tag 'pull-maintainer-july24-050724-1' of https://gitlab.com/stsquad/qemu into staging

Updates for testing, plugins, gdbstub

  - restore some 32 bit host builds and testing
  - move some physmem tracepoint definitions
  - use --userns keep-id for podman builds
  - cleanup check-tcg compiler flag checking for Arm
  - fix some casting in fcvt test
  - tweak check-tcg inline asm for clang
  - suppress some invalid clang warnings
  - disable KVM for the TCI builds
  - improve the insn tracking plugin
  - cleanups to the lockstep plugin
  - free plugin data on cpu finalise
  - assert cpu->index assigned
  - move qemu_plugin_vcpu_init__async into plugin code
  - add support for dynamic gdb command tables
  - allow targets to extend gdb capabilities
  - enable user-mode MTE support

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmaH3bEACgkQ+9DbCVqe
# KkTnvwf9HS68sTICEJqBfY663hjcfdFGsSV/h3q7SN3fhKm/3JHGNK+kumgqdnaC
# ykd7tx0AtBGgKm83B7G6MPywsVMIosMeV3mFeJTVHhKsFwGNjSiGkr3j4R2qxjFt
# nYQ977FqBKyhvhSplR2wwhwi+JpuGWFGlnQTvdF2Z7ni4YCDFcbl4eiMyGwsjbWm
# 0VBP+wCSSMIIbS9Qb7DrhZlfu0+wKZK/q0FLzVVofcLSXGou+Mse/qhtG+yAU/FI
# qqqV+7J4PU9E4BqFaklxyRtBrpXNDgpo77pu6ZR7oDXD7HNMuIAuEIlkxMJjarNM
# xN64WOOzw15R2RMVyXdYx6ccxWft2Q==
# =9Gmk
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 05 Jul 2024 04:49:05 AM PDT
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]

* tag 'pull-maintainer-july24-050724-1' of https://gitlab.com/stsquad/qemu: (40 commits)
  tests/tcg/aarch64: Add MTE gdbstub tests
  gdbstub: Add support for MTE in user mode
  gdbstub: Use true to set cmd_startswith
  gdbstub: Pass CPU context to command handler
  gdbstub: Make hex conversion function non-internal
  target/arm: Factor out code for setting MTE TCF0 field
  target/arm: Make some MTE helpers widely available
  target/arm: Fix exception case in allocation_tag_mem_probe
  gdbstub: Add support for target-specific stubs
  gdbstub: Move GdbCmdParseEntry into a new header file
  gdbstub: Clean up process_string_cmd
  accel/tcg: Move qemu_plugin_vcpu_init__async() to plugins/
  plugins: Free CPUPluginState before destroying vCPU state
  plugins: Ensure vCPU index is assigned in init/exit hooks
  plugins/lockstep: clean-up output
  plugins/lockstep: mention the one-insn-per-tb option
  plugins/lockstep: make mixed-mode safe
  plugins/lockstep: preserve sock_path
  test/plugins: preserve the instruction record over translations
  test/plugin: make insn plugin less noisy by default
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2024-07-05 09:15:48 -07:00
50 changed files with 1771 additions and 946 deletions
+1 -1
View File
@@ -635,7 +635,7 @@ build-tci:
- TARGETS="aarch64 arm hppa m68k microblaze ppc64 s390x x86_64"
- mkdir build
- cd build
- ../configure --enable-tcg-interpreter --disable-docs --disable-gtk --disable-vnc
- ../configure --enable-tcg-interpreter --disable-kvm --disable-docs --disable-gtk --disable-vnc
--target-list="$(for tg in $TARGETS; do echo -n ${tg}'-softmmu '; done)"
|| { cat config.log meson-logs/meson-log.txt && exit 1; }
- make -j"$JOBS"
+12 -1
View File
@@ -37,6 +37,17 @@ cross-arm64-kvm-only:
IMAGE: debian-arm64-cross
EXTRA_CONFIGURE_OPTS: --disable-tcg --without-default-features
cross-i686-system:
extends:
- .cross_system_build_job
- .cross_test_artifacts
needs:
job: i686-debian-cross-container
variables:
IMAGE: debian-i686-cross
EXTRA_CONFIGURE_OPTS: --disable-kvm
MAKE_CHECK_ARGS: check-qtest
cross-i686-user:
extends:
- .cross_user_build_job
@@ -57,7 +68,7 @@ cross-i686-tci:
variables:
IMAGE: debian-i686-cross
ACCEL: tcg-interpreter
EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user --disable-plugins
EXTRA_CONFIGURE_OPTS: --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user --disable-plugins --disable-kvm
MAKE_CHECK_ARGS: check check-tcg
cross-mipsel-system:
+1 -1
View File
@@ -1,6 +1,6 @@
TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml gdb-xml/aarch64-mte.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
Vendored
+4
View File
@@ -1673,6 +1673,10 @@ for target in $target_list; do
echo "GDB=$gdb_bin" >> $config_target_mak
fi
if test "${arch}" = "aarch64" && version_ge ${gdb_version##* } 15.0; then
echo "GDB_HAS_MTE=y" >> $config_target_mak
fi
echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> Makefile.prereqs
tcg_tests_targets="$tcg_tests_targets $target"
fi
+12 -11
View File
@@ -14,7 +14,8 @@
* particular run may execute the exact same sequence of blocks. An
* asynchronous event (for example X11 graphics update) may cause a
* block to end early and a new partial block to start. This means
* serial only test cases are a better bet. -d nochain may also help.
* serial only test cases are a better bet. -d nochain may also help
* as well as -accel tcg,one-insn-per-tb=on
*
* This code is not thread safe!
*
@@ -57,7 +58,7 @@ typedef struct {
/* The execution state we compare */
typedef struct {
uint64_t pc;
unsigned long insn_count;
uint64_t insn_count;
} ExecState;
typedef struct {
@@ -134,10 +135,13 @@ static void report_divergance(ExecState *us, ExecState *them)
/* Output short log entry of going out of sync... */
if (verbose || divrec.distance == 1 || diverged) {
g_string_printf(out,
"@ 0x%016" PRIx64 " vs 0x%016" PRIx64
g_string_printf(out, "@ "
"0x%016" PRIx64 " (%" PRId64 ") vs "
"0x%016" PRIx64 " (%" PRId64 ")"
" (%d/%d since last)\n",
us->pc, them->pc, g_slist_length(divergence_log),
us->pc, us->insn_count,
them->pc, them->insn_count,
g_slist_length(divergence_log),
divrec.distance);
qemu_plugin_outs(out->str);
}
@@ -146,10 +150,7 @@ static void report_divergance(ExecState *us, ExecState *them)
int i;
GSList *entry;
g_string_printf(out,
"Δ insn_count @ 0x%016" PRIx64
" (%ld) vs 0x%016" PRIx64 " (%ld)\n",
us->pc, us->insn_count, them->pc, them->insn_count);
g_string_printf(out, "Δ too high, we have diverged, previous insns\n");
for (entry = log, i = 0;
g_slist_next(entry) && i < 5;
@@ -162,7 +163,7 @@ static void report_divergance(ExecState *us, ExecState *them)
prev->insn_count);
}
qemu_plugin_outs(out->str);
qemu_plugin_outs("too much divergence... giving up.");
qemu_plugin_outs("giving up\n");
qemu_plugin_uninstall(our_id, plugin_cleanup);
}
}
@@ -347,7 +348,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
return -1;
}
} else if (g_strcmp0(tokens[0], "sockpath") == 0) {
sock_path = tokens[1];
sock_path = g_strdup(tokens[1]);
} else {
fprintf(stderr, "option parsing failed: %s\n", p);
return -1;
+11
View File
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2021-2023 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.aarch64.mte">
<reg name="tag_ctl" bitsize="64" type="uint64" group="system" save-restore="no"/>
</feature>
+200 -141
View File
File diff suppressed because it is too large Load Diff
-23
View File
@@ -106,9 +106,7 @@ static inline int tohex(int v)
*/
void gdb_put_strbuf(void);
int gdb_put_packet(const char *buf);
int gdb_put_packet_binary(const char *buf, int len, bool dump);
void gdb_hextomem(GByteArray *mem, const char *buf, int len);
void gdb_memtohex(GString *buf, const uint8_t *mem, int len);
void gdb_memtox(GString *buf, const char *mem, int len);
void gdb_read_byte(uint8_t ch);
@@ -166,27 +164,6 @@ void gdb_put_buffer(const uint8_t *buf, int len);
*/
void gdb_init_gdbserver_state(void);
typedef enum GDBThreadIdKind {
GDB_ONE_THREAD = 0,
GDB_ALL_THREADS, /* One process, all threads */
GDB_ALL_PROCESSES,
GDB_READ_THREAD_ERR
} GDBThreadIdKind;
typedef union GdbCmdVariant {
const char *data;
uint8_t opcode;
unsigned long val_ul;
unsigned long long val_ull;
struct {
GDBThreadIdKind kind;
uint32_t pid;
uint32_t tid;
} thread_id;
} GdbCmdVariant;
#define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
void gdb_handle_query_rcmd(GArray *params, void *ctx); /* system */
void gdb_handle_query_offsets(GArray *params, void *user_ctx); /* user */
void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx); /*user */
+4 -3
View File
@@ -16,6 +16,7 @@
#include "sysemu/runstate.h"
#include "gdbstub/user.h"
#include "gdbstub/syscalls.h"
#include "gdbstub/commands.h"
#include "trace.h"
#include "internals.h"
@@ -154,9 +155,9 @@ void gdb_handle_file_io(GArray *params, void *user_ctx)
uint64_t ret;
int err;
ret = get_param(params, 0)->val_ull;
ret = gdb_get_cmd_param(params, 0)->val_ull;
if (params->len >= 2) {
err = get_param(params, 1)->val_ull;
err = gdb_get_cmd_param(params, 1)->val_ull;
} else {
err = 0;
}
@@ -196,7 +197,7 @@ void gdb_handle_file_io(GArray *params, void *user_ctx)
gdbserver_syscall_state.current_syscall_cb = NULL;
}
if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
if (params->len >= 3 && gdb_get_cmd_param(params, 2)->opcode == (uint8_t)'C') {
gdb_put_packet("T02");
return;
}
+4 -3
View File
@@ -16,6 +16,7 @@
#include "qemu/cutils.h"
#include "exec/gdbstub.h"
#include "gdbstub/syscalls.h"
#include "gdbstub/commands.h"
#include "exec/hwaddr.h"
#include "exec/tb-flush.h"
#include "sysemu/cpus.h"
@@ -501,7 +502,7 @@ void gdb_handle_set_qemu_phy_mem_mode(GArray *params, void *ctx)
return;
}
if (!get_param(params, 0)->val_ul) {
if (!gdb_get_cmd_param(params, 0)->val_ul) {
phy_memory_mode = 0;
} else {
phy_memory_mode = 1;
@@ -519,7 +520,7 @@ void gdb_handle_query_rcmd(GArray *params, void *ctx)
return;
}
len = strlen(get_param(params, 0)->data);
len = strlen(gdb_get_cmd_param(params, 0)->data);
if (len % 2) {
gdb_put_packet("E01");
return;
@@ -527,7 +528,7 @@ void gdb_handle_query_rcmd(GArray *params, void *ctx)
g_assert(gdbserver_state.mem_buf->len == 0);
len = len / 2;
gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
gdb_hextomem(gdbserver_state.mem_buf, gdb_get_cmd_param(params, 0)->data, len);
g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
qemu_chr_be_write(gdbserver_system_state.mon_chr,
gdbserver_state.mem_buf->data,
+13 -12
View File
@@ -9,6 +9,7 @@
#include "qemu/osdep.h"
#include "exec/gdbstub.h"
#include "gdbstub/commands.h"
#include "qemu.h"
#include "internals.h"
#ifdef CONFIG_LINUX
@@ -250,8 +251,8 @@ void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx)
return;
}
offset = get_param(params, 0)->val_ul;
len = get_param(params, 1)->val_ul;
offset = gdb_get_cmd_param(params, 0)->val_ul;
len = gdb_get_cmd_param(params, 1)->val_ul;
ts = get_task_state(gdbserver_state.c_cpu);
saved_auxv = ts->info->saved_auxv;
auxv_len = ts->info->auxv_len;
@@ -288,7 +289,7 @@ void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx)
static const char *get_filename_param(GArray *params, int i)
{
const char *hex_filename = get_param(params, i)->data;
const char *hex_filename = gdb_get_cmd_param(params, i)->data;
gdb_hextomem(gdbserver_state.mem_buf, hex_filename,
strlen(hex_filename) / 2);
g_byte_array_append(gdbserver_state.mem_buf, (const guint8 *)"", 1);
@@ -306,8 +307,8 @@ static void hostio_reply_with_data(const void *buf, size_t n)
void gdb_handle_v_file_open(GArray *params, void *user_ctx)
{
const char *filename = get_filename_param(params, 0);
uint64_t flags = get_param(params, 1)->val_ull;
uint64_t mode = get_param(params, 2)->val_ull;
uint64_t flags = gdb_get_cmd_param(params, 1)->val_ull;
uint64_t mode = gdb_get_cmd_param(params, 2)->val_ull;
#ifdef CONFIG_LINUX
int fd = do_guest_openat(cpu_env(gdbserver_state.g_cpu), 0, filename,
@@ -325,7 +326,7 @@ void gdb_handle_v_file_open(GArray *params, void *user_ctx)
void gdb_handle_v_file_close(GArray *params, void *user_ctx)
{
int fd = get_param(params, 0)->val_ul;
int fd = gdb_get_cmd_param(params, 0)->val_ul;
if (close(fd) == -1) {
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
@@ -338,9 +339,9 @@ void gdb_handle_v_file_close(GArray *params, void *user_ctx)
void gdb_handle_v_file_pread(GArray *params, void *user_ctx)
{
int fd = get_param(params, 0)->val_ul;
size_t count = get_param(params, 1)->val_ull;
off_t offset = get_param(params, 2)->val_ull;
int fd = gdb_get_cmd_param(params, 0)->val_ul;
size_t count = gdb_get_cmd_param(params, 1)->val_ull;
off_t offset = gdb_get_cmd_param(params, 2)->val_ull;
size_t bufsiz = MIN(count, BUFSIZ);
g_autofree char *buf = g_try_malloc(bufsiz);
@@ -383,9 +384,9 @@ void gdb_handle_v_file_readlink(GArray *params, void *user_ctx)
void gdb_handle_query_xfer_exec_file(GArray *params, void *user_ctx)
{
uint32_t pid = get_param(params, 0)->val_ul;
uint32_t offset = get_param(params, 1)->val_ul;
uint32_t length = get_param(params, 2)->val_ul;
uint32_t pid = gdb_get_cmd_param(params, 0)->val_ul;
uint32_t offset = gdb_get_cmd_param(params, 1)->val_ul;
uint32_t length = gdb_get_cmd_param(params, 2)->val_ul;
GDBProcess *process = gdb_get_process(pid);
if (!process) {
+4 -3
View File
@@ -16,6 +16,7 @@
#include "exec/hwaddr.h"
#include "exec/tb-flush.h"
#include "exec/gdbstub.h"
#include "gdbstub/commands.h"
#include "gdbstub/syscalls.h"
#include "gdbstub/user.h"
#include "gdbstub/enums.h"
@@ -793,7 +794,7 @@ void gdb_syscall_return(CPUState *cs, int num)
void gdb_handle_set_catch_syscalls(GArray *params, void *user_ctx)
{
const char *param = get_param(params, 0)->data;
const char *param = gdb_get_cmd_param(params, 0)->data;
GDBSyscallsMask catch_syscalls_mask;
bool catch_all_syscalls;
unsigned int num;
@@ -858,8 +859,8 @@ void gdb_handle_query_xfer_siginfo(GArray *params, void *user_ctx)
unsigned long offset, len;
uint8_t *siginfo_offset;
offset = get_param(params, 0)->val_ul;
len = get_param(params, 1)->val_ul;
offset = gdb_get_cmd_param(params, 0)->val_ul;
len = gdb_get_cmd_param(params, 1)->val_ul;
if (offset + len > gdbserver_user_state.siginfo_len) {
/* Invalid offset and/or requested length. */
+6 -8
View File
@@ -192,13 +192,6 @@ static void cpu_common_parse_features(const char *typename, char *features,
}
}
#ifdef CONFIG_PLUGIN
static void qemu_plugin_vcpu_init__async(CPUState *cpu, run_on_cpu_data unused)
{
qemu_plugin_vcpu_init_hook(cpu);
}
#endif
static void cpu_common_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cpu = CPU(dev);
@@ -274,7 +267,7 @@ static void cpu_common_initfn(Object *obj)
#ifdef CONFIG_PLUGIN
if (tcg_enabled()) {
cpu->plugin_state = qemu_plugin_create_vcpu_state();
async_run_on_cpu(cpu, qemu_plugin_vcpu_init__async, RUN_ON_CPU_NULL);
qemu_plugin_vcpu_init_hook(cpu);
}
#endif
}
@@ -283,6 +276,11 @@ static void cpu_common_finalize(Object *obj)
{
CPUState *cpu = CPU(obj);
#ifdef CONFIG_PLUGIN
if (tcg_enabled()) {
g_free(cpu->plugin_state);
}
#endif
g_array_free(cpu->gdb_regs, TRUE);
qemu_lockcnt_destroy(&cpu->in_ioctl_lock);
qemu_mutex_destroy(&cpu->work_mutex);
+1 -1
View File
@@ -267,7 +267,7 @@ int load_fit(const struct fit_loader *ldr, const char *filename, void *opaque)
const char *def_cfg_name;
char path[FIT_LOADER_MAX_PATH];
int itb_size, configs, cfg_off, off;
hwaddr kernel_end;
hwaddr kernel_end = 0;
int ret;
itb = load_device_tree(filename, &itb_size);
+103
View File
@@ -0,0 +1,103 @@
#ifndef GDBSTUB_COMMANDS_H
#define GDBSTUB
typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
typedef enum GDBThreadIdKind {
GDB_ONE_THREAD = 0,
GDB_ALL_THREADS, /* One process, all threads */
GDB_ALL_PROCESSES,
GDB_READ_THREAD_ERR
} GDBThreadIdKind;
typedef union GdbCmdVariant {
const char *data;
uint8_t opcode;
unsigned long val_ul;
unsigned long long val_ull;
struct {
GDBThreadIdKind kind;
uint32_t pid;
uint32_t tid;
} thread_id;
} GdbCmdVariant;
#define gdb_get_cmd_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
/**
* typedef GdbCmdParseEntry - gdb command parser
*
* This structure keeps the information necessary to match a gdb command,
* parse it (extract its parameters), and select the correct handler for it.
*
* @cmd: The command to be matched
* @cmd_startswith: If true, @cmd is compared using startswith
* @schema: Each schema for the command parameter entry consists of 2 chars,
* the first char represents the parameter type handling the second char
* represents the delimiter for the next parameter.
*
* Currently supported schema types:
* 'l' -> unsigned long (stored in .val_ul)
* 'L' -> unsigned long long (stored in .val_ull)
* 's' -> string (stored in .data)
* 'o' -> single char (stored in .opcode)
* 't' -> thread id (stored in .thread_id)
* '?' -> skip according to delimiter
*
* Currently supported delimiters:
* '?' -> Stop at any delimiter (",;:=\0")
* '0' -> Stop at "\0"
* '.' -> Skip 1 char unless reached "\0"
* Any other value is treated as the delimiter value itself
*
* @allow_stop_reply: True iff the gdbstub can respond to this command with a
* "stop reply" packet. The list of commands that accept such response is
* defined at the GDB Remote Serial Protocol documentation. See:
* https://sourceware.org/gdb/onlinedocs/gdb/Stop-Reply-Packets.html#Stop-Reply-Packets.
*
* @need_cpu_context: Pass current CPU context to command handler via user_ctx.
*/
typedef struct GdbCmdParseEntry {
GdbCmdHandler handler;
const char *cmd;
bool cmd_startswith;
const char *schema;
bool allow_stop_reply;
bool need_cpu_context;
} GdbCmdParseEntry;
/**
* gdb_put_packet() - put string into gdb server's buffer so it is sent
* to the client
*/
int gdb_put_packet(const char *buf);
/**
* gdb_extend_query_table() - Extend query table.
* @table: The table with the additional query packet handlers.
* @size: The number of handlers to be added.
*/
void gdb_extend_query_table(GdbCmdParseEntry *table, int size);
/**
* gdb_extend_set_table() - Extend set table.
* @table: The table with the additional set packet handlers.
* @size: The number of handlers to be added.
*/
void gdb_extend_set_table(GdbCmdParseEntry *table, int size);
/**
* gdb_extend_qsupported_features() - Extend the qSupported features string.
* @qsupported_features: The additional qSupported feature(s) string. The string
* should start with a semicolon and, if there are more than one feature, the
* features should be separate by a semiocolon.
*/
void gdb_extend_qsupported_features(char *qsupported_features);
/**
* Convert a hex string to bytes. Conversion is done per byte, so 2 hex digits
* are converted to 1 byte. Invalid hex digits are treated as 0 digits.
*/
void gdb_hextomem(GByteArray *mem, const char *buf, int len);
#endif /* GDBSTUB_COMMANDS_H */
+3
View File
@@ -149,6 +149,9 @@ struct CPUPluginState {
/**
* qemu_plugin_create_vcpu_state: allocate plugin state
*
* The returned data must be released with g_free()
* when no longer required.
*/
CPUPluginState *qemu_plugin_create_vcpu_state(void);
+2
View File
@@ -9,3 +9,5 @@ vdso_le_inc = gen_vdso.process('vdso-le.so',
extra_args: ['-r', '__kernel_rt_sigreturn'])
linux_user_ss.add(when: 'TARGET_AARCH64', if_true: [vdso_be_inc, vdso_le_inc])
linux_user_ss.add(when: 'TARGET_AARCH64', if_true: [files('mte_user_helper.c')])
+35
View File
@@ -0,0 +1,35 @@
/*
* ARM MemTag convenience functions.
*
* This code is licensed under the GNU GPL v2 or later.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "qemu/osdep.h"
#include "qemu.h"
#include "mte_user_helper.h"
void arm_set_mte_tcf0(CPUArchState *env, abi_long value)
{
/*
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
*
* The kernel has a per-cpu configuration for the sysadmin,
* /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
* which qemu does not implement.
*
* Because there is no performance difference between the modes, and
* because SYNC is most useful for debugging MTE errors, choose SYNC
* as the preferred mode. With this preference, and the way the API
* uses only two bits, there is no way for the program to select
* ASYMM mode.
*/
unsigned tcf = 0;
if (value & PR_MTE_TCF_SYNC) {
tcf = 1;
} else if (value & PR_MTE_TCF_ASYNC) {
tcf = 2;
}
env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
}
+32
View File
@@ -0,0 +1,32 @@
/*
* ARM MemTag convenience functions.
*
* This code is licensed under the GNU GPL v2 or later.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef AARCH64_MTE_USER_HELPER_H
#define AARCH64_MTE USER_HELPER_H
#ifndef PR_MTE_TCF_SHIFT
# define PR_MTE_TCF_SHIFT 1
# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT)
# define PR_MTE_TAG_SHIFT 3
# define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT)
#endif
/**
* arm_set_mte_tcf0 - Set TCF0 field in SCTLR_EL1 register
* @env: The CPU environment
* @value: The value to be set for the Tag Check Fault in EL0 field.
*
* Only SYNC and ASYNC modes can be selected. If ASYMM mode is given, the SYNC
* mode is selected instead. So, there is no way to set the ASYMM mode.
*/
void arm_set_mte_tcf0(CPUArchState *env, abi_long value);
#endif /* AARCH64_MTE_USER_HELPER_H */
+2 -20
View File
@@ -7,6 +7,7 @@
#define AARCH64_TARGET_PRCTL_H
#include "target/arm/cpu-features.h"
#include "mte_user_helper.h"
static abi_long do_prctl_sve_get_vl(CPUArchState *env)
{
@@ -173,26 +174,7 @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
if (cpu_isar_feature(aa64_mte, cpu)) {
/*
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
*
* The kernel has a per-cpu configuration for the sysadmin,
* /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
* which qemu does not implement.
*
* Because there is no performance difference between the modes, and
* because SYNC is most useful for debugging MTE errors, choose SYNC
* as the preferred mode. With this preference, and the way the API
* uses only two bits, there is no way for the program to select
* ASYMM mode.
*/
unsigned tcf = 0;
if (arg2 & PR_MTE_TCF_SYNC) {
tcf = 1;
} else if (arg2 & PR_MTE_TCF_ASYNC) {
tcf = 2;
}
env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
arm_set_mte_tcf0(env, arg2);
/*
* Write PR_MTE_TAG to GCR_EL1[Exclude].

Some files were not shown because too many files have changed in this diff Show More