[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Merged.



# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 8f722ac17efa4ba84eb6c678c7f33dab82fceb3e
# Parent  1577043d8e362633f94b30e3c267aaeaec71be88
# Parent  bddcfe70fbef16ff1d2391c41943853245627c4a
Merged.

diff -r 1577043d8e36 -r 8f722ac17efa 
linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Thu Mar 23 16:27:48 2006
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Thu Mar 23 16:37:37 2006
@@ -32,13 +32,13 @@
 #endif
 
 static int direct_remap_area_pte_fn(pte_t *pte, 
-                                   struct page *pte_page,
+                                   struct page *pmd_page,
                                    unsigned long address, 
                                    void *data)
 {
        mmu_update_t **v = (mmu_update_t **)data;
 
-       (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pte_page)) <<
+       (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
                     PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
        (*v)++;
 
@@ -67,9 +67,9 @@
        for (i = 0; i < size; i += PAGE_SIZE) {
                if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
                        /* Fill in the PTE pointers. */
-                       rc = generic_page_range(mm, start_address, 
-                                               address - start_address,
-                                               direct_remap_area_pte_fn, &w);
+                       rc = apply_to_page_range(mm, start_address, 
+                                                address - start_address,
+                                                direct_remap_area_pte_fn, &w);
                        if (rc)
                                goto out;
                        w = u;
@@ -93,8 +93,9 @@
 
        if (v != u) {
                /* get the ptep's filled in */
-               rc = generic_page_range(mm, start_address, address - 
start_address,
-                                  direct_remap_area_pte_fn, &w);
+               rc = apply_to_page_range(mm, start_address,
+                                        address - start_address,
+                                        direct_remap_area_pte_fn, &w);
                if (rc)
                        goto out;
                rc = -EFAULT;
@@ -142,11 +143,11 @@
 EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
 
 static int lookup_pte_fn(
-       pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+       pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 {
        uint64_t *ptep = (uint64_t *)data;
        if (ptep)
-               *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pte_page)) <<
+               *ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
                         PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
        return 0;
 }
@@ -155,13 +156,14 @@
                           unsigned long address,
                           uint64_t *ptep)
 {
-       return generic_page_range(mm, address, PAGE_SIZE, lookup_pte_fn, ptep);
+       return apply_to_page_range(mm, address, PAGE_SIZE,
+                                  lookup_pte_fn, ptep);
 }
 
 EXPORT_SYMBOL(create_lookup_pte_addr);
 
 static int noop_fn(
-       pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+       pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 {
        return 0;
 }
@@ -170,7 +172,7 @@
                    unsigned long address,
                    unsigned long size)
 {
-       return generic_page_range(mm, address, size, noop_fn, NULL);
+       return apply_to_page_range(mm, address, size, noop_fn, NULL);
 } 
 
 EXPORT_SYMBOL(touch_pte_range);
diff -r 1577043d8e36 -r 8f722ac17efa 
linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c        Thu Mar 23 
16:27:48 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/apic-xen.c        Thu Mar 23 
16:37:37 2006
@@ -114,8 +114,6 @@
        irq_exit();
 }
 
-int __initdata unsync_tsc_on_multicluster;
-
 /*
  * This interrupt should _never_ happen with our APIC/SMP architecture
  */
diff -r 1577043d8e36 -r 8f722ac17efa 
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
--- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Thu Mar 23 
16:27:48 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c        Thu Mar 23 
16:37:37 2006
@@ -517,7 +517,7 @@
 }
 
 static int dealloc_pte_fn(
-       pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+       pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 {
        unsigned long mfn = pte_mfn(*pte);
        int ret;
@@ -547,8 +547,8 @@
        scrub_pages(vstart, 1 << order);
 
        balloon_lock(flags);
-       ret = generic_page_range(
-               &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL);
+       ret = apply_to_page_range(&init_mm, vstart,
+                                 PAGE_SIZE << order, dealloc_pte_fn, NULL);
        BUG_ON(ret);
        current_pages -= 1UL << order;
        totalram_pages = current_pages;
diff -r 1577043d8e36 -r 8f722ac17efa 
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Thu Mar 23 16:27:48 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c    Thu Mar 23 16:37:37 2006
@@ -360,7 +360,7 @@
 }
 
 #ifndef __ia64__
-static int map_pte_fn(pte_t *pte, struct page *pte_page,
+static int map_pte_fn(pte_t *pte, struct page *pmd_page,
                      unsigned long addr, void *data)
 {
        unsigned long **frames = (unsigned long **)data;
@@ -370,7 +370,7 @@
        return 0;
 }
 
-static int unmap_pte_fn(pte_t *pte, struct page *pte_page,
+static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
                      unsigned long addr, void *data)
 {
 
@@ -384,6 +384,7 @@
 {
        gnttab_setup_table_t setup;
        unsigned long frames[NR_GRANT_FRAMES];
+       int rc;
 #ifndef __ia64__
        void *pframes = frames;
        struct vm_struct *area;
@@ -393,8 +394,8 @@
        setup.nr_frames  = NR_GRANT_FRAMES;
        setup.frame_list = frames;
 
-       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
-       BUG_ON(setup.status != 0);
+       rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+       BUG_ON(rc || setup.status);
 
 #ifndef __ia64__
        if (shared == NULL) {
@@ -402,9 +403,10 @@
                BUG_ON(area == NULL);
                shared = area->addr;
        }
-       BUG_ON(generic_page_range(&init_mm, (unsigned long)shared,
-                                 PAGE_SIZE * NR_GRANT_FRAMES,
-                                 map_pte_fn, &pframes));
+       rc = apply_to_page_range(&init_mm, (unsigned long)shared,
+                                PAGE_SIZE * NR_GRANT_FRAMES,
+                                map_pte_fn, &pframes);
+       BUG_ON(rc);
 #else
        shared = __va(frames[0] << PAGE_SHIFT);
        printk("grant table at %p\n", shared);
@@ -418,9 +420,9 @@
 {
 
 #ifndef __ia64__
-       generic_page_range(&init_mm, (unsigned long)shared,
-                          PAGE_SIZE * NR_GRANT_FRAMES,
-                          unmap_pte_fn, NULL);
+       apply_to_page_range(&init_mm, (unsigned long)shared,
+                           PAGE_SIZE * NR_GRANT_FRAMES,
+                           unmap_pte_fn, NULL);
 #endif
 
        return 0;
diff -r 1577043d8e36 -r 8f722ac17efa linux-2.6-xen-sparse/drivers/xen/util.c
--- a/linux-2.6-xen-sparse/drivers/xen/util.c   Thu Mar 23 16:27:48 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/util.c   Thu Mar 23 16:37:37 2006
@@ -6,9 +6,9 @@
 #include <asm/uaccess.h>
 #include <xen/driver_util.h>
 
-static int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+static int f(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
 {
-       /* generic_page_range() does all the hard work. */
+       /* apply_to_page_range() does all the hard work. */
        return 0;
 }
 
@@ -24,8 +24,8 @@
         * This ensures that page tables are constructed for this region
         * of kernel virtual address space and mapped into init_mm.
         */
-       if (generic_page_range(&init_mm, (unsigned long)area->addr,
-                              area->size, f, NULL)) {
+       if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
+                               area->size, f, NULL)) {
                free_vm_area(area);
                return NULL;
        }
diff -r 1577043d8e36 -r 8f722ac17efa linux-2.6-xen-sparse/include/linux/mm.h
--- a/linux-2.6-xen-sparse/include/linux/mm.h   Thu Mar 23 16:27:48 2006
+++ b/linux-2.6-xen-sparse/include/linux/mm.h   Thu Mar 23 16:37:37 2006
@@ -1020,10 +1020,10 @@
 #define FOLL_ANON      0x08    /* give ZERO_PAGE if no pgtable */
 
 #ifdef CONFIG_XEN
-typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr,
-                        void *data);
-extern int generic_page_range(struct mm_struct *mm, unsigned long address,
-                              unsigned long size, pte_fn_t fn, void *data);
+typedef int (*pte_fn_t)(pte_t *pte, struct page *pmd_page, unsigned long addr,
+                       void *data);
+extern int apply_to_page_range(struct mm_struct *mm, unsigned long address,
+                              unsigned long size, pte_fn_t fn, void *data);
 #endif
 
 #ifdef CONFIG_PROC_FS
diff -r 1577043d8e36 -r 8f722ac17efa linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c  Thu Mar 23 16:27:48 2006
+++ b/linux-2.6-xen-sparse/mm/memory.c  Thu Mar 23 16:37:37 2006
@@ -1378,36 +1378,39 @@
 EXPORT_SYMBOL(remap_pfn_range);
 
 #ifdef CONFIG_XEN
-static inline int generic_pte_range(struct mm_struct *mm, pmd_t *pmd,
-                                   unsigned long addr, unsigned long end,
-                                   pte_fn_t fn, void *data)
+static inline int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
+                                    unsigned long addr, unsigned long end,
+                                    pte_fn_t fn, void *data)
 {
        pte_t *pte;
        int err;
-       struct page *pte_page;
+       struct page *pmd_page;
+       spinlock_t *ptl;
 
        pte = (mm == &init_mm) ?
                pte_alloc_kernel(pmd, addr) :
-               pte_alloc_map(mm, pmd, addr);
+               pte_alloc_map_lock(mm, pmd, addr, &ptl);
        if (!pte)
                return -ENOMEM;
 
-       pte_page = pmd_page(*pmd);
+       BUG_ON(pmd_huge(*pmd));
+
+       pmd_page = pmd_page(*pmd);
 
        do {
-               err = fn(pte, pte_page, addr, data);
+               err = fn(pte, pmd_page, addr, data);
                if (err)
                        break;
        } while (pte++, addr += PAGE_SIZE, addr != end);
 
        if (mm != &init_mm)
-               pte_unmap(pte-1);
+               pte_unmap_unlock(pte-1, ptl);
        return err;
 }
 
-static inline int generic_pmd_range(struct mm_struct *mm, pud_t *pud,
-                                   unsigned long addr, unsigned long end,
-                                   pte_fn_t fn, void *data)
+static inline int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
+                                    unsigned long addr, unsigned long end,
+                                    pte_fn_t fn, void *data)
 {
        pmd_t *pmd;
        unsigned long next;
@@ -1418,16 +1421,16 @@
                return -ENOMEM;
        do {
                next = pmd_addr_end(addr, end);
-               err = generic_pte_range(mm, pmd, addr, next, fn, data);
+               err = apply_to_pte_range(mm, pmd, addr, next, fn, data);
                if (err)
                        break;
        } while (pmd++, addr = next, addr != end);
        return err;
 }
 
-static inline int generic_pud_range(struct mm_struct *mm, pgd_t *pgd,
-                                   unsigned long addr, unsigned long end,
-                                   pte_fn_t fn, void *data)
+static inline int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd,
+                                    unsigned long addr, unsigned long end,
+                                    pte_fn_t fn, void *data)
 {
        pud_t *pud;
        unsigned long next;
@@ -1438,7 +1441,7 @@
                return -ENOMEM;
        do {
                next = pud_addr_end(addr, end);
-               err = generic_pmd_range(mm, pud, addr, next, fn, data);
+               err = apply_to_pmd_range(mm, pud, addr, next, fn, data);
                if (err)
                        break;
        } while (pud++, addr = next, addr != end);
@@ -1449,8 +1452,8 @@
  * Scan a region of virtual memory, filling in page tables as necessary
  * and calling a provided function on each leaf page table.
  */
-int generic_page_range(struct mm_struct *mm, unsigned long addr,
-                      unsigned long size, pte_fn_t fn, void *data)
+int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
+                       unsigned long size, pte_fn_t fn, void *data)
 {
        pgd_t *pgd;
        unsigned long next;
@@ -1461,12 +1464,13 @@
        pgd = pgd_offset(mm, addr);
        do {
                next = pgd_addr_end(addr, end);
-               err = generic_pud_range(mm, pgd, addr, next, fn, data);
+               err = apply_to_pud_range(mm, pgd, addr, next, fn, data);
                if (err)
                        break;
        } while (pgd++, addr = next, addr != end);
        return err;
 }
+EXPORT_SYMBOL_GPL(apply_to_page_range);
 #endif
 
 /*
diff -r 1577043d8e36 -r 8f722ac17efa xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Thu Mar 23 16:27:48 2006
+++ b/xen/arch/x86/dom0_ops.c   Thu Mar 23 16:37:37 2006
@@ -460,8 +460,7 @@
 
     if ( hvm_guest(v) )
     {
-        hvm_store_cpu_guest_regs(v, &c->user_regs);
-        hvm_store_cpu_guest_ctrl_regs(v, c->ctrlreg);
+        hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg);
     }
     else
     {
diff -r 1577043d8e36 -r 8f722ac17efa xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Thu Mar 23 16:27:48 2006
+++ b/xen/arch/x86/hvm/platform.c       Thu Mar 23 16:37:37 2006
@@ -773,7 +773,7 @@
     mmio_opp = &v->arch.hvm_vcpu.mmio_op;
 
     regs = mmio_opp->inst_decoder_regs;
-    hvm_store_cpu_guest_regs(v, regs);
+    hvm_store_cpu_guest_regs(v, regs, NULL);
 
     if ((inst_len = hvm_instruction_length(v)) <= 0) {
         printf("handle_mmio: failed to get instruction length\n");
diff -r 1577043d8e36 -r 8f722ac17efa xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Thu Mar 23 16:27:48 2006
+++ b/xen/arch/x86/hvm/svm/svm.c        Thu Mar 23 16:37:37 2006
@@ -201,31 +201,41 @@
 }
 
 static void svm_store_cpu_guest_regs(
-    struct vcpu *v, struct cpu_user_regs *regs)
+    struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
 
+    if ( regs != NULL )
+    {
 #if defined (__x86_64__)
-    regs->rip    = vmcb->rip;
-    regs->rsp    = vmcb->rsp;
-    regs->rflags = vmcb->rflags;
-    regs->cs     = vmcb->cs.sel;
-    regs->ds     = vmcb->ds.sel;
-    regs->es     = vmcb->es.sel;
-    regs->ss     = vmcb->ss.sel;
-    regs->gs     = vmcb->gs.sel;
-    regs->fs     = vmcb->fs.sel;
+        regs->rip    = vmcb->rip;
+        regs->rsp    = vmcb->rsp;
+        regs->rflags = vmcb->rflags;
+        regs->cs     = vmcb->cs.sel;
+        regs->ds     = vmcb->ds.sel;
+        regs->es     = vmcb->es.sel;
+        regs->ss     = vmcb->ss.sel;
+        regs->gs     = vmcb->gs.sel;
+        regs->fs     = vmcb->fs.sel;
 #elif defined (__i386__)
-    regs->eip    = vmcb->rip;
-    regs->esp    = vmcb->rsp;
-    regs->eflags = vmcb->rflags;
-    regs->cs     = vmcb->cs.sel;
-    regs->ds     = vmcb->ds.sel;
-    regs->es     = vmcb->es.sel;
-    regs->ss     = vmcb->ss.sel;
-    regs->gs     = vmcb->gs.sel;
-    regs->fs     = vmcb->fs.sel;
+        regs->eip    = vmcb->rip;
+        regs->esp    = vmcb->rsp;
+        regs->eflags = vmcb->rflags;
+        regs->cs     = vmcb->cs.sel;
+        regs->ds     = vmcb->ds.sel;
+        regs->es     = vmcb->es.sel;
+        regs->ss     = vmcb->ss.sel;
+        regs->gs     = vmcb->gs.sel;
+        regs->fs     = vmcb->fs.sel;
 #endif
+    }
+
+    if ( crs != NULL )
+    {
+        crs[0] = vmcb->cr0;
+        crs[3] = vmcb->cr3;
+        crs[4] = vmcb->cr4;
+    }
 }
 
 static void svm_load_cpu_guest_regs(
@@ -372,15 +382,6 @@
     return 1;
 }
 
-void svm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    crs[0] = vmcb->cr0;
-    crs[3] = vmcb->cr3;
-    crs[4] = vmcb->cr4;
-}
-
 void svm_modify_guest_state(struct vcpu *v)
 {
     svm_modify_vmcb(v, &v->arch.guest_context.user_regs);
@@ -448,7 +449,6 @@
     hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
     hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
 
-    hvm_funcs.store_cpu_guest_ctrl_regs = svm_store_cpu_guest_ctrl_regs;
     hvm_funcs.modify_guest_state = svm_modify_guest_state;
 
     hvm_funcs.realmode = svm_realmode;
diff -r 1577043d8e36 -r 8f722ac17efa xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Thu Mar 23 16:27:48 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Thu Mar 23 16:37:37 2006
@@ -398,31 +398,81 @@
         migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
 }
 
-void vmx_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
-{
+struct vmx_store_cpu_guest_regs_callback_info {
+    struct vcpu *v;
+    struct cpu_user_regs *regs;
+    unsigned long *crs;
+};
+
+static void vmx_store_cpu_guest_regs(
+    struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs);
+
+static void vmx_store_cpu_guest_regs_callback(void *data)
+{
+    struct vmx_store_cpu_guest_regs_callback_info *info = data;
+    vmx_store_cpu_guest_regs(info->v, info->regs, info->crs);
+}
+
+static void vmx_store_cpu_guest_regs(
+    struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
+{
+    if ( v != current )
+    {
+        /* Non-current VCPUs must be paused to get a register snapshot. */
+        ASSERT(atomic_read(&v->pausecnt) != 0);
+
+        if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
+        {
+            /* Get register details from remote CPU. */
+            struct vmx_store_cpu_guest_regs_callback_info info = {
+                .v = v, .regs = regs, .crs = crs };
+            cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
+            on_selected_cpus(cpumask, vmx_store_cpu_guest_regs_callback,
+                             &info, 1, 1);
+            return;
+        }
+
+        /* Register details are on this CPU. Load the correct VMCS. */
+        __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+    }
+
+    ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());
+
+    if ( regs != NULL )
+    {
 #if defined (__x86_64__)
-    __vmread(GUEST_RFLAGS, &regs->rflags);
-    __vmread(GUEST_SS_SELECTOR, &regs->ss);
-    __vmread(GUEST_CS_SELECTOR, &regs->cs);
-    __vmread(GUEST_DS_SELECTOR, &regs->ds);
-    __vmread(GUEST_ES_SELECTOR, &regs->es);
-    __vmread(GUEST_GS_SELECTOR, &regs->gs);
-    __vmread(GUEST_FS_SELECTOR, &regs->fs);
-    __vmread(GUEST_RIP, &regs->rip);
-    __vmread(GUEST_RSP, &regs->rsp);
+        __vmread(GUEST_RFLAGS, &regs->rflags);
+        __vmread(GUEST_SS_SELECTOR, &regs->ss);
+        __vmread(GUEST_CS_SELECTOR, &regs->cs);
+        __vmread(GUEST_DS_SELECTOR, &regs->ds);
+        __vmread(GUEST_ES_SELECTOR, &regs->es);
+        __vmread(GUEST_GS_SELECTOR, &regs->gs);
+        __vmread(GUEST_FS_SELECTOR, &regs->fs);
+        __vmread(GUEST_RIP, &regs->rip);
+        __vmread(GUEST_RSP, &regs->rsp);
 #elif defined (__i386__)
-    __vmread(GUEST_RFLAGS, &regs->eflags);
-    __vmread(GUEST_SS_SELECTOR, &regs->ss);
-    __vmread(GUEST_CS_SELECTOR, &regs->cs);
-    __vmread(GUEST_DS_SELECTOR, &regs->ds);
-    __vmread(GUEST_ES_SELECTOR, &regs->es);
-    __vmread(GUEST_GS_SELECTOR, &regs->gs);
-    __vmread(GUEST_FS_SELECTOR, &regs->fs);
-    __vmread(GUEST_RIP, &regs->eip);
-    __vmread(GUEST_RSP, &regs->esp);
-#else
-#error Unsupported architecture
+        __vmread(GUEST_RFLAGS, &regs->eflags);
+        __vmread(GUEST_SS_SELECTOR, &regs->ss);
+        __vmread(GUEST_CS_SELECTOR, &regs->cs);
+        __vmread(GUEST_DS_SELECTOR, &regs->ds);
+        __vmread(GUEST_ES_SELECTOR, &regs->es);
+        __vmread(GUEST_GS_SELECTOR, &regs->gs);
+        __vmread(GUEST_FS_SELECTOR, &regs->fs);
+        __vmread(GUEST_RIP, &regs->eip);
+        __vmread(GUEST_RSP, &regs->esp);
 #endif
+    }
+
+    if ( crs != NULL )
+    {
+        __vmread(CR0_READ_SHADOW, &crs[0]);
+        __vmread(GUEST_CR3, &crs[3]);
+        __vmread(CR4_READ_SHADOW, &crs[4]);
+    }
+
+    /* Reload current VCPU's VMCS if it was temporarily unloaded. */
+    if ( (v != current) && hvm_guest(current) )
+        __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
 }
 
 void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
@@ -454,13 +504,6 @@
 #else
 #error Unsupported architecture
 #endif
-}
-
-void vmx_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
-    __vmread(CR0_READ_SHADOW, &crs[0]);
-    __vmread(GUEST_CR3, &crs[3]);
-    __vmread(CR4_READ_SHADOW, &crs[4]);
 }
 
 void vmx_modify_guest_state(struct vcpu *v)
@@ -616,7 +659,6 @@
     hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
     hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
 
-    hvm_funcs.store_cpu_guest_ctrl_regs = vmx_store_cpu_guest_ctrl_regs;
     hvm_funcs.modify_guest_state = vmx_modify_guest_state;
 
     hvm_funcs.realmode = vmx_realmode;
diff -r 1577043d8e36 -r 8f722ac17efa xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Thu Mar 23 16:27:48 2006
+++ b/xen/arch/x86/x86_32/traps.c       Thu Mar 23 16:37:37 2006
@@ -27,8 +27,7 @@
     if ( hvm_guest(current) && guest_mode(regs) )
     {
         context = "hvm";
-        hvm_store_cpu_guest_regs(current, &fault_regs);
-        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
+        hvm_store_cpu_guest_regs(current, &fault_regs, fault_crs);
     }
     else
     {
diff -r 1577043d8e36 -r 8f722ac17efa xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Thu Mar 23 16:27:48 2006
+++ b/xen/arch/x86/x86_64/traps.c       Thu Mar 23 16:37:37 2006
@@ -27,8 +27,7 @@
     if ( hvm_guest(current) && guest_mode(regs) )
     {
         context = "hvm";
-        hvm_store_cpu_guest_regs(current, &fault_regs);
-        hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
+        hvm_store_cpu_guest_regs(current, &fault_regs, fault_crs);
     }
     else
     {
diff -r 1577043d8e36 -r 8f722ac17efa xen/common/gdbstub.c
--- a/xen/common/gdbstub.c      Thu Mar 23 16:27:48 2006
+++ b/xen/common/gdbstub.c      Thu Mar 23 16:37:37 2006
@@ -562,6 +562,7 @@
     gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
     if ( gdb_ctx->serhnd != -1 )
         printk("GDB stub initialised.\n");
+    serial_start_sync(gdb_ctx->serhnd);
 }
 
 /*
diff -r 1577043d8e36 -r 8f722ac17efa xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Thu Mar 23 16:27:48 2006
+++ b/xen/drivers/char/ns16550.c        Thu Mar 23 16:37:37 2006
@@ -121,8 +121,11 @@
 
     while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) )
     {
-        serial_tx_interrupt(port, regs);
-        serial_rx_interrupt(port, regs);
+        char lsr = ns_read_reg(uart, LSR);
+        if ( lsr & LSR_THRE )
+            serial_tx_interrupt(port, regs);
+        if ( lsr & LSR_DR )
+            serial_rx_interrupt(port, regs);
     }
 }
 
diff -r 1577043d8e36 -r 8f722ac17efa xen/drivers/char/serial.c
--- a/xen/drivers/char/serial.c Thu Mar 23 16:27:48 2006
+++ b/xen/drivers/char/serial.c Thu Mar 23 16:37:37 2006
@@ -7,6 +7,7 @@
  */
 
 #include <xen/config.h>
+#include <xen/delay.h>
 #include <xen/init.h>
 #include <xen/irq.h>
 #include <xen/keyhandler.h> 
@@ -15,8 +16,8 @@
 #include <xen/serial.h>
 
 static struct serial_port com[2] = {
-    { .lock = SPIN_LOCK_UNLOCKED }, 
-    { .lock = SPIN_LOCK_UNLOCKED }
+    { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }, 
+    { .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }
 };
 
 void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
@@ -25,7 +26,7 @@
     serial_rx_fn fn = NULL;
     unsigned long flags;
 
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->rx_lock, flags);
 
     if ( port->driver->getc(port, &c) )
     {
@@ -39,7 +40,7 @@
             port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufp++)] = c;            
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->rx_lock, flags);
 
     if ( fn != NULL )
         (*fn)(c & 0x7f, regs);
@@ -50,7 +51,19 @@
     int i;
     unsigned long flags;
 
-    spin_lock_irqsave(&port->lock, flags);
+    local_irq_save(flags);
+
+    /*
+     * Avoid spinning for a long time: if there is a long-term lock holder
+     * then we know that they'll be stuffing bytes into the transmitter which
+     * will therefore not be empty for long.
+     */
+    while ( !spin_trylock(&port->tx_lock) )
+    {
+        if ( !port->driver->tx_empty(port) )
+            return;
+        cpu_relax();
+    }
 
     if ( port->driver->tx_empty(port) )
     {
@@ -63,7 +76,7 @@
         }
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 static void __serial_putc(struct serial_port *port, char c)
@@ -117,7 +130,7 @@
     if ( (handle == -1) || !port->driver || !port->driver->putc )
         return;
 
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->tx_lock, flags);
 
     if ( (c == '\n') && (handle & SERHND_COOKED) )
         __serial_putc(port, '\r');
@@ -129,7 +142,7 @@
 
     __serial_putc(port, c);
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 void serial_puts(int handle, const char *s)
@@ -141,7 +154,7 @@
     if ( (handle == -1) || !port->driver || !port->driver->putc )
         return;
 
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->tx_lock, flags);
 
     while ( (c = *s++) != '\0' )
     {
@@ -156,7 +169,7 @@
         __serial_putc(port, c);
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 char serial_getc(int handle)
@@ -168,27 +181,28 @@
     if ( (handle == -1) || !port->driver || !port->driver->getc )
         return '\0';
 
-    do {        
+    do {
         for ( ; ; )
         {
-            spin_lock_irqsave(&port->lock, flags);
+            spin_lock_irqsave(&port->rx_lock, flags);
             
             if ( port->rxbufp != port->rxbufc )
             {
                 c = port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufc++)];
-                spin_unlock_irqrestore(&port->lock, flags);
+                spin_unlock_irqrestore(&port->rx_lock, flags);
                 break;
             }
             
             if ( port->driver->getc(port, &c) )
             {
-                spin_unlock_irqrestore(&port->lock, flags);
+                spin_unlock_irqrestore(&port->rx_lock, flags);
                 break;
             }
 
-            spin_unlock_irqrestore(&port->lock, flags);
+            spin_unlock_irqrestore(&port->rx_lock, flags);
 
             cpu_relax();
+            udelay(100);
         }
     } while ( ((handle & SERHND_LO) &&  (c & 0x80)) ||
               ((handle & SERHND_HI) && !(c & 0x80)) );
@@ -241,7 +255,7 @@
     if ( handle == -1 )
         return;
 
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->rx_lock, flags);
 
     if ( port->rx != NULL )
         goto fail;
@@ -265,11 +279,11 @@
         port->rx = fn;
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->rx_lock, flags);
     return;
 
  fail:
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->rx_lock, flags);
     printk("ERROR: Conflicting receive handlers for COM%d\n", 
            handle & SERHND_IDX);
 }
@@ -277,8 +291,13 @@
 void serial_force_unlock(int handle)
 {
     struct serial_port *port = &com[handle & SERHND_IDX];
-    if ( handle != -1 )
-        port->lock = SPIN_LOCK_UNLOCKED;
+
+    if ( handle == -1 )
+        return;
+
+    port->rx_lock = SPIN_LOCK_UNLOCKED;
+    port->tx_lock = SPIN_LOCK_UNLOCKED;
+
     serial_start_sync(handle);
 }
 
@@ -290,7 +309,7 @@
     if ( handle == -1 )
         return;
     
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->tx_lock, flags);
 
     if ( port->sync++ == 0 )
     {
@@ -303,7 +322,7 @@
         }
     }
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 void serial_end_sync(int handle)
@@ -314,11 +333,11 @@
     if ( handle == -1 )
         return;
     
-    spin_lock_irqsave(&port->lock, flags);
+    spin_lock_irqsave(&port->tx_lock, flags);
 
     port->sync--;
 
-    spin_unlock_irqrestore(&port->lock, flags);
+    spin_unlock_irqrestore(&port->tx_lock, flags);
 }
 
 int serial_tx_space(int handle)
diff -r 1577043d8e36 -r 8f722ac17efa xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h     Thu Mar 23 16:27:48 2006
+++ b/xen/include/asm-x86/hvm/hvm.h     Thu Mar 23 16:37:37 2006
@@ -41,12 +41,12 @@
     /*
      * Store and load guest state:
      * 1) load/store guest register state,
-     * 2) store guest control register state (used for panic dumps),
-     * 3) modify guest state (e.g., set debug flags).
+     * 2) modify guest state (e.g., set debug flags).
      */
-    void (*store_cpu_guest_regs)(struct vcpu *v, struct cpu_user_regs *r);
-    void (*load_cpu_guest_regs)(struct vcpu *v, struct cpu_user_regs *r);
-    void (*store_cpu_guest_ctrl_regs)(struct vcpu *v, unsigned long crs[8]);
+    void (*store_cpu_guest_regs)(
+        struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs);
+    void (*load_cpu_guest_regs)(
+        struct vcpu *v, struct cpu_user_regs *r);
     void (*modify_guest_state)(struct vcpu *v);
 
     /*
@@ -93,21 +93,16 @@
 }
 
 static inline void
-hvm_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
+hvm_store_cpu_guest_regs(
+    struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs)
 {
-    hvm_funcs.store_cpu_guest_regs(v, r);
+    hvm_funcs.store_cpu_guest_regs(v, r, crs);
 }
 
 static inline void
 hvm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
 {
     hvm_funcs.load_cpu_guest_regs(v, r);
-}
-
-static inline void
-hvm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
-{
-    hvm_funcs.store_cpu_guest_ctrl_regs(v, crs);
 }
 
 static inline void
diff -r 1577043d8e36 -r 8f722ac17efa xen/include/xen/serial.h
--- a/xen/include/xen/serial.h  Thu Mar 23 16:27:48 2006
+++ b/xen/include/xen/serial.h  Thu Mar 23 16:37:37 2006
@@ -42,7 +42,7 @@
     char                rxbuf[SERIAL_RXBUFSZ];
     unsigned int        rxbufp, rxbufc;
     /* Serial I/O is concurrency-safe. */
-    spinlock_t          lock;
+    spinlock_t          rx_lock, tx_lock;
 };
 
 struct uart_driver {

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.