diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2009-11-20 10:44:01 -0500 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2009-11-27 08:16:27 -0500 |
commit | aeb26f55337d4310840c8adc3ec7d6aebb714472 (patch) | |
tree | 9ce73b81101613adf42fcee68860dc4e767e0fee /arch | |
parent | 601367d76bd19b7eea2286ae99e5b1cb5d74f38d (diff) |
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/amd_iommu_types.h | 7 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 33 | ||||
-rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 8 |
3 files changed, 48 insertions, 0 deletions
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index e68b14811380..b332b7f7d8d6 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h | |||
@@ -231,6 +231,7 @@ extern bool amd_iommu_dump; | |||
231 | * independent of their use. | 231 | * independent of their use. |
232 | */ | 232 | */ |
233 | struct protection_domain { | 233 | struct protection_domain { |
234 | struct list_head list; /* for list of all protection domains */ | ||
234 | spinlock_t lock; /* mostly used to lock the page table*/ | 235 | spinlock_t lock; /* mostly used to lock the page table*/ |
235 | u16 id; /* the domain id written to the device table */ | 236 | u16 id; /* the domain id written to the device table */ |
236 | int mode; /* paging mode (0-6 levels) */ | 237 | int mode; /* paging mode (0-6 levels) */ |
@@ -376,6 +377,12 @@ extern struct amd_iommu *amd_iommus[MAX_IOMMUS]; | |||
376 | extern int amd_iommus_present; | 377 | extern int amd_iommus_present; |
377 | 378 | ||
378 | /* | 379 | /* |
380 | * Declarations for the global list of all protection domains | ||
381 | */ | ||
382 | extern spinlock_t amd_iommu_pd_lock; | ||
383 | extern struct list_head amd_iommu_pd_list; | ||
384 | |||
385 | /* | ||
379 | * Structure defining one entry in the device table | 386 | * Structure defining one entry in the device table |
380 | */ | 387 | */ |
381 | struct dev_table_entry { | 388 | struct dev_table_entry { |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index b2c19f41f238..0c4319b13014 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -985,6 +985,31 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom, | |||
985 | * | 985 | * |
986 | ****************************************************************************/ | 986 | ****************************************************************************/ |
987 | 987 | ||
988 | /* | ||
989 | * This function adds a protection domain to the global protection domain list | ||
990 | */ | ||
991 | static void add_domain_to_list(struct protection_domain *domain) | ||
992 | { | ||
993 | unsigned long flags; | ||
994 | |||
995 | spin_lock_irqsave(&amd_iommu_pd_lock, flags); | ||
996 | list_add(&domain->list, &amd_iommu_pd_list); | ||
997 | spin_unlock_irqrestore(&amd_iommu_pd_lock, flags); | ||
998 | } | ||
999 | |||
1000 | /* | ||
1001 | * This function removes a protection domain to the global | ||
1002 | * protection domain list | ||
1003 | */ | ||
1004 | static void del_domain_from_list(struct protection_domain *domain) | ||
1005 | { | ||
1006 | unsigned long flags; | ||
1007 | |||
1008 | spin_lock_irqsave(&amd_iommu_pd_lock, flags); | ||
1009 | list_del(&domain->list); | ||
1010 | spin_unlock_irqrestore(&amd_iommu_pd_lock, flags); | ||
1011 | } | ||
1012 | |||
988 | static u16 domain_id_alloc(void) | 1013 | static u16 domain_id_alloc(void) |
989 | { | 1014 | { |
990 | unsigned long flags; | 1015 | unsigned long flags; |
@@ -1073,6 +1098,8 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom) | |||
1073 | if (!dom) | 1098 | if (!dom) |
1074 | return; | 1099 | return; |
1075 | 1100 | ||
1101 | del_domain_from_list(&dom->domain); | ||
1102 | |||
1076 | free_pagetable(&dom->domain); | 1103 | free_pagetable(&dom->domain); |
1077 | 1104 | ||
1078 | for (i = 0; i < APERTURE_MAX_RANGES; ++i) { | 1105 | 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 | dma_dom->need_flush = false; | 1140 | dma_dom->need_flush = false; |
1114 | dma_dom->target_dev = 0xffff; | 1141 | dma_dom->target_dev = 0xffff; |
1115 | 1142 | ||
1143 | add_domain_to_list(&dma_dom->domain); | ||
1144 | |||
1116 | if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL)) | 1145 | if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL)) |
1117 | goto free_dma_dom; | 1146 | goto free_dma_dom; |
1118 | 1147 | ||
@@ -2188,6 +2217,8 @@ static void protection_domain_free(struct protection_domain *domain) | |||
2188 | if (!domain) | 2217 | if (!domain) |
2189 | return; | 2218 | return; |
2190 | 2219 | ||
2220 | del_domain_from_list(domain); | ||
2221 | |||
2191 | if (domain->id) | 2222 | if (domain->id) |
2192 | domain_id_free(domain->id); | 2223 | domain_id_free(domain->id); |
2193 | 2224 | ||
@@ -2207,6 +2238,8 @@ static struct protection_domain *protection_domain_alloc(void) | |||
2207 | if (!domain->id) | 2238 | if (!domain->id) |
2208 | goto out_err; | 2239 | goto out_err; |
2209 | 2240 | ||
2241 | add_domain_to_list(domain); | ||
2242 | |||
2210 | return domain; | 2243 | return domain; |
2211 | 2244 | ||
2212 | out_err: | 2245 | out_err: |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 8567d1698027..73d5173765d2 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -142,6 +142,12 @@ struct amd_iommu *amd_iommus[MAX_IOMMUS]; | |||
142 | int amd_iommus_present; | 142 | int amd_iommus_present; |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * List of protection domains - used during resume | ||
146 | */ | ||
147 | LIST_HEAD(amd_iommu_pd_list); | ||
148 | spinlock_t amd_iommu_pd_lock; | ||
149 | |||
150 | /* | ||
145 | * Pointer to the device table which is shared by all AMD IOMMUs | 151 | * Pointer to the device table which is shared by all AMD IOMMUs |
146 | * it is indexed by the PCI device id or the HT unit id and contains | 152 | * it is indexed by the PCI device id or the HT unit id and contains |
147 | * information about the domain the device belongs to as well as the | 153 | * information about the domain the device belongs to as well as the |
@@ -1263,6 +1269,8 @@ static int __init amd_iommu_init(void) | |||
1263 | */ | 1269 | */ |
1264 | amd_iommu_pd_alloc_bitmap[0] = 1; | 1270 | amd_iommu_pd_alloc_bitmap[0] = 1; |
1265 | 1271 | ||
1272 | spin_lock_init(&amd_iommu_pd_lock); | ||
1273 | |||
1266 | /* | 1274 | /* |
1267 | * now the data structures are allocated and basically initialized | 1275 | * now the data structures are allocated and basically initialized |
1268 | * start the real acpi table scan | 1276 | * start the real acpi table scan |