Messages in this thread Patch in this message | | | Date | Thu, 13 Aug 2009 12:15:46 +0900 | Subject | Re: [RFC patch] init default dma_ops to prepare intel_iommu_init failure | From | FUJITA Tomonori <> |
| |
On Thu, 13 Aug 2009 10:24:20 +0800 Luming Yu <luming.yu@gmail.com> wrote:
> On Thu, Aug 13, 2009 at 10:11 AM, FUJITA > Tomonori<fujita.tomonori@lab.ntt.co.jp> wrote: > > On Wed, 12 Aug 2009 17:20:11 +0800 > > Luming Yu <luming.yu@gmail.com> wrote: > > > >> Hi there, > >> > >> On ia64 platform with dmar table and new upstream > >> kernel(config_dmar_default_on enabled), > >> if intel_iommu_init ends up without dma_ops initialized or other iommu > >> failures. > >> We got nothing to fall back. The following patch fixes it. > > > > Hmm, I think that the current code should work. > > Without the patch, I encounters boot failure with the following .config > > 162-CONFIG_IA64_GENERIC=y > 163-# CONFIG_IA64_DIG is not set > 164:# CONFIG_IA64_DIG_VTD is not set
Duh, yeah, intel_iommu_init() fails, it doesn't work.
X86 falls back into nommu_dam_ops but IA64 has nothing.
pci_swiotlb_init() can't set swiotlb to 1 or overwrite dma_ops? If it sets swiotlb to 1, intel_iommu_init() fails.
A quick fix could be something like this:
diff --git a/arch/ia64/include/asm/swiotlb.h b/arch/ia64/include/asm/swiotlb.h index dcbaea7..21b076e 100644 --- a/arch/ia64/include/asm/swiotlb.h +++ b/arch/ia64/include/asm/swiotlb.h @@ -5,6 +5,7 @@ #include <linux/swiotlb.h> extern int swiotlb_force; +extern struct dma_map_ops swiotlb_dma_ops; #ifdef CONFIG_SWIOTLB extern int swiotlb; diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index f6b1ff0..344d783 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -11,6 +11,7 @@ #include <asm/iommu.h> #include <asm/machvec.h> #include <linux/dma-mapping.h> +#include <asm/swiotlb.h> #include <asm/system.h> @@ -47,8 +48,13 @@ extern struct dma_map_ops intel_dma_ops; static int __init pci_iommu_init(void) { - if (iommu_detected) - intel_iommu_init(); + int ret; + + if (iommu_detected) { + ret = intel_iommu_init(); + if (ret) + dma_ops = &swiotlb_dma_ops; + } return 0; } diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c index 223abb1..ad164cf 100644 --- a/arch/ia64/kernel/pci-swiotlb.c +++ b/arch/ia64/kernel/pci-swiotlb.c @@ -46,12 +46,14 @@ void __init swiotlb_dma_init(void) void __init pci_swiotlb_init(void) { - if (!iommu_detected || iommu_pass_through) { + /* for fallback */ + swiotlb_init(); + + if (!dma_ops) { #ifdef CONFIG_IA64_GENERIC swiotlb = 1; printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n"); machvec_init("dig"); - swiotlb_init(); dma_ops = &swiotlb_dma_ops; #else panic("Unable to find Intel IOMMU");
| |