aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/include/asm/processor.h
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2011-10-30 10:16:48 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-10-30 10:16:43 -0400
commitccf45cafb0805978e6f13a672caca0e536e87cad (patch)
treef4abcadaf691ee952527ad434db3ab91b6e46e7f /arch/s390/include/asm/processor.h
parent20b40a794baf3b4b0320c0a77ce944d5d1a01f25 (diff)
[S390] addressing mode limits and psw address wrapping
An instruction with an address right below the adress limit for the current addressing mode will wrap. The instruction restart logic in the protection fault handler and the signal code need to follow the wrapping rules to find the correct instruction address. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/include/asm/processor.h')
-rw-r--r--arch/s390/include/asm/processor.h22
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index a4b6229e5d4b..306c93c1b184 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -187,7 +187,6 @@ static inline void __load_psw(psw_t psw)
187 * Set PSW mask to specified value, while leaving the 187 * Set PSW mask to specified value, while leaving the
188 * PSW addr pointing to the next instruction. 188 * PSW addr pointing to the next instruction.
189 */ 189 */
190
191static inline void __load_psw_mask (unsigned long mask) 190static inline void __load_psw_mask (unsigned long mask)
192{ 191{
193 unsigned long addr; 192 unsigned long addr;
@@ -212,6 +211,27 @@ static inline void __load_psw_mask (unsigned long mask)
212 : "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc"); 211 : "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
213#endif /* __s390x__ */ 212#endif /* __s390x__ */
214} 213}
214
215/*
216 * Rewind PSW instruction address by specified number of bytes.
217 */
218static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc)
219{
220#ifndef __s390x__
221 if (psw.addr & PSW_ADDR_AMODE)
222 /* 31 bit mode */
223 return (psw.addr - ilc) | PSW_ADDR_AMODE;
224 /* 24 bit mode */
225 return (psw.addr - ilc) & ((1UL << 24) - 1);
226#else
227 unsigned long mask;
228
229 mask = (psw.mask & PSW_MASK_EA) ? -1UL :
230 (psw.mask & PSW_MASK_BA) ? (1UL << 31) - 1 :
231 (1UL << 24) - 1;
232 return (psw.addr - ilc) & mask;
233#endif
234}
215 235
216/* 236/*
217 * Function to stop a processor until an interruption occurred 237 * Function to stop a processor until an interruption occurred