Skip to contentSkip to conversation

target-xtensa: fix missing window check in entry

PATCH New Max Filippov 1 participant 3 messages Nov 7, 2014

lore
Share & tools
lore
#0 lore raw

cover target-xtensa: fix missing window check in entry

Hi,

this series fixes missing window check in the entry opcode and adds a test for it.

Max Filippov (2):
target-xtensa: add missing window check for entry
target-xtensa: add entry overflow test

 target-xtensa/cpu.h              |  6 +++++
 target-xtensa/op_helper.c        |  6 +++++
 tests/tcg/xtensa/test_windowed.S | 51 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+)
Signature · 1 line
1.8.1.4
#1 lore raw

PATCH 1/2 target-xtensa: add missing window check for entry

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.

---
 target-xtensa/cpu.h       | 6 ++++++
 target-xtensa/op_helper.c | 6 ++++++
 2 files changed, 12 insertions(+)
target-xtensa/cpu.h +6 -0
index beb5486..ac463f2 100644
@@ -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
target-xtensa/op_helper.c +6 -0
index dae1386..872e5a8 100644
@@ -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] |=
Signature · 1 line
1.8.1.4
#2 lore raw

PATCH 2/2 target-xtensa: add entry overflow test

In reply to Max Filippov

Check that entry instruction raises window overflow exception when PS.CALLINC points to live registers.

---
 tests/tcg/xtensa/test_windowed.S | 51 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
tests/tcg/xtensa/test_windowed.S +51 -0
index 3de6d37..d851e8f 100644
@@ -299,4 +299,55 @@ test entry
     entry_test 12
 test_end
 
+.macro entry_overflow_test window, free, next_window
+    set_vector window_overflow_4, 0
+    set_vector window_overflow_8, 0
+    set_vector window_overflow_12, 0
+    set_vector window_overflow_\next_window, 10f
+
+    movi    a2, \window
+    movi    a2, \free
+    movi    a2, \next_window
+    reset_window %(1 | ((1 | (1 << ((\next_window) / 4))) << ((\free) / 4)))
+    reset_ps
+    movi    a2, 0x4000f | ((\window) << 14)
+    wsr     a2, ps
+    isync
+    movi    a3, 0x12345678
+    j       1f
+    .align  4
+1:
+    entry   a3, 0x5678
+    test_fail
+    .align  4
+10:
+    rsr     a2, epc1
+    movi    a3, 1b
+    assert  eq, a2, a3
+    movi    a2, 2f
+    wsr     a2, epc1
+
+    rsr     a2, windowbase
+    movi    a3, (\free) / 4
+    assert  eq, a2, a3
+    rfwo
+2:
+.endm
+
+.macro all_entry_overflow_tests
+    .irp window, 4, 8, 12
+    .irp next_window, 4, 8, 12
+    .irp free, 4, 8, 12
+    .if \free <= \window
+    entry_overflow_test \window, \free, \next_window
+    .endif
+    .endr
+    .endr
+    .endr
+.endm
+
+test entry_overflow
+    all_entry_overflow_tests
+test_end
+
 test_suite_end
Signature · 1 line
1.8.1.4