ia64/xen-unstable

changeset 2044:be651e93909d

bitkeeper revision 1.1108.33.39 (410f5c80HHs32Qoh3S41tB5KdiU-uA)

Fix pci_alloc_consistent() to always return contiguous
machine memory.
author kaf24@scramble.cl.cam.ac.uk
date Tue Aug 03 09:36:00 2004 +0000 (2004-08-03)
parents a27094c8e6f3
children 5f6716a0d4a5
files linux-2.4.26-xen-sparse/arch/xen/kernel/pci-dma.c linux-2.4.26-xen-sparse/mkbuildtree
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/pci-dma.c	Tue Aug 03 08:14:11 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/pci-dma.c	Tue Aug 03 09:36:00 2004 +0000
     1.3 @@ -18,15 +18,59 @@ void *pci_alloc_consistent(struct pci_de
     1.4  {
     1.5  	void *ret;
     1.6  	int gfp = GFP_ATOMIC;
     1.7 +	unsigned int order = get_order(size);
     1.8 +	unsigned long vstart;
     1.9  
    1.10  	if (hwdev == NULL || ((u32)hwdev->dma_mask < 0xffffffff))
    1.11  		gfp |= GFP_DMA;
    1.12 -	ret = (void *)__get_free_pages(gfp, get_order(size));
    1.13 +
    1.14 +	ret = (void *)vstart = __get_free_pages(gfp, order);
    1.15 +	if (ret == NULL)
    1.16 +		return ret;
    1.17  
    1.18 -	if (ret != NULL) {
    1.19 -		memset(ret, 0, size);
    1.20 -		*dma_handle = virt_to_bus(ret);
    1.21 +	/*
    1.22 +	 * Ensure multi-page extents are contiguous in machine memory.
    1.23 +	 * This code could be cleaned up some, and the number of
    1.24 +	 * hypercalls reduced.
    1.25 +	 */
    1.26 +	if (size > PAGE_SIZE) {
    1.27 +		pgd_t         *pgd; 
    1.28 +		pmd_t         *pmd;
    1.29 +		pte_t         *pte;
    1.30 +		unsigned long  pfn, i;
    1.31 +		/* 1. Zap current PTEs, giving away the underlying pages. */
    1.32 +		for (i = 0; i < (1<<order); i++) {
    1.33 +			pgd = pgd_offset_k(   (vstart + (i*PAGE_SIZE)));
    1.34 +			pmd = pmd_offset(pgd, (vstart + (i*PAGE_SIZE)));
    1.35 +			pte = pte_offset(pmd, (vstart + (i*PAGE_SIZE)));
    1.36 +			pfn = pte->pte_low >> PAGE_SHIFT;
    1.37 +			queue_l1_entry_update(pte, 0);
    1.38 +			flush_page_update_queue();
    1.39 +			if (HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, 
    1.40 +				&pfn, 1, 0) != 1) BUG();
    1.41 +		}
    1.42 +		/* 2. Get a new contiguous memory extent. */
    1.43 +		if (HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,
    1.44 +			&pfn, 1, order) != 1) BUG();
    1.45 +		/* 3. Map the new extent in place of old pages. */
    1.46 +		for (i = 0; i < (1<<order); i++) {
    1.47 +			pgd = pgd_offset_k(   (vstart + (i*PAGE_SIZE)));
    1.48 +			pmd = pmd_offset(pgd, (vstart + (i*PAGE_SIZE)));
    1.49 +			pte = pte_offset(pmd, (vstart + (i*PAGE_SIZE)));
    1.50 +			queue_l1_entry_update(pte, 
    1.51 +				((pfn+i)<<PAGE_SHIFT)|__PAGE_KERNEL);
    1.52 +			queue_machphys_update(pfn+i,
    1.53 +				(__pa(ret)>>PAGE_SHIFT)+i);
    1.54 +			phys_to_machine_mapping[(__pa(ret)>>PAGE_SHIFT)+i] =
    1.55 +				pfn+i;
    1.56 +                        flush_page_update_queue();
    1.57 +		}
    1.58 +		flush_page_update_queue();
    1.59  	}
    1.60 +
    1.61 +	memset(ret, 0, size);
    1.62 +	*dma_handle = virt_to_bus(ret);
    1.63 +
    1.64  	return ret;
    1.65  }
    1.66  
     2.1 --- a/linux-2.4.26-xen-sparse/mkbuildtree	Tue Aug 03 08:14:11 2004 +0000
     2.2 +++ b/linux-2.4.26-xen-sparse/mkbuildtree	Tue Aug 03 09:36:00 2004 +0000
     2.3 @@ -213,7 +213,6 @@ ln -sf ../../${LINUX_26}/include/asm-xen
     2.4  cd ${AD}/arch/xen/kernel
     2.5  ln -sf ../../i386/kernel/i387.c
     2.6  ln -sf ../../i386/kernel/init_task.c
     2.7 -ln -sf ../../i386/kernel/pci-dma.c
     2.8  ln -sf ../../i386/kernel/pci-i386.c
     2.9  ln -sf ../../i386/kernel/pci-i386.h
    2.10  ln -sf ../../i386/kernel/ptrace.c