aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShai Fultheim <shai@scalemp.com>2012-04-16 03:39:35 -0400
committerIngo Molnar <mingo@kernel.org>2012-05-14 08:42:33 -0400
commitead91d4b8c3b1fb08a73aaa4a191230ecf717ee0 (patch)
treedb906a57cfa3824b8d3f6dcf39a10113076853e7
parentb2d0b7a061bfddd27155c7dcd53f365d9dc0c7c3 (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/Kconfig1
-rw-r--r--arch/x86/kernel/vsmp_64.c40
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
156static 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
152void __init vsmp_init(void) 190void __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}