Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 154761
b: refs/heads/master
c: c7ab48d
h: refs/heads/master
i:
  154759: 998da21
v: v3
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jun 29, 2009
1 parent 0ef7290 commit 56a281a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 89 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b213203e475212a69ad6fedfb73464087e317148
refs/heads/master: c7ab48d2acaf959e4d59c3f55d12fdb7ca9afd7c
15 changes: 2 additions & 13 deletions trunk/arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1913,25 +1913,14 @@ config DMAR_DEFAULT_ON
recommended you say N here while the DMAR code remains
experimental.

config DMAR_GFX_WA
def_bool y
prompt "Support for Graphics workaround"
depends on DMAR
---help---
Current Graphics drivers tend to use physical address
for DMA and avoid using DMA APIs. Setting this config
option permits the IOMMU driver to set a unity map for
all the OS-visible memory. Hence the driver can continue
to use physical addresses for DMA.

config DMAR_FLOPPY_WA
def_bool y
depends on DMAR
---help---
Floppy disk drivers are know to bypass DMA API calls
Floppy disk drivers are known to bypass DMA API calls
thereby failing to work when IOMMU is enabled. This
workaround will setup a 1:1 mapping for the first
16M to make floppy (an ISA device) work.
16MiB to make floppy (an ISA device) work.

config INTR_REMAP
bool "Support for Interrupt Remapping (EXPERIMENTAL)"
Expand Down
107 changes: 32 additions & 75 deletions trunk/drivers/pci/intel-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1889,11 +1889,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
"IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
pci_name(pdev), start, end);

if (iommu_identity_mapping)
domain = si_domain;
else
/* page table init */
domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
if (!domain)
return -ENOMEM;

Expand Down Expand Up @@ -1922,64 +1918,6 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
rmrr->end_address + 1);
}

struct iommu_prepare_data {
struct pci_dev *pdev;
int ret;
};

static int __init iommu_prepare_work_fn(unsigned long start_pfn,
unsigned long end_pfn, void *datax)
{
struct iommu_prepare_data *data;

data = (struct iommu_prepare_data *)datax;

data->ret = iommu_prepare_identity_map(data->pdev,
start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
return data->ret;

}

static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev)
{
int nid;
struct iommu_prepare_data data;

data.pdev = pdev;
data.ret = 0;

for_each_online_node(nid) {
work_with_active_regions(nid, iommu_prepare_work_fn, &data);
if (data.ret)
return data.ret;
}
return data.ret;
}

#ifdef CONFIG_DMAR_GFX_WA
static void __init iommu_prepare_gfx_mapping(void)
{
struct pci_dev *pdev = NULL;
int ret;

for_each_pci_dev(pdev) {
if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO ||
!IS_GFX_DEVICE(pdev))
continue;
printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
pci_name(pdev));
ret = iommu_prepare_with_active_regions(pdev);
if (ret)
printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
}
}
#else /* !CONFIG_DMAR_GFX_WA */
static inline void iommu_prepare_gfx_mapping(void)
{
return;
}
#endif

#ifdef CONFIG_DMAR_FLOPPY_WA
static inline void iommu_prepare_isa(void)
{
Expand All @@ -1990,12 +1928,12 @@ static inline void iommu_prepare_isa(void)
if (!pdev)
return;

printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n");
printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n");
ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);

if (ret)
printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, "
"floppy might not work\n");
printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; "
"floppy might not work\n");

}
#else
Expand Down Expand Up @@ -2023,16 +1961,30 @@ static int __init init_context_pass_through(void)
}

static int md_domain_init(struct dmar_domain *domain, int guest_width);

static int __init si_domain_work_fn(unsigned long start_pfn,
unsigned long end_pfn, void *datax)
{
int *ret = datax;

*ret = iommu_domain_identity_map(si_domain,
(uint64_t)start_pfn << PAGE_SHIFT,
(uint64_t)end_pfn << PAGE_SHIFT);
return *ret;

}

static int si_domain_init(void)
{
struct dmar_drhd_unit *drhd;
struct intel_iommu *iommu;
int ret = 0;
int nid, ret = 0;

si_domain = alloc_domain();
if (!si_domain)
return -EFAULT;

pr_debug("Identity mapping domain is domain %d\n", si_domain->id);

for_each_active_iommu(iommu, drhd) {
ret = iommu_attach_domain(si_domain, iommu);
Expand All @@ -2049,6 +2001,12 @@ static int si_domain_init(void)

si_domain->flags = DOMAIN_FLAG_STATIC_IDENTITY;

for_each_online_node(nid) {
work_with_active_regions(nid, si_domain_work_fn, &ret);
if (ret)
return ret;
}

return 0;
}

Expand Down Expand Up @@ -2102,13 +2060,14 @@ static int iommu_prepare_static_identity_mapping(void)
if (ret)
return -EFAULT;

printk(KERN_INFO "IOMMU: Setting identity map:\n");
for_each_pci_dev(pdev) {
ret = iommu_prepare_with_active_regions(pdev);
if (ret) {
printk(KERN_INFO "1:1 mapping to one domain failed.\n");
return -EFAULT;
}
printk(KERN_INFO "IOMMU: identity mapping for device %s\n",
pci_name(pdev));

ret = domain_context_mapping(si_domain, pdev,
CONTEXT_TT_MULTI_LEVEL);
if (ret)
return ret;
ret = domain_add_dev_info(si_domain, pdev);
if (ret)
return ret;
Expand Down Expand Up @@ -2299,8 +2258,6 @@ int __init init_dmars(void)
}
}

iommu_prepare_gfx_mapping();

iommu_prepare_isa();
}

Expand Down

0 comments on commit 56a281a

Please sign in to comment.