Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 112606
b: refs/heads/master
c: bd60b73
h: refs/heads/master
v: v3
  • Loading branch information
Joerg Roedel authored and Ingo Molnar committed Sep 19, 2008
1 parent a663068 commit d5f2c3e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 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: b39ba6ad004a31bf2a08ba2b08c1e0f9b3530bb7
refs/heads/master: bd60b735c658e6e8c656e89771d281bcfcf51279
43 changes: 38 additions & 5 deletions trunk/arch/x86/kernel/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@

static DEFINE_RWLOCK(amd_iommu_devtable_lock);

/* A list of preallocated protection domains */
static LIST_HEAD(iommu_pd_list);
static DEFINE_SPINLOCK(iommu_pd_list_lock);

/*
* general struct to manage commands send to an IOMMU
*/
Expand Down Expand Up @@ -663,6 +667,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
dma_dom->next_bit = 0;

dma_dom->need_flush = false;
dma_dom->target_dev = 0xffff;

/* Intialize the exclusion range if necessary */
if (iommu->exclusion_start &&
Expand Down Expand Up @@ -768,6 +773,33 @@ static bool check_device(struct device *dev)
return true;
}

/*
* In this function the list of preallocated protection domains is traversed to
* find the domain for a specific device
*/
static struct dma_ops_domain *find_protection_domain(u16 devid)
{
struct dma_ops_domain *entry, *ret = NULL;
unsigned long flags;

if (list_empty(&iommu_pd_list))
return NULL;

spin_lock_irqsave(&iommu_pd_list_lock, flags);

list_for_each_entry(entry, &iommu_pd_list, list) {
if (entry->target_dev == devid) {
ret = entry;
list_del(&ret->list);
break;
}
}

spin_unlock_irqrestore(&iommu_pd_list_lock, flags);

return ret;
}

/*
* In the dma_ops path we only have the struct device. This function
* finds the corresponding IOMMU, the protection domain and the
Expand Down Expand Up @@ -803,9 +835,11 @@ static int get_device_resources(struct device *dev,
*iommu = amd_iommu_rlookup_table[*bdf];
if (*iommu == NULL)
return 0;
dma_dom = (*iommu)->default_dom;
*domain = domain_for_device(*bdf);
if (*domain == NULL) {
dma_dom = find_protection_domain(*bdf);
if (!dma_dom)
dma_dom = (*iommu)->default_dom;
*domain = &dma_dom->domain;
set_device_domain(*iommu, *domain, *bdf);
printk(KERN_INFO "AMD IOMMU: Using protection domain %d for "
Expand Down Expand Up @@ -1257,10 +1291,9 @@ void prealloc_protection_domains(void)
if (!dma_dom)
continue;
init_unity_mappings_for_device(dma_dom, devid);
set_device_domain(iommu, &dma_dom->domain, devid);
printk(KERN_INFO "AMD IOMMU: Allocated domain %d for device ",
dma_dom->domain.id);
print_devid(devid, 1);
dma_dom->target_dev = devid;

list_add_tail(&dma_dom->list, &iommu_pd_list);
}
}

Expand Down
6 changes: 6 additions & 0 deletions trunk/include/asm-x86/amd_iommu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ struct dma_ops_domain {

/* This will be set to true when TLB needs to be flushed */
bool need_flush;

/*
* if this is a preallocated domain, keep the device for which it was
* preallocated in this variable
*/
u16 target_dev;
};

/*
Expand Down

0 comments on commit d5f2c3e

Please sign in to comment.