Skip to content

Commit

Permalink
Merge tag 'pull-misc-20240409' of https://gitlab.com/rth7680/qemu int…
Browse files Browse the repository at this point in the history
…o staging

target/m68k: Fix fp accrued exception reporting
target/hppa: Fix IIAOQ, IIASQ for pa2.0
target/sh4: Fixes to mac.l and mac.w saturation
target/sh4: Fixes to illegal delay slot reporting
linux-user: Fix waitid return of siginfo_t and rusage
linux-user: Preserve unswapped siginfo_t for strace
tcg/optimize: Do not attempt to constant fold neg_vec
accel/tcg: Improve can_do_io management, mmio bug fix

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmYVl/kdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/MXgf/bMzLStvB+DvcpKCR
# hxewlDvNaDHntpXc0+3KzFPOeP9ELGlRDWSUcsdfR0v6BjUQHoUx9t+wC7R/Qe1B
# K9EWQUW9ayU++ELF9dXqtNDLGZaaSAx73PuCd+sDykBdj4/iuX0yc6htWQ+AbP0L
# x1j8CCKuCy/qDjQXyaAtCltlUurHgnswBgnZBxa2Bm0OSszDEBe49IXRIuFW5CcH
# PkVT250zZXU1lblOhpSnOBApZgxbSotk3Wdz7ARbzWisrCEW5x91ClWrP88odjX4
# wiRAe+LvFeLBjlFo+TWbdsvU6Zu2TNxSbv/Tr0HQSFoDkiXKU+5IM4L9Rx9x9EMo
# x1lmkg==
# =FYg/
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 09 Apr 2024 20:33:13 BST
# 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-misc-20240409' of https://gitlab.com/rth7680/qemu:
  linux-user: Preserve unswapped siginfo_t for strace
  accel/tcg: Improve can_do_io management
  target/s390x: Use insn_start from DisasContextBase
  target/riscv: Use insn_start from DisasContextBase
  target/microblaze: Use insn_start from DisasContextBase
  target/i386: Preserve DisasContextBase.insn_start across rewind
  target/hppa: Use insn_start from DisasContextBase
  target/arm: Use insn_start from DisasContextBase
  accel/tcg: Add insn_start to DisasContextBase
  tcg: Add TCGContext.emit_before_op
  target/m68k: Map FPU exceptions to FPSR register
  target/sh4: add missing CHECK_NOT_DELAY_SLOT
  target/sh4: Fix mac.w with saturation enabled
  target/sh4: Fix mac.l with saturation enabled
  target/sh4: Merge mach and macl into a union
  target/sh4: mac.w: memory accesses are 16-bit words
  target/hppa: Fix IIAOQ, IIASQ for pa2.0
  linux-user: replace calloc() with g_new0()
  linux-user: Fix waitid return of siginfo_t and rusage
  tcg/optimize: Do not attempt to constant fold neg_vec

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Apr 9, 2024
2 parents 927284d + 143bcc1 commit fee571c
Show file tree
Hide file tree
Showing 33 changed files with 412 additions and 129 deletions.
47 changes: 25 additions & 22 deletions accel/tcg/translator.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,14 @@

static void set_can_do_io(DisasContextBase *db, bool val)
{
if (db->saved_can_do_io != val) {
db->saved_can_do_io = val;

QEMU_BUILD_BUG_ON(sizeof_field(CPUState, neg.can_do_io) != 1);
tcg_gen_st8_i32(tcg_constant_i32(val), tcg_env,
offsetof(ArchCPU, parent_obj.neg.can_do_io) -
offsetof(ArchCPU, env));
}
QEMU_BUILD_BUG_ON(sizeof_field(CPUState, neg.can_do_io) != 1);
tcg_gen_st8_i32(tcg_constant_i32(val), tcg_env,
offsetof(ArchCPU, parent_obj.neg.can_do_io) -
offsetof(ArchCPU, env));
}

bool translator_io_start(DisasContextBase *db)
{
set_can_do_io(db, true);

/*
* Ensure that this instruction will be the last in the TB.
* The target may override this to something more forceful.
Expand Down Expand Up @@ -84,13 +78,6 @@ static TCGOp *gen_tb_start(DisasContextBase *db, uint32_t cflags)
- offsetof(ArchCPU, env));
}

/*
* cpu->neg.can_do_io is set automatically here at the beginning of
* each translation block. The cost is minimal, plus it would be
* very easy to forget doing it in the translator.
*/
set_can_do_io(db, db->max_insns == 1);

return icount_start_insn;
}

Expand Down Expand Up @@ -129,6 +116,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
{
uint32_t cflags = tb_cflags(tb);
TCGOp *icount_start_insn;
TCGOp *first_insn_start = NULL;
bool plugin_enabled;

/* Initialize DisasContext */
Expand All @@ -139,7 +127,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
db->num_insns = 0;
db->max_insns = *max_insns;
db->singlestep_enabled = cflags & CF_SINGLE_STEP;
db->saved_can_do_io = -1;
db->insn_start = NULL;
db->host_addr[0] = host_pc;
db->host_addr[1] = NULL;

Expand All @@ -157,6 +145,10 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
while (true) {
*max_insns = ++db->num_insns;
ops->insn_start(db, cpu);
db->insn_start = tcg_last_op();
if (first_insn_start == NULL) {
first_insn_start = db->insn_start;
}
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */

if (plugin_enabled) {
Expand All @@ -169,10 +161,6 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
* done next -- either exiting this loop or locate the start of
* the next instruction.
*/
if (db->num_insns == db->max_insns) {
/* Accept I/O on the last instruction. */
set_can_do_io(db, true);
}
ops->translate_insn(db, cpu);

/*
Expand Down Expand Up @@ -205,6 +193,21 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
ops->tb_stop(db, cpu);
gen_tb_end(tb, cflags, icount_start_insn, db->num_insns);

/*
* Manage can_do_io for the translation block: set to false before
* the first insn and set to true before the last insn.
*/
if (db->num_insns == 1) {
tcg_debug_assert(first_insn_start == db->insn_start);
} else {
tcg_debug_assert(first_insn_start != db->insn_start);
tcg_ctx->emit_before_op = first_insn_start;
set_can_do_io(db, false);
}
tcg_ctx->emit_before_op = db->insn_start;
set_can_do_io(db, true);
tcg_ctx->emit_before_op = NULL;

if (plugin_enabled) {
plugin_gen_tb_end(cpu, db->num_insns);
}
Expand Down
4 changes: 3 additions & 1 deletion include/exec/translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ typedef enum DisasJumpType {
* @singlestep_enabled: "Hardware" single stepping enabled.
* @saved_can_do_io: Known value of cpu->neg.can_do_io, or -1 for unknown.
* @plugin_enabled: TCG plugin enabled in this TB.
* @insn_start: The last op emitted by the insn_start hook,
* which is expected to be INDEX_op_insn_start.
*
* Architecture-agnostic disassembly context.
*/
Expand All @@ -85,8 +87,8 @@ typedef struct DisasContextBase {
int num_insns;
int max_insns;
bool singlestep_enabled;
int8_t saved_can_do_io;
bool plugin_enabled;
struct TCGOp *insn_start;
void *host_addr[2];
} DisasContextBase;

Expand Down
6 changes: 6 additions & 0 deletions include/tcg/tcg.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,12 @@ struct TCGContext {
QTAILQ_HEAD(, TCGOp) ops, free_ops;
QSIMPLEQ_HEAD(, TCGLabel) labels;

/*
* When clear, new ops are added to the tail of @ops.
* When set, new ops are added in front of @emit_before_op.
*/
TCGOp *emit_before_op;

/* Tells which temporary holds a given register.
It does not take into account fixed registers */
TCGTemp *reg_to_temp[TCG_TARGET_NB_REGS];
Expand Down
6 changes: 1 addition & 5 deletions linux-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -928,11 +928,7 @@ int main(int argc, char **argv, char **envp)
* Prepare copy of argv vector for target.
*/
target_argc = argc - optind;
target_argv = calloc(target_argc + 1, sizeof (char *));
if (target_argv == NULL) {
(void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
exit(EXIT_FAILURE);
}
target_argv = g_new0(char *, target_argc + 1);

/*
* If argv0 is specified (using '-0' switch) we replace
Expand Down
12 changes: 9 additions & 3 deletions linux-user/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
CPUState *cpu = env_cpu(cpu_env);
abi_ulong handler;
sigset_t set;
target_siginfo_t unswapped;
target_sigset_t target_old_set;
struct target_sigaction *sa;
TaskState *ts = get_task_state(cpu);
Expand All @@ -1182,9 +1183,14 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
k->pending = 0;

/*
* Writes out siginfo values byteswapped, accordingly to the target. It also
* cleans the si_type from si_code making it correct for the target.
* Writes out siginfo values byteswapped, accordingly to the target.
* It also cleans the si_type from si_code making it correct for
* the target. We must hold on to the original unswapped copy for
* strace below, because si_type is still required there.
*/
if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
unswapped = k->info;
}
tswap_siginfo(&k->info, &k->info);

sig = gdb_handlesig(cpu, sig, NULL, &k->info, sizeof(k->info));
Expand All @@ -1197,7 +1203,7 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
}

if (unlikely(qemu_loglevel_mask(LOG_STRACE))) {
print_taken_signal(sig, &k->info);
print_taken_signal(sig, &unswapped);
}

if (handler == TARGET_SIG_DFL) {
Expand Down
22 changes: 16 additions & 6 deletions linux-user/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -9272,14 +9272,24 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR_waitid
case TARGET_NR_waitid:
{
struct rusage ru;
siginfo_t info;
info.si_pid = 0;
ret = get_errno(safe_waitid(arg1, arg2, &info, arg4, NULL));
if (!is_error(ret) && arg3 && info.si_pid != 0) {
if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))

ret = get_errno(safe_waitid(arg1, arg2, (arg3 ? &info : NULL),
arg4, (arg5 ? &ru : NULL)));
if (!is_error(ret)) {
if (arg3) {
p = lock_user(VERIFY_WRITE, arg3,
sizeof(target_siginfo_t), 0);
if (!p) {
return -TARGET_EFAULT;
}
host_to_target_siginfo(p, &info);
unlock_user(p, arg3, sizeof(target_siginfo_t));
}
if (arg5 && host_to_target_rusage(arg5, &ru)) {
return -TARGET_EFAULT;
host_to_target_siginfo(p, &info);
unlock_user(p, arg3, sizeof(target_siginfo_t));
}
}
}
return ret;
Expand Down
2 changes: 1 addition & 1 deletion target/arm/tcg/translate-a64.c
Original file line number Diff line number Diff line change
Expand Up @@ -14179,7 +14179,7 @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
pc_arg &= ~TARGET_PAGE_MASK;
}
tcg_gen_insn_start(pc_arg, 0, 0);
dc->insn_start = tcg_last_op();
dc->insn_start_updated = false;
}

static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
Expand Down
2 changes: 1 addition & 1 deletion target/arm/tcg/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -9273,7 +9273,7 @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
condexec_bits = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
}
tcg_gen_insn_start(pc_arg, condexec_bits, 0);
dc->insn_start = tcg_last_op();
dc->insn_start_updated = false;
}

static bool arm_check_kernelpage(DisasContext *dc)
Expand Down
12 changes: 6 additions & 6 deletions target/arm/tcg/translate.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,10 @@ typedef struct DisasContext {
uint8_t gm_blocksize;
/* True if this page is guarded. */
bool guarded_page;
/* True if the current insn_start has been updated. */
bool insn_start_updated;
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
int c15_cpar;
/* TCG op of the current insn_start. */
TCGOp *insn_start;
/* Offset from VNCR_EL2 when FEAT_NV2 redirects this reg to memory */
uint32_t nv2_redirect_offset;
} DisasContext;
Expand Down Expand Up @@ -276,10 +276,10 @@ static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
syn &= ARM_INSN_START_WORD2_MASK;
syn >>= ARM_INSN_START_WORD2_SHIFT;

/* We check and clear insn_start_idx to catch multiple updates. */
assert(s->insn_start != NULL);
tcg_set_insn_start_param(s->insn_start, 2, syn);
s->insn_start = NULL;
/* Check for multiple updates. */
assert(!s->insn_start_updated);
s->insn_start_updated = true;
tcg_set_insn_start_param(s->base.insn_start, 2, syn);
}

static inline int curr_insn_len(DisasContext *s)
Expand Down
20 changes: 11 additions & 9 deletions target/hppa/int_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,10 @@ void hppa_cpu_do_interrupt(CPUState *cs)

/* step 3 */
/*
* For pa1.x, IIASQ is simply a copy of IASQ.
* For pa2.0, IIASQ is the top bits of the virtual address,
* or zero if translation is disabled.
* IIASQ is the top bits of the virtual address, or zero if translation
* is disabled -- with PSW_W == 0, this will reduce to the space.
*/
if (!hppa_is_pa20(env)) {
env->cr[CR_IIASQ] = env->iasq_f >> 32;
env->cr_back[0] = env->iasq_b >> 32;
} else if (old_psw & PSW_C) {
if (old_psw & PSW_C) {
env->cr[CR_IIASQ] =
hppa_form_gva_psw(old_psw, env->iasq_f, env->iaoq_f) >> 32;
env->cr_back[0] =
Expand All @@ -123,8 +119,14 @@ void hppa_cpu_do_interrupt(CPUState *cs)
env->cr[CR_IIASQ] = 0;
env->cr_back[0] = 0;
}
env->cr[CR_IIAOQ] = env->iaoq_f;
env->cr_back[1] = env->iaoq_b;
/* IIAOQ is the full offset for wide mode, or 32 bits for narrow mode. */
if (old_psw & PSW_W) {
env->cr[CR_IIAOQ] = env->iaoq_f;
env->cr_back[1] = env->iaoq_b;
} else {
env->cr[CR_IIAOQ] = (uint32_t)env->iaoq_f;
env->cr_back[1] = (uint32_t)env->iaoq_b;
}

if (old_psw & PSW_Q) {
/* step 5 */
Expand Down
18 changes: 9 additions & 9 deletions target/hppa/sys_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,21 +78,21 @@ target_ulong HELPER(swap_system_mask)(CPUHPPAState *env, target_ulong nsm)

void HELPER(rfi)(CPUHPPAState *env)
{
env->iasq_f = (uint64_t)env->cr[CR_IIASQ] << 32;
env->iasq_b = (uint64_t)env->cr_back[0] << 32;
env->iaoq_f = env->cr[CR_IIAOQ];
env->iaoq_b = env->cr_back[1];
uint64_t mask;

cpu_hppa_put_psw(env, env->cr[CR_IPSW]);

/*
* For pa2.0, IIASQ is the top bits of the virtual address.
* To recreate the space identifier, remove the offset bits.
* For pa1.x, the mask reduces to no change to space.
*/
if (hppa_is_pa20(env)) {
env->iasq_f &= ~env->iaoq_f;
env->iasq_b &= ~env->iaoq_b;
}
mask = gva_offset_mask(env->psw);

cpu_hppa_put_psw(env, env->cr[CR_IPSW]);
env->iaoq_f = env->cr[CR_IIAOQ];
env->iaoq_b = env->cr_back[1];
env->iasq_f = (env->cr[CR_IIASQ] << 32) & ~(env->iaoq_f & mask);
env->iasq_b = (env->cr_back[0] << 32) & ~(env->iaoq_b & mask);
}

static void getshadowregs(CPUHPPAState *env)
Expand Down
10 changes: 5 additions & 5 deletions target/hppa/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ typedef struct DisasCond {
typedef struct DisasContext {
DisasContextBase base;
CPUState *cs;
TCGOp *insn_start;

uint64_t iaoq_f;
uint64_t iaoq_b;
Expand All @@ -62,6 +61,7 @@ typedef struct DisasContext {
int privilege;
bool psw_n_nonzero;
bool is_pa20;
bool insn_start_updated;

#ifdef CONFIG_USER_ONLY
MemOp unalign;
Expand Down Expand Up @@ -300,9 +300,9 @@ void hppa_translate_init(void)

static void set_insn_breg(DisasContext *ctx, int breg)
{
assert(ctx->insn_start != NULL);
tcg_set_insn_start_param(ctx->insn_start, 2, breg);
ctx->insn_start = NULL;
assert(!ctx->insn_start_updated);
ctx->insn_start_updated = true;
tcg_set_insn_start_param(ctx->base.insn_start, 2, breg);
}

static DisasCond cond_make_f(void)
Expand Down Expand Up @@ -4694,7 +4694,7 @@ static void hppa_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
DisasContext *ctx = container_of(dcbase, DisasContext, base);

tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b, 0);
ctx->insn_start = tcg_last_op();
ctx->insn_start_updated = false;
}

static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
Expand Down
3 changes: 3 additions & 0 deletions target/i386/tcg/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ typedef struct DisasContext {
TCGv_i64 tmp1_i64;

sigjmp_buf jmpbuf;
TCGOp *prev_insn_start;
TCGOp *prev_insn_end;
} DisasContext;

Expand Down Expand Up @@ -3123,6 +3124,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
/* END TODO */
s->base.num_insns--;
tcg_remove_ops_after(s->prev_insn_end);
s->base.insn_start = s->prev_insn_start;
s->base.is_jmp = DISAS_TOO_MANY;
return false;
default:
Expand Down Expand Up @@ -6995,6 +6997,7 @@ static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
DisasContext *dc = container_of(dcbase, DisasContext, base);
target_ulong pc_arg = dc->base.pc_next;

dc->prev_insn_start = dc->base.insn_start;
dc->prev_insn_end = tcg_last_op();
if (tb_cflags(dcbase->tb) & CF_PCREL) {
pc_arg &= ~TARGET_PAGE_MASK;
Expand Down

0 comments on commit fee571c

Please sign in to comment.