blob: 5b112b6a2c9c0ebea986be3bdae1a5e735316c57 [file] [log] [blame]
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001/*
David Woodhouseea8ea462014-03-05 17:09:32 +00002 * Copyright © 2006-2014 Intel Corporation.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003 *
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 *
David Woodhouseea8ea462014-03-05 17:09:32 +000013 * Authors: David Woodhouse <dwmw2@infradead.org>,
14 * Ashok Raj <ashok.raj@intel.com>,
15 * Shaohua Li <shaohua.li@intel.com>,
16 * Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>,
17 * Fenghua Yu <fenghua.yu@intel.com>
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020018 * Joerg Roedel <jroedel@suse.de>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070019 */
20
Joerg Roedel9f10e5b2015-06-12 09:57:06 +020021#define pr_fmt(fmt) "DMAR: " fmt
22
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070023#include <linux/init.h>
24#include <linux/bitmap.h>
mark gross5e0d2a62008-03-04 15:22:08 -080025#include <linux/debugfs.h>
Paul Gortmaker54485c32011-10-29 10:26:25 -040026#include <linux/export.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070027#include <linux/slab.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070030#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>
Jiang Liu75f05562014-02-19 14:07:37 +080035#include <linux/memory.h>
Omer Pelegaa473242016-04-20 11:33:02 +030036#include <linux/cpu.h>
mark gross5e0d2a62008-03-04 15:22:08 -080037#include <linux/timer.h>
Dan Williamsdfddb9692015-10-09 18:16:46 -040038#include <linux/io.h>
Kay, Allen M38717942008-09-09 18:37:29 +030039#include <linux/iova.h>
Joerg Roedel5d450802008-12-03 14:52:32 +010040#include <linux/iommu.h>
Kay, Allen M38717942008-09-09 18:37:29 +030041#include <linux/intel-iommu.h>
Rafael J. Wysocki134fac32011-03-23 22:16:14 +010042#include <linux/syscore_ops.h>
Shane Wang69575d32009-09-01 18:25:07 -070043#include <linux/tboot.h>
Stephen Rothwelladb2fe02009-08-31 15:24:23 +100044#include <linux/dmi.h>
Joerg Roedel5cdede22011-04-04 15:55:18 +020045#include <linux/pci-ats.h>
Tejun Heo0ee332c2011-12-08 10:22:09 -080046#include <linux/memblock.h>
Akinobu Mita36746432014-06-04 16:06:51 -070047#include <linux/dma-contiguous.h>
Joerg Roedel091d42e2015-06-12 11:56:10 +020048#include <linux/crash_dump.h>
Suresh Siddha8a8f4222012-03-30 11:47:08 -070049#include <asm/irq_remapping.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070050#include <asm/cacheflush.h>
FUJITA Tomonori46a7fa22008-07-11 10:23:42 +090051#include <asm/iommu.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070052
Joerg Roedel078e1ee2012-09-26 12:44:43 +020053#include "irq_remapping.h"
54
Fenghua Yu5b6985c2008-10-16 18:02:32 -070055#define ROOT_SIZE VTD_PAGE_SIZE
56#define CONTEXT_SIZE VTD_PAGE_SIZE
57
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070058#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
David Woodhouse18436af2015-03-25 15:05:47 +000059#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070060#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
David Woodhousee0fc7e02009-09-30 09:12:17 -070061#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070062
63#define IOAPIC_RANGE_START (0xfee00000)
64#define IOAPIC_RANGE_END (0xfeefffff)
65#define IOVA_START_ADDR (0x1000)
66
67#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
68
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070069#define MAX_AGAW_WIDTH 64
Jiang Liu5c645b32014-01-06 14:18:12 +080070#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070071
David Woodhouse2ebe3152009-09-19 07:34:04 -070072#define __DOMAIN_MAX_PFN(gaw) ((((uint64_t)1) << (gaw-VTD_PAGE_SHIFT)) - 1)
73#define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << gaw) - 1)
74
75/* We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR
76 to match. That way, we can use 'unsigned long' for PFNs with impunity. */
77#define DOMAIN_MAX_PFN(gaw) ((unsigned long) min_t(uint64_t, \
78 __DOMAIN_MAX_PFN(gaw), (unsigned long)-1))
79#define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAGE_SHIFT)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070080
Robin Murphy1b722502015-01-12 17:51:15 +000081/* IO virtual address start page frame number */
82#define IOVA_START_PFN (1)
83
Mark McLoughlinf27be032008-11-20 15:49:43 +000084#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
Yang Hongyang284901a2009-04-06 19:01:15 -070085#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
Yang Hongyang6a355282009-04-06 19:01:13 -070086#define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64))
mark gross5e0d2a62008-03-04 15:22:08 -080087
Andrew Mortondf08cdc2010-09-22 13:05:11 -070088/* page table handling */
89#define LEVEL_STRIDE (9)
90#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
91
Ohad Ben-Cohen6d1c56a2011-11-10 11:32:30 +020092/*
93 * This bitmap is used to advertise the page sizes our hardware support
94 * to the IOMMU core, which will then use this information to split
95 * physically contiguous memory regions it is mapping into page sizes
96 * that we support.
97 *
98 * Traditionally the IOMMU core just handed us the mappings directly,
99 * after making sure the size is an order of a 4KiB page and that the
100 * mapping has natural alignment.
101 *
102 * To retain this behavior, we currently advertise that we support
103 * all page sizes that are an order of 4KiB.
104 *
105 * If at some point we'd like to utilize the IOMMU core's new behavior,
106 * we could change this to advertise the real page sizes we support.
107 */
108#define INTEL_IOMMU_PGSIZES (~0xFFFUL)
109
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700110static inline int agaw_to_level(int agaw)
111{
112 return agaw + 2;
113}
114
115static inline int agaw_to_width(int agaw)
116{
Jiang Liu5c645b32014-01-06 14:18:12 +0800117 return min_t(int, 30 + agaw * LEVEL_STRIDE, MAX_AGAW_WIDTH);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700118}
119
120static inline int width_to_agaw(int width)
121{
Jiang Liu5c645b32014-01-06 14:18:12 +0800122 return DIV_ROUND_UP(width - 30, LEVEL_STRIDE);
Andrew Mortondf08cdc2010-09-22 13:05:11 -0700123}
124
125static inline unsigned int level_to_offset_bits(int level)
126{
127 return (level - 1) * LEVEL_STRIDE;
128}
129
130static inline int pfn_level_offset(unsigned long pfn, int level)
131{
132 return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
133}
134
135static inline unsigned long level_mask(int level)
136{
137 return -1UL << level_to_offset_bits(level);
138}
139
140static inline unsigned long level_size(int level)
141{
142 return 1UL << level_to_offset_bits(level);
143}
144
145static inline unsigned long align_to_level(unsigned long pfn, int level)
146{
147 return (pfn + level_size(level) - 1) & level_mask(level);
148}
David Woodhousefd18de52009-05-10 23:57:41 +0100149
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100150static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
151{
Jiang Liu5c645b32014-01-06 14:18:12 +0800152 return 1 << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100153}
154
David Woodhousedd4e8312009-06-27 16:21:20 +0100155/* VT-d pages must always be _smaller_ than MM pages. Otherwise things
156 are never going to work. */
157static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn)
158{
159 return dma_pfn >> (PAGE_SHIFT - VTD_PAGE_SHIFT);
160}
161
162static inline unsigned long mm_to_dma_pfn(unsigned long mm_pfn)
163{
164 return mm_pfn << (PAGE_SHIFT - VTD_PAGE_SHIFT);
165}
166static inline unsigned long page_to_dma_pfn(struct page *pg)
167{
168 return mm_to_dma_pfn(page_to_pfn(pg));
169}
170static inline unsigned long virt_to_dma_pfn(void *p)
171{
172 return page_to_dma_pfn(virt_to_page(p));
173}
174
Weidong Hand9630fe2008-12-08 11:06:32 +0800175/* global iommu list, set NULL for ignored DMAR units */
176static struct intel_iommu **g_iommus;
177
David Woodhousee0fc7e02009-09-30 09:12:17 -0700178static void __init check_tylersburg_isoch(void);
David Woodhouse9af88142009-02-13 23:18:03 +0000179static int rwbf_quirk;
180
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000181/*
Joseph Cihulab7792602011-05-03 00:08:37 -0700182 * set to 1 to panic kernel if can't successfully enable VT-d
183 * (used when kernel is launched w/ TXT)
184 */
185static int force_on = 0;
Shaohua Libfd20f12017-04-26 09:18:35 -0700186int intel_iommu_tboot_noforce;
Joseph Cihulab7792602011-05-03 00:08:37 -0700187
188/*
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000189 * 0: Present
190 * 1-11: Reserved
191 * 12-63: Context Ptr (12 - (haw-1))
192 * 64-127: Reserved
193 */
194struct root_entry {
David Woodhouse03ecc322015-02-13 14:35:21 +0000195 u64 lo;
196 u64 hi;
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000197};
198#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry))
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000199
Joerg Roedel091d42e2015-06-12 11:56:10 +0200200/*
201 * Take a root_entry and return the Lower Context Table Pointer (LCTP)
202 * if marked present.
203 */
204static phys_addr_t root_entry_lctp(struct root_entry *re)
205{
206 if (!(re->lo & 1))
207 return 0;
Mark McLoughlin46b08e12008-11-20 15:49:44 +0000208
Joerg Roedel091d42e2015-06-12 11:56:10 +0200209 return re->lo & VTD_PAGE_MASK;
210}
211
212/*
213 * Take a root_entry and return the Upper Context Table Pointer (UCTP)
214 * if marked present.
215 */
216static phys_addr_t root_entry_uctp(struct root_entry *re)
217{
218 if (!(re->hi & 1))
219 return 0;
220
221 return re->hi & VTD_PAGE_MASK;
222}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000223/*
224 * low 64 bits:
225 * 0: present
226 * 1: fault processing disable
227 * 2-3: translation type
228 * 12-63: address space root
229 * high 64 bits:
230 * 0-2: address width
231 * 3-6: aval
232 * 8-23: domain id
233 */
234struct context_entry {
235 u64 lo;
236 u64 hi;
237};
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000238
Joerg Roedelcf484d02015-06-12 12:21:46 +0200239static inline void context_clear_pasid_enable(struct context_entry *context)
240{
241 context->lo &= ~(1ULL << 11);
242}
243
244static inline bool context_pasid_enabled(struct context_entry *context)
245{
246 return !!(context->lo & (1ULL << 11));
247}
248
249static inline void context_set_copied(struct context_entry *context)
250{
251 context->hi |= (1ull << 3);
252}
253
254static inline bool context_copied(struct context_entry *context)
255{
256 return !!(context->hi & (1ULL << 3));
257}
258
259static inline bool __context_present(struct context_entry *context)
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000260{
261 return (context->lo & 1);
262}
Joerg Roedelcf484d02015-06-12 12:21:46 +0200263
264static inline bool context_present(struct context_entry *context)
265{
266 return context_pasid_enabled(context) ?
267 __context_present(context) :
268 __context_present(context) && !context_copied(context);
269}
270
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000271static inline void context_set_present(struct context_entry *context)
272{
273 context->lo |= 1;
274}
275
276static inline void context_set_fault_enable(struct context_entry *context)
277{
278 context->lo &= (((u64)-1) << 2) | 1;
279}
280
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000281static inline void context_set_translation_type(struct context_entry *context,
282 unsigned long value)
283{
284 context->lo &= (((u64)-1) << 4) | 3;
285 context->lo |= (value & 3) << 2;
286}
287
288static inline void context_set_address_root(struct context_entry *context,
289 unsigned long value)
290{
Li, Zhen-Hua1a2262f2014-11-05 15:30:19 +0800291 context->lo &= ~VTD_PAGE_MASK;
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000292 context->lo |= value & VTD_PAGE_MASK;
293}
294
295static inline void context_set_address_width(struct context_entry *context,
296 unsigned long value)
297{
298 context->hi |= value & 7;
299}
300
301static inline void context_set_domain_id(struct context_entry *context,
302 unsigned long value)
303{
304 context->hi |= (value & ((1 << 16) - 1)) << 8;
305}
306
Joerg Roedeldbcd8612015-06-12 12:02:09 +0200307static inline int context_domain_id(struct context_entry *c)
308{
309 return((c->hi >> 8) & 0xffff);
310}
311
Mark McLoughlinc07e7d22008-11-21 16:54:46 +0000312static inline void context_clear_entry(struct context_entry *context)
313{
314 context->lo = 0;
315 context->hi = 0;
316}
Mark McLoughlin7a8fc252008-11-20 15:49:45 +0000317
Mark McLoughlin622ba122008-11-20 15:49:46 +0000318/*
319 * 0: readable
320 * 1: writable
321 * 2-6: reserved
322 * 7: super page
Sheng Yang9cf06692009-03-18 15:33:07 +0800323 * 8-10: available
324 * 11: snoop behavior
Mark McLoughlin622ba122008-11-20 15:49:46 +0000325 * 12-63: Host physcial address
326 */
327struct dma_pte {
328 u64 val;
329};
Mark McLoughlin622ba122008-11-20 15:49:46 +0000330
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000331static inline void dma_clear_pte(struct dma_pte *pte)
332{
333 pte->val = 0;
334}
335
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000336static inline u64 dma_pte_addr(struct dma_pte *pte)
337{
David Woodhousec85994e2009-07-01 19:21:24 +0100338#ifdef CONFIG_64BIT
339 return pte->val & VTD_PAGE_MASK;
340#else
341 /* Must have a full atomic 64-bit read */
David Woodhouse1a8bd482010-08-10 01:38:53 +0100342 return __cmpxchg64(&pte->val, 0ULL, 0ULL) & VTD_PAGE_MASK;
David Woodhousec85994e2009-07-01 19:21:24 +0100343#endif
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000344}
345
Mark McLoughlin19c239c2008-11-21 16:56:53 +0000346static inline bool dma_pte_present(struct dma_pte *pte)
347{
348 return (pte->val & 3) != 0;
349}
Mark McLoughlin622ba122008-11-20 15:49:46 +0000350
Allen Kay4399c8b2011-10-14 12:32:46 -0700351static inline bool dma_pte_superpage(struct dma_pte *pte)
352{
Joerg Roedelc3c75eb2014-07-04 11:19:10 +0200353 return (pte->val & DMA_PTE_LARGE_PAGE);
Allen Kay4399c8b2011-10-14 12:32:46 -0700354}
355
David Woodhouse75e6bf92009-07-02 11:21:16 +0100356static inline int first_pte_in_page(struct dma_pte *pte)
357{
358 return !((unsigned long)pte & ~VTD_PAGE_MASK);
359}
360
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700361/*
362 * This domain is a statically identity mapping domain.
363 * 1. This domain creats a static 1:1 mapping to all usable memory.
364 * 2. It maps to each iommu if successful.
365 * 3. Each iommu mapps to this domain if successful.
366 */
David Woodhouse19943b02009-08-04 16:19:20 +0100367static struct dmar_domain *si_domain;
368static int hw_pass_through = 1;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700369
Joerg Roedel28ccce02015-07-21 14:45:31 +0200370/*
371 * Domain represents a virtual machine, more than one devices
Weidong Han1ce28fe2008-12-08 16:35:39 +0800372 * across iommus may be owned in one domain, e.g. kvm guest.
373 */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800374#define DOMAIN_FLAG_VIRTUAL_MACHINE (1 << 0)
Weidong Han1ce28fe2008-12-08 16:35:39 +0800375
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700376/* si_domain contains mulitple devices */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800377#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 1)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700378
Joerg Roedel29a27712015-07-21 17:17:12 +0200379#define for_each_domain_iommu(idx, domain) \
380 for (idx = 0; idx < g_num_of_iommus; idx++) \
381 if (domain->iommu_refcnt[idx])
382
Mark McLoughlin99126f72008-11-20 15:49:47 +0000383struct dmar_domain {
Suresh Siddha4c923d42009-10-02 11:01:24 -0700384 int nid; /* node id */
Joerg Roedel29a27712015-07-21 17:17:12 +0200385
386 unsigned iommu_refcnt[DMAR_UNITS_SUPPORTED];
387 /* Refcount of devices per iommu */
388
Mark McLoughlin99126f72008-11-20 15:49:47 +0000389
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +0200390 u16 iommu_did[DMAR_UNITS_SUPPORTED];
391 /* Domain ids per IOMMU. Use u16 since
392 * domain ids are 16 bit wide according
393 * to VT-d spec, section 9.3 */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000394
Omer Peleg0824c592016-04-20 19:03:35 +0300395 bool has_iotlb_device;
Joerg Roedel00a77de2015-03-26 13:43:08 +0100396 struct list_head devices; /* all devices' list */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000397 struct iova_domain iovad; /* iova's that belong to this domain */
398
399 struct dma_pte *pgd; /* virtual address */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000400 int gaw; /* max guest address width */
401
402 /* adjusted guest address width, 0 is level 2 30-bit */
403 int agaw;
404
Weidong Han3b5410e2008-12-08 09:17:15 +0800405 int flags; /* flags to find out type of domain */
Weidong Han8e6040972008-12-08 15:49:06 +0800406
407 int iommu_coherency;/* indicate coherency of iommu access */
Sheng Yang58c610b2009-03-18 15:33:05 +0800408 int iommu_snooping; /* indicate snooping control feature*/
Weidong Hanc7151a82008-12-08 22:51:37 +0800409 int iommu_count; /* reference count of iommu */
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100410 int iommu_superpage;/* Level of superpages supported:
411 0 == 4KiB (no superpages), 1 == 2MiB,
412 2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
Weidong Hanfe40f1e2008-12-08 23:10:23 +0800413 u64 max_addr; /* maximum mapped address */
Joerg Roedel00a77de2015-03-26 13:43:08 +0100414
415 struct iommu_domain domain; /* generic domain data structure for
416 iommu core */
Mark McLoughlin99126f72008-11-20 15:49:47 +0000417};
418
Mark McLoughlina647dac2008-11-20 15:49:48 +0000419/* PCI domain-device relationship */
420struct device_domain_info {
421 struct list_head link; /* link to domain siblings */
422 struct list_head global; /* link to global list */
David Woodhouse276dbf992009-04-04 01:45:37 +0100423 u8 bus; /* PCI bus number */
Mark McLoughlina647dac2008-11-20 15:49:48 +0000424 u8 devfn; /* PCI devfn number */
David Woodhouseb16d0cb2015-10-12 14:17:37 +0100425 u8 pasid_supported:3;
426 u8 pasid_enabled:1;
427 u8 pri_supported:1;
428 u8 pri_enabled:1;
429 u8 ats_supported:1;
430 u8 ats_enabled:1;
431 u8 ats_qdep;
David Woodhouse0bcb3e22014-03-06 17:12:03 +0000432 struct device *dev; /* it's NULL for PCIe-to-PCI bridge */
Yu Zhao93a23a72009-05-18 13:51:37 +0800433 struct intel_iommu *iommu; /* IOMMU used by this device */
Mark McLoughlina647dac2008-11-20 15:49:48 +0000434 struct dmar_domain *domain; /* pointer to domain */
435};
436
Jiang Liub94e4112014-02-19 14:07:25 +0800437struct dmar_rmrr_unit {
438 struct list_head list; /* list of rmrr units */
439 struct acpi_dmar_header *hdr; /* ACPI header */
440 u64 base_address; /* reserved base address*/
441 u64 end_address; /* reserved end address */
David Woodhouse832bd852014-03-07 15:08:36 +0000442 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800443 int devices_cnt; /* target device count */
Eric Auger0659b8d2017-01-19 20:57:53 +0000444 struct iommu_resv_region *resv; /* reserved region handle */
Jiang Liub94e4112014-02-19 14:07:25 +0800445};
446
447struct dmar_atsr_unit {
448 struct list_head list; /* list of ATSR units */
449 struct acpi_dmar_header *hdr; /* ACPI header */
David Woodhouse832bd852014-03-07 15:08:36 +0000450 struct dmar_dev_scope *devices; /* target devices */
Jiang Liub94e4112014-02-19 14:07:25 +0800451 int devices_cnt; /* target device count */
452 u8 include_all:1; /* include all ports */
453};
454
455static LIST_HEAD(dmar_atsr_units);
456static LIST_HEAD(dmar_rmrr_units);
457
458#define for_each_rmrr_units(rmrr) \
459 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
460
mark gross5e0d2a62008-03-04 15:22:08 -0800461static void flush_unmaps_timeout(unsigned long data);
462
Omer Peleg314f1dc2016-04-20 11:32:45 +0300463struct deferred_flush_entry {
Omer Peleg2aac6302016-04-20 11:33:57 +0300464 unsigned long iova_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +0300465 unsigned long nrpages;
Omer Peleg314f1dc2016-04-20 11:32:45 +0300466 struct dmar_domain *domain;
467 struct page *freelist;
mark gross80b20dd2008-04-18 13:53:58 -0700468};
469
Omer Peleg314f1dc2016-04-20 11:32:45 +0300470#define HIGH_WATER_MARK 250
471struct deferred_flush_table {
472 int next;
473 struct deferred_flush_entry entries[HIGH_WATER_MARK];
474};
475
Omer Pelegaa473242016-04-20 11:33:02 +0300476struct deferred_flush_data {
477 spinlock_t lock;
478 int timer_on;
479 struct timer_list timer;
480 long size;
481 struct deferred_flush_table *tables;
482};
483
Sebastian Andrzej Siewior58c4a95f2017-06-27 18:16:48 +0200484static DEFINE_PER_CPU(struct deferred_flush_data, deferred_flush);
mark gross80b20dd2008-04-18 13:53:58 -0700485
mark gross5e0d2a62008-03-04 15:22:08 -0800486/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -0800487static int g_num_of_iommus;
488
Jiang Liu92d03cc2014-02-19 14:07:28 +0800489static void domain_exit(struct dmar_domain *domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700490static void domain_remove_dev_info(struct dmar_domain *domain);
Joerg Roedele6de0f82015-07-22 16:30:36 +0200491static void dmar_remove_one_dev_info(struct dmar_domain *domain,
492 struct device *dev);
Joerg Roedel127c7612015-07-23 17:44:46 +0200493static void __dmar_remove_one_dev_info(struct device_domain_info *info);
Joerg Roedel2452d9d2015-07-23 16:20:14 +0200494static void domain_context_clear(struct intel_iommu *iommu,
495 struct device *dev);
Jiang Liu2a46ddf2014-07-11 14:19:30 +0800496static int domain_detach_iommu(struct dmar_domain *domain,
497 struct intel_iommu *iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700498
Suresh Siddhad3f13812011-08-23 17:05:25 -0700499#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800500int dmar_disabled = 0;
501#else
502int dmar_disabled = 1;
Suresh Siddhad3f13812011-08-23 17:05:25 -0700503#endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800504
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -0200505int intel_iommu_enabled = 0;
506EXPORT_SYMBOL_GPL(intel_iommu_enabled);
507
David Woodhouse2d9e6672010-06-15 10:57:57 +0100508static int dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700509static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -0800510static int intel_iommu_strict;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100511static int intel_iommu_superpage = 1;
David Woodhousec83b2f22015-06-12 10:15:49 +0100512static int intel_iommu_ecs = 1;
David Woodhouseae853dd2015-09-09 11:58:59 +0100513static int intel_iommu_pasid28;
514static int iommu_identity_mapping;
David Woodhousec83b2f22015-06-12 10:15:49 +0100515
David Woodhouseae853dd2015-09-09 11:58:59 +0100516#define IDENTMAP_ALL 1
517#define IDENTMAP_GFX 2
518#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100519
David Woodhoused42fde72015-10-24 21:33:01 +0200520/* Broadwell and Skylake have broken ECS support — normal so-called "second
521 * level" translation of DMA requests-without-PASID doesn't actually happen
522 * unless you also set the NESTE bit in an extended context-entry. Which of
523 * course means that SVM doesn't work because it's trying to do nested
524 * translation of the physical addresses it finds in the process page tables,
525 * through the IOVA->phys mapping found in the "second level" page tables.
526 *
527 * The VT-d specification was retroactively changed to change the definition
528 * of the capability bits and pretend that Broadwell/Skylake never happened...
529 * but unfortunately the wrong bit was changed. It's ECS which is broken, but
530 * for some reason it was the PASID capability bit which was redefined (from
531 * bit 28 on BDW/SKL to bit 40 in future).
532 *
533 * So our test for ECS needs to eschew those implementations which set the old
534 * PASID capabiity bit 28, since those are the ones on which ECS is broken.
535 * Unless we are working around the 'pasid28' limitations, that is, by putting
536 * the device into passthrough mode for normal DMA and thus masking the bug.
537 */
David Woodhousec83b2f22015-06-12 10:15:49 +0100538#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \
David Woodhoused42fde72015-10-24 21:33:01 +0200539 (intel_iommu_pasid28 || !ecap_broken_pasid(iommu->ecap)))
540/* PASID support is thus enabled if ECS is enabled and *either* of the old
541 * or new capability bits are set. */
542#define pasid_enabled(iommu) (ecs_enabled(iommu) && \
543 (ecap_pasid(iommu->ecap) || ecap_broken_pasid(iommu->ecap)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700544
David Woodhousec0771df2011-10-14 20:59:46 +0100545int intel_iommu_gfx_mapped;
546EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
547
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700548#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
549static DEFINE_SPINLOCK(device_domain_lock);
550static LIST_HEAD(device_domain_list);
551
Joerg Roedelb0119e82017-02-01 13:23:08 +0100552const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100553
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200554static bool translation_pre_enabled(struct intel_iommu *iommu)
555{
556 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
557}
558
Joerg Roedel091d42e2015-06-12 11:56:10 +0200559static void clear_translation_pre_enabled(struct intel_iommu *iommu)
560{
561 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
562}
563
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200564static void init_translation_status(struct intel_iommu *iommu)
565{
566 u32 gsts;
567
568 gsts = readl(iommu->reg + DMAR_GSTS_REG);
569 if (gsts & DMA_GSTS_TES)
570 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
571}
572
Joerg Roedel00a77de2015-03-26 13:43:08 +0100573/* Convert generic 'struct iommu_domain to private struct dmar_domain */
574static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
575{
576 return container_of(dom, struct dmar_domain, domain);
577}
578
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700579static int __init intel_iommu_setup(char *str)
580{
581 if (!str)
582 return -EINVAL;
583 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800584 if (!strncmp(str, "on", 2)) {
585 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200586 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800587 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700588 dmar_disabled = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200589 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700590 } else if (!strncmp(str, "igfx_off", 8)) {
591 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200592 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700593 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200594 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700595 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800596 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200597 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800598 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100599 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200600 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100601 intel_iommu_superpage = 0;
David Woodhousec83b2f22015-06-12 10:15:49 +0100602 } else if (!strncmp(str, "ecs_off", 7)) {
603 printk(KERN_INFO
604 "Intel-IOMMU: disable extended context table support\n");
605 intel_iommu_ecs = 0;
David Woodhouseae853dd2015-09-09 11:58:59 +0100606 } else if (!strncmp(str, "pasid28", 7)) {
607 printk(KERN_INFO
608 "Intel-IOMMU: enable pre-production PASID support\n");
609 intel_iommu_pasid28 = 1;
610 iommu_identity_mapping |= IDENTMAP_GFX;
Shaohua Libfd20f12017-04-26 09:18:35 -0700611 } else if (!strncmp(str, "tboot_noforce", 13)) {
612 printk(KERN_INFO
613 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
614 intel_iommu_tboot_noforce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700615 }
616
617 str += strcspn(str, ",");
618 while (*str == ',')
619 str++;
620 }
621 return 0;
622}
623__setup("intel_iommu=", intel_iommu_setup);
624
625static struct kmem_cache *iommu_domain_cache;
626static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700627
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200628static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
629{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200630 struct dmar_domain **domains;
631 int idx = did >> 8;
632
633 domains = iommu->domains[idx];
634 if (!domains)
635 return NULL;
636
637 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200638}
639
640static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
641 struct dmar_domain *domain)
642{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200643 struct dmar_domain **domains;
644 int idx = did >> 8;
645
646 if (!iommu->domains[idx]) {
647 size_t size = 256 * sizeof(struct dmar_domain *);
648 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
649 }
650
651 domains = iommu->domains[idx];
652 if (WARN_ON(!domains))
653 return;
654 else
655 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200656}
657
Suresh Siddha4c923d42009-10-02 11:01:24 -0700658static inline void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700659{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700660 struct page *page;
661 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700662
Suresh Siddha4c923d42009-10-02 11:01:24 -0700663 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
664 if (page)
665 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700666 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700667}
668
669static inline void free_pgtable_page(void *vaddr)
670{
671 free_page((unsigned long)vaddr);
672}
673
674static inline void *alloc_domain_mem(void)
675{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900676 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700677}
678
Kay, Allen M38717942008-09-09 18:37:29 +0300679static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700680{
681 kmem_cache_free(iommu_domain_cache, vaddr);
682}
683
684static inline void * alloc_devinfo_mem(void)
685{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900686 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700687}
688
689static inline void free_devinfo_mem(void *vaddr)
690{
691 kmem_cache_free(iommu_devinfo_cache, vaddr);
692}
693
Jiang Liuab8dfe22014-07-11 14:19:27 +0800694static inline int domain_type_is_vm(struct dmar_domain *domain)
695{
696 return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
697}
698
Joerg Roedel28ccce02015-07-21 14:45:31 +0200699static inline int domain_type_is_si(struct dmar_domain *domain)
700{
701 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
702}
703
Jiang Liuab8dfe22014-07-11 14:19:27 +0800704static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
705{
706 return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
707 DOMAIN_FLAG_STATIC_IDENTITY);
708}
Weidong Han1b573682008-12-08 15:34:06 +0800709
Jiang Liu162d1b12014-07-11 14:19:35 +0800710static inline int domain_pfn_supported(struct dmar_domain *domain,
711 unsigned long pfn)
712{
713 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
714
715 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
716}
717
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700718static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800719{
720 unsigned long sagaw;
721 int agaw = -1;
722
723 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700724 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800725 agaw >= 0; agaw--) {
726 if (test_bit(agaw, &sagaw))
727 break;
728 }
729
730 return agaw;
731}
732
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700733/*
734 * Calculate max SAGAW for each iommu.
735 */
736int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
737{
738 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
739}
740
741/*
742 * calculate agaw for each iommu.
743 * "SAGAW" may be different across iommus, use a default agaw, and
744 * get a supported less agaw for iommus that don't support the default agaw.
745 */
746int iommu_calculate_agaw(struct intel_iommu *iommu)
747{
748 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
749}
750
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700751/* This functionin only returns single iommu in a domain */
Weidong Han8c11e792008-12-08 15:29:22 +0800752static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
753{
754 int iommu_id;
755
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700756 /* si_domain and vm domain should not get here. */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800757 BUG_ON(domain_type_is_vm_or_si(domain));
Joerg Roedel29a27712015-07-21 17:17:12 +0200758 for_each_domain_iommu(iommu_id, domain)
759 break;
760
Weidong Han8c11e792008-12-08 15:29:22 +0800761 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
762 return NULL;
763
764 return g_iommus[iommu_id];
765}
766
Weidong Han8e6040972008-12-08 15:49:06 +0800767static void domain_update_iommu_coherency(struct dmar_domain *domain)
768{
David Woodhoused0501962014-03-11 17:10:29 -0700769 struct dmar_drhd_unit *drhd;
770 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100771 bool found = false;
772 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800773
David Woodhoused0501962014-03-11 17:10:29 -0700774 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800775
Joerg Roedel29a27712015-07-21 17:17:12 +0200776 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100777 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800778 if (!ecap_coherent(g_iommus[i]->ecap)) {
779 domain->iommu_coherency = 0;
780 break;
781 }
Weidong Han8e6040972008-12-08 15:49:06 +0800782 }
David Woodhoused0501962014-03-11 17:10:29 -0700783 if (found)
784 return;
785
786 /* No hardware attached; use lowest common denominator */
787 rcu_read_lock();
788 for_each_active_iommu(iommu, drhd) {
789 if (!ecap_coherent(iommu->ecap)) {
790 domain->iommu_coherency = 0;
791 break;
792 }
793 }
794 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800795}
796
Jiang Liu161f6932014-07-11 14:19:37 +0800797static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100798{
Allen Kay8140a952011-10-14 12:32:17 -0700799 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800800 struct intel_iommu *iommu;
801 int ret = 1;
802
803 rcu_read_lock();
804 for_each_active_iommu(iommu, drhd) {
805 if (iommu != skip) {
806 if (!ecap_sc_support(iommu->ecap)) {
807 ret = 0;
808 break;
809 }
810 }
811 }
812 rcu_read_unlock();
813
814 return ret;
815}
816
817static int domain_update_iommu_superpage(struct intel_iommu *skip)
818{
819 struct dmar_drhd_unit *drhd;
820 struct intel_iommu *iommu;
Allen Kay8140a952011-10-14 12:32:17 -0700821 int mask = 0xf;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100822
823 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800824 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100825 }
826
Allen Kay8140a952011-10-14 12:32:17 -0700827 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800828 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700829 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800830 if (iommu != skip) {
831 mask &= cap_super_page_val(iommu->cap);
832 if (!mask)
833 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100834 }
835 }
Jiang Liu0e242612014-02-19 14:07:34 +0800836 rcu_read_unlock();
837
Jiang Liu161f6932014-07-11 14:19:37 +0800838 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100839}
840
Sheng Yang58c610b2009-03-18 15:33:05 +0800841/* Some capabilities may be different across iommus */
842static void domain_update_iommu_cap(struct dmar_domain *domain)
843{
844 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800845 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
846 domain->iommu_superpage = domain_update_iommu_superpage(NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800847}
848
David Woodhouse03ecc322015-02-13 14:35:21 +0000849static inline struct context_entry *iommu_context_addr(struct intel_iommu *iommu,
850 u8 bus, u8 devfn, int alloc)
851{
852 struct root_entry *root = &iommu->root_entry[bus];
853 struct context_entry *context;
854 u64 *entry;
855
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200856 entry = &root->lo;
David Woodhousec83b2f22015-06-12 10:15:49 +0100857 if (ecs_enabled(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000858 if (devfn >= 0x80) {
859 devfn -= 0x80;
860 entry = &root->hi;
861 }
862 devfn *= 2;
863 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000864 if (*entry & 1)
865 context = phys_to_virt(*entry & VTD_PAGE_MASK);
866 else {
867 unsigned long phy_addr;
868 if (!alloc)
869 return NULL;
870
871 context = alloc_pgtable_page(iommu->node);
872 if (!context)
873 return NULL;
874
875 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
876 phy_addr = virt_to_phys((void *)context);
877 *entry = phy_addr | 1;
878 __iommu_flush_cache(iommu, entry, sizeof(*entry));
879 }
880 return &context[devfn];
881}
882
David Woodhouse4ed6a542015-05-11 14:59:20 +0100883static int iommu_dummy(struct device *dev)
884{
885 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
886}
887
David Woodhouse156baca2014-03-09 14:00:57 -0700888static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800889{
890 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800891 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700892 struct device *tmp;
893 struct pci_dev *ptmp, *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800894 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800895 int i;
896
David Woodhouse4ed6a542015-05-11 14:59:20 +0100897 if (iommu_dummy(dev))
898 return NULL;
899
David Woodhouse156baca2014-03-09 14:00:57 -0700900 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700901 struct pci_dev *pf_pdev;
902
David Woodhouse156baca2014-03-09 14:00:57 -0700903 pdev = to_pci_dev(dev);
Ashok Raj1c387182016-10-21 15:32:05 -0700904 /* VFs aren't listed in scope tables; we need to look up
905 * the PF instead to find the IOMMU. */
906 pf_pdev = pci_physfn(pdev);
907 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700908 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100909 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700910 dev = &ACPI_COMPANION(dev)->dev;
911
Jiang Liu0e242612014-02-19 14:07:34 +0800912 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800913 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700914 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100915 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800916
Jiang Liub683b232014-02-19 14:07:32 +0800917 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700918 drhd->devices_cnt, i, tmp) {
919 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700920 /* For a VF use its original BDF# not that of the PF
921 * which we used for the IOMMU lookup. Strictly speaking
922 * we could do this for all PCI devices; we only need to
923 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100924 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700925 goto got_pdev;
926
David Woodhouse156baca2014-03-09 14:00:57 -0700927 *bus = drhd->devices[i].bus;
928 *devfn = drhd->devices[i].devfn;
929 goto out;
930 }
931
932 if (!pdev || !dev_is_pci(tmp))
David Woodhouse832bd852014-03-07 15:08:36 +0000933 continue;
David Woodhouse156baca2014-03-09 14:00:57 -0700934
935 ptmp = to_pci_dev(tmp);
936 if (ptmp->subordinate &&
937 ptmp->subordinate->number <= pdev->bus->number &&
938 ptmp->subordinate->busn_res.end >= pdev->bus->number)
939 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100940 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800941
David Woodhouse156baca2014-03-09 14:00:57 -0700942 if (pdev && drhd->include_all) {
943 got_pdev:
944 *bus = pdev->bus->number;
945 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800946 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700947 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800948 }
Jiang Liub683b232014-02-19 14:07:32 +0800949 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700950 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800951 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800952
Jiang Liub683b232014-02-19 14:07:32 +0800953 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800954}
955
Weidong Han5331fe62008-12-08 23:00:00 +0800956static void domain_flush_cache(struct dmar_domain *domain,
957 void *addr, int size)
958{
959 if (!domain->iommu_coherency)
960 clflush_cache_range(addr, size);
961}
962
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700963static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
964{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700965 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000966 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700967 unsigned long flags;
968
969 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000970 context = iommu_context_addr(iommu, bus, devfn, 0);
971 if (context)
972 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700973 spin_unlock_irqrestore(&iommu->lock, flags);
974 return ret;
975}
976
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700977static void free_context_table(struct intel_iommu *iommu)
978{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700979 int i;
980 unsigned long flags;
981 struct context_entry *context;
982
983 spin_lock_irqsave(&iommu->lock, flags);
984 if (!iommu->root_entry) {
985 goto out;
986 }
987 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000988 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700989 if (context)
990 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000991
David Woodhousec83b2f22015-06-12 10:15:49 +0100992 if (!ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000993 continue;
994
995 context = iommu_context_addr(iommu, i, 0x80, 0);
996 if (context)
997 free_pgtable_page(context);
998
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700999 }
1000 free_pgtable_page(iommu->root_entry);
1001 iommu->root_entry = NULL;
1002out:
1003 spin_unlock_irqrestore(&iommu->lock, flags);
1004}
1005
David Woodhouseb026fd22009-06-28 10:37:25 +01001006static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +00001007 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001008{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001009 struct dma_pte *parent, *pte = NULL;
1010 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -07001011 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001012
1013 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +02001014
Jiang Liu162d1b12014-07-11 14:19:35 +08001015 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +02001016 /* Address beyond IOMMU's addressing capabilities. */
1017 return NULL;
1018
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001019 parent = domain->pgd;
1020
David Woodhouse5cf0a762014-03-19 16:07:49 +00001021 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001022 void *tmp_page;
1023
David Woodhouseb026fd22009-06-28 10:37:25 +01001024 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001025 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +00001026 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001027 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +00001028 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001029 break;
1030
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001031 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +01001032 uint64_t pteval;
1033
Suresh Siddha4c923d42009-10-02 11:01:24 -07001034 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001035
David Woodhouse206a73c2009-07-01 19:30:28 +01001036 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001037 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +01001038
David Woodhousec85994e2009-07-01 19:21:24 +01001039 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -04001040 pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
Yijing Wangeffad4b2014-05-26 20:13:47 +08001041 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +01001042 /* Someone else set it while we were thinking; use theirs. */
1043 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +08001044 else
David Woodhousec85994e2009-07-01 19:21:24 +01001045 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001046 }
David Woodhouse5cf0a762014-03-19 16:07:49 +00001047 if (level == 1)
1048 break;
1049
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001050 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001051 level--;
1052 }
1053
David Woodhouse5cf0a762014-03-19 16:07:49 +00001054 if (!*target_level)
1055 *target_level = level;
1056
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001057 return pte;
1058}
1059
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001060
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001061/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +01001062static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
1063 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001064 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001065{
1066 struct dma_pte *parent, *pte = NULL;
1067 int total = agaw_to_level(domain->agaw);
1068 int offset;
1069
1070 parent = domain->pgd;
1071 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +01001072 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001073 pte = &parent[offset];
1074 if (level == total)
1075 return pte;
1076
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001077 if (!dma_pte_present(pte)) {
1078 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001079 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001080 }
1081
Yijing Wange16922a2014-05-20 20:37:51 +08001082 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001083 *large_page = total;
1084 return pte;
1085 }
1086
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001087 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001088 total--;
1089 }
1090 return NULL;
1091}
1092
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001093/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +00001094static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf2009-06-27 22:09:11 +01001095 unsigned long start_pfn,
1096 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001097{
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001098 unsigned int large_page = 1;
David Woodhouse310a5ab2009-06-28 18:52:20 +01001099 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001100
Jiang Liu162d1b12014-07-11 14:19:35 +08001101 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1102 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001103 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001104
David Woodhouse04b18e62009-06-27 19:15:01 +01001105 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001106 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001107 large_page = 1;
1108 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001109 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001110 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001111 continue;
1112 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001113 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001114 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001115 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001116 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001117 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1118
David Woodhouse310a5ab2009-06-28 18:52:20 +01001119 domain_flush_cache(domain, first_pte,
1120 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001121
1122 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001123}
1124
Alex Williamson3269ee02013-06-15 10:27:19 -06001125static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001126 int retain_level, struct dma_pte *pte,
1127 unsigned long pfn, unsigned long start_pfn,
1128 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001129{
1130 pfn = max(start_pfn, pfn);
1131 pte = &pte[pfn_level_offset(pfn, level)];
1132
1133 do {
1134 unsigned long level_pfn;
1135 struct dma_pte *level_pte;
1136
1137 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1138 goto next;
1139
David Dillowf7116e12017-01-30 19:11:11 -08001140 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001141 level_pte = phys_to_virt(dma_pte_addr(pte));
1142
David Dillowbc24c572017-06-28 19:42:23 -07001143 if (level > 2) {
1144 dma_pte_free_level(domain, level - 1, retain_level,
1145 level_pte, level_pfn, start_pfn,
1146 last_pfn);
1147 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001148
David Dillowbc24c572017-06-28 19:42:23 -07001149 /*
1150 * Free the page table if we're below the level we want to
1151 * retain and the range covers the entire table.
1152 */
1153 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001154 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001155 dma_clear_pte(pte);
1156 domain_flush_cache(domain, pte, sizeof(*pte));
1157 free_pgtable_page(level_pte);
1158 }
1159next:
1160 pfn += level_size(level);
1161 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1162}
1163
David Dillowbc24c572017-06-28 19:42:23 -07001164/*
1165 * clear last level (leaf) ptes and free page table pages below the
1166 * level we wish to keep intact.
1167 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001168static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001169 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001170 unsigned long last_pfn,
1171 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001172{
Jiang Liu162d1b12014-07-11 14:19:35 +08001173 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1174 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001175 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001176
Jiang Liud41a4ad2014-07-11 14:19:34 +08001177 dma_pte_clear_range(domain, start_pfn, last_pfn);
1178
David Woodhousef3a0a522009-06-30 03:40:07 +01001179 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001180 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001181 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001182
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001183 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001184 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001185 free_pgtable_page(domain->pgd);
1186 domain->pgd = NULL;
1187 }
1188}
1189
David Woodhouseea8ea462014-03-05 17:09:32 +00001190/* When a page at a given level is being unlinked from its parent, we don't
1191 need to *modify* it at all. All we need to do is make a list of all the
1192 pages which can be freed just as soon as we've flushed the IOTLB and we
1193 know the hardware page-walk will no longer touch them.
1194 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1195 be freed. */
1196static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1197 int level, struct dma_pte *pte,
1198 struct page *freelist)
1199{
1200 struct page *pg;
1201
1202 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1203 pg->freelist = freelist;
1204 freelist = pg;
1205
1206 if (level == 1)
1207 return freelist;
1208
Jiang Liuadeb2592014-04-09 10:20:39 +08001209 pte = page_address(pg);
1210 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001211 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1212 freelist = dma_pte_list_pagetables(domain, level - 1,
1213 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001214 pte++;
1215 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001216
1217 return freelist;
1218}
1219
1220static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1221 struct dma_pte *pte, unsigned long pfn,
1222 unsigned long start_pfn,
1223 unsigned long last_pfn,
1224 struct page *freelist)
1225{
1226 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1227
1228 pfn = max(start_pfn, pfn);
1229 pte = &pte[pfn_level_offset(pfn, level)];
1230
1231 do {
1232 unsigned long level_pfn;
1233
1234 if (!dma_pte_present(pte))
1235 goto next;
1236
1237 level_pfn = pfn & level_mask(level);
1238
1239 /* If range covers entire pagetable, free it */
1240 if (start_pfn <= level_pfn &&
1241 last_pfn >= level_pfn + level_size(level) - 1) {
1242 /* These suborbinate page tables are going away entirely. Don't
1243 bother to clear them; we're just going to *free* them. */
1244 if (level > 1 && !dma_pte_superpage(pte))
1245 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1246
1247 dma_clear_pte(pte);
1248 if (!first_pte)
1249 first_pte = pte;
1250 last_pte = pte;
1251 } else if (level > 1) {
1252 /* Recurse down into a level that isn't *entirely* obsolete */
1253 freelist = dma_pte_clear_level(domain, level - 1,
1254 phys_to_virt(dma_pte_addr(pte)),
1255 level_pfn, start_pfn, last_pfn,
1256 freelist);
1257 }
1258next:
1259 pfn += level_size(level);
1260 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1261
1262 if (first_pte)
1263 domain_flush_cache(domain, first_pte,
1264 (void *)++last_pte - (void *)first_pte);
1265
1266 return freelist;
1267}
1268
1269/* We can't just free the pages because the IOMMU may still be walking
1270 the page tables, and may have cached the intermediate levels. The
1271 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001272static struct page *domain_unmap(struct dmar_domain *domain,
1273 unsigned long start_pfn,
1274 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001275{
David Woodhouseea8ea462014-03-05 17:09:32 +00001276 struct page *freelist = NULL;
1277
Jiang Liu162d1b12014-07-11 14:19:35 +08001278 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1279 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001280 BUG_ON(start_pfn > last_pfn);
1281
1282 /* we don't need lock here; nobody else touches the iova range */
1283 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1284 domain->pgd, 0, start_pfn, last_pfn, NULL);
1285
1286 /* free pgd */
1287 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1288 struct page *pgd_page = virt_to_page(domain->pgd);
1289 pgd_page->freelist = freelist;
1290 freelist = pgd_page;
1291
1292 domain->pgd = NULL;
1293 }
1294
1295 return freelist;
1296}
1297
Joerg Roedelb6904202015-08-13 11:32:18 +02001298static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001299{
1300 struct page *pg;
1301
1302 while ((pg = freelist)) {
1303 freelist = pg->freelist;
1304 free_pgtable_page(page_address(pg));
1305 }
1306}
1307
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001308/* iommu handling */
1309static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1310{
1311 struct root_entry *root;
1312 unsigned long flags;
1313
Suresh Siddha4c923d42009-10-02 11:01:24 -07001314 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001315 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001316 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001317 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001318 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001319 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001320
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001321 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001322
1323 spin_lock_irqsave(&iommu->lock, flags);
1324 iommu->root_entry = root;
1325 spin_unlock_irqrestore(&iommu->lock, flags);
1326
1327 return 0;
1328}
1329
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001330static void iommu_set_root_entry(struct intel_iommu *iommu)
1331{
David Woodhouse03ecc322015-02-13 14:35:21 +00001332 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001333 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001334 unsigned long flag;
1335
David Woodhouse03ecc322015-02-13 14:35:21 +00001336 addr = virt_to_phys(iommu->root_entry);
David Woodhousec83b2f22015-06-12 10:15:49 +01001337 if (ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +00001338 addr |= DMA_RTADDR_RTT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001339
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001340 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001341 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001342
David Woodhousec416daa2009-05-10 20:30:58 +01001343 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001344
1345 /* Make sure hardware complete it */
1346 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001347 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001348
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001349 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001350}
1351
1352static void iommu_flush_write_buffer(struct intel_iommu *iommu)
1353{
1354 u32 val;
1355 unsigned long flag;
1356
David Woodhouse9af88142009-02-13 23:18:03 +00001357 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001358 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001359
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001360 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001361 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001362
1363 /* Make sure hardware complete it */
1364 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001365 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001366
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001367 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001368}
1369
1370/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001371static void __iommu_flush_context(struct intel_iommu *iommu,
1372 u16 did, u16 source_id, u8 function_mask,
1373 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001374{
1375 u64 val = 0;
1376 unsigned long flag;
1377
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001378 switch (type) {
1379 case DMA_CCMD_GLOBAL_INVL:
1380 val = DMA_CCMD_GLOBAL_INVL;
1381 break;
1382 case DMA_CCMD_DOMAIN_INVL:
1383 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1384 break;
1385 case DMA_CCMD_DEVICE_INVL:
1386 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1387 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1388 break;
1389 default:
1390 BUG();
1391 }
1392 val |= DMA_CCMD_ICC;
1393
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001394 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001395 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1396
1397 /* Make sure hardware complete it */
1398 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1399 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1400
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001401 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001402}
1403
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001404/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001405static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1406 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001407{
1408 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1409 u64 val = 0, val_iva = 0;
1410 unsigned long flag;
1411
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001412 switch (type) {
1413 case DMA_TLB_GLOBAL_FLUSH:
1414 /* global flush doesn't need set IVA_REG */
1415 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1416 break;
1417 case DMA_TLB_DSI_FLUSH:
1418 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1419 break;
1420 case DMA_TLB_PSI_FLUSH:
1421 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001422 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001423 val_iva = size_order | addr;
1424 break;
1425 default:
1426 BUG();
1427 }
1428 /* Note: set drain read/write */
1429#if 0
1430 /*
1431 * This is probably to be super secure.. Looks like we can
1432 * ignore it without any impact.
1433 */
1434 if (cap_read_drain(iommu->cap))
1435 val |= DMA_TLB_READ_DRAIN;
1436#endif
1437 if (cap_write_drain(iommu->cap))
1438 val |= DMA_TLB_WRITE_DRAIN;
1439
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001440 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001441 /* Note: Only uses first TLB reg currently */
1442 if (val_iva)
1443 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1444 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1445
1446 /* Make sure hardware complete it */
1447 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1448 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1449
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001450 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001451
1452 /* check IOTLB invalidation granularity */
1453 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001454 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001455 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001456 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001457 (unsigned long long)DMA_TLB_IIRG(type),
1458 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001459}
1460
David Woodhouse64ae8922014-03-09 12:52:30 -07001461static struct device_domain_info *
1462iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1463 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001464{
Yu Zhao93a23a72009-05-18 13:51:37 +08001465 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001466
Joerg Roedel55d94042015-07-22 16:50:40 +02001467 assert_spin_locked(&device_domain_lock);
1468
Yu Zhao93a23a72009-05-18 13:51:37 +08001469 if (!iommu->qi)
1470 return NULL;
1471
Yu Zhao93a23a72009-05-18 13:51:37 +08001472 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001473 if (info->iommu == iommu && info->bus == bus &&
1474 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001475 if (info->ats_supported && info->dev)
1476 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001477 break;
1478 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001479
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001480 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001481}
1482
Omer Peleg0824c592016-04-20 19:03:35 +03001483static void domain_update_iotlb(struct dmar_domain *domain)
1484{
1485 struct device_domain_info *info;
1486 bool has_iotlb_device = false;
1487
1488 assert_spin_locked(&device_domain_lock);
1489
1490 list_for_each_entry(info, &domain->devices, link) {
1491 struct pci_dev *pdev;
1492
1493 if (!info->dev || !dev_is_pci(info->dev))
1494 continue;
1495
1496 pdev = to_pci_dev(info->dev);
1497 if (pdev->ats_enabled) {
1498 has_iotlb_device = true;
1499 break;
1500 }
1501 }
1502
1503 domain->has_iotlb_device = has_iotlb_device;
1504}
1505
Yu Zhao93a23a72009-05-18 13:51:37 +08001506static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1507{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001508 struct pci_dev *pdev;
1509
Omer Peleg0824c592016-04-20 19:03:35 +03001510 assert_spin_locked(&device_domain_lock);
1511
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001512 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001513 return;
1514
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001515 pdev = to_pci_dev(info->dev);
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001516
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001517#ifdef CONFIG_INTEL_IOMMU_SVM
1518 /* The PCIe spec, in its wisdom, declares that the behaviour of
1519 the device if you enable PASID support after ATS support is
1520 undefined. So always enable PASID support on devices which
1521 have it, even if we can't yet know if we're ever going to
1522 use it. */
1523 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1524 info->pasid_enabled = 1;
1525
1526 if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
1527 info->pri_enabled = 1;
1528#endif
1529 if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
1530 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001531 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001532 info->ats_qdep = pci_ats_queue_depth(pdev);
1533 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001534}
1535
1536static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1537{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001538 struct pci_dev *pdev;
1539
Omer Peleg0824c592016-04-20 19:03:35 +03001540 assert_spin_locked(&device_domain_lock);
1541
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001542 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001543 return;
1544
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001545 pdev = to_pci_dev(info->dev);
1546
1547 if (info->ats_enabled) {
1548 pci_disable_ats(pdev);
1549 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001550 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001551 }
1552#ifdef CONFIG_INTEL_IOMMU_SVM
1553 if (info->pri_enabled) {
1554 pci_disable_pri(pdev);
1555 info->pri_enabled = 0;
1556 }
1557 if (info->pasid_enabled) {
1558 pci_disable_pasid(pdev);
1559 info->pasid_enabled = 0;
1560 }
1561#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001562}
1563
1564static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1565 u64 addr, unsigned mask)
1566{
1567 u16 sid, qdep;
1568 unsigned long flags;
1569 struct device_domain_info *info;
1570
Omer Peleg0824c592016-04-20 19:03:35 +03001571 if (!domain->has_iotlb_device)
1572 return;
1573
Yu Zhao93a23a72009-05-18 13:51:37 +08001574 spin_lock_irqsave(&device_domain_lock, flags);
1575 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001576 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001577 continue;
1578
1579 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001580 qdep = info->ats_qdep;
Yu Zhao93a23a72009-05-18 13:51:37 +08001581 qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
1582 }
1583 spin_unlock_irqrestore(&device_domain_lock, flags);
1584}
1585
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001586static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1587 struct dmar_domain *domain,
1588 unsigned long pfn, unsigned int pages,
1589 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001590{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001591 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001592 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001593 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001594
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001595 BUG_ON(pages == 0);
1596
David Woodhouseea8ea462014-03-05 17:09:32 +00001597 if (ih)
1598 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001599 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001600 * Fallback to domain selective flush if no PSI support or the size is
1601 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001602 * PSI requires page size to be 2 ^ x, and the base address is naturally
1603 * aligned to the size
1604 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001605 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1606 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001607 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001608 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001609 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001610 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001611
1612 /*
Nadav Amit82653632010-04-01 13:24:40 +03001613 * In caching mode, changes of pages from non-present to present require
1614 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001615 */
Nadav Amit82653632010-04-01 13:24:40 +03001616 if (!cap_caching_mode(iommu->cap) || !map)
Joerg Roedel9452d5b2015-07-21 10:00:56 +02001617 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1618 addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001619}
1620
mark grossf8bab732008-02-08 04:18:38 -08001621static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1622{
1623 u32 pmen;
1624 unsigned long flags;
1625
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001626 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001627 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1628 pmen &= ~DMA_PMEN_EPM;
1629 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1630
1631 /* wait for the protected region status bit to clear */
1632 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1633 readl, !(pmen & DMA_PMEN_PRS), pmen);
1634
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001635 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001636}
1637
Jiang Liu2a41cce2014-07-11 14:19:33 +08001638static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001639{
1640 u32 sts;
1641 unsigned long flags;
1642
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001643 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001644 iommu->gcmd |= DMA_GCMD_TE;
1645 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001646
1647 /* Make sure hardware complete it */
1648 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001649 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001650
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001651 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001652}
1653
Jiang Liu2a41cce2014-07-11 14:19:33 +08001654static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001655{
1656 u32 sts;
1657 unsigned long flag;
1658
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001659 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001660 iommu->gcmd &= ~DMA_GCMD_TE;
1661 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1662
1663 /* Make sure hardware complete it */
1664 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001665 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001666
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001667 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001668}
1669
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001670
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001671static int iommu_init_domains(struct intel_iommu *iommu)
1672{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001673 u32 ndomains, nlongs;
1674 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001675
1676 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001677 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001678 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001679 nlongs = BITS_TO_LONGS(ndomains);
1680
Donald Dutile94a91b52009-08-20 16:51:34 -04001681 spin_lock_init(&iommu->lock);
1682
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001683 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1684 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001685 pr_err("%s: Allocating domain id array failed\n",
1686 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001687 return -ENOMEM;
1688 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001689
Wei Yang86f004c2016-05-21 02:41:51 +00001690 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001691 iommu->domains = kzalloc(size, GFP_KERNEL);
1692
1693 if (iommu->domains) {
1694 size = 256 * sizeof(struct dmar_domain *);
1695 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1696 }
1697
1698 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001699 pr_err("%s: Allocating domain array failed\n",
1700 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001701 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001702 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001703 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001704 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001705 return -ENOMEM;
1706 }
1707
Joerg Roedel8bf47812015-07-21 10:41:21 +02001708
1709
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001710 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001711 * If Caching mode is set, then invalid translations are tagged
1712 * with domain-id 0, hence we need to pre-allocate it. We also
1713 * use domain-id 0 as a marker for non-allocated domain-id, so
1714 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001715 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001716 set_bit(0, iommu->domain_ids);
1717
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001718 return 0;
1719}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001720
Jiang Liuffebeb42014-11-09 22:48:02 +08001721static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001722{
Joerg Roedel29a27712015-07-21 17:17:12 +02001723 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001724 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001725
Joerg Roedel29a27712015-07-21 17:17:12 +02001726 if (!iommu->domains || !iommu->domain_ids)
1727 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001728
Joerg Roedelbea64032016-11-08 15:08:26 +01001729again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001730 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001731 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1732 struct dmar_domain *domain;
1733
1734 if (info->iommu != iommu)
1735 continue;
1736
1737 if (!info->dev || !info->domain)
1738 continue;
1739
1740 domain = info->domain;
1741
Joerg Roedelbea64032016-11-08 15:08:26 +01001742 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001743
Joerg Roedelbea64032016-11-08 15:08:26 +01001744 if (!domain_type_is_vm_or_si(domain)) {
1745 /*
1746 * The domain_exit() function can't be called under
1747 * device_domain_lock, as it takes this lock itself.
1748 * So release the lock here and re-run the loop
1749 * afterwards.
1750 */
1751 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001752 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001753 goto again;
1754 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001755 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001756 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001757
1758 if (iommu->gcmd & DMA_GCMD_TE)
1759 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001760}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001761
Jiang Liuffebeb42014-11-09 22:48:02 +08001762static void free_dmar_iommu(struct intel_iommu *iommu)
1763{
1764 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001765 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001766 int i;
1767
1768 for (i = 0; i < elems; i++)
1769 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001770 kfree(iommu->domains);
1771 kfree(iommu->domain_ids);
1772 iommu->domains = NULL;
1773 iommu->domain_ids = NULL;
1774 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001775
Weidong Hand9630fe2008-12-08 11:06:32 +08001776 g_iommus[iommu->seq_id] = NULL;
1777
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001778 /* free context mapping */
1779 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001780
1781#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001782 if (pasid_enabled(iommu)) {
1783 if (ecap_prs(iommu->ecap))
1784 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001785 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001786 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001787#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001788}
1789
Jiang Liuab8dfe22014-07-11 14:19:27 +08001790static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001791{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001792 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001793
1794 domain = alloc_domain_mem();
1795 if (!domain)
1796 return NULL;
1797
Jiang Liuab8dfe22014-07-11 14:19:27 +08001798 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001799 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001800 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001801 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001802 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001803
1804 return domain;
1805}
1806
Joerg Roedeld160aca2015-07-22 11:52:53 +02001807/* Must be called with iommu->lock */
1808static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001809 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001810{
Jiang Liu44bde612014-07-11 14:19:29 +08001811 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001812 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001813
Joerg Roedel55d94042015-07-22 16:50:40 +02001814 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001815 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001816
Joerg Roedel29a27712015-07-21 17:17:12 +02001817 domain->iommu_refcnt[iommu->seq_id] += 1;
1818 domain->iommu_count += 1;
1819 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001820 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001821 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1822
1823 if (num >= ndomains) {
1824 pr_err("%s: No free domain ids\n", iommu->name);
1825 domain->iommu_refcnt[iommu->seq_id] -= 1;
1826 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001827 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001828 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001829
Joerg Roedeld160aca2015-07-22 11:52:53 +02001830 set_bit(num, iommu->domain_ids);
1831 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001832
Joerg Roedeld160aca2015-07-22 11:52:53 +02001833 domain->iommu_did[iommu->seq_id] = num;
1834 domain->nid = iommu->node;
1835
Jiang Liufb170fb2014-07-11 14:19:28 +08001836 domain_update_iommu_cap(domain);
1837 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001838
Joerg Roedel55d94042015-07-22 16:50:40 +02001839 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001840}
1841
1842static int domain_detach_iommu(struct dmar_domain *domain,
1843 struct intel_iommu *iommu)
1844{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001845 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001846
Joerg Roedel55d94042015-07-22 16:50:40 +02001847 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001848 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001849
Joerg Roedel29a27712015-07-21 17:17:12 +02001850 domain->iommu_refcnt[iommu->seq_id] -= 1;
1851 count = --domain->iommu_count;
1852 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001853 num = domain->iommu_did[iommu->seq_id];
1854 clear_bit(num, iommu->domain_ids);
1855 set_iommu_domain(iommu, num, NULL);
1856
Jiang Liufb170fb2014-07-11 14:19:28 +08001857 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001858 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001859 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001860
1861 return count;
1862}
1863
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001864static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001865static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001866
Joseph Cihula51a63e62011-03-21 11:04:24 -07001867static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001868{
1869 struct pci_dev *pdev = NULL;
1870 struct iova *iova;
1871 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001872
Robin Murphy0fb5fe82015-01-12 17:51:16 +00001873 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN,
1874 DMA_32BIT_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001875
Mark Gross8a443df2008-03-04 14:59:31 -08001876 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1877 &reserved_rbtree_key);
1878
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001879 /* IOAPIC ranges shouldn't be accessed by DMA */
1880 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1881 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001882 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001883 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001884 return -ENODEV;
1885 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001886
1887 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1888 for_each_pci_dev(pdev) {
1889 struct resource *r;
1890
1891 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1892 r = &pdev->resource[i];
1893 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1894 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001895 iova = reserve_iova(&reserved_iova_list,
1896 IOVA_PFN(r->start),
1897 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001898 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001899 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001900 return -ENODEV;
1901 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001902 }
1903 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001904 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001905}
1906
1907static void domain_reserve_special_ranges(struct dmar_domain *domain)
1908{
1909 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1910}
1911
1912static inline int guestwidth_to_adjustwidth(int gaw)
1913{
1914 int agaw;
1915 int r = (gaw - 12) % 9;
1916
1917 if (r == 0)
1918 agaw = gaw;
1919 else
1920 agaw = gaw + 9 - r;
1921 if (agaw > 64)
1922 agaw = 64;
1923 return agaw;
1924}
1925
Joerg Roedeldc534b22015-07-22 12:44:02 +02001926static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1927 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001928{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001929 int adjust_width, agaw;
1930 unsigned long sagaw;
1931
Robin Murphy0fb5fe82015-01-12 17:51:16 +00001932 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
1933 DMA_32BIT_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001934 domain_reserve_special_ranges(domain);
1935
1936 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001937 if (guest_width > cap_mgaw(iommu->cap))
1938 guest_width = cap_mgaw(iommu->cap);
1939 domain->gaw = guest_width;
1940 adjust_width = guestwidth_to_adjustwidth(guest_width);
1941 agaw = width_to_agaw(adjust_width);
1942 sagaw = cap_sagaw(iommu->cap);
1943 if (!test_bit(agaw, &sagaw)) {
1944 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001945 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001946 agaw = find_next_bit(&sagaw, 5, agaw);
1947 if (agaw >= 5)
1948 return -ENODEV;
1949 }
1950 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001951
Weidong Han8e6040972008-12-08 15:49:06 +08001952 if (ecap_coherent(iommu->ecap))
1953 domain->iommu_coherency = 1;
1954 else
1955 domain->iommu_coherency = 0;
1956
Sheng Yang58c610b2009-03-18 15:33:05 +08001957 if (ecap_sc_support(iommu->ecap))
1958 domain->iommu_snooping = 1;
1959 else
1960 domain->iommu_snooping = 0;
1961
David Woodhouse214e39a2014-03-19 10:38:49 +00001962 if (intel_iommu_superpage)
1963 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1964 else
1965 domain->iommu_superpage = 0;
1966
Suresh Siddha4c923d42009-10-02 11:01:24 -07001967 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001968
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001969 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001970 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001971 if (!domain->pgd)
1972 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001973 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001974 return 0;
1975}
1976
1977static void domain_exit(struct dmar_domain *domain)
1978{
David Woodhouseea8ea462014-03-05 17:09:32 +00001979 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001980
1981 /* Domain 0 is reserved, so dont process it */
1982 if (!domain)
1983 return;
1984
Alex Williamson7b668352011-05-24 12:02:41 +01001985 /* Flush any lazy unmaps that may reference this domain */
Omer Pelegaa473242016-04-20 11:33:02 +03001986 if (!intel_iommu_strict) {
1987 int cpu;
1988
1989 for_each_possible_cpu(cpu)
1990 flush_unmaps_timeout(cpu);
1991 }
Alex Williamson7b668352011-05-24 12:02:41 +01001992
Joerg Roedeld160aca2015-07-22 11:52:53 +02001993 /* Remove associated devices and clear attached or cached domains */
1994 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001995 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001996 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08001997
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001998 /* destroy iovas */
1999 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002000
David Woodhouseea8ea462014-03-05 17:09:32 +00002001 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002002
David Woodhouseea8ea462014-03-05 17:09:32 +00002003 dma_free_pagelist(freelist);
2004
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002005 free_domain_mem(domain);
2006}
2007
David Woodhouse64ae8922014-03-09 12:52:30 -07002008static int domain_context_mapping_one(struct dmar_domain *domain,
2009 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002010 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002011{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002012 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002013 int translation = CONTEXT_TT_MULTI_LEVEL;
2014 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002015 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002016 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002017 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002018 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002019
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002020 WARN_ON(did == 0);
2021
Joerg Roedel28ccce02015-07-21 14:45:31 +02002022 if (hw_pass_through && domain_type_is_si(domain))
2023 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002024
2025 pr_debug("Set context mapping for %02x:%02x.%d\n",
2026 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002027
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002028 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002029
Joerg Roedel55d94042015-07-22 16:50:40 +02002030 spin_lock_irqsave(&device_domain_lock, flags);
2031 spin_lock(&iommu->lock);
2032
2033 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002034 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002035 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002036 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002037
Joerg Roedel55d94042015-07-22 16:50:40 +02002038 ret = 0;
2039 if (context_present(context))
2040 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002041
Xunlei Pangaec0e862016-12-05 20:09:07 +08002042 /*
2043 * For kdump cases, old valid entries may be cached due to the
2044 * in-flight DMA and copied pgtable, but there is no unmapping
2045 * behaviour for them, thus we need an explicit cache flush for
2046 * the newly-mapped device. For kdump, at this point, the device
2047 * is supposed to finish reset at its driver probe stage, so no
2048 * in-flight DMA will exist, and we don't need to worry anymore
2049 * hereafter.
2050 */
2051 if (context_copied(context)) {
2052 u16 did_old = context_domain_id(context);
2053
2054 if (did_old >= 0 && did_old < cap_ndoms(iommu->cap))
2055 iommu->flush.flush_context(iommu, did_old,
2056 (((u16)bus) << 8) | devfn,
2057 DMA_CCMD_MASK_NOBIT,
2058 DMA_CCMD_DEVICE_INVL);
2059 }
2060
Weidong Hanea6606b2008-12-08 23:08:15 +08002061 pgd = domain->pgd;
2062
Joerg Roedelde24e552015-07-21 14:53:04 +02002063 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002064 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002065
Joerg Roedelde24e552015-07-21 14:53:04 +02002066 /*
2067 * Skip top levels of page tables for iommu which has less agaw
2068 * than default. Unnecessary for PT mode.
2069 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002070 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002071 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002072 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002073 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002074 if (!dma_pte_present(pgd))
2075 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002076 }
2077
David Woodhouse64ae8922014-03-09 12:52:30 -07002078 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002079 if (info && info->ats_supported)
2080 translation = CONTEXT_TT_DEV_IOTLB;
2081 else
2082 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002083
Yu Zhao93a23a72009-05-18 13:51:37 +08002084 context_set_address_root(context, virt_to_phys(pgd));
2085 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002086 } else {
2087 /*
2088 * In pass through mode, AW must be programmed to
2089 * indicate the largest AGAW value supported by
2090 * hardware. And ASR is ignored by hardware.
2091 */
2092 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002093 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002094
2095 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002096 context_set_fault_enable(context);
2097 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002098 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002099
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002100 /*
2101 * It's a non-present to present mapping. If hardware doesn't cache
2102 * non-present entry we only need to flush the write-buffer. If the
2103 * _does_ cache non-present entries, then it does so in the special
2104 * domain #0, which we have to flush:
2105 */
2106 if (cap_caching_mode(iommu->cap)) {
2107 iommu->flush.flush_context(iommu, 0,
2108 (((u16)bus) << 8) | devfn,
2109 DMA_CCMD_MASK_NOBIT,
2110 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002111 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002112 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002113 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002114 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002115 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002116
Joerg Roedel55d94042015-07-22 16:50:40 +02002117 ret = 0;
2118
2119out_unlock:
2120 spin_unlock(&iommu->lock);
2121 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002122
Wei Yang5c365d12016-07-13 13:53:21 +00002123 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002124}
2125
Alex Williamson579305f2014-07-03 09:51:43 -06002126struct domain_context_mapping_data {
2127 struct dmar_domain *domain;
2128 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002129};
2130
2131static int domain_context_mapping_cb(struct pci_dev *pdev,
2132 u16 alias, void *opaque)
2133{
2134 struct domain_context_mapping_data *data = opaque;
2135
2136 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002137 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002138}
2139
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002140static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002141domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002142{
David Woodhouse64ae8922014-03-09 12:52:30 -07002143 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002144 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002145 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002146
David Woodhousee1f167f2014-03-09 15:24:46 -07002147 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002148 if (!iommu)
2149 return -ENODEV;
2150
Alex Williamson579305f2014-07-03 09:51:43 -06002151 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002152 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002153
2154 data.domain = domain;
2155 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002156
2157 return pci_for_each_dma_alias(to_pci_dev(dev),
2158 &domain_context_mapping_cb, &data);
2159}
2160
2161static int domain_context_mapped_cb(struct pci_dev *pdev,
2162 u16 alias, void *opaque)
2163{
2164 struct intel_iommu *iommu = opaque;
2165
2166 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002167}
2168
David Woodhousee1f167f2014-03-09 15:24:46 -07002169static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002170{
Weidong Han5331fe62008-12-08 23:00:00 +08002171 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002172 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002173
David Woodhousee1f167f2014-03-09 15:24:46 -07002174 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002175 if (!iommu)
2176 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002177
Alex Williamson579305f2014-07-03 09:51:43 -06002178 if (!dev_is_pci(dev))
2179 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002180
Alex Williamson579305f2014-07-03 09:51:43 -06002181 return !pci_for_each_dma_alias(to_pci_dev(dev),
2182 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002183}
2184
Fenghua Yuf5329592009-08-04 15:09:37 -07002185/* Returns a number of VTD pages, but aligned to MM page size */
2186static inline unsigned long aligned_nrpages(unsigned long host_addr,
2187 size_t size)
2188{
2189 host_addr &= ~PAGE_MASK;
2190 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2191}
2192
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002193/* Return largest possible superpage level for a given mapping */
2194static inline int hardware_largepage_caps(struct dmar_domain *domain,
2195 unsigned long iov_pfn,
2196 unsigned long phy_pfn,
2197 unsigned long pages)
2198{
2199 int support, level = 1;
2200 unsigned long pfnmerge;
2201
2202 support = domain->iommu_superpage;
2203
2204 /* To use a large page, the virtual *and* physical addresses
2205 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2206 of them will mean we have to use smaller pages. So just
2207 merge them and check both at once. */
2208 pfnmerge = iov_pfn | phy_pfn;
2209
2210 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2211 pages >>= VTD_STRIDE_SHIFT;
2212 if (!pages)
2213 break;
2214 pfnmerge >>= VTD_STRIDE_SHIFT;
2215 level++;
2216 support--;
2217 }
2218 return level;
2219}
2220
David Woodhouse9051aa02009-06-29 12:30:54 +01002221static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2222 struct scatterlist *sg, unsigned long phys_pfn,
2223 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002224{
2225 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002226 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002227 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002228 unsigned int largepage_lvl = 0;
2229 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002230
Jiang Liu162d1b12014-07-11 14:19:35 +08002231 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002232
2233 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2234 return -EINVAL;
2235
2236 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2237
Jiang Liucc4f14a2014-11-26 09:42:10 +08002238 if (!sg) {
2239 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002240 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2241 }
2242
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002243 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002244 uint64_t tmp;
2245
David Woodhousee1605492009-06-29 11:17:38 +01002246 if (!sg_res) {
Fenghua Yuf5329592009-08-04 15:09:37 -07002247 sg_res = aligned_nrpages(sg->offset, sg->length);
David Woodhousee1605492009-06-29 11:17:38 +01002248 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
2249 sg->dma_length = sg->length;
Dan Williams3e6110f2015-12-15 12:54:06 -08002250 pteval = page_to_phys(sg_page(sg)) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002251 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002252 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002253
David Woodhousee1605492009-06-29 11:17:38 +01002254 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002255 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2256
David Woodhouse5cf0a762014-03-19 16:07:49 +00002257 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002258 if (!pte)
2259 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002260 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002261 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002262 unsigned long nr_superpages, end_pfn;
2263
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002264 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002265 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002266
2267 nr_superpages = sg_res / lvl_pages;
2268 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2269
Jiang Liud41a4ad2014-07-11 14:19:34 +08002270 /*
2271 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002272 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002273 * We're adding new large pages, so make sure
2274 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002275 */
David Dillowbc24c572017-06-28 19:42:23 -07002276 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2277 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002278 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002279 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002280 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002281
David Woodhousee1605492009-06-29 11:17:38 +01002282 }
2283 /* We don't need lock here, nobody else
2284 * touches the iova range
2285 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002286 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002287 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002288 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002289 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2290 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002291 if (dumps) {
2292 dumps--;
2293 debug_dma_dump_mappings(NULL);
2294 }
2295 WARN_ON(1);
2296 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002297
2298 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2299
2300 BUG_ON(nr_pages < lvl_pages);
2301 BUG_ON(sg_res < lvl_pages);
2302
2303 nr_pages -= lvl_pages;
2304 iov_pfn += lvl_pages;
2305 phys_pfn += lvl_pages;
2306 pteval += lvl_pages * VTD_PAGE_SIZE;
2307 sg_res -= lvl_pages;
2308
2309 /* If the next PTE would be the first in a new page, then we
2310 need to flush the cache on the entries we've just written.
2311 And then we'll need to recalculate 'pte', so clear it and
2312 let it get set again in the if (!pte) block above.
2313
2314 If we're done (!nr_pages) we need to flush the cache too.
2315
2316 Also if we've been setting superpages, we may need to
2317 recalculate 'pte' and switch back to smaller pages for the
2318 end of the mapping, if the trailing size is not enough to
2319 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002320 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002321 if (!nr_pages || first_pte_in_page(pte) ||
2322 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002323 domain_flush_cache(domain, first_pte,
2324 (void *)pte - (void *)first_pte);
2325 pte = NULL;
2326 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002327
2328 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002329 sg = sg_next(sg);
2330 }
2331 return 0;
2332}
2333
David Woodhouse9051aa02009-06-29 12:30:54 +01002334static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2335 struct scatterlist *sg, unsigned long nr_pages,
2336 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002337{
David Woodhouse9051aa02009-06-29 12:30:54 +01002338 return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
2339}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002340
David Woodhouse9051aa02009-06-29 12:30:54 +01002341static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2342 unsigned long phys_pfn, unsigned long nr_pages,
2343 int prot)
2344{
2345 return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002346}
2347
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002348static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002349{
Filippo Sironi50822192017-08-31 10:58:11 +02002350 unsigned long flags;
2351 struct context_entry *context;
2352 u16 did_old;
2353
Weidong Hanc7151a82008-12-08 22:51:37 +08002354 if (!iommu)
2355 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002356
Filippo Sironi50822192017-08-31 10:58:11 +02002357 spin_lock_irqsave(&iommu->lock, flags);
2358 context = iommu_context_addr(iommu, bus, devfn, 0);
2359 if (!context) {
2360 spin_unlock_irqrestore(&iommu->lock, flags);
2361 return;
2362 }
2363 did_old = context_domain_id(context);
2364 context_clear_entry(context);
2365 __iommu_flush_cache(iommu, context, sizeof(*context));
2366 spin_unlock_irqrestore(&iommu->lock, flags);
2367 iommu->flush.flush_context(iommu,
2368 did_old,
2369 (((u16)bus) << 8) | devfn,
2370 DMA_CCMD_MASK_NOBIT,
2371 DMA_CCMD_DEVICE_INVL);
2372 iommu->flush.flush_iotlb(iommu,
2373 did_old,
2374 0,
2375 0,
2376 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002377}
2378
David Woodhouse109b9b02012-05-25 17:43:02 +01002379static inline void unlink_domain_info(struct device_domain_info *info)
2380{
2381 assert_spin_locked(&device_domain_lock);
2382 list_del(&info->link);
2383 list_del(&info->global);
2384 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002385 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002386}
2387
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002388static void domain_remove_dev_info(struct dmar_domain *domain)
2389{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002390 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002391 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002392
2393 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002394 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002395 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002396 spin_unlock_irqrestore(&device_domain_lock, flags);
2397}
2398
2399/*
2400 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002401 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002402 */
David Woodhouse1525a292014-03-06 16:19:30 +00002403static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002404{
2405 struct device_domain_info *info;
2406
2407 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002408 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002409 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002410 return info->domain;
2411 return NULL;
2412}
2413
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002414static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002415dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2416{
2417 struct device_domain_info *info;
2418
2419 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002420 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002421 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002422 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002423
2424 return NULL;
2425}
2426
Joerg Roedel5db31562015-07-22 12:40:43 +02002427static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2428 int bus, int devfn,
2429 struct device *dev,
2430 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002431{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002432 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002433 struct device_domain_info *info;
2434 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002435 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002436
2437 info = alloc_devinfo_mem();
2438 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002439 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002440
Jiang Liu745f2582014-02-19 14:07:26 +08002441 info->bus = bus;
2442 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002443 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2444 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2445 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002446 info->dev = dev;
2447 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002448 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002449
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002450 if (dev && dev_is_pci(dev)) {
2451 struct pci_dev *pdev = to_pci_dev(info->dev);
2452
2453 if (ecap_dev_iotlb_support(iommu->ecap) &&
2454 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2455 dmar_find_matched_atsr_unit(pdev))
2456 info->ats_supported = 1;
2457
2458 if (ecs_enabled(iommu)) {
2459 if (pasid_enabled(iommu)) {
2460 int features = pci_pasid_features(pdev);
2461 if (features >= 0)
2462 info->pasid_supported = features | 1;
2463 }
2464
2465 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2466 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2467 info->pri_supported = 1;
2468 }
2469 }
2470
Jiang Liu745f2582014-02-19 14:07:26 +08002471 spin_lock_irqsave(&device_domain_lock, flags);
2472 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002473 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002474
2475 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002476 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002477 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002478 if (info2) {
2479 found = info2->domain;
2480 info2->dev = dev;
2481 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002482 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002483
Jiang Liu745f2582014-02-19 14:07:26 +08002484 if (found) {
2485 spin_unlock_irqrestore(&device_domain_lock, flags);
2486 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002487 /* Caller must free the original domain */
2488 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002489 }
2490
Joerg Roedeld160aca2015-07-22 11:52:53 +02002491 spin_lock(&iommu->lock);
2492 ret = domain_attach_iommu(domain, iommu);
2493 spin_unlock(&iommu->lock);
2494
2495 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002496 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302497 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002498 return NULL;
2499 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002500
David Woodhouseb718cd32014-03-09 13:11:33 -07002501 list_add(&info->link, &domain->devices);
2502 list_add(&info->global, &device_domain_list);
2503 if (dev)
2504 dev->archdata.iommu = info;
2505 spin_unlock_irqrestore(&device_domain_lock, flags);
2506
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002507 if (dev && domain_context_mapping(domain, dev)) {
2508 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002509 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002510 return NULL;
2511 }
2512
David Woodhouseb718cd32014-03-09 13:11:33 -07002513 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002514}
2515
Alex Williamson579305f2014-07-03 09:51:43 -06002516static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2517{
2518 *(u16 *)opaque = alias;
2519 return 0;
2520}
2521
Joerg Roedel76208352016-08-25 14:25:12 +02002522static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002523{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002524 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002525 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002526 struct intel_iommu *iommu;
Joerg Roedel08a7f452015-07-23 18:09:11 +02002527 u16 req_id, dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002528 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002529 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002530
David Woodhouse146922e2014-03-09 15:44:17 -07002531 iommu = device_to_iommu(dev, &bus, &devfn);
2532 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002533 return NULL;
2534
Joerg Roedel08a7f452015-07-23 18:09:11 +02002535 req_id = ((u16)bus << 8) | devfn;
2536
Alex Williamson579305f2014-07-03 09:51:43 -06002537 if (dev_is_pci(dev)) {
2538 struct pci_dev *pdev = to_pci_dev(dev);
2539
2540 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2541
2542 spin_lock_irqsave(&device_domain_lock, flags);
2543 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2544 PCI_BUS_NUM(dma_alias),
2545 dma_alias & 0xff);
2546 if (info) {
2547 iommu = info->iommu;
2548 domain = info->domain;
2549 }
2550 spin_unlock_irqrestore(&device_domain_lock, flags);
2551
Joerg Roedel76208352016-08-25 14:25:12 +02002552 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002553 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002554 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002555 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002556
David Woodhouse146922e2014-03-09 15:44:17 -07002557 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002558 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002559 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002560 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002561 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002562 domain_exit(domain);
2563 return NULL;
2564 }
2565
Joerg Roedel76208352016-08-25 14:25:12 +02002566out:
Alex Williamson579305f2014-07-03 09:51:43 -06002567
Joerg Roedel76208352016-08-25 14:25:12 +02002568 return domain;
2569}
2570
2571static struct dmar_domain *set_domain_for_dev(struct device *dev,
2572 struct dmar_domain *domain)
2573{
2574 struct intel_iommu *iommu;
2575 struct dmar_domain *tmp;
2576 u16 req_id, dma_alias;
2577 u8 bus, devfn;
2578
2579 iommu = device_to_iommu(dev, &bus, &devfn);
2580 if (!iommu)
2581 return NULL;
2582
2583 req_id = ((u16)bus << 8) | devfn;
2584
2585 if (dev_is_pci(dev)) {
2586 struct pci_dev *pdev = to_pci_dev(dev);
2587
2588 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2589
2590 /* register PCI DMA alias device */
2591 if (req_id != dma_alias) {
2592 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2593 dma_alias & 0xff, NULL, domain);
2594
2595 if (!tmp || tmp != domain)
2596 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002597 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002598 }
2599
Joerg Roedel5db31562015-07-22 12:40:43 +02002600 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002601 if (!tmp || tmp != domain)
2602 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002603
Joerg Roedel76208352016-08-25 14:25:12 +02002604 return domain;
2605}
2606
2607static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2608{
2609 struct dmar_domain *domain, *tmp;
2610
2611 domain = find_domain(dev);
2612 if (domain)
2613 goto out;
2614
2615 domain = find_or_alloc_domain(dev, gaw);
2616 if (!domain)
2617 goto out;
2618
2619 tmp = set_domain_for_dev(dev, domain);
2620 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002621 domain_exit(domain);
2622 domain = tmp;
2623 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002624
Joerg Roedel76208352016-08-25 14:25:12 +02002625out:
2626
David Woodhouseb718cd32014-03-09 13:11:33 -07002627 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002628}
2629
David Woodhouseb2132032009-06-26 18:50:28 +01002630static int iommu_domain_identity_map(struct dmar_domain *domain,
2631 unsigned long long start,
2632 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002633{
David Woodhousec5395d52009-06-28 16:35:56 +01002634 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2635 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002636
David Woodhousec5395d52009-06-28 16:35:56 +01002637 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2638 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002639 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002640 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002641 }
2642
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002643 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002644 /*
2645 * RMRR range might have overlap with physical memory range,
2646 * clear it first
2647 */
David Woodhousec5395d52009-06-28 16:35:56 +01002648 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002649
David Woodhousec5395d52009-06-28 16:35:56 +01002650 return domain_pfn_mapping(domain, first_vpfn, first_vpfn,
2651 last_vpfn - first_vpfn + 1,
David Woodhouse61df7442009-06-28 11:55:58 +01002652 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002653}
2654
Joerg Roedeld66ce542015-09-23 19:00:10 +02002655static int domain_prepare_identity_map(struct device *dev,
2656 struct dmar_domain *domain,
2657 unsigned long long start,
2658 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002659{
David Woodhouse19943b02009-08-04 16:19:20 +01002660 /* For _hardware_ passthrough, don't bother. But for software
2661 passthrough, we do it anyway -- it may indicate a memory
2662 range which is reserved in E820, so which didn't get set
2663 up to start with in si_domain */
2664 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002665 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2666 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002667 return 0;
2668 }
2669
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002670 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2671 dev_name(dev), start, end);
2672
David Woodhouse5595b522009-12-02 09:21:55 +00002673 if (end < start) {
2674 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2675 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2676 dmi_get_system_info(DMI_BIOS_VENDOR),
2677 dmi_get_system_info(DMI_BIOS_VERSION),
2678 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002679 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002680 }
2681
David Woodhouse2ff729f2009-08-26 14:25:41 +01002682 if (end >> agaw_to_width(domain->agaw)) {
2683 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2684 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2685 agaw_to_width(domain->agaw),
2686 dmi_get_system_info(DMI_BIOS_VENDOR),
2687 dmi_get_system_info(DMI_BIOS_VERSION),
2688 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002689 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002690 }
David Woodhouse19943b02009-08-04 16:19:20 +01002691
Joerg Roedeld66ce542015-09-23 19:00:10 +02002692 return iommu_domain_identity_map(domain, start, end);
2693}
2694
2695static int iommu_prepare_identity_map(struct device *dev,
2696 unsigned long long start,
2697 unsigned long long end)
2698{
2699 struct dmar_domain *domain;
2700 int ret;
2701
2702 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2703 if (!domain)
2704 return -ENOMEM;
2705
2706 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002707 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002708 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002709
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002710 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002711}
2712
2713static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002714 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002715{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002716 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002717 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002718 return iommu_prepare_identity_map(dev, rmrr->base_address,
2719 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002720}
2721
Suresh Siddhad3f13812011-08-23 17:05:25 -07002722#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002723static inline void iommu_prepare_isa(void)
2724{
2725 struct pci_dev *pdev;
2726 int ret;
2727
2728 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2729 if (!pdev)
2730 return;
2731
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002732 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002733 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002734
2735 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002736 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002737
Yijing Wang9b27e822014-05-20 20:37:52 +08002738 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002739}
2740#else
2741static inline void iommu_prepare_isa(void)
2742{
2743 return;
2744}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002745#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002746
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002747static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002748
Matt Kraai071e1372009-08-23 22:30:22 -07002749static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002750{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002751 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002752
Jiang Liuab8dfe22014-07-11 14:19:27 +08002753 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002754 if (!si_domain)
2755 return -EFAULT;
2756
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002757 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2758 domain_exit(si_domain);
2759 return -EFAULT;
2760 }
2761
Joerg Roedel0dc79712015-07-21 15:40:06 +02002762 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002763
David Woodhouse19943b02009-08-04 16:19:20 +01002764 if (hw)
2765 return 0;
2766
David Woodhousec7ab48d2009-06-26 19:10:36 +01002767 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002768 unsigned long start_pfn, end_pfn;
2769 int i;
2770
2771 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2772 ret = iommu_domain_identity_map(si_domain,
2773 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2774 if (ret)
2775 return ret;
2776 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002777 }
2778
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002779 return 0;
2780}
2781
David Woodhouse9b226622014-03-09 14:03:28 -07002782static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002783{
2784 struct device_domain_info *info;
2785
2786 if (likely(!iommu_identity_mapping))
2787 return 0;
2788
David Woodhouse9b226622014-03-09 14:03:28 -07002789 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002790 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2791 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002792
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002793 return 0;
2794}
2795
Joerg Roedel28ccce02015-07-21 14:45:31 +02002796static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002797{
David Woodhouse0ac72662014-03-09 13:19:22 -07002798 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002799 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002800 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002801
David Woodhouse5913c9b2014-03-09 16:27:31 -07002802 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002803 if (!iommu)
2804 return -ENODEV;
2805
Joerg Roedel5db31562015-07-22 12:40:43 +02002806 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002807 if (ndomain != domain)
2808 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002809
2810 return 0;
2811}
2812
David Woodhouse0b9d9752014-03-09 15:48:15 -07002813static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002814{
2815 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002816 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002817 int i;
2818
Jiang Liu0e242612014-02-19 14:07:34 +08002819 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002820 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002821 /*
2822 * Return TRUE if this RMRR contains the device that
2823 * is passed in.
2824 */
2825 for_each_active_dev_scope(rmrr->devices,
2826 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002827 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002828 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002829 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002830 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002831 }
Jiang Liu0e242612014-02-19 14:07:34 +08002832 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002833 return false;
2834}
2835
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002836/*
2837 * There are a couple cases where we need to restrict the functionality of
2838 * devices associated with RMRRs. The first is when evaluating a device for
2839 * identity mapping because problems exist when devices are moved in and out
2840 * of domains and their respective RMRR information is lost. This means that
2841 * a device with associated RMRRs will never be in a "passthrough" domain.
2842 * The second is use of the device through the IOMMU API. This interface
2843 * expects to have full control of the IOVA space for the device. We cannot
2844 * satisfy both the requirement that RMRR access is maintained and have an
2845 * unencumbered IOVA space. We also have no ability to quiesce the device's
2846 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2847 * We therefore prevent devices associated with an RMRR from participating in
2848 * the IOMMU API, which eliminates them from device assignment.
2849 *
2850 * In both cases we assume that PCI USB devices with RMRRs have them largely
2851 * for historical reasons and that the RMRR space is not actively used post
2852 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002853 *
2854 * The same exception is made for graphics devices, with the requirement that
2855 * any use of the RMRR regions will be torn down before assigning the device
2856 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002857 */
2858static bool device_is_rmrr_locked(struct device *dev)
2859{
2860 if (!device_has_rmrr(dev))
2861 return false;
2862
2863 if (dev_is_pci(dev)) {
2864 struct pci_dev *pdev = to_pci_dev(dev);
2865
David Woodhouse18436af2015-03-25 15:05:47 +00002866 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002867 return false;
2868 }
2869
2870 return true;
2871}
2872
David Woodhouse3bdb2592014-03-09 16:03:08 -07002873static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002874{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002875
David Woodhouse3bdb2592014-03-09 16:03:08 -07002876 if (dev_is_pci(dev)) {
2877 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002878
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002879 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002880 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002881
David Woodhouse3bdb2592014-03-09 16:03:08 -07002882 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2883 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002884
David Woodhouse3bdb2592014-03-09 16:03:08 -07002885 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2886 return 1;
2887
2888 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2889 return 0;
2890
2891 /*
2892 * We want to start off with all devices in the 1:1 domain, and
2893 * take them out later if we find they can't access all of memory.
2894 *
2895 * However, we can't do this for PCI devices behind bridges,
2896 * because all PCI devices behind the same bridge will end up
2897 * with the same source-id on their transactions.
2898 *
2899 * Practically speaking, we can't change things around for these
2900 * devices at run-time, because we can't be sure there'll be no
2901 * DMA transactions in flight for any of their siblings.
2902 *
2903 * So PCI devices (unless they're on the root bus) as well as
2904 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2905 * the 1:1 domain, just in _case_ one of their siblings turns out
2906 * not to be able to map all of memory.
2907 */
2908 if (!pci_is_pcie(pdev)) {
2909 if (!pci_is_root_bus(pdev->bus))
2910 return 0;
2911 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2912 return 0;
2913 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2914 return 0;
2915 } else {
2916 if (device_has_rmrr(dev))
2917 return 0;
2918 }
David Woodhouse6941af22009-07-04 18:24:27 +01002919
David Woodhouse3dfc8132009-07-04 19:11:08 +01002920 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002921 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002922 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002923 * take them out of the 1:1 domain later.
2924 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002925 if (!startup) {
2926 /*
2927 * If the device's dma_mask is less than the system's memory
2928 * size then this is not a candidate for identity mapping.
2929 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002930 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002931
David Woodhouse3bdb2592014-03-09 16:03:08 -07002932 if (dev->coherent_dma_mask &&
2933 dev->coherent_dma_mask < dma_mask)
2934 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002935
David Woodhouse3bdb2592014-03-09 16:03:08 -07002936 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002937 }
David Woodhouse6941af22009-07-04 18:24:27 +01002938
2939 return 1;
2940}
2941
David Woodhousecf04eee2014-03-21 16:49:04 +00002942static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2943{
2944 int ret;
2945
2946 if (!iommu_should_identity_map(dev, 1))
2947 return 0;
2948
Joerg Roedel28ccce02015-07-21 14:45:31 +02002949 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002950 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002951 pr_info("%s identity mapping for device %s\n",
2952 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002953 else if (ret == -ENODEV)
2954 /* device not associated with an iommu */
2955 ret = 0;
2956
2957 return ret;
2958}
2959
2960
Matt Kraai071e1372009-08-23 22:30:22 -07002961static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002962{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002963 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002964 struct dmar_drhd_unit *drhd;
2965 struct intel_iommu *iommu;
2966 struct device *dev;
2967 int i;
2968 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002969
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002970 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002971 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2972 if (ret)
2973 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002974 }
2975
David Woodhousecf04eee2014-03-21 16:49:04 +00002976 for_each_active_iommu(iommu, drhd)
2977 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2978 struct acpi_device_physical_node *pn;
2979 struct acpi_device *adev;
2980
2981 if (dev->bus != &acpi_bus_type)
2982 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02002983
David Woodhousecf04eee2014-03-21 16:49:04 +00002984 adev= to_acpi_device(dev);
2985 mutex_lock(&adev->physical_node_lock);
2986 list_for_each_entry(pn, &adev->physical_node_list, node) {
2987 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
2988 if (ret)
2989 break;
2990 }
2991 mutex_unlock(&adev->physical_node_lock);
2992 if (ret)
2993 return ret;
2994 }
2995
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002996 return 0;
2997}
2998
Jiang Liuffebeb42014-11-09 22:48:02 +08002999static void intel_iommu_init_qi(struct intel_iommu *iommu)
3000{
3001 /*
3002 * Start from the sane iommu hardware state.
3003 * If the queued invalidation is already initialized by us
3004 * (for example, while enabling interrupt-remapping) then
3005 * we got the things already rolling from a sane state.
3006 */
3007 if (!iommu->qi) {
3008 /*
3009 * Clear any previous faults.
3010 */
3011 dmar_fault(-1, iommu);
3012 /*
3013 * Disable queued invalidation if supported and already enabled
3014 * before OS handover.
3015 */
3016 dmar_disable_qi(iommu);
3017 }
3018
3019 if (dmar_enable_qi(iommu)) {
3020 /*
3021 * Queued Invalidate not enabled, use Register Based Invalidate
3022 */
3023 iommu->flush.flush_context = __iommu_flush_context;
3024 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003025 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003026 iommu->name);
3027 } else {
3028 iommu->flush.flush_context = qi_flush_context;
3029 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003030 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003031 }
3032}
3033
Joerg Roedel091d42e2015-06-12 11:56:10 +02003034static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003035 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003036 struct context_entry **tbl,
3037 int bus, bool ext)
3038{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003039 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003040 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003041 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003042 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003043 phys_addr_t old_ce_phys;
3044
3045 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003046 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003047
3048 for (devfn = 0; devfn < 256; devfn++) {
3049 /* First calculate the correct index */
3050 idx = (ext ? devfn * 2 : devfn) % 256;
3051
3052 if (idx == 0) {
3053 /* First save what we may have and clean up */
3054 if (new_ce) {
3055 tbl[tbl_idx] = new_ce;
3056 __iommu_flush_cache(iommu, new_ce,
3057 VTD_PAGE_SIZE);
3058 pos = 1;
3059 }
3060
3061 if (old_ce)
3062 iounmap(old_ce);
3063
3064 ret = 0;
3065 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003066 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003067 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003068 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003069
3070 if (!old_ce_phys) {
3071 if (ext && devfn == 0) {
3072 /* No LCTP, try UCTP */
3073 devfn = 0x7f;
3074 continue;
3075 } else {
3076 goto out;
3077 }
3078 }
3079
3080 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003081 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3082 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003083 if (!old_ce)
3084 goto out;
3085
3086 new_ce = alloc_pgtable_page(iommu->node);
3087 if (!new_ce)
3088 goto out_unmap;
3089
3090 ret = 0;
3091 }
3092
3093 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003094 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003095
Joerg Roedelcf484d02015-06-12 12:21:46 +02003096 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003097 continue;
3098
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003099 did = context_domain_id(&ce);
3100 if (did >= 0 && did < cap_ndoms(iommu->cap))
3101 set_bit(did, iommu->domain_ids);
3102
Joerg Roedelcf484d02015-06-12 12:21:46 +02003103 /*
3104 * We need a marker for copied context entries. This
3105 * marker needs to work for the old format as well as
3106 * for extended context entries.
3107 *
3108 * Bit 67 of the context entry is used. In the old
3109 * format this bit is available to software, in the
3110 * extended format it is the PGE bit, but PGE is ignored
3111 * by HW if PASIDs are disabled (and thus still
3112 * available).
3113 *
3114 * So disable PASIDs first and then mark the entry
3115 * copied. This means that we don't copy PASID
3116 * translations from the old kernel, but this is fine as
3117 * faults there are not fatal.
3118 */
3119 context_clear_pasid_enable(&ce);
3120 context_set_copied(&ce);
3121
Joerg Roedel091d42e2015-06-12 11:56:10 +02003122 new_ce[idx] = ce;
3123 }
3124
3125 tbl[tbl_idx + pos] = new_ce;
3126
3127 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3128
3129out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003130 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003131
3132out:
3133 return ret;
3134}
3135
3136static int copy_translation_tables(struct intel_iommu *iommu)
3137{
3138 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003139 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003140 phys_addr_t old_rt_phys;
3141 int ctxt_table_entries;
3142 unsigned long flags;
3143 u64 rtaddr_reg;
3144 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003145 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003146
3147 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3148 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003149 new_ext = !!ecap_ecs(iommu->ecap);
3150
3151 /*
3152 * The RTT bit can only be changed when translation is disabled,
3153 * but disabling translation means to open a window for data
3154 * corruption. So bail out and don't copy anything if we would
3155 * have to change the bit.
3156 */
3157 if (new_ext != ext)
3158 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003159
3160 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3161 if (!old_rt_phys)
3162 return -EINVAL;
3163
Dan Williamsdfddb9692015-10-09 18:16:46 -04003164 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003165 if (!old_rt)
3166 return -ENOMEM;
3167
3168 /* This is too big for the stack - allocate it from slab */
3169 ctxt_table_entries = ext ? 512 : 256;
3170 ret = -ENOMEM;
3171 ctxt_tbls = kzalloc(ctxt_table_entries * sizeof(void *), GFP_KERNEL);
3172 if (!ctxt_tbls)
3173 goto out_unmap;
3174
3175 for (bus = 0; bus < 256; bus++) {
3176 ret = copy_context_table(iommu, &old_rt[bus],
3177 ctxt_tbls, bus, ext);
3178 if (ret) {
3179 pr_err("%s: Failed to copy context table for bus %d\n",
3180 iommu->name, bus);
3181 continue;
3182 }
3183 }
3184
3185 spin_lock_irqsave(&iommu->lock, flags);
3186
3187 /* Context tables are copied, now write them to the root_entry table */
3188 for (bus = 0; bus < 256; bus++) {
3189 int idx = ext ? bus * 2 : bus;
3190 u64 val;
3191
3192 if (ctxt_tbls[idx]) {
3193 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3194 iommu->root_entry[bus].lo = val;
3195 }
3196
3197 if (!ext || !ctxt_tbls[idx + 1])
3198 continue;
3199
3200 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3201 iommu->root_entry[bus].hi = val;
3202 }
3203
3204 spin_unlock_irqrestore(&iommu->lock, flags);
3205
3206 kfree(ctxt_tbls);
3207
3208 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3209
3210 ret = 0;
3211
3212out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003213 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003214
3215 return ret;
3216}
3217
Joseph Cihulab7792602011-05-03 00:08:37 -07003218static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003219{
3220 struct dmar_drhd_unit *drhd;
3221 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003222 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003223 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003224 struct intel_iommu *iommu;
Omer Pelegaa473242016-04-20 11:33:02 +03003225 int i, ret, cpu;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003226
3227 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003228 * for each drhd
3229 * allocate root
3230 * initialize and program root entry to not present
3231 * endfor
3232 */
3233 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003234 /*
3235 * lock not needed as this is only incremented in the single
3236 * threaded kernel __init code path all other access are read
3237 * only
3238 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003239 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003240 g_num_of_iommus++;
3241 continue;
3242 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003243 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003244 }
3245
Jiang Liuffebeb42014-11-09 22:48:02 +08003246 /* Preallocate enough resources for IOMMU hot-addition */
3247 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3248 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3249
Weidong Hand9630fe2008-12-08 11:06:32 +08003250 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3251 GFP_KERNEL);
3252 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003253 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003254 ret = -ENOMEM;
3255 goto error;
3256 }
3257
Omer Pelegaa473242016-04-20 11:33:02 +03003258 for_each_possible_cpu(cpu) {
3259 struct deferred_flush_data *dfd = per_cpu_ptr(&deferred_flush,
3260 cpu);
3261
3262 dfd->tables = kzalloc(g_num_of_iommus *
3263 sizeof(struct deferred_flush_table),
3264 GFP_KERNEL);
3265 if (!dfd->tables) {
3266 ret = -ENOMEM;
3267 goto free_g_iommus;
3268 }
3269
3270 spin_lock_init(&dfd->lock);
3271 setup_timer(&dfd->timer, flush_unmaps_timeout, cpu);
mark gross5e0d2a62008-03-04 15:22:08 -08003272 }
3273
Jiang Liu7c919772014-01-06 14:18:18 +08003274 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003275 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003276
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003277 intel_iommu_init_qi(iommu);
3278
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003279 ret = iommu_init_domains(iommu);
3280 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003281 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003282
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003283 init_translation_status(iommu);
3284
Joerg Roedel091d42e2015-06-12 11:56:10 +02003285 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3286 iommu_disable_translation(iommu);
3287 clear_translation_pre_enabled(iommu);
3288 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3289 iommu->name);
3290 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003291
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003292 /*
3293 * TBD:
3294 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003295 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003296 */
3297 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003298 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003299 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003300
Joerg Roedel091d42e2015-06-12 11:56:10 +02003301 if (translation_pre_enabled(iommu)) {
3302 pr_info("Translation already enabled - trying to copy translation structures\n");
3303
3304 ret = copy_translation_tables(iommu);
3305 if (ret) {
3306 /*
3307 * We found the IOMMU with translation
3308 * enabled - but failed to copy over the
3309 * old root-entry table. Try to proceed
3310 * by disabling translation now and
3311 * allocating a clean root-entry table.
3312 * This might cause DMAR faults, but
3313 * probably the dump will still succeed.
3314 */
3315 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3316 iommu->name);
3317 iommu_disable_translation(iommu);
3318 clear_translation_pre_enabled(iommu);
3319 } else {
3320 pr_info("Copied translation tables from previous kernel for %s\n",
3321 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003322 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003323 }
3324 }
3325
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003326 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003327 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003328#ifdef CONFIG_INTEL_IOMMU_SVM
3329 if (pasid_enabled(iommu))
3330 intel_svm_alloc_pasid_tables(iommu);
3331#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003332 }
3333
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003334 /*
3335 * Now that qi is enabled on all iommus, set the root entry and flush
3336 * caches. This is required on some Intel X58 chipsets, otherwise the
3337 * flush_context function will loop forever and the boot hangs.
3338 */
3339 for_each_active_iommu(iommu, drhd) {
3340 iommu_flush_write_buffer(iommu);
3341 iommu_set_root_entry(iommu);
3342 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3343 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3344 }
3345
David Woodhouse19943b02009-08-04 16:19:20 +01003346 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003347 iommu_identity_mapping |= IDENTMAP_ALL;
3348
Suresh Siddhad3f13812011-08-23 17:05:25 -07003349#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003350 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003351#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003352
Ashok Raj21e722c2017-01-30 09:39:53 -08003353 check_tylersburg_isoch();
3354
Joerg Roedel86080cc2015-06-12 12:27:16 +02003355 if (iommu_identity_mapping) {
3356 ret = si_domain_init(hw_pass_through);
3357 if (ret)
3358 goto free_iommu;
3359 }
3360
David Woodhousee0fc7e02009-09-30 09:12:17 -07003361
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003362 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003363 * If we copied translations from a previous kernel in the kdump
3364 * case, we can not assign the devices to domains now, as that
3365 * would eliminate the old mappings. So skip this part and defer
3366 * the assignment to device driver initialization time.
3367 */
3368 if (copied_tables)
3369 goto domains_done;
3370
3371 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003372 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003373 * identity mappings for rmrr, gfx, and isa and may fall back to static
3374 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003375 */
David Woodhouse19943b02009-08-04 16:19:20 +01003376 if (iommu_identity_mapping) {
3377 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3378 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003379 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003380 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003381 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003382 }
David Woodhouse19943b02009-08-04 16:19:20 +01003383 /*
3384 * For each rmrr
3385 * for each dev attached to rmrr
3386 * do
3387 * locate drhd for dev, alloc domain for dev
3388 * allocate free domain
3389 * allocate page table entries for rmrr
3390 * if context not allocated for bus
3391 * allocate and init context
3392 * set present in root table for this bus
3393 * init context with domain, translation etc
3394 * endfor
3395 * endfor
3396 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003397 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003398 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003399 /* some BIOS lists non-exist devices in DMAR table. */
3400 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003401 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003402 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003403 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003404 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003405 }
3406 }
3407
3408 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003409
Joerg Roedela87f4912015-06-12 12:32:54 +02003410domains_done:
3411
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003412 /*
3413 * for each drhd
3414 * enable fault log
3415 * global invalidate context cache
3416 * global invalidate iotlb
3417 * enable translation
3418 */
Jiang Liu7c919772014-01-06 14:18:18 +08003419 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003420 if (drhd->ignored) {
3421 /*
3422 * we always have to disable PMRs or DMA may fail on
3423 * this device
3424 */
3425 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003426 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003427 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003428 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003429
3430 iommu_flush_write_buffer(iommu);
3431
David Woodhousea222a7f2015-10-07 23:35:18 +01003432#ifdef CONFIG_INTEL_IOMMU_SVM
3433 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3434 ret = intel_svm_enable_prq(iommu);
3435 if (ret)
3436 goto free_iommu;
3437 }
3438#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003439 ret = dmar_set_interrupt(iommu);
3440 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003441 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003442
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003443 if (!translation_pre_enabled(iommu))
3444 iommu_enable_translation(iommu);
3445
David Woodhouseb94996c2009-09-19 15:28:12 -07003446 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003447 }
3448
3449 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003450
3451free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003452 for_each_active_iommu(iommu, drhd) {
3453 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003454 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003455 }
Jiang Liu989d51f2014-02-19 14:07:21 +08003456free_g_iommus:
Omer Pelegaa473242016-04-20 11:33:02 +03003457 for_each_possible_cpu(cpu)
3458 kfree(per_cpu_ptr(&deferred_flush, cpu)->tables);
Weidong Hand9630fe2008-12-08 11:06:32 +08003459 kfree(g_iommus);
Jiang Liu989d51f2014-02-19 14:07:21 +08003460error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003461 return ret;
3462}
3463
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003464/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003465static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003466 struct dmar_domain *domain,
3467 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003468{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003469 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003470
David Woodhouse875764d2009-06-28 21:20:51 +01003471 /* Restrict dma_mask to the width that the iommu can handle */
3472 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003473 /* Ensure we reserve the whole size-aligned region */
3474 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003475
3476 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003477 /*
3478 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003479 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003480 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003481 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003482 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3483 IOVA_PFN(DMA_BIT_MASK(32)));
3484 if (iova_pfn)
3485 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003486 }
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003487 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages, IOVA_PFN(dma_mask));
3488 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003489 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003490 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003491 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003492 }
3493
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003494 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003495}
3496
Peter Xub316d022017-05-22 18:28:51 +08003497static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003498{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003499 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003500 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003501 struct device *i_dev;
3502 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003503
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003504 domain = find_domain(dev);
3505 if (domain)
3506 goto out;
3507
3508 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3509 if (!domain)
3510 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003511
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003512 /* We have a new domain - setup possible RMRRs for the device */
3513 rcu_read_lock();
3514 for_each_rmrr_units(rmrr) {
3515 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3516 i, i_dev) {
3517 if (i_dev != dev)
3518 continue;
3519
3520 ret = domain_prepare_identity_map(dev, domain,
3521 rmrr->base_address,
3522 rmrr->end_address);
3523 if (ret)
3524 dev_err(dev, "Mapping reserved region failed\n");
3525 }
3526 }
3527 rcu_read_unlock();
3528
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003529 tmp = set_domain_for_dev(dev, domain);
3530 if (!tmp || domain != tmp) {
3531 domain_exit(domain);
3532 domain = tmp;
3533 }
3534
3535out:
3536
3537 if (!domain)
3538 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3539
3540
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003541 return domain;
3542}
3543
David Woodhouseecb509e2014-03-09 16:29:55 -07003544/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003545static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003546{
3547 int found;
3548
David Woodhouse3d891942014-03-06 15:59:26 +00003549 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003550 return 1;
3551
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003552 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003553 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003554
David Woodhouse9b226622014-03-09 14:03:28 -07003555 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003556 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003557 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003558 return 1;
3559 else {
3560 /*
3561 * 32 bit DMA is removed from si_domain and fall back
3562 * to non-identity mapping.
3563 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003564 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003565 pr_info("32bit %s uses non-identity mapping\n",
3566 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003567 return 0;
3568 }
3569 } else {
3570 /*
3571 * In case of a detached 64 bit DMA device from vm, the device
3572 * is put into si_domain for identity mapping.
3573 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003574 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003575 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003576 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003577 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003578 pr_info("64bit %s uses identity mapping\n",
3579 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003580 return 1;
3581 }
3582 }
3583 }
3584
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003585 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003586}
3587
David Woodhouse5040a912014-03-09 16:14:00 -07003588static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003589 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003590{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003591 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003592 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003593 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003594 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003595 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003596 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003597 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003598
3599 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003600
David Woodhouse5040a912014-03-09 16:14:00 -07003601 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003602 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003603
David Woodhouse5040a912014-03-09 16:14:00 -07003604 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003605 if (!domain)
3606 return 0;
3607
Weidong Han8c11e792008-12-08 15:29:22 +08003608 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003609 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003610
Omer Peleg2aac6302016-04-20 11:33:57 +03003611 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3612 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003613 goto error;
3614
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003615 /*
3616 * Check if DMAR supports zero-length reads on write only
3617 * mappings..
3618 */
3619 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003620 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003621 prot |= DMA_PTE_READ;
3622 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3623 prot |= DMA_PTE_WRITE;
3624 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003625 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003626 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003627 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003628 * is not a big problem
3629 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003630 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003631 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003632 if (ret)
3633 goto error;
3634
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003635 /* it's a non-present to present mapping. Only flush if caching mode */
3636 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003637 iommu_flush_iotlb_psi(iommu, domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003638 mm_to_dma_pfn(iova_pfn),
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003639 size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003640 else
Weidong Han8c11e792008-12-08 15:29:22 +08003641 iommu_flush_write_buffer(iommu);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003642
Omer Peleg2aac6302016-04-20 11:33:57 +03003643 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003644 start_paddr += paddr & ~PAGE_MASK;
3645 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003646
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003647error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003648 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003649 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003650 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003651 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003652 return 0;
3653}
3654
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003655static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3656 unsigned long offset, size_t size,
3657 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003658 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003659{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003660 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003661 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003662}
3663
Omer Pelegaa473242016-04-20 11:33:02 +03003664static void flush_unmaps(struct deferred_flush_data *flush_data)
mark gross5e0d2a62008-03-04 15:22:08 -08003665{
mark gross80b20dd2008-04-18 13:53:58 -07003666 int i, j;
mark gross5e0d2a62008-03-04 15:22:08 -08003667
Omer Pelegaa473242016-04-20 11:33:02 +03003668 flush_data->timer_on = 0;
mark gross5e0d2a62008-03-04 15:22:08 -08003669
3670 /* just flush them all */
3671 for (i = 0; i < g_num_of_iommus; i++) {
Weidong Hana2bb8452008-12-08 11:24:12 +08003672 struct intel_iommu *iommu = g_iommus[i];
Omer Pelegaa473242016-04-20 11:33:02 +03003673 struct deferred_flush_table *flush_table =
3674 &flush_data->tables[i];
Weidong Hana2bb8452008-12-08 11:24:12 +08003675 if (!iommu)
3676 continue;
Suresh Siddhac42d9f32008-07-10 11:16:36 -07003677
Omer Pelegaa473242016-04-20 11:33:02 +03003678 if (!flush_table->next)
Yu Zhao9dd2fe82009-05-18 13:51:36 +08003679 continue;
3680
Nadav Amit78d5f0f2010-04-08 23:00:41 +03003681 /* In caching mode, global flushes turn emulation expensive */
3682 if (!cap_caching_mode(iommu->cap))
3683 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
Yu Zhao93a23a72009-05-18 13:51:37 +08003684 DMA_TLB_GLOBAL_FLUSH);
Omer Pelegaa473242016-04-20 11:33:02 +03003685 for (j = 0; j < flush_table->next; j++) {
Yu Zhao93a23a72009-05-18 13:51:37 +08003686 unsigned long mask;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003687 struct deferred_flush_entry *entry =
Omer Pelegaa473242016-04-20 11:33:02 +03003688 &flush_table->entries[j];
Omer Peleg2aac6302016-04-20 11:33:57 +03003689 unsigned long iova_pfn = entry->iova_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003690 unsigned long nrpages = entry->nrpages;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003691 struct dmar_domain *domain = entry->domain;
3692 struct page *freelist = entry->freelist;
Yu Zhao93a23a72009-05-18 13:51:37 +08003693
Nadav Amit78d5f0f2010-04-08 23:00:41 +03003694 /* On real hardware multiple invalidations are expensive */
3695 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003696 iommu_flush_iotlb_psi(iommu, domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003697 mm_to_dma_pfn(iova_pfn),
Omer Peleg769530e2016-04-20 11:33:25 +03003698 nrpages, !freelist, 0);
Nadav Amit78d5f0f2010-04-08 23:00:41 +03003699 else {
Omer Peleg769530e2016-04-20 11:33:25 +03003700 mask = ilog2(nrpages);
Omer Peleg314f1dc2016-04-20 11:32:45 +03003701 iommu_flush_dev_iotlb(domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003702 (uint64_t)iova_pfn << PAGE_SHIFT, mask);
Nadav Amit78d5f0f2010-04-08 23:00:41 +03003703 }
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003704 free_iova_fast(&domain->iovad, iova_pfn, nrpages);
Omer Peleg314f1dc2016-04-20 11:32:45 +03003705 if (freelist)
3706 dma_free_pagelist(freelist);
mark gross80b20dd2008-04-18 13:53:58 -07003707 }
Omer Pelegaa473242016-04-20 11:33:02 +03003708 flush_table->next = 0;
mark gross5e0d2a62008-03-04 15:22:08 -08003709 }
3710
Omer Pelegaa473242016-04-20 11:33:02 +03003711 flush_data->size = 0;
mark gross5e0d2a62008-03-04 15:22:08 -08003712}
3713
Omer Pelegaa473242016-04-20 11:33:02 +03003714static void flush_unmaps_timeout(unsigned long cpuid)
mark gross5e0d2a62008-03-04 15:22:08 -08003715{
Omer Pelegaa473242016-04-20 11:33:02 +03003716 struct deferred_flush_data *flush_data = per_cpu_ptr(&deferred_flush, cpuid);
mark gross80b20dd2008-04-18 13:53:58 -07003717 unsigned long flags;
3718
Omer Pelegaa473242016-04-20 11:33:02 +03003719 spin_lock_irqsave(&flush_data->lock, flags);
3720 flush_unmaps(flush_data);
3721 spin_unlock_irqrestore(&flush_data->lock, flags);
mark gross5e0d2a62008-03-04 15:22:08 -08003722}
3723
Omer Peleg2aac6302016-04-20 11:33:57 +03003724static void add_unmap(struct dmar_domain *dom, unsigned long iova_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003725 unsigned long nrpages, struct page *freelist)
mark gross5e0d2a62008-03-04 15:22:08 -08003726{
3727 unsigned long flags;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003728 int entry_id, iommu_id;
Weidong Han8c11e792008-12-08 15:29:22 +08003729 struct intel_iommu *iommu;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003730 struct deferred_flush_entry *entry;
Omer Pelegaa473242016-04-20 11:33:02 +03003731 struct deferred_flush_data *flush_data;
mark gross5e0d2a62008-03-04 15:22:08 -08003732
Sebastian Andrzej Siewior58c4a95f2017-06-27 18:16:48 +02003733 flush_data = raw_cpu_ptr(&deferred_flush);
Omer Pelegaa473242016-04-20 11:33:02 +03003734
3735 /* Flush all CPUs' entries to avoid deferring too much. If
3736 * this becomes a bottleneck, can just flush us, and rely on
3737 * flush timer for the rest.
3738 */
3739 if (flush_data->size == HIGH_WATER_MARK) {
3740 int cpu;
3741
3742 for_each_online_cpu(cpu)
3743 flush_unmaps_timeout(cpu);
3744 }
3745
3746 spin_lock_irqsave(&flush_data->lock, flags);
mark gross80b20dd2008-04-18 13:53:58 -07003747
Weidong Han8c11e792008-12-08 15:29:22 +08003748 iommu = domain_get_iommu(dom);
3749 iommu_id = iommu->seq_id;
Suresh Siddhac42d9f32008-07-10 11:16:36 -07003750
Omer Pelegaa473242016-04-20 11:33:02 +03003751 entry_id = flush_data->tables[iommu_id].next;
3752 ++(flush_data->tables[iommu_id].next);
mark gross5e0d2a62008-03-04 15:22:08 -08003753
Omer Pelegaa473242016-04-20 11:33:02 +03003754 entry = &flush_data->tables[iommu_id].entries[entry_id];
Omer Peleg314f1dc2016-04-20 11:32:45 +03003755 entry->domain = dom;
Omer Peleg2aac6302016-04-20 11:33:57 +03003756 entry->iova_pfn = iova_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003757 entry->nrpages = nrpages;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003758 entry->freelist = freelist;
mark gross5e0d2a62008-03-04 15:22:08 -08003759
Omer Pelegaa473242016-04-20 11:33:02 +03003760 if (!flush_data->timer_on) {
3761 mod_timer(&flush_data->timer, jiffies + msecs_to_jiffies(10));
3762 flush_data->timer_on = 1;
mark gross5e0d2a62008-03-04 15:22:08 -08003763 }
Omer Pelegaa473242016-04-20 11:33:02 +03003764 flush_data->size++;
3765 spin_unlock_irqrestore(&flush_data->lock, flags);
mark gross5e0d2a62008-03-04 15:22:08 -08003766}
3767
Omer Peleg769530e2016-04-20 11:33:25 +03003768static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003769{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003770 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003771 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003772 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003773 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003774 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003775 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003776
David Woodhouse73676832009-07-04 14:08:36 +01003777 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003778 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003779
David Woodhouse1525a292014-03-06 16:19:30 +00003780 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003781 BUG_ON(!domain);
3782
Weidong Han8c11e792008-12-08 15:29:22 +08003783 iommu = domain_get_iommu(domain);
3784
Omer Peleg2aac6302016-04-20 11:33:57 +03003785 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003786
Omer Peleg769530e2016-04-20 11:33:25 +03003787 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003788 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003789 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003790
David Woodhoused794dc92009-06-28 00:27:49 +01003791 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003792 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003793
David Woodhouseea8ea462014-03-05 17:09:32 +00003794 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003795
mark gross5e0d2a62008-03-04 15:22:08 -08003796 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003797 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003798 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003799 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003800 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003801 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003802 } else {
Omer Peleg2aac6302016-04-20 11:33:57 +03003803 add_unmap(domain, iova_pfn, nrpages, freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003804 /*
3805 * queue up the release of the unmap to save the 1/6th of the
3806 * cpu used up by the iotlb flush operation...
3807 */
mark gross5e0d2a62008-03-04 15:22:08 -08003808 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003809}
3810
Jiang Liud41a4ad2014-07-11 14:19:34 +08003811static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3812 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003813 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003814{
Omer Peleg769530e2016-04-20 11:33:25 +03003815 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003816}
3817
David Woodhouse5040a912014-03-09 16:14:00 -07003818static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003819 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003820 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003821{
Akinobu Mita36746432014-06-04 16:06:51 -07003822 struct page *page = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003823 int order;
3824
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003825 size = PAGE_ALIGN(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003826 order = get_order(size);
Alex Williamsone8bb9102009-11-04 15:59:34 -07003827
David Woodhouse5040a912014-03-09 16:14:00 -07003828 if (!iommu_no_mapping(dev))
Alex Williamsone8bb9102009-11-04 15:59:34 -07003829 flags &= ~(GFP_DMA | GFP_DMA32);
David Woodhouse5040a912014-03-09 16:14:00 -07003830 else if (dev->coherent_dma_mask < dma_get_required_mask(dev)) {
3831 if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
Alex Williamsone8bb9102009-11-04 15:59:34 -07003832 flags |= GFP_DMA;
3833 else
3834 flags |= GFP_DMA32;
3835 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003836
Mel Gormand0164ad2015-11-06 16:28:21 -08003837 if (gfpflags_allow_blocking(flags)) {
Akinobu Mita36746432014-06-04 16:06:51 -07003838 unsigned int count = size >> PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003839
Lucas Stach712c6042017-02-24 14:58:44 -08003840 page = dma_alloc_from_contiguous(dev, count, order, flags);
Akinobu Mita36746432014-06-04 16:06:51 -07003841 if (page && iommu_no_mapping(dev) &&
3842 page_to_phys(page) + size > dev->coherent_dma_mask) {
3843 dma_release_from_contiguous(dev, page, count);
3844 page = NULL;
3845 }
3846 }
3847
3848 if (!page)
3849 page = alloc_pages(flags, order);
3850 if (!page)
3851 return NULL;
3852 memset(page_address(page), 0, size);
3853
3854 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003855 DMA_BIDIRECTIONAL,
David Woodhouse5040a912014-03-09 16:14:00 -07003856 dev->coherent_dma_mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003857 if (*dma_handle)
Akinobu Mita36746432014-06-04 16:06:51 -07003858 return page_address(page);
3859 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3860 __free_pages(page, order);
3861
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003862 return NULL;
3863}
3864
David Woodhouse5040a912014-03-09 16:14:00 -07003865static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003866 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003867{
3868 int order;
Akinobu Mita36746432014-06-04 16:06:51 -07003869 struct page *page = virt_to_page(vaddr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003870
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003871 size = PAGE_ALIGN(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003872 order = get_order(size);
3873
Omer Peleg769530e2016-04-20 11:33:25 +03003874 intel_unmap(dev, dma_handle, size);
Akinobu Mita36746432014-06-04 16:06:51 -07003875 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3876 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003877}
3878
David Woodhouse5040a912014-03-09 16:14:00 -07003879static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003880 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003881 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003882{
Omer Peleg769530e2016-04-20 11:33:25 +03003883 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3884 unsigned long nrpages = 0;
3885 struct scatterlist *sg;
3886 int i;
3887
3888 for_each_sg(sglist, sg, nelems, i) {
3889 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3890 }
3891
3892 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003893}
3894
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003895static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003896 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003897{
3898 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003899 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003900
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003901 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003902 BUG_ON(!sg_page(sg));
Dan Williams3e6110f2015-12-15 12:54:06 -08003903 sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003904 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003905 }
3906 return nelems;
3907}
3908
David Woodhouse5040a912014-03-09 16:14:00 -07003909static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003910 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003911{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003912 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003913 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003914 size_t size = 0;
3915 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003916 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003917 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003918 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003919 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003920 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003921
3922 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003923 if (iommu_no_mapping(dev))
3924 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003925
David Woodhouse5040a912014-03-09 16:14:00 -07003926 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003927 if (!domain)
3928 return 0;
3929
Weidong Han8c11e792008-12-08 15:29:22 +08003930 iommu = domain_get_iommu(domain);
3931
David Woodhouseb536d242009-06-28 14:49:31 +01003932 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003933 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003934
Omer Peleg2aac6302016-04-20 11:33:57 +03003935 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003936 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003937 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003938 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003939 return 0;
3940 }
3941
3942 /*
3943 * Check if DMAR supports zero-length reads on write only
3944 * mappings..
3945 */
3946 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003947 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003948 prot |= DMA_PTE_READ;
3949 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3950 prot |= DMA_PTE_WRITE;
3951
Omer Peleg2aac6302016-04-20 11:33:57 +03003952 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003953
Fenghua Yuf5329592009-08-04 15:09:37 -07003954 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003955 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003956 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003957 start_vpfn + size - 1,
3958 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003959 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003960 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003961 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003962
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003963 /* it's a non-present to present mapping. Only flush if caching mode */
3964 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003965 iommu_flush_iotlb_psi(iommu, domain, start_vpfn, size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003966 else
Weidong Han8c11e792008-12-08 15:29:22 +08003967 iommu_flush_write_buffer(iommu);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003968
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003969 return nelems;
3970}
3971
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003972static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3973{
3974 return !dma_addr;
3975}
3976
Arvind Yadav01e19322017-06-28 16:39:32 +05303977const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003978 .alloc = intel_alloc_coherent,
3979 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003980 .map_sg = intel_map_sg,
3981 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003982 .map_page = intel_map_page,
3983 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003984 .mapping_error = intel_mapping_error,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003985};
3986
3987static inline int iommu_domain_cache_init(void)
3988{
3989 int ret = 0;
3990
3991 iommu_domain_cache = kmem_cache_create("iommu_domain",
3992 sizeof(struct dmar_domain),
3993 0,
3994 SLAB_HWCACHE_ALIGN,
3995
3996 NULL);
3997 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003998 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003999 ret = -ENOMEM;
4000 }
4001
4002 return ret;
4003}
4004
4005static inline int iommu_devinfo_cache_init(void)
4006{
4007 int ret = 0;
4008
4009 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
4010 sizeof(struct device_domain_info),
4011 0,
4012 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004013 NULL);
4014 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004015 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004016 ret = -ENOMEM;
4017 }
4018
4019 return ret;
4020}
4021
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004022static int __init iommu_init_mempool(void)
4023{
4024 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004025 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004026 if (ret)
4027 return ret;
4028
4029 ret = iommu_domain_cache_init();
4030 if (ret)
4031 goto domain_error;
4032
4033 ret = iommu_devinfo_cache_init();
4034 if (!ret)
4035 return ret;
4036
4037 kmem_cache_destroy(iommu_domain_cache);
4038domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004039 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004040
4041 return -ENOMEM;
4042}
4043
4044static void __init iommu_exit_mempool(void)
4045{
4046 kmem_cache_destroy(iommu_devinfo_cache);
4047 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004048 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004049}
4050
Dan Williams556ab452010-07-23 15:47:56 -07004051static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
4052{
4053 struct dmar_drhd_unit *drhd;
4054 u32 vtbar;
4055 int rc;
4056
4057 /* We know that this device on this chipset has its own IOMMU.
4058 * If we find it under a different IOMMU, then the BIOS is lying
4059 * to us. Hope that the IOMMU for this device is actually
4060 * disabled, and it needs no translation...
4061 */
4062 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
4063 if (rc) {
4064 /* "can't" happen */
4065 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
4066 return;
4067 }
4068 vtbar &= 0xffff0000;
4069
4070 /* we know that the this iommu should be at offset 0xa000 from vtbar */
4071 drhd = dmar_find_matched_drhd_unit(pdev);
4072 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
4073 TAINT_FIRMWARE_WORKAROUND,
4074 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
4075 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
4076}
4077DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
4078
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004079static void __init init_no_remapping_devices(void)
4080{
4081 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00004082 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08004083 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004084
4085 for_each_drhd_unit(drhd) {
4086 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08004087 for_each_active_dev_scope(drhd->devices,
4088 drhd->devices_cnt, i, dev)
4089 break;
David Woodhouse832bd852014-03-07 15:08:36 +00004090 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004091 if (i == drhd->devices_cnt)
4092 drhd->ignored = 1;
4093 }
4094 }
4095
Jiang Liu7c919772014-01-06 14:18:18 +08004096 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08004097 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004098 continue;
4099
Jiang Liub683b232014-02-19 14:07:32 +08004100 for_each_active_dev_scope(drhd->devices,
4101 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004102 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004103 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004104 if (i < drhd->devices_cnt)
4105 continue;
4106
David Woodhousec0771df2011-10-14 20:59:46 +01004107 /* This IOMMU has *only* gfx devices. Either bypass it or
4108 set the gfx_mapped flag, as appropriate */
4109 if (dmar_map_gfx) {
4110 intel_iommu_gfx_mapped = 1;
4111 } else {
4112 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004113 for_each_active_dev_scope(drhd->devices,
4114 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004115 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004116 }
4117 }
4118}
4119
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004120#ifdef CONFIG_SUSPEND
4121static int init_iommu_hw(void)
4122{
4123 struct dmar_drhd_unit *drhd;
4124 struct intel_iommu *iommu = NULL;
4125
4126 for_each_active_iommu(iommu, drhd)
4127 if (iommu->qi)
4128 dmar_reenable_qi(iommu);
4129
Joseph Cihulab7792602011-05-03 00:08:37 -07004130 for_each_iommu(iommu, drhd) {
4131 if (drhd->ignored) {
4132 /*
4133 * we always have to disable PMRs or DMA may fail on
4134 * this device
4135 */
4136 if (force_on)
4137 iommu_disable_protect_mem_regions(iommu);
4138 continue;
4139 }
4140
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004141 iommu_flush_write_buffer(iommu);
4142
4143 iommu_set_root_entry(iommu);
4144
4145 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004146 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004147 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4148 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004149 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004150 }
4151
4152 return 0;
4153}
4154
4155static void iommu_flush_all(void)
4156{
4157 struct dmar_drhd_unit *drhd;
4158 struct intel_iommu *iommu;
4159
4160 for_each_active_iommu(iommu, drhd) {
4161 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004162 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004163 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004164 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004165 }
4166}
4167
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004168static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004169{
4170 struct dmar_drhd_unit *drhd;
4171 struct intel_iommu *iommu = NULL;
4172 unsigned long flag;
4173
4174 for_each_active_iommu(iommu, drhd) {
4175 iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
4176 GFP_ATOMIC);
4177 if (!iommu->iommu_state)
4178 goto nomem;
4179 }
4180
4181 iommu_flush_all();
4182
4183 for_each_active_iommu(iommu, drhd) {
4184 iommu_disable_translation(iommu);
4185
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004186 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004187
4188 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4189 readl(iommu->reg + DMAR_FECTL_REG);
4190 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4191 readl(iommu->reg + DMAR_FEDATA_REG);
4192 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4193 readl(iommu->reg + DMAR_FEADDR_REG);
4194 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4195 readl(iommu->reg + DMAR_FEUADDR_REG);
4196
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004197 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004198 }
4199 return 0;
4200
4201nomem:
4202 for_each_active_iommu(iommu, drhd)
4203 kfree(iommu->iommu_state);
4204
4205 return -ENOMEM;
4206}
4207
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004208static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004209{
4210 struct dmar_drhd_unit *drhd;
4211 struct intel_iommu *iommu = NULL;
4212 unsigned long flag;
4213
4214 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004215 if (force_on)
4216 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4217 else
4218 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004219 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004220 }
4221
4222 for_each_active_iommu(iommu, drhd) {
4223
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004224 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004225
4226 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4227 iommu->reg + DMAR_FECTL_REG);
4228 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4229 iommu->reg + DMAR_FEDATA_REG);
4230 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4231 iommu->reg + DMAR_FEADDR_REG);
4232 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4233 iommu->reg + DMAR_FEUADDR_REG);
4234
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004235 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004236 }
4237
4238 for_each_active_iommu(iommu, drhd)
4239 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004240}
4241
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004242static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004243 .resume = iommu_resume,
4244 .suspend = iommu_suspend,
4245};
4246
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004247static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004248{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004249 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004250}
4251
4252#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004253static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004254#endif /* CONFIG_PM */
4255
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004256
Jiang Liuc2a0b532014-11-09 22:47:56 +08004257int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004258{
4259 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004260 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004261 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004262 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004263
4264 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4265 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004266 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004267
4268 rmrru->hdr = header;
4269 rmrr = (struct acpi_dmar_reserved_memory *)header;
4270 rmrru->base_address = rmrr->base_address;
4271 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004272
4273 length = rmrr->end_address - rmrr->base_address + 1;
4274 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4275 IOMMU_RESV_DIRECT);
4276 if (!rmrru->resv)
4277 goto free_rmrru;
4278
Jiang Liu2e455282014-02-19 14:07:36 +08004279 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4280 ((void *)rmrr) + rmrr->header.length,
4281 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004282 if (rmrru->devices_cnt && rmrru->devices == NULL)
4283 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004284
Jiang Liu2e455282014-02-19 14:07:36 +08004285 list_add(&rmrru->list, &dmar_rmrr_units);
4286
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004287 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004288free_all:
4289 kfree(rmrru->resv);
4290free_rmrru:
4291 kfree(rmrru);
4292out:
4293 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004294}
4295
Jiang Liu6b197242014-11-09 22:47:58 +08004296static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4297{
4298 struct dmar_atsr_unit *atsru;
4299 struct acpi_dmar_atsr *tmp;
4300
4301 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4302 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4303 if (atsr->segment != tmp->segment)
4304 continue;
4305 if (atsr->header.length != tmp->header.length)
4306 continue;
4307 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4308 return atsru;
4309 }
4310
4311 return NULL;
4312}
4313
4314int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004315{
4316 struct acpi_dmar_atsr *atsr;
4317 struct dmar_atsr_unit *atsru;
4318
Jiang Liu6b197242014-11-09 22:47:58 +08004319 if (system_state != SYSTEM_BOOTING && !intel_iommu_enabled)
4320 return 0;
4321
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004322 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004323 atsru = dmar_find_atsr(atsr);
4324 if (atsru)
4325 return 0;
4326
4327 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004328 if (!atsru)
4329 return -ENOMEM;
4330
Jiang Liu6b197242014-11-09 22:47:58 +08004331 /*
4332 * If memory is allocated from slab by ACPI _DSM method, we need to
4333 * copy the memory content because the memory buffer will be freed
4334 * on return.
4335 */
4336 atsru->hdr = (void *)(atsru + 1);
4337 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004338 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004339 if (!atsru->include_all) {
4340 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4341 (void *)atsr + atsr->header.length,
4342 &atsru->devices_cnt);
4343 if (atsru->devices_cnt && atsru->devices == NULL) {
4344 kfree(atsru);
4345 return -ENOMEM;
4346 }
4347 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004348
Jiang Liu0e242612014-02-19 14:07:34 +08004349 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004350
4351 return 0;
4352}
4353
Jiang Liu9bdc5312014-01-06 14:18:27 +08004354static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4355{
4356 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4357 kfree(atsru);
4358}
4359
Jiang Liu6b197242014-11-09 22:47:58 +08004360int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4361{
4362 struct acpi_dmar_atsr *atsr;
4363 struct dmar_atsr_unit *atsru;
4364
4365 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4366 atsru = dmar_find_atsr(atsr);
4367 if (atsru) {
4368 list_del_rcu(&atsru->list);
4369 synchronize_rcu();
4370 intel_iommu_free_atsr(atsru);
4371 }
4372
4373 return 0;
4374}
4375
4376int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4377{
4378 int i;
4379 struct device *dev;
4380 struct acpi_dmar_atsr *atsr;
4381 struct dmar_atsr_unit *atsru;
4382
4383 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4384 atsru = dmar_find_atsr(atsr);
4385 if (!atsru)
4386 return 0;
4387
Linus Torvalds194dc872016-07-27 20:03:31 -07004388 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004389 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4390 i, dev)
4391 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004392 }
Jiang Liu6b197242014-11-09 22:47:58 +08004393
4394 return 0;
4395}
4396
Jiang Liuffebeb42014-11-09 22:48:02 +08004397static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4398{
4399 int sp, ret = 0;
4400 struct intel_iommu *iommu = dmaru->iommu;
4401
4402 if (g_iommus[iommu->seq_id])
4403 return 0;
4404
4405 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004406 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004407 iommu->name);
4408 return -ENXIO;
4409 }
4410 if (!ecap_sc_support(iommu->ecap) &&
4411 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004412 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004413 iommu->name);
4414 return -ENXIO;
4415 }
4416 sp = domain_update_iommu_superpage(iommu) - 1;
4417 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004418 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004419 iommu->name);
4420 return -ENXIO;
4421 }
4422
4423 /*
4424 * Disable translation if already enabled prior to OS handover.
4425 */
4426 if (iommu->gcmd & DMA_GCMD_TE)
4427 iommu_disable_translation(iommu);
4428
4429 g_iommus[iommu->seq_id] = iommu;
4430 ret = iommu_init_domains(iommu);
4431 if (ret == 0)
4432 ret = iommu_alloc_root_entry(iommu);
4433 if (ret)
4434 goto out;
4435
David Woodhouse8a94ade2015-03-24 14:54:56 +00004436#ifdef CONFIG_INTEL_IOMMU_SVM
4437 if (pasid_enabled(iommu))
4438 intel_svm_alloc_pasid_tables(iommu);
4439#endif
4440
Jiang Liuffebeb42014-11-09 22:48:02 +08004441 if (dmaru->ignored) {
4442 /*
4443 * we always have to disable PMRs or DMA may fail on this device
4444 */
4445 if (force_on)
4446 iommu_disable_protect_mem_regions(iommu);
4447 return 0;
4448 }
4449
4450 intel_iommu_init_qi(iommu);
4451 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004452
4453#ifdef CONFIG_INTEL_IOMMU_SVM
4454 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4455 ret = intel_svm_enable_prq(iommu);
4456 if (ret)
4457 goto disable_iommu;
4458 }
4459#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004460 ret = dmar_set_interrupt(iommu);
4461 if (ret)
4462 goto disable_iommu;
4463
4464 iommu_set_root_entry(iommu);
4465 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4466 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4467 iommu_enable_translation(iommu);
4468
Jiang Liuffebeb42014-11-09 22:48:02 +08004469 iommu_disable_protect_mem_regions(iommu);
4470 return 0;
4471
4472disable_iommu:
4473 disable_dmar_iommu(iommu);
4474out:
4475 free_dmar_iommu(iommu);
4476 return ret;
4477}
4478
Jiang Liu6b197242014-11-09 22:47:58 +08004479int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4480{
Jiang Liuffebeb42014-11-09 22:48:02 +08004481 int ret = 0;
4482 struct intel_iommu *iommu = dmaru->iommu;
4483
4484 if (!intel_iommu_enabled)
4485 return 0;
4486 if (iommu == NULL)
4487 return -EINVAL;
4488
4489 if (insert) {
4490 ret = intel_iommu_add(dmaru);
4491 } else {
4492 disable_dmar_iommu(iommu);
4493 free_dmar_iommu(iommu);
4494 }
4495
4496 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004497}
4498
Jiang Liu9bdc5312014-01-06 14:18:27 +08004499static void intel_iommu_free_dmars(void)
4500{
4501 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4502 struct dmar_atsr_unit *atsru, *atsr_n;
4503
4504 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4505 list_del(&rmrru->list);
4506 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004507 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004508 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004509 }
4510
Jiang Liu9bdc5312014-01-06 14:18:27 +08004511 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4512 list_del(&atsru->list);
4513 intel_iommu_free_atsr(atsru);
4514 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004515}
4516
4517int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4518{
Jiang Liub683b232014-02-19 14:07:32 +08004519 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004520 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004521 struct pci_dev *bridge = NULL;
4522 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004523 struct acpi_dmar_atsr *atsr;
4524 struct dmar_atsr_unit *atsru;
4525
4526 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004527 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004528 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004529 /* If it's an integrated device, allow ATS */
4530 if (!bridge)
4531 return 1;
4532 /* Connected via non-PCIe: no ATS */
4533 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004534 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004535 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004536 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004537 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004538 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004539 }
4540
Jiang Liu0e242612014-02-19 14:07:34 +08004541 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004542 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4543 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4544 if (atsr->segment != pci_domain_nr(dev->bus))
4545 continue;
4546
Jiang Liub683b232014-02-19 14:07:32 +08004547 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004548 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004549 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004550
4551 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004552 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004553 }
Jiang Liub683b232014-02-19 14:07:32 +08004554 ret = 0;
4555out:
Jiang Liu0e242612014-02-19 14:07:34 +08004556 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004557
Jiang Liub683b232014-02-19 14:07:32 +08004558 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004559}
4560
Jiang Liu59ce0512014-02-19 14:07:35 +08004561int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4562{
4563 int ret = 0;
4564 struct dmar_rmrr_unit *rmrru;
4565 struct dmar_atsr_unit *atsru;
4566 struct acpi_dmar_atsr *atsr;
4567 struct acpi_dmar_reserved_memory *rmrr;
4568
4569 if (!intel_iommu_enabled && system_state != SYSTEM_BOOTING)
4570 return 0;
4571
4572 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4573 rmrr = container_of(rmrru->hdr,
4574 struct acpi_dmar_reserved_memory, header);
4575 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4576 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4577 ((void *)rmrr) + rmrr->header.length,
4578 rmrr->segment, rmrru->devices,
4579 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004580 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004581 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004582 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004583 dmar_remove_dev_scope(info, rmrr->segment,
4584 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004585 }
4586 }
4587
4588 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4589 if (atsru->include_all)
4590 continue;
4591
4592 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4593 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4594 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4595 (void *)atsr + atsr->header.length,
4596 atsr->segment, atsru->devices,
4597 atsru->devices_cnt);
4598 if (ret > 0)
4599 break;
4600 else if(ret < 0)
4601 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004602 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004603 if (dmar_remove_dev_scope(info, atsr->segment,
4604 atsru->devices, atsru->devices_cnt))
4605 break;
4606 }
4607 }
4608
4609 return 0;
4610}
4611
Fenghua Yu99dcade2009-11-11 07:23:06 -08004612/*
4613 * Here we only respond to action of unbound device from driver.
4614 *
4615 * Added device is not attached to its DMAR domain here yet. That will happen
4616 * when mapping the device to iova.
4617 */
4618static int device_notifier(struct notifier_block *nb,
4619 unsigned long action, void *data)
4620{
4621 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004622 struct dmar_domain *domain;
4623
David Woodhouse3d891942014-03-06 15:59:26 +00004624 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004625 return 0;
4626
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004627 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004628 return 0;
4629
David Woodhouse1525a292014-03-06 16:19:30 +00004630 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004631 if (!domain)
4632 return 0;
4633
Joerg Roedele6de0f82015-07-22 16:30:36 +02004634 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004635 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004636 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004637
Fenghua Yu99dcade2009-11-11 07:23:06 -08004638 return 0;
4639}
4640
4641static struct notifier_block device_nb = {
4642 .notifier_call = device_notifier,
4643};
4644
Jiang Liu75f05562014-02-19 14:07:37 +08004645static int intel_iommu_memory_notifier(struct notifier_block *nb,
4646 unsigned long val, void *v)
4647{
4648 struct memory_notify *mhp = v;
4649 unsigned long long start, end;
4650 unsigned long start_vpfn, last_vpfn;
4651
4652 switch (val) {
4653 case MEM_GOING_ONLINE:
4654 start = mhp->start_pfn << PAGE_SHIFT;
4655 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4656 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004657 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004658 start, end);
4659 return NOTIFY_BAD;
4660 }
4661 break;
4662
4663 case MEM_OFFLINE:
4664 case MEM_CANCEL_ONLINE:
4665 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4666 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4667 while (start_vpfn <= last_vpfn) {
4668 struct iova *iova;
4669 struct dmar_drhd_unit *drhd;
4670 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004671 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004672
4673 iova = find_iova(&si_domain->iovad, start_vpfn);
4674 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004675 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004676 start_vpfn);
4677 break;
4678 }
4679
4680 iova = split_and_remove_iova(&si_domain->iovad, iova,
4681 start_vpfn, last_vpfn);
4682 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004683 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004684 start_vpfn, last_vpfn);
4685 return NOTIFY_BAD;
4686 }
4687
David Woodhouseea8ea462014-03-05 17:09:32 +00004688 freelist = domain_unmap(si_domain, iova->pfn_lo,
4689 iova->pfn_hi);
4690
Jiang Liu75f05562014-02-19 14:07:37 +08004691 rcu_read_lock();
4692 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004693 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004694 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004695 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004696 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004697 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004698
4699 start_vpfn = iova->pfn_hi + 1;
4700 free_iova_mem(iova);
4701 }
4702 break;
4703 }
4704
4705 return NOTIFY_OK;
4706}
4707
4708static struct notifier_block intel_iommu_memory_nb = {
4709 .notifier_call = intel_iommu_memory_notifier,
4710 .priority = 0
4711};
4712
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004713static void free_all_cpu_cached_iovas(unsigned int cpu)
4714{
4715 int i;
4716
4717 for (i = 0; i < g_num_of_iommus; i++) {
4718 struct intel_iommu *iommu = g_iommus[i];
4719 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004720 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004721
4722 if (!iommu)
4723 continue;
4724
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004725 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004726 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004727
4728 if (!domain)
4729 continue;
4730 free_cpu_cached_iovas(cpu, &domain->iovad);
4731 }
4732 }
4733}
4734
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004735static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004736{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004737 free_all_cpu_cached_iovas(cpu);
4738 flush_unmaps_timeout(cpu);
4739 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004740}
4741
Joerg Roedel161b28a2017-03-28 17:04:52 +02004742static void intel_disable_iommus(void)
4743{
4744 struct intel_iommu *iommu = NULL;
4745 struct dmar_drhd_unit *drhd;
4746
4747 for_each_iommu(iommu, drhd)
4748 iommu_disable_translation(iommu);
4749}
4750
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004751static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4752{
4753 return container_of(dev, struct intel_iommu, iommu.dev);
4754}
4755
Alex Williamsona5459cf2014-06-12 16:12:31 -06004756static ssize_t intel_iommu_show_version(struct device *dev,
4757 struct device_attribute *attr,
4758 char *buf)
4759{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004760 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004761 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4762 return sprintf(buf, "%d:%d\n",
4763 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4764}
4765static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4766
4767static ssize_t intel_iommu_show_address(struct device *dev,
4768 struct device_attribute *attr,
4769 char *buf)
4770{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004771 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004772 return sprintf(buf, "%llx\n", iommu->reg_phys);
4773}
4774static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4775
4776static ssize_t intel_iommu_show_cap(struct device *dev,
4777 struct device_attribute *attr,
4778 char *buf)
4779{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004780 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004781 return sprintf(buf, "%llx\n", iommu->cap);
4782}
4783static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4784
4785static ssize_t intel_iommu_show_ecap(struct device *dev,
4786 struct device_attribute *attr,
4787 char *buf)
4788{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004789 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004790 return sprintf(buf, "%llx\n", iommu->ecap);
4791}
4792static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4793
Alex Williamson2238c082015-07-14 15:24:53 -06004794static ssize_t intel_iommu_show_ndoms(struct device *dev,
4795 struct device_attribute *attr,
4796 char *buf)
4797{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004798 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004799 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4800}
4801static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4802
4803static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4804 struct device_attribute *attr,
4805 char *buf)
4806{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004807 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004808 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4809 cap_ndoms(iommu->cap)));
4810}
4811static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4812
Alex Williamsona5459cf2014-06-12 16:12:31 -06004813static struct attribute *intel_iommu_attrs[] = {
4814 &dev_attr_version.attr,
4815 &dev_attr_address.attr,
4816 &dev_attr_cap.attr,
4817 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004818 &dev_attr_domains_supported.attr,
4819 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004820 NULL,
4821};
4822
4823static struct attribute_group intel_iommu_group = {
4824 .name = "intel-iommu",
4825 .attrs = intel_iommu_attrs,
4826};
4827
4828const struct attribute_group *intel_iommu_groups[] = {
4829 &intel_iommu_group,
4830 NULL,
4831};
4832
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004833int __init intel_iommu_init(void)
4834{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004835 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004836 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004837 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004838
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004839 /* VT-d is required for a TXT/tboot launch, so enforce that */
4840 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004841
Jiang Liu3a5670e2014-02-19 14:07:33 +08004842 if (iommu_init_mempool()) {
4843 if (force_on)
4844 panic("tboot: Failed to initialize iommu memory\n");
4845 return -ENOMEM;
4846 }
4847
4848 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004849 if (dmar_table_init()) {
4850 if (force_on)
4851 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004852 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004853 }
4854
Suresh Siddhac2c72862011-08-23 17:05:19 -07004855 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004856 if (force_on)
4857 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004858 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004859 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004860
Joerg Roedel161b28a2017-03-28 17:04:52 +02004861 if (no_iommu || dmar_disabled) {
4862 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004863 * We exit the function here to ensure IOMMU's remapping and
4864 * mempool aren't setup, which means that the IOMMU's PMRs
4865 * won't be disabled via the call to init_dmars(). So disable
4866 * it explicitly here. The PMRs were setup by tboot prior to
4867 * calling SENTER, but the kernel is expected to reset/tear
4868 * down the PMRs.
4869 */
4870 if (intel_iommu_tboot_noforce) {
4871 for_each_iommu(iommu, drhd)
4872 iommu_disable_protect_mem_regions(iommu);
4873 }
4874
4875 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004876 * Make sure the IOMMUs are switched off, even when we
4877 * boot into a kexec kernel and the previous kernel left
4878 * them enabled
4879 */
4880 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004881 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004882 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004883
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004884 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004885 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004886
4887 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004888 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004889
Joseph Cihula51a63e62011-03-21 11:04:24 -07004890 if (dmar_init_reserved_ranges()) {
4891 if (force_on)
4892 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004893 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004894 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004895
4896 init_no_remapping_devices();
4897
Joseph Cihulab7792602011-05-03 00:08:37 -07004898 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004899 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004900 if (force_on)
4901 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004902 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004903 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004904 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004905 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004906 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004907
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004908#ifdef CONFIG_SWIOTLB
4909 swiotlb = 0;
4910#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004911 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004912
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004913 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004914
Joerg Roedel39ab9552017-02-01 16:56:46 +01004915 for_each_active_iommu(iommu, drhd) {
4916 iommu_device_sysfs_add(&iommu->iommu, NULL,
4917 intel_iommu_groups,
4918 "%s", iommu->name);
4919 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4920 iommu_device_register(&iommu->iommu);
4921 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004922
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004923 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004924 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004925 if (si_domain && !hw_pass_through)
4926 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004927 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4928 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004929 intel_iommu_enabled = 1;
4930
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004931 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004932
4933out_free_reserved_range:
4934 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004935out_free_dmar:
4936 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004937 up_write(&dmar_global_lock);
4938 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004939 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004940}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004941
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004942static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004943{
4944 struct intel_iommu *iommu = opaque;
4945
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004946 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004947 return 0;
4948}
4949
4950/*
4951 * NB - intel-iommu lacks any sort of reference counting for the users of
4952 * dependent devices. If multiple endpoints have intersecting dependent
4953 * devices, unbinding the driver from any one of them will possibly leave
4954 * the others unable to operate.
4955 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004956static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004957{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004958 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004959 return;
4960
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004961 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004962}
4963
Joerg Roedel127c7612015-07-23 17:44:46 +02004964static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004965{
Weidong Hanc7151a82008-12-08 22:51:37 +08004966 struct intel_iommu *iommu;
4967 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004968
Joerg Roedel55d94042015-07-22 16:50:40 +02004969 assert_spin_locked(&device_domain_lock);
4970
Joerg Roedelb608ac32015-07-21 18:19:08 +02004971 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004972 return;
4973
Joerg Roedel127c7612015-07-23 17:44:46 +02004974 iommu = info->iommu;
4975
4976 if (info->dev) {
4977 iommu_disable_dev_iotlb(info);
4978 domain_context_clear(iommu, info->dev);
4979 }
4980
Joerg Roedelb608ac32015-07-21 18:19:08 +02004981 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004982
Joerg Roedeld160aca2015-07-22 11:52:53 +02004983 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004984 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004985 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004986
4987 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004988}
4989
Joerg Roedel55d94042015-07-22 16:50:40 +02004990static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4991 struct device *dev)
4992{
Joerg Roedel127c7612015-07-23 17:44:46 +02004993 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004994 unsigned long flags;
4995
Weidong Hanc7151a82008-12-08 22:51:37 +08004996 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004997 info = dev->archdata.iommu;
4998 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004999 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005000}
5001
5002static int md_domain_init(struct dmar_domain *domain, int guest_width)
5003{
5004 int adjust_width;
5005
Robin Murphy0fb5fe82015-01-12 17:51:16 +00005006 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
5007 DMA_32BIT_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005008 domain_reserve_special_ranges(domain);
5009
5010 /* calculate AGAW */
5011 domain->gaw = guest_width;
5012 adjust_width = guestwidth_to_adjustwidth(guest_width);
5013 domain->agaw = width_to_agaw(adjust_width);
5014
Weidong Han5e98c4b2008-12-08 23:03:27 +08005015 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08005016 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01005017 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005018 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08005019
5020 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07005021 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005022 if (!domain->pgd)
5023 return -ENOMEM;
5024 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
5025 return 0;
5026}
5027
Joerg Roedel00a77de2015-03-26 13:43:08 +01005028static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03005029{
Joerg Roedel5d450802008-12-03 14:52:32 +01005030 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01005031 struct iommu_domain *domain;
5032
5033 if (type != IOMMU_DOMAIN_UNMANAGED)
5034 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005035
Jiang Liuab8dfe22014-07-11 14:19:27 +08005036 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01005037 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005038 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01005039 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005040 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07005041 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005042 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08005043 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01005044 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005045 }
Allen Kay8140a952011-10-14 12:32:17 -07005046 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005047
Joerg Roedel00a77de2015-03-26 13:43:08 +01005048 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01005049 domain->geometry.aperture_start = 0;
5050 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
5051 domain->geometry.force_aperture = true;
5052
Joerg Roedel00a77de2015-03-26 13:43:08 +01005053 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03005054}
Kay, Allen M38717942008-09-09 18:37:29 +03005055
Joerg Roedel00a77de2015-03-26 13:43:08 +01005056static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03005057{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005058 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03005059}
Kay, Allen M38717942008-09-09 18:37:29 +03005060
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005061static int intel_iommu_attach_device(struct iommu_domain *domain,
5062 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005063{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005064 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005065 struct intel_iommu *iommu;
5066 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07005067 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03005068
Alex Williamsonc875d2c2014-07-03 09:57:02 -06005069 if (device_is_rmrr_locked(dev)) {
5070 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
5071 return -EPERM;
5072 }
5073
David Woodhouse7207d8f2014-03-09 16:31:06 -07005074 /* normally dev is not mapped */
5075 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005076 struct dmar_domain *old_domain;
5077
David Woodhouse1525a292014-03-06 16:19:30 +00005078 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005079 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02005080 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02005081 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02005082 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01005083
5084 if (!domain_type_is_vm_or_si(old_domain) &&
5085 list_empty(&old_domain->devices))
5086 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005087 }
5088 }
5089
David Woodhouse156baca2014-03-09 14:00:57 -07005090 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005091 if (!iommu)
5092 return -ENODEV;
5093
5094 /* check if this iommu agaw is sufficient for max mapped address */
5095 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01005096 if (addr_width > cap_mgaw(iommu->cap))
5097 addr_width = cap_mgaw(iommu->cap);
5098
5099 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005100 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005101 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01005102 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005103 return -EFAULT;
5104 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005105 dmar_domain->gaw = addr_width;
5106
5107 /*
5108 * Knock out extra levels of page tables if necessary
5109 */
5110 while (iommu->agaw < dmar_domain->agaw) {
5111 struct dma_pte *pte;
5112
5113 pte = dmar_domain->pgd;
5114 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005115 dmar_domain->pgd = (struct dma_pte *)
5116 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005117 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005118 }
5119 dmar_domain->agaw--;
5120 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005121
Joerg Roedel28ccce02015-07-21 14:45:31 +02005122 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005123}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005124
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005125static void intel_iommu_detach_device(struct iommu_domain *domain,
5126 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005127{
Joerg Roedele6de0f82015-07-22 16:30:36 +02005128 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005129}
Kay, Allen M38717942008-09-09 18:37:29 +03005130
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005131static int intel_iommu_map(struct iommu_domain *domain,
5132 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005133 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005134{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005135 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005136 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005137 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005138 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005139
Joerg Roedeldde57a22008-12-03 15:04:09 +01005140 if (iommu_prot & IOMMU_READ)
5141 prot |= DMA_PTE_READ;
5142 if (iommu_prot & IOMMU_WRITE)
5143 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005144 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5145 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005146
David Woodhouse163cc522009-06-28 00:51:17 +01005147 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005148 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005149 u64 end;
5150
5151 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005152 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005153 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005154 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005155 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005156 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005157 return -EFAULT;
5158 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005159 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005160 }
David Woodhousead051222009-06-28 14:22:28 +01005161 /* Round up size to next multiple of PAGE_SIZE, if it and
5162 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005163 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005164 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5165 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005166 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005167}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005168
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005169static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005170 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005171{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005172 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005173 struct page *freelist = NULL;
5174 struct intel_iommu *iommu;
5175 unsigned long start_pfn, last_pfn;
5176 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005177 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005178
David Woodhouse5cf0a762014-03-19 16:07:49 +00005179 /* Cope with horrid API which requires us to unmap more than the
5180 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005181 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005182
5183 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5184 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5185
David Woodhouseea8ea462014-03-05 17:09:32 +00005186 start_pfn = iova >> VTD_PAGE_SHIFT;
5187 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5188
5189 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5190
5191 npages = last_pfn - start_pfn + 1;
5192
Joerg Roedel29a27712015-07-21 17:17:12 +02005193 for_each_domain_iommu(iommu_id, dmar_domain) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02005194 iommu = g_iommus[iommu_id];
David Woodhouseea8ea462014-03-05 17:09:32 +00005195
Joerg Roedel42e8c182015-07-21 15:50:02 +02005196 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5197 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005198 }
5199
5200 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005201
David Woodhouse163cc522009-06-28 00:51:17 +01005202 if (dmar_domain->max_addr == iova + size)
5203 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005204
David Woodhouse5cf0a762014-03-19 16:07:49 +00005205 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005206}
Kay, Allen M38717942008-09-09 18:37:29 +03005207
Joerg Roedeld14d6572008-12-03 15:06:57 +01005208static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305209 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005210{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005211 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005212 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005213 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005214 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005215
David Woodhouse5cf0a762014-03-19 16:07:49 +00005216 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005217 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005218 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005219
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005220 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005221}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005222
Joerg Roedel5d587b82014-09-05 10:50:45 +02005223static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005224{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005225 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005226 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005227 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005228 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005229
Joerg Roedel5d587b82014-09-05 10:50:45 +02005230 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005231}
5232
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005233static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005234{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005235 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005236 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005237 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005238
Alex Williamsona5459cf2014-06-12 16:12:31 -06005239 iommu = device_to_iommu(dev, &bus, &devfn);
5240 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005241 return -ENODEV;
5242
Joerg Roedele3d10af2017-02-01 17:23:22 +01005243 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005244
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005245 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005246
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005247 if (IS_ERR(group))
5248 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005249
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005250 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005251 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005252}
5253
5254static void intel_iommu_remove_device(struct device *dev)
5255{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005256 struct intel_iommu *iommu;
5257 u8 bus, devfn;
5258
5259 iommu = device_to_iommu(dev, &bus, &devfn);
5260 if (!iommu)
5261 return;
5262
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005263 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005264
Joerg Roedele3d10af2017-02-01 17:23:22 +01005265 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005266}
5267
Eric Auger0659b8d2017-01-19 20:57:53 +00005268static void intel_iommu_get_resv_regions(struct device *device,
5269 struct list_head *head)
5270{
5271 struct iommu_resv_region *reg;
5272 struct dmar_rmrr_unit *rmrr;
5273 struct device *i_dev;
5274 int i;
5275
5276 rcu_read_lock();
5277 for_each_rmrr_units(rmrr) {
5278 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5279 i, i_dev) {
5280 if (i_dev != device)
5281 continue;
5282
5283 list_add_tail(&rmrr->resv->list, head);
5284 }
5285 }
5286 rcu_read_unlock();
5287
5288 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5289 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005290 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005291 if (!reg)
5292 return;
5293 list_add_tail(&reg->list, head);
5294}
5295
5296static void intel_iommu_put_resv_regions(struct device *dev,
5297 struct list_head *head)
5298{
5299 struct iommu_resv_region *entry, *next;
5300
5301 list_for_each_entry_safe(entry, next, head, list) {
5302 if (entry->type == IOMMU_RESV_RESERVED)
5303 kfree(entry);
5304 }
Kay, Allen M38717942008-09-09 18:37:29 +03005305}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005306
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005307#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005308#define MAX_NR_PASID_BITS (20)
5309static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5310{
5311 /*
5312 * Convert ecap_pss to extend context entry pts encoding, also
5313 * respect the soft pasid_max value set by the iommu.
5314 * - number of PASID bits = ecap_pss + 1
5315 * - number of PASID table entries = 2^(pts + 5)
5316 * Therefore, pts = ecap_pss - 4
5317 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5318 */
5319 if (ecap_pss(iommu->ecap) < 5)
5320 return 0;
5321
5322 /* pasid_max is encoded as actual number of entries not the bits */
5323 return find_first_bit((unsigned long *)&iommu->pasid_max,
5324 MAX_NR_PASID_BITS) - 5;
5325}
5326
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005327int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5328{
5329 struct device_domain_info *info;
5330 struct context_entry *context;
5331 struct dmar_domain *domain;
5332 unsigned long flags;
5333 u64 ctx_lo;
5334 int ret;
5335
5336 domain = get_valid_domain_for_dev(sdev->dev);
5337 if (!domain)
5338 return -EINVAL;
5339
5340 spin_lock_irqsave(&device_domain_lock, flags);
5341 spin_lock(&iommu->lock);
5342
5343 ret = -EINVAL;
5344 info = sdev->dev->archdata.iommu;
5345 if (!info || !info->pasid_supported)
5346 goto out;
5347
5348 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5349 if (WARN_ON(!context))
5350 goto out;
5351
5352 ctx_lo = context[0].lo;
5353
5354 sdev->did = domain->iommu_did[iommu->seq_id];
5355 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5356
5357 if (!(ctx_lo & CONTEXT_PASIDE)) {
Ashok Raj11b93eb2017-08-08 13:29:28 -07005358 if (iommu->pasid_state_table)
5359 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005360 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5361 intel_iommu_get_pts(iommu);
5362
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005363 wmb();
5364 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5365 * extended to permit requests-with-PASID if the PASIDE bit
5366 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5367 * however, the PASIDE bit is ignored and requests-with-PASID
5368 * are unconditionally blocked. Which makes less sense.
5369 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5370 * "guest mode" translation types depending on whether ATS
5371 * is available or not. Annoyingly, we can't use the new
5372 * modes *unless* PASIDE is set. */
5373 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5374 ctx_lo &= ~CONTEXT_TT_MASK;
5375 if (info->ats_supported)
5376 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5377 else
5378 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5379 }
5380 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005381 if (iommu->pasid_state_table)
5382 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005383 if (info->pri_supported)
5384 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005385 context[0].lo = ctx_lo;
5386 wmb();
5387 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5388 DMA_CCMD_MASK_NOBIT,
5389 DMA_CCMD_DEVICE_INVL);
5390 }
5391
5392 /* Enable PASID support in the device, if it wasn't already */
5393 if (!info->pasid_enabled)
5394 iommu_enable_dev_iotlb(info);
5395
5396 if (info->ats_enabled) {
5397 sdev->dev_iotlb = 1;
5398 sdev->qdep = info->ats_qdep;
5399 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5400 sdev->qdep = 0;
5401 }
5402 ret = 0;
5403
5404 out:
5405 spin_unlock(&iommu->lock);
5406 spin_unlock_irqrestore(&device_domain_lock, flags);
5407
5408 return ret;
5409}
5410
5411struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5412{
5413 struct intel_iommu *iommu;
5414 u8 bus, devfn;
5415
5416 if (iommu_dummy(dev)) {
5417 dev_warn(dev,
5418 "No IOMMU translation for device; cannot enable SVM\n");
5419 return NULL;
5420 }
5421
5422 iommu = device_to_iommu(dev, &bus, &devfn);
5423 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005424 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005425 return NULL;
5426 }
5427
5428 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005429 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005430 return NULL;
5431 }
5432
5433 return iommu;
5434}
5435#endif /* CONFIG_INTEL_IOMMU_SVM */
5436
Joerg Roedelb0119e82017-02-01 13:23:08 +01005437const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005438 .capable = intel_iommu_capable,
5439 .domain_alloc = intel_iommu_domain_alloc,
5440 .domain_free = intel_iommu_domain_free,
5441 .attach_dev = intel_iommu_attach_device,
5442 .detach_dev = intel_iommu_detach_device,
5443 .map = intel_iommu_map,
5444 .unmap = intel_iommu_unmap,
5445 .map_sg = default_iommu_map_sg,
5446 .iova_to_phys = intel_iommu_iova_to_phys,
5447 .add_device = intel_iommu_add_device,
5448 .remove_device = intel_iommu_remove_device,
5449 .get_resv_regions = intel_iommu_get_resv_regions,
5450 .put_resv_regions = intel_iommu_put_resv_regions,
5451 .device_group = pci_device_group,
5452 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005453};
David Woodhouse9af88142009-02-13 23:18:03 +00005454
Daniel Vetter94526182013-01-20 23:50:13 +01005455static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5456{
5457 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005458 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005459 dmar_map_gfx = 0;
5460}
5461
5462DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5463DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5464DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5465DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5466DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5467DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5468DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5469
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005470static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005471{
5472 /*
5473 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005474 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005475 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005476 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005477 rwbf_quirk = 1;
5478}
5479
5480DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005481DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5482DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5483DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5484DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5485DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5486DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005487
Adam Jacksoneecfd572010-08-25 21:17:34 +01005488#define GGC 0x52
5489#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5490#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5491#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5492#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5493#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5494#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5495#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5496#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5497
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005498static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005499{
5500 unsigned short ggc;
5501
Adam Jacksoneecfd572010-08-25 21:17:34 +01005502 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005503 return;
5504
Adam Jacksoneecfd572010-08-25 21:17:34 +01005505 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005506 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005507 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005508 } else if (dmar_map_gfx) {
5509 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005510 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005511 intel_iommu_strict = 1;
5512 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005513}
5514DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5515DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5516DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5517DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5518
David Woodhousee0fc7e02009-09-30 09:12:17 -07005519/* On Tylersburg chipsets, some BIOSes have been known to enable the
5520 ISOCH DMAR unit for the Azalia sound device, but not give it any
5521 TLB entries, which causes it to deadlock. Check for that. We do
5522 this in a function called from init_dmars(), instead of in a PCI
5523 quirk, because we don't want to print the obnoxious "BIOS broken"
5524 message if VT-d is actually disabled.
5525*/
5526static void __init check_tylersburg_isoch(void)
5527{
5528 struct pci_dev *pdev;
5529 uint32_t vtisochctrl;
5530
5531 /* If there's no Azalia in the system anyway, forget it. */
5532 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5533 if (!pdev)
5534 return;
5535 pci_dev_put(pdev);
5536
5537 /* System Management Registers. Might be hidden, in which case
5538 we can't do the sanity check. But that's OK, because the
5539 known-broken BIOSes _don't_ actually hide it, so far. */
5540 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5541 if (!pdev)
5542 return;
5543
5544 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5545 pci_dev_put(pdev);
5546 return;
5547 }
5548
5549 pci_dev_put(pdev);
5550
5551 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5552 if (vtisochctrl & 1)
5553 return;
5554
5555 /* Drop all bits other than the number of TLB entries */
5556 vtisochctrl &= 0x1c;
5557
5558 /* If we have the recommended number of TLB entries (16), fine. */
5559 if (vtisochctrl == 0x10)
5560 return;
5561
5562 /* Zero TLB entries? You get to ride the short bus to school. */
5563 if (!vtisochctrl) {
5564 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5565 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5566 dmi_get_system_info(DMI_BIOS_VENDOR),
5567 dmi_get_system_info(DMI_BIOS_VERSION),
5568 dmi_get_system_info(DMI_PRODUCT_VERSION));
5569 iommu_identity_mapping |= IDENTMAP_AZALIA;
5570 return;
5571 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005572
5573 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005574 vtisochctrl);
5575}