blob: d5e8b8628a1a62c97c24f63d87d4a69a964279c5 [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 -0800461/* bitmap for indexing intel_iommus */
mark gross5e0d2a62008-03-04 15:22:08 -0800462static int g_num_of_iommus;
463
Jiang Liu92d03cc2014-02-19 14:07:28 +0800464static void domain_exit(struct dmar_domain *domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700465static void domain_remove_dev_info(struct dmar_domain *domain);
Joerg Roedele6de0f82015-07-22 16:30:36 +0200466static void dmar_remove_one_dev_info(struct dmar_domain *domain,
467 struct device *dev);
Joerg Roedel127c7612015-07-23 17:44:46 +0200468static void __dmar_remove_one_dev_info(struct device_domain_info *info);
Joerg Roedel2452d9d2015-07-23 16:20:14 +0200469static void domain_context_clear(struct intel_iommu *iommu,
470 struct device *dev);
Jiang Liu2a46ddf2014-07-11 14:19:30 +0800471static int domain_detach_iommu(struct dmar_domain *domain,
472 struct intel_iommu *iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700473
Suresh Siddhad3f13812011-08-23 17:05:25 -0700474#ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800475int dmar_disabled = 0;
476#else
477int dmar_disabled = 1;
Suresh Siddhad3f13812011-08-23 17:05:25 -0700478#endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800479
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -0200480int intel_iommu_enabled = 0;
481EXPORT_SYMBOL_GPL(intel_iommu_enabled);
482
David Woodhouse2d9e6672010-06-15 10:57:57 +0100483static int dmar_map_gfx = 1;
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700484static int dmar_forcedac;
mark gross5e0d2a62008-03-04 15:22:08 -0800485static int intel_iommu_strict;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100486static int intel_iommu_superpage = 1;
David Woodhousec83b2f22015-06-12 10:15:49 +0100487static int intel_iommu_ecs = 1;
David Woodhouseae853dd2015-09-09 11:58:59 +0100488static int intel_iommu_pasid28;
489static int iommu_identity_mapping;
David Woodhousec83b2f22015-06-12 10:15:49 +0100490
David Woodhouseae853dd2015-09-09 11:58:59 +0100491#define IDENTMAP_ALL 1
492#define IDENTMAP_GFX 2
493#define IDENTMAP_AZALIA 4
David Woodhousec83b2f22015-06-12 10:15:49 +0100494
David Woodhoused42fde72015-10-24 21:33:01 +0200495/* Broadwell and Skylake have broken ECS support — normal so-called "second
496 * level" translation of DMA requests-without-PASID doesn't actually happen
497 * unless you also set the NESTE bit in an extended context-entry. Which of
498 * course means that SVM doesn't work because it's trying to do nested
499 * translation of the physical addresses it finds in the process page tables,
500 * through the IOVA->phys mapping found in the "second level" page tables.
501 *
502 * The VT-d specification was retroactively changed to change the definition
503 * of the capability bits and pretend that Broadwell/Skylake never happened...
504 * but unfortunately the wrong bit was changed. It's ECS which is broken, but
505 * for some reason it was the PASID capability bit which was redefined (from
506 * bit 28 on BDW/SKL to bit 40 in future).
507 *
508 * So our test for ECS needs to eschew those implementations which set the old
509 * PASID capabiity bit 28, since those are the ones on which ECS is broken.
510 * Unless we are working around the 'pasid28' limitations, that is, by putting
511 * the device into passthrough mode for normal DMA and thus masking the bug.
512 */
David Woodhousec83b2f22015-06-12 10:15:49 +0100513#define ecs_enabled(iommu) (intel_iommu_ecs && ecap_ecs(iommu->ecap) && \
David Woodhoused42fde72015-10-24 21:33:01 +0200514 (intel_iommu_pasid28 || !ecap_broken_pasid(iommu->ecap)))
515/* PASID support is thus enabled if ECS is enabled and *either* of the old
516 * or new capability bits are set. */
517#define pasid_enabled(iommu) (ecs_enabled(iommu) && \
518 (ecap_pasid(iommu->ecap) || ecap_broken_pasid(iommu->ecap)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700519
David Woodhousec0771df2011-10-14 20:59:46 +0100520int intel_iommu_gfx_mapped;
521EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
522
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700523#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
524static DEFINE_SPINLOCK(device_domain_lock);
525static LIST_HEAD(device_domain_list);
526
Joerg Roedelb0119e82017-02-01 13:23:08 +0100527const struct iommu_ops intel_iommu_ops;
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +0100528
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200529static bool translation_pre_enabled(struct intel_iommu *iommu)
530{
531 return (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED);
532}
533
Joerg Roedel091d42e2015-06-12 11:56:10 +0200534static void clear_translation_pre_enabled(struct intel_iommu *iommu)
535{
536 iommu->flags &= ~VTD_FLAG_TRANS_PRE_ENABLED;
537}
538
Joerg Roedel4158c2e2015-06-12 10:14:02 +0200539static void init_translation_status(struct intel_iommu *iommu)
540{
541 u32 gsts;
542
543 gsts = readl(iommu->reg + DMAR_GSTS_REG);
544 if (gsts & DMA_GSTS_TES)
545 iommu->flags |= VTD_FLAG_TRANS_PRE_ENABLED;
546}
547
Joerg Roedel00a77de2015-03-26 13:43:08 +0100548/* Convert generic 'struct iommu_domain to private struct dmar_domain */
549static struct dmar_domain *to_dmar_domain(struct iommu_domain *dom)
550{
551 return container_of(dom, struct dmar_domain, domain);
552}
553
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700554static int __init intel_iommu_setup(char *str)
555{
556 if (!str)
557 return -EINVAL;
558 while (*str) {
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800559 if (!strncmp(str, "on", 2)) {
560 dmar_disabled = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200561 pr_info("IOMMU enabled\n");
Kyle McMartin0cd5c3c2009-02-04 14:29:19 -0800562 } else if (!strncmp(str, "off", 3)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700563 dmar_disabled = 1;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200564 pr_info("IOMMU disabled\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700565 } else if (!strncmp(str, "igfx_off", 8)) {
566 dmar_map_gfx = 0;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200567 pr_info("Disable GFX device mapping\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700568 } else if (!strncmp(str, "forcedac", 8)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200569 pr_info("Forcing DAC for PCI devices\n");
Keshavamurthy, Anil S7d3b03c2007-10-21 16:41:53 -0700570 dmar_forcedac = 1;
mark gross5e0d2a62008-03-04 15:22:08 -0800571 } else if (!strncmp(str, "strict", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200572 pr_info("Disable batched IOTLB flush\n");
mark gross5e0d2a62008-03-04 15:22:08 -0800573 intel_iommu_strict = 1;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100574 } else if (!strncmp(str, "sp_off", 6)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +0200575 pr_info("Disable supported super page\n");
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100576 intel_iommu_superpage = 0;
David Woodhousec83b2f22015-06-12 10:15:49 +0100577 } else if (!strncmp(str, "ecs_off", 7)) {
578 printk(KERN_INFO
579 "Intel-IOMMU: disable extended context table support\n");
580 intel_iommu_ecs = 0;
David Woodhouseae853dd2015-09-09 11:58:59 +0100581 } else if (!strncmp(str, "pasid28", 7)) {
582 printk(KERN_INFO
583 "Intel-IOMMU: enable pre-production PASID support\n");
584 intel_iommu_pasid28 = 1;
585 iommu_identity_mapping |= IDENTMAP_GFX;
Shaohua Libfd20f12017-04-26 09:18:35 -0700586 } else if (!strncmp(str, "tboot_noforce", 13)) {
587 printk(KERN_INFO
588 "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
589 intel_iommu_tboot_noforce = 1;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700590 }
591
592 str += strcspn(str, ",");
593 while (*str == ',')
594 str++;
595 }
596 return 0;
597}
598__setup("intel_iommu=", intel_iommu_setup);
599
600static struct kmem_cache *iommu_domain_cache;
601static struct kmem_cache *iommu_devinfo_cache;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700602
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200603static struct dmar_domain* get_iommu_domain(struct intel_iommu *iommu, u16 did)
604{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200605 struct dmar_domain **domains;
606 int idx = did >> 8;
607
608 domains = iommu->domains[idx];
609 if (!domains)
610 return NULL;
611
612 return domains[did & 0xff];
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200613}
614
615static void set_iommu_domain(struct intel_iommu *iommu, u16 did,
616 struct dmar_domain *domain)
617{
Joerg Roedel8bf47812015-07-21 10:41:21 +0200618 struct dmar_domain **domains;
619 int idx = did >> 8;
620
621 if (!iommu->domains[idx]) {
622 size_t size = 256 * sizeof(struct dmar_domain *);
623 iommu->domains[idx] = kzalloc(size, GFP_ATOMIC);
624 }
625
626 domains = iommu->domains[idx];
627 if (WARN_ON(!domains))
628 return;
629 else
630 domains[did & 0xff] = domain;
Joerg Roedel9452d5b2015-07-21 10:00:56 +0200631}
632
Suresh Siddha4c923d42009-10-02 11:01:24 -0700633static inline void *alloc_pgtable_page(int node)
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700634{
Suresh Siddha4c923d42009-10-02 11:01:24 -0700635 struct page *page;
636 void *vaddr = NULL;
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700637
Suresh Siddha4c923d42009-10-02 11:01:24 -0700638 page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
639 if (page)
640 vaddr = page_address(page);
Keshavamurthy, Anil Seb3fa7c2007-10-21 16:41:52 -0700641 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700642}
643
644static inline void free_pgtable_page(void *vaddr)
645{
646 free_page((unsigned long)vaddr);
647}
648
649static inline void *alloc_domain_mem(void)
650{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900651 return kmem_cache_alloc(iommu_domain_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700652}
653
Kay, Allen M38717942008-09-09 18:37:29 +0300654static void free_domain_mem(void *vaddr)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700655{
656 kmem_cache_free(iommu_domain_cache, vaddr);
657}
658
659static inline void * alloc_devinfo_mem(void)
660{
KOSAKI Motohiro354bb652009-11-17 16:21:09 +0900661 return kmem_cache_alloc(iommu_devinfo_cache, GFP_ATOMIC);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700662}
663
664static inline void free_devinfo_mem(void *vaddr)
665{
666 kmem_cache_free(iommu_devinfo_cache, vaddr);
667}
668
Jiang Liuab8dfe22014-07-11 14:19:27 +0800669static inline int domain_type_is_vm(struct dmar_domain *domain)
670{
671 return domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE;
672}
673
Joerg Roedel28ccce02015-07-21 14:45:31 +0200674static inline int domain_type_is_si(struct dmar_domain *domain)
675{
676 return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
677}
678
Jiang Liuab8dfe22014-07-11 14:19:27 +0800679static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
680{
681 return domain->flags & (DOMAIN_FLAG_VIRTUAL_MACHINE |
682 DOMAIN_FLAG_STATIC_IDENTITY);
683}
Weidong Han1b573682008-12-08 15:34:06 +0800684
Jiang Liu162d1b12014-07-11 14:19:35 +0800685static inline int domain_pfn_supported(struct dmar_domain *domain,
686 unsigned long pfn)
687{
688 int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
689
690 return !(addr_width < BITS_PER_LONG && pfn >> addr_width);
691}
692
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700693static int __iommu_calculate_agaw(struct intel_iommu *iommu, int max_gaw)
Weidong Han1b573682008-12-08 15:34:06 +0800694{
695 unsigned long sagaw;
696 int agaw = -1;
697
698 sagaw = cap_sagaw(iommu->cap);
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700699 for (agaw = width_to_agaw(max_gaw);
Weidong Han1b573682008-12-08 15:34:06 +0800700 agaw >= 0; agaw--) {
701 if (test_bit(agaw, &sagaw))
702 break;
703 }
704
705 return agaw;
706}
707
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -0700708/*
709 * Calculate max SAGAW for each iommu.
710 */
711int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
712{
713 return __iommu_calculate_agaw(iommu, MAX_AGAW_WIDTH);
714}
715
716/*
717 * calculate agaw for each iommu.
718 * "SAGAW" may be different across iommus, use a default agaw, and
719 * get a supported less agaw for iommus that don't support the default agaw.
720 */
721int iommu_calculate_agaw(struct intel_iommu *iommu)
722{
723 return __iommu_calculate_agaw(iommu, DEFAULT_DOMAIN_ADDRESS_WIDTH);
724}
725
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700726/* This functionin only returns single iommu in a domain */
Weidong Han8c11e792008-12-08 15:29:22 +0800727static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
728{
729 int iommu_id;
730
Fenghua Yu2c2e2c32009-06-19 13:47:29 -0700731 /* si_domain and vm domain should not get here. */
Jiang Liuab8dfe22014-07-11 14:19:27 +0800732 BUG_ON(domain_type_is_vm_or_si(domain));
Joerg Roedel29a27712015-07-21 17:17:12 +0200733 for_each_domain_iommu(iommu_id, domain)
734 break;
735
Weidong Han8c11e792008-12-08 15:29:22 +0800736 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
737 return NULL;
738
739 return g_iommus[iommu_id];
740}
741
Weidong Han8e6040972008-12-08 15:49:06 +0800742static void domain_update_iommu_coherency(struct dmar_domain *domain)
743{
David Woodhoused0501962014-03-11 17:10:29 -0700744 struct dmar_drhd_unit *drhd;
745 struct intel_iommu *iommu;
Quentin Lambert2f119c72015-02-06 10:59:53 +0100746 bool found = false;
747 int i;
Weidong Han8e6040972008-12-08 15:49:06 +0800748
David Woodhoused0501962014-03-11 17:10:29 -0700749 domain->iommu_coherency = 1;
Weidong Han8e6040972008-12-08 15:49:06 +0800750
Joerg Roedel29a27712015-07-21 17:17:12 +0200751 for_each_domain_iommu(i, domain) {
Quentin Lambert2f119c72015-02-06 10:59:53 +0100752 found = true;
Weidong Han8e6040972008-12-08 15:49:06 +0800753 if (!ecap_coherent(g_iommus[i]->ecap)) {
754 domain->iommu_coherency = 0;
755 break;
756 }
Weidong Han8e6040972008-12-08 15:49:06 +0800757 }
David Woodhoused0501962014-03-11 17:10:29 -0700758 if (found)
759 return;
760
761 /* No hardware attached; use lowest common denominator */
762 rcu_read_lock();
763 for_each_active_iommu(iommu, drhd) {
764 if (!ecap_coherent(iommu->ecap)) {
765 domain->iommu_coherency = 0;
766 break;
767 }
768 }
769 rcu_read_unlock();
Weidong Han8e6040972008-12-08 15:49:06 +0800770}
771
Jiang Liu161f6932014-07-11 14:19:37 +0800772static int domain_update_iommu_snooping(struct intel_iommu *skip)
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100773{
Allen Kay8140a952011-10-14 12:32:17 -0700774 struct dmar_drhd_unit *drhd;
Jiang Liu161f6932014-07-11 14:19:37 +0800775 struct intel_iommu *iommu;
776 int ret = 1;
777
778 rcu_read_lock();
779 for_each_active_iommu(iommu, drhd) {
780 if (iommu != skip) {
781 if (!ecap_sc_support(iommu->ecap)) {
782 ret = 0;
783 break;
784 }
785 }
786 }
787 rcu_read_unlock();
788
789 return ret;
790}
791
792static int domain_update_iommu_superpage(struct intel_iommu *skip)
793{
794 struct dmar_drhd_unit *drhd;
795 struct intel_iommu *iommu;
Allen Kay8140a952011-10-14 12:32:17 -0700796 int mask = 0xf;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100797
798 if (!intel_iommu_superpage) {
Jiang Liu161f6932014-07-11 14:19:37 +0800799 return 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100800 }
801
Allen Kay8140a952011-10-14 12:32:17 -0700802 /* set iommu_superpage to the smallest common denominator */
Jiang Liu0e242612014-02-19 14:07:34 +0800803 rcu_read_lock();
Allen Kay8140a952011-10-14 12:32:17 -0700804 for_each_active_iommu(iommu, drhd) {
Jiang Liu161f6932014-07-11 14:19:37 +0800805 if (iommu != skip) {
806 mask &= cap_super_page_val(iommu->cap);
807 if (!mask)
808 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100809 }
810 }
Jiang Liu0e242612014-02-19 14:07:34 +0800811 rcu_read_unlock();
812
Jiang Liu161f6932014-07-11 14:19:37 +0800813 return fls(mask);
Youquan Song6dd9a7c2011-05-25 19:13:49 +0100814}
815
Sheng Yang58c610b2009-03-18 15:33:05 +0800816/* Some capabilities may be different across iommus */
817static void domain_update_iommu_cap(struct dmar_domain *domain)
818{
819 domain_update_iommu_coherency(domain);
Jiang Liu161f6932014-07-11 14:19:37 +0800820 domain->iommu_snooping = domain_update_iommu_snooping(NULL);
821 domain->iommu_superpage = domain_update_iommu_superpage(NULL);
Sheng Yang58c610b2009-03-18 15:33:05 +0800822}
823
David Woodhouse03ecc322015-02-13 14:35:21 +0000824static inline struct context_entry *iommu_context_addr(struct intel_iommu *iommu,
825 u8 bus, u8 devfn, int alloc)
826{
827 struct root_entry *root = &iommu->root_entry[bus];
828 struct context_entry *context;
829 u64 *entry;
830
Joerg Roedel4df4eab2015-08-25 10:54:28 +0200831 entry = &root->lo;
David Woodhousec83b2f22015-06-12 10:15:49 +0100832 if (ecs_enabled(iommu)) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000833 if (devfn >= 0x80) {
834 devfn -= 0x80;
835 entry = &root->hi;
836 }
837 devfn *= 2;
838 }
David Woodhouse03ecc322015-02-13 14:35:21 +0000839 if (*entry & 1)
840 context = phys_to_virt(*entry & VTD_PAGE_MASK);
841 else {
842 unsigned long phy_addr;
843 if (!alloc)
844 return NULL;
845
846 context = alloc_pgtable_page(iommu->node);
847 if (!context)
848 return NULL;
849
850 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE);
851 phy_addr = virt_to_phys((void *)context);
852 *entry = phy_addr | 1;
853 __iommu_flush_cache(iommu, entry, sizeof(*entry));
854 }
855 return &context[devfn];
856}
857
David Woodhouse4ed6a542015-05-11 14:59:20 +0100858static int iommu_dummy(struct device *dev)
859{
860 return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO;
861}
862
David Woodhouse156baca2014-03-09 14:00:57 -0700863static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn)
Weidong Hanc7151a82008-12-08 22:51:37 +0800864{
865 struct dmar_drhd_unit *drhd = NULL;
Jiang Liub683b232014-02-19 14:07:32 +0800866 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -0700867 struct device *tmp;
868 struct pci_dev *ptmp, *pdev = NULL;
Yijing Wangaa4d0662014-05-26 20:14:06 +0800869 u16 segment = 0;
Weidong Hanc7151a82008-12-08 22:51:37 +0800870 int i;
871
David Woodhouse4ed6a542015-05-11 14:59:20 +0100872 if (iommu_dummy(dev))
873 return NULL;
874
David Woodhouse156baca2014-03-09 14:00:57 -0700875 if (dev_is_pci(dev)) {
Ashok Raj1c387182016-10-21 15:32:05 -0700876 struct pci_dev *pf_pdev;
877
David Woodhouse156baca2014-03-09 14:00:57 -0700878 pdev = to_pci_dev(dev);
Ashok Raj1c387182016-10-21 15:32:05 -0700879 /* VFs aren't listed in scope tables; we need to look up
880 * the PF instead to find the IOMMU. */
881 pf_pdev = pci_physfn(pdev);
882 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700883 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100884 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700885 dev = &ACPI_COMPANION(dev)->dev;
886
Jiang Liu0e242612014-02-19 14:07:34 +0800887 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800888 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700889 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100890 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800891
Jiang Liub683b232014-02-19 14:07:32 +0800892 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700893 drhd->devices_cnt, i, tmp) {
894 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700895 /* For a VF use its original BDF# not that of the PF
896 * which we used for the IOMMU lookup. Strictly speaking
897 * we could do this for all PCI devices; we only need to
898 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100899 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700900 goto got_pdev;
901
David Woodhouse156baca2014-03-09 14:00:57 -0700902 *bus = drhd->devices[i].bus;
903 *devfn = drhd->devices[i].devfn;
904 goto out;
905 }
906
907 if (!pdev || !dev_is_pci(tmp))
David Woodhouse832bd852014-03-07 15:08:36 +0000908 continue;
David Woodhouse156baca2014-03-09 14:00:57 -0700909
910 ptmp = to_pci_dev(tmp);
911 if (ptmp->subordinate &&
912 ptmp->subordinate->number <= pdev->bus->number &&
913 ptmp->subordinate->busn_res.end >= pdev->bus->number)
914 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100915 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800916
David Woodhouse156baca2014-03-09 14:00:57 -0700917 if (pdev && drhd->include_all) {
918 got_pdev:
919 *bus = pdev->bus->number;
920 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800921 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700922 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800923 }
Jiang Liub683b232014-02-19 14:07:32 +0800924 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700925 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800926 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800927
Jiang Liub683b232014-02-19 14:07:32 +0800928 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800929}
930
Weidong Han5331fe62008-12-08 23:00:00 +0800931static void domain_flush_cache(struct dmar_domain *domain,
932 void *addr, int size)
933{
934 if (!domain->iommu_coherency)
935 clflush_cache_range(addr, size);
936}
937
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700938static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
939{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700940 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000941 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700942 unsigned long flags;
943
944 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000945 context = iommu_context_addr(iommu, bus, devfn, 0);
946 if (context)
947 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700948 spin_unlock_irqrestore(&iommu->lock, flags);
949 return ret;
950}
951
952static void clear_context_table(struct intel_iommu *iommu, u8 bus, u8 devfn)
953{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700954 struct context_entry *context;
955 unsigned long flags;
956
957 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000958 context = iommu_context_addr(iommu, bus, devfn, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700959 if (context) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000960 context_clear_entry(context);
961 __iommu_flush_cache(iommu, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700962 }
963 spin_unlock_irqrestore(&iommu->lock, flags);
964}
965
966static void free_context_table(struct intel_iommu *iommu)
967{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700968 int i;
969 unsigned long flags;
970 struct context_entry *context;
971
972 spin_lock_irqsave(&iommu->lock, flags);
973 if (!iommu->root_entry) {
974 goto out;
975 }
976 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000977 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700978 if (context)
979 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000980
David Woodhousec83b2f22015-06-12 10:15:49 +0100981 if (!ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000982 continue;
983
984 context = iommu_context_addr(iommu, i, 0x80, 0);
985 if (context)
986 free_pgtable_page(context);
987
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700988 }
989 free_pgtable_page(iommu->root_entry);
990 iommu->root_entry = NULL;
991out:
992 spin_unlock_irqrestore(&iommu->lock, flags);
993}
994
David Woodhouseb026fd22009-06-28 10:37:25 +0100995static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000996 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700997{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700998 struct dma_pte *parent, *pte = NULL;
999 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -07001000 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001001
1002 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +02001003
Jiang Liu162d1b12014-07-11 14:19:35 +08001004 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +02001005 /* Address beyond IOMMU's addressing capabilities. */
1006 return NULL;
1007
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001008 parent = domain->pgd;
1009
David Woodhouse5cf0a762014-03-19 16:07:49 +00001010 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001011 void *tmp_page;
1012
David Woodhouseb026fd22009-06-28 10:37:25 +01001013 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001014 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +00001015 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001016 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +00001017 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001018 break;
1019
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001020 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +01001021 uint64_t pteval;
1022
Suresh Siddha4c923d42009-10-02 11:01:24 -07001023 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001024
David Woodhouse206a73c2009-07-01 19:30:28 +01001025 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001026 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +01001027
David Woodhousec85994e2009-07-01 19:21:24 +01001028 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -04001029 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 +08001030 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +01001031 /* Someone else set it while we were thinking; use theirs. */
1032 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +08001033 else
David Woodhousec85994e2009-07-01 19:21:24 +01001034 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001035 }
David Woodhouse5cf0a762014-03-19 16:07:49 +00001036 if (level == 1)
1037 break;
1038
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001039 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001040 level--;
1041 }
1042
David Woodhouse5cf0a762014-03-19 16:07:49 +00001043 if (!*target_level)
1044 *target_level = level;
1045
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001046 return pte;
1047}
1048
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001049
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001050/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +01001051static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
1052 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001053 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001054{
1055 struct dma_pte *parent, *pte = NULL;
1056 int total = agaw_to_level(domain->agaw);
1057 int offset;
1058
1059 parent = domain->pgd;
1060 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +01001061 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001062 pte = &parent[offset];
1063 if (level == total)
1064 return pte;
1065
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001066 if (!dma_pte_present(pte)) {
1067 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001068 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001069 }
1070
Yijing Wange16922a2014-05-20 20:37:51 +08001071 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001072 *large_page = total;
1073 return pte;
1074 }
1075
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001076 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001077 total--;
1078 }
1079 return NULL;
1080}
1081
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001082/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +00001083static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf2009-06-27 22:09:11 +01001084 unsigned long start_pfn,
1085 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001086{
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001087 unsigned int large_page = 1;
David Woodhouse310a5ab2009-06-28 18:52:20 +01001088 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001089
Jiang Liu162d1b12014-07-11 14:19:35 +08001090 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1091 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001092 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001093
David Woodhouse04b18e62009-06-27 19:15:01 +01001094 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001095 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001096 large_page = 1;
1097 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001098 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001099 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001100 continue;
1101 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001102 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001103 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001104 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001105 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001106 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1107
David Woodhouse310a5ab2009-06-28 18:52:20 +01001108 domain_flush_cache(domain, first_pte,
1109 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001110
1111 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001112}
1113
Alex Williamson3269ee02013-06-15 10:27:19 -06001114static void dma_pte_free_level(struct dmar_domain *domain, int level,
1115 struct dma_pte *pte, unsigned long pfn,
1116 unsigned long start_pfn, unsigned long last_pfn)
1117{
1118 pfn = max(start_pfn, pfn);
1119 pte = &pte[pfn_level_offset(pfn, level)];
1120
1121 do {
1122 unsigned long level_pfn;
1123 struct dma_pte *level_pte;
1124
1125 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1126 goto next;
1127
David Dillowf7116e12017-01-30 19:11:11 -08001128 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001129 level_pte = phys_to_virt(dma_pte_addr(pte));
1130
1131 if (level > 2)
1132 dma_pte_free_level(domain, level - 1, level_pte,
1133 level_pfn, start_pfn, last_pfn);
1134
1135 /* If range covers entire pagetable, free it */
1136 if (!(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001137 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001138 dma_clear_pte(pte);
1139 domain_flush_cache(domain, pte, sizeof(*pte));
1140 free_pgtable_page(level_pte);
1141 }
1142next:
1143 pfn += level_size(level);
1144 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1145}
1146
Michael S. Tsirkin3d1a2442016-03-23 20:34:19 +02001147/* clear last level (leaf) ptes and free page table pages. */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001148static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001149 unsigned long start_pfn,
1150 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001151{
Jiang Liu162d1b12014-07-11 14:19:35 +08001152 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1153 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001154 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001155
Jiang Liud41a4ad2014-07-11 14:19:34 +08001156 dma_pte_clear_range(domain, start_pfn, last_pfn);
1157
David Woodhousef3a0a522009-06-30 03:40:07 +01001158 /* We don't need lock here; nobody else touches the iova range */
Alex Williamson3269ee02013-06-15 10:27:19 -06001159 dma_pte_free_level(domain, agaw_to_level(domain->agaw),
1160 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001161
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001162 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001163 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001164 free_pgtable_page(domain->pgd);
1165 domain->pgd = NULL;
1166 }
1167}
1168
David Woodhouseea8ea462014-03-05 17:09:32 +00001169/* When a page at a given level is being unlinked from its parent, we don't
1170 need to *modify* it at all. All we need to do is make a list of all the
1171 pages which can be freed just as soon as we've flushed the IOTLB and we
1172 know the hardware page-walk will no longer touch them.
1173 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1174 be freed. */
1175static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1176 int level, struct dma_pte *pte,
1177 struct page *freelist)
1178{
1179 struct page *pg;
1180
1181 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1182 pg->freelist = freelist;
1183 freelist = pg;
1184
1185 if (level == 1)
1186 return freelist;
1187
Jiang Liuadeb2592014-04-09 10:20:39 +08001188 pte = page_address(pg);
1189 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001190 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1191 freelist = dma_pte_list_pagetables(domain, level - 1,
1192 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001193 pte++;
1194 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001195
1196 return freelist;
1197}
1198
1199static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1200 struct dma_pte *pte, unsigned long pfn,
1201 unsigned long start_pfn,
1202 unsigned long last_pfn,
1203 struct page *freelist)
1204{
1205 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1206
1207 pfn = max(start_pfn, pfn);
1208 pte = &pte[pfn_level_offset(pfn, level)];
1209
1210 do {
1211 unsigned long level_pfn;
1212
1213 if (!dma_pte_present(pte))
1214 goto next;
1215
1216 level_pfn = pfn & level_mask(level);
1217
1218 /* If range covers entire pagetable, free it */
1219 if (start_pfn <= level_pfn &&
1220 last_pfn >= level_pfn + level_size(level) - 1) {
1221 /* These suborbinate page tables are going away entirely. Don't
1222 bother to clear them; we're just going to *free* them. */
1223 if (level > 1 && !dma_pte_superpage(pte))
1224 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1225
1226 dma_clear_pte(pte);
1227 if (!first_pte)
1228 first_pte = pte;
1229 last_pte = pte;
1230 } else if (level > 1) {
1231 /* Recurse down into a level that isn't *entirely* obsolete */
1232 freelist = dma_pte_clear_level(domain, level - 1,
1233 phys_to_virt(dma_pte_addr(pte)),
1234 level_pfn, start_pfn, last_pfn,
1235 freelist);
1236 }
1237next:
1238 pfn += level_size(level);
1239 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1240
1241 if (first_pte)
1242 domain_flush_cache(domain, first_pte,
1243 (void *)++last_pte - (void *)first_pte);
1244
1245 return freelist;
1246}
1247
1248/* We can't just free the pages because the IOMMU may still be walking
1249 the page tables, and may have cached the intermediate levels. The
1250 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001251static struct page *domain_unmap(struct dmar_domain *domain,
1252 unsigned long start_pfn,
1253 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001254{
David Woodhouseea8ea462014-03-05 17:09:32 +00001255 struct page *freelist = NULL;
1256
Jiang Liu162d1b12014-07-11 14:19:35 +08001257 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1258 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001259 BUG_ON(start_pfn > last_pfn);
1260
1261 /* we don't need lock here; nobody else touches the iova range */
1262 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1263 domain->pgd, 0, start_pfn, last_pfn, NULL);
1264
1265 /* free pgd */
1266 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1267 struct page *pgd_page = virt_to_page(domain->pgd);
1268 pgd_page->freelist = freelist;
1269 freelist = pgd_page;
1270
1271 domain->pgd = NULL;
1272 }
1273
1274 return freelist;
1275}
1276
Joerg Roedelb6904202015-08-13 11:32:18 +02001277static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001278{
1279 struct page *pg;
1280
1281 while ((pg = freelist)) {
1282 freelist = pg->freelist;
1283 free_pgtable_page(page_address(pg));
1284 }
1285}
1286
Joerg Roedel13cf0172017-08-11 11:40:10 +02001287static void iova_entry_free(unsigned long data)
1288{
1289 struct page *freelist = (struct page *)data;
1290
1291 dma_free_pagelist(freelist);
1292}
1293
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001294/* iommu handling */
1295static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1296{
1297 struct root_entry *root;
1298 unsigned long flags;
1299
Suresh Siddha4c923d42009-10-02 11:01:24 -07001300 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001301 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001302 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001303 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001304 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001305 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001306
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001307 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001308
1309 spin_lock_irqsave(&iommu->lock, flags);
1310 iommu->root_entry = root;
1311 spin_unlock_irqrestore(&iommu->lock, flags);
1312
1313 return 0;
1314}
1315
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001316static void iommu_set_root_entry(struct intel_iommu *iommu)
1317{
David Woodhouse03ecc322015-02-13 14:35:21 +00001318 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001319 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001320 unsigned long flag;
1321
David Woodhouse03ecc322015-02-13 14:35:21 +00001322 addr = virt_to_phys(iommu->root_entry);
David Woodhousec83b2f22015-06-12 10:15:49 +01001323 if (ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +00001324 addr |= DMA_RTADDR_RTT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001325
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001326 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001327 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001328
David Woodhousec416daa2009-05-10 20:30:58 +01001329 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001330
1331 /* Make sure hardware complete it */
1332 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001333 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001334
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001335 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001336}
1337
1338static void iommu_flush_write_buffer(struct intel_iommu *iommu)
1339{
1340 u32 val;
1341 unsigned long flag;
1342
David Woodhouse9af88142009-02-13 23:18:03 +00001343 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001344 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001345
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001346 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001347 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001348
1349 /* Make sure hardware complete it */
1350 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001351 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001352
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001353 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001354}
1355
1356/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001357static void __iommu_flush_context(struct intel_iommu *iommu,
1358 u16 did, u16 source_id, u8 function_mask,
1359 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001360{
1361 u64 val = 0;
1362 unsigned long flag;
1363
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001364 switch (type) {
1365 case DMA_CCMD_GLOBAL_INVL:
1366 val = DMA_CCMD_GLOBAL_INVL;
1367 break;
1368 case DMA_CCMD_DOMAIN_INVL:
1369 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1370 break;
1371 case DMA_CCMD_DEVICE_INVL:
1372 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1373 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1374 break;
1375 default:
1376 BUG();
1377 }
1378 val |= DMA_CCMD_ICC;
1379
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001380 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001381 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1382
1383 /* Make sure hardware complete it */
1384 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1385 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1386
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001387 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001388}
1389
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001390/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001391static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1392 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001393{
1394 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1395 u64 val = 0, val_iva = 0;
1396 unsigned long flag;
1397
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001398 switch (type) {
1399 case DMA_TLB_GLOBAL_FLUSH:
1400 /* global flush doesn't need set IVA_REG */
1401 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1402 break;
1403 case DMA_TLB_DSI_FLUSH:
1404 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1405 break;
1406 case DMA_TLB_PSI_FLUSH:
1407 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001408 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001409 val_iva = size_order | addr;
1410 break;
1411 default:
1412 BUG();
1413 }
1414 /* Note: set drain read/write */
1415#if 0
1416 /*
1417 * This is probably to be super secure.. Looks like we can
1418 * ignore it without any impact.
1419 */
1420 if (cap_read_drain(iommu->cap))
1421 val |= DMA_TLB_READ_DRAIN;
1422#endif
1423 if (cap_write_drain(iommu->cap))
1424 val |= DMA_TLB_WRITE_DRAIN;
1425
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001426 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001427 /* Note: Only uses first TLB reg currently */
1428 if (val_iva)
1429 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1430 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1431
1432 /* Make sure hardware complete it */
1433 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1434 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1435
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001436 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001437
1438 /* check IOTLB invalidation granularity */
1439 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001440 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001441 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001442 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001443 (unsigned long long)DMA_TLB_IIRG(type),
1444 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001445}
1446
David Woodhouse64ae8922014-03-09 12:52:30 -07001447static struct device_domain_info *
1448iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1449 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001450{
Yu Zhao93a23a72009-05-18 13:51:37 +08001451 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001452
Joerg Roedel55d94042015-07-22 16:50:40 +02001453 assert_spin_locked(&device_domain_lock);
1454
Yu Zhao93a23a72009-05-18 13:51:37 +08001455 if (!iommu->qi)
1456 return NULL;
1457
Yu Zhao93a23a72009-05-18 13:51:37 +08001458 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001459 if (info->iommu == iommu && info->bus == bus &&
1460 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001461 if (info->ats_supported && info->dev)
1462 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001463 break;
1464 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001465
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001466 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001467}
1468
Omer Peleg0824c592016-04-20 19:03:35 +03001469static void domain_update_iotlb(struct dmar_domain *domain)
1470{
1471 struct device_domain_info *info;
1472 bool has_iotlb_device = false;
1473
1474 assert_spin_locked(&device_domain_lock);
1475
1476 list_for_each_entry(info, &domain->devices, link) {
1477 struct pci_dev *pdev;
1478
1479 if (!info->dev || !dev_is_pci(info->dev))
1480 continue;
1481
1482 pdev = to_pci_dev(info->dev);
1483 if (pdev->ats_enabled) {
1484 has_iotlb_device = true;
1485 break;
1486 }
1487 }
1488
1489 domain->has_iotlb_device = has_iotlb_device;
1490}
1491
Yu Zhao93a23a72009-05-18 13:51:37 +08001492static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1493{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001494 struct pci_dev *pdev;
1495
Omer Peleg0824c592016-04-20 19:03:35 +03001496 assert_spin_locked(&device_domain_lock);
1497
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001498 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001499 return;
1500
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001501 pdev = to_pci_dev(info->dev);
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001502
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001503#ifdef CONFIG_INTEL_IOMMU_SVM
1504 /* The PCIe spec, in its wisdom, declares that the behaviour of
1505 the device if you enable PASID support after ATS support is
1506 undefined. So always enable PASID support on devices which
1507 have it, even if we can't yet know if we're ever going to
1508 use it. */
1509 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1510 info->pasid_enabled = 1;
1511
1512 if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
1513 info->pri_enabled = 1;
1514#endif
1515 if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
1516 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001517 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001518 info->ats_qdep = pci_ats_queue_depth(pdev);
1519 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001520}
1521
1522static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1523{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001524 struct pci_dev *pdev;
1525
Omer Peleg0824c592016-04-20 19:03:35 +03001526 assert_spin_locked(&device_domain_lock);
1527
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001528 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001529 return;
1530
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001531 pdev = to_pci_dev(info->dev);
1532
1533 if (info->ats_enabled) {
1534 pci_disable_ats(pdev);
1535 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001536 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001537 }
1538#ifdef CONFIG_INTEL_IOMMU_SVM
1539 if (info->pri_enabled) {
1540 pci_disable_pri(pdev);
1541 info->pri_enabled = 0;
1542 }
1543 if (info->pasid_enabled) {
1544 pci_disable_pasid(pdev);
1545 info->pasid_enabled = 0;
1546 }
1547#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001548}
1549
1550static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1551 u64 addr, unsigned mask)
1552{
1553 u16 sid, qdep;
1554 unsigned long flags;
1555 struct device_domain_info *info;
1556
Omer Peleg0824c592016-04-20 19:03:35 +03001557 if (!domain->has_iotlb_device)
1558 return;
1559
Yu Zhao93a23a72009-05-18 13:51:37 +08001560 spin_lock_irqsave(&device_domain_lock, flags);
1561 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001562 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001563 continue;
1564
1565 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001566 qdep = info->ats_qdep;
Yu Zhao93a23a72009-05-18 13:51:37 +08001567 qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
1568 }
1569 spin_unlock_irqrestore(&device_domain_lock, flags);
1570}
1571
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001572static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1573 struct dmar_domain *domain,
1574 unsigned long pfn, unsigned int pages,
1575 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001576{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001577 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001578 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001579 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001580
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001581 BUG_ON(pages == 0);
1582
David Woodhouseea8ea462014-03-05 17:09:32 +00001583 if (ih)
1584 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001585 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001586 * Fallback to domain selective flush if no PSI support or the size is
1587 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001588 * PSI requires page size to be 2 ^ x, and the base address is naturally
1589 * aligned to the size
1590 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001591 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1592 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001593 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001594 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001595 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001596 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001597
1598 /*
Nadav Amit82653632010-04-01 13:24:40 +03001599 * In caching mode, changes of pages from non-present to present require
1600 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001601 */
Nadav Amit82653632010-04-01 13:24:40 +03001602 if (!cap_caching_mode(iommu->cap) || !map)
Joerg Roedel9452d5b2015-07-21 10:00:56 +02001603 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1604 addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001605}
1606
Joerg Roedel13cf0172017-08-11 11:40:10 +02001607static void iommu_flush_iova(struct iova_domain *iovad)
1608{
1609 struct dmar_domain *domain;
1610 int idx;
1611
1612 domain = container_of(iovad, struct dmar_domain, iovad);
1613
1614 for_each_domain_iommu(idx, domain) {
1615 struct intel_iommu *iommu = g_iommus[idx];
1616 u16 did = domain->iommu_did[iommu->seq_id];
1617
1618 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1619
1620 if (!cap_caching_mode(iommu->cap))
1621 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1622 0, MAX_AGAW_PFN_WIDTH);
1623 }
1624}
1625
mark grossf8bab732008-02-08 04:18:38 -08001626static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1627{
1628 u32 pmen;
1629 unsigned long flags;
1630
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001631 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001632 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1633 pmen &= ~DMA_PMEN_EPM;
1634 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1635
1636 /* wait for the protected region status bit to clear */
1637 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1638 readl, !(pmen & DMA_PMEN_PRS), pmen);
1639
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001640 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001641}
1642
Jiang Liu2a41cce2014-07-11 14:19:33 +08001643static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001644{
1645 u32 sts;
1646 unsigned long flags;
1647
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001648 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001649 iommu->gcmd |= DMA_GCMD_TE;
1650 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001651
1652 /* Make sure hardware complete it */
1653 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001654 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001655
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001656 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001657}
1658
Jiang Liu2a41cce2014-07-11 14:19:33 +08001659static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001660{
1661 u32 sts;
1662 unsigned long flag;
1663
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001664 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001665 iommu->gcmd &= ~DMA_GCMD_TE;
1666 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1667
1668 /* Make sure hardware complete it */
1669 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001670 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001671
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001672 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001673}
1674
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001675
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001676static int iommu_init_domains(struct intel_iommu *iommu)
1677{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001678 u32 ndomains, nlongs;
1679 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001680
1681 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001682 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001683 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001684 nlongs = BITS_TO_LONGS(ndomains);
1685
Donald Dutile94a91b52009-08-20 16:51:34 -04001686 spin_lock_init(&iommu->lock);
1687
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001688 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1689 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001690 pr_err("%s: Allocating domain id array failed\n",
1691 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001692 return -ENOMEM;
1693 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001694
Wei Yang86f004c2016-05-21 02:41:51 +00001695 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001696 iommu->domains = kzalloc(size, GFP_KERNEL);
1697
1698 if (iommu->domains) {
1699 size = 256 * sizeof(struct dmar_domain *);
1700 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1701 }
1702
1703 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001704 pr_err("%s: Allocating domain array failed\n",
1705 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001706 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001707 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001708 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001709 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001710 return -ENOMEM;
1711 }
1712
Joerg Roedel8bf47812015-07-21 10:41:21 +02001713
1714
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001715 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001716 * If Caching mode is set, then invalid translations are tagged
1717 * with domain-id 0, hence we need to pre-allocate it. We also
1718 * use domain-id 0 as a marker for non-allocated domain-id, so
1719 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001720 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001721 set_bit(0, iommu->domain_ids);
1722
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001723 return 0;
1724}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001725
Jiang Liuffebeb42014-11-09 22:48:02 +08001726static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001727{
Joerg Roedel29a27712015-07-21 17:17:12 +02001728 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001729 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001730
Joerg Roedel29a27712015-07-21 17:17:12 +02001731 if (!iommu->domains || !iommu->domain_ids)
1732 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001733
Joerg Roedelbea64032016-11-08 15:08:26 +01001734again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001735 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001736 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1737 struct dmar_domain *domain;
1738
1739 if (info->iommu != iommu)
1740 continue;
1741
1742 if (!info->dev || !info->domain)
1743 continue;
1744
1745 domain = info->domain;
1746
Joerg Roedelbea64032016-11-08 15:08:26 +01001747 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001748
Joerg Roedelbea64032016-11-08 15:08:26 +01001749 if (!domain_type_is_vm_or_si(domain)) {
1750 /*
1751 * The domain_exit() function can't be called under
1752 * device_domain_lock, as it takes this lock itself.
1753 * So release the lock here and re-run the loop
1754 * afterwards.
1755 */
1756 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001757 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001758 goto again;
1759 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001760 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001761 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001762
1763 if (iommu->gcmd & DMA_GCMD_TE)
1764 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001765}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001766
Jiang Liuffebeb42014-11-09 22:48:02 +08001767static void free_dmar_iommu(struct intel_iommu *iommu)
1768{
1769 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001770 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001771 int i;
1772
1773 for (i = 0; i < elems; i++)
1774 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001775 kfree(iommu->domains);
1776 kfree(iommu->domain_ids);
1777 iommu->domains = NULL;
1778 iommu->domain_ids = NULL;
1779 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001780
Weidong Hand9630fe2008-12-08 11:06:32 +08001781 g_iommus[iommu->seq_id] = NULL;
1782
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001783 /* free context mapping */
1784 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001785
1786#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001787 if (pasid_enabled(iommu)) {
1788 if (ecap_prs(iommu->ecap))
1789 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001790 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001791 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001792#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001793}
1794
Jiang Liuab8dfe22014-07-11 14:19:27 +08001795static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001796{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001797 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001798
1799 domain = alloc_domain_mem();
1800 if (!domain)
1801 return NULL;
1802
Jiang Liuab8dfe22014-07-11 14:19:27 +08001803 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001804 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001805 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001806 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001807 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001808
1809 return domain;
1810}
1811
Joerg Roedeld160aca2015-07-22 11:52:53 +02001812/* Must be called with iommu->lock */
1813static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001814 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001815{
Jiang Liu44bde612014-07-11 14:19:29 +08001816 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001817 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001818
Joerg Roedel55d94042015-07-22 16:50:40 +02001819 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001820 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001821
Joerg Roedel29a27712015-07-21 17:17:12 +02001822 domain->iommu_refcnt[iommu->seq_id] += 1;
1823 domain->iommu_count += 1;
1824 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001825 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001826 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1827
1828 if (num >= ndomains) {
1829 pr_err("%s: No free domain ids\n", iommu->name);
1830 domain->iommu_refcnt[iommu->seq_id] -= 1;
1831 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001832 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001833 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001834
Joerg Roedeld160aca2015-07-22 11:52:53 +02001835 set_bit(num, iommu->domain_ids);
1836 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001837
Joerg Roedeld160aca2015-07-22 11:52:53 +02001838 domain->iommu_did[iommu->seq_id] = num;
1839 domain->nid = iommu->node;
1840
Jiang Liufb170fb2014-07-11 14:19:28 +08001841 domain_update_iommu_cap(domain);
1842 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001843
Joerg Roedel55d94042015-07-22 16:50:40 +02001844 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001845}
1846
1847static int domain_detach_iommu(struct dmar_domain *domain,
1848 struct intel_iommu *iommu)
1849{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001850 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001851
Joerg Roedel55d94042015-07-22 16:50:40 +02001852 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001853 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001854
Joerg Roedel29a27712015-07-21 17:17:12 +02001855 domain->iommu_refcnt[iommu->seq_id] -= 1;
1856 count = --domain->iommu_count;
1857 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001858 num = domain->iommu_did[iommu->seq_id];
1859 clear_bit(num, iommu->domain_ids);
1860 set_iommu_domain(iommu, num, NULL);
1861
Jiang Liufb170fb2014-07-11 14:19:28 +08001862 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001863 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001864 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001865
1866 return count;
1867}
1868
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001869static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001870static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001871
Joseph Cihula51a63e62011-03-21 11:04:24 -07001872static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001873{
1874 struct pci_dev *pdev = NULL;
1875 struct iova *iova;
1876 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001877
Robin Murphy0fb5fe82015-01-12 17:51:16 +00001878 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN,
1879 DMA_32BIT_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001880
Mark Gross8a443df2008-03-04 14:59:31 -08001881 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1882 &reserved_rbtree_key);
1883
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001884 /* IOAPIC ranges shouldn't be accessed by DMA */
1885 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1886 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001887 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001888 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001889 return -ENODEV;
1890 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001891
1892 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1893 for_each_pci_dev(pdev) {
1894 struct resource *r;
1895
1896 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1897 r = &pdev->resource[i];
1898 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1899 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001900 iova = reserve_iova(&reserved_iova_list,
1901 IOVA_PFN(r->start),
1902 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001903 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001904 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001905 return -ENODEV;
1906 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001907 }
1908 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001909 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001910}
1911
1912static void domain_reserve_special_ranges(struct dmar_domain *domain)
1913{
1914 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1915}
1916
1917static inline int guestwidth_to_adjustwidth(int gaw)
1918{
1919 int agaw;
1920 int r = (gaw - 12) % 9;
1921
1922 if (r == 0)
1923 agaw = gaw;
1924 else
1925 agaw = gaw + 9 - r;
1926 if (agaw > 64)
1927 agaw = 64;
1928 return agaw;
1929}
1930
Joerg Roedeldc534b22015-07-22 12:44:02 +02001931static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1932 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001933{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001934 int adjust_width, agaw;
1935 unsigned long sagaw;
Joerg Roedel13cf0172017-08-11 11:40:10 +02001936 int err;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001937
Robin Murphy0fb5fe82015-01-12 17:51:16 +00001938 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
1939 DMA_32BIT_PFN);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001940
1941 err = init_iova_flush_queue(&domain->iovad,
1942 iommu_flush_iova, iova_entry_free);
1943 if (err)
1944 return err;
1945
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001946 domain_reserve_special_ranges(domain);
1947
1948 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001949 if (guest_width > cap_mgaw(iommu->cap))
1950 guest_width = cap_mgaw(iommu->cap);
1951 domain->gaw = guest_width;
1952 adjust_width = guestwidth_to_adjustwidth(guest_width);
1953 agaw = width_to_agaw(adjust_width);
1954 sagaw = cap_sagaw(iommu->cap);
1955 if (!test_bit(agaw, &sagaw)) {
1956 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001957 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001958 agaw = find_next_bit(&sagaw, 5, agaw);
1959 if (agaw >= 5)
1960 return -ENODEV;
1961 }
1962 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001963
Weidong Han8e6040972008-12-08 15:49:06 +08001964 if (ecap_coherent(iommu->ecap))
1965 domain->iommu_coherency = 1;
1966 else
1967 domain->iommu_coherency = 0;
1968
Sheng Yang58c610b2009-03-18 15:33:05 +08001969 if (ecap_sc_support(iommu->ecap))
1970 domain->iommu_snooping = 1;
1971 else
1972 domain->iommu_snooping = 0;
1973
David Woodhouse214e39a2014-03-19 10:38:49 +00001974 if (intel_iommu_superpage)
1975 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1976 else
1977 domain->iommu_superpage = 0;
1978
Suresh Siddha4c923d42009-10-02 11:01:24 -07001979 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001980
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001981 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001982 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001983 if (!domain->pgd)
1984 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001985 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001986 return 0;
1987}
1988
1989static void domain_exit(struct dmar_domain *domain)
1990{
David Woodhouseea8ea462014-03-05 17:09:32 +00001991 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001992
1993 /* Domain 0 is reserved, so dont process it */
1994 if (!domain)
1995 return;
1996
Joerg Roedeld160aca2015-07-22 11:52:53 +02001997 /* Remove associated devices and clear attached or cached domains */
1998 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001999 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02002000 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08002001
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002002 /* destroy iovas */
2003 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002004
David Woodhouseea8ea462014-03-05 17:09:32 +00002005 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002006
David Woodhouseea8ea462014-03-05 17:09:32 +00002007 dma_free_pagelist(freelist);
2008
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002009 free_domain_mem(domain);
2010}
2011
David Woodhouse64ae8922014-03-09 12:52:30 -07002012static int domain_context_mapping_one(struct dmar_domain *domain,
2013 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002014 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002015{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002016 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002017 int translation = CONTEXT_TT_MULTI_LEVEL;
2018 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002019 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002020 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002021 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002022 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002023
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002024 WARN_ON(did == 0);
2025
Joerg Roedel28ccce02015-07-21 14:45:31 +02002026 if (hw_pass_through && domain_type_is_si(domain))
2027 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002028
2029 pr_debug("Set context mapping for %02x:%02x.%d\n",
2030 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002031
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002032 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002033
Joerg Roedel55d94042015-07-22 16:50:40 +02002034 spin_lock_irqsave(&device_domain_lock, flags);
2035 spin_lock(&iommu->lock);
2036
2037 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002038 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002039 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002040 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002041
Joerg Roedel55d94042015-07-22 16:50:40 +02002042 ret = 0;
2043 if (context_present(context))
2044 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002045
Xunlei Pangaec0e862016-12-05 20:09:07 +08002046 /*
2047 * For kdump cases, old valid entries may be cached due to the
2048 * in-flight DMA and copied pgtable, but there is no unmapping
2049 * behaviour for them, thus we need an explicit cache flush for
2050 * the newly-mapped device. For kdump, at this point, the device
2051 * is supposed to finish reset at its driver probe stage, so no
2052 * in-flight DMA will exist, and we don't need to worry anymore
2053 * hereafter.
2054 */
2055 if (context_copied(context)) {
2056 u16 did_old = context_domain_id(context);
2057
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002058 if (did_old >= 0 && did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002059 iommu->flush.flush_context(iommu, did_old,
2060 (((u16)bus) << 8) | devfn,
2061 DMA_CCMD_MASK_NOBIT,
2062 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002063 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2064 DMA_TLB_DSI_FLUSH);
2065 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002066 }
2067
Weidong Hanea6606b2008-12-08 23:08:15 +08002068 pgd = domain->pgd;
2069
Joerg Roedelde24e552015-07-21 14:53:04 +02002070 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002071 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002072
Joerg Roedelde24e552015-07-21 14:53:04 +02002073 /*
2074 * Skip top levels of page tables for iommu which has less agaw
2075 * than default. Unnecessary for PT mode.
2076 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002077 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002078 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002079 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002080 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002081 if (!dma_pte_present(pgd))
2082 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002083 }
2084
David Woodhouse64ae8922014-03-09 12:52:30 -07002085 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002086 if (info && info->ats_supported)
2087 translation = CONTEXT_TT_DEV_IOTLB;
2088 else
2089 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002090
Yu Zhao93a23a72009-05-18 13:51:37 +08002091 context_set_address_root(context, virt_to_phys(pgd));
2092 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002093 } else {
2094 /*
2095 * In pass through mode, AW must be programmed to
2096 * indicate the largest AGAW value supported by
2097 * hardware. And ASR is ignored by hardware.
2098 */
2099 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002100 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002101
2102 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002103 context_set_fault_enable(context);
2104 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002105 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002106
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002107 /*
2108 * It's a non-present to present mapping. If hardware doesn't cache
2109 * non-present entry we only need to flush the write-buffer. If the
2110 * _does_ cache non-present entries, then it does so in the special
2111 * domain #0, which we have to flush:
2112 */
2113 if (cap_caching_mode(iommu->cap)) {
2114 iommu->flush.flush_context(iommu, 0,
2115 (((u16)bus) << 8) | devfn,
2116 DMA_CCMD_MASK_NOBIT,
2117 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002118 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002119 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002120 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002121 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002122 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002123
Joerg Roedel55d94042015-07-22 16:50:40 +02002124 ret = 0;
2125
2126out_unlock:
2127 spin_unlock(&iommu->lock);
2128 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002129
Wei Yang5c365d12016-07-13 13:53:21 +00002130 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002131}
2132
Alex Williamson579305f2014-07-03 09:51:43 -06002133struct domain_context_mapping_data {
2134 struct dmar_domain *domain;
2135 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002136};
2137
2138static int domain_context_mapping_cb(struct pci_dev *pdev,
2139 u16 alias, void *opaque)
2140{
2141 struct domain_context_mapping_data *data = opaque;
2142
2143 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002144 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002145}
2146
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002147static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002148domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002149{
David Woodhouse64ae8922014-03-09 12:52:30 -07002150 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002151 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002152 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002153
David Woodhousee1f167f2014-03-09 15:24:46 -07002154 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002155 if (!iommu)
2156 return -ENODEV;
2157
Alex Williamson579305f2014-07-03 09:51:43 -06002158 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002159 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002160
2161 data.domain = domain;
2162 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002163
2164 return pci_for_each_dma_alias(to_pci_dev(dev),
2165 &domain_context_mapping_cb, &data);
2166}
2167
2168static int domain_context_mapped_cb(struct pci_dev *pdev,
2169 u16 alias, void *opaque)
2170{
2171 struct intel_iommu *iommu = opaque;
2172
2173 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002174}
2175
David Woodhousee1f167f2014-03-09 15:24:46 -07002176static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002177{
Weidong Han5331fe62008-12-08 23:00:00 +08002178 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002179 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002180
David Woodhousee1f167f2014-03-09 15:24:46 -07002181 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002182 if (!iommu)
2183 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002184
Alex Williamson579305f2014-07-03 09:51:43 -06002185 if (!dev_is_pci(dev))
2186 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002187
Alex Williamson579305f2014-07-03 09:51:43 -06002188 return !pci_for_each_dma_alias(to_pci_dev(dev),
2189 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002190}
2191
Fenghua Yuf5329592009-08-04 15:09:37 -07002192/* Returns a number of VTD pages, but aligned to MM page size */
2193static inline unsigned long aligned_nrpages(unsigned long host_addr,
2194 size_t size)
2195{
2196 host_addr &= ~PAGE_MASK;
2197 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2198}
2199
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002200/* Return largest possible superpage level for a given mapping */
2201static inline int hardware_largepage_caps(struct dmar_domain *domain,
2202 unsigned long iov_pfn,
2203 unsigned long phy_pfn,
2204 unsigned long pages)
2205{
2206 int support, level = 1;
2207 unsigned long pfnmerge;
2208
2209 support = domain->iommu_superpage;
2210
2211 /* To use a large page, the virtual *and* physical addresses
2212 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2213 of them will mean we have to use smaller pages. So just
2214 merge them and check both at once. */
2215 pfnmerge = iov_pfn | phy_pfn;
2216
2217 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2218 pages >>= VTD_STRIDE_SHIFT;
2219 if (!pages)
2220 break;
2221 pfnmerge >>= VTD_STRIDE_SHIFT;
2222 level++;
2223 support--;
2224 }
2225 return level;
2226}
2227
David Woodhouse9051aa02009-06-29 12:30:54 +01002228static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2229 struct scatterlist *sg, unsigned long phys_pfn,
2230 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002231{
2232 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002233 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002234 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002235 unsigned int largepage_lvl = 0;
2236 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002237
Jiang Liu162d1b12014-07-11 14:19:35 +08002238 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002239
2240 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2241 return -EINVAL;
2242
2243 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2244
Jiang Liucc4f14a2014-11-26 09:42:10 +08002245 if (!sg) {
2246 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002247 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2248 }
2249
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002250 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002251 uint64_t tmp;
2252
David Woodhousee1605492009-06-29 11:17:38 +01002253 if (!sg_res) {
Fenghua Yuf5329592009-08-04 15:09:37 -07002254 sg_res = aligned_nrpages(sg->offset, sg->length);
David Woodhousee1605492009-06-29 11:17:38 +01002255 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
2256 sg->dma_length = sg->length;
Dan Williams3e6110f2015-12-15 12:54:06 -08002257 pteval = page_to_phys(sg_page(sg)) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002258 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002259 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002260
David Woodhousee1605492009-06-29 11:17:38 +01002261 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002262 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2263
David Woodhouse5cf0a762014-03-19 16:07:49 +00002264 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002265 if (!pte)
2266 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002267 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002268 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002269 unsigned long nr_superpages, end_pfn;
2270
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002271 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002272 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002273
2274 nr_superpages = sg_res / lvl_pages;
2275 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2276
Jiang Liud41a4ad2014-07-11 14:19:34 +08002277 /*
2278 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002279 * removed to make room for superpage(s).
Jiang Liud41a4ad2014-07-11 14:19:34 +08002280 */
Christian Zanderba2374f2015-06-10 09:41:45 -07002281 dma_pte_free_pagetable(domain, iov_pfn, end_pfn);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002282 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002283 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002284 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002285
David Woodhousee1605492009-06-29 11:17:38 +01002286 }
2287 /* We don't need lock here, nobody else
2288 * touches the iova range
2289 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002290 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002291 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002292 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002293 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2294 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002295 if (dumps) {
2296 dumps--;
2297 debug_dma_dump_mappings(NULL);
2298 }
2299 WARN_ON(1);
2300 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002301
2302 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2303
2304 BUG_ON(nr_pages < lvl_pages);
2305 BUG_ON(sg_res < lvl_pages);
2306
2307 nr_pages -= lvl_pages;
2308 iov_pfn += lvl_pages;
2309 phys_pfn += lvl_pages;
2310 pteval += lvl_pages * VTD_PAGE_SIZE;
2311 sg_res -= lvl_pages;
2312
2313 /* If the next PTE would be the first in a new page, then we
2314 need to flush the cache on the entries we've just written.
2315 And then we'll need to recalculate 'pte', so clear it and
2316 let it get set again in the if (!pte) block above.
2317
2318 If we're done (!nr_pages) we need to flush the cache too.
2319
2320 Also if we've been setting superpages, we may need to
2321 recalculate 'pte' and switch back to smaller pages for the
2322 end of the mapping, if the trailing size is not enough to
2323 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002324 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002325 if (!nr_pages || first_pte_in_page(pte) ||
2326 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002327 domain_flush_cache(domain, first_pte,
2328 (void *)pte - (void *)first_pte);
2329 pte = NULL;
2330 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002331
2332 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002333 sg = sg_next(sg);
2334 }
2335 return 0;
2336}
2337
David Woodhouse9051aa02009-06-29 12:30:54 +01002338static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2339 struct scatterlist *sg, unsigned long nr_pages,
2340 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002341{
David Woodhouse9051aa02009-06-29 12:30:54 +01002342 return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
2343}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002344
David Woodhouse9051aa02009-06-29 12:30:54 +01002345static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2346 unsigned long phys_pfn, unsigned long nr_pages,
2347 int prot)
2348{
2349 return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002350}
2351
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002352static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002353{
Weidong Hanc7151a82008-12-08 22:51:37 +08002354 if (!iommu)
2355 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002356
2357 clear_context_table(iommu, bus, devfn);
2358 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002359 DMA_CCMD_GLOBAL_INVL);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01002360 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002361}
2362
David Woodhouse109b9b02012-05-25 17:43:02 +01002363static inline void unlink_domain_info(struct device_domain_info *info)
2364{
2365 assert_spin_locked(&device_domain_lock);
2366 list_del(&info->link);
2367 list_del(&info->global);
2368 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002369 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002370}
2371
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002372static void domain_remove_dev_info(struct dmar_domain *domain)
2373{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002374 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002375 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002376
2377 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002378 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002379 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002380 spin_unlock_irqrestore(&device_domain_lock, flags);
2381}
2382
2383/*
2384 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002385 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002386 */
David Woodhouse1525a292014-03-06 16:19:30 +00002387static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002388{
2389 struct device_domain_info *info;
2390
2391 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002392 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002393 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002394 return info->domain;
2395 return NULL;
2396}
2397
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002398static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002399dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2400{
2401 struct device_domain_info *info;
2402
2403 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002404 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002405 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002406 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002407
2408 return NULL;
2409}
2410
Joerg Roedel5db31562015-07-22 12:40:43 +02002411static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2412 int bus, int devfn,
2413 struct device *dev,
2414 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002415{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002416 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002417 struct device_domain_info *info;
2418 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002419 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002420
2421 info = alloc_devinfo_mem();
2422 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002423 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002424
Jiang Liu745f2582014-02-19 14:07:26 +08002425 info->bus = bus;
2426 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002427 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2428 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2429 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002430 info->dev = dev;
2431 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002432 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002433
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002434 if (dev && dev_is_pci(dev)) {
2435 struct pci_dev *pdev = to_pci_dev(info->dev);
2436
2437 if (ecap_dev_iotlb_support(iommu->ecap) &&
2438 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2439 dmar_find_matched_atsr_unit(pdev))
2440 info->ats_supported = 1;
2441
2442 if (ecs_enabled(iommu)) {
2443 if (pasid_enabled(iommu)) {
2444 int features = pci_pasid_features(pdev);
2445 if (features >= 0)
2446 info->pasid_supported = features | 1;
2447 }
2448
2449 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2450 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2451 info->pri_supported = 1;
2452 }
2453 }
2454
Jiang Liu745f2582014-02-19 14:07:26 +08002455 spin_lock_irqsave(&device_domain_lock, flags);
2456 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002457 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002458
2459 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002460 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002461 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002462 if (info2) {
2463 found = info2->domain;
2464 info2->dev = dev;
2465 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002466 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002467
Jiang Liu745f2582014-02-19 14:07:26 +08002468 if (found) {
2469 spin_unlock_irqrestore(&device_domain_lock, flags);
2470 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002471 /* Caller must free the original domain */
2472 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002473 }
2474
Joerg Roedeld160aca2015-07-22 11:52:53 +02002475 spin_lock(&iommu->lock);
2476 ret = domain_attach_iommu(domain, iommu);
2477 spin_unlock(&iommu->lock);
2478
2479 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002480 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302481 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002482 return NULL;
2483 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002484
David Woodhouseb718cd32014-03-09 13:11:33 -07002485 list_add(&info->link, &domain->devices);
2486 list_add(&info->global, &device_domain_list);
2487 if (dev)
2488 dev->archdata.iommu = info;
2489 spin_unlock_irqrestore(&device_domain_lock, flags);
2490
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002491 if (dev && domain_context_mapping(domain, dev)) {
2492 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002493 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002494 return NULL;
2495 }
2496
David Woodhouseb718cd32014-03-09 13:11:33 -07002497 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002498}
2499
Alex Williamson579305f2014-07-03 09:51:43 -06002500static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2501{
2502 *(u16 *)opaque = alias;
2503 return 0;
2504}
2505
Joerg Roedel76208352016-08-25 14:25:12 +02002506static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002507{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002508 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002509 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002510 struct intel_iommu *iommu;
Joerg Roedel08a7f452015-07-23 18:09:11 +02002511 u16 req_id, dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002512 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002513 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002514
David Woodhouse146922e2014-03-09 15:44:17 -07002515 iommu = device_to_iommu(dev, &bus, &devfn);
2516 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002517 return NULL;
2518
Joerg Roedel08a7f452015-07-23 18:09:11 +02002519 req_id = ((u16)bus << 8) | devfn;
2520
Alex Williamson579305f2014-07-03 09:51:43 -06002521 if (dev_is_pci(dev)) {
2522 struct pci_dev *pdev = to_pci_dev(dev);
2523
2524 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2525
2526 spin_lock_irqsave(&device_domain_lock, flags);
2527 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2528 PCI_BUS_NUM(dma_alias),
2529 dma_alias & 0xff);
2530 if (info) {
2531 iommu = info->iommu;
2532 domain = info->domain;
2533 }
2534 spin_unlock_irqrestore(&device_domain_lock, flags);
2535
Joerg Roedel76208352016-08-25 14:25:12 +02002536 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002537 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002538 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002539 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002540
David Woodhouse146922e2014-03-09 15:44:17 -07002541 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002542 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002543 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002544 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002545 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002546 domain_exit(domain);
2547 return NULL;
2548 }
2549
Joerg Roedel76208352016-08-25 14:25:12 +02002550out:
Alex Williamson579305f2014-07-03 09:51:43 -06002551
Joerg Roedel76208352016-08-25 14:25:12 +02002552 return domain;
2553}
2554
2555static struct dmar_domain *set_domain_for_dev(struct device *dev,
2556 struct dmar_domain *domain)
2557{
2558 struct intel_iommu *iommu;
2559 struct dmar_domain *tmp;
2560 u16 req_id, dma_alias;
2561 u8 bus, devfn;
2562
2563 iommu = device_to_iommu(dev, &bus, &devfn);
2564 if (!iommu)
2565 return NULL;
2566
2567 req_id = ((u16)bus << 8) | devfn;
2568
2569 if (dev_is_pci(dev)) {
2570 struct pci_dev *pdev = to_pci_dev(dev);
2571
2572 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2573
2574 /* register PCI DMA alias device */
2575 if (req_id != dma_alias) {
2576 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2577 dma_alias & 0xff, NULL, domain);
2578
2579 if (!tmp || tmp != domain)
2580 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002581 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002582 }
2583
Joerg Roedel5db31562015-07-22 12:40:43 +02002584 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002585 if (!tmp || tmp != domain)
2586 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002587
Joerg Roedel76208352016-08-25 14:25:12 +02002588 return domain;
2589}
2590
2591static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2592{
2593 struct dmar_domain *domain, *tmp;
2594
2595 domain = find_domain(dev);
2596 if (domain)
2597 goto out;
2598
2599 domain = find_or_alloc_domain(dev, gaw);
2600 if (!domain)
2601 goto out;
2602
2603 tmp = set_domain_for_dev(dev, domain);
2604 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002605 domain_exit(domain);
2606 domain = tmp;
2607 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002608
Joerg Roedel76208352016-08-25 14:25:12 +02002609out:
2610
David Woodhouseb718cd32014-03-09 13:11:33 -07002611 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002612}
2613
David Woodhouseb2132032009-06-26 18:50:28 +01002614static int iommu_domain_identity_map(struct dmar_domain *domain,
2615 unsigned long long start,
2616 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002617{
David Woodhousec5395d52009-06-28 16:35:56 +01002618 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2619 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002620
David Woodhousec5395d52009-06-28 16:35:56 +01002621 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2622 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002623 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002624 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002625 }
2626
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002627 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002628 /*
2629 * RMRR range might have overlap with physical memory range,
2630 * clear it first
2631 */
David Woodhousec5395d52009-06-28 16:35:56 +01002632 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002633
David Woodhousec5395d52009-06-28 16:35:56 +01002634 return domain_pfn_mapping(domain, first_vpfn, first_vpfn,
2635 last_vpfn - first_vpfn + 1,
David Woodhouse61df7442009-06-28 11:55:58 +01002636 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002637}
2638
Joerg Roedeld66ce542015-09-23 19:00:10 +02002639static int domain_prepare_identity_map(struct device *dev,
2640 struct dmar_domain *domain,
2641 unsigned long long start,
2642 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002643{
David Woodhouse19943b02009-08-04 16:19:20 +01002644 /* For _hardware_ passthrough, don't bother. But for software
2645 passthrough, we do it anyway -- it may indicate a memory
2646 range which is reserved in E820, so which didn't get set
2647 up to start with in si_domain */
2648 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002649 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2650 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002651 return 0;
2652 }
2653
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002654 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2655 dev_name(dev), start, end);
2656
David Woodhouse5595b522009-12-02 09:21:55 +00002657 if (end < start) {
2658 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2659 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2660 dmi_get_system_info(DMI_BIOS_VENDOR),
2661 dmi_get_system_info(DMI_BIOS_VERSION),
2662 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002663 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002664 }
2665
David Woodhouse2ff729f2009-08-26 14:25:41 +01002666 if (end >> agaw_to_width(domain->agaw)) {
2667 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2668 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2669 agaw_to_width(domain->agaw),
2670 dmi_get_system_info(DMI_BIOS_VENDOR),
2671 dmi_get_system_info(DMI_BIOS_VERSION),
2672 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002673 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002674 }
David Woodhouse19943b02009-08-04 16:19:20 +01002675
Joerg Roedeld66ce542015-09-23 19:00:10 +02002676 return iommu_domain_identity_map(domain, start, end);
2677}
2678
2679static int iommu_prepare_identity_map(struct device *dev,
2680 unsigned long long start,
2681 unsigned long long end)
2682{
2683 struct dmar_domain *domain;
2684 int ret;
2685
2686 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2687 if (!domain)
2688 return -ENOMEM;
2689
2690 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002691 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002692 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002693
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002694 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002695}
2696
2697static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002698 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002699{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002700 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002701 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002702 return iommu_prepare_identity_map(dev, rmrr->base_address,
2703 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002704}
2705
Suresh Siddhad3f13812011-08-23 17:05:25 -07002706#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002707static inline void iommu_prepare_isa(void)
2708{
2709 struct pci_dev *pdev;
2710 int ret;
2711
2712 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2713 if (!pdev)
2714 return;
2715
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002716 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002717 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002718
2719 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002720 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002721
Yijing Wang9b27e822014-05-20 20:37:52 +08002722 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002723}
2724#else
2725static inline void iommu_prepare_isa(void)
2726{
2727 return;
2728}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002729#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002730
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002731static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002732
Matt Kraai071e1372009-08-23 22:30:22 -07002733static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002734{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002735 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002736
Jiang Liuab8dfe22014-07-11 14:19:27 +08002737 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002738 if (!si_domain)
2739 return -EFAULT;
2740
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002741 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2742 domain_exit(si_domain);
2743 return -EFAULT;
2744 }
2745
Joerg Roedel0dc79712015-07-21 15:40:06 +02002746 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002747
David Woodhouse19943b02009-08-04 16:19:20 +01002748 if (hw)
2749 return 0;
2750
David Woodhousec7ab48d2009-06-26 19:10:36 +01002751 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002752 unsigned long start_pfn, end_pfn;
2753 int i;
2754
2755 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2756 ret = iommu_domain_identity_map(si_domain,
2757 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2758 if (ret)
2759 return ret;
2760 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002761 }
2762
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002763 return 0;
2764}
2765
David Woodhouse9b226622014-03-09 14:03:28 -07002766static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002767{
2768 struct device_domain_info *info;
2769
2770 if (likely(!iommu_identity_mapping))
2771 return 0;
2772
David Woodhouse9b226622014-03-09 14:03:28 -07002773 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002774 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2775 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002776
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002777 return 0;
2778}
2779
Joerg Roedel28ccce02015-07-21 14:45:31 +02002780static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002781{
David Woodhouse0ac72662014-03-09 13:19:22 -07002782 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002783 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002784 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002785
David Woodhouse5913c9b2014-03-09 16:27:31 -07002786 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002787 if (!iommu)
2788 return -ENODEV;
2789
Joerg Roedel5db31562015-07-22 12:40:43 +02002790 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002791 if (ndomain != domain)
2792 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002793
2794 return 0;
2795}
2796
David Woodhouse0b9d9752014-03-09 15:48:15 -07002797static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002798{
2799 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002800 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002801 int i;
2802
Jiang Liu0e242612014-02-19 14:07:34 +08002803 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002804 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002805 /*
2806 * Return TRUE if this RMRR contains the device that
2807 * is passed in.
2808 */
2809 for_each_active_dev_scope(rmrr->devices,
2810 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002811 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002812 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002813 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002814 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002815 }
Jiang Liu0e242612014-02-19 14:07:34 +08002816 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002817 return false;
2818}
2819
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002820/*
2821 * There are a couple cases where we need to restrict the functionality of
2822 * devices associated with RMRRs. The first is when evaluating a device for
2823 * identity mapping because problems exist when devices are moved in and out
2824 * of domains and their respective RMRR information is lost. This means that
2825 * a device with associated RMRRs will never be in a "passthrough" domain.
2826 * The second is use of the device through the IOMMU API. This interface
2827 * expects to have full control of the IOVA space for the device. We cannot
2828 * satisfy both the requirement that RMRR access is maintained and have an
2829 * unencumbered IOVA space. We also have no ability to quiesce the device's
2830 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2831 * We therefore prevent devices associated with an RMRR from participating in
2832 * the IOMMU API, which eliminates them from device assignment.
2833 *
2834 * In both cases we assume that PCI USB devices with RMRRs have them largely
2835 * for historical reasons and that the RMRR space is not actively used post
2836 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002837 *
2838 * The same exception is made for graphics devices, with the requirement that
2839 * any use of the RMRR regions will be torn down before assigning the device
2840 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002841 */
2842static bool device_is_rmrr_locked(struct device *dev)
2843{
2844 if (!device_has_rmrr(dev))
2845 return false;
2846
2847 if (dev_is_pci(dev)) {
2848 struct pci_dev *pdev = to_pci_dev(dev);
2849
David Woodhouse18436af2015-03-25 15:05:47 +00002850 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002851 return false;
2852 }
2853
2854 return true;
2855}
2856
David Woodhouse3bdb2592014-03-09 16:03:08 -07002857static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002858{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002859
David Woodhouse3bdb2592014-03-09 16:03:08 -07002860 if (dev_is_pci(dev)) {
2861 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002862
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002863 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002864 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002865
David Woodhouse3bdb2592014-03-09 16:03:08 -07002866 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2867 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002868
David Woodhouse3bdb2592014-03-09 16:03:08 -07002869 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2870 return 1;
2871
2872 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2873 return 0;
2874
2875 /*
2876 * We want to start off with all devices in the 1:1 domain, and
2877 * take them out later if we find they can't access all of memory.
2878 *
2879 * However, we can't do this for PCI devices behind bridges,
2880 * because all PCI devices behind the same bridge will end up
2881 * with the same source-id on their transactions.
2882 *
2883 * Practically speaking, we can't change things around for these
2884 * devices at run-time, because we can't be sure there'll be no
2885 * DMA transactions in flight for any of their siblings.
2886 *
2887 * So PCI devices (unless they're on the root bus) as well as
2888 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2889 * the 1:1 domain, just in _case_ one of their siblings turns out
2890 * not to be able to map all of memory.
2891 */
2892 if (!pci_is_pcie(pdev)) {
2893 if (!pci_is_root_bus(pdev->bus))
2894 return 0;
2895 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2896 return 0;
2897 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2898 return 0;
2899 } else {
2900 if (device_has_rmrr(dev))
2901 return 0;
2902 }
David Woodhouse6941af22009-07-04 18:24:27 +01002903
David Woodhouse3dfc8132009-07-04 19:11:08 +01002904 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002905 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002906 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002907 * take them out of the 1:1 domain later.
2908 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002909 if (!startup) {
2910 /*
2911 * If the device's dma_mask is less than the system's memory
2912 * size then this is not a candidate for identity mapping.
2913 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002914 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002915
David Woodhouse3bdb2592014-03-09 16:03:08 -07002916 if (dev->coherent_dma_mask &&
2917 dev->coherent_dma_mask < dma_mask)
2918 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002919
David Woodhouse3bdb2592014-03-09 16:03:08 -07002920 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002921 }
David Woodhouse6941af22009-07-04 18:24:27 +01002922
2923 return 1;
2924}
2925
David Woodhousecf04eee2014-03-21 16:49:04 +00002926static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2927{
2928 int ret;
2929
2930 if (!iommu_should_identity_map(dev, 1))
2931 return 0;
2932
Joerg Roedel28ccce02015-07-21 14:45:31 +02002933 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002934 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002935 pr_info("%s identity mapping for device %s\n",
2936 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002937 else if (ret == -ENODEV)
2938 /* device not associated with an iommu */
2939 ret = 0;
2940
2941 return ret;
2942}
2943
2944
Matt Kraai071e1372009-08-23 22:30:22 -07002945static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002946{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002947 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002948 struct dmar_drhd_unit *drhd;
2949 struct intel_iommu *iommu;
2950 struct device *dev;
2951 int i;
2952 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002953
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002954 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002955 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2956 if (ret)
2957 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002958 }
2959
David Woodhousecf04eee2014-03-21 16:49:04 +00002960 for_each_active_iommu(iommu, drhd)
2961 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2962 struct acpi_device_physical_node *pn;
2963 struct acpi_device *adev;
2964
2965 if (dev->bus != &acpi_bus_type)
2966 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02002967
David Woodhousecf04eee2014-03-21 16:49:04 +00002968 adev= to_acpi_device(dev);
2969 mutex_lock(&adev->physical_node_lock);
2970 list_for_each_entry(pn, &adev->physical_node_list, node) {
2971 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
2972 if (ret)
2973 break;
2974 }
2975 mutex_unlock(&adev->physical_node_lock);
2976 if (ret)
2977 return ret;
2978 }
2979
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002980 return 0;
2981}
2982
Jiang Liuffebeb42014-11-09 22:48:02 +08002983static void intel_iommu_init_qi(struct intel_iommu *iommu)
2984{
2985 /*
2986 * Start from the sane iommu hardware state.
2987 * If the queued invalidation is already initialized by us
2988 * (for example, while enabling interrupt-remapping) then
2989 * we got the things already rolling from a sane state.
2990 */
2991 if (!iommu->qi) {
2992 /*
2993 * Clear any previous faults.
2994 */
2995 dmar_fault(-1, iommu);
2996 /*
2997 * Disable queued invalidation if supported and already enabled
2998 * before OS handover.
2999 */
3000 dmar_disable_qi(iommu);
3001 }
3002
3003 if (dmar_enable_qi(iommu)) {
3004 /*
3005 * Queued Invalidate not enabled, use Register Based Invalidate
3006 */
3007 iommu->flush.flush_context = __iommu_flush_context;
3008 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003009 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003010 iommu->name);
3011 } else {
3012 iommu->flush.flush_context = qi_flush_context;
3013 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003014 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003015 }
3016}
3017
Joerg Roedel091d42e2015-06-12 11:56:10 +02003018static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003019 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003020 struct context_entry **tbl,
3021 int bus, bool ext)
3022{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003023 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003024 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003025 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003026 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003027 phys_addr_t old_ce_phys;
3028
3029 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003030 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003031
3032 for (devfn = 0; devfn < 256; devfn++) {
3033 /* First calculate the correct index */
3034 idx = (ext ? devfn * 2 : devfn) % 256;
3035
3036 if (idx == 0) {
3037 /* First save what we may have and clean up */
3038 if (new_ce) {
3039 tbl[tbl_idx] = new_ce;
3040 __iommu_flush_cache(iommu, new_ce,
3041 VTD_PAGE_SIZE);
3042 pos = 1;
3043 }
3044
3045 if (old_ce)
3046 iounmap(old_ce);
3047
3048 ret = 0;
3049 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003050 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003051 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003052 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003053
3054 if (!old_ce_phys) {
3055 if (ext && devfn == 0) {
3056 /* No LCTP, try UCTP */
3057 devfn = 0x7f;
3058 continue;
3059 } else {
3060 goto out;
3061 }
3062 }
3063
3064 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003065 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3066 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003067 if (!old_ce)
3068 goto out;
3069
3070 new_ce = alloc_pgtable_page(iommu->node);
3071 if (!new_ce)
3072 goto out_unmap;
3073
3074 ret = 0;
3075 }
3076
3077 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003078 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003079
Joerg Roedelcf484d02015-06-12 12:21:46 +02003080 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003081 continue;
3082
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003083 did = context_domain_id(&ce);
3084 if (did >= 0 && did < cap_ndoms(iommu->cap))
3085 set_bit(did, iommu->domain_ids);
3086
Joerg Roedelcf484d02015-06-12 12:21:46 +02003087 /*
3088 * We need a marker for copied context entries. This
3089 * marker needs to work for the old format as well as
3090 * for extended context entries.
3091 *
3092 * Bit 67 of the context entry is used. In the old
3093 * format this bit is available to software, in the
3094 * extended format it is the PGE bit, but PGE is ignored
3095 * by HW if PASIDs are disabled (and thus still
3096 * available).
3097 *
3098 * So disable PASIDs first and then mark the entry
3099 * copied. This means that we don't copy PASID
3100 * translations from the old kernel, but this is fine as
3101 * faults there are not fatal.
3102 */
3103 context_clear_pasid_enable(&ce);
3104 context_set_copied(&ce);
3105
Joerg Roedel091d42e2015-06-12 11:56:10 +02003106 new_ce[idx] = ce;
3107 }
3108
3109 tbl[tbl_idx + pos] = new_ce;
3110
3111 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3112
3113out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003114 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003115
3116out:
3117 return ret;
3118}
3119
3120static int copy_translation_tables(struct intel_iommu *iommu)
3121{
3122 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003123 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003124 phys_addr_t old_rt_phys;
3125 int ctxt_table_entries;
3126 unsigned long flags;
3127 u64 rtaddr_reg;
3128 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003129 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003130
3131 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3132 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003133 new_ext = !!ecap_ecs(iommu->ecap);
3134
3135 /*
3136 * The RTT bit can only be changed when translation is disabled,
3137 * but disabling translation means to open a window for data
3138 * corruption. So bail out and don't copy anything if we would
3139 * have to change the bit.
3140 */
3141 if (new_ext != ext)
3142 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003143
3144 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3145 if (!old_rt_phys)
3146 return -EINVAL;
3147
Dan Williamsdfddb9692015-10-09 18:16:46 -04003148 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003149 if (!old_rt)
3150 return -ENOMEM;
3151
3152 /* This is too big for the stack - allocate it from slab */
3153 ctxt_table_entries = ext ? 512 : 256;
3154 ret = -ENOMEM;
3155 ctxt_tbls = kzalloc(ctxt_table_entries * sizeof(void *), GFP_KERNEL);
3156 if (!ctxt_tbls)
3157 goto out_unmap;
3158
3159 for (bus = 0; bus < 256; bus++) {
3160 ret = copy_context_table(iommu, &old_rt[bus],
3161 ctxt_tbls, bus, ext);
3162 if (ret) {
3163 pr_err("%s: Failed to copy context table for bus %d\n",
3164 iommu->name, bus);
3165 continue;
3166 }
3167 }
3168
3169 spin_lock_irqsave(&iommu->lock, flags);
3170
3171 /* Context tables are copied, now write them to the root_entry table */
3172 for (bus = 0; bus < 256; bus++) {
3173 int idx = ext ? bus * 2 : bus;
3174 u64 val;
3175
3176 if (ctxt_tbls[idx]) {
3177 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3178 iommu->root_entry[bus].lo = val;
3179 }
3180
3181 if (!ext || !ctxt_tbls[idx + 1])
3182 continue;
3183
3184 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3185 iommu->root_entry[bus].hi = val;
3186 }
3187
3188 spin_unlock_irqrestore(&iommu->lock, flags);
3189
3190 kfree(ctxt_tbls);
3191
3192 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3193
3194 ret = 0;
3195
3196out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003197 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003198
3199 return ret;
3200}
3201
Joseph Cihulab7792602011-05-03 00:08:37 -07003202static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003203{
3204 struct dmar_drhd_unit *drhd;
3205 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003206 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003207 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003208 struct intel_iommu *iommu;
Joerg Roedel13cf0172017-08-11 11:40:10 +02003209 int i, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003210
3211 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003212 * for each drhd
3213 * allocate root
3214 * initialize and program root entry to not present
3215 * endfor
3216 */
3217 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003218 /*
3219 * lock not needed as this is only incremented in the single
3220 * threaded kernel __init code path all other access are read
3221 * only
3222 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003223 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003224 g_num_of_iommus++;
3225 continue;
3226 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003227 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003228 }
3229
Jiang Liuffebeb42014-11-09 22:48:02 +08003230 /* Preallocate enough resources for IOMMU hot-addition */
3231 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3232 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3233
Weidong Hand9630fe2008-12-08 11:06:32 +08003234 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3235 GFP_KERNEL);
3236 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003237 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003238 ret = -ENOMEM;
3239 goto error;
3240 }
3241
Jiang Liu7c919772014-01-06 14:18:18 +08003242 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003243 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003244
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003245 intel_iommu_init_qi(iommu);
3246
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003247 ret = iommu_init_domains(iommu);
3248 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003249 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003250
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003251 init_translation_status(iommu);
3252
Joerg Roedel091d42e2015-06-12 11:56:10 +02003253 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3254 iommu_disable_translation(iommu);
3255 clear_translation_pre_enabled(iommu);
3256 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3257 iommu->name);
3258 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003259
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003260 /*
3261 * TBD:
3262 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003263 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003264 */
3265 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003266 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003267 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003268
Joerg Roedel091d42e2015-06-12 11:56:10 +02003269 if (translation_pre_enabled(iommu)) {
3270 pr_info("Translation already enabled - trying to copy translation structures\n");
3271
3272 ret = copy_translation_tables(iommu);
3273 if (ret) {
3274 /*
3275 * We found the IOMMU with translation
3276 * enabled - but failed to copy over the
3277 * old root-entry table. Try to proceed
3278 * by disabling translation now and
3279 * allocating a clean root-entry table.
3280 * This might cause DMAR faults, but
3281 * probably the dump will still succeed.
3282 */
3283 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3284 iommu->name);
3285 iommu_disable_translation(iommu);
3286 clear_translation_pre_enabled(iommu);
3287 } else {
3288 pr_info("Copied translation tables from previous kernel for %s\n",
3289 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003290 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003291 }
3292 }
3293
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003294 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003295 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003296#ifdef CONFIG_INTEL_IOMMU_SVM
3297 if (pasid_enabled(iommu))
3298 intel_svm_alloc_pasid_tables(iommu);
3299#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003300 }
3301
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003302 /*
3303 * Now that qi is enabled on all iommus, set the root entry and flush
3304 * caches. This is required on some Intel X58 chipsets, otherwise the
3305 * flush_context function will loop forever and the boot hangs.
3306 */
3307 for_each_active_iommu(iommu, drhd) {
3308 iommu_flush_write_buffer(iommu);
3309 iommu_set_root_entry(iommu);
3310 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3311 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3312 }
3313
David Woodhouse19943b02009-08-04 16:19:20 +01003314 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003315 iommu_identity_mapping |= IDENTMAP_ALL;
3316
Suresh Siddhad3f13812011-08-23 17:05:25 -07003317#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003318 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003319#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003320
Ashok Raj21e722c2017-01-30 09:39:53 -08003321 check_tylersburg_isoch();
3322
Joerg Roedel86080cc2015-06-12 12:27:16 +02003323 if (iommu_identity_mapping) {
3324 ret = si_domain_init(hw_pass_through);
3325 if (ret)
3326 goto free_iommu;
3327 }
3328
David Woodhousee0fc7e02009-09-30 09:12:17 -07003329
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003330 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003331 * If we copied translations from a previous kernel in the kdump
3332 * case, we can not assign the devices to domains now, as that
3333 * would eliminate the old mappings. So skip this part and defer
3334 * the assignment to device driver initialization time.
3335 */
3336 if (copied_tables)
3337 goto domains_done;
3338
3339 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003340 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003341 * identity mappings for rmrr, gfx, and isa and may fall back to static
3342 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003343 */
David Woodhouse19943b02009-08-04 16:19:20 +01003344 if (iommu_identity_mapping) {
3345 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3346 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003347 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003348 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003349 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003350 }
David Woodhouse19943b02009-08-04 16:19:20 +01003351 /*
3352 * For each rmrr
3353 * for each dev attached to rmrr
3354 * do
3355 * locate drhd for dev, alloc domain for dev
3356 * allocate free domain
3357 * allocate page table entries for rmrr
3358 * if context not allocated for bus
3359 * allocate and init context
3360 * set present in root table for this bus
3361 * init context with domain, translation etc
3362 * endfor
3363 * endfor
3364 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003365 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003366 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003367 /* some BIOS lists non-exist devices in DMAR table. */
3368 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003369 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003370 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003371 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003372 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003373 }
3374 }
3375
3376 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003377
Joerg Roedela87f4912015-06-12 12:32:54 +02003378domains_done:
3379
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003380 /*
3381 * for each drhd
3382 * enable fault log
3383 * global invalidate context cache
3384 * global invalidate iotlb
3385 * enable translation
3386 */
Jiang Liu7c919772014-01-06 14:18:18 +08003387 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003388 if (drhd->ignored) {
3389 /*
3390 * we always have to disable PMRs or DMA may fail on
3391 * this device
3392 */
3393 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003394 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003395 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003396 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003397
3398 iommu_flush_write_buffer(iommu);
3399
David Woodhousea222a7f2015-10-07 23:35:18 +01003400#ifdef CONFIG_INTEL_IOMMU_SVM
3401 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3402 ret = intel_svm_enable_prq(iommu);
3403 if (ret)
3404 goto free_iommu;
3405 }
3406#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003407 ret = dmar_set_interrupt(iommu);
3408 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003409 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003410
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003411 if (!translation_pre_enabled(iommu))
3412 iommu_enable_translation(iommu);
3413
David Woodhouseb94996c2009-09-19 15:28:12 -07003414 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003415 }
3416
3417 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003418
3419free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003420 for_each_active_iommu(iommu, drhd) {
3421 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003422 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003423 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003424
Weidong Hand9630fe2008-12-08 11:06:32 +08003425 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003426
Jiang Liu989d51f2014-02-19 14:07:21 +08003427error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003428 return ret;
3429}
3430
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003431/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003432static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003433 struct dmar_domain *domain,
3434 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003435{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003436 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003437
David Woodhouse875764d2009-06-28 21:20:51 +01003438 /* Restrict dma_mask to the width that the iommu can handle */
3439 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003440 /* Ensure we reserve the whole size-aligned region */
3441 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003442
3443 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003444 /*
3445 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003446 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003447 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003448 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003449 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3450 IOVA_PFN(DMA_BIT_MASK(32)));
3451 if (iova_pfn)
3452 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003453 }
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003454 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages, IOVA_PFN(dma_mask));
3455 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003456 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003457 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003458 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003459 }
3460
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003461 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003462}
3463
Peter Xub316d022017-05-22 18:28:51 +08003464static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003465{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003466 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003467 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003468 struct device *i_dev;
3469 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003470
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003471 domain = find_domain(dev);
3472 if (domain)
3473 goto out;
3474
3475 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3476 if (!domain)
3477 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003478
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003479 /* We have a new domain - setup possible RMRRs for the device */
3480 rcu_read_lock();
3481 for_each_rmrr_units(rmrr) {
3482 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3483 i, i_dev) {
3484 if (i_dev != dev)
3485 continue;
3486
3487 ret = domain_prepare_identity_map(dev, domain,
3488 rmrr->base_address,
3489 rmrr->end_address);
3490 if (ret)
3491 dev_err(dev, "Mapping reserved region failed\n");
3492 }
3493 }
3494 rcu_read_unlock();
3495
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003496 tmp = set_domain_for_dev(dev, domain);
3497 if (!tmp || domain != tmp) {
3498 domain_exit(domain);
3499 domain = tmp;
3500 }
3501
3502out:
3503
3504 if (!domain)
3505 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3506
3507
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003508 return domain;
3509}
3510
David Woodhouseecb509e2014-03-09 16:29:55 -07003511/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003512static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003513{
3514 int found;
3515
David Woodhouse3d891942014-03-06 15:59:26 +00003516 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003517 return 1;
3518
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003519 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003520 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003521
David Woodhouse9b226622014-03-09 14:03:28 -07003522 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003523 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003524 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003525 return 1;
3526 else {
3527 /*
3528 * 32 bit DMA is removed from si_domain and fall back
3529 * to non-identity mapping.
3530 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003531 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003532 pr_info("32bit %s uses non-identity mapping\n",
3533 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003534 return 0;
3535 }
3536 } else {
3537 /*
3538 * In case of a detached 64 bit DMA device from vm, the device
3539 * is put into si_domain for identity mapping.
3540 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003541 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003542 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003543 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003544 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003545 pr_info("64bit %s uses identity mapping\n",
3546 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003547 return 1;
3548 }
3549 }
3550 }
3551
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003552 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003553}
3554
David Woodhouse5040a912014-03-09 16:14:00 -07003555static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003556 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003557{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003558 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003559 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003560 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003561 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003562 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003563 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003564 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003565
3566 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003567
David Woodhouse5040a912014-03-09 16:14:00 -07003568 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003569 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003570
David Woodhouse5040a912014-03-09 16:14:00 -07003571 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003572 if (!domain)
3573 return 0;
3574
Weidong Han8c11e792008-12-08 15:29:22 +08003575 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003576 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003577
Omer Peleg2aac6302016-04-20 11:33:57 +03003578 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3579 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003580 goto error;
3581
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003582 /*
3583 * Check if DMAR supports zero-length reads on write only
3584 * mappings..
3585 */
3586 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003587 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003588 prot |= DMA_PTE_READ;
3589 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3590 prot |= DMA_PTE_WRITE;
3591 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003592 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003593 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003594 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003595 * is not a big problem
3596 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003597 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003598 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003599 if (ret)
3600 goto error;
3601
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003602 /* it's a non-present to present mapping. Only flush if caching mode */
3603 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003604 iommu_flush_iotlb_psi(iommu, domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003605 mm_to_dma_pfn(iova_pfn),
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003606 size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003607 else
Weidong Han8c11e792008-12-08 15:29:22 +08003608 iommu_flush_write_buffer(iommu);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003609
Omer Peleg2aac6302016-04-20 11:33:57 +03003610 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003611 start_paddr += paddr & ~PAGE_MASK;
3612 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003613
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003614error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003615 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003616 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003617 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003618 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003619 return 0;
3620}
3621
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003622static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3623 unsigned long offset, size_t size,
3624 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003625 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003626{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003627 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003628 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003629}
3630
Omer Peleg769530e2016-04-20 11:33:25 +03003631static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003632{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003633 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003634 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003635 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003636 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003637 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003638 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003639
David Woodhouse73676832009-07-04 14:08:36 +01003640 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003641 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003642
David Woodhouse1525a292014-03-06 16:19:30 +00003643 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003644 BUG_ON(!domain);
3645
Weidong Han8c11e792008-12-08 15:29:22 +08003646 iommu = domain_get_iommu(domain);
3647
Omer Peleg2aac6302016-04-20 11:33:57 +03003648 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003649
Omer Peleg769530e2016-04-20 11:33:25 +03003650 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003651 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003652 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003653
David Woodhoused794dc92009-06-28 00:27:49 +01003654 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003655 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003656
David Woodhouseea8ea462014-03-05 17:09:32 +00003657 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003658
mark gross5e0d2a62008-03-04 15:22:08 -08003659 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003660 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003661 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003662 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003663 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003664 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003665 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003666 queue_iova(&domain->iovad, iova_pfn, nrpages,
3667 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003668 /*
3669 * queue up the release of the unmap to save the 1/6th of the
3670 * cpu used up by the iotlb flush operation...
3671 */
mark gross5e0d2a62008-03-04 15:22:08 -08003672 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003673}
3674
Jiang Liud41a4ad2014-07-11 14:19:34 +08003675static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3676 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003677 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003678{
Omer Peleg769530e2016-04-20 11:33:25 +03003679 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003680}
3681
David Woodhouse5040a912014-03-09 16:14:00 -07003682static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003683 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003684 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003685{
Akinobu Mita36746432014-06-04 16:06:51 -07003686 struct page *page = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003687 int order;
3688
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003689 size = PAGE_ALIGN(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003690 order = get_order(size);
Alex Williamsone8bb9102009-11-04 15:59:34 -07003691
David Woodhouse5040a912014-03-09 16:14:00 -07003692 if (!iommu_no_mapping(dev))
Alex Williamsone8bb9102009-11-04 15:59:34 -07003693 flags &= ~(GFP_DMA | GFP_DMA32);
David Woodhouse5040a912014-03-09 16:14:00 -07003694 else if (dev->coherent_dma_mask < dma_get_required_mask(dev)) {
3695 if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
Alex Williamsone8bb9102009-11-04 15:59:34 -07003696 flags |= GFP_DMA;
3697 else
3698 flags |= GFP_DMA32;
3699 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003700
Mel Gormand0164ad2015-11-06 16:28:21 -08003701 if (gfpflags_allow_blocking(flags)) {
Akinobu Mita36746432014-06-04 16:06:51 -07003702 unsigned int count = size >> PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003703
Lucas Stach712c6042017-02-24 14:58:44 -08003704 page = dma_alloc_from_contiguous(dev, count, order, flags);
Akinobu Mita36746432014-06-04 16:06:51 -07003705 if (page && iommu_no_mapping(dev) &&
3706 page_to_phys(page) + size > dev->coherent_dma_mask) {
3707 dma_release_from_contiguous(dev, page, count);
3708 page = NULL;
3709 }
3710 }
3711
3712 if (!page)
3713 page = alloc_pages(flags, order);
3714 if (!page)
3715 return NULL;
3716 memset(page_address(page), 0, size);
3717
3718 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003719 DMA_BIDIRECTIONAL,
David Woodhouse5040a912014-03-09 16:14:00 -07003720 dev->coherent_dma_mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003721 if (*dma_handle)
Akinobu Mita36746432014-06-04 16:06:51 -07003722 return page_address(page);
3723 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3724 __free_pages(page, order);
3725
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003726 return NULL;
3727}
3728
David Woodhouse5040a912014-03-09 16:14:00 -07003729static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003730 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003731{
3732 int order;
Akinobu Mita36746432014-06-04 16:06:51 -07003733 struct page *page = virt_to_page(vaddr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003734
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003735 size = PAGE_ALIGN(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003736 order = get_order(size);
3737
Omer Peleg769530e2016-04-20 11:33:25 +03003738 intel_unmap(dev, dma_handle, size);
Akinobu Mita36746432014-06-04 16:06:51 -07003739 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3740 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003741}
3742
David Woodhouse5040a912014-03-09 16:14:00 -07003743static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003744 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003745 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003746{
Omer Peleg769530e2016-04-20 11:33:25 +03003747 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3748 unsigned long nrpages = 0;
3749 struct scatterlist *sg;
3750 int i;
3751
3752 for_each_sg(sglist, sg, nelems, i) {
3753 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3754 }
3755
3756 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003757}
3758
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003759static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003760 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003761{
3762 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003763 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003764
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003765 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003766 BUG_ON(!sg_page(sg));
Dan Williams3e6110f2015-12-15 12:54:06 -08003767 sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003768 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003769 }
3770 return nelems;
3771}
3772
David Woodhouse5040a912014-03-09 16:14:00 -07003773static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003774 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003775{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003776 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003777 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003778 size_t size = 0;
3779 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003780 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003781 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003782 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003783 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003784 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003785
3786 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003787 if (iommu_no_mapping(dev))
3788 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003789
David Woodhouse5040a912014-03-09 16:14:00 -07003790 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003791 if (!domain)
3792 return 0;
3793
Weidong Han8c11e792008-12-08 15:29:22 +08003794 iommu = domain_get_iommu(domain);
3795
David Woodhouseb536d242009-06-28 14:49:31 +01003796 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003797 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003798
Omer Peleg2aac6302016-04-20 11:33:57 +03003799 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003800 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003801 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003802 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003803 return 0;
3804 }
3805
3806 /*
3807 * Check if DMAR supports zero-length reads on write only
3808 * mappings..
3809 */
3810 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003811 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003812 prot |= DMA_PTE_READ;
3813 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3814 prot |= DMA_PTE_WRITE;
3815
Omer Peleg2aac6302016-04-20 11:33:57 +03003816 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003817
Fenghua Yuf5329592009-08-04 15:09:37 -07003818 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003819 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003820 dma_pte_free_pagetable(domain, start_vpfn,
3821 start_vpfn + size - 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003822 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003823 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003824 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003825
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003826 /* it's a non-present to present mapping. Only flush if caching mode */
3827 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003828 iommu_flush_iotlb_psi(iommu, domain, start_vpfn, size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003829 else
Weidong Han8c11e792008-12-08 15:29:22 +08003830 iommu_flush_write_buffer(iommu);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003831
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003832 return nelems;
3833}
3834
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003835static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3836{
3837 return !dma_addr;
3838}
3839
Arvind Yadav01e19322017-06-28 16:39:32 +05303840const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003841 .alloc = intel_alloc_coherent,
3842 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003843 .map_sg = intel_map_sg,
3844 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003845 .map_page = intel_map_page,
3846 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003847 .mapping_error = intel_mapping_error,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003848#ifdef CONFIG_X86
3849 .dma_supported = x86_dma_supported,
3850#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003851};
3852
3853static inline int iommu_domain_cache_init(void)
3854{
3855 int ret = 0;
3856
3857 iommu_domain_cache = kmem_cache_create("iommu_domain",
3858 sizeof(struct dmar_domain),
3859 0,
3860 SLAB_HWCACHE_ALIGN,
3861
3862 NULL);
3863 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003864 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003865 ret = -ENOMEM;
3866 }
3867
3868 return ret;
3869}
3870
3871static inline int iommu_devinfo_cache_init(void)
3872{
3873 int ret = 0;
3874
3875 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3876 sizeof(struct device_domain_info),
3877 0,
3878 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003879 NULL);
3880 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003881 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003882 ret = -ENOMEM;
3883 }
3884
3885 return ret;
3886}
3887
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003888static int __init iommu_init_mempool(void)
3889{
3890 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003891 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003892 if (ret)
3893 return ret;
3894
3895 ret = iommu_domain_cache_init();
3896 if (ret)
3897 goto domain_error;
3898
3899 ret = iommu_devinfo_cache_init();
3900 if (!ret)
3901 return ret;
3902
3903 kmem_cache_destroy(iommu_domain_cache);
3904domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003905 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003906
3907 return -ENOMEM;
3908}
3909
3910static void __init iommu_exit_mempool(void)
3911{
3912 kmem_cache_destroy(iommu_devinfo_cache);
3913 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003914 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003915}
3916
Dan Williams556ab452010-07-23 15:47:56 -07003917static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3918{
3919 struct dmar_drhd_unit *drhd;
3920 u32 vtbar;
3921 int rc;
3922
3923 /* We know that this device on this chipset has its own IOMMU.
3924 * If we find it under a different IOMMU, then the BIOS is lying
3925 * to us. Hope that the IOMMU for this device is actually
3926 * disabled, and it needs no translation...
3927 */
3928 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3929 if (rc) {
3930 /* "can't" happen */
3931 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3932 return;
3933 }
3934 vtbar &= 0xffff0000;
3935
3936 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3937 drhd = dmar_find_matched_drhd_unit(pdev);
3938 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3939 TAINT_FIRMWARE_WORKAROUND,
3940 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3941 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3942}
3943DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3944
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003945static void __init init_no_remapping_devices(void)
3946{
3947 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003948 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003949 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003950
3951 for_each_drhd_unit(drhd) {
3952 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003953 for_each_active_dev_scope(drhd->devices,
3954 drhd->devices_cnt, i, dev)
3955 break;
David Woodhouse832bd852014-03-07 15:08:36 +00003956 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003957 if (i == drhd->devices_cnt)
3958 drhd->ignored = 1;
3959 }
3960 }
3961
Jiang Liu7c919772014-01-06 14:18:18 +08003962 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08003963 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003964 continue;
3965
Jiang Liub683b232014-02-19 14:07:32 +08003966 for_each_active_dev_scope(drhd->devices,
3967 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003968 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003969 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003970 if (i < drhd->devices_cnt)
3971 continue;
3972
David Woodhousec0771df2011-10-14 20:59:46 +01003973 /* This IOMMU has *only* gfx devices. Either bypass it or
3974 set the gfx_mapped flag, as appropriate */
3975 if (dmar_map_gfx) {
3976 intel_iommu_gfx_mapped = 1;
3977 } else {
3978 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08003979 for_each_active_dev_scope(drhd->devices,
3980 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003981 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003982 }
3983 }
3984}
3985
Fenghua Yuf59c7b62009-03-27 14:22:42 -07003986#ifdef CONFIG_SUSPEND
3987static int init_iommu_hw(void)
3988{
3989 struct dmar_drhd_unit *drhd;
3990 struct intel_iommu *iommu = NULL;
3991
3992 for_each_active_iommu(iommu, drhd)
3993 if (iommu->qi)
3994 dmar_reenable_qi(iommu);
3995
Joseph Cihulab7792602011-05-03 00:08:37 -07003996 for_each_iommu(iommu, drhd) {
3997 if (drhd->ignored) {
3998 /*
3999 * we always have to disable PMRs or DMA may fail on
4000 * this device
4001 */
4002 if (force_on)
4003 iommu_disable_protect_mem_regions(iommu);
4004 continue;
4005 }
4006
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004007 iommu_flush_write_buffer(iommu);
4008
4009 iommu_set_root_entry(iommu);
4010
4011 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004012 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004013 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4014 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004015 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004016 }
4017
4018 return 0;
4019}
4020
4021static void iommu_flush_all(void)
4022{
4023 struct dmar_drhd_unit *drhd;
4024 struct intel_iommu *iommu;
4025
4026 for_each_active_iommu(iommu, drhd) {
4027 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004028 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004029 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004030 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004031 }
4032}
4033
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004034static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004035{
4036 struct dmar_drhd_unit *drhd;
4037 struct intel_iommu *iommu = NULL;
4038 unsigned long flag;
4039
4040 for_each_active_iommu(iommu, drhd) {
4041 iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
4042 GFP_ATOMIC);
4043 if (!iommu->iommu_state)
4044 goto nomem;
4045 }
4046
4047 iommu_flush_all();
4048
4049 for_each_active_iommu(iommu, drhd) {
4050 iommu_disable_translation(iommu);
4051
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004052 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004053
4054 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4055 readl(iommu->reg + DMAR_FECTL_REG);
4056 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4057 readl(iommu->reg + DMAR_FEDATA_REG);
4058 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4059 readl(iommu->reg + DMAR_FEADDR_REG);
4060 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4061 readl(iommu->reg + DMAR_FEUADDR_REG);
4062
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004063 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004064 }
4065 return 0;
4066
4067nomem:
4068 for_each_active_iommu(iommu, drhd)
4069 kfree(iommu->iommu_state);
4070
4071 return -ENOMEM;
4072}
4073
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004074static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004075{
4076 struct dmar_drhd_unit *drhd;
4077 struct intel_iommu *iommu = NULL;
4078 unsigned long flag;
4079
4080 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004081 if (force_on)
4082 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4083 else
4084 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004085 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004086 }
4087
4088 for_each_active_iommu(iommu, drhd) {
4089
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004090 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004091
4092 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4093 iommu->reg + DMAR_FECTL_REG);
4094 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4095 iommu->reg + DMAR_FEDATA_REG);
4096 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4097 iommu->reg + DMAR_FEADDR_REG);
4098 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4099 iommu->reg + DMAR_FEUADDR_REG);
4100
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004101 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004102 }
4103
4104 for_each_active_iommu(iommu, drhd)
4105 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004106}
4107
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004108static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004109 .resume = iommu_resume,
4110 .suspend = iommu_suspend,
4111};
4112
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004113static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004114{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004115 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004116}
4117
4118#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004119static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004120#endif /* CONFIG_PM */
4121
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004122
Jiang Liuc2a0b532014-11-09 22:47:56 +08004123int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004124{
4125 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004126 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004127 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004128 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004129
4130 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4131 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004132 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004133
4134 rmrru->hdr = header;
4135 rmrr = (struct acpi_dmar_reserved_memory *)header;
4136 rmrru->base_address = rmrr->base_address;
4137 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004138
4139 length = rmrr->end_address - rmrr->base_address + 1;
4140 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4141 IOMMU_RESV_DIRECT);
4142 if (!rmrru->resv)
4143 goto free_rmrru;
4144
Jiang Liu2e455282014-02-19 14:07:36 +08004145 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4146 ((void *)rmrr) + rmrr->header.length,
4147 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004148 if (rmrru->devices_cnt && rmrru->devices == NULL)
4149 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004150
Jiang Liu2e455282014-02-19 14:07:36 +08004151 list_add(&rmrru->list, &dmar_rmrr_units);
4152
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004153 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004154free_all:
4155 kfree(rmrru->resv);
4156free_rmrru:
4157 kfree(rmrru);
4158out:
4159 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004160}
4161
Jiang Liu6b197242014-11-09 22:47:58 +08004162static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4163{
4164 struct dmar_atsr_unit *atsru;
4165 struct acpi_dmar_atsr *tmp;
4166
4167 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4168 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4169 if (atsr->segment != tmp->segment)
4170 continue;
4171 if (atsr->header.length != tmp->header.length)
4172 continue;
4173 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4174 return atsru;
4175 }
4176
4177 return NULL;
4178}
4179
4180int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004181{
4182 struct acpi_dmar_atsr *atsr;
4183 struct dmar_atsr_unit *atsru;
4184
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004185 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004186 return 0;
4187
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004188 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004189 atsru = dmar_find_atsr(atsr);
4190 if (atsru)
4191 return 0;
4192
4193 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004194 if (!atsru)
4195 return -ENOMEM;
4196
Jiang Liu6b197242014-11-09 22:47:58 +08004197 /*
4198 * If memory is allocated from slab by ACPI _DSM method, we need to
4199 * copy the memory content because the memory buffer will be freed
4200 * on return.
4201 */
4202 atsru->hdr = (void *)(atsru + 1);
4203 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004204 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004205 if (!atsru->include_all) {
4206 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4207 (void *)atsr + atsr->header.length,
4208 &atsru->devices_cnt);
4209 if (atsru->devices_cnt && atsru->devices == NULL) {
4210 kfree(atsru);
4211 return -ENOMEM;
4212 }
4213 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004214
Jiang Liu0e242612014-02-19 14:07:34 +08004215 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004216
4217 return 0;
4218}
4219
Jiang Liu9bdc5312014-01-06 14:18:27 +08004220static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4221{
4222 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4223 kfree(atsru);
4224}
4225
Jiang Liu6b197242014-11-09 22:47:58 +08004226int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4227{
4228 struct acpi_dmar_atsr *atsr;
4229 struct dmar_atsr_unit *atsru;
4230
4231 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4232 atsru = dmar_find_atsr(atsr);
4233 if (atsru) {
4234 list_del_rcu(&atsru->list);
4235 synchronize_rcu();
4236 intel_iommu_free_atsr(atsru);
4237 }
4238
4239 return 0;
4240}
4241
4242int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4243{
4244 int i;
4245 struct device *dev;
4246 struct acpi_dmar_atsr *atsr;
4247 struct dmar_atsr_unit *atsru;
4248
4249 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4250 atsru = dmar_find_atsr(atsr);
4251 if (!atsru)
4252 return 0;
4253
Linus Torvalds194dc872016-07-27 20:03:31 -07004254 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004255 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4256 i, dev)
4257 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004258 }
Jiang Liu6b197242014-11-09 22:47:58 +08004259
4260 return 0;
4261}
4262
Jiang Liuffebeb42014-11-09 22:48:02 +08004263static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4264{
4265 int sp, ret = 0;
4266 struct intel_iommu *iommu = dmaru->iommu;
4267
4268 if (g_iommus[iommu->seq_id])
4269 return 0;
4270
4271 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004272 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004273 iommu->name);
4274 return -ENXIO;
4275 }
4276 if (!ecap_sc_support(iommu->ecap) &&
4277 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004278 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004279 iommu->name);
4280 return -ENXIO;
4281 }
4282 sp = domain_update_iommu_superpage(iommu) - 1;
4283 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004284 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004285 iommu->name);
4286 return -ENXIO;
4287 }
4288
4289 /*
4290 * Disable translation if already enabled prior to OS handover.
4291 */
4292 if (iommu->gcmd & DMA_GCMD_TE)
4293 iommu_disable_translation(iommu);
4294
4295 g_iommus[iommu->seq_id] = iommu;
4296 ret = iommu_init_domains(iommu);
4297 if (ret == 0)
4298 ret = iommu_alloc_root_entry(iommu);
4299 if (ret)
4300 goto out;
4301
David Woodhouse8a94ade2015-03-24 14:54:56 +00004302#ifdef CONFIG_INTEL_IOMMU_SVM
4303 if (pasid_enabled(iommu))
4304 intel_svm_alloc_pasid_tables(iommu);
4305#endif
4306
Jiang Liuffebeb42014-11-09 22:48:02 +08004307 if (dmaru->ignored) {
4308 /*
4309 * we always have to disable PMRs or DMA may fail on this device
4310 */
4311 if (force_on)
4312 iommu_disable_protect_mem_regions(iommu);
4313 return 0;
4314 }
4315
4316 intel_iommu_init_qi(iommu);
4317 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004318
4319#ifdef CONFIG_INTEL_IOMMU_SVM
4320 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4321 ret = intel_svm_enable_prq(iommu);
4322 if (ret)
4323 goto disable_iommu;
4324 }
4325#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004326 ret = dmar_set_interrupt(iommu);
4327 if (ret)
4328 goto disable_iommu;
4329
4330 iommu_set_root_entry(iommu);
4331 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4332 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4333 iommu_enable_translation(iommu);
4334
Jiang Liuffebeb42014-11-09 22:48:02 +08004335 iommu_disable_protect_mem_regions(iommu);
4336 return 0;
4337
4338disable_iommu:
4339 disable_dmar_iommu(iommu);
4340out:
4341 free_dmar_iommu(iommu);
4342 return ret;
4343}
4344
Jiang Liu6b197242014-11-09 22:47:58 +08004345int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4346{
Jiang Liuffebeb42014-11-09 22:48:02 +08004347 int ret = 0;
4348 struct intel_iommu *iommu = dmaru->iommu;
4349
4350 if (!intel_iommu_enabled)
4351 return 0;
4352 if (iommu == NULL)
4353 return -EINVAL;
4354
4355 if (insert) {
4356 ret = intel_iommu_add(dmaru);
4357 } else {
4358 disable_dmar_iommu(iommu);
4359 free_dmar_iommu(iommu);
4360 }
4361
4362 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004363}
4364
Jiang Liu9bdc5312014-01-06 14:18:27 +08004365static void intel_iommu_free_dmars(void)
4366{
4367 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4368 struct dmar_atsr_unit *atsru, *atsr_n;
4369
4370 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4371 list_del(&rmrru->list);
4372 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004373 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004374 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004375 }
4376
Jiang Liu9bdc5312014-01-06 14:18:27 +08004377 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4378 list_del(&atsru->list);
4379 intel_iommu_free_atsr(atsru);
4380 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004381}
4382
4383int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4384{
Jiang Liub683b232014-02-19 14:07:32 +08004385 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004386 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004387 struct pci_dev *bridge = NULL;
4388 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004389 struct acpi_dmar_atsr *atsr;
4390 struct dmar_atsr_unit *atsru;
4391
4392 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004393 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004394 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004395 /* If it's an integrated device, allow ATS */
4396 if (!bridge)
4397 return 1;
4398 /* Connected via non-PCIe: no ATS */
4399 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004400 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004401 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004402 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004403 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004404 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004405 }
4406
Jiang Liu0e242612014-02-19 14:07:34 +08004407 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004408 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4409 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4410 if (atsr->segment != pci_domain_nr(dev->bus))
4411 continue;
4412
Jiang Liub683b232014-02-19 14:07:32 +08004413 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004414 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004415 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004416
4417 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004418 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004419 }
Jiang Liub683b232014-02-19 14:07:32 +08004420 ret = 0;
4421out:
Jiang Liu0e242612014-02-19 14:07:34 +08004422 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004423
Jiang Liub683b232014-02-19 14:07:32 +08004424 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004425}
4426
Jiang Liu59ce0512014-02-19 14:07:35 +08004427int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4428{
4429 int ret = 0;
4430 struct dmar_rmrr_unit *rmrru;
4431 struct dmar_atsr_unit *atsru;
4432 struct acpi_dmar_atsr *atsr;
4433 struct acpi_dmar_reserved_memory *rmrr;
4434
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004435 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004436 return 0;
4437
4438 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4439 rmrr = container_of(rmrru->hdr,
4440 struct acpi_dmar_reserved_memory, header);
4441 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4442 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4443 ((void *)rmrr) + rmrr->header.length,
4444 rmrr->segment, rmrru->devices,
4445 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004446 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004447 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004448 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004449 dmar_remove_dev_scope(info, rmrr->segment,
4450 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004451 }
4452 }
4453
4454 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4455 if (atsru->include_all)
4456 continue;
4457
4458 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4459 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4460 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4461 (void *)atsr + atsr->header.length,
4462 atsr->segment, atsru->devices,
4463 atsru->devices_cnt);
4464 if (ret > 0)
4465 break;
4466 else if(ret < 0)
4467 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004468 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004469 if (dmar_remove_dev_scope(info, atsr->segment,
4470 atsru->devices, atsru->devices_cnt))
4471 break;
4472 }
4473 }
4474
4475 return 0;
4476}
4477
Fenghua Yu99dcade2009-11-11 07:23:06 -08004478/*
4479 * Here we only respond to action of unbound device from driver.
4480 *
4481 * Added device is not attached to its DMAR domain here yet. That will happen
4482 * when mapping the device to iova.
4483 */
4484static int device_notifier(struct notifier_block *nb,
4485 unsigned long action, void *data)
4486{
4487 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004488 struct dmar_domain *domain;
4489
David Woodhouse3d891942014-03-06 15:59:26 +00004490 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004491 return 0;
4492
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004493 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004494 return 0;
4495
David Woodhouse1525a292014-03-06 16:19:30 +00004496 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004497 if (!domain)
4498 return 0;
4499
Joerg Roedele6de0f82015-07-22 16:30:36 +02004500 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004501 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004502 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004503
Fenghua Yu99dcade2009-11-11 07:23:06 -08004504 return 0;
4505}
4506
4507static struct notifier_block device_nb = {
4508 .notifier_call = device_notifier,
4509};
4510
Jiang Liu75f05562014-02-19 14:07:37 +08004511static int intel_iommu_memory_notifier(struct notifier_block *nb,
4512 unsigned long val, void *v)
4513{
4514 struct memory_notify *mhp = v;
4515 unsigned long long start, end;
4516 unsigned long start_vpfn, last_vpfn;
4517
4518 switch (val) {
4519 case MEM_GOING_ONLINE:
4520 start = mhp->start_pfn << PAGE_SHIFT;
4521 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4522 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004523 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004524 start, end);
4525 return NOTIFY_BAD;
4526 }
4527 break;
4528
4529 case MEM_OFFLINE:
4530 case MEM_CANCEL_ONLINE:
4531 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4532 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4533 while (start_vpfn <= last_vpfn) {
4534 struct iova *iova;
4535 struct dmar_drhd_unit *drhd;
4536 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004537 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004538
4539 iova = find_iova(&si_domain->iovad, start_vpfn);
4540 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004541 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004542 start_vpfn);
4543 break;
4544 }
4545
4546 iova = split_and_remove_iova(&si_domain->iovad, iova,
4547 start_vpfn, last_vpfn);
4548 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004549 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004550 start_vpfn, last_vpfn);
4551 return NOTIFY_BAD;
4552 }
4553
David Woodhouseea8ea462014-03-05 17:09:32 +00004554 freelist = domain_unmap(si_domain, iova->pfn_lo,
4555 iova->pfn_hi);
4556
Jiang Liu75f05562014-02-19 14:07:37 +08004557 rcu_read_lock();
4558 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004559 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004560 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004561 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004562 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004563 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004564
4565 start_vpfn = iova->pfn_hi + 1;
4566 free_iova_mem(iova);
4567 }
4568 break;
4569 }
4570
4571 return NOTIFY_OK;
4572}
4573
4574static struct notifier_block intel_iommu_memory_nb = {
4575 .notifier_call = intel_iommu_memory_notifier,
4576 .priority = 0
4577};
4578
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004579static void free_all_cpu_cached_iovas(unsigned int cpu)
4580{
4581 int i;
4582
4583 for (i = 0; i < g_num_of_iommus; i++) {
4584 struct intel_iommu *iommu = g_iommus[i];
4585 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004586 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004587
4588 if (!iommu)
4589 continue;
4590
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004591 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004592 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004593
4594 if (!domain)
4595 continue;
4596 free_cpu_cached_iovas(cpu, &domain->iovad);
4597 }
4598 }
4599}
4600
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004601static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004602{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004603 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004604 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004605}
4606
Joerg Roedel161b28a2017-03-28 17:04:52 +02004607static void intel_disable_iommus(void)
4608{
4609 struct intel_iommu *iommu = NULL;
4610 struct dmar_drhd_unit *drhd;
4611
4612 for_each_iommu(iommu, drhd)
4613 iommu_disable_translation(iommu);
4614}
4615
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004616static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4617{
4618 return container_of(dev, struct intel_iommu, iommu.dev);
4619}
4620
Alex Williamsona5459cf2014-06-12 16:12:31 -06004621static ssize_t intel_iommu_show_version(struct device *dev,
4622 struct device_attribute *attr,
4623 char *buf)
4624{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004625 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004626 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4627 return sprintf(buf, "%d:%d\n",
4628 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4629}
4630static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4631
4632static ssize_t intel_iommu_show_address(struct device *dev,
4633 struct device_attribute *attr,
4634 char *buf)
4635{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004636 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004637 return sprintf(buf, "%llx\n", iommu->reg_phys);
4638}
4639static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4640
4641static ssize_t intel_iommu_show_cap(struct device *dev,
4642 struct device_attribute *attr,
4643 char *buf)
4644{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004645 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004646 return sprintf(buf, "%llx\n", iommu->cap);
4647}
4648static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4649
4650static ssize_t intel_iommu_show_ecap(struct device *dev,
4651 struct device_attribute *attr,
4652 char *buf)
4653{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004654 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004655 return sprintf(buf, "%llx\n", iommu->ecap);
4656}
4657static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4658
Alex Williamson2238c082015-07-14 15:24:53 -06004659static ssize_t intel_iommu_show_ndoms(struct device *dev,
4660 struct device_attribute *attr,
4661 char *buf)
4662{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004663 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004664 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4665}
4666static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4667
4668static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4669 struct device_attribute *attr,
4670 char *buf)
4671{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004672 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004673 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4674 cap_ndoms(iommu->cap)));
4675}
4676static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4677
Alex Williamsona5459cf2014-06-12 16:12:31 -06004678static struct attribute *intel_iommu_attrs[] = {
4679 &dev_attr_version.attr,
4680 &dev_attr_address.attr,
4681 &dev_attr_cap.attr,
4682 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004683 &dev_attr_domains_supported.attr,
4684 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004685 NULL,
4686};
4687
4688static struct attribute_group intel_iommu_group = {
4689 .name = "intel-iommu",
4690 .attrs = intel_iommu_attrs,
4691};
4692
4693const struct attribute_group *intel_iommu_groups[] = {
4694 &intel_iommu_group,
4695 NULL,
4696};
4697
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004698int __init intel_iommu_init(void)
4699{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004700 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004701 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004702 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004703
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004704 /* VT-d is required for a TXT/tboot launch, so enforce that */
4705 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004706
Jiang Liu3a5670e2014-02-19 14:07:33 +08004707 if (iommu_init_mempool()) {
4708 if (force_on)
4709 panic("tboot: Failed to initialize iommu memory\n");
4710 return -ENOMEM;
4711 }
4712
4713 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004714 if (dmar_table_init()) {
4715 if (force_on)
4716 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004717 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004718 }
4719
Suresh Siddhac2c72862011-08-23 17:05:19 -07004720 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004721 if (force_on)
4722 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004723 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004724 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004725
Joerg Roedel161b28a2017-03-28 17:04:52 +02004726 if (no_iommu || dmar_disabled) {
4727 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004728 * We exit the function here to ensure IOMMU's remapping and
4729 * mempool aren't setup, which means that the IOMMU's PMRs
4730 * won't be disabled via the call to init_dmars(). So disable
4731 * it explicitly here. The PMRs were setup by tboot prior to
4732 * calling SENTER, but the kernel is expected to reset/tear
4733 * down the PMRs.
4734 */
4735 if (intel_iommu_tboot_noforce) {
4736 for_each_iommu(iommu, drhd)
4737 iommu_disable_protect_mem_regions(iommu);
4738 }
4739
4740 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004741 * Make sure the IOMMUs are switched off, even when we
4742 * boot into a kexec kernel and the previous kernel left
4743 * them enabled
4744 */
4745 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004746 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004747 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004748
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004749 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004750 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004751
4752 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004753 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004754
Joseph Cihula51a63e62011-03-21 11:04:24 -07004755 if (dmar_init_reserved_ranges()) {
4756 if (force_on)
4757 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004758 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004759 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004760
4761 init_no_remapping_devices();
4762
Joseph Cihulab7792602011-05-03 00:08:37 -07004763 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004764 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004765 if (force_on)
4766 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004767 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004768 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004769 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004770 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004771 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004772
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004773#ifdef CONFIG_SWIOTLB
4774 swiotlb = 0;
4775#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004776 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004777
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004778 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004779
Joerg Roedel39ab9552017-02-01 16:56:46 +01004780 for_each_active_iommu(iommu, drhd) {
4781 iommu_device_sysfs_add(&iommu->iommu, NULL,
4782 intel_iommu_groups,
4783 "%s", iommu->name);
4784 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4785 iommu_device_register(&iommu->iommu);
4786 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004787
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004788 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004789 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004790 if (si_domain && !hw_pass_through)
4791 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004792 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4793 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004794 intel_iommu_enabled = 1;
4795
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004796 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004797
4798out_free_reserved_range:
4799 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004800out_free_dmar:
4801 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004802 up_write(&dmar_global_lock);
4803 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004804 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004805}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004806
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004807static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004808{
4809 struct intel_iommu *iommu = opaque;
4810
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004811 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004812 return 0;
4813}
4814
4815/*
4816 * NB - intel-iommu lacks any sort of reference counting for the users of
4817 * dependent devices. If multiple endpoints have intersecting dependent
4818 * devices, unbinding the driver from any one of them will possibly leave
4819 * the others unable to operate.
4820 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004821static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004822{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004823 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004824 return;
4825
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004826 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004827}
4828
Joerg Roedel127c7612015-07-23 17:44:46 +02004829static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004830{
Weidong Hanc7151a82008-12-08 22:51:37 +08004831 struct intel_iommu *iommu;
4832 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004833
Joerg Roedel55d94042015-07-22 16:50:40 +02004834 assert_spin_locked(&device_domain_lock);
4835
Joerg Roedelb608ac32015-07-21 18:19:08 +02004836 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004837 return;
4838
Joerg Roedel127c7612015-07-23 17:44:46 +02004839 iommu = info->iommu;
4840
4841 if (info->dev) {
4842 iommu_disable_dev_iotlb(info);
4843 domain_context_clear(iommu, info->dev);
4844 }
4845
Joerg Roedelb608ac32015-07-21 18:19:08 +02004846 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004847
Joerg Roedeld160aca2015-07-22 11:52:53 +02004848 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004849 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004850 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004851
4852 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004853}
4854
Joerg Roedel55d94042015-07-22 16:50:40 +02004855static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4856 struct device *dev)
4857{
Joerg Roedel127c7612015-07-23 17:44:46 +02004858 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004859 unsigned long flags;
4860
Weidong Hanc7151a82008-12-08 22:51:37 +08004861 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004862 info = dev->archdata.iommu;
4863 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004864 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004865}
4866
4867static int md_domain_init(struct dmar_domain *domain, int guest_width)
4868{
4869 int adjust_width;
4870
Robin Murphy0fb5fe82015-01-12 17:51:16 +00004871 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
4872 DMA_32BIT_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004873 domain_reserve_special_ranges(domain);
4874
4875 /* calculate AGAW */
4876 domain->gaw = guest_width;
4877 adjust_width = guestwidth_to_adjustwidth(guest_width);
4878 domain->agaw = width_to_agaw(adjust_width);
4879
Weidong Han5e98c4b2008-12-08 23:03:27 +08004880 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08004881 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01004882 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004883 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08004884
4885 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07004886 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004887 if (!domain->pgd)
4888 return -ENOMEM;
4889 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
4890 return 0;
4891}
4892
Joerg Roedel00a77de2015-03-26 13:43:08 +01004893static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03004894{
Joerg Roedel5d450802008-12-03 14:52:32 +01004895 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01004896 struct iommu_domain *domain;
4897
4898 if (type != IOMMU_DOMAIN_UNMANAGED)
4899 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004900
Jiang Liuab8dfe22014-07-11 14:19:27 +08004901 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01004902 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004903 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01004904 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004905 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07004906 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004907 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08004908 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01004909 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004910 }
Allen Kay8140a952011-10-14 12:32:17 -07004911 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004912
Joerg Roedel00a77de2015-03-26 13:43:08 +01004913 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01004914 domain->geometry.aperture_start = 0;
4915 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
4916 domain->geometry.force_aperture = true;
4917
Joerg Roedel00a77de2015-03-26 13:43:08 +01004918 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03004919}
Kay, Allen M38717942008-09-09 18:37:29 +03004920
Joerg Roedel00a77de2015-03-26 13:43:08 +01004921static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03004922{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004923 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03004924}
Kay, Allen M38717942008-09-09 18:37:29 +03004925
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004926static int intel_iommu_attach_device(struct iommu_domain *domain,
4927 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004928{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004929 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004930 struct intel_iommu *iommu;
4931 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07004932 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03004933
Alex Williamsonc875d2c2014-07-03 09:57:02 -06004934 if (device_is_rmrr_locked(dev)) {
4935 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
4936 return -EPERM;
4937 }
4938
David Woodhouse7207d8f2014-03-09 16:31:06 -07004939 /* normally dev is not mapped */
4940 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004941 struct dmar_domain *old_domain;
4942
David Woodhouse1525a292014-03-06 16:19:30 +00004943 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004944 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02004945 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02004946 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004947 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01004948
4949 if (!domain_type_is_vm_or_si(old_domain) &&
4950 list_empty(&old_domain->devices))
4951 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004952 }
4953 }
4954
David Woodhouse156baca2014-03-09 14:00:57 -07004955 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004956 if (!iommu)
4957 return -ENODEV;
4958
4959 /* check if this iommu agaw is sufficient for max mapped address */
4960 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01004961 if (addr_width > cap_mgaw(iommu->cap))
4962 addr_width = cap_mgaw(iommu->cap);
4963
4964 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004965 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004966 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01004967 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004968 return -EFAULT;
4969 }
Tom Lyona99c47a2010-05-17 08:20:45 +01004970 dmar_domain->gaw = addr_width;
4971
4972 /*
4973 * Knock out extra levels of page tables if necessary
4974 */
4975 while (iommu->agaw < dmar_domain->agaw) {
4976 struct dma_pte *pte;
4977
4978 pte = dmar_domain->pgd;
4979 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08004980 dmar_domain->pgd = (struct dma_pte *)
4981 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01004982 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01004983 }
4984 dmar_domain->agaw--;
4985 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004986
Joerg Roedel28ccce02015-07-21 14:45:31 +02004987 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004988}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004989
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004990static void intel_iommu_detach_device(struct iommu_domain *domain,
4991 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004992{
Joerg Roedele6de0f82015-07-22 16:30:36 +02004993 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03004994}
Kay, Allen M38717942008-09-09 18:37:29 +03004995
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01004996static int intel_iommu_map(struct iommu_domain *domain,
4997 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02004998 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03004999{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005000 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005001 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005002 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005003 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005004
Joerg Roedeldde57a22008-12-03 15:04:09 +01005005 if (iommu_prot & IOMMU_READ)
5006 prot |= DMA_PTE_READ;
5007 if (iommu_prot & IOMMU_WRITE)
5008 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005009 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5010 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005011
David Woodhouse163cc522009-06-28 00:51:17 +01005012 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005013 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005014 u64 end;
5015
5016 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005017 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005018 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005019 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005020 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005021 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005022 return -EFAULT;
5023 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005024 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005025 }
David Woodhousead051222009-06-28 14:22:28 +01005026 /* Round up size to next multiple of PAGE_SIZE, if it and
5027 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005028 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005029 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5030 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005031 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005032}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005033
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005034static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005035 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005036{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005037 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005038 struct page *freelist = NULL;
5039 struct intel_iommu *iommu;
5040 unsigned long start_pfn, last_pfn;
5041 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005042 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005043
David Woodhouse5cf0a762014-03-19 16:07:49 +00005044 /* Cope with horrid API which requires us to unmap more than the
5045 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005046 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005047
5048 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5049 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5050
David Woodhouseea8ea462014-03-05 17:09:32 +00005051 start_pfn = iova >> VTD_PAGE_SHIFT;
5052 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5053
5054 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5055
5056 npages = last_pfn - start_pfn + 1;
5057
Joerg Roedel29a27712015-07-21 17:17:12 +02005058 for_each_domain_iommu(iommu_id, dmar_domain) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02005059 iommu = g_iommus[iommu_id];
David Woodhouseea8ea462014-03-05 17:09:32 +00005060
Joerg Roedel42e8c182015-07-21 15:50:02 +02005061 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5062 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005063 }
5064
5065 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005066
David Woodhouse163cc522009-06-28 00:51:17 +01005067 if (dmar_domain->max_addr == iova + size)
5068 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005069
David Woodhouse5cf0a762014-03-19 16:07:49 +00005070 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005071}
Kay, Allen M38717942008-09-09 18:37:29 +03005072
Joerg Roedeld14d6572008-12-03 15:06:57 +01005073static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305074 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005075{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005076 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005077 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005078 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005079 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005080
David Woodhouse5cf0a762014-03-19 16:07:49 +00005081 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005082 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005083 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005084
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005085 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005086}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005087
Joerg Roedel5d587b82014-09-05 10:50:45 +02005088static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005089{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005090 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005091 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005092 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005093 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005094
Joerg Roedel5d587b82014-09-05 10:50:45 +02005095 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005096}
5097
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005098static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005099{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005100 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005101 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005102 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005103
Alex Williamsona5459cf2014-06-12 16:12:31 -06005104 iommu = device_to_iommu(dev, &bus, &devfn);
5105 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005106 return -ENODEV;
5107
Joerg Roedele3d10af2017-02-01 17:23:22 +01005108 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005109
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005110 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005111
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005112 if (IS_ERR(group))
5113 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005114
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005115 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005116 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005117}
5118
5119static void intel_iommu_remove_device(struct device *dev)
5120{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005121 struct intel_iommu *iommu;
5122 u8 bus, devfn;
5123
5124 iommu = device_to_iommu(dev, &bus, &devfn);
5125 if (!iommu)
5126 return;
5127
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005128 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005129
Joerg Roedele3d10af2017-02-01 17:23:22 +01005130 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005131}
5132
Eric Auger0659b8d2017-01-19 20:57:53 +00005133static void intel_iommu_get_resv_regions(struct device *device,
5134 struct list_head *head)
5135{
5136 struct iommu_resv_region *reg;
5137 struct dmar_rmrr_unit *rmrr;
5138 struct device *i_dev;
5139 int i;
5140
5141 rcu_read_lock();
5142 for_each_rmrr_units(rmrr) {
5143 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5144 i, i_dev) {
5145 if (i_dev != device)
5146 continue;
5147
5148 list_add_tail(&rmrr->resv->list, head);
5149 }
5150 }
5151 rcu_read_unlock();
5152
5153 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5154 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005155 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005156 if (!reg)
5157 return;
5158 list_add_tail(&reg->list, head);
5159}
5160
5161static void intel_iommu_put_resv_regions(struct device *dev,
5162 struct list_head *head)
5163{
5164 struct iommu_resv_region *entry, *next;
5165
5166 list_for_each_entry_safe(entry, next, head, list) {
5167 if (entry->type == IOMMU_RESV_RESERVED)
5168 kfree(entry);
5169 }
Kay, Allen M38717942008-09-09 18:37:29 +03005170}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005171
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005172#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005173#define MAX_NR_PASID_BITS (20)
5174static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5175{
5176 /*
5177 * Convert ecap_pss to extend context entry pts encoding, also
5178 * respect the soft pasid_max value set by the iommu.
5179 * - number of PASID bits = ecap_pss + 1
5180 * - number of PASID table entries = 2^(pts + 5)
5181 * Therefore, pts = ecap_pss - 4
5182 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5183 */
5184 if (ecap_pss(iommu->ecap) < 5)
5185 return 0;
5186
5187 /* pasid_max is encoded as actual number of entries not the bits */
5188 return find_first_bit((unsigned long *)&iommu->pasid_max,
5189 MAX_NR_PASID_BITS) - 5;
5190}
5191
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005192int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5193{
5194 struct device_domain_info *info;
5195 struct context_entry *context;
5196 struct dmar_domain *domain;
5197 unsigned long flags;
5198 u64 ctx_lo;
5199 int ret;
5200
5201 domain = get_valid_domain_for_dev(sdev->dev);
5202 if (!domain)
5203 return -EINVAL;
5204
5205 spin_lock_irqsave(&device_domain_lock, flags);
5206 spin_lock(&iommu->lock);
5207
5208 ret = -EINVAL;
5209 info = sdev->dev->archdata.iommu;
5210 if (!info || !info->pasid_supported)
5211 goto out;
5212
5213 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5214 if (WARN_ON(!context))
5215 goto out;
5216
5217 ctx_lo = context[0].lo;
5218
5219 sdev->did = domain->iommu_did[iommu->seq_id];
5220 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5221
5222 if (!(ctx_lo & CONTEXT_PASIDE)) {
5223 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005224 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5225 intel_iommu_get_pts(iommu);
5226
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005227 wmb();
5228 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5229 * extended to permit requests-with-PASID if the PASIDE bit
5230 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5231 * however, the PASIDE bit is ignored and requests-with-PASID
5232 * are unconditionally blocked. Which makes less sense.
5233 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5234 * "guest mode" translation types depending on whether ATS
5235 * is available or not. Annoyingly, we can't use the new
5236 * modes *unless* PASIDE is set. */
5237 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5238 ctx_lo &= ~CONTEXT_TT_MASK;
5239 if (info->ats_supported)
5240 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5241 else
5242 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5243 }
5244 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005245 if (iommu->pasid_state_table)
5246 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005247 if (info->pri_supported)
5248 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005249 context[0].lo = ctx_lo;
5250 wmb();
5251 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5252 DMA_CCMD_MASK_NOBIT,
5253 DMA_CCMD_DEVICE_INVL);
5254 }
5255
5256 /* Enable PASID support in the device, if it wasn't already */
5257 if (!info->pasid_enabled)
5258 iommu_enable_dev_iotlb(info);
5259
5260 if (info->ats_enabled) {
5261 sdev->dev_iotlb = 1;
5262 sdev->qdep = info->ats_qdep;
5263 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5264 sdev->qdep = 0;
5265 }
5266 ret = 0;
5267
5268 out:
5269 spin_unlock(&iommu->lock);
5270 spin_unlock_irqrestore(&device_domain_lock, flags);
5271
5272 return ret;
5273}
5274
5275struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5276{
5277 struct intel_iommu *iommu;
5278 u8 bus, devfn;
5279
5280 if (iommu_dummy(dev)) {
5281 dev_warn(dev,
5282 "No IOMMU translation for device; cannot enable SVM\n");
5283 return NULL;
5284 }
5285
5286 iommu = device_to_iommu(dev, &bus, &devfn);
5287 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005288 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005289 return NULL;
5290 }
5291
5292 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005293 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005294 return NULL;
5295 }
5296
5297 return iommu;
5298}
5299#endif /* CONFIG_INTEL_IOMMU_SVM */
5300
Joerg Roedelb0119e82017-02-01 13:23:08 +01005301const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005302 .capable = intel_iommu_capable,
5303 .domain_alloc = intel_iommu_domain_alloc,
5304 .domain_free = intel_iommu_domain_free,
5305 .attach_dev = intel_iommu_attach_device,
5306 .detach_dev = intel_iommu_detach_device,
5307 .map = intel_iommu_map,
5308 .unmap = intel_iommu_unmap,
5309 .map_sg = default_iommu_map_sg,
5310 .iova_to_phys = intel_iommu_iova_to_phys,
5311 .add_device = intel_iommu_add_device,
5312 .remove_device = intel_iommu_remove_device,
5313 .get_resv_regions = intel_iommu_get_resv_regions,
5314 .put_resv_regions = intel_iommu_put_resv_regions,
5315 .device_group = pci_device_group,
5316 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005317};
David Woodhouse9af88142009-02-13 23:18:03 +00005318
Daniel Vetter94526182013-01-20 23:50:13 +01005319static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5320{
5321 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005322 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005323 dmar_map_gfx = 0;
5324}
5325
5326DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5327DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5328DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5329DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5330DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5331DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5332DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5333
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005334static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005335{
5336 /*
5337 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005338 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005339 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005340 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005341 rwbf_quirk = 1;
5342}
5343
5344DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005345DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5346DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5347DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5348DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5349DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5350DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005351
Adam Jacksoneecfd572010-08-25 21:17:34 +01005352#define GGC 0x52
5353#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5354#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5355#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5356#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5357#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5358#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5359#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5360#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5361
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005362static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005363{
5364 unsigned short ggc;
5365
Adam Jacksoneecfd572010-08-25 21:17:34 +01005366 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005367 return;
5368
Adam Jacksoneecfd572010-08-25 21:17:34 +01005369 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005370 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005371 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005372 } else if (dmar_map_gfx) {
5373 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005374 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005375 intel_iommu_strict = 1;
5376 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005377}
5378DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5379DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5380DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5381DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5382
David Woodhousee0fc7e02009-09-30 09:12:17 -07005383/* On Tylersburg chipsets, some BIOSes have been known to enable the
5384 ISOCH DMAR unit for the Azalia sound device, but not give it any
5385 TLB entries, which causes it to deadlock. Check for that. We do
5386 this in a function called from init_dmars(), instead of in a PCI
5387 quirk, because we don't want to print the obnoxious "BIOS broken"
5388 message if VT-d is actually disabled.
5389*/
5390static void __init check_tylersburg_isoch(void)
5391{
5392 struct pci_dev *pdev;
5393 uint32_t vtisochctrl;
5394
5395 /* If there's no Azalia in the system anyway, forget it. */
5396 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5397 if (!pdev)
5398 return;
5399 pci_dev_put(pdev);
5400
5401 /* System Management Registers. Might be hidden, in which case
5402 we can't do the sanity check. But that's OK, because the
5403 known-broken BIOSes _don't_ actually hide it, so far. */
5404 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5405 if (!pdev)
5406 return;
5407
5408 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5409 pci_dev_put(pdev);
5410 return;
5411 }
5412
5413 pci_dev_put(pdev);
5414
5415 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5416 if (vtisochctrl & 1)
5417 return;
5418
5419 /* Drop all bits other than the number of TLB entries */
5420 vtisochctrl &= 0x1c;
5421
5422 /* If we have the recommended number of TLB entries (16), fine. */
5423 if (vtisochctrl == 0x10)
5424 return;
5425
5426 /* Zero TLB entries? You get to ride the short bus to school. */
5427 if (!vtisochctrl) {
5428 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5429 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5430 dmi_get_system_info(DMI_BIOS_VENDOR),
5431 dmi_get_system_info(DMI_BIOS_VERSION),
5432 dmi_get_system_info(DMI_PRODUCT_VERSION));
5433 iommu_identity_mapping |= IDENTMAP_AZALIA;
5434 return;
5435 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005436
5437 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005438 vtisochctrl);
5439}