Commit b52bdf53 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Greg Kroah-Hartman

s390/setup: fix early warning messages

commit 87276384 upstream.

The setup_lowcore() function creates a new prefix page for the boot CPU.
The PSW mask for the system_call, external interrupt, i/o interrupt and
the program check handler have the DAT bit set in this new prefix page.

At the time setup_lowcore is called the system still runs without virtual
address translation, the paging_init() function creates the kernel page
table and loads the CR13 with the kernel ASCE.

Any code between setup_lowcore() and the end of paging_init() that has
a BUG or WARN statement will create a program check that can not be
handled correctly as there is no kernel page table yet.

To allow early WARN statements initially setup the lowcore with DAT off
and set the DAT bit only after paging_init() has completed.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e19ca3fe
...@@ -303,7 +303,7 @@ early_param("vmalloc", parse_vmalloc); ...@@ -303,7 +303,7 @@ early_param("vmalloc", parse_vmalloc);
void *restart_stack __section(.data); void *restart_stack __section(.data);
static void __init setup_lowcore(void) static void __init setup_lowcore_dat_off(void)
{ {
struct lowcore *lc; struct lowcore *lc;
...@@ -314,19 +314,16 @@ static void __init setup_lowcore(void) ...@@ -314,19 +314,16 @@ static void __init setup_lowcore(void)
lc = memblock_virt_alloc_low(sizeof(*lc), sizeof(*lc)); lc = memblock_virt_alloc_low(sizeof(*lc), sizeof(*lc));
lc->restart_psw.mask = PSW_KERNEL_BITS; lc->restart_psw.mask = PSW_KERNEL_BITS;
lc->restart_psw.addr = (unsigned long) restart_int_handler; lc->restart_psw.addr = (unsigned long) restart_int_handler;
lc->external_new_psw.mask = PSW_KERNEL_BITS | lc->external_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK;
PSW_MASK_DAT | PSW_MASK_MCHECK;
lc->external_new_psw.addr = (unsigned long) ext_int_handler; lc->external_new_psw.addr = (unsigned long) ext_int_handler;
lc->svc_new_psw.mask = PSW_KERNEL_BITS | lc->svc_new_psw.mask = PSW_KERNEL_BITS |
PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
lc->svc_new_psw.addr = (unsigned long) system_call; lc->svc_new_psw.addr = (unsigned long) system_call;
lc->program_new_psw.mask = PSW_KERNEL_BITS | lc->program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK;
PSW_MASK_DAT | PSW_MASK_MCHECK;
lc->program_new_psw.addr = (unsigned long) pgm_check_handler; lc->program_new_psw.addr = (unsigned long) pgm_check_handler;
lc->mcck_new_psw.mask = PSW_KERNEL_BITS; lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler;
lc->io_new_psw.mask = PSW_KERNEL_BITS | lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK;
PSW_MASK_DAT | PSW_MASK_MCHECK;
lc->io_new_psw.addr = (unsigned long) io_int_handler; lc->io_new_psw.addr = (unsigned long) io_int_handler;
lc->clock_comparator = clock_comparator_max; lc->clock_comparator = clock_comparator_max;
lc->kernel_stack = ((unsigned long) &init_thread_union) lc->kernel_stack = ((unsigned long) &init_thread_union)
...@@ -388,6 +385,17 @@ static void __init setup_lowcore(void) ...@@ -388,6 +385,17 @@ static void __init setup_lowcore(void)
lowcore_ptr[0] = lc; lowcore_ptr[0] = lc;
} }
static void __init setup_lowcore_dat_on(void)
{
struct lowcore *lc;
lc = lowcore_ptr[0];
lc->external_new_psw.mask |= PSW_MASK_DAT;
lc->svc_new_psw.mask |= PSW_MASK_DAT;
lc->program_new_psw.mask |= PSW_MASK_DAT;
lc->io_new_psw.mask |= PSW_MASK_DAT;
}
static struct resource code_resource = { static struct resource code_resource = {
.name = "Kernel code", .name = "Kernel code",
.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
...@@ -946,7 +954,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -946,7 +954,7 @@ void __init setup_arch(char **cmdline_p)
#endif #endif
setup_resources(); setup_resources();
setup_lowcore(); setup_lowcore_dat_off();
smp_fill_possible_mask(); smp_fill_possible_mask();
cpu_detect_mhz_feature(); cpu_detect_mhz_feature();
cpu_init(); cpu_init();
...@@ -959,6 +967,12 @@ void __init setup_arch(char **cmdline_p) ...@@ -959,6 +967,12 @@ void __init setup_arch(char **cmdline_p)
*/ */
paging_init(); paging_init();
/*
* After paging_init created the kernel page table, the new PSWs
* in lowcore can now run with DAT enabled.
*/
setup_lowcore_dat_on();
/* Setup default console */ /* Setup default console */
conmode_default(); conmode_default();
set_preferred_console(); set_preferred_console();
......
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