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: