aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-07-25 07:40:39 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-07-25 07:40:39 -0400
commitd85f4eb6993d8c743ac89e427479cbe9efc14683 (patch)
tree19721887e8b2c9823d55e0e1a5887f244b8c2634
parent523d939ef98fd712632d93a5a2b588e477a7565e (diff)
parent4bac6fa73db77d4ff49a965a7c6dc69d9e235e5f (diff)
Merge branch 'acpi-numa'
* acpi-numa: ACPI / NUMA: Enable ACPI based NUMA on ARM64 arm64, ACPI, NUMA: NUMA support based on SRAT and SLIT ACPI / processor: Add acpi_map_madt_entry() ACPI / NUMA: Improve SRAT error detection and add messages ACPI / NUMA: Move acpi_numa_memory_affinity_init() to drivers/acpi/numa.c ACPI / NUMA: remove unneeded acpi_numa=1 ACPI / NUMA: move bad_srat() and srat_disabled() to drivers/acpi/numa.c x86 / ACPI / NUMA: cleanup acpi_numa_processor_affinity_init() arm64, NUMA: Cleanup NUMA disabled messages arm64, NUMA: rework numa_add_memblk() ACPI / NUMA: move acpi_numa_slit_init() to drivers/acpi/numa.c ACPI / NUMA: Move acpi_numa_arch_fixup() to ia64 only ACPI / NUMA: remove duplicate NULL check ACPI / NUMA: Replace ACPI_DEBUG_PRINT() with pr_debug() ACPI / NUMA: Use pr_fmt() instead of printk
-rw-r--r--arch/arm64/include/asm/acpi.h8
-rw-r--r--arch/arm64/include/asm/numa.h2
-rw-r--r--arch/arm64/kernel/Makefile1
-rw-r--r--arch/arm64/kernel/acpi_numa.c112
-rw-r--r--arch/arm64/kernel/smp.c2
-rw-r--r--arch/arm64/mm/numa.c28
-rw-r--r--arch/ia64/include/asm/acpi.h3
-rw-r--r--arch/ia64/kernel/acpi.c2
-rw-r--r--arch/ia64/kernel/setup.c1
-rw-r--r--arch/x86/include/asm/acpi.h1
-rw-r--r--arch/x86/mm/numa.c2
-rw-r--r--arch/x86/mm/srat.c116
-rw-r--r--drivers/acpi/Kconfig4
-rw-r--r--drivers/acpi/numa.c226
-rw-r--r--drivers/acpi/processor_core.c26
-rw-r--r--drivers/of/of_numa.c4
-rw-r--r--include/acpi/acpi_numa.h4
-rw-r--r--include/acpi/processor.h1
-rw-r--r--include/linux/acpi.h18
19 files changed, 369 insertions, 192 deletions
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index aee323b13802..4b13ecd3977a 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -113,4 +113,12 @@ static inline const char *acpi_get_enable_method(int cpu)
113pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr); 113pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
114#endif 114#endif
115 115
116#ifdef CONFIG_ACPI_NUMA
117int arm64_acpi_numa_init(void);
118int acpi_numa_get_nid(unsigned int cpu, u64 hwid);
119#else
120static inline int arm64_acpi_numa_init(void) { return -ENOSYS; }
121static inline int acpi_numa_get_nid(unsigned int cpu, u64 hwid) { return NUMA_NO_NODE; }
122#endif /* CONFIG_ACPI_NUMA */
123
116#endif /*_ASM_ACPI_H*/ 124#endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
index e9b4f2942335..600887e491fd 100644
--- a/arch/arm64/include/asm/numa.h
+++ b/arch/arm64/include/asm/numa.h
@@ -5,6 +5,8 @@
5 5
6#ifdef CONFIG_NUMA 6#ifdef CONFIG_NUMA
7 7
8#define NR_NODE_MEMBLKS (MAX_NUMNODES * 2)
9
8/* currently, arm64 implements flat NUMA topology */ 10/* currently, arm64 implements flat NUMA topology */
9#define parent_node(node) (node) 11#define parent_node(node) (node)
10 12
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2173149d8954..a5125c6d1f87 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -42,6 +42,7 @@ arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o
42arm64-obj-$(CONFIG_PCI) += pci.o 42arm64-obj-$(CONFIG_PCI) += pci.o
43arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o 43arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
44arm64-obj-$(CONFIG_ACPI) += acpi.o 44arm64-obj-$(CONFIG_ACPI) += acpi.o
45arm64-obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o
45arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o 46arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o
46arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o 47arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o
47arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o 48arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
new file mode 100644
index 000000000000..f85149cc7c71
--- /dev/null
+++ b/arch/arm64/kernel/acpi_numa.c
@@ -0,0 +1,112 @@
1/*
2 * ACPI 5.1 based NUMA setup for ARM64
3 * Lots of code was borrowed from arch/x86/mm/srat.c
4 *
5 * Copyright 2004 Andi Kleen, SuSE Labs.
6 * Copyright (C) 2013-2016, Linaro Ltd.
7 * Author: Hanjun Guo <hanjun.guo@linaro.org>
8 *
9 * Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
10 *
11 * Called from acpi_numa_init while reading the SRAT and SLIT tables.
12 * Assumes all memory regions belonging to a single proximity domain
13 * are in one chunk. Holes between them will be included in the node.
14 */
15
16#define pr_fmt(fmt) "ACPI: NUMA: " fmt
17
18#include <linux/acpi.h>
19#include <linux/bitmap.h>
20#include <linux/bootmem.h>
21#include <linux/kernel.h>
22#include <linux/mm.h>
23#include <linux/memblock.h>
24#include <linux/mmzone.h>
25#include <linux/module.h>
26#include <linux/topology.h>
27
28#include <acpi/processor.h>
29#include <asm/numa.h>
30
31static int cpus_in_srat;
32
33struct __node_cpu_hwid {
34 u32 node_id; /* logical node containing this CPU */
35 u64 cpu_hwid; /* MPIDR for this CPU */
36};
37
38static struct __node_cpu_hwid early_node_cpu_hwid[NR_CPUS] = {
39[0 ... NR_CPUS - 1] = {NUMA_NO_NODE, PHYS_CPUID_INVALID} };
40
41int acpi_numa_get_nid(unsigned int cpu, u64 hwid)
42{
43 int i;
44
45 for (i = 0; i < cpus_in_srat; i++) {
46 if (hwid == early_node_cpu_hwid[i].cpu_hwid)
47 return early_node_cpu_hwid[i].node_id;
48 }
49
50 return NUMA_NO_NODE;
51}
52
53/* Callback for Proximity Domain -> ACPI processor UID mapping */
54void __init acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa)
55{
56 int pxm, node;
57 phys_cpuid_t mpidr;
58
59 if (srat_disabled())
60 return;
61
62 if (pa->header.length < sizeof(struct acpi_srat_gicc_affinity)) {
63 pr_err("SRAT: Invalid SRAT header length: %d\n",
64 pa->header.length);
65 bad_srat();
66 return;
67 }
68
69 if (!(pa->flags & ACPI_SRAT_GICC_ENABLED))
70 return;
71
72 if (cpus_in_srat >= NR_CPUS) {
73 pr_warn_once("SRAT: cpu_to_node_map[%d] is too small, may not be able to use all cpus\n",
74 NR_CPUS);
75 return;
76 }
77
78 pxm = pa->proximity_domain;
79 node = acpi_map_pxm_to_node(pxm);
80
81 if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
82 pr_err("SRAT: Too many proximity domains %d\n", pxm);
83 bad_srat();
84 return;
85 }
86
87 mpidr = acpi_map_madt_entry(pa->acpi_processor_uid);
88 if (mpidr == PHYS_CPUID_INVALID) {
89 pr_err("SRAT: PXM %d with ACPI ID %d has no valid MPIDR in MADT\n",
90 pxm, pa->acpi_processor_uid);
91 bad_srat();
92 return;
93 }
94
95 early_node_cpu_hwid[cpus_in_srat].node_id = node;
96 early_node_cpu_hwid[cpus_in_srat].cpu_hwid = mpidr;
97 node_set(node, numa_nodes_parsed);
98 cpus_in_srat++;
99 pr_info("SRAT: PXM %d -> MPIDR 0x%Lx -> Node %d\n",
100 pxm, mpidr, node);
101}
102
103int __init arm64_acpi_numa_init(void)
104{
105 int ret;
106
107 ret = acpi_numa_init();
108 if (ret)
109 return ret;
110
111 return srat_disabled() ? -EINVAL : 0;
112}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 62ff3c0622e2..a68e0ccd9f4b 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -560,6 +560,8 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
560 */ 560 */
561 acpi_set_mailbox_entry(cpu_count, processor); 561 acpi_set_mailbox_entry(cpu_count, processor);
562 562
563 early_map_cpu_to_node(cpu_count, acpi_numa_get_nid(cpu_count, hwid));
564
563 cpu_count++; 565 cpu_count++;
564} 566}
565 567
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
index 98dc1047f2a2..c7fe3ec70774 100644
--- a/arch/arm64/mm/numa.c
+++ b/arch/arm64/mm/numa.c
@@ -17,6 +17,7 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19 19
20#include <linux/acpi.h>
20#include <linux/bootmem.h> 21#include <linux/bootmem.h>
21#include <linux/memblock.h> 22#include <linux/memblock.h>
22#include <linux/module.h> 23#include <linux/module.h>
@@ -29,7 +30,7 @@ static int cpu_to_node_map[NR_CPUS] = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
29 30
30static int numa_distance_cnt; 31static int numa_distance_cnt;
31static u8 *numa_distance; 32static u8 *numa_distance;
32static int numa_off; 33static bool numa_off;
33 34
34static __init int numa_parse_early_param(char *opt) 35static __init int numa_parse_early_param(char *opt)
35{ 36{
@@ -37,7 +38,7 @@ static __init int numa_parse_early_param(char *opt)
37 return -EINVAL; 38 return -EINVAL;
38 if (!strncmp(opt, "off", 3)) { 39 if (!strncmp(opt, "off", 3)) {
39 pr_info("%s\n", "NUMA turned off"); 40 pr_info("%s\n", "NUMA turned off");
40 numa_off = 1; 41 numa_off = true;
41 } 42 }
42 return 0; 43 return 0;
43} 44}
@@ -131,25 +132,25 @@ void __init early_map_cpu_to_node(unsigned int cpu, int nid)
131 * numa_add_memblk - Set node id to memblk 132 * numa_add_memblk - Set node id to memblk
132 * @nid: NUMA node ID of the new memblk 133 * @nid: NUMA node ID of the new memblk
133 * @start: Start address of the new memblk 134 * @start: Start address of the new memblk
134 * @size: Size of the new memblk 135 * @end: End address of the new memblk
135 * 136 *
136 * RETURNS: 137 * RETURNS:
137 * 0 on success, -errno on failure. 138 * 0 on success, -errno on failure.
138 */ 139 */
139int __init numa_add_memblk(int nid, u64 start, u64 size) 140int __init numa_add_memblk(int nid, u64 start, u64 end)
140{ 141{
141 int ret; 142 int ret;
142 143
143 ret = memblock_set_node(start, size, &memblock.memory, nid); 144 ret = memblock_set_node(start, (end - start), &memblock.memory, nid);
144 if (ret < 0) { 145 if (ret < 0) {
145 pr_err("NUMA: memblock [0x%llx - 0x%llx] failed to add on node %d\n", 146 pr_err("NUMA: memblock [0x%llx - 0x%llx] failed to add on node %d\n",
146 start, (start + size - 1), nid); 147 start, (end - 1), nid);
147 return ret; 148 return ret;
148 } 149 }
149 150
150 node_set(nid, numa_nodes_parsed); 151 node_set(nid, numa_nodes_parsed);
151 pr_info("NUMA: Adding memblock [0x%llx - 0x%llx] on node %d\n", 152 pr_info("NUMA: Adding memblock [0x%llx - 0x%llx] on node %d\n",
152 start, (start + size - 1), nid); 153 start, (end - 1), nid);
153 return ret; 154 return ret;
154} 155}
155 156
@@ -362,12 +363,15 @@ static int __init dummy_numa_init(void)
362 int ret; 363 int ret;
363 struct memblock_region *mblk; 364 struct memblock_region *mblk;
364 365
365 pr_info("%s\n", "No NUMA configuration found"); 366 if (numa_off)
367 pr_info("NUMA disabled\n"); /* Forced off on command line. */
368 else
369 pr_info("No NUMA configuration found\n");
366 pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n", 370 pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n",
367 0LLU, PFN_PHYS(max_pfn) - 1); 371 0LLU, PFN_PHYS(max_pfn) - 1);
368 372
369 for_each_memblock(memory, mblk) { 373 for_each_memblock(memory, mblk) {
370 ret = numa_add_memblk(0, mblk->base, mblk->size); 374 ret = numa_add_memblk(0, mblk->base, mblk->base + mblk->size);
371 if (!ret) 375 if (!ret)
372 continue; 376 continue;
373 377
@@ -375,7 +379,7 @@ static int __init dummy_numa_init(void)
375 return ret; 379 return ret;
376 } 380 }
377 381
378 numa_off = 1; 382 numa_off = true;
379 return 0; 383 return 0;
380} 384}
381 385
@@ -388,7 +392,9 @@ static int __init dummy_numa_init(void)
388void __init arm64_numa_init(void) 392void __init arm64_numa_init(void)
389{ 393{
390 if (!numa_off) { 394 if (!numa_off) {
391 if (!numa_init(of_numa_init)) 395 if (!acpi_disabled && !numa_init(arm64_acpi_numa_init))
396 return;
397 if (acpi_disabled && !numa_init(of_numa_init))
392 return; 398 return;
393 } 399 }
394 400
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h
index aa0fdf125aba..a3d0211970e9 100644
--- a/arch/ia64/include/asm/acpi.h
+++ b/arch/ia64/include/asm/acpi.h
@@ -140,6 +140,9 @@ static inline void per_cpu_scan_finalize(int min_cpus, int reserve_cpus)
140 } 140 }
141 } 141 }
142} 142}
143
144extern void acpi_numa_fixup(void);
145
143#endif /* CONFIG_ACPI_NUMA */ 146#endif /* CONFIG_ACPI_NUMA */
144 147
145#endif /*__KERNEL__*/ 148#endif /*__KERNEL__*/
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index b1698bc042c8..92b7bc956795 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -524,7 +524,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
524 return 0; 524 return 0;
525} 525}
526 526
527void __init acpi_numa_arch_fixup(void) 527void __init acpi_numa_fixup(void)
528{ 528{
529 int i, j, node_from, node_to; 529 int i, j, node_from, node_to;
530 530
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 2029a38a72ae..afddb3e80a29 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -552,6 +552,7 @@ setup_arch (char **cmdline_p)
552 early_acpi_boot_init(); 552 early_acpi_boot_init();
553# ifdef CONFIG_ACPI_NUMA 553# ifdef CONFIG_ACPI_NUMA
554 acpi_numa_init(); 554 acpi_numa_init();
555 acpi_numa_fixup();
555# ifdef CONFIG_ACPI_HOTPLUG_CPU 556# ifdef CONFIG_ACPI_HOTPLUG_CPU
556 prefill_possible_map(); 557 prefill_possible_map();
557# endif 558# endif
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 94c18ebfd68c..65f1e95cade9 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -145,7 +145,6 @@ static inline void disable_acpi(void) { }
145#define ARCH_HAS_POWER_INIT 1 145#define ARCH_HAS_POWER_INIT 1
146 146
147#ifdef CONFIG_ACPI_NUMA 147#ifdef CONFIG_ACPI_NUMA
148extern int acpi_numa;
149extern int x86_acpi_numa_init(void); 148extern int x86_acpi_numa_init(void);
150#endif /* CONFIG_ACPI_NUMA */ 149#endif /* CONFIG_ACPI_NUMA */
151 150
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 9c086c57105c..968ac028c34e 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -1,4 +1,5 @@
1/* Common code for 32 and 64-bit NUMA */ 1/* Common code for 32 and 64-bit NUMA */
2#include <linux/acpi.h>
2#include <linux/kernel.h> 3#include <linux/kernel.h>
3#include <linux/mm.h> 4#include <linux/mm.h>
4#include <linux/string.h> 5#include <linux/string.h>
@@ -15,7 +16,6 @@
15#include <asm/e820.h> 16#include <asm/e820.h>
16#include <asm/proto.h> 17#include <asm/proto.h>
17#include <asm/dma.h> 18#include <asm/dma.h>
18#include <asm/acpi.h>
19#include <asm/amd_nb.h> 19#include <asm/amd_nb.h>
20 20
21#include "numa_internal.h" 21#include "numa_internal.h"
diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c
index b5f821881465..b1ecff460a46 100644
--- a/arch/x86/mm/srat.c
+++ b/arch/x86/mm/srat.c
@@ -15,8 +15,6 @@
15#include <linux/bitmap.h> 15#include <linux/bitmap.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/topology.h> 17#include <linux/topology.h>
18#include <linux/bootmem.h>
19#include <linux/memblock.h>
20#include <linux/mm.h> 18#include <linux/mm.h>
21#include <asm/proto.h> 19#include <asm/proto.h>
22#include <asm/numa.h> 20#include <asm/numa.h>
@@ -24,51 +22,6 @@
24#include <asm/apic.h> 22#include <asm/apic.h>
25#include <asm/uv/uv.h> 23#include <asm/uv/uv.h>
26 24
27int acpi_numa __initdata;
28
29static __init int setup_node(int pxm)
30{
31 return acpi_map_pxm_to_node(pxm);
32}
33
34static __init void bad_srat(void)
35{
36 printk(KERN_ERR "SRAT: SRAT not used.\n");
37 acpi_numa = -1;
38}
39
40static __init inline int srat_disabled(void)
41{
42 return acpi_numa < 0;
43}
44
45/*
46 * Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
47 * I/O localities since SRAT does not list them. I/O localities are
48 * not supported at this point.
49 */
50void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
51{
52 int i, j;
53
54 for (i = 0; i < slit->locality_count; i++) {
55 const int from_node = pxm_to_node(i);
56
57 if (from_node == NUMA_NO_NODE)
58 continue;
59
60 for (j = 0; j < slit->locality_count; j++) {
61 const int to_node = pxm_to_node(j);
62
63 if (to_node == NUMA_NO_NODE)
64 continue;
65
66 numa_set_distance(from_node, to_node,
67 slit->entry[slit->locality_count * i + j]);
68 }
69 }
70}
71
72/* Callback for Proximity Domain -> x2APIC mapping */ 25/* Callback for Proximity Domain -> x2APIC mapping */
73void __init 26void __init
74acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) 27acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
@@ -91,7 +44,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
91 pxm, apic_id); 44 pxm, apic_id);
92 return; 45 return;
93 } 46 }
94 node = setup_node(pxm); 47 node = acpi_map_pxm_to_node(pxm);
95 if (node < 0) { 48 if (node < 0) {
96 printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm); 49 printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
97 bad_srat(); 50 bad_srat();
@@ -104,7 +57,6 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
104 } 57 }
105 set_apicid_to_node(apic_id, node); 58 set_apicid_to_node(apic_id, node);
106 node_set(node, numa_nodes_parsed); 59 node_set(node, numa_nodes_parsed);
107 acpi_numa = 1;
108 printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n", 60 printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
109 pxm, apic_id, node); 61 pxm, apic_id, node);
110} 62}
@@ -127,7 +79,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
127 pxm = pa->proximity_domain_lo; 79 pxm = pa->proximity_domain_lo;
128 if (acpi_srat_revision >= 2) 80 if (acpi_srat_revision >= 2)
129 pxm |= *((unsigned int*)pa->proximity_domain_hi) << 8; 81 pxm |= *((unsigned int*)pa->proximity_domain_hi) << 8;
130 node = setup_node(pxm); 82 node = acpi_map_pxm_to_node(pxm);
131 if (node < 0) { 83 if (node < 0) {
132 printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm); 84 printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
133 bad_srat(); 85 bad_srat();
@@ -146,74 +98,10 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
146 98
147 set_apicid_to_node(apic_id, node); 99 set_apicid_to_node(apic_id, node);
148 node_set(node, numa_nodes_parsed); 100 node_set(node, numa_nodes_parsed);
149 acpi_numa = 1;
150 printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n", 101 printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
151 pxm, apic_id, node); 102 pxm, apic_id, node);
152} 103}
153 104
154#ifdef CONFIG_MEMORY_HOTPLUG
155static inline int save_add_info(void) {return 1;}
156#else
157static inline int save_add_info(void) {return 0;}
158#endif
159
160/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
161int __init
162acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
163{
164 u64 start, end;
165 u32 hotpluggable;
166 int node, pxm;
167
168 if (srat_disabled())
169 goto out_err;
170 if (ma->header.length != sizeof(struct acpi_srat_mem_affinity))
171 goto out_err_bad_srat;
172 if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
173 goto out_err;
174 hotpluggable = ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE;
175 if (hotpluggable && !save_add_info())
176 goto out_err;
177
178 start = ma->base_address;
179 end = start + ma->length;
180 pxm = ma->proximity_domain;
181 if (acpi_srat_revision <= 1)
182 pxm &= 0xff;
183
184 node = setup_node(pxm);
185 if (node < 0) {
186 printk(KERN_ERR "SRAT: Too many proximity domains.\n");
187 goto out_err_bad_srat;
188 }
189
190 if (numa_add_memblk(node, start, end) < 0)
191 goto out_err_bad_srat;
192
193 node_set(node, numa_nodes_parsed);
194
195 pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]%s%s\n",
196 node, pxm,
197 (unsigned long long) start, (unsigned long long) end - 1,
198 hotpluggable ? " hotplug" : "",
199 ma->flags & ACPI_SRAT_MEM_NON_VOLATILE ? " non-volatile" : "");
200
201 /* Mark hotplug range in memblock. */
202 if (hotpluggable && memblock_mark_hotplug(start, ma->length))
203 pr_warn("SRAT: Failed to mark hotplug range [mem %#010Lx-%#010Lx] in memblock\n",
204 (unsigned long long)start, (unsigned long long)end - 1);
205
206 max_possible_pfn = max(max_possible_pfn, PFN_UP(end - 1));
207
208 return 0;
209out_err_bad_srat:
210 bad_srat();
211out_err:
212 return -1;
213}
214
215void __init acpi_numa_arch_fixup(void) {}
216
217int __init x86_acpi_numa_init(void) 105int __init x86_acpi_numa_init(void)
218{ 106{
219 int ret; 107 int ret;
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index b7e2e776397d..dd76b36c431f 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -291,8 +291,8 @@ config ACPI_THERMAL
291config ACPI_NUMA 291config ACPI_NUMA
292 bool "NUMA support" 292 bool "NUMA support"
293 depends on NUMA 293 depends on NUMA
294 depends on (X86 || IA64) 294 depends on (X86 || IA64 || ARM64)
295 default y if IA64_GENERIC || IA64_SGI_SN2 295 default y if IA64_GENERIC || IA64_SGI_SN2 || ARM64
296 296
297config ACPI_CUSTOM_DSDT_FILE 297config ACPI_CUSTOM_DSDT_FILE
298 string "Custom DSDT Table file to include" 298 string "Custom DSDT Table file to include"
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index d176e0ece470..ce3a7a16f03f 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -18,22 +18,21 @@
18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19 * 19 *
20 */ 20 */
21
22#define pr_fmt(fmt) "ACPI: " fmt
23
21#include <linux/module.h> 24#include <linux/module.h>
22#include <linux/init.h> 25#include <linux/init.h>
23#include <linux/kernel.h> 26#include <linux/kernel.h>
24#include <linux/types.h> 27#include <linux/types.h>
25#include <linux/errno.h> 28#include <linux/errno.h>
26#include <linux/acpi.h> 29#include <linux/acpi.h>
30#include <linux/bootmem.h>
31#include <linux/memblock.h>
27#include <linux/numa.h> 32#include <linux/numa.h>
28#include <linux/nodemask.h> 33#include <linux/nodemask.h>
29#include <linux/topology.h> 34#include <linux/topology.h>
30 35
31#define PREFIX "ACPI: "
32
33#define ACPI_NUMA 0x80000000
34#define _COMPONENT ACPI_NUMA
35ACPI_MODULE_NAME("numa");
36
37static nodemask_t nodes_found_map = NODE_MASK_NONE; 36static nodemask_t nodes_found_map = NODE_MASK_NONE;
38 37
39/* maps to convert between proximity domain and logical node ID */ 38/* maps to convert between proximity domain and logical node ID */
@@ -43,6 +42,7 @@ static int node_to_pxm_map[MAX_NUMNODES]
43 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; 42 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
44 43
45unsigned char acpi_srat_revision __initdata; 44unsigned char acpi_srat_revision __initdata;
45int acpi_numa __initdata;
46 46
47int pxm_to_node(int pxm) 47int pxm_to_node(int pxm)
48{ 48{
@@ -128,68 +128,63 @@ EXPORT_SYMBOL(acpi_map_pxm_to_online_node);
128static void __init 128static void __init
129acpi_table_print_srat_entry(struct acpi_subtable_header *header) 129acpi_table_print_srat_entry(struct acpi_subtable_header *header)
130{ 130{
131
132 ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
133
134 if (!header)
135 return;
136
137 switch (header->type) { 131 switch (header->type) {
138
139 case ACPI_SRAT_TYPE_CPU_AFFINITY: 132 case ACPI_SRAT_TYPE_CPU_AFFINITY:
140#ifdef ACPI_DEBUG_OUTPUT
141 { 133 {
142 struct acpi_srat_cpu_affinity *p = 134 struct acpi_srat_cpu_affinity *p =
143 (struct acpi_srat_cpu_affinity *)header; 135 (struct acpi_srat_cpu_affinity *)header;
144 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 136 pr_debug("SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
145 "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n", 137 p->apic_id, p->local_sapic_eid,
146 p->apic_id, p->local_sapic_eid, 138 p->proximity_domain_lo,
147 p->proximity_domain_lo, 139 (p->flags & ACPI_SRAT_CPU_ENABLED) ?
148 (p->flags & ACPI_SRAT_CPU_ENABLED)? 140 "enabled" : "disabled");
149 "enabled" : "disabled"));
150 } 141 }
151#endif /* ACPI_DEBUG_OUTPUT */
152 break; 142 break;
153 143
154 case ACPI_SRAT_TYPE_MEMORY_AFFINITY: 144 case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
155#ifdef ACPI_DEBUG_OUTPUT
156 { 145 {
157 struct acpi_srat_mem_affinity *p = 146 struct acpi_srat_mem_affinity *p =
158 (struct acpi_srat_mem_affinity *)header; 147 (struct acpi_srat_mem_affinity *)header;
159 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 148 pr_debug("SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s%s\n",
160 "SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s%s\n", 149 (unsigned long)p->base_address,
161 (unsigned long)p->base_address, 150 (unsigned long)p->length,
162 (unsigned long)p->length, 151 p->proximity_domain,
163 p->proximity_domain, 152 (p->flags & ACPI_SRAT_MEM_ENABLED) ?
164 (p->flags & ACPI_SRAT_MEM_ENABLED)? 153 "enabled" : "disabled",
165 "enabled" : "disabled", 154 (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
166 (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)? 155 " hot-pluggable" : "",
167 " hot-pluggable" : "", 156 (p->flags & ACPI_SRAT_MEM_NON_VOLATILE) ?
168 (p->flags & ACPI_SRAT_MEM_NON_VOLATILE)? 157 " non-volatile" : "");
169 " non-volatile" : ""));
170 } 158 }
171#endif /* ACPI_DEBUG_OUTPUT */
172 break; 159 break;
173 160
174 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: 161 case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
175#ifdef ACPI_DEBUG_OUTPUT
176 { 162 {
177 struct acpi_srat_x2apic_cpu_affinity *p = 163 struct acpi_srat_x2apic_cpu_affinity *p =
178 (struct acpi_srat_x2apic_cpu_affinity *)header; 164 (struct acpi_srat_x2apic_cpu_affinity *)header;
179 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 165 pr_debug("SRAT Processor (x2apicid[0x%08x]) in proximity domain %d %s\n",
180 "SRAT Processor (x2apicid[0x%08x]) in" 166 p->apic_id,
181 " proximity domain %d %s\n", 167 p->proximity_domain,
182 p->apic_id, 168 (p->flags & ACPI_SRAT_CPU_ENABLED) ?
183 p->proximity_domain, 169 "enabled" : "disabled");
184 (p->flags & ACPI_SRAT_CPU_ENABLED) ?
185 "enabled" : "disabled"));
186 } 170 }
187#endif /* ACPI_DEBUG_OUTPUT */
188 break; 171 break;
172
173 case ACPI_SRAT_TYPE_GICC_AFFINITY:
174 {
175 struct acpi_srat_gicc_affinity *p =
176 (struct acpi_srat_gicc_affinity *)header;
177 pr_debug("SRAT Processor (acpi id[0x%04x]) in proximity domain %d %s\n",
178 p->acpi_processor_uid,
179 p->proximity_domain,
180 (p->flags & ACPI_SRAT_GICC_ENABLED) ?
181 "enabled" : "disabled");
182 }
183 break;
184
189 default: 185 default:
190 printk(KERN_WARNING PREFIX 186 pr_warn("Found unsupported SRAT entry (type = 0x%x)\n",
191 "Found unsupported SRAT entry (type = 0x%x)\n", 187 header->type);
192 header->type);
193 break; 188 break;
194 } 189 }
195} 190}
@@ -217,12 +212,117 @@ static int __init slit_valid(struct acpi_table_slit *slit)
217 return 1; 212 return 1;
218} 213}
219 214
215void __init bad_srat(void)
216{
217 pr_err("SRAT: SRAT not used.\n");
218 acpi_numa = -1;
219}
220
221int __init srat_disabled(void)
222{
223 return acpi_numa < 0;
224}
225
226#if defined(CONFIG_X86) || defined(CONFIG_ARM64)
227/*
228 * Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
229 * I/O localities since SRAT does not list them. I/O localities are
230 * not supported at this point.
231 */
232void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
233{
234 int i, j;
235
236 for (i = 0; i < slit->locality_count; i++) {
237 const int from_node = pxm_to_node(i);
238
239 if (from_node == NUMA_NO_NODE)
240 continue;
241
242 for (j = 0; j < slit->locality_count; j++) {
243 const int to_node = pxm_to_node(j);
244
245 if (to_node == NUMA_NO_NODE)
246 continue;
247
248 numa_set_distance(from_node, to_node,
249 slit->entry[slit->locality_count * i + j]);
250 }
251 }
252}
253
254/*
255 * Default callback for parsing of the Proximity Domain <-> Memory
256 * Area mappings
257 */
258int __init
259acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
260{
261 u64 start, end;
262 u32 hotpluggable;
263 int node, pxm;
264
265 if (srat_disabled())
266 goto out_err;
267 if (ma->header.length < sizeof(struct acpi_srat_mem_affinity)) {
268 pr_err("SRAT: Unexpected header length: %d\n",
269 ma->header.length);
270 goto out_err_bad_srat;
271 }
272 if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
273 goto out_err;
274 hotpluggable = ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE;
275 if (hotpluggable && !IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
276 goto out_err;
277
278 start = ma->base_address;
279 end = start + ma->length;
280 pxm = ma->proximity_domain;
281 if (acpi_srat_revision <= 1)
282 pxm &= 0xff;
283
284 node = acpi_map_pxm_to_node(pxm);
285 if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
286 pr_err("SRAT: Too many proximity domains.\n");
287 goto out_err_bad_srat;
288 }
289
290 if (numa_add_memblk(node, start, end) < 0) {
291 pr_err("SRAT: Failed to add memblk to node %u [mem %#010Lx-%#010Lx]\n",
292 node, (unsigned long long) start,
293 (unsigned long long) end - 1);
294 goto out_err_bad_srat;
295 }
296
297 node_set(node, numa_nodes_parsed);
298
299 pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]%s%s\n",
300 node, pxm,
301 (unsigned long long) start, (unsigned long long) end - 1,
302 hotpluggable ? " hotplug" : "",
303 ma->flags & ACPI_SRAT_MEM_NON_VOLATILE ? " non-volatile" : "");
304
305 /* Mark hotplug range in memblock. */
306 if (hotpluggable && memblock_mark_hotplug(start, ma->length))
307 pr_warn("SRAT: Failed to mark hotplug range [mem %#010Lx-%#010Lx] in memblock\n",
308 (unsigned long long)start, (unsigned long long)end - 1);
309
310 max_possible_pfn = max(max_possible_pfn, PFN_UP(end - 1));
311
312 return 0;
313out_err_bad_srat:
314 bad_srat();
315out_err:
316 return -EINVAL;
317}
318#endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
319
220static int __init acpi_parse_slit(struct acpi_table_header *table) 320static int __init acpi_parse_slit(struct acpi_table_header *table)
221{ 321{
222 struct acpi_table_slit *slit = (struct acpi_table_slit *)table; 322 struct acpi_table_slit *slit = (struct acpi_table_slit *)table;
223 323
224 if (!slit_valid(slit)) { 324 if (!slit_valid(slit)) {
225 printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); 325 pr_info("SLIT table looks invalid. Not used.\n");
226 return -EINVAL; 326 return -EINVAL;
227 } 327 }
228 acpi_numa_slit_init(slit); 328 acpi_numa_slit_init(slit);
@@ -233,12 +333,9 @@ static int __init acpi_parse_slit(struct acpi_table_header *table)
233void __init __weak 333void __init __weak
234acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) 334acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
235{ 335{
236 printk(KERN_WARNING PREFIX 336 pr_warn("Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
237 "Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
238 return;
239} 337}
240 338
241
242static int __init 339static int __init
243acpi_parse_x2apic_affinity(struct acpi_subtable_header *header, 340acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
244 const unsigned long end) 341 const unsigned long end)
@@ -275,6 +372,24 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header,
275 return 0; 372 return 0;
276} 373}
277 374
375static int __init
376acpi_parse_gicc_affinity(struct acpi_subtable_header *header,
377 const unsigned long end)
378{
379 struct acpi_srat_gicc_affinity *processor_affinity;
380
381 processor_affinity = (struct acpi_srat_gicc_affinity *)header;
382 if (!processor_affinity)
383 return -EINVAL;
384
385 acpi_table_print_srat_entry(header);
386
387 /* let architecture-dependent part to do it */
388 acpi_numa_gicc_affinity_init(processor_affinity);
389
390 return 0;
391}
392
278static int __initdata parsed_numa_memblks; 393static int __initdata parsed_numa_memblks;
279 394
280static int __init 395static int __init
@@ -319,6 +434,9 @@ int __init acpi_numa_init(void)
319{ 434{
320 int cnt = 0; 435 int cnt = 0;
321 436
437 if (acpi_disabled)
438 return -EINVAL;
439
322 /* 440 /*
323 * Should not limit number with cpu num that is from NR_CPUS or nr_cpus= 441 * Should not limit number with cpu num that is from NR_CPUS or nr_cpus=
324 * SRAT cpu entries could have different order with that in MADT. 442 * SRAT cpu entries could have different order with that in MADT.
@@ -327,13 +445,15 @@ int __init acpi_numa_init(void)
327 445
328 /* SRAT: Static Resource Affinity Table */ 446 /* SRAT: Static Resource Affinity Table */
329 if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { 447 if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
330 struct acpi_subtable_proc srat_proc[2]; 448 struct acpi_subtable_proc srat_proc[3];
331 449
332 memset(srat_proc, 0, sizeof(srat_proc)); 450 memset(srat_proc, 0, sizeof(srat_proc));
333 srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY; 451 srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY;
334 srat_proc[0].handler = acpi_parse_processor_affinity; 452 srat_proc[0].handler = acpi_parse_processor_affinity;
335 srat_proc[1].id = ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY; 453 srat_proc[1].id = ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY;
336 srat_proc[1].handler = acpi_parse_x2apic_affinity; 454 srat_proc[1].handler = acpi_parse_x2apic_affinity;
455 srat_proc[2].id = ACPI_SRAT_TYPE_GICC_AFFINITY;
456 srat_proc[2].handler = acpi_parse_gicc_affinity;
337 457
338 acpi_table_parse_entries_array(ACPI_SIG_SRAT, 458 acpi_table_parse_entries_array(ACPI_SIG_SRAT,
339 sizeof(struct acpi_table_srat), 459 sizeof(struct acpi_table_srat),
@@ -347,8 +467,6 @@ int __init acpi_numa_init(void)
347 /* SLIT: System Locality Information Table */ 467 /* SLIT: System Locality Information Table */
348 acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); 468 acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
349 469
350 acpi_numa_arch_fixup();
351
352 if (cnt < 0) 470 if (cnt < 0)
353 return cnt; 471 return cnt;
354 else if (!parsed_numa_memblks) 472 else if (!parsed_numa_memblks)
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 33a38d604630..9125d7d96372 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -108,13 +108,12 @@ static int map_gicc_mpidr(struct acpi_subtable_header *entry,
108 return -EINVAL; 108 return -EINVAL;
109} 109}
110 110
111static phys_cpuid_t map_madt_entry(int type, u32 acpi_id) 111static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
112 int type, u32 acpi_id)
112{ 113{
113 unsigned long madt_end, entry; 114 unsigned long madt_end, entry;
114 phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */ 115 phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */
115 struct acpi_table_madt *madt;
116 116
117 madt = get_madt_table();
118 if (!madt) 117 if (!madt)
119 return phys_id; 118 return phys_id;
120 119
@@ -145,6 +144,25 @@ static phys_cpuid_t map_madt_entry(int type, u32 acpi_id)
145 return phys_id; 144 return phys_id;
146} 145}
147 146
147phys_cpuid_t __init acpi_map_madt_entry(u32 acpi_id)
148{
149 struct acpi_table_madt *madt = NULL;
150 acpi_size tbl_size;
151 phys_cpuid_t rv;
152
153 acpi_get_table_with_size(ACPI_SIG_MADT, 0,
154 (struct acpi_table_header **)&madt,
155 &tbl_size);
156 if (!madt)
157 return PHYS_CPUID_INVALID;
158
159 rv = map_madt_entry(madt, 1, acpi_id);
160
161 early_acpi_os_unmap_memory(madt, tbl_size);
162
163 return rv;
164}
165
148static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id) 166static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
149{ 167{
150 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 168 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -185,7 +203,7 @@ phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)
185 203
186 phys_id = map_mat_entry(handle, type, acpi_id); 204 phys_id = map_mat_entry(handle, type, acpi_id);
187 if (invalid_phys_cpuid(phys_id)) 205 if (invalid_phys_cpuid(phys_id))
188 phys_id = map_madt_entry(type, acpi_id); 206 phys_id = map_madt_entry(get_madt_table(), type, acpi_id);
189 207
190 return phys_id; 208 return phys_id;
191} 209}
diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c
index 0f2784bc1874..ed5a097f0801 100644
--- a/drivers/of/of_numa.c
+++ b/drivers/of/of_numa.c
@@ -91,8 +91,8 @@ static int __init of_numa_parse_memory_nodes(void)
91 pr_debug("NUMA: base = %llx len = %llx, node = %u\n", 91 pr_debug("NUMA: base = %llx len = %llx, node = %u\n",
92 rsrc.start, rsrc.end - rsrc.start + 1, nid); 92 rsrc.start, rsrc.end - rsrc.start + 1, nid);
93 93
94 r = numa_add_memblk(nid, rsrc.start, 94
95 rsrc.end - rsrc.start + 1); 95 r = numa_add_memblk(nid, rsrc.start, rsrc.end + 1);
96 if (r) 96 if (r)
97 break; 97 break;
98 } 98 }
diff --git a/include/acpi/acpi_numa.h b/include/acpi/acpi_numa.h
index 94a37cd7fbda..d4b72944ccda 100644
--- a/include/acpi/acpi_numa.h
+++ b/include/acpi/acpi_numa.h
@@ -15,6 +15,10 @@ extern int pxm_to_node(int);
15extern int node_to_pxm(int); 15extern int node_to_pxm(int);
16extern int acpi_map_pxm_to_node(int); 16extern int acpi_map_pxm_to_node(int);
17extern unsigned char acpi_srat_revision; 17extern unsigned char acpi_srat_revision;
18extern int acpi_numa __initdata;
19
20extern void bad_srat(void);
21extern int srat_disabled(void);
18 22
19#endif /* CONFIG_ACPI_NUMA */ 23#endif /* CONFIG_ACPI_NUMA */
20#endif /* __ACP_NUMA_H */ 24#endif /* __ACP_NUMA_H */
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 6f1805dd5d3c..f473e6618339 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -309,6 +309,7 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
309 309
310/* in processor_core.c */ 310/* in processor_core.c */
311phys_cpuid_t acpi_get_phys_id(acpi_handle, int type, u32 acpi_id); 311phys_cpuid_t acpi_get_phys_id(acpi_handle, int type, u32 acpi_id);
312phys_cpuid_t acpi_map_madt_entry(u32 acpi_id);
312int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id); 313int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id);
313int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id); 314int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id);
314 315
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5294f5..9515db6f03f0 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -232,12 +232,26 @@ int acpi_table_parse_madt(enum acpi_madt_type id,
232int acpi_parse_mcfg (struct acpi_table_header *header); 232int acpi_parse_mcfg (struct acpi_table_header *header);
233void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); 233void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
234 234
235/* the following four functions are architecture-dependent */ 235/* the following numa functions are architecture-dependent */
236void acpi_numa_slit_init (struct acpi_table_slit *slit); 236void acpi_numa_slit_init (struct acpi_table_slit *slit);
237
238#if defined(CONFIG_X86) || defined(CONFIG_IA64)
237void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); 239void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
240#else
241static inline void
242acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) { }
243#endif
244
238void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa); 245void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
246
247#ifdef CONFIG_ARM64
248void acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa);
249#else
250static inline void
251acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa) { }
252#endif
253
239int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); 254int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
240void acpi_numa_arch_fixup(void);
241 255
242#ifndef PHYS_CPUID_INVALID 256#ifndef PHYS_CPUID_INVALID
243typedef u32 phys_cpuid_t; 257typedef u32 phys_cpuid_t;