ia64/xen-unstable

changeset 8865:b32cad914390

Upgrade smpboot.c to linux-2.6.16-rc2 codebase.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Feb 16 16:31:22 2006 +0100 (2006-02-16)
parents c6c739bf254d
children c53a9a3be3f7
files xen/arch/x86/setup.c xen/arch/x86/smpboot.c xen/include/asm-ia64/config.h xen/include/asm-x86/mach-default/smpboot_hooks.h xen/include/asm-x86/smp.h xen/include/xen/smp.h
line diff
     1.1 --- a/xen/arch/x86/setup.c	Thu Feb 16 14:26:02 2006 +0000
     1.2 +++ b/xen/arch/x86/setup.c	Thu Feb 16 16:31:22 2006 +0100
     1.3 @@ -445,11 +445,6 @@ void __init __start_xen(multiboot_info_t
     1.4  
     1.5      smp_prepare_cpus(max_cpus);
     1.6  
     1.7 -    /* We aren't hotplug-capable yet. */
     1.8 -    BUG_ON(!cpus_empty(cpu_present_map));
     1.9 -    for_each_cpu ( i )
    1.10 -        cpu_set(i, cpu_present_map);
    1.11 -
    1.12      /*
    1.13       * Initialise higher-level timer functions. We do this fairly late
    1.14       * (post-SMP) because the time bases and scale factors need to be updated 
     2.1 --- a/xen/arch/x86/smpboot.c	Thu Feb 16 14:26:02 2006 +0000
     2.2 +++ b/xen/arch/x86/smpboot.c	Thu Feb 16 16:31:22 2006 +0100
     2.3 @@ -49,32 +49,60 @@
     2.4  #include <asm/msr.h>
     2.5  #include <mach_apic.h>
     2.6  #include <mach_wakecpu.h>
     2.7 +#include <smpboot_hooks.h>
     2.8  
     2.9 -static int _foo;
    2.10 -#define set_kernel_exec(x,y) (_foo=0)
    2.11 +static inline int set_kernel_exec(unsigned long x, int y) { return 0; }
    2.12  #define alloc_bootmem_low_pages(x) __va(0x90000) /* trampoline address */
    2.13  
    2.14  /* Set if we find a B stepping CPU */
    2.15 -static int __initdata smp_b_stepping;
    2.16 +static int __devinitdata smp_b_stepping;
    2.17  
    2.18  /* Number of siblings per CPU package */
    2.19  int smp_num_siblings = 1;
    2.20 -int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
    2.21 -EXPORT_SYMBOL(phys_proc_id);
    2.22 -int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
    2.23 -EXPORT_SYMBOL(cpu_core_id);
    2.24 +#ifdef CONFIG_X86_HT
    2.25 +EXPORT_SYMBOL(smp_num_siblings);
    2.26 +#endif
    2.27 +
    2.28 +/* Package ID of each logical CPU */
    2.29 +int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
    2.30 +
    2.31 +/* Core ID of each logical CPU */
    2.32 +int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
    2.33 +
    2.34 +/* representing HT siblings of each logical CPU */
    2.35 +cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
    2.36 +EXPORT_SYMBOL(cpu_sibling_map);
    2.37 +
    2.38 +/* representing HT and core siblings of each logical CPU */
    2.39 +cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
    2.40 +EXPORT_SYMBOL(cpu_core_map);
    2.41  
    2.42  /* bitmap of online cpus */
    2.43 -cpumask_t cpu_online_map;
    2.44 +cpumask_t cpu_online_map __read_mostly;
    2.45 +EXPORT_SYMBOL(cpu_online_map);
    2.46  
    2.47  cpumask_t cpu_callin_map;
    2.48  cpumask_t cpu_callout_map;
    2.49 +EXPORT_SYMBOL(cpu_callout_map);
    2.50 +#ifdef CONFIG_HOTPLUG_CPU
    2.51 +cpumask_t cpu_possible_map = CPU_MASK_ALL;
    2.52 +#else
    2.53 +cpumask_t cpu_possible_map;
    2.54 +#endif
    2.55 +EXPORT_SYMBOL(cpu_possible_map);
    2.56  static cpumask_t smp_commenced_mask;
    2.57  
    2.58 +/* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there
    2.59 + * is no way to resync one AP against BP. TBD: for prescott and above, we
    2.60 + * should use IA64's algorithm
    2.61 + */
    2.62 +static int __devinitdata tsc_sync_disabled;
    2.63 +
    2.64  /* Per CPU bogomips and other parameters */
    2.65  struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
    2.66 +EXPORT_SYMBOL(cpu_data);
    2.67  
    2.68 -u8 x86_cpu_to_apicid[NR_CPUS] =
    2.69 +u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
    2.70  			{ [0 ... NR_CPUS-1] = 0xff };
    2.71  EXPORT_SYMBOL(x86_cpu_to_apicid);
    2.72  
    2.73 @@ -87,13 +115,18 @@ extern unsigned char trampoline_end  [];
    2.74  static unsigned char *trampoline_base;
    2.75  static int trampoline_exec;
    2.76  
    2.77 +static void map_cpu_to_logical_apicid(void);
    2.78 +
    2.79 +/* State of each CPU. */
    2.80 +/*DEFINE_PER_CPU(int, cpu_state) = { 0 };*/
    2.81 +
    2.82  /*
    2.83   * Currently trivial. Write the real->protected mode
    2.84   * bootstrap into the page concerned. The caller
    2.85   * has made sure it's suitably aligned.
    2.86   */
    2.87  
    2.88 -static unsigned long __init setup_trampoline(void)
    2.89 +static unsigned long __devinit setup_trampoline(void)
    2.90  {
    2.91  	memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
    2.92  	return virt_to_maddr(trampoline_base);
    2.93 @@ -123,7 +156,7 @@ void __init smp_alloc_memory(void)
    2.94   * a given CPU
    2.95   */
    2.96  
    2.97 -static void __init smp_store_cpu_info(int id)
    2.98 +static void __devinit smp_store_cpu_info(int id)
    2.99  {
   2.100  	struct cpuinfo_x86 *c = cpu_data + id;
   2.101  
   2.102 @@ -169,7 +202,7 @@ static void __init smp_store_cpu_info(in
   2.103  				goto valid_k7;
   2.104  
   2.105  		/* If we get here, it's not a certified SMP capable AMD system. */
   2.106 -		tainted |= TAINT_UNSAFE_SMP;
   2.107 +		add_taint(TAINT_UNSAFE_SMP);
   2.108  	}
   2.109  
   2.110  valid_k7:
   2.111 @@ -196,7 +229,7 @@ static void __init synchronize_tsc_bp (v
   2.112  	unsigned long long t0;
   2.113  	unsigned long long sum, avg;
   2.114  	long long delta;
   2.115 -	unsigned long one_usec;
   2.116 +	unsigned int one_usec;
   2.117  	int buggy = 0;
   2.118  
   2.119  	printk(KERN_INFO "checking TSC synchronization across %u CPUs: ", num_booting_cpus());
   2.120 @@ -317,7 +350,7 @@ extern void calibrate_delay(void);
   2.121  
   2.122  static atomic_t init_deasserted;
   2.123  
   2.124 -void __init smp_callin(void)
   2.125 +void __devinit smp_callin(void)
   2.126  {
   2.127  	int cpuid, phys_id, i;
   2.128  
   2.129 @@ -403,12 +436,69 @@ void __init smp_callin(void)
   2.130  	/*
   2.131  	 *      Synchronize the TSC with the BP
   2.132  	 */
   2.133 -	if (cpu_has_tsc && cpu_khz)
   2.134 +	if (cpu_has_tsc && cpu_khz && !tsc_sync_disabled)
   2.135  		synchronize_tsc_ap();
   2.136  	calibrate_tsc_ap();
   2.137  }
   2.138  
   2.139 -int cpucount;
   2.140 +static int cpucount;
   2.141 +
   2.142 +/* representing cpus for which sibling maps can be computed */
   2.143 +static cpumask_t cpu_sibling_setup_map;
   2.144 +
   2.145 +static inline void
   2.146 +set_cpu_sibling_map(int cpu)
   2.147 +{
   2.148 +	int i;
   2.149 +	struct cpuinfo_x86 *c = cpu_data;
   2.150 +
   2.151 +	cpu_set(cpu, cpu_sibling_setup_map);
   2.152 +
   2.153 +	if (smp_num_siblings > 1) {
   2.154 +		for_each_cpu_mask(i, cpu_sibling_setup_map) {
   2.155 +			if (phys_proc_id[cpu] == phys_proc_id[i] &&
   2.156 +			    cpu_core_id[cpu] == cpu_core_id[i]) {
   2.157 +				cpu_set(i, cpu_sibling_map[cpu]);
   2.158 +				cpu_set(cpu, cpu_sibling_map[i]);
   2.159 +				cpu_set(i, cpu_core_map[cpu]);
   2.160 +				cpu_set(cpu, cpu_core_map[i]);
   2.161 +			}
   2.162 +		}
   2.163 +	} else {
   2.164 +		cpu_set(cpu, cpu_sibling_map[cpu]);
   2.165 +	}
   2.166 +
   2.167 +	if (current_cpu_data.x86_max_cores == 1) {
   2.168 +		cpu_core_map[cpu] = cpu_sibling_map[cpu];
   2.169 +		c[cpu].booted_cores = 1;
   2.170 +		return;
   2.171 +	}
   2.172 +
   2.173 +	for_each_cpu_mask(i, cpu_sibling_setup_map) {
   2.174 +		if (phys_proc_id[cpu] == phys_proc_id[i]) {
   2.175 +			cpu_set(i, cpu_core_map[cpu]);
   2.176 +			cpu_set(cpu, cpu_core_map[i]);
   2.177 +			/*
   2.178 +			 *  Does this new cpu bringup a new core?
   2.179 +			 */
   2.180 +			if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
   2.181 +				/*
   2.182 +				 * for each core in package, increment
   2.183 +				 * the booted_cores for this new cpu
   2.184 +				 */
   2.185 +				if (first_cpu(cpu_sibling_map[i]) == i)
   2.186 +					c[cpu].booted_cores++;
   2.187 +				/*
   2.188 +				 * increment the core count for all
   2.189 +				 * the other cpus in this package
   2.190 +				 */
   2.191 +				if (i != cpu)
   2.192 +					c[i].booted_cores++;
   2.193 +			} else if (i != cpu && !c[cpu].booted_cores)
   2.194 +				c[cpu].booted_cores = c[i].booted_cores;
   2.195 +		}
   2.196 +	}
   2.197 +}
   2.198  
   2.199  #ifdef CONFIG_X86_32
   2.200  static void construct_percpu_idt(unsigned int cpu)
   2.201 @@ -427,8 +517,13 @@ static void construct_percpu_idt(unsigne
   2.202  /*
   2.203   * Activate a secondary processor.
   2.204   */
   2.205 -void __init start_secondary(void *unused)
   2.206 +void __devinit start_secondary(void *unused)
   2.207  {
   2.208 +	/*
   2.209 +	 * Dont put anything before smp_callin(), SMP
   2.210 +	 * booting is too fragile that we want to limit the
   2.211 +	 * things done here to the most necessary things.
   2.212 +	 */
   2.213  	unsigned int cpu = cpucount;
   2.214  
   2.215  	extern void percpu_traps_init(void);
   2.216 @@ -439,6 +534,7 @@ void __init start_secondary(void *unused
   2.217  	percpu_traps_init();
   2.218  
   2.219  	cpu_init();
   2.220 +	/*preempt_disable();*/
   2.221  	smp_callin();
   2.222  	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
   2.223  		rep_nop();
   2.224 @@ -453,13 +549,28 @@ void __init start_secondary(void *unused
   2.225  
   2.226  	setup_secondary_APIC_clock();
   2.227  	enable_APIC_timer();
   2.228 -
   2.229  	/*
   2.230  	 * low-memory mappings have been cleared, flush them from
   2.231  	 * the local TLBs too.
   2.232  	 */
   2.233  	local_flush_tlb();
   2.234 +
   2.235 +	/* This must be done before setting cpu_online_map */
   2.236 +	set_cpu_sibling_map(raw_smp_processor_id());
   2.237 +	wmb();
   2.238 +
   2.239 +	/*
   2.240 +	 * We need to hold call_lock, so there is no inconsistency
   2.241 +	 * between the time smp_call_function() determines number of
   2.242 +	 * IPI receipients, and the time when the determination is made
   2.243 +	 * for which cpus receive the IPI. Holding this
   2.244 +	 * lock helps us to not include this cpu in a currently in progress
   2.245 +	 * smp_call_function().
   2.246 +	 */
   2.247 +	/*lock_ipi_call_lock();*/
   2.248  	cpu_set(smp_processor_id(), cpu_online_map);
   2.249 +	/*unlock_ipi_call_lock();*/
   2.250 +	/*per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;*/
   2.251  
   2.252  	/* We can take interrupts now: we're officially "up". */
   2.253  	local_irq_enable();
   2.254 @@ -478,10 +589,10 @@ extern struct {
   2.255  #ifdef CONFIG_NUMA
   2.256  
   2.257  /* which logical CPUs are on which nodes */
   2.258 -cpumask_t node_2_cpu_mask[MAX_NUMNODES] =
   2.259 +cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly =
   2.260  				{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
   2.261  /* which node each logical CPU is on */
   2.262 -int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
   2.263 +int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
   2.264  EXPORT_SYMBOL(cpu_2_node);
   2.265  
   2.266  /* set up a mapping between cpu and node. */
   2.267 @@ -509,9 +620,9 @@ static inline void unmap_cpu_to_node(int
   2.268  
   2.269  #endif /* CONFIG_NUMA */
   2.270  
   2.271 -u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
   2.272 +u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
   2.273  
   2.274 -void map_cpu_to_logical_apicid(void)
   2.275 +static void map_cpu_to_logical_apicid(void)
   2.276  {
   2.277  	int cpu = smp_processor_id();
   2.278  	int apicid = logical_smp_processor_id();
   2.279 @@ -520,7 +631,7 @@ void map_cpu_to_logical_apicid(void)
   2.280  	map_cpu_to_node(cpu, apicid_to_node(apicid));
   2.281  }
   2.282  
   2.283 -void unmap_cpu_to_logical_apicid(int cpu)
   2.284 +static void unmap_cpu_to_logical_apicid(int cpu)
   2.285  {
   2.286  	cpu_2_logical_apicid[cpu] = BAD_APICID;
   2.287  	unmap_cpu_to_node(cpu);
   2.288 @@ -535,7 +646,7 @@ static inline void __inquire_remote_apic
   2.289  
   2.290  	printk("Inquiring remote APIC #%d...\n", apicid);
   2.291  
   2.292 -	for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) {
   2.293 +	for (i = 0; i < ARRAY_SIZE(regs); i++) {
   2.294  		printk("... APIC #%d %s: ", apicid, names[i]);
   2.295  
   2.296  		/*
   2.297 @@ -570,7 +681,7 @@ static inline void __inquire_remote_apic
   2.298   * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
   2.299   * won't ... remember to clear down the APIC, etc later.
   2.300   */
   2.301 -static int __init
   2.302 +static int __devinit
   2.303  wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
   2.304  {
   2.305  	unsigned long send_status = 0, accept_status = 0;
   2.306 @@ -616,7 +727,7 @@ wakeup_secondary_cpu(int logical_apicid,
   2.307  #endif	/* WAKE_SECONDARY_VIA_NMI */
   2.308  
   2.309  #ifdef WAKE_SECONDARY_VIA_INIT
   2.310 -static int __init
   2.311 +static int __devinit
   2.312  wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
   2.313  {
   2.314  	unsigned long send_status = 0, accept_status = 0;
   2.315 @@ -751,8 +862,18 @@ wakeup_secondary_cpu(int phys_apicid, un
   2.316  #endif	/* WAKE_SECONDARY_VIA_INIT */
   2.317  
   2.318  extern cpumask_t cpu_initialized;
   2.319 +static inline int alloc_cpu_id(void)
   2.320 +{
   2.321 +	cpumask_t	tmp_map;
   2.322 +	int cpu;
   2.323 +	cpus_complement(tmp_map, cpu_present_map);
   2.324 +	cpu = first_cpu(tmp_map);
   2.325 +	if (cpu >= NR_CPUS)
   2.326 +		return -ENODEV;
   2.327 +	return cpu;
   2.328 +}
   2.329  
   2.330 -static int __init do_boot_cpu(int apicid)
   2.331 +static int __devinit do_boot_cpu(int apicid, int cpu)
   2.332  /*
   2.333   * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
   2.334   * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
   2.335 @@ -761,11 +882,11 @@ static int __init do_boot_cpu(int apicid
   2.336  {
   2.337  	struct vcpu *v;
   2.338  	unsigned long boot_error;
   2.339 -	int timeout, cpu;
   2.340 +	int timeout;
   2.341  	unsigned long start_eip;
   2.342  	unsigned short nmi_high = 0, nmi_low = 0;
   2.343  
   2.344 -	cpu = ++cpucount;
   2.345 +	++cpucount;
   2.346  
   2.347  	v = idle_vcpu[cpu] = alloc_vcpu(idle_vcpu[0]->domain, cpu, cpu);
   2.348          BUG_ON(v == NULL);
   2.349 @@ -794,13 +915,7 @@ static int __init do_boot_cpu(int apicid
   2.350  
   2.351  	store_NMI_vector(&nmi_high, &nmi_low);
   2.352  
   2.353 -	CMOS_WRITE(0xa, 0xf);
   2.354 -	local_flush_tlb();
   2.355 -	Dprintk("1.\n");
   2.356 -	*((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4;
   2.357 -	Dprintk("2.\n");
   2.358 -	*((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf;
   2.359 -	Dprintk("3.\n");
   2.360 +	smpboot_setup_warm_reset_vector(start_eip);
   2.361  
   2.362  	/*
   2.363  	 * Starting actual IPI sequence...
   2.364 @@ -842,13 +957,16 @@ static int __init do_boot_cpu(int apicid
   2.365  			inquire_remote_apic(apicid);
   2.366  		}
   2.367  	}
   2.368 -	x86_cpu_to_apicid[cpu] = apicid;
   2.369 +
   2.370  	if (boot_error) {
   2.371  		/* Try to put things back the way they were before ... */
   2.372  		unmap_cpu_to_logical_apicid(cpu);
   2.373  		cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
   2.374  		cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
   2.375  		cpucount--;
   2.376 +	} else {
   2.377 +		x86_cpu_to_apicid[cpu] = apicid;
   2.378 +		cpu_set(cpu, cpu_present_map);
   2.379  	}
   2.380  
   2.381  	/* mark "stuck" area as not stuck */
   2.382 @@ -857,54 +975,6 @@ static int __init do_boot_cpu(int apicid
   2.383  	return boot_error;
   2.384  }
   2.385  
   2.386 -#if 0
   2.387 -cycles_t cacheflush_time;
   2.388 -unsigned long cache_decay_ticks;
   2.389 -
   2.390 -static void smp_tune_scheduling (void)
   2.391 -{
   2.392 -	unsigned long cachesize;       /* kB   */
   2.393 -	unsigned long bandwidth = 350; /* MB/s */
   2.394 -	/*
   2.395 -	 * Rough estimation for SMP scheduling, this is the number of
   2.396 -	 * cycles it takes for a fully memory-limited process to flush
   2.397 -	 * the SMP-local cache.
   2.398 -	 *
   2.399 -	 * (For a P5 this pretty much means we will choose another idle
   2.400 -	 *  CPU almost always at wakeup time (this is due to the small
   2.401 -	 *  L1 cache), on PIIs it's around 50-100 usecs, depending on
   2.402 -	 *  the cache size)
   2.403 -	 */
   2.404 -
   2.405 -	if (!cpu_khz) {
   2.406 -		/*
   2.407 -		 * this basically disables processor-affinity
   2.408 -		 * scheduling on SMP without a TSC.
   2.409 -		 */
   2.410 -		cacheflush_time = 0;
   2.411 -		return;
   2.412 -	} else {
   2.413 -		cachesize = boot_cpu_data.x86_cache_size;
   2.414 -		if (cachesize == -1) {
   2.415 -			cachesize = 16; /* Pentiums, 2x8kB cache */
   2.416 -			bandwidth = 100;
   2.417 -		}
   2.418 -
   2.419 -		cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth;
   2.420 -	}
   2.421 -
   2.422 -	cache_decay_ticks = (long)cacheflush_time/cpu_khz + 1;
   2.423 -
   2.424 -	printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n",
   2.425 -		(long)cacheflush_time/(cpu_khz/1000),
   2.426 -		((long)cacheflush_time*100/(cpu_khz/1000)) % 100);
   2.427 -	printk("task migration cache decay timeout: %ld msecs.\n",
   2.428 -		cache_decay_ticks);
   2.429 -}
   2.430 -#else
   2.431 -#define smp_tune_scheduling() ((void)0)
   2.432 -#endif
   2.433 -
   2.434  /*
   2.435   * Cycle through the processors sending APIC IPIs to boot each.
   2.436   */
   2.437 @@ -912,10 +982,9 @@ static void smp_tune_scheduling (void)
   2.438  static int boot_cpu_logical_apicid;
   2.439  /* Where the IO area was mapped on multiquad, always 0 otherwise */
   2.440  void *xquad_portio;
   2.441 -
   2.442 -cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
   2.443 -cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
   2.444 -EXPORT_SYMBOL(cpu_core_map);
   2.445 +#ifdef CONFIG_X86_NUMAQ
   2.446 +EXPORT_SYMBOL(xquad_portio);
   2.447 +#endif
   2.448  
   2.449  static void __init smp_boot_cpus(unsigned int max_cpus)
   2.450  {
   2.451 @@ -936,12 +1005,9 @@ static void __init smp_boot_cpus(unsigne
   2.452  	x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
   2.453  
   2.454  	/*current_thread_info()->cpu = 0;*/
   2.455 -	smp_tune_scheduling();
   2.456 -	cpus_clear(cpu_sibling_map[0]);
   2.457 -	cpu_set(0, cpu_sibling_map[0]);
   2.458 +	/*smp_tune_scheduling();*/
   2.459  
   2.460 -	cpus_clear(cpu_core_map[0]);
   2.461 -	cpu_set(0, cpu_core_map[0]);
   2.462 +	set_cpu_sibling_map(0);
   2.463  
   2.464  	/*
   2.465  	 * If we couldn't find an SMP configuration at boot time,
   2.466 @@ -1018,7 +1084,7 @@ static void __init smp_boot_cpus(unsigne
   2.467  		if (max_cpus <= cpucount+1)
   2.468  			continue;
   2.469  
   2.470 -		if (do_boot_cpu(apicid))
   2.471 +		if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
   2.472  			printk("CPU #%d not responding - cannot use it.\n",
   2.473  								apicid);
   2.474  		else
   2.475 @@ -1026,17 +1092,9 @@ static void __init smp_boot_cpus(unsigne
   2.476  	}
   2.477  
   2.478  	/*
   2.479 -	 * Install writable page 0 entry to set BIOS data area.
   2.480 +	 * Cleanup possible dangling ends...
   2.481  	 */
   2.482 -	local_flush_tlb();
   2.483 -
   2.484 -	/*
   2.485 -	 * Paranoid:  Set warm reset code and vector here back
   2.486 -	 * to default values.
   2.487 -	 */
   2.488 -	CMOS_WRITE(0, 0xf);
   2.489 -
   2.490 -	*((volatile long *) maddr_to_virt(0x467)) = 0;
   2.491 +	smpboot_restore_warm_reset_vector();
   2.492  
   2.493  #ifdef BOGOMIPS
   2.494  	/*
   2.495 @@ -1082,54 +1140,13 @@ static void __init smp_boot_cpus(unsigne
   2.496  		cpus_clear(cpu_core_map[cpu]);
   2.497  	}
   2.498  
   2.499 -	for (cpu = 0; cpu < NR_CPUS; cpu++) {
   2.500 -		struct cpuinfo_x86 *c = cpu_data + cpu;
   2.501 -		int siblings = 0;
   2.502 -		int i;
   2.503 -		if (!cpu_isset(cpu, cpu_callout_map))
   2.504 -			continue;
   2.505 -
   2.506 -		if (smp_num_siblings > 1) {
   2.507 -			for (i = 0; i < NR_CPUS; i++) {
   2.508 -				if (!cpu_isset(i, cpu_callout_map))
   2.509 -					continue;
   2.510 -				if (cpu_core_id[cpu] == cpu_core_id[i]) {
   2.511 -					siblings++;
   2.512 -					cpu_set(i, cpu_sibling_map[cpu]);
   2.513 -				}
   2.514 -			}
   2.515 -		} else {
   2.516 -			siblings++;
   2.517 -			cpu_set(cpu, cpu_sibling_map[cpu]);
   2.518 -		}
   2.519 -
   2.520 -		if (siblings != smp_num_siblings) {
   2.521 -			printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
   2.522 -			smp_num_siblings = siblings;
   2.523 -		}
   2.524 -
   2.525 -		if (c->x86_max_cores > 1) {
   2.526 -			for (i = 0; i < NR_CPUS; i++) {
   2.527 -				if (!cpu_isset(i, cpu_callout_map))
   2.528 -					continue;
   2.529 -				if (phys_proc_id[cpu] == phys_proc_id[i]) {
   2.530 -					cpu_set(i, cpu_core_map[cpu]);
   2.531 -				}
   2.532 -			}
   2.533 -		} else {
   2.534 -			cpu_core_map[cpu] = cpu_sibling_map[cpu];
   2.535 -		}
   2.536 -	}
   2.537 +	cpu_set(0, cpu_sibling_map[0]);
   2.538 +	cpu_set(0, cpu_core_map[0]);
   2.539  
   2.540  	if (nmi_watchdog == NMI_LOCAL_APIC)
   2.541  		check_nmi_watchdog();
   2.542  
   2.543 -	/*
   2.544 -	 * Here we can be sure that there is an IO-APIC in the system. Let's
   2.545 -	 * go and set it up:
   2.546 -	 */
   2.547 -	if (!skip_ioapic_setup && nr_ioapics)
   2.548 -		setup_IO_APIC();
   2.549 +	smpboot_setup_io_apic();
   2.550  
   2.551  	setup_boot_APIC_clock();
   2.552  
   2.553 @@ -1145,6 +1162,9 @@ static void __init smp_boot_cpus(unsigne
   2.554     who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */
   2.555  void __init smp_prepare_cpus(unsigned int max_cpus)
   2.556  {
   2.557 +	smp_commenced_mask = cpumask_of_cpu(0);
   2.558 +	cpu_callin_map = cpumask_of_cpu(0);
   2.559 +	mb();
   2.560  	smp_boot_cpus(max_cpus);
   2.561  }
   2.562  
   2.563 @@ -1152,18 +1172,22 @@ void __devinit smp_prepare_boot_cpu(void
   2.564  {
   2.565  	cpu_set(smp_processor_id(), cpu_online_map);
   2.566  	cpu_set(smp_processor_id(), cpu_callout_map);
   2.567 +	cpu_set(smp_processor_id(), cpu_present_map);
   2.568 +	cpu_set(smp_processor_id(), cpu_possible_map);
   2.569 +	/*per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;*/
   2.570  }
   2.571  
   2.572  int __devinit __cpu_up(unsigned int cpu)
   2.573  {
   2.574 -	/* This only works at boot for x86.  See "rewrite" above. */
   2.575 -	if (cpu_isset(cpu, smp_commenced_mask))
   2.576 -		return -ENOSYS;
   2.577 +	/* In case one didn't come up */
   2.578 +	if (!cpu_isset(cpu, cpu_callin_map)) {
   2.579 +		printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);
   2.580 +		local_irq_enable();
   2.581 +		return -EIO;
   2.582 +	}
   2.583  
   2.584 -	/* In case one didn't come up */
   2.585 -	if (!cpu_isset(cpu, cpu_callin_map))
   2.586 -		return -EIO;
   2.587 -
   2.588 +	local_irq_enable();
   2.589 +	/*per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;*/
   2.590  	/* Unleash the CPU! */
   2.591  	cpu_set(cpu, smp_commenced_mask);
   2.592  	while (!cpu_isset(cpu, cpu_online_map)) {
   2.593 @@ -1171,7 +1195,6 @@ int __devinit __cpu_up(unsigned int cpu)
   2.594  		if (softirq_pending(0))
   2.595  			do_softirq();
   2.596  	}
   2.597 -
   2.598  	return 0;
   2.599  }
   2.600  
   2.601 @@ -1183,10 +1206,12 @@ void __init smp_cpus_done(unsigned int m
   2.602  #ifdef CONFIG_X86_64
   2.603  	zap_low_mappings();
   2.604  #endif
   2.605 +#ifndef CONFIG_HOTPLUG_CPU
   2.606  	/*
   2.607  	 * Disable executability of the SMP trampoline:
   2.608  	 */
   2.609  	set_kernel_exec((unsigned long)trampoline_base, trampoline_exec);
   2.610 +#endif
   2.611  }
   2.612  
   2.613  void __init smp_intr_init(void)
     3.1 --- a/xen/include/asm-ia64/config.h	Thu Feb 16 14:26:02 2006 +0000
     3.2 +++ b/xen/include/asm-ia64/config.h	Thu Feb 16 16:31:22 2006 +0100
     3.3 @@ -299,9 +299,9 @@ extern int ht_per_core;
     3.4  
     3.5  // needed for include/xen/smp.h
     3.6  #ifdef CONFIG_SMP
     3.7 -#define __smp_processor_id()	current->processor
     3.8 +#define raw_smp_processor_id()	current->processor
     3.9  #else
    3.10 -#define __smp_processor_id()	0
    3.11 +#define raw_smp_processor_id()	0
    3.12  #endif
    3.13  
    3.14  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/include/asm-x86/mach-default/smpboot_hooks.h	Thu Feb 16 16:31:22 2006 +0100
     4.3 @@ -0,0 +1,44 @@
     4.4 +/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
     4.5 + * which needs to alter them. */
     4.6 +
     4.7 +static inline void smpboot_clear_io_apic_irqs(void)
     4.8 +{
     4.9 +	io_apic_irqs = 0;
    4.10 +}
    4.11 +
    4.12 +static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
    4.13 +{
    4.14 +	CMOS_WRITE(0xa, 0xf);
    4.15 +	local_flush_tlb();
    4.16 +	Dprintk("1.\n");
    4.17 +	*((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4;
    4.18 +	Dprintk("2.\n");
    4.19 +	*((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf;
    4.20 +	Dprintk("3.\n");
    4.21 +}
    4.22 +
    4.23 +static inline void smpboot_restore_warm_reset_vector(void)
    4.24 +{
    4.25 +	/*
    4.26 +	 * Install writable page 0 entry to set BIOS data area.
    4.27 +	 */
    4.28 +	local_flush_tlb();
    4.29 +
    4.30 +	/*
    4.31 +	 * Paranoid:  Set warm reset code and vector here back
    4.32 +	 * to default values.
    4.33 +	 */
    4.34 +	CMOS_WRITE(0, 0xf);
    4.35 +
    4.36 +	*((volatile long *) maddr_to_virt(0x467)) = 0;
    4.37 +}
    4.38 +
    4.39 +static inline void smpboot_setup_io_apic(void)
    4.40 +{
    4.41 +	/*
    4.42 +	 * Here we can be sure that there is an IO-APIC in the system. Let's
    4.43 +	 * go and set it up:
    4.44 +	 */
    4.45 +	if (!skip_ioapic_setup && nr_ioapics)
    4.46 +		setup_IO_APIC();
    4.47 +}
     5.1 --- a/xen/include/asm-x86/smp.h	Thu Feb 16 14:26:02 2006 +0000
     5.2 +++ b/xen/include/asm-x86/smp.h	Thu Feb 16 16:31:22 2006 +0100
     5.3 @@ -37,8 +37,6 @@ extern int smp_num_siblings;
     5.4  extern cpumask_t cpu_sibling_map[];
     5.5  extern cpumask_t cpu_core_map[];
     5.6  
     5.7 -extern void smp_flush_tlb(void);
     5.8 -extern void smp_invalidate_rcv(void);		/* Process an NMI */
     5.9  extern void (*mtrr_hook) (void);
    5.10  
    5.11  #ifdef CONFIG_X86_64
    5.12 @@ -50,16 +48,23 @@ extern void zap_low_mappings(l2_pgentry_
    5.13  #define MAX_APICID 256
    5.14  extern u8 x86_cpu_to_apicid[];
    5.15  
    5.16 +#define cpu_physical_id(cpu)	x86_cpu_to_apicid[cpu]
    5.17 +
    5.18 +#ifdef CONFIG_HOTPLUG_CPU
    5.19 +extern void cpu_exit_clear(void);
    5.20 +extern void cpu_uninit(void);
    5.21 +#endif
    5.22 +
    5.23  /*
    5.24   * This function is needed by all SMP systems. It must _always_ be valid
    5.25   * from the initial startup. We map APIC_BASE very early in page_setup(),
    5.26   * so this is correct in the x86 case.
    5.27   */
    5.28 -#define __smp_processor_id() (get_processor_id())
    5.29 +#define raw_smp_processor_id() (get_processor_id())
    5.30  
    5.31  extern cpumask_t cpu_callout_map;
    5.32  extern cpumask_t cpu_callin_map;
    5.33 -#define cpu_possible_map cpu_callout_map
    5.34 +extern cpumask_t cpu_possible_map;
    5.35  
    5.36  /* We don't mark CPUs online until __cpu_up(), so we need another measure */
    5.37  static inline int num_booting_cpus(void)
    5.38 @@ -67,9 +72,6 @@ static inline int num_booting_cpus(void)
    5.39  	return cpus_weight(cpu_callout_map);
    5.40  }
    5.41  
    5.42 -extern void map_cpu_to_logical_apicid(void);
    5.43 -extern void unmap_cpu_to_logical_apicid(int cpu);
    5.44 -
    5.45  #ifdef CONFIG_X86_LOCAL_APIC
    5.46  
    5.47  #ifdef APIC_DEFINITION
    5.48 @@ -90,8 +92,15 @@ static __inline int logical_smp_processo
    5.49  }
    5.50  
    5.51  #endif
    5.52 +
    5.53 +extern int __cpu_disable(void);
    5.54 +extern void __cpu_die(unsigned int cpu);
    5.55  #endif /* !__ASSEMBLY__ */
    5.56  
    5.57 +#else /* CONFIG_SMP */
    5.58 +
    5.59 +#define cpu_physical_id(cpu)		boot_cpu_physical_apicid
    5.60 +
    5.61  #define NO_PROC_ID		0xFF		/* No processor magic marker */
    5.62  
    5.63  #endif
     6.1 --- a/xen/include/xen/smp.h	Thu Feb 16 14:26:02 2006 +0000
     6.2 +++ b/xen/include/xen/smp.h	Thu Feb 16 16:31:22 2006 +0100
     6.3 @@ -86,9 +86,7 @@ void smp_prepare_boot_cpu(void);
     6.4  
     6.5  #define smp_send_event_check_mask(m)            ((void)0)
     6.6  #define smp_send_event_check_cpu(p)             ((void)0) 
     6.7 -#ifndef __smp_processor_id
     6.8 -#define smp_processor_id()			0
     6.9 -#endif
    6.10 +#define raw_smp_processor_id()			0
    6.11  #define hard_smp_processor_id()			0
    6.12  #define smp_call_function(func,info,retry,wait)	({ do {} while (0); 0; })
    6.13  #define on_each_cpu(func,info,retry,wait)	({ func(info); 0; })
    6.14 @@ -97,10 +95,6 @@ void smp_prepare_boot_cpu(void);
    6.15  
    6.16  #endif
    6.17  
    6.18 -#ifdef __smp_processor_id
    6.19 -#define smp_processor_id() __smp_processor_id()
    6.20 -#else
    6.21 -extern unsigned int smp_processor_id(void);
    6.22 -#endif
    6.23 +#define smp_processor_id() raw_smp_processor_id()
    6.24  
    6.25  #endif