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.
Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
(cherry picked from commit 1b3e71f8ee)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
			
			
This commit is contained in:
		
							parent
							
								
									aae114b7ed
								
							
						
					
					
						commit
						ea227e222b
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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] |=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue