Skip to content

Commit 298a049

Browse files
rth7680pm215
authored andcommitted
target/arm: Make DisasContext.{fp, sve}_access_checked tristate
The check for fp_excp_el in assert_fp_access_checked is incorrect. For SME, with StreamingMode enabled, the access is really against the streaming mode vectors, and access to the normal fp registers is allowed to be disabled. C.f. sme_enabled_check. Convert sve_access_checked to match, even though we don't currently check the exception state. Cc: [email protected] Fixes: 3d74825 ("target/arm: Add SME enablement checks") Signed-off-by: Richard Henderson <[email protected]> Message-id: [email protected] Reviewed-by: Peter Maydell <[email protected]> Signed-off-by: Peter Maydell <[email protected]>
1 parent e6c38d2 commit 298a049

File tree

3 files changed

+17
-12
lines changed

3 files changed

+17
-12
lines changed

target/arm/tcg/translate-a64.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,14 +1381,14 @@ static bool fp_access_check_only(DisasContext *s)
13811381
{
13821382
if (s->fp_excp_el) {
13831383
assert(!s->fp_access_checked);
1384-
s->fp_access_checked = true;
1384+
s->fp_access_checked = -1;
13851385

13861386
gen_exception_insn_el(s, 0, EXCP_UDEF,
13871387
syn_fp_access_trap(1, 0xe, false, 0),
13881388
s->fp_excp_el);
13891389
return false;
13901390
}
1391-
s->fp_access_checked = true;
1391+
s->fp_access_checked = 1;
13921392
return true;
13931393
}
13941394

@@ -1465,13 +1465,13 @@ bool sve_access_check(DisasContext *s)
14651465
syn_sve_access_trap(), s->sve_excp_el);
14661466
goto fail_exit;
14671467
}
1468-
s->sve_access_checked = true;
1468+
s->sve_access_checked = 1;
14691469
return fp_access_check(s);
14701470

14711471
fail_exit:
14721472
/* Assert that we only raise one exception per instruction. */
14731473
assert(!s->sve_access_checked);
1474-
s->sve_access_checked = true;
1474+
s->sve_access_checked = -1;
14751475
return false;
14761476
}
14771477

@@ -1500,8 +1500,9 @@ bool sme_enabled_check(DisasContext *s)
15001500
* sme_excp_el by itself for cpregs access checks.
15011501
*/
15021502
if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
1503-
s->fp_access_checked = true;
1504-
return sme_access_check(s);
1503+
bool ret = sme_access_check(s);
1504+
s->fp_access_checked = (ret ? 1 : -1);
1505+
return ret;
15051506
}
15061507
return fp_access_check_only(s);
15071508
}
@@ -10257,8 +10258,8 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1025710258
s->insn = insn;
1025810259
s->base.pc_next = pc + 4;
1025910260

10260-
s->fp_access_checked = false;
10261-
s->sve_access_checked = false;
10261+
s->fp_access_checked = 0;
10262+
s->sve_access_checked = 0;
1026210263

1026310264
if (s->pstate_il) {
1026410265
/*

target/arm/tcg/translate-a64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
6565
static inline void assert_fp_access_checked(DisasContext *s)
6666
{
6767
#ifdef CONFIG_DEBUG_TCG
68-
if (unlikely(!s->fp_access_checked || s->fp_excp_el)) {
68+
if (unlikely(s->fp_access_checked <= 0)) {
6969
fprintf(stderr, "target-arm: FP access check missing for "
7070
"instruction 0x%08x\n", s->insn);
7171
abort();

target/arm/tcg/translate.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,19 @@ typedef struct DisasContext {
9292
bool aarch64;
9393
bool thumb;
9494
bool lse2;
95-
/* Because unallocated encodings generate different exception syndrome
95+
/*
96+
* Because unallocated encodings generate different exception syndrome
9697
* information from traps due to FP being disabled, we can't do a single
9798
* "is fp access disabled" check at a high level in the decode tree.
9899
* To help in catching bugs where the access check was forgotten in some
99100
* code path, we set this flag when the access check is done, and assert
100101
* that it is set at the point where we actually touch the FP regs.
102+
* 0: not checked,
103+
* 1: checked, access ok
104+
* -1: checked, access denied
101105
*/
102-
bool fp_access_checked;
103-
bool sve_access_checked;
106+
int8_t fp_access_checked;
107+
int8_t sve_access_checked;
104108
/* ARMv8 single-step state (this is distinct from the QEMU gdbstub
105109
* single-step support).
106110
*/

0 commit comments

Comments
 (0)