WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86: reduce GDT switching

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: reduce GDT switching
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 19 Nov 2008 08:10:22 -0800
Delivery-date: Wed, 19 Nov 2008 08:11:35 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1226491295 0
# Node ID 8e18dd41c6c7bb0980b29393b275c564cfb96437
# Parent  2bd99c5faa420612544a9d94e298332e0e72a86a
x86: reduce GDT switching

Both idle and HVM vCPU-s can easily run on the GDT mapped into general
hypervisor space (rather than that placed in per-vCPU virtual space).

This makes unnecessary some of the additions c/s 18520 did.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
 xen/arch/x86/cpu/common.c   |    9 +++++----
 xen/arch/x86/domain.c       |   44 ++++++++++++++++++++++++--------------------
 xen/arch/x86/domain_build.c |   34 ++++++----------------------------
 xen/arch/x86/hvm/vmx/vmcs.c |    5 ++---
 xen/arch/x86/setup.c        |    8 +-------
 xen/arch/x86/smpboot.c      |   17 +++++------------
 xen/arch/x86/x86_32/mm.c    |   24 ------------------------
 xen/arch/x86/x86_64/mm.c    |   19 -------------------
 xen/include/asm-x86/page.h  |    1 -
 9 files changed, 43 insertions(+), 118 deletions(-)

diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/arch/x86/cpu/common.c
--- a/xen/arch/x86/cpu/common.c Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/arch/x86/cpu/common.c Wed Nov 12 12:01:35 2008 +0000
@@ -564,7 +564,10 @@ void __cpuinit cpu_init(void)
 {
        int cpu = smp_processor_id();
        struct tss_struct *t = &init_tss[cpu];
-       char gdt_load[10];
+       struct desc_ptr gdt_desc = {
+               .base = (unsigned long)(this_cpu(gdt_table) - 
FIRST_RESERVED_GDT_ENTRY),
+               .limit = LAST_RESERVED_GDT_BYTE
+       };
 
        if (cpu_test_and_set(cpu, cpu_initialized)) {
                printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
@@ -578,9 +581,7 @@ void __cpuinit cpu_init(void)
        /* Install correct page table. */
        write_ptbase(current);
 
-       *(unsigned short *)(&gdt_load[0]) = LAST_RESERVED_GDT_BYTE;
-       *(unsigned long  *)(&gdt_load[2]) = GDT_VIRT_START(current);
-       asm volatile ( "lgdt %0" : "=m" (gdt_load) );
+       asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
 
        /* No nested task. */
        asm volatile ("pushf ; andw $0xbfff,(%"__OP"sp) ; popf" );
diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/arch/x86/domain.c     Wed Nov 12 12:01:35 2008 +0000
@@ -310,12 +310,7 @@ int vcpu_initialise(struct vcpu *v)
         if ( is_idle_domain(d) )
         {
             v->arch.schedule_tail = continue_idle_domain;
-            if ( v->vcpu_id )
-                v->arch.cr3 = d->vcpu[0]->arch.cr3;
-            else if ( !*idle_vcpu )
-                v->arch.cr3 = __pa(idle_pg_table);
-            else if ( !(v->arch.cr3 = clone_idle_pagetable(v)) )
-                return -ENOMEM;
+            v->arch.cr3           = __pa(idle_pg_table);
         }
 
         v->arch.guest_context.ctrlreg[4] =
@@ -1172,14 +1167,18 @@ static void paravirt_ctxt_switch_to(stru
     }
 }
 
+static inline int need_full_gdt(struct vcpu *v)
+{
+    return (!is_hvm_vcpu(v) && !is_idle_vcpu(v));
+}
+
 static void __context_switch(void)
 {
     struct cpu_user_regs *stack_regs = guest_cpu_user_regs();
-    unsigned int          i, cpu = smp_processor_id();
+    unsigned int          cpu = smp_processor_id();
     struct vcpu          *p = per_cpu(curr_vcpu, cpu);
     struct vcpu          *n = current;
     struct desc_struct   *gdt;
-    struct page_info     *page;
     struct desc_ptr       gdt_desc;
 
     ASSERT(p != n);
@@ -1208,16 +1207,19 @@ static void __context_switch(void)
 
     gdt = !is_pv_32on64_vcpu(n) ? per_cpu(gdt_table, cpu) :
                                   per_cpu(compat_gdt_table, cpu);
-    page = virt_to_page(gdt);
-    for (i = 0; i < NR_RESERVED_GDT_PAGES; ++i)
-    {
-        l1e_write(n->domain->arch.mm_perdomain_pt +
-                  (n->vcpu_id << GDT_LDT_VCPU_SHIFT) +
-                  FIRST_RESERVED_GDT_PAGE + i,
-                  l1e_from_page(page + i, __PAGE_HYPERVISOR));
-    }
-
-    if ( p->vcpu_id != n->vcpu_id )
+    if ( need_full_gdt(n) )
+    {
+        struct page_info *page = virt_to_page(gdt);
+        unsigned int i;
+        for ( i = 0; i < NR_RESERVED_GDT_PAGES; i++ )
+            l1e_write(n->domain->arch.mm_perdomain_pt +
+                      (n->vcpu_id << GDT_LDT_VCPU_SHIFT) +
+                      FIRST_RESERVED_GDT_PAGE + i,
+                      l1e_from_page(page + i, __PAGE_HYPERVISOR));
+    }
+
+    if ( need_full_gdt(p) &&
+         ((p->vcpu_id != n->vcpu_id) || !need_full_gdt(n)) )
     {
         gdt_desc.limit = LAST_RESERVED_GDT_BYTE;
         gdt_desc.base  = (unsigned long)(gdt - FIRST_RESERVED_GDT_ENTRY);
@@ -1226,8 +1228,10 @@ static void __context_switch(void)
 
     write_ptbase(n);
 
-    if ( p->vcpu_id != n->vcpu_id )
-    {
+    if ( need_full_gdt(n) &&
+         ((p->vcpu_id != n->vcpu_id) || !need_full_gdt(p)) )
+    {
+        gdt_desc.limit = LAST_RESERVED_GDT_BYTE;
         gdt_desc.base = GDT_VIRT_START(n);
         asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
     }
diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/arch/x86/domain_build.c       Wed Nov 12 12:01:35 2008 +0000
@@ -194,30 +194,6 @@ static void __init process_dom0_ioports_
     }
 }
 
-/* We run on dom0's page tables for the final part of the build process. */
-static void dom0_pt_enter(struct vcpu *v)
-{
-    struct desc_ptr gdt_desc = {
-        .limit = LAST_RESERVED_GDT_BYTE,
-        .base = (unsigned long)(this_cpu(gdt_table) - FIRST_RESERVED_GDT_ENTRY)
-    };
-
-    asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
-    write_ptbase(v);
-}
-
-/* Return to idle domain's page tables. */
-static void dom0_pt_exit(void)
-{
-    struct desc_ptr gdt_desc = {
-        .limit = LAST_RESERVED_GDT_BYTE,
-        .base = GDT_VIRT_START(current)
-    };
-
-    write_ptbase(current);
-    asm volatile ( "lgdt %0" : : "m" (gdt_desc) );
-}
-
 int __init construct_dom0(
     struct domain *d,
     unsigned long _image_start, unsigned long image_len, 
@@ -729,7 +705,8 @@ int __init construct_dom0(
     else
         update_cr3(v);
 
-    dom0_pt_enter(v);
+    /* We run on dom0's page tables for the final part of the build process. */
+    write_ptbase(v);
 
     /* Copy the OS image and free temporary buffer. */
     elf.dest = (void*)vkern_start;
@@ -741,11 +718,11 @@ int __init construct_dom0(
              (parms.virt_hypercall >= v_end) )
         {
             write_ptbase(current);
-            local_irq_enable();
             printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
             return -1;
         }
-        hypercall_page_initialise(d, (void *)(unsigned 
long)parms.virt_hypercall);
+        hypercall_page_initialise(
+            d, (void *)(unsigned long)parms.virt_hypercall);
     }
 
     /* Copy the initial ramdisk. */
@@ -826,7 +803,8 @@ int __init construct_dom0(
         xlat_start_info(si, XLAT_start_info_console_dom0);
 #endif
 
-    dom0_pt_exit();
+    /* Return to idle domain's page tables. */
+    write_ptbase(current);
 
 #if defined(__i386__)
     /* Destroy low mappings - they were only for our convenience. */
diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Wed Nov 12 12:01:35 2008 +0000
@@ -444,6 +444,8 @@ static void vmx_set_host_env(struct vcpu
 {
     unsigned int cpu = smp_processor_id();
 
+    __vmwrite(HOST_GDTR_BASE,
+              (unsigned long)(this_cpu(gdt_table) - FIRST_RESERVED_GDT_ENTRY));
     __vmwrite(HOST_IDTR_BASE, (unsigned long)idt_tables[cpu]);
 
     __vmwrite(HOST_TR_SELECTOR, TSS_ENTRY << 3);
@@ -540,9 +542,6 @@ static int construct_vmcs(struct vcpu *v
     /* I/O access bitmap. */
     __vmwrite(IO_BITMAP_A, virt_to_maddr((char *)hvm_io_bitmap + 0));
     __vmwrite(IO_BITMAP_B, virt_to_maddr((char *)hvm_io_bitmap + PAGE_SIZE));
-
-    /* Host GDTR base. */
-    __vmwrite(HOST_GDTR_BASE, GDT_VIRT_START(v));
 
     /* Host data selectors. */
     __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/arch/x86/setup.c      Wed Nov 12 12:01:35 2008 +0000
@@ -230,7 +230,6 @@ static void __init init_idle_domain(void
 static void __init init_idle_domain(void)
 {
     struct domain *idle_domain;
-    unsigned int i;
 
     /* Domain creation requires that scheduler structures are initialised. */
     scheduler_init();
@@ -243,12 +242,6 @@ static void __init init_idle_domain(void
     idle_vcpu[0] = this_cpu(curr_vcpu) = current;
 
     setup_idle_pagetable();
-
-    for (i = 0; i < NR_RESERVED_GDT_PAGES; ++i)
-        idle_domain->arch.mm_perdomain_pt[FIRST_RESERVED_GDT_PAGE + i] =
-            l1e_from_page(virt_to_page(boot_cpu_gdt_table) + i,
-                          __PAGE_HYPERVISOR);
-
 }
 
 static void __init srat_detect_node(int cpu)
@@ -456,6 +449,7 @@ void __init __start_xen(unsigned long mb
     parse_video_info();
 
     set_current((struct vcpu *)0xfffff000); /* debug sanity */
+    idle_vcpu[0] = current;
     set_processor_id(0); /* needed early, for smp_processor_id() */
     if ( cpu_has_efer )
         rdmsrl(MSR_EFER, this_cpu(efer));
diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/arch/x86/smpboot.c    Wed Nov 12 12:01:35 2008 +0000
@@ -821,7 +821,7 @@ static int __devinit do_boot_cpu(int api
  */
 {
        unsigned long boot_error;
-       unsigned int i;
+       unsigned int order;
        int timeout;
        unsigned long start_eip;
        unsigned short nmi_high = 0, nmi_low = 0;
@@ -857,34 +857,27 @@ static int __devinit do_boot_cpu(int api
 
        gdt = per_cpu(gdt_table, cpu);
        if (gdt == boot_cpu_gdt_table) {
-               i = get_order_from_pages(NR_RESERVED_GDT_PAGES);
+               order = get_order_from_pages(NR_RESERVED_GDT_PAGES);
 #ifdef __x86_64__
 #ifdef CONFIG_COMPAT
-               page = alloc_domheap_pages(NULL, i,
+               page = alloc_domheap_pages(NULL, order,
                                           MEMF_node(cpu_to_node(cpu)));
                per_cpu(compat_gdt_table, cpu) = gdt = page_to_virt(page);
                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
-               page = alloc_domheap_pages(NULL, i,
+               page = alloc_domheap_pages(NULL, order,
                                           MEMF_node(cpu_to_node(cpu)));
                per_cpu(gdt_table, cpu) = gdt = page_to_virt(page);
 #else
-               per_cpu(gdt_table, cpu) = gdt = alloc_xenheap_pages(i);
+               per_cpu(gdt_table, cpu) = gdt = alloc_xenheap_pages(order);
 #endif
                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;
        }
-
-       for (i = 0; i < NR_RESERVED_GDT_PAGES; ++i)
-               v->domain->arch.mm_perdomain_pt
-                       [(v->vcpu_id << GDT_LDT_VCPU_SHIFT) +
-                        FIRST_RESERVED_GDT_PAGE + i]
-                       = l1e_from_page(virt_to_page(gdt) + i,
-                                       __PAGE_HYPERVISOR);
 
 #ifdef __i386__
        if (!per_cpu(doublefault_tss, cpu)) {
diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/arch/x86/x86_32/mm.c  Wed Nov 12 12:01:35 2008 +0000
@@ -132,30 +132,6 @@ void __init setup_idle_pagetable(void)
                                 __PAGE_HYPERVISOR));
 }
 
-unsigned long clone_idle_pagetable(struct vcpu *v)
-{
-    unsigned int i;
-    struct domain *d = v->domain;
-    l3_pgentry_t *l3_table = v->arch.pae_l3_cache.table[0];
-    l2_pgentry_t *l2_table = alloc_xenheap_page();
-
-    if ( !l2_table )
-        return 0;
-
-    memcpy(l3_table, idle_pg_table, L3_PAGETABLE_ENTRIES * sizeof(*l3_table));
-    l3_table[l3_table_offset(PERDOMAIN_VIRT_START)] =
-        l3e_from_page(virt_to_page(l2_table), _PAGE_PRESENT);
-
-    copy_page(l2_table, idle_pg_table_l2 +
-              l3_table_offset(PERDOMAIN_VIRT_START) * L2_PAGETABLE_ENTRIES);
-    for ( i = 0; i < PDPT_L2_ENTRIES; ++i )
-        l2_table[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
-            l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
-                          __PAGE_HYPERVISOR);
-
-    return __pa(l3_table);
-}
-
 void __init zap_low_mappings(l2_pgentry_t *dom0_l2)
 {
     int i;
diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/arch/x86/x86_64/mm.c  Wed Nov 12 12:01:35 2008 +0000
@@ -21,7 +21,6 @@
 #include <xen/lib.h>
 #include <xen/init.h>
 #include <xen/mm.h>
-#include <xen/numa.h>
 #include <xen/sched.h>
 #include <xen/guest_access.h>
 #include <asm/current.h>
@@ -207,24 +206,6 @@ void __init setup_idle_pagetable(void)
                   __PAGE_HYPERVISOR));
 }
 
-unsigned long clone_idle_pagetable(struct vcpu *v)
-{
-    struct domain *d = v->domain;
-    struct page_info *page = alloc_domheap_page(NULL,
-                                                MEMF_node(vcpu_to_node(v)));
-    l4_pgentry_t *l4_table = page_to_virt(page);
-
-    if ( !page )
-        return 0;
-
-    copy_page(l4_table, idle_pg_table);
-    l4_table[l4_table_offset(PERDOMAIN_VIRT_START)] =
-        l4e_from_page(virt_to_page(d->arch.mm_perdomain_l3),
-                      __PAGE_HYPERVISOR);
-
-    return __pa(l4_table);
-}
-
 void __init zap_low_mappings(void)
 {
     BUG_ON(num_online_cpus() != 1);
diff -r 2bd99c5faa42 -r 8e18dd41c6c7 xen/include/asm-x86/page.h
--- a/xen/include/asm-x86/page.h        Wed Nov 12 11:50:25 2008 +0000
+++ b/xen/include/asm-x86/page.h        Wed Nov 12 12:01:35 2008 +0000
@@ -278,7 +278,6 @@ extern unsigned int   m2p_compat_vstart;
 #endif
 void paging_init(void);
 void setup_idle_pagetable(void);
-unsigned long clone_idle_pagetable(struct vcpu *);
 #endif /* !defined(__ASSEMBLY__) */
 
 #define _PAGE_PRESENT  0x001U

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: reduce GDT switching, Xen patchbot-unstable <=