blob: 601d3789211f511a1e67fae3ff90fcb519bc8a4e [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>
Christoph Hellwigd657c5c2018-03-19 11:38:20 +010034#include <linux/dma-direct.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070035#include <linux/mempool.h>
Jiang Liu75f05562014-02-19 14:07:37 +080036#include <linux/memory.h>
Omer Pelegaa473242016-04-20 11:33:02 +030037#include <linux/cpu.h>
mark gross5e0d2a62008-03-04 15:22:08 -080038#include <linux/timer.h>
Dan Williamsdfddb9692015-10-09 18:16:46 -040039#include <linux/io.h>
Kay, Allen M38717942008-09-09 18:37:29 +030040#include <linux/iova.h>
Joerg Roedel5d450802008-12-03 14:52:32 +010041#include <linux/iommu.h>
Kay, Allen M38717942008-09-09 18:37:29 +030042#include <linux/intel-iommu.h>
Rafael J. Wysocki134fac32011-03-23 22:16:14 +010043#include <linux/syscore_ops.h>
Shane Wang69575d32009-09-01 18:25:07 -070044#include <linux/tboot.h>
Stephen Rothwelladb2fe02009-08-31 15:24:23 +100045#include <linux/dmi.h>
Joerg Roedel5cdede22011-04-04 15:55:18 +020046#include <linux/pci-ats.h>
Tejun Heo0ee332c2011-12-08 10:22:09 -080047#include <linux/memblock.h>
Akinobu Mita36746432014-06-04 16:06:51 -070048#include <linux/dma-contiguous.h>
Christoph Hellwigfec777c2018-03-19 11:38:15 +010049#include <linux/dma-direct.h>
Joerg Roedel091d42e2015-06-12 11:56:10 +020050#include <linux/crash_dump.h>
Suresh Siddha8a8f4222012-03-30 11:47:08 -070051#include <asm/irq_remapping.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070052#include <asm/cacheflush.h>
FUJITA Tomonori46a7fa22008-07-11 10:23:42 +090053#include <asm/iommu.h>
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070054
Joerg Roedel078e1ee2012-09-26 12:44:43 +020055#include "irq_remapping.h"
56
Fenghua Yu5b6985c2008-10-16 18:02:32 -070057#define ROOT_SIZE VTD_PAGE_SIZE
58#define CONTEXT_SIZE VTD_PAGE_SIZE
59
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070060#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
David Woodhouse18436af2015-03-25 15:05:47 +000061#define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070062#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
David Woodhousee0fc7e02009-09-30 09:12:17 -070063#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070064
65#define IOAPIC_RANGE_START (0xfee00000)
66#define IOAPIC_RANGE_END (0xfeefffff)
67#define IOVA_START_ADDR (0x1000)
68
Sohil Mehta5e3b4a12017-12-20 11:59:24 -080069#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070070
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070071#define MAX_AGAW_WIDTH 64
Jiang Liu5c645b32014-01-06 14:18:12 +080072#define MAX_AGAW_PFN_WIDTH (MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -070073
David Woodhouse2ebe3152009-09-19 07:34:04 -070074#define __DOMAIN_MAX_PFN(gaw) ((((uint64_t)1) << (gaw-VTD_PAGE_SHIFT)) - 1)
75#define __DOMAIN_MAX_ADDR(gaw) ((((uint64_t)1) << gaw) - 1)
76
77/* We limit DOMAIN_MAX_PFN to fit in an unsigned long, and DOMAIN_MAX_ADDR
78 to match. That way, we can use 'unsigned long' for PFNs with impunity. */
79#define DOMAIN_MAX_PFN(gaw) ((unsigned long) min_t(uint64_t, \
80 __DOMAIN_MAX_PFN(gaw), (unsigned long)-1))
81#define DOMAIN_MAX_ADDR(gaw) (((uint64_t)__DOMAIN_MAX_PFN(gaw)) << VTD_PAGE_SHIFT)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -070082
Robin Murphy1b722502015-01-12 17:51:15 +000083/* IO virtual address start page frame number */
84#define IOVA_START_PFN (1)
85
Mark McLoughlinf27be032008-11-20 15:49:43 +000086#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT)
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)
Peter Xu9d2e6502018-01-10 13:51:37 +08001606 iommu_flush_dev_iotlb(domain, addr, mask);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001607}
1608
Peter Xueed91a02018-05-04 10:34:52 +08001609/* Notification for newly created mappings */
1610static inline void __mapping_notify_one(struct intel_iommu *iommu,
1611 struct dmar_domain *domain,
1612 unsigned long pfn, unsigned int pages)
1613{
1614 /* It's a non-present to present mapping. Only flush if caching mode */
1615 if (cap_caching_mode(iommu->cap))
1616 iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
1617 else
1618 iommu_flush_write_buffer(iommu);
1619}
1620
Joerg Roedel13cf0172017-08-11 11:40:10 +02001621static void iommu_flush_iova(struct iova_domain *iovad)
1622{
1623 struct dmar_domain *domain;
1624 int idx;
1625
1626 domain = container_of(iovad, struct dmar_domain, iovad);
1627
1628 for_each_domain_iommu(idx, domain) {
1629 struct intel_iommu *iommu = g_iommus[idx];
1630 u16 did = domain->iommu_did[iommu->seq_id];
1631
1632 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1633
1634 if (!cap_caching_mode(iommu->cap))
1635 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1636 0, MAX_AGAW_PFN_WIDTH);
1637 }
1638}
1639
mark grossf8bab732008-02-08 04:18:38 -08001640static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1641{
1642 u32 pmen;
1643 unsigned long flags;
1644
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001645 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001646 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1647 pmen &= ~DMA_PMEN_EPM;
1648 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1649
1650 /* wait for the protected region status bit to clear */
1651 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1652 readl, !(pmen & DMA_PMEN_PRS), pmen);
1653
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001654 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001655}
1656
Jiang Liu2a41cce2014-07-11 14:19:33 +08001657static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001658{
1659 u32 sts;
1660 unsigned long flags;
1661
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001662 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001663 iommu->gcmd |= DMA_GCMD_TE;
1664 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001665
1666 /* Make sure hardware complete it */
1667 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001668 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001669
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001670 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001671}
1672
Jiang Liu2a41cce2014-07-11 14:19:33 +08001673static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001674{
1675 u32 sts;
1676 unsigned long flag;
1677
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001678 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001679 iommu->gcmd &= ~DMA_GCMD_TE;
1680 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1681
1682 /* Make sure hardware complete it */
1683 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001684 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001685
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001686 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001687}
1688
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001689
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001690static int iommu_init_domains(struct intel_iommu *iommu)
1691{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001692 u32 ndomains, nlongs;
1693 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001694
1695 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001696 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001697 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001698 nlongs = BITS_TO_LONGS(ndomains);
1699
Donald Dutile94a91b52009-08-20 16:51:34 -04001700 spin_lock_init(&iommu->lock);
1701
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001702 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1703 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001704 pr_err("%s: Allocating domain id array failed\n",
1705 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001706 return -ENOMEM;
1707 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001708
Wei Yang86f004c2016-05-21 02:41:51 +00001709 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001710 iommu->domains = kzalloc(size, GFP_KERNEL);
1711
1712 if (iommu->domains) {
1713 size = 256 * sizeof(struct dmar_domain *);
1714 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1715 }
1716
1717 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001718 pr_err("%s: Allocating domain array failed\n",
1719 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001720 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001721 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001722 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001723 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001724 return -ENOMEM;
1725 }
1726
Joerg Roedel8bf47812015-07-21 10:41:21 +02001727
1728
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001729 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001730 * If Caching mode is set, then invalid translations are tagged
1731 * with domain-id 0, hence we need to pre-allocate it. We also
1732 * use domain-id 0 as a marker for non-allocated domain-id, so
1733 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001734 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001735 set_bit(0, iommu->domain_ids);
1736
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001737 return 0;
1738}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001739
Jiang Liuffebeb42014-11-09 22:48:02 +08001740static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001741{
Joerg Roedel29a27712015-07-21 17:17:12 +02001742 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001743 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001744
Joerg Roedel29a27712015-07-21 17:17:12 +02001745 if (!iommu->domains || !iommu->domain_ids)
1746 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001747
Joerg Roedelbea64032016-11-08 15:08:26 +01001748again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001749 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001750 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1751 struct dmar_domain *domain;
1752
1753 if (info->iommu != iommu)
1754 continue;
1755
1756 if (!info->dev || !info->domain)
1757 continue;
1758
1759 domain = info->domain;
1760
Joerg Roedelbea64032016-11-08 15:08:26 +01001761 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001762
Joerg Roedelbea64032016-11-08 15:08:26 +01001763 if (!domain_type_is_vm_or_si(domain)) {
1764 /*
1765 * The domain_exit() function can't be called under
1766 * device_domain_lock, as it takes this lock itself.
1767 * So release the lock here and re-run the loop
1768 * afterwards.
1769 */
1770 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001771 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001772 goto again;
1773 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001774 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001775 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001776
1777 if (iommu->gcmd & DMA_GCMD_TE)
1778 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001779}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001780
Jiang Liuffebeb42014-11-09 22:48:02 +08001781static void free_dmar_iommu(struct intel_iommu *iommu)
1782{
1783 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001784 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001785 int i;
1786
1787 for (i = 0; i < elems; i++)
1788 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001789 kfree(iommu->domains);
1790 kfree(iommu->domain_ids);
1791 iommu->domains = NULL;
1792 iommu->domain_ids = NULL;
1793 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001794
Weidong Hand9630fe2008-12-08 11:06:32 +08001795 g_iommus[iommu->seq_id] = NULL;
1796
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001797 /* free context mapping */
1798 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001799
1800#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001801 if (pasid_enabled(iommu)) {
1802 if (ecap_prs(iommu->ecap))
1803 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001804 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001805 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001806#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001807}
1808
Jiang Liuab8dfe22014-07-11 14:19:27 +08001809static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001810{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001811 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001812
1813 domain = alloc_domain_mem();
1814 if (!domain)
1815 return NULL;
1816
Jiang Liuab8dfe22014-07-11 14:19:27 +08001817 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001818 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001819 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001820 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001821 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001822
1823 return domain;
1824}
1825
Joerg Roedeld160aca2015-07-22 11:52:53 +02001826/* Must be called with iommu->lock */
1827static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001828 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001829{
Jiang Liu44bde612014-07-11 14:19:29 +08001830 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001831 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001832
Joerg Roedel55d94042015-07-22 16:50:40 +02001833 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001834 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001835
Joerg Roedel29a27712015-07-21 17:17:12 +02001836 domain->iommu_refcnt[iommu->seq_id] += 1;
1837 domain->iommu_count += 1;
1838 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001839 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001840 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1841
1842 if (num >= ndomains) {
1843 pr_err("%s: No free domain ids\n", iommu->name);
1844 domain->iommu_refcnt[iommu->seq_id] -= 1;
1845 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001846 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001847 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001848
Joerg Roedeld160aca2015-07-22 11:52:53 +02001849 set_bit(num, iommu->domain_ids);
1850 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001851
Joerg Roedeld160aca2015-07-22 11:52:53 +02001852 domain->iommu_did[iommu->seq_id] = num;
1853 domain->nid = iommu->node;
1854
Jiang Liufb170fb2014-07-11 14:19:28 +08001855 domain_update_iommu_cap(domain);
1856 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001857
Joerg Roedel55d94042015-07-22 16:50:40 +02001858 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001859}
1860
1861static int domain_detach_iommu(struct dmar_domain *domain,
1862 struct intel_iommu *iommu)
1863{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001864 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001865
Joerg Roedel55d94042015-07-22 16:50:40 +02001866 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001867 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001868
Joerg Roedel29a27712015-07-21 17:17:12 +02001869 domain->iommu_refcnt[iommu->seq_id] -= 1;
1870 count = --domain->iommu_count;
1871 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001872 num = domain->iommu_did[iommu->seq_id];
1873 clear_bit(num, iommu->domain_ids);
1874 set_iommu_domain(iommu, num, NULL);
1875
Jiang Liufb170fb2014-07-11 14:19:28 +08001876 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001877 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001878 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001879
1880 return count;
1881}
1882
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001883static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001884static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001885
Joseph Cihula51a63e62011-03-21 11:04:24 -07001886static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001887{
1888 struct pci_dev *pdev = NULL;
1889 struct iova *iova;
1890 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001891
Zhen Leiaa3ac942017-09-21 16:52:45 +01001892 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001893
Mark Gross8a443df2008-03-04 14:59:31 -08001894 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1895 &reserved_rbtree_key);
1896
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001897 /* IOAPIC ranges shouldn't be accessed by DMA */
1898 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1899 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001900 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001901 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001902 return -ENODEV;
1903 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001904
1905 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1906 for_each_pci_dev(pdev) {
1907 struct resource *r;
1908
1909 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1910 r = &pdev->resource[i];
1911 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1912 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001913 iova = reserve_iova(&reserved_iova_list,
1914 IOVA_PFN(r->start),
1915 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001916 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001917 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001918 return -ENODEV;
1919 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001920 }
1921 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001922 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001923}
1924
1925static void domain_reserve_special_ranges(struct dmar_domain *domain)
1926{
1927 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1928}
1929
1930static inline int guestwidth_to_adjustwidth(int gaw)
1931{
1932 int agaw;
1933 int r = (gaw - 12) % 9;
1934
1935 if (r == 0)
1936 agaw = gaw;
1937 else
1938 agaw = gaw + 9 - r;
1939 if (agaw > 64)
1940 agaw = 64;
1941 return agaw;
1942}
1943
Joerg Roedeldc534b22015-07-22 12:44:02 +02001944static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1945 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001946{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001947 int adjust_width, agaw;
1948 unsigned long sagaw;
Joerg Roedel13cf0172017-08-11 11:40:10 +02001949 int err;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001950
Zhen Leiaa3ac942017-09-21 16:52:45 +01001951 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001952
1953 err = init_iova_flush_queue(&domain->iovad,
1954 iommu_flush_iova, iova_entry_free);
1955 if (err)
1956 return err;
1957
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001958 domain_reserve_special_ranges(domain);
1959
1960 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001961 if (guest_width > cap_mgaw(iommu->cap))
1962 guest_width = cap_mgaw(iommu->cap);
1963 domain->gaw = guest_width;
1964 adjust_width = guestwidth_to_adjustwidth(guest_width);
1965 agaw = width_to_agaw(adjust_width);
1966 sagaw = cap_sagaw(iommu->cap);
1967 if (!test_bit(agaw, &sagaw)) {
1968 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001969 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001970 agaw = find_next_bit(&sagaw, 5, agaw);
1971 if (agaw >= 5)
1972 return -ENODEV;
1973 }
1974 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001975
Weidong Han8e6040972008-12-08 15:49:06 +08001976 if (ecap_coherent(iommu->ecap))
1977 domain->iommu_coherency = 1;
1978 else
1979 domain->iommu_coherency = 0;
1980
Sheng Yang58c610b2009-03-18 15:33:05 +08001981 if (ecap_sc_support(iommu->ecap))
1982 domain->iommu_snooping = 1;
1983 else
1984 domain->iommu_snooping = 0;
1985
David Woodhouse214e39a2014-03-19 10:38:49 +00001986 if (intel_iommu_superpage)
1987 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1988 else
1989 domain->iommu_superpage = 0;
1990
Suresh Siddha4c923d42009-10-02 11:01:24 -07001991 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001992
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001993 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001994 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001995 if (!domain->pgd)
1996 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001997 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001998 return 0;
1999}
2000
2001static void domain_exit(struct dmar_domain *domain)
2002{
David Woodhouseea8ea462014-03-05 17:09:32 +00002003 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002004
2005 /* Domain 0 is reserved, so dont process it */
2006 if (!domain)
2007 return;
2008
Joerg Roedeld160aca2015-07-22 11:52:53 +02002009 /* Remove associated devices and clear attached or cached domains */
2010 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002011 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02002012 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08002013
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002014 /* destroy iovas */
2015 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002016
David Woodhouseea8ea462014-03-05 17:09:32 +00002017 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002018
David Woodhouseea8ea462014-03-05 17:09:32 +00002019 dma_free_pagelist(freelist);
2020
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002021 free_domain_mem(domain);
2022}
2023
David Woodhouse64ae8922014-03-09 12:52:30 -07002024static int domain_context_mapping_one(struct dmar_domain *domain,
2025 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002026 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002027{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002028 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002029 int translation = CONTEXT_TT_MULTI_LEVEL;
2030 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002031 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002032 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002033 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002034 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002035
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002036 WARN_ON(did == 0);
2037
Joerg Roedel28ccce02015-07-21 14:45:31 +02002038 if (hw_pass_through && domain_type_is_si(domain))
2039 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002040
2041 pr_debug("Set context mapping for %02x:%02x.%d\n",
2042 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002043
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002044 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002045
Joerg Roedel55d94042015-07-22 16:50:40 +02002046 spin_lock_irqsave(&device_domain_lock, flags);
2047 spin_lock(&iommu->lock);
2048
2049 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002050 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002051 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002052 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002053
Joerg Roedel55d94042015-07-22 16:50:40 +02002054 ret = 0;
2055 if (context_present(context))
2056 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002057
Xunlei Pangaec0e862016-12-05 20:09:07 +08002058 /*
2059 * For kdump cases, old valid entries may be cached due to the
2060 * in-flight DMA and copied pgtable, but there is no unmapping
2061 * behaviour for them, thus we need an explicit cache flush for
2062 * the newly-mapped device. For kdump, at this point, the device
2063 * is supposed to finish reset at its driver probe stage, so no
2064 * in-flight DMA will exist, and we don't need to worry anymore
2065 * hereafter.
2066 */
2067 if (context_copied(context)) {
2068 u16 did_old = context_domain_id(context);
2069
Christos Gkekasb117e032017-10-08 23:33:31 +01002070 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002071 iommu->flush.flush_context(iommu, did_old,
2072 (((u16)bus) << 8) | devfn,
2073 DMA_CCMD_MASK_NOBIT,
2074 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002075 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2076 DMA_TLB_DSI_FLUSH);
2077 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002078 }
2079
Weidong Hanea6606b2008-12-08 23:08:15 +08002080 pgd = domain->pgd;
2081
Joerg Roedelde24e552015-07-21 14:53:04 +02002082 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002083 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002084
Joerg Roedelde24e552015-07-21 14:53:04 +02002085 /*
2086 * Skip top levels of page tables for iommu which has less agaw
2087 * than default. Unnecessary for PT mode.
2088 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002089 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002090 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002091 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002092 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002093 if (!dma_pte_present(pgd))
2094 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002095 }
2096
David Woodhouse64ae8922014-03-09 12:52:30 -07002097 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002098 if (info && info->ats_supported)
2099 translation = CONTEXT_TT_DEV_IOTLB;
2100 else
2101 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002102
Yu Zhao93a23a72009-05-18 13:51:37 +08002103 context_set_address_root(context, virt_to_phys(pgd));
2104 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002105 } else {
2106 /*
2107 * In pass through mode, AW must be programmed to
2108 * indicate the largest AGAW value supported by
2109 * hardware. And ASR is ignored by hardware.
2110 */
2111 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002112 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002113
2114 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002115 context_set_fault_enable(context);
2116 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002117 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002118
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002119 /*
2120 * It's a non-present to present mapping. If hardware doesn't cache
2121 * non-present entry we only need to flush the write-buffer. If the
2122 * _does_ cache non-present entries, then it does so in the special
2123 * domain #0, which we have to flush:
2124 */
2125 if (cap_caching_mode(iommu->cap)) {
2126 iommu->flush.flush_context(iommu, 0,
2127 (((u16)bus) << 8) | devfn,
2128 DMA_CCMD_MASK_NOBIT,
2129 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002130 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002131 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002132 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002133 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002134 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002135
Joerg Roedel55d94042015-07-22 16:50:40 +02002136 ret = 0;
2137
2138out_unlock:
2139 spin_unlock(&iommu->lock);
2140 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002141
Wei Yang5c365d12016-07-13 13:53:21 +00002142 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002143}
2144
Alex Williamson579305f2014-07-03 09:51:43 -06002145struct domain_context_mapping_data {
2146 struct dmar_domain *domain;
2147 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002148};
2149
2150static int domain_context_mapping_cb(struct pci_dev *pdev,
2151 u16 alias, void *opaque)
2152{
2153 struct domain_context_mapping_data *data = opaque;
2154
2155 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002156 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002157}
2158
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002159static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002160domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002161{
David Woodhouse64ae8922014-03-09 12:52:30 -07002162 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002163 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002164 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002165
David Woodhousee1f167f2014-03-09 15:24:46 -07002166 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002167 if (!iommu)
2168 return -ENODEV;
2169
Alex Williamson579305f2014-07-03 09:51:43 -06002170 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002171 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002172
2173 data.domain = domain;
2174 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002175
2176 return pci_for_each_dma_alias(to_pci_dev(dev),
2177 &domain_context_mapping_cb, &data);
2178}
2179
2180static int domain_context_mapped_cb(struct pci_dev *pdev,
2181 u16 alias, void *opaque)
2182{
2183 struct intel_iommu *iommu = opaque;
2184
2185 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002186}
2187
David Woodhousee1f167f2014-03-09 15:24:46 -07002188static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002189{
Weidong Han5331fe62008-12-08 23:00:00 +08002190 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002191 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002192
David Woodhousee1f167f2014-03-09 15:24:46 -07002193 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002194 if (!iommu)
2195 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002196
Alex Williamson579305f2014-07-03 09:51:43 -06002197 if (!dev_is_pci(dev))
2198 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002199
Alex Williamson579305f2014-07-03 09:51:43 -06002200 return !pci_for_each_dma_alias(to_pci_dev(dev),
2201 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002202}
2203
Fenghua Yuf5329592009-08-04 15:09:37 -07002204/* Returns a number of VTD pages, but aligned to MM page size */
2205static inline unsigned long aligned_nrpages(unsigned long host_addr,
2206 size_t size)
2207{
2208 host_addr &= ~PAGE_MASK;
2209 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2210}
2211
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002212/* Return largest possible superpage level for a given mapping */
2213static inline int hardware_largepage_caps(struct dmar_domain *domain,
2214 unsigned long iov_pfn,
2215 unsigned long phy_pfn,
2216 unsigned long pages)
2217{
2218 int support, level = 1;
2219 unsigned long pfnmerge;
2220
2221 support = domain->iommu_superpage;
2222
2223 /* To use a large page, the virtual *and* physical addresses
2224 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2225 of them will mean we have to use smaller pages. So just
2226 merge them and check both at once. */
2227 pfnmerge = iov_pfn | phy_pfn;
2228
2229 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2230 pages >>= VTD_STRIDE_SHIFT;
2231 if (!pages)
2232 break;
2233 pfnmerge >>= VTD_STRIDE_SHIFT;
2234 level++;
2235 support--;
2236 }
2237 return level;
2238}
2239
David Woodhouse9051aa02009-06-29 12:30:54 +01002240static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2241 struct scatterlist *sg, unsigned long phys_pfn,
2242 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002243{
2244 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002245 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002246 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002247 unsigned int largepage_lvl = 0;
2248 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002249
Jiang Liu162d1b12014-07-11 14:19:35 +08002250 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002251
2252 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2253 return -EINVAL;
2254
2255 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2256
Jiang Liucc4f14a2014-11-26 09:42:10 +08002257 if (!sg) {
2258 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002259 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2260 }
2261
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002262 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002263 uint64_t tmp;
2264
David Woodhousee1605492009-06-29 11:17:38 +01002265 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002266 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2267
Fenghua Yuf5329592009-08-04 15:09:37 -07002268 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002269 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002270 sg->dma_length = sg->length;
Robin Murphy29a90b72017-09-28 15:14:01 +01002271 pteval = (sg_phys(sg) - pgoff) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002272 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002273 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002274
David Woodhousee1605492009-06-29 11:17:38 +01002275 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002276 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2277
David Woodhouse5cf0a762014-03-19 16:07:49 +00002278 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002279 if (!pte)
2280 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002281 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002282 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002283 unsigned long nr_superpages, end_pfn;
2284
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002285 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002286 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002287
2288 nr_superpages = sg_res / lvl_pages;
2289 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2290
Jiang Liud41a4ad2014-07-11 14:19:34 +08002291 /*
2292 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002293 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002294 * We're adding new large pages, so make sure
2295 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002296 */
David Dillowbc24c572017-06-28 19:42:23 -07002297 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2298 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002299 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002300 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002301 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002302
David Woodhousee1605492009-06-29 11:17:38 +01002303 }
2304 /* We don't need lock here, nobody else
2305 * touches the iova range
2306 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002307 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002308 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002309 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002310 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2311 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002312 if (dumps) {
2313 dumps--;
2314 debug_dma_dump_mappings(NULL);
2315 }
2316 WARN_ON(1);
2317 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002318
2319 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2320
2321 BUG_ON(nr_pages < lvl_pages);
2322 BUG_ON(sg_res < lvl_pages);
2323
2324 nr_pages -= lvl_pages;
2325 iov_pfn += lvl_pages;
2326 phys_pfn += lvl_pages;
2327 pteval += lvl_pages * VTD_PAGE_SIZE;
2328 sg_res -= lvl_pages;
2329
2330 /* If the next PTE would be the first in a new page, then we
2331 need to flush the cache on the entries we've just written.
2332 And then we'll need to recalculate 'pte', so clear it and
2333 let it get set again in the if (!pte) block above.
2334
2335 If we're done (!nr_pages) we need to flush the cache too.
2336
2337 Also if we've been setting superpages, we may need to
2338 recalculate 'pte' and switch back to smaller pages for the
2339 end of the mapping, if the trailing size is not enough to
2340 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002341 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002342 if (!nr_pages || first_pte_in_page(pte) ||
2343 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002344 domain_flush_cache(domain, first_pte,
2345 (void *)pte - (void *)first_pte);
2346 pte = NULL;
2347 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002348
2349 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002350 sg = sg_next(sg);
2351 }
2352 return 0;
2353}
2354
Peter Xu87684fd2018-05-04 10:34:53 +08002355static int domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2356 struct scatterlist *sg, unsigned long phys_pfn,
2357 unsigned long nr_pages, int prot)
2358{
2359 int ret;
2360 struct intel_iommu *iommu;
2361
2362 /* Do the real mapping first */
2363 ret = __domain_mapping(domain, iov_pfn, sg, phys_pfn, nr_pages, prot);
2364 if (ret)
2365 return ret;
2366
2367 /* Notify about the new mapping */
2368 if (domain_type_is_vm(domain)) {
2369 /* VM typed domains can have more than one IOMMUs */
2370 int iommu_id;
2371 for_each_domain_iommu(iommu_id, domain) {
2372 iommu = g_iommus[iommu_id];
2373 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2374 }
2375 } else {
2376 /* General domains only have one IOMMU */
2377 iommu = domain_get_iommu(domain);
2378 __mapping_notify_one(iommu, domain, iov_pfn, nr_pages);
2379 }
2380
2381 return 0;
2382}
2383
David Woodhouse9051aa02009-06-29 12:30:54 +01002384static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2385 struct scatterlist *sg, unsigned long nr_pages,
2386 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002387{
Peter Xu87684fd2018-05-04 10:34:53 +08002388 return domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
David Woodhouse9051aa02009-06-29 12:30:54 +01002389}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002390
David Woodhouse9051aa02009-06-29 12:30:54 +01002391static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2392 unsigned long phys_pfn, unsigned long nr_pages,
2393 int prot)
2394{
Peter Xu87684fd2018-05-04 10:34:53 +08002395 return domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002396}
2397
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002398static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002399{
Filippo Sironi50822192017-08-31 10:58:11 +02002400 unsigned long flags;
2401 struct context_entry *context;
2402 u16 did_old;
2403
Weidong Hanc7151a82008-12-08 22:51:37 +08002404 if (!iommu)
2405 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002406
Filippo Sironi50822192017-08-31 10:58:11 +02002407 spin_lock_irqsave(&iommu->lock, flags);
2408 context = iommu_context_addr(iommu, bus, devfn, 0);
2409 if (!context) {
2410 spin_unlock_irqrestore(&iommu->lock, flags);
2411 return;
2412 }
2413 did_old = context_domain_id(context);
2414 context_clear_entry(context);
2415 __iommu_flush_cache(iommu, context, sizeof(*context));
2416 spin_unlock_irqrestore(&iommu->lock, flags);
2417 iommu->flush.flush_context(iommu,
2418 did_old,
2419 (((u16)bus) << 8) | devfn,
2420 DMA_CCMD_MASK_NOBIT,
2421 DMA_CCMD_DEVICE_INVL);
2422 iommu->flush.flush_iotlb(iommu,
2423 did_old,
2424 0,
2425 0,
2426 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002427}
2428
David Woodhouse109b9b02012-05-25 17:43:02 +01002429static inline void unlink_domain_info(struct device_domain_info *info)
2430{
2431 assert_spin_locked(&device_domain_lock);
2432 list_del(&info->link);
2433 list_del(&info->global);
2434 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002435 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002436}
2437
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002438static void domain_remove_dev_info(struct dmar_domain *domain)
2439{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002440 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002441 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002442
2443 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002444 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002445 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002446 spin_unlock_irqrestore(&device_domain_lock, flags);
2447}
2448
2449/*
2450 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002451 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002452 */
David Woodhouse1525a292014-03-06 16:19:30 +00002453static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002454{
2455 struct device_domain_info *info;
2456
2457 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002458 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002459 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002460 return info->domain;
2461 return NULL;
2462}
2463
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002464static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002465dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2466{
2467 struct device_domain_info *info;
2468
2469 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002470 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002471 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002472 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002473
2474 return NULL;
2475}
2476
Joerg Roedel5db31562015-07-22 12:40:43 +02002477static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2478 int bus, int devfn,
2479 struct device *dev,
2480 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002481{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002482 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002483 struct device_domain_info *info;
2484 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002485 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002486
2487 info = alloc_devinfo_mem();
2488 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002489 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002490
Jiang Liu745f2582014-02-19 14:07:26 +08002491 info->bus = bus;
2492 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002493 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2494 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2495 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002496 info->dev = dev;
2497 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002498 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002499
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002500 if (dev && dev_is_pci(dev)) {
2501 struct pci_dev *pdev = to_pci_dev(info->dev);
2502
2503 if (ecap_dev_iotlb_support(iommu->ecap) &&
2504 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2505 dmar_find_matched_atsr_unit(pdev))
2506 info->ats_supported = 1;
2507
2508 if (ecs_enabled(iommu)) {
2509 if (pasid_enabled(iommu)) {
2510 int features = pci_pasid_features(pdev);
2511 if (features >= 0)
2512 info->pasid_supported = features | 1;
2513 }
2514
2515 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2516 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2517 info->pri_supported = 1;
2518 }
2519 }
2520
Jiang Liu745f2582014-02-19 14:07:26 +08002521 spin_lock_irqsave(&device_domain_lock, flags);
2522 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002523 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002524
2525 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002526 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002527 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002528 if (info2) {
2529 found = info2->domain;
2530 info2->dev = dev;
2531 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002532 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002533
Jiang Liu745f2582014-02-19 14:07:26 +08002534 if (found) {
2535 spin_unlock_irqrestore(&device_domain_lock, flags);
2536 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002537 /* Caller must free the original domain */
2538 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002539 }
2540
Joerg Roedeld160aca2015-07-22 11:52:53 +02002541 spin_lock(&iommu->lock);
2542 ret = domain_attach_iommu(domain, iommu);
2543 spin_unlock(&iommu->lock);
2544
2545 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002546 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302547 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002548 return NULL;
2549 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002550
David Woodhouseb718cd32014-03-09 13:11:33 -07002551 list_add(&info->link, &domain->devices);
2552 list_add(&info->global, &device_domain_list);
2553 if (dev)
2554 dev->archdata.iommu = info;
2555 spin_unlock_irqrestore(&device_domain_lock, flags);
2556
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002557 if (dev && domain_context_mapping(domain, dev)) {
2558 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002559 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002560 return NULL;
2561 }
2562
David Woodhouseb718cd32014-03-09 13:11:33 -07002563 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002564}
2565
Alex Williamson579305f2014-07-03 09:51:43 -06002566static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2567{
2568 *(u16 *)opaque = alias;
2569 return 0;
2570}
2571
Joerg Roedel76208352016-08-25 14:25:12 +02002572static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002573{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002574 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002575 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002576 struct intel_iommu *iommu;
Joerg Roedel08a7f452015-07-23 18:09:11 +02002577 u16 req_id, dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002578 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002579 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002580
David Woodhouse146922e2014-03-09 15:44:17 -07002581 iommu = device_to_iommu(dev, &bus, &devfn);
2582 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002583 return NULL;
2584
Joerg Roedel08a7f452015-07-23 18:09:11 +02002585 req_id = ((u16)bus << 8) | devfn;
2586
Alex Williamson579305f2014-07-03 09:51:43 -06002587 if (dev_is_pci(dev)) {
2588 struct pci_dev *pdev = to_pci_dev(dev);
2589
2590 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2591
2592 spin_lock_irqsave(&device_domain_lock, flags);
2593 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2594 PCI_BUS_NUM(dma_alias),
2595 dma_alias & 0xff);
2596 if (info) {
2597 iommu = info->iommu;
2598 domain = info->domain;
2599 }
2600 spin_unlock_irqrestore(&device_domain_lock, flags);
2601
Joerg Roedel76208352016-08-25 14:25:12 +02002602 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002603 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002604 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002605 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002606
David Woodhouse146922e2014-03-09 15:44:17 -07002607 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002608 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002609 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002610 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002611 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002612 domain_exit(domain);
2613 return NULL;
2614 }
2615
Joerg Roedel76208352016-08-25 14:25:12 +02002616out:
Alex Williamson579305f2014-07-03 09:51:43 -06002617
Joerg Roedel76208352016-08-25 14:25:12 +02002618 return domain;
2619}
2620
2621static struct dmar_domain *set_domain_for_dev(struct device *dev,
2622 struct dmar_domain *domain)
2623{
2624 struct intel_iommu *iommu;
2625 struct dmar_domain *tmp;
2626 u16 req_id, dma_alias;
2627 u8 bus, devfn;
2628
2629 iommu = device_to_iommu(dev, &bus, &devfn);
2630 if (!iommu)
2631 return NULL;
2632
2633 req_id = ((u16)bus << 8) | devfn;
2634
2635 if (dev_is_pci(dev)) {
2636 struct pci_dev *pdev = to_pci_dev(dev);
2637
2638 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2639
2640 /* register PCI DMA alias device */
2641 if (req_id != dma_alias) {
2642 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2643 dma_alias & 0xff, NULL, domain);
2644
2645 if (!tmp || tmp != domain)
2646 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002647 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002648 }
2649
Joerg Roedel5db31562015-07-22 12:40:43 +02002650 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002651 if (!tmp || tmp != domain)
2652 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002653
Joerg Roedel76208352016-08-25 14:25:12 +02002654 return domain;
2655}
2656
2657static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2658{
2659 struct dmar_domain *domain, *tmp;
2660
2661 domain = find_domain(dev);
2662 if (domain)
2663 goto out;
2664
2665 domain = find_or_alloc_domain(dev, gaw);
2666 if (!domain)
2667 goto out;
2668
2669 tmp = set_domain_for_dev(dev, domain);
2670 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002671 domain_exit(domain);
2672 domain = tmp;
2673 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002674
Joerg Roedel76208352016-08-25 14:25:12 +02002675out:
2676
David Woodhouseb718cd32014-03-09 13:11:33 -07002677 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002678}
2679
David Woodhouseb2132032009-06-26 18:50:28 +01002680static int iommu_domain_identity_map(struct dmar_domain *domain,
2681 unsigned long long start,
2682 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002683{
David Woodhousec5395d52009-06-28 16:35:56 +01002684 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2685 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002686
David Woodhousec5395d52009-06-28 16:35:56 +01002687 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2688 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002689 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002690 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002691 }
2692
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002693 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002694 /*
2695 * RMRR range might have overlap with physical memory range,
2696 * clear it first
2697 */
David Woodhousec5395d52009-06-28 16:35:56 +01002698 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002699
Peter Xu87684fd2018-05-04 10:34:53 +08002700 return __domain_mapping(domain, first_vpfn, NULL,
2701 first_vpfn, last_vpfn - first_vpfn + 1,
2702 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002703}
2704
Joerg Roedeld66ce542015-09-23 19:00:10 +02002705static int domain_prepare_identity_map(struct device *dev,
2706 struct dmar_domain *domain,
2707 unsigned long long start,
2708 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002709{
David Woodhouse19943b02009-08-04 16:19:20 +01002710 /* For _hardware_ passthrough, don't bother. But for software
2711 passthrough, we do it anyway -- it may indicate a memory
2712 range which is reserved in E820, so which didn't get set
2713 up to start with in si_domain */
2714 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002715 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2716 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002717 return 0;
2718 }
2719
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002720 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2721 dev_name(dev), start, end);
2722
David Woodhouse5595b522009-12-02 09:21:55 +00002723 if (end < start) {
2724 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2725 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2726 dmi_get_system_info(DMI_BIOS_VENDOR),
2727 dmi_get_system_info(DMI_BIOS_VERSION),
2728 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002729 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002730 }
2731
David Woodhouse2ff729f2009-08-26 14:25:41 +01002732 if (end >> agaw_to_width(domain->agaw)) {
2733 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2734 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2735 agaw_to_width(domain->agaw),
2736 dmi_get_system_info(DMI_BIOS_VENDOR),
2737 dmi_get_system_info(DMI_BIOS_VERSION),
2738 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002739 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002740 }
David Woodhouse19943b02009-08-04 16:19:20 +01002741
Joerg Roedeld66ce542015-09-23 19:00:10 +02002742 return iommu_domain_identity_map(domain, start, end);
2743}
2744
2745static int iommu_prepare_identity_map(struct device *dev,
2746 unsigned long long start,
2747 unsigned long long end)
2748{
2749 struct dmar_domain *domain;
2750 int ret;
2751
2752 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2753 if (!domain)
2754 return -ENOMEM;
2755
2756 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002757 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002758 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002759
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002760 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002761}
2762
2763static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002764 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002765{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002766 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002767 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002768 return iommu_prepare_identity_map(dev, rmrr->base_address,
2769 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002770}
2771
Suresh Siddhad3f13812011-08-23 17:05:25 -07002772#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002773static inline void iommu_prepare_isa(void)
2774{
2775 struct pci_dev *pdev;
2776 int ret;
2777
2778 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2779 if (!pdev)
2780 return;
2781
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002782 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002783 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002784
2785 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002786 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002787
Yijing Wang9b27e822014-05-20 20:37:52 +08002788 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002789}
2790#else
2791static inline void iommu_prepare_isa(void)
2792{
2793 return;
2794}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002795#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002796
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002797static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002798
Matt Kraai071e1372009-08-23 22:30:22 -07002799static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002800{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002801 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002802
Jiang Liuab8dfe22014-07-11 14:19:27 +08002803 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002804 if (!si_domain)
2805 return -EFAULT;
2806
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002807 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2808 domain_exit(si_domain);
2809 return -EFAULT;
2810 }
2811
Joerg Roedel0dc79712015-07-21 15:40:06 +02002812 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002813
David Woodhouse19943b02009-08-04 16:19:20 +01002814 if (hw)
2815 return 0;
2816
David Woodhousec7ab48d2009-06-26 19:10:36 +01002817 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002818 unsigned long start_pfn, end_pfn;
2819 int i;
2820
2821 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2822 ret = iommu_domain_identity_map(si_domain,
2823 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2824 if (ret)
2825 return ret;
2826 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002827 }
2828
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002829 return 0;
2830}
2831
David Woodhouse9b226622014-03-09 14:03:28 -07002832static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002833{
2834 struct device_domain_info *info;
2835
2836 if (likely(!iommu_identity_mapping))
2837 return 0;
2838
David Woodhouse9b226622014-03-09 14:03:28 -07002839 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002840 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2841 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002842
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002843 return 0;
2844}
2845
Joerg Roedel28ccce02015-07-21 14:45:31 +02002846static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002847{
David Woodhouse0ac72662014-03-09 13:19:22 -07002848 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002849 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002850 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002851
David Woodhouse5913c9b2014-03-09 16:27:31 -07002852 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002853 if (!iommu)
2854 return -ENODEV;
2855
Joerg Roedel5db31562015-07-22 12:40:43 +02002856 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002857 if (ndomain != domain)
2858 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002859
2860 return 0;
2861}
2862
David Woodhouse0b9d9752014-03-09 15:48:15 -07002863static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002864{
2865 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002866 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002867 int i;
2868
Jiang Liu0e242612014-02-19 14:07:34 +08002869 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002870 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002871 /*
2872 * Return TRUE if this RMRR contains the device that
2873 * is passed in.
2874 */
2875 for_each_active_dev_scope(rmrr->devices,
2876 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002877 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002878 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002879 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002880 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002881 }
Jiang Liu0e242612014-02-19 14:07:34 +08002882 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002883 return false;
2884}
2885
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002886/*
2887 * There are a couple cases where we need to restrict the functionality of
2888 * devices associated with RMRRs. The first is when evaluating a device for
2889 * identity mapping because problems exist when devices are moved in and out
2890 * of domains and their respective RMRR information is lost. This means that
2891 * a device with associated RMRRs will never be in a "passthrough" domain.
2892 * The second is use of the device through the IOMMU API. This interface
2893 * expects to have full control of the IOVA space for the device. We cannot
2894 * satisfy both the requirement that RMRR access is maintained and have an
2895 * unencumbered IOVA space. We also have no ability to quiesce the device's
2896 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2897 * We therefore prevent devices associated with an RMRR from participating in
2898 * the IOMMU API, which eliminates them from device assignment.
2899 *
2900 * In both cases we assume that PCI USB devices with RMRRs have them largely
2901 * for historical reasons and that the RMRR space is not actively used post
2902 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002903 *
2904 * The same exception is made for graphics devices, with the requirement that
2905 * any use of the RMRR regions will be torn down before assigning the device
2906 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002907 */
2908static bool device_is_rmrr_locked(struct device *dev)
2909{
2910 if (!device_has_rmrr(dev))
2911 return false;
2912
2913 if (dev_is_pci(dev)) {
2914 struct pci_dev *pdev = to_pci_dev(dev);
2915
David Woodhouse18436af2015-03-25 15:05:47 +00002916 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002917 return false;
2918 }
2919
2920 return true;
2921}
2922
David Woodhouse3bdb2592014-03-09 16:03:08 -07002923static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002924{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002925
David Woodhouse3bdb2592014-03-09 16:03:08 -07002926 if (dev_is_pci(dev)) {
2927 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002928
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002929 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002930 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002931
David Woodhouse3bdb2592014-03-09 16:03:08 -07002932 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2933 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002934
David Woodhouse3bdb2592014-03-09 16:03:08 -07002935 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2936 return 1;
2937
2938 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2939 return 0;
2940
2941 /*
2942 * We want to start off with all devices in the 1:1 domain, and
2943 * take them out later if we find they can't access all of memory.
2944 *
2945 * However, we can't do this for PCI devices behind bridges,
2946 * because all PCI devices behind the same bridge will end up
2947 * with the same source-id on their transactions.
2948 *
2949 * Practically speaking, we can't change things around for these
2950 * devices at run-time, because we can't be sure there'll be no
2951 * DMA transactions in flight for any of their siblings.
2952 *
2953 * So PCI devices (unless they're on the root bus) as well as
2954 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2955 * the 1:1 domain, just in _case_ one of their siblings turns out
2956 * not to be able to map all of memory.
2957 */
2958 if (!pci_is_pcie(pdev)) {
2959 if (!pci_is_root_bus(pdev->bus))
2960 return 0;
2961 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2962 return 0;
2963 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2964 return 0;
2965 } else {
2966 if (device_has_rmrr(dev))
2967 return 0;
2968 }
David Woodhouse6941af22009-07-04 18:24:27 +01002969
David Woodhouse3dfc8132009-07-04 19:11:08 +01002970 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002971 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002972 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002973 * take them out of the 1:1 domain later.
2974 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002975 if (!startup) {
2976 /*
2977 * If the device's dma_mask is less than the system's memory
2978 * size then this is not a candidate for identity mapping.
2979 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002980 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002981
David Woodhouse3bdb2592014-03-09 16:03:08 -07002982 if (dev->coherent_dma_mask &&
2983 dev->coherent_dma_mask < dma_mask)
2984 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002985
David Woodhouse3bdb2592014-03-09 16:03:08 -07002986 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002987 }
David Woodhouse6941af22009-07-04 18:24:27 +01002988
2989 return 1;
2990}
2991
David Woodhousecf04eee2014-03-21 16:49:04 +00002992static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2993{
2994 int ret;
2995
2996 if (!iommu_should_identity_map(dev, 1))
2997 return 0;
2998
Joerg Roedel28ccce02015-07-21 14:45:31 +02002999 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00003000 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003001 pr_info("%s identity mapping for device %s\n",
3002 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00003003 else if (ret == -ENODEV)
3004 /* device not associated with an iommu */
3005 ret = 0;
3006
3007 return ret;
3008}
3009
3010
Matt Kraai071e1372009-08-23 22:30:22 -07003011static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003012{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003013 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00003014 struct dmar_drhd_unit *drhd;
3015 struct intel_iommu *iommu;
3016 struct device *dev;
3017 int i;
3018 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003019
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003020 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00003021 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
3022 if (ret)
3023 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003024 }
3025
David Woodhousecf04eee2014-03-21 16:49:04 +00003026 for_each_active_iommu(iommu, drhd)
3027 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
3028 struct acpi_device_physical_node *pn;
3029 struct acpi_device *adev;
3030
3031 if (dev->bus != &acpi_bus_type)
3032 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02003033
David Woodhousecf04eee2014-03-21 16:49:04 +00003034 adev= to_acpi_device(dev);
3035 mutex_lock(&adev->physical_node_lock);
3036 list_for_each_entry(pn, &adev->physical_node_list, node) {
3037 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
3038 if (ret)
3039 break;
3040 }
3041 mutex_unlock(&adev->physical_node_lock);
3042 if (ret)
3043 return ret;
3044 }
3045
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003046 return 0;
3047}
3048
Jiang Liuffebeb42014-11-09 22:48:02 +08003049static void intel_iommu_init_qi(struct intel_iommu *iommu)
3050{
3051 /*
3052 * Start from the sane iommu hardware state.
3053 * If the queued invalidation is already initialized by us
3054 * (for example, while enabling interrupt-remapping) then
3055 * we got the things already rolling from a sane state.
3056 */
3057 if (!iommu->qi) {
3058 /*
3059 * Clear any previous faults.
3060 */
3061 dmar_fault(-1, iommu);
3062 /*
3063 * Disable queued invalidation if supported and already enabled
3064 * before OS handover.
3065 */
3066 dmar_disable_qi(iommu);
3067 }
3068
3069 if (dmar_enable_qi(iommu)) {
3070 /*
3071 * Queued Invalidate not enabled, use Register Based Invalidate
3072 */
3073 iommu->flush.flush_context = __iommu_flush_context;
3074 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003075 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003076 iommu->name);
3077 } else {
3078 iommu->flush.flush_context = qi_flush_context;
3079 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003080 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003081 }
3082}
3083
Joerg Roedel091d42e2015-06-12 11:56:10 +02003084static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003085 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003086 struct context_entry **tbl,
3087 int bus, bool ext)
3088{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003089 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003090 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003091 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003092 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003093 phys_addr_t old_ce_phys;
3094
3095 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003096 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003097
3098 for (devfn = 0; devfn < 256; devfn++) {
3099 /* First calculate the correct index */
3100 idx = (ext ? devfn * 2 : devfn) % 256;
3101
3102 if (idx == 0) {
3103 /* First save what we may have and clean up */
3104 if (new_ce) {
3105 tbl[tbl_idx] = new_ce;
3106 __iommu_flush_cache(iommu, new_ce,
3107 VTD_PAGE_SIZE);
3108 pos = 1;
3109 }
3110
3111 if (old_ce)
3112 iounmap(old_ce);
3113
3114 ret = 0;
3115 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003116 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003117 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003118 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003119
3120 if (!old_ce_phys) {
3121 if (ext && devfn == 0) {
3122 /* No LCTP, try UCTP */
3123 devfn = 0x7f;
3124 continue;
3125 } else {
3126 goto out;
3127 }
3128 }
3129
3130 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003131 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3132 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003133 if (!old_ce)
3134 goto out;
3135
3136 new_ce = alloc_pgtable_page(iommu->node);
3137 if (!new_ce)
3138 goto out_unmap;
3139
3140 ret = 0;
3141 }
3142
3143 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003144 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003145
Joerg Roedelcf484d02015-06-12 12:21:46 +02003146 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003147 continue;
3148
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003149 did = context_domain_id(&ce);
3150 if (did >= 0 && did < cap_ndoms(iommu->cap))
3151 set_bit(did, iommu->domain_ids);
3152
Joerg Roedelcf484d02015-06-12 12:21:46 +02003153 /*
3154 * We need a marker for copied context entries. This
3155 * marker needs to work for the old format as well as
3156 * for extended context entries.
3157 *
3158 * Bit 67 of the context entry is used. In the old
3159 * format this bit is available to software, in the
3160 * extended format it is the PGE bit, but PGE is ignored
3161 * by HW if PASIDs are disabled (and thus still
3162 * available).
3163 *
3164 * So disable PASIDs first and then mark the entry
3165 * copied. This means that we don't copy PASID
3166 * translations from the old kernel, but this is fine as
3167 * faults there are not fatal.
3168 */
3169 context_clear_pasid_enable(&ce);
3170 context_set_copied(&ce);
3171
Joerg Roedel091d42e2015-06-12 11:56:10 +02003172 new_ce[idx] = ce;
3173 }
3174
3175 tbl[tbl_idx + pos] = new_ce;
3176
3177 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3178
3179out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003180 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003181
3182out:
3183 return ret;
3184}
3185
3186static int copy_translation_tables(struct intel_iommu *iommu)
3187{
3188 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003189 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003190 phys_addr_t old_rt_phys;
3191 int ctxt_table_entries;
3192 unsigned long flags;
3193 u64 rtaddr_reg;
3194 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003195 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003196
3197 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3198 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003199 new_ext = !!ecap_ecs(iommu->ecap);
3200
3201 /*
3202 * The RTT bit can only be changed when translation is disabled,
3203 * but disabling translation means to open a window for data
3204 * corruption. So bail out and don't copy anything if we would
3205 * have to change the bit.
3206 */
3207 if (new_ext != ext)
3208 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003209
3210 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3211 if (!old_rt_phys)
3212 return -EINVAL;
3213
Dan Williamsdfddb9692015-10-09 18:16:46 -04003214 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003215 if (!old_rt)
3216 return -ENOMEM;
3217
3218 /* This is too big for the stack - allocate it from slab */
3219 ctxt_table_entries = ext ? 512 : 256;
3220 ret = -ENOMEM;
3221 ctxt_tbls = kzalloc(ctxt_table_entries * sizeof(void *), GFP_KERNEL);
3222 if (!ctxt_tbls)
3223 goto out_unmap;
3224
3225 for (bus = 0; bus < 256; bus++) {
3226 ret = copy_context_table(iommu, &old_rt[bus],
3227 ctxt_tbls, bus, ext);
3228 if (ret) {
3229 pr_err("%s: Failed to copy context table for bus %d\n",
3230 iommu->name, bus);
3231 continue;
3232 }
3233 }
3234
3235 spin_lock_irqsave(&iommu->lock, flags);
3236
3237 /* Context tables are copied, now write them to the root_entry table */
3238 for (bus = 0; bus < 256; bus++) {
3239 int idx = ext ? bus * 2 : bus;
3240 u64 val;
3241
3242 if (ctxt_tbls[idx]) {
3243 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3244 iommu->root_entry[bus].lo = val;
3245 }
3246
3247 if (!ext || !ctxt_tbls[idx + 1])
3248 continue;
3249
3250 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3251 iommu->root_entry[bus].hi = val;
3252 }
3253
3254 spin_unlock_irqrestore(&iommu->lock, flags);
3255
3256 kfree(ctxt_tbls);
3257
3258 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3259
3260 ret = 0;
3261
3262out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003263 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003264
3265 return ret;
3266}
3267
Joseph Cihulab7792602011-05-03 00:08:37 -07003268static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003269{
3270 struct dmar_drhd_unit *drhd;
3271 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003272 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003273 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003274 struct intel_iommu *iommu;
Joerg Roedel13cf0172017-08-11 11:40:10 +02003275 int i, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003276
3277 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003278 * for each drhd
3279 * allocate root
3280 * initialize and program root entry to not present
3281 * endfor
3282 */
3283 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003284 /*
3285 * lock not needed as this is only incremented in the single
3286 * threaded kernel __init code path all other access are read
3287 * only
3288 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003289 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003290 g_num_of_iommus++;
3291 continue;
3292 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003293 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003294 }
3295
Jiang Liuffebeb42014-11-09 22:48:02 +08003296 /* Preallocate enough resources for IOMMU hot-addition */
3297 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3298 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3299
Weidong Hand9630fe2008-12-08 11:06:32 +08003300 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3301 GFP_KERNEL);
3302 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003303 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003304 ret = -ENOMEM;
3305 goto error;
3306 }
3307
Jiang Liu7c919772014-01-06 14:18:18 +08003308 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003309 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003310
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003311 intel_iommu_init_qi(iommu);
3312
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003313 ret = iommu_init_domains(iommu);
3314 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003315 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003316
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003317 init_translation_status(iommu);
3318
Joerg Roedel091d42e2015-06-12 11:56:10 +02003319 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3320 iommu_disable_translation(iommu);
3321 clear_translation_pre_enabled(iommu);
3322 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3323 iommu->name);
3324 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003325
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003326 /*
3327 * TBD:
3328 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003329 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003330 */
3331 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003332 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003333 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003334
Joerg Roedel091d42e2015-06-12 11:56:10 +02003335 if (translation_pre_enabled(iommu)) {
3336 pr_info("Translation already enabled - trying to copy translation structures\n");
3337
3338 ret = copy_translation_tables(iommu);
3339 if (ret) {
3340 /*
3341 * We found the IOMMU with translation
3342 * enabled - but failed to copy over the
3343 * old root-entry table. Try to proceed
3344 * by disabling translation now and
3345 * allocating a clean root-entry table.
3346 * This might cause DMAR faults, but
3347 * probably the dump will still succeed.
3348 */
3349 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3350 iommu->name);
3351 iommu_disable_translation(iommu);
3352 clear_translation_pre_enabled(iommu);
3353 } else {
3354 pr_info("Copied translation tables from previous kernel for %s\n",
3355 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003356 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003357 }
3358 }
3359
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003360 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003361 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003362#ifdef CONFIG_INTEL_IOMMU_SVM
3363 if (pasid_enabled(iommu))
3364 intel_svm_alloc_pasid_tables(iommu);
3365#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003366 }
3367
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003368 /*
3369 * Now that qi is enabled on all iommus, set the root entry and flush
3370 * caches. This is required on some Intel X58 chipsets, otherwise the
3371 * flush_context function will loop forever and the boot hangs.
3372 */
3373 for_each_active_iommu(iommu, drhd) {
3374 iommu_flush_write_buffer(iommu);
3375 iommu_set_root_entry(iommu);
3376 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3377 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3378 }
3379
David Woodhouse19943b02009-08-04 16:19:20 +01003380 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003381 iommu_identity_mapping |= IDENTMAP_ALL;
3382
Suresh Siddhad3f13812011-08-23 17:05:25 -07003383#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003384 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003385#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003386
Ashok Raj21e722c2017-01-30 09:39:53 -08003387 check_tylersburg_isoch();
3388
Joerg Roedel86080cc2015-06-12 12:27:16 +02003389 if (iommu_identity_mapping) {
3390 ret = si_domain_init(hw_pass_through);
3391 if (ret)
3392 goto free_iommu;
3393 }
3394
David Woodhousee0fc7e02009-09-30 09:12:17 -07003395
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003396 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003397 * If we copied translations from a previous kernel in the kdump
3398 * case, we can not assign the devices to domains now, as that
3399 * would eliminate the old mappings. So skip this part and defer
3400 * the assignment to device driver initialization time.
3401 */
3402 if (copied_tables)
3403 goto domains_done;
3404
3405 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003406 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003407 * identity mappings for rmrr, gfx, and isa and may fall back to static
3408 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003409 */
David Woodhouse19943b02009-08-04 16:19:20 +01003410 if (iommu_identity_mapping) {
3411 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3412 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003413 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003414 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003415 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003416 }
David Woodhouse19943b02009-08-04 16:19:20 +01003417 /*
3418 * For each rmrr
3419 * for each dev attached to rmrr
3420 * do
3421 * locate drhd for dev, alloc domain for dev
3422 * allocate free domain
3423 * allocate page table entries for rmrr
3424 * if context not allocated for bus
3425 * allocate and init context
3426 * set present in root table for this bus
3427 * init context with domain, translation etc
3428 * endfor
3429 * endfor
3430 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003431 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003432 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003433 /* some BIOS lists non-exist devices in DMAR table. */
3434 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003435 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003436 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003437 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003438 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003439 }
3440 }
3441
3442 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003443
Joerg Roedela87f4912015-06-12 12:32:54 +02003444domains_done:
3445
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003446 /*
3447 * for each drhd
3448 * enable fault log
3449 * global invalidate context cache
3450 * global invalidate iotlb
3451 * enable translation
3452 */
Jiang Liu7c919772014-01-06 14:18:18 +08003453 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003454 if (drhd->ignored) {
3455 /*
3456 * we always have to disable PMRs or DMA may fail on
3457 * this device
3458 */
3459 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003460 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003461 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003462 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003463
3464 iommu_flush_write_buffer(iommu);
3465
David Woodhousea222a7f2015-10-07 23:35:18 +01003466#ifdef CONFIG_INTEL_IOMMU_SVM
3467 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3468 ret = intel_svm_enable_prq(iommu);
3469 if (ret)
3470 goto free_iommu;
3471 }
3472#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003473 ret = dmar_set_interrupt(iommu);
3474 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003475 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003476
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003477 if (!translation_pre_enabled(iommu))
3478 iommu_enable_translation(iommu);
3479
David Woodhouseb94996c2009-09-19 15:28:12 -07003480 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003481 }
3482
3483 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003484
3485free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003486 for_each_active_iommu(iommu, drhd) {
3487 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003488 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003489 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003490
Weidong Hand9630fe2008-12-08 11:06:32 +08003491 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003492
Jiang Liu989d51f2014-02-19 14:07:21 +08003493error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003494 return ret;
3495}
3496
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003497/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003498static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003499 struct dmar_domain *domain,
3500 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003501{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003502 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003503
David Woodhouse875764d2009-06-28 21:20:51 +01003504 /* Restrict dma_mask to the width that the iommu can handle */
3505 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003506 /* Ensure we reserve the whole size-aligned region */
3507 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003508
3509 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003510 /*
3511 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003512 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003513 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003514 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003515 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003516 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003517 if (iova_pfn)
3518 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003519 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003520 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3521 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003522 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003523 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003524 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003525 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003526 }
3527
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003528 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003529}
3530
Peter Xub316d022017-05-22 18:28:51 +08003531static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003532{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003533 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003534 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003535 struct device *i_dev;
3536 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003537
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003538 domain = find_domain(dev);
3539 if (domain)
3540 goto out;
3541
3542 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3543 if (!domain)
3544 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003545
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003546 /* We have a new domain - setup possible RMRRs for the device */
3547 rcu_read_lock();
3548 for_each_rmrr_units(rmrr) {
3549 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3550 i, i_dev) {
3551 if (i_dev != dev)
3552 continue;
3553
3554 ret = domain_prepare_identity_map(dev, domain,
3555 rmrr->base_address,
3556 rmrr->end_address);
3557 if (ret)
3558 dev_err(dev, "Mapping reserved region failed\n");
3559 }
3560 }
3561 rcu_read_unlock();
3562
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003563 tmp = set_domain_for_dev(dev, domain);
3564 if (!tmp || domain != tmp) {
3565 domain_exit(domain);
3566 domain = tmp;
3567 }
3568
3569out:
3570
3571 if (!domain)
3572 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3573
3574
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003575 return domain;
3576}
3577
David Woodhouseecb509e2014-03-09 16:29:55 -07003578/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003579static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003580{
3581 int found;
3582
David Woodhouse3d891942014-03-06 15:59:26 +00003583 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003584 return 1;
3585
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003586 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003587 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003588
David Woodhouse9b226622014-03-09 14:03:28 -07003589 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003590 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003591 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003592 return 1;
3593 else {
3594 /*
3595 * 32 bit DMA is removed from si_domain and fall back
3596 * to non-identity mapping.
3597 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003598 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003599 pr_info("32bit %s uses non-identity mapping\n",
3600 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003601 return 0;
3602 }
3603 } else {
3604 /*
3605 * In case of a detached 64 bit DMA device from vm, the device
3606 * is put into si_domain for identity mapping.
3607 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003608 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003609 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003610 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003611 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003612 pr_info("64bit %s uses identity mapping\n",
3613 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003614 return 1;
3615 }
3616 }
3617 }
3618
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003619 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003620}
3621
David Woodhouse5040a912014-03-09 16:14:00 -07003622static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003623 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003624{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003625 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003626 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003627 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003628 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003629 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003630 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003631 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003632
3633 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003634
David Woodhouse5040a912014-03-09 16:14:00 -07003635 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003636 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003637
David Woodhouse5040a912014-03-09 16:14:00 -07003638 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003639 if (!domain)
3640 return 0;
3641
Weidong Han8c11e792008-12-08 15:29:22 +08003642 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003643 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003644
Omer Peleg2aac6302016-04-20 11:33:57 +03003645 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3646 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003647 goto error;
3648
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003649 /*
3650 * Check if DMAR supports zero-length reads on write only
3651 * mappings..
3652 */
3653 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003654 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003655 prot |= DMA_PTE_READ;
3656 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3657 prot |= DMA_PTE_WRITE;
3658 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003659 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003660 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003661 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003662 * is not a big problem
3663 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003664 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003665 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003666 if (ret)
3667 goto error;
3668
Omer Peleg2aac6302016-04-20 11:33:57 +03003669 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003670 start_paddr += paddr & ~PAGE_MASK;
3671 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003672
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003673error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003674 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003675 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003676 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003677 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003678 return 0;
3679}
3680
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003681static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3682 unsigned long offset, size_t size,
3683 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003684 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003685{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003686 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003687 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003688}
3689
Omer Peleg769530e2016-04-20 11:33:25 +03003690static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003691{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003692 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003693 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003694 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003695 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003696 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003697 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003698
David Woodhouse73676832009-07-04 14:08:36 +01003699 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003700 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003701
David Woodhouse1525a292014-03-06 16:19:30 +00003702 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003703 BUG_ON(!domain);
3704
Weidong Han8c11e792008-12-08 15:29:22 +08003705 iommu = domain_get_iommu(domain);
3706
Omer Peleg2aac6302016-04-20 11:33:57 +03003707 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003708
Omer Peleg769530e2016-04-20 11:33:25 +03003709 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003710 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003711 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003712
David Woodhoused794dc92009-06-28 00:27:49 +01003713 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003714 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003715
David Woodhouseea8ea462014-03-05 17:09:32 +00003716 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003717
mark gross5e0d2a62008-03-04 15:22:08 -08003718 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003719 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003720 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003721 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003722 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003723 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003724 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003725 queue_iova(&domain->iovad, iova_pfn, nrpages,
3726 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003727 /*
3728 * queue up the release of the unmap to save the 1/6th of the
3729 * cpu used up by the iotlb flush operation...
3730 */
mark gross5e0d2a62008-03-04 15:22:08 -08003731 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003732}
3733
Jiang Liud41a4ad2014-07-11 14:19:34 +08003734static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3735 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003736 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003737{
Omer Peleg769530e2016-04-20 11:33:25 +03003738 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003739}
3740
David Woodhouse5040a912014-03-09 16:14:00 -07003741static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003742 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003743 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003744{
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003745 void *vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003746
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003747 vaddr = dma_direct_alloc(dev, size, dma_handle, flags, attrs);
3748 if (iommu_no_mapping(dev) || !vaddr)
3749 return vaddr;
Alex Williamsone8bb9102009-11-04 15:59:34 -07003750
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003751 *dma_handle = __intel_map_single(dev, virt_to_phys(vaddr),
3752 PAGE_ALIGN(size), DMA_BIDIRECTIONAL,
3753 dev->coherent_dma_mask);
3754 if (!*dma_handle)
3755 goto out_free_pages;
3756 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003757
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003758out_free_pages:
3759 dma_direct_free(dev, size, vaddr, *dma_handle, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003760 return NULL;
3761}
3762
David Woodhouse5040a912014-03-09 16:14:00 -07003763static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003764 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003765{
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003766 if (!iommu_no_mapping(dev))
3767 intel_unmap(dev, dma_handle, PAGE_ALIGN(size));
3768 dma_direct_free(dev, size, vaddr, dma_handle, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003769}
3770
David Woodhouse5040a912014-03-09 16:14:00 -07003771static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003772 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003773 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003774{
Omer Peleg769530e2016-04-20 11:33:25 +03003775 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3776 unsigned long nrpages = 0;
3777 struct scatterlist *sg;
3778 int i;
3779
3780 for_each_sg(sglist, sg, nelems, i) {
3781 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3782 }
3783
3784 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003785}
3786
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003787static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003788 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003789{
3790 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003791 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003792
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003793 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003794 BUG_ON(!sg_page(sg));
Robin Murphy29a90b72017-09-28 15:14:01 +01003795 sg->dma_address = sg_phys(sg);
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003796 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003797 }
3798 return nelems;
3799}
3800
David Woodhouse5040a912014-03-09 16:14:00 -07003801static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003802 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003803{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003804 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003805 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003806 size_t size = 0;
3807 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003808 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003809 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003810 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003811 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003812 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003813
3814 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003815 if (iommu_no_mapping(dev))
3816 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003817
David Woodhouse5040a912014-03-09 16:14:00 -07003818 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003819 if (!domain)
3820 return 0;
3821
Weidong Han8c11e792008-12-08 15:29:22 +08003822 iommu = domain_get_iommu(domain);
3823
David Woodhouseb536d242009-06-28 14:49:31 +01003824 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003825 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003826
Omer Peleg2aac6302016-04-20 11:33:57 +03003827 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003828 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003829 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003830 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003831 return 0;
3832 }
3833
3834 /*
3835 * Check if DMAR supports zero-length reads on write only
3836 * mappings..
3837 */
3838 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003839 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003840 prot |= DMA_PTE_READ;
3841 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3842 prot |= DMA_PTE_WRITE;
3843
Omer Peleg2aac6302016-04-20 11:33:57 +03003844 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003845
Fenghua Yuf5329592009-08-04 15:09:37 -07003846 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003847 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003848 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003849 start_vpfn + size - 1,
3850 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003851 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003852 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003853 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003854
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003855 return nelems;
3856}
3857
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003858static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3859{
3860 return !dma_addr;
3861}
3862
Arvind Yadav01e19322017-06-28 16:39:32 +05303863const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003864 .alloc = intel_alloc_coherent,
3865 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003866 .map_sg = intel_map_sg,
3867 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003868 .map_page = intel_map_page,
3869 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003870 .mapping_error = intel_mapping_error,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003871#ifdef CONFIG_X86
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003872 .dma_supported = dma_direct_supported,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003873#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003874};
3875
3876static inline int iommu_domain_cache_init(void)
3877{
3878 int ret = 0;
3879
3880 iommu_domain_cache = kmem_cache_create("iommu_domain",
3881 sizeof(struct dmar_domain),
3882 0,
3883 SLAB_HWCACHE_ALIGN,
3884
3885 NULL);
3886 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003887 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003888 ret = -ENOMEM;
3889 }
3890
3891 return ret;
3892}
3893
3894static inline int iommu_devinfo_cache_init(void)
3895{
3896 int ret = 0;
3897
3898 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3899 sizeof(struct device_domain_info),
3900 0,
3901 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003902 NULL);
3903 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003904 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003905 ret = -ENOMEM;
3906 }
3907
3908 return ret;
3909}
3910
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003911static int __init iommu_init_mempool(void)
3912{
3913 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003914 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003915 if (ret)
3916 return ret;
3917
3918 ret = iommu_domain_cache_init();
3919 if (ret)
3920 goto domain_error;
3921
3922 ret = iommu_devinfo_cache_init();
3923 if (!ret)
3924 return ret;
3925
3926 kmem_cache_destroy(iommu_domain_cache);
3927domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003928 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003929
3930 return -ENOMEM;
3931}
3932
3933static void __init iommu_exit_mempool(void)
3934{
3935 kmem_cache_destroy(iommu_devinfo_cache);
3936 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003937 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003938}
3939
Dan Williams556ab452010-07-23 15:47:56 -07003940static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3941{
3942 struct dmar_drhd_unit *drhd;
3943 u32 vtbar;
3944 int rc;
3945
3946 /* We know that this device on this chipset has its own IOMMU.
3947 * If we find it under a different IOMMU, then the BIOS is lying
3948 * to us. Hope that the IOMMU for this device is actually
3949 * disabled, and it needs no translation...
3950 */
3951 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3952 if (rc) {
3953 /* "can't" happen */
3954 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3955 return;
3956 }
3957 vtbar &= 0xffff0000;
3958
3959 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3960 drhd = dmar_find_matched_drhd_unit(pdev);
3961 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3962 TAINT_FIRMWARE_WORKAROUND,
3963 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3964 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3965}
3966DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3967
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003968static void __init init_no_remapping_devices(void)
3969{
3970 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003971 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003972 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003973
3974 for_each_drhd_unit(drhd) {
3975 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003976 for_each_active_dev_scope(drhd->devices,
3977 drhd->devices_cnt, i, dev)
3978 break;
David Woodhouse832bd852014-03-07 15:08:36 +00003979 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003980 if (i == drhd->devices_cnt)
3981 drhd->ignored = 1;
3982 }
3983 }
3984
Jiang Liu7c919772014-01-06 14:18:18 +08003985 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08003986 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003987 continue;
3988
Jiang Liub683b232014-02-19 14:07:32 +08003989 for_each_active_dev_scope(drhd->devices,
3990 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003991 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003992 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003993 if (i < drhd->devices_cnt)
3994 continue;
3995
David Woodhousec0771df2011-10-14 20:59:46 +01003996 /* This IOMMU has *only* gfx devices. Either bypass it or
3997 set the gfx_mapped flag, as appropriate */
3998 if (dmar_map_gfx) {
3999 intel_iommu_gfx_mapped = 1;
4000 } else {
4001 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08004002 for_each_active_dev_scope(drhd->devices,
4003 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00004004 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004005 }
4006 }
4007}
4008
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004009#ifdef CONFIG_SUSPEND
4010static int init_iommu_hw(void)
4011{
4012 struct dmar_drhd_unit *drhd;
4013 struct intel_iommu *iommu = NULL;
4014
4015 for_each_active_iommu(iommu, drhd)
4016 if (iommu->qi)
4017 dmar_reenable_qi(iommu);
4018
Joseph Cihulab7792602011-05-03 00:08:37 -07004019 for_each_iommu(iommu, drhd) {
4020 if (drhd->ignored) {
4021 /*
4022 * we always have to disable PMRs or DMA may fail on
4023 * this device
4024 */
4025 if (force_on)
4026 iommu_disable_protect_mem_regions(iommu);
4027 continue;
4028 }
4029
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004030 iommu_flush_write_buffer(iommu);
4031
4032 iommu_set_root_entry(iommu);
4033
4034 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004035 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004036 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4037 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004038 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004039 }
4040
4041 return 0;
4042}
4043
4044static void iommu_flush_all(void)
4045{
4046 struct dmar_drhd_unit *drhd;
4047 struct intel_iommu *iommu;
4048
4049 for_each_active_iommu(iommu, drhd) {
4050 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004051 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004052 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004053 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004054 }
4055}
4056
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004057static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004058{
4059 struct dmar_drhd_unit *drhd;
4060 struct intel_iommu *iommu = NULL;
4061 unsigned long flag;
4062
4063 for_each_active_iommu(iommu, drhd) {
4064 iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
4065 GFP_ATOMIC);
4066 if (!iommu->iommu_state)
4067 goto nomem;
4068 }
4069
4070 iommu_flush_all();
4071
4072 for_each_active_iommu(iommu, drhd) {
4073 iommu_disable_translation(iommu);
4074
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004075 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004076
4077 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4078 readl(iommu->reg + DMAR_FECTL_REG);
4079 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4080 readl(iommu->reg + DMAR_FEDATA_REG);
4081 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4082 readl(iommu->reg + DMAR_FEADDR_REG);
4083 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4084 readl(iommu->reg + DMAR_FEUADDR_REG);
4085
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004086 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004087 }
4088 return 0;
4089
4090nomem:
4091 for_each_active_iommu(iommu, drhd)
4092 kfree(iommu->iommu_state);
4093
4094 return -ENOMEM;
4095}
4096
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004097static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004098{
4099 struct dmar_drhd_unit *drhd;
4100 struct intel_iommu *iommu = NULL;
4101 unsigned long flag;
4102
4103 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004104 if (force_on)
4105 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4106 else
4107 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004108 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004109 }
4110
4111 for_each_active_iommu(iommu, drhd) {
4112
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004113 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004114
4115 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4116 iommu->reg + DMAR_FECTL_REG);
4117 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4118 iommu->reg + DMAR_FEDATA_REG);
4119 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4120 iommu->reg + DMAR_FEADDR_REG);
4121 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4122 iommu->reg + DMAR_FEUADDR_REG);
4123
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004124 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004125 }
4126
4127 for_each_active_iommu(iommu, drhd)
4128 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004129}
4130
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004131static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004132 .resume = iommu_resume,
4133 .suspend = iommu_suspend,
4134};
4135
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004136static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004137{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004138 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004139}
4140
4141#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004142static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004143#endif /* CONFIG_PM */
4144
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004145
Jiang Liuc2a0b532014-11-09 22:47:56 +08004146int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004147{
4148 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004149 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004150 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004151 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004152
4153 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4154 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004155 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004156
4157 rmrru->hdr = header;
4158 rmrr = (struct acpi_dmar_reserved_memory *)header;
4159 rmrru->base_address = rmrr->base_address;
4160 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004161
4162 length = rmrr->end_address - rmrr->base_address + 1;
4163 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4164 IOMMU_RESV_DIRECT);
4165 if (!rmrru->resv)
4166 goto free_rmrru;
4167
Jiang Liu2e455282014-02-19 14:07:36 +08004168 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4169 ((void *)rmrr) + rmrr->header.length,
4170 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004171 if (rmrru->devices_cnt && rmrru->devices == NULL)
4172 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004173
Jiang Liu2e455282014-02-19 14:07:36 +08004174 list_add(&rmrru->list, &dmar_rmrr_units);
4175
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004176 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004177free_all:
4178 kfree(rmrru->resv);
4179free_rmrru:
4180 kfree(rmrru);
4181out:
4182 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004183}
4184
Jiang Liu6b197242014-11-09 22:47:58 +08004185static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4186{
4187 struct dmar_atsr_unit *atsru;
4188 struct acpi_dmar_atsr *tmp;
4189
4190 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4191 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4192 if (atsr->segment != tmp->segment)
4193 continue;
4194 if (atsr->header.length != tmp->header.length)
4195 continue;
4196 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4197 return atsru;
4198 }
4199
4200 return NULL;
4201}
4202
4203int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004204{
4205 struct acpi_dmar_atsr *atsr;
4206 struct dmar_atsr_unit *atsru;
4207
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004208 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004209 return 0;
4210
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004211 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004212 atsru = dmar_find_atsr(atsr);
4213 if (atsru)
4214 return 0;
4215
4216 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004217 if (!atsru)
4218 return -ENOMEM;
4219
Jiang Liu6b197242014-11-09 22:47:58 +08004220 /*
4221 * If memory is allocated from slab by ACPI _DSM method, we need to
4222 * copy the memory content because the memory buffer will be freed
4223 * on return.
4224 */
4225 atsru->hdr = (void *)(atsru + 1);
4226 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004227 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004228 if (!atsru->include_all) {
4229 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4230 (void *)atsr + atsr->header.length,
4231 &atsru->devices_cnt);
4232 if (atsru->devices_cnt && atsru->devices == NULL) {
4233 kfree(atsru);
4234 return -ENOMEM;
4235 }
4236 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004237
Jiang Liu0e242612014-02-19 14:07:34 +08004238 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004239
4240 return 0;
4241}
4242
Jiang Liu9bdc5312014-01-06 14:18:27 +08004243static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4244{
4245 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4246 kfree(atsru);
4247}
4248
Jiang Liu6b197242014-11-09 22:47:58 +08004249int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4250{
4251 struct acpi_dmar_atsr *atsr;
4252 struct dmar_atsr_unit *atsru;
4253
4254 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4255 atsru = dmar_find_atsr(atsr);
4256 if (atsru) {
4257 list_del_rcu(&atsru->list);
4258 synchronize_rcu();
4259 intel_iommu_free_atsr(atsru);
4260 }
4261
4262 return 0;
4263}
4264
4265int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4266{
4267 int i;
4268 struct device *dev;
4269 struct acpi_dmar_atsr *atsr;
4270 struct dmar_atsr_unit *atsru;
4271
4272 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4273 atsru = dmar_find_atsr(atsr);
4274 if (!atsru)
4275 return 0;
4276
Linus Torvalds194dc872016-07-27 20:03:31 -07004277 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004278 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4279 i, dev)
4280 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004281 }
Jiang Liu6b197242014-11-09 22:47:58 +08004282
4283 return 0;
4284}
4285
Jiang Liuffebeb42014-11-09 22:48:02 +08004286static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4287{
4288 int sp, ret = 0;
4289 struct intel_iommu *iommu = dmaru->iommu;
4290
4291 if (g_iommus[iommu->seq_id])
4292 return 0;
4293
4294 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004295 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004296 iommu->name);
4297 return -ENXIO;
4298 }
4299 if (!ecap_sc_support(iommu->ecap) &&
4300 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004301 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004302 iommu->name);
4303 return -ENXIO;
4304 }
4305 sp = domain_update_iommu_superpage(iommu) - 1;
4306 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004307 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004308 iommu->name);
4309 return -ENXIO;
4310 }
4311
4312 /*
4313 * Disable translation if already enabled prior to OS handover.
4314 */
4315 if (iommu->gcmd & DMA_GCMD_TE)
4316 iommu_disable_translation(iommu);
4317
4318 g_iommus[iommu->seq_id] = iommu;
4319 ret = iommu_init_domains(iommu);
4320 if (ret == 0)
4321 ret = iommu_alloc_root_entry(iommu);
4322 if (ret)
4323 goto out;
4324
David Woodhouse8a94ade2015-03-24 14:54:56 +00004325#ifdef CONFIG_INTEL_IOMMU_SVM
4326 if (pasid_enabled(iommu))
4327 intel_svm_alloc_pasid_tables(iommu);
4328#endif
4329
Jiang Liuffebeb42014-11-09 22:48:02 +08004330 if (dmaru->ignored) {
4331 /*
4332 * we always have to disable PMRs or DMA may fail on this device
4333 */
4334 if (force_on)
4335 iommu_disable_protect_mem_regions(iommu);
4336 return 0;
4337 }
4338
4339 intel_iommu_init_qi(iommu);
4340 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004341
4342#ifdef CONFIG_INTEL_IOMMU_SVM
4343 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4344 ret = intel_svm_enable_prq(iommu);
4345 if (ret)
4346 goto disable_iommu;
4347 }
4348#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004349 ret = dmar_set_interrupt(iommu);
4350 if (ret)
4351 goto disable_iommu;
4352
4353 iommu_set_root_entry(iommu);
4354 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4355 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4356 iommu_enable_translation(iommu);
4357
Jiang Liuffebeb42014-11-09 22:48:02 +08004358 iommu_disable_protect_mem_regions(iommu);
4359 return 0;
4360
4361disable_iommu:
4362 disable_dmar_iommu(iommu);
4363out:
4364 free_dmar_iommu(iommu);
4365 return ret;
4366}
4367
Jiang Liu6b197242014-11-09 22:47:58 +08004368int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4369{
Jiang Liuffebeb42014-11-09 22:48:02 +08004370 int ret = 0;
4371 struct intel_iommu *iommu = dmaru->iommu;
4372
4373 if (!intel_iommu_enabled)
4374 return 0;
4375 if (iommu == NULL)
4376 return -EINVAL;
4377
4378 if (insert) {
4379 ret = intel_iommu_add(dmaru);
4380 } else {
4381 disable_dmar_iommu(iommu);
4382 free_dmar_iommu(iommu);
4383 }
4384
4385 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004386}
4387
Jiang Liu9bdc5312014-01-06 14:18:27 +08004388static void intel_iommu_free_dmars(void)
4389{
4390 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4391 struct dmar_atsr_unit *atsru, *atsr_n;
4392
4393 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4394 list_del(&rmrru->list);
4395 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004396 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004397 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004398 }
4399
Jiang Liu9bdc5312014-01-06 14:18:27 +08004400 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4401 list_del(&atsru->list);
4402 intel_iommu_free_atsr(atsru);
4403 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004404}
4405
4406int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4407{
Jiang Liub683b232014-02-19 14:07:32 +08004408 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004409 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004410 struct pci_dev *bridge = NULL;
4411 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004412 struct acpi_dmar_atsr *atsr;
4413 struct dmar_atsr_unit *atsru;
4414
4415 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004416 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004417 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004418 /* If it's an integrated device, allow ATS */
4419 if (!bridge)
4420 return 1;
4421 /* Connected via non-PCIe: no ATS */
4422 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004423 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004424 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004425 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004426 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004427 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004428 }
4429
Jiang Liu0e242612014-02-19 14:07:34 +08004430 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004431 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4432 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4433 if (atsr->segment != pci_domain_nr(dev->bus))
4434 continue;
4435
Jiang Liub683b232014-02-19 14:07:32 +08004436 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004437 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004438 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004439
4440 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004441 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004442 }
Jiang Liub683b232014-02-19 14:07:32 +08004443 ret = 0;
4444out:
Jiang Liu0e242612014-02-19 14:07:34 +08004445 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004446
Jiang Liub683b232014-02-19 14:07:32 +08004447 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004448}
4449
Jiang Liu59ce0512014-02-19 14:07:35 +08004450int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4451{
4452 int ret = 0;
4453 struct dmar_rmrr_unit *rmrru;
4454 struct dmar_atsr_unit *atsru;
4455 struct acpi_dmar_atsr *atsr;
4456 struct acpi_dmar_reserved_memory *rmrr;
4457
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004458 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004459 return 0;
4460
4461 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4462 rmrr = container_of(rmrru->hdr,
4463 struct acpi_dmar_reserved_memory, header);
4464 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4465 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4466 ((void *)rmrr) + rmrr->header.length,
4467 rmrr->segment, rmrru->devices,
4468 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004469 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004470 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004471 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004472 dmar_remove_dev_scope(info, rmrr->segment,
4473 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004474 }
4475 }
4476
4477 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4478 if (atsru->include_all)
4479 continue;
4480
4481 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4482 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4483 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4484 (void *)atsr + atsr->header.length,
4485 atsr->segment, atsru->devices,
4486 atsru->devices_cnt);
4487 if (ret > 0)
4488 break;
4489 else if(ret < 0)
4490 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004491 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004492 if (dmar_remove_dev_scope(info, atsr->segment,
4493 atsru->devices, atsru->devices_cnt))
4494 break;
4495 }
4496 }
4497
4498 return 0;
4499}
4500
Fenghua Yu99dcade2009-11-11 07:23:06 -08004501/*
4502 * Here we only respond to action of unbound device from driver.
4503 *
4504 * Added device is not attached to its DMAR domain here yet. That will happen
4505 * when mapping the device to iova.
4506 */
4507static int device_notifier(struct notifier_block *nb,
4508 unsigned long action, void *data)
4509{
4510 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004511 struct dmar_domain *domain;
4512
David Woodhouse3d891942014-03-06 15:59:26 +00004513 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004514 return 0;
4515
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004516 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004517 return 0;
4518
David Woodhouse1525a292014-03-06 16:19:30 +00004519 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004520 if (!domain)
4521 return 0;
4522
Joerg Roedele6de0f82015-07-22 16:30:36 +02004523 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004524 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004525 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004526
Fenghua Yu99dcade2009-11-11 07:23:06 -08004527 return 0;
4528}
4529
4530static struct notifier_block device_nb = {
4531 .notifier_call = device_notifier,
4532};
4533
Jiang Liu75f05562014-02-19 14:07:37 +08004534static int intel_iommu_memory_notifier(struct notifier_block *nb,
4535 unsigned long val, void *v)
4536{
4537 struct memory_notify *mhp = v;
4538 unsigned long long start, end;
4539 unsigned long start_vpfn, last_vpfn;
4540
4541 switch (val) {
4542 case MEM_GOING_ONLINE:
4543 start = mhp->start_pfn << PAGE_SHIFT;
4544 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4545 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004546 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004547 start, end);
4548 return NOTIFY_BAD;
4549 }
4550 break;
4551
4552 case MEM_OFFLINE:
4553 case MEM_CANCEL_ONLINE:
4554 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4555 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4556 while (start_vpfn <= last_vpfn) {
4557 struct iova *iova;
4558 struct dmar_drhd_unit *drhd;
4559 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004560 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004561
4562 iova = find_iova(&si_domain->iovad, start_vpfn);
4563 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004564 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004565 start_vpfn);
4566 break;
4567 }
4568
4569 iova = split_and_remove_iova(&si_domain->iovad, iova,
4570 start_vpfn, last_vpfn);
4571 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004572 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004573 start_vpfn, last_vpfn);
4574 return NOTIFY_BAD;
4575 }
4576
David Woodhouseea8ea462014-03-05 17:09:32 +00004577 freelist = domain_unmap(si_domain, iova->pfn_lo,
4578 iova->pfn_hi);
4579
Jiang Liu75f05562014-02-19 14:07:37 +08004580 rcu_read_lock();
4581 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004582 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004583 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004584 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004585 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004586 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004587
4588 start_vpfn = iova->pfn_hi + 1;
4589 free_iova_mem(iova);
4590 }
4591 break;
4592 }
4593
4594 return NOTIFY_OK;
4595}
4596
4597static struct notifier_block intel_iommu_memory_nb = {
4598 .notifier_call = intel_iommu_memory_notifier,
4599 .priority = 0
4600};
4601
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004602static void free_all_cpu_cached_iovas(unsigned int cpu)
4603{
4604 int i;
4605
4606 for (i = 0; i < g_num_of_iommus; i++) {
4607 struct intel_iommu *iommu = g_iommus[i];
4608 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004609 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004610
4611 if (!iommu)
4612 continue;
4613
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004614 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004615 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004616
4617 if (!domain)
4618 continue;
4619 free_cpu_cached_iovas(cpu, &domain->iovad);
4620 }
4621 }
4622}
4623
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004624static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004625{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004626 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004627 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004628}
4629
Joerg Roedel161b28a2017-03-28 17:04:52 +02004630static void intel_disable_iommus(void)
4631{
4632 struct intel_iommu *iommu = NULL;
4633 struct dmar_drhd_unit *drhd;
4634
4635 for_each_iommu(iommu, drhd)
4636 iommu_disable_translation(iommu);
4637}
4638
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004639static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4640{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004641 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4642
4643 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004644}
4645
Alex Williamsona5459cf2014-06-12 16:12:31 -06004646static ssize_t intel_iommu_show_version(struct device *dev,
4647 struct device_attribute *attr,
4648 char *buf)
4649{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004650 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004651 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4652 return sprintf(buf, "%d:%d\n",
4653 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4654}
4655static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4656
4657static ssize_t intel_iommu_show_address(struct device *dev,
4658 struct device_attribute *attr,
4659 char *buf)
4660{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004661 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004662 return sprintf(buf, "%llx\n", iommu->reg_phys);
4663}
4664static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4665
4666static ssize_t intel_iommu_show_cap(struct device *dev,
4667 struct device_attribute *attr,
4668 char *buf)
4669{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004670 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004671 return sprintf(buf, "%llx\n", iommu->cap);
4672}
4673static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4674
4675static ssize_t intel_iommu_show_ecap(struct device *dev,
4676 struct device_attribute *attr,
4677 char *buf)
4678{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004679 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004680 return sprintf(buf, "%llx\n", iommu->ecap);
4681}
4682static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4683
Alex Williamson2238c082015-07-14 15:24:53 -06004684static ssize_t intel_iommu_show_ndoms(struct device *dev,
4685 struct device_attribute *attr,
4686 char *buf)
4687{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004688 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004689 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4690}
4691static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4692
4693static ssize_t intel_iommu_show_ndoms_used(struct device *dev,
4694 struct device_attribute *attr,
4695 char *buf)
4696{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004697 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamson2238c082015-07-14 15:24:53 -06004698 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4699 cap_ndoms(iommu->cap)));
4700}
4701static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4702
Alex Williamsona5459cf2014-06-12 16:12:31 -06004703static struct attribute *intel_iommu_attrs[] = {
4704 &dev_attr_version.attr,
4705 &dev_attr_address.attr,
4706 &dev_attr_cap.attr,
4707 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004708 &dev_attr_domains_supported.attr,
4709 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004710 NULL,
4711};
4712
4713static struct attribute_group intel_iommu_group = {
4714 .name = "intel-iommu",
4715 .attrs = intel_iommu_attrs,
4716};
4717
4718const struct attribute_group *intel_iommu_groups[] = {
4719 &intel_iommu_group,
4720 NULL,
4721};
4722
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004723int __init intel_iommu_init(void)
4724{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004725 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004726 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004727 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004728
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004729 /* VT-d is required for a TXT/tboot launch, so enforce that */
4730 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004731
Jiang Liu3a5670e2014-02-19 14:07:33 +08004732 if (iommu_init_mempool()) {
4733 if (force_on)
4734 panic("tboot: Failed to initialize iommu memory\n");
4735 return -ENOMEM;
4736 }
4737
4738 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004739 if (dmar_table_init()) {
4740 if (force_on)
4741 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004742 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004743 }
4744
Suresh Siddhac2c72862011-08-23 17:05:19 -07004745 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004746 if (force_on)
4747 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004748 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004749 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004750
Joerg Roedelec154bf2017-10-06 15:00:53 +02004751 up_write(&dmar_global_lock);
4752
4753 /*
4754 * The bus notifier takes the dmar_global_lock, so lockdep will
4755 * complain later when we register it under the lock.
4756 */
4757 dmar_register_bus_notifier();
4758
4759 down_write(&dmar_global_lock);
4760
Joerg Roedel161b28a2017-03-28 17:04:52 +02004761 if (no_iommu || dmar_disabled) {
4762 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004763 * We exit the function here to ensure IOMMU's remapping and
4764 * mempool aren't setup, which means that the IOMMU's PMRs
4765 * won't be disabled via the call to init_dmars(). So disable
4766 * it explicitly here. The PMRs were setup by tboot prior to
4767 * calling SENTER, but the kernel is expected to reset/tear
4768 * down the PMRs.
4769 */
4770 if (intel_iommu_tboot_noforce) {
4771 for_each_iommu(iommu, drhd)
4772 iommu_disable_protect_mem_regions(iommu);
4773 }
4774
4775 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004776 * Make sure the IOMMUs are switched off, even when we
4777 * boot into a kexec kernel and the previous kernel left
4778 * them enabled
4779 */
4780 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004781 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004782 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004783
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004784 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004785 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004786
4787 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004788 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004789
Joseph Cihula51a63e62011-03-21 11:04:24 -07004790 if (dmar_init_reserved_ranges()) {
4791 if (force_on)
4792 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004793 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004794 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004795
4796 init_no_remapping_devices();
4797
Joseph Cihulab7792602011-05-03 00:08:37 -07004798 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004799 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004800 if (force_on)
4801 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004802 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004803 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004804 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004805 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004806 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004807
Christoph Hellwig4fac8072017-12-24 13:57:08 +01004808#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004809 swiotlb = 0;
4810#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004811 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004812
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004813 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004814
Joerg Roedel39ab9552017-02-01 16:56:46 +01004815 for_each_active_iommu(iommu, drhd) {
4816 iommu_device_sysfs_add(&iommu->iommu, NULL,
4817 intel_iommu_groups,
4818 "%s", iommu->name);
4819 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4820 iommu_device_register(&iommu->iommu);
4821 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004822
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004823 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004824 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004825 if (si_domain && !hw_pass_through)
4826 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004827 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4828 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004829 intel_iommu_enabled = 1;
4830
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004831 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004832
4833out_free_reserved_range:
4834 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004835out_free_dmar:
4836 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004837 up_write(&dmar_global_lock);
4838 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004839 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004840}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004841
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004842static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004843{
4844 struct intel_iommu *iommu = opaque;
4845
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004846 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004847 return 0;
4848}
4849
4850/*
4851 * NB - intel-iommu lacks any sort of reference counting for the users of
4852 * dependent devices. If multiple endpoints have intersecting dependent
4853 * devices, unbinding the driver from any one of them will possibly leave
4854 * the others unable to operate.
4855 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004856static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004857{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004858 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004859 return;
4860
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004861 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004862}
4863
Joerg Roedel127c7612015-07-23 17:44:46 +02004864static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004865{
Weidong Hanc7151a82008-12-08 22:51:37 +08004866 struct intel_iommu *iommu;
4867 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004868
Joerg Roedel55d94042015-07-22 16:50:40 +02004869 assert_spin_locked(&device_domain_lock);
4870
Joerg Roedelb608ac32015-07-21 18:19:08 +02004871 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004872 return;
4873
Joerg Roedel127c7612015-07-23 17:44:46 +02004874 iommu = info->iommu;
4875
4876 if (info->dev) {
4877 iommu_disable_dev_iotlb(info);
4878 domain_context_clear(iommu, info->dev);
4879 }
4880
Joerg Roedelb608ac32015-07-21 18:19:08 +02004881 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004882
Joerg Roedeld160aca2015-07-22 11:52:53 +02004883 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004884 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004885 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004886
4887 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004888}
4889
Joerg Roedel55d94042015-07-22 16:50:40 +02004890static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4891 struct device *dev)
4892{
Joerg Roedel127c7612015-07-23 17:44:46 +02004893 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004894 unsigned long flags;
4895
Weidong Hanc7151a82008-12-08 22:51:37 +08004896 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004897 info = dev->archdata.iommu;
4898 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004899 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004900}
4901
4902static int md_domain_init(struct dmar_domain *domain, int guest_width)
4903{
4904 int adjust_width;
4905
Zhen Leiaa3ac942017-09-21 16:52:45 +01004906 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004907 domain_reserve_special_ranges(domain);
4908
4909 /* calculate AGAW */
4910 domain->gaw = guest_width;
4911 adjust_width = guestwidth_to_adjustwidth(guest_width);
4912 domain->agaw = width_to_agaw(adjust_width);
4913
Weidong Han5e98c4b2008-12-08 23:03:27 +08004914 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08004915 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01004916 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004917 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08004918
4919 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07004920 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004921 if (!domain->pgd)
4922 return -ENOMEM;
4923 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
4924 return 0;
4925}
4926
Joerg Roedel00a77de2015-03-26 13:43:08 +01004927static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03004928{
Joerg Roedel5d450802008-12-03 14:52:32 +01004929 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01004930 struct iommu_domain *domain;
4931
4932 if (type != IOMMU_DOMAIN_UNMANAGED)
4933 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004934
Jiang Liuab8dfe22014-07-11 14:19:27 +08004935 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01004936 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004937 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01004938 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004939 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07004940 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004941 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08004942 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01004943 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004944 }
Allen Kay8140a952011-10-14 12:32:17 -07004945 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004946
Joerg Roedel00a77de2015-03-26 13:43:08 +01004947 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01004948 domain->geometry.aperture_start = 0;
4949 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
4950 domain->geometry.force_aperture = true;
4951
Joerg Roedel00a77de2015-03-26 13:43:08 +01004952 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03004953}
Kay, Allen M38717942008-09-09 18:37:29 +03004954
Joerg Roedel00a77de2015-03-26 13:43:08 +01004955static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03004956{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004957 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03004958}
Kay, Allen M38717942008-09-09 18:37:29 +03004959
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004960static int intel_iommu_attach_device(struct iommu_domain *domain,
4961 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004962{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004963 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004964 struct intel_iommu *iommu;
4965 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07004966 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03004967
Alex Williamsonc875d2c2014-07-03 09:57:02 -06004968 if (device_is_rmrr_locked(dev)) {
4969 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
4970 return -EPERM;
4971 }
4972
David Woodhouse7207d8f2014-03-09 16:31:06 -07004973 /* normally dev is not mapped */
4974 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004975 struct dmar_domain *old_domain;
4976
David Woodhouse1525a292014-03-06 16:19:30 +00004977 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004978 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02004979 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02004980 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004981 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01004982
4983 if (!domain_type_is_vm_or_si(old_domain) &&
4984 list_empty(&old_domain->devices))
4985 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004986 }
4987 }
4988
David Woodhouse156baca2014-03-09 14:00:57 -07004989 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004990 if (!iommu)
4991 return -ENODEV;
4992
4993 /* check if this iommu agaw is sufficient for max mapped address */
4994 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01004995 if (addr_width > cap_mgaw(iommu->cap))
4996 addr_width = cap_mgaw(iommu->cap);
4997
4998 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004999 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005000 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01005001 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005002 return -EFAULT;
5003 }
Tom Lyona99c47a2010-05-17 08:20:45 +01005004 dmar_domain->gaw = addr_width;
5005
5006 /*
5007 * Knock out extra levels of page tables if necessary
5008 */
5009 while (iommu->agaw < dmar_domain->agaw) {
5010 struct dma_pte *pte;
5011
5012 pte = dmar_domain->pgd;
5013 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08005014 dmar_domain->pgd = (struct dma_pte *)
5015 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01005016 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01005017 }
5018 dmar_domain->agaw--;
5019 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005020
Joerg Roedel28ccce02015-07-21 14:45:31 +02005021 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005022}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005023
Joerg Roedel4c5478c2008-12-03 14:58:24 +01005024static void intel_iommu_detach_device(struct iommu_domain *domain,
5025 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03005026{
Joerg Roedele6de0f82015-07-22 16:30:36 +02005027 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005028}
Kay, Allen M38717942008-09-09 18:37:29 +03005029
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005030static int intel_iommu_map(struct iommu_domain *domain,
5031 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005032 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005033{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005034 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005035 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005036 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005037 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005038
Joerg Roedeldde57a22008-12-03 15:04:09 +01005039 if (iommu_prot & IOMMU_READ)
5040 prot |= DMA_PTE_READ;
5041 if (iommu_prot & IOMMU_WRITE)
5042 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005043 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5044 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005045
David Woodhouse163cc522009-06-28 00:51:17 +01005046 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005047 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005048 u64 end;
5049
5050 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005051 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005052 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005053 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005054 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005055 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005056 return -EFAULT;
5057 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005058 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005059 }
David Woodhousead051222009-06-28 14:22:28 +01005060 /* Round up size to next multiple of PAGE_SIZE, if it and
5061 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005062 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005063 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5064 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005065 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005066}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005067
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005068static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005069 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005070{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005071 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005072 struct page *freelist = NULL;
David Woodhouseea8ea462014-03-05 17:09:32 +00005073 unsigned long start_pfn, last_pfn;
5074 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005075 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005076
David Woodhouse5cf0a762014-03-19 16:07:49 +00005077 /* Cope with horrid API which requires us to unmap more than the
5078 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005079 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005080
5081 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5082 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5083
David Woodhouseea8ea462014-03-05 17:09:32 +00005084 start_pfn = iova >> VTD_PAGE_SHIFT;
5085 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5086
5087 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5088
5089 npages = last_pfn - start_pfn + 1;
5090
Shaokun Zhangf746a022018-03-22 18:18:06 +08005091 for_each_domain_iommu(iommu_id, dmar_domain)
Joerg Roedel42e8c182015-07-21 15:50:02 +02005092 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5093 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005094
5095 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005096
David Woodhouse163cc522009-06-28 00:51:17 +01005097 if (dmar_domain->max_addr == iova + size)
5098 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005099
David Woodhouse5cf0a762014-03-19 16:07:49 +00005100 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005101}
Kay, Allen M38717942008-09-09 18:37:29 +03005102
Joerg Roedeld14d6572008-12-03 15:06:57 +01005103static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305104 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005105{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005106 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005107 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005108 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005109 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005110
David Woodhouse5cf0a762014-03-19 16:07:49 +00005111 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005112 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005113 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005114
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005115 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005116}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005117
Joerg Roedel5d587b82014-09-05 10:50:45 +02005118static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005119{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005120 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005121 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005122 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005123 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005124
Joerg Roedel5d587b82014-09-05 10:50:45 +02005125 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005126}
5127
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005128static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005129{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005130 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005131 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005132 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005133
Alex Williamsona5459cf2014-06-12 16:12:31 -06005134 iommu = device_to_iommu(dev, &bus, &devfn);
5135 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005136 return -ENODEV;
5137
Joerg Roedele3d10af2017-02-01 17:23:22 +01005138 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005139
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005140 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005141
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005142 if (IS_ERR(group))
5143 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005144
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005145 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005146 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005147}
5148
5149static void intel_iommu_remove_device(struct device *dev)
5150{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005151 struct intel_iommu *iommu;
5152 u8 bus, devfn;
5153
5154 iommu = device_to_iommu(dev, &bus, &devfn);
5155 if (!iommu)
5156 return;
5157
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005158 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005159
Joerg Roedele3d10af2017-02-01 17:23:22 +01005160 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005161}
5162
Eric Auger0659b8d2017-01-19 20:57:53 +00005163static void intel_iommu_get_resv_regions(struct device *device,
5164 struct list_head *head)
5165{
5166 struct iommu_resv_region *reg;
5167 struct dmar_rmrr_unit *rmrr;
5168 struct device *i_dev;
5169 int i;
5170
5171 rcu_read_lock();
5172 for_each_rmrr_units(rmrr) {
5173 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5174 i, i_dev) {
5175 if (i_dev != device)
5176 continue;
5177
5178 list_add_tail(&rmrr->resv->list, head);
5179 }
5180 }
5181 rcu_read_unlock();
5182
5183 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5184 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005185 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005186 if (!reg)
5187 return;
5188 list_add_tail(&reg->list, head);
5189}
5190
5191static void intel_iommu_put_resv_regions(struct device *dev,
5192 struct list_head *head)
5193{
5194 struct iommu_resv_region *entry, *next;
5195
5196 list_for_each_entry_safe(entry, next, head, list) {
5197 if (entry->type == IOMMU_RESV_RESERVED)
5198 kfree(entry);
5199 }
Kay, Allen M38717942008-09-09 18:37:29 +03005200}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005201
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005202#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005203#define MAX_NR_PASID_BITS (20)
5204static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5205{
5206 /*
5207 * Convert ecap_pss to extend context entry pts encoding, also
5208 * respect the soft pasid_max value set by the iommu.
5209 * - number of PASID bits = ecap_pss + 1
5210 * - number of PASID table entries = 2^(pts + 5)
5211 * Therefore, pts = ecap_pss - 4
5212 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5213 */
5214 if (ecap_pss(iommu->ecap) < 5)
5215 return 0;
5216
5217 /* pasid_max is encoded as actual number of entries not the bits */
5218 return find_first_bit((unsigned long *)&iommu->pasid_max,
5219 MAX_NR_PASID_BITS) - 5;
5220}
5221
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005222int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5223{
5224 struct device_domain_info *info;
5225 struct context_entry *context;
5226 struct dmar_domain *domain;
5227 unsigned long flags;
5228 u64 ctx_lo;
5229 int ret;
5230
5231 domain = get_valid_domain_for_dev(sdev->dev);
5232 if (!domain)
5233 return -EINVAL;
5234
5235 spin_lock_irqsave(&device_domain_lock, flags);
5236 spin_lock(&iommu->lock);
5237
5238 ret = -EINVAL;
5239 info = sdev->dev->archdata.iommu;
5240 if (!info || !info->pasid_supported)
5241 goto out;
5242
5243 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5244 if (WARN_ON(!context))
5245 goto out;
5246
5247 ctx_lo = context[0].lo;
5248
5249 sdev->did = domain->iommu_did[iommu->seq_id];
5250 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5251
5252 if (!(ctx_lo & CONTEXT_PASIDE)) {
Ashok Raj11b93eb2017-08-08 13:29:28 -07005253 if (iommu->pasid_state_table)
5254 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005255 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5256 intel_iommu_get_pts(iommu);
5257
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005258 wmb();
5259 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5260 * extended to permit requests-with-PASID if the PASIDE bit
5261 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5262 * however, the PASIDE bit is ignored and requests-with-PASID
5263 * are unconditionally blocked. Which makes less sense.
5264 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5265 * "guest mode" translation types depending on whether ATS
5266 * is available or not. Annoyingly, we can't use the new
5267 * modes *unless* PASIDE is set. */
5268 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5269 ctx_lo &= ~CONTEXT_TT_MASK;
5270 if (info->ats_supported)
5271 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5272 else
5273 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5274 }
5275 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005276 if (iommu->pasid_state_table)
5277 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005278 if (info->pri_supported)
5279 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005280 context[0].lo = ctx_lo;
5281 wmb();
5282 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5283 DMA_CCMD_MASK_NOBIT,
5284 DMA_CCMD_DEVICE_INVL);
5285 }
5286
5287 /* Enable PASID support in the device, if it wasn't already */
5288 if (!info->pasid_enabled)
5289 iommu_enable_dev_iotlb(info);
5290
5291 if (info->ats_enabled) {
5292 sdev->dev_iotlb = 1;
5293 sdev->qdep = info->ats_qdep;
5294 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5295 sdev->qdep = 0;
5296 }
5297 ret = 0;
5298
5299 out:
5300 spin_unlock(&iommu->lock);
5301 spin_unlock_irqrestore(&device_domain_lock, flags);
5302
5303 return ret;
5304}
5305
5306struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5307{
5308 struct intel_iommu *iommu;
5309 u8 bus, devfn;
5310
5311 if (iommu_dummy(dev)) {
5312 dev_warn(dev,
5313 "No IOMMU translation for device; cannot enable SVM\n");
5314 return NULL;
5315 }
5316
5317 iommu = device_to_iommu(dev, &bus, &devfn);
5318 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005319 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005320 return NULL;
5321 }
5322
5323 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005324 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005325 return NULL;
5326 }
5327
5328 return iommu;
5329}
5330#endif /* CONFIG_INTEL_IOMMU_SVM */
5331
Joerg Roedelb0119e82017-02-01 13:23:08 +01005332const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005333 .capable = intel_iommu_capable,
5334 .domain_alloc = intel_iommu_domain_alloc,
5335 .domain_free = intel_iommu_domain_free,
5336 .attach_dev = intel_iommu_attach_device,
5337 .detach_dev = intel_iommu_detach_device,
5338 .map = intel_iommu_map,
5339 .unmap = intel_iommu_unmap,
5340 .map_sg = default_iommu_map_sg,
5341 .iova_to_phys = intel_iommu_iova_to_phys,
5342 .add_device = intel_iommu_add_device,
5343 .remove_device = intel_iommu_remove_device,
5344 .get_resv_regions = intel_iommu_get_resv_regions,
5345 .put_resv_regions = intel_iommu_put_resv_regions,
5346 .device_group = pci_device_group,
5347 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005348};
David Woodhouse9af88142009-02-13 23:18:03 +00005349
Daniel Vetter94526182013-01-20 23:50:13 +01005350static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5351{
5352 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005353 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005354 dmar_map_gfx = 0;
5355}
5356
5357DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5358DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5359DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5360DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5361DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5362DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5363DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5364
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005365static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005366{
5367 /*
5368 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005369 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005370 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005371 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005372 rwbf_quirk = 1;
5373}
5374
5375DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005376DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5377DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5378DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5379DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5380DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5381DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005382
Adam Jacksoneecfd572010-08-25 21:17:34 +01005383#define GGC 0x52
5384#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5385#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5386#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5387#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5388#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5389#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5390#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5391#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5392
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005393static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005394{
5395 unsigned short ggc;
5396
Adam Jacksoneecfd572010-08-25 21:17:34 +01005397 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005398 return;
5399
Adam Jacksoneecfd572010-08-25 21:17:34 +01005400 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005401 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005402 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005403 } else if (dmar_map_gfx) {
5404 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005405 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005406 intel_iommu_strict = 1;
5407 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005408}
5409DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5410DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5411DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5412DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5413
David Woodhousee0fc7e02009-09-30 09:12:17 -07005414/* On Tylersburg chipsets, some BIOSes have been known to enable the
5415 ISOCH DMAR unit for the Azalia sound device, but not give it any
5416 TLB entries, which causes it to deadlock. Check for that. We do
5417 this in a function called from init_dmars(), instead of in a PCI
5418 quirk, because we don't want to print the obnoxious "BIOS broken"
5419 message if VT-d is actually disabled.
5420*/
5421static void __init check_tylersburg_isoch(void)
5422{
5423 struct pci_dev *pdev;
5424 uint32_t vtisochctrl;
5425
5426 /* If there's no Azalia in the system anyway, forget it. */
5427 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5428 if (!pdev)
5429 return;
5430 pci_dev_put(pdev);
5431
5432 /* System Management Registers. Might be hidden, in which case
5433 we can't do the sanity check. But that's OK, because the
5434 known-broken BIOSes _don't_ actually hide it, so far. */
5435 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5436 if (!pdev)
5437 return;
5438
5439 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5440 pci_dev_put(pdev);
5441 return;
5442 }
5443
5444 pci_dev_put(pdev);
5445
5446 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5447 if (vtisochctrl & 1)
5448 return;
5449
5450 /* Drop all bits other than the number of TLB entries */
5451 vtisochctrl &= 0x1c;
5452
5453 /* If we have the recommended number of TLB entries (16), fine. */
5454 if (vtisochctrl == 0x10)
5455 return;
5456
5457 /* Zero TLB entries? You get to ride the short bus to school. */
5458 if (!vtisochctrl) {
5459 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5460 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5461 dmi_get_system_info(DMI_BIOS_VENDOR),
5462 dmi_get_system_info(DMI_BIOS_VERSION),
5463 dmi_get_system_info(DMI_PRODUCT_VERSION));
5464 iommu_identity_mapping |= IDENTMAP_AZALIA;
5465 return;
5466 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005467
5468 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005469 vtisochctrl);
5470}