qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2.2 1/2] target-xtensa: add missing window check for


From: Max Filippov
Subject: [Qemu-devel] [PATCH 2.2 1/2] target-xtensa: add missing window check for entry
Date: Fri, 7 Nov 2014 23:40:47 +0300

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: address@hidden
Signed-off-by: Max Filippov <address@hidden>
---
 target-xtensa/cpu.h       | 6 ++++++
 target-xtensa/op_helper.c | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index beb5486..ac463f2 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -472,6 +472,12 @@ static inline xtensa_tlb_entry 
*xtensa_tlb_get_entry(CPUXtensaState *env,
         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
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index dae1386..872e5a8 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -235,6 +235,12 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, 
uint32_t s, uint32_t imm)
                 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] |=
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]