@@ -1779,13 +1780,25 @@ void riscv_cpu_do_interrupt(CPUState *cs)
env->pc += 4;
return;
case RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT:
+ if (always_storeamo) {
+ cause = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
+ }
+ goto load_store_fault;
case RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT:
case RISCV_EXCP_LOAD_ADDR_MIS:
case RISCV_EXCP_STORE_AMO_ADDR_MIS:
case RISCV_EXCP_LOAD_ACCESS_FAULT:
+ if (always_storeamo) {
+ cause = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
+ }
+ goto load_store_fault;
case RISCV_EXCP_STORE_AMO_ACCESS_FAULT:
case RISCV_EXCP_LOAD_PAGE_FAULT:
case RISCV_EXCP_STORE_PAGE_FAULT:
+ if (always_storeamo) {
+ cause = RISCV_EXCP_STORE_PAGE_FAULT;
+ }
+ load_store_fault:
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d44103a273..8961dda244 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -121,6 +121,7 @@ typedef struct DisasContext {
bool fcfi_lp_expected;
/* zicfiss extension, if shadow stack was enabled during TB gen */
bool bcfi_enabled;
+ target_ulong excp_uw2;
} DisasContext;
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -144,6 +145,9 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
#define get_address_xl(ctx) ((ctx)->address_xl)
#endif
+#define SET_INSTR_ALWAYS_STORE_AMO(ctx) \
+ (ctx->excp_uw2 |= RISCV_UW2_ALWAYS_STORE_AMO)
+
/* The word size for this machine mode. */
static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
{
@@ -214,6 +218,12 @@ static void decode_save_opc(DisasContext *ctx)
assert(!ctx->insn_start_updated);
ctx->insn_start_updated = true;
tcg_set_insn_start_param(ctx->base.insn_start, 1, ctx->opcode);
+
+ if (ctx->excp_uw2) {
+ tcg_set_insn_start_param(ctx->base.insn_start, 2,
+ ctx->excp_uw2);
+ ctx->excp_uw2 = 0;
+ }