tcg: Allow first half of insn in ram, and second half in mmio

linux-user/sparc: SIGILL for unknown trap vectors
 linux-user/microblaze: SIGILL for privileged insns
 linux-user: Fix deadlock while exiting due to signal
 target/microblaze: Add gdbstub xml
 util: Adjust cacheflush for windows-arm64
 include/sysemu/os-win32: Adjust setjmp/longjmp for windows-arm64
 -----BEGIN PGP SIGNATURE-----
 
 iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmP1dpkdHHJpY2hhcmQu
 aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+70gf+OOM3KmsFpsJ4+68W
 v/ulVwye3RFQXv4KRtuRPeKCKMk7vXmBRj9gsyOpc23TaoYiMNbFbztpAkcc/Z/1
 +6H8QeZGLWDqiX6ashwGNm/2bqPbvY7znaCvNuLkNGCPBeJ12C19uN1BBiGdeqOe
 IXIIk1r0U6rfIDhP2PJALXOxgHd/8/onYbhU6kU5tQjM24pycW44UUGPSeV++I0e
 xWezAYOmZ4PK58bXHDPMZ0UkzuefaNmiLlfwj/4nlaWQetwQTy7BeEU6FpKolUN2
 wrvfCqth/c3SdUaZHu4DoX1yWt72L37SpO0ijvk8E+AqsvXTn9gFdWK2dsEiPEeS
 Z9abFw==
 =dxZo
 -----END PGP SIGNATURE-----

Merge tag 'pull-tcg-20230221' of https://gitlab.com/rth7680/qemu into staging

tcg: Allow first half of insn in ram, and second half in mmio
linux-user/sparc: SIGILL for unknown trap vectors
linux-user/microblaze: SIGILL for privileged insns
linux-user: Fix deadlock while exiting due to signal
target/microblaze: Add gdbstub xml
util: Adjust cacheflush for windows-arm64
include/sysemu/os-win32: Adjust setjmp/longjmp for windows-arm64

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmP1dpkdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+70gf+OOM3KmsFpsJ4+68W
# v/ulVwye3RFQXv4KRtuRPeKCKMk7vXmBRj9gsyOpc23TaoYiMNbFbztpAkcc/Z/1
# +6H8QeZGLWDqiX6ashwGNm/2bqPbvY7znaCvNuLkNGCPBeJ12C19uN1BBiGdeqOe
# IXIIk1r0U6rfIDhP2PJALXOxgHd/8/onYbhU6kU5tQjM24pycW44UUGPSeV++I0e
# xWezAYOmZ4PK58bXHDPMZ0UkzuefaNmiLlfwj/4nlaWQetwQTy7BeEU6FpKolUN2
# wrvfCqth/c3SdUaZHu4DoX1yWt72L37SpO0ijvk8E+AqsvXTn9gFdWK2dsEiPEeS
# Z9abFw==
# =dxZo
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 22 Feb 2023 01:57:45 GMT
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* tag 'pull-tcg-20230221' of https://gitlab.com/rth7680/qemu:
  sysemu/os-win32: fix setjmp/longjmp on windows-arm64
  util/cacheflush: fix cache on windows-arm64
  target/microblaze: Add gdbstub xml
  linux-user/microblaze: Handle privileged exception
  cpus: Make {start,end}_exclusive() recursive
  linux-user: Always exit from exclusive state in fork_end()
  linux-user/sparc: Raise SIGILL for all unhandled software traps
  accel/tcg: Allow the second page of an instruction to be MMIO

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2023-02-24 10:05:43 +00:00
commit ed9128c177
19 changed files with 229 additions and 34 deletions

View File

@ -176,8 +176,16 @@ static void *translator_access(CPUArchState *env, DisasContextBase *db,
if (host == NULL) {
tb_page_addr_t phys_page =
get_page_addr_code_hostp(env, base, &db->host_addr[1]);
/* We cannot handle MMIO as second page. */
assert(phys_page != -1);
/*
* If the second page is MMIO, treat as if the first page
* was MMIO as well, so that we do not cache the TB.
*/
if (unlikely(phys_page == -1)) {
tb_set_page_addr0(tb, -1);
return NULL;
}
tb_set_page_addr1(tb, phys_page);
#ifdef CONFIG_USER_ONLY
page_protect(end);

View File

@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common
TARGET_SYSTBL=syscall.tbl
TARGET_BIG_ENDIAN=y
TARGET_HAS_BFLT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -2,3 +2,4 @@ TARGET_ARCH=microblaze
TARGET_BIG_ENDIAN=y
TARGET_SUPPORTS_MTTCG=y
TARGET_NEED_FDT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -2,3 +2,4 @@ TARGET_ARCH=microblaze
TARGET_SYSTBL_ABI=common
TARGET_SYSTBL=syscall.tbl
TARGET_HAS_BFLT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -1,3 +1,4 @@
TARGET_ARCH=microblaze
TARGET_SUPPORTS_MTTCG=y
TARGET_NEED_FDT=y
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml

View File

@ -192,6 +192,11 @@ void start_exclusive(void)
CPUState *other_cpu;
int running_cpus;
if (current_cpu->exclusive_context_count) {
current_cpu->exclusive_context_count++;
return;
}
qemu_mutex_lock(&qemu_cpu_list_lock);
exclusive_idle();
@ -219,13 +224,16 @@ void start_exclusive(void)
*/
qemu_mutex_unlock(&qemu_cpu_list_lock);
current_cpu->in_exclusive_context = true;
current_cpu->exclusive_context_count = 1;
}
/* Finish an exclusive operation. */
void end_exclusive(void)
{
current_cpu->in_exclusive_context = false;
current_cpu->exclusive_context_count--;
if (current_cpu->exclusive_context_count) {
return;
}
qemu_mutex_lock(&qemu_cpu_list_lock);
qatomic_set(&pending_cpus, 0);

View File

@ -0,0 +1,67 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2008 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.microblaze.core">
<reg name="r0" bitsize="32" regnum="0"/>
<reg name="r1" bitsize="32" type="data_ptr"/>
<reg name="r2" bitsize="32"/>
<reg name="r3" bitsize="32"/>
<reg name="r4" bitsize="32"/>
<reg name="r5" bitsize="32"/>
<reg name="r6" bitsize="32"/>
<reg name="r7" bitsize="32"/>
<reg name="r8" bitsize="32"/>
<reg name="r9" bitsize="32"/>
<reg name="r10" bitsize="32"/>
<reg name="r11" bitsize="32"/>
<reg name="r12" bitsize="32"/>
<reg name="r13" bitsize="32"/>
<reg name="r14" bitsize="32"/>
<reg name="r15" bitsize="32"/>
<reg name="r16" bitsize="32"/>
<reg name="r17" bitsize="32"/>
<reg name="r18" bitsize="32"/>
<reg name="r19" bitsize="32"/>
<reg name="r20" bitsize="32"/>
<reg name="r21" bitsize="32"/>
<reg name="r22" bitsize="32"/>
<reg name="r23" bitsize="32"/>
<reg name="r24" bitsize="32"/>
<reg name="r25" bitsize="32"/>
<reg name="r26" bitsize="32"/>
<reg name="r27" bitsize="32"/>
<reg name="r28" bitsize="32"/>
<reg name="r29" bitsize="32"/>
<reg name="r30" bitsize="32"/>
<reg name="r31" bitsize="32"/>
<reg name="rpc" bitsize="32" type="code_ptr"/>
<reg name="rmsr" bitsize="32"/>
<reg name="rear" bitsize="32"/>
<reg name="resr" bitsize="32"/>
<reg name="rfsr" bitsize="32"/>
<reg name="rbtr" bitsize="32"/>
<reg name="rpvr0" bitsize="32"/>
<reg name="rpvr1" bitsize="32"/>
<reg name="rpvr2" bitsize="32"/>
<reg name="rpvr3" bitsize="32"/>
<reg name="rpvr4" bitsize="32"/>
<reg name="rpvr5" bitsize="32"/>
<reg name="rpvr6" bitsize="32"/>
<reg name="rpvr7" bitsize="32"/>
<reg name="rpvr8" bitsize="32"/>
<reg name="rpvr9" bitsize="32"/>
<reg name="rpvr10" bitsize="32"/>
<reg name="rpvr11" bitsize="32"/>
<reg name="redr" bitsize="32"/>
<reg name="rpid" bitsize="32"/>
<reg name="rzpr" bitsize="32"/>
<reg name="rtlbx" bitsize="32"/>
<reg name="rtlbsx" bitsize="32"/>
<reg name="rtlblo" bitsize="32"/>
<reg name="rtlbhi" bitsize="32"/>
</feature>

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2008 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.microblaze.stack-protect">
<reg name="rslr" bitsize="32"/>
<reg name="rshr" bitsize="32"/>
</feature>

View File

@ -349,7 +349,7 @@ struct CPUState {
bool unplug;
bool crash_occurred;
bool exit_request;
bool in_exclusive_context;
int exclusive_context_count;
uint32_t cflags_next_tb;
/* updates protected by BQL */
uint32_t interrupt_request;
@ -758,7 +758,7 @@ void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data
*/
static inline bool cpu_in_exclusive_context(const CPUState *cpu)
{
return cpu->in_exclusive_context;
return cpu->exclusive_context_count;
}
/**

View File

@ -51,14 +51,34 @@ typedef struct sockaddr_un {
extern "C" {
#endif
#if defined(_WIN64)
/* On w64, setjmp is implemented by _setjmp which needs a second parameter.
#if defined(__aarch64__)
/*
* On windows-arm64, setjmp is available in only one variant, and longjmp always
* does stack unwinding. This crash with generated code.
* Thus, we use another implementation of setjmp (not windows one), coming from
* mingw, which never performs stack unwinding.
*/
#undef setjmp
#undef longjmp
/*
* These functions are not declared in setjmp.h because __aarch64__ defines
* setjmp to _setjmpex instead. However, they are still defined in libmingwex.a,
* which gets linked automatically.
*/
extern int __mingw_setjmp(jmp_buf);
extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
#define setjmp(env) __mingw_setjmp(env)
#define longjmp(env, val) __mingw_longjmp(env, val)
#elif defined(_WIN64)
/*
* On windows-x64, setjmp is implemented by _setjmp which needs a second parameter.
* If this parameter is NULL, longjump does no stack unwinding.
* That is what we need for QEMU. Passing the value of register rsp (default)
* lets longjmp try a stack unwinding which will crash with generated code. */
* lets longjmp try a stack unwinding which will crash with generated code.
*/
# undef setjmp
# define setjmp(env) _setjmp(env, NULL)
#endif
#endif /* __aarch64__ */
/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify
* "longjmp and don't touch the signal masks". Since we know that the
* savemask parameter will always be zero we can safely define these

View File

@ -161,13 +161,15 @@ void fork_end(int child)
}
qemu_init_cpu_list();
gdbserver_fork(thread_cpu);
/* qemu_init_cpu_list() takes care of reinitializing the
* exclusive state, so we don't need to end_exclusive() here.
*/
} else {
cpu_list_unlock();
end_exclusive();
}
/*
* qemu_init_cpu_list() reinitialized the child exclusive state, but we
* also need to keep current_cpu consistent, so call end_exclusive() for
* both child and parent.
*/
end_exclusive();
}
__thread CPUState *thread_cpu;

View File

@ -25,8 +25,8 @@
void cpu_loop(CPUMBState *env)
{
int trapnr, ret, si_code, sig;
CPUState *cs = env_cpu(env);
int trapnr, ret, si_code;
while (1) {
cpu_exec_start(cs);
@ -76,6 +76,7 @@ void cpu_loop(CPUMBState *env)
env->iflags &= ~(IMM_FLAG | D_FLAG);
switch (env->esr & 31) {
case ESR_EC_DIVZERO:
sig = TARGET_SIGFPE;
si_code = TARGET_FPE_INTDIV;
break;
case ESR_EC_FPU:
@ -84,6 +85,7 @@ void cpu_loop(CPUMBState *env)
* if there's no recognized bit set. Possibly this
* implies that si_code is 0, but follow the structure.
*/
sig = TARGET_SIGFPE;
si_code = env->fsr;
if (si_code & FSR_IO) {
si_code = TARGET_FPE_FLTINV;
@ -97,13 +99,17 @@ void cpu_loop(CPUMBState *env)
si_code = TARGET_FPE_FLTRES;
}
break;
case ESR_EC_PRIVINSN:
sig = SIGILL;
si_code = ILL_PRVOPC;
break;
default:
fprintf(stderr, "Unhandled hw-exception: 0x%x\n",
env->esr & ESR_EC_MASK);
cpu_dump_state(cs, stderr, 0);
exit(EXIT_FAILURE);
}
force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
force_sig_fault(sig, si_code, env->pc);
break;
case EXCP_DEBUG:

View File

@ -248,6 +248,14 @@ void cpu_loop (CPUSPARCState *env)
cpu_exec_step_atomic(cs);
break;
default:
/*
* Most software trap numbers vector to BAD_TRAP.
* Handle anything not explicitly matched above.
*/
if (trapnr >= TT_TRAP && trapnr <= TT_TRAP + 0x7f) {
force_sig_fault(TARGET_SIGILL, ILL_ILLTRP, env->pc);
break;
}
fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(cs, stderr, 0);
exit(EXIT_FAILURE);

View File

@ -6752,6 +6752,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
cpu_clone_regs_parent(env, flags);
fork_end(0);
}
g_assert(!cpu_in_exclusive_context(cpu));
}
return ret;
}

View File

@ -2466,6 +2466,27 @@ if targetos == 'windows'
}''', name: '_lock_file and _unlock_file'))
endif
if targetos == 'windows'
mingw_has_setjmp_longjmp = cc.links('''
#include <setjmp.h>
int main(void) {
/*
* These functions are not available in setjmp header, but may be
* available at link time, from libmingwex.a.
*/
extern int __mingw_setjmp(jmp_buf);
extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
jmp_buf env;
__mingw_setjmp(env);
__mingw_longjmp(env, 0);
}
''', name: 'mingw setjmp and longjmp')
if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
error('mingw must provide setjmp/longjmp for windows-arm64')
endif
endif
########################
# Target configuration #
########################

View File

@ -28,6 +28,7 @@
#include "qemu/module.h"
#include "hw/qdev-properties.h"
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
#include "fpu/softfloat-helpers.h"
static const struct {
@ -294,6 +295,9 @@ static void mb_cpu_initfn(Object *obj)
CPUMBState *env = &cpu->env;
cpu_set_cpustate_pointers(cpu);
gdb_register_coprocessor(CPU(cpu), mb_cpu_gdb_read_stack_protect,
mb_cpu_gdb_write_stack_protect, 2,
"microblaze-stack-protect.xml", 0);
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
@ -422,7 +426,8 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
cc->sysemu_ops = &mb_sysemu_ops;
#endif
device_class_set_props(dc, mb_properties);
cc->gdb_num_core_regs = 32 + 27;
cc->gdb_num_core_regs = 32 + 25;
cc->gdb_core_xml_file = "microblaze-core.xml";
cc->disas_set_info = mb_disas_set_info;
cc->tcg_ops = &mb_tcg_ops;

View File

@ -367,6 +367,8 @@ hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
MemTxAttrs *attrs);
int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
int mb_cpu_gdb_read_stack_protect(CPUArchState *cpu, GByteArray *buf, int reg);
int mb_cpu_gdb_write_stack_protect(CPUArchState *cpu, uint8_t *buf, int reg);
static inline uint32_t mb_cpu_read_msr(const CPUMBState *env)
{

View File

@ -39,8 +39,11 @@ enum {
GDB_PVR0 = 32 + 6,
GDB_PVR11 = 32 + 17,
GDB_EDR = 32 + 18,
GDB_SLR = 32 + 25,
GDB_SHR = 32 + 26,
};
enum {
GDB_SP_SHL,
GDB_SP_SHR,
};
int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
@ -83,12 +86,6 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
case GDB_EDR:
val = env->edr;
break;
case GDB_SLR:
val = env->slr;
break;
case GDB_SHR:
val = env->shr;
break;
default:
/* Other SRegs aren't modeled, so report a value of 0 */
val = 0;
@ -97,6 +94,23 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
return gdb_get_reg32(mem_buf, val);
}
int mb_cpu_gdb_read_stack_protect(CPUMBState *env, GByteArray *mem_buf, int n)
{
uint32_t val;
switch (n) {
case GDB_SP_SHL:
val = env->slr;
break;
case GDB_SP_SHR:
val = env->shr;
break;
default:
return 0;
}
return gdb_get_reg32(mem_buf, val);
}
int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
@ -135,12 +149,21 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
case GDB_EDR:
env->edr = tmp;
break;
case GDB_SLR:
env->slr = tmp;
break;
case GDB_SHR:
env->shr = tmp;
break;
}
return 4;
}
int mb_cpu_gdb_write_stack_protect(CPUMBState *env, uint8_t *mem_buf, int n)
{
switch (n) {
case GDB_SP_SHL:
env->slr = ldl_p(mem_buf);
break;
case GDB_SP_SHR:
env->shr = ldl_p(mem_buf);
break;
default:
return 0;
}
return 4;
}

View File

@ -121,8 +121,12 @@ static void sys_cache_info(int *isize, int *dsize)
static bool have_coherent_icache;
#endif
#if defined(__aarch64__) && !defined(CONFIG_DARWIN)
/* Apple does not expose CTR_EL0, so we must use system interfaces. */
#if defined(__aarch64__) && !defined(CONFIG_DARWIN) && !defined(CONFIG_WIN32)
/*
* Apple does not expose CTR_EL0, so we must use system interfaces.
* Windows neither, but we use a generic implementation of flush_idcache_range
* in this case.
*/
static uint64_t save_ctr_el0;
static void arch_cache_info(int *isize, int *dsize)
{
@ -225,7 +229,11 @@ static void __attribute__((constructor)) init_cache_info(void)
/* Caches are coherent and do not require flushing; symbol inline. */
#elif defined(__aarch64__)
#elif defined(__aarch64__) && !defined(CONFIG_WIN32)
/*
* For Windows, we use generic implementation of flush_idcache_range, that
* performs a call to FlushInstructionCache, through __builtin___clear_cache.
*/
#ifdef CONFIG_DARWIN
/* Apple does not expose CTR_EL0, so we must use system interfaces. */