diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2008-07-11 11:14:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-11 12:01:10 -0400 |
commit | 431b2a2015337533f1a9e39a840266a8a2c93144 (patch) | |
tree | 300bc72db7e995ecaf8b3c00981773acb9289067 /arch/x86/kernel/amd_iommu.c | |
parent | b65233a9c1da587bf19ee161982f4f0ec59941c0 (diff) |
x86, AMD IOMMU: add comments to core code
This patch adds comments about how the AMD IOMMU core code works for the DMA
remapping functionality.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Cc: iommu@lists.linux-foundation.org
Cc: bhavna.sarathy@amd.com
Cc: robert.richter@amd.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
-rw-r--r-- | arch/x86/kernel/amd_iommu.c | 201 |
1 files changed, 199 insertions, 2 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index f2766d84c7a0..4bae96ca7c11 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -34,6 +34,9 @@ | |||
34 | 34 | ||
35 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); | 35 | static DEFINE_RWLOCK(amd_iommu_devtable_lock); |
36 | 36 | ||
37 | /* | ||
38 | * general struct to manage commands send to an IOMMU | ||
39 | */ | ||
37 | struct command { | 40 | struct command { |
38 | u32 data[4]; | 41 | u32 data[4]; |
39 | }; | 42 | }; |
@@ -41,11 +44,22 @@ struct command { | |||
41 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | 44 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, |
42 | struct unity_map_entry *e); | 45 | struct unity_map_entry *e); |
43 | 46 | ||
47 | /* returns !0 if the IOMMU is caching non-present entries in its TLB */ | ||
44 | static int iommu_has_npcache(struct amd_iommu *iommu) | 48 | static int iommu_has_npcache(struct amd_iommu *iommu) |
45 | { | 49 | { |
46 | return iommu->cap & IOMMU_CAP_NPCACHE; | 50 | return iommu->cap & IOMMU_CAP_NPCACHE; |
47 | } | 51 | } |
48 | 52 | ||
53 | /**************************************************************************** | ||
54 | * | ||
55 | * IOMMU command queuing functions | ||
56 | * | ||
57 | ****************************************************************************/ | ||
58 | |||
59 | /* | ||
60 | * Writes the command to the IOMMUs command buffer and informs the | ||
61 | * hardware about the new command. Must be called with iommu->lock held. | ||
62 | */ | ||
49 | static int __iommu_queue_command(struct amd_iommu *iommu, struct command *cmd) | 63 | static int __iommu_queue_command(struct amd_iommu *iommu, struct command *cmd) |
50 | { | 64 | { |
51 | u32 tail, head; | 65 | u32 tail, head; |
@@ -63,6 +77,10 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct command *cmd) | |||
63 | return 0; | 77 | return 0; |
64 | } | 78 | } |
65 | 79 | ||
80 | /* | ||
81 | * General queuing function for commands. Takes iommu->lock and calls | ||
82 | * __iommu_queue_command(). | ||
83 | */ | ||
66 | static int iommu_queue_command(struct amd_iommu *iommu, struct command *cmd) | 84 | static int iommu_queue_command(struct amd_iommu *iommu, struct command *cmd) |
67 | { | 85 | { |
68 | unsigned long flags; | 86 | unsigned long flags; |
@@ -75,6 +93,13 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct command *cmd) | |||
75 | return ret; | 93 | return ret; |
76 | } | 94 | } |
77 | 95 | ||
96 | /* | ||
97 | * This function is called whenever we need to ensure that the IOMMU has | ||
98 | * completed execution of all commands we sent. It sends a | ||
99 | * COMPLETION_WAIT command and waits for it to finish. The IOMMU informs | ||
100 | * us about that by writing a value to a physical address we pass with | ||
101 | * the command. | ||
102 | */ | ||
78 | static int iommu_completion_wait(struct amd_iommu *iommu) | 103 | static int iommu_completion_wait(struct amd_iommu *iommu) |
79 | { | 104 | { |
80 | int ret; | 105 | int ret; |
@@ -101,6 +126,9 @@ static int iommu_completion_wait(struct amd_iommu *iommu) | |||
101 | return 0; | 126 | return 0; |
102 | } | 127 | } |
103 | 128 | ||
129 | /* | ||
130 | * Command send function for invalidating a device table entry | ||
131 | */ | ||
104 | static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid) | 132 | static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid) |
105 | { | 133 | { |
106 | struct command cmd; | 134 | struct command cmd; |
@@ -116,6 +144,9 @@ static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid) | |||
116 | return iommu_queue_command(iommu, &cmd); | 144 | return iommu_queue_command(iommu, &cmd); |
117 | } | 145 | } |
118 | 146 | ||
147 | /* | ||
148 | * Generic command send function for invalidaing TLB entries | ||
149 | */ | ||
119 | static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, | 150 | static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, |
120 | u64 address, u16 domid, int pde, int s) | 151 | u64 address, u16 domid, int pde, int s) |
121 | { | 152 | { |
@@ -127,9 +158,9 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, | |||
127 | cmd.data[1] |= domid; | 158 | cmd.data[1] |= domid; |
128 | cmd.data[2] = LOW_U32(address); | 159 | cmd.data[2] = LOW_U32(address); |
129 | cmd.data[3] = HIGH_U32(address); | 160 | cmd.data[3] = HIGH_U32(address); |
130 | if (s) | 161 | if (s) /* size bit - we flush more than one 4kb page */ |
131 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; | 162 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK; |
132 | if (pde) | 163 | if (pde) /* PDE bit - we wan't flush everything not only the PTEs */ |
133 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK; | 164 | cmd.data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK; |
134 | 165 | ||
135 | iommu->need_sync = 1; | 166 | iommu->need_sync = 1; |
@@ -137,6 +168,11 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu, | |||
137 | return iommu_queue_command(iommu, &cmd); | 168 | return iommu_queue_command(iommu, &cmd); |
138 | } | 169 | } |
139 | 170 | ||
171 | /* | ||
172 | * TLB invalidation function which is called from the mapping functions. | ||
173 | * It invalidates a single PTE if the range to flush is within a single | ||
174 | * page. Otherwise it flushes the whole TLB of the IOMMU. | ||
175 | */ | ||
140 | static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid, | 176 | static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid, |
141 | u64 address, size_t size) | 177 | u64 address, size_t size) |
142 | { | 178 | { |
@@ -159,6 +195,20 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid, | |||
159 | return 0; | 195 | return 0; |
160 | } | 196 | } |
161 | 197 | ||
198 | /**************************************************************************** | ||
199 | * | ||
200 | * The functions below are used the create the page table mappings for | ||
201 | * unity mapped regions. | ||
202 | * | ||
203 | ****************************************************************************/ | ||
204 | |||
205 | /* | ||
206 | * Generic mapping functions. It maps a physical address into a DMA | ||
207 | * address space. It allocates the page table pages if necessary. | ||
208 | * In the future it can be extended to a generic mapping function | ||
209 | * supporting all features of AMD IOMMU page tables like level skipping | ||
210 | * and full 64 bit address spaces. | ||
211 | */ | ||
162 | static int iommu_map(struct protection_domain *dom, | 212 | static int iommu_map(struct protection_domain *dom, |
163 | unsigned long bus_addr, | 213 | unsigned long bus_addr, |
164 | unsigned long phys_addr, | 214 | unsigned long phys_addr, |
@@ -209,6 +259,10 @@ static int iommu_map(struct protection_domain *dom, | |||
209 | return 0; | 259 | return 0; |
210 | } | 260 | } |
211 | 261 | ||
262 | /* | ||
263 | * This function checks if a specific unity mapping entry is needed for | ||
264 | * this specific IOMMU. | ||
265 | */ | ||
212 | static int iommu_for_unity_map(struct amd_iommu *iommu, | 266 | static int iommu_for_unity_map(struct amd_iommu *iommu, |
213 | struct unity_map_entry *entry) | 267 | struct unity_map_entry *entry) |
214 | { | 268 | { |
@@ -223,6 +277,12 @@ static int iommu_for_unity_map(struct amd_iommu *iommu, | |||
223 | return 0; | 277 | return 0; |
224 | } | 278 | } |
225 | 279 | ||
280 | /* | ||
281 | * Init the unity mappings for a specific IOMMU in the system | ||
282 | * | ||
283 | * Basically iterates over all unity mapping entries and applies them to | ||
284 | * the default domain DMA of that IOMMU if necessary. | ||
285 | */ | ||
226 | static int iommu_init_unity_mappings(struct amd_iommu *iommu) | 286 | static int iommu_init_unity_mappings(struct amd_iommu *iommu) |
227 | { | 287 | { |
228 | struct unity_map_entry *entry; | 288 | struct unity_map_entry *entry; |
@@ -239,6 +299,10 @@ static int iommu_init_unity_mappings(struct amd_iommu *iommu) | |||
239 | return 0; | 299 | return 0; |
240 | } | 300 | } |
241 | 301 | ||
302 | /* | ||
303 | * This function actually applies the mapping to the page table of the | ||
304 | * dma_ops domain. | ||
305 | */ | ||
242 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | 306 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, |
243 | struct unity_map_entry *e) | 307 | struct unity_map_entry *e) |
244 | { | 308 | { |
@@ -261,6 +325,9 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | |||
261 | return 0; | 325 | return 0; |
262 | } | 326 | } |
263 | 327 | ||
328 | /* | ||
329 | * Inits the unity mappings required for a specific device | ||
330 | */ | ||
264 | static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom, | 331 | static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom, |
265 | u16 devid) | 332 | u16 devid) |
266 | { | 333 | { |
@@ -278,12 +345,26 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom, | |||
278 | return 0; | 345 | return 0; |
279 | } | 346 | } |
280 | 347 | ||
348 | /**************************************************************************** | ||
349 | * | ||
350 | * The next functions belong to the address allocator for the dma_ops | ||
351 | * interface functions. They work like the allocators in the other IOMMU | ||
352 | * drivers. Its basically a bitmap which marks the allocated pages in | ||
353 | * the aperture. Maybe it could be enhanced in the future to a more | ||
354 | * efficient allocator. | ||
355 | * | ||
356 | ****************************************************************************/ | ||
281 | static unsigned long dma_mask_to_pages(unsigned long mask) | 357 | static unsigned long dma_mask_to_pages(unsigned long mask) |
282 | { | 358 | { |
283 | return (mask >> PAGE_SHIFT) + | 359 | return (mask >> PAGE_SHIFT) + |
284 | (PAGE_ALIGN(mask & ~PAGE_MASK) >> PAGE_SHIFT); | 360 | (PAGE_ALIGN(mask & ~PAGE_MASK) >> PAGE_SHIFT); |
285 | } | 361 | } |
286 | 362 | ||
363 | /* | ||
364 | * The address allocator core function. | ||
365 | * | ||
366 | * called with domain->lock held | ||
367 | */ | ||
287 | static unsigned long dma_ops_alloc_addresses(struct device *dev, | 368 | static unsigned long dma_ops_alloc_addresses(struct device *dev, |
288 | struct dma_ops_domain *dom, | 369 | struct dma_ops_domain *dom, |
289 | unsigned int pages) | 370 | unsigned int pages) |
@@ -317,6 +398,11 @@ static unsigned long dma_ops_alloc_addresses(struct device *dev, | |||
317 | return address; | 398 | return address; |
318 | } | 399 | } |
319 | 400 | ||
401 | /* | ||
402 | * The address free function. | ||
403 | * | ||
404 | * called with domain->lock held | ||
405 | */ | ||
320 | static void dma_ops_free_addresses(struct dma_ops_domain *dom, | 406 | static void dma_ops_free_addresses(struct dma_ops_domain *dom, |
321 | unsigned long address, | 407 | unsigned long address, |
322 | unsigned int pages) | 408 | unsigned int pages) |
@@ -325,6 +411,16 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom, | |||
325 | iommu_area_free(dom->bitmap, address, pages); | 411 | iommu_area_free(dom->bitmap, address, pages); |
326 | } | 412 | } |
327 | 413 | ||
414 | /**************************************************************************** | ||
415 | * | ||
416 | * The next functions belong to the domain allocation. A domain is | ||
417 | * allocated for every IOMMU as the default domain. If device isolation | ||
418 | * is enabled, every device get its own domain. The most important thing | ||
419 | * about domains is the page table mapping the DMA address space they | ||
420 | * contain. | ||
421 | * | ||
422 | ****************************************************************************/ | ||
423 | |||
328 | static u16 domain_id_alloc(void) | 424 | static u16 domain_id_alloc(void) |
329 | { | 425 | { |
330 | unsigned long flags; | 426 | unsigned long flags; |
@@ -342,6 +438,10 @@ static u16 domain_id_alloc(void) | |||
342 | return id; | 438 | return id; |
343 | } | 439 | } |
344 | 440 | ||
441 | /* | ||
442 | * Used to reserve address ranges in the aperture (e.g. for exclusion | ||
443 | * ranges. | ||
444 | */ | ||
345 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | 445 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, |
346 | unsigned long start_page, | 446 | unsigned long start_page, |
347 | unsigned int pages) | 447 | unsigned int pages) |
@@ -382,6 +482,10 @@ static void dma_ops_free_pagetable(struct dma_ops_domain *dma_dom) | |||
382 | free_page((unsigned long)p1); | 482 | free_page((unsigned long)p1); |
383 | } | 483 | } |
384 | 484 | ||
485 | /* | ||
486 | * Free a domain, only used if something went wrong in the | ||
487 | * allocation path and we need to free an already allocated page table | ||
488 | */ | ||
385 | static void dma_ops_domain_free(struct dma_ops_domain *dom) | 489 | static void dma_ops_domain_free(struct dma_ops_domain *dom) |
386 | { | 490 | { |
387 | if (!dom) | 491 | if (!dom) |
@@ -396,6 +500,11 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom) | |||
396 | kfree(dom); | 500 | kfree(dom); |
397 | } | 501 | } |
398 | 502 | ||
503 | /* | ||
504 | * Allocates a new protection domain usable for the dma_ops functions. | ||
505 | * It also intializes the page table and the address allocator data | ||
506 | * structures required for the dma_ops interface | ||
507 | */ | ||
399 | static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | 508 | static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, |
400 | unsigned order) | 509 | unsigned order) |
401 | { | 510 | { |
@@ -436,6 +545,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | |||
436 | dma_dom->bitmap[0] = 1; | 545 | dma_dom->bitmap[0] = 1; |
437 | dma_dom->next_bit = 0; | 546 | dma_dom->next_bit = 0; |
438 | 547 | ||
548 | /* Intialize the exclusion range if necessary */ | ||
439 | if (iommu->exclusion_start && | 549 | if (iommu->exclusion_start && |
440 | iommu->exclusion_start < dma_dom->aperture_size) { | 550 | iommu->exclusion_start < dma_dom->aperture_size) { |
441 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; | 551 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; |
@@ -444,6 +554,11 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | |||
444 | dma_ops_reserve_addresses(dma_dom, startpage, pages); | 554 | dma_ops_reserve_addresses(dma_dom, startpage, pages); |
445 | } | 555 | } |
446 | 556 | ||
557 | /* | ||
558 | * At the last step, build the page tables so we don't need to | ||
559 | * allocate page table pages in the dma_ops mapping/unmapping | ||
560 | * path. | ||
561 | */ | ||
447 | num_pte_pages = dma_dom->aperture_size / (PAGE_SIZE * 512); | 562 | num_pte_pages = dma_dom->aperture_size / (PAGE_SIZE * 512); |
448 | dma_dom->pte_pages = kzalloc(num_pte_pages * sizeof(void *), | 563 | dma_dom->pte_pages = kzalloc(num_pte_pages * sizeof(void *), |
449 | GFP_KERNEL); | 564 | GFP_KERNEL); |
@@ -472,6 +587,10 @@ free_dma_dom: | |||
472 | return NULL; | 587 | return NULL; |
473 | } | 588 | } |
474 | 589 | ||
590 | /* | ||
591 | * Find out the protection domain structure for a given PCI device. This | ||
592 | * will give us the pointer to the page table root for example. | ||
593 | */ | ||
475 | static struct protection_domain *domain_for_device(u16 devid) | 594 | static struct protection_domain *domain_for_device(u16 devid) |
476 | { | 595 | { |
477 | struct protection_domain *dom; | 596 | struct protection_domain *dom; |
@@ -484,6 +603,10 @@ static struct protection_domain *domain_for_device(u16 devid) | |||
484 | return dom; | 603 | return dom; |
485 | } | 604 | } |
486 | 605 | ||
606 | /* | ||
607 | * If a device is not yet associated with a domain, this function does | ||
608 | * assigns it visible for the hardware | ||
609 | */ | ||
487 | static void set_device_domain(struct amd_iommu *iommu, | 610 | static void set_device_domain(struct amd_iommu *iommu, |
488 | struct protection_domain *domain, | 611 | struct protection_domain *domain, |
489 | u16 devid) | 612 | u16 devid) |
@@ -508,6 +631,19 @@ static void set_device_domain(struct amd_iommu *iommu, | |||
508 | iommu->need_sync = 1; | 631 | iommu->need_sync = 1; |
509 | } | 632 | } |
510 | 633 | ||
634 | /***************************************************************************** | ||
635 | * | ||
636 | * The next functions belong to the dma_ops mapping/unmapping code. | ||
637 | * | ||
638 | *****************************************************************************/ | ||
639 | |||
640 | /* | ||
641 | * In the dma_ops path we only have the struct device. This function | ||
642 | * finds the corresponding IOMMU, the protection domain and the | ||
643 | * requestor id for a given device. | ||
644 | * If the device is not yet associated with a domain this is also done | ||
645 | * in this function. | ||
646 | */ | ||
511 | static int get_device_resources(struct device *dev, | 647 | static int get_device_resources(struct device *dev, |
512 | struct amd_iommu **iommu, | 648 | struct amd_iommu **iommu, |
513 | struct protection_domain **domain, | 649 | struct protection_domain **domain, |
@@ -522,6 +658,7 @@ static int get_device_resources(struct device *dev, | |||
522 | pcidev = to_pci_dev(dev); | 658 | pcidev = to_pci_dev(dev); |
523 | _bdf = (pcidev->bus->number << 8) | pcidev->devfn; | 659 | _bdf = (pcidev->bus->number << 8) | pcidev->devfn; |
524 | 660 | ||
661 | /* device not translated by any IOMMU in the system? */ | ||
525 | if (_bdf >= amd_iommu_last_bdf) { | 662 | if (_bdf >= amd_iommu_last_bdf) { |
526 | *iommu = NULL; | 663 | *iommu = NULL; |
527 | *domain = NULL; | 664 | *domain = NULL; |
@@ -547,6 +684,10 @@ static int get_device_resources(struct device *dev, | |||
547 | return 1; | 684 | return 1; |
548 | } | 685 | } |
549 | 686 | ||
687 | /* | ||
688 | * This is the generic map function. It maps one 4kb page at paddr to | ||
689 | * the given address in the DMA address space for the domain. | ||
690 | */ | ||
550 | static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu, | 691 | static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu, |
551 | struct dma_ops_domain *dom, | 692 | struct dma_ops_domain *dom, |
552 | unsigned long address, | 693 | unsigned long address, |
@@ -578,6 +719,9 @@ static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu, | |||
578 | return (dma_addr_t)address; | 719 | return (dma_addr_t)address; |
579 | } | 720 | } |
580 | 721 | ||
722 | /* | ||
723 | * The generic unmapping function for on page in the DMA address space. | ||
724 | */ | ||
581 | static void dma_ops_domain_unmap(struct amd_iommu *iommu, | 725 | static void dma_ops_domain_unmap(struct amd_iommu *iommu, |
582 | struct dma_ops_domain *dom, | 726 | struct dma_ops_domain *dom, |
583 | unsigned long address) | 727 | unsigned long address) |
@@ -597,6 +741,12 @@ static void dma_ops_domain_unmap(struct amd_iommu *iommu, | |||
597 | *pte = 0ULL; | 741 | *pte = 0ULL; |
598 | } | 742 | } |
599 | 743 | ||
744 | /* | ||
745 | * This function contains common code for mapping of a physically | ||
746 | * contiguous memory region into DMA address space. It is uses by all | ||
747 | * mapping functions provided by this IOMMU driver. | ||
748 | * Must be called with the domain lock held. | ||
749 | */ | ||
600 | static dma_addr_t __map_single(struct device *dev, | 750 | static dma_addr_t __map_single(struct device *dev, |
601 | struct amd_iommu *iommu, | 751 | struct amd_iommu *iommu, |
602 | struct dma_ops_domain *dma_dom, | 752 | struct dma_ops_domain *dma_dom, |
@@ -628,6 +778,10 @@ out: | |||
628 | return address; | 778 | return address; |
629 | } | 779 | } |
630 | 780 | ||
781 | /* | ||
782 | * Does the reverse of the __map_single function. Must be called with | ||
783 | * the domain lock held too | ||
784 | */ | ||
631 | static void __unmap_single(struct amd_iommu *iommu, | 785 | static void __unmap_single(struct amd_iommu *iommu, |
632 | struct dma_ops_domain *dma_dom, | 786 | struct dma_ops_domain *dma_dom, |
633 | dma_addr_t dma_addr, | 787 | dma_addr_t dma_addr, |
@@ -652,6 +806,9 @@ static void __unmap_single(struct amd_iommu *iommu, | |||
652 | dma_ops_free_addresses(dma_dom, dma_addr, pages); | 806 | dma_ops_free_addresses(dma_dom, dma_addr, pages); |
653 | } | 807 | } |
654 | 808 | ||
809 | /* | ||
810 | * The exported map_single function for dma_ops. | ||
811 | */ | ||
655 | static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, | 812 | static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, |
656 | size_t size, int dir) | 813 | size_t size, int dir) |
657 | { | 814 | { |
@@ -664,6 +821,7 @@ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr, | |||
664 | get_device_resources(dev, &iommu, &domain, &devid); | 821 | get_device_resources(dev, &iommu, &domain, &devid); |
665 | 822 | ||
666 | if (iommu == NULL || domain == NULL) | 823 | if (iommu == NULL || domain == NULL) |
824 | /* device not handled by any AMD IOMMU */ | ||
667 | return (dma_addr_t)paddr; | 825 | return (dma_addr_t)paddr; |
668 | 826 | ||
669 | spin_lock_irqsave(&domain->lock, flags); | 827 | spin_lock_irqsave(&domain->lock, flags); |
@@ -683,6 +841,9 @@ out: | |||
683 | return addr; | 841 | return addr; |
684 | } | 842 | } |
685 | 843 | ||
844 | /* | ||
845 | * The exported unmap_single function for dma_ops. | ||
846 | */ | ||
686 | static void unmap_single(struct device *dev, dma_addr_t dma_addr, | 847 | static void unmap_single(struct device *dev, dma_addr_t dma_addr, |
687 | size_t size, int dir) | 848 | size_t size, int dir) |
688 | { | 849 | { |
@@ -692,6 +853,7 @@ static void unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
692 | u16 devid; | 853 | u16 devid; |
693 | 854 | ||
694 | if (!get_device_resources(dev, &iommu, &domain, &devid)) | 855 | if (!get_device_resources(dev, &iommu, &domain, &devid)) |
856 | /* device not handled by any AMD IOMMU */ | ||
695 | return; | 857 | return; |
696 | 858 | ||
697 | spin_lock_irqsave(&domain->lock, flags); | 859 | spin_lock_irqsave(&domain->lock, flags); |
@@ -706,6 +868,10 @@ static void unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
706 | spin_unlock_irqrestore(&domain->lock, flags); | 868 | spin_unlock_irqrestore(&domain->lock, flags); |
707 | } | 869 | } |
708 | 870 | ||
871 | /* | ||
872 | * This is a special map_sg function which is used if we should map a | ||
873 | * device which is not handled by an AMD IOMMU in the system. | ||
874 | */ | ||
709 | static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist, | 875 | static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist, |
710 | int nelems, int dir) | 876 | int nelems, int dir) |
711 | { | 877 | { |
@@ -720,6 +886,10 @@ static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist, | |||
720 | return nelems; | 886 | return nelems; |
721 | } | 887 | } |
722 | 888 | ||
889 | /* | ||
890 | * The exported map_sg function for dma_ops (handles scatter-gather | ||
891 | * lists). | ||
892 | */ | ||
723 | static int map_sg(struct device *dev, struct scatterlist *sglist, | 893 | static int map_sg(struct device *dev, struct scatterlist *sglist, |
724 | int nelems, int dir) | 894 | int nelems, int dir) |
725 | { | 895 | { |
@@ -775,6 +945,10 @@ unmap: | |||
775 | goto out; | 945 | goto out; |
776 | } | 946 | } |
777 | 947 | ||
948 | /* | ||
949 | * The exported map_sg function for dma_ops (handles scatter-gather | ||
950 | * lists). | ||
951 | */ | ||
778 | static void unmap_sg(struct device *dev, struct scatterlist *sglist, | 952 | static void unmap_sg(struct device *dev, struct scatterlist *sglist, |
779 | int nelems, int dir) | 953 | int nelems, int dir) |
780 | { | 954 | { |
@@ -804,6 +978,9 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
804 | spin_unlock_irqrestore(&domain->lock, flags); | 978 | spin_unlock_irqrestore(&domain->lock, flags); |
805 | } | 979 | } |
806 | 980 | ||
981 | /* | ||
982 | * The exported alloc_coherent function for dma_ops. | ||
983 | */ | ||
807 | static void *alloc_coherent(struct device *dev, size_t size, | 984 | static void *alloc_coherent(struct device *dev, size_t size, |
808 | dma_addr_t *dma_addr, gfp_t flag) | 985 | dma_addr_t *dma_addr, gfp_t flag) |
809 | { | 986 | { |
@@ -851,6 +1028,11 @@ out: | |||
851 | return virt_addr; | 1028 | return virt_addr; |
852 | } | 1029 | } |
853 | 1030 | ||
1031 | /* | ||
1032 | * The exported free_coherent function for dma_ops. | ||
1033 | * FIXME: fix the generic x86 DMA layer so that it actually calls that | ||
1034 | * function. | ||
1035 | */ | ||
854 | static void free_coherent(struct device *dev, size_t size, | 1036 | static void free_coherent(struct device *dev, size_t size, |
855 | void *virt_addr, dma_addr_t dma_addr) | 1037 | void *virt_addr, dma_addr_t dma_addr) |
856 | { | 1038 | { |
@@ -879,6 +1061,8 @@ free_mem: | |||
879 | } | 1061 | } |
880 | 1062 | ||
881 | /* | 1063 | /* |
1064 | * The function for pre-allocating protection domains. | ||
1065 | * | ||
882 | * If the driver core informs the DMA layer if a driver grabs a device | 1066 | * If the driver core informs the DMA layer if a driver grabs a device |
883 | * we don't need to preallocate the protection domains anymore. | 1067 | * we don't need to preallocate the protection domains anymore. |
884 | * For now we have to. | 1068 | * For now we have to. |
@@ -921,12 +1105,20 @@ static struct dma_mapping_ops amd_iommu_dma_ops = { | |||
921 | .unmap_sg = unmap_sg, | 1105 | .unmap_sg = unmap_sg, |
922 | }; | 1106 | }; |
923 | 1107 | ||
1108 | /* | ||
1109 | * The function which clues the AMD IOMMU driver into dma_ops. | ||
1110 | */ | ||
924 | int __init amd_iommu_init_dma_ops(void) | 1111 | int __init amd_iommu_init_dma_ops(void) |
925 | { | 1112 | { |
926 | struct amd_iommu *iommu; | 1113 | struct amd_iommu *iommu; |
927 | int order = amd_iommu_aperture_order; | 1114 | int order = amd_iommu_aperture_order; |
928 | int ret; | 1115 | int ret; |
929 | 1116 | ||
1117 | /* | ||
1118 | * first allocate a default protection domain for every IOMMU we | ||
1119 | * found in the system. Devices not assigned to any other | ||
1120 | * protection domain will be assigned to the default one. | ||
1121 | */ | ||
930 | list_for_each_entry(iommu, &amd_iommu_list, list) { | 1122 | list_for_each_entry(iommu, &amd_iommu_list, list) { |
931 | iommu->default_dom = dma_ops_domain_alloc(iommu, order); | 1123 | iommu->default_dom = dma_ops_domain_alloc(iommu, order); |
932 | if (iommu->default_dom == NULL) | 1124 | if (iommu->default_dom == NULL) |
@@ -936,6 +1128,10 @@ int __init amd_iommu_init_dma_ops(void) | |||
936 | goto free_domains; | 1128 | goto free_domains; |
937 | } | 1129 | } |
938 | 1130 | ||
1131 | /* | ||
1132 | * If device isolation is enabled, pre-allocate the protection | ||
1133 | * domains for each device. | ||
1134 | */ | ||
939 | if (amd_iommu_isolate) | 1135 | if (amd_iommu_isolate) |
940 | prealloc_protection_domains(); | 1136 | prealloc_protection_domains(); |
941 | 1137 | ||
@@ -947,6 +1143,7 @@ int __init amd_iommu_init_dma_ops(void) | |||
947 | gart_iommu_aperture = 0; | 1143 | gart_iommu_aperture = 0; |
948 | #endif | 1144 | #endif |
949 | 1145 | ||
1146 | /* Make the driver finally visible to the drivers */ | ||
950 | dma_ops = &amd_iommu_dma_ops; | 1147 | dma_ops = &amd_iommu_dma_ops; |
951 | 1148 | ||
952 | return 0; | 1149 | return 0; |