blob: 2800a6ee8cc96a407ce0c80d57d7d32ca73eefff [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);
Jon Derrick5823e332017-08-30 15:05:59 -0600904
905#ifdef CONFIG_X86
906 /* VMD child devices currently cannot be handled individually */
907 if (is_vmd(pdev->bus))
908 return NULL;
909#endif
910
Ashok Raj1c387182016-10-21 15:32:05 -0700911 /* VFs aren't listed in scope tables; we need to look up
912 * the PF instead to find the IOMMU. */
913 pf_pdev = pci_physfn(pdev);
914 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700915 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100916 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700917 dev = &ACPI_COMPANION(dev)->dev;
918
Jiang Liu0e242612014-02-19 14:07:34 +0800919 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800920 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700921 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100922 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800923
Jiang Liub683b232014-02-19 14:07:32 +0800924 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700925 drhd->devices_cnt, i, tmp) {
926 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700927 /* For a VF use its original BDF# not that of the PF
928 * which we used for the IOMMU lookup. Strictly speaking
929 * we could do this for all PCI devices; we only need to
930 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100931 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700932 goto got_pdev;
933
David Woodhouse156baca2014-03-09 14:00:57 -0700934 *bus = drhd->devices[i].bus;
935 *devfn = drhd->devices[i].devfn;
936 goto out;
937 }
938
939 if (!pdev || !dev_is_pci(tmp))
David Woodhouse832bd852014-03-07 15:08:36 +0000940 continue;
David Woodhouse156baca2014-03-09 14:00:57 -0700941
942 ptmp = to_pci_dev(tmp);
943 if (ptmp->subordinate &&
944 ptmp->subordinate->number <= pdev->bus->number &&
945 ptmp->subordinate->busn_res.end >= pdev->bus->number)
946 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100947 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800948
David Woodhouse156baca2014-03-09 14:00:57 -0700949 if (pdev && drhd->include_all) {
950 got_pdev:
951 *bus = pdev->bus->number;
952 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800953 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700954 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800955 }
Jiang Liub683b232014-02-19 14:07:32 +0800956 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700957 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800958 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800959
Jiang Liub683b232014-02-19 14:07:32 +0800960 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800961}
962
Weidong Han5331fe62008-12-08 23:00:00 +0800963static void domain_flush_cache(struct dmar_domain *domain,
964 void *addr, int size)
965{
966 if (!domain->iommu_coherency)
967 clflush_cache_range(addr, size);
968}
969
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700970static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
971{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700972 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000973 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700974 unsigned long flags;
975
976 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000977 context = iommu_context_addr(iommu, bus, devfn, 0);
978 if (context)
979 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700980 spin_unlock_irqrestore(&iommu->lock, flags);
981 return ret;
982}
983
984static void clear_context_table(struct intel_iommu *iommu, u8 bus, u8 devfn)
985{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700986 struct context_entry *context;
987 unsigned long flags;
988
989 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000990 context = iommu_context_addr(iommu, bus, devfn, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700991 if (context) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000992 context_clear_entry(context);
993 __iommu_flush_cache(iommu, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700994 }
995 spin_unlock_irqrestore(&iommu->lock, flags);
996}
997
998static void free_context_table(struct intel_iommu *iommu)
999{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001000 int i;
1001 unsigned long flags;
1002 struct context_entry *context;
1003
1004 spin_lock_irqsave(&iommu->lock, flags);
1005 if (!iommu->root_entry) {
1006 goto out;
1007 }
1008 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +00001009 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001010 if (context)
1011 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +00001012
David Woodhousec83b2f22015-06-12 10:15:49 +01001013 if (!ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +00001014 continue;
1015
1016 context = iommu_context_addr(iommu, i, 0x80, 0);
1017 if (context)
1018 free_pgtable_page(context);
1019
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001020 }
1021 free_pgtable_page(iommu->root_entry);
1022 iommu->root_entry = NULL;
1023out:
1024 spin_unlock_irqrestore(&iommu->lock, flags);
1025}
1026
David Woodhouseb026fd22009-06-28 10:37:25 +01001027static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +00001028 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001029{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001030 struct dma_pte *parent, *pte = NULL;
1031 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -07001032 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001033
1034 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +02001035
Jiang Liu162d1b12014-07-11 14:19:35 +08001036 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +02001037 /* Address beyond IOMMU's addressing capabilities. */
1038 return NULL;
1039
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001040 parent = domain->pgd;
1041
David Woodhouse5cf0a762014-03-19 16:07:49 +00001042 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001043 void *tmp_page;
1044
David Woodhouseb026fd22009-06-28 10:37:25 +01001045 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001046 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +00001047 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001048 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +00001049 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001050 break;
1051
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001052 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +01001053 uint64_t pteval;
1054
Suresh Siddha4c923d42009-10-02 11:01:24 -07001055 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001056
David Woodhouse206a73c2009-07-01 19:30:28 +01001057 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001058 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +01001059
David Woodhousec85994e2009-07-01 19:21:24 +01001060 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -04001061 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 +08001062 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +01001063 /* Someone else set it while we were thinking; use theirs. */
1064 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +08001065 else
David Woodhousec85994e2009-07-01 19:21:24 +01001066 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001067 }
David Woodhouse5cf0a762014-03-19 16:07:49 +00001068 if (level == 1)
1069 break;
1070
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001071 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001072 level--;
1073 }
1074
David Woodhouse5cf0a762014-03-19 16:07:49 +00001075 if (!*target_level)
1076 *target_level = level;
1077
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001078 return pte;
1079}
1080
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001081
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001082/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +01001083static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
1084 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001085 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001086{
1087 struct dma_pte *parent, *pte = NULL;
1088 int total = agaw_to_level(domain->agaw);
1089 int offset;
1090
1091 parent = domain->pgd;
1092 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +01001093 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001094 pte = &parent[offset];
1095 if (level == total)
1096 return pte;
1097
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001098 if (!dma_pte_present(pte)) {
1099 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001100 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001101 }
1102
Yijing Wange16922a2014-05-20 20:37:51 +08001103 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001104 *large_page = total;
1105 return pte;
1106 }
1107
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001108 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001109 total--;
1110 }
1111 return NULL;
1112}
1113
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001114/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +00001115static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf2009-06-27 22:09:11 +01001116 unsigned long start_pfn,
1117 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001118{
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001119 unsigned int large_page = 1;
David Woodhouse310a5ab2009-06-28 18:52:20 +01001120 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001121
Jiang Liu162d1b12014-07-11 14:19:35 +08001122 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1123 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001124 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001125
David Woodhouse04b18e62009-06-27 19:15:01 +01001126 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001127 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001128 large_page = 1;
1129 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001130 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001131 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001132 continue;
1133 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001134 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001135 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001136 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001137 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001138 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1139
David Woodhouse310a5ab2009-06-28 18:52:20 +01001140 domain_flush_cache(domain, first_pte,
1141 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001142
1143 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001144}
1145
Alex Williamson3269ee02013-06-15 10:27:19 -06001146static void dma_pte_free_level(struct dmar_domain *domain, int level,
1147 struct dma_pte *pte, unsigned long pfn,
1148 unsigned long start_pfn, unsigned long last_pfn)
1149{
1150 pfn = max(start_pfn, pfn);
1151 pte = &pte[pfn_level_offset(pfn, level)];
1152
1153 do {
1154 unsigned long level_pfn;
1155 struct dma_pte *level_pte;
1156
1157 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1158 goto next;
1159
David Dillowf7116e12017-01-30 19:11:11 -08001160 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001161 level_pte = phys_to_virt(dma_pte_addr(pte));
1162
1163 if (level > 2)
1164 dma_pte_free_level(domain, level - 1, level_pte,
1165 level_pfn, start_pfn, last_pfn);
1166
1167 /* If range covers entire pagetable, free it */
1168 if (!(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001169 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001170 dma_clear_pte(pte);
1171 domain_flush_cache(domain, pte, sizeof(*pte));
1172 free_pgtable_page(level_pte);
1173 }
1174next:
1175 pfn += level_size(level);
1176 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1177}
1178
Michael S. Tsirkin3d1a2442016-03-23 20:34:19 +02001179/* clear last level (leaf) ptes and free page table pages. */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001180static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001181 unsigned long start_pfn,
1182 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001183{
Jiang Liu162d1b12014-07-11 14:19:35 +08001184 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1185 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001186 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001187
Jiang Liud41a4ad2014-07-11 14:19:34 +08001188 dma_pte_clear_range(domain, start_pfn, last_pfn);
1189
David Woodhousef3a0a522009-06-30 03:40:07 +01001190 /* We don't need lock here; nobody else touches the iova range */
Alex Williamson3269ee02013-06-15 10:27:19 -06001191 dma_pte_free_level(domain, agaw_to_level(domain->agaw),
1192 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001193
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001194 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001195 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001196 free_pgtable_page(domain->pgd);
1197 domain->pgd = NULL;
1198 }
1199}
1200
David Woodhouseea8ea462014-03-05 17:09:32 +00001201/* When a page at a given level is being unlinked from its parent, we don't
1202 need to *modify* it at all. All we need to do is make a list of all the
1203 pages which can be freed just as soon as we've flushed the IOTLB and we
1204 know the hardware page-walk will no longer touch them.
1205 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1206 be freed. */
1207static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1208 int level, struct dma_pte *pte,
1209 struct page *freelist)
1210{
1211 struct page *pg;
1212
1213 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1214 pg->freelist = freelist;
1215 freelist = pg;
1216
1217 if (level == 1)
1218 return freelist;
1219
Jiang Liuadeb2592014-04-09 10:20:39 +08001220 pte = page_address(pg);
1221 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001222 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1223 freelist = dma_pte_list_pagetables(domain, level - 1,
1224 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001225 pte++;
1226 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001227
1228 return freelist;
1229}
1230
1231static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1232 struct dma_pte *pte, unsigned long pfn,
1233 unsigned long start_pfn,
1234 unsigned long last_pfn,
1235 struct page *freelist)
1236{
1237 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1238
1239 pfn = max(start_pfn, pfn);
1240 pte = &pte[pfn_level_offset(pfn, level)];
1241
1242 do {
1243 unsigned long level_pfn;
1244
1245 if (!dma_pte_present(pte))
1246 goto next;
1247
1248 level_pfn = pfn & level_mask(level);
1249
1250 /* If range covers entire pagetable, free it */
1251 if (start_pfn <= level_pfn &&
1252 last_pfn >= level_pfn + level_size(level) - 1) {
1253 /* These suborbinate page tables are going away entirely. Don't
1254 bother to clear them; we're just going to *free* them. */
1255 if (level > 1 && !dma_pte_superpage(pte))
1256 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1257
1258 dma_clear_pte(pte);
1259 if (!first_pte)
1260 first_pte = pte;
1261 last_pte = pte;
1262 } else if (level > 1) {
1263 /* Recurse down into a level that isn't *entirely* obsolete */
1264 freelist = dma_pte_clear_level(domain, level - 1,
1265 phys_to_virt(dma_pte_addr(pte)),
1266 level_pfn, start_pfn, last_pfn,
1267 freelist);
1268 }
1269next:
1270 pfn += level_size(level);
1271 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1272
1273 if (first_pte)
1274 domain_flush_cache(domain, first_pte,
1275 (void *)++last_pte - (void *)first_pte);
1276
1277 return freelist;
1278}
1279
1280/* We can't just free the pages because the IOMMU may still be walking
1281 the page tables, and may have cached the intermediate levels. The
1282 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001283static struct page *domain_unmap(struct dmar_domain *domain,
1284 unsigned long start_pfn,
1285 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001286{
David Woodhouseea8ea462014-03-05 17:09:32 +00001287 struct page *freelist = NULL;
1288
Jiang Liu162d1b12014-07-11 14:19:35 +08001289 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1290 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001291 BUG_ON(start_pfn > last_pfn);
1292
1293 /* we don't need lock here; nobody else touches the iova range */
1294 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1295 domain->pgd, 0, start_pfn, last_pfn, NULL);
1296
1297 /* free pgd */
1298 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1299 struct page *pgd_page = virt_to_page(domain->pgd);
1300 pgd_page->freelist = freelist;
1301 freelist = pgd_page;
1302
1303 domain->pgd = NULL;
1304 }
1305
1306 return freelist;
1307}
1308
Joerg Roedelb6904202015-08-13 11:32:18 +02001309static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001310{
1311 struct page *pg;
1312
1313 while ((pg = freelist)) {
1314 freelist = pg->freelist;
1315 free_pgtable_page(page_address(pg));
1316 }
1317}
1318
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001319/* iommu handling */
1320static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1321{
1322 struct root_entry *root;
1323 unsigned long flags;
1324
Suresh Siddha4c923d42009-10-02 11:01:24 -07001325 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001326 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001327 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001328 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001329 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001330 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001331
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001332 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001333
1334 spin_lock_irqsave(&iommu->lock, flags);
1335 iommu->root_entry = root;
1336 spin_unlock_irqrestore(&iommu->lock, flags);
1337
1338 return 0;
1339}
1340
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001341static void iommu_set_root_entry(struct intel_iommu *iommu)
1342{
David Woodhouse03ecc322015-02-13 14:35:21 +00001343 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001344 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001345 unsigned long flag;
1346
David Woodhouse03ecc322015-02-13 14:35:21 +00001347 addr = virt_to_phys(iommu->root_entry);
David Woodhousec83b2f22015-06-12 10:15:49 +01001348 if (ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +00001349 addr |= DMA_RTADDR_RTT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001350
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001351 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001352 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001353
David Woodhousec416daa2009-05-10 20:30:58 +01001354 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001355
1356 /* Make sure hardware complete it */
1357 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001358 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001359
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001360 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001361}
1362
1363static void iommu_flush_write_buffer(struct intel_iommu *iommu)
1364{
1365 u32 val;
1366 unsigned long flag;
1367
David Woodhouse9af88142009-02-13 23:18:03 +00001368 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001369 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001370
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001371 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001372 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001373
1374 /* Make sure hardware complete it */
1375 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001376 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001377
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001378 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001379}
1380
1381/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001382static void __iommu_flush_context(struct intel_iommu *iommu,
1383 u16 did, u16 source_id, u8 function_mask,
1384 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001385{
1386 u64 val = 0;
1387 unsigned long flag;
1388
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001389 switch (type) {
1390 case DMA_CCMD_GLOBAL_INVL:
1391 val = DMA_CCMD_GLOBAL_INVL;
1392 break;
1393 case DMA_CCMD_DOMAIN_INVL:
1394 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1395 break;
1396 case DMA_CCMD_DEVICE_INVL:
1397 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1398 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1399 break;
1400 default:
1401 BUG();
1402 }
1403 val |= DMA_CCMD_ICC;
1404
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001405 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001406 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1407
1408 /* Make sure hardware complete it */
1409 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1410 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1411
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001412 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001413}
1414
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001415/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001416static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1417 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001418{
1419 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1420 u64 val = 0, val_iva = 0;
1421 unsigned long flag;
1422
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001423 switch (type) {
1424 case DMA_TLB_GLOBAL_FLUSH:
1425 /* global flush doesn't need set IVA_REG */
1426 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1427 break;
1428 case DMA_TLB_DSI_FLUSH:
1429 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1430 break;
1431 case DMA_TLB_PSI_FLUSH:
1432 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001433 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001434 val_iva = size_order | addr;
1435 break;
1436 default:
1437 BUG();
1438 }
1439 /* Note: set drain read/write */
1440#if 0
1441 /*
1442 * This is probably to be super secure.. Looks like we can
1443 * ignore it without any impact.
1444 */
1445 if (cap_read_drain(iommu->cap))
1446 val |= DMA_TLB_READ_DRAIN;
1447#endif
1448 if (cap_write_drain(iommu->cap))
1449 val |= DMA_TLB_WRITE_DRAIN;
1450
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001451 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001452 /* Note: Only uses first TLB reg currently */
1453 if (val_iva)
1454 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1455 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1456
1457 /* Make sure hardware complete it */
1458 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1459 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1460
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001461 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001462
1463 /* check IOTLB invalidation granularity */
1464 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001465 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001466 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001467 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001468 (unsigned long long)DMA_TLB_IIRG(type),
1469 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001470}
1471
David Woodhouse64ae8922014-03-09 12:52:30 -07001472static struct device_domain_info *
1473iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1474 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001475{
Yu Zhao93a23a72009-05-18 13:51:37 +08001476 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001477
Joerg Roedel55d94042015-07-22 16:50:40 +02001478 assert_spin_locked(&device_domain_lock);
1479
Yu Zhao93a23a72009-05-18 13:51:37 +08001480 if (!iommu->qi)
1481 return NULL;
1482
Yu Zhao93a23a72009-05-18 13:51:37 +08001483 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001484 if (info->iommu == iommu && info->bus == bus &&
1485 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001486 if (info->ats_supported && info->dev)
1487 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001488 break;
1489 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001490
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001491 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001492}
1493
Omer Peleg0824c592016-04-20 19:03:35 +03001494static void domain_update_iotlb(struct dmar_domain *domain)
1495{
1496 struct device_domain_info *info;
1497 bool has_iotlb_device = false;
1498
1499 assert_spin_locked(&device_domain_lock);
1500
1501 list_for_each_entry(info, &domain->devices, link) {
1502 struct pci_dev *pdev;
1503
1504 if (!info->dev || !dev_is_pci(info->dev))
1505 continue;
1506
1507 pdev = to_pci_dev(info->dev);
1508 if (pdev->ats_enabled) {
1509 has_iotlb_device = true;
1510 break;
1511 }
1512 }
1513
1514 domain->has_iotlb_device = has_iotlb_device;
1515}
1516
Yu Zhao93a23a72009-05-18 13:51:37 +08001517static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1518{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001519 struct pci_dev *pdev;
1520
Omer Peleg0824c592016-04-20 19:03:35 +03001521 assert_spin_locked(&device_domain_lock);
1522
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001523 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001524 return;
1525
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001526 pdev = to_pci_dev(info->dev);
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001527
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001528#ifdef CONFIG_INTEL_IOMMU_SVM
1529 /* The PCIe spec, in its wisdom, declares that the behaviour of
1530 the device if you enable PASID support after ATS support is
1531 undefined. So always enable PASID support on devices which
1532 have it, even if we can't yet know if we're ever going to
1533 use it. */
1534 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1535 info->pasid_enabled = 1;
1536
1537 if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
1538 info->pri_enabled = 1;
1539#endif
1540 if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
1541 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001542 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001543 info->ats_qdep = pci_ats_queue_depth(pdev);
1544 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001545}
1546
1547static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1548{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001549 struct pci_dev *pdev;
1550
Omer Peleg0824c592016-04-20 19:03:35 +03001551 assert_spin_locked(&device_domain_lock);
1552
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001553 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001554 return;
1555
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001556 pdev = to_pci_dev(info->dev);
1557
1558 if (info->ats_enabled) {
1559 pci_disable_ats(pdev);
1560 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001561 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001562 }
1563#ifdef CONFIG_INTEL_IOMMU_SVM
1564 if (info->pri_enabled) {
1565 pci_disable_pri(pdev);
1566 info->pri_enabled = 0;
1567 }
1568 if (info->pasid_enabled) {
1569 pci_disable_pasid(pdev);
1570 info->pasid_enabled = 0;
1571 }
1572#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001573}
1574
1575static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1576 u64 addr, unsigned mask)
1577{
1578 u16 sid, qdep;
1579 unsigned long flags;
1580 struct device_domain_info *info;
1581
Omer Peleg0824c592016-04-20 19:03:35 +03001582 if (!domain->has_iotlb_device)
1583 return;
1584
Yu Zhao93a23a72009-05-18 13:51:37 +08001585 spin_lock_irqsave(&device_domain_lock, flags);
1586 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001587 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001588 continue;
1589
1590 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001591 qdep = info->ats_qdep;
Yu Zhao93a23a72009-05-18 13:51:37 +08001592 qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
1593 }
1594 spin_unlock_irqrestore(&device_domain_lock, flags);
1595}
1596
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001597static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1598 struct dmar_domain *domain,
1599 unsigned long pfn, unsigned int pages,
1600 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001601{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001602 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001603 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001604 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001605
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001606 BUG_ON(pages == 0);
1607
David Woodhouseea8ea462014-03-05 17:09:32 +00001608 if (ih)
1609 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001610 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001611 * Fallback to domain selective flush if no PSI support or the size is
1612 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001613 * PSI requires page size to be 2 ^ x, and the base address is naturally
1614 * aligned to the size
1615 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001616 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1617 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001618 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001619 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001620 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001621 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001622
1623 /*
Nadav Amit82653632010-04-01 13:24:40 +03001624 * In caching mode, changes of pages from non-present to present require
1625 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001626 */
Nadav Amit82653632010-04-01 13:24:40 +03001627 if (!cap_caching_mode(iommu->cap) || !map)
Joerg Roedel9452d5b2015-07-21 10:00:56 +02001628 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1629 addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001630}
1631
mark grossf8bab732008-02-08 04:18:38 -08001632static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1633{
1634 u32 pmen;
1635 unsigned long flags;
1636
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001637 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001638 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1639 pmen &= ~DMA_PMEN_EPM;
1640 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1641
1642 /* wait for the protected region status bit to clear */
1643 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1644 readl, !(pmen & DMA_PMEN_PRS), pmen);
1645
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001646 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001647}
1648
Jiang Liu2a41cce2014-07-11 14:19:33 +08001649static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001650{
1651 u32 sts;
1652 unsigned long flags;
1653
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001654 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001655 iommu->gcmd |= DMA_GCMD_TE;
1656 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001657
1658 /* Make sure hardware complete it */
1659 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001660 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001661
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001662 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001663}
1664
Jiang Liu2a41cce2014-07-11 14:19:33 +08001665static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001666{
1667 u32 sts;
1668 unsigned long flag;
1669
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001670 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001671 iommu->gcmd &= ~DMA_GCMD_TE;
1672 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1673
1674 /* Make sure hardware complete it */
1675 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001676 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001677
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001678 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001679}
1680
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001681
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001682static int iommu_init_domains(struct intel_iommu *iommu)
1683{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001684 u32 ndomains, nlongs;
1685 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001686
1687 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001688 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001689 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001690 nlongs = BITS_TO_LONGS(ndomains);
1691
Donald Dutile94a91b52009-08-20 16:51:34 -04001692 spin_lock_init(&iommu->lock);
1693
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001694 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1695 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001696 pr_err("%s: Allocating domain id array failed\n",
1697 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001698 return -ENOMEM;
1699 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001700
Wei Yang86f004c2016-05-21 02:41:51 +00001701 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001702 iommu->domains = kzalloc(size, GFP_KERNEL);
1703
1704 if (iommu->domains) {
1705 size = 256 * sizeof(struct dmar_domain *);
1706 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1707 }
1708
1709 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001710 pr_err("%s: Allocating domain array failed\n",
1711 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001712 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001713 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001714 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001715 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001716 return -ENOMEM;
1717 }
1718
Joerg Roedel8bf47812015-07-21 10:41:21 +02001719
1720
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001721 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001722 * If Caching mode is set, then invalid translations are tagged
1723 * with domain-id 0, hence we need to pre-allocate it. We also
1724 * use domain-id 0 as a marker for non-allocated domain-id, so
1725 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001726 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001727 set_bit(0, iommu->domain_ids);
1728
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001729 return 0;
1730}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001731
Jiang Liuffebeb42014-11-09 22:48:02 +08001732static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001733{
Joerg Roedel29a27712015-07-21 17:17:12 +02001734 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001735 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001736
Joerg Roedel29a27712015-07-21 17:17:12 +02001737 if (!iommu->domains || !iommu->domain_ids)
1738 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001739
Joerg Roedelbea64032016-11-08 15:08:26 +01001740again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001741 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001742 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1743 struct dmar_domain *domain;
1744
1745 if (info->iommu != iommu)
1746 continue;
1747
1748 if (!info->dev || !info->domain)
1749 continue;
1750
1751 domain = info->domain;
1752
Joerg Roedelbea64032016-11-08 15:08:26 +01001753 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001754
Joerg Roedelbea64032016-11-08 15:08:26 +01001755 if (!domain_type_is_vm_or_si(domain)) {
1756 /*
1757 * The domain_exit() function can't be called under
1758 * device_domain_lock, as it takes this lock itself.
1759 * So release the lock here and re-run the loop
1760 * afterwards.
1761 */
1762 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001763 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001764 goto again;
1765 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001766 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001767 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001768
1769 if (iommu->gcmd & DMA_GCMD_TE)
1770 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001771}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001772
Jiang Liuffebeb42014-11-09 22:48:02 +08001773static void free_dmar_iommu(struct intel_iommu *iommu)
1774{
1775 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001776 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001777 int i;
1778
1779 for (i = 0; i < elems; i++)
1780 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001781 kfree(iommu->domains);
1782 kfree(iommu->domain_ids);
1783 iommu->domains = NULL;
1784 iommu->domain_ids = NULL;
1785 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001786
Weidong Hand9630fe2008-12-08 11:06:32 +08001787 g_iommus[iommu->seq_id] = NULL;
1788
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001789 /* free context mapping */
1790 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001791
1792#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001793 if (pasid_enabled(iommu)) {
1794 if (ecap_prs(iommu->ecap))
1795 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001796 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001797 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001798#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001799}
1800
Jiang Liuab8dfe22014-07-11 14:19:27 +08001801static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001802{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001803 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001804
1805 domain = alloc_domain_mem();
1806 if (!domain)
1807 return NULL;
1808
Jiang Liuab8dfe22014-07-11 14:19:27 +08001809 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001810 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001811 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001812 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001813 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001814
1815 return domain;
1816}
1817
Joerg Roedeld160aca2015-07-22 11:52:53 +02001818/* Must be called with iommu->lock */
1819static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001820 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001821{
Jiang Liu44bde612014-07-11 14:19:29 +08001822 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001823 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001824
Joerg Roedel55d94042015-07-22 16:50:40 +02001825 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001826 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001827
Joerg Roedel29a27712015-07-21 17:17:12 +02001828 domain->iommu_refcnt[iommu->seq_id] += 1;
1829 domain->iommu_count += 1;
1830 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001831 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001832 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1833
1834 if (num >= ndomains) {
1835 pr_err("%s: No free domain ids\n", iommu->name);
1836 domain->iommu_refcnt[iommu->seq_id] -= 1;
1837 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001838 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001839 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001840
Joerg Roedeld160aca2015-07-22 11:52:53 +02001841 set_bit(num, iommu->domain_ids);
1842 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001843
Joerg Roedeld160aca2015-07-22 11:52:53 +02001844 domain->iommu_did[iommu->seq_id] = num;
1845 domain->nid = iommu->node;
1846
Jiang Liufb170fb2014-07-11 14:19:28 +08001847 domain_update_iommu_cap(domain);
1848 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001849
Joerg Roedel55d94042015-07-22 16:50:40 +02001850 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001851}
1852
1853static int domain_detach_iommu(struct dmar_domain *domain,
1854 struct intel_iommu *iommu)
1855{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001856 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001857
Joerg Roedel55d94042015-07-22 16:50:40 +02001858 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001859 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001860
Joerg Roedel29a27712015-07-21 17:17:12 +02001861 domain->iommu_refcnt[iommu->seq_id] -= 1;
1862 count = --domain->iommu_count;
1863 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001864 num = domain->iommu_did[iommu->seq_id];
1865 clear_bit(num, iommu->domain_ids);
1866 set_iommu_domain(iommu, num, NULL);
1867
Jiang Liufb170fb2014-07-11 14:19:28 +08001868 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001869 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001870 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001871
1872 return count;
1873}
1874
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001875static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001876static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001877
Joseph Cihula51a63e62011-03-21 11:04:24 -07001878static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001879{
1880 struct pci_dev *pdev = NULL;
1881 struct iova *iova;
1882 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001883
Robin Murphy0fb5fe82015-01-12 17:51:16 +00001884 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN,
1885 DMA_32BIT_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001886
Mark Gross8a443df2008-03-04 14:59:31 -08001887 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1888 &reserved_rbtree_key);
1889
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001890 /* IOAPIC ranges shouldn't be accessed by DMA */
1891 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1892 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001893 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001894 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001895 return -ENODEV;
1896 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001897
1898 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1899 for_each_pci_dev(pdev) {
1900 struct resource *r;
1901
1902 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1903 r = &pdev->resource[i];
1904 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1905 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001906 iova = reserve_iova(&reserved_iova_list,
1907 IOVA_PFN(r->start),
1908 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001909 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001910 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001911 return -ENODEV;
1912 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001913 }
1914 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001915 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001916}
1917
1918static void domain_reserve_special_ranges(struct dmar_domain *domain)
1919{
1920 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1921}
1922
1923static inline int guestwidth_to_adjustwidth(int gaw)
1924{
1925 int agaw;
1926 int r = (gaw - 12) % 9;
1927
1928 if (r == 0)
1929 agaw = gaw;
1930 else
1931 agaw = gaw + 9 - r;
1932 if (agaw > 64)
1933 agaw = 64;
1934 return agaw;
1935}
1936
Joerg Roedeldc534b22015-07-22 12:44:02 +02001937static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1938 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001939{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001940 int adjust_width, agaw;
1941 unsigned long sagaw;
1942
Robin Murphy0fb5fe82015-01-12 17:51:16 +00001943 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
1944 DMA_32BIT_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001945 domain_reserve_special_ranges(domain);
1946
1947 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001948 if (guest_width > cap_mgaw(iommu->cap))
1949 guest_width = cap_mgaw(iommu->cap);
1950 domain->gaw = guest_width;
1951 adjust_width = guestwidth_to_adjustwidth(guest_width);
1952 agaw = width_to_agaw(adjust_width);
1953 sagaw = cap_sagaw(iommu->cap);
1954 if (!test_bit(agaw, &sagaw)) {
1955 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001956 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001957 agaw = find_next_bit(&sagaw, 5, agaw);
1958 if (agaw >= 5)
1959 return -ENODEV;
1960 }
1961 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001962
Weidong Han8e6040972008-12-08 15:49:06 +08001963 if (ecap_coherent(iommu->ecap))
1964 domain->iommu_coherency = 1;
1965 else
1966 domain->iommu_coherency = 0;
1967
Sheng Yang58c610b2009-03-18 15:33:05 +08001968 if (ecap_sc_support(iommu->ecap))
1969 domain->iommu_snooping = 1;
1970 else
1971 domain->iommu_snooping = 0;
1972
David Woodhouse214e39a2014-03-19 10:38:49 +00001973 if (intel_iommu_superpage)
1974 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1975 else
1976 domain->iommu_superpage = 0;
1977
Suresh Siddha4c923d42009-10-02 11:01:24 -07001978 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001979
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001980 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001981 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001982 if (!domain->pgd)
1983 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001984 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001985 return 0;
1986}
1987
1988static void domain_exit(struct dmar_domain *domain)
1989{
David Woodhouseea8ea462014-03-05 17:09:32 +00001990 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001991
1992 /* Domain 0 is reserved, so dont process it */
1993 if (!domain)
1994 return;
1995
Alex Williamson7b668352011-05-24 12:02:41 +01001996 /* Flush any lazy unmaps that may reference this domain */
Omer Pelegaa473242016-04-20 11:33:02 +03001997 if (!intel_iommu_strict) {
1998 int cpu;
1999
2000 for_each_possible_cpu(cpu)
2001 flush_unmaps_timeout(cpu);
2002 }
Alex Williamson7b668352011-05-24 12:02:41 +01002003
Joerg Roedeld160aca2015-07-22 11:52:53 +02002004 /* Remove associated devices and clear attached or cached domains */
2005 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002006 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02002007 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08002008
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002009 /* destroy iovas */
2010 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002011
David Woodhouseea8ea462014-03-05 17:09:32 +00002012 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002013
David Woodhouseea8ea462014-03-05 17:09:32 +00002014 dma_free_pagelist(freelist);
2015
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002016 free_domain_mem(domain);
2017}
2018
David Woodhouse64ae8922014-03-09 12:52:30 -07002019static int domain_context_mapping_one(struct dmar_domain *domain,
2020 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002021 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002022{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002023 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002024 int translation = CONTEXT_TT_MULTI_LEVEL;
2025 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002026 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002027 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002028 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002029 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002030
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002031 WARN_ON(did == 0);
2032
Joerg Roedel28ccce02015-07-21 14:45:31 +02002033 if (hw_pass_through && domain_type_is_si(domain))
2034 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002035
2036 pr_debug("Set context mapping for %02x:%02x.%d\n",
2037 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002038
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002039 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002040
Joerg Roedel55d94042015-07-22 16:50:40 +02002041 spin_lock_irqsave(&device_domain_lock, flags);
2042 spin_lock(&iommu->lock);
2043
2044 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002045 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002046 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002047 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002048
Joerg Roedel55d94042015-07-22 16:50:40 +02002049 ret = 0;
2050 if (context_present(context))
2051 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002052
Xunlei Pangaec0e862016-12-05 20:09:07 +08002053 /*
2054 * For kdump cases, old valid entries may be cached due to the
2055 * in-flight DMA and copied pgtable, but there is no unmapping
2056 * behaviour for them, thus we need an explicit cache flush for
2057 * the newly-mapped device. For kdump, at this point, the device
2058 * is supposed to finish reset at its driver probe stage, so no
2059 * in-flight DMA will exist, and we don't need to worry anymore
2060 * hereafter.
2061 */
2062 if (context_copied(context)) {
2063 u16 did_old = context_domain_id(context);
2064
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002065 if (did_old >= 0 && did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002066 iommu->flush.flush_context(iommu, did_old,
2067 (((u16)bus) << 8) | devfn,
2068 DMA_CCMD_MASK_NOBIT,
2069 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002070 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2071 DMA_TLB_DSI_FLUSH);
2072 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002073 }
2074
Weidong Hanea6606b2008-12-08 23:08:15 +08002075 pgd = domain->pgd;
2076
Joerg Roedelde24e552015-07-21 14:53:04 +02002077 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002078 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002079
Joerg Roedelde24e552015-07-21 14:53:04 +02002080 /*
2081 * Skip top levels of page tables for iommu which has less agaw
2082 * than default. Unnecessary for PT mode.
2083 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002084 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002085 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002086 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002087 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002088 if (!dma_pte_present(pgd))
2089 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002090 }
2091
David Woodhouse64ae8922014-03-09 12:52:30 -07002092 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002093 if (info && info->ats_supported)
2094 translation = CONTEXT_TT_DEV_IOTLB;
2095 else
2096 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002097
Yu Zhao93a23a72009-05-18 13:51:37 +08002098 context_set_address_root(context, virt_to_phys(pgd));
2099 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002100 } else {
2101 /*
2102 * In pass through mode, AW must be programmed to
2103 * indicate the largest AGAW value supported by
2104 * hardware. And ASR is ignored by hardware.
2105 */
2106 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002107 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002108
2109 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002110 context_set_fault_enable(context);
2111 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002112 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002113
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002114 /*
2115 * It's a non-present to present mapping. If hardware doesn't cache
2116 * non-present entry we only need to flush the write-buffer. If the
2117 * _does_ cache non-present entries, then it does so in the special
2118 * domain #0, which we have to flush:
2119 */
2120 if (cap_caching_mode(iommu->cap)) {
2121 iommu->flush.flush_context(iommu, 0,
2122 (((u16)bus) << 8) | devfn,
2123 DMA_CCMD_MASK_NOBIT,
2124 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002125 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002126 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002127 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002128 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002129 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002130
Joerg Roedel55d94042015-07-22 16:50:40 +02002131 ret = 0;
2132
2133out_unlock:
2134 spin_unlock(&iommu->lock);
2135 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002136
Wei Yang5c365d12016-07-13 13:53:21 +00002137 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002138}
2139
Alex Williamson579305f2014-07-03 09:51:43 -06002140struct domain_context_mapping_data {
2141 struct dmar_domain *domain;
2142 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002143};
2144
2145static int domain_context_mapping_cb(struct pci_dev *pdev,
2146 u16 alias, void *opaque)
2147{
2148 struct domain_context_mapping_data *data = opaque;
2149
2150 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002151 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002152}
2153
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002154static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002155domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002156{
David Woodhouse64ae8922014-03-09 12:52:30 -07002157 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002158 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002159 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002160
David Woodhousee1f167f2014-03-09 15:24:46 -07002161 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002162 if (!iommu)
2163 return -ENODEV;
2164
Alex Williamson579305f2014-07-03 09:51:43 -06002165 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002166 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002167
2168 data.domain = domain;
2169 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002170
2171 return pci_for_each_dma_alias(to_pci_dev(dev),
2172 &domain_context_mapping_cb, &data);
2173}
2174
2175static int domain_context_mapped_cb(struct pci_dev *pdev,
2176 u16 alias, void *opaque)
2177{
2178 struct intel_iommu *iommu = opaque;
2179
2180 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002181}
2182
David Woodhousee1f167f2014-03-09 15:24:46 -07002183static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002184{
Weidong Han5331fe62008-12-08 23:00:00 +08002185 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002186 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002187
David Woodhousee1f167f2014-03-09 15:24:46 -07002188 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002189 if (!iommu)
2190 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002191
Alex Williamson579305f2014-07-03 09:51:43 -06002192 if (!dev_is_pci(dev))
2193 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002194
Alex Williamson579305f2014-07-03 09:51:43 -06002195 return !pci_for_each_dma_alias(to_pci_dev(dev),
2196 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002197}
2198
Fenghua Yuf5329592009-08-04 15:09:37 -07002199/* Returns a number of VTD pages, but aligned to MM page size */
2200static inline unsigned long aligned_nrpages(unsigned long host_addr,
2201 size_t size)
2202{
2203 host_addr &= ~PAGE_MASK;
2204 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2205}
2206
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002207/* Return largest possible superpage level for a given mapping */
2208static inline int hardware_largepage_caps(struct dmar_domain *domain,
2209 unsigned long iov_pfn,
2210 unsigned long phy_pfn,
2211 unsigned long pages)
2212{
2213 int support, level = 1;
2214 unsigned long pfnmerge;
2215
2216 support = domain->iommu_superpage;
2217
2218 /* To use a large page, the virtual *and* physical addresses
2219 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2220 of them will mean we have to use smaller pages. So just
2221 merge them and check both at once. */
2222 pfnmerge = iov_pfn | phy_pfn;
2223
2224 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2225 pages >>= VTD_STRIDE_SHIFT;
2226 if (!pages)
2227 break;
2228 pfnmerge >>= VTD_STRIDE_SHIFT;
2229 level++;
2230 support--;
2231 }
2232 return level;
2233}
2234
David Woodhouse9051aa02009-06-29 12:30:54 +01002235static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2236 struct scatterlist *sg, unsigned long phys_pfn,
2237 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002238{
2239 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002240 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002241 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002242 unsigned int largepage_lvl = 0;
2243 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002244
Jiang Liu162d1b12014-07-11 14:19:35 +08002245 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002246
2247 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2248 return -EINVAL;
2249
2250 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2251
Jiang Liucc4f14a2014-11-26 09:42:10 +08002252 if (!sg) {
2253 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002254 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2255 }
2256
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002257 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002258 uint64_t tmp;
2259
David Woodhousee1605492009-06-29 11:17:38 +01002260 if (!sg_res) {
Fenghua Yuf5329592009-08-04 15:09:37 -07002261 sg_res = aligned_nrpages(sg->offset, sg->length);
David Woodhousee1605492009-06-29 11:17:38 +01002262 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
2263 sg->dma_length = sg->length;
Dan Williams3e6110f2015-12-15 12:54:06 -08002264 pteval = page_to_phys(sg_page(sg)) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002265 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002266 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002267
David Woodhousee1605492009-06-29 11:17:38 +01002268 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002269 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2270
David Woodhouse5cf0a762014-03-19 16:07:49 +00002271 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002272 if (!pte)
2273 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002274 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002275 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002276 unsigned long nr_superpages, end_pfn;
2277
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002278 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002279 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002280
2281 nr_superpages = sg_res / lvl_pages;
2282 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2283
Jiang Liud41a4ad2014-07-11 14:19:34 +08002284 /*
2285 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002286 * removed to make room for superpage(s).
Jiang Liud41a4ad2014-07-11 14:19:34 +08002287 */
Christian Zanderba2374f2015-06-10 09:41:45 -07002288 dma_pte_free_pagetable(domain, iov_pfn, end_pfn);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002289 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002290 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002291 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002292
David Woodhousee1605492009-06-29 11:17:38 +01002293 }
2294 /* We don't need lock here, nobody else
2295 * touches the iova range
2296 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002297 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002298 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002299 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002300 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2301 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002302 if (dumps) {
2303 dumps--;
2304 debug_dma_dump_mappings(NULL);
2305 }
2306 WARN_ON(1);
2307 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002308
2309 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2310
2311 BUG_ON(nr_pages < lvl_pages);
2312 BUG_ON(sg_res < lvl_pages);
2313
2314 nr_pages -= lvl_pages;
2315 iov_pfn += lvl_pages;
2316 phys_pfn += lvl_pages;
2317 pteval += lvl_pages * VTD_PAGE_SIZE;
2318 sg_res -= lvl_pages;
2319
2320 /* If the next PTE would be the first in a new page, then we
2321 need to flush the cache on the entries we've just written.
2322 And then we'll need to recalculate 'pte', so clear it and
2323 let it get set again in the if (!pte) block above.
2324
2325 If we're done (!nr_pages) we need to flush the cache too.
2326
2327 Also if we've been setting superpages, we may need to
2328 recalculate 'pte' and switch back to smaller pages for the
2329 end of the mapping, if the trailing size is not enough to
2330 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002331 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002332 if (!nr_pages || first_pte_in_page(pte) ||
2333 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002334 domain_flush_cache(domain, first_pte,
2335 (void *)pte - (void *)first_pte);
2336 pte = NULL;
2337 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002338
2339 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002340 sg = sg_next(sg);
2341 }
2342 return 0;
2343}
2344
David Woodhouse9051aa02009-06-29 12:30:54 +01002345static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2346 struct scatterlist *sg, unsigned long nr_pages,
2347 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002348{
David Woodhouse9051aa02009-06-29 12:30:54 +01002349 return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
2350}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002351
David Woodhouse9051aa02009-06-29 12:30:54 +01002352static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2353 unsigned long phys_pfn, unsigned long nr_pages,
2354 int prot)
2355{
2356 return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002357}
2358
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002359static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002360{
Weidong Hanc7151a82008-12-08 22:51:37 +08002361 if (!iommu)
2362 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002363
2364 clear_context_table(iommu, bus, devfn);
2365 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002366 DMA_CCMD_GLOBAL_INVL);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01002367 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002368}
2369
David Woodhouse109b9b02012-05-25 17:43:02 +01002370static inline void unlink_domain_info(struct device_domain_info *info)
2371{
2372 assert_spin_locked(&device_domain_lock);
2373 list_del(&info->link);
2374 list_del(&info->global);
2375 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002376 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002377}
2378
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002379static void domain_remove_dev_info(struct dmar_domain *domain)
2380{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002381 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002382 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002383
2384 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002385 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002386 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002387 spin_unlock_irqrestore(&device_domain_lock, flags);
2388}
2389
2390/*
2391 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002392 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002393 */
David Woodhouse1525a292014-03-06 16:19:30 +00002394static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002395{
2396 struct device_domain_info *info;
2397
2398 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002399 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002400 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002401 return info->domain;
2402 return NULL;
2403}
2404
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002405static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002406dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2407{
2408 struct device_domain_info *info;
2409
2410 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002411 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002412 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002413 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002414
2415 return NULL;
2416}
2417
Joerg Roedel5db31562015-07-22 12:40:43 +02002418static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2419 int bus, int devfn,
2420 struct device *dev,
2421 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002422{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002423 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002424 struct device_domain_info *info;
2425 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002426 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002427
2428 info = alloc_devinfo_mem();
2429 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002430 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002431
Jiang Liu745f2582014-02-19 14:07:26 +08002432 info->bus = bus;
2433 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002434 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2435 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2436 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002437 info->dev = dev;
2438 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002439 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002440
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002441 if (dev && dev_is_pci(dev)) {
2442 struct pci_dev *pdev = to_pci_dev(info->dev);
2443
2444 if (ecap_dev_iotlb_support(iommu->ecap) &&
2445 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2446 dmar_find_matched_atsr_unit(pdev))
2447 info->ats_supported = 1;
2448
2449 if (ecs_enabled(iommu)) {
2450 if (pasid_enabled(iommu)) {
2451 int features = pci_pasid_features(pdev);
2452 if (features >= 0)
2453 info->pasid_supported = features | 1;
2454 }
2455
2456 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2457 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2458 info->pri_supported = 1;
2459 }
2460 }
2461
Jiang Liu745f2582014-02-19 14:07:26 +08002462 spin_lock_irqsave(&device_domain_lock, flags);
2463 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002464 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002465
2466 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002467 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002468 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002469 if (info2) {
2470 found = info2->domain;
2471 info2->dev = dev;
2472 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002473 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002474
Jiang Liu745f2582014-02-19 14:07:26 +08002475 if (found) {
2476 spin_unlock_irqrestore(&device_domain_lock, flags);
2477 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002478 /* Caller must free the original domain */
2479 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002480 }
2481
Joerg Roedeld160aca2015-07-22 11:52:53 +02002482 spin_lock(&iommu->lock);
2483 ret = domain_attach_iommu(domain, iommu);
2484 spin_unlock(&iommu->lock);
2485
2486 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002487 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302488 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002489 return NULL;
2490 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002491
David Woodhouseb718cd32014-03-09 13:11:33 -07002492 list_add(&info->link, &domain->devices);
2493 list_add(&info->global, &device_domain_list);
2494 if (dev)
2495 dev->archdata.iommu = info;
2496 spin_unlock_irqrestore(&device_domain_lock, flags);
2497
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002498 if (dev && domain_context_mapping(domain, dev)) {
2499 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002500 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002501 return NULL;
2502 }
2503
David Woodhouseb718cd32014-03-09 13:11:33 -07002504 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002505}
2506
Alex Williamson579305f2014-07-03 09:51:43 -06002507static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2508{
2509 *(u16 *)opaque = alias;
2510 return 0;
2511}
2512
Joerg Roedel76208352016-08-25 14:25:12 +02002513static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002514{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002515 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002516 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002517 struct intel_iommu *iommu;
Joerg Roedel08a7f452015-07-23 18:09:11 +02002518 u16 req_id, dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002519 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002520 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002521
David Woodhouse146922e2014-03-09 15:44:17 -07002522 iommu = device_to_iommu(dev, &bus, &devfn);
2523 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002524 return NULL;
2525
Joerg Roedel08a7f452015-07-23 18:09:11 +02002526 req_id = ((u16)bus << 8) | devfn;
2527
Alex Williamson579305f2014-07-03 09:51:43 -06002528 if (dev_is_pci(dev)) {
2529 struct pci_dev *pdev = to_pci_dev(dev);
2530
2531 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2532
2533 spin_lock_irqsave(&device_domain_lock, flags);
2534 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2535 PCI_BUS_NUM(dma_alias),
2536 dma_alias & 0xff);
2537 if (info) {
2538 iommu = info->iommu;
2539 domain = info->domain;
2540 }
2541 spin_unlock_irqrestore(&device_domain_lock, flags);
2542
Joerg Roedel76208352016-08-25 14:25:12 +02002543 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002544 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002545 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002546 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002547
David Woodhouse146922e2014-03-09 15:44:17 -07002548 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002549 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002550 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002551 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002552 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002553 domain_exit(domain);
2554 return NULL;
2555 }
2556
Joerg Roedel76208352016-08-25 14:25:12 +02002557out:
Alex Williamson579305f2014-07-03 09:51:43 -06002558
Joerg Roedel76208352016-08-25 14:25:12 +02002559 return domain;
2560}
2561
2562static struct dmar_domain *set_domain_for_dev(struct device *dev,
2563 struct dmar_domain *domain)
2564{
2565 struct intel_iommu *iommu;
2566 struct dmar_domain *tmp;
2567 u16 req_id, dma_alias;
2568 u8 bus, devfn;
2569
2570 iommu = device_to_iommu(dev, &bus, &devfn);
2571 if (!iommu)
2572 return NULL;
2573
2574 req_id = ((u16)bus << 8) | devfn;
2575
2576 if (dev_is_pci(dev)) {
2577 struct pci_dev *pdev = to_pci_dev(dev);
2578
2579 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2580
2581 /* register PCI DMA alias device */
2582 if (req_id != dma_alias) {
2583 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2584 dma_alias & 0xff, NULL, domain);
2585
2586 if (!tmp || tmp != domain)
2587 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002588 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002589 }
2590
Joerg Roedel5db31562015-07-22 12:40:43 +02002591 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002592 if (!tmp || tmp != domain)
2593 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002594
Joerg Roedel76208352016-08-25 14:25:12 +02002595 return domain;
2596}
2597
2598static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2599{
2600 struct dmar_domain *domain, *tmp;
2601
2602 domain = find_domain(dev);
2603 if (domain)
2604 goto out;
2605
2606 domain = find_or_alloc_domain(dev, gaw);
2607 if (!domain)
2608 goto out;
2609
2610 tmp = set_domain_for_dev(dev, domain);
2611 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002612 domain_exit(domain);
2613 domain = tmp;
2614 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002615
Joerg Roedel76208352016-08-25 14:25:12 +02002616out:
2617
David Woodhouseb718cd32014-03-09 13:11:33 -07002618 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002619}
2620
David Woodhouseb2132032009-06-26 18:50:28 +01002621static int iommu_domain_identity_map(struct dmar_domain *domain,
2622 unsigned long long start,
2623 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002624{
David Woodhousec5395d52009-06-28 16:35:56 +01002625 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2626 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002627
David Woodhousec5395d52009-06-28 16:35:56 +01002628 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2629 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002630 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002631 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002632 }
2633
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002634 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002635 /*
2636 * RMRR range might have overlap with physical memory range,
2637 * clear it first
2638 */
David Woodhousec5395d52009-06-28 16:35:56 +01002639 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002640
David Woodhousec5395d52009-06-28 16:35:56 +01002641 return domain_pfn_mapping(domain, first_vpfn, first_vpfn,
2642 last_vpfn - first_vpfn + 1,
David Woodhouse61df7442009-06-28 11:55:58 +01002643 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002644}
2645
Joerg Roedeld66ce542015-09-23 19:00:10 +02002646static int domain_prepare_identity_map(struct device *dev,
2647 struct dmar_domain *domain,
2648 unsigned long long start,
2649 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002650{
David Woodhouse19943b02009-08-04 16:19:20 +01002651 /* For _hardware_ passthrough, don't bother. But for software
2652 passthrough, we do it anyway -- it may indicate a memory
2653 range which is reserved in E820, so which didn't get set
2654 up to start with in si_domain */
2655 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002656 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2657 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002658 return 0;
2659 }
2660
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002661 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2662 dev_name(dev), start, end);
2663
David Woodhouse5595b522009-12-02 09:21:55 +00002664 if (end < start) {
2665 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2666 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2667 dmi_get_system_info(DMI_BIOS_VENDOR),
2668 dmi_get_system_info(DMI_BIOS_VERSION),
2669 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002670 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002671 }
2672
David Woodhouse2ff729f2009-08-26 14:25:41 +01002673 if (end >> agaw_to_width(domain->agaw)) {
2674 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2675 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2676 agaw_to_width(domain->agaw),
2677 dmi_get_system_info(DMI_BIOS_VENDOR),
2678 dmi_get_system_info(DMI_BIOS_VERSION),
2679 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002680 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002681 }
David Woodhouse19943b02009-08-04 16:19:20 +01002682
Joerg Roedeld66ce542015-09-23 19:00:10 +02002683 return iommu_domain_identity_map(domain, start, end);
2684}
2685
2686static int iommu_prepare_identity_map(struct device *dev,
2687 unsigned long long start,
2688 unsigned long long end)
2689{
2690 struct dmar_domain *domain;
2691 int ret;
2692
2693 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2694 if (!domain)
2695 return -ENOMEM;
2696
2697 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002698 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002699 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002700
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002701 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002702}
2703
2704static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002705 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002706{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002707 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002708 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002709 return iommu_prepare_identity_map(dev, rmrr->base_address,
2710 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002711}
2712
Suresh Siddhad3f13812011-08-23 17:05:25 -07002713#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002714static inline void iommu_prepare_isa(void)
2715{
2716 struct pci_dev *pdev;
2717 int ret;
2718
2719 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2720 if (!pdev)
2721 return;
2722
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002723 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002724 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002725
2726 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002727 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002728
Yijing Wang9b27e822014-05-20 20:37:52 +08002729 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002730}
2731#else
2732static inline void iommu_prepare_isa(void)
2733{
2734 return;
2735}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002736#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002737
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002738static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002739
Matt Kraai071e1372009-08-23 22:30:22 -07002740static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002741{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002742 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002743
Jiang Liuab8dfe22014-07-11 14:19:27 +08002744 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002745 if (!si_domain)
2746 return -EFAULT;
2747
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002748 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2749 domain_exit(si_domain);
2750 return -EFAULT;
2751 }
2752
Joerg Roedel0dc79712015-07-21 15:40:06 +02002753 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002754
David Woodhouse19943b02009-08-04 16:19:20 +01002755 if (hw)
2756 return 0;
2757
David Woodhousec7ab48d2009-06-26 19:10:36 +01002758 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002759 unsigned long start_pfn, end_pfn;
2760 int i;
2761
2762 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2763 ret = iommu_domain_identity_map(si_domain,
2764 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2765 if (ret)
2766 return ret;
2767 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002768 }
2769
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002770 return 0;
2771}
2772
David Woodhouse9b226622014-03-09 14:03:28 -07002773static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002774{
2775 struct device_domain_info *info;
2776
2777 if (likely(!iommu_identity_mapping))
2778 return 0;
2779
David Woodhouse9b226622014-03-09 14:03:28 -07002780 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002781 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2782 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002783
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002784 return 0;
2785}
2786
Joerg Roedel28ccce02015-07-21 14:45:31 +02002787static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002788{
David Woodhouse0ac72662014-03-09 13:19:22 -07002789 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002790 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002791 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002792
David Woodhouse5913c9b2014-03-09 16:27:31 -07002793 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002794 if (!iommu)
2795 return -ENODEV;
2796
Joerg Roedel5db31562015-07-22 12:40:43 +02002797 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002798 if (ndomain != domain)
2799 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002800
2801 return 0;
2802}
2803
David Woodhouse0b9d9752014-03-09 15:48:15 -07002804static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002805{
2806 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002807 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002808 int i;
2809
Jiang Liu0e242612014-02-19 14:07:34 +08002810 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002811 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002812 /*
2813 * Return TRUE if this RMRR contains the device that
2814 * is passed in.
2815 */
2816 for_each_active_dev_scope(rmrr->devices,
2817 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002818 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002819 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002820 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002821 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002822 }
Jiang Liu0e242612014-02-19 14:07:34 +08002823 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002824 return false;
2825}
2826
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002827/*
2828 * There are a couple cases where we need to restrict the functionality of
2829 * devices associated with RMRRs. The first is when evaluating a device for
2830 * identity mapping because problems exist when devices are moved in and out
2831 * of domains and their respective RMRR information is lost. This means that
2832 * a device with associated RMRRs will never be in a "passthrough" domain.
2833 * The second is use of the device through the IOMMU API. This interface
2834 * expects to have full control of the IOVA space for the device. We cannot
2835 * satisfy both the requirement that RMRR access is maintained and have an
2836 * unencumbered IOVA space. We also have no ability to quiesce the device's
2837 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2838 * We therefore prevent devices associated with an RMRR from participating in
2839 * the IOMMU API, which eliminates them from device assignment.
2840 *
2841 * In both cases we assume that PCI USB devices with RMRRs have them largely
2842 * for historical reasons and that the RMRR space is not actively used post
2843 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002844 *
2845 * The same exception is made for graphics devices, with the requirement that
2846 * any use of the RMRR regions will be torn down before assigning the device
2847 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002848 */
2849static bool device_is_rmrr_locked(struct device *dev)
2850{
2851 if (!device_has_rmrr(dev))
2852 return false;
2853
2854 if (dev_is_pci(dev)) {
2855 struct pci_dev *pdev = to_pci_dev(dev);
2856
David Woodhouse18436af2015-03-25 15:05:47 +00002857 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002858 return false;
2859 }
2860
2861 return true;
2862}
2863
David Woodhouse3bdb2592014-03-09 16:03:08 -07002864static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002865{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002866
David Woodhouse3bdb2592014-03-09 16:03:08 -07002867 if (dev_is_pci(dev)) {
2868 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002869
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002870 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002871 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002872
David Woodhouse3bdb2592014-03-09 16:03:08 -07002873 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2874 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002875
David Woodhouse3bdb2592014-03-09 16:03:08 -07002876 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2877 return 1;
2878
2879 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2880 return 0;
2881
2882 /*
2883 * We want to start off with all devices in the 1:1 domain, and
2884 * take them out later if we find they can't access all of memory.
2885 *
2886 * However, we can't do this for PCI devices behind bridges,
2887 * because all PCI devices behind the same bridge will end up
2888 * with the same source-id on their transactions.
2889 *
2890 * Practically speaking, we can't change things around for these
2891 * devices at run-time, because we can't be sure there'll be no
2892 * DMA transactions in flight for any of their siblings.
2893 *
2894 * So PCI devices (unless they're on the root bus) as well as
2895 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2896 * the 1:1 domain, just in _case_ one of their siblings turns out
2897 * not to be able to map all of memory.
2898 */
2899 if (!pci_is_pcie(pdev)) {
2900 if (!pci_is_root_bus(pdev->bus))
2901 return 0;
2902 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2903 return 0;
2904 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2905 return 0;
2906 } else {
2907 if (device_has_rmrr(dev))
2908 return 0;
2909 }
David Woodhouse6941af22009-07-04 18:24:27 +01002910
David Woodhouse3dfc8132009-07-04 19:11:08 +01002911 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002912 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002913 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002914 * take them out of the 1:1 domain later.
2915 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002916 if (!startup) {
2917 /*
2918 * If the device's dma_mask is less than the system's memory
2919 * size then this is not a candidate for identity mapping.
2920 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002921 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002922
David Woodhouse3bdb2592014-03-09 16:03:08 -07002923 if (dev->coherent_dma_mask &&
2924 dev->coherent_dma_mask < dma_mask)
2925 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002926
David Woodhouse3bdb2592014-03-09 16:03:08 -07002927 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002928 }
David Woodhouse6941af22009-07-04 18:24:27 +01002929
2930 return 1;
2931}
2932
David Woodhousecf04eee2014-03-21 16:49:04 +00002933static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2934{
2935 int ret;
2936
2937 if (!iommu_should_identity_map(dev, 1))
2938 return 0;
2939
Joerg Roedel28ccce02015-07-21 14:45:31 +02002940 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002941 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002942 pr_info("%s identity mapping for device %s\n",
2943 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002944 else if (ret == -ENODEV)
2945 /* device not associated with an iommu */
2946 ret = 0;
2947
2948 return ret;
2949}
2950
2951
Matt Kraai071e1372009-08-23 22:30:22 -07002952static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002953{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002954 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002955 struct dmar_drhd_unit *drhd;
2956 struct intel_iommu *iommu;
2957 struct device *dev;
2958 int i;
2959 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002960
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002961 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002962 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2963 if (ret)
2964 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002965 }
2966
David Woodhousecf04eee2014-03-21 16:49:04 +00002967 for_each_active_iommu(iommu, drhd)
2968 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2969 struct acpi_device_physical_node *pn;
2970 struct acpi_device *adev;
2971
2972 if (dev->bus != &acpi_bus_type)
2973 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02002974
David Woodhousecf04eee2014-03-21 16:49:04 +00002975 adev= to_acpi_device(dev);
2976 mutex_lock(&adev->physical_node_lock);
2977 list_for_each_entry(pn, &adev->physical_node_list, node) {
2978 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
2979 if (ret)
2980 break;
2981 }
2982 mutex_unlock(&adev->physical_node_lock);
2983 if (ret)
2984 return ret;
2985 }
2986
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002987 return 0;
2988}
2989
Jiang Liuffebeb42014-11-09 22:48:02 +08002990static void intel_iommu_init_qi(struct intel_iommu *iommu)
2991{
2992 /*
2993 * Start from the sane iommu hardware state.
2994 * If the queued invalidation is already initialized by us
2995 * (for example, while enabling interrupt-remapping) then
2996 * we got the things already rolling from a sane state.
2997 */
2998 if (!iommu->qi) {
2999 /*
3000 * Clear any previous faults.
3001 */
3002 dmar_fault(-1, iommu);
3003 /*
3004 * Disable queued invalidation if supported and already enabled
3005 * before OS handover.
3006 */
3007 dmar_disable_qi(iommu);
3008 }
3009
3010 if (dmar_enable_qi(iommu)) {
3011 /*
3012 * Queued Invalidate not enabled, use Register Based Invalidate
3013 */
3014 iommu->flush.flush_context = __iommu_flush_context;
3015 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003016 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003017 iommu->name);
3018 } else {
3019 iommu->flush.flush_context = qi_flush_context;
3020 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003021 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003022 }
3023}
3024
Joerg Roedel091d42e2015-06-12 11:56:10 +02003025static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003026 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003027 struct context_entry **tbl,
3028 int bus, bool ext)
3029{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003030 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003031 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003032 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003033 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003034 phys_addr_t old_ce_phys;
3035
3036 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003037 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003038
3039 for (devfn = 0; devfn < 256; devfn++) {
3040 /* First calculate the correct index */
3041 idx = (ext ? devfn * 2 : devfn) % 256;
3042
3043 if (idx == 0) {
3044 /* First save what we may have and clean up */
3045 if (new_ce) {
3046 tbl[tbl_idx] = new_ce;
3047 __iommu_flush_cache(iommu, new_ce,
3048 VTD_PAGE_SIZE);
3049 pos = 1;
3050 }
3051
3052 if (old_ce)
3053 iounmap(old_ce);
3054
3055 ret = 0;
3056 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003057 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003058 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003059 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003060
3061 if (!old_ce_phys) {
3062 if (ext && devfn == 0) {
3063 /* No LCTP, try UCTP */
3064 devfn = 0x7f;
3065 continue;
3066 } else {
3067 goto out;
3068 }
3069 }
3070
3071 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003072 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3073 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003074 if (!old_ce)
3075 goto out;
3076
3077 new_ce = alloc_pgtable_page(iommu->node);
3078 if (!new_ce)
3079 goto out_unmap;
3080
3081 ret = 0;
3082 }
3083
3084 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003085 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003086
Joerg Roedelcf484d02015-06-12 12:21:46 +02003087 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003088 continue;
3089
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003090 did = context_domain_id(&ce);
3091 if (did >= 0 && did < cap_ndoms(iommu->cap))
3092 set_bit(did, iommu->domain_ids);
3093
Joerg Roedelcf484d02015-06-12 12:21:46 +02003094 /*
3095 * We need a marker for copied context entries. This
3096 * marker needs to work for the old format as well as
3097 * for extended context entries.
3098 *
3099 * Bit 67 of the context entry is used. In the old
3100 * format this bit is available to software, in the
3101 * extended format it is the PGE bit, but PGE is ignored
3102 * by HW if PASIDs are disabled (and thus still
3103 * available).
3104 *
3105 * So disable PASIDs first and then mark the entry
3106 * copied. This means that we don't copy PASID
3107 * translations from the old kernel, but this is fine as
3108 * faults there are not fatal.
3109 */
3110 context_clear_pasid_enable(&ce);
3111 context_set_copied(&ce);
3112
Joerg Roedel091d42e2015-06-12 11:56:10 +02003113 new_ce[idx] = ce;
3114 }
3115
3116 tbl[tbl_idx + pos] = new_ce;
3117
3118 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3119
3120out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003121 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003122
3123out:
3124 return ret;
3125}
3126
3127static int copy_translation_tables(struct intel_iommu *iommu)
3128{
3129 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003130 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003131 phys_addr_t old_rt_phys;
3132 int ctxt_table_entries;
3133 unsigned long flags;
3134 u64 rtaddr_reg;
3135 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003136 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003137
3138 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3139 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003140 new_ext = !!ecap_ecs(iommu->ecap);
3141
3142 /*
3143 * The RTT bit can only be changed when translation is disabled,
3144 * but disabling translation means to open a window for data
3145 * corruption. So bail out and don't copy anything if we would
3146 * have to change the bit.
3147 */
3148 if (new_ext != ext)
3149 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003150
3151 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3152 if (!old_rt_phys)
3153 return -EINVAL;
3154
Dan Williamsdfddb9692015-10-09 18:16:46 -04003155 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003156 if (!old_rt)
3157 return -ENOMEM;
3158
3159 /* This is too big for the stack - allocate it from slab */
3160 ctxt_table_entries = ext ? 512 : 256;
3161 ret = -ENOMEM;
3162 ctxt_tbls = kzalloc(ctxt_table_entries * sizeof(void *), GFP_KERNEL);
3163 if (!ctxt_tbls)
3164 goto out_unmap;
3165
3166 for (bus = 0; bus < 256; bus++) {
3167 ret = copy_context_table(iommu, &old_rt[bus],
3168 ctxt_tbls, bus, ext);
3169 if (ret) {
3170 pr_err("%s: Failed to copy context table for bus %d\n",
3171 iommu->name, bus);
3172 continue;
3173 }
3174 }
3175
3176 spin_lock_irqsave(&iommu->lock, flags);
3177
3178 /* Context tables are copied, now write them to the root_entry table */
3179 for (bus = 0; bus < 256; bus++) {
3180 int idx = ext ? bus * 2 : bus;
3181 u64 val;
3182
3183 if (ctxt_tbls[idx]) {
3184 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3185 iommu->root_entry[bus].lo = val;
3186 }
3187
3188 if (!ext || !ctxt_tbls[idx + 1])
3189 continue;
3190
3191 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3192 iommu->root_entry[bus].hi = val;
3193 }
3194
3195 spin_unlock_irqrestore(&iommu->lock, flags);
3196
3197 kfree(ctxt_tbls);
3198
3199 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3200
3201 ret = 0;
3202
3203out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003204 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003205
3206 return ret;
3207}
3208
Joseph Cihulab7792602011-05-03 00:08:37 -07003209static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003210{
3211 struct dmar_drhd_unit *drhd;
3212 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003213 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003214 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003215 struct intel_iommu *iommu;
Omer Pelegaa473242016-04-20 11:33:02 +03003216 int i, ret, cpu;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003217
3218 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003219 * for each drhd
3220 * allocate root
3221 * initialize and program root entry to not present
3222 * endfor
3223 */
3224 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003225 /*
3226 * lock not needed as this is only incremented in the single
3227 * threaded kernel __init code path all other access are read
3228 * only
3229 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003230 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003231 g_num_of_iommus++;
3232 continue;
3233 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003234 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003235 }
3236
Jiang Liuffebeb42014-11-09 22:48:02 +08003237 /* Preallocate enough resources for IOMMU hot-addition */
3238 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3239 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3240
Weidong Hand9630fe2008-12-08 11:06:32 +08003241 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3242 GFP_KERNEL);
3243 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003244 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003245 ret = -ENOMEM;
3246 goto error;
3247 }
3248
Omer Pelegaa473242016-04-20 11:33:02 +03003249 for_each_possible_cpu(cpu) {
3250 struct deferred_flush_data *dfd = per_cpu_ptr(&deferred_flush,
3251 cpu);
3252
3253 dfd->tables = kzalloc(g_num_of_iommus *
3254 sizeof(struct deferred_flush_table),
3255 GFP_KERNEL);
3256 if (!dfd->tables) {
3257 ret = -ENOMEM;
3258 goto free_g_iommus;
3259 }
3260
3261 spin_lock_init(&dfd->lock);
3262 setup_timer(&dfd->timer, flush_unmaps_timeout, cpu);
mark gross5e0d2a62008-03-04 15:22:08 -08003263 }
3264
Jiang Liu7c919772014-01-06 14:18:18 +08003265 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003266 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003267
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003268 intel_iommu_init_qi(iommu);
3269
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003270 ret = iommu_init_domains(iommu);
3271 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003272 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003273
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003274 init_translation_status(iommu);
3275
Joerg Roedel091d42e2015-06-12 11:56:10 +02003276 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3277 iommu_disable_translation(iommu);
3278 clear_translation_pre_enabled(iommu);
3279 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3280 iommu->name);
3281 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003282
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003283 /*
3284 * TBD:
3285 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003286 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003287 */
3288 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003289 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003290 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003291
Joerg Roedel091d42e2015-06-12 11:56:10 +02003292 if (translation_pre_enabled(iommu)) {
3293 pr_info("Translation already enabled - trying to copy translation structures\n");
3294
3295 ret = copy_translation_tables(iommu);
3296 if (ret) {
3297 /*
3298 * We found the IOMMU with translation
3299 * enabled - but failed to copy over the
3300 * old root-entry table. Try to proceed
3301 * by disabling translation now and
3302 * allocating a clean root-entry table.
3303 * This might cause DMAR faults, but
3304 * probably the dump will still succeed.
3305 */
3306 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3307 iommu->name);
3308 iommu_disable_translation(iommu);
3309 clear_translation_pre_enabled(iommu);
3310 } else {
3311 pr_info("Copied translation tables from previous kernel for %s\n",
3312 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003313 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003314 }
3315 }
3316
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003317 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003318 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003319#ifdef CONFIG_INTEL_IOMMU_SVM
3320 if (pasid_enabled(iommu))
3321 intel_svm_alloc_pasid_tables(iommu);
3322#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003323 }
3324
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003325 /*
3326 * Now that qi is enabled on all iommus, set the root entry and flush
3327 * caches. This is required on some Intel X58 chipsets, otherwise the
3328 * flush_context function will loop forever and the boot hangs.
3329 */
3330 for_each_active_iommu(iommu, drhd) {
3331 iommu_flush_write_buffer(iommu);
3332 iommu_set_root_entry(iommu);
3333 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3334 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3335 }
3336
David Woodhouse19943b02009-08-04 16:19:20 +01003337 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003338 iommu_identity_mapping |= IDENTMAP_ALL;
3339
Suresh Siddhad3f13812011-08-23 17:05:25 -07003340#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003341 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003342#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003343
Ashok Raj21e722c2017-01-30 09:39:53 -08003344 check_tylersburg_isoch();
3345
Joerg Roedel86080cc2015-06-12 12:27:16 +02003346 if (iommu_identity_mapping) {
3347 ret = si_domain_init(hw_pass_through);
3348 if (ret)
3349 goto free_iommu;
3350 }
3351
David Woodhousee0fc7e02009-09-30 09:12:17 -07003352
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003353 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003354 * If we copied translations from a previous kernel in the kdump
3355 * case, we can not assign the devices to domains now, as that
3356 * would eliminate the old mappings. So skip this part and defer
3357 * the assignment to device driver initialization time.
3358 */
3359 if (copied_tables)
3360 goto domains_done;
3361
3362 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003363 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003364 * identity mappings for rmrr, gfx, and isa and may fall back to static
3365 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003366 */
David Woodhouse19943b02009-08-04 16:19:20 +01003367 if (iommu_identity_mapping) {
3368 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3369 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003370 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003371 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003372 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003373 }
David Woodhouse19943b02009-08-04 16:19:20 +01003374 /*
3375 * For each rmrr
3376 * for each dev attached to rmrr
3377 * do
3378 * locate drhd for dev, alloc domain for dev
3379 * allocate free domain
3380 * allocate page table entries for rmrr
3381 * if context not allocated for bus
3382 * allocate and init context
3383 * set present in root table for this bus
3384 * init context with domain, translation etc
3385 * endfor
3386 * endfor
3387 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003388 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003389 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003390 /* some BIOS lists non-exist devices in DMAR table. */
3391 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003392 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003393 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003394 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003395 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003396 }
3397 }
3398
3399 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003400
Joerg Roedela87f4912015-06-12 12:32:54 +02003401domains_done:
3402
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003403 /*
3404 * for each drhd
3405 * enable fault log
3406 * global invalidate context cache
3407 * global invalidate iotlb
3408 * enable translation
3409 */
Jiang Liu7c919772014-01-06 14:18:18 +08003410 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003411 if (drhd->ignored) {
3412 /*
3413 * we always have to disable PMRs or DMA may fail on
3414 * this device
3415 */
3416 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003417 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003418 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003419 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003420
3421 iommu_flush_write_buffer(iommu);
3422
David Woodhousea222a7f2015-10-07 23:35:18 +01003423#ifdef CONFIG_INTEL_IOMMU_SVM
3424 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3425 ret = intel_svm_enable_prq(iommu);
3426 if (ret)
3427 goto free_iommu;
3428 }
3429#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003430 ret = dmar_set_interrupt(iommu);
3431 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003432 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003433
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003434 if (!translation_pre_enabled(iommu))
3435 iommu_enable_translation(iommu);
3436
David Woodhouseb94996c2009-09-19 15:28:12 -07003437 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003438 }
3439
3440 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003441
3442free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003443 for_each_active_iommu(iommu, drhd) {
3444 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003445 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003446 }
Jiang Liu989d51f2014-02-19 14:07:21 +08003447free_g_iommus:
Omer Pelegaa473242016-04-20 11:33:02 +03003448 for_each_possible_cpu(cpu)
3449 kfree(per_cpu_ptr(&deferred_flush, cpu)->tables);
Weidong Hand9630fe2008-12-08 11:06:32 +08003450 kfree(g_iommus);
Jiang Liu989d51f2014-02-19 14:07:21 +08003451error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003452 return ret;
3453}
3454
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003455/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003456static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003457 struct dmar_domain *domain,
3458 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003459{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003460 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003461
David Woodhouse875764d2009-06-28 21:20:51 +01003462 /* Restrict dma_mask to the width that the iommu can handle */
3463 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003464 /* Ensure we reserve the whole size-aligned region */
3465 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003466
3467 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003468 /*
3469 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003470 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003471 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003472 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003473 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3474 IOVA_PFN(DMA_BIT_MASK(32)));
3475 if (iova_pfn)
3476 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003477 }
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003478 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages, IOVA_PFN(dma_mask));
3479 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003480 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003481 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003482 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003483 }
3484
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003485 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003486}
3487
Peter Xub316d022017-05-22 18:28:51 +08003488static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003489{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003490 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003491 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003492 struct device *i_dev;
3493 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003494
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003495 domain = find_domain(dev);
3496 if (domain)
3497 goto out;
3498
3499 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3500 if (!domain)
3501 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003502
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003503 /* We have a new domain - setup possible RMRRs for the device */
3504 rcu_read_lock();
3505 for_each_rmrr_units(rmrr) {
3506 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3507 i, i_dev) {
3508 if (i_dev != dev)
3509 continue;
3510
3511 ret = domain_prepare_identity_map(dev, domain,
3512 rmrr->base_address,
3513 rmrr->end_address);
3514 if (ret)
3515 dev_err(dev, "Mapping reserved region failed\n");
3516 }
3517 }
3518 rcu_read_unlock();
3519
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003520 tmp = set_domain_for_dev(dev, domain);
3521 if (!tmp || domain != tmp) {
3522 domain_exit(domain);
3523 domain = tmp;
3524 }
3525
3526out:
3527
3528 if (!domain)
3529 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3530
3531
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003532 return domain;
3533}
3534
David Woodhouseecb509e2014-03-09 16:29:55 -07003535/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003536static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003537{
3538 int found;
3539
David Woodhouse3d891942014-03-06 15:59:26 +00003540 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003541 return 1;
3542
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003543 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003544 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003545
David Woodhouse9b226622014-03-09 14:03:28 -07003546 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003547 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003548 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003549 return 1;
3550 else {
3551 /*
3552 * 32 bit DMA is removed from si_domain and fall back
3553 * to non-identity mapping.
3554 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003555 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003556 pr_info("32bit %s uses non-identity mapping\n",
3557 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003558 return 0;
3559 }
3560 } else {
3561 /*
3562 * In case of a detached 64 bit DMA device from vm, the device
3563 * is put into si_domain for identity mapping.
3564 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003565 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003566 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003567 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003568 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003569 pr_info("64bit %s uses identity mapping\n",
3570 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003571 return 1;
3572 }
3573 }
3574 }
3575
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003576 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003577}
3578
David Woodhouse5040a912014-03-09 16:14:00 -07003579static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003580 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003581{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003582 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003583 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003584 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003585 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003586 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003587 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003588 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003589
3590 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003591
David Woodhouse5040a912014-03-09 16:14:00 -07003592 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003593 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003594
David Woodhouse5040a912014-03-09 16:14:00 -07003595 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003596 if (!domain)
3597 return 0;
3598
Weidong Han8c11e792008-12-08 15:29:22 +08003599 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003600 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003601
Omer Peleg2aac6302016-04-20 11:33:57 +03003602 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3603 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003604 goto error;
3605
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003606 /*
3607 * Check if DMAR supports zero-length reads on write only
3608 * mappings..
3609 */
3610 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003611 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003612 prot |= DMA_PTE_READ;
3613 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3614 prot |= DMA_PTE_WRITE;
3615 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003616 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003617 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003618 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003619 * is not a big problem
3620 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003621 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003622 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003623 if (ret)
3624 goto error;
3625
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003626 /* it's a non-present to present mapping. Only flush if caching mode */
3627 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003628 iommu_flush_iotlb_psi(iommu, domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003629 mm_to_dma_pfn(iova_pfn),
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003630 size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003631 else
Weidong Han8c11e792008-12-08 15:29:22 +08003632 iommu_flush_write_buffer(iommu);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003633
Omer Peleg2aac6302016-04-20 11:33:57 +03003634 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003635 start_paddr += paddr & ~PAGE_MASK;
3636 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003637
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003638error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003639 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003640 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003641 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003642 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003643 return 0;
3644}
3645
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003646static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3647 unsigned long offset, size_t size,
3648 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003649 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003650{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003651 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003652 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003653}
3654
Omer Pelegaa473242016-04-20 11:33:02 +03003655static void flush_unmaps(struct deferred_flush_data *flush_data)
mark gross5e0d2a62008-03-04 15:22:08 -08003656{
mark gross80b20dd2008-04-18 13:53:58 -07003657 int i, j;
mark gross5e0d2a62008-03-04 15:22:08 -08003658
Omer Pelegaa473242016-04-20 11:33:02 +03003659 flush_data->timer_on = 0;
mark gross5e0d2a62008-03-04 15:22:08 -08003660
3661 /* just flush them all */
3662 for (i = 0; i < g_num_of_iommus; i++) {
Weidong Hana2bb8452008-12-08 11:24:12 +08003663 struct intel_iommu *iommu = g_iommus[i];
Omer Pelegaa473242016-04-20 11:33:02 +03003664 struct deferred_flush_table *flush_table =
3665 &flush_data->tables[i];
Weidong Hana2bb8452008-12-08 11:24:12 +08003666 if (!iommu)
3667 continue;
Suresh Siddhac42d9f32008-07-10 11:16:36 -07003668
Omer Pelegaa473242016-04-20 11:33:02 +03003669 if (!flush_table->next)
Yu Zhao9dd2fe82009-05-18 13:51:36 +08003670 continue;
3671
Nadav Amit78d5f0f2010-04-08 23:00:41 +03003672 /* In caching mode, global flushes turn emulation expensive */
3673 if (!cap_caching_mode(iommu->cap))
3674 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
Yu Zhao93a23a72009-05-18 13:51:37 +08003675 DMA_TLB_GLOBAL_FLUSH);
Omer Pelegaa473242016-04-20 11:33:02 +03003676 for (j = 0; j < flush_table->next; j++) {
Yu Zhao93a23a72009-05-18 13:51:37 +08003677 unsigned long mask;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003678 struct deferred_flush_entry *entry =
Omer Pelegaa473242016-04-20 11:33:02 +03003679 &flush_table->entries[j];
Omer Peleg2aac6302016-04-20 11:33:57 +03003680 unsigned long iova_pfn = entry->iova_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003681 unsigned long nrpages = entry->nrpages;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003682 struct dmar_domain *domain = entry->domain;
3683 struct page *freelist = entry->freelist;
Yu Zhao93a23a72009-05-18 13:51:37 +08003684
Nadav Amit78d5f0f2010-04-08 23:00:41 +03003685 /* On real hardware multiple invalidations are expensive */
3686 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003687 iommu_flush_iotlb_psi(iommu, domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003688 mm_to_dma_pfn(iova_pfn),
Omer Peleg769530e2016-04-20 11:33:25 +03003689 nrpages, !freelist, 0);
Nadav Amit78d5f0f2010-04-08 23:00:41 +03003690 else {
Omer Peleg769530e2016-04-20 11:33:25 +03003691 mask = ilog2(nrpages);
Omer Peleg314f1dc2016-04-20 11:32:45 +03003692 iommu_flush_dev_iotlb(domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003693 (uint64_t)iova_pfn << PAGE_SHIFT, mask);
Nadav Amit78d5f0f2010-04-08 23:00:41 +03003694 }
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003695 free_iova_fast(&domain->iovad, iova_pfn, nrpages);
Omer Peleg314f1dc2016-04-20 11:32:45 +03003696 if (freelist)
3697 dma_free_pagelist(freelist);
mark gross80b20dd2008-04-18 13:53:58 -07003698 }
Omer Pelegaa473242016-04-20 11:33:02 +03003699 flush_table->next = 0;
mark gross5e0d2a62008-03-04 15:22:08 -08003700 }
3701
Omer Pelegaa473242016-04-20 11:33:02 +03003702 flush_data->size = 0;
mark gross5e0d2a62008-03-04 15:22:08 -08003703}
3704
Omer Pelegaa473242016-04-20 11:33:02 +03003705static void flush_unmaps_timeout(unsigned long cpuid)
mark gross5e0d2a62008-03-04 15:22:08 -08003706{
Omer Pelegaa473242016-04-20 11:33:02 +03003707 struct deferred_flush_data *flush_data = per_cpu_ptr(&deferred_flush, cpuid);
mark gross80b20dd2008-04-18 13:53:58 -07003708 unsigned long flags;
3709
Omer Pelegaa473242016-04-20 11:33:02 +03003710 spin_lock_irqsave(&flush_data->lock, flags);
3711 flush_unmaps(flush_data);
3712 spin_unlock_irqrestore(&flush_data->lock, flags);
mark gross5e0d2a62008-03-04 15:22:08 -08003713}
3714
Omer Peleg2aac6302016-04-20 11:33:57 +03003715static void add_unmap(struct dmar_domain *dom, unsigned long iova_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003716 unsigned long nrpages, struct page *freelist)
mark gross5e0d2a62008-03-04 15:22:08 -08003717{
3718 unsigned long flags;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003719 int entry_id, iommu_id;
Weidong Han8c11e792008-12-08 15:29:22 +08003720 struct intel_iommu *iommu;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003721 struct deferred_flush_entry *entry;
Omer Pelegaa473242016-04-20 11:33:02 +03003722 struct deferred_flush_data *flush_data;
mark gross5e0d2a62008-03-04 15:22:08 -08003723
Sebastian Andrzej Siewior58c4a95f2017-06-27 18:16:48 +02003724 flush_data = raw_cpu_ptr(&deferred_flush);
Omer Pelegaa473242016-04-20 11:33:02 +03003725
3726 /* Flush all CPUs' entries to avoid deferring too much. If
3727 * this becomes a bottleneck, can just flush us, and rely on
3728 * flush timer for the rest.
3729 */
3730 if (flush_data->size == HIGH_WATER_MARK) {
3731 int cpu;
3732
3733 for_each_online_cpu(cpu)
3734 flush_unmaps_timeout(cpu);
3735 }
3736
3737 spin_lock_irqsave(&flush_data->lock, flags);
mark gross80b20dd2008-04-18 13:53:58 -07003738
Weidong Han8c11e792008-12-08 15:29:22 +08003739 iommu = domain_get_iommu(dom);
3740 iommu_id = iommu->seq_id;
Suresh Siddhac42d9f32008-07-10 11:16:36 -07003741
Omer Pelegaa473242016-04-20 11:33:02 +03003742 entry_id = flush_data->tables[iommu_id].next;
3743 ++(flush_data->tables[iommu_id].next);
mark gross5e0d2a62008-03-04 15:22:08 -08003744
Omer Pelegaa473242016-04-20 11:33:02 +03003745 entry = &flush_data->tables[iommu_id].entries[entry_id];
Omer Peleg314f1dc2016-04-20 11:32:45 +03003746 entry->domain = dom;
Omer Peleg2aac6302016-04-20 11:33:57 +03003747 entry->iova_pfn = iova_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003748 entry->nrpages = nrpages;
Omer Peleg314f1dc2016-04-20 11:32:45 +03003749 entry->freelist = freelist;
mark gross5e0d2a62008-03-04 15:22:08 -08003750
Omer Pelegaa473242016-04-20 11:33:02 +03003751 if (!flush_data->timer_on) {
3752 mod_timer(&flush_data->timer, jiffies + msecs_to_jiffies(10));
3753 flush_data->timer_on = 1;
mark gross5e0d2a62008-03-04 15:22:08 -08003754 }
Omer Pelegaa473242016-04-20 11:33:02 +03003755 flush_data->size++;
3756 spin_unlock_irqrestore(&flush_data->lock, flags);
mark gross5e0d2a62008-03-04 15:22:08 -08003757}
3758
Omer Peleg769530e2016-04-20 11:33:25 +03003759static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003760{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003761 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003762 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003763 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003764 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003765 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003766 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003767
David Woodhouse73676832009-07-04 14:08:36 +01003768 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003769 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003770
David Woodhouse1525a292014-03-06 16:19:30 +00003771 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003772 BUG_ON(!domain);
3773
Weidong Han8c11e792008-12-08 15:29:22 +08003774 iommu = domain_get_iommu(domain);
3775
Omer Peleg2aac6302016-04-20 11:33:57 +03003776 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003777
Omer Peleg769530e2016-04-20 11:33:25 +03003778 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003779 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003780 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003781
David Woodhoused794dc92009-06-28 00:27:49 +01003782 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003783 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003784
David Woodhouseea8ea462014-03-05 17:09:32 +00003785 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003786
mark gross5e0d2a62008-03-04 15:22:08 -08003787 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003788 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003789 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003790 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003791 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003792 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003793 } else {
Omer Peleg2aac6302016-04-20 11:33:57 +03003794 add_unmap(domain, iova_pfn, nrpages, freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003795 /*
3796 * queue up the release of the unmap to save the 1/6th of the
3797 * cpu used up by the iotlb flush operation...
3798 */
mark gross5e0d2a62008-03-04 15:22:08 -08003799 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003800}
3801
Jiang Liud41a4ad2014-07-11 14:19:34 +08003802static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3803 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003804 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003805{
Omer Peleg769530e2016-04-20 11:33:25 +03003806 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003807}
3808
David Woodhouse5040a912014-03-09 16:14:00 -07003809static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003810 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003811 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003812{
Akinobu Mita36746432014-06-04 16:06:51 -07003813 struct page *page = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003814 int order;
3815
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003816 size = PAGE_ALIGN(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003817 order = get_order(size);
Alex Williamsone8bb9102009-11-04 15:59:34 -07003818
David Woodhouse5040a912014-03-09 16:14:00 -07003819 if (!iommu_no_mapping(dev))
Alex Williamsone8bb9102009-11-04 15:59:34 -07003820 flags &= ~(GFP_DMA | GFP_DMA32);
David Woodhouse5040a912014-03-09 16:14:00 -07003821 else if (dev->coherent_dma_mask < dma_get_required_mask(dev)) {
3822 if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
Alex Williamsone8bb9102009-11-04 15:59:34 -07003823 flags |= GFP_DMA;
3824 else
3825 flags |= GFP_DMA32;
3826 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003827
Mel Gormand0164ad2015-11-06 16:28:21 -08003828 if (gfpflags_allow_blocking(flags)) {
Akinobu Mita36746432014-06-04 16:06:51 -07003829 unsigned int count = size >> PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003830
Lucas Stach712c6042017-02-24 14:58:44 -08003831 page = dma_alloc_from_contiguous(dev, count, order, flags);
Akinobu Mita36746432014-06-04 16:06:51 -07003832 if (page && iommu_no_mapping(dev) &&
3833 page_to_phys(page) + size > dev->coherent_dma_mask) {
3834 dma_release_from_contiguous(dev, page, count);
3835 page = NULL;
3836 }
3837 }
3838
3839 if (!page)
3840 page = alloc_pages(flags, order);
3841 if (!page)
3842 return NULL;
3843 memset(page_address(page), 0, size);
3844
3845 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003846 DMA_BIDIRECTIONAL,
David Woodhouse5040a912014-03-09 16:14:00 -07003847 dev->coherent_dma_mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003848 if (*dma_handle)
Akinobu Mita36746432014-06-04 16:06:51 -07003849 return page_address(page);
3850 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3851 __free_pages(page, order);
3852
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003853 return NULL;
3854}
3855
David Woodhouse5040a912014-03-09 16:14:00 -07003856static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003857 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003858{
3859 int order;
Akinobu Mita36746432014-06-04 16:06:51 -07003860 struct page *page = virt_to_page(vaddr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003861
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003862 size = PAGE_ALIGN(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003863 order = get_order(size);
3864
Omer Peleg769530e2016-04-20 11:33:25 +03003865 intel_unmap(dev, dma_handle, size);
Akinobu Mita36746432014-06-04 16:06:51 -07003866 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3867 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003868}
3869
David Woodhouse5040a912014-03-09 16:14:00 -07003870static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003871 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003872 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003873{
Omer Peleg769530e2016-04-20 11:33:25 +03003874 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3875 unsigned long nrpages = 0;
3876 struct scatterlist *sg;
3877 int i;
3878
3879 for_each_sg(sglist, sg, nelems, i) {
3880 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3881 }
3882
3883 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003884}
3885
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003886static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003887 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003888{
3889 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003890 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003891
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003892 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003893 BUG_ON(!sg_page(sg));
Dan Williams3e6110f2015-12-15 12:54:06 -08003894 sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003895 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003896 }
3897 return nelems;
3898}
3899
David Woodhouse5040a912014-03-09 16:14:00 -07003900static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003901 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003902{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003903 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003904 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003905 size_t size = 0;
3906 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003907 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003908 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003909 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003910 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003911 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003912
3913 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003914 if (iommu_no_mapping(dev))
3915 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003916
David Woodhouse5040a912014-03-09 16:14:00 -07003917 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003918 if (!domain)
3919 return 0;
3920
Weidong Han8c11e792008-12-08 15:29:22 +08003921 iommu = domain_get_iommu(domain);
3922
David Woodhouseb536d242009-06-28 14:49:31 +01003923 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003924 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003925
Omer Peleg2aac6302016-04-20 11:33:57 +03003926 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003927 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003928 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003929 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003930 return 0;
3931 }
3932
3933 /*
3934 * Check if DMAR supports zero-length reads on write only
3935 * mappings..
3936 */
3937 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003938 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003939 prot |= DMA_PTE_READ;
3940 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3941 prot |= DMA_PTE_WRITE;
3942
Omer Peleg2aac6302016-04-20 11:33:57 +03003943 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003944
Fenghua Yuf5329592009-08-04 15:09:37 -07003945 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003946 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003947 dma_pte_free_pagetable(domain, start_vpfn,
3948 start_vpfn + size - 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003949 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003950 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003951 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003952
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003953 /* it's a non-present to present mapping. Only flush if caching mode */
3954 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003955 iommu_flush_iotlb_psi(iommu, domain, start_vpfn, size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003956 else
Weidong Han8c11e792008-12-08 15:29:22 +08003957 iommu_flush_write_buffer(iommu);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003958
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003959 return nelems;
3960}
3961
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003962static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3963{
3964 return !dma_addr;
3965}
3966
Arvind Yadav01e19322017-06-28 16:39:32 +05303967const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003968 .alloc = intel_alloc_coherent,
3969 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003970 .map_sg = intel_map_sg,
3971 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003972 .map_page = intel_map_page,
3973 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003974 .mapping_error = intel_mapping_error,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003975#ifdef CONFIG_X86
3976 .dma_supported = x86_dma_supported,
3977#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003978};
3979
3980static inline int iommu_domain_cache_init(void)
3981{
3982 int ret = 0;
3983
3984 iommu_domain_cache = kmem_cache_create("iommu_domain",
3985 sizeof(struct dmar_domain),
3986 0,
3987 SLAB_HWCACHE_ALIGN,
3988
3989 NULL);
3990 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003991 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003992 ret = -ENOMEM;
3993 }
3994
3995 return ret;
3996}
3997
3998static inline int iommu_devinfo_cache_init(void)
3999{
4000 int ret = 0;
4001
4002 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
4003 sizeof(struct device_domain_info),
4004 0,
4005 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004006 NULL);
4007 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004008 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004009 ret = -ENOMEM;
4010 }
4011
4012 return ret;
4013}
4014
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004015static int __init iommu_init_mempool(void)
4016{
4017 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004018 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004019 if (ret)
4020 return ret;
4021
4022 ret = iommu_domain_cache_init();
4023 if (ret)
4024 goto domain_error;
4025
4026 ret = iommu_devinfo_cache_init();
4027 if (!ret)
4028 return ret;
4029
4030 kmem_cache_destroy(iommu_domain_cache);
4031domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004032 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004033
4034 return -ENOMEM;
4035}
4036
4037static void __init iommu_exit_mempool(void)
4038{
4039 kmem_cache_destroy(iommu_devinfo_cache);
4040 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03004041 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004042}
4043
Dan Williams556ab452010-07-23 15:47:56 -07004044static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
4045{
4046 struct dmar_drhd_unit *drhd;
4047 u32 vtbar;
4048 int rc;
4049
4050 /* We know that this device on this chipset has its own IOMMU.
4051 * If we find it under a different IOMMU, then the BIOS is lying
4052 * to us. Hope that the IOMMU for this device is actually
4053 * disabled, and it needs no translation...
4054 */
4055 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
4056 if (rc) {
4057 /* "can't" happen */
4058 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
4059 return;
4060 }
4061 vtbar &= 0xffff0000;
4062
4063 /* we know that the this iommu should be at offset 0xa000 from vtbar */
4064 drhd = dmar_find_matched_drhd_unit(pdev);
4065 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
4066 TAINT_FIRMWARE_WORKAROUND,
4067 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
4068 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
4069}
4070DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
4071
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004072static void __init init_no_remapping_devices(void)
4073{
4074 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00004075 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08004076 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004077
4078 for_each_drhd_unit(drhd) {
4079 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08004080 for_each_active_dev_scope(drhd->devices,
4081 drhd->devices_cnt, i, dev)
4082 break;
David Woodhouse832bd852014-03-07 15:08:36 +00004083 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004084 if (i == drhd->devices_cnt)
4085 drhd->ignored = 1;
4086 }
4087 }
4088
Jiang Liu7c919772014-01-06 14:18:18 +08004089 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08004090 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004091 continue;
4092
Jiang Liub683b232014-02-19 14:07:32 +08004093 for_each_active_dev_scope(drhd->devices,
4094 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004095 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004096 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004097 if (i < drhd->devices_cnt)
4098 continue;
4099
David Woodhousec0771df2011-10-14 20:59:46 +01004100 /* This IOMMU has *only* gfx devices. Either bypass it or
4101 set the gfx_mapped flag, as appropriate */
4102 if (dmar_map_gfx) {
4103 intel_iommu_gfx_mapped = 1;
4104 } else {
4105 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004106 for_each_active_dev_scope(drhd->devices,
4107 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004108 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004109 }
4110 }
4111}
4112
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004113#ifdef CONFIG_SUSPEND
4114static int init_iommu_hw(void)
4115{
4116 struct dmar_drhd_unit *drhd;
4117 struct intel_iommu *iommu = NULL;
4118
4119 for_each_active_iommu(iommu, drhd)
4120 if (iommu->qi)
4121 dmar_reenable_qi(iommu);
4122
Joseph Cihulab7792602011-05-03 00:08:37 -07004123 for_each_iommu(iommu, drhd) {
4124 if (drhd->ignored) {
4125 /*
4126 * we always have to disable PMRs or DMA may fail on
4127 * this device
4128 */
4129 if (force_on)
4130 iommu_disable_protect_mem_regions(iommu);
4131 continue;
4132 }
4133
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004134 iommu_flush_write_buffer(iommu);
4135
4136 iommu_set_root_entry(iommu);
4137
4138 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004139 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004140 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4141 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004142 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004143 }
4144
4145 return 0;
4146}
4147
4148static void iommu_flush_all(void)
4149{
4150 struct dmar_drhd_unit *drhd;
4151 struct intel_iommu *iommu;
4152
4153 for_each_active_iommu(iommu, drhd) {
4154 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004155 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004156 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004157 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004158 }
4159}
4160
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004161static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004162{
4163 struct dmar_drhd_unit *drhd;
4164 struct intel_iommu *iommu = NULL;
4165 unsigned long flag;
4166
4167 for_each_active_iommu(iommu, drhd) {
4168 iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
4169 GFP_ATOMIC);
4170 if (!iommu->iommu_state)
4171 goto nomem;
4172 }
4173
4174 iommu_flush_all();
4175
4176 for_each_active_iommu(iommu, drhd) {
4177 iommu_disable_translation(iommu);
4178
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004179 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004180
4181 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4182 readl(iommu->reg + DMAR_FECTL_REG);
4183 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4184 readl(iommu->reg + DMAR_FEDATA_REG);
4185 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4186 readl(iommu->reg + DMAR_FEADDR_REG);
4187 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4188 readl(iommu->reg + DMAR_FEUADDR_REG);
4189
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004190 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004191 }
4192 return 0;
4193
4194nomem:
4195 for_each_active_iommu(iommu, drhd)
4196 kfree(iommu->iommu_state);
4197
4198 return -ENOMEM;
4199}
4200
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004201static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004202{
4203 struct dmar_drhd_unit *drhd;
4204 struct intel_iommu *iommu = NULL;
4205 unsigned long flag;
4206
4207 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004208 if (force_on)
4209 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4210 else
4211 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004212 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004213 }
4214
4215 for_each_active_iommu(iommu, drhd) {
4216
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004217 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004218
4219 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4220 iommu->reg + DMAR_FECTL_REG);
4221 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4222 iommu->reg + DMAR_FEDATA_REG);
4223 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4224 iommu->reg + DMAR_FEADDR_REG);
4225 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4226 iommu->reg + DMAR_FEUADDR_REG);
4227
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004228 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004229 }
4230
4231 for_each_active_iommu(iommu, drhd)
4232 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004233}
4234
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004235static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004236 .resume = iommu_resume,
4237 .suspend = iommu_suspend,
4238};
4239
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004240static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004241{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004242 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004243}
4244
4245#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004246static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004247#endif /* CONFIG_PM */
4248
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004249
Jiang Liuc2a0b532014-11-09 22:47:56 +08004250int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004251{
4252 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004253 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004254 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004255 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004256
4257 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4258 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004259 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004260
4261 rmrru->hdr = header;
4262 rmrr = (struct acpi_dmar_reserved_memory *)header;
4263 rmrru->base_address = rmrr->base_address;
4264 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004265
4266 length = rmrr->end_address - rmrr->base_address + 1;
4267 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4268 IOMMU_RESV_DIRECT);
4269 if (!rmrru->resv)
4270 goto free_rmrru;
4271
Jiang Liu2e455282014-02-19 14:07:36 +08004272 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4273 ((void *)rmrr) + rmrr->header.length,
4274 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004275 if (rmrru->devices_cnt && rmrru->devices == NULL)
4276 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004277
Jiang Liu2e455282014-02-19 14:07:36 +08004278 list_add(&rmrru->list, &dmar_rmrr_units);
4279
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004280 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004281free_all:
4282 kfree(rmrru->resv);
4283free_rmrru:
4284 kfree(rmrru);
4285out:
4286 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004287}
4288
Jiang Liu6b197242014-11-09 22:47:58 +08004289static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4290{
4291 struct dmar_atsr_unit *atsru;
4292 struct acpi_dmar_atsr *tmp;
4293
4294 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4295 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4296 if (atsr->segment != tmp->segment)
4297 continue;
4298 if (atsr->header.length != tmp->header.length)
4299 continue;
4300 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4301 return atsru;
4302 }
4303
4304 return NULL;
4305}
4306
4307int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004308{
4309 struct acpi_dmar_atsr *atsr;
4310 struct dmar_atsr_unit *atsru;
4311
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004312 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004313 return 0;
4314
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004315 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004316 atsru = dmar_find_atsr(atsr);
4317 if (atsru)
4318 return 0;
4319
4320 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004321 if (!atsru)
4322 return -ENOMEM;
4323
Jiang Liu6b197242014-11-09 22:47:58 +08004324 /*
4325 * If memory is allocated from slab by ACPI _DSM method, we need to
4326 * copy the memory content because the memory buffer will be freed
4327 * on return.
4328 */
4329 atsru->hdr = (void *)(atsru + 1);
4330 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004331 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004332 if (!atsru->include_all) {
4333 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4334 (void *)atsr + atsr->header.length,
4335 &atsru->devices_cnt);
4336 if (atsru->devices_cnt && atsru->devices == NULL) {
4337 kfree(atsru);
4338 return -ENOMEM;
4339 }
4340 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004341
Jiang Liu0e242612014-02-19 14:07:34 +08004342 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004343
4344 return 0;
4345}
4346
Jiang Liu9bdc5312014-01-06 14:18:27 +08004347static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4348{
4349 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4350 kfree(atsru);
4351}
4352
Jiang Liu6b197242014-11-09 22:47:58 +08004353int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4354{
4355 struct acpi_dmar_atsr *atsr;
4356 struct dmar_atsr_unit *atsru;
4357
4358 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4359 atsru = dmar_find_atsr(atsr);
4360 if (atsru) {
4361 list_del_rcu(&atsru->list);
4362 synchronize_rcu();
4363 intel_iommu_free_atsr(atsru);
4364 }
4365
4366 return 0;
4367}
4368
4369int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4370{
4371 int i;
4372 struct device *dev;
4373 struct acpi_dmar_atsr *atsr;
4374 struct dmar_atsr_unit *atsru;
4375
4376 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4377 atsru = dmar_find_atsr(atsr);
4378 if (!atsru)
4379 return 0;
4380
Linus Torvalds194dc872016-07-27 20:03:31 -07004381 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004382 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4383 i, dev)
4384 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004385 }
Jiang Liu6b197242014-11-09 22:47:58 +08004386
4387 return 0;
4388}
4389
Jiang Liuffebeb42014-11-09 22:48:02 +08004390static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4391{
4392 int sp, ret = 0;
4393 struct intel_iommu *iommu = dmaru->iommu;
4394
4395 if (g_iommus[iommu->seq_id])
4396 return 0;
4397
4398 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004399 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004400 iommu->name);
4401 return -ENXIO;
4402 }
4403 if (!ecap_sc_support(iommu->ecap) &&
4404 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004405 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004406 iommu->name);
4407 return -ENXIO;
4408 }
4409 sp = domain_update_iommu_superpage(iommu) - 1;
4410 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004411 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004412 iommu->name);
4413 return -ENXIO;
4414 }
4415
4416 /*
4417 * Disable translation if already enabled prior to OS handover.
4418 */
4419 if (iommu->gcmd & DMA_GCMD_TE)
4420 iommu_disable_translation(iommu);
4421
4422 g_iommus[iommu->seq_id] = iommu;
4423 ret = iommu_init_domains(iommu);
4424 if (ret == 0)
4425 ret = iommu_alloc_root_entry(iommu);
4426 if (ret)
4427 goto out;
4428
David Woodhouse8a94ade2015-03-24 14:54:56 +00004429#ifdef CONFIG_INTEL_IOMMU_SVM
4430 if (pasid_enabled(iommu))
4431 intel_svm_alloc_pasid_tables(iommu);
4432#endif
4433
Jiang Liuffebeb42014-11-09 22:48:02 +08004434 if (dmaru->ignored) {
4435 /*
4436 * we always have to disable PMRs or DMA may fail on this device
4437 */
4438 if (force_on)
4439 iommu_disable_protect_mem_regions(iommu);
4440 return 0;
4441 }
4442
4443 intel_iommu_init_qi(iommu);
4444 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004445
4446#ifdef CONFIG_INTEL_IOMMU_SVM
4447 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4448 ret = intel_svm_enable_prq(iommu);
4449 if (ret)
4450 goto disable_iommu;
4451 }
4452#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004453 ret = dmar_set_interrupt(iommu);
4454 if (ret)
4455 goto disable_iommu;
4456
4457 iommu_set_root_entry(iommu);
4458 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4459 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4460 iommu_enable_translation(iommu);
4461
Jiang Liuffebeb42014-11-09 22:48:02 +08004462 iommu_disable_protect_mem_regions(iommu);
4463 return 0;
4464
4465disable_iommu:
4466 disable_dmar_iommu(iommu);
4467out:
4468 free_dmar_iommu(iommu);
4469 return ret;
4470}
4471
Jiang Liu6b197242014-11-09 22:47:58 +08004472int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4473{
Jiang Liuffebeb42014-11-09 22:48:02 +08004474 int ret = 0;
4475 struct intel_iommu *iommu = dmaru->iommu;
4476
4477 if (!intel_iommu_enabled)
4478 return 0;
4479 if (iommu == NULL)
4480 return -EINVAL;
4481
4482 if (insert) {
4483 ret = intel_iommu_add(dmaru);
4484 } else {
4485 disable_dmar_iommu(iommu);
4486 free_dmar_iommu(iommu);
4487 }
4488
4489 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004490}
4491
Jiang Liu9bdc5312014-01-06 14:18:27 +08004492static void intel_iommu_free_dmars(void)
4493{
4494 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4495 struct dmar_atsr_unit *atsru, *atsr_n;
4496
4497 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4498 list_del(&rmrru->list);
4499 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004500 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004501 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004502 }
4503
Jiang Liu9bdc5312014-01-06 14:18:27 +08004504 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4505 list_del(&atsru->list);
4506 intel_iommu_free_atsr(atsru);
4507 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004508}
4509
4510int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4511{
Jiang Liub683b232014-02-19 14:07:32 +08004512 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004513 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004514 struct pci_dev *bridge = NULL;
4515 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004516 struct acpi_dmar_atsr *atsr;
4517 struct dmar_atsr_unit *atsru;
4518
4519 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004520 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004521 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004522 /* If it's an integrated device, allow ATS */
4523 if (!bridge)
4524 return 1;
4525 /* Connected via non-PCIe: no ATS */
4526 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004527 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004528 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004529 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004530 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004531 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004532 }
4533
Jiang Liu0e242612014-02-19 14:07:34 +08004534 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004535 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4536 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4537 if (atsr->segment != pci_domain_nr(dev->bus))
4538 continue;
4539
Jiang Liub683b232014-02-19 14:07:32 +08004540 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004541 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004542 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004543
4544 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004545 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004546 }
Jiang Liub683b232014-02-19 14:07:32 +08004547 ret = 0;
4548out:
Jiang Liu0e242612014-02-19 14:07:34 +08004549 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004550
Jiang Liub683b232014-02-19 14:07:32 +08004551 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004552}
4553
Jiang Liu59ce0512014-02-19 14:07:35 +08004554int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4555{
4556 int ret = 0;
4557 struct dmar_rmrr_unit *rmrru;
4558 struct dmar_atsr_unit *atsru;
4559 struct acpi_dmar_atsr *atsr;
4560 struct acpi_dmar_reserved_memory *rmrr;
4561
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004562 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004563 return 0;
4564
4565 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4566 rmrr = container_of(rmrru->hdr,
4567 struct acpi_dmar_reserved_memory, header);
4568 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4569 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4570 ((void *)rmrr) + rmrr->header.length,
4571 rmrr->segment, rmrru->devices,
4572 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004573 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004574 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004575 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004576 dmar_remove_dev_scope(info, rmrr->segment,
4577 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004578 }
4579 }
4580
4581 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4582 if (atsru->include_all)
4583 continue;
4584
4585 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4586 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4587 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4588 (void *)atsr + atsr->header.length,
4589 atsr->segment, atsru->devices,
4590 atsru->devices_cnt);
4591 if (ret > 0)
4592 break;
4593 else if(ret < 0)
4594 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004595 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004596 if (dmar_remove_dev_scope(info, atsr->segment,
4597 atsru->devices, atsru->devices_cnt))
4598 break;
4599 }
4600 }
4601
4602 return 0;
4603}
4604
Fenghua Yu99dcade2009-11-11 07:23:06 -08004605/*
4606 * Here we only respond to action of unbound device from driver.
4607 *
4608 * Added device is not attached to its DMAR domain here yet. That will happen
4609 * when mapping the device to iova.
4610 */
4611static int device_notifier(struct notifier_block *nb,
4612 unsigned long action, void *data)
4613{
4614 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004615 struct dmar_domain *domain;
4616
David Woodhouse3d891942014-03-06 15:59:26 +00004617 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004618 return 0;
4619
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004620 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004621 return 0;
4622
David Woodhouse1525a292014-03-06 16:19:30 +00004623 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004624 if (!domain)
4625 return 0;
4626
Joerg Roedele6de0f82015-07-22 16:30:36 +02004627 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004628 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004629 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004630
Fenghua Yu99dcade2009-11-11 07:23:06 -08004631 return 0;
4632}
4633
4634static struct notifier_block device_nb = {
4635 .notifier_call = device_notifier,
4636};
4637
Jiang Liu75f05562014-02-19 14:07:37 +08004638static int intel_iommu_memory_notifier(struct notifier_block *nb,
4639 unsigned long val, void *v)
4640{
4641 struct memory_notify *mhp = v;
4642 unsigned long long start, end;
4643 unsigned long start_vpfn, last_vpfn;
4644
4645 switch (val) {
4646 case MEM_GOING_ONLINE:
4647 start = mhp->start_pfn << PAGE_SHIFT;
4648 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4649 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004650 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004651 start, end);
4652 return NOTIFY_BAD;
4653 }
4654 break;
4655
4656 case MEM_OFFLINE:
4657 case MEM_CANCEL_ONLINE:
4658 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4659 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4660 while (start_vpfn <= last_vpfn) {
4661 struct iova *iova;
4662 struct dmar_drhd_unit *drhd;
4663 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004664 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004665
4666 iova = find_iova(&si_domain->iovad, start_vpfn);
4667 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004668 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004669 start_vpfn);
4670 break;
4671 }
4672
4673 iova = split_and_remove_iova(&si_domain->iovad, iova,
4674 start_vpfn, last_vpfn);
4675 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004676 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004677 start_vpfn, last_vpfn);
4678 return NOTIFY_BAD;
4679 }
4680
David Woodhouseea8ea462014-03-05 17:09:32 +00004681 freelist = domain_unmap(si_domain, iova->pfn_lo,
4682 iova->pfn_hi);
4683
Jiang Liu75f05562014-02-19 14:07:37 +08004684 rcu_read_lock();
4685 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004686 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004687 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004688 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004689 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004690 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004691
4692 start_vpfn = iova->pfn_hi + 1;
4693 free_iova_mem(iova);
4694 }
4695 break;
4696 }
4697
4698 return NOTIFY_OK;
4699}
4700
4701static struct notifier_block intel_iommu_memory_nb = {
4702 .notifier_call = intel_iommu_memory_notifier,
4703 .priority = 0
4704};
4705
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004706static void free_all_cpu_cached_iovas(unsigned int cpu)
4707{
4708 int i;
4709
4710 for (i = 0; i < g_num_of_iommus; i++) {
4711 struct intel_iommu *iommu = g_iommus[i];
4712 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004713 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004714
4715 if (!iommu)
4716 continue;
4717
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004718 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004719 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004720
4721 if (!domain)
4722 continue;
4723 free_cpu_cached_iovas(cpu, &domain->iovad);
4724 }
4725 }
4726}
4727
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004728static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004729{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004730 free_all_cpu_cached_iovas(cpu);
4731 flush_unmaps_timeout(cpu);
4732 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004733}
4734
Joerg Roedel161b28a2017-03-28 17:04:52 +02004735static void intel_disable_iommus(void)
4736{
4737 struct intel_iommu *iommu = NULL;
4738 struct dmar_drhd_unit *drhd;
4739
4740 for_each_iommu(iommu, drhd)
4741 iommu_disable_translation(iommu);
4742}
4743
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004744static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4745{
4746 return container_of(dev, struct intel_iommu, iommu.dev);
4747}
4748
Alex Williamsona5459cf2014-06-12 16:12:31 -06004749static ssize_t intel_iommu_show_version(struct device *dev,
4750 struct device_attribute *attr,
4751 char *buf)
4752{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004753 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004754 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4755 return sprintf(buf, "%d:%d\n",
4756 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4757}
4758static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4759
4760static ssize_t intel_iommu_show_address(struct device *dev,
4761 struct device_attribute *attr,
4762 char *buf)
4763{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004764 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004765 return sprintf(buf, "%llx\n", iommu->reg_phys);
4766}
4767static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4768
4769static ssize_t intel_iommu_show_cap(struct device *dev,
4770 struct device_attribute *attr,
4771 char *buf)
4772{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004773 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004774 return sprintf(buf, "%llx\n", iommu->cap);
4775}
4776static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4777
4778static ssize_t intel_iommu_show_ecap(struct device *dev,
4779 struct device_attribute *attr,
4780 char *buf)
4781{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004782 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004783 return sprintf(buf, "%llx\n", iommu->ecap);
4784}
4785static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4786
Alex Williamson2238c082015-07-14 15:24:53 -06004787static ssize_t intel_iommu_show_ndoms(struct device *dev,
4788 struct device_attribute *attr,
4789 char *buf)
4790{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004791 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004792 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4793}
4794static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4795
4796static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4797 struct device_attribute *attr,
4798 char *buf)
4799{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004800 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004801 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4802 cap_ndoms(iommu->cap)));
4803}
4804static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4805
Alex Williamsona5459cf2014-06-12 16:12:31 -06004806static struct attribute *intel_iommu_attrs[] = {
4807 &dev_attr_version.attr,
4808 &dev_attr_address.attr,
4809 &dev_attr_cap.attr,
4810 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004811 &dev_attr_domains_supported.attr,
4812 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004813 NULL,
4814};
4815
4816static struct attribute_group intel_iommu_group = {
4817 .name = "intel-iommu",
4818 .attrs = intel_iommu_attrs,
4819};
4820
4821const struct attribute_group *intel_iommu_groups[] = {
4822 &intel_iommu_group,
4823 NULL,
4824};
4825
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004826int __init intel_iommu_init(void)
4827{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004828 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004829 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004830 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004831
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004832 /* VT-d is required for a TXT/tboot launch, so enforce that */
4833 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004834
Jiang Liu3a5670e2014-02-19 14:07:33 +08004835 if (iommu_init_mempool()) {
4836 if (force_on)
4837 panic("tboot: Failed to initialize iommu memory\n");
4838 return -ENOMEM;
4839 }
4840
4841 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004842 if (dmar_table_init()) {
4843 if (force_on)
4844 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004845 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004846 }
4847
Suresh Siddhac2c72862011-08-23 17:05:19 -07004848 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004849 if (force_on)
4850 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004851 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004852 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004853
Joerg Roedel161b28a2017-03-28 17:04:52 +02004854 if (no_iommu || dmar_disabled) {
4855 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004856 * We exit the function here to ensure IOMMU's remapping and
4857 * mempool aren't setup, which means that the IOMMU's PMRs
4858 * won't be disabled via the call to init_dmars(). So disable
4859 * it explicitly here. The PMRs were setup by tboot prior to
4860 * calling SENTER, but the kernel is expected to reset/tear
4861 * down the PMRs.
4862 */
4863 if (intel_iommu_tboot_noforce) {
4864 for_each_iommu(iommu, drhd)
4865 iommu_disable_protect_mem_regions(iommu);
4866 }
4867
4868 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004869 * Make sure the IOMMUs are switched off, even when we
4870 * boot into a kexec kernel and the previous kernel left
4871 * them enabled
4872 */
4873 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004874 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004875 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004876
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004877 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004878 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004879
4880 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004881 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004882
Joseph Cihula51a63e62011-03-21 11:04:24 -07004883 if (dmar_init_reserved_ranges()) {
4884 if (force_on)
4885 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004886 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004887 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004888
4889 init_no_remapping_devices();
4890
Joseph Cihulab7792602011-05-03 00:08:37 -07004891 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004892 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004893 if (force_on)
4894 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004895 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004896 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004897 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004898 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004899 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004900
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004901#ifdef CONFIG_SWIOTLB
4902 swiotlb = 0;
4903#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004904 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004905
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004906 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004907
Joerg Roedel39ab9552017-02-01 16:56:46 +01004908 for_each_active_iommu(iommu, drhd) {
4909 iommu_device_sysfs_add(&iommu->iommu, NULL,
4910 intel_iommu_groups,
4911 "%s", iommu->name);
4912 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4913 iommu_device_register(&iommu->iommu);
4914 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004915
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004916 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004917 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004918 if (si_domain && !hw_pass_through)
4919 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004920 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4921 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004922 intel_iommu_enabled = 1;
4923
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004924 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004925
4926out_free_reserved_range:
4927 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004928out_free_dmar:
4929 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004930 up_write(&dmar_global_lock);
4931 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004932 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004933}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004934
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004935static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004936{
4937 struct intel_iommu *iommu = opaque;
4938
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004939 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004940 return 0;
4941}
4942
4943/*
4944 * NB - intel-iommu lacks any sort of reference counting for the users of
4945 * dependent devices. If multiple endpoints have intersecting dependent
4946 * devices, unbinding the driver from any one of them will possibly leave
4947 * the others unable to operate.
4948 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004949static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004950{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004951 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004952 return;
4953
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004954 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004955}
4956
Joerg Roedel127c7612015-07-23 17:44:46 +02004957static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004958{
Weidong Hanc7151a82008-12-08 22:51:37 +08004959 struct intel_iommu *iommu;
4960 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004961
Joerg Roedel55d94042015-07-22 16:50:40 +02004962 assert_spin_locked(&device_domain_lock);
4963
Joerg Roedelb608ac32015-07-21 18:19:08 +02004964 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004965 return;
4966
Joerg Roedel127c7612015-07-23 17:44:46 +02004967 iommu = info->iommu;
4968
4969 if (info->dev) {
4970 iommu_disable_dev_iotlb(info);
4971 domain_context_clear(iommu, info->dev);
4972 }
4973
Joerg Roedelb608ac32015-07-21 18:19:08 +02004974 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004975
Joerg Roedeld160aca2015-07-22 11:52:53 +02004976 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004977 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004978 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004979
4980 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004981}
4982
Joerg Roedel55d94042015-07-22 16:50:40 +02004983static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4984 struct device *dev)
4985{
Joerg Roedel127c7612015-07-23 17:44:46 +02004986 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004987 unsigned long flags;
4988
Weidong Hanc7151a82008-12-08 22:51:37 +08004989 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004990 info = dev->archdata.iommu;
4991 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004992 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004993}
4994
4995static int md_domain_init(struct dmar_domain *domain, int guest_width)
4996{
4997 int adjust_width;
4998
Robin Murphy0fb5fe82015-01-12 17:51:16 +00004999 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
5000 DMA_32BIT_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005001 domain_reserve_special_ranges(domain);
5002
5003 /* calculate AGAW */
5004 domain->gaw = guest_width;
5005 adjust_width = guestwidth_to_adjustwidth(guest_width);
5006 domain->agaw = width_to_agaw(adjust_width);
5007
Weidong Han5e98c4b2008-12-08 23:03:27 +08005008 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08005009 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01005010 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005011 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08005012
5013 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07005014 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08005015 if (!domain->pgd)
5016 return -ENOMEM;
5017 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
5018 return 0;
5019}
5020
Joerg Roedel00a77de2015-03-26 13:43:08 +01005021static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03005022{
Joerg Roedel5d450802008-12-03 14:52:32 +01005023 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01005024 struct iommu_domain *domain;
5025
5026 if (type != IOMMU_DOMAIN_UNMANAGED)
5027 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005028
Jiang Liuab8dfe22014-07-11 14:19:27 +08005029 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01005030 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005031 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01005032 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005033 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07005034 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005035 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08005036 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01005037 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03005038 }
Allen Kay8140a952011-10-14 12:32:17 -07005039 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005040
Joerg Roedel00a77de2015-03-26 13:43:08 +01005041 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01005042 domain->geometry.aperture_start = 0;
5043 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
5044 domain->geometry.force_aperture = true;
5045
Joerg Roedel00a77de2015-03-26 13:43:08 +01005046 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03005047}
Kay, Allen M38717942008-09-09 18:37:29 +03005048
Joerg Roedel00a77de2015-03-26 13:43:08 +01005049static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03005050{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005051 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03005052}
Kay, Allen M38717942008-09-09 18:37:29 +03005053
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005054static int intel_iommu_attach_device(struct iommu_domain *domain,
5055 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005056{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005057 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005058 struct intel_iommu *iommu;
5059 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07005060 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03005061
Alex Williamsonc875d2c2014-07-03 09:57:02 -06005062 if (device_is_rmrr_locked(dev)) {
5063 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
5064 return -EPERM;
5065 }
5066
David Woodhouse7207d8f2014-03-09 16:31:06 -07005067 /* normally dev is not mapped */
5068 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005069 struct dmar_domain *old_domain;
5070
David Woodhouse1525a292014-03-06 16:19:30 +00005071 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005072 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02005073 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02005074 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02005075 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01005076
5077 if (!domain_type_is_vm_or_si(old_domain) &&
5078 list_empty(&old_domain->devices))
5079 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005080 }
5081 }
5082
David Woodhouse156baca2014-03-09 14:00:57 -07005083 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005084 if (!iommu)
5085 return -ENODEV;
5086
5087 /* check if this iommu agaw is sufficient for max mapped address */
5088 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01005089 if (addr_width > cap_mgaw(iommu->cap))
5090 addr_width = cap_mgaw(iommu->cap);
5091
5092 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005093 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005094 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01005095 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005096 return -EFAULT;
5097 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005098 dmar_domain->gaw = addr_width;
5099
5100 /*
5101 * Knock out extra levels of page tables if necessary
5102 */
5103 while (iommu->agaw < dmar_domain->agaw) {
5104 struct dma_pte *pte;
5105
5106 pte = dmar_domain->pgd;
5107 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005108 dmar_domain->pgd = (struct dma_pte *)
5109 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005110 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005111 }
5112 dmar_domain->agaw--;
5113 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005114
Joerg Roedel28ccce02015-07-21 14:45:31 +02005115 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005116}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005117
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005118static void intel_iommu_detach_device(struct iommu_domain *domain,
5119 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005120{
Joerg Roedele6de0f82015-07-22 16:30:36 +02005121 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005122}
Kay, Allen M38717942008-09-09 18:37:29 +03005123
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005124static int intel_iommu_map(struct iommu_domain *domain,
5125 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005126 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005127{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005128 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005129 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005130 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005131 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005132
Joerg Roedeldde57a22008-12-03 15:04:09 +01005133 if (iommu_prot & IOMMU_READ)
5134 prot |= DMA_PTE_READ;
5135 if (iommu_prot & IOMMU_WRITE)
5136 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005137 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5138 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005139
David Woodhouse163cc522009-06-28 00:51:17 +01005140 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005141 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005142 u64 end;
5143
5144 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005145 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005146 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005147 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005148 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005149 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005150 return -EFAULT;
5151 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005152 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005153 }
David Woodhousead051222009-06-28 14:22:28 +01005154 /* Round up size to next multiple of PAGE_SIZE, if it and
5155 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005156 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005157 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5158 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005159 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005160}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005161
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005162static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005163 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005164{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005165 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005166 struct page *freelist = NULL;
5167 struct intel_iommu *iommu;
5168 unsigned long start_pfn, last_pfn;
5169 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005170 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005171
David Woodhouse5cf0a762014-03-19 16:07:49 +00005172 /* Cope with horrid API which requires us to unmap more than the
5173 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005174 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005175
5176 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5177 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5178
David Woodhouseea8ea462014-03-05 17:09:32 +00005179 start_pfn = iova >> VTD_PAGE_SHIFT;
5180 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5181
5182 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5183
5184 npages = last_pfn - start_pfn + 1;
5185
Joerg Roedel29a27712015-07-21 17:17:12 +02005186 for_each_domain_iommu(iommu_id, dmar_domain) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02005187 iommu = g_iommus[iommu_id];
David Woodhouseea8ea462014-03-05 17:09:32 +00005188
Joerg Roedel42e8c182015-07-21 15:50:02 +02005189 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5190 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005191 }
5192
5193 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005194
David Woodhouse163cc522009-06-28 00:51:17 +01005195 if (dmar_domain->max_addr == iova + size)
5196 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005197
David Woodhouse5cf0a762014-03-19 16:07:49 +00005198 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005199}
Kay, Allen M38717942008-09-09 18:37:29 +03005200
Joerg Roedeld14d6572008-12-03 15:06:57 +01005201static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305202 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005203{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005204 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005205 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005206 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005207 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005208
David Woodhouse5cf0a762014-03-19 16:07:49 +00005209 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005210 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005211 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005212
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005213 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005214}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005215
Joerg Roedel5d587b82014-09-05 10:50:45 +02005216static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005217{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005218 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005219 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005220 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005221 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005222
Joerg Roedel5d587b82014-09-05 10:50:45 +02005223 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005224}
5225
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005226static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005227{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005228 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005229 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005230 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005231
Alex Williamsona5459cf2014-06-12 16:12:31 -06005232 iommu = device_to_iommu(dev, &bus, &devfn);
5233 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005234 return -ENODEV;
5235
Joerg Roedele3d10af2017-02-01 17:23:22 +01005236 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005237
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005238 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005239
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005240 if (IS_ERR(group))
5241 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005242
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005243 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005244 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005245}
5246
5247static void intel_iommu_remove_device(struct device *dev)
5248{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005249 struct intel_iommu *iommu;
5250 u8 bus, devfn;
5251
5252 iommu = device_to_iommu(dev, &bus, &devfn);
5253 if (!iommu)
5254 return;
5255
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005256 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005257
Joerg Roedele3d10af2017-02-01 17:23:22 +01005258 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005259}
5260
Eric Auger0659b8d2017-01-19 20:57:53 +00005261static void intel_iommu_get_resv_regions(struct device *device,
5262 struct list_head *head)
5263{
5264 struct iommu_resv_region *reg;
5265 struct dmar_rmrr_unit *rmrr;
5266 struct device *i_dev;
5267 int i;
5268
5269 rcu_read_lock();
5270 for_each_rmrr_units(rmrr) {
5271 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5272 i, i_dev) {
5273 if (i_dev != device)
5274 continue;
5275
5276 list_add_tail(&rmrr->resv->list, head);
5277 }
5278 }
5279 rcu_read_unlock();
5280
5281 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5282 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005283 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005284 if (!reg)
5285 return;
5286 list_add_tail(&reg->list, head);
5287}
5288
5289static void intel_iommu_put_resv_regions(struct device *dev,
5290 struct list_head *head)
5291{
5292 struct iommu_resv_region *entry, *next;
5293
5294 list_for_each_entry_safe(entry, next, head, list) {
5295 if (entry->type == IOMMU_RESV_RESERVED)
5296 kfree(entry);
5297 }
Kay, Allen M38717942008-09-09 18:37:29 +03005298}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005299
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005300#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005301#define MAX_NR_PASID_BITS (20)
5302static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5303{
5304 /*
5305 * Convert ecap_pss to extend context entry pts encoding, also
5306 * respect the soft pasid_max value set by the iommu.
5307 * - number of PASID bits = ecap_pss + 1
5308 * - number of PASID table entries = 2^(pts + 5)
5309 * Therefore, pts = ecap_pss - 4
5310 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5311 */
5312 if (ecap_pss(iommu->ecap) < 5)
5313 return 0;
5314
5315 /* pasid_max is encoded as actual number of entries not the bits */
5316 return find_first_bit((unsigned long *)&iommu->pasid_max,
5317 MAX_NR_PASID_BITS) - 5;
5318}
5319
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005320int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5321{
5322 struct device_domain_info *info;
5323 struct context_entry *context;
5324 struct dmar_domain *domain;
5325 unsigned long flags;
5326 u64 ctx_lo;
5327 int ret;
5328
5329 domain = get_valid_domain_for_dev(sdev->dev);
5330 if (!domain)
5331 return -EINVAL;
5332
5333 spin_lock_irqsave(&device_domain_lock, flags);
5334 spin_lock(&iommu->lock);
5335
5336 ret = -EINVAL;
5337 info = sdev->dev->archdata.iommu;
5338 if (!info || !info->pasid_supported)
5339 goto out;
5340
5341 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5342 if (WARN_ON(!context))
5343 goto out;
5344
5345 ctx_lo = context[0].lo;
5346
5347 sdev->did = domain->iommu_did[iommu->seq_id];
5348 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5349
5350 if (!(ctx_lo & CONTEXT_PASIDE)) {
5351 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005352 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5353 intel_iommu_get_pts(iommu);
5354
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005355 wmb();
5356 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5357 * extended to permit requests-with-PASID if the PASIDE bit
5358 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5359 * however, the PASIDE bit is ignored and requests-with-PASID
5360 * are unconditionally blocked. Which makes less sense.
5361 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5362 * "guest mode" translation types depending on whether ATS
5363 * is available or not. Annoyingly, we can't use the new
5364 * modes *unless* PASIDE is set. */
5365 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5366 ctx_lo &= ~CONTEXT_TT_MASK;
5367 if (info->ats_supported)
5368 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5369 else
5370 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5371 }
5372 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005373 if (iommu->pasid_state_table)
5374 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005375 if (info->pri_supported)
5376 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005377 context[0].lo = ctx_lo;
5378 wmb();
5379 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5380 DMA_CCMD_MASK_NOBIT,
5381 DMA_CCMD_DEVICE_INVL);
5382 }
5383
5384 /* Enable PASID support in the device, if it wasn't already */
5385 if (!info->pasid_enabled)
5386 iommu_enable_dev_iotlb(info);
5387
5388 if (info->ats_enabled) {
5389 sdev->dev_iotlb = 1;
5390 sdev->qdep = info->ats_qdep;
5391 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5392 sdev->qdep = 0;
5393 }
5394 ret = 0;
5395
5396 out:
5397 spin_unlock(&iommu->lock);
5398 spin_unlock_irqrestore(&device_domain_lock, flags);
5399
5400 return ret;
5401}
5402
5403struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5404{
5405 struct intel_iommu *iommu;
5406 u8 bus, devfn;
5407
5408 if (iommu_dummy(dev)) {
5409 dev_warn(dev,
5410 "No IOMMU translation for device; cannot enable SVM\n");
5411 return NULL;
5412 }
5413
5414 iommu = device_to_iommu(dev, &bus, &devfn);
5415 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005416 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005417 return NULL;
5418 }
5419
5420 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005421 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005422 return NULL;
5423 }
5424
5425 return iommu;
5426}
5427#endif /* CONFIG_INTEL_IOMMU_SVM */
5428
Joerg Roedelb0119e82017-02-01 13:23:08 +01005429const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005430 .capable = intel_iommu_capable,
5431 .domain_alloc = intel_iommu_domain_alloc,
5432 .domain_free = intel_iommu_domain_free,
5433 .attach_dev = intel_iommu_attach_device,
5434 .detach_dev = intel_iommu_detach_device,
5435 .map = intel_iommu_map,
5436 .unmap = intel_iommu_unmap,
5437 .map_sg = default_iommu_map_sg,
5438 .iova_to_phys = intel_iommu_iova_to_phys,
5439 .add_device = intel_iommu_add_device,
5440 .remove_device = intel_iommu_remove_device,
5441 .get_resv_regions = intel_iommu_get_resv_regions,
5442 .put_resv_regions = intel_iommu_put_resv_regions,
5443 .device_group = pci_device_group,
5444 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005445};
David Woodhouse9af88142009-02-13 23:18:03 +00005446
Daniel Vetter94526182013-01-20 23:50:13 +01005447static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5448{
5449 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005450 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005451 dmar_map_gfx = 0;
5452}
5453
5454DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5455DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5456DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5457DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5458DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5459DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5460DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5461
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005462static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005463{
5464 /*
5465 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005466 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005467 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005468 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005469 rwbf_quirk = 1;
5470}
5471
5472DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005473DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5474DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5475DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5476DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5477DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5478DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005479
Adam Jacksoneecfd572010-08-25 21:17:34 +01005480#define GGC 0x52
5481#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5482#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5483#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5484#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5485#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5486#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5487#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5488#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5489
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005490static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005491{
5492 unsigned short ggc;
5493
Adam Jacksoneecfd572010-08-25 21:17:34 +01005494 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005495 return;
5496
Adam Jacksoneecfd572010-08-25 21:17:34 +01005497 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005498 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005499 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005500 } else if (dmar_map_gfx) {
5501 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005502 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005503 intel_iommu_strict = 1;
5504 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005505}
5506DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5507DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5508DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5509DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5510
David Woodhousee0fc7e02009-09-30 09:12:17 -07005511/* On Tylersburg chipsets, some BIOSes have been known to enable the
5512 ISOCH DMAR unit for the Azalia sound device, but not give it any
5513 TLB entries, which causes it to deadlock. Check for that. We do
5514 this in a function called from init_dmars(), instead of in a PCI
5515 quirk, because we don't want to print the obnoxious "BIOS broken"
5516 message if VT-d is actually disabled.
5517*/
5518static void __init check_tylersburg_isoch(void)
5519{
5520 struct pci_dev *pdev;
5521 uint32_t vtisochctrl;
5522
5523 /* If there's no Azalia in the system anyway, forget it. */
5524 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5525 if (!pdev)
5526 return;
5527 pci_dev_put(pdev);
5528
5529 /* System Management Registers. Might be hidden, in which case
5530 we can't do the sanity check. But that's OK, because the
5531 known-broken BIOSes _don't_ actually hide it, so far. */
5532 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5533 if (!pdev)
5534 return;
5535
5536 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5537 pci_dev_put(pdev);
5538 return;
5539 }
5540
5541 pci_dev_put(pdev);
5542
5543 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5544 if (vtisochctrl & 1)
5545 return;
5546
5547 /* Drop all bits other than the number of TLB entries */
5548 vtisochctrl &= 0x1c;
5549
5550 /* If we have the recommended number of TLB entries (16), fine. */
5551 if (vtisochctrl == 0x10)
5552 return;
5553
5554 /* Zero TLB entries? You get to ride the short bus to school. */
5555 if (!vtisochctrl) {
5556 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5557 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5558 dmi_get_system_info(DMI_BIOS_VENDOR),
5559 dmi_get_system_info(DMI_BIOS_VERSION),
5560 dmi_get_system_info(DMI_PRODUCT_VERSION));
5561 iommu_identity_mapping |= IDENTMAP_AZALIA;
5562 return;
5563 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005564
5565 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005566 vtisochctrl);
5567}