diff options
author | Shai Fultheim <shai@scalemp.com> | 2012-04-16 03:39:35 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-05-14 08:42:33 -0400 |
commit | ead91d4b8c3b1fb08a73aaa4a191230ecf717ee0 (patch) | |
tree | db906a57cfa3824b8d3f6dcf39a10113076853e7 | |
parent | b2d0b7a061bfddd27155c7dcd53f365d9dc0c7c3 (diff) |
x86/vsmp: Fix number of CPUs when vsmp is disabled
In case CONFIG_X86_VSMP is not set, limit the number of CPUs to
the number of CPUs of the first board.
Also make CONFIG_X86_VSMP depend on CONFIG_SMP, as there's
little point in having a vsmp machine with a single CPU.
Signed-off-by: Shai Fultheim <shai@scalemp.com>
[ido@wizery.com: rebased, fixed minor coding-style issues]
Signed-off-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/kernel/vsmp_64.c | 40 |
2 files changed, 41 insertions, 0 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f9ed801abaf9..d2599a0ea208 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -376,6 +376,7 @@ config X86_VSMP | |||
376 | select PARAVIRT | 376 | select PARAVIRT |
377 | depends on X86_64 && PCI | 377 | depends on X86_64 && PCI |
378 | depends on X86_EXTENDED_PLATFORM | 378 | depends on X86_EXTENDED_PLATFORM |
379 | depends on SMP | ||
379 | ---help--- | 380 | ---help--- |
380 | Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is | 381 | Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is |
381 | supposed to run on these EM64T-based machines. Only choose this option | 382 | supposed to run on these EM64T-based machines. Only choose this option |
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index a1d804bcd483..8eeb55a551b4 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/pci_ids.h> | 16 | #include <linux/pci_ids.h> |
17 | #include <linux/pci_regs.h> | 17 | #include <linux/pci_regs.h> |
18 | #include <linux/smp.h> | ||
18 | 19 | ||
19 | #include <asm/apic.h> | 20 | #include <asm/apic.h> |
20 | #include <asm/pci-direct.h> | 21 | #include <asm/pci-direct.h> |
@@ -22,6 +23,8 @@ | |||
22 | #include <asm/paravirt.h> | 23 | #include <asm/paravirt.h> |
23 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
24 | 25 | ||
26 | #define TOPOLOGY_REGISTER_OFFSET 0x10 | ||
27 | |||
25 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT | 28 | #if defined CONFIG_PCI && defined CONFIG_PARAVIRT |
26 | /* | 29 | /* |
27 | * Interrupt control on vSMPowered systems: | 30 | * Interrupt control on vSMPowered systems: |
@@ -149,12 +152,49 @@ int is_vsmp_box(void) | |||
149 | return 0; | 152 | return 0; |
150 | } | 153 | } |
151 | #endif | 154 | #endif |
155 | |||
156 | static void __init vsmp_cap_cpus(void) | ||
157 | { | ||
158 | #if !defined(CONFIG_X86_VSMP) && defined(CONFIG_SMP) | ||
159 | void __iomem *address; | ||
160 | unsigned int cfg, topology, node_shift, maxcpus; | ||
161 | |||
162 | /* | ||
163 | * CONFIG_X86_VSMP is not configured, so limit the number CPUs to the | ||
164 | * ones present in the first board, unless explicitly overridden by | ||
165 | * setup_max_cpus | ||
166 | */ | ||
167 | if (setup_max_cpus != NR_CPUS) | ||
168 | return; | ||
169 | |||
170 | /* Read the vSMP Foundation topology register */ | ||
171 | cfg = read_pci_config(0, 0x1f, 0, PCI_BASE_ADDRESS_0); | ||
172 | address = early_ioremap(cfg + TOPOLOGY_REGISTER_OFFSET, 4); | ||
173 | if (WARN_ON(!address)) | ||
174 | return; | ||
175 | |||
176 | topology = readl(address); | ||
177 | node_shift = (topology >> 16) & 0x7; | ||
178 | if (!node_shift) | ||
179 | /* The value 0 should be decoded as 8 */ | ||
180 | node_shift = 8; | ||
181 | maxcpus = (topology & ((1 << node_shift) - 1)) + 1; | ||
182 | |||
183 | pr_info("vSMP CTL: Capping CPUs to %d (CONFIG_X86_VSMP is unset)\n", | ||
184 | maxcpus); | ||
185 | setup_max_cpus = maxcpus; | ||
186 | early_iounmap(address, 4); | ||
187 | #endif | ||
188 | } | ||
189 | |||
152 | void __init vsmp_init(void) | 190 | void __init vsmp_init(void) |
153 | { | 191 | { |
154 | detect_vsmp_box(); | 192 | detect_vsmp_box(); |
155 | if (!is_vsmp_box()) | 193 | if (!is_vsmp_box()) |
156 | return; | 194 | return; |
157 | 195 | ||
196 | vsmp_cap_cpus(); | ||
197 | |||
158 | set_vsmp_pv_ops(); | 198 | set_vsmp_pv_ops(); |
159 | return; | 199 | return; |
160 | } | 200 | } |