summaryrefslogtreecommitdiffstats
path: root/arch/s390/include/asm/processor.h
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2011-10-30 15:16:48 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-10-30 15:16:43 +0100
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 a4b6229e5d4..306c93c1b18 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)
* Set PSW mask to specified value, while leaving the
* PSW addr pointing to the next instruction.
*/
-
static inline void __load_psw_mask (unsigned long mask)
{
unsigned long addr;
@@ -212,6 +211,27 @@ static inline void __load_psw_mask (unsigned long mask)
: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
#endif /* __s390x__ */
}
+
+/*
+ * Rewind PSW instruction address by specified number of bytes.
+ */
+static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc)
+{
+#ifndef __s390x__
+ if (psw.addr & PSW_ADDR_AMODE)
+ /* 31 bit mode */
+ return (psw.addr - ilc) | PSW_ADDR_AMODE;
+ /* 24 bit mode */
+ return (psw.addr - ilc) & ((1UL << 24) - 1);
+#else
+ unsigned long mask;
+
+ mask = (psw.mask & PSW_MASK_EA) ? -1UL :
+ (psw.mask & PSW_MASK_BA) ? (1UL << 31) - 1 :
+ (1UL << 24) - 1;
+ return (psw.addr - ilc) & mask;
+#endif
+}
/*
* Function to stop a processor until an interruption occurred