aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-22 14:40:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-22 14:40:52 -0400
commit37a535edd72cacf73b456d4e9272ff2ee4bf7405 (patch)
tree0d856238eea6293d4cb2d3a00dd17736a2f3c506
parentc1e9dae0a9bf3394818abafaf376a34248c5f638 (diff)
parent05189820da23fc87ee2a7d87c20257f298af27f4 (diff)
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "A small set of fixes for x86: - Prevent X2APIC ID 0xFFFFFFFF from being treated as valid, which causes the possible CPU count to be wrong. - Prevent 32bit truncation in calc_hpet_ref() which causes the TSC calibration to fail - Fix the page table setup for temporary text mappings in the resume code which causes resume failures - Make the page table dump code handle HIGHPTE correctly instead of oopsing - Support for topologies where NUMA nodes share an LLC to prevent a invalid topology warning and further malfunction on such systems. - Remove the now unused pci-nommu code - Remove stale function declarations" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/power/64: Fix page-table setup for temporary text mapping x86/mm: Prevent kernel Oops in PTDUMP code with HIGHPTE=y x86,sched: Allow topologies where NUMA nodes share an LLC x86/processor: Remove two unused function declarations x86/acpi: Prevent X2APIC id 0xffffffff from being accounted x86/tsc: Prevent 32bit truncation in calc_hpet_ref() x86: Remove pci-nommu.c
-rw-r--r--arch/x86/include/asm/processor.h2
-rw-r--r--arch/x86/kernel/acpi/boot.c4
-rw-r--r--arch/x86/kernel/pci-nommu.c90
-rw-r--r--arch/x86/kernel/smpboot.c45
-rw-r--r--arch/x86/kernel/tsc.c2
-rw-r--r--arch/x86/mm/dump_pagetables.c11
-rw-r--r--arch/x86/power/hibernate_64.c2
7 files changed, 52 insertions, 104 deletions
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 4fa4206029e3..21a114914ba4 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -749,13 +749,11 @@ enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
749extern void enable_sep_cpu(void); 749extern void enable_sep_cpu(void);
750extern int sysenter_setup(void); 750extern int sysenter_setup(void);
751 751
752extern void early_trap_init(void);
753void early_trap_pf_init(void); 752void early_trap_pf_init(void);
754 753
755/* Defined in head.S */ 754/* Defined in head.S */
756extern struct desc_ptr early_gdt_descr; 755extern struct desc_ptr early_gdt_descr;
757 756
758extern void cpu_set_gdt(int);
759extern void switch_to_new_gdt(int); 757extern void switch_to_new_gdt(int);
760extern void load_direct_gdt(int); 758extern void load_direct_gdt(int);
761extern void load_fixmap_gdt(int); 759extern void load_fixmap_gdt(int);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index dde444f932c1..3b20607d581b 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -215,6 +215,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
215 apic_id = processor->local_apic_id; 215 apic_id = processor->local_apic_id;
216 enabled = processor->lapic_flags & ACPI_MADT_ENABLED; 216 enabled = processor->lapic_flags & ACPI_MADT_ENABLED;
217 217
218 /* Ignore invalid ID */
219 if (apic_id == 0xffffffff)
220 return 0;
221
218 /* 222 /*
219 * We need to register disabled CPU as well to permit 223 * We need to register disabled CPU as well to permit
220 * counting disabled CPUs. This allows us to size 224 * counting disabled CPUs. This allows us to size
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
deleted file mode 100644
index ac7ea3a8242f..000000000000
--- a/arch/x86/kernel/pci-nommu.c
+++ /dev/null
@@ -1,90 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Fallback functions when the main IOMMU code is not compiled in. This
3 code is roughly equivalent to i386. */
4#include <linux/dma-direct.h>
5#include <linux/scatterlist.h>
6#include <linux/string.h>
7#include <linux/gfp.h>
8#include <linux/pci.h>
9#include <linux/mm.h>
10
11#include <asm/processor.h>
12#include <asm/iommu.h>
13#include <asm/dma.h>
14
15#define NOMMU_MAPPING_ERROR 0
16
17static int
18check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size)
19{
20 if (hwdev && !dma_capable(hwdev, bus, size)) {
21 if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
22 printk(KERN_ERR
23 "nommu_%s: overflow %Lx+%zu of device mask %Lx\n",
24 name, (long long)bus, size,
25 (long long)*hwdev->dma_mask);
26 return 0;
27 }
28 return 1;
29}
30
31static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
32 unsigned long offset, size_t size,
33 enum dma_data_direction dir,
34 unsigned long attrs)
35{
36 dma_addr_t bus = phys_to_dma(dev, page_to_phys(page)) + offset;
37 WARN_ON(size == 0);
38 if (!check_addr("map_single", dev, bus, size))
39 return NOMMU_MAPPING_ERROR;
40 return bus;
41}
42
43/* Map a set of buffers described by scatterlist in streaming
44 * mode for DMA. This is the scatter-gather version of the
45 * above pci_map_single interface. Here the scatter gather list
46 * elements are each tagged with the appropriate dma address
47 * and length. They are obtained via sg_dma_{address,length}(SG).
48 *
49 * NOTE: An implementation may be able to use a smaller number of
50 * DMA address/length pairs than there are SG table elements.
51 * (for example via virtual mapping capabilities)
52 * The routine returns the number of addr/length pairs actually
53 * used, at most nents.
54 *
55 * Device ownership issues as mentioned above for pci_map_single are
56 * the same here.
57 */
58static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
59 int nents, enum dma_data_direction dir,
60 unsigned long attrs)
61{
62 struct scatterlist *s;
63 int i;
64
65 WARN_ON(nents == 0 || sg[0].length == 0);
66
67 for_each_sg(sg, s, nents, i) {
68 BUG_ON(!sg_page(s));
69 s->dma_address = sg_phys(s);
70 if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
71 return 0;
72 s->dma_length = s->length;
73 }
74 return nents;
75}
76
77static int nommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
78{
79 return dma_addr == NOMMU_MAPPING_ERROR;
80}
81
82const struct dma_map_ops nommu_dma_ops = {
83 .alloc = dma_generic_alloc_coherent,
84 .free = dma_generic_free_coherent,
85 .map_sg = nommu_map_sg,
86 .map_page = nommu_map_page,
87 .is_phys = 1,
88 .mapping_error = nommu_mapping_error,
89 .dma_supported = x86_dma_supported,
90};
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index ff99e2b6fc54..45175b81dd5b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -77,6 +77,8 @@
77#include <asm/i8259.h> 77#include <asm/i8259.h>
78#include <asm/misc.h> 78#include <asm/misc.h>
79#include <asm/qspinlock.h> 79#include <asm/qspinlock.h>
80#include <asm/intel-family.h>
81#include <asm/cpu_device_id.h>
80 82
81/* Number of siblings per CPU package */ 83/* Number of siblings per CPU package */
82int smp_num_siblings = 1; 84int smp_num_siblings = 1;
@@ -390,15 +392,47 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
390 return false; 392 return false;
391} 393}
392 394
395/*
396 * Define snc_cpu[] for SNC (Sub-NUMA Cluster) CPUs.
397 *
398 * These are Intel CPUs that enumerate an LLC that is shared by
399 * multiple NUMA nodes. The LLC on these systems is shared for
400 * off-package data access but private to the NUMA node (half
401 * of the package) for on-package access.
402 *
403 * CPUID (the source of the information about the LLC) can only
404 * enumerate the cache as being shared *or* unshared, but not
405 * this particular configuration. The CPU in this case enumerates
406 * the cache to be shared across the entire package (spanning both
407 * NUMA nodes).
408 */
409
410static const struct x86_cpu_id snc_cpu[] = {
411 { X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X },
412 {}
413};
414
393static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) 415static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
394{ 416{
395 int cpu1 = c->cpu_index, cpu2 = o->cpu_index; 417 int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
396 418
397 if (per_cpu(cpu_llc_id, cpu1) != BAD_APICID && 419 /* Do not match if we do not have a valid APICID for cpu: */
398 per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2)) 420 if (per_cpu(cpu_llc_id, cpu1) == BAD_APICID)
399 return topology_sane(c, o, "llc"); 421 return false;
400 422
401 return false; 423 /* Do not match if LLC id does not match: */
424 if (per_cpu(cpu_llc_id, cpu1) != per_cpu(cpu_llc_id, cpu2))
425 return false;
426
427 /*
428 * Allow the SNC topology without warning. Return of false
429 * means 'c' does not share the LLC of 'o'. This will be
430 * reflected to userspace.
431 */
432 if (!topology_same_node(c, o) && x86_match_cpu(snc_cpu))
433 return false;
434
435 return topology_sane(c, o, "llc");
402} 436}
403 437
404/* 438/*
@@ -456,7 +490,8 @@ static struct sched_domain_topology_level x86_topology[] = {
456 490
457/* 491/*
458 * Set if a package/die has multiple NUMA nodes inside. 492 * Set if a package/die has multiple NUMA nodes inside.
459 * AMD Magny-Cours and Intel Cluster-on-Die have this. 493 * AMD Magny-Cours, Intel Cluster-on-Die, and Intel
494 * Sub-NUMA Clustering have this.
460 */ 495 */
461static bool x86_has_numa_in_package; 496static bool x86_has_numa_in_package;
462 497
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index ef32297ff17e..91e6da48cbb6 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -317,7 +317,7 @@ static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2)
317 hpet2 -= hpet1; 317 hpet2 -= hpet1;
318 tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); 318 tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
319 do_div(tmp, 1000000); 319 do_div(tmp, 1000000);
320 do_div(deltatsc, tmp); 320 deltatsc = div64_u64(deltatsc, tmp);
321 321
322 return (unsigned long) deltatsc; 322 return (unsigned long) deltatsc;
323} 323}
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 62a7e9f65dec..cc7ff5957194 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -18,6 +18,7 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/seq_file.h> 20#include <linux/seq_file.h>
21#include <linux/highmem.h>
21 22
22#include <asm/pgtable.h> 23#include <asm/pgtable.h>
23 24
@@ -334,16 +335,16 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
334 pgprotval_t eff_in, unsigned long P) 335 pgprotval_t eff_in, unsigned long P)
335{ 336{
336 int i; 337 int i;
337 pte_t *start; 338 pte_t *pte;
338 pgprotval_t prot, eff; 339 pgprotval_t prot, eff;
339 340
340 start = (pte_t *)pmd_page_vaddr(addr);
341 for (i = 0; i < PTRS_PER_PTE; i++) { 341 for (i = 0; i < PTRS_PER_PTE; i++) {
342 prot = pte_flags(*start);
343 eff = effective_prot(eff_in, prot);
344 st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT); 342 st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT);
343 pte = pte_offset_map(&addr, st->current_address);
344 prot = pte_flags(*pte);
345 eff = effective_prot(eff_in, prot);
345 note_page(m, st, __pgprot(prot), eff, 5); 346 note_page(m, st, __pgprot(prot), eff, 5);
346 start++; 347 pte_unmap(pte);
347 } 348 }
348} 349}
349#ifdef CONFIG_KASAN 350#ifdef CONFIG_KASAN
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
index 48b14b534897..ccf4a49bb065 100644
--- a/arch/x86/power/hibernate_64.c
+++ b/arch/x86/power/hibernate_64.c
@@ -98,7 +98,7 @@ static int set_up_temporary_text_mapping(pgd_t *pgd)
98 set_pgd(pgd + pgd_index(restore_jump_address), new_pgd); 98 set_pgd(pgd + pgd_index(restore_jump_address), new_pgd);
99 } else { 99 } else {
100 /* No p4d for 4-level paging: point the pgd to the pud page table */ 100 /* No p4d for 4-level paging: point the pgd to the pud page table */
101 pgd_t new_pgd = __pgd(__pa(p4d) | pgprot_val(pgtable_prot)); 101 pgd_t new_pgd = __pgd(__pa(pud) | pgprot_val(pgtable_prot));
102 set_pgd(pgd + pgd_index(restore_jump_address), new_pgd); 102 set_pgd(pgd + pgd_index(restore_jump_address), new_pgd);
103 } 103 }
104 104