qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 58/88] target-xtensa: add missing window check for e


From: Michael Roth
Subject: [Qemu-devel] [PATCH 58/88] target-xtensa: add missing window check for entry
Date: Thu, 8 Jan 2015 11:34:02 -0600

From: Max Filippov <address@hidden>

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>
(cherry picked from commit 1b3e71f8ee17ced609213d9b41758110f3c026e9)
Signed-off-by: Michael Roth <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 d797d26..6e4e2b2 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -471,6 +471,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.9.1




reply via email to

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