x86: Simplify smpboot_alloc by merging x86-{32,64} code as far as
authorKeir Fraser <keir@xen.org>
Thu, 13 Oct 2011 14:59:22 +0000 (15:59 +0100)
committerKeir Fraser <keir@xen.org>
Thu, 13 Oct 2011 14:59:22 +0000 (15:59 +0100)
possible.

We still need one ifdef, as x86-32 does not have a compat_gdt_table.

On x86-32 there is 1/2-page wastage due to allocating a whole page for
the per-CPU IDT, however we expect very few users of the x86-32
hypervisor. Those that cannot move to the 64-bit hypervisor are likely
using old single-processor systems or new single-procesor netbooks. On
UP and small MP systems, the wastage is insignificant.

Signed-off-by: Keir Fraser <keir@xen.org>
Committed-by: Keir Fraser <keir@xen.org>
xen/arch/x86/smpboot.c

index 6dd3b34959f337f9a498eacec3a5bd833d899ff9..c0084687943f496cb01d3501133073df63ab366c 100644 (file)
@@ -640,21 +640,16 @@ static void cpu_smpboot_free(unsigned int cpu)
     unsigned int order;
 
     order = get_order_from_pages(NR_RESERVED_GDT_PAGES);
+    free_xenheap_pages(per_cpu(gdt_table, cpu), order);
+    per_cpu(gdt_table, cpu) = NULL;
+
 #ifdef __x86_64__
-    if ( per_cpu(compat_gdt_table, cpu) )
-        free_domheap_pages(virt_to_page(per_cpu(gdt_table, cpu)), order);
-    if ( per_cpu(gdt_table, cpu) )
-        free_domheap_pages(virt_to_page(per_cpu(compat_gdt_table, cpu)),
-                           order);
+    free_xenheap_pages(per_cpu(compat_gdt_table, cpu), order);
     per_cpu(compat_gdt_table, cpu) = NULL;
-    order = get_order_from_bytes(IDT_ENTRIES * sizeof(**idt_tables));
-    if ( idt_tables[cpu] )
-        free_domheap_pages(virt_to_page(idt_tables[cpu]), order);
-#else
-    free_xenheap_pages(per_cpu(gdt_table, cpu), order);
-    xfree(idt_tables[cpu]);
 #endif
-    per_cpu(gdt_table, cpu) = NULL;
+
+    order = get_order_from_bytes(IDT_ENTRIES * sizeof(idt_entry_t));
+    free_xenheap_pages(idt_tables[cpu], order);
     idt_tables[cpu] = NULL;
 
     if ( stack_base[cpu] != NULL )
@@ -669,9 +664,6 @@ static int cpu_smpboot_alloc(unsigned int cpu)
 {
     unsigned int order;
     struct desc_struct *gdt;
-#ifdef __x86_64__
-    struct page_info *page;
-#endif
 
     stack_base[cpu] = alloc_xenheap_pages(STACK_ORDER, 0);
     if ( stack_base[cpu] == NULL )
@@ -679,41 +671,28 @@ static int cpu_smpboot_alloc(unsigned int cpu)
     memguard_guard_stack(stack_base[cpu]);
 
     order = get_order_from_pages(NR_RESERVED_GDT_PAGES);
-#ifdef __x86_64__
-    page = alloc_domheap_pages(NULL, order,
-                               MEMF_node(cpu_to_node(cpu)));
-    if ( !page )
+    per_cpu(gdt_table, cpu) = gdt =
+        alloc_xenheap_pages(order, MEMF_node(cpu_to_node(cpu)));
+    if ( gdt == NULL )
         goto oom;
-    per_cpu(compat_gdt_table, cpu) = gdt = page_to_virt(page);
-    memcpy(gdt, boot_cpu_compat_gdt_table,
-           NR_RESERVED_GDT_PAGES * PAGE_SIZE);
+    memcpy(gdt, boot_cpu_gdt_table, NR_RESERVED_GDT_PAGES * PAGE_SIZE);
+    BUILD_BUG_ON(NR_CPUS > 0x10000);
     gdt[PER_CPU_GDT_ENTRY - FIRST_RESERVED_GDT_ENTRY].a = cpu;
-    page = alloc_domheap_pages(NULL, order,
-                               MEMF_node(cpu_to_node(cpu)));
-    if ( !page )
-        goto oom;
-    per_cpu(gdt_table, cpu) = gdt = page_to_virt(page);
-    order = get_order_from_bytes(IDT_ENTRIES * sizeof(**idt_tables));
-    page = alloc_domheap_pages(NULL, order,
-                               MEMF_node(cpu_to_node(cpu)));
-    if ( !page )
-        goto oom;
-    idt_tables[cpu] = page_to_virt(page);
-#else
-    per_cpu(gdt_table, cpu) = gdt = alloc_xenheap_pages(order, 0);
-    if ( !gdt )
-        goto oom;
-    idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES);
-    if ( idt_tables[cpu] == NULL )
+
+#ifdef __x86_64__
+    per_cpu(compat_gdt_table, cpu) = gdt =
+        alloc_xenheap_pages(order, MEMF_node(cpu_to_node(cpu)));
+    if ( gdt == NULL )
         goto oom;
-#endif
-    memcpy(gdt, boot_cpu_gdt_table,
-           NR_RESERVED_GDT_PAGES * PAGE_SIZE);
-    BUILD_BUG_ON(NR_CPUS > 0x10000);
+    memcpy(gdt, boot_cpu_compat_gdt_table, NR_RESERVED_GDT_PAGES * PAGE_SIZE);
     gdt[PER_CPU_GDT_ENTRY - FIRST_RESERVED_GDT_ENTRY].a = cpu;
+#endif
 
-    memcpy(idt_tables[cpu], idt_table,
-           IDT_ENTRIES*sizeof(idt_entry_t));
+    order = get_order_from_bytes(IDT_ENTRIES * sizeof(idt_entry_t));
+    idt_tables[cpu] = alloc_xenheap_pages(order, MEMF_node(cpu_to_node(cpu)));
+    if ( idt_tables[cpu] == NULL )
+        goto oom;
+    memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES * sizeof(idt_entry_t));
 
     return 0;