Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad3bc0ac authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

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
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -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)
+6 −5
Original line number Diff line number Diff line
@@ -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
+3 −1
Original line number Diff line number Diff line
@@ -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
+15 −15
Original line number Diff line number Diff line
@@ -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;