aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-10-27 20:19:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-10-27 20:19:39 -0400
commitd3eab75a7fdd32b4b9c342a07be3525c4d31a41a (patch)
tree4cb6f857e66216691f4bb7e794e59171ba8666c9
parent11dc76f0a4161073be4b85b265ba0d3a5bccbf96 (diff)
parent90edaac62729d3b9cbb97756261a0049a7fdd6a0 (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.S2
-rw-r--r--arch/x86/include/asm/io.h4
-rw-r--r--arch/x86/kernel/amd_nb.c41
-rw-r--r--arch/x86/kernel/unwind_orc.c29
-rw-r--r--arch/x86/mm/mmap.c12
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
810ENTRY(\sym) 810ENTRY(\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
114extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
115extern 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
30const struct pci_device_id amd_nb_misc_ids[] = { 32const 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};
42EXPORT_SYMBOL_GPL(amd_nb_misc_ids); 45EXPORT_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}
403EXPORT_SYMBOL_GPL(amd_flush_garts); 407EXPORT_SYMBOL_GPL(amd_flush_garts);
404 408
409static 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. */
418static __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
405static __init int init_amd_nbs(void) 444static __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
178int valid_phys_addr_range(phys_addr_t addr, size_t count)
179{
180 return addr + count <= __pa(high_memory);
181}
182
183int 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}