[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, ®s->rflags); - __vmread(GUEST_SS_SELECTOR, ®s->ss); - __vmread(GUEST_CS_SELECTOR, ®s->cs); - __vmread(GUEST_DS_SELECTOR, ®s->ds); - __vmread(GUEST_ES_SELECTOR, ®s->es); - __vmread(GUEST_GS_SELECTOR, ®s->gs); - __vmread(GUEST_FS_SELECTOR, ®s->fs); - __vmread(GUEST_RIP, ®s->rip); - __vmread(GUEST_RSP, ®s->rsp); + __vmread(GUEST_RFLAGS, ®s->rflags); + __vmread(GUEST_SS_SELECTOR, ®s->ss); + __vmread(GUEST_CS_SELECTOR, ®s->cs); + __vmread(GUEST_DS_SELECTOR, ®s->ds); + __vmread(GUEST_ES_SELECTOR, ®s->es); + __vmread(GUEST_GS_SELECTOR, ®s->gs); + __vmread(GUEST_FS_SELECTOR, ®s->fs); + __vmread(GUEST_RIP, ®s->rip); + __vmread(GUEST_RSP, ®s->rsp); #elif defined (__i386__) - __vmread(GUEST_RFLAGS, ®s->eflags); - __vmread(GUEST_SS_SELECTOR, ®s->ss); - __vmread(GUEST_CS_SELECTOR, ®s->cs); - __vmread(GUEST_DS_SELECTOR, ®s->ds); - __vmread(GUEST_ES_SELECTOR, ®s->es); - __vmread(GUEST_GS_SELECTOR, ®s->gs); - __vmread(GUEST_FS_SELECTOR, ®s->fs); - __vmread(GUEST_RIP, ®s->eip); - __vmread(GUEST_RSP, ®s->esp); -#else -#error Unsupported architecture + __vmread(GUEST_RFLAGS, ®s->eflags); + __vmread(GUEST_SS_SELECTOR, ®s->ss); + __vmread(GUEST_CS_SELECTOR, ®s->cs); + __vmread(GUEST_DS_SELECTOR, ®s->ds); + __vmread(GUEST_ES_SELECTOR, ®s->es); + __vmread(GUEST_GS_SELECTOR, ®s->gs); + __vmread(GUEST_FS_SELECTOR, ®s->fs); + __vmread(GUEST_RIP, ®s->eip); + __vmread(GUEST_RSP, ®s->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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |