blob: 1c0270d3e2e55c9d232841164b91bf132a54ae4c [file] [log] [blame]
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001/*
2 * Copyright (c) 2006, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
mark gross98bcef52008-02-23 15:23:35 -080017 * Copyright (C) 2006-2008 Intel Corporation
18 * Author: Ashok Raj <ashok.raj@intel.com>
19 * Author: Shaohua Li <shaohua.li@intel.com>
20 * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070021 */
22
23#include <linux/init.h>
24#include <linux/bitmap.h>
mark gross5e0d2a62008-03-04 15:22:08 -080025#include <linux/debugfs.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070026#include <linux/slab.h>
27#include <linux/irq.h>
28#include <linux/interrupt.h>
29#include <linux/sysdev.h>
30#include <linux/spinlock.h>
31#include <linux/pci.h>
32#include <linux/dmar.h>
33#include <linux/dma-mapping.h>
34#include <linux/mempool.h>
mark gross5e0d2a62008-03-04 15:22:08 -080035#include <linux/timer.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070036#include "iova.h"
37#include "intel-iommu.h"
38#include <asm/proto.h> /* force_iommu in this header in x86-64*/
39#include <asm/cacheflush.h>
Joerg Roedel395624f2007-10-24 12:49:47 +020040#include <asm/gart.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070041#include "pci.h"
42
43#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
44#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
45
46#define IOAPIC_RANGE_START (0xfee00000)
47#define IOAPIC_RANGE_END (0xfeefffff)
48#define IOVA_START_ADDR (0x1000)
49
50#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
51
mark grossa7eb08c2008-05-12 13:41:57 -070052#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070053
54#define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
55
mark gross5e0d2a62008-03-04 15:22:08 -080056
57static void flush_unmaps_timeout(unsigned long data);
58
59DEFINE_TIMER(unmap_timer, flush_unmaps_timeout, 0, 0);
60
61static struct intel_iommu *g_iommus;
mark gross80b20dd2008-04-18 13:53:58 -070062
63#define HIGH_WATER_MARK 250
64struct deferred_flush_tables {
65 int next;
66 struct iova *iova[HIGH_WATER_MARK];
67 struct dmar_domain *domain[HIGH_WATER_MARK];
68};
69
70static struct deferred_flush_tables *deferred_flush;
71
mark gross5e0d2a62008-03-04 15:22:08 -080072/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -080073static int g_num_of_iommus;
74
75static DEFINE_SPINLOCK(async_umap_flush_lock);
76static LIST_HEAD(unmaps_to_do);
77
78static int timer_on;
79static long list_size;
mark gross5e0d2a62008-03-04 15:22:08 -080080
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070081static void domain_remove_dev_info(struct dmar_domain *domain);
82
83static int dmar_disabled;
84static int __initdata dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -070085static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -080086static int intel_iommu_strict;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070087
88#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
89static DEFINE_SPINLOCK(device_domain_lock);
90static LIST_HEAD(device_domain_list);
91
92static int __init intel_iommu_setup(char *str)
93{
94 if (!str)
95 return -EINVAL;
96 while (*str) {
97 if (!strncmp(str, "off", 3)) {
98 dmar_disabled = 1;
99 printk(KERN_INFO"Intel-IOMMU: disabled\n");
100 } else if (!strncmp(str, "igfx_off", 8)) {
101 dmar_map_gfx = 0;
102 printk(KERN_INFO
103 "Intel-IOMMU: disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700104 } else if (!strncmp(str, "forcedac", 8)) {
mark gross5e0d2a62008-03-04 15:22:08 -0800105 printk(KERN_INFO
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700106 "Intel-IOMMU: Forcing DAC for PCI devices\n");
107 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800108 } else if (!strncmp(str, "strict", 6)) {
109 printk(KERN_INFO
110 "Intel-IOMMU: disable batched IOTLB flush\n");
111 intel_iommu_strict = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700112 }
113
114 str += strcspn(str, ",");
115 while (*str == ',')
116 str++;
117 }
118 return 0;
119}
120__setup("intel_iommu=", intel_iommu_setup);
121
122static struct kmem_cache *iommu_domain_cache;
123static struct kmem_cache *iommu_devinfo_cache;
124static struct kmem_cache *iommu_iova_cache;
125
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700126static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep)
127{
128 unsigned int flags;
129 void *vaddr;
130
131 /* trying to avoid low memory issues */
132 flags = current->flags & PF_MEMALLOC;
133 current->flags |= PF_MEMALLOC;
134 vaddr = kmem_cache_alloc(cachep, GFP_ATOMIC);
135 current->flags &= (~PF_MEMALLOC | flags);
136 return vaddr;
137}
138
139
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700140static inline void *alloc_pgtable_page(void)
141{
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700142 unsigned int flags;
143 void *vaddr;
144
145 /* trying to avoid low memory issues */
146 flags = current->flags & PF_MEMALLOC;
147 current->flags |= PF_MEMALLOC;
148 vaddr = (void *)get_zeroed_page(GFP_ATOMIC);
149 current->flags &= (~PF_MEMALLOC | flags);
150 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700151}
152
153static inline void free_pgtable_page(void *vaddr)
154{
155 free_page((unsigned long)vaddr);
156}
157
158static inline void *alloc_domain_mem(void)
159{
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700160 return iommu_kmem_cache_alloc(iommu_domain_cache);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700161}
162
163static inline void free_domain_mem(void *vaddr)
164{
165 kmem_cache_free(iommu_domain_cache, vaddr);
166}
167
168static inline void * alloc_devinfo_mem(void)
169{
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700170 return iommu_kmem_cache_alloc(iommu_devinfo_cache);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700171}
172
173static inline void free_devinfo_mem(void *vaddr)
174{
175 kmem_cache_free(iommu_devinfo_cache, vaddr);
176}
177
178struct iova *alloc_iova_mem(void)
179{
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700180 return iommu_kmem_cache_alloc(iommu_iova_cache);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700181}
182
183void free_iova_mem(struct iova *iova)
184{
185 kmem_cache_free(iommu_iova_cache, iova);
186}
187
188static inline void __iommu_flush_cache(
189 struct intel_iommu *iommu, void *addr, int size)
190{
191 if (!ecap_coherent(iommu->ecap))
192 clflush_cache_range(addr, size);
193}
194
195/* Gets context entry for a given bus and devfn */
196static struct context_entry * device_to_context_entry(struct intel_iommu *iommu,
197 u8 bus, u8 devfn)
198{
199 struct root_entry *root;
200 struct context_entry *context;
201 unsigned long phy_addr;
202 unsigned long flags;
203
204 spin_lock_irqsave(&iommu->lock, flags);
205 root = &iommu->root_entry[bus];
206 context = get_context_addr_from_root(root);
207 if (!context) {
208 context = (struct context_entry *)alloc_pgtable_page();
209 if (!context) {
210 spin_unlock_irqrestore(&iommu->lock, flags);
211 return NULL;
212 }
213 __iommu_flush_cache(iommu, (void *)context, PAGE_SIZE_4K);
214 phy_addr = virt_to_phys((void *)context);
215 set_root_value(root, phy_addr);
216 set_root_present(root);
217 __iommu_flush_cache(iommu, root, sizeof(*root));
218 }
219 spin_unlock_irqrestore(&iommu->lock, flags);
220 return &context[devfn];
221}
222
223static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
224{
225 struct root_entry *root;
226 struct context_entry *context;
227 int ret;
228 unsigned long flags;
229
230 spin_lock_irqsave(&iommu->lock, flags);
231 root = &iommu->root_entry[bus];
232 context = get_context_addr_from_root(root);
233 if (!context) {
234 ret = 0;
235 goto out;
236 }
237 ret = context_present(context[devfn]);
238out:
239 spin_unlock_irqrestore(&iommu->lock, flags);
240 return ret;
241}
242
243static void clear_context_table(struct intel_iommu *iommu, u8 bus, u8 devfn)
244{
245 struct root_entry *root;
246 struct context_entry *context;
247 unsigned long flags;
248
249 spin_lock_irqsave(&iommu->lock, flags);
250 root = &iommu->root_entry[bus];
251 context = get_context_addr_from_root(root);
252 if (context) {
253 context_clear_entry(context[devfn]);
254 __iommu_flush_cache(iommu, &context[devfn], \
255 sizeof(*context));
256 }
257 spin_unlock_irqrestore(&iommu->lock, flags);
258}
259
260static void free_context_table(struct intel_iommu *iommu)
261{
262 struct root_entry *root;
263 int i;
264 unsigned long flags;
265 struct context_entry *context;
266
267 spin_lock_irqsave(&iommu->lock, flags);
268 if (!iommu->root_entry) {
269 goto out;
270 }
271 for (i = 0; i < ROOT_ENTRY_NR; i++) {
272 root = &iommu->root_entry[i];
273 context = get_context_addr_from_root(root);
274 if (context)
275 free_pgtable_page(context);
276 }
277 free_pgtable_page(iommu->root_entry);
278 iommu->root_entry = NULL;
279out:
280 spin_unlock_irqrestore(&iommu->lock, flags);
281}
282
283/* page table handling */
284#define LEVEL_STRIDE (9)
285#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
286
287static inline int agaw_to_level(int agaw)
288{
289 return agaw + 2;
290}
291
292static inline int agaw_to_width(int agaw)
293{
294 return 30 + agaw * LEVEL_STRIDE;
295
296}
297
298static inline int width_to_agaw(int width)
299{
300 return (width - 30) / LEVEL_STRIDE;
301}
302
303static inline unsigned int level_to_offset_bits(int level)
304{
305 return (12 + (level - 1) * LEVEL_STRIDE);
306}
307
308static inline int address_level_offset(u64 addr, int level)
309{
310 return ((addr >> level_to_offset_bits(level)) & LEVEL_MASK);
311}
312
313static inline u64 level_mask(int level)
314{
315 return ((u64)-1 << level_to_offset_bits(level));
316}
317
318static inline u64 level_size(int level)
319{
320 return ((u64)1 << level_to_offset_bits(level));
321}
322
323static inline u64 align_to_level(u64 addr, int level)
324{
325 return ((addr + level_size(level) - 1) & level_mask(level));
326}
327
328static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr)
329{
330 int addr_width = agaw_to_width(domain->agaw);
331 struct dma_pte *parent, *pte = NULL;
332 int level = agaw_to_level(domain->agaw);
333 int offset;
334 unsigned long flags;
335
336 BUG_ON(!domain->pgd);
337
338 addr &= (((u64)1) << addr_width) - 1;
339 parent = domain->pgd;
340
341 spin_lock_irqsave(&domain->mapping_lock, flags);
342 while (level > 0) {
343 void *tmp_page;
344
345 offset = address_level_offset(addr, level);
346 pte = &parent[offset];
347 if (level == 1)
348 break;
349
350 if (!dma_pte_present(*pte)) {
351 tmp_page = alloc_pgtable_page();
352
353 if (!tmp_page) {
354 spin_unlock_irqrestore(&domain->mapping_lock,
355 flags);
356 return NULL;
357 }
358 __iommu_flush_cache(domain->iommu, tmp_page,
359 PAGE_SIZE_4K);
360 dma_set_pte_addr(*pte, virt_to_phys(tmp_page));
361 /*
362 * high level table always sets r/w, last level page
363 * table control read/write
364 */
365 dma_set_pte_readable(*pte);
366 dma_set_pte_writable(*pte);
367 __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
368 }
369 parent = phys_to_virt(dma_pte_addr(*pte));
370 level--;
371 }
372
373 spin_unlock_irqrestore(&domain->mapping_lock, flags);
374 return pte;
375}
376
377/* return address's pte at specific level */
378static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr,
379 int level)
380{
381 struct dma_pte *parent, *pte = NULL;
382 int total = agaw_to_level(domain->agaw);
383 int offset;
384
385 parent = domain->pgd;
386 while (level <= total) {
387 offset = address_level_offset(addr, total);
388 pte = &parent[offset];
389 if (level == total)
390 return pte;
391
392 if (!dma_pte_present(*pte))
393 break;
394 parent = phys_to_virt(dma_pte_addr(*pte));
395 total--;
396 }
397 return NULL;
398}
399
400/* clear one page's page table */
401static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr)
402{
403 struct dma_pte *pte = NULL;
404
405 /* get last level pte */
406 pte = dma_addr_level_pte(domain, addr, 1);
407
408 if (pte) {
409 dma_clear_pte(*pte);
410 __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
411 }
412}
413
414/* clear last level pte, a tlb flush should be followed */
415static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
416{
417 int addr_width = agaw_to_width(domain->agaw);
418
419 start &= (((u64)1) << addr_width) - 1;
420 end &= (((u64)1) << addr_width) - 1;
421 /* in case it's partial page */
422 start = PAGE_ALIGN_4K(start);
423 end &= PAGE_MASK_4K;
424
425 /* we don't need lock here, nobody else touches the iova range */
426 while (start < end) {
427 dma_pte_clear_one(domain, start);
428 start += PAGE_SIZE_4K;
429 }
430}
431
432/* free page table pages. last level pte should already be cleared */
433static void dma_pte_free_pagetable(struct dmar_domain *domain,
434 u64 start, u64 end)
435{
436 int addr_width = agaw_to_width(domain->agaw);
437 struct dma_pte *pte;
438 int total = agaw_to_level(domain->agaw);
439 int level;
440 u64 tmp;
441
442 start &= (((u64)1) << addr_width) - 1;
443 end &= (((u64)1) << addr_width) - 1;
444
445 /* we don't need lock here, nobody else touches the iova range */
446 level = 2;
447 while (level <= total) {
448 tmp = align_to_level(start, level);
449 if (tmp >= end || (tmp + level_size(level) > end))
450 return;
451
452 while (tmp < end) {
453 pte = dma_addr_level_pte(domain, tmp, level);
454 if (pte) {
455 free_pgtable_page(
456 phys_to_virt(dma_pte_addr(*pte)));
457 dma_clear_pte(*pte);
458 __iommu_flush_cache(domain->iommu,
459 pte, sizeof(*pte));
460 }
461 tmp += level_size(level);
462 }
463 level++;
464 }
465 /* free pgd */
466 if (start == 0 && end >= ((((u64)1) << addr_width) - 1)) {
467 free_pgtable_page(domain->pgd);
468 domain->pgd = NULL;
469 }
470}
471
472/* iommu handling */
473static int iommu_alloc_root_entry(struct intel_iommu *iommu)
474{
475 struct root_entry *root;
476 unsigned long flags;
477
478 root = (struct root_entry *)alloc_pgtable_page();
479 if (!root)
480 return -ENOMEM;
481
482 __iommu_flush_cache(iommu, root, PAGE_SIZE_4K);
483
484 spin_lock_irqsave(&iommu->lock, flags);
485 iommu->root_entry = root;
486 spin_unlock_irqrestore(&iommu->lock, flags);
487
488 return 0;
489}
490
491#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
492{\
mark grossa7eb08c2008-05-12 13:41:57 -0700493 cycles_t start_time = get_cycles();\
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700494 while (1) {\
495 sts = op (iommu->reg + offset);\
496 if (cond)\
497 break;\
mark grossa7eb08c2008-05-12 13:41:57 -0700498 if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700499 panic("DMAR hardware is malfunctioning\n");\
500 cpu_relax();\
501 }\
502}
503
504static void iommu_set_root_entry(struct intel_iommu *iommu)
505{
506 void *addr;
507 u32 cmd, sts;
508 unsigned long flag;
509
510 addr = iommu->root_entry;
511
512 spin_lock_irqsave(&iommu->register_lock, flag);
513 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, virt_to_phys(addr));
514
515 cmd = iommu->gcmd | DMA_GCMD_SRTP;
516 writel(cmd, iommu->reg + DMAR_GCMD_REG);
517
518 /* Make sure hardware complete it */
519 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
520 readl, (sts & DMA_GSTS_RTPS), sts);
521
522 spin_unlock_irqrestore(&iommu->register_lock, flag);
523}
524
525static void iommu_flush_write_buffer(struct intel_iommu *iommu)
526{
527 u32 val;
528 unsigned long flag;
529
530 if (!cap_rwbf(iommu->cap))
531 return;
532 val = iommu->gcmd | DMA_GCMD_WBF;
533
534 spin_lock_irqsave(&iommu->register_lock, flag);
535 writel(val, iommu->reg + DMAR_GCMD_REG);
536
537 /* Make sure hardware complete it */
538 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
539 readl, (!(val & DMA_GSTS_WBFS)), val);
540
541 spin_unlock_irqrestore(&iommu->register_lock, flag);
542}
543
544/* return value determine if we need a write buffer flush */
545static int __iommu_flush_context(struct intel_iommu *iommu,
546 u16 did, u16 source_id, u8 function_mask, u64 type,
547 int non_present_entry_flush)
548{
549 u64 val = 0;
550 unsigned long flag;
551
552 /*
553 * In the non-present entry flush case, if hardware doesn't cache
554 * non-present entry we do nothing and if hardware cache non-present
555 * entry, we flush entries of domain 0 (the domain id is used to cache
556 * any non-present entries)
557 */
558 if (non_present_entry_flush) {
559 if (!cap_caching_mode(iommu->cap))
560 return 1;
561 else
562 did = 0;
563 }
564
565 switch (type) {
566 case DMA_CCMD_GLOBAL_INVL:
567 val = DMA_CCMD_GLOBAL_INVL;
568 break;
569 case DMA_CCMD_DOMAIN_INVL:
570 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
571 break;
572 case DMA_CCMD_DEVICE_INVL:
573 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
574 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
575 break;
576 default:
577 BUG();
578 }
579 val |= DMA_CCMD_ICC;
580
581 spin_lock_irqsave(&iommu->register_lock, flag);
582 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
583
584 /* Make sure hardware complete it */
585 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
586 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
587
588 spin_unlock_irqrestore(&iommu->register_lock, flag);
589
590 /* flush context entry will implictly flush write buffer */
591 return 0;
592}
593
594static int inline iommu_flush_context_global(struct intel_iommu *iommu,
595 int non_present_entry_flush)
596{
597 return __iommu_flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL,
598 non_present_entry_flush);
599}
600
601static int inline iommu_flush_context_domain(struct intel_iommu *iommu, u16 did,
602 int non_present_entry_flush)
603{
604 return __iommu_flush_context(iommu, did, 0, 0, DMA_CCMD_DOMAIN_INVL,
605 non_present_entry_flush);
606}
607
608static int inline iommu_flush_context_device(struct intel_iommu *iommu,
609 u16 did, u16 source_id, u8 function_mask, int non_present_entry_flush)
610{
611 return __iommu_flush_context(iommu, did, source_id, function_mask,
612 DMA_CCMD_DEVICE_INVL, non_present_entry_flush);
613}
614
615/* return value determine if we need a write buffer flush */
616static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
617 u64 addr, unsigned int size_order, u64 type,
618 int non_present_entry_flush)
619{
620 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
621 u64 val = 0, val_iva = 0;
622 unsigned long flag;
623
624 /*
625 * In the non-present entry flush case, if hardware doesn't cache
626 * non-present entry we do nothing and if hardware cache non-present
627 * entry, we flush entries of domain 0 (the domain id is used to cache
628 * any non-present entries)
629 */
630 if (non_present_entry_flush) {
631 if (!cap_caching_mode(iommu->cap))
632 return 1;
633 else
634 did = 0;
635 }
636
637 switch (type) {
638 case DMA_TLB_GLOBAL_FLUSH:
639 /* global flush doesn't need set IVA_REG */
640 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
641 break;
642 case DMA_TLB_DSI_FLUSH:
643 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
644 break;
645 case DMA_TLB_PSI_FLUSH:
646 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
647 /* Note: always flush non-leaf currently */
648 val_iva = size_order | addr;
649 break;
650 default:
651 BUG();
652 }
653 /* Note: set drain read/write */
654#if 0
655 /*
656 * This is probably to be super secure.. Looks like we can
657 * ignore it without any impact.
658 */
659 if (cap_read_drain(iommu->cap))
660 val |= DMA_TLB_READ_DRAIN;
661#endif
662 if (cap_write_drain(iommu->cap))
663 val |= DMA_TLB_WRITE_DRAIN;
664
665 spin_lock_irqsave(&iommu->register_lock, flag);
666 /* Note: Only uses first TLB reg currently */
667 if (val_iva)
668 dmar_writeq(iommu->reg + tlb_offset, val_iva);
669 dmar_writeq(iommu->reg + tlb_offset + 8, val);
670
671 /* Make sure hardware complete it */
672 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
673 dmar_readq, (!(val & DMA_TLB_IVT)), val);
674
675 spin_unlock_irqrestore(&iommu->register_lock, flag);
676
677 /* check IOTLB invalidation granularity */
678 if (DMA_TLB_IAIG(val) == 0)
679 printk(KERN_ERR"IOMMU: flush IOTLB failed\n");
680 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
681 pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n",
682 DMA_TLB_IIRG(type), DMA_TLB_IAIG(val));
683 /* flush context entry will implictly flush write buffer */
684 return 0;
685}
686
687static int inline iommu_flush_iotlb_global(struct intel_iommu *iommu,
688 int non_present_entry_flush)
689{
690 return __iommu_flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH,
691 non_present_entry_flush);
692}
693
694static int inline iommu_flush_iotlb_dsi(struct intel_iommu *iommu, u16 did,
695 int non_present_entry_flush)
696{
697 return __iommu_flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH,
698 non_present_entry_flush);
699}
700
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700701static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
702 u64 addr, unsigned int pages, int non_present_entry_flush)
703{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -0700704 unsigned int mask;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700705
706 BUG_ON(addr & (~PAGE_MASK_4K));
707 BUG_ON(pages == 0);
708
709 /* Fallback to domain selective flush if no PSI support */
710 if (!cap_pgsel_inv(iommu->cap))
711 return iommu_flush_iotlb_dsi(iommu, did,
712 non_present_entry_flush);
713
714 /*
715 * PSI requires page size to be 2 ^ x, and the base address is naturally
716 * aligned to the size
717 */
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -0700718 mask = ilog2(__roundup_pow_of_two(pages));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700719 /* Fallback to domain selective flush if size is too big */
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -0700720 if (mask > cap_max_amask_val(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700721 return iommu_flush_iotlb_dsi(iommu, did,
722 non_present_entry_flush);
723
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -0700724 return __iommu_flush_iotlb(iommu, did, addr, mask,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700725 DMA_TLB_PSI_FLUSH, non_present_entry_flush);
726}
727
mark grossf8bab732008-02-08 04:18:38 -0800728static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
729{
730 u32 pmen;
731 unsigned long flags;
732
733 spin_lock_irqsave(&iommu->register_lock, flags);
734 pmen = readl(iommu->reg + DMAR_PMEN_REG);
735 pmen &= ~DMA_PMEN_EPM;
736 writel(pmen, iommu->reg + DMAR_PMEN_REG);
737
738 /* wait for the protected region status bit to clear */
739 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
740 readl, !(pmen & DMA_PMEN_PRS), pmen);
741
742 spin_unlock_irqrestore(&iommu->register_lock, flags);
743}
744
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700745static int iommu_enable_translation(struct intel_iommu *iommu)
746{
747 u32 sts;
748 unsigned long flags;
749
750 spin_lock_irqsave(&iommu->register_lock, flags);
751 writel(iommu->gcmd|DMA_GCMD_TE, iommu->reg + DMAR_GCMD_REG);
752
753 /* Make sure hardware complete it */
754 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
755 readl, (sts & DMA_GSTS_TES), sts);
756
757 iommu->gcmd |= DMA_GCMD_TE;
758 spin_unlock_irqrestore(&iommu->register_lock, flags);
759 return 0;
760}
761
762static int iommu_disable_translation(struct intel_iommu *iommu)
763{
764 u32 sts;
765 unsigned long flag;
766
767 spin_lock_irqsave(&iommu->register_lock, flag);
768 iommu->gcmd &= ~DMA_GCMD_TE;
769 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
770
771 /* Make sure hardware complete it */
772 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
773 readl, (!(sts & DMA_GSTS_TES)), sts);
774
775 spin_unlock_irqrestore(&iommu->register_lock, flag);
776 return 0;
777}
778
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -0700779/* iommu interrupt handling. Most stuff are MSI-like. */
780
mark grossd94afc62008-02-08 04:18:39 -0800781static const char *fault_reason_strings[] =
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -0700782{
783 "Software",
784 "Present bit in root entry is clear",
785 "Present bit in context entry is clear",
786 "Invalid context entry",
787 "Access beyond MGAW",
788 "PTE Write access is not set",
789 "PTE Read access is not set",
790 "Next page table ptr is invalid",
791 "Root table address invalid",
792 "Context table ptr is invalid",
793 "non-zero reserved fields in RTP",
794 "non-zero reserved fields in CTP",
795 "non-zero reserved fields in PTE",
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -0700796};
mark grossf8bab732008-02-08 04:18:38 -0800797#define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1)
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -0700798
mark grossd94afc62008-02-08 04:18:39 -0800799const char *dmar_get_fault_reason(u8 fault_reason)
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -0700800{
mark grossd94afc62008-02-08 04:18:39 -0800801 if (fault_reason > MAX_FAULT_REASON_IDX)
802 return "Unknown";
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -0700803 else
804 return fault_reason_strings[fault_reason];
805}
806
807void dmar_msi_unmask(unsigned int irq)
808{
809 struct intel_iommu *iommu = get_irq_data(irq);
810 unsigned long flag;
811
812 /* unmask it */
813 spin_lock_irqsave(&iommu->register_lock, flag);
814 writel(0, iommu->reg + DMAR_FECTL_REG);
815 /* Read a reg to force flush the post write */
816 readl(iommu->reg + DMAR_FECTL_REG);
817 spin_unlock_irqrestore(&iommu->register_lock, flag);
818}
819
820void dmar_msi_mask(unsigned int irq)
821{
822 unsigned long flag;
823 struct intel_iommu *iommu = get_irq_data(irq);
824
825 /* mask it */
826 spin_lock_irqsave(&iommu->register_lock, flag);
827 writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
828 /* Read a reg to force flush the post write */
829 readl(iommu->reg + DMAR_FECTL_REG);
830 spin_unlock_irqrestore(&iommu->register_lock, flag);
831}
832
833void dmar_msi_write(int irq, struct msi_msg *msg)
834{
835 struct intel_iommu *iommu = get_irq_data(irq);
836 unsigned long flag;
837
838 spin_lock_irqsave(&iommu->register_lock, flag);
839 writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
840 writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
841 writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
842 spin_unlock_irqrestore(&iommu->register_lock, flag);
843}
844
845void dmar_msi_read(int irq, struct msi_msg *msg)
846{
847 struct intel_iommu *iommu = get_irq_data(irq);
848 unsigned long flag;
849
850 spin_lock_irqsave(&iommu->register_lock, flag);
851 msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
852 msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
853 msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
854 spin_unlock_irqrestore(&iommu->register_lock, flag);
855}
856
857static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
858 u8 fault_reason, u16 source_id, u64 addr)
859{
mark grossd94afc62008-02-08 04:18:39 -0800860 const char *reason;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -0700861
862 reason = dmar_get_fault_reason(fault_reason);
863
864 printk(KERN_ERR
865 "DMAR:[%s] Request device [%02x:%02x.%d] "
866 "fault addr %llx \n"
867 "DMAR:[fault reason %02d] %s\n",
868 (type ? "DMA Read" : "DMA Write"),
869 (source_id >> 8), PCI_SLOT(source_id & 0xFF),
870 PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
871 return 0;
872}
873
874#define PRIMARY_FAULT_REG_LEN (16)
875static irqreturn_t iommu_page_fault(int irq, void *dev_id)
876{
877 struct intel_iommu *iommu = dev_id;
878 int reg, fault_index;
879 u32 fault_status;
880 unsigned long flag;
881
882 spin_lock_irqsave(&iommu->register_lock, flag);
883 fault_status = readl(iommu->reg + DMAR_FSTS_REG);
884
885 /* TBD: ignore advanced fault log currently */
886 if (!(fault_status & DMA_FSTS_PPF))
887 goto clear_overflow;
888
889 fault_index = dma_fsts_fault_record_index(fault_status);
890 reg = cap_fault_reg_offset(iommu->cap);
891 while (1) {
892 u8 fault_reason;
893 u16 source_id;
894 u64 guest_addr;
895 int type;
896 u32 data;
897
898 /* highest 32 bits */
899 data = readl(iommu->reg + reg +
900 fault_index * PRIMARY_FAULT_REG_LEN + 12);
901 if (!(data & DMA_FRCD_F))
902 break;
903
904 fault_reason = dma_frcd_fault_reason(data);
905 type = dma_frcd_type(data);
906
907 data = readl(iommu->reg + reg +
908 fault_index * PRIMARY_FAULT_REG_LEN + 8);
909 source_id = dma_frcd_source_id(data);
910
911 guest_addr = dmar_readq(iommu->reg + reg +
912 fault_index * PRIMARY_FAULT_REG_LEN);
913 guest_addr = dma_frcd_page_addr(guest_addr);
914 /* clear the fault */
915 writel(DMA_FRCD_F, iommu->reg + reg +
916 fault_index * PRIMARY_FAULT_REG_LEN + 12);
917
918 spin_unlock_irqrestore(&iommu->register_lock, flag);
919
920 iommu_page_fault_do_one(iommu, type, fault_reason,
921 source_id, guest_addr);
922
923 fault_index++;
924 if (fault_index > cap_num_fault_regs(iommu->cap))
925 fault_index = 0;
926 spin_lock_irqsave(&iommu->register_lock, flag);
927 }
928clear_overflow:
929 /* clear primary fault overflow */
930 fault_status = readl(iommu->reg + DMAR_FSTS_REG);
931 if (fault_status & DMA_FSTS_PFO)
932 writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG);
933
934 spin_unlock_irqrestore(&iommu->register_lock, flag);
935 return IRQ_HANDLED;
936}
937
938int dmar_set_interrupt(struct intel_iommu *iommu)
939{
940 int irq, ret;
941
942 irq = create_irq();
943 if (!irq) {
944 printk(KERN_ERR "IOMMU: no free vectors\n");
945 return -EINVAL;
946 }
947
948 set_irq_data(irq, iommu);
949 iommu->irq = irq;
950
951 ret = arch_setup_dmar_msi(irq);
952 if (ret) {
953 set_irq_data(irq, NULL);
954 iommu->irq = 0;
955 destroy_irq(irq);
956 return 0;
957 }
958
959 /* Force fault register is cleared */
960 iommu_page_fault(irq, iommu);
961
962 ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu);
963 if (ret)
964 printk(KERN_ERR "IOMMU: can't request irq\n");
965 return ret;
966}
967
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700968static int iommu_init_domains(struct intel_iommu *iommu)
969{
970 unsigned long ndomains;
971 unsigned long nlongs;
972
973 ndomains = cap_ndoms(iommu->cap);
974 pr_debug("Number of Domains supportd <%ld>\n", ndomains);
975 nlongs = BITS_TO_LONGS(ndomains);
976
977 /* TBD: there might be 64K domains,
978 * consider other allocation for future chip
979 */
980 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
981 if (!iommu->domain_ids) {
982 printk(KERN_ERR "Allocating domain id array failed\n");
983 return -ENOMEM;
984 }
985 iommu->domains = kcalloc(ndomains, sizeof(struct dmar_domain *),
986 GFP_KERNEL);
987 if (!iommu->domains) {
988 printk(KERN_ERR "Allocating domain array failed\n");
989 kfree(iommu->domain_ids);
990 return -ENOMEM;
991 }
992
Suresh Siddhae61d98d2008-07-10 11:16:35 -0700993 spin_lock_init(&iommu->lock);
994
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700995 /*
996 * if Caching mode is set, then invalid translations are tagged
997 * with domainid 0. Hence we need to pre-allocate it.
998 */
999 if (cap_caching_mode(iommu->cap))
1000 set_bit(0, iommu->domain_ids);
1001 return 0;
1002}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001003
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001004
1005static void domain_exit(struct dmar_domain *domain);
Suresh Siddhae61d98d2008-07-10 11:16:35 -07001006
1007void free_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001008{
1009 struct dmar_domain *domain;
1010 int i;
1011
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001012 i = find_first_bit(iommu->domain_ids, cap_ndoms(iommu->cap));
1013 for (; i < cap_ndoms(iommu->cap); ) {
1014 domain = iommu->domains[i];
1015 clear_bit(i, iommu->domain_ids);
1016 domain_exit(domain);
1017 i = find_next_bit(iommu->domain_ids,
1018 cap_ndoms(iommu->cap), i+1);
1019 }
1020
1021 if (iommu->gcmd & DMA_GCMD_TE)
1022 iommu_disable_translation(iommu);
1023
1024 if (iommu->irq) {
1025 set_irq_data(iommu->irq, NULL);
1026 /* This will mask the irq */
1027 free_irq(iommu->irq, iommu);
1028 destroy_irq(iommu->irq);
1029 }
1030
1031 kfree(iommu->domains);
1032 kfree(iommu->domain_ids);
1033
1034 /* free context mapping */
1035 free_context_table(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001036}
1037
1038static struct dmar_domain * iommu_alloc_domain(struct intel_iommu *iommu)
1039{
1040 unsigned long num;
1041 unsigned long ndomains;
1042 struct dmar_domain *domain;
1043 unsigned long flags;
1044
1045 domain = alloc_domain_mem();
1046 if (!domain)
1047 return NULL;
1048
1049 ndomains = cap_ndoms(iommu->cap);
1050
1051 spin_lock_irqsave(&iommu->lock, flags);
1052 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1053 if (num >= ndomains) {
1054 spin_unlock_irqrestore(&iommu->lock, flags);
1055 free_domain_mem(domain);
1056 printk(KERN_ERR "IOMMU: no free domain ids\n");
1057 return NULL;
1058 }
1059
1060 set_bit(num, iommu->domain_ids);
1061 domain->id = num;
1062 domain->iommu = iommu;
1063 iommu->domains[num] = domain;
1064 spin_unlock_irqrestore(&iommu->lock, flags);
1065
1066 return domain;
1067}
1068
1069static void iommu_free_domain(struct dmar_domain *domain)
1070{
1071 unsigned long flags;
1072
1073 spin_lock_irqsave(&domain->iommu->lock, flags);
1074 clear_bit(domain->id, domain->iommu->domain_ids);
1075 spin_unlock_irqrestore(&domain->iommu->lock, flags);
1076}
1077
1078static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001079static struct lock_class_key reserved_alloc_key;
1080static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001081
1082static void dmar_init_reserved_ranges(void)
1083{
1084 struct pci_dev *pdev = NULL;
1085 struct iova *iova;
1086 int i;
1087 u64 addr, size;
1088
David Millerf6611972008-02-06 01:36:23 -08001089 init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001090
Mark Gross8a443df2008-03-04 14:59:31 -08001091 lockdep_set_class(&reserved_iova_list.iova_alloc_lock,
1092 &reserved_alloc_key);
1093 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1094 &reserved_rbtree_key);
1095
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001096 /* IOAPIC ranges shouldn't be accessed by DMA */
1097 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1098 IOVA_PFN(IOAPIC_RANGE_END));
1099 if (!iova)
1100 printk(KERN_ERR "Reserve IOAPIC range failed\n");
1101
1102 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1103 for_each_pci_dev(pdev) {
1104 struct resource *r;
1105
1106 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1107 r = &pdev->resource[i];
1108 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1109 continue;
1110 addr = r->start;
1111 addr &= PAGE_MASK_4K;
1112 size = r->end - addr;
1113 size = PAGE_ALIGN_4K(size);
1114 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
1115 IOVA_PFN(size + addr) - 1);
1116 if (!iova)
1117 printk(KERN_ERR "Reserve iova failed\n");
1118 }
1119 }
1120
1121}
1122
1123static void domain_reserve_special_ranges(struct dmar_domain *domain)
1124{
1125 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1126}
1127
1128static inline int guestwidth_to_adjustwidth(int gaw)
1129{
1130 int agaw;
1131 int r = (gaw - 12) % 9;
1132
1133 if (r == 0)
1134 agaw = gaw;
1135 else
1136 agaw = gaw + 9 - r;
1137 if (agaw > 64)
1138 agaw = 64;
1139 return agaw;
1140}
1141
1142static int domain_init(struct dmar_domain *domain, int guest_width)
1143{
1144 struct intel_iommu *iommu;
1145 int adjust_width, agaw;
1146 unsigned long sagaw;
1147
David Millerf6611972008-02-06 01:36:23 -08001148 init_iova_domain(&domain->iovad, DMA_32BIT_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001149 spin_lock_init(&domain->mapping_lock);
1150
1151 domain_reserve_special_ranges(domain);
1152
1153 /* calculate AGAW */
1154 iommu = domain->iommu;
1155 if (guest_width > cap_mgaw(iommu->cap))
1156 guest_width = cap_mgaw(iommu->cap);
1157 domain->gaw = guest_width;
1158 adjust_width = guestwidth_to_adjustwidth(guest_width);
1159 agaw = width_to_agaw(adjust_width);
1160 sagaw = cap_sagaw(iommu->cap);
1161 if (!test_bit(agaw, &sagaw)) {
1162 /* hardware doesn't support it, choose a bigger one */
1163 pr_debug("IOMMU: hardware doesn't support agaw %d\n", agaw);
1164 agaw = find_next_bit(&sagaw, 5, agaw);
1165 if (agaw >= 5)
1166 return -ENODEV;
1167 }
1168 domain->agaw = agaw;
1169 INIT_LIST_HEAD(&domain->devices);
1170
1171 /* always allocate the top pgd */
1172 domain->pgd = (struct dma_pte *)alloc_pgtable_page();
1173 if (!domain->pgd)
1174 return -ENOMEM;
1175 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE_4K);
1176 return 0;
1177}
1178
1179static void domain_exit(struct dmar_domain *domain)
1180{
1181 u64 end;
1182
1183 /* Domain 0 is reserved, so dont process it */
1184 if (!domain)
1185 return;
1186
1187 domain_remove_dev_info(domain);
1188 /* destroy iovas */
1189 put_iova_domain(&domain->iovad);
1190 end = DOMAIN_MAX_ADDR(domain->gaw);
1191 end = end & (~PAGE_MASK_4K);
1192
1193 /* clear ptes */
1194 dma_pte_clear_range(domain, 0, end);
1195
1196 /* free page tables */
1197 dma_pte_free_pagetable(domain, 0, end);
1198
1199 iommu_free_domain(domain);
1200 free_domain_mem(domain);
1201}
1202
1203static int domain_context_mapping_one(struct dmar_domain *domain,
1204 u8 bus, u8 devfn)
1205{
1206 struct context_entry *context;
1207 struct intel_iommu *iommu = domain->iommu;
1208 unsigned long flags;
1209
1210 pr_debug("Set context mapping for %02x:%02x.%d\n",
1211 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
1212 BUG_ON(!domain->pgd);
1213 context = device_to_context_entry(iommu, bus, devfn);
1214 if (!context)
1215 return -ENOMEM;
1216 spin_lock_irqsave(&iommu->lock, flags);
1217 if (context_present(*context)) {
1218 spin_unlock_irqrestore(&iommu->lock, flags);
1219 return 0;
1220 }
1221
1222 context_set_domain_id(*context, domain->id);
1223 context_set_address_width(*context, domain->agaw);
1224 context_set_address_root(*context, virt_to_phys(domain->pgd));
1225 context_set_translation_type(*context, CONTEXT_TT_MULTI_LEVEL);
1226 context_set_fault_enable(*context);
1227 context_set_present(*context);
1228 __iommu_flush_cache(iommu, context, sizeof(*context));
1229
1230 /* it's a non-present to present mapping */
1231 if (iommu_flush_context_device(iommu, domain->id,
1232 (((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT, 1))
1233 iommu_flush_write_buffer(iommu);
1234 else
1235 iommu_flush_iotlb_dsi(iommu, 0, 0);
1236 spin_unlock_irqrestore(&iommu->lock, flags);
1237 return 0;
1238}
1239
1240static int
1241domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
1242{
1243 int ret;
1244 struct pci_dev *tmp, *parent;
1245
1246 ret = domain_context_mapping_one(domain, pdev->bus->number,
1247 pdev->devfn);
1248 if (ret)
1249 return ret;
1250
1251 /* dependent device mapping */
1252 tmp = pci_find_upstream_pcie_bridge(pdev);
1253 if (!tmp)
1254 return 0;
1255 /* Secondary interface's bus number and devfn 0 */
1256 parent = pdev->bus->self;
1257 while (parent != tmp) {
1258 ret = domain_context_mapping_one(domain, parent->bus->number,
1259 parent->devfn);
1260 if (ret)
1261 return ret;
1262 parent = parent->bus->self;
1263 }
1264 if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
1265 return domain_context_mapping_one(domain,
1266 tmp->subordinate->number, 0);
1267 else /* this is a legacy PCI bridge */
1268 return domain_context_mapping_one(domain,
1269 tmp->bus->number, tmp->devfn);
1270}
1271
1272static int domain_context_mapped(struct dmar_domain *domain,
1273 struct pci_dev *pdev)
1274{
1275 int ret;
1276 struct pci_dev *tmp, *parent;
1277
1278 ret = device_context_mapped(domain->iommu,
1279 pdev->bus->number, pdev->devfn);
1280 if (!ret)
1281 return ret;
1282 /* dependent device mapping */
1283 tmp = pci_find_upstream_pcie_bridge(pdev);
1284 if (!tmp)
1285 return ret;
1286 /* Secondary interface's bus number and devfn 0 */
1287 parent = pdev->bus->self;
1288 while (parent != tmp) {
1289 ret = device_context_mapped(domain->iommu, parent->bus->number,
1290 parent->devfn);
1291 if (!ret)
1292 return ret;
1293 parent = parent->bus->self;
1294 }
1295 if (tmp->is_pcie)
1296 return device_context_mapped(domain->iommu,
1297 tmp->subordinate->number, 0);
1298 else
1299 return device_context_mapped(domain->iommu,
1300 tmp->bus->number, tmp->devfn);
1301}
1302
1303static int
1304domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
1305 u64 hpa, size_t size, int prot)
1306{
1307 u64 start_pfn, end_pfn;
1308 struct dma_pte *pte;
1309 int index;
1310
1311 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
1312 return -EINVAL;
1313 iova &= PAGE_MASK_4K;
1314 start_pfn = ((u64)hpa) >> PAGE_SHIFT_4K;
1315 end_pfn = (PAGE_ALIGN_4K(((u64)hpa) + size)) >> PAGE_SHIFT_4K;
1316 index = 0;
1317 while (start_pfn < end_pfn) {
1318 pte = addr_to_dma_pte(domain, iova + PAGE_SIZE_4K * index);
1319 if (!pte)
1320 return -ENOMEM;
1321 /* We don't need lock here, nobody else
1322 * touches the iova range
1323 */
1324 BUG_ON(dma_pte_addr(*pte));
1325 dma_set_pte_addr(*pte, start_pfn << PAGE_SHIFT_4K);
1326 dma_set_pte_prot(*pte, prot);
1327 __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
1328 start_pfn++;
1329 index++;
1330 }
1331 return 0;
1332}
1333
1334static void detach_domain_for_dev(struct dmar_domain *domain, u8 bus, u8 devfn)
1335{
1336 clear_context_table(domain->iommu, bus, devfn);
1337 iommu_flush_context_global(domain->iommu, 0);
1338 iommu_flush_iotlb_global(domain->iommu, 0);
1339}
1340
1341static void domain_remove_dev_info(struct dmar_domain *domain)
1342{
1343 struct device_domain_info *info;
1344 unsigned long flags;
1345
1346 spin_lock_irqsave(&device_domain_lock, flags);
1347 while (!list_empty(&domain->devices)) {
1348 info = list_entry(domain->devices.next,
1349 struct device_domain_info, link);
1350 list_del(&info->link);
1351 list_del(&info->global);
1352 if (info->dev)
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07001353 info->dev->dev.archdata.iommu = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001354 spin_unlock_irqrestore(&device_domain_lock, flags);
1355
1356 detach_domain_for_dev(info->domain, info->bus, info->devfn);
1357 free_devinfo_mem(info);
1358
1359 spin_lock_irqsave(&device_domain_lock, flags);
1360 }
1361 spin_unlock_irqrestore(&device_domain_lock, flags);
1362}
1363
1364/*
1365 * find_domain
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07001366 * Note: we use struct pci_dev->dev.archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001367 */
1368struct dmar_domain *
1369find_domain(struct pci_dev *pdev)
1370{
1371 struct device_domain_info *info;
1372
1373 /* No lock here, assumes no domain exit in normal case */
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07001374 info = pdev->dev.archdata.iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001375 if (info)
1376 return info->domain;
1377 return NULL;
1378}
1379
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001380/* domain is initialized */
1381static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
1382{
1383 struct dmar_domain *domain, *found = NULL;
1384 struct intel_iommu *iommu;
1385 struct dmar_drhd_unit *drhd;
1386 struct device_domain_info *info, *tmp;
1387 struct pci_dev *dev_tmp;
1388 unsigned long flags;
1389 int bus = 0, devfn = 0;
1390
1391 domain = find_domain(pdev);
1392 if (domain)
1393 return domain;
1394
1395 dev_tmp = pci_find_upstream_pcie_bridge(pdev);
1396 if (dev_tmp) {
1397 if (dev_tmp->is_pcie) {
1398 bus = dev_tmp->subordinate->number;
1399 devfn = 0;
1400 } else {
1401 bus = dev_tmp->bus->number;
1402 devfn = dev_tmp->devfn;
1403 }
1404 spin_lock_irqsave(&device_domain_lock, flags);
1405 list_for_each_entry(info, &device_domain_list, global) {
1406 if (info->bus == bus && info->devfn == devfn) {
1407 found = info->domain;
1408 break;
1409 }
1410 }
1411 spin_unlock_irqrestore(&device_domain_lock, flags);
1412 /* pcie-pci bridge already has a domain, uses it */
1413 if (found) {
1414 domain = found;
1415 goto found_domain;
1416 }
1417 }
1418
1419 /* Allocate new domain for the device */
1420 drhd = dmar_find_matched_drhd_unit(pdev);
1421 if (!drhd) {
1422 printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n",
1423 pci_name(pdev));
1424 return NULL;
1425 }
1426 iommu = drhd->iommu;
1427
1428 domain = iommu_alloc_domain(iommu);
1429 if (!domain)
1430 goto error;
1431
1432 if (domain_init(domain, gaw)) {
1433 domain_exit(domain);
1434 goto error;
1435 }
1436
1437 /* register pcie-to-pci device */
1438 if (dev_tmp) {
1439 info = alloc_devinfo_mem();
1440 if (!info) {
1441 domain_exit(domain);
1442 goto error;
1443 }
1444 info->bus = bus;
1445 info->devfn = devfn;
1446 info->dev = NULL;
1447 info->domain = domain;
1448 /* This domain is shared by devices under p2p bridge */
1449 domain->flags |= DOMAIN_FLAG_MULTIPLE_DEVICES;
1450
1451 /* pcie-to-pci bridge already has a domain, uses it */
1452 found = NULL;
1453 spin_lock_irqsave(&device_domain_lock, flags);
1454 list_for_each_entry(tmp, &device_domain_list, global) {
1455 if (tmp->bus == bus && tmp->devfn == devfn) {
1456 found = tmp->domain;
1457 break;
1458 }
1459 }
1460 if (found) {
1461 free_devinfo_mem(info);
1462 domain_exit(domain);
1463 domain = found;
1464 } else {
1465 list_add(&info->link, &domain->devices);
1466 list_add(&info->global, &device_domain_list);
1467 }
1468 spin_unlock_irqrestore(&device_domain_lock, flags);
1469 }
1470
1471found_domain:
1472 info = alloc_devinfo_mem();
1473 if (!info)
1474 goto error;
1475 info->bus = pdev->bus->number;
1476 info->devfn = pdev->devfn;
1477 info->dev = pdev;
1478 info->domain = domain;
1479 spin_lock_irqsave(&device_domain_lock, flags);
1480 /* somebody is fast */
1481 found = find_domain(pdev);
1482 if (found != NULL) {
1483 spin_unlock_irqrestore(&device_domain_lock, flags);
1484 if (found != domain) {
1485 domain_exit(domain);
1486 domain = found;
1487 }
1488 free_devinfo_mem(info);
1489 return domain;
1490 }
1491 list_add(&info->link, &domain->devices);
1492 list_add(&info->global, &device_domain_list);
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07001493 pdev->dev.archdata.iommu = info;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001494 spin_unlock_irqrestore(&device_domain_lock, flags);
1495 return domain;
1496error:
1497 /* recheck it here, maybe others set it */
1498 return find_domain(pdev);
1499}
1500
1501static int iommu_prepare_identity_map(struct pci_dev *pdev, u64 start, u64 end)
1502{
1503 struct dmar_domain *domain;
1504 unsigned long size;
1505 u64 base;
1506 int ret;
1507
1508 printk(KERN_INFO
1509 "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
1510 pci_name(pdev), start, end);
1511 /* page table init */
1512 domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
1513 if (!domain)
1514 return -ENOMEM;
1515
1516 /* The address might not be aligned */
1517 base = start & PAGE_MASK_4K;
1518 size = end - base;
1519 size = PAGE_ALIGN_4K(size);
1520 if (!reserve_iova(&domain->iovad, IOVA_PFN(base),
1521 IOVA_PFN(base + size) - 1)) {
1522 printk(KERN_ERR "IOMMU: reserve iova failed\n");
1523 ret = -ENOMEM;
1524 goto error;
1525 }
1526
1527 pr_debug("Mapping reserved region %lx@%llx for %s\n",
1528 size, base, pci_name(pdev));
1529 /*
1530 * RMRR range might have overlap with physical memory range,
1531 * clear it first
1532 */
1533 dma_pte_clear_range(domain, base, base + size);
1534
1535 ret = domain_page_mapping(domain, base, base, size,
1536 DMA_PTE_READ|DMA_PTE_WRITE);
1537 if (ret)
1538 goto error;
1539
1540 /* context entry init */
1541 ret = domain_context_mapping(domain, pdev);
1542 if (!ret)
1543 return 0;
1544error:
1545 domain_exit(domain);
1546 return ret;
1547
1548}
1549
1550static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
1551 struct pci_dev *pdev)
1552{
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07001553 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001554 return 0;
1555 return iommu_prepare_identity_map(pdev, rmrr->base_address,
1556 rmrr->end_address + 1);
1557}
1558
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07001559#ifdef CONFIG_DMAR_GFX_WA
Yinghai Lud52d53b2008-06-16 20:10:55 -07001560struct iommu_prepare_data {
1561 struct pci_dev *pdev;
1562 int ret;
1563};
1564
1565static int __init iommu_prepare_work_fn(unsigned long start_pfn,
1566 unsigned long end_pfn, void *datax)
1567{
1568 struct iommu_prepare_data *data;
1569
1570 data = (struct iommu_prepare_data *)datax;
1571
1572 data->ret = iommu_prepare_identity_map(data->pdev,
1573 start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
1574 return data->ret;
1575
1576}
1577
1578static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev)
1579{
1580 int nid;
1581 struct iommu_prepare_data data;
1582
1583 data.pdev = pdev;
1584 data.ret = 0;
1585
1586 for_each_online_node(nid) {
1587 work_with_active_regions(nid, iommu_prepare_work_fn, &data);
1588 if (data.ret)
1589 return data.ret;
1590 }
1591 return data.ret;
1592}
1593
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07001594static void __init iommu_prepare_gfx_mapping(void)
1595{
1596 struct pci_dev *pdev = NULL;
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07001597 int ret;
1598
1599 for_each_pci_dev(pdev) {
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07001600 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO ||
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07001601 !IS_GFX_DEVICE(pdev))
1602 continue;
1603 printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
1604 pci_name(pdev));
Yinghai Lud52d53b2008-06-16 20:10:55 -07001605 ret = iommu_prepare_with_active_regions(pdev);
1606 if (ret)
1607 printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07001608 }
1609}
1610#endif
1611
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07001612#ifdef CONFIG_DMAR_FLOPPY_WA
1613static inline void iommu_prepare_isa(void)
1614{
1615 struct pci_dev *pdev;
1616 int ret;
1617
1618 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
1619 if (!pdev)
1620 return;
1621
1622 printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n");
1623 ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
1624
1625 if (ret)
1626 printk("IOMMU: Failed to create 0-64M identity map, "
1627 "floppy might not work\n");
1628
1629}
1630#else
1631static inline void iommu_prepare_isa(void)
1632{
1633 return;
1634}
1635#endif /* !CONFIG_DMAR_FLPY_WA */
1636
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001637int __init init_dmars(void)
1638{
1639 struct dmar_drhd_unit *drhd;
1640 struct dmar_rmrr_unit *rmrr;
1641 struct pci_dev *pdev;
1642 struct intel_iommu *iommu;
mark gross80b20dd2008-04-18 13:53:58 -07001643 int i, ret, unit = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001644
1645 /*
1646 * for each drhd
1647 * allocate root
1648 * initialize and program root entry to not present
1649 * endfor
1650 */
1651 for_each_drhd_unit(drhd) {
1652 if (drhd->ignored)
1653 continue;
mark gross5e0d2a62008-03-04 15:22:08 -08001654 g_num_of_iommus++;
1655 /*
1656 * lock not needed as this is only incremented in the single
1657 * threaded kernel __init code path all other access are read
1658 * only
1659 */
1660 }
1661
mark gross5e0d2a62008-03-04 15:22:08 -08001662 g_iommus = kzalloc(g_num_of_iommus * sizeof(*iommu), GFP_KERNEL);
1663 if (!g_iommus) {
mark gross80b20dd2008-04-18 13:53:58 -07001664 ret = -ENOMEM;
1665 goto error;
1666 }
1667
1668 deferred_flush = kzalloc(g_num_of_iommus *
1669 sizeof(struct deferred_flush_tables), GFP_KERNEL);
1670 if (!deferred_flush) {
1671 kfree(g_iommus);
mark gross5e0d2a62008-03-04 15:22:08 -08001672 ret = -ENOMEM;
1673 goto error;
1674 }
1675
1676 i = 0;
1677 for_each_drhd_unit(drhd) {
1678 if (drhd->ignored)
1679 continue;
1680 iommu = alloc_iommu(&g_iommus[i], drhd);
1681 i++;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001682 if (!iommu) {
1683 ret = -ENOMEM;
1684 goto error;
1685 }
1686
Suresh Siddhae61d98d2008-07-10 11:16:35 -07001687 ret = iommu_init_domains(iommu);
1688 if (ret)
1689 goto error;
1690
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001691 /*
1692 * TBD:
1693 * we could share the same root & context tables
1694 * amoung all IOMMU's. Need to Split it later.
1695 */
1696 ret = iommu_alloc_root_entry(iommu);
1697 if (ret) {
1698 printk(KERN_ERR "IOMMU: allocate root entry failed\n");
1699 goto error;
1700 }
1701 }
1702
1703 /*
1704 * For each rmrr
1705 * for each dev attached to rmrr
1706 * do
1707 * locate drhd for dev, alloc domain for dev
1708 * allocate free domain
1709 * allocate page table entries for rmrr
1710 * if context not allocated for bus
1711 * allocate and init context
1712 * set present in root table for this bus
1713 * init context with domain, translation etc
1714 * endfor
1715 * endfor
1716 */
1717 for_each_rmrr_units(rmrr) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001718 for (i = 0; i < rmrr->devices_cnt; i++) {
1719 pdev = rmrr->devices[i];
1720 /* some BIOS lists non-exist devices in DMAR table */
1721 if (!pdev)
1722 continue;
1723 ret = iommu_prepare_rmrr_dev(rmrr, pdev);
1724 if (ret)
1725 printk(KERN_ERR
1726 "IOMMU: mapping reserved region failed\n");
1727 }
1728 }
1729
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07001730 iommu_prepare_gfx_mapping();
1731
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07001732 iommu_prepare_isa();
1733
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001734 /*
1735 * for each drhd
1736 * enable fault log
1737 * global invalidate context cache
1738 * global invalidate iotlb
1739 * enable translation
1740 */
1741 for_each_drhd_unit(drhd) {
1742 if (drhd->ignored)
1743 continue;
1744 iommu = drhd->iommu;
1745 sprintf (iommu->name, "dmar%d", unit++);
1746
1747 iommu_flush_write_buffer(iommu);
1748
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001749 ret = dmar_set_interrupt(iommu);
1750 if (ret)
1751 goto error;
1752
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001753 iommu_set_root_entry(iommu);
1754
1755 iommu_flush_context_global(iommu, 0);
1756 iommu_flush_iotlb_global(iommu, 0);
1757
mark grossf8bab732008-02-08 04:18:38 -08001758 iommu_disable_protect_mem_regions(iommu);
1759
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001760 ret = iommu_enable_translation(iommu);
1761 if (ret)
1762 goto error;
1763 }
1764
1765 return 0;
1766error:
1767 for_each_drhd_unit(drhd) {
1768 if (drhd->ignored)
1769 continue;
1770 iommu = drhd->iommu;
1771 free_iommu(iommu);
1772 }
mark gross5e0d2a62008-03-04 15:22:08 -08001773 kfree(g_iommus);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001774 return ret;
1775}
1776
1777static inline u64 aligned_size(u64 host_addr, size_t size)
1778{
1779 u64 addr;
1780 addr = (host_addr & (~PAGE_MASK_4K)) + size;
1781 return PAGE_ALIGN_4K(addr);
1782}
1783
1784struct iova *
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001785iommu_alloc_iova(struct dmar_domain *domain, size_t size, u64 end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001786{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001787 struct iova *piova;
1788
1789 /* Make sure it's in range */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001790 end = min_t(u64, DOMAIN_MAX_ADDR(domain->gaw), end);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001791 if (!size || (IOVA_START_ADDR + size > end))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001792 return NULL;
1793
1794 piova = alloc_iova(&domain->iovad,
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001795 size >> PAGE_SHIFT_4K, IOVA_PFN(end), 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001796 return piova;
1797}
1798
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001799static struct iova *
1800__intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
1801 size_t size)
1802{
1803 struct pci_dev *pdev = to_pci_dev(dev);
1804 struct iova *iova = NULL;
1805
1806 if ((pdev->dma_mask <= DMA_32BIT_MASK) || (dmar_forcedac)) {
1807 iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
1808 } else {
1809 /*
1810 * First try to allocate an io virtual address in
1811 * DMA_32BIT_MASK and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08001812 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001813 */
1814 iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK);
1815 if (!iova)
1816 iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
1817 }
1818
1819 if (!iova) {
1820 printk(KERN_ERR"Allocating iova for %s failed", pci_name(pdev));
1821 return NULL;
1822 }
1823
1824 return iova;
1825}
1826
1827static struct dmar_domain *
1828get_valid_domain_for_dev(struct pci_dev *pdev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001829{
1830 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001831 int ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001832
1833 domain = get_domain_for_dev(pdev,
1834 DEFAULT_DOMAIN_ADDRESS_WIDTH);
1835 if (!domain) {
1836 printk(KERN_ERR
1837 "Allocating domain for %s failed", pci_name(pdev));
Al Viro4fe05bb2007-10-29 04:51:16 +00001838 return NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001839 }
1840
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001841 /* make sure context mapping is ok */
1842 if (unlikely(!domain_context_mapped(domain, pdev))) {
1843 ret = domain_context_mapping(domain, pdev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001844 if (ret) {
1845 printk(KERN_ERR
1846 "Domain context map for %s failed",
1847 pci_name(pdev));
Al Viro4fe05bb2007-10-29 04:51:16 +00001848 return NULL;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001849 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001850 }
1851
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001852 return domain;
1853}
1854
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001855static dma_addr_t
1856intel_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, int dir)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001857{
1858 struct pci_dev *pdev = to_pci_dev(hwdev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001859 struct dmar_domain *domain;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001860 unsigned long start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001861 struct iova *iova;
1862 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001863 int ret;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001864
1865 BUG_ON(dir == DMA_NONE);
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07001866 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001867 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001868
1869 domain = get_valid_domain_for_dev(pdev);
1870 if (!domain)
1871 return 0;
1872
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001873 size = aligned_size((u64)paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001874
1875 iova = __intel_alloc_iova(hwdev, domain, size);
1876 if (!iova)
1877 goto error;
1878
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001879 start_paddr = iova->pfn_lo << PAGE_SHIFT_4K;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001880
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001881 /*
1882 * Check if DMAR supports zero-length reads on write only
1883 * mappings..
1884 */
1885 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
1886 !cap_zlr(domain->iommu->cap))
1887 prot |= DMA_PTE_READ;
1888 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
1889 prot |= DMA_PTE_WRITE;
1890 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001891 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001892 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001893 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001894 * is not a big problem
1895 */
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001896 ret = domain_page_mapping(domain, start_paddr,
1897 ((u64)paddr) & PAGE_MASK_4K, size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001898 if (ret)
1899 goto error;
1900
1901 pr_debug("Device %s request: %lx@%llx mapping: %lx@%llx, dir %d\n",
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001902 pci_name(pdev), size, (u64)paddr,
1903 size, (u64)start_paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001904
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001905 /* it's a non-present to present mapping */
1906 ret = iommu_flush_iotlb_psi(domain->iommu, domain->id,
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001907 start_paddr, size >> PAGE_SHIFT_4K, 1);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001908 if (ret)
1909 iommu_flush_write_buffer(domain->iommu);
1910
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001911 return (start_paddr + ((u64)paddr & (~PAGE_MASK_4K)));
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001912
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001913error:
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001914 if (iova)
1915 __free_iova(&domain->iovad, iova);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001916 printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
Ingo Molnar6865f0d2008-04-22 11:09:04 +02001917 pci_name(pdev), size, (u64)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001918 return 0;
1919}
1920
mark gross5e0d2a62008-03-04 15:22:08 -08001921static void flush_unmaps(void)
1922{
mark gross80b20dd2008-04-18 13:53:58 -07001923 int i, j;
mark gross5e0d2a62008-03-04 15:22:08 -08001924
mark gross5e0d2a62008-03-04 15:22:08 -08001925 timer_on = 0;
1926
1927 /* just flush them all */
1928 for (i = 0; i < g_num_of_iommus; i++) {
mark gross80b20dd2008-04-18 13:53:58 -07001929 if (deferred_flush[i].next) {
mark gross5e0d2a62008-03-04 15:22:08 -08001930 iommu_flush_iotlb_global(&g_iommus[i], 0);
mark gross80b20dd2008-04-18 13:53:58 -07001931 for (j = 0; j < deferred_flush[i].next; j++) {
1932 __free_iova(&deferred_flush[i].domain[j]->iovad,
1933 deferred_flush[i].iova[j]);
1934 }
1935 deferred_flush[i].next = 0;
1936 }
mark gross5e0d2a62008-03-04 15:22:08 -08001937 }
1938
mark gross5e0d2a62008-03-04 15:22:08 -08001939 list_size = 0;
mark gross5e0d2a62008-03-04 15:22:08 -08001940}
1941
1942static void flush_unmaps_timeout(unsigned long data)
1943{
mark gross80b20dd2008-04-18 13:53:58 -07001944 unsigned long flags;
1945
1946 spin_lock_irqsave(&async_umap_flush_lock, flags);
mark gross5e0d2a62008-03-04 15:22:08 -08001947 flush_unmaps();
mark gross80b20dd2008-04-18 13:53:58 -07001948 spin_unlock_irqrestore(&async_umap_flush_lock, flags);
mark gross5e0d2a62008-03-04 15:22:08 -08001949}
1950
1951static void add_unmap(struct dmar_domain *dom, struct iova *iova)
1952{
1953 unsigned long flags;
mark gross80b20dd2008-04-18 13:53:58 -07001954 int next, iommu_id;
mark gross5e0d2a62008-03-04 15:22:08 -08001955
1956 spin_lock_irqsave(&async_umap_flush_lock, flags);
mark gross80b20dd2008-04-18 13:53:58 -07001957 if (list_size == HIGH_WATER_MARK)
1958 flush_unmaps();
1959
1960 iommu_id = dom->iommu - g_iommus;
1961 next = deferred_flush[iommu_id].next;
1962 deferred_flush[iommu_id].domain[next] = dom;
1963 deferred_flush[iommu_id].iova[next] = iova;
1964 deferred_flush[iommu_id].next++;
mark gross5e0d2a62008-03-04 15:22:08 -08001965
1966 if (!timer_on) {
1967 mod_timer(&unmap_timer, jiffies + msecs_to_jiffies(10));
1968 timer_on = 1;
1969 }
1970 list_size++;
1971 spin_unlock_irqrestore(&async_umap_flush_lock, flags);
1972}
1973
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001974static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr,
1975 size_t size, int dir)
1976{
1977 struct pci_dev *pdev = to_pci_dev(dev);
1978 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001979 unsigned long start_addr;
1980 struct iova *iova;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001981
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07001982 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001983 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001984 domain = find_domain(pdev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001985 BUG_ON(!domain);
1986
1987 iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr));
1988 if (!iova)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001989 return;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07001990
1991 start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
1992 size = aligned_size((u64)dev_addr, size);
1993
1994 pr_debug("Device %s unmapping: %lx@%llx\n",
1995 pci_name(pdev), size, (u64)start_addr);
1996
1997 /* clear the whole page */
1998 dma_pte_clear_range(domain, start_addr, start_addr + size);
1999 /* free page tables */
2000 dma_pte_free_pagetable(domain, start_addr, start_addr + size);
mark gross5e0d2a62008-03-04 15:22:08 -08002001 if (intel_iommu_strict) {
2002 if (iommu_flush_iotlb_psi(domain->iommu,
2003 domain->id, start_addr, size >> PAGE_SHIFT_4K, 0))
2004 iommu_flush_write_buffer(domain->iommu);
2005 /* free iova */
2006 __free_iova(&domain->iovad, iova);
2007 } else {
2008 add_unmap(domain, iova);
2009 /*
2010 * queue up the release of the unmap to save the 1/6th of the
2011 * cpu used up by the iotlb flush operation...
2012 */
mark gross5e0d2a62008-03-04 15:22:08 -08002013 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002014}
2015
2016static void * intel_alloc_coherent(struct device *hwdev, size_t size,
2017 dma_addr_t *dma_handle, gfp_t flags)
2018{
2019 void *vaddr;
2020 int order;
2021
2022 size = PAGE_ALIGN_4K(size);
2023 order = get_order(size);
2024 flags &= ~(GFP_DMA | GFP_DMA32);
2025
2026 vaddr = (void *)__get_free_pages(flags, order);
2027 if (!vaddr)
2028 return NULL;
2029 memset(vaddr, 0, size);
2030
Ingo Molnar6865f0d2008-04-22 11:09:04 +02002031 *dma_handle = intel_map_single(hwdev, virt_to_bus(vaddr), size, DMA_BIDIRECTIONAL);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002032 if (*dma_handle)
2033 return vaddr;
2034 free_pages((unsigned long)vaddr, order);
2035 return NULL;
2036}
2037
2038static void intel_free_coherent(struct device *hwdev, size_t size,
2039 void *vaddr, dma_addr_t dma_handle)
2040{
2041 int order;
2042
2043 size = PAGE_ALIGN_4K(size);
2044 order = get_order(size);
2045
2046 intel_unmap_single(hwdev, dma_handle, size, DMA_BIDIRECTIONAL);
2047 free_pages((unsigned long)vaddr, order);
2048}
2049
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02002050#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg)))
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002051static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002052 int nelems, int dir)
2053{
2054 int i;
2055 struct pci_dev *pdev = to_pci_dev(hwdev);
2056 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002057 unsigned long start_addr;
2058 struct iova *iova;
2059 size_t size = 0;
2060 void *addr;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002061 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002062
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07002063 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002064 return;
2065
2066 domain = find_domain(pdev);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002067
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002068 iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address));
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002069 if (!iova)
2070 return;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002071 for_each_sg(sglist, sg, nelems, i) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002072 addr = SG_ENT_VIRT_ADDRESS(sg);
2073 size += aligned_size((u64)addr, sg->length);
2074 }
2075
2076 start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
2077
2078 /* clear the whole page */
2079 dma_pte_clear_range(domain, start_addr, start_addr + size);
2080 /* free page tables */
2081 dma_pte_free_pagetable(domain, start_addr, start_addr + size);
2082
2083 if (iommu_flush_iotlb_psi(domain->iommu, domain->id, start_addr,
2084 size >> PAGE_SHIFT_4K, 0))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002085 iommu_flush_write_buffer(domain->iommu);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002086
2087 /* free iova */
2088 __free_iova(&domain->iovad, iova);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002089}
2090
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002091static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002092 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002093{
2094 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002095 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002096
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002097 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02002098 BUG_ON(!sg_page(sg));
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002099 sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
2100 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002101 }
2102 return nelems;
2103}
2104
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002105static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist,
2106 int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002107{
2108 void *addr;
2109 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002110 struct pci_dev *pdev = to_pci_dev(hwdev);
2111 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002112 size_t size = 0;
2113 int prot = 0;
2114 size_t offset = 0;
2115 struct iova *iova = NULL;
2116 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002117 struct scatterlist *sg;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002118 unsigned long start_addr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002119
2120 BUG_ON(dir == DMA_NONE);
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07002121 if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002122 return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002123
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002124 domain = get_valid_domain_for_dev(pdev);
2125 if (!domain)
2126 return 0;
2127
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002128 for_each_sg(sglist, sg, nelems, i) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002129 addr = SG_ENT_VIRT_ADDRESS(sg);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002130 addr = (void *)virt_to_phys(addr);
2131 size += aligned_size((u64)addr, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002132 }
2133
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002134 iova = __intel_alloc_iova(hwdev, domain, size);
2135 if (!iova) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002136 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002137 return 0;
2138 }
2139
2140 /*
2141 * Check if DMAR supports zero-length reads on write only
2142 * mappings..
2143 */
2144 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
2145 !cap_zlr(domain->iommu->cap))
2146 prot |= DMA_PTE_READ;
2147 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
2148 prot |= DMA_PTE_WRITE;
2149
2150 start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
2151 offset = 0;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07002152 for_each_sg(sglist, sg, nelems, i) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002153 addr = SG_ENT_VIRT_ADDRESS(sg);
2154 addr = (void *)virt_to_phys(addr);
2155 size = aligned_size((u64)addr, sg->length);
2156 ret = domain_page_mapping(domain, start_addr + offset,
2157 ((u64)addr) & PAGE_MASK_4K,
2158 size, prot);
2159 if (ret) {
2160 /* clear the page */
2161 dma_pte_clear_range(domain, start_addr,
2162 start_addr + offset);
2163 /* free page tables */
2164 dma_pte_free_pagetable(domain, start_addr,
2165 start_addr + offset);
2166 /* free iova */
2167 __free_iova(&domain->iovad, iova);
2168 return 0;
2169 }
2170 sg->dma_address = start_addr + offset +
2171 ((u64)addr & (~PAGE_MASK_4K));
2172 sg->dma_length = sg->length;
2173 offset += size;
2174 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002175
2176 /* it's a non-present to present mapping */
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07002177 if (iommu_flush_iotlb_psi(domain->iommu, domain->id,
2178 start_addr, offset >> PAGE_SHIFT_4K, 1))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002179 iommu_flush_write_buffer(domain->iommu);
2180 return nelems;
2181}
2182
2183static struct dma_mapping_ops intel_dma_ops = {
2184 .alloc_coherent = intel_alloc_coherent,
2185 .free_coherent = intel_free_coherent,
2186 .map_single = intel_map_single,
2187 .unmap_single = intel_unmap_single,
2188 .map_sg = intel_map_sg,
2189 .unmap_sg = intel_unmap_sg,
2190};
2191
2192static inline int iommu_domain_cache_init(void)
2193{
2194 int ret = 0;
2195
2196 iommu_domain_cache = kmem_cache_create("iommu_domain",
2197 sizeof(struct dmar_domain),
2198 0,
2199 SLAB_HWCACHE_ALIGN,
2200
2201 NULL);
2202 if (!iommu_domain_cache) {
2203 printk(KERN_ERR "Couldn't create iommu_domain cache\n");
2204 ret = -ENOMEM;
2205 }
2206
2207 return ret;
2208}
2209
2210static inline int iommu_devinfo_cache_init(void)
2211{
2212 int ret = 0;
2213
2214 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
2215 sizeof(struct device_domain_info),
2216 0,
2217 SLAB_HWCACHE_ALIGN,
2218
2219 NULL);
2220 if (!iommu_devinfo_cache) {
2221 printk(KERN_ERR "Couldn't create devinfo cache\n");
2222 ret = -ENOMEM;
2223 }
2224
2225 return ret;
2226}
2227
2228static inline int iommu_iova_cache_init(void)
2229{
2230 int ret = 0;
2231
2232 iommu_iova_cache = kmem_cache_create("iommu_iova",
2233 sizeof(struct iova),
2234 0,
2235 SLAB_HWCACHE_ALIGN,
2236
2237 NULL);
2238 if (!iommu_iova_cache) {
2239 printk(KERN_ERR "Couldn't create iova cache\n");
2240 ret = -ENOMEM;
2241 }
2242
2243 return ret;
2244}
2245
2246static int __init iommu_init_mempool(void)
2247{
2248 int ret;
2249 ret = iommu_iova_cache_init();
2250 if (ret)
2251 return ret;
2252
2253 ret = iommu_domain_cache_init();
2254 if (ret)
2255 goto domain_error;
2256
2257 ret = iommu_devinfo_cache_init();
2258 if (!ret)
2259 return ret;
2260
2261 kmem_cache_destroy(iommu_domain_cache);
2262domain_error:
2263 kmem_cache_destroy(iommu_iova_cache);
2264
2265 return -ENOMEM;
2266}
2267
2268static void __init iommu_exit_mempool(void)
2269{
2270 kmem_cache_destroy(iommu_devinfo_cache);
2271 kmem_cache_destroy(iommu_domain_cache);
2272 kmem_cache_destroy(iommu_iova_cache);
2273
2274}
2275
2276void __init detect_intel_iommu(void)
2277{
2278 if (swiotlb || no_iommu || iommu_detected || dmar_disabled)
2279 return;
2280 if (early_dmar_detect()) {
2281 iommu_detected = 1;
2282 }
2283}
2284
2285static void __init init_no_remapping_devices(void)
2286{
2287 struct dmar_drhd_unit *drhd;
2288
2289 for_each_drhd_unit(drhd) {
2290 if (!drhd->include_all) {
2291 int i;
2292 for (i = 0; i < drhd->devices_cnt; i++)
2293 if (drhd->devices[i] != NULL)
2294 break;
2295 /* ignore DMAR unit if no pci devices exist */
2296 if (i == drhd->devices_cnt)
2297 drhd->ignored = 1;
2298 }
2299 }
2300
2301 if (dmar_map_gfx)
2302 return;
2303
2304 for_each_drhd_unit(drhd) {
2305 int i;
2306 if (drhd->ignored || drhd->include_all)
2307 continue;
2308
2309 for (i = 0; i < drhd->devices_cnt; i++)
2310 if (drhd->devices[i] &&
2311 !IS_GFX_DEVICE(drhd->devices[i]))
2312 break;
2313
2314 if (i < drhd->devices_cnt)
2315 continue;
2316
2317 /* bypass IOMMU if it is just for gfx devices */
2318 drhd->ignored = 1;
2319 for (i = 0; i < drhd->devices_cnt; i++) {
2320 if (!drhd->devices[i])
2321 continue;
Keshavamurthy, Anil S358dd8a2007-10-21 16:41:59 -07002322 drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002323 }
2324 }
2325}
2326
2327int __init intel_iommu_init(void)
2328{
2329 int ret = 0;
2330
2331 if (no_iommu || swiotlb || dmar_disabled)
2332 return -ENODEV;
2333
2334 if (dmar_table_init())
2335 return -ENODEV;
2336
2337 iommu_init_mempool();
2338 dmar_init_reserved_ranges();
2339
2340 init_no_remapping_devices();
2341
2342 ret = init_dmars();
2343 if (ret) {
2344 printk(KERN_ERR "IOMMU: dmar init failed\n");
2345 put_iova_domain(&reserved_iova_list);
2346 iommu_exit_mempool();
2347 return ret;
2348 }
2349 printk(KERN_INFO
2350 "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
2351
mark gross5e0d2a62008-03-04 15:22:08 -08002352 init_timer(&unmap_timer);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002353 force_iommu = 1;
2354 dma_ops = &intel_dma_ops;
2355 return 0;
2356}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07002357