aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'xen/arch/x86/setup.c')
-rw-r--r--xen/arch/x86/setup.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 721b6781d8..70f2822524 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -14,6 +14,7 @@
#include <xen/domain_page.h>
#include <xen/compile.h>
#include <xen/gdbstub.h>
+#include <xen/percpu.h>
#include <public/version.h>
#include <asm/bitops.h>
#include <asm/smp.h>
@@ -159,6 +160,38 @@ void discard_initial_images(void)
init_domheap_pages(initial_images_start, initial_images_end);
}
+extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[];
+
+static void percpu_init_areas(void)
+{
+ unsigned int i, data_size = __per_cpu_data_end - __per_cpu_start;
+
+ BUG_ON(data_size > PERCPU_SIZE);
+
+ for ( i = 1; i < NR_CPUS; i++ )
+ memcpy(__per_cpu_start + (i << PERCPU_SHIFT),
+ __per_cpu_start,
+ data_size);
+}
+
+static void percpu_free_unused_areas(void)
+{
+ unsigned int i, first_unused;
+
+ /* Find first unused CPU number. */
+ for ( i = 0; i < NR_CPUS; i++ )
+ if ( !cpu_online(i) )
+ break;
+ first_unused = i;
+
+ /* Check that there are no holes in cpu_online_map. */
+ for ( ; i < NR_CPUS; i++ )
+ BUG_ON(cpu_online(i));
+
+ init_xenheap_pages(__pa(__per_cpu_start) + (first_unused << PERCPU_SHIFT),
+ __pa(__per_cpu_end));
+}
+
void __init __start_xen(multiboot_info_t *mbi)
{
char *cmdline;
@@ -209,6 +242,8 @@ void __init __start_xen(multiboot_info_t *mbi)
EARLY_FAIL();
}
+ percpu_init_areas();
+
xenheap_phys_end = opt_xenheap_megabytes << 20;
if ( mbi->flags & MBI_MEMMAP )
@@ -405,7 +440,7 @@ void __init __start_xen(multiboot_info_t *mbi)
BUG_ON(idle_domain == NULL);
set_current(idle_domain->vcpu[0]);
- set_current_execstate(idle_domain->vcpu[0]);
+ this_cpu(curr_vcpu) = idle_domain->vcpu[0];
idle_vcpu[0] = current;
paging_init();
@@ -482,6 +517,8 @@ void __init __start_xen(multiboot_info_t *mbi)
printk("Brought up %ld CPUs\n", (long)num_online_cpus());
smp_cpus_done(max_cpus);
+ percpu_free_unused_areas();
+
initialise_gdb(); /* could be moved earlier */
do_initcalls();