blob: 934cef924461bc3fbf52995739082ef63c9755a9 [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);
Jon Derrick5823e332017-08-30 15:05:59 -0600879
880#ifdef CONFIG_X86
881 /* VMD child devices currently cannot be handled individually */
882 if (is_vmd(pdev->bus))
883 return NULL;
884#endif
885
Ashok Raj1c387182016-10-21 15:32:05 -0700886 /* VFs aren't listed in scope tables; we need to look up
887 * the PF instead to find the IOMMU. */
888 pf_pdev = pci_physfn(pdev);
889 dev = &pf_pdev->dev;
David Woodhouse156baca2014-03-09 14:00:57 -0700890 segment = pci_domain_nr(pdev->bus);
Rafael J. Wysockica5b74d2015-03-16 23:49:08 +0100891 } else if (has_acpi_companion(dev))
David Woodhouse156baca2014-03-09 14:00:57 -0700892 dev = &ACPI_COMPANION(dev)->dev;
893
Jiang Liu0e242612014-02-19 14:07:34 +0800894 rcu_read_lock();
Jiang Liub683b232014-02-19 14:07:32 +0800895 for_each_active_iommu(iommu, drhd) {
David Woodhouse156baca2014-03-09 14:00:57 -0700896 if (pdev && segment != drhd->segment)
David Woodhouse276dbf992009-04-04 01:45:37 +0100897 continue;
Weidong Hanc7151a82008-12-08 22:51:37 +0800898
Jiang Liub683b232014-02-19 14:07:32 +0800899 for_each_active_dev_scope(drhd->devices,
David Woodhouse156baca2014-03-09 14:00:57 -0700900 drhd->devices_cnt, i, tmp) {
901 if (tmp == dev) {
Ashok Raj1c387182016-10-21 15:32:05 -0700902 /* For a VF use its original BDF# not that of the PF
903 * which we used for the IOMMU lookup. Strictly speaking
904 * we could do this for all PCI devices; we only need to
905 * get the BDF# from the scope table for ACPI matches. */
Koos Vriezen5003ae12017-03-01 21:02:50 +0100906 if (pdev && pdev->is_virtfn)
Ashok Raj1c387182016-10-21 15:32:05 -0700907 goto got_pdev;
908
David Woodhouse156baca2014-03-09 14:00:57 -0700909 *bus = drhd->devices[i].bus;
910 *devfn = drhd->devices[i].devfn;
911 goto out;
912 }
913
914 if (!pdev || !dev_is_pci(tmp))
David Woodhouse832bd852014-03-07 15:08:36 +0000915 continue;
David Woodhouse156baca2014-03-09 14:00:57 -0700916
917 ptmp = to_pci_dev(tmp);
918 if (ptmp->subordinate &&
919 ptmp->subordinate->number <= pdev->bus->number &&
920 ptmp->subordinate->busn_res.end >= pdev->bus->number)
921 goto got_pdev;
David Woodhouse924b6232009-04-04 00:39:25 +0100922 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800923
David Woodhouse156baca2014-03-09 14:00:57 -0700924 if (pdev && drhd->include_all) {
925 got_pdev:
926 *bus = pdev->bus->number;
927 *devfn = pdev->devfn;
Jiang Liub683b232014-02-19 14:07:32 +0800928 goto out;
David Woodhouse156baca2014-03-09 14:00:57 -0700929 }
Weidong Hanc7151a82008-12-08 22:51:37 +0800930 }
Jiang Liub683b232014-02-19 14:07:32 +0800931 iommu = NULL;
David Woodhouse156baca2014-03-09 14:00:57 -0700932 out:
Jiang Liu0e242612014-02-19 14:07:34 +0800933 rcu_read_unlock();
Weidong Hanc7151a82008-12-08 22:51:37 +0800934
Jiang Liub683b232014-02-19 14:07:32 +0800935 return iommu;
Weidong Hanc7151a82008-12-08 22:51:37 +0800936}
937
Weidong Han5331fe62008-12-08 23:00:00 +0800938static void domain_flush_cache(struct dmar_domain *domain,
939 void *addr, int size)
940{
941 if (!domain->iommu_coherency)
942 clflush_cache_range(addr, size);
943}
944
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700945static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
946{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700947 struct context_entry *context;
David Woodhouse03ecc322015-02-13 14:35:21 +0000948 int ret = 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700949 unsigned long flags;
950
951 spin_lock_irqsave(&iommu->lock, flags);
David Woodhouse03ecc322015-02-13 14:35:21 +0000952 context = iommu_context_addr(iommu, bus, devfn, 0);
953 if (context)
954 ret = context_present(context);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700955 spin_unlock_irqrestore(&iommu->lock, flags);
956 return ret;
957}
958
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700959static void free_context_table(struct intel_iommu *iommu)
960{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700961 int i;
962 unsigned long flags;
963 struct context_entry *context;
964
965 spin_lock_irqsave(&iommu->lock, flags);
966 if (!iommu->root_entry) {
967 goto out;
968 }
969 for (i = 0; i < ROOT_ENTRY_NR; i++) {
David Woodhouse03ecc322015-02-13 14:35:21 +0000970 context = iommu_context_addr(iommu, i, 0, 0);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700971 if (context)
972 free_pgtable_page(context);
David Woodhouse03ecc322015-02-13 14:35:21 +0000973
David Woodhousec83b2f22015-06-12 10:15:49 +0100974 if (!ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +0000975 continue;
976
977 context = iommu_context_addr(iommu, i, 0x80, 0);
978 if (context)
979 free_pgtable_page(context);
980
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700981 }
982 free_pgtable_page(iommu->root_entry);
983 iommu->root_entry = NULL;
984out:
985 spin_unlock_irqrestore(&iommu->lock, flags);
986}
987
David Woodhouseb026fd22009-06-28 10:37:25 +0100988static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
David Woodhouse5cf0a762014-03-19 16:07:49 +0000989 unsigned long pfn, int *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700990{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700991 struct dma_pte *parent, *pte = NULL;
992 int level = agaw_to_level(domain->agaw);
Allen Kay4399c8b2011-10-14 12:32:46 -0700993 int offset;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -0700994
995 BUG_ON(!domain->pgd);
Julian Stecklinaf9423602013-10-09 10:03:52 +0200996
Jiang Liu162d1b12014-07-11 14:19:35 +0800997 if (!domain_pfn_supported(domain, pfn))
Julian Stecklinaf9423602013-10-09 10:03:52 +0200998 /* Address beyond IOMMU's addressing capabilities. */
999 return NULL;
1000
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001001 parent = domain->pgd;
1002
David Woodhouse5cf0a762014-03-19 16:07:49 +00001003 while (1) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001004 void *tmp_page;
1005
David Woodhouseb026fd22009-06-28 10:37:25 +01001006 offset = pfn_level_offset(pfn, level);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001007 pte = &parent[offset];
David Woodhouse5cf0a762014-03-19 16:07:49 +00001008 if (!*target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001009 break;
David Woodhouse5cf0a762014-03-19 16:07:49 +00001010 if (level == *target_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001011 break;
1012
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001013 if (!dma_pte_present(pte)) {
David Woodhousec85994e2009-07-01 19:21:24 +01001014 uint64_t pteval;
1015
Suresh Siddha4c923d42009-10-02 11:01:24 -07001016 tmp_page = alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001017
David Woodhouse206a73c2009-07-01 19:30:28 +01001018 if (!tmp_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001019 return NULL;
David Woodhouse206a73c2009-07-01 19:30:28 +01001020
David Woodhousec85994e2009-07-01 19:21:24 +01001021 domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
Benjamin LaHaise64de5af2009-09-16 21:05:55 -04001022 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 +08001023 if (cmpxchg64(&pte->val, 0ULL, pteval))
David Woodhousec85994e2009-07-01 19:21:24 +01001024 /* Someone else set it while we were thinking; use theirs. */
1025 free_pgtable_page(tmp_page);
Yijing Wangeffad4b2014-05-26 20:13:47 +08001026 else
David Woodhousec85994e2009-07-01 19:21:24 +01001027 domain_flush_cache(domain, pte, sizeof(*pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001028 }
David Woodhouse5cf0a762014-03-19 16:07:49 +00001029 if (level == 1)
1030 break;
1031
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001032 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001033 level--;
1034 }
1035
David Woodhouse5cf0a762014-03-19 16:07:49 +00001036 if (!*target_level)
1037 *target_level = level;
1038
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001039 return pte;
1040}
1041
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001042
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001043/* return address's pte at specific level */
David Woodhouse90dcfb52009-06-27 17:14:59 +01001044static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
1045 unsigned long pfn,
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001046 int level, int *large_page)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001047{
1048 struct dma_pte *parent, *pte = NULL;
1049 int total = agaw_to_level(domain->agaw);
1050 int offset;
1051
1052 parent = domain->pgd;
1053 while (level <= total) {
David Woodhouse90dcfb52009-06-27 17:14:59 +01001054 offset = pfn_level_offset(pfn, total);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001055 pte = &parent[offset];
1056 if (level == total)
1057 return pte;
1058
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001059 if (!dma_pte_present(pte)) {
1060 *large_page = total;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001061 break;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001062 }
1063
Yijing Wange16922a2014-05-20 20:37:51 +08001064 if (dma_pte_superpage(pte)) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001065 *large_page = total;
1066 return pte;
1067 }
1068
Mark McLoughlin19c239c2008-11-21 16:56:53 +00001069 parent = phys_to_virt(dma_pte_addr(pte));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001070 total--;
1071 }
1072 return NULL;
1073}
1074
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001075/* clear last level pte, a tlb flush should be followed */
David Woodhouse5cf0a762014-03-19 16:07:49 +00001076static void dma_pte_clear_range(struct dmar_domain *domain,
David Woodhouse595badf2009-06-27 22:09:11 +01001077 unsigned long start_pfn,
1078 unsigned long last_pfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001079{
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001080 unsigned int large_page = 1;
David Woodhouse310a5ab2009-06-28 18:52:20 +01001081 struct dma_pte *first_pte, *pte;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001082
Jiang Liu162d1b12014-07-11 14:19:35 +08001083 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1084 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001085 BUG_ON(start_pfn > last_pfn);
David Woodhouse66eae842009-06-27 19:00:32 +01001086
David Woodhouse04b18e62009-06-27 19:15:01 +01001087 /* we don't need lock here; nobody else touches the iova range */
David Woodhouse59c36282009-09-19 07:36:28 -07001088 do {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001089 large_page = 1;
1090 first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001091 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001092 start_pfn = align_to_level(start_pfn + 1, large_page + 1);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001093 continue;
1094 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001095 do {
David Woodhouse310a5ab2009-06-28 18:52:20 +01001096 dma_clear_pte(pte);
Youquan Song6dd9a7c2011-05-25 19:13:49 +01001097 start_pfn += lvl_to_nr_pages(large_page);
David Woodhouse310a5ab2009-06-28 18:52:20 +01001098 pte++;
David Woodhouse75e6bf92009-07-02 11:21:16 +01001099 } while (start_pfn <= last_pfn && !first_pte_in_page(pte));
1100
David Woodhouse310a5ab2009-06-28 18:52:20 +01001101 domain_flush_cache(domain, first_pte,
1102 (void *)pte - (void *)first_pte);
David Woodhouse59c36282009-09-19 07:36:28 -07001103
1104 } while (start_pfn && start_pfn <= last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001105}
1106
Alex Williamson3269ee02013-06-15 10:27:19 -06001107static void dma_pte_free_level(struct dmar_domain *domain, int level,
David Dillowbc24c572017-06-28 19:42:23 -07001108 int retain_level, struct dma_pte *pte,
1109 unsigned long pfn, unsigned long start_pfn,
1110 unsigned long last_pfn)
Alex Williamson3269ee02013-06-15 10:27:19 -06001111{
1112 pfn = max(start_pfn, pfn);
1113 pte = &pte[pfn_level_offset(pfn, level)];
1114
1115 do {
1116 unsigned long level_pfn;
1117 struct dma_pte *level_pte;
1118
1119 if (!dma_pte_present(pte) || dma_pte_superpage(pte))
1120 goto next;
1121
David Dillowf7116e12017-01-30 19:11:11 -08001122 level_pfn = pfn & level_mask(level);
Alex Williamson3269ee02013-06-15 10:27:19 -06001123 level_pte = phys_to_virt(dma_pte_addr(pte));
1124
David Dillowbc24c572017-06-28 19:42:23 -07001125 if (level > 2) {
1126 dma_pte_free_level(domain, level - 1, retain_level,
1127 level_pte, level_pfn, start_pfn,
1128 last_pfn);
1129 }
Alex Williamson3269ee02013-06-15 10:27:19 -06001130
David Dillowbc24c572017-06-28 19:42:23 -07001131 /*
1132 * Free the page table if we're below the level we want to
1133 * retain and the range covers the entire table.
1134 */
1135 if (level < retain_level && !(start_pfn > level_pfn ||
Alex Williamson08336fd2014-01-21 15:48:18 -08001136 last_pfn < level_pfn + level_size(level) - 1)) {
Alex Williamson3269ee02013-06-15 10:27:19 -06001137 dma_clear_pte(pte);
1138 domain_flush_cache(domain, pte, sizeof(*pte));
1139 free_pgtable_page(level_pte);
1140 }
1141next:
1142 pfn += level_size(level);
1143 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1144}
1145
David Dillowbc24c572017-06-28 19:42:23 -07001146/*
1147 * clear last level (leaf) ptes and free page table pages below the
1148 * level we wish to keep intact.
1149 */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001150static void dma_pte_free_pagetable(struct dmar_domain *domain,
David Woodhoused794dc92009-06-28 00:27:49 +01001151 unsigned long start_pfn,
David Dillowbc24c572017-06-28 19:42:23 -07001152 unsigned long last_pfn,
1153 int retain_level)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001154{
Jiang Liu162d1b12014-07-11 14:19:35 +08001155 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1156 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouse59c36282009-09-19 07:36:28 -07001157 BUG_ON(start_pfn > last_pfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001158
Jiang Liud41a4ad2014-07-11 14:19:34 +08001159 dma_pte_clear_range(domain, start_pfn, last_pfn);
1160
David Woodhousef3a0a522009-06-30 03:40:07 +01001161 /* We don't need lock here; nobody else touches the iova range */
David Dillowbc24c572017-06-28 19:42:23 -07001162 dma_pte_free_level(domain, agaw_to_level(domain->agaw), retain_level,
Alex Williamson3269ee02013-06-15 10:27:19 -06001163 domain->pgd, 0, start_pfn, last_pfn);
David Woodhouse6660c632009-06-27 22:41:00 +01001164
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001165 /* free pgd */
David Woodhoused794dc92009-06-28 00:27:49 +01001166 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001167 free_pgtable_page(domain->pgd);
1168 domain->pgd = NULL;
1169 }
1170}
1171
David Woodhouseea8ea462014-03-05 17:09:32 +00001172/* When a page at a given level is being unlinked from its parent, we don't
1173 need to *modify* it at all. All we need to do is make a list of all the
1174 pages which can be freed just as soon as we've flushed the IOTLB and we
1175 know the hardware page-walk will no longer touch them.
1176 The 'pte' argument is the *parent* PTE, pointing to the page that is to
1177 be freed. */
1178static struct page *dma_pte_list_pagetables(struct dmar_domain *domain,
1179 int level, struct dma_pte *pte,
1180 struct page *freelist)
1181{
1182 struct page *pg;
1183
1184 pg = pfn_to_page(dma_pte_addr(pte) >> PAGE_SHIFT);
1185 pg->freelist = freelist;
1186 freelist = pg;
1187
1188 if (level == 1)
1189 return freelist;
1190
Jiang Liuadeb2592014-04-09 10:20:39 +08001191 pte = page_address(pg);
1192 do {
David Woodhouseea8ea462014-03-05 17:09:32 +00001193 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1194 freelist = dma_pte_list_pagetables(domain, level - 1,
1195 pte, freelist);
Jiang Liuadeb2592014-04-09 10:20:39 +08001196 pte++;
1197 } while (!first_pte_in_page(pte));
David Woodhouseea8ea462014-03-05 17:09:32 +00001198
1199 return freelist;
1200}
1201
1202static struct page *dma_pte_clear_level(struct dmar_domain *domain, int level,
1203 struct dma_pte *pte, unsigned long pfn,
1204 unsigned long start_pfn,
1205 unsigned long last_pfn,
1206 struct page *freelist)
1207{
1208 struct dma_pte *first_pte = NULL, *last_pte = NULL;
1209
1210 pfn = max(start_pfn, pfn);
1211 pte = &pte[pfn_level_offset(pfn, level)];
1212
1213 do {
1214 unsigned long level_pfn;
1215
1216 if (!dma_pte_present(pte))
1217 goto next;
1218
1219 level_pfn = pfn & level_mask(level);
1220
1221 /* If range covers entire pagetable, free it */
1222 if (start_pfn <= level_pfn &&
1223 last_pfn >= level_pfn + level_size(level) - 1) {
1224 /* These suborbinate page tables are going away entirely. Don't
1225 bother to clear them; we're just going to *free* them. */
1226 if (level > 1 && !dma_pte_superpage(pte))
1227 freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist);
1228
1229 dma_clear_pte(pte);
1230 if (!first_pte)
1231 first_pte = pte;
1232 last_pte = pte;
1233 } else if (level > 1) {
1234 /* Recurse down into a level that isn't *entirely* obsolete */
1235 freelist = dma_pte_clear_level(domain, level - 1,
1236 phys_to_virt(dma_pte_addr(pte)),
1237 level_pfn, start_pfn, last_pfn,
1238 freelist);
1239 }
1240next:
1241 pfn += level_size(level);
1242 } while (!first_pte_in_page(++pte) && pfn <= last_pfn);
1243
1244 if (first_pte)
1245 domain_flush_cache(domain, first_pte,
1246 (void *)++last_pte - (void *)first_pte);
1247
1248 return freelist;
1249}
1250
1251/* We can't just free the pages because the IOMMU may still be walking
1252 the page tables, and may have cached the intermediate levels. The
1253 pages can only be freed after the IOTLB flush has been done. */
Joerg Roedelb6904202015-08-13 11:32:18 +02001254static struct page *domain_unmap(struct dmar_domain *domain,
1255 unsigned long start_pfn,
1256 unsigned long last_pfn)
David Woodhouseea8ea462014-03-05 17:09:32 +00001257{
David Woodhouseea8ea462014-03-05 17:09:32 +00001258 struct page *freelist = NULL;
1259
Jiang Liu162d1b12014-07-11 14:19:35 +08001260 BUG_ON(!domain_pfn_supported(domain, start_pfn));
1261 BUG_ON(!domain_pfn_supported(domain, last_pfn));
David Woodhouseea8ea462014-03-05 17:09:32 +00001262 BUG_ON(start_pfn > last_pfn);
1263
1264 /* we don't need lock here; nobody else touches the iova range */
1265 freelist = dma_pte_clear_level(domain, agaw_to_level(domain->agaw),
1266 domain->pgd, 0, start_pfn, last_pfn, NULL);
1267
1268 /* free pgd */
1269 if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
1270 struct page *pgd_page = virt_to_page(domain->pgd);
1271 pgd_page->freelist = freelist;
1272 freelist = pgd_page;
1273
1274 domain->pgd = NULL;
1275 }
1276
1277 return freelist;
1278}
1279
Joerg Roedelb6904202015-08-13 11:32:18 +02001280static void dma_free_pagelist(struct page *freelist)
David Woodhouseea8ea462014-03-05 17:09:32 +00001281{
1282 struct page *pg;
1283
1284 while ((pg = freelist)) {
1285 freelist = pg->freelist;
1286 free_pgtable_page(page_address(pg));
1287 }
1288}
1289
Joerg Roedel13cf0172017-08-11 11:40:10 +02001290static void iova_entry_free(unsigned long data)
1291{
1292 struct page *freelist = (struct page *)data;
1293
1294 dma_free_pagelist(freelist);
1295}
1296
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001297/* iommu handling */
1298static int iommu_alloc_root_entry(struct intel_iommu *iommu)
1299{
1300 struct root_entry *root;
1301 unsigned long flags;
1302
Suresh Siddha4c923d42009-10-02 11:01:24 -07001303 root = (struct root_entry *)alloc_pgtable_page(iommu->node);
Jiang Liuffebeb42014-11-09 22:48:02 +08001304 if (!root) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001305 pr_err("Allocating root entry for %s failed\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08001306 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001307 return -ENOMEM;
Jiang Liuffebeb42014-11-09 22:48:02 +08001308 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001309
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001310 __iommu_flush_cache(iommu, root, ROOT_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001311
1312 spin_lock_irqsave(&iommu->lock, flags);
1313 iommu->root_entry = root;
1314 spin_unlock_irqrestore(&iommu->lock, flags);
1315
1316 return 0;
1317}
1318
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001319static void iommu_set_root_entry(struct intel_iommu *iommu)
1320{
David Woodhouse03ecc322015-02-13 14:35:21 +00001321 u64 addr;
David Woodhousec416daa2009-05-10 20:30:58 +01001322 u32 sts;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001323 unsigned long flag;
1324
David Woodhouse03ecc322015-02-13 14:35:21 +00001325 addr = virt_to_phys(iommu->root_entry);
David Woodhousec83b2f22015-06-12 10:15:49 +01001326 if (ecs_enabled(iommu))
David Woodhouse03ecc322015-02-13 14:35:21 +00001327 addr |= DMA_RTADDR_RTT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001328
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001329 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse03ecc322015-02-13 14:35:21 +00001330 dmar_writeq(iommu->reg + DMAR_RTADDR_REG, addr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001331
David Woodhousec416daa2009-05-10 20:30:58 +01001332 writel(iommu->gcmd | DMA_GCMD_SRTP, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001333
1334 /* Make sure hardware complete it */
1335 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001336 readl, (sts & DMA_GSTS_RTPS), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001337
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001338 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001339}
1340
1341static void iommu_flush_write_buffer(struct intel_iommu *iommu)
1342{
1343 u32 val;
1344 unsigned long flag;
1345
David Woodhouse9af88142009-02-13 23:18:03 +00001346 if (!rwbf_quirk && !cap_rwbf(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001347 return;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001348
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001349 raw_spin_lock_irqsave(&iommu->register_lock, flag);
David Woodhouse462b60f2009-05-10 20:18:18 +01001350 writel(iommu->gcmd | DMA_GCMD_WBF, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001351
1352 /* Make sure hardware complete it */
1353 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001354 readl, (!(val & DMA_GSTS_WBFS)), val);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001355
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001356 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001357}
1358
1359/* return value determine if we need a write buffer flush */
David Woodhouse4c25a2c2009-05-10 17:16:06 +01001360static void __iommu_flush_context(struct intel_iommu *iommu,
1361 u16 did, u16 source_id, u8 function_mask,
1362 u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001363{
1364 u64 val = 0;
1365 unsigned long flag;
1366
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001367 switch (type) {
1368 case DMA_CCMD_GLOBAL_INVL:
1369 val = DMA_CCMD_GLOBAL_INVL;
1370 break;
1371 case DMA_CCMD_DOMAIN_INVL:
1372 val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
1373 break;
1374 case DMA_CCMD_DEVICE_INVL:
1375 val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
1376 | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
1377 break;
1378 default:
1379 BUG();
1380 }
1381 val |= DMA_CCMD_ICC;
1382
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001383 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001384 dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
1385
1386 /* Make sure hardware complete it */
1387 IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
1388 dmar_readq, (!(val & DMA_CCMD_ICC)), val);
1389
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001390 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001391}
1392
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001393/* return value determine if we need a write buffer flush */
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001394static void __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
1395 u64 addr, unsigned int size_order, u64 type)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001396{
1397 int tlb_offset = ecap_iotlb_offset(iommu->ecap);
1398 u64 val = 0, val_iva = 0;
1399 unsigned long flag;
1400
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001401 switch (type) {
1402 case DMA_TLB_GLOBAL_FLUSH:
1403 /* global flush doesn't need set IVA_REG */
1404 val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
1405 break;
1406 case DMA_TLB_DSI_FLUSH:
1407 val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
1408 break;
1409 case DMA_TLB_PSI_FLUSH:
1410 val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
David Woodhouseea8ea462014-03-05 17:09:32 +00001411 /* IH bit is passed in as part of address */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001412 val_iva = size_order | addr;
1413 break;
1414 default:
1415 BUG();
1416 }
1417 /* Note: set drain read/write */
1418#if 0
1419 /*
1420 * This is probably to be super secure.. Looks like we can
1421 * ignore it without any impact.
1422 */
1423 if (cap_read_drain(iommu->cap))
1424 val |= DMA_TLB_READ_DRAIN;
1425#endif
1426 if (cap_write_drain(iommu->cap))
1427 val |= DMA_TLB_WRITE_DRAIN;
1428
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001429 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001430 /* Note: Only uses first TLB reg currently */
1431 if (val_iva)
1432 dmar_writeq(iommu->reg + tlb_offset, val_iva);
1433 dmar_writeq(iommu->reg + tlb_offset + 8, val);
1434
1435 /* Make sure hardware complete it */
1436 IOMMU_WAIT_OP(iommu, tlb_offset + 8,
1437 dmar_readq, (!(val & DMA_TLB_IVT)), val);
1438
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001439 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001440
1441 /* check IOTLB invalidation granularity */
1442 if (DMA_TLB_IAIG(val) == 0)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001443 pr_err("Flush IOTLB failed\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001444 if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001445 pr_debug("TLB flush request %Lx, actual %Lx\n",
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001446 (unsigned long long)DMA_TLB_IIRG(type),
1447 (unsigned long long)DMA_TLB_IAIG(val));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001448}
1449
David Woodhouse64ae8922014-03-09 12:52:30 -07001450static struct device_domain_info *
1451iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1452 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001453{
Yu Zhao93a23a72009-05-18 13:51:37 +08001454 struct device_domain_info *info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001455
Joerg Roedel55d94042015-07-22 16:50:40 +02001456 assert_spin_locked(&device_domain_lock);
1457
Yu Zhao93a23a72009-05-18 13:51:37 +08001458 if (!iommu->qi)
1459 return NULL;
1460
Yu Zhao93a23a72009-05-18 13:51:37 +08001461 list_for_each_entry(info, &domain->devices, link)
Jiang Liuc3b497c2014-07-11 14:19:25 +08001462 if (info->iommu == iommu && info->bus == bus &&
1463 info->devfn == devfn) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001464 if (info->ats_supported && info->dev)
1465 return info;
Yu Zhao93a23a72009-05-18 13:51:37 +08001466 break;
1467 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001468
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001469 return NULL;
Yu Zhao93a23a72009-05-18 13:51:37 +08001470}
1471
Omer Peleg0824c592016-04-20 19:03:35 +03001472static void domain_update_iotlb(struct dmar_domain *domain)
1473{
1474 struct device_domain_info *info;
1475 bool has_iotlb_device = false;
1476
1477 assert_spin_locked(&device_domain_lock);
1478
1479 list_for_each_entry(info, &domain->devices, link) {
1480 struct pci_dev *pdev;
1481
1482 if (!info->dev || !dev_is_pci(info->dev))
1483 continue;
1484
1485 pdev = to_pci_dev(info->dev);
1486 if (pdev->ats_enabled) {
1487 has_iotlb_device = true;
1488 break;
1489 }
1490 }
1491
1492 domain->has_iotlb_device = has_iotlb_device;
1493}
1494
Yu Zhao93a23a72009-05-18 13:51:37 +08001495static void iommu_enable_dev_iotlb(struct device_domain_info *info)
1496{
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001497 struct pci_dev *pdev;
1498
Omer Peleg0824c592016-04-20 19:03:35 +03001499 assert_spin_locked(&device_domain_lock);
1500
David Woodhouse0bcb3e22014-03-06 17:12:03 +00001501 if (!info || !dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001502 return;
1503
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001504 pdev = to_pci_dev(info->dev);
Bjorn Helgaasfb0cc3a2015-07-20 09:10:36 -05001505
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001506#ifdef CONFIG_INTEL_IOMMU_SVM
1507 /* The PCIe spec, in its wisdom, declares that the behaviour of
1508 the device if you enable PASID support after ATS support is
1509 undefined. So always enable PASID support on devices which
1510 have it, even if we can't yet know if we're ever going to
1511 use it. */
1512 if (info->pasid_supported && !pci_enable_pasid(pdev, info->pasid_supported & ~1))
1513 info->pasid_enabled = 1;
1514
1515 if (info->pri_supported && !pci_reset_pri(pdev) && !pci_enable_pri(pdev, 32))
1516 info->pri_enabled = 1;
1517#endif
1518 if (info->ats_supported && !pci_enable_ats(pdev, VTD_PAGE_SHIFT)) {
1519 info->ats_enabled = 1;
Omer Peleg0824c592016-04-20 19:03:35 +03001520 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001521 info->ats_qdep = pci_ats_queue_depth(pdev);
1522 }
Yu Zhao93a23a72009-05-18 13:51:37 +08001523}
1524
1525static void iommu_disable_dev_iotlb(struct device_domain_info *info)
1526{
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001527 struct pci_dev *pdev;
1528
Omer Peleg0824c592016-04-20 19:03:35 +03001529 assert_spin_locked(&device_domain_lock);
1530
Jeremy McNicollda972fb2016-01-14 21:33:06 -08001531 if (!dev_is_pci(info->dev))
Yu Zhao93a23a72009-05-18 13:51:37 +08001532 return;
1533
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001534 pdev = to_pci_dev(info->dev);
1535
1536 if (info->ats_enabled) {
1537 pci_disable_ats(pdev);
1538 info->ats_enabled = 0;
Omer Peleg0824c592016-04-20 19:03:35 +03001539 domain_update_iotlb(info->domain);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001540 }
1541#ifdef CONFIG_INTEL_IOMMU_SVM
1542 if (info->pri_enabled) {
1543 pci_disable_pri(pdev);
1544 info->pri_enabled = 0;
1545 }
1546 if (info->pasid_enabled) {
1547 pci_disable_pasid(pdev);
1548 info->pasid_enabled = 0;
1549 }
1550#endif
Yu Zhao93a23a72009-05-18 13:51:37 +08001551}
1552
1553static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
1554 u64 addr, unsigned mask)
1555{
1556 u16 sid, qdep;
1557 unsigned long flags;
1558 struct device_domain_info *info;
1559
Omer Peleg0824c592016-04-20 19:03:35 +03001560 if (!domain->has_iotlb_device)
1561 return;
1562
Yu Zhao93a23a72009-05-18 13:51:37 +08001563 spin_lock_irqsave(&device_domain_lock, flags);
1564 list_for_each_entry(info, &domain->devices, link) {
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001565 if (!info->ats_enabled)
Yu Zhao93a23a72009-05-18 13:51:37 +08001566 continue;
1567
1568 sid = info->bus << 8 | info->devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01001569 qdep = info->ats_qdep;
Yu Zhao93a23a72009-05-18 13:51:37 +08001570 qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
1571 }
1572 spin_unlock_irqrestore(&device_domain_lock, flags);
1573}
1574
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001575static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
1576 struct dmar_domain *domain,
1577 unsigned long pfn, unsigned int pages,
1578 int ih, int map)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001579{
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001580 unsigned int mask = ilog2(__roundup_pow_of_two(pages));
David Woodhouse03d6a242009-06-28 15:33:46 +01001581 uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02001582 u16 did = domain->iommu_did[iommu->seq_id];
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001583
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001584 BUG_ON(pages == 0);
1585
David Woodhouseea8ea462014-03-05 17:09:32 +00001586 if (ih)
1587 ih = 1 << 6;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001588 /*
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001589 * Fallback to domain selective flush if no PSI support or the size is
1590 * too big.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001591 * PSI requires page size to be 2 ^ x, and the base address is naturally
1592 * aligned to the size
1593 */
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001594 if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
1595 iommu->flush.flush_iotlb(iommu, did, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01001596 DMA_TLB_DSI_FLUSH);
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001597 else
David Woodhouseea8ea462014-03-05 17:09:32 +00001598 iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
Yu Zhao9dd2fe82009-05-18 13:51:36 +08001599 DMA_TLB_PSI_FLUSH);
Yu Zhaobf92df32009-06-29 11:31:45 +08001600
1601 /*
Nadav Amit82653632010-04-01 13:24:40 +03001602 * In caching mode, changes of pages from non-present to present require
1603 * flush. However, device IOTLB doesn't need to be flushed in this case.
Yu Zhaobf92df32009-06-29 11:31:45 +08001604 */
Nadav Amit82653632010-04-01 13:24:40 +03001605 if (!cap_caching_mode(iommu->cap) || !map)
Joerg Roedel9452d5b2015-07-21 10:00:56 +02001606 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1607 addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001608}
1609
Joerg Roedel13cf0172017-08-11 11:40:10 +02001610static void iommu_flush_iova(struct iova_domain *iovad)
1611{
1612 struct dmar_domain *domain;
1613 int idx;
1614
1615 domain = container_of(iovad, struct dmar_domain, iovad);
1616
1617 for_each_domain_iommu(idx, domain) {
1618 struct intel_iommu *iommu = g_iommus[idx];
1619 u16 did = domain->iommu_did[iommu->seq_id];
1620
1621 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1622
1623 if (!cap_caching_mode(iommu->cap))
1624 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1625 0, MAX_AGAW_PFN_WIDTH);
1626 }
1627}
1628
mark grossf8bab732008-02-08 04:18:38 -08001629static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1630{
1631 u32 pmen;
1632 unsigned long flags;
1633
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001634 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001635 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1636 pmen &= ~DMA_PMEN_EPM;
1637 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1638
1639 /* wait for the protected region status bit to clear */
1640 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1641 readl, !(pmen & DMA_PMEN_PRS), pmen);
1642
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001643 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001644}
1645
Jiang Liu2a41cce2014-07-11 14:19:33 +08001646static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001647{
1648 u32 sts;
1649 unsigned long flags;
1650
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001651 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001652 iommu->gcmd |= DMA_GCMD_TE;
1653 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001654
1655 /* Make sure hardware complete it */
1656 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001657 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001658
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001659 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001660}
1661
Jiang Liu2a41cce2014-07-11 14:19:33 +08001662static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001663{
1664 u32 sts;
1665 unsigned long flag;
1666
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001667 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001668 iommu->gcmd &= ~DMA_GCMD_TE;
1669 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1670
1671 /* Make sure hardware complete it */
1672 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001673 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001674
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001675 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001676}
1677
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001678
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001679static int iommu_init_domains(struct intel_iommu *iommu)
1680{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001681 u32 ndomains, nlongs;
1682 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001683
1684 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001685 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001686 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001687 nlongs = BITS_TO_LONGS(ndomains);
1688
Donald Dutile94a91b52009-08-20 16:51:34 -04001689 spin_lock_init(&iommu->lock);
1690
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001691 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1692 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001693 pr_err("%s: Allocating domain id array failed\n",
1694 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001695 return -ENOMEM;
1696 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001697
Wei Yang86f004c2016-05-21 02:41:51 +00001698 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001699 iommu->domains = kzalloc(size, GFP_KERNEL);
1700
1701 if (iommu->domains) {
1702 size = 256 * sizeof(struct dmar_domain *);
1703 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1704 }
1705
1706 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001707 pr_err("%s: Allocating domain array failed\n",
1708 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001709 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001710 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001711 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001712 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001713 return -ENOMEM;
1714 }
1715
Joerg Roedel8bf47812015-07-21 10:41:21 +02001716
1717
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001718 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001719 * If Caching mode is set, then invalid translations are tagged
1720 * with domain-id 0, hence we need to pre-allocate it. We also
1721 * use domain-id 0 as a marker for non-allocated domain-id, so
1722 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001723 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001724 set_bit(0, iommu->domain_ids);
1725
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001726 return 0;
1727}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001728
Jiang Liuffebeb42014-11-09 22:48:02 +08001729static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001730{
Joerg Roedel29a27712015-07-21 17:17:12 +02001731 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001732 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001733
Joerg Roedel29a27712015-07-21 17:17:12 +02001734 if (!iommu->domains || !iommu->domain_ids)
1735 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001736
Joerg Roedelbea64032016-11-08 15:08:26 +01001737again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001738 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001739 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1740 struct dmar_domain *domain;
1741
1742 if (info->iommu != iommu)
1743 continue;
1744
1745 if (!info->dev || !info->domain)
1746 continue;
1747
1748 domain = info->domain;
1749
Joerg Roedelbea64032016-11-08 15:08:26 +01001750 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001751
Joerg Roedelbea64032016-11-08 15:08:26 +01001752 if (!domain_type_is_vm_or_si(domain)) {
1753 /*
1754 * The domain_exit() function can't be called under
1755 * device_domain_lock, as it takes this lock itself.
1756 * So release the lock here and re-run the loop
1757 * afterwards.
1758 */
1759 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001760 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001761 goto again;
1762 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001763 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001764 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001765
1766 if (iommu->gcmd & DMA_GCMD_TE)
1767 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001768}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001769
Jiang Liuffebeb42014-11-09 22:48:02 +08001770static void free_dmar_iommu(struct intel_iommu *iommu)
1771{
1772 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001773 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001774 int i;
1775
1776 for (i = 0; i < elems; i++)
1777 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001778 kfree(iommu->domains);
1779 kfree(iommu->domain_ids);
1780 iommu->domains = NULL;
1781 iommu->domain_ids = NULL;
1782 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001783
Weidong Hand9630fe2008-12-08 11:06:32 +08001784 g_iommus[iommu->seq_id] = NULL;
1785
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001786 /* free context mapping */
1787 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001788
1789#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001790 if (pasid_enabled(iommu)) {
1791 if (ecap_prs(iommu->ecap))
1792 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001793 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001794 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001795#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001796}
1797
Jiang Liuab8dfe22014-07-11 14:19:27 +08001798static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001799{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001800 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001801
1802 domain = alloc_domain_mem();
1803 if (!domain)
1804 return NULL;
1805
Jiang Liuab8dfe22014-07-11 14:19:27 +08001806 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001807 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001808 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001809 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001810 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001811
1812 return domain;
1813}
1814
Joerg Roedeld160aca2015-07-22 11:52:53 +02001815/* Must be called with iommu->lock */
1816static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001817 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001818{
Jiang Liu44bde612014-07-11 14:19:29 +08001819 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001820 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001821
Joerg Roedel55d94042015-07-22 16:50:40 +02001822 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001823 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001824
Joerg Roedel29a27712015-07-21 17:17:12 +02001825 domain->iommu_refcnt[iommu->seq_id] += 1;
1826 domain->iommu_count += 1;
1827 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001828 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001829 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1830
1831 if (num >= ndomains) {
1832 pr_err("%s: No free domain ids\n", iommu->name);
1833 domain->iommu_refcnt[iommu->seq_id] -= 1;
1834 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001835 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001836 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001837
Joerg Roedeld160aca2015-07-22 11:52:53 +02001838 set_bit(num, iommu->domain_ids);
1839 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001840
Joerg Roedeld160aca2015-07-22 11:52:53 +02001841 domain->iommu_did[iommu->seq_id] = num;
1842 domain->nid = iommu->node;
1843
Jiang Liufb170fb2014-07-11 14:19:28 +08001844 domain_update_iommu_cap(domain);
1845 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001846
Joerg Roedel55d94042015-07-22 16:50:40 +02001847 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001848}
1849
1850static int domain_detach_iommu(struct dmar_domain *domain,
1851 struct intel_iommu *iommu)
1852{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001853 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001854
Joerg Roedel55d94042015-07-22 16:50:40 +02001855 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001856 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001857
Joerg Roedel29a27712015-07-21 17:17:12 +02001858 domain->iommu_refcnt[iommu->seq_id] -= 1;
1859 count = --domain->iommu_count;
1860 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001861 num = domain->iommu_did[iommu->seq_id];
1862 clear_bit(num, iommu->domain_ids);
1863 set_iommu_domain(iommu, num, NULL);
1864
Jiang Liufb170fb2014-07-11 14:19:28 +08001865 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001866 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001867 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001868
1869 return count;
1870}
1871
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001872static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001873static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001874
Joseph Cihula51a63e62011-03-21 11:04:24 -07001875static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001876{
1877 struct pci_dev *pdev = NULL;
1878 struct iova *iova;
1879 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001880
Robin Murphy0fb5fe82015-01-12 17:51:16 +00001881 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN,
1882 DMA_32BIT_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001883
Mark Gross8a443df2008-03-04 14:59:31 -08001884 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1885 &reserved_rbtree_key);
1886
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001887 /* IOAPIC ranges shouldn't be accessed by DMA */
1888 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1889 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001890 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001891 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001892 return -ENODEV;
1893 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001894
1895 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1896 for_each_pci_dev(pdev) {
1897 struct resource *r;
1898
1899 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1900 r = &pdev->resource[i];
1901 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1902 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001903 iova = reserve_iova(&reserved_iova_list,
1904 IOVA_PFN(r->start),
1905 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001906 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001907 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001908 return -ENODEV;
1909 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001910 }
1911 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001912 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001913}
1914
1915static void domain_reserve_special_ranges(struct dmar_domain *domain)
1916{
1917 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1918}
1919
1920static inline int guestwidth_to_adjustwidth(int gaw)
1921{
1922 int agaw;
1923 int r = (gaw - 12) % 9;
1924
1925 if (r == 0)
1926 agaw = gaw;
1927 else
1928 agaw = gaw + 9 - r;
1929 if (agaw > 64)
1930 agaw = 64;
1931 return agaw;
1932}
1933
Joerg Roedeldc534b22015-07-22 12:44:02 +02001934static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1935 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001936{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001937 int adjust_width, agaw;
1938 unsigned long sagaw;
Joerg Roedel13cf0172017-08-11 11:40:10 +02001939 int err;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001940
Robin Murphy0fb5fe82015-01-12 17:51:16 +00001941 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
1942 DMA_32BIT_PFN);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001943
1944 err = init_iova_flush_queue(&domain->iovad,
1945 iommu_flush_iova, iova_entry_free);
1946 if (err)
1947 return err;
1948
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001949 domain_reserve_special_ranges(domain);
1950
1951 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001952 if (guest_width > cap_mgaw(iommu->cap))
1953 guest_width = cap_mgaw(iommu->cap);
1954 domain->gaw = guest_width;
1955 adjust_width = guestwidth_to_adjustwidth(guest_width);
1956 agaw = width_to_agaw(adjust_width);
1957 sagaw = cap_sagaw(iommu->cap);
1958 if (!test_bit(agaw, &sagaw)) {
1959 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001960 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001961 agaw = find_next_bit(&sagaw, 5, agaw);
1962 if (agaw >= 5)
1963 return -ENODEV;
1964 }
1965 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001966
Weidong Han8e6040972008-12-08 15:49:06 +08001967 if (ecap_coherent(iommu->ecap))
1968 domain->iommu_coherency = 1;
1969 else
1970 domain->iommu_coherency = 0;
1971
Sheng Yang58c610b2009-03-18 15:33:05 +08001972 if (ecap_sc_support(iommu->ecap))
1973 domain->iommu_snooping = 1;
1974 else
1975 domain->iommu_snooping = 0;
1976
David Woodhouse214e39a2014-03-19 10:38:49 +00001977 if (intel_iommu_superpage)
1978 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1979 else
1980 domain->iommu_superpage = 0;
1981
Suresh Siddha4c923d42009-10-02 11:01:24 -07001982 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001983
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001984 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001985 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001986 if (!domain->pgd)
1987 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001988 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001989 return 0;
1990}
1991
1992static void domain_exit(struct dmar_domain *domain)
1993{
David Woodhouseea8ea462014-03-05 17:09:32 +00001994 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001995
1996 /* Domain 0 is reserved, so dont process it */
1997 if (!domain)
1998 return;
1999
Joerg Roedeld160aca2015-07-22 11:52:53 +02002000 /* Remove associated devices and clear attached or cached domains */
2001 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002002 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02002003 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08002004
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002005 /* destroy iovas */
2006 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002007
David Woodhouseea8ea462014-03-05 17:09:32 +00002008 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002009
David Woodhouseea8ea462014-03-05 17:09:32 +00002010 dma_free_pagelist(freelist);
2011
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002012 free_domain_mem(domain);
2013}
2014
David Woodhouse64ae8922014-03-09 12:52:30 -07002015static int domain_context_mapping_one(struct dmar_domain *domain,
2016 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002017 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002018{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002019 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002020 int translation = CONTEXT_TT_MULTI_LEVEL;
2021 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002022 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002023 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002024 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002025 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002026
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002027 WARN_ON(did == 0);
2028
Joerg Roedel28ccce02015-07-21 14:45:31 +02002029 if (hw_pass_through && domain_type_is_si(domain))
2030 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002031
2032 pr_debug("Set context mapping for %02x:%02x.%d\n",
2033 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002034
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002035 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002036
Joerg Roedel55d94042015-07-22 16:50:40 +02002037 spin_lock_irqsave(&device_domain_lock, flags);
2038 spin_lock(&iommu->lock);
2039
2040 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002041 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002042 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002043 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002044
Joerg Roedel55d94042015-07-22 16:50:40 +02002045 ret = 0;
2046 if (context_present(context))
2047 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002048
Xunlei Pangaec0e862016-12-05 20:09:07 +08002049 /*
2050 * For kdump cases, old valid entries may be cached due to the
2051 * in-flight DMA and copied pgtable, but there is no unmapping
2052 * behaviour for them, thus we need an explicit cache flush for
2053 * the newly-mapped device. For kdump, at this point, the device
2054 * is supposed to finish reset at its driver probe stage, so no
2055 * in-flight DMA will exist, and we don't need to worry anymore
2056 * hereafter.
2057 */
2058 if (context_copied(context)) {
2059 u16 did_old = context_domain_id(context);
2060
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002061 if (did_old >= 0 && did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002062 iommu->flush.flush_context(iommu, did_old,
2063 (((u16)bus) << 8) | devfn,
2064 DMA_CCMD_MASK_NOBIT,
2065 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002066 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2067 DMA_TLB_DSI_FLUSH);
2068 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002069 }
2070
Weidong Hanea6606b2008-12-08 23:08:15 +08002071 pgd = domain->pgd;
2072
Joerg Roedelde24e552015-07-21 14:53:04 +02002073 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002074 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002075
Joerg Roedelde24e552015-07-21 14:53:04 +02002076 /*
2077 * Skip top levels of page tables for iommu which has less agaw
2078 * than default. Unnecessary for PT mode.
2079 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002080 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002081 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002082 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002083 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002084 if (!dma_pte_present(pgd))
2085 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002086 }
2087
David Woodhouse64ae8922014-03-09 12:52:30 -07002088 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002089 if (info && info->ats_supported)
2090 translation = CONTEXT_TT_DEV_IOTLB;
2091 else
2092 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002093
Yu Zhao93a23a72009-05-18 13:51:37 +08002094 context_set_address_root(context, virt_to_phys(pgd));
2095 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002096 } else {
2097 /*
2098 * In pass through mode, AW must be programmed to
2099 * indicate the largest AGAW value supported by
2100 * hardware. And ASR is ignored by hardware.
2101 */
2102 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002103 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002104
2105 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002106 context_set_fault_enable(context);
2107 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002108 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002109
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002110 /*
2111 * It's a non-present to present mapping. If hardware doesn't cache
2112 * non-present entry we only need to flush the write-buffer. If the
2113 * _does_ cache non-present entries, then it does so in the special
2114 * domain #0, which we have to flush:
2115 */
2116 if (cap_caching_mode(iommu->cap)) {
2117 iommu->flush.flush_context(iommu, 0,
2118 (((u16)bus) << 8) | devfn,
2119 DMA_CCMD_MASK_NOBIT,
2120 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002121 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002122 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002123 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002124 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002125 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002126
Joerg Roedel55d94042015-07-22 16:50:40 +02002127 ret = 0;
2128
2129out_unlock:
2130 spin_unlock(&iommu->lock);
2131 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002132
Wei Yang5c365d12016-07-13 13:53:21 +00002133 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002134}
2135
Alex Williamson579305f2014-07-03 09:51:43 -06002136struct domain_context_mapping_data {
2137 struct dmar_domain *domain;
2138 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002139};
2140
2141static int domain_context_mapping_cb(struct pci_dev *pdev,
2142 u16 alias, void *opaque)
2143{
2144 struct domain_context_mapping_data *data = opaque;
2145
2146 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002147 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002148}
2149
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002150static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002151domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002152{
David Woodhouse64ae8922014-03-09 12:52:30 -07002153 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002154 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002155 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002156
David Woodhousee1f167f2014-03-09 15:24:46 -07002157 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002158 if (!iommu)
2159 return -ENODEV;
2160
Alex Williamson579305f2014-07-03 09:51:43 -06002161 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002162 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002163
2164 data.domain = domain;
2165 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002166
2167 return pci_for_each_dma_alias(to_pci_dev(dev),
2168 &domain_context_mapping_cb, &data);
2169}
2170
2171static int domain_context_mapped_cb(struct pci_dev *pdev,
2172 u16 alias, void *opaque)
2173{
2174 struct intel_iommu *iommu = opaque;
2175
2176 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002177}
2178
David Woodhousee1f167f2014-03-09 15:24:46 -07002179static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002180{
Weidong Han5331fe62008-12-08 23:00:00 +08002181 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002182 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002183
David Woodhousee1f167f2014-03-09 15:24:46 -07002184 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002185 if (!iommu)
2186 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002187
Alex Williamson579305f2014-07-03 09:51:43 -06002188 if (!dev_is_pci(dev))
2189 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002190
Alex Williamson579305f2014-07-03 09:51:43 -06002191 return !pci_for_each_dma_alias(to_pci_dev(dev),
2192 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002193}
2194
Fenghua Yuf5329592009-08-04 15:09:37 -07002195/* Returns a number of VTD pages, but aligned to MM page size */
2196static inline unsigned long aligned_nrpages(unsigned long host_addr,
2197 size_t size)
2198{
2199 host_addr &= ~PAGE_MASK;
2200 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2201}
2202
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002203/* Return largest possible superpage level for a given mapping */
2204static inline int hardware_largepage_caps(struct dmar_domain *domain,
2205 unsigned long iov_pfn,
2206 unsigned long phy_pfn,
2207 unsigned long pages)
2208{
2209 int support, level = 1;
2210 unsigned long pfnmerge;
2211
2212 support = domain->iommu_superpage;
2213
2214 /* To use a large page, the virtual *and* physical addresses
2215 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2216 of them will mean we have to use smaller pages. So just
2217 merge them and check both at once. */
2218 pfnmerge = iov_pfn | phy_pfn;
2219
2220 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2221 pages >>= VTD_STRIDE_SHIFT;
2222 if (!pages)
2223 break;
2224 pfnmerge >>= VTD_STRIDE_SHIFT;
2225 level++;
2226 support--;
2227 }
2228 return level;
2229}
2230
David Woodhouse9051aa02009-06-29 12:30:54 +01002231static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2232 struct scatterlist *sg, unsigned long phys_pfn,
2233 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002234{
2235 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002236 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002237 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002238 unsigned int largepage_lvl = 0;
2239 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002240
Jiang Liu162d1b12014-07-11 14:19:35 +08002241 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002242
2243 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2244 return -EINVAL;
2245
2246 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2247
Jiang Liucc4f14a2014-11-26 09:42:10 +08002248 if (!sg) {
2249 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002250 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2251 }
2252
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002253 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002254 uint64_t tmp;
2255
David Woodhousee1605492009-06-29 11:17:38 +01002256 if (!sg_res) {
Fenghua Yuf5329592009-08-04 15:09:37 -07002257 sg_res = aligned_nrpages(sg->offset, sg->length);
David Woodhousee1605492009-06-29 11:17:38 +01002258 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
2259 sg->dma_length = sg->length;
Dan Williams3e6110f2015-12-15 12:54:06 -08002260 pteval = page_to_phys(sg_page(sg)) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002261 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002262 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002263
David Woodhousee1605492009-06-29 11:17:38 +01002264 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002265 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2266
David Woodhouse5cf0a762014-03-19 16:07:49 +00002267 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002268 if (!pte)
2269 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002270 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002271 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002272 unsigned long nr_superpages, end_pfn;
2273
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002274 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002275 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002276
2277 nr_superpages = sg_res / lvl_pages;
2278 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2279
Jiang Liud41a4ad2014-07-11 14:19:34 +08002280 /*
2281 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002282 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002283 * We're adding new large pages, so make sure
2284 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002285 */
David Dillowbc24c572017-06-28 19:42:23 -07002286 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2287 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002288 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002289 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002290 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002291
David Woodhousee1605492009-06-29 11:17:38 +01002292 }
2293 /* We don't need lock here, nobody else
2294 * touches the iova range
2295 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002296 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002297 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002298 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002299 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2300 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002301 if (dumps) {
2302 dumps--;
2303 debug_dma_dump_mappings(NULL);
2304 }
2305 WARN_ON(1);
2306 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002307
2308 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2309
2310 BUG_ON(nr_pages < lvl_pages);
2311 BUG_ON(sg_res < lvl_pages);
2312
2313 nr_pages -= lvl_pages;
2314 iov_pfn += lvl_pages;
2315 phys_pfn += lvl_pages;
2316 pteval += lvl_pages * VTD_PAGE_SIZE;
2317 sg_res -= lvl_pages;
2318
2319 /* If the next PTE would be the first in a new page, then we
2320 need to flush the cache on the entries we've just written.
2321 And then we'll need to recalculate 'pte', so clear it and
2322 let it get set again in the if (!pte) block above.
2323
2324 If we're done (!nr_pages) we need to flush the cache too.
2325
2326 Also if we've been setting superpages, we may need to
2327 recalculate 'pte' and switch back to smaller pages for the
2328 end of the mapping, if the trailing size is not enough to
2329 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002330 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002331 if (!nr_pages || first_pte_in_page(pte) ||
2332 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002333 domain_flush_cache(domain, first_pte,
2334 (void *)pte - (void *)first_pte);
2335 pte = NULL;
2336 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002337
2338 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002339 sg = sg_next(sg);
2340 }
2341 return 0;
2342}
2343
David Woodhouse9051aa02009-06-29 12:30:54 +01002344static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2345 struct scatterlist *sg, unsigned long nr_pages,
2346 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002347{
David Woodhouse9051aa02009-06-29 12:30:54 +01002348 return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
2349}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002350
David Woodhouse9051aa02009-06-29 12:30:54 +01002351static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2352 unsigned long phys_pfn, unsigned long nr_pages,
2353 int prot)
2354{
2355 return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002356}
2357
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002358static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002359{
Filippo Sironi50822192017-08-31 10:58:11 +02002360 unsigned long flags;
2361 struct context_entry *context;
2362 u16 did_old;
2363
Weidong Hanc7151a82008-12-08 22:51:37 +08002364 if (!iommu)
2365 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002366
Filippo Sironi50822192017-08-31 10:58:11 +02002367 spin_lock_irqsave(&iommu->lock, flags);
2368 context = iommu_context_addr(iommu, bus, devfn, 0);
2369 if (!context) {
2370 spin_unlock_irqrestore(&iommu->lock, flags);
2371 return;
2372 }
2373 did_old = context_domain_id(context);
2374 context_clear_entry(context);
2375 __iommu_flush_cache(iommu, context, sizeof(*context));
2376 spin_unlock_irqrestore(&iommu->lock, flags);
2377 iommu->flush.flush_context(iommu,
2378 did_old,
2379 (((u16)bus) << 8) | devfn,
2380 DMA_CCMD_MASK_NOBIT,
2381 DMA_CCMD_DEVICE_INVL);
2382 iommu->flush.flush_iotlb(iommu,
2383 did_old,
2384 0,
2385 0,
2386 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002387}
2388
David Woodhouse109b9b02012-05-25 17:43:02 +01002389static inline void unlink_domain_info(struct device_domain_info *info)
2390{
2391 assert_spin_locked(&device_domain_lock);
2392 list_del(&info->link);
2393 list_del(&info->global);
2394 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002395 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002396}
2397
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002398static void domain_remove_dev_info(struct dmar_domain *domain)
2399{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002400 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002401 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002402
2403 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002404 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002405 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002406 spin_unlock_irqrestore(&device_domain_lock, flags);
2407}
2408
2409/*
2410 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002411 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002412 */
David Woodhouse1525a292014-03-06 16:19:30 +00002413static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002414{
2415 struct device_domain_info *info;
2416
2417 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002418 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002419 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002420 return info->domain;
2421 return NULL;
2422}
2423
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002424static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002425dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2426{
2427 struct device_domain_info *info;
2428
2429 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002430 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002431 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002432 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002433
2434 return NULL;
2435}
2436
Joerg Roedel5db31562015-07-22 12:40:43 +02002437static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2438 int bus, int devfn,
2439 struct device *dev,
2440 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002441{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002442 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002443 struct device_domain_info *info;
2444 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002445 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002446
2447 info = alloc_devinfo_mem();
2448 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002449 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002450
Jiang Liu745f2582014-02-19 14:07:26 +08002451 info->bus = bus;
2452 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002453 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2454 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2455 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002456 info->dev = dev;
2457 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002458 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002459
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002460 if (dev && dev_is_pci(dev)) {
2461 struct pci_dev *pdev = to_pci_dev(info->dev);
2462
2463 if (ecap_dev_iotlb_support(iommu->ecap) &&
2464 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2465 dmar_find_matched_atsr_unit(pdev))
2466 info->ats_supported = 1;
2467
2468 if (ecs_enabled(iommu)) {
2469 if (pasid_enabled(iommu)) {
2470 int features = pci_pasid_features(pdev);
2471 if (features >= 0)
2472 info->pasid_supported = features | 1;
2473 }
2474
2475 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2476 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2477 info->pri_supported = 1;
2478 }
2479 }
2480
Jiang Liu745f2582014-02-19 14:07:26 +08002481 spin_lock_irqsave(&device_domain_lock, flags);
2482 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002483 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002484
2485 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002486 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002487 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002488 if (info2) {
2489 found = info2->domain;
2490 info2->dev = dev;
2491 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002492 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002493
Jiang Liu745f2582014-02-19 14:07:26 +08002494 if (found) {
2495 spin_unlock_irqrestore(&device_domain_lock, flags);
2496 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002497 /* Caller must free the original domain */
2498 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002499 }
2500
Joerg Roedeld160aca2015-07-22 11:52:53 +02002501 spin_lock(&iommu->lock);
2502 ret = domain_attach_iommu(domain, iommu);
2503 spin_unlock(&iommu->lock);
2504
2505 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002506 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302507 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002508 return NULL;
2509 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002510
David Woodhouseb718cd32014-03-09 13:11:33 -07002511 list_add(&info->link, &domain->devices);
2512 list_add(&info->global, &device_domain_list);
2513 if (dev)
2514 dev->archdata.iommu = info;
2515 spin_unlock_irqrestore(&device_domain_lock, flags);
2516
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002517 if (dev && domain_context_mapping(domain, dev)) {
2518 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002519 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002520 return NULL;
2521 }
2522
David Woodhouseb718cd32014-03-09 13:11:33 -07002523 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002524}
2525
Alex Williamson579305f2014-07-03 09:51:43 -06002526static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2527{
2528 *(u16 *)opaque = alias;
2529 return 0;
2530}
2531
Joerg Roedel76208352016-08-25 14:25:12 +02002532static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002533{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002534 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002535 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002536 struct intel_iommu *iommu;
Joerg Roedel08a7f452015-07-23 18:09:11 +02002537 u16 req_id, dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002538 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002539 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002540
David Woodhouse146922e2014-03-09 15:44:17 -07002541 iommu = device_to_iommu(dev, &bus, &devfn);
2542 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002543 return NULL;
2544
Joerg Roedel08a7f452015-07-23 18:09:11 +02002545 req_id = ((u16)bus << 8) | devfn;
2546
Alex Williamson579305f2014-07-03 09:51:43 -06002547 if (dev_is_pci(dev)) {
2548 struct pci_dev *pdev = to_pci_dev(dev);
2549
2550 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2551
2552 spin_lock_irqsave(&device_domain_lock, flags);
2553 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2554 PCI_BUS_NUM(dma_alias),
2555 dma_alias & 0xff);
2556 if (info) {
2557 iommu = info->iommu;
2558 domain = info->domain;
2559 }
2560 spin_unlock_irqrestore(&device_domain_lock, flags);
2561
Joerg Roedel76208352016-08-25 14:25:12 +02002562 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002563 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002564 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002565 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002566
David Woodhouse146922e2014-03-09 15:44:17 -07002567 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002568 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002569 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002570 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002571 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002572 domain_exit(domain);
2573 return NULL;
2574 }
2575
Joerg Roedel76208352016-08-25 14:25:12 +02002576out:
Alex Williamson579305f2014-07-03 09:51:43 -06002577
Joerg Roedel76208352016-08-25 14:25:12 +02002578 return domain;
2579}
2580
2581static struct dmar_domain *set_domain_for_dev(struct device *dev,
2582 struct dmar_domain *domain)
2583{
2584 struct intel_iommu *iommu;
2585 struct dmar_domain *tmp;
2586 u16 req_id, dma_alias;
2587 u8 bus, devfn;
2588
2589 iommu = device_to_iommu(dev, &bus, &devfn);
2590 if (!iommu)
2591 return NULL;
2592
2593 req_id = ((u16)bus << 8) | devfn;
2594
2595 if (dev_is_pci(dev)) {
2596 struct pci_dev *pdev = to_pci_dev(dev);
2597
2598 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2599
2600 /* register PCI DMA alias device */
2601 if (req_id != dma_alias) {
2602 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2603 dma_alias & 0xff, NULL, domain);
2604
2605 if (!tmp || tmp != domain)
2606 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002607 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002608 }
2609
Joerg Roedel5db31562015-07-22 12:40:43 +02002610 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002611 if (!tmp || tmp != domain)
2612 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002613
Joerg Roedel76208352016-08-25 14:25:12 +02002614 return domain;
2615}
2616
2617static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2618{
2619 struct dmar_domain *domain, *tmp;
2620
2621 domain = find_domain(dev);
2622 if (domain)
2623 goto out;
2624
2625 domain = find_or_alloc_domain(dev, gaw);
2626 if (!domain)
2627 goto out;
2628
2629 tmp = set_domain_for_dev(dev, domain);
2630 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002631 domain_exit(domain);
2632 domain = tmp;
2633 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002634
Joerg Roedel76208352016-08-25 14:25:12 +02002635out:
2636
David Woodhouseb718cd32014-03-09 13:11:33 -07002637 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002638}
2639
David Woodhouseb2132032009-06-26 18:50:28 +01002640static int iommu_domain_identity_map(struct dmar_domain *domain,
2641 unsigned long long start,
2642 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002643{
David Woodhousec5395d52009-06-28 16:35:56 +01002644 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2645 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002646
David Woodhousec5395d52009-06-28 16:35:56 +01002647 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2648 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002649 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002650 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002651 }
2652
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002653 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002654 /*
2655 * RMRR range might have overlap with physical memory range,
2656 * clear it first
2657 */
David Woodhousec5395d52009-06-28 16:35:56 +01002658 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002659
David Woodhousec5395d52009-06-28 16:35:56 +01002660 return domain_pfn_mapping(domain, first_vpfn, first_vpfn,
2661 last_vpfn - first_vpfn + 1,
David Woodhouse61df7442009-06-28 11:55:58 +01002662 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002663}
2664
Joerg Roedeld66ce542015-09-23 19:00:10 +02002665static int domain_prepare_identity_map(struct device *dev,
2666 struct dmar_domain *domain,
2667 unsigned long long start,
2668 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002669{
David Woodhouse19943b02009-08-04 16:19:20 +01002670 /* For _hardware_ passthrough, don't bother. But for software
2671 passthrough, we do it anyway -- it may indicate a memory
2672 range which is reserved in E820, so which didn't get set
2673 up to start with in si_domain */
2674 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002675 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2676 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002677 return 0;
2678 }
2679
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002680 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2681 dev_name(dev), start, end);
2682
David Woodhouse5595b522009-12-02 09:21:55 +00002683 if (end < start) {
2684 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2685 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2686 dmi_get_system_info(DMI_BIOS_VENDOR),
2687 dmi_get_system_info(DMI_BIOS_VERSION),
2688 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002689 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002690 }
2691
David Woodhouse2ff729f2009-08-26 14:25:41 +01002692 if (end >> agaw_to_width(domain->agaw)) {
2693 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2694 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2695 agaw_to_width(domain->agaw),
2696 dmi_get_system_info(DMI_BIOS_VENDOR),
2697 dmi_get_system_info(DMI_BIOS_VERSION),
2698 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002699 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002700 }
David Woodhouse19943b02009-08-04 16:19:20 +01002701
Joerg Roedeld66ce542015-09-23 19:00:10 +02002702 return iommu_domain_identity_map(domain, start, end);
2703}
2704
2705static int iommu_prepare_identity_map(struct device *dev,
2706 unsigned long long start,
2707 unsigned long long end)
2708{
2709 struct dmar_domain *domain;
2710 int ret;
2711
2712 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2713 if (!domain)
2714 return -ENOMEM;
2715
2716 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002717 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002718 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002719
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002720 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002721}
2722
2723static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002724 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002725{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002726 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002727 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002728 return iommu_prepare_identity_map(dev, rmrr->base_address,
2729 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002730}
2731
Suresh Siddhad3f13812011-08-23 17:05:25 -07002732#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002733static inline void iommu_prepare_isa(void)
2734{
2735 struct pci_dev *pdev;
2736 int ret;
2737
2738 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2739 if (!pdev)
2740 return;
2741
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002742 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002743 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002744
2745 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002746 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002747
Yijing Wang9b27e822014-05-20 20:37:52 +08002748 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002749}
2750#else
2751static inline void iommu_prepare_isa(void)
2752{
2753 return;
2754}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002755#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002756
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002757static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002758
Matt Kraai071e1372009-08-23 22:30:22 -07002759static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002760{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002761 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002762
Jiang Liuab8dfe22014-07-11 14:19:27 +08002763 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002764 if (!si_domain)
2765 return -EFAULT;
2766
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002767 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2768 domain_exit(si_domain);
2769 return -EFAULT;
2770 }
2771
Joerg Roedel0dc79712015-07-21 15:40:06 +02002772 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002773
David Woodhouse19943b02009-08-04 16:19:20 +01002774 if (hw)
2775 return 0;
2776
David Woodhousec7ab48d2009-06-26 19:10:36 +01002777 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002778 unsigned long start_pfn, end_pfn;
2779 int i;
2780
2781 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2782 ret = iommu_domain_identity_map(si_domain,
2783 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2784 if (ret)
2785 return ret;
2786 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002787 }
2788
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002789 return 0;
2790}
2791
David Woodhouse9b226622014-03-09 14:03:28 -07002792static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002793{
2794 struct device_domain_info *info;
2795
2796 if (likely(!iommu_identity_mapping))
2797 return 0;
2798
David Woodhouse9b226622014-03-09 14:03:28 -07002799 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002800 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2801 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002802
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002803 return 0;
2804}
2805
Joerg Roedel28ccce02015-07-21 14:45:31 +02002806static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002807{
David Woodhouse0ac72662014-03-09 13:19:22 -07002808 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002809 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002810 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002811
David Woodhouse5913c9b2014-03-09 16:27:31 -07002812 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002813 if (!iommu)
2814 return -ENODEV;
2815
Joerg Roedel5db31562015-07-22 12:40:43 +02002816 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002817 if (ndomain != domain)
2818 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002819
2820 return 0;
2821}
2822
David Woodhouse0b9d9752014-03-09 15:48:15 -07002823static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002824{
2825 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002826 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002827 int i;
2828
Jiang Liu0e242612014-02-19 14:07:34 +08002829 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002830 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002831 /*
2832 * Return TRUE if this RMRR contains the device that
2833 * is passed in.
2834 */
2835 for_each_active_dev_scope(rmrr->devices,
2836 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002837 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002838 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002839 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002840 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002841 }
Jiang Liu0e242612014-02-19 14:07:34 +08002842 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002843 return false;
2844}
2845
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002846/*
2847 * There are a couple cases where we need to restrict the functionality of
2848 * devices associated with RMRRs. The first is when evaluating a device for
2849 * identity mapping because problems exist when devices are moved in and out
2850 * of domains and their respective RMRR information is lost. This means that
2851 * a device with associated RMRRs will never be in a "passthrough" domain.
2852 * The second is use of the device through the IOMMU API. This interface
2853 * expects to have full control of the IOVA space for the device. We cannot
2854 * satisfy both the requirement that RMRR access is maintained and have an
2855 * unencumbered IOVA space. We also have no ability to quiesce the device's
2856 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2857 * We therefore prevent devices associated with an RMRR from participating in
2858 * the IOMMU API, which eliminates them from device assignment.
2859 *
2860 * In both cases we assume that PCI USB devices with RMRRs have them largely
2861 * for historical reasons and that the RMRR space is not actively used post
2862 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002863 *
2864 * The same exception is made for graphics devices, with the requirement that
2865 * any use of the RMRR regions will be torn down before assigning the device
2866 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002867 */
2868static bool device_is_rmrr_locked(struct device *dev)
2869{
2870 if (!device_has_rmrr(dev))
2871 return false;
2872
2873 if (dev_is_pci(dev)) {
2874 struct pci_dev *pdev = to_pci_dev(dev);
2875
David Woodhouse18436af2015-03-25 15:05:47 +00002876 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002877 return false;
2878 }
2879
2880 return true;
2881}
2882
David Woodhouse3bdb2592014-03-09 16:03:08 -07002883static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002884{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002885
David Woodhouse3bdb2592014-03-09 16:03:08 -07002886 if (dev_is_pci(dev)) {
2887 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002888
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002889 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002890 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002891
David Woodhouse3bdb2592014-03-09 16:03:08 -07002892 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2893 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002894
David Woodhouse3bdb2592014-03-09 16:03:08 -07002895 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2896 return 1;
2897
2898 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2899 return 0;
2900
2901 /*
2902 * We want to start off with all devices in the 1:1 domain, and
2903 * take them out later if we find they can't access all of memory.
2904 *
2905 * However, we can't do this for PCI devices behind bridges,
2906 * because all PCI devices behind the same bridge will end up
2907 * with the same source-id on their transactions.
2908 *
2909 * Practically speaking, we can't change things around for these
2910 * devices at run-time, because we can't be sure there'll be no
2911 * DMA transactions in flight for any of their siblings.
2912 *
2913 * So PCI devices (unless they're on the root bus) as well as
2914 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2915 * the 1:1 domain, just in _case_ one of their siblings turns out
2916 * not to be able to map all of memory.
2917 */
2918 if (!pci_is_pcie(pdev)) {
2919 if (!pci_is_root_bus(pdev->bus))
2920 return 0;
2921 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2922 return 0;
2923 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2924 return 0;
2925 } else {
2926 if (device_has_rmrr(dev))
2927 return 0;
2928 }
David Woodhouse6941af22009-07-04 18:24:27 +01002929
David Woodhouse3dfc8132009-07-04 19:11:08 +01002930 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002931 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002932 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002933 * take them out of the 1:1 domain later.
2934 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002935 if (!startup) {
2936 /*
2937 * If the device's dma_mask is less than the system's memory
2938 * size then this is not a candidate for identity mapping.
2939 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002940 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002941
David Woodhouse3bdb2592014-03-09 16:03:08 -07002942 if (dev->coherent_dma_mask &&
2943 dev->coherent_dma_mask < dma_mask)
2944 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002945
David Woodhouse3bdb2592014-03-09 16:03:08 -07002946 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002947 }
David Woodhouse6941af22009-07-04 18:24:27 +01002948
2949 return 1;
2950}
2951
David Woodhousecf04eee2014-03-21 16:49:04 +00002952static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2953{
2954 int ret;
2955
2956 if (!iommu_should_identity_map(dev, 1))
2957 return 0;
2958
Joerg Roedel28ccce02015-07-21 14:45:31 +02002959 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002960 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002961 pr_info("%s identity mapping for device %s\n",
2962 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002963 else if (ret == -ENODEV)
2964 /* device not associated with an iommu */
2965 ret = 0;
2966
2967 return ret;
2968}
2969
2970
Matt Kraai071e1372009-08-23 22:30:22 -07002971static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002972{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002973 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002974 struct dmar_drhd_unit *drhd;
2975 struct intel_iommu *iommu;
2976 struct device *dev;
2977 int i;
2978 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002979
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002980 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002981 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2982 if (ret)
2983 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002984 }
2985
David Woodhousecf04eee2014-03-21 16:49:04 +00002986 for_each_active_iommu(iommu, drhd)
2987 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2988 struct acpi_device_physical_node *pn;
2989 struct acpi_device *adev;
2990
2991 if (dev->bus != &acpi_bus_type)
2992 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02002993
David Woodhousecf04eee2014-03-21 16:49:04 +00002994 adev= to_acpi_device(dev);
2995 mutex_lock(&adev->physical_node_lock);
2996 list_for_each_entry(pn, &adev->physical_node_list, node) {
2997 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
2998 if (ret)
2999 break;
3000 }
3001 mutex_unlock(&adev->physical_node_lock);
3002 if (ret)
3003 return ret;
3004 }
3005
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003006 return 0;
3007}
3008
Jiang Liuffebeb42014-11-09 22:48:02 +08003009static void intel_iommu_init_qi(struct intel_iommu *iommu)
3010{
3011 /*
3012 * Start from the sane iommu hardware state.
3013 * If the queued invalidation is already initialized by us
3014 * (for example, while enabling interrupt-remapping) then
3015 * we got the things already rolling from a sane state.
3016 */
3017 if (!iommu->qi) {
3018 /*
3019 * Clear any previous faults.
3020 */
3021 dmar_fault(-1, iommu);
3022 /*
3023 * Disable queued invalidation if supported and already enabled
3024 * before OS handover.
3025 */
3026 dmar_disable_qi(iommu);
3027 }
3028
3029 if (dmar_enable_qi(iommu)) {
3030 /*
3031 * Queued Invalidate not enabled, use Register Based Invalidate
3032 */
3033 iommu->flush.flush_context = __iommu_flush_context;
3034 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003035 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003036 iommu->name);
3037 } else {
3038 iommu->flush.flush_context = qi_flush_context;
3039 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003040 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003041 }
3042}
3043
Joerg Roedel091d42e2015-06-12 11:56:10 +02003044static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003045 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003046 struct context_entry **tbl,
3047 int bus, bool ext)
3048{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003049 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003050 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003051 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003052 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003053 phys_addr_t old_ce_phys;
3054
3055 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003056 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003057
3058 for (devfn = 0; devfn < 256; devfn++) {
3059 /* First calculate the correct index */
3060 idx = (ext ? devfn * 2 : devfn) % 256;
3061
3062 if (idx == 0) {
3063 /* First save what we may have and clean up */
3064 if (new_ce) {
3065 tbl[tbl_idx] = new_ce;
3066 __iommu_flush_cache(iommu, new_ce,
3067 VTD_PAGE_SIZE);
3068 pos = 1;
3069 }
3070
3071 if (old_ce)
3072 iounmap(old_ce);
3073
3074 ret = 0;
3075 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003076 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003077 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003078 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003079
3080 if (!old_ce_phys) {
3081 if (ext && devfn == 0) {
3082 /* No LCTP, try UCTP */
3083 devfn = 0x7f;
3084 continue;
3085 } else {
3086 goto out;
3087 }
3088 }
3089
3090 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003091 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3092 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003093 if (!old_ce)
3094 goto out;
3095
3096 new_ce = alloc_pgtable_page(iommu->node);
3097 if (!new_ce)
3098 goto out_unmap;
3099
3100 ret = 0;
3101 }
3102
3103 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003104 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003105
Joerg Roedelcf484d02015-06-12 12:21:46 +02003106 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003107 continue;
3108
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003109 did = context_domain_id(&ce);
3110 if (did >= 0 && did < cap_ndoms(iommu->cap))
3111 set_bit(did, iommu->domain_ids);
3112
Joerg Roedelcf484d02015-06-12 12:21:46 +02003113 /*
3114 * We need a marker for copied context entries. This
3115 * marker needs to work for the old format as well as
3116 * for extended context entries.
3117 *
3118 * Bit 67 of the context entry is used. In the old
3119 * format this bit is available to software, in the
3120 * extended format it is the PGE bit, but PGE is ignored
3121 * by HW if PASIDs are disabled (and thus still
3122 * available).
3123 *
3124 * So disable PASIDs first and then mark the entry
3125 * copied. This means that we don't copy PASID
3126 * translations from the old kernel, but this is fine as
3127 * faults there are not fatal.
3128 */
3129 context_clear_pasid_enable(&ce);
3130 context_set_copied(&ce);
3131
Joerg Roedel091d42e2015-06-12 11:56:10 +02003132 new_ce[idx] = ce;
3133 }
3134
3135 tbl[tbl_idx + pos] = new_ce;
3136
3137 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3138
3139out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003140 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003141
3142out:
3143 return ret;
3144}
3145
3146static int copy_translation_tables(struct intel_iommu *iommu)
3147{
3148 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003149 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003150 phys_addr_t old_rt_phys;
3151 int ctxt_table_entries;
3152 unsigned long flags;
3153 u64 rtaddr_reg;
3154 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003155 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003156
3157 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3158 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003159 new_ext = !!ecap_ecs(iommu->ecap);
3160
3161 /*
3162 * The RTT bit can only be changed when translation is disabled,
3163 * but disabling translation means to open a window for data
3164 * corruption. So bail out and don't copy anything if we would
3165 * have to change the bit.
3166 */
3167 if (new_ext != ext)
3168 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003169
3170 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3171 if (!old_rt_phys)
3172 return -EINVAL;
3173
Dan Williamsdfddb9692015-10-09 18:16:46 -04003174 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003175 if (!old_rt)
3176 return -ENOMEM;
3177
3178 /* This is too big for the stack - allocate it from slab */
3179 ctxt_table_entries = ext ? 512 : 256;
3180 ret = -ENOMEM;
3181 ctxt_tbls = kzalloc(ctxt_table_entries * sizeof(void *), GFP_KERNEL);
3182 if (!ctxt_tbls)
3183 goto out_unmap;
3184
3185 for (bus = 0; bus < 256; bus++) {
3186 ret = copy_context_table(iommu, &old_rt[bus],
3187 ctxt_tbls, bus, ext);
3188 if (ret) {
3189 pr_err("%s: Failed to copy context table for bus %d\n",
3190 iommu->name, bus);
3191 continue;
3192 }
3193 }
3194
3195 spin_lock_irqsave(&iommu->lock, flags);
3196
3197 /* Context tables are copied, now write them to the root_entry table */
3198 for (bus = 0; bus < 256; bus++) {
3199 int idx = ext ? bus * 2 : bus;
3200 u64 val;
3201
3202 if (ctxt_tbls[idx]) {
3203 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3204 iommu->root_entry[bus].lo = val;
3205 }
3206
3207 if (!ext || !ctxt_tbls[idx + 1])
3208 continue;
3209
3210 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3211 iommu->root_entry[bus].hi = val;
3212 }
3213
3214 spin_unlock_irqrestore(&iommu->lock, flags);
3215
3216 kfree(ctxt_tbls);
3217
3218 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3219
3220 ret = 0;
3221
3222out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003223 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003224
3225 return ret;
3226}
3227
Joseph Cihulab7792602011-05-03 00:08:37 -07003228static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003229{
3230 struct dmar_drhd_unit *drhd;
3231 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003232 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003233 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003234 struct intel_iommu *iommu;
Joerg Roedel13cf0172017-08-11 11:40:10 +02003235 int i, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003236
3237 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003238 * for each drhd
3239 * allocate root
3240 * initialize and program root entry to not present
3241 * endfor
3242 */
3243 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003244 /*
3245 * lock not needed as this is only incremented in the single
3246 * threaded kernel __init code path all other access are read
3247 * only
3248 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003249 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003250 g_num_of_iommus++;
3251 continue;
3252 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003253 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003254 }
3255
Jiang Liuffebeb42014-11-09 22:48:02 +08003256 /* Preallocate enough resources for IOMMU hot-addition */
3257 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3258 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3259
Weidong Hand9630fe2008-12-08 11:06:32 +08003260 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3261 GFP_KERNEL);
3262 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003263 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003264 ret = -ENOMEM;
3265 goto error;
3266 }
3267
Jiang Liu7c919772014-01-06 14:18:18 +08003268 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003269 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003270
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003271 intel_iommu_init_qi(iommu);
3272
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003273 ret = iommu_init_domains(iommu);
3274 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003275 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003276
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003277 init_translation_status(iommu);
3278
Joerg Roedel091d42e2015-06-12 11:56:10 +02003279 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3280 iommu_disable_translation(iommu);
3281 clear_translation_pre_enabled(iommu);
3282 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3283 iommu->name);
3284 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003285
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003286 /*
3287 * TBD:
3288 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003289 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003290 */
3291 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003292 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003293 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003294
Joerg Roedel091d42e2015-06-12 11:56:10 +02003295 if (translation_pre_enabled(iommu)) {
3296 pr_info("Translation already enabled - trying to copy translation structures\n");
3297
3298 ret = copy_translation_tables(iommu);
3299 if (ret) {
3300 /*
3301 * We found the IOMMU with translation
3302 * enabled - but failed to copy over the
3303 * old root-entry table. Try to proceed
3304 * by disabling translation now and
3305 * allocating a clean root-entry table.
3306 * This might cause DMAR faults, but
3307 * probably the dump will still succeed.
3308 */
3309 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3310 iommu->name);
3311 iommu_disable_translation(iommu);
3312 clear_translation_pre_enabled(iommu);
3313 } else {
3314 pr_info("Copied translation tables from previous kernel for %s\n",
3315 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003316 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003317 }
3318 }
3319
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003320 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003321 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003322#ifdef CONFIG_INTEL_IOMMU_SVM
3323 if (pasid_enabled(iommu))
3324 intel_svm_alloc_pasid_tables(iommu);
3325#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003326 }
3327
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003328 /*
3329 * Now that qi is enabled on all iommus, set the root entry and flush
3330 * caches. This is required on some Intel X58 chipsets, otherwise the
3331 * flush_context function will loop forever and the boot hangs.
3332 */
3333 for_each_active_iommu(iommu, drhd) {
3334 iommu_flush_write_buffer(iommu);
3335 iommu_set_root_entry(iommu);
3336 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3337 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3338 }
3339
David Woodhouse19943b02009-08-04 16:19:20 +01003340 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003341 iommu_identity_mapping |= IDENTMAP_ALL;
3342
Suresh Siddhad3f13812011-08-23 17:05:25 -07003343#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003344 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003345#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003346
Ashok Raj21e722c2017-01-30 09:39:53 -08003347 check_tylersburg_isoch();
3348
Joerg Roedel86080cc2015-06-12 12:27:16 +02003349 if (iommu_identity_mapping) {
3350 ret = si_domain_init(hw_pass_through);
3351 if (ret)
3352 goto free_iommu;
3353 }
3354
David Woodhousee0fc7e02009-09-30 09:12:17 -07003355
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003356 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003357 * If we copied translations from a previous kernel in the kdump
3358 * case, we can not assign the devices to domains now, as that
3359 * would eliminate the old mappings. So skip this part and defer
3360 * the assignment to device driver initialization time.
3361 */
3362 if (copied_tables)
3363 goto domains_done;
3364
3365 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003366 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003367 * identity mappings for rmrr, gfx, and isa and may fall back to static
3368 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003369 */
David Woodhouse19943b02009-08-04 16:19:20 +01003370 if (iommu_identity_mapping) {
3371 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3372 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003373 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003374 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003375 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003376 }
David Woodhouse19943b02009-08-04 16:19:20 +01003377 /*
3378 * For each rmrr
3379 * for each dev attached to rmrr
3380 * do
3381 * locate drhd for dev, alloc domain for dev
3382 * allocate free domain
3383 * allocate page table entries for rmrr
3384 * if context not allocated for bus
3385 * allocate and init context
3386 * set present in root table for this bus
3387 * init context with domain, translation etc
3388 * endfor
3389 * endfor
3390 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003391 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003392 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003393 /* some BIOS lists non-exist devices in DMAR table. */
3394 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003395 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003396 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003397 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003398 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003399 }
3400 }
3401
3402 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003403
Joerg Roedela87f4912015-06-12 12:32:54 +02003404domains_done:
3405
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003406 /*
3407 * for each drhd
3408 * enable fault log
3409 * global invalidate context cache
3410 * global invalidate iotlb
3411 * enable translation
3412 */
Jiang Liu7c919772014-01-06 14:18:18 +08003413 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003414 if (drhd->ignored) {
3415 /*
3416 * we always have to disable PMRs or DMA may fail on
3417 * this device
3418 */
3419 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003420 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003421 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003422 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003423
3424 iommu_flush_write_buffer(iommu);
3425
David Woodhousea222a7f2015-10-07 23:35:18 +01003426#ifdef CONFIG_INTEL_IOMMU_SVM
3427 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3428 ret = intel_svm_enable_prq(iommu);
3429 if (ret)
3430 goto free_iommu;
3431 }
3432#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003433 ret = dmar_set_interrupt(iommu);
3434 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003435 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003436
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003437 if (!translation_pre_enabled(iommu))
3438 iommu_enable_translation(iommu);
3439
David Woodhouseb94996c2009-09-19 15:28:12 -07003440 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003441 }
3442
3443 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003444
3445free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003446 for_each_active_iommu(iommu, drhd) {
3447 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003448 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003449 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003450
Weidong Hand9630fe2008-12-08 11:06:32 +08003451 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003452
Jiang Liu989d51f2014-02-19 14:07:21 +08003453error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003454 return ret;
3455}
3456
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003457/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003458static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003459 struct dmar_domain *domain,
3460 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003461{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003462 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003463
David Woodhouse875764d2009-06-28 21:20:51 +01003464 /* Restrict dma_mask to the width that the iommu can handle */
3465 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003466 /* Ensure we reserve the whole size-aligned region */
3467 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003468
3469 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003470 /*
3471 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003472 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003473 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003474 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003475 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3476 IOVA_PFN(DMA_BIT_MASK(32)));
3477 if (iova_pfn)
3478 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003479 }
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003480 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages, IOVA_PFN(dma_mask));
3481 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003482 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003483 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003484 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003485 }
3486
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003487 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003488}
3489
Peter Xub316d022017-05-22 18:28:51 +08003490static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003491{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003492 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003493 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003494 struct device *i_dev;
3495 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003496
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003497 domain = find_domain(dev);
3498 if (domain)
3499 goto out;
3500
3501 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3502 if (!domain)
3503 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003504
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003505 /* We have a new domain - setup possible RMRRs for the device */
3506 rcu_read_lock();
3507 for_each_rmrr_units(rmrr) {
3508 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3509 i, i_dev) {
3510 if (i_dev != dev)
3511 continue;
3512
3513 ret = domain_prepare_identity_map(dev, domain,
3514 rmrr->base_address,
3515 rmrr->end_address);
3516 if (ret)
3517 dev_err(dev, "Mapping reserved region failed\n");
3518 }
3519 }
3520 rcu_read_unlock();
3521
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003522 tmp = set_domain_for_dev(dev, domain);
3523 if (!tmp || domain != tmp) {
3524 domain_exit(domain);
3525 domain = tmp;
3526 }
3527
3528out:
3529
3530 if (!domain)
3531 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3532
3533
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003534 return domain;
3535}
3536
David Woodhouseecb509e2014-03-09 16:29:55 -07003537/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003538static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003539{
3540 int found;
3541
David Woodhouse3d891942014-03-06 15:59:26 +00003542 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003543 return 1;
3544
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003545 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003546 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003547
David Woodhouse9b226622014-03-09 14:03:28 -07003548 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003549 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003550 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003551 return 1;
3552 else {
3553 /*
3554 * 32 bit DMA is removed from si_domain and fall back
3555 * to non-identity mapping.
3556 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003557 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003558 pr_info("32bit %s uses non-identity mapping\n",
3559 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003560 return 0;
3561 }
3562 } else {
3563 /*
3564 * In case of a detached 64 bit DMA device from vm, the device
3565 * is put into si_domain for identity mapping.
3566 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003567 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003568 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003569 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003570 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003571 pr_info("64bit %s uses identity mapping\n",
3572 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003573 return 1;
3574 }
3575 }
3576 }
3577
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003578 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003579}
3580
David Woodhouse5040a912014-03-09 16:14:00 -07003581static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003582 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003583{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003584 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003585 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003586 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003587 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003588 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003589 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003590 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003591
3592 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003593
David Woodhouse5040a912014-03-09 16:14:00 -07003594 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003595 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003596
David Woodhouse5040a912014-03-09 16:14:00 -07003597 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003598 if (!domain)
3599 return 0;
3600
Weidong Han8c11e792008-12-08 15:29:22 +08003601 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003602 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003603
Omer Peleg2aac6302016-04-20 11:33:57 +03003604 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3605 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003606 goto error;
3607
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003608 /*
3609 * Check if DMAR supports zero-length reads on write only
3610 * mappings..
3611 */
3612 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003613 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003614 prot |= DMA_PTE_READ;
3615 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3616 prot |= DMA_PTE_WRITE;
3617 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003618 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003619 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003620 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003621 * is not a big problem
3622 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003623 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003624 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003625 if (ret)
3626 goto error;
3627
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003628 /* it's a non-present to present mapping. Only flush if caching mode */
3629 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003630 iommu_flush_iotlb_psi(iommu, domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003631 mm_to_dma_pfn(iova_pfn),
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003632 size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003633 else
Weidong Han8c11e792008-12-08 15:29:22 +08003634 iommu_flush_write_buffer(iommu);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003635
Omer Peleg2aac6302016-04-20 11:33:57 +03003636 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003637 start_paddr += paddr & ~PAGE_MASK;
3638 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003639
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003640error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003641 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003642 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003643 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003644 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003645 return 0;
3646}
3647
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003648static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3649 unsigned long offset, size_t size,
3650 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003651 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003652{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003653 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003654 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003655}
3656
Omer Peleg769530e2016-04-20 11:33:25 +03003657static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003658{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003659 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003660 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003661 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003662 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003663 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003664 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003665
David Woodhouse73676832009-07-04 14:08:36 +01003666 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003667 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003668
David Woodhouse1525a292014-03-06 16:19:30 +00003669 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003670 BUG_ON(!domain);
3671
Weidong Han8c11e792008-12-08 15:29:22 +08003672 iommu = domain_get_iommu(domain);
3673
Omer Peleg2aac6302016-04-20 11:33:57 +03003674 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003675
Omer Peleg769530e2016-04-20 11:33:25 +03003676 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003677 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003678 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003679
David Woodhoused794dc92009-06-28 00:27:49 +01003680 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003681 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003682
David Woodhouseea8ea462014-03-05 17:09:32 +00003683 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003684
mark gross5e0d2a62008-03-04 15:22:08 -08003685 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003686 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003687 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003688 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003689 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003690 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003691 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003692 queue_iova(&domain->iovad, iova_pfn, nrpages,
3693 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003694 /*
3695 * queue up the release of the unmap to save the 1/6th of the
3696 * cpu used up by the iotlb flush operation...
3697 */
mark gross5e0d2a62008-03-04 15:22:08 -08003698 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003699}
3700
Jiang Liud41a4ad2014-07-11 14:19:34 +08003701static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3702 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003703 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003704{
Omer Peleg769530e2016-04-20 11:33:25 +03003705 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003706}
3707
David Woodhouse5040a912014-03-09 16:14:00 -07003708static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003709 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003710 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003711{
Akinobu Mita36746432014-06-04 16:06:51 -07003712 struct page *page = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003713 int order;
3714
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003715 size = PAGE_ALIGN(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003716 order = get_order(size);
Alex Williamsone8bb9102009-11-04 15:59:34 -07003717
David Woodhouse5040a912014-03-09 16:14:00 -07003718 if (!iommu_no_mapping(dev))
Alex Williamsone8bb9102009-11-04 15:59:34 -07003719 flags &= ~(GFP_DMA | GFP_DMA32);
David Woodhouse5040a912014-03-09 16:14:00 -07003720 else if (dev->coherent_dma_mask < dma_get_required_mask(dev)) {
3721 if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
Alex Williamsone8bb9102009-11-04 15:59:34 -07003722 flags |= GFP_DMA;
3723 else
3724 flags |= GFP_DMA32;
3725 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003726
Mel Gormand0164ad2015-11-06 16:28:21 -08003727 if (gfpflags_allow_blocking(flags)) {
Akinobu Mita36746432014-06-04 16:06:51 -07003728 unsigned int count = size >> PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003729
Lucas Stach712c6042017-02-24 14:58:44 -08003730 page = dma_alloc_from_contiguous(dev, count, order, flags);
Akinobu Mita36746432014-06-04 16:06:51 -07003731 if (page && iommu_no_mapping(dev) &&
3732 page_to_phys(page) + size > dev->coherent_dma_mask) {
3733 dma_release_from_contiguous(dev, page, count);
3734 page = NULL;
3735 }
3736 }
3737
3738 if (!page)
3739 page = alloc_pages(flags, order);
3740 if (!page)
3741 return NULL;
3742 memset(page_address(page), 0, size);
3743
3744 *dma_handle = __intel_map_single(dev, page_to_phys(page), size,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003745 DMA_BIDIRECTIONAL,
David Woodhouse5040a912014-03-09 16:14:00 -07003746 dev->coherent_dma_mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003747 if (*dma_handle)
Akinobu Mita36746432014-06-04 16:06:51 -07003748 return page_address(page);
3749 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3750 __free_pages(page, order);
3751
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003752 return NULL;
3753}
3754
David Woodhouse5040a912014-03-09 16:14:00 -07003755static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003756 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003757{
3758 int order;
Akinobu Mita36746432014-06-04 16:06:51 -07003759 struct page *page = virt_to_page(vaddr);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003760
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003761 size = PAGE_ALIGN(size);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003762 order = get_order(size);
3763
Omer Peleg769530e2016-04-20 11:33:25 +03003764 intel_unmap(dev, dma_handle, size);
Akinobu Mita36746432014-06-04 16:06:51 -07003765 if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT))
3766 __free_pages(page, order);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003767}
3768
David Woodhouse5040a912014-03-09 16:14:00 -07003769static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003770 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003771 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003772{
Omer Peleg769530e2016-04-20 11:33:25 +03003773 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3774 unsigned long nrpages = 0;
3775 struct scatterlist *sg;
3776 int i;
3777
3778 for_each_sg(sglist, sg, nelems, i) {
3779 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3780 }
3781
3782 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003783}
3784
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003785static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003786 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003787{
3788 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003789 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003790
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003791 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003792 BUG_ON(!sg_page(sg));
Dan Williams3e6110f2015-12-15 12:54:06 -08003793 sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003794 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003795 }
3796 return nelems;
3797}
3798
David Woodhouse5040a912014-03-09 16:14:00 -07003799static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003800 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003801{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003802 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003803 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003804 size_t size = 0;
3805 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003806 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003807 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003808 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003809 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003810 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003811
3812 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003813 if (iommu_no_mapping(dev))
3814 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003815
David Woodhouse5040a912014-03-09 16:14:00 -07003816 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003817 if (!domain)
3818 return 0;
3819
Weidong Han8c11e792008-12-08 15:29:22 +08003820 iommu = domain_get_iommu(domain);
3821
David Woodhouseb536d242009-06-28 14:49:31 +01003822 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003823 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003824
Omer Peleg2aac6302016-04-20 11:33:57 +03003825 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003826 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003827 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003828 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003829 return 0;
3830 }
3831
3832 /*
3833 * Check if DMAR supports zero-length reads on write only
3834 * mappings..
3835 */
3836 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003837 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003838 prot |= DMA_PTE_READ;
3839 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3840 prot |= DMA_PTE_WRITE;
3841
Omer Peleg2aac6302016-04-20 11:33:57 +03003842 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003843
Fenghua Yuf5329592009-08-04 15:09:37 -07003844 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003845 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003846 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003847 start_vpfn + size - 1,
3848 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003849 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003850 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003851 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003852
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003853 /* it's a non-present to present mapping. Only flush if caching mode */
3854 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003855 iommu_flush_iotlb_psi(iommu, domain, start_vpfn, size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003856 else
Weidong Han8c11e792008-12-08 15:29:22 +08003857 iommu_flush_write_buffer(iommu);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003858
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003859 return nelems;
3860}
3861
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003862static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3863{
3864 return !dma_addr;
3865}
3866
Arvind Yadav01e19322017-06-28 16:39:32 +05303867const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003868 .alloc = intel_alloc_coherent,
3869 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003870 .map_sg = intel_map_sg,
3871 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003872 .map_page = intel_map_page,
3873 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003874 .mapping_error = intel_mapping_error,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003875#ifdef CONFIG_X86
3876 .dma_supported = x86_dma_supported,
3877#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003878};
3879
3880static inline int iommu_domain_cache_init(void)
3881{
3882 int ret = 0;
3883
3884 iommu_domain_cache = kmem_cache_create("iommu_domain",
3885 sizeof(struct dmar_domain),
3886 0,
3887 SLAB_HWCACHE_ALIGN,
3888
3889 NULL);
3890 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003891 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003892 ret = -ENOMEM;
3893 }
3894
3895 return ret;
3896}
3897
3898static inline int iommu_devinfo_cache_init(void)
3899{
3900 int ret = 0;
3901
3902 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3903 sizeof(struct device_domain_info),
3904 0,
3905 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003906 NULL);
3907 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003908 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003909 ret = -ENOMEM;
3910 }
3911
3912 return ret;
3913}
3914
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003915static int __init iommu_init_mempool(void)
3916{
3917 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003918 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003919 if (ret)
3920 return ret;
3921
3922 ret = iommu_domain_cache_init();
3923 if (ret)
3924 goto domain_error;
3925
3926 ret = iommu_devinfo_cache_init();
3927 if (!ret)
3928 return ret;
3929
3930 kmem_cache_destroy(iommu_domain_cache);
3931domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003932 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003933
3934 return -ENOMEM;
3935}
3936
3937static void __init iommu_exit_mempool(void)
3938{
3939 kmem_cache_destroy(iommu_devinfo_cache);
3940 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003941 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003942}
3943
Dan Williams556ab452010-07-23 15:47:56 -07003944static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3945{
3946 struct dmar_drhd_unit *drhd;
3947 u32 vtbar;
3948 int rc;
3949
3950 /* We know that this device on this chipset has its own IOMMU.
3951 * If we find it under a different IOMMU, then the BIOS is lying
3952 * to us. Hope that the IOMMU for this device is actually
3953 * disabled, and it needs no translation...
3954 */
3955 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3956 if (rc) {
3957 /* "can't" happen */
3958 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3959 return;
3960 }
3961 vtbar &= 0xffff0000;
3962
3963 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3964 drhd = dmar_find_matched_drhd_unit(pdev);
3965 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3966 TAINT_FIRMWARE_WORKAROUND,
3967 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3968 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3969}
3970DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3971
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003972static void __init init_no_remapping_devices(void)
3973{
3974 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003975 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003976 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003977
3978 for_each_drhd_unit(drhd) {
3979 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003980 for_each_active_dev_scope(drhd->devices,
3981 drhd->devices_cnt, i, dev)
3982 break;
David Woodhouse832bd852014-03-07 15:08:36 +00003983 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003984 if (i == drhd->devices_cnt)
3985 drhd->ignored = 1;
3986 }
3987 }
3988
Jiang Liu7c919772014-01-06 14:18:18 +08003989 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08003990 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003991 continue;
3992
Jiang Liub683b232014-02-19 14:07:32 +08003993 for_each_active_dev_scope(drhd->devices,
3994 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003995 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003996 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003997 if (i < drhd->devices_cnt)
3998 continue;
3999
David Woodhousec0771df2011-10-14 20:59:46 +01004000 /* This IOMMU has *only* gfx devices. Either bypass it or
4001 set the gfx_mapped flag, as appropriate */
4002 if (dmar_map_gfx) {
4003 intel_iommu_gfx_mapped = 1;
4004 } else {
4005 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004006 for_each_active_dev_scope(drhd->devices,
4007 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004008 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004009 }
4010 }
4011}
4012
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004013#ifdef CONFIG_SUSPEND
4014static int init_iommu_hw(void)
4015{
4016 struct dmar_drhd_unit *drhd;
4017 struct intel_iommu *iommu = NULL;
4018
4019 for_each_active_iommu(iommu, drhd)
4020 if (iommu->qi)
4021 dmar_reenable_qi(iommu);
4022
Joseph Cihulab7792602011-05-03 00:08:37 -07004023 for_each_iommu(iommu, drhd) {
4024 if (drhd->ignored) {
4025 /*
4026 * we always have to disable PMRs or DMA may fail on
4027 * this device
4028 */
4029 if (force_on)
4030 iommu_disable_protect_mem_regions(iommu);
4031 continue;
4032 }
4033
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004034 iommu_flush_write_buffer(iommu);
4035
4036 iommu_set_root_entry(iommu);
4037
4038 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004039 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004040 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4041 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004042 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004043 }
4044
4045 return 0;
4046}
4047
4048static void iommu_flush_all(void)
4049{
4050 struct dmar_drhd_unit *drhd;
4051 struct intel_iommu *iommu;
4052
4053 for_each_active_iommu(iommu, drhd) {
4054 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004055 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004056 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004057 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004058 }
4059}
4060
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004061static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004062{
4063 struct dmar_drhd_unit *drhd;
4064 struct intel_iommu *iommu = NULL;
4065 unsigned long flag;
4066
4067 for_each_active_iommu(iommu, drhd) {
4068 iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
4069 GFP_ATOMIC);
4070 if (!iommu->iommu_state)
4071 goto nomem;
4072 }
4073
4074 iommu_flush_all();
4075
4076 for_each_active_iommu(iommu, drhd) {
4077 iommu_disable_translation(iommu);
4078
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004079 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004080
4081 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4082 readl(iommu->reg + DMAR_FECTL_REG);
4083 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4084 readl(iommu->reg + DMAR_FEDATA_REG);
4085 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4086 readl(iommu->reg + DMAR_FEADDR_REG);
4087 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4088 readl(iommu->reg + DMAR_FEUADDR_REG);
4089
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004090 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004091 }
4092 return 0;
4093
4094nomem:
4095 for_each_active_iommu(iommu, drhd)
4096 kfree(iommu->iommu_state);
4097
4098 return -ENOMEM;
4099}
4100
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004101static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004102{
4103 struct dmar_drhd_unit *drhd;
4104 struct intel_iommu *iommu = NULL;
4105 unsigned long flag;
4106
4107 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004108 if (force_on)
4109 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4110 else
4111 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004112 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004113 }
4114
4115 for_each_active_iommu(iommu, drhd) {
4116
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004117 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004118
4119 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4120 iommu->reg + DMAR_FECTL_REG);
4121 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4122 iommu->reg + DMAR_FEDATA_REG);
4123 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4124 iommu->reg + DMAR_FEADDR_REG);
4125 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4126 iommu->reg + DMAR_FEUADDR_REG);
4127
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004128 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004129 }
4130
4131 for_each_active_iommu(iommu, drhd)
4132 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004133}
4134
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004135static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004136 .resume = iommu_resume,
4137 .suspend = iommu_suspend,
4138};
4139
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004140static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004141{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004142 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004143}
4144
4145#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004146static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004147#endif /* CONFIG_PM */
4148
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004149
Jiang Liuc2a0b532014-11-09 22:47:56 +08004150int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004151{
4152 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004153 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004154 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004155 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004156
4157 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4158 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004159 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004160
4161 rmrru->hdr = header;
4162 rmrr = (struct acpi_dmar_reserved_memory *)header;
4163 rmrru->base_address = rmrr->base_address;
4164 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004165
4166 length = rmrr->end_address - rmrr->base_address + 1;
4167 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4168 IOMMU_RESV_DIRECT);
4169 if (!rmrru->resv)
4170 goto free_rmrru;
4171
Jiang Liu2e455282014-02-19 14:07:36 +08004172 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4173 ((void *)rmrr) + rmrr->header.length,
4174 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004175 if (rmrru->devices_cnt && rmrru->devices == NULL)
4176 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004177
Jiang Liu2e455282014-02-19 14:07:36 +08004178 list_add(&rmrru->list, &dmar_rmrr_units);
4179
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004180 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004181free_all:
4182 kfree(rmrru->resv);
4183free_rmrru:
4184 kfree(rmrru);
4185out:
4186 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004187}
4188
Jiang Liu6b197242014-11-09 22:47:58 +08004189static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4190{
4191 struct dmar_atsr_unit *atsru;
4192 struct acpi_dmar_atsr *tmp;
4193
4194 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4195 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4196 if (atsr->segment != tmp->segment)
4197 continue;
4198 if (atsr->header.length != tmp->header.length)
4199 continue;
4200 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4201 return atsru;
4202 }
4203
4204 return NULL;
4205}
4206
4207int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004208{
4209 struct acpi_dmar_atsr *atsr;
4210 struct dmar_atsr_unit *atsru;
4211
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004212 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004213 return 0;
4214
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004215 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004216 atsru = dmar_find_atsr(atsr);
4217 if (atsru)
4218 return 0;
4219
4220 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004221 if (!atsru)
4222 return -ENOMEM;
4223
Jiang Liu6b197242014-11-09 22:47:58 +08004224 /*
4225 * If memory is allocated from slab by ACPI _DSM method, we need to
4226 * copy the memory content because the memory buffer will be freed
4227 * on return.
4228 */
4229 atsru->hdr = (void *)(atsru + 1);
4230 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004231 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004232 if (!atsru->include_all) {
4233 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4234 (void *)atsr + atsr->header.length,
4235 &atsru->devices_cnt);
4236 if (atsru->devices_cnt && atsru->devices == NULL) {
4237 kfree(atsru);
4238 return -ENOMEM;
4239 }
4240 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004241
Jiang Liu0e242612014-02-19 14:07:34 +08004242 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004243
4244 return 0;
4245}
4246
Jiang Liu9bdc5312014-01-06 14:18:27 +08004247static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4248{
4249 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4250 kfree(atsru);
4251}
4252
Jiang Liu6b197242014-11-09 22:47:58 +08004253int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4254{
4255 struct acpi_dmar_atsr *atsr;
4256 struct dmar_atsr_unit *atsru;
4257
4258 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4259 atsru = dmar_find_atsr(atsr);
4260 if (atsru) {
4261 list_del_rcu(&atsru->list);
4262 synchronize_rcu();
4263 intel_iommu_free_atsr(atsru);
4264 }
4265
4266 return 0;
4267}
4268
4269int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4270{
4271 int i;
4272 struct device *dev;
4273 struct acpi_dmar_atsr *atsr;
4274 struct dmar_atsr_unit *atsru;
4275
4276 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4277 atsru = dmar_find_atsr(atsr);
4278 if (!atsru)
4279 return 0;
4280
Linus Torvalds194dc872016-07-27 20:03:31 -07004281 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004282 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4283 i, dev)
4284 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004285 }
Jiang Liu6b197242014-11-09 22:47:58 +08004286
4287 return 0;
4288}
4289
Jiang Liuffebeb42014-11-09 22:48:02 +08004290static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4291{
4292 int sp, ret = 0;
4293 struct intel_iommu *iommu = dmaru->iommu;
4294
4295 if (g_iommus[iommu->seq_id])
4296 return 0;
4297
4298 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004299 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004300 iommu->name);
4301 return -ENXIO;
4302 }
4303 if (!ecap_sc_support(iommu->ecap) &&
4304 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004305 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004306 iommu->name);
4307 return -ENXIO;
4308 }
4309 sp = domain_update_iommu_superpage(iommu) - 1;
4310 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004311 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004312 iommu->name);
4313 return -ENXIO;
4314 }
4315
4316 /*
4317 * Disable translation if already enabled prior to OS handover.
4318 */
4319 if (iommu->gcmd & DMA_GCMD_TE)
4320 iommu_disable_translation(iommu);
4321
4322 g_iommus[iommu->seq_id] = iommu;
4323 ret = iommu_init_domains(iommu);
4324 if (ret == 0)
4325 ret = iommu_alloc_root_entry(iommu);
4326 if (ret)
4327 goto out;
4328
David Woodhouse8a94ade2015-03-24 14:54:56 +00004329#ifdef CONFIG_INTEL_IOMMU_SVM
4330 if (pasid_enabled(iommu))
4331 intel_svm_alloc_pasid_tables(iommu);
4332#endif
4333
Jiang Liuffebeb42014-11-09 22:48:02 +08004334 if (dmaru->ignored) {
4335 /*
4336 * we always have to disable PMRs or DMA may fail on this device
4337 */
4338 if (force_on)
4339 iommu_disable_protect_mem_regions(iommu);
4340 return 0;
4341 }
4342
4343 intel_iommu_init_qi(iommu);
4344 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004345
4346#ifdef CONFIG_INTEL_IOMMU_SVM
4347 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4348 ret = intel_svm_enable_prq(iommu);
4349 if (ret)
4350 goto disable_iommu;
4351 }
4352#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004353 ret = dmar_set_interrupt(iommu);
4354 if (ret)
4355 goto disable_iommu;
4356
4357 iommu_set_root_entry(iommu);
4358 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4359 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4360 iommu_enable_translation(iommu);
4361
Jiang Liuffebeb42014-11-09 22:48:02 +08004362 iommu_disable_protect_mem_regions(iommu);
4363 return 0;
4364
4365disable_iommu:
4366 disable_dmar_iommu(iommu);
4367out:
4368 free_dmar_iommu(iommu);
4369 return ret;
4370}
4371
Jiang Liu6b197242014-11-09 22:47:58 +08004372int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4373{
Jiang Liuffebeb42014-11-09 22:48:02 +08004374 int ret = 0;
4375 struct intel_iommu *iommu = dmaru->iommu;
4376
4377 if (!intel_iommu_enabled)
4378 return 0;
4379 if (iommu == NULL)
4380 return -EINVAL;
4381
4382 if (insert) {
4383 ret = intel_iommu_add(dmaru);
4384 } else {
4385 disable_dmar_iommu(iommu);
4386 free_dmar_iommu(iommu);
4387 }
4388
4389 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004390}
4391
Jiang Liu9bdc5312014-01-06 14:18:27 +08004392static void intel_iommu_free_dmars(void)
4393{
4394 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4395 struct dmar_atsr_unit *atsru, *atsr_n;
4396
4397 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4398 list_del(&rmrru->list);
4399 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004400 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004401 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004402 }
4403
Jiang Liu9bdc5312014-01-06 14:18:27 +08004404 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4405 list_del(&atsru->list);
4406 intel_iommu_free_atsr(atsru);
4407 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004408}
4409
4410int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4411{
Jiang Liub683b232014-02-19 14:07:32 +08004412 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004413 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004414 struct pci_dev *bridge = NULL;
4415 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004416 struct acpi_dmar_atsr *atsr;
4417 struct dmar_atsr_unit *atsru;
4418
4419 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004420 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004421 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004422 /* If it's an integrated device, allow ATS */
4423 if (!bridge)
4424 return 1;
4425 /* Connected via non-PCIe: no ATS */
4426 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004427 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004428 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004429 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004430 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004431 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004432 }
4433
Jiang Liu0e242612014-02-19 14:07:34 +08004434 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004435 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4436 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4437 if (atsr->segment != pci_domain_nr(dev->bus))
4438 continue;
4439
Jiang Liub683b232014-02-19 14:07:32 +08004440 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004441 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004442 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004443
4444 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004445 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004446 }
Jiang Liub683b232014-02-19 14:07:32 +08004447 ret = 0;
4448out:
Jiang Liu0e242612014-02-19 14:07:34 +08004449 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004450
Jiang Liub683b232014-02-19 14:07:32 +08004451 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004452}
4453
Jiang Liu59ce0512014-02-19 14:07:35 +08004454int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4455{
4456 int ret = 0;
4457 struct dmar_rmrr_unit *rmrru;
4458 struct dmar_atsr_unit *atsru;
4459 struct acpi_dmar_atsr *atsr;
4460 struct acpi_dmar_reserved_memory *rmrr;
4461
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004462 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004463 return 0;
4464
4465 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4466 rmrr = container_of(rmrru->hdr,
4467 struct acpi_dmar_reserved_memory, header);
4468 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4469 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4470 ((void *)rmrr) + rmrr->header.length,
4471 rmrr->segment, rmrru->devices,
4472 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004473 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004474 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004475 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004476 dmar_remove_dev_scope(info, rmrr->segment,
4477 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004478 }
4479 }
4480
4481 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4482 if (atsru->include_all)
4483 continue;
4484
4485 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4486 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4487 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4488 (void *)atsr + atsr->header.length,
4489 atsr->segment, atsru->devices,
4490 atsru->devices_cnt);
4491 if (ret > 0)
4492 break;
4493 else if(ret < 0)
4494 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004495 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004496 if (dmar_remove_dev_scope(info, atsr->segment,
4497 atsru->devices, atsru->devices_cnt))
4498 break;
4499 }
4500 }
4501
4502 return 0;
4503}
4504
Fenghua Yu99dcade2009-11-11 07:23:06 -08004505/*
4506 * Here we only respond to action of unbound device from driver.
4507 *
4508 * Added device is not attached to its DMAR domain here yet. That will happen
4509 * when mapping the device to iova.
4510 */
4511static int device_notifier(struct notifier_block *nb,
4512 unsigned long action, void *data)
4513{
4514 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004515 struct dmar_domain *domain;
4516
David Woodhouse3d891942014-03-06 15:59:26 +00004517 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004518 return 0;
4519
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004520 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004521 return 0;
4522
David Woodhouse1525a292014-03-06 16:19:30 +00004523 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004524 if (!domain)
4525 return 0;
4526
Joerg Roedele6de0f82015-07-22 16:30:36 +02004527 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004528 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004529 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004530
Fenghua Yu99dcade2009-11-11 07:23:06 -08004531 return 0;
4532}
4533
4534static struct notifier_block device_nb = {
4535 .notifier_call = device_notifier,
4536};
4537
Jiang Liu75f05562014-02-19 14:07:37 +08004538static int intel_iommu_memory_notifier(struct notifier_block *nb,
4539 unsigned long val, void *v)
4540{
4541 struct memory_notify *mhp = v;
4542 unsigned long long start, end;
4543 unsigned long start_vpfn, last_vpfn;
4544
4545 switch (val) {
4546 case MEM_GOING_ONLINE:
4547 start = mhp->start_pfn << PAGE_SHIFT;
4548 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4549 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004550 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004551 start, end);
4552 return NOTIFY_BAD;
4553 }
4554 break;
4555
4556 case MEM_OFFLINE:
4557 case MEM_CANCEL_ONLINE:
4558 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4559 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4560 while (start_vpfn <= last_vpfn) {
4561 struct iova *iova;
4562 struct dmar_drhd_unit *drhd;
4563 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004564 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004565
4566 iova = find_iova(&si_domain->iovad, start_vpfn);
4567 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004568 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004569 start_vpfn);
4570 break;
4571 }
4572
4573 iova = split_and_remove_iova(&si_domain->iovad, iova,
4574 start_vpfn, last_vpfn);
4575 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004576 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004577 start_vpfn, last_vpfn);
4578 return NOTIFY_BAD;
4579 }
4580
David Woodhouseea8ea462014-03-05 17:09:32 +00004581 freelist = domain_unmap(si_domain, iova->pfn_lo,
4582 iova->pfn_hi);
4583
Jiang Liu75f05562014-02-19 14:07:37 +08004584 rcu_read_lock();
4585 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004586 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004587 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004588 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004589 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004590 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004591
4592 start_vpfn = iova->pfn_hi + 1;
4593 free_iova_mem(iova);
4594 }
4595 break;
4596 }
4597
4598 return NOTIFY_OK;
4599}
4600
4601static struct notifier_block intel_iommu_memory_nb = {
4602 .notifier_call = intel_iommu_memory_notifier,
4603 .priority = 0
4604};
4605
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004606static void free_all_cpu_cached_iovas(unsigned int cpu)
4607{
4608 int i;
4609
4610 for (i = 0; i < g_num_of_iommus; i++) {
4611 struct intel_iommu *iommu = g_iommus[i];
4612 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004613 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004614
4615 if (!iommu)
4616 continue;
4617
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004618 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004619 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004620
4621 if (!domain)
4622 continue;
4623 free_cpu_cached_iovas(cpu, &domain->iovad);
4624 }
4625 }
4626}
4627
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004628static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004629{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004630 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004631 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004632}
4633
Joerg Roedel161b28a2017-03-28 17:04:52 +02004634static void intel_disable_iommus(void)
4635{
4636 struct intel_iommu *iommu = NULL;
4637 struct dmar_drhd_unit *drhd;
4638
4639 for_each_iommu(iommu, drhd)
4640 iommu_disable_translation(iommu);
4641}
4642
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004643static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4644{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004645 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4646
4647 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004648}
4649
Alex Williamsona5459cf2014-06-12 16:12:31 -06004650static ssize_t intel_iommu_show_version(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 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4656 return sprintf(buf, "%d:%d\n",
4657 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4658}
4659static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4660
4661static ssize_t intel_iommu_show_address(struct device *dev,
4662 struct device_attribute *attr,
4663 char *buf)
4664{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004665 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004666 return sprintf(buf, "%llx\n", iommu->reg_phys);
4667}
4668static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4669
4670static ssize_t intel_iommu_show_cap(struct device *dev,
4671 struct device_attribute *attr,
4672 char *buf)
4673{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004674 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004675 return sprintf(buf, "%llx\n", iommu->cap);
4676}
4677static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4678
4679static ssize_t intel_iommu_show_ecap(struct device *dev,
4680 struct device_attribute *attr,
4681 char *buf)
4682{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004683 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004684 return sprintf(buf, "%llx\n", iommu->ecap);
4685}
4686static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4687
Alex Williamson2238c082015-07-14 15:24:53 -06004688static ssize_t intel_iommu_show_ndoms(struct device *dev,
4689 struct device_attribute *attr,
4690 char *buf)
4691{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004692 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004693 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4694}
4695static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4696
4697static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4698 struct device_attribute *attr,
4699 char *buf)
4700{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004701 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004702 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4703 cap_ndoms(iommu->cap)));
4704}
4705static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4706
Alex Williamsona5459cf2014-06-12 16:12:31 -06004707static struct attribute *intel_iommu_attrs[] = {
4708 &dev_attr_version.attr,
4709 &dev_attr_address.attr,
4710 &dev_attr_cap.attr,
4711 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004712 &dev_attr_domains_supported.attr,
4713 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004714 NULL,
4715};
4716
4717static struct attribute_group intel_iommu_group = {
4718 .name = "intel-iommu",
4719 .attrs = intel_iommu_attrs,
4720};
4721
4722const struct attribute_group *intel_iommu_groups[] = {
4723 &intel_iommu_group,
4724 NULL,
4725};
4726
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004727int __init intel_iommu_init(void)
4728{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004729 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004730 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004731 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004732
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004733 /* VT-d is required for a TXT/tboot launch, so enforce that */
4734 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004735
Jiang Liu3a5670e2014-02-19 14:07:33 +08004736 if (iommu_init_mempool()) {
4737 if (force_on)
4738 panic("tboot: Failed to initialize iommu memory\n");
4739 return -ENOMEM;
4740 }
4741
4742 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004743 if (dmar_table_init()) {
4744 if (force_on)
4745 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004746 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004747 }
4748
Suresh Siddhac2c72862011-08-23 17:05:19 -07004749 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004750 if (force_on)
4751 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004752 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004753 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004754
Joerg Roedelec154bf2017-10-06 15:00:53 +02004755 up_write(&dmar_global_lock);
4756
4757 /*
4758 * The bus notifier takes the dmar_global_lock, so lockdep will
4759 * complain later when we register it under the lock.
4760 */
4761 dmar_register_bus_notifier();
4762
4763 down_write(&dmar_global_lock);
4764
Joerg Roedel161b28a2017-03-28 17:04:52 +02004765 if (no_iommu || dmar_disabled) {
4766 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004767 * We exit the function here to ensure IOMMU's remapping and
4768 * mempool aren't setup, which means that the IOMMU's PMRs
4769 * won't be disabled via the call to init_dmars(). So disable
4770 * it explicitly here. The PMRs were setup by tboot prior to
4771 * calling SENTER, but the kernel is expected to reset/tear
4772 * down the PMRs.
4773 */
4774 if (intel_iommu_tboot_noforce) {
4775 for_each_iommu(iommu, drhd)
4776 iommu_disable_protect_mem_regions(iommu);
4777 }
4778
4779 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004780 * Make sure the IOMMUs are switched off, even when we
4781 * boot into a kexec kernel and the previous kernel left
4782 * them enabled
4783 */
4784 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004785 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004786 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004787
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004788 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004789 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004790
4791 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004792 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004793
Joseph Cihula51a63e62011-03-21 11:04:24 -07004794 if (dmar_init_reserved_ranges()) {
4795 if (force_on)
4796 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004797 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004798 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004799
4800 init_no_remapping_devices();
4801
Joseph Cihulab7792602011-05-03 00:08:37 -07004802 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004803 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004804 if (force_on)
4805 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004806 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004807 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004808 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004809 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004810 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004811
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004812#ifdef CONFIG_SWIOTLB
4813 swiotlb = 0;
4814#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004815 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004816
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004817 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004818
Joerg Roedel39ab9552017-02-01 16:56:46 +01004819 for_each_active_iommu(iommu, drhd) {
4820 iommu_device_sysfs_add(&iommu->iommu, NULL,
4821 intel_iommu_groups,
4822 "%s", iommu->name);
4823 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4824 iommu_device_register(&iommu->iommu);
4825 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004826
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004827 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004828 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004829 if (si_domain && !hw_pass_through)
4830 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004831 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4832 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004833 intel_iommu_enabled = 1;
4834
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004835 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004836
4837out_free_reserved_range:
4838 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004839out_free_dmar:
4840 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004841 up_write(&dmar_global_lock);
4842 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004843 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004844}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004845
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004846static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004847{
4848 struct intel_iommu *iommu = opaque;
4849
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004850 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004851 return 0;
4852}
4853
4854/*
4855 * NB - intel-iommu lacks any sort of reference counting for the users of
4856 * dependent devices. If multiple endpoints have intersecting dependent
4857 * devices, unbinding the driver from any one of them will possibly leave
4858 * the others unable to operate.
4859 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004860static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004861{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004862 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004863 return;
4864
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004865 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004866}
4867
Joerg Roedel127c7612015-07-23 17:44:46 +02004868static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004869{
Weidong Hanc7151a82008-12-08 22:51:37 +08004870 struct intel_iommu *iommu;
4871 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004872
Joerg Roedel55d94042015-07-22 16:50:40 +02004873 assert_spin_locked(&device_domain_lock);
4874
Joerg Roedelb608ac32015-07-21 18:19:08 +02004875 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004876 return;
4877
Joerg Roedel127c7612015-07-23 17:44:46 +02004878 iommu = info->iommu;
4879
4880 if (info->dev) {
4881 iommu_disable_dev_iotlb(info);
4882 domain_context_clear(iommu, info->dev);
4883 }
4884
Joerg Roedelb608ac32015-07-21 18:19:08 +02004885 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004886
Joerg Roedeld160aca2015-07-22 11:52:53 +02004887 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004888 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004889 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004890
4891 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004892}
4893
Joerg Roedel55d94042015-07-22 16:50:40 +02004894static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4895 struct device *dev)
4896{
Joerg Roedel127c7612015-07-23 17:44:46 +02004897 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004898 unsigned long flags;
4899
Weidong Hanc7151a82008-12-08 22:51:37 +08004900 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004901 info = dev->archdata.iommu;
4902 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004903 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004904}
4905
4906static int md_domain_init(struct dmar_domain *domain, int guest_width)
4907{
4908 int adjust_width;
4909
Robin Murphy0fb5fe82015-01-12 17:51:16 +00004910 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN,
4911 DMA_32BIT_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004912 domain_reserve_special_ranges(domain);
4913
4914 /* calculate AGAW */
4915 domain->gaw = guest_width;
4916 adjust_width = guestwidth_to_adjustwidth(guest_width);
4917 domain->agaw = width_to_agaw(adjust_width);
4918
Weidong Han5e98c4b2008-12-08 23:03:27 +08004919 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08004920 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01004921 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004922 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08004923
4924 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07004925 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004926 if (!domain->pgd)
4927 return -ENOMEM;
4928 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
4929 return 0;
4930}
4931
Joerg Roedel00a77de2015-03-26 13:43:08 +01004932static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03004933{
Joerg Roedel5d450802008-12-03 14:52:32 +01004934 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01004935 struct iommu_domain *domain;
4936
4937 if (type != IOMMU_DOMAIN_UNMANAGED)
4938 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004939
Jiang Liuab8dfe22014-07-11 14:19:27 +08004940 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01004941 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004942 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01004943 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004944 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07004945 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004946 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08004947 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01004948 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004949 }
Allen Kay8140a952011-10-14 12:32:17 -07004950 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004951
Joerg Roedel00a77de2015-03-26 13:43:08 +01004952 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01004953 domain->geometry.aperture_start = 0;
4954 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
4955 domain->geometry.force_aperture = true;
4956
Joerg Roedel00a77de2015-03-26 13:43:08 +01004957 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03004958}
Kay, Allen M38717942008-09-09 18:37:29 +03004959
Joerg Roedel00a77de2015-03-26 13:43:08 +01004960static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03004961{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004962 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03004963}
Kay, Allen M38717942008-09-09 18:37:29 +03004964
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004965static int intel_iommu_attach_device(struct iommu_domain *domain,
4966 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004967{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004968 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004969 struct intel_iommu *iommu;
4970 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07004971 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03004972
Alex Williamsonc875d2c2014-07-03 09:57:02 -06004973 if (device_is_rmrr_locked(dev)) {
4974 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
4975 return -EPERM;
4976 }
4977
David Woodhouse7207d8f2014-03-09 16:31:06 -07004978 /* normally dev is not mapped */
4979 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004980 struct dmar_domain *old_domain;
4981
David Woodhouse1525a292014-03-06 16:19:30 +00004982 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004983 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02004984 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02004985 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004986 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01004987
4988 if (!domain_type_is_vm_or_si(old_domain) &&
4989 list_empty(&old_domain->devices))
4990 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004991 }
4992 }
4993
David Woodhouse156baca2014-03-09 14:00:57 -07004994 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004995 if (!iommu)
4996 return -ENODEV;
4997
4998 /* check if this iommu agaw is sufficient for max mapped address */
4999 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01005000 if (addr_width > cap_mgaw(iommu->cap))
5001 addr_width = cap_mgaw(iommu->cap);
5002
5003 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005004 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005005 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01005006 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005007 return -EFAULT;
5008 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005009 dmar_domain->gaw = addr_width;
5010
5011 /*
5012 * Knock out extra levels of page tables if necessary
5013 */
5014 while (iommu->agaw < dmar_domain->agaw) {
5015 struct dma_pte *pte;
5016
5017 pte = dmar_domain->pgd;
5018 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005019 dmar_domain->pgd = (struct dma_pte *)
5020 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005021 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005022 }
5023 dmar_domain->agaw--;
5024 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005025
Joerg Roedel28ccce02015-07-21 14:45:31 +02005026 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005027}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005028
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005029static void intel_iommu_detach_device(struct iommu_domain *domain,
5030 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005031{
Joerg Roedele6de0f82015-07-22 16:30:36 +02005032 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005033}
Kay, Allen M38717942008-09-09 18:37:29 +03005034
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005035static int intel_iommu_map(struct iommu_domain *domain,
5036 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005037 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005038{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005039 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005040 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005041 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005042 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005043
Joerg Roedeldde57a22008-12-03 15:04:09 +01005044 if (iommu_prot & IOMMU_READ)
5045 prot |= DMA_PTE_READ;
5046 if (iommu_prot & IOMMU_WRITE)
5047 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005048 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5049 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005050
David Woodhouse163cc522009-06-28 00:51:17 +01005051 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005052 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005053 u64 end;
5054
5055 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005056 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005057 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005058 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005059 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005060 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005061 return -EFAULT;
5062 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005063 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005064 }
David Woodhousead051222009-06-28 14:22:28 +01005065 /* Round up size to next multiple of PAGE_SIZE, if it and
5066 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005067 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005068 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5069 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005070 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005071}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005072
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005073static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005074 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005075{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005076 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005077 struct page *freelist = NULL;
5078 struct intel_iommu *iommu;
5079 unsigned long start_pfn, last_pfn;
5080 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005081 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005082
David Woodhouse5cf0a762014-03-19 16:07:49 +00005083 /* Cope with horrid API which requires us to unmap more than the
5084 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005085 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005086
5087 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5088 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5089
David Woodhouseea8ea462014-03-05 17:09:32 +00005090 start_pfn = iova >> VTD_PAGE_SHIFT;
5091 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5092
5093 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5094
5095 npages = last_pfn - start_pfn + 1;
5096
Joerg Roedel29a27712015-07-21 17:17:12 +02005097 for_each_domain_iommu(iommu_id, dmar_domain) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02005098 iommu = g_iommus[iommu_id];
David Woodhouseea8ea462014-03-05 17:09:32 +00005099
Joerg Roedel42e8c182015-07-21 15:50:02 +02005100 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5101 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005102 }
5103
5104 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005105
David Woodhouse163cc522009-06-28 00:51:17 +01005106 if (dmar_domain->max_addr == iova + size)
5107 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005108
David Woodhouse5cf0a762014-03-19 16:07:49 +00005109 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005110}
Kay, Allen M38717942008-09-09 18:37:29 +03005111
Joerg Roedeld14d6572008-12-03 15:06:57 +01005112static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305113 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005114{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005115 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005116 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005117 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005118 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005119
David Woodhouse5cf0a762014-03-19 16:07:49 +00005120 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005121 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005122 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005123
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005124 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005125}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005126
Joerg Roedel5d587b82014-09-05 10:50:45 +02005127static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005128{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005129 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005130 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005131 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005132 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005133
Joerg Roedel5d587b82014-09-05 10:50:45 +02005134 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005135}
5136
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005137static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005138{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005139 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005140 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005141 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005142
Alex Williamsona5459cf2014-06-12 16:12:31 -06005143 iommu = device_to_iommu(dev, &bus, &devfn);
5144 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005145 return -ENODEV;
5146
Joerg Roedele3d10af2017-02-01 17:23:22 +01005147 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005148
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005149 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005150
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005151 if (IS_ERR(group))
5152 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005153
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005154 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005155 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005156}
5157
5158static void intel_iommu_remove_device(struct device *dev)
5159{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005160 struct intel_iommu *iommu;
5161 u8 bus, devfn;
5162
5163 iommu = device_to_iommu(dev, &bus, &devfn);
5164 if (!iommu)
5165 return;
5166
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005167 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005168
Joerg Roedele3d10af2017-02-01 17:23:22 +01005169 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005170}
5171
Eric Auger0659b8d2017-01-19 20:57:53 +00005172static void intel_iommu_get_resv_regions(struct device *device,
5173 struct list_head *head)
5174{
5175 struct iommu_resv_region *reg;
5176 struct dmar_rmrr_unit *rmrr;
5177 struct device *i_dev;
5178 int i;
5179
5180 rcu_read_lock();
5181 for_each_rmrr_units(rmrr) {
5182 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5183 i, i_dev) {
5184 if (i_dev != device)
5185 continue;
5186
5187 list_add_tail(&rmrr->resv->list, head);
5188 }
5189 }
5190 rcu_read_unlock();
5191
5192 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5193 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005194 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005195 if (!reg)
5196 return;
5197 list_add_tail(&reg->list, head);
5198}
5199
5200static void intel_iommu_put_resv_regions(struct device *dev,
5201 struct list_head *head)
5202{
5203 struct iommu_resv_region *entry, *next;
5204
5205 list_for_each_entry_safe(entry, next, head, list) {
5206 if (entry->type == IOMMU_RESV_RESERVED)
5207 kfree(entry);
5208 }
Kay, Allen M38717942008-09-09 18:37:29 +03005209}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005210
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005211#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005212#define MAX_NR_PASID_BITS (20)
5213static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5214{
5215 /*
5216 * Convert ecap_pss to extend context entry pts encoding, also
5217 * respect the soft pasid_max value set by the iommu.
5218 * - number of PASID bits = ecap_pss + 1
5219 * - number of PASID table entries = 2^(pts + 5)
5220 * Therefore, pts = ecap_pss - 4
5221 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5222 */
5223 if (ecap_pss(iommu->ecap) < 5)
5224 return 0;
5225
5226 /* pasid_max is encoded as actual number of entries not the bits */
5227 return find_first_bit((unsigned long *)&iommu->pasid_max,
5228 MAX_NR_PASID_BITS) - 5;
5229}
5230
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005231int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5232{
5233 struct device_domain_info *info;
5234 struct context_entry *context;
5235 struct dmar_domain *domain;
5236 unsigned long flags;
5237 u64 ctx_lo;
5238 int ret;
5239
5240 domain = get_valid_domain_for_dev(sdev->dev);
5241 if (!domain)
5242 return -EINVAL;
5243
5244 spin_lock_irqsave(&device_domain_lock, flags);
5245 spin_lock(&iommu->lock);
5246
5247 ret = -EINVAL;
5248 info = sdev->dev->archdata.iommu;
5249 if (!info || !info->pasid_supported)
5250 goto out;
5251
5252 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5253 if (WARN_ON(!context))
5254 goto out;
5255
5256 ctx_lo = context[0].lo;
5257
5258 sdev->did = domain->iommu_did[iommu->seq_id];
5259 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5260
5261 if (!(ctx_lo & CONTEXT_PASIDE)) {
Ashok Raj11b93eb2017-08-08 13:29:28 -07005262 if (iommu->pasid_state_table)
5263 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005264 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5265 intel_iommu_get_pts(iommu);
5266
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005267 wmb();
5268 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5269 * extended to permit requests-with-PASID if the PASIDE bit
5270 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5271 * however, the PASIDE bit is ignored and requests-with-PASID
5272 * are unconditionally blocked. Which makes less sense.
5273 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5274 * "guest mode" translation types depending on whether ATS
5275 * is available or not. Annoyingly, we can't use the new
5276 * modes *unless* PASIDE is set. */
5277 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5278 ctx_lo &= ~CONTEXT_TT_MASK;
5279 if (info->ats_supported)
5280 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5281 else
5282 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5283 }
5284 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005285 if (iommu->pasid_state_table)
5286 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005287 if (info->pri_supported)
5288 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005289 context[0].lo = ctx_lo;
5290 wmb();
5291 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5292 DMA_CCMD_MASK_NOBIT,
5293 DMA_CCMD_DEVICE_INVL);
5294 }
5295
5296 /* Enable PASID support in the device, if it wasn't already */
5297 if (!info->pasid_enabled)
5298 iommu_enable_dev_iotlb(info);
5299
5300 if (info->ats_enabled) {
5301 sdev->dev_iotlb = 1;
5302 sdev->qdep = info->ats_qdep;
5303 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5304 sdev->qdep = 0;
5305 }
5306 ret = 0;
5307
5308 out:
5309 spin_unlock(&iommu->lock);
5310 spin_unlock_irqrestore(&device_domain_lock, flags);
5311
5312 return ret;
5313}
5314
5315struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5316{
5317 struct intel_iommu *iommu;
5318 u8 bus, devfn;
5319
5320 if (iommu_dummy(dev)) {
5321 dev_warn(dev,
5322 "No IOMMU translation for device; cannot enable SVM\n");
5323 return NULL;
5324 }
5325
5326 iommu = device_to_iommu(dev, &bus, &devfn);
5327 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005328 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005329 return NULL;
5330 }
5331
5332 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005333 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005334 return NULL;
5335 }
5336
5337 return iommu;
5338}
5339#endif /* CONFIG_INTEL_IOMMU_SVM */
5340
Joerg Roedelb0119e82017-02-01 13:23:08 +01005341const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005342 .capable = intel_iommu_capable,
5343 .domain_alloc = intel_iommu_domain_alloc,
5344 .domain_free = intel_iommu_domain_free,
5345 .attach_dev = intel_iommu_attach_device,
5346 .detach_dev = intel_iommu_detach_device,
5347 .map = intel_iommu_map,
5348 .unmap = intel_iommu_unmap,
5349 .map_sg = default_iommu_map_sg,
5350 .iova_to_phys = intel_iommu_iova_to_phys,
5351 .add_device = intel_iommu_add_device,
5352 .remove_device = intel_iommu_remove_device,
5353 .get_resv_regions = intel_iommu_get_resv_regions,
5354 .put_resv_regions = intel_iommu_put_resv_regions,
5355 .device_group = pci_device_group,
5356 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005357};
David Woodhouse9af88142009-02-13 23:18:03 +00005358
Daniel Vetter94526182013-01-20 23:50:13 +01005359static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5360{
5361 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005362 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005363 dmar_map_gfx = 0;
5364}
5365
5366DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5367DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5368DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5369DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5370DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5371DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5372DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5373
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005374static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005375{
5376 /*
5377 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005378 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005379 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005380 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005381 rwbf_quirk = 1;
5382}
5383
5384DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005385DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5386DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5387DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5388DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5389DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5390DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005391
Adam Jacksoneecfd572010-08-25 21:17:34 +01005392#define GGC 0x52
5393#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5394#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5395#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5396#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5397#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5398#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5399#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5400#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5401
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005402static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005403{
5404 unsigned short ggc;
5405
Adam Jacksoneecfd572010-08-25 21:17:34 +01005406 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005407 return;
5408
Adam Jacksoneecfd572010-08-25 21:17:34 +01005409 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005410 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005411 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005412 } else if (dmar_map_gfx) {
5413 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005414 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005415 intel_iommu_strict = 1;
5416 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005417}
5418DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5419DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5420DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5421DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5422
David Woodhousee0fc7e02009-09-30 09:12:17 -07005423/* On Tylersburg chipsets, some BIOSes have been known to enable the
5424 ISOCH DMAR unit for the Azalia sound device, but not give it any
5425 TLB entries, which causes it to deadlock. Check for that. We do
5426 this in a function called from init_dmars(), instead of in a PCI
5427 quirk, because we don't want to print the obnoxious "BIOS broken"
5428 message if VT-d is actually disabled.
5429*/
5430static void __init check_tylersburg_isoch(void)
5431{
5432 struct pci_dev *pdev;
5433 uint32_t vtisochctrl;
5434
5435 /* If there's no Azalia in the system anyway, forget it. */
5436 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5437 if (!pdev)
5438 return;
5439 pci_dev_put(pdev);
5440
5441 /* System Management Registers. Might be hidden, in which case
5442 we can't do the sanity check. But that's OK, because the
5443 known-broken BIOSes _don't_ actually hide it, so far. */
5444 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5445 if (!pdev)
5446 return;
5447
5448 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5449 pci_dev_put(pdev);
5450 return;
5451 }
5452
5453 pci_dev_put(pdev);
5454
5455 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5456 if (vtisochctrl & 1)
5457 return;
5458
5459 /* Drop all bits other than the number of TLB entries */
5460 vtisochctrl &= 0x1c;
5461
5462 /* If we have the recommended number of TLB entries (16), fine. */
5463 if (vtisochctrl == 0x10)
5464 return;
5465
5466 /* Zero TLB entries? You get to ride the short bus to school. */
5467 if (!vtisochctrl) {
5468 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5469 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5470 dmi_get_system_info(DMI_BIOS_VENDOR),
5471 dmi_get_system_info(DMI_BIOS_VERSION),
5472 dmi_get_system_info(DMI_PRODUCT_VERSION));
5473 iommu_identity_mapping |= IDENTMAP_AZALIA;
5474 return;
5475 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005476
5477 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005478 vtisochctrl);
5479}