]>
Commit | Line | Data |
---|---|---|
df1bfe5f GKH |
1 | From 8727638426b0aea59d7f904ad8ddf483f9234f88 Mon Sep 17 00:00:00 2001 |
2 | From: Martin Schwidefsky <schwidefsky@de.ibm.com> | |
3 | Date: Thu, 14 Feb 2019 15:40:56 +0100 | |
4 | Subject: s390/setup: fix early warning messages | |
5 | ||
6 | From: Martin Schwidefsky <schwidefsky@de.ibm.com> | |
7 | ||
8 | commit 8727638426b0aea59d7f904ad8ddf483f9234f88 upstream. | |
9 | ||
10 | The setup_lowcore() function creates a new prefix page for the boot CPU. | |
11 | The PSW mask for the system_call, external interrupt, i/o interrupt and | |
12 | the program check handler have the DAT bit set in this new prefix page. | |
13 | ||
14 | At the time setup_lowcore is called the system still runs without virtual | |
15 | address translation, the paging_init() function creates the kernel page | |
16 | table and loads the CR13 with the kernel ASCE. | |
17 | ||
18 | Any code between setup_lowcore() and the end of paging_init() that has | |
19 | a BUG or WARN statement will create a program check that can not be | |
20 | handled correctly as there is no kernel page table yet. | |
21 | ||
22 | To allow early WARN statements initially setup the lowcore with DAT off | |
23 | and set the DAT bit only after paging_init() has completed. | |
24 | ||
25 | Cc: stable@vger.kernel.org | |
26 | Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> | |
27 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
28 | ||
29 | --- | |
30 | arch/s390/kernel/setup.c | 32 +++++++++++++++++++++++--------- | |
31 | 1 file changed, 23 insertions(+), 9 deletions(-) | |
32 | ||
33 | --- a/arch/s390/kernel/setup.c | |
34 | +++ b/arch/s390/kernel/setup.c | |
35 | @@ -303,7 +303,7 @@ early_param("vmalloc", parse_vmalloc); | |
36 | ||
37 | void *restart_stack __section(.data); | |
38 | ||
39 | -static void __init setup_lowcore(void) | |
40 | +static void __init setup_lowcore_dat_off(void) | |
41 | { | |
42 | struct lowcore *lc; | |
43 | ||
44 | @@ -314,19 +314,16 @@ static void __init setup_lowcore(void) | |
45 | lc = memblock_virt_alloc_low(sizeof(*lc), sizeof(*lc)); | |
46 | lc->restart_psw.mask = PSW_KERNEL_BITS; | |
47 | lc->restart_psw.addr = (unsigned long) restart_int_handler; | |
48 | - lc->external_new_psw.mask = PSW_KERNEL_BITS | | |
49 | - PSW_MASK_DAT | PSW_MASK_MCHECK; | |
50 | + lc->external_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; | |
51 | lc->external_new_psw.addr = (unsigned long) ext_int_handler; | |
52 | lc->svc_new_psw.mask = PSW_KERNEL_BITS | | |
53 | - PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; | |
54 | + PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; | |
55 | lc->svc_new_psw.addr = (unsigned long) system_call; | |
56 | - lc->program_new_psw.mask = PSW_KERNEL_BITS | | |
57 | - PSW_MASK_DAT | PSW_MASK_MCHECK; | |
58 | + lc->program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; | |
59 | lc->program_new_psw.addr = (unsigned long) pgm_check_handler; | |
60 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; | |
61 | lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; | |
62 | - lc->io_new_psw.mask = PSW_KERNEL_BITS | | |
63 | - PSW_MASK_DAT | PSW_MASK_MCHECK; | |
64 | + lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; | |
65 | lc->io_new_psw.addr = (unsigned long) io_int_handler; | |
66 | lc->clock_comparator = clock_comparator_max; | |
67 | lc->kernel_stack = ((unsigned long) &init_thread_union) | |
68 | @@ -388,6 +385,17 @@ static void __init setup_lowcore(void) | |
69 | lowcore_ptr[0] = lc; | |
70 | } | |
71 | ||
72 | +static void __init setup_lowcore_dat_on(void) | |
73 | +{ | |
74 | + struct lowcore *lc; | |
75 | + | |
76 | + lc = lowcore_ptr[0]; | |
77 | + lc->external_new_psw.mask |= PSW_MASK_DAT; | |
78 | + lc->svc_new_psw.mask |= PSW_MASK_DAT; | |
79 | + lc->program_new_psw.mask |= PSW_MASK_DAT; | |
80 | + lc->io_new_psw.mask |= PSW_MASK_DAT; | |
81 | +} | |
82 | + | |
83 | static struct resource code_resource = { | |
84 | .name = "Kernel code", | |
85 | .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, | |
86 | @@ -946,7 +954,7 @@ void __init setup_arch(char **cmdline_p) | |
87 | #endif | |
88 | ||
89 | setup_resources(); | |
90 | - setup_lowcore(); | |
91 | + setup_lowcore_dat_off(); | |
92 | smp_fill_possible_mask(); | |
93 | cpu_detect_mhz_feature(); | |
94 | cpu_init(); | |
95 | @@ -959,6 +967,12 @@ void __init setup_arch(char **cmdline_p) | |
96 | */ | |
97 | paging_init(); | |
98 | ||
99 | + /* | |
100 | + * After paging_init created the kernel page table, the new PSWs | |
101 | + * in lowcore can now run with DAT enabled. | |
102 | + */ | |
103 | + setup_lowcore_dat_on(); | |
104 | + | |
105 | /* Setup default console */ | |
106 | conmode_default(); | |
107 | set_preferred_console(); |