Entry opcode needs to check if moving to new register frame would cause
register window overflow. Entry used in function prologue never
overflows because preceding windowed call* opcode writes return address
to the target register window frame, causing overflow exceptions at the
point of call. But when a sequence of entry opcodes is used for register
window spilling there may not be a call or other opcode that would cause
window check between entries and they would not raise overflow exception
themselves resulting in data corruption.
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
env->itlb[wi] + ei;
}
+static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
+{
+ return env->sregs[WINDOW_START] |
+ (env->sregs[WINDOW_START] << env->config->nareg / 4);
+}
+
/* MMU modes definitions */
#define MMU_MODE0_SUFFIX _ring0
#define MMU_MODE1_SUFFIX _ring1
pc, env->sregs[PS]);
HELPER(exception_cause)(env, pc, ILLEGAL_INSTRUCTION_CAUSE);
} else {
+ uint32_t windowstart = xtensa_replicate_windowstart(env) >>
+ (env->sregs[WINDOW_BASE] + 1);
+
+ if (windowstart & ((1 << callinc) - 1)) {
+ HELPER(window_check)(env, pc, callinc);
+ }
env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - (imm << 3);
rotate_window(env, callinc);
env->sregs[WINDOW_START] |=