|
@@ -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)
|
|
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)
|
|
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)
|
|
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)
|
|
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:
|