Commit ad3bc0ac authored by Martin Schwidefsky's avatar Martin Schwidefsky

s390/ctl_reg: use decoding unions in update_cr_regs

Add a decoding union for the bits in control registers 2 and use
'union ctlreg0' and 'union ctlreg2' in update_cr_regs to improve
readability.
Reviewed-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: default avatarHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 00a8f886
...@@ -54,7 +54,11 @@ void smp_ctl_clear_bit(int cr, int bit); ...@@ -54,7 +54,11 @@ void smp_ctl_clear_bit(int cr, int bit);
union ctlreg0 { union ctlreg0 {
unsigned long val; unsigned long val;
struct { struct {
unsigned long : 32; unsigned long : 8;
unsigned long tcx : 1; /* Transactional-Execution control */
unsigned long pifo : 1; /* Transactional-Execution Program-
Interruption-Filtering Override */
unsigned long : 22;
unsigned long : 3; unsigned long : 3;
unsigned long lap : 1; /* Low-address-protection control */ unsigned long lap : 1; /* Low-address-protection control */
unsigned long : 4; unsigned long : 4;
...@@ -70,6 +74,19 @@ union ctlreg0 { ...@@ -70,6 +74,19 @@ union ctlreg0 {
}; };
}; };
union ctlreg2 {
unsigned long val;
struct {
unsigned long : 33;
unsigned long ducto : 25;
unsigned long : 1;
unsigned long gse : 1;
unsigned long : 1;
unsigned long tds : 1;
unsigned long tdc : 2;
};
};
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
# define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit) # define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit)
# define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit) # define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit)
......
...@@ -105,7 +105,7 @@ static void __do_machine_kdump(void *image) ...@@ -105,7 +105,7 @@ static void __do_machine_kdump(void *image)
static noinline void __machine_kdump(void *image) static noinline void __machine_kdump(void *image)
{ {
struct mcesa *mcesa; struct mcesa *mcesa;
unsigned long cr2_old, cr2_new; union ctlreg2 cr2_old, cr2_new;
int this_cpu, cpu; int this_cpu, cpu;
lgr_info_log(); lgr_info_log();
...@@ -122,11 +122,12 @@ static noinline void __machine_kdump(void *image) ...@@ -122,11 +122,12 @@ static noinline void __machine_kdump(void *image)
if (MACHINE_HAS_VX) if (MACHINE_HAS_VX)
save_vx_regs((__vector128 *) mcesa->vector_save_area); save_vx_regs((__vector128 *) mcesa->vector_save_area);
if (MACHINE_HAS_GS) { if (MACHINE_HAS_GS) {
__ctl_store(cr2_old, 2, 2); __ctl_store(cr2_old.val, 2, 2);
cr2_new = cr2_old | (1UL << 4); cr2_new = cr2_old;
__ctl_load(cr2_new, 2, 2); cr2_new.gse = 1;
__ctl_load(cr2_new.val, 2, 2);
save_gs_cb((struct gs_cb *) mcesa->guarded_storage_save_area); save_gs_cb((struct gs_cb *) mcesa->guarded_storage_save_area);
__ctl_load(cr2_old, 2, 2); __ctl_load(cr2_old.val, 2, 2);
} }
/* /*
* To create a good backchain for this CPU in the dump store_status * To create a good backchain for this CPU in the dump store_status
......
...@@ -107,6 +107,7 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck); ...@@ -107,6 +107,7 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
*/ */
static int notrace s390_validate_registers(union mci mci, int umode) static int notrace s390_validate_registers(union mci mci, int umode)
{ {
union ctlreg2 cr2;
int kill_task; int kill_task;
u64 zero; u64 zero;
void *fpt_save_area; void *fpt_save_area;
...@@ -231,7 +232,8 @@ static int notrace s390_validate_registers(union mci mci, int umode) ...@@ -231,7 +232,8 @@ static int notrace s390_validate_registers(union mci mci, int umode)
kill_task = 1; kill_task = 1;
} }
/* Validate guarded storage registers */ /* Validate guarded storage registers */
if (MACHINE_HAS_GS && (S390_lowcore.cregs_save_area[2] & (1UL << 4))) { cr2.val = S390_lowcore.cregs_save_area[2];
if (cr2.gse) {
if (!mci.gs) if (!mci.gs)
/* /*
* Guarded storage register can't be restored and * Guarded storage register can't be restored and
......
...@@ -47,42 +47,42 @@ void update_cr_regs(struct task_struct *task) ...@@ -47,42 +47,42 @@ void update_cr_regs(struct task_struct *task)
struct pt_regs *regs = task_pt_regs(task); struct pt_regs *regs = task_pt_regs(task);
struct thread_struct *thread = &task->thread; struct thread_struct *thread = &task->thread;
struct per_regs old, new; struct per_regs old, new;
unsigned long cr0_old, cr0_new; union ctlreg0 cr0_old, cr0_new;
unsigned long cr2_old, cr2_new; union ctlreg2 cr2_old, cr2_new;
int cr0_changed, cr2_changed; int cr0_changed, cr2_changed;
__ctl_store(cr0_old, 0, 0); __ctl_store(cr0_old.val, 0, 0);
__ctl_store(cr2_old, 2, 2); __ctl_store(cr2_old.val, 2, 2);
cr0_new = cr0_old; cr0_new = cr0_old;
cr2_new = cr2_old; cr2_new = cr2_old;
/* Take care of the enable/disable of transactional execution. */ /* Take care of the enable/disable of transactional execution. */
if (MACHINE_HAS_TE) { if (MACHINE_HAS_TE) {
/* Set or clear transaction execution TXC bit 8. */ /* Set or clear transaction execution TXC bit 8. */
cr0_new |= (1UL << 55); cr0_new.tcx = 1;
if (task->thread.per_flags & PER_FLAG_NO_TE) if (task->thread.per_flags & PER_FLAG_NO_TE)
cr0_new &= ~(1UL << 55); cr0_new.tcx = 0;
/* Set or clear transaction execution TDC bits 62 and 63. */ /* Set or clear transaction execution TDC bits 62 and 63. */
cr2_new &= ~3UL; cr2_new.tdc = 0;
if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) { if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) {
if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND) if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND)
cr2_new |= 1UL; cr2_new.tdc = 1;
else else
cr2_new |= 2UL; cr2_new.tdc = 2;
} }
} }
/* Take care of enable/disable of guarded storage. */ /* Take care of enable/disable of guarded storage. */
if (MACHINE_HAS_GS) { if (MACHINE_HAS_GS) {
cr2_new &= ~(1UL << 4); cr2_new.gse = 0;
if (task->thread.gs_cb) if (task->thread.gs_cb)
cr2_new |= (1UL << 4); cr2_new.gse = 1;
} }
/* Load control register 0/2 iff changed */ /* Load control register 0/2 iff changed */
cr0_changed = cr0_new != cr0_old; cr0_changed = cr0_new.val != cr0_old.val;
cr2_changed = cr2_new != cr2_old; cr2_changed = cr2_new.val != cr2_old.val;
if (cr0_changed) if (cr0_changed)
__ctl_load(cr0_new, 0, 0); __ctl_load(cr0_new.val, 0, 0);
if (cr2_changed) if (cr2_changed)
__ctl_load(cr2_new, 2, 2); __ctl_load(cr2_new.val, 2, 2);
/* Copy user specified PER registers */ /* Copy user specified PER registers */
new.control = thread->per_user.control; new.control = thread->per_user.control;
new.start = thread->per_user.start; new.start = thread->per_user.start;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment