Commit aeb26f55 authored by Joerg Roedel's avatar Joerg Roedel

x86/amd-iommu: Implement protection domain list

This patch adds code to keep a global list of all protection
domains. This allows to simplify the resume code.
Signed-off-by: default avatarJoerg Roedel <joerg.roedel@amd.com>
parent 601367d7
...@@ -231,6 +231,7 @@ extern bool amd_iommu_dump; ...@@ -231,6 +231,7 @@ extern bool amd_iommu_dump;
* independent of their use. * independent of their use.
*/ */
struct protection_domain { struct protection_domain {
struct list_head list; /* for list of all protection domains */
spinlock_t lock; /* mostly used to lock the page table*/ spinlock_t lock; /* mostly used to lock the page table*/
u16 id; /* the domain id written to the device table */ u16 id; /* the domain id written to the device table */
int mode; /* paging mode (0-6 levels) */ int mode; /* paging mode (0-6 levels) */
...@@ -375,6 +376,12 @@ extern struct amd_iommu *amd_iommus[MAX_IOMMUS]; ...@@ -375,6 +376,12 @@ extern struct amd_iommu *amd_iommus[MAX_IOMMUS];
/* Number of IOMMUs present in the system */ /* Number of IOMMUs present in the system */
extern int amd_iommus_present; extern int amd_iommus_present;
/*
* Declarations for the global list of all protection domains
*/
extern spinlock_t amd_iommu_pd_lock;
extern struct list_head amd_iommu_pd_list;
/* /*
* Structure defining one entry in the device table * Structure defining one entry in the device table
*/ */
......
...@@ -985,6 +985,31 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom, ...@@ -985,6 +985,31 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom,
* *
****************************************************************************/ ****************************************************************************/
/*
* This function adds a protection domain to the global protection domain list
*/
static void add_domain_to_list(struct protection_domain *domain)
{
unsigned long flags;
spin_lock_irqsave(&amd_iommu_pd_lock, flags);
list_add(&domain->list, &amd_iommu_pd_list);
spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
}
/*
* This function removes a protection domain to the global
* protection domain list
*/
static void del_domain_from_list(struct protection_domain *domain)
{
unsigned long flags;
spin_lock_irqsave(&amd_iommu_pd_lock, flags);
list_del(&domain->list);
spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
}
static u16 domain_id_alloc(void) static u16 domain_id_alloc(void)
{ {
unsigned long flags; unsigned long flags;
...@@ -1073,6 +1098,8 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom) ...@@ -1073,6 +1098,8 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
if (!dom) if (!dom)
return; return;
del_domain_from_list(&dom->domain);
free_pagetable(&dom->domain); free_pagetable(&dom->domain);
for (i = 0; i < APERTURE_MAX_RANGES; ++i) { for (i = 0; i < APERTURE_MAX_RANGES; ++i) {
...@@ -1113,6 +1140,8 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu) ...@@ -1113,6 +1140,8 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
dma_dom->need_flush = false; dma_dom->need_flush = false;
dma_dom->target_dev = 0xffff; dma_dom->target_dev = 0xffff;
add_domain_to_list(&dma_dom->domain);
if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL)) if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL))
goto free_dma_dom; goto free_dma_dom;
...@@ -2188,6 +2217,8 @@ static void protection_domain_free(struct protection_domain *domain) ...@@ -2188,6 +2217,8 @@ static void protection_domain_free(struct protection_domain *domain)
if (!domain) if (!domain)
return; return;
del_domain_from_list(domain);
if (domain->id) if (domain->id)
domain_id_free(domain->id); domain_id_free(domain->id);
...@@ -2207,6 +2238,8 @@ static struct protection_domain *protection_domain_alloc(void) ...@@ -2207,6 +2238,8 @@ static struct protection_domain *protection_domain_alloc(void)
if (!domain->id) if (!domain->id)
goto out_err; goto out_err;
add_domain_to_list(domain);
return domain; return domain;
out_err: out_err:
......
...@@ -141,6 +141,12 @@ LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the ...@@ -141,6 +141,12 @@ LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the
struct amd_iommu *amd_iommus[MAX_IOMMUS]; struct amd_iommu *amd_iommus[MAX_IOMMUS];
int amd_iommus_present; int amd_iommus_present;
/*
* List of protection domains - used during resume
*/
LIST_HEAD(amd_iommu_pd_list);
spinlock_t amd_iommu_pd_lock;
/* /*
* Pointer to the device table which is shared by all AMD IOMMUs * Pointer to the device table which is shared by all AMD IOMMUs
* it is indexed by the PCI device id or the HT unit id and contains * it is indexed by the PCI device id or the HT unit id and contains
...@@ -1263,6 +1269,8 @@ static int __init amd_iommu_init(void) ...@@ -1263,6 +1269,8 @@ static int __init amd_iommu_init(void)
*/ */
amd_iommu_pd_alloc_bitmap[0] = 1; amd_iommu_pd_alloc_bitmap[0] = 1;
spin_lock_init(&amd_iommu_pd_lock);
/* /*
* now the data structures are allocated and basically initialized * now the data structures are allocated and basically initialized
* start the real acpi table scan * start the real acpi table scan
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment