Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions hw/arm/tests/native_int_check.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* 4 x18, x29 and x30 as ordinary operands and load destinations
* 5 NZCV set before a page-crossing (slow-path) load and store and
* consumed after them
* 7 MRS TPIDR_EL0 / TPIDRRO_EL0 (plain field reads) in the middle of
* ALU code, after MSR TPIDR_EL0 at EL0 and TPIDRRO_EL0 set at EL1
* 6 a store over code later in the same block (the store's slow
* path invalidates the TB being executed), then the architectural
* DC CVAU/IC IVAU/ISB sequence: registers and NZCV written before
Expand Down Expand Up @@ -124,6 +126,8 @@ _start:
dsb ish
isb

ldr x0, =0x7070707070707070
msr tpidrro_el0, x0
ldr x0, =BUF
msr sp_el0, x0
adr x0, el0_main
Expand Down Expand Up @@ -303,6 +307,19 @@ fault2:
CHK x15, 0x1111 - 0x2222, 6
CHK x17, 1, 6

/* 7: TLS register reads in the middle of a block */
LI x0, 0x0123456789abcdef
msr tpidr_el0, x0
movz x1, #7
mrs x2, tpidr_el0
add x3, x2, x1
mrs x4, tpidrro_el0
eor x5, x4, x3
mrs x6, tpidr_el0
CHK x3, 0x0123456789abcdef + 7, 7
CHK x5, 0x7070707070707070 ^ (0x0123456789abcdef + 7), 7
CHK x6, 0x0123456789abcdef, 7

svc #0

/* copied to CODE; x11 = the new instruction, x12 = where it goes */
Expand Down
2 changes: 2 additions & 0 deletions include/tcg/tcg-sit.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ typedef enum SitKind
SIT_BCOND,
SIT_CBZ,
SIT_TBZ,
/* rt = the 64-bit CPU state field at offset imm (a system register read with no side effects). */
SIT_LDENV,
} SitKind;

/* SitInsn.mode: addressing mode of a load or store. */
Expand Down
22 changes: 22 additions & 0 deletions target/arm/tcg/translate-a64.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,23 @@ static SitInsn* sit_ldst(DisasContext* s, SitKind kind, int rt, int rt2, int rn,
return si;
}

/*
* MRS of a system register that is a plain 64-bit field with no access
* check, read function or I/O (e.g. TPIDR_EL0, TPIDRRO_EL0): a load from
* the CPU state. Only if this insn has not emitted TCG ops yet.
*/
static bool sit_ldenv(DisasContext* s, int rt, int ofs)
{
SitInsn* si;

if (!sit_admit(s, 0) || tcg_last_op() != s->base.insn_start || ofs < 0 || (ofs & 7)) { return false; }
si = sit_new(s, SIT_LDENV);
si->rt = sit_reg(rt, false);
si->imm = ofs;
sit_emit(s, si);
return true;
}

/* A conditional branch to @l (taken path): ends the region. */
static void sit_brcond(DisasContext* s, SitInsn* si, TCGLabel* l)
{
Expand Down Expand Up @@ -2559,6 +2576,11 @@ static void handle_sys(DisasContext* s, bool isread, unsigned int op0, unsigned
default: tcg_debug_assert_not_reached();
}

if (isread && !(ri->type & (ARM_CP_IO | ARM_CP_CONST)) && !ri->readfn && !tcg_ri &&
sit_ldenv(s, rt, cpreg_field_offset(s, ri))) {
return;
}

if (ri->type & ARM_CP_IO) {
/* I/O operations must end the TB here (whether read or write) */
need_exit_tb = translator_io_start(&s->base);
Expand Down
10 changes: 10 additions & 0 deletions tcg/aarch64/tcg-target-sit.c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,15 @@ static void sit_copy(TCGContext* s, const SitInsn* si)
if (si->nzcv & SIT_NZCV_W) { s->sit->m.nzcv = SIT_FL_DIRTY; }
}

static void sit_ldenv(TCGContext* s, const SitInsn* si)
{
TCGReg rd = sit_def(s, si->rt, sit_bit(si->rt));

if (rd == TCG_REG_XZR) { return; }
tcg_out_ldst(s, I3312_LDRX, rd, TCG_AREG0, si->imm, 3);
sit_dirty(s, si->rt);
}

static void sit_addpc(TCGContext* s, const SitInsn* si)
{
TCGReg rd = sit_def(s, si->rt, sit_bit(si->rt));
Expand Down Expand Up @@ -473,6 +482,7 @@ static void tcg_out_sit(TCGContext* s, const SitInsn* si, TCGLabel* l)
switch (si->kind) {
case SIT_COPY : sit_copy(s, si); break;
case SIT_ADDPC: sit_addpc(s, si); break;
case SIT_LDENV: sit_ldenv(s, si); break;
case SIT_LD :
case SIT_ST :
case SIT_LDP :
Expand Down
Loading