diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-10-27 20:19:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-10-27 20:19:39 -0400 |
commit | d3eab75a7fdd32b4b9c342a07be3525c4d31a41a (patch) | |
tree | 4cb6f857e66216691f4bb7e794e59171ba8666c9 | |
parent | 11dc76f0a4161073be4b85b265ba0d3a5bccbf96 (diff) | |
parent | 90edaac62729d3b9cbb97756261a0049a7fdd6a0 (diff) |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar:
"Misc fixes:
- revert a /dev/mem restriction change that crashes with certain boot
parameters
- an AMD erratum fix for cases where the BIOS doesn't apply it
- fix unwinder debuginfo
- improve ORC unwinder warning printouts"
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
Revert "x86/mm: Limit mmap() of /dev/mem to valid physical addresses"
x86/unwind: Show function name+offset in ORC error messages
x86/entry: Fix idtentry unwind hint
x86/cpu/AMD: Apply the Erratum 688 fix when the BIOS doesn't
-rw-r--r-- | arch/x86/entry/entry_64.S | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/io.h | 4 | ||||
-rw-r--r-- | arch/x86/kernel/amd_nb.c | 41 | ||||
-rw-r--r-- | arch/x86/kernel/unwind_orc.c | 29 | ||||
-rw-r--r-- | arch/x86/mm/mmap.c | 12 |
5 files changed, 57 insertions, 31 deletions
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 49167258d587..f6cdb7a1455e 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S | |||
@@ -808,7 +808,7 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt | |||
808 | 808 | ||
809 | .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 | 809 | .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 |
810 | ENTRY(\sym) | 810 | ENTRY(\sym) |
811 | UNWIND_HINT_IRET_REGS offset=8 | 811 | UNWIND_HINT_IRET_REGS offset=\has_error_code*8 |
812 | 812 | ||
813 | /* Sanity check */ | 813 | /* Sanity check */ |
814 | .if \shift_ist != -1 && \paranoid == 0 | 814 | .if \shift_ist != -1 && \paranoid == 0 |
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 322d25ae23ab..c40a95c33bb8 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h | |||
@@ -110,10 +110,6 @@ build_mmio_write(__writeq, "q", unsigned long, "r", ) | |||
110 | 110 | ||
111 | #endif | 111 | #endif |
112 | 112 | ||
113 | #define ARCH_HAS_VALID_PHYS_ADDR_RANGE | ||
114 | extern int valid_phys_addr_range(phys_addr_t addr, size_t size); | ||
115 | extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); | ||
116 | |||
117 | /** | 113 | /** |
118 | * virt_to_phys - map virtual addresses to physical | 114 | * virt_to_phys - map virtual addresses to physical |
119 | * @address: address to remap | 115 | * @address: address to remap |
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 458da8509b75..6db28f17ff28 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c | |||
@@ -27,6 +27,8 @@ static const struct pci_device_id amd_root_ids[] = { | |||
27 | {} | 27 | {} |
28 | }; | 28 | }; |
29 | 29 | ||
30 | #define PCI_DEVICE_ID_AMD_CNB17H_F4 0x1704 | ||
31 | |||
30 | const struct pci_device_id amd_nb_misc_ids[] = { | 32 | const struct pci_device_id amd_nb_misc_ids[] = { |
31 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, | 33 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, |
32 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, | 34 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, |
@@ -37,6 +39,7 @@ const struct pci_device_id amd_nb_misc_ids[] = { | |||
37 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, | 39 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, |
38 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, | 40 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, |
39 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, | 41 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, |
42 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, | ||
40 | {} | 43 | {} |
41 | }; | 44 | }; |
42 | EXPORT_SYMBOL_GPL(amd_nb_misc_ids); | 45 | EXPORT_SYMBOL_GPL(amd_nb_misc_ids); |
@@ -48,6 +51,7 @@ static const struct pci_device_id amd_nb_link_ids[] = { | |||
48 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, | 51 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, |
49 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) }, | 52 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) }, |
50 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) }, | 53 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) }, |
54 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, | ||
51 | {} | 55 | {} |
52 | }; | 56 | }; |
53 | 57 | ||
@@ -402,11 +406,48 @@ void amd_flush_garts(void) | |||
402 | } | 406 | } |
403 | EXPORT_SYMBOL_GPL(amd_flush_garts); | 407 | EXPORT_SYMBOL_GPL(amd_flush_garts); |
404 | 408 | ||
409 | static void __fix_erratum_688(void *info) | ||
410 | { | ||
411 | #define MSR_AMD64_IC_CFG 0xC0011021 | ||
412 | |||
413 | msr_set_bit(MSR_AMD64_IC_CFG, 3); | ||
414 | msr_set_bit(MSR_AMD64_IC_CFG, 14); | ||
415 | } | ||
416 | |||
417 | /* Apply erratum 688 fix so machines without a BIOS fix work. */ | ||
418 | static __init void fix_erratum_688(void) | ||
419 | { | ||
420 | struct pci_dev *F4; | ||
421 | u32 val; | ||
422 | |||
423 | if (boot_cpu_data.x86 != 0x14) | ||
424 | return; | ||
425 | |||
426 | if (!amd_northbridges.num) | ||
427 | return; | ||
428 | |||
429 | F4 = node_to_amd_nb(0)->link; | ||
430 | if (!F4) | ||
431 | return; | ||
432 | |||
433 | if (pci_read_config_dword(F4, 0x164, &val)) | ||
434 | return; | ||
435 | |||
436 | if (val & BIT(2)) | ||
437 | return; | ||
438 | |||
439 | on_each_cpu(__fix_erratum_688, NULL, 0); | ||
440 | |||
441 | pr_info("x86/cpu/AMD: CPU erratum 688 worked around\n"); | ||
442 | } | ||
443 | |||
405 | static __init int init_amd_nbs(void) | 444 | static __init int init_amd_nbs(void) |
406 | { | 445 | { |
407 | amd_cache_northbridges(); | 446 | amd_cache_northbridges(); |
408 | amd_cache_gart(); | 447 | amd_cache_gart(); |
409 | 448 | ||
449 | fix_erratum_688(); | ||
450 | |||
410 | return 0; | 451 | return 0; |
411 | } | 452 | } |
412 | 453 | ||
diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index 570b70d3f604..b95007e7c1b3 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c | |||
@@ -86,8 +86,8 @@ static struct orc_entry *orc_find(unsigned long ip) | |||
86 | idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE; | 86 | idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE; |
87 | 87 | ||
88 | if (unlikely((idx >= lookup_num_blocks-1))) { | 88 | if (unlikely((idx >= lookup_num_blocks-1))) { |
89 | orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%lx\n", | 89 | orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%pB\n", |
90 | idx, lookup_num_blocks, ip); | 90 | idx, lookup_num_blocks, (void *)ip); |
91 | return NULL; | 91 | return NULL; |
92 | } | 92 | } |
93 | 93 | ||
@@ -96,8 +96,8 @@ static struct orc_entry *orc_find(unsigned long ip) | |||
96 | 96 | ||
97 | if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) || | 97 | if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) || |
98 | (__start_orc_unwind + stop > __stop_orc_unwind))) { | 98 | (__start_orc_unwind + stop > __stop_orc_unwind))) { |
99 | orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%lx\n", | 99 | orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%pB\n", |
100 | idx, lookup_num_blocks, start, stop, ip); | 100 | idx, lookup_num_blocks, start, stop, (void *)ip); |
101 | return NULL; | 101 | return NULL; |
102 | } | 102 | } |
103 | 103 | ||
@@ -373,7 +373,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
373 | 373 | ||
374 | case ORC_REG_R10: | 374 | case ORC_REG_R10: |
375 | if (!state->regs || !state->full_regs) { | 375 | if (!state->regs || !state->full_regs) { |
376 | orc_warn("missing regs for base reg R10 at ip %p\n", | 376 | orc_warn("missing regs for base reg R10 at ip %pB\n", |
377 | (void *)state->ip); | 377 | (void *)state->ip); |
378 | goto done; | 378 | goto done; |
379 | } | 379 | } |
@@ -382,7 +382,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
382 | 382 | ||
383 | case ORC_REG_R13: | 383 | case ORC_REG_R13: |
384 | if (!state->regs || !state->full_regs) { | 384 | if (!state->regs || !state->full_regs) { |
385 | orc_warn("missing regs for base reg R13 at ip %p\n", | 385 | orc_warn("missing regs for base reg R13 at ip %pB\n", |
386 | (void *)state->ip); | 386 | (void *)state->ip); |
387 | goto done; | 387 | goto done; |
388 | } | 388 | } |
@@ -391,7 +391,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
391 | 391 | ||
392 | case ORC_REG_DI: | 392 | case ORC_REG_DI: |
393 | if (!state->regs || !state->full_regs) { | 393 | if (!state->regs || !state->full_regs) { |
394 | orc_warn("missing regs for base reg DI at ip %p\n", | 394 | orc_warn("missing regs for base reg DI at ip %pB\n", |
395 | (void *)state->ip); | 395 | (void *)state->ip); |
396 | goto done; | 396 | goto done; |
397 | } | 397 | } |
@@ -400,7 +400,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
400 | 400 | ||
401 | case ORC_REG_DX: | 401 | case ORC_REG_DX: |
402 | if (!state->regs || !state->full_regs) { | 402 | if (!state->regs || !state->full_regs) { |
403 | orc_warn("missing regs for base reg DX at ip %p\n", | 403 | orc_warn("missing regs for base reg DX at ip %pB\n", |
404 | (void *)state->ip); | 404 | (void *)state->ip); |
405 | goto done; | 405 | goto done; |
406 | } | 406 | } |
@@ -408,7 +408,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
408 | break; | 408 | break; |
409 | 409 | ||
410 | default: | 410 | default: |
411 | orc_warn("unknown SP base reg %d for ip %p\n", | 411 | orc_warn("unknown SP base reg %d for ip %pB\n", |
412 | orc->sp_reg, (void *)state->ip); | 412 | orc->sp_reg, (void *)state->ip); |
413 | goto done; | 413 | goto done; |
414 | } | 414 | } |
@@ -436,7 +436,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
436 | 436 | ||
437 | case ORC_TYPE_REGS: | 437 | case ORC_TYPE_REGS: |
438 | if (!deref_stack_regs(state, sp, &state->ip, &state->sp, true)) { | 438 | if (!deref_stack_regs(state, sp, &state->ip, &state->sp, true)) { |
439 | orc_warn("can't dereference registers at %p for ip %p\n", | 439 | orc_warn("can't dereference registers at %p for ip %pB\n", |
440 | (void *)sp, (void *)orig_ip); | 440 | (void *)sp, (void *)orig_ip); |
441 | goto done; | 441 | goto done; |
442 | } | 442 | } |
@@ -448,7 +448,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
448 | 448 | ||
449 | case ORC_TYPE_REGS_IRET: | 449 | case ORC_TYPE_REGS_IRET: |
450 | if (!deref_stack_regs(state, sp, &state->ip, &state->sp, false)) { | 450 | if (!deref_stack_regs(state, sp, &state->ip, &state->sp, false)) { |
451 | orc_warn("can't dereference iret registers at %p for ip %p\n", | 451 | orc_warn("can't dereference iret registers at %p for ip %pB\n", |
452 | (void *)sp, (void *)orig_ip); | 452 | (void *)sp, (void *)orig_ip); |
453 | goto done; | 453 | goto done; |
454 | } | 454 | } |
@@ -465,7 +465,8 @@ bool unwind_next_frame(struct unwind_state *state) | |||
465 | break; | 465 | break; |
466 | 466 | ||
467 | default: | 467 | default: |
468 | orc_warn("unknown .orc_unwind entry type %d\n", orc->type); | 468 | orc_warn("unknown .orc_unwind entry type %d for ip %pB\n", |
469 | orc->type, (void *)orig_ip); | ||
469 | break; | 470 | break; |
470 | } | 471 | } |
471 | 472 | ||
@@ -487,7 +488,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
487 | break; | 488 | break; |
488 | 489 | ||
489 | default: | 490 | default: |
490 | orc_warn("unknown BP base reg %d for ip %p\n", | 491 | orc_warn("unknown BP base reg %d for ip %pB\n", |
491 | orc->bp_reg, (void *)orig_ip); | 492 | orc->bp_reg, (void *)orig_ip); |
492 | goto done; | 493 | goto done; |
493 | } | 494 | } |
@@ -496,7 +497,7 @@ bool unwind_next_frame(struct unwind_state *state) | |||
496 | if (state->stack_info.type == prev_type && | 497 | if (state->stack_info.type == prev_type && |
497 | on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) && | 498 | on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) && |
498 | state->sp <= prev_sp) { | 499 | state->sp <= prev_sp) { |
499 | orc_warn("stack going in the wrong direction? ip=%p\n", | 500 | orc_warn("stack going in the wrong direction? ip=%pB\n", |
500 | (void *)orig_ip); | 501 | (void *)orig_ip); |
501 | goto done; | 502 | goto done; |
502 | } | 503 | } |
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 320c6237e1d1..a99679826846 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c | |||
@@ -174,15 +174,3 @@ const char *arch_vma_name(struct vm_area_struct *vma) | |||
174 | return "[mpx]"; | 174 | return "[mpx]"; |
175 | return NULL; | 175 | return NULL; |
176 | } | 176 | } |
177 | |||
178 | int valid_phys_addr_range(phys_addr_t addr, size_t count) | ||
179 | { | ||
180 | return addr + count <= __pa(high_memory); | ||
181 | } | ||
182 | |||
183 | int valid_mmap_phys_addr_range(unsigned long pfn, size_t count) | ||
184 | { | ||
185 | phys_addr_t addr = (phys_addr_t)pfn << PAGE_SHIFT; | ||
186 | |||
187 | return valid_phys_addr_range(addr, count); | ||
188 | } | ||