[S390] cleanup psw related bits and pieces
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Sun, 30 Oct 2011 14:16:50 +0000 (15:16 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Sun, 30 Oct 2011 14:16:43 +0000 (15:16 +0100)
Split out addressing mode bits from PSW_BASE_BITS, rename PSW_BASE_BITS
to PSW_MASK_BASE, get rid of psw_user32_bits, remove unused function
enabled_wait(), introduce PSW_MASK_USER, and drop PSW_MASK_MERGE macros.
Change psw_kernel_bits / psw_user_bits to contain only the bits that
are always set in the respective mode.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
20 files changed:
arch/s390/include/asm/compat.h
arch/s390/include/asm/processor.h
arch/s390/include/asm/ptrace.h
arch/s390/include/asm/system.h
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_signal.c
arch/s390/kernel/early.c
arch/s390/kernel/ipl.c
arch/s390/kernel/machine_kexec.c
arch/s390/kernel/process.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/setup.c
arch/s390/kernel/signal.c
arch/s390/kernel/smp.c
arch/s390/kernel/traps.c
arch/s390/kernel/vtime.c
arch/s390/lib/delay.c
arch/s390/mm/fault.c
drivers/s390/char/sclp_cmd.c
drivers/s390/char/sclp_quiesce.c

index cdb9b78f6c082e277f6726344bf8dfebc25f3fe0..2e49748b27dab5ca3e62c2b4f63909c50058a593 100644 (file)
@@ -12,6 +12,7 @@
 #define PSW32_MASK_IO          0x02000000UL
 #define PSW32_MASK_EXT         0x01000000UL
 #define PSW32_MASK_KEY         0x00F00000UL
+#define PSW32_MASK_BASE                0x00080000UL    /* Always one */
 #define PSW32_MASK_MCHECK      0x00040000UL
 #define PSW32_MASK_WAIT                0x00020000UL
 #define PSW32_MASK_PSTATE      0x00010000UL
 #define PSW32_MASK_CC          0x00003000UL
 #define PSW32_MASK_PM          0x00000f00UL
 
-#define PSW32_ADDR_AMODE31     0x80000000UL
+#define PSW32_MASK_USER                0x00003F00UL
+
+#define PSW32_ADDR_AMODE       0x80000000UL
 #define PSW32_ADDR_INSN                0x7FFFFFFFUL
 
-#define PSW32_BASE_BITS                0x00080000UL
+#define PSW32_DEFAULT_KEY      (((u32) PAGE_DEFAULT_ACC) << 20)
 
 #define PSW32_ASC_PRIMARY      0x00000000UL
 #define PSW32_ASC_ACCREG       0x00004000UL
 #define PSW32_ASC_SECONDARY    0x00008000UL
 #define PSW32_ASC_HOME         0x0000C000UL
 
-#define PSW32_MASK_MERGE(CURRENT,NEW) \
-       (((CURRENT) & ~(PSW32_MASK_CC|PSW32_MASK_PM)) | \
-        ((NEW) & (PSW32_MASK_CC|PSW32_MASK_PM)))
-
-extern long psw32_user_bits;
+extern u32 psw32_user_bits;
 
 #define COMPAT_USER_HZ         100
 #define COMPAT_UTS_MACHINE     "s390\0\0\0\0"
index 306c93c1b184a1da69789faaedbc04af857576a5..20ffb12d4ae9ff60e304a043d34bfa00dc0a67f6 100644 (file)
@@ -118,17 +118,17 @@ struct stack_frame {
 /*
  * Do necessary setup to start up a new thread.
  */
-#define start_thread(regs, new_psw, new_stackp) do {           \
-       regs->psw.mask  = psw_user_bits;                        \
-       regs->psw.addr  = new_psw | PSW_ADDR_AMODE;             \
-       regs->gprs[15]  = new_stackp;                           \
+#define start_thread(regs, new_psw, new_stackp) do {                   \
+       regs->psw.mask  = psw_user_bits | PSW_MASK_EA | PSW_MASK_BA;    \
+       regs->psw.addr  = new_psw | PSW_ADDR_AMODE;                     \
+       regs->gprs[15]  = new_stackp;                                   \
 } while (0)
 
-#define start_thread31(regs, new_psw, new_stackp) do {         \
-       regs->psw.mask  = psw_user32_bits;                      \
-       regs->psw.addr  = new_psw | PSW_ADDR_AMODE;             \
-       regs->gprs[15]  = new_stackp;                           \
-       crst_table_downgrade(current->mm, 1UL << 31);           \
+#define start_thread31(regs, new_psw, new_stackp) do {                 \
+       regs->psw.mask  = psw_user_bits | PSW_MASK_BA;                  \
+       regs->psw.addr  = new_psw | PSW_ADDR_AMODE;                     \
+       regs->gprs[15]  = new_stackp;                                   \
+       crst_table_downgrade(current->mm, 1UL << 31);                   \
 } while (0)
 
 /* Forward declaration, a strange C thing */
@@ -233,25 +233,15 @@ static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc)
 #endif
 }
  
-/*
- * Function to stop a processor until an interruption occurred
- */
-static inline void enabled_wait(void)
-{
-       __load_psw_mask(PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
-                       PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY);
-}
-
 /*
  * Function to drop a processor into disabled wait state
  */
-
 static inline void ATTRIB_NORET disabled_wait(unsigned long code)
 {
         unsigned long ctl_buf;
         psw_t dw_psw;
 
-        dw_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
+       dw_psw.mask = PSW_MASK_BASE | PSW_MASK_WAIT | PSW_MASK_BA | PSW_MASK_EA;
         dw_psw.addr = code;
         /* 
          * Store status and then load disabled wait psw,
index 2904cc66967a69a16f7630659b721982e1967b83..6fc00d268143f2f59382dd6128ddb5fe8e06fcfa 100644 (file)
@@ -230,6 +230,7 @@ typedef struct
 #define PSW_MASK_IO            0x02000000UL
 #define PSW_MASK_EXT           0x01000000UL
 #define PSW_MASK_KEY           0x00F00000UL
+#define PSW_MASK_BASE          0x00080000UL    /* always one */
 #define PSW_MASK_MCHECK                0x00040000UL
 #define PSW_MASK_WAIT          0x00020000UL
 #define PSW_MASK_PSTATE                0x00010000UL
@@ -239,10 +240,11 @@ typedef struct
 #define PSW_MASK_EA            0x00000000UL
 #define PSW_MASK_BA            0x00000000UL
 
+#define PSW_MASK_USER          0x00003F00UL
+
 #define PSW_ADDR_AMODE         0x80000000UL
 #define PSW_ADDR_INSN          0x7FFFFFFFUL
 
-#define PSW_BASE_BITS          0x00080000UL
 #define PSW_DEFAULT_KEY                (((unsigned long) PAGE_DEFAULT_ACC) << 20)
 
 #define PSW_ASC_PRIMARY                0x00000000UL
@@ -256,6 +258,7 @@ typedef struct
 #define PSW_MASK_DAT           0x0400000000000000UL
 #define PSW_MASK_IO            0x0200000000000000UL
 #define PSW_MASK_EXT           0x0100000000000000UL
+#define PSW_MASK_BASE          0x0000000000000000UL
 #define PSW_MASK_KEY           0x00F0000000000000UL
 #define PSW_MASK_MCHECK                0x0004000000000000UL
 #define PSW_MASK_WAIT          0x0002000000000000UL
@@ -266,11 +269,11 @@ typedef struct
 #define PSW_MASK_EA            0x0000000100000000UL
 #define PSW_MASK_BA            0x0000000080000000UL
 
+#define PSW_MASK_USER          0x00003F0000000000UL
+
 #define PSW_ADDR_AMODE         0x0000000000000000UL
 #define PSW_ADDR_INSN          0xFFFFFFFFFFFFFFFFUL
 
-#define PSW_BASE_BITS          0x0000000180000000UL
-#define PSW_BASE32_BITS                0x0000000080000000UL
 #define PSW_DEFAULT_KEY                (((unsigned long) PAGE_DEFAULT_ACC) << 52)
 
 #define PSW_ASC_PRIMARY                0x0000000000000000UL
@@ -283,18 +286,7 @@ typedef struct
 #ifdef __KERNEL__
 extern long psw_kernel_bits;
 extern long psw_user_bits;
-#ifdef CONFIG_64BIT
-extern long psw_user32_bits;
 #endif
-#endif
-
-/* This macro merges a NEW PSW mask specified by the user into
-   the currently active PSW mask CURRENT, modifying only those
-   bits in CURRENT that the user may be allowed to change: this
-   is the condition code and the program mask bits.  */
-#define PSW_MASK_MERGE(CURRENT,NEW) \
-       (((CURRENT) & ~(PSW_MASK_CC|PSW_MASK_PM)) | \
-        ((NEW) & (PSW_MASK_CC|PSW_MASK_PM)))
 
 /*
  * The s390_regs structure is used to define the elf_gregset_t.
index afb849e4bf4b57101bf4eead361df3030c40ad2e..d73cc6b60000044e48aa5253eeea2707d5d5ffba 100644 (file)
@@ -212,8 +212,10 @@ __set_psw_mask(unsigned long mask)
        __load_psw_mask(mask | (arch_local_save_flags() & ~(-1UL >> 8)));
 }
 
-#define local_mcck_enable()  __set_psw_mask(psw_kernel_bits)
-#define local_mcck_disable() __set_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK)
+#define local_mcck_enable() \
+       __set_psw_mask(psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK)
+#define local_mcck_disable() \
+       __set_psw_mask(psw_kernel_bits | PSW_MASK_DAT)
 
 #ifdef CONFIG_SMP
 
index 53acaa86dd94f353e36beb03f5c9e904c14d42d3..24b218737b9b6ed628366daa5837e15593891a91 100644 (file)
 
 #include "compat_linux.h"
 
-long psw_user32_bits   = (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
-                          PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
-                          PSW_MASK_PSTATE | PSW_DEFAULT_KEY);
-long psw32_user_bits   = (PSW32_BASE_BITS | PSW32_MASK_DAT | PSW32_ASC_HOME |
-                          PSW32_MASK_IO | PSW32_MASK_EXT | PSW32_MASK_MCHECK |
-                          PSW32_MASK_PSTATE);
+u32 psw32_user_bits = PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT |
+                     PSW32_DEFAULT_KEY | PSW32_MASK_BASE | PSW32_MASK_MCHECK |
+                     PSW32_MASK_PSTATE | PSW32_ASC_HOME;
  
 /* For this source file, we want overflow handling. */
 
index 72a1c8d8d2126857c0e1a220fcb5e1d18676ebda..fd83b69207f5fd1aed6901988f450d1a804ce58b 100644 (file)
@@ -300,9 +300,9 @@ static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
        _s390_regs_common32 regs32;
        int err, i;
 
-       regs32.psw.mask = PSW32_MASK_MERGE(psw32_user_bits,
-                                          (__u32)(regs->psw.mask >> 32));
-       regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
+       regs32.psw.mask = psw32_user_bits |
+               ((__u32)(regs->psw.mask >> 32) & PSW32_MASK_USER);
+       regs32.psw.addr = PSW32_ADDR_AMODE | (__u32) regs->psw.addr;
        for (i = 0; i < NUM_GPRS; i++)
                regs32.gprs[i] = (__u32) regs->gprs[i];
        save_access_regs(current->thread.acrs);
@@ -327,8 +327,8 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
        err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
        if (err)
                return err;
-       regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
-                                       (__u64)regs32.psw.mask << 32);
+       regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+               (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32;
        regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
        for (i = 0; i < NUM_GPRS; i++)
                regs->gprs[i] = (__u64) regs32.gprs[i];
index f297456dba7a9eb3282fe0377097e99f97a488d0..37394b3413e2776dfd24586f0578045e488bd054 100644 (file)
@@ -252,7 +252,7 @@ static noinline __init void setup_lowcore_early(void)
 {
        psw_t psw;
 
-       psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+       psw.mask = PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA;
        psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_ext_handler;
        S390_lowcore.external_new_psw = psw;
        psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
index ca0520c52547f0f70c4a7be21bd7f6e559dbcfae..296458360a32a2409ab48831173d891e1ec1cbdb 100644 (file)
@@ -2033,12 +2033,12 @@ void s390_reset_system(void (*func)(void *), void *data)
        __ctl_clear_bit(0,28);
 
        /* Set new machine check handler */
-       S390_lowcore.mcck_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
+       S390_lowcore.mcck_new_psw.mask = psw_kernel_bits | PSW_MASK_DAT;
        S390_lowcore.mcck_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
 
        /* Set new program check handler */
-       S390_lowcore.program_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
+       S390_lowcore.program_new_psw.mask = psw_kernel_bits | PSW_MASK_DAT;
        S390_lowcore.program_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
 
index 13a0b528c70bad9b5dc4aebe870a75ad9ebd5a8a..3cd0f25ab015cc7ef7633f73ab528b2ae34185df 100644 (file)
@@ -108,7 +108,7 @@ static void __do_machine_kdump(void *image)
 #ifdef CONFIG_CRASH_DUMP
        int (*start_kdump)(int) = (void *)((struct kimage *) image)->start;
 
-       __load_psw_mask(PSW_BASE_BITS | PSW_DEFAULT_KEY);
+       __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
        setup_regs();
        start_kdump(1);
 #endif
index 541a7509faebd47f7b9d5a72a1f779c3efa2e1f4..5e64a9a29ea4c921e595e330bb8bb467095954c5 100644 (file)
@@ -117,7 +117,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
        struct pt_regs regs;
 
        memset(&regs, 0, sizeof(regs));
-       regs.psw.mask = psw_kernel_bits | PSW_MASK_IO | PSW_MASK_EXT;
+       regs.psw.mask = psw_kernel_bits |
+               PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
        regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
        regs.gprs[9] = (unsigned long) fn;
        regs.gprs[10] = (unsigned long) arg;
index 3519c99ae0c01efc94536bab801db0d47497c970..41e20763886e0a321f9568d8ef99951bdeb4512d 100644 (file)
@@ -169,8 +169,9 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
                 */
                tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
                if (addr == (addr_t) &dummy->regs.psw.mask)
-                       /* Remove per bit from user psw. */
-                       tmp &= ~PSW_MASK_PER;
+                       /* Return a clean psw mask. */
+                       tmp = psw_user_bits | (tmp & PSW_MASK_USER) |
+                               PSW_MASK_EA | PSW_MASK_BA;
 
        } else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
                /*
@@ -285,17 +286,18 @@ static inline void __poke_user_per(struct task_struct *child,
 static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
 {
        struct user *dummy = NULL;
-       addr_t offset;
+       addr_t offset, tmp;
 
        if (addr < (addr_t) &dummy->regs.acrs) {
                /*
                 * psw and gprs are stored on the stack
                 */
+               tmp = (data & ~PSW_MASK_USER) ^ psw_user_bits;
                if (addr == (addr_t) &dummy->regs.psw.mask &&
 #ifdef CONFIG_COMPAT
-                   data != PSW_MASK_MERGE(psw_user32_bits, data) &&
+                   tmp != PSW_MASK_BA &&
 #endif
-                   data != PSW_MASK_MERGE(psw_user_bits, data))
+                   tmp != (PSW_MASK_EA | PSW_MASK_BA))
                        /* Invalid psw mask. */
                        return -EINVAL;
 #ifndef CONFIG_64BIT
@@ -505,21 +507,20 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
        __u32 tmp;
 
        if (addr < (addr_t) &dummy32->regs.acrs) {
+               struct pt_regs *regs = task_pt_regs(child);
                /*
                 * psw and gprs are stored on the stack
                 */
                if (addr == (addr_t) &dummy32->regs.psw.mask) {
                        /* Fake a 31 bit psw mask. */
-                       tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32);
-                       tmp = PSW32_MASK_MERGE(psw32_user_bits, tmp);
+                       tmp = (__u32)(regs->psw.mask >> 32);
+                       tmp = psw32_user_bits | (tmp & PSW32_MASK_USER);
                } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
                        /* Fake a 31 bit psw address. */
-                       tmp = (__u32) task_pt_regs(child)->psw.addr |
-                               PSW32_ADDR_AMODE31;
+                       tmp = (__u32) regs->psw.addr | PSW32_ADDR_AMODE;
                } else {
                        /* gpr 0-15 */
-                       tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw +
-                                        addr*2 + 4);
+                       tmp = *(__u32 *)((addr_t) &regs->psw + addr*2 + 4);
                }
        } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
                /*
@@ -604,20 +605,20 @@ static int __poke_user_compat(struct task_struct *child,
        addr_t offset;
 
        if (addr < (addr_t) &dummy32->regs.acrs) {
+               struct pt_regs *regs = task_pt_regs(child);
                /*
                 * psw, gprs, acrs and orig_gpr2 are stored on the stack
                 */
                if (addr == (addr_t) &dummy32->regs.psw.mask) {
                        /* Build a 64 bit psw mask from 31 bit mask. */
-                       if (tmp != PSW32_MASK_MERGE(psw32_user_bits, tmp))
+                       if ((tmp & ~PSW32_MASK_USER) != psw32_user_bits)
                                /* Invalid psw mask. */
                                return -EINVAL;
-                       task_pt_regs(child)->psw.mask =
-                               PSW_MASK_MERGE(psw_user32_bits, (__u64) tmp << 32);
+                       regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+                               (__u64)(tmp & PSW32_MASK_USER) << 32;
                } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
                        /* Build a 64 bit psw address from 31 bit address. */
-                       task_pt_regs(child)->psw.addr =
-                               (__u64) tmp & PSW32_ADDR_INSN;
+                       regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN;
                        /*
                         * The debugger changed the instruction address,
                         * reset system call restart, see signal.c:do_signal
@@ -625,8 +626,7 @@ static int __poke_user_compat(struct task_struct *child,
                        task_thread_info(child)->system_call = 0;
                } else {
                        /* gpr 0-15 */
-                       *(__u32*)((addr_t) &task_pt_regs(child)->psw
-                                 + addr*2 + 4) = tmp;
+                       *(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
                }
        } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
                /*
index 6f8e3777a0c8d9d2edd22300090037069102ccde..8ac6bfa2786cbe139d9964b1f4ab374e4302e2e8 100644 (file)
 #include <asm/kvm_virtio.h>
 #include <asm/diag.h>
 
-long psw_kernel_bits   = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
-                          PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
-long psw_user_bits     = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
-                          PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
-                          PSW_MASK_PSTATE | PSW_DEFAULT_KEY);
+long psw_kernel_bits   = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY |
+                         PSW_MASK_EA | PSW_MASK_BA;
+long psw_user_bits     = PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT |
+                         PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK |
+                         PSW_MASK_PSTATE | PSW_ASC_HOME;
 
 /*
  * User copy operations.
@@ -278,22 +278,14 @@ early_param("mem", early_parse_mem);
 unsigned int user_mode = HOME_SPACE_MODE;
 EXPORT_SYMBOL_GPL(user_mode);
 
-static int set_amode_and_uaccess(unsigned long user_amode,
-                                unsigned long user32_amode)
+static int set_amode_primary(void)
 {
-       psw_user_bits = PSW_BASE_BITS | PSW_MASK_DAT | user_amode |
-                       PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
-                       PSW_MASK_PSTATE | PSW_DEFAULT_KEY;
+       psw_kernel_bits = (psw_kernel_bits & ~PSW_MASK_ASC) | PSW_ASC_HOME;
+       psw_user_bits = (psw_user_bits & ~PSW_MASK_ASC) | PSW_ASC_PRIMARY;
 #ifdef CONFIG_COMPAT
-       psw_user32_bits = PSW_BASE32_BITS | PSW_MASK_DAT | user_amode |
-                         PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
-                         PSW_MASK_PSTATE | PSW_DEFAULT_KEY;
-       psw32_user_bits = PSW32_BASE_BITS | PSW32_MASK_DAT | user32_amode |
-                         PSW32_MASK_IO | PSW32_MASK_EXT | PSW32_MASK_MCHECK |
-                         PSW32_MASK_PSTATE;
+       psw32_user_bits =
+               (psw32_user_bits & ~PSW32_MASK_ASC) | PSW32_ASC_PRIMARY;
 #endif
-       psw_kernel_bits = PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
-                         PSW_MASK_MCHECK | PSW_DEFAULT_KEY;
 
        if (MACHINE_HAS_MVCOS) {
                memcpy(&uaccess, &uaccess_mvcos_switch, sizeof(uaccess));
@@ -329,7 +321,7 @@ early_param("user_mode", early_parse_user_mode);
 static void setup_addressing_mode(void)
 {
        if (user_mode == PRIMARY_SPACE_MODE) {
-               if (set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY))
+               if (set_amode_primary())
                        pr_info("Address spaces switched, "
                                "mvcos available\n");
                else
@@ -348,24 +340,25 @@ setup_lowcore(void)
         */
        BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
        lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
-       lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+       lc->restart_psw.mask = psw_kernel_bits;
        lc->restart_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
-       if (user_mode != HOME_SPACE_MODE)
-               lc->restart_psw.mask |= PSW_ASC_HOME;
-       lc->external_new_psw.mask = psw_kernel_bits;
+       lc->external_new_psw.mask = psw_kernel_bits |
+               PSW_MASK_DAT | PSW_MASK_MCHECK;
        lc->external_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
-       lc->svc_new_psw.mask = psw_kernel_bits | PSW_MASK_IO | PSW_MASK_EXT;
+       lc->svc_new_psw.mask = psw_kernel_bits |
+               PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
        lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;
-       lc->program_new_psw.mask = psw_kernel_bits;
+       lc->program_new_psw.mask = psw_kernel_bits |
+               PSW_MASK_DAT | PSW_MASK_MCHECK;
        lc->program_new_psw.addr =
-               PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;
-       lc->mcck_new_psw.mask =
-               psw_kernel_bits & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT;
+               PSW_ADDR_AMODE | (unsigned long) pgm_check_handler;
+       lc->mcck_new_psw.mask = psw_kernel_bits;
        lc->mcck_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
-       lc->io_new_psw.mask = psw_kernel_bits;
+       lc->io_new_psw.mask = psw_kernel_bits |
+               PSW_MASK_DAT | PSW_MASK_MCHECK;
        lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
        lc->clock_comparator = -1ULL;
        lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
@@ -554,7 +547,7 @@ static void __init setup_restart_psw(void)
         * Setup restart PSW for absolute zero lowcore. This is necesary
         * if PSW restart is done on an offline CPU that has lowcore zero
         */
-       psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+       psw.mask = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
        psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
        copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
 }
index 0e905cb7604ab1417d2d0cbad587a78176b8db19..c19755815e530c86544f6dfd55c143eb63d02f5f 100644 (file)
@@ -117,7 +117,8 @@ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
 
        /* Copy a 'clean' PSW mask to the user to avoid leaking
           information about whether PER is currently on.  */
-       user_sregs.regs.psw.mask = PSW_MASK_MERGE(psw_user_bits, regs->psw.mask);
+       user_sregs.regs.psw.mask = psw_user_bits | PSW_MASK_EA | PSW_MASK_BA |
+                                  (regs->psw.mask & PSW_MASK_USER);
        user_sregs.regs.psw.addr = regs->psw.addr;
        memcpy(&user_sregs.regs.gprs, &regs->gprs, sizeof(sregs->regs.gprs));
        memcpy(&user_sregs.regs.acrs, current->thread.acrs,
@@ -144,8 +145,8 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
        err = __copy_from_user(&user_sregs, sregs, sizeof(_sigregs));
        if (err)
                return err;
-       regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
-                                       user_sregs.regs.psw.mask);
+       regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
+                        (user_sregs.regs.psw.mask & PSW_MASK_USER);
        regs->psw.addr = PSW_ADDR_AMODE | user_sregs.regs.psw.addr;
        memcpy(&regs->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs));
        memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
index e3f51dfa5cad67808bd3dc6b4b82fab56069bd17..6c8a977af595343f19430d19ea5ae88fef436b60 100644 (file)
@@ -108,7 +108,7 @@ void smp_restart_with_online_cpu(void)
        for_each_online_cpu(cpu) {
                if (stap() == __cpu_logical_map[cpu]) {
                        /* We are online: Enable DAT again and return */
-                       __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
+                       __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
                        return;
                }
        }
@@ -130,14 +130,16 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
 
        if (smp_processor_id() == 0)
                func(data);
-       __load_psw_mask(PSW_BASE_BITS | PSW_DEFAULT_KEY);
+       __load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE |
+                       PSW_MASK_EA | PSW_MASK_BA);
        /* Disable lowcore protection */
        __ctl_clear_bit(0, 28);
        current_lc = lowcore_ptr[smp_processor_id()];
        lc = lowcore_ptr[0];
        if (!lc)
                lc = current_lc;
-       lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+       lc->restart_psw.mask =
+               PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
        lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
        if (!cpu_online(0))
                smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
@@ -159,7 +161,7 @@ void smp_send_stop(void)
        int cpu, rc;
 
        /* Disable all interrupts/machine checks */
-       __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
+       __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
        trace_hardirqs_off();
 
        /* stop all processors */
@@ -501,7 +503,8 @@ int __cpuinit start_secondary(void *cpuvoid)
        set_cpu_online(smp_processor_id(), true);
        ipi_call_unlock();
        __ctl_clear_bit(0, 28); /* Disable lowcore protection */
-       S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+       S390_lowcore.restart_psw.mask =
+               PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
        S390_lowcore.restart_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
        __ctl_set_bit(0, 28); /* Enable lowcore protection */
@@ -549,7 +552,8 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
        memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
        lowcore->async_stack = async_stack + ASYNC_SIZE;
        lowcore->panic_stack = panic_stack + PAGE_SIZE;
-       lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+       lowcore->restart_psw.mask =
+               PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
        lowcore->restart_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
        if (user_mode != HOME_SPACE_MODE)
index ffabcd9d33635dbcff5f35077ee5853bee8f8758..79eee3f27afb4a7475b2a4f0d1c639f4e0fce016 100644 (file)
@@ -200,7 +200,7 @@ void show_registers(struct pt_regs *regs)
               mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC),
               mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM));
 #ifdef CONFIG_64BIT
-       printk(" EA:%x", mask_bits(regs, PSW_BASE_BITS));
+       printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA));
 #endif
        printk("\n%s GPRS: " FOURLONG, mode,
               regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]);
index 2d6228f60cd69ec9d5e6ee2f670cbf93cc608c42..4f3de980b0e585c997585ae2bf22509675d2312a 100644 (file)
@@ -170,7 +170,8 @@ void __kprobes vtime_stop_cpu(void)
        psw_t psw;
 
        /* Wait for external, I/O or machine check interrupt. */
-       psw.mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_IO | PSW_MASK_EXT;
+       psw.mask = psw_kernel_bits | PSW_MASK_WAIT |
+               PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
 
        idle->nohz_delay = 0;
 
@@ -183,7 +184,8 @@ void __kprobes vtime_stop_cpu(void)
                 *      set_cpu_timer(VTIMER_MAX_SLICE);
                 *      idle->idle_enter = get_clock();
                 *      __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
-                *                         PSW_MASK_IO | PSW_MASK_EXT);
+                *                         PSW_MASK_DAT | PSW_MASK_IO |
+                *                         PSW_MASK_EXT | PSW_MASK_MCHECK);
                 * The difference is that the inline assembly makes sure that
                 * the last three instruction are stpt, stck and lpsw in that
                 * order. This is done to increase the precision.
@@ -216,7 +218,8 @@ void __kprobes vtime_stop_cpu(void)
                 *      vq->idle = get_cpu_timer();
                 *      idle->idle_enter = get_clock();
                 *      __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
-                *                         PSW_MASK_IO | PSW_MASK_EXT);
+                *                         PSW_MASK_DAT | PSW_MASK_IO |
+                *                         PSW_MASK_EXT | PSW_MASK_MCHECK);
                 * The difference is that the inline assembly makes sure that
                 * the last three instruction are stpt, stck and lpsw in that
                 * order. This is done to increase the precision.
index a65229d91c92be055931de197528c67d3403837c..db92f044024c4508993fd4b0e7c67c9b74e37b0e 100644 (file)
@@ -32,7 +32,8 @@ static void __udelay_disabled(unsigned long long usecs)
        u64 clock_saved;
        u64 end;
 
-       mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT;
+       mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_WAIT |
+               PSW_MASK_EXT | PSW_MASK_MCHECK;
        end = get_clock() + (usecs << 12);
        clock_saved = local_tick_disable();
        __ctl_store(cr0_saved, 0, 0);
index a90fd91a9c7227e151f7c2ac21bb3c9d1f91ccdb..de3af0c053c0df2dfd3a525339ab6757a3015586 100644 (file)
@@ -454,7 +454,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
        struct pt_regs regs;
        int access, fault;
 
-       regs.psw.mask = psw_kernel_bits;
+       regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK;
        if (!irqs_disabled())
                regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
        regs.psw.addr = (unsigned long) __builtin_return_address(0);
index 837e010299a894f4f249fc6c0707a95634146598..0b54a91f8dcd2aa23d23634910fb92a683cea949 100644 (file)
@@ -61,8 +61,8 @@ static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb)
        rc = sclp_service_call(cmd, sccb);
        if (rc)
                goto out;
-       __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT |
-                       PSW_MASK_WAIT | PSW_DEFAULT_KEY);
+       __load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA |
+                       PSW_MASK_BA | PSW_MASK_EXT | PSW_MASK_WAIT);
        local_irq_disable();
 out:
        /* Contents of the sccb might have changed. */
index a90a02c28d6a1d2c75ecbb6d287e82950fe1785d..87fc0ac11e6766b16e3c4386010afe4cdabe67d2 100644 (file)
@@ -30,7 +30,8 @@ static void do_machine_quiesce(void)
        psw_t quiesce_psw;
 
        smp_send_stop();
-       quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
+       quiesce_psw.mask =
+               PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA | PSW_MASK_WAIT;
        quiesce_psw.addr = 0xfff;
        __load_psw(quiesce_psw);
 }