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: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
Родитель
601367d76b
Коммит
aeb26f5533
|
@ -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];
|
||||||
/* 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,
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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:
|
||||||
|
|
|
@ -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)
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче