s390/sclp: make early sclp irq handler more robust
Make the early sclp interrupt handler more robust: - disable all interrupt sub classes except for the service signal subclass - extend ctlreg0 union so it is easily possible to set the service signal subclass mask bit without using a magic number - disable lowcore protection before writing to it - make sure that all write accesses are done before the original content of control register 0 is restored, which could enable lowcore protection Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
68cc795d19
commit
742dc5773c
|
@ -62,7 +62,9 @@ union ctlreg0 {
|
|||
unsigned long : 4;
|
||||
unsigned long afp : 1; /* AFP-register control */
|
||||
unsigned long vx : 1; /* Vector enablement control */
|
||||
unsigned long : 17;
|
||||
unsigned long : 7;
|
||||
unsigned long sssm : 1; /* Service signal subclass mask */
|
||||
unsigned long : 9;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -18,12 +18,16 @@ static bool have_linemode __section(data);
|
|||
|
||||
static void _sclp_wait_int(void)
|
||||
{
|
||||
unsigned long cr0, cr0_new, psw_mask, addr;
|
||||
unsigned long psw_mask, addr, flags;
|
||||
psw_t psw_ext_save, psw_wait;
|
||||
union ctlreg0 cr0, cr0_new;
|
||||
|
||||
__ctl_store(cr0, 0, 0);
|
||||
cr0_new = cr0 | 0x200;
|
||||
__ctl_load(cr0_new, 0, 0);
|
||||
raw_local_irq_save(flags);
|
||||
__ctl_store(cr0.val, 0, 0);
|
||||
cr0_new.val = cr0.val & ~CR0_IRQ_SUBCLASS_MASK;
|
||||
cr0_new.lap = 0;
|
||||
cr0_new.sssm = 1;
|
||||
__ctl_load(cr0_new.val, 0, 0);
|
||||
|
||||
psw_ext_save = S390_lowcore.external_new_psw;
|
||||
psw_mask = __extract_psw();
|
||||
|
@ -45,8 +49,9 @@ static void _sclp_wait_int(void)
|
|||
: "cc", "memory");
|
||||
} while (S390_lowcore.ext_int_code != EXT_IRQ_SERVICE_SIG);
|
||||
|
||||
__ctl_load(cr0, 0, 0);
|
||||
S390_lowcore.external_new_psw = psw_ext_save;
|
||||
__ctl_load(cr0.val, 0, 0);
|
||||
raw_local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static int _sclp_servc(unsigned int cmd, char *sccb)
|
||||
|
|
Loading…
Reference in New Issue