diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c --- old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c 2005-05-24 17:34:53.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c 2005-06-09 11:52:51.000000000 +0000 @@ -36,7 +36,7 @@ xen_contig_memory(unsigned long vstart, pud_t *pud; pmd_t *pmd; pte_t *pte; - unsigned long pfn, i, flags; + unsigned long mfn, i, flags; scrub_pages(vstart, 1 << order); @@ -45,26 +45,26 @@ xen_contig_memory(unsigned long vstart, /* 1. Zap current PTEs, giving away the underlying pages. */ for (i = 0; i < (1<> PAGE_SHIFT; - HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE), + pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE))); + pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE))); + pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE))); + mfn = pte_mfn(*pte); + HYPERVISOR_update_va_mapping((vstart + (i*PAGE_SIZE)), __pte_ma(0), 0); phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = - INVALID_P2M_ENTRY; + (u32)INVALID_P2M_ENTRY; if (HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, - &pfn, 1, 0) != 1) BUG(); + &mfn, 1, 0) != 1) BUG(); } /* 2. Get a new contiguous memory extent. */ if (HYPERVISOR_dom_mem_op(MEMOP_increase_reservation, - &pfn, 1, order) != 1) BUG(); + &mfn, 1, order) != 1) BUG(); /* 3. Map the new extent in place of old pages. */ for (i = 0; i < (1<>PAGE_SHIFT)+i); - phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = pfn+i; + __pte_ma(((mfn+i)<>PAGE_SHIFT)+i); + phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = mfn+i; } flush_tlb_all(); @@ -123,6 +123,7 @@ void dma_free_coherent(struct device *de free_pages((unsigned long)vaddr, order); } +#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, dma_addr_t device_addr, size_t size, int flags) { @@ -199,3 +200,4 @@ void *dma_mark_declared_memory_occupied( return mem->virt_base + (pos << PAGE_SHIFT); } EXPORT_SYMBOL(dma_mark_declared_memory_occupied); +#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */ diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c --- old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c 2005-06-06 16:39:54.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c 2005-06-09 12:38:43.000000000 +0000 @@ -209,7 +209,7 @@ unsigned long allocate_empty_lowmem_regi pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE))); pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE))); pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE))); - pfn_array[i] = pte->pte_low >> PAGE_SHIFT; + pfn_array[i] = pte_mfn(*pte); HYPERVISOR_update_va_mapping(vstart + (i*PAGE_SIZE), __pte_ma(0), 0); phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = INVALID_P2M_ENTRY; diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/Makefile new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/Makefile --- old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/Makefile 2005-06-03 01:44:40.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/Makefile 2005-06-09 11:44:20.000000000 +0000 @@ -14,7 +14,7 @@ obj-y := process.o signal.o entry.o trap c-obj-y := semaphore.o i387.o sys_x86_64.o \ ptrace.o quirks.o syscall.o bootflag.o -i386-obj-y := time.o +i386-obj-y := time.o pci-dma.o obj-y += ../../i386/kernel/timers/ s-obj-y := @@ -35,7 +35,7 @@ c-obj-$(CONFIG_X86_IO_APIC) += genapic.o #obj-$(CONFIG_CPU_FREQ) += cpufreq/ #obj-$(CONFIG_EARLY_PRINTK) += early_printk.o #obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o -c-obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o +c-obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o #obj-$(CONFIG_SWIOTLB) += swiotlb.o obj-$(CONFIG_KPROBES) += kprobes.o diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/pci-dma.c new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/pci-dma.c --- old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/pci-dma.c 2005-05-24 17:34:54.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/pci-dma.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,256 +0,0 @@ -/* - * Dynamic DMA mapping support. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* Map a set of buffers described by scatterlist in streaming - * mode for DMA. This is the scatter-gather version of the - * above pci_map_single interface. Here the scatter gather list - * elements are each tagged with the appropriate dma address - * and length. They are obtained via sg_dma_{address,length}(SG). - * - * NOTE: An implementation may be able to use a smaller number of - * DMA address/length pairs than there are SG table elements. - * (for example via virtual mapping capabilities) - * The routine returns the number of addr/length pairs actually - * used, at most nents. - * - * Device ownership issues as mentioned above for pci_map_single are - * the same here. - */ -int dma_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, int direction) -{ - int i; - - BUG_ON(direction == DMA_NONE); - for (i = 0; i < nents; i++ ) { - struct scatterlist *s = &sg[i]; - BUG_ON(!s->page); - s->dma_address = virt_to_bus(page_address(s->page) +s->offset); - s->dma_length = s->length; - } - return nents; -} - -EXPORT_SYMBOL(dma_map_sg); - -/* Unmap a set of streaming mode DMA translations. - * Again, cpu read rules concerning calls here are the same as for - * pci_unmap_single() above. - */ -void dma_unmap_sg(struct device *dev, struct scatterlist *sg, - int nents, int dir) -{ - int i; - for (i = 0; i < nents; i++) { - struct scatterlist *s = &sg[i]; - BUG_ON(s->page == NULL); - BUG_ON(s->dma_address == 0); - dma_unmap_single(dev, s->dma_address, s->dma_length, dir); - } -} - -struct dma_coherent_mem { - void *virt_base; - u32 device_base; - int size; - int flags; - unsigned long *bitmap; -}; - -static void -xen_contig_memory(unsigned long vstart, unsigned int order) -{ - /* - * Ensure multi-page extents are contiguous in machine memory. - * This code could be cleaned up some, and the number of - * hypercalls reduced. - */ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - unsigned long pfn, i, flags; - - scrub_pages(vstart, 1 << order); - - balloon_lock(flags); - - /* 1. Zap current PTEs, giving away the underlying pages. */ - for (i = 0; i < (1<pte >> PAGE_SHIFT; - xen_l1_entry_update(pte, 0); - phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = - (u32)INVALID_P2M_ENTRY; - if (HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, - &pfn, 1, 0) != 1) BUG(); - } - /* 2. Get a new contiguous memory extent. */ - if (HYPERVISOR_dom_mem_op(MEMOP_increase_reservation, - &pfn, 1, order) != 1) BUG(); - /* 3. Map the new extent in place of old pages. */ - for (i = 0; i < (1<>PAGE_SHIFT)+i); - phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = - pfn+i; - } - /* Flush updates through and flush the TLB. */ - xen_tlb_flush(); - - balloon_unlock(flags); -} - -void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, unsigned gfp) -{ - void *ret; - unsigned int order = get_order(size); - unsigned long vstart; - - struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; - - /* ignore region specifiers */ - gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); - - if (mem) { - int page = bitmap_find_free_region(mem->bitmap, mem->size, - order); - if (page >= 0) { - *dma_handle = mem->device_base + (page << PAGE_SHIFT); - ret = mem->virt_base + (page << PAGE_SHIFT); - memset(ret, 0, size); - return ret; - } - if (mem->flags & DMA_MEMORY_EXCLUSIVE) - return NULL; - } - - if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) - gfp |= GFP_DMA; - - vstart = __get_free_pages(gfp, order); - ret = (void *)vstart; - if (ret == NULL) - return ret; - - xen_contig_memory(vstart, order); - - memset(ret, 0, size); - *dma_handle = virt_to_bus(ret); - - return ret; -} -EXPORT_SYMBOL(dma_alloc_coherent); - -void dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; - int order = get_order(size); - - if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { - int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; - - bitmap_release_region(mem->bitmap, page, order); - } else - free_pages((unsigned long)vaddr, order); -} -EXPORT_SYMBOL(dma_free_coherent); - -#if 0 -int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, - dma_addr_t device_addr, size_t size, int flags) -{ - void __iomem *mem_base; - int pages = size >> PAGE_SHIFT; - int bitmap_size = (pages + 31)/32; - - if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) - goto out; - if (!size) - goto out; - if (dev->dma_mem) - goto out; - - /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ - - mem_base = ioremap(bus_addr, size); - if (!mem_base) - goto out; - - dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); - if (!dev->dma_mem) - goto out; - memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem)); - dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL); - if (!dev->dma_mem->bitmap) - goto free1_out; - memset(dev->dma_mem->bitmap, 0, bitmap_size); - - dev->dma_mem->virt_base = mem_base; - dev->dma_mem->device_base = device_addr; - dev->dma_mem->size = pages; - dev->dma_mem->flags = flags; - - if (flags & DMA_MEMORY_MAP) - return DMA_MEMORY_MAP; - - return DMA_MEMORY_IO; - - free1_out: - kfree(dev->dma_mem->bitmap); - out: - return 0; -} -EXPORT_SYMBOL(dma_declare_coherent_memory); - -void dma_release_declared_memory(struct device *dev) -{ - struct dma_coherent_mem *mem = dev->dma_mem; - - if(!mem) - return; - dev->dma_mem = NULL; - iounmap(mem->virt_base); - kfree(mem->bitmap); - kfree(mem); -} -EXPORT_SYMBOL(dma_release_declared_memory); - -void *dma_mark_declared_memory_occupied(struct device *dev, - dma_addr_t device_addr, size_t size) -{ - struct dma_coherent_mem *mem = dev->dma_mem; - int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT; - int pos, err; - - if (!mem) - return ERR_PTR(-EINVAL); - - pos = (device_addr - mem->device_base) >> PAGE_SHIFT; - err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); - if (err != 0) - return ERR_PTR(err); - return mem->virt_base + (pos << PAGE_SHIFT); -} -EXPORT_SYMBOL(dma_mark_declared_memory_occupied); -#endif diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c --- old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c 2005-05-24 17:34:54.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c 2005-06-09 11:24:34.000000000 +0000 @@ -97,6 +97,9 @@ EXPORT_SYMBOL(copy_to_user); EXPORT_SYMBOL(copy_in_user); EXPORT_SYMBOL(strnlen_user); +EXPORT_SYMBOL(dma_alloc_coherent); +EXPORT_SYMBOL(dma_free_coherent); + #ifdef CONFIG_PCI EXPORT_SYMBOL(pci_alloc_consistent); EXPORT_SYMBOL(pci_free_consistent); diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c --- old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c 2005-06-06 16:39:54.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/hypervisor.c 2005-06-07 20:35:16.000000000 +0000 @@ -256,7 +276,7 @@ unsigned long allocate_empty_lowmem_regi pud = pud_offset(pgd, (vstart + (i*PAGE_SIZE))); pmd = pmd_offset(pud, (vstart + (i*PAGE_SIZE))); pte = pte_offset_kernel(pmd, (vstart + (i*PAGE_SIZE))); - pfn_array[i] = pte->pte >> PAGE_SHIFT; + pfn_array[i] = pte_mfn(*pte); xen_l1_entry_update(pte, 0); phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = (u32)INVALID_P2M_ENTRY; diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c --- old-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c 2005-06-02 23:09:31.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c 2005-06-07 15:39:50.000000000 +0000 @@ -395,7 +395,7 @@ unsigned long get_machine_pfn(unsigned l pmd_t* pmd = pmd_offset(pud, addr); pte_t *pte = pte_offset_kernel(pmd, addr); - return (pte->pte >> PAGE_SHIFT); + return pte_mfn(*pte); } #define ALIGN_TO_4K __attribute__((section(".data.page_aligned"))) diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h new-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h --- old-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h 2005-05-24 17:34:54.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h 2005-06-09 12:11:58.000000000 +0000 @@ -46,9 +46,10 @@ */ #define INVALID_P2M_ENTRY (~0U) #define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1))) +#define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT) #define pte_pfn(_pte) \ ({ \ - unsigned long mfn = (_pte).pte_low >> PAGE_SHIFT; \ + unsigned long mfn = pte_mfn(_pte); \ unsigned long pfn = mfn_to_pfn(mfn); \ if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn)) \ pfn = max_mapnr; /* special: force !pfn_valid() */ \ diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/dma-mapping.h new-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/dma-mapping.h --- old-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/dma-mapping.h 2005-06-06 16:39:51.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/dma-mapping.h 2005-06-09 11:51:36.000000000 +0000 @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -17,7 +18,7 @@ extern dma_addr_t bad_dma_address; (swiotlb ? swiotlb_dma_mapping_error(x) : ((x) == bad_dma_address)) void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - unsigned gfp); + int gfp); void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle); @@ -53,6 +56,54 @@ static inline void dma_unmap_single(stru out_of_line_bug(); /* Nothing to do */ } + +/* Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scatter-gather version of the + * above pci_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for pci_map_single are + * the same here. + */ +static inline int dma_map_sg(struct device *hwdev, struct scatterlist *sg, + int nents, int direction) +{ + int i; + + BUG_ON(direction == DMA_NONE); + for (i = 0; i < nents; i++ ) { + struct scatterlist *s = &sg[i]; + BUG_ON(!s->page); + s->dma_address = virt_to_bus(page_address(s->page) +s->offset); + s->dma_length = s->length; + } + return nents; +} + +EXPORT_SYMBOL(dma_map_sg); + +/* Unmap a set of streaming mode DMA translations. + * Again, cpu read rules concerning calls here are the same as for + * pci_unmap_single() above. + */ +static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, int dir) +{ + int i; + for (i = 0; i < nents; i++) { + struct scatterlist *s = &sg[i]; + BUG_ON(s->page == NULL); + BUG_ON(s->dma_address == 0); + dma_unmap_single(dev, s->dma_address, s->dma_length, dir); + } +} #endif #define dma_map_page(dev,page,offset,size,dir) \ diff -rN -u -p old-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h new-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h --- old-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h 2005-05-28 09:20:36.000000000 +0000 +++ new-xen-64-4/linux-2.6.11-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h 2005-06-08 02:48:53.000000000 +0000 @@ -277,9 +292,10 @@ static inline unsigned long pud_bad(pud_ */ #define INVALID_P2M_ENTRY (~0UL) #define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1))) +#define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT) #define pte_pfn(_pte) \ ({ \ - unsigned long mfn = (_pte).pte >> PAGE_SHIFT; \ + unsigned long mfn = pte_mfn(_pte); \ unsigned pfn = mfn_to_pfn(mfn); \ if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn)) \ pfn = max_mapnr; /* special: force !pfn_valid() */ \