[S390] cleanup psw related bits and pieces
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>
This commit is contained in:
		
					parent
					
						
							
								b6ef5bb3d9
							
						
					
				
			
			
				commit
				
					
						b50511e41a
					
				
			
		
					 20 changed files with 109 additions and 125 deletions
				
			
		| 
						 | 
					@ -12,6 +12,7 @@
 | 
				
			||||||
#define PSW32_MASK_IO		0x02000000UL
 | 
					#define PSW32_MASK_IO		0x02000000UL
 | 
				
			||||||
#define PSW32_MASK_EXT		0x01000000UL
 | 
					#define PSW32_MASK_EXT		0x01000000UL
 | 
				
			||||||
#define PSW32_MASK_KEY		0x00F00000UL
 | 
					#define PSW32_MASK_KEY		0x00F00000UL
 | 
				
			||||||
 | 
					#define PSW32_MASK_BASE		0x00080000UL	/* Always one */
 | 
				
			||||||
#define PSW32_MASK_MCHECK	0x00040000UL
 | 
					#define PSW32_MASK_MCHECK	0x00040000UL
 | 
				
			||||||
#define PSW32_MASK_WAIT		0x00020000UL
 | 
					#define PSW32_MASK_WAIT		0x00020000UL
 | 
				
			||||||
#define PSW32_MASK_PSTATE	0x00010000UL
 | 
					#define PSW32_MASK_PSTATE	0x00010000UL
 | 
				
			||||||
| 
						 | 
					@ -19,21 +20,19 @@
 | 
				
			||||||
#define PSW32_MASK_CC		0x00003000UL
 | 
					#define PSW32_MASK_CC		0x00003000UL
 | 
				
			||||||
#define PSW32_MASK_PM		0x00000f00UL
 | 
					#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_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_PRIMARY	0x00000000UL
 | 
				
			||||||
#define PSW32_ASC_ACCREG	0x00004000UL
 | 
					#define PSW32_ASC_ACCREG	0x00004000UL
 | 
				
			||||||
#define PSW32_ASC_SECONDARY	0x00008000UL
 | 
					#define PSW32_ASC_SECONDARY	0x00008000UL
 | 
				
			||||||
#define PSW32_ASC_HOME		0x0000C000UL
 | 
					#define PSW32_ASC_HOME		0x0000C000UL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PSW32_MASK_MERGE(CURRENT,NEW) \
 | 
					extern u32 psw32_user_bits;
 | 
				
			||||||
	(((CURRENT) & ~(PSW32_MASK_CC|PSW32_MASK_PM)) | \
 | 
					 | 
				
			||||||
	 ((NEW) & (PSW32_MASK_CC|PSW32_MASK_PM)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern long psw32_user_bits;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define COMPAT_USER_HZ		100
 | 
					#define COMPAT_USER_HZ		100
 | 
				
			||||||
#define COMPAT_UTS_MACHINE	"s390\0\0\0\0"
 | 
					#define COMPAT_UTS_MACHINE	"s390\0\0\0\0"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,13 +119,13 @@ struct stack_frame {
 | 
				
			||||||
 * Do necessary setup to start up a new thread.
 | 
					 * Do necessary setup to start up a new thread.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define start_thread(regs, new_psw, new_stackp) do {			\
 | 
					#define start_thread(regs, new_psw, new_stackp) do {			\
 | 
				
			||||||
	regs->psw.mask	= psw_user_bits;			\
 | 
						regs->psw.mask	= psw_user_bits | PSW_MASK_EA | PSW_MASK_BA;	\
 | 
				
			||||||
	regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
 | 
						regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
 | 
				
			||||||
	regs->gprs[15]	= new_stackp;					\
 | 
						regs->gprs[15]	= new_stackp;					\
 | 
				
			||||||
} while (0)
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define start_thread31(regs, new_psw, new_stackp) do {			\
 | 
					#define start_thread31(regs, new_psw, new_stackp) do {			\
 | 
				
			||||||
	regs->psw.mask	= psw_user32_bits;			\
 | 
						regs->psw.mask	= psw_user_bits | PSW_MASK_BA;			\
 | 
				
			||||||
	regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
 | 
						regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
 | 
				
			||||||
	regs->gprs[15]	= new_stackp;					\
 | 
						regs->gprs[15]	= new_stackp;					\
 | 
				
			||||||
	crst_table_downgrade(current->mm, 1UL << 31);			\
 | 
						crst_table_downgrade(current->mm, 1UL << 31);			\
 | 
				
			||||||
| 
						 | 
					@ -233,25 +233,15 @@ static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc)
 | 
				
			||||||
#endif
 | 
					#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
 | 
					 * Function to drop a processor into disabled wait state
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline void ATTRIB_NORET disabled_wait(unsigned long code)
 | 
					static inline void ATTRIB_NORET disabled_wait(unsigned long code)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
        unsigned long ctl_buf;
 | 
					        unsigned long ctl_buf;
 | 
				
			||||||
        psw_t dw_psw;
 | 
					        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;
 | 
					        dw_psw.addr = code;
 | 
				
			||||||
        /* 
 | 
					        /* 
 | 
				
			||||||
         * Store status and then load disabled wait psw,
 | 
					         * Store status and then load disabled wait psw,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,6 +230,7 @@ typedef struct
 | 
				
			||||||
#define PSW_MASK_IO		0x02000000UL
 | 
					#define PSW_MASK_IO		0x02000000UL
 | 
				
			||||||
#define PSW_MASK_EXT		0x01000000UL
 | 
					#define PSW_MASK_EXT		0x01000000UL
 | 
				
			||||||
#define PSW_MASK_KEY		0x00F00000UL
 | 
					#define PSW_MASK_KEY		0x00F00000UL
 | 
				
			||||||
 | 
					#define PSW_MASK_BASE		0x00080000UL	/* always one */
 | 
				
			||||||
#define PSW_MASK_MCHECK		0x00040000UL
 | 
					#define PSW_MASK_MCHECK		0x00040000UL
 | 
				
			||||||
#define PSW_MASK_WAIT		0x00020000UL
 | 
					#define PSW_MASK_WAIT		0x00020000UL
 | 
				
			||||||
#define PSW_MASK_PSTATE		0x00010000UL
 | 
					#define PSW_MASK_PSTATE		0x00010000UL
 | 
				
			||||||
| 
						 | 
					@ -239,10 +240,11 @@ typedef struct
 | 
				
			||||||
#define PSW_MASK_EA		0x00000000UL
 | 
					#define PSW_MASK_EA		0x00000000UL
 | 
				
			||||||
#define PSW_MASK_BA		0x00000000UL
 | 
					#define PSW_MASK_BA		0x00000000UL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PSW_MASK_USER		0x00003F00UL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PSW_ADDR_AMODE		0x80000000UL
 | 
					#define PSW_ADDR_AMODE		0x80000000UL
 | 
				
			||||||
#define PSW_ADDR_INSN		0x7FFFFFFFUL
 | 
					#define PSW_ADDR_INSN		0x7FFFFFFFUL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PSW_BASE_BITS		0x00080000UL
 | 
					 | 
				
			||||||
#define PSW_DEFAULT_KEY		(((unsigned long) PAGE_DEFAULT_ACC) << 20)
 | 
					#define PSW_DEFAULT_KEY		(((unsigned long) PAGE_DEFAULT_ACC) << 20)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PSW_ASC_PRIMARY		0x00000000UL
 | 
					#define PSW_ASC_PRIMARY		0x00000000UL
 | 
				
			||||||
| 
						 | 
					@ -256,6 +258,7 @@ typedef struct
 | 
				
			||||||
#define PSW_MASK_DAT		0x0400000000000000UL
 | 
					#define PSW_MASK_DAT		0x0400000000000000UL
 | 
				
			||||||
#define PSW_MASK_IO		0x0200000000000000UL
 | 
					#define PSW_MASK_IO		0x0200000000000000UL
 | 
				
			||||||
#define PSW_MASK_EXT		0x0100000000000000UL
 | 
					#define PSW_MASK_EXT		0x0100000000000000UL
 | 
				
			||||||
 | 
					#define PSW_MASK_BASE		0x0000000000000000UL
 | 
				
			||||||
#define PSW_MASK_KEY		0x00F0000000000000UL
 | 
					#define PSW_MASK_KEY		0x00F0000000000000UL
 | 
				
			||||||
#define PSW_MASK_MCHECK		0x0004000000000000UL
 | 
					#define PSW_MASK_MCHECK		0x0004000000000000UL
 | 
				
			||||||
#define PSW_MASK_WAIT		0x0002000000000000UL
 | 
					#define PSW_MASK_WAIT		0x0002000000000000UL
 | 
				
			||||||
| 
						 | 
					@ -266,11 +269,11 @@ typedef struct
 | 
				
			||||||
#define PSW_MASK_EA		0x0000000100000000UL
 | 
					#define PSW_MASK_EA		0x0000000100000000UL
 | 
				
			||||||
#define PSW_MASK_BA		0x0000000080000000UL
 | 
					#define PSW_MASK_BA		0x0000000080000000UL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PSW_MASK_USER		0x00003F0000000000UL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PSW_ADDR_AMODE		0x0000000000000000UL
 | 
					#define PSW_ADDR_AMODE		0x0000000000000000UL
 | 
				
			||||||
#define PSW_ADDR_INSN		0xFFFFFFFFFFFFFFFFUL
 | 
					#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_DEFAULT_KEY		(((unsigned long) PAGE_DEFAULT_ACC) << 52)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PSW_ASC_PRIMARY		0x0000000000000000UL
 | 
					#define PSW_ASC_PRIMARY		0x0000000000000000UL
 | 
				
			||||||
| 
						 | 
					@ -283,18 +286,7 @@ typedef struct
 | 
				
			||||||
#ifdef __KERNEL__
 | 
					#ifdef __KERNEL__
 | 
				
			||||||
extern long psw_kernel_bits;
 | 
					extern long psw_kernel_bits;
 | 
				
			||||||
extern long psw_user_bits;
 | 
					extern long psw_user_bits;
 | 
				
			||||||
#ifdef CONFIG_64BIT
 | 
					 | 
				
			||||||
extern long psw_user32_bits;
 | 
					 | 
				
			||||||
#endif
 | 
					#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.
 | 
					 * The s390_regs structure is used to define the elf_gregset_t.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -212,8 +212,10 @@ __set_psw_mask(unsigned long mask)
 | 
				
			||||||
	__load_psw_mask(mask | (arch_local_save_flags() & ~(-1UL >> 8)));
 | 
						__load_psw_mask(mask | (arch_local_save_flags() & ~(-1UL >> 8)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define local_mcck_enable()  __set_psw_mask(psw_kernel_bits)
 | 
					#define local_mcck_enable() \
 | 
				
			||||||
#define local_mcck_disable() __set_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK)
 | 
						__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
 | 
					#ifdef CONFIG_SMP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,12 +60,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "compat_linux.h"
 | 
					#include "compat_linux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
long psw_user32_bits	= (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
 | 
					u32 psw32_user_bits = PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT |
 | 
				
			||||||
			   PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
 | 
							      PSW32_DEFAULT_KEY | PSW32_MASK_BASE | PSW32_MASK_MCHECK |
 | 
				
			||||||
			   PSW_MASK_PSTATE | PSW_DEFAULT_KEY);
 | 
							      PSW32_MASK_PSTATE | PSW32_ASC_HOME;
 | 
				
			||||||
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);
 | 
					 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
/* For this source file, we want overflow handling. */
 | 
					/* For this source file, we want overflow handling. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -300,9 +300,9 @@ static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
 | 
				
			||||||
	_s390_regs_common32 regs32;
 | 
						_s390_regs_common32 regs32;
 | 
				
			||||||
	int err, i;
 | 
						int err, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regs32.psw.mask = PSW32_MASK_MERGE(psw32_user_bits,
 | 
						regs32.psw.mask = psw32_user_bits |
 | 
				
			||||||
					   (__u32)(regs->psw.mask >> 32));
 | 
							((__u32)(regs->psw.mask >> 32) & PSW32_MASK_USER);
 | 
				
			||||||
	regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
 | 
						regs32.psw.addr = PSW32_ADDR_AMODE | (__u32) regs->psw.addr;
 | 
				
			||||||
	for (i = 0; i < NUM_GPRS; i++)
 | 
						for (i = 0; i < NUM_GPRS; i++)
 | 
				
			||||||
		regs32.gprs[i] = (__u32) regs->gprs[i];
 | 
							regs32.gprs[i] = (__u32) regs->gprs[i];
 | 
				
			||||||
	save_access_regs(current->thread.acrs);
 | 
						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(®s32, &sregs->regs, sizeof(regs32));
 | 
						err = __copy_from_user(®s32, &sregs->regs, sizeof(regs32));
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
 | 
						regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
 | 
				
			||||||
				        (__u64)regs32.psw.mask << 32);
 | 
							(__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32;
 | 
				
			||||||
	regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
 | 
						regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
 | 
				
			||||||
	for (i = 0; i < NUM_GPRS; i++)
 | 
						for (i = 0; i < NUM_GPRS; i++)
 | 
				
			||||||
		regs->gprs[i] = (__u64) regs32.gprs[i];
 | 
							regs->gprs[i] = (__u64) regs32.gprs[i];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -252,7 +252,7 @@ static noinline __init void setup_lowcore_early(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	psw_t psw;
 | 
						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;
 | 
						psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_ext_handler;
 | 
				
			||||||
	S390_lowcore.external_new_psw = psw;
 | 
						S390_lowcore.external_new_psw = psw;
 | 
				
			||||||
	psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
 | 
						psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2033,12 +2033,12 @@ void s390_reset_system(void (*func)(void *), void *data)
 | 
				
			||||||
	__ctl_clear_bit(0,28);
 | 
						__ctl_clear_bit(0,28);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set new machine check handler */
 | 
						/* 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 =
 | 
						S390_lowcore.mcck_new_psw.addr =
 | 
				
			||||||
		PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
 | 
							PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set new program check 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 =
 | 
						S390_lowcore.program_new_psw.addr =
 | 
				
			||||||
		PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
 | 
							PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,7 +108,7 @@ static void __do_machine_kdump(void *image)
 | 
				
			||||||
#ifdef CONFIG_CRASH_DUMP
 | 
					#ifdef CONFIG_CRASH_DUMP
 | 
				
			||||||
	int (*start_kdump)(int) = (void *)((struct kimage *) image)->start;
 | 
						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();
 | 
						setup_regs();
 | 
				
			||||||
	start_kdump(1);
 | 
						start_kdump(1);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 | 
				
			||||||
	struct pt_regs regs;
 | 
						struct pt_regs regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(®s, 0, sizeof(regs));
 | 
						memset(®s, 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.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
 | 
				
			||||||
	regs.gprs[9] = (unsigned long) fn;
 | 
						regs.gprs[9] = (unsigned long) fn;
 | 
				
			||||||
	regs.gprs[10] = (unsigned long) arg;
 | 
						regs.gprs[10] = (unsigned long) arg;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
							tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
 | 
				
			||||||
		if (addr == (addr_t) &dummy->regs.psw.mask)
 | 
							if (addr == (addr_t) &dummy->regs.psw.mask)
 | 
				
			||||||
			/* Remove per bit from user psw. */
 | 
								/* Return a clean psw mask. */
 | 
				
			||||||
			tmp &= ~PSW_MASK_PER;
 | 
								tmp = psw_user_bits | (tmp & PSW_MASK_USER) |
 | 
				
			||||||
 | 
									PSW_MASK_EA | PSW_MASK_BA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	} else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
 | 
						} 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)
 | 
					static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct user *dummy = NULL;
 | 
						struct user *dummy = NULL;
 | 
				
			||||||
	addr_t offset;
 | 
						addr_t offset, tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (addr < (addr_t) &dummy->regs.acrs) {
 | 
						if (addr < (addr_t) &dummy->regs.acrs) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * psw and gprs are stored on the stack
 | 
							 * psw and gprs are stored on the stack
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
 | 
							tmp = (data & ~PSW_MASK_USER) ^ psw_user_bits;
 | 
				
			||||||
		if (addr == (addr_t) &dummy->regs.psw.mask &&
 | 
							if (addr == (addr_t) &dummy->regs.psw.mask &&
 | 
				
			||||||
#ifdef CONFIG_COMPAT
 | 
					#ifdef CONFIG_COMPAT
 | 
				
			||||||
		    data != PSW_MASK_MERGE(psw_user32_bits, data) &&
 | 
							    tmp != PSW_MASK_BA &&
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		    data != PSW_MASK_MERGE(psw_user_bits, data))
 | 
							    tmp != (PSW_MASK_EA | PSW_MASK_BA))
 | 
				
			||||||
			/* Invalid psw mask. */
 | 
								/* Invalid psw mask. */
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
#ifndef CONFIG_64BIT
 | 
					#ifndef CONFIG_64BIT
 | 
				
			||||||
| 
						 | 
					@ -505,21 +507,20 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
 | 
				
			||||||
	__u32 tmp;
 | 
						__u32 tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (addr < (addr_t) &dummy32->regs.acrs) {
 | 
						if (addr < (addr_t) &dummy32->regs.acrs) {
 | 
				
			||||||
 | 
							struct pt_regs *regs = task_pt_regs(child);
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * psw and gprs are stored on the stack
 | 
							 * psw and gprs are stored on the stack
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (addr == (addr_t) &dummy32->regs.psw.mask) {
 | 
							if (addr == (addr_t) &dummy32->regs.psw.mask) {
 | 
				
			||||||
			/* Fake a 31 bit psw mask. */
 | 
								/* Fake a 31 bit psw mask. */
 | 
				
			||||||
			tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32);
 | 
								tmp = (__u32)(regs->psw.mask >> 32);
 | 
				
			||||||
			tmp = PSW32_MASK_MERGE(psw32_user_bits, tmp);
 | 
								tmp = psw32_user_bits | (tmp & PSW32_MASK_USER);
 | 
				
			||||||
		} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
 | 
							} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
 | 
				
			||||||
			/* Fake a 31 bit psw address. */
 | 
								/* Fake a 31 bit psw address. */
 | 
				
			||||||
			tmp = (__u32) task_pt_regs(child)->psw.addr |
 | 
								tmp = (__u32) regs->psw.addr | PSW32_ADDR_AMODE;
 | 
				
			||||||
				PSW32_ADDR_AMODE31;
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* gpr 0-15 */
 | 
								/* gpr 0-15 */
 | 
				
			||||||
			tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw +
 | 
								tmp = *(__u32 *)((addr_t) ®s->psw + addr*2 + 4);
 | 
				
			||||||
					 addr*2 + 4);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
 | 
						} 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;
 | 
						addr_t offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (addr < (addr_t) &dummy32->regs.acrs) {
 | 
						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
 | 
							 * psw, gprs, acrs and orig_gpr2 are stored on the stack
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (addr == (addr_t) &dummy32->regs.psw.mask) {
 | 
							if (addr == (addr_t) &dummy32->regs.psw.mask) {
 | 
				
			||||||
			/* Build a 64 bit psw mask from 31 bit 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. */
 | 
									/* Invalid psw mask. */
 | 
				
			||||||
				return -EINVAL;
 | 
									return -EINVAL;
 | 
				
			||||||
			task_pt_regs(child)->psw.mask =
 | 
								regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
 | 
				
			||||||
				PSW_MASK_MERGE(psw_user32_bits, (__u64) tmp << 32);
 | 
									(__u64)(tmp & PSW32_MASK_USER) << 32;
 | 
				
			||||||
		} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
 | 
							} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
 | 
				
			||||||
			/* Build a 64 bit psw address from 31 bit address. */
 | 
								/* Build a 64 bit psw address from 31 bit address. */
 | 
				
			||||||
			task_pt_regs(child)->psw.addr =
 | 
								regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN;
 | 
				
			||||||
				(__u64) tmp & PSW32_ADDR_INSN;
 | 
					 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * The debugger changed the instruction address,
 | 
								 * The debugger changed the instruction address,
 | 
				
			||||||
			 * reset system call restart, see signal.c:do_signal
 | 
								 * 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;
 | 
								task_thread_info(child)->system_call = 0;
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			/* gpr 0-15 */
 | 
								/* gpr 0-15 */
 | 
				
			||||||
			*(__u32*)((addr_t) &task_pt_regs(child)->psw
 | 
								*(__u32*)((addr_t) ®s->psw + addr*2 + 4) = tmp;
 | 
				
			||||||
				  + addr*2 + 4) = tmp;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
 | 
						} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,11 +62,11 @@
 | 
				
			||||||
#include <asm/kvm_virtio.h>
 | 
					#include <asm/kvm_virtio.h>
 | 
				
			||||||
#include <asm/diag.h>
 | 
					#include <asm/diag.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
long psw_kernel_bits	= (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
 | 
					long psw_kernel_bits	= PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY |
 | 
				
			||||||
			   PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
 | 
								  PSW_MASK_EA | PSW_MASK_BA;
 | 
				
			||||||
long psw_user_bits	= (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
 | 
					long psw_user_bits	= PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT |
 | 
				
			||||||
			   PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
 | 
								  PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_MCHECK |
 | 
				
			||||||
			   PSW_MASK_PSTATE | PSW_DEFAULT_KEY);
 | 
								  PSW_MASK_PSTATE | PSW_ASC_HOME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * User copy operations.
 | 
					 * User copy operations.
 | 
				
			||||||
| 
						 | 
					@ -278,22 +278,14 @@ early_param("mem", early_parse_mem);
 | 
				
			||||||
unsigned int user_mode = HOME_SPACE_MODE;
 | 
					unsigned int user_mode = HOME_SPACE_MODE;
 | 
				
			||||||
EXPORT_SYMBOL_GPL(user_mode);
 | 
					EXPORT_SYMBOL_GPL(user_mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_amode_and_uaccess(unsigned long user_amode,
 | 
					static int set_amode_primary(void)
 | 
				
			||||||
				 unsigned long user32_amode)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	psw_user_bits = PSW_BASE_BITS | PSW_MASK_DAT | user_amode |
 | 
						psw_kernel_bits = (psw_kernel_bits & ~PSW_MASK_ASC) | PSW_ASC_HOME;
 | 
				
			||||||
			PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
 | 
						psw_user_bits = (psw_user_bits & ~PSW_MASK_ASC) | PSW_ASC_PRIMARY;
 | 
				
			||||||
			PSW_MASK_PSTATE | PSW_DEFAULT_KEY;
 | 
					 | 
				
			||||||
#ifdef CONFIG_COMPAT
 | 
					#ifdef CONFIG_COMPAT
 | 
				
			||||||
	psw_user32_bits = PSW_BASE32_BITS | PSW_MASK_DAT | user_amode |
 | 
						psw32_user_bits =
 | 
				
			||||||
			  PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
 | 
							(psw32_user_bits & ~PSW32_MASK_ASC) | PSW32_ASC_PRIMARY;
 | 
				
			||||||
			  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;
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	psw_kernel_bits = PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
 | 
					 | 
				
			||||||
			  PSW_MASK_MCHECK | PSW_DEFAULT_KEY;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (MACHINE_HAS_MVCOS) {
 | 
						if (MACHINE_HAS_MVCOS) {
 | 
				
			||||||
		memcpy(&uaccess, &uaccess_mvcos_switch, sizeof(uaccess));
 | 
							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)
 | 
					static void setup_addressing_mode(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (user_mode == PRIMARY_SPACE_MODE) {
 | 
						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, "
 | 
								pr_info("Address spaces switched, "
 | 
				
			||||||
				"mvcos available\n");
 | 
									"mvcos available\n");
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
| 
						 | 
					@ -348,24 +340,25 @@ setup_lowcore(void)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
 | 
						BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
 | 
				
			||||||
	lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
 | 
						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 =
 | 
						lc->restart_psw.addr =
 | 
				
			||||||
		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
 | 
							PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
 | 
				
			||||||
	if (user_mode != HOME_SPACE_MODE)
 | 
						lc->external_new_psw.mask = psw_kernel_bits |
 | 
				
			||||||
		lc->restart_psw.mask |= PSW_ASC_HOME;
 | 
							PSW_MASK_DAT | PSW_MASK_MCHECK;
 | 
				
			||||||
	lc->external_new_psw.mask = psw_kernel_bits;
 | 
					 | 
				
			||||||
	lc->external_new_psw.addr =
 | 
						lc->external_new_psw.addr =
 | 
				
			||||||
		PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
 | 
							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->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 =
 | 
						lc->program_new_psw.addr =
 | 
				
			||||||
		PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;
 | 
							PSW_ADDR_AMODE | (unsigned long) pgm_check_handler;
 | 
				
			||||||
	lc->mcck_new_psw.mask =
 | 
						lc->mcck_new_psw.mask = psw_kernel_bits;
 | 
				
			||||||
		psw_kernel_bits & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT;
 | 
					 | 
				
			||||||
	lc->mcck_new_psw.addr =
 | 
						lc->mcck_new_psw.addr =
 | 
				
			||||||
		PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
 | 
							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->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
 | 
				
			||||||
	lc->clock_comparator = -1ULL;
 | 
						lc->clock_comparator = -1ULL;
 | 
				
			||||||
	lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
 | 
						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
 | 
						 * Setup restart PSW for absolute zero lowcore. This is necesary
 | 
				
			||||||
	 * if PSW restart is done on an offline CPU that has lowcore zero
 | 
						 * 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;
 | 
						psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
 | 
				
			||||||
	copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
 | 
						copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
						/* Copy a 'clean' PSW mask to the user to avoid leaking
 | 
				
			||||||
	   information about whether PER is currently on.  */
 | 
						   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;
 | 
						user_sregs.regs.psw.addr = regs->psw.addr;
 | 
				
			||||||
	memcpy(&user_sregs.regs.gprs, ®s->gprs, sizeof(sregs->regs.gprs));
 | 
						memcpy(&user_sregs.regs.gprs, ®s->gprs, sizeof(sregs->regs.gprs));
 | 
				
			||||||
	memcpy(&user_sregs.regs.acrs, current->thread.acrs,
 | 
						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));
 | 
						err = __copy_from_user(&user_sregs, sregs, sizeof(_sigregs));
 | 
				
			||||||
	if (err)
 | 
						if (err)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
 | 
						regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
 | 
				
			||||||
					user_sregs.regs.psw.mask);
 | 
								 (user_sregs.regs.psw.mask & PSW_MASK_USER);
 | 
				
			||||||
	regs->psw.addr = PSW_ADDR_AMODE | user_sregs.regs.psw.addr;
 | 
						regs->psw.addr = PSW_ADDR_AMODE | user_sregs.regs.psw.addr;
 | 
				
			||||||
	memcpy(®s->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs));
 | 
						memcpy(®s->gprs, &user_sregs.regs.gprs, sizeof(sregs->regs.gprs));
 | 
				
			||||||
	memcpy(¤t->thread.acrs, &user_sregs.regs.acrs,
 | 
						memcpy(¤t->thread.acrs, &user_sregs.regs.acrs,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,7 +108,7 @@ void smp_restart_with_online_cpu(void)
 | 
				
			||||||
	for_each_online_cpu(cpu) {
 | 
						for_each_online_cpu(cpu) {
 | 
				
			||||||
		if (stap() == __cpu_logical_map[cpu]) {
 | 
							if (stap() == __cpu_logical_map[cpu]) {
 | 
				
			||||||
			/* We are online: Enable DAT again and return */
 | 
								/* 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;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -130,14 +130,16 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (smp_processor_id() == 0)
 | 
						if (smp_processor_id() == 0)
 | 
				
			||||||
		func(data);
 | 
							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 */
 | 
						/* Disable lowcore protection */
 | 
				
			||||||
	__ctl_clear_bit(0, 28);
 | 
						__ctl_clear_bit(0, 28);
 | 
				
			||||||
	current_lc = lowcore_ptr[smp_processor_id()];
 | 
						current_lc = lowcore_ptr[smp_processor_id()];
 | 
				
			||||||
	lc = lowcore_ptr[0];
 | 
						lc = lowcore_ptr[0];
 | 
				
			||||||
	if (!lc)
 | 
						if (!lc)
 | 
				
			||||||
		lc = current_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;
 | 
						lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
 | 
				
			||||||
	if (!cpu_online(0))
 | 
						if (!cpu_online(0))
 | 
				
			||||||
		smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[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;
 | 
						int cpu, rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Disable all interrupts/machine checks */
 | 
						/* 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();
 | 
						trace_hardirqs_off();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* stop all processors */
 | 
						/* stop all processors */
 | 
				
			||||||
| 
						 | 
					@ -501,7 +503,8 @@ int __cpuinit start_secondary(void *cpuvoid)
 | 
				
			||||||
	set_cpu_online(smp_processor_id(), true);
 | 
						set_cpu_online(smp_processor_id(), true);
 | 
				
			||||||
	ipi_call_unlock();
 | 
						ipi_call_unlock();
 | 
				
			||||||
	__ctl_clear_bit(0, 28); /* Disable lowcore protection */
 | 
						__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 =
 | 
						S390_lowcore.restart_psw.addr =
 | 
				
			||||||
		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
 | 
							PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
 | 
				
			||||||
	__ctl_set_bit(0, 28); /* Enable lowcore protection */
 | 
						__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);
 | 
						memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
 | 
				
			||||||
	lowcore->async_stack = async_stack + ASYNC_SIZE;
 | 
						lowcore->async_stack = async_stack + ASYNC_SIZE;
 | 
				
			||||||
	lowcore->panic_stack = panic_stack + PAGE_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 =
 | 
						lowcore->restart_psw.addr =
 | 
				
			||||||
		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
 | 
							PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
 | 
				
			||||||
	if (user_mode != HOME_SPACE_MODE)
 | 
						if (user_mode != HOME_SPACE_MODE)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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_PSTATE), mask_bits(regs, PSW_MASK_ASC),
 | 
				
			||||||
	       mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM));
 | 
						       mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM));
 | 
				
			||||||
#ifdef CONFIG_64BIT
 | 
					#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
 | 
					#endif
 | 
				
			||||||
	printk("\n%s GPRS: " FOURLONG, mode,
 | 
						printk("\n%s GPRS: " FOURLONG, mode,
 | 
				
			||||||
	       regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]);
 | 
						       regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,7 +170,8 @@ void __kprobes vtime_stop_cpu(void)
 | 
				
			||||||
	psw_t psw;
 | 
						psw_t psw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Wait for external, I/O or machine check interrupt. */
 | 
						/* 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;
 | 
						idle->nohz_delay = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,7 +184,8 @@ void __kprobes vtime_stop_cpu(void)
 | 
				
			||||||
		 *	set_cpu_timer(VTIMER_MAX_SLICE);
 | 
							 *	set_cpu_timer(VTIMER_MAX_SLICE);
 | 
				
			||||||
		 *	idle->idle_enter = get_clock();
 | 
							 *	idle->idle_enter = get_clock();
 | 
				
			||||||
		 *	__load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
 | 
							 *	__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 difference is that the inline assembly makes sure that
 | 
				
			||||||
		 * the last three instruction are stpt, stck and lpsw in that
 | 
							 * the last three instruction are stpt, stck and lpsw in that
 | 
				
			||||||
		 * order. This is done to increase the precision.
 | 
							 * order. This is done to increase the precision.
 | 
				
			||||||
| 
						 | 
					@ -216,7 +218,8 @@ void __kprobes vtime_stop_cpu(void)
 | 
				
			||||||
		 *	vq->idle = get_cpu_timer();
 | 
							 *	vq->idle = get_cpu_timer();
 | 
				
			||||||
		 *	idle->idle_enter = get_clock();
 | 
							 *	idle->idle_enter = get_clock();
 | 
				
			||||||
		 *	__load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
 | 
							 *	__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 difference is that the inline assembly makes sure that
 | 
				
			||||||
		 * the last three instruction are stpt, stck and lpsw in that
 | 
							 * the last three instruction are stpt, stck and lpsw in that
 | 
				
			||||||
		 * order. This is done to increase the precision.
 | 
							 * order. This is done to increase the precision.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,8 @@ static void __udelay_disabled(unsigned long long usecs)
 | 
				
			||||||
	u64 clock_saved;
 | 
						u64 clock_saved;
 | 
				
			||||||
	u64 end;
 | 
						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);
 | 
						end = get_clock() + (usecs << 12);
 | 
				
			||||||
	clock_saved = local_tick_disable();
 | 
						clock_saved = local_tick_disable();
 | 
				
			||||||
	__ctl_store(cr0_saved, 0, 0);
 | 
						__ctl_store(cr0_saved, 0, 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -454,7 +454,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
 | 
				
			||||||
	struct pt_regs regs;
 | 
						struct pt_regs regs;
 | 
				
			||||||
	int access, fault;
 | 
						int access, fault;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regs.psw.mask = psw_kernel_bits;
 | 
						regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK;
 | 
				
			||||||
	if (!irqs_disabled())
 | 
						if (!irqs_disabled())
 | 
				
			||||||
		regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
 | 
							regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
 | 
				
			||||||
	regs.psw.addr = (unsigned long) __builtin_return_address(0);
 | 
						regs.psw.addr = (unsigned long) __builtin_return_address(0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,8 +61,8 @@ static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb)
 | 
				
			||||||
	rc = sclp_service_call(cmd, sccb);
 | 
						rc = sclp_service_call(cmd, sccb);
 | 
				
			||||||
	if (rc)
 | 
						if (rc)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	__load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT |
 | 
						__load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA |
 | 
				
			||||||
			PSW_MASK_WAIT | PSW_DEFAULT_KEY);
 | 
								PSW_MASK_BA | PSW_MASK_EXT | PSW_MASK_WAIT);
 | 
				
			||||||
	local_irq_disable();
 | 
						local_irq_disable();
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	/* Contents of the sccb might have changed. */
 | 
						/* Contents of the sccb might have changed. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,8 @@ static void do_machine_quiesce(void)
 | 
				
			||||||
	psw_t quiesce_psw;
 | 
						psw_t quiesce_psw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	smp_send_stop();
 | 
						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;
 | 
						quiesce_psw.addr = 0xfff;
 | 
				
			||||||
	__load_psw(quiesce_psw);
 | 
						__load_psw(quiesce_psw);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue