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

Bug#399691: Potential Patch: Backported from 3.0.4



I ran into this same problem on trying to upgrade from a locally built
2.6.16 kernel with Xen to both the Debian packaged
linux-image-2.6.18-3-xen-k7 (version 2.6.18-8) and a locally built
image using linux-source-2.6.18 and linux-patch-debian-2.6.18 (both at
version 2.6.18.dfsg.1-9).

After researching this problem for a while, I discovered that this
problem appeared to have been fixed upstream back in December:

    http://news.gmane.org/find-root.php?message_id=%3c20061220051443.GA25598%40gondor.apana.org.au%3e

I could find these fixes in the 2.6.19/3.0.4 Fedora kernel repository
(http://hg.et.redhat.com/kernel/linux-2.6.19-xen-3.0.4?cs=285436ca48cd),
but not the 2.6.18/3.0.3 repository that provides Debian's Xen patch.

So I took the three files mentioned in that changeset from Xen's
3.0.4-testing repository and used them to prepare a patch against
Debian's Linux source (with the Xen patch applied).  I then integrated
that patch into Debian's kernel patching mechanism (under
/usr/src/kernel-patch), and rebuilt my kernel.  For my purposes, it
seems to be working fine.  Keep in mind that I am not a kernel hacker,
so this may just be trouble waiting to happen.  Also, I am testing on
a machine with 1G of RAM, and the upstream changeset says the
developer needed a machine with >1G of RAM to test the fix when it
went into 3.0.4.  That said, this is 3.0.4 code (for the affected
files) backported to 3.0.3.

I have attached my patch to this message.  It must be applied from the
/usr/src directory on a machine with linux-patch-debian-2.6.18
installed.  Then, unpack the linux-source-2.6.18.tar.bz file and use
the debian patching mechanism to apply the patches for a Xen flavored
kernel and rebuild.  That step will apply my patch as well.  You may
be able to apply these patches with "make-kpkg --added-patches...",
but I use the /usr/src/kernel-patches/all/2.6.18/apply/debian script
directly.


Mike
diff -N -ru kernel-patches.orig/all/2.6.18/debian/features/all/xen/backported-3.0.4-dma-fixes.patch kernel-patches/all/2.6.18/debian/features/all/xen/backported-3.0.4-dma-fixes.patch
--- kernel-patches.orig/all/2.6.18/debian/features/all/xen/backported-3.0.4-dma-fixes.patch	1969-12-31 18:00:00.000000000 -0600
+++ kernel-patches/all/2.6.18/debian/features/all/xen/backported-3.0.4-dma-fixes.patch	2007-01-28 10:43:40.000000000 -0600
@@ -0,0 +1,151 @@
+diff -ur linux-source-2.6.18-with-xen-patch/arch/i386/kernel/pci-dma-xen.c linux-source-2.6.18-with-3.0.4-dma-fixes/arch/i386/kernel/pci-dma-xen.c
+--- linux-source-2.6.18-with-xen-patch/arch/i386/kernel/pci-dma-xen.c	2007-01-28 01:49:12.000000000 -0600
++++ linux-source-2.6.18-with-3.0.4-dma-fixes/arch/i386/kernel/pci-dma-xen.c	2007-01-28 01:53:53.000000000 -0600
+@@ -15,6 +15,7 @@
+ #include <linux/version.h>
+ #include <asm/io.h>
+ #include <xen/balloon.h>
++#include <asm/swiotlb.h>
+ #include <asm/tlbflush.h>
+ #include <asm-i386/mach-xen/asm/swiotlb.h>
+ #include <asm/bug.h>
+@@ -31,41 +32,6 @@
+ int iommu_bio_merge __read_mostly = 0;
+ EXPORT_SYMBOL(iommu_bio_merge);
+ 
+-int iommu_sac_force __read_mostly = 0;
+-EXPORT_SYMBOL(iommu_sac_force);
+-
+-int no_iommu __read_mostly;
+-#ifdef CONFIG_IOMMU_DEBUG
+-int panic_on_overflow __read_mostly = 1;
+-int force_iommu __read_mostly = 1;
+-#else
+-int panic_on_overflow __read_mostly = 0;
+-int force_iommu __read_mostly= 0;
+-#endif
+-
+-/* Set this to 1 if there is a HW IOMMU in the system */
+-int iommu_detected __read_mostly = 0;
+-
+-void __init pci_iommu_alloc(void)
+-{
+-	/*
+-	 * The order of these functions is important for
+-	 * fall-back/fail-over reasons
+-	 */
+-#ifdef CONFIG_IOMMU
+-	iommu_hole_init();
+-#endif
+-
+-#ifdef CONFIG_CALGARY_IOMMU
+-#include <asm/calgary.h>
+-	detect_calgary();
+-#endif
+-
+-#ifdef CONFIG_SWIOTLB
+-	pci_swiotlb_init();
+-#endif
+-}
+-
+ __init int iommu_setup(char *p)
+ {
+     return 1;
+@@ -218,8 +184,8 @@
+ 	ret = (void *)vstart;
+ 
+ 	if (ret != NULL) {
+-		/* NB. Hardcode 31 address bits for now: aacraid limitation. */
+-		if (xen_create_contiguous_region(vstart, order, 31) != 0) {
++		if (xen_create_contiguous_region(vstart, order,
++						 dma_bits) != 0) {
+ 			free_pages(vstart, order);
+ 			return NULL;
+ 		}
+diff -ur linux-source-2.6.18-with-xen-patch/arch/i386/kernel/swiotlb.c linux-source-2.6.18-with-3.0.4-dma-fixes/arch/i386/kernel/swiotlb.c
+--- linux-source-2.6.18-with-xen-patch/arch/i386/kernel/swiotlb.c	2007-01-28 01:49:12.000000000 -0600
++++ linux-source-2.6.18-with-3.0.4-dma-fixes/arch/i386/kernel/swiotlb.c	2007-01-28 01:53:53.000000000 -0600
+@@ -47,10 +47,10 @@
+  */
+ #define IO_TLB_SHIFT 11
+ 
+-/* Width of DMA addresses in the IO TLB. 31 bits is an aacraid limitation. */
+-#define IO_TLB_DMA_BITS 31
++/* Width of DMA addresses. 30 bits is a b44 limitation. */
++#define DEFAULT_DMA_BITS 30
+ 
+-int swiotlb_force;
++static int swiotlb_force;
+ static char *iotlb_virt_start;
+ static unsigned long iotlb_nslabs;
+ 
+@@ -98,6 +98,15 @@
+  */
+ static DEFINE_SPINLOCK(io_tlb_lock);
+ 
++unsigned int dma_bits = DEFAULT_DMA_BITS;
++static int __init
++setup_dma_bits(char *str)
++{
++	dma_bits = simple_strtoul(str, NULL, 0);
++	return 0;
++}
++__setup("dma_bits=", setup_dma_bits);
++
+ static int __init
+ setup_io_tlb_npages(char *str)
+ {
+@@ -158,7 +167,7 @@
+ 		int rc = xen_create_contiguous_region(
+ 			(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
+ 			get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
+-			IO_TLB_DMA_BITS);
++			dma_bits);
+ 		BUG_ON(rc);
+ 	}
+ 
+@@ -183,10 +192,12 @@
+ 
+ 	printk(KERN_INFO "Software IO TLB enabled: \n"
+ 	       " Aperture:     %lu megabytes\n"
+-	       " Kernel range: 0x%016lx - 0x%016lx\n",
++	       " Kernel range: 0x%016lx - 0x%016lx\n"
++	       " Address size: %u bits\n",
+ 	       bytes >> 20,
+ 	       (unsigned long)iotlb_virt_start,
+-	       (unsigned long)iotlb_virt_start + bytes);
++	       (unsigned long)iotlb_virt_start + bytes,
++	       dma_bits);
+ }
+ 
+ void
+@@ -654,7 +665,7 @@
+ int
+ swiotlb_dma_supported (struct device *hwdev, u64 mask)
+ {
+-	return (mask >= ((1UL << IO_TLB_DMA_BITS) - 1));
++	return (mask >= ((1UL << dma_bits) - 1));
+ }
+ 
+ EXPORT_SYMBOL(swiotlb_init);
+diff -ur linux-source-2.6.18-with-xen-patch/include/asm-i386/mach-xen/asm/swiotlb.h linux-source-2.6.18-with-3.0.4-dma-fixes/include/asm-i386/mach-xen/asm/swiotlb.h
+--- linux-source-2.6.18-with-xen-patch/include/asm-i386/mach-xen/asm/swiotlb.h	2007-01-28 01:49:13.000000000 -0600
++++ linux-source-2.6.18-with-3.0.4-dma-fixes/include/asm-i386/mach-xen/asm/swiotlb.h	2007-01-28 01:53:57.000000000 -0600
+@@ -1,6 +1,8 @@
+ #ifndef _ASM_SWIOTLB_H
+ #define _ASM_SWIOTLB_H 1
+ 
++#include <linux/config.h>
++
+ /* SWIOTLB interface */
+ 
+ extern dma_addr_t swiotlb_map_single(struct device *hwdev, void *ptr, size_t size,
+@@ -32,6 +34,8 @@
+ extern int swiotlb_dma_supported(struct device *hwdev, u64 mask);
+ extern void swiotlb_init(void);
+ 
++extern unsigned int dma_bits;
++
+ #ifdef CONFIG_SWIOTLB
+ extern int swiotlb;
+ #else
diff -N -ru kernel-patches.orig/all/2.6.18/debian/series/9-extra kernel-patches/all/2.6.18/debian/series/9-extra
--- kernel-patches.orig/all/2.6.18/debian/series/9-extra	2007-01-28 10:57:39.000000000 -0600
+++ kernel-patches/all/2.6.18/debian/series/9-extra	2007-01-28 10:45:26.000000000 -0600
@@ -2,6 +2,7 @@
 + features/all/vserver/bindmount-dev.patch *_vserver *_xen-vserver
 + features/all/xen/vserver-clash.patch *_xen-vserver
 + features/all/xen/fedora-2.6.18-36186.patch *_xen *_xen-vserver
++ features/all/xen/backported-3.0.4-dma-fixes.patch *_xen *_xen-vserver
 + features/all/xen/vserver-update.patch *_xen-vserver
 + m68k-atari-net.patch m68k
 + m68k-atari-video2.patch m68k

Reply to: