mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
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: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
00a8f886db
commit
ad3bc0ac1d
4 changed files with 42 additions and 22 deletions
|
@ -54,7 +54,11 @@ void smp_ctl_clear_bit(int cr, int bit);
|
|||
union ctlreg0 {
|
||||
unsigned long val;
|
||||
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 lap : 1; /* Low-address-protection control */
|
||||
unsigned long : 4;
|
||||
|
@ -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
|
||||
# define ctl_set_bit(cr, bit) smp_ctl_set_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)
|
|||
static noinline void __machine_kdump(void *image)
|
||||
{
|
||||
struct mcesa *mcesa;
|
||||
unsigned long cr2_old, cr2_new;
|
||||
union ctlreg2 cr2_old, cr2_new;
|
||||
int this_cpu, cpu;
|
||||
|
||||
lgr_info_log();
|
||||
|
@ -122,11 +122,12 @@ static noinline void __machine_kdump(void *image)
|
|||
if (MACHINE_HAS_VX)
|
||||
save_vx_regs((__vector128 *) mcesa->vector_save_area);
|
||||
if (MACHINE_HAS_GS) {
|
||||
__ctl_store(cr2_old, 2, 2);
|
||||
cr2_new = cr2_old | (1UL << 4);
|
||||
__ctl_load(cr2_new, 2, 2);
|
||||
__ctl_store(cr2_old.val, 2, 2);
|
||||
cr2_new = cr2_old;
|
||||
cr2_new.gse = 1;
|
||||
__ctl_load(cr2_new.val, 2, 2);
|
||||
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
|
||||
|
|
|
@ -107,6 +107,7 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
|
|||
*/
|
||||
static int notrace s390_validate_registers(union mci mci, int umode)
|
||||
{
|
||||
union ctlreg2 cr2;
|
||||
int kill_task;
|
||||
u64 zero;
|
||||
void *fpt_save_area;
|
||||
|
@ -231,7 +232,8 @@ static int notrace s390_validate_registers(union mci mci, int umode)
|
|||
kill_task = 1;
|
||||
}
|
||||
/* 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)
|
||||
/*
|
||||
* Guarded storage register can't be restored and
|
||||
|
|
|
@ -47,42 +47,42 @@ void update_cr_regs(struct task_struct *task)
|
|||
struct pt_regs *regs = task_pt_regs(task);
|
||||
struct thread_struct *thread = &task->thread;
|
||||
struct per_regs old, new;
|
||||
unsigned long cr0_old, cr0_new;
|
||||
unsigned long cr2_old, cr2_new;
|
||||
union ctlreg0 cr0_old, cr0_new;
|
||||
union ctlreg2 cr2_old, cr2_new;
|
||||
int cr0_changed, cr2_changed;
|
||||
|
||||
__ctl_store(cr0_old, 0, 0);
|
||||
__ctl_store(cr2_old, 2, 2);
|
||||
__ctl_store(cr0_old.val, 0, 0);
|
||||
__ctl_store(cr2_old.val, 2, 2);
|
||||
cr0_new = cr0_old;
|
||||
cr2_new = cr2_old;
|
||||
/* Take care of the enable/disable of transactional execution. */
|
||||
if (MACHINE_HAS_TE) {
|
||||
/* 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)
|
||||
cr0_new &= ~(1UL << 55);
|
||||
cr0_new.tcx = 0;
|
||||
/* 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_TEND)
|
||||
cr2_new |= 1UL;
|
||||
cr2_new.tdc = 1;
|
||||
else
|
||||
cr2_new |= 2UL;
|
||||
cr2_new.tdc = 2;
|
||||
}
|
||||
}
|
||||
/* Take care of enable/disable of guarded storage. */
|
||||
if (MACHINE_HAS_GS) {
|
||||
cr2_new &= ~(1UL << 4);
|
||||
cr2_new.gse = 0;
|
||||
if (task->thread.gs_cb)
|
||||
cr2_new |= (1UL << 4);
|
||||
cr2_new.gse = 1;
|
||||
}
|
||||
/* Load control register 0/2 iff changed */
|
||||
cr0_changed = cr0_new != cr0_old;
|
||||
cr2_changed = cr2_new != cr2_old;
|
||||
cr0_changed = cr0_new.val != cr0_old.val;
|
||||
cr2_changed = cr2_new.val != cr2_old.val;
|
||||
if (cr0_changed)
|
||||
__ctl_load(cr0_new, 0, 0);
|
||||
__ctl_load(cr0_new.val, 0, 0);
|
||||
if (cr2_changed)
|
||||
__ctl_load(cr2_new, 2, 2);
|
||||
__ctl_load(cr2_new.val, 2, 2);
|
||||
/* Copy user specified PER registers */
|
||||
new.control = thread->per_user.control;
|
||||
new.start = thread->per_user.start;
|
||||
|
|
Loading…
Reference in a new issue