diff options
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 19 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_32.S | 8 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 9 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_intel.c | 19 | ||||
-rw-r--r-- | arch/x86/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/ldt.c | 11 | ||||
-rw-r--r-- | drivers/firmware/efi/efi-stub-helper.c | 6 |
9 files changed, 67 insertions, 28 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 1e6146137f8e..4703a6c4b8e3 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -112,7 +112,7 @@ __file_size64(void *__fh, efi_char16_t *filename_16, | |||
112 | efi_file_info_t *info; | 112 | efi_file_info_t *info; |
113 | efi_status_t status; | 113 | efi_status_t status; |
114 | efi_guid_t info_guid = EFI_FILE_INFO_ID; | 114 | efi_guid_t info_guid = EFI_FILE_INFO_ID; |
115 | u32 info_sz; | 115 | u64 info_sz; |
116 | 116 | ||
117 | status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16, | 117 | status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16, |
118 | EFI_FILE_MODE_READ, (u64)0); | 118 | EFI_FILE_MODE_READ, (u64)0); |
@@ -167,31 +167,31 @@ efi_file_size(efi_system_table_t *sys_table, void *__fh, | |||
167 | } | 167 | } |
168 | 168 | ||
169 | static inline efi_status_t | 169 | static inline efi_status_t |
170 | efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr) | 170 | efi_file_read(void *handle, unsigned long *size, void *addr) |
171 | { | 171 | { |
172 | unsigned long func; | 172 | unsigned long func; |
173 | 173 | ||
174 | if (efi_early->is64) { | 174 | if (efi_early->is64) { |
175 | efi_file_handle_64_t *fh = __fh; | 175 | efi_file_handle_64_t *fh = handle; |
176 | 176 | ||
177 | func = (unsigned long)fh->read; | 177 | func = (unsigned long)fh->read; |
178 | return efi_early->call(func, handle, size, addr); | 178 | return efi_early->call(func, handle, size, addr); |
179 | } else { | 179 | } else { |
180 | efi_file_handle_32_t *fh = __fh; | 180 | efi_file_handle_32_t *fh = handle; |
181 | 181 | ||
182 | func = (unsigned long)fh->read; | 182 | func = (unsigned long)fh->read; |
183 | return efi_early->call(func, handle, size, addr); | 183 | return efi_early->call(func, handle, size, addr); |
184 | } | 184 | } |
185 | } | 185 | } |
186 | 186 | ||
187 | static inline efi_status_t efi_file_close(void *__fh, void *handle) | 187 | static inline efi_status_t efi_file_close(void *handle) |
188 | { | 188 | { |
189 | if (efi_early->is64) { | 189 | if (efi_early->is64) { |
190 | efi_file_handle_64_t *fh = __fh; | 190 | efi_file_handle_64_t *fh = handle; |
191 | 191 | ||
192 | return efi_early->call((unsigned long)fh->close, handle); | 192 | return efi_early->call((unsigned long)fh->close, handle); |
193 | } else { | 193 | } else { |
194 | efi_file_handle_32_t *fh = __fh; | 194 | efi_file_handle_32_t *fh = handle; |
195 | 195 | ||
196 | return efi_early->call((unsigned long)fh->close, handle); | 196 | return efi_early->call((unsigned long)fh->close, handle); |
197 | } | 197 | } |
@@ -1016,6 +1016,9 @@ void setup_graphics(struct boot_params *boot_params) | |||
1016 | * Because the x86 boot code expects to be passed a boot_params we | 1016 | * Because the x86 boot code expects to be passed a boot_params we |
1017 | * need to create one ourselves (usually the bootloader would create | 1017 | * need to create one ourselves (usually the bootloader would create |
1018 | * one for us). | 1018 | * one for us). |
1019 | * | ||
1020 | * The caller is responsible for filling out ->code32_start in the | ||
1021 | * returned boot_params. | ||
1019 | */ | 1022 | */ |
1020 | struct boot_params *make_boot_params(struct efi_config *c) | 1023 | struct boot_params *make_boot_params(struct efi_config *c) |
1021 | { | 1024 | { |
@@ -1081,8 +1084,6 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
1081 | hdr->vid_mode = 0xffff; | 1084 | hdr->vid_mode = 0xffff; |
1082 | hdr->boot_flag = 0xAA55; | 1085 | hdr->boot_flag = 0xAA55; |
1083 | 1086 | ||
1084 | hdr->code32_start = (__u64)(unsigned long)image->image_base; | ||
1085 | |||
1086 | hdr->type_of_loader = 0x21; | 1087 | hdr->type_of_loader = 0x21; |
1087 | 1088 | ||
1088 | /* Convert unicode cmdline to ascii */ | 1089 | /* Convert unicode cmdline to ascii */ |
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index de9d4200d305..cbed1407a5cd 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
@@ -59,6 +59,7 @@ ENTRY(efi_pe_entry) | |||
59 | call make_boot_params | 59 | call make_boot_params |
60 | cmpl $0, %eax | 60 | cmpl $0, %eax |
61 | je fail | 61 | je fail |
62 | movl %esi, BP_code32_start(%eax) | ||
62 | popl %ecx | 63 | popl %ecx |
63 | pushl %eax | 64 | pushl %eax |
64 | pushl %ecx | 65 | pushl %ecx |
@@ -90,12 +91,7 @@ fail: | |||
90 | hlt | 91 | hlt |
91 | jmp fail | 92 | jmp fail |
92 | 2: | 93 | 2: |
93 | call 3f | 94 | movl BP_code32_start(%esi), %eax |
94 | 3: | ||
95 | popl %eax | ||
96 | subl $3b, %eax | ||
97 | subl BP_pref_address(%esi), %eax | ||
98 | add BP_code32_start(%esi), %eax | ||
99 | leal preferred_addr(%eax), %eax | 95 | leal preferred_addr(%eax), %eax |
100 | jmp *%eax | 96 | jmp *%eax |
101 | 97 | ||
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 57e58a5fa210..0d558ee899ae 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
@@ -261,6 +261,8 @@ ENTRY(efi_pe_entry) | |||
261 | cmpq $0,%rax | 261 | cmpq $0,%rax |
262 | je fail | 262 | je fail |
263 | mov %rax, %rsi | 263 | mov %rax, %rsi |
264 | leaq startup_32(%rip), %rax | ||
265 | movl %eax, BP_code32_start(%rsi) | ||
264 | jmp 2f /* Skip the relocation */ | 266 | jmp 2f /* Skip the relocation */ |
265 | 267 | ||
266 | handover_entry: | 268 | handover_entry: |
@@ -284,12 +286,7 @@ fail: | |||
284 | hlt | 286 | hlt |
285 | jmp fail | 287 | jmp fail |
286 | 2: | 288 | 2: |
287 | call 3f | 289 | movl BP_code32_start(%esi), %eax |
288 | 3: | ||
289 | popq %rax | ||
290 | subq $3b, %rax | ||
291 | subq BP_pref_address(%rsi), %rax | ||
292 | add BP_code32_start(%esi), %eax | ||
293 | leaq preferred_addr(%rax), %rax | 290 | leaq preferred_addr(%rax), %rax |
294 | jmp *%rax | 291 | jmp *%rax |
295 | 292 | ||
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 481ae38f6a44..ad28db7e6bde 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -1996,7 +1996,8 @@ static inline void __smp_error_interrupt(struct pt_regs *regs) | |||
1996 | }; | 1996 | }; |
1997 | 1997 | ||
1998 | /* First tickle the hardware, only then report what went on. -- REW */ | 1998 | /* First tickle the hardware, only then report what went on. -- REW */ |
1999 | apic_write(APIC_ESR, 0); | 1999 | if (lapic_get_maxlvt() > 3) /* Due to the Pentium erratum 3AP. */ |
2000 | apic_write(APIC_ESR, 0); | ||
2000 | v = apic_read(APIC_ESR); | 2001 | v = apic_read(APIC_ESR); |
2001 | ack_APIC_irq(); | 2002 | ack_APIC_irq(); |
2002 | atomic_inc(&irq_err_count); | 2003 | atomic_inc(&irq_err_count); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 9b7734b1f975..eeee23ff75ef 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -89,6 +89,9 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_chrdev_wait); | |||
89 | static DEFINE_PER_CPU(struct mce, mces_seen); | 89 | static DEFINE_PER_CPU(struct mce, mces_seen); |
90 | static int cpu_missing; | 90 | static int cpu_missing; |
91 | 91 | ||
92 | /* CMCI storm detection filter */ | ||
93 | static DEFINE_PER_CPU(unsigned long, mce_polled_error); | ||
94 | |||
92 | /* | 95 | /* |
93 | * MCA banks polled by the period polling timer for corrected events. | 96 | * MCA banks polled by the period polling timer for corrected events. |
94 | * With Intel CMCI, this only has MCA banks which do not support CMCI (if any). | 97 | * With Intel CMCI, this only has MCA banks which do not support CMCI (if any). |
@@ -595,6 +598,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) | |||
595 | { | 598 | { |
596 | struct mce m; | 599 | struct mce m; |
597 | int i; | 600 | int i; |
601 | unsigned long *v; | ||
598 | 602 | ||
599 | this_cpu_inc(mce_poll_count); | 603 | this_cpu_inc(mce_poll_count); |
600 | 604 | ||
@@ -614,6 +618,8 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) | |||
614 | if (!(m.status & MCI_STATUS_VAL)) | 618 | if (!(m.status & MCI_STATUS_VAL)) |
615 | continue; | 619 | continue; |
616 | 620 | ||
621 | v = &get_cpu_var(mce_polled_error); | ||
622 | set_bit(0, v); | ||
617 | /* | 623 | /* |
618 | * Uncorrected or signalled events are handled by the exception | 624 | * Uncorrected or signalled events are handled by the exception |
619 | * handler when it is enabled, so don't process those here. | 625 | * handler when it is enabled, so don't process those here. |
@@ -1278,10 +1284,18 @@ static unsigned long mce_adjust_timer_default(unsigned long interval) | |||
1278 | static unsigned long (*mce_adjust_timer)(unsigned long interval) = | 1284 | static unsigned long (*mce_adjust_timer)(unsigned long interval) = |
1279 | mce_adjust_timer_default; | 1285 | mce_adjust_timer_default; |
1280 | 1286 | ||
1287 | static int cmc_error_seen(void) | ||
1288 | { | ||
1289 | unsigned long *v = &__get_cpu_var(mce_polled_error); | ||
1290 | |||
1291 | return test_and_clear_bit(0, v); | ||
1292 | } | ||
1293 | |||
1281 | static void mce_timer_fn(unsigned long data) | 1294 | static void mce_timer_fn(unsigned long data) |
1282 | { | 1295 | { |
1283 | struct timer_list *t = &__get_cpu_var(mce_timer); | 1296 | struct timer_list *t = &__get_cpu_var(mce_timer); |
1284 | unsigned long iv; | 1297 | unsigned long iv; |
1298 | int notify; | ||
1285 | 1299 | ||
1286 | WARN_ON(smp_processor_id() != data); | 1300 | WARN_ON(smp_processor_id() != data); |
1287 | 1301 | ||
@@ -1296,7 +1310,9 @@ static void mce_timer_fn(unsigned long data) | |||
1296 | * polling interval, otherwise increase the polling interval. | 1310 | * polling interval, otherwise increase the polling interval. |
1297 | */ | 1311 | */ |
1298 | iv = __this_cpu_read(mce_next_interval); | 1312 | iv = __this_cpu_read(mce_next_interval); |
1299 | if (mce_notify_irq()) { | 1313 | notify = mce_notify_irq(); |
1314 | notify |= cmc_error_seen(); | ||
1315 | if (notify) { | ||
1300 | iv = max(iv / 2, (unsigned long) HZ/100); | 1316 | iv = max(iv / 2, (unsigned long) HZ/100); |
1301 | } else { | 1317 | } else { |
1302 | iv = min(iv * 2, round_jiffies_relative(check_interval * HZ)); | 1318 | iv = min(iv * 2, round_jiffies_relative(check_interval * HZ)); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index fb6156fee6f7..3bdb95ae8c43 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
10 | #include <linux/percpu.h> | 10 | #include <linux/percpu.h> |
11 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
12 | #include <linux/cpumask.h> | ||
12 | #include <asm/apic.h> | 13 | #include <asm/apic.h> |
13 | #include <asm/processor.h> | 14 | #include <asm/processor.h> |
14 | #include <asm/msr.h> | 15 | #include <asm/msr.h> |
@@ -137,6 +138,22 @@ unsigned long mce_intel_adjust_timer(unsigned long interval) | |||
137 | } | 138 | } |
138 | } | 139 | } |
139 | 140 | ||
141 | static void cmci_storm_disable_banks(void) | ||
142 | { | ||
143 | unsigned long flags, *owned; | ||
144 | int bank; | ||
145 | u64 val; | ||
146 | |||
147 | raw_spin_lock_irqsave(&cmci_discover_lock, flags); | ||
148 | owned = __get_cpu_var(mce_banks_owned); | ||
149 | for_each_set_bit(bank, owned, MAX_NR_BANKS) { | ||
150 | rdmsrl(MSR_IA32_MCx_CTL2(bank), val); | ||
151 | val &= ~MCI_CTL2_CMCI_EN; | ||
152 | wrmsrl(MSR_IA32_MCx_CTL2(bank), val); | ||
153 | } | ||
154 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); | ||
155 | } | ||
156 | |||
140 | static bool cmci_storm_detect(void) | 157 | static bool cmci_storm_detect(void) |
141 | { | 158 | { |
142 | unsigned int cnt = __this_cpu_read(cmci_storm_cnt); | 159 | unsigned int cnt = __this_cpu_read(cmci_storm_cnt); |
@@ -158,7 +175,7 @@ static bool cmci_storm_detect(void) | |||
158 | if (cnt <= CMCI_STORM_THRESHOLD) | 175 | if (cnt <= CMCI_STORM_THRESHOLD) |
159 | return false; | 176 | return false; |
160 | 177 | ||
161 | cmci_clear(); | 178 | cmci_storm_disable_banks(); |
162 | __this_cpu_write(cmci_storm_state, CMCI_STORM_ACTIVE); | 179 | __this_cpu_write(cmci_storm_state, CMCI_STORM_ACTIVE); |
163 | r = atomic_add_return(1, &cmci_storm_on_cpus); | 180 | r = atomic_add_return(1, &cmci_storm_on_cpus); |
164 | mce_timer_kick(CMCI_POLL_INTERVAL); | 181 | mce_timer_kick(CMCI_POLL_INTERVAL); |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 42805fac0092..283a76a9cc40 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -125,7 +125,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
125 | seq_printf(p, "%10u ", per_cpu(mce_poll_count, j)); | 125 | seq_printf(p, "%10u ", per_cpu(mce_poll_count, j)); |
126 | seq_printf(p, " Machine check polls\n"); | 126 | seq_printf(p, " Machine check polls\n"); |
127 | #endif | 127 | #endif |
128 | #if defined(CONFIG_HYPERV) || defined(CONFIG_XEN) | 128 | #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) |
129 | seq_printf(p, "%*s: ", prec, "THR"); | 129 | seq_printf(p, "%*s: ", prec, "THR"); |
130 | for_each_online_cpu(j) | 130 | for_each_online_cpu(j) |
131 | seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); | 131 | seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); |
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index ebc987398923..af1d14a9ebda 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
@@ -229,6 +229,17 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) | |||
229 | } | 229 | } |
230 | } | 230 | } |
231 | 231 | ||
232 | /* | ||
233 | * On x86-64 we do not support 16-bit segments due to | ||
234 | * IRET leaking the high bits of the kernel stack address. | ||
235 | */ | ||
236 | #ifdef CONFIG_X86_64 | ||
237 | if (!ldt_info.seg_32bit) { | ||
238 | error = -EINVAL; | ||
239 | goto out_unlock; | ||
240 | } | ||
241 | #endif | ||
242 | |||
232 | fill_ldt(&ldt, &ldt_info); | 243 | fill_ldt(&ldt, &ldt_info); |
233 | if (oldmode) | 244 | if (oldmode) |
234 | ldt.avl = 0; | 245 | ldt.avl = 0; |
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c index ff50aeebf0d9..2c41eaece2c1 100644 --- a/drivers/firmware/efi/efi-stub-helper.c +++ b/drivers/firmware/efi/efi-stub-helper.c | |||
@@ -397,7 +397,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, | |||
397 | else | 397 | else |
398 | chunksize = size; | 398 | chunksize = size; |
399 | 399 | ||
400 | status = efi_file_read(fh, files[j].handle, | 400 | status = efi_file_read(files[j].handle, |
401 | &chunksize, | 401 | &chunksize, |
402 | (void *)addr); | 402 | (void *)addr); |
403 | if (status != EFI_SUCCESS) { | 403 | if (status != EFI_SUCCESS) { |
@@ -408,7 +408,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, | |||
408 | size -= chunksize; | 408 | size -= chunksize; |
409 | } | 409 | } |
410 | 410 | ||
411 | efi_file_close(fh, files[j].handle); | 411 | efi_file_close(files[j].handle); |
412 | } | 412 | } |
413 | 413 | ||
414 | } | 414 | } |
@@ -425,7 +425,7 @@ free_file_total: | |||
425 | 425 | ||
426 | close_handles: | 426 | close_handles: |
427 | for (k = j; k < i; k++) | 427 | for (k = j; k < i; k++) |
428 | efi_file_close(fh, files[k].handle); | 428 | efi_file_close(files[k].handle); |
429 | free_files: | 429 | free_files: |
430 | efi_call_early(free_pool, files); | 430 | efi_call_early(free_pool, files); |
431 | fail: | 431 | fail: |