Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 99622
b: refs/heads/master
c: b20ac0d
h: refs/heads/master
v: v3
  • Loading branch information
Joerg Roedel authored and Ingo Molnar committed Jun 27, 2008
1 parent b248e3b commit 2ff0cd5
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ec487d1a110abfffebdf116560db5c1d71b94cab
refs/heads/master: b20ac0d4d6cff969d7074bbf02a1b86058df0804
75 changes: 75 additions & 0 deletions trunk/arch/x86/kernel/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,3 +461,78 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
return NULL;
}

static struct protection_domain *domain_for_device(u16 devid)
{
struct protection_domain *dom;
unsigned long flags;

read_lock_irqsave(&amd_iommu_devtable_lock, flags);
dom = amd_iommu_pd_table[devid];
read_unlock_irqrestore(&amd_iommu_devtable_lock, flags);

return dom;
}

static void set_device_domain(struct amd_iommu *iommu,
struct protection_domain *domain,
u16 devid)
{
unsigned long flags;

u64 pte_root = virt_to_phys(domain->pt_root);

pte_root |= (domain->mode & 0x07) << 9;
pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | 2;

write_lock_irqsave(&amd_iommu_devtable_lock, flags);
amd_iommu_dev_table[devid].data[0] = pte_root;
amd_iommu_dev_table[devid].data[1] = pte_root >> 32;
amd_iommu_dev_table[devid].data[2] = domain->id;

amd_iommu_pd_table[devid] = domain;
write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);

iommu_queue_inv_dev_entry(iommu, devid);

iommu->need_sync = 1;
}

static int get_device_resources(struct device *dev,
struct amd_iommu **iommu,
struct protection_domain **domain,
u16 *bdf)
{
struct dma_ops_domain *dma_dom;
struct pci_dev *pcidev;
u16 _bdf;

BUG_ON(!dev || dev->bus != &pci_bus_type || !dev->dma_mask);

pcidev = to_pci_dev(dev);
_bdf = (pcidev->bus->number << 8) | pcidev->devfn;

if (_bdf >= amd_iommu_last_bdf) {
*iommu = NULL;
*domain = NULL;
*bdf = 0xffff;
return 0;
}

*bdf = amd_iommu_alias_table[_bdf];

*iommu = amd_iommu_rlookup_table[*bdf];
if (*iommu == NULL)
return 0;
dma_dom = (*iommu)->default_dom;
*domain = domain_for_device(*bdf);
if (*domain == NULL) {
*domain = &dma_dom->domain;
set_device_domain(*iommu, *domain, *bdf);
printk(KERN_INFO "AMD IOMMU: Using protection domain %d for "
"device ", (*domain)->id);
print_devid(_bdf, 1);
}

return 1;
}

0 comments on commit 2ff0cd5

Please sign in to comment.