blob: 24d1b1b420133358614c105b0e8c6e096600887b [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
Joerg Roedel13cf0172017-08-11 11:40:10 +02001609static void iommu_flush_iova(struct iova_domain *iovad)
1610{
1611 struct dmar_domain *domain;
1612 int idx;
1613
1614 domain = container_of(iovad, struct dmar_domain, iovad);
1615
1616 for_each_domain_iommu(idx, domain) {
1617 struct intel_iommu *iommu = g_iommus[idx];
1618 u16 did = domain->iommu_did[iommu->seq_id];
1619
1620 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
1621
1622 if (!cap_caching_mode(iommu->cap))
1623 iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
1624 0, MAX_AGAW_PFN_WIDTH);
1625 }
1626}
1627
mark grossf8bab732008-02-08 04:18:38 -08001628static void iommu_disable_protect_mem_regions(struct intel_iommu *iommu)
1629{
1630 u32 pmen;
1631 unsigned long flags;
1632
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001633 raw_spin_lock_irqsave(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001634 pmen = readl(iommu->reg + DMAR_PMEN_REG);
1635 pmen &= ~DMA_PMEN_EPM;
1636 writel(pmen, iommu->reg + DMAR_PMEN_REG);
1637
1638 /* wait for the protected region status bit to clear */
1639 IOMMU_WAIT_OP(iommu, DMAR_PMEN_REG,
1640 readl, !(pmen & DMA_PMEN_PRS), pmen);
1641
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001642 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
mark grossf8bab732008-02-08 04:18:38 -08001643}
1644
Jiang Liu2a41cce2014-07-11 14:19:33 +08001645static void iommu_enable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001646{
1647 u32 sts;
1648 unsigned long flags;
1649
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001650 raw_spin_lock_irqsave(&iommu->register_lock, flags);
David Woodhousec416daa2009-05-10 20:30:58 +01001651 iommu->gcmd |= DMA_GCMD_TE;
1652 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001653
1654 /* Make sure hardware complete it */
1655 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001656 readl, (sts & DMA_GSTS_TES), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001657
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001658 raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001659}
1660
Jiang Liu2a41cce2014-07-11 14:19:33 +08001661static void iommu_disable_translation(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001662{
1663 u32 sts;
1664 unsigned long flag;
1665
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001666 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001667 iommu->gcmd &= ~DMA_GCMD_TE;
1668 writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
1669
1670 /* Make sure hardware complete it */
1671 IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
David Woodhousec416daa2009-05-10 20:30:58 +01001672 readl, (!(sts & DMA_GSTS_TES)), sts);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001673
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02001674 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001675}
1676
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07001677
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001678static int iommu_init_domains(struct intel_iommu *iommu)
1679{
Joerg Roedel8bf47812015-07-21 10:41:21 +02001680 u32 ndomains, nlongs;
1681 size_t size;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001682
1683 ndomains = cap_ndoms(iommu->cap);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001684 pr_debug("%s: Number of Domains supported <%d>\n",
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001685 iommu->name, ndomains);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001686 nlongs = BITS_TO_LONGS(ndomains);
1687
Donald Dutile94a91b52009-08-20 16:51:34 -04001688 spin_lock_init(&iommu->lock);
1689
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001690 iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
1691 if (!iommu->domain_ids) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001692 pr_err("%s: Allocating domain id array failed\n",
1693 iommu->name);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001694 return -ENOMEM;
1695 }
Joerg Roedel8bf47812015-07-21 10:41:21 +02001696
Wei Yang86f004c2016-05-21 02:41:51 +00001697 size = (ALIGN(ndomains, 256) >> 8) * sizeof(struct dmar_domain **);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001698 iommu->domains = kzalloc(size, GFP_KERNEL);
1699
1700 if (iommu->domains) {
1701 size = 256 * sizeof(struct dmar_domain *);
1702 iommu->domains[0] = kzalloc(size, GFP_KERNEL);
1703 }
1704
1705 if (!iommu->domains || !iommu->domains[0]) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001706 pr_err("%s: Allocating domain array failed\n",
1707 iommu->name);
Jiang Liu852bdb02014-01-06 14:18:11 +08001708 kfree(iommu->domain_ids);
Joerg Roedel8bf47812015-07-21 10:41:21 +02001709 kfree(iommu->domains);
Jiang Liu852bdb02014-01-06 14:18:11 +08001710 iommu->domain_ids = NULL;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001711 iommu->domains = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001712 return -ENOMEM;
1713 }
1714
Joerg Roedel8bf47812015-07-21 10:41:21 +02001715
1716
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001717 /*
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001718 * If Caching mode is set, then invalid translations are tagged
1719 * with domain-id 0, hence we need to pre-allocate it. We also
1720 * use domain-id 0 as a marker for non-allocated domain-id, so
1721 * make sure it is not used for a real domain.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001722 */
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001723 set_bit(0, iommu->domain_ids);
1724
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001725 return 0;
1726}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001727
Jiang Liuffebeb42014-11-09 22:48:02 +08001728static void disable_dmar_iommu(struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001729{
Joerg Roedel29a27712015-07-21 17:17:12 +02001730 struct device_domain_info *info, *tmp;
Joerg Roedel55d94042015-07-22 16:50:40 +02001731 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001732
Joerg Roedel29a27712015-07-21 17:17:12 +02001733 if (!iommu->domains || !iommu->domain_ids)
1734 return;
Jiang Liua4eaa862014-02-19 14:07:30 +08001735
Joerg Roedelbea64032016-11-08 15:08:26 +01001736again:
Joerg Roedel55d94042015-07-22 16:50:40 +02001737 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001738 list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
1739 struct dmar_domain *domain;
1740
1741 if (info->iommu != iommu)
1742 continue;
1743
1744 if (!info->dev || !info->domain)
1745 continue;
1746
1747 domain = info->domain;
1748
Joerg Roedelbea64032016-11-08 15:08:26 +01001749 __dmar_remove_one_dev_info(info);
Joerg Roedel29a27712015-07-21 17:17:12 +02001750
Joerg Roedelbea64032016-11-08 15:08:26 +01001751 if (!domain_type_is_vm_or_si(domain)) {
1752 /*
1753 * The domain_exit() function can't be called under
1754 * device_domain_lock, as it takes this lock itself.
1755 * So release the lock here and re-run the loop
1756 * afterwards.
1757 */
1758 spin_unlock_irqrestore(&device_domain_lock, flags);
Joerg Roedel29a27712015-07-21 17:17:12 +02001759 domain_exit(domain);
Joerg Roedelbea64032016-11-08 15:08:26 +01001760 goto again;
1761 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001762 }
Joerg Roedel55d94042015-07-22 16:50:40 +02001763 spin_unlock_irqrestore(&device_domain_lock, flags);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001764
1765 if (iommu->gcmd & DMA_GCMD_TE)
1766 iommu_disable_translation(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08001767}
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001768
Jiang Liuffebeb42014-11-09 22:48:02 +08001769static void free_dmar_iommu(struct intel_iommu *iommu)
1770{
1771 if ((iommu->domains) && (iommu->domain_ids)) {
Wei Yang86f004c2016-05-21 02:41:51 +00001772 int elems = ALIGN(cap_ndoms(iommu->cap), 256) >> 8;
Joerg Roedel8bf47812015-07-21 10:41:21 +02001773 int i;
1774
1775 for (i = 0; i < elems; i++)
1776 kfree(iommu->domains[i]);
Jiang Liuffebeb42014-11-09 22:48:02 +08001777 kfree(iommu->domains);
1778 kfree(iommu->domain_ids);
1779 iommu->domains = NULL;
1780 iommu->domain_ids = NULL;
1781 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001782
Weidong Hand9630fe2008-12-08 11:06:32 +08001783 g_iommus[iommu->seq_id] = NULL;
1784
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001785 /* free context mapping */
1786 free_context_table(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001787
1788#ifdef CONFIG_INTEL_IOMMU_SVM
David Woodhousea222a7f2015-10-07 23:35:18 +01001789 if (pasid_enabled(iommu)) {
1790 if (ecap_prs(iommu->ecap))
1791 intel_svm_finish_prq(iommu);
David Woodhouse8a94ade2015-03-24 14:54:56 +00001792 intel_svm_free_pasid_tables(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01001793 }
David Woodhouse8a94ade2015-03-24 14:54:56 +00001794#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001795}
1796
Jiang Liuab8dfe22014-07-11 14:19:27 +08001797static struct dmar_domain *alloc_domain(int flags)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001798{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001799 struct dmar_domain *domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001800
1801 domain = alloc_domain_mem();
1802 if (!domain)
1803 return NULL;
1804
Jiang Liuab8dfe22014-07-11 14:19:27 +08001805 memset(domain, 0, sizeof(*domain));
Suresh Siddha4c923d42009-10-02 11:01:24 -07001806 domain->nid = -1;
Jiang Liuab8dfe22014-07-11 14:19:27 +08001807 domain->flags = flags;
Omer Peleg0824c592016-04-20 19:03:35 +03001808 domain->has_iotlb_device = false;
Jiang Liu92d03cc2014-02-19 14:07:28 +08001809 INIT_LIST_HEAD(&domain->devices);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001810
1811 return domain;
1812}
1813
Joerg Roedeld160aca2015-07-22 11:52:53 +02001814/* Must be called with iommu->lock */
1815static int domain_attach_iommu(struct dmar_domain *domain,
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001816 struct intel_iommu *iommu)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001817{
Jiang Liu44bde612014-07-11 14:19:29 +08001818 unsigned long ndomains;
Joerg Roedel55d94042015-07-22 16:50:40 +02001819 int num;
Jiang Liu44bde612014-07-11 14:19:29 +08001820
Joerg Roedel55d94042015-07-22 16:50:40 +02001821 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001822 assert_spin_locked(&iommu->lock);
Jiang Liu44bde612014-07-11 14:19:29 +08001823
Joerg Roedel29a27712015-07-21 17:17:12 +02001824 domain->iommu_refcnt[iommu->seq_id] += 1;
1825 domain->iommu_count += 1;
1826 if (domain->iommu_refcnt[iommu->seq_id] == 1) {
Jiang Liufb170fb2014-07-11 14:19:28 +08001827 ndomains = cap_ndoms(iommu->cap);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001828 num = find_first_zero_bit(iommu->domain_ids, ndomains);
1829
1830 if (num >= ndomains) {
1831 pr_err("%s: No free domain ids\n", iommu->name);
1832 domain->iommu_refcnt[iommu->seq_id] -= 1;
1833 domain->iommu_count -= 1;
Joerg Roedel55d94042015-07-22 16:50:40 +02001834 return -ENOSPC;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07001835 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001836
Joerg Roedeld160aca2015-07-22 11:52:53 +02001837 set_bit(num, iommu->domain_ids);
1838 set_iommu_domain(iommu, num, domain);
Jiang Liufb170fb2014-07-11 14:19:28 +08001839
Joerg Roedeld160aca2015-07-22 11:52:53 +02001840 domain->iommu_did[iommu->seq_id] = num;
1841 domain->nid = iommu->node;
1842
Jiang Liufb170fb2014-07-11 14:19:28 +08001843 domain_update_iommu_cap(domain);
1844 }
Joerg Roedeld160aca2015-07-22 11:52:53 +02001845
Joerg Roedel55d94042015-07-22 16:50:40 +02001846 return 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001847}
1848
1849static int domain_detach_iommu(struct dmar_domain *domain,
1850 struct intel_iommu *iommu)
1851{
Joerg Roedeld160aca2015-07-22 11:52:53 +02001852 int num, count = INT_MAX;
Jiang Liufb170fb2014-07-11 14:19:28 +08001853
Joerg Roedel55d94042015-07-22 16:50:40 +02001854 assert_spin_locked(&device_domain_lock);
Joerg Roedeld160aca2015-07-22 11:52:53 +02001855 assert_spin_locked(&iommu->lock);
Jiang Liufb170fb2014-07-11 14:19:28 +08001856
Joerg Roedel29a27712015-07-21 17:17:12 +02001857 domain->iommu_refcnt[iommu->seq_id] -= 1;
1858 count = --domain->iommu_count;
1859 if (domain->iommu_refcnt[iommu->seq_id] == 0) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02001860 num = domain->iommu_did[iommu->seq_id];
1861 clear_bit(num, iommu->domain_ids);
1862 set_iommu_domain(iommu, num, NULL);
1863
Jiang Liufb170fb2014-07-11 14:19:28 +08001864 domain_update_iommu_cap(domain);
Joerg Roedelc0e8a6c2015-07-21 09:39:46 +02001865 domain->iommu_did[iommu->seq_id] = 0;
Jiang Liufb170fb2014-07-11 14:19:28 +08001866 }
Jiang Liufb170fb2014-07-11 14:19:28 +08001867
1868 return count;
1869}
1870
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001871static struct iova_domain reserved_iova_list;
Mark Gross8a443df2008-03-04 14:59:31 -08001872static struct lock_class_key reserved_rbtree_key;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001873
Joseph Cihula51a63e62011-03-21 11:04:24 -07001874static int dmar_init_reserved_ranges(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001875{
1876 struct pci_dev *pdev = NULL;
1877 struct iova *iova;
1878 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001879
Zhen Leiaa3ac942017-09-21 16:52:45 +01001880 init_iova_domain(&reserved_iova_list, VTD_PAGE_SIZE, IOVA_START_PFN);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001881
Mark Gross8a443df2008-03-04 14:59:31 -08001882 lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
1883 &reserved_rbtree_key);
1884
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001885 /* IOAPIC ranges shouldn't be accessed by DMA */
1886 iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
1887 IOVA_PFN(IOAPIC_RANGE_END));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001888 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001889 pr_err("Reserve IOAPIC range failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001890 return -ENODEV;
1891 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001892
1893 /* Reserve all PCI MMIO to avoid peer-to-peer access */
1894 for_each_pci_dev(pdev) {
1895 struct resource *r;
1896
1897 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1898 r = &pdev->resource[i];
1899 if (!r->flags || !(r->flags & IORESOURCE_MEM))
1900 continue;
David Woodhouse1a4a4552009-06-28 16:00:42 +01001901 iova = reserve_iova(&reserved_iova_list,
1902 IOVA_PFN(r->start),
1903 IOVA_PFN(r->end));
Joseph Cihula51a63e62011-03-21 11:04:24 -07001904 if (!iova) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001905 pr_err("Reserve iova failed\n");
Joseph Cihula51a63e62011-03-21 11:04:24 -07001906 return -ENODEV;
1907 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001908 }
1909 }
Joseph Cihula51a63e62011-03-21 11:04:24 -07001910 return 0;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001911}
1912
1913static void domain_reserve_special_ranges(struct dmar_domain *domain)
1914{
1915 copy_reserved_iova(&reserved_iova_list, &domain->iovad);
1916}
1917
1918static inline int guestwidth_to_adjustwidth(int gaw)
1919{
1920 int agaw;
1921 int r = (gaw - 12) % 9;
1922
1923 if (r == 0)
1924 agaw = gaw;
1925 else
1926 agaw = gaw + 9 - r;
1927 if (agaw > 64)
1928 agaw = 64;
1929 return agaw;
1930}
1931
Joerg Roedeldc534b22015-07-22 12:44:02 +02001932static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
1933 int guest_width)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001934{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001935 int adjust_width, agaw;
1936 unsigned long sagaw;
Joerg Roedel13cf0172017-08-11 11:40:10 +02001937 int err;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001938
Zhen Leiaa3ac942017-09-21 16:52:45 +01001939 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Joerg Roedel13cf0172017-08-11 11:40:10 +02001940
1941 err = init_iova_flush_queue(&domain->iovad,
1942 iommu_flush_iova, iova_entry_free);
1943 if (err)
1944 return err;
1945
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001946 domain_reserve_special_ranges(domain);
1947
1948 /* calculate AGAW */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001949 if (guest_width > cap_mgaw(iommu->cap))
1950 guest_width = cap_mgaw(iommu->cap);
1951 domain->gaw = guest_width;
1952 adjust_width = guestwidth_to_adjustwidth(guest_width);
1953 agaw = width_to_agaw(adjust_width);
1954 sagaw = cap_sagaw(iommu->cap);
1955 if (!test_bit(agaw, &sagaw)) {
1956 /* hardware doesn't support it, choose a bigger one */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02001957 pr_debug("Hardware doesn't support agaw %d\n", agaw);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001958 agaw = find_next_bit(&sagaw, 5, agaw);
1959 if (agaw >= 5)
1960 return -ENODEV;
1961 }
1962 domain->agaw = agaw;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001963
Weidong Han8e6040972008-12-08 15:49:06 +08001964 if (ecap_coherent(iommu->ecap))
1965 domain->iommu_coherency = 1;
1966 else
1967 domain->iommu_coherency = 0;
1968
Sheng Yang58c610b2009-03-18 15:33:05 +08001969 if (ecap_sc_support(iommu->ecap))
1970 domain->iommu_snooping = 1;
1971 else
1972 domain->iommu_snooping = 0;
1973
David Woodhouse214e39a2014-03-19 10:38:49 +00001974 if (intel_iommu_superpage)
1975 domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
1976 else
1977 domain->iommu_superpage = 0;
1978
Suresh Siddha4c923d42009-10-02 11:01:24 -07001979 domain->nid = iommu->node;
Weidong Hanc7151a82008-12-08 22:51:37 +08001980
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001981 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07001982 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001983 if (!domain->pgd)
1984 return -ENOMEM;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07001985 __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001986 return 0;
1987}
1988
1989static void domain_exit(struct dmar_domain *domain)
1990{
David Woodhouseea8ea462014-03-05 17:09:32 +00001991 struct page *freelist = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001992
1993 /* Domain 0 is reserved, so dont process it */
1994 if (!domain)
1995 return;
1996
Joerg Roedeld160aca2015-07-22 11:52:53 +02001997 /* Remove associated devices and clear attached or cached domains */
1998 rcu_read_lock();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07001999 domain_remove_dev_info(domain);
Joerg Roedeld160aca2015-07-22 11:52:53 +02002000 rcu_read_unlock();
Jiang Liu92d03cc2014-02-19 14:07:28 +08002001
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002002 /* destroy iovas */
2003 put_iova_domain(&domain->iovad);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002004
David Woodhouseea8ea462014-03-05 17:09:32 +00002005 freelist = domain_unmap(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002006
David Woodhouseea8ea462014-03-05 17:09:32 +00002007 dma_free_pagelist(freelist);
2008
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002009 free_domain_mem(domain);
2010}
2011
David Woodhouse64ae8922014-03-09 12:52:30 -07002012static int domain_context_mapping_one(struct dmar_domain *domain,
2013 struct intel_iommu *iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002014 u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002015{
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002016 u16 did = domain->iommu_did[iommu->seq_id];
Joerg Roedel28ccce02015-07-21 14:45:31 +02002017 int translation = CONTEXT_TT_MULTI_LEVEL;
2018 struct device_domain_info *info = NULL;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002019 struct context_entry *context;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002020 unsigned long flags;
Weidong Hanea6606b2008-12-08 23:08:15 +08002021 struct dma_pte *pgd;
Joerg Roedel55d94042015-07-22 16:50:40 +02002022 int ret, agaw;
Joerg Roedel28ccce02015-07-21 14:45:31 +02002023
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002024 WARN_ON(did == 0);
2025
Joerg Roedel28ccce02015-07-21 14:45:31 +02002026 if (hw_pass_through && domain_type_is_si(domain))
2027 translation = CONTEXT_TT_PASS_THROUGH;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002028
2029 pr_debug("Set context mapping for %02x:%02x.%d\n",
2030 bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002031
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002032 BUG_ON(!domain->pgd);
Weidong Han5331fe62008-12-08 23:00:00 +08002033
Joerg Roedel55d94042015-07-22 16:50:40 +02002034 spin_lock_irqsave(&device_domain_lock, flags);
2035 spin_lock(&iommu->lock);
2036
2037 ret = -ENOMEM;
David Woodhouse03ecc322015-02-13 14:35:21 +00002038 context = iommu_context_addr(iommu, bus, devfn, 1);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002039 if (!context)
Joerg Roedel55d94042015-07-22 16:50:40 +02002040 goto out_unlock;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002041
Joerg Roedel55d94042015-07-22 16:50:40 +02002042 ret = 0;
2043 if (context_present(context))
2044 goto out_unlock;
Joerg Roedelcf484d02015-06-12 12:21:46 +02002045
Xunlei Pangaec0e862016-12-05 20:09:07 +08002046 /*
2047 * For kdump cases, old valid entries may be cached due to the
2048 * in-flight DMA and copied pgtable, but there is no unmapping
2049 * behaviour for them, thus we need an explicit cache flush for
2050 * the newly-mapped device. For kdump, at this point, the device
2051 * is supposed to finish reset at its driver probe stage, so no
2052 * in-flight DMA will exist, and we don't need to worry anymore
2053 * hereafter.
2054 */
2055 if (context_copied(context)) {
2056 u16 did_old = context_domain_id(context);
2057
Christos Gkekasb117e032017-10-08 23:33:31 +01002058 if (did_old < cap_ndoms(iommu->cap)) {
Xunlei Pangaec0e862016-12-05 20:09:07 +08002059 iommu->flush.flush_context(iommu, did_old,
2060 (((u16)bus) << 8) | devfn,
2061 DMA_CCMD_MASK_NOBIT,
2062 DMA_CCMD_DEVICE_INVL);
KarimAllah Ahmedf73a7ee2017-05-05 11:39:59 -07002063 iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
2064 DMA_TLB_DSI_FLUSH);
2065 }
Xunlei Pangaec0e862016-12-05 20:09:07 +08002066 }
2067
Weidong Hanea6606b2008-12-08 23:08:15 +08002068 pgd = domain->pgd;
2069
Joerg Roedelde24e552015-07-21 14:53:04 +02002070 context_clear_entry(context);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002071 context_set_domain_id(context, did);
Weidong Hanea6606b2008-12-08 23:08:15 +08002072
Joerg Roedelde24e552015-07-21 14:53:04 +02002073 /*
2074 * Skip top levels of page tables for iommu which has less agaw
2075 * than default. Unnecessary for PT mode.
2076 */
Yu Zhao93a23a72009-05-18 13:51:37 +08002077 if (translation != CONTEXT_TT_PASS_THROUGH) {
Joerg Roedelde24e552015-07-21 14:53:04 +02002078 for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) {
Joerg Roedel55d94042015-07-22 16:50:40 +02002079 ret = -ENOMEM;
Joerg Roedelde24e552015-07-21 14:53:04 +02002080 pgd = phys_to_virt(dma_pte_addr(pgd));
Joerg Roedel55d94042015-07-22 16:50:40 +02002081 if (!dma_pte_present(pgd))
2082 goto out_unlock;
Joerg Roedelde24e552015-07-21 14:53:04 +02002083 }
2084
David Woodhouse64ae8922014-03-09 12:52:30 -07002085 info = iommu_support_dev_iotlb(domain, iommu, bus, devfn);
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002086 if (info && info->ats_supported)
2087 translation = CONTEXT_TT_DEV_IOTLB;
2088 else
2089 translation = CONTEXT_TT_MULTI_LEVEL;
Joerg Roedelde24e552015-07-21 14:53:04 +02002090
Yu Zhao93a23a72009-05-18 13:51:37 +08002091 context_set_address_root(context, virt_to_phys(pgd));
2092 context_set_address_width(context, iommu->agaw);
Joerg Roedelde24e552015-07-21 14:53:04 +02002093 } else {
2094 /*
2095 * In pass through mode, AW must be programmed to
2096 * indicate the largest AGAW value supported by
2097 * hardware. And ASR is ignored by hardware.
2098 */
2099 context_set_address_width(context, iommu->msagaw);
Yu Zhao93a23a72009-05-18 13:51:37 +08002100 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07002101
2102 context_set_translation_type(context, translation);
Mark McLoughlinc07e7d22008-11-21 16:54:46 +00002103 context_set_fault_enable(context);
2104 context_set_present(context);
Weidong Han5331fe62008-12-08 23:00:00 +08002105 domain_flush_cache(domain, context, sizeof(*context));
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002106
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002107 /*
2108 * It's a non-present to present mapping. If hardware doesn't cache
2109 * non-present entry we only need to flush the write-buffer. If the
2110 * _does_ cache non-present entries, then it does so in the special
2111 * domain #0, which we have to flush:
2112 */
2113 if (cap_caching_mode(iommu->cap)) {
2114 iommu->flush.flush_context(iommu, 0,
2115 (((u16)bus) << 8) | devfn,
2116 DMA_CCMD_MASK_NOBIT,
2117 DMA_CCMD_DEVICE_INVL);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002118 iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002119 } else {
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002120 iommu_flush_write_buffer(iommu);
David Woodhouse4c25a2c2009-05-10 17:16:06 +01002121 }
Yu Zhao93a23a72009-05-18 13:51:37 +08002122 iommu_enable_dev_iotlb(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08002123
Joerg Roedel55d94042015-07-22 16:50:40 +02002124 ret = 0;
2125
2126out_unlock:
2127 spin_unlock(&iommu->lock);
2128 spin_unlock_irqrestore(&device_domain_lock, flags);
Jiang Liufb170fb2014-07-11 14:19:28 +08002129
Wei Yang5c365d12016-07-13 13:53:21 +00002130 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002131}
2132
Alex Williamson579305f2014-07-03 09:51:43 -06002133struct domain_context_mapping_data {
2134 struct dmar_domain *domain;
2135 struct intel_iommu *iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002136};
2137
2138static int domain_context_mapping_cb(struct pci_dev *pdev,
2139 u16 alias, void *opaque)
2140{
2141 struct domain_context_mapping_data *data = opaque;
2142
2143 return domain_context_mapping_one(data->domain, data->iommu,
Joerg Roedel28ccce02015-07-21 14:45:31 +02002144 PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06002145}
2146
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002147static int
Joerg Roedel28ccce02015-07-21 14:45:31 +02002148domain_context_mapping(struct dmar_domain *domain, struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002149{
David Woodhouse64ae8922014-03-09 12:52:30 -07002150 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002151 u8 bus, devfn;
Alex Williamson579305f2014-07-03 09:51:43 -06002152 struct domain_context_mapping_data data;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002153
David Woodhousee1f167f2014-03-09 15:24:46 -07002154 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse64ae8922014-03-09 12:52:30 -07002155 if (!iommu)
2156 return -ENODEV;
2157
Alex Williamson579305f2014-07-03 09:51:43 -06002158 if (!dev_is_pci(dev))
Joerg Roedel28ccce02015-07-21 14:45:31 +02002159 return domain_context_mapping_one(domain, iommu, bus, devfn);
Alex Williamson579305f2014-07-03 09:51:43 -06002160
2161 data.domain = domain;
2162 data.iommu = iommu;
Alex Williamson579305f2014-07-03 09:51:43 -06002163
2164 return pci_for_each_dma_alias(to_pci_dev(dev),
2165 &domain_context_mapping_cb, &data);
2166}
2167
2168static int domain_context_mapped_cb(struct pci_dev *pdev,
2169 u16 alias, void *opaque)
2170{
2171 struct intel_iommu *iommu = opaque;
2172
2173 return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002174}
2175
David Woodhousee1f167f2014-03-09 15:24:46 -07002176static int domain_context_mapped(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002177{
Weidong Han5331fe62008-12-08 23:00:00 +08002178 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002179 u8 bus, devfn;
Weidong Han5331fe62008-12-08 23:00:00 +08002180
David Woodhousee1f167f2014-03-09 15:24:46 -07002181 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Han5331fe62008-12-08 23:00:00 +08002182 if (!iommu)
2183 return -ENODEV;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002184
Alex Williamson579305f2014-07-03 09:51:43 -06002185 if (!dev_is_pci(dev))
2186 return device_context_mapped(iommu, bus, devfn);
David Woodhousee1f167f2014-03-09 15:24:46 -07002187
Alex Williamson579305f2014-07-03 09:51:43 -06002188 return !pci_for_each_dma_alias(to_pci_dev(dev),
2189 domain_context_mapped_cb, iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002190}
2191
Fenghua Yuf5329592009-08-04 15:09:37 -07002192/* Returns a number of VTD pages, but aligned to MM page size */
2193static inline unsigned long aligned_nrpages(unsigned long host_addr,
2194 size_t size)
2195{
2196 host_addr &= ~PAGE_MASK;
2197 return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
2198}
2199
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002200/* Return largest possible superpage level for a given mapping */
2201static inline int hardware_largepage_caps(struct dmar_domain *domain,
2202 unsigned long iov_pfn,
2203 unsigned long phy_pfn,
2204 unsigned long pages)
2205{
2206 int support, level = 1;
2207 unsigned long pfnmerge;
2208
2209 support = domain->iommu_superpage;
2210
2211 /* To use a large page, the virtual *and* physical addresses
2212 must be aligned to 2MiB/1GiB/etc. Lower bits set in either
2213 of them will mean we have to use smaller pages. So just
2214 merge them and check both at once. */
2215 pfnmerge = iov_pfn | phy_pfn;
2216
2217 while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
2218 pages >>= VTD_STRIDE_SHIFT;
2219 if (!pages)
2220 break;
2221 pfnmerge >>= VTD_STRIDE_SHIFT;
2222 level++;
2223 support--;
2224 }
2225 return level;
2226}
2227
David Woodhouse9051aa02009-06-29 12:30:54 +01002228static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2229 struct scatterlist *sg, unsigned long phys_pfn,
2230 unsigned long nr_pages, int prot)
David Woodhousee1605492009-06-29 11:17:38 +01002231{
2232 struct dma_pte *first_pte = NULL, *pte = NULL;
David Woodhouse9051aa02009-06-29 12:30:54 +01002233 phys_addr_t uninitialized_var(pteval);
Jiang Liucc4f14a2014-11-26 09:42:10 +08002234 unsigned long sg_res = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002235 unsigned int largepage_lvl = 0;
2236 unsigned long lvl_pages = 0;
David Woodhousee1605492009-06-29 11:17:38 +01002237
Jiang Liu162d1b12014-07-11 14:19:35 +08002238 BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
David Woodhousee1605492009-06-29 11:17:38 +01002239
2240 if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
2241 return -EINVAL;
2242
2243 prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
2244
Jiang Liucc4f14a2014-11-26 09:42:10 +08002245 if (!sg) {
2246 sg_res = nr_pages;
David Woodhouse9051aa02009-06-29 12:30:54 +01002247 pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
2248 }
2249
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002250 while (nr_pages > 0) {
David Woodhousec85994e2009-07-01 19:21:24 +01002251 uint64_t tmp;
2252
David Woodhousee1605492009-06-29 11:17:38 +01002253 if (!sg_res) {
Robin Murphy29a90b72017-09-28 15:14:01 +01002254 unsigned int pgoff = sg->offset & ~PAGE_MASK;
2255
Fenghua Yuf5329592009-08-04 15:09:37 -07002256 sg_res = aligned_nrpages(sg->offset, sg->length);
Robin Murphy29a90b72017-09-28 15:14:01 +01002257 sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
David Woodhousee1605492009-06-29 11:17:38 +01002258 sg->dma_length = sg->length;
Robin Murphy29a90b72017-09-28 15:14:01 +01002259 pteval = (sg_phys(sg) - pgoff) | prot;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002260 phys_pfn = pteval >> VTD_PAGE_SHIFT;
David Woodhousee1605492009-06-29 11:17:38 +01002261 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002262
David Woodhousee1605492009-06-29 11:17:38 +01002263 if (!pte) {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002264 largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
2265
David Woodhouse5cf0a762014-03-19 16:07:49 +00002266 first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl);
David Woodhousee1605492009-06-29 11:17:38 +01002267 if (!pte)
2268 return -ENOMEM;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002269 /* It is large page*/
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002270 if (largepage_lvl > 1) {
Christian Zanderba2374f2015-06-10 09:41:45 -07002271 unsigned long nr_superpages, end_pfn;
2272
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002273 pteval |= DMA_PTE_LARGE_PAGE;
Jiang Liud41a4ad2014-07-11 14:19:34 +08002274 lvl_pages = lvl_to_nr_pages(largepage_lvl);
Christian Zanderba2374f2015-06-10 09:41:45 -07002275
2276 nr_superpages = sg_res / lvl_pages;
2277 end_pfn = iov_pfn + nr_superpages * lvl_pages - 1;
2278
Jiang Liud41a4ad2014-07-11 14:19:34 +08002279 /*
2280 * Ensure that old small page tables are
Christian Zanderba2374f2015-06-10 09:41:45 -07002281 * removed to make room for superpage(s).
David Dillowbc24c572017-06-28 19:42:23 -07002282 * We're adding new large pages, so make sure
2283 * we don't remove their parent tables.
Jiang Liud41a4ad2014-07-11 14:19:34 +08002284 */
David Dillowbc24c572017-06-28 19:42:23 -07002285 dma_pte_free_pagetable(domain, iov_pfn, end_pfn,
2286 largepage_lvl + 1);
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002287 } else {
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002288 pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
Woodhouse, David6491d4d2012-12-19 13:25:35 +00002289 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002290
David Woodhousee1605492009-06-29 11:17:38 +01002291 }
2292 /* We don't need lock here, nobody else
2293 * touches the iova range
2294 */
David Woodhouse7766a3f2009-07-01 20:27:03 +01002295 tmp = cmpxchg64_local(&pte->val, 0ULL, pteval);
David Woodhousec85994e2009-07-01 19:21:24 +01002296 if (tmp) {
David Woodhouse1bf20f02009-06-29 22:06:43 +01002297 static int dumps = 5;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002298 pr_crit("ERROR: DMA PTE for vPFN 0x%lx already set (to %llx not %llx)\n",
2299 iov_pfn, tmp, (unsigned long long)pteval);
David Woodhouse1bf20f02009-06-29 22:06:43 +01002300 if (dumps) {
2301 dumps--;
2302 debug_dma_dump_mappings(NULL);
2303 }
2304 WARN_ON(1);
2305 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002306
2307 lvl_pages = lvl_to_nr_pages(largepage_lvl);
2308
2309 BUG_ON(nr_pages < lvl_pages);
2310 BUG_ON(sg_res < lvl_pages);
2311
2312 nr_pages -= lvl_pages;
2313 iov_pfn += lvl_pages;
2314 phys_pfn += lvl_pages;
2315 pteval += lvl_pages * VTD_PAGE_SIZE;
2316 sg_res -= lvl_pages;
2317
2318 /* If the next PTE would be the first in a new page, then we
2319 need to flush the cache on the entries we've just written.
2320 And then we'll need to recalculate 'pte', so clear it and
2321 let it get set again in the if (!pte) block above.
2322
2323 If we're done (!nr_pages) we need to flush the cache too.
2324
2325 Also if we've been setting superpages, we may need to
2326 recalculate 'pte' and switch back to smaller pages for the
2327 end of the mapping, if the trailing size is not enough to
2328 use another superpage (i.e. sg_res < lvl_pages). */
David Woodhousee1605492009-06-29 11:17:38 +01002329 pte++;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002330 if (!nr_pages || first_pte_in_page(pte) ||
2331 (largepage_lvl > 1 && sg_res < lvl_pages)) {
David Woodhousee1605492009-06-29 11:17:38 +01002332 domain_flush_cache(domain, first_pte,
2333 (void *)pte - (void *)first_pte);
2334 pte = NULL;
2335 }
Youquan Song6dd9a7c2011-05-25 19:13:49 +01002336
2337 if (!sg_res && nr_pages)
David Woodhousee1605492009-06-29 11:17:38 +01002338 sg = sg_next(sg);
2339 }
2340 return 0;
2341}
2342
David Woodhouse9051aa02009-06-29 12:30:54 +01002343static inline int domain_sg_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2344 struct scatterlist *sg, unsigned long nr_pages,
2345 int prot)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002346{
David Woodhouse9051aa02009-06-29 12:30:54 +01002347 return __domain_mapping(domain, iov_pfn, sg, 0, nr_pages, prot);
2348}
Fenghua Yu5b6985c2008-10-16 18:02:32 -07002349
David Woodhouse9051aa02009-06-29 12:30:54 +01002350static inline int domain_pfn_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
2351 unsigned long phys_pfn, unsigned long nr_pages,
2352 int prot)
2353{
2354 return __domain_mapping(domain, iov_pfn, NULL, phys_pfn, nr_pages, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002355}
2356
Joerg Roedel2452d9d2015-07-23 16:20:14 +02002357static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002358{
Filippo Sironi50822192017-08-31 10:58:11 +02002359 unsigned long flags;
2360 struct context_entry *context;
2361 u16 did_old;
2362
Weidong Hanc7151a82008-12-08 22:51:37 +08002363 if (!iommu)
2364 return;
Weidong Han8c11e792008-12-08 15:29:22 +08002365
Filippo Sironi50822192017-08-31 10:58:11 +02002366 spin_lock_irqsave(&iommu->lock, flags);
2367 context = iommu_context_addr(iommu, bus, devfn, 0);
2368 if (!context) {
2369 spin_unlock_irqrestore(&iommu->lock, flags);
2370 return;
2371 }
2372 did_old = context_domain_id(context);
2373 context_clear_entry(context);
2374 __iommu_flush_cache(iommu, context, sizeof(*context));
2375 spin_unlock_irqrestore(&iommu->lock, flags);
2376 iommu->flush.flush_context(iommu,
2377 did_old,
2378 (((u16)bus) << 8) | devfn,
2379 DMA_CCMD_MASK_NOBIT,
2380 DMA_CCMD_DEVICE_INVL);
2381 iommu->flush.flush_iotlb(iommu,
2382 did_old,
2383 0,
2384 0,
2385 DMA_TLB_DSI_FLUSH);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002386}
2387
David Woodhouse109b9b02012-05-25 17:43:02 +01002388static inline void unlink_domain_info(struct device_domain_info *info)
2389{
2390 assert_spin_locked(&device_domain_lock);
2391 list_del(&info->link);
2392 list_del(&info->global);
2393 if (info->dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002394 info->dev->archdata.iommu = NULL;
David Woodhouse109b9b02012-05-25 17:43:02 +01002395}
2396
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002397static void domain_remove_dev_info(struct dmar_domain *domain)
2398{
Yijing Wang3a74ca02014-05-20 20:37:47 +08002399 struct device_domain_info *info, *tmp;
Jiang Liufb170fb2014-07-11 14:19:28 +08002400 unsigned long flags;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002401
2402 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel76f45fe2015-07-21 18:25:11 +02002403 list_for_each_entry_safe(info, tmp, &domain->devices, link)
Joerg Roedel127c7612015-07-23 17:44:46 +02002404 __dmar_remove_one_dev_info(info);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002405 spin_unlock_irqrestore(&device_domain_lock, flags);
2406}
2407
2408/*
2409 * find_domain
David Woodhouse1525a292014-03-06 16:19:30 +00002410 * Note: we use struct device->archdata.iommu stores the info
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002411 */
David Woodhouse1525a292014-03-06 16:19:30 +00002412static struct dmar_domain *find_domain(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002413{
2414 struct device_domain_info *info;
2415
2416 /* No lock here, assumes no domain exit in normal case */
David Woodhouse1525a292014-03-06 16:19:30 +00002417 info = dev->archdata.iommu;
Peter Xub316d022017-05-22 18:28:51 +08002418 if (likely(info))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002419 return info->domain;
2420 return NULL;
2421}
2422
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002423static inline struct device_domain_info *
Jiang Liu745f2582014-02-19 14:07:26 +08002424dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2425{
2426 struct device_domain_info *info;
2427
2428 list_for_each_entry(info, &device_domain_list, global)
David Woodhouse41e80dca2014-03-09 13:55:54 -07002429 if (info->iommu->segment == segment && info->bus == bus &&
Jiang Liu745f2582014-02-19 14:07:26 +08002430 info->devfn == devfn)
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002431 return info;
Jiang Liu745f2582014-02-19 14:07:26 +08002432
2433 return NULL;
2434}
2435
Joerg Roedel5db31562015-07-22 12:40:43 +02002436static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
2437 int bus, int devfn,
2438 struct device *dev,
2439 struct dmar_domain *domain)
Jiang Liu745f2582014-02-19 14:07:26 +08002440{
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002441 struct dmar_domain *found = NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002442 struct device_domain_info *info;
2443 unsigned long flags;
Joerg Roedeld160aca2015-07-22 11:52:53 +02002444 int ret;
Jiang Liu745f2582014-02-19 14:07:26 +08002445
2446 info = alloc_devinfo_mem();
2447 if (!info)
David Woodhouseb718cd32014-03-09 13:11:33 -07002448 return NULL;
Jiang Liu745f2582014-02-19 14:07:26 +08002449
Jiang Liu745f2582014-02-19 14:07:26 +08002450 info->bus = bus;
2451 info->devfn = devfn;
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002452 info->ats_supported = info->pasid_supported = info->pri_supported = 0;
2453 info->ats_enabled = info->pasid_enabled = info->pri_enabled = 0;
2454 info->ats_qdep = 0;
Jiang Liu745f2582014-02-19 14:07:26 +08002455 info->dev = dev;
2456 info->domain = domain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002457 info->iommu = iommu;
Jiang Liu745f2582014-02-19 14:07:26 +08002458
David Woodhouseb16d0cb2015-10-12 14:17:37 +01002459 if (dev && dev_is_pci(dev)) {
2460 struct pci_dev *pdev = to_pci_dev(info->dev);
2461
2462 if (ecap_dev_iotlb_support(iommu->ecap) &&
2463 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS) &&
2464 dmar_find_matched_atsr_unit(pdev))
2465 info->ats_supported = 1;
2466
2467 if (ecs_enabled(iommu)) {
2468 if (pasid_enabled(iommu)) {
2469 int features = pci_pasid_features(pdev);
2470 if (features >= 0)
2471 info->pasid_supported = features | 1;
2472 }
2473
2474 if (info->ats_supported && ecap_prs(iommu->ecap) &&
2475 pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI))
2476 info->pri_supported = 1;
2477 }
2478 }
2479
Jiang Liu745f2582014-02-19 14:07:26 +08002480 spin_lock_irqsave(&device_domain_lock, flags);
2481 if (dev)
David Woodhouse0bcb3e22014-03-06 17:12:03 +00002482 found = find_domain(dev);
Joerg Roedelf303e502015-07-23 18:37:13 +02002483
2484 if (!found) {
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002485 struct device_domain_info *info2;
David Woodhouse41e80dca2014-03-09 13:55:54 -07002486 info2 = dmar_search_domain_by_dev_info(iommu->segment, bus, devfn);
Joerg Roedelf303e502015-07-23 18:37:13 +02002487 if (info2) {
2488 found = info2->domain;
2489 info2->dev = dev;
2490 }
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002491 }
Joerg Roedelf303e502015-07-23 18:37:13 +02002492
Jiang Liu745f2582014-02-19 14:07:26 +08002493 if (found) {
2494 spin_unlock_irqrestore(&device_domain_lock, flags);
2495 free_devinfo_mem(info);
David Woodhouseb718cd32014-03-09 13:11:33 -07002496 /* Caller must free the original domain */
2497 return found;
Jiang Liu745f2582014-02-19 14:07:26 +08002498 }
2499
Joerg Roedeld160aca2015-07-22 11:52:53 +02002500 spin_lock(&iommu->lock);
2501 ret = domain_attach_iommu(domain, iommu);
2502 spin_unlock(&iommu->lock);
2503
2504 if (ret) {
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002505 spin_unlock_irqrestore(&device_domain_lock, flags);
Sudip Mukherjee499f3aa2015-09-18 16:27:07 +05302506 free_devinfo_mem(info);
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002507 return NULL;
2508 }
Joerg Roedelc6c2ceb2015-07-22 13:11:53 +02002509
David Woodhouseb718cd32014-03-09 13:11:33 -07002510 list_add(&info->link, &domain->devices);
2511 list_add(&info->global, &device_domain_list);
2512 if (dev)
2513 dev->archdata.iommu = info;
2514 spin_unlock_irqrestore(&device_domain_lock, flags);
2515
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002516 if (dev && domain_context_mapping(domain, dev)) {
2517 pr_err("Domain context map for %s failed\n", dev_name(dev));
Joerg Roedele6de0f82015-07-22 16:30:36 +02002518 dmar_remove_one_dev_info(domain, dev);
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002519 return NULL;
2520 }
2521
David Woodhouseb718cd32014-03-09 13:11:33 -07002522 return domain;
Jiang Liu745f2582014-02-19 14:07:26 +08002523}
2524
Alex Williamson579305f2014-07-03 09:51:43 -06002525static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
2526{
2527 *(u16 *)opaque = alias;
2528 return 0;
2529}
2530
Joerg Roedel76208352016-08-25 14:25:12 +02002531static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002532{
Joerg Roedelcc4e2572015-07-22 10:04:36 +02002533 struct device_domain_info *info = NULL;
Joerg Roedel76208352016-08-25 14:25:12 +02002534 struct dmar_domain *domain = NULL;
Alex Williamson579305f2014-07-03 09:51:43 -06002535 struct intel_iommu *iommu;
Joerg Roedel08a7f452015-07-23 18:09:11 +02002536 u16 req_id, dma_alias;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002537 unsigned long flags;
Yijing Wangaa4d0662014-05-26 20:14:06 +08002538 u8 bus, devfn;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002539
David Woodhouse146922e2014-03-09 15:44:17 -07002540 iommu = device_to_iommu(dev, &bus, &devfn);
2541 if (!iommu)
Alex Williamson579305f2014-07-03 09:51:43 -06002542 return NULL;
2543
Joerg Roedel08a7f452015-07-23 18:09:11 +02002544 req_id = ((u16)bus << 8) | devfn;
2545
Alex Williamson579305f2014-07-03 09:51:43 -06002546 if (dev_is_pci(dev)) {
2547 struct pci_dev *pdev = to_pci_dev(dev);
2548
2549 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2550
2551 spin_lock_irqsave(&device_domain_lock, flags);
2552 info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
2553 PCI_BUS_NUM(dma_alias),
2554 dma_alias & 0xff);
2555 if (info) {
2556 iommu = info->iommu;
2557 domain = info->domain;
2558 }
2559 spin_unlock_irqrestore(&device_domain_lock, flags);
2560
Joerg Roedel76208352016-08-25 14:25:12 +02002561 /* DMA alias already has a domain, use it */
Alex Williamson579305f2014-07-03 09:51:43 -06002562 if (info)
Joerg Roedel76208352016-08-25 14:25:12 +02002563 goto out;
Alex Williamson579305f2014-07-03 09:51:43 -06002564 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002565
David Woodhouse146922e2014-03-09 15:44:17 -07002566 /* Allocate and initialize new domain for the device */
Jiang Liuab8dfe22014-07-11 14:19:27 +08002567 domain = alloc_domain(0);
Jiang Liu745f2582014-02-19 14:07:26 +08002568 if (!domain)
Alex Williamson579305f2014-07-03 09:51:43 -06002569 return NULL;
Joerg Roedeldc534b22015-07-22 12:44:02 +02002570 if (domain_init(domain, iommu, gaw)) {
Alex Williamson579305f2014-07-03 09:51:43 -06002571 domain_exit(domain);
2572 return NULL;
2573 }
2574
Joerg Roedel76208352016-08-25 14:25:12 +02002575out:
Alex Williamson579305f2014-07-03 09:51:43 -06002576
Joerg Roedel76208352016-08-25 14:25:12 +02002577 return domain;
2578}
2579
2580static struct dmar_domain *set_domain_for_dev(struct device *dev,
2581 struct dmar_domain *domain)
2582{
2583 struct intel_iommu *iommu;
2584 struct dmar_domain *tmp;
2585 u16 req_id, dma_alias;
2586 u8 bus, devfn;
2587
2588 iommu = device_to_iommu(dev, &bus, &devfn);
2589 if (!iommu)
2590 return NULL;
2591
2592 req_id = ((u16)bus << 8) | devfn;
2593
2594 if (dev_is_pci(dev)) {
2595 struct pci_dev *pdev = to_pci_dev(dev);
2596
2597 pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
2598
2599 /* register PCI DMA alias device */
2600 if (req_id != dma_alias) {
2601 tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
2602 dma_alias & 0xff, NULL, domain);
2603
2604 if (!tmp || tmp != domain)
2605 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002606 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002607 }
2608
Joerg Roedel5db31562015-07-22 12:40:43 +02002609 tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
Joerg Roedel76208352016-08-25 14:25:12 +02002610 if (!tmp || tmp != domain)
2611 return tmp;
Alex Williamson579305f2014-07-03 09:51:43 -06002612
Joerg Roedel76208352016-08-25 14:25:12 +02002613 return domain;
2614}
2615
2616static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2617{
2618 struct dmar_domain *domain, *tmp;
2619
2620 domain = find_domain(dev);
2621 if (domain)
2622 goto out;
2623
2624 domain = find_or_alloc_domain(dev, gaw);
2625 if (!domain)
2626 goto out;
2627
2628 tmp = set_domain_for_dev(dev, domain);
2629 if (!tmp || domain != tmp) {
Alex Williamson579305f2014-07-03 09:51:43 -06002630 domain_exit(domain);
2631 domain = tmp;
2632 }
David Woodhouseb718cd32014-03-09 13:11:33 -07002633
Joerg Roedel76208352016-08-25 14:25:12 +02002634out:
2635
David Woodhouseb718cd32014-03-09 13:11:33 -07002636 return domain;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002637}
2638
David Woodhouseb2132032009-06-26 18:50:28 +01002639static int iommu_domain_identity_map(struct dmar_domain *domain,
2640 unsigned long long start,
2641 unsigned long long end)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002642{
David Woodhousec5395d52009-06-28 16:35:56 +01002643 unsigned long first_vpfn = start >> VTD_PAGE_SHIFT;
2644 unsigned long last_vpfn = end >> VTD_PAGE_SHIFT;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002645
David Woodhousec5395d52009-06-28 16:35:56 +01002646 if (!reserve_iova(&domain->iovad, dma_to_mm_pfn(first_vpfn),
2647 dma_to_mm_pfn(last_vpfn))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002648 pr_err("Reserving iova failed\n");
David Woodhouseb2132032009-06-26 18:50:28 +01002649 return -ENOMEM;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002650 }
2651
Joerg Roedelaf1089c2015-07-21 15:45:19 +02002652 pr_debug("Mapping reserved region %llx-%llx\n", start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002653 /*
2654 * RMRR range might have overlap with physical memory range,
2655 * clear it first
2656 */
David Woodhousec5395d52009-06-28 16:35:56 +01002657 dma_pte_clear_range(domain, first_vpfn, last_vpfn);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002658
David Woodhousec5395d52009-06-28 16:35:56 +01002659 return domain_pfn_mapping(domain, first_vpfn, first_vpfn,
2660 last_vpfn - first_vpfn + 1,
David Woodhouse61df7442009-06-28 11:55:58 +01002661 DMA_PTE_READ|DMA_PTE_WRITE);
David Woodhouseb2132032009-06-26 18:50:28 +01002662}
2663
Joerg Roedeld66ce542015-09-23 19:00:10 +02002664static int domain_prepare_identity_map(struct device *dev,
2665 struct dmar_domain *domain,
2666 unsigned long long start,
2667 unsigned long long end)
David Woodhouseb2132032009-06-26 18:50:28 +01002668{
David Woodhouse19943b02009-08-04 16:19:20 +01002669 /* For _hardware_ passthrough, don't bother. But for software
2670 passthrough, we do it anyway -- it may indicate a memory
2671 range which is reserved in E820, so which didn't get set
2672 up to start with in si_domain */
2673 if (domain == si_domain && hw_pass_through) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002674 pr_warn("Ignoring identity map for HW passthrough device %s [0x%Lx - 0x%Lx]\n",
2675 dev_name(dev), start, end);
David Woodhouse19943b02009-08-04 16:19:20 +01002676 return 0;
2677 }
2678
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002679 pr_info("Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
2680 dev_name(dev), start, end);
2681
David Woodhouse5595b522009-12-02 09:21:55 +00002682 if (end < start) {
2683 WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
2684 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2685 dmi_get_system_info(DMI_BIOS_VENDOR),
2686 dmi_get_system_info(DMI_BIOS_VERSION),
2687 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002688 return -EIO;
David Woodhouse5595b522009-12-02 09:21:55 +00002689 }
2690
David Woodhouse2ff729f2009-08-26 14:25:41 +01002691 if (end >> agaw_to_width(domain->agaw)) {
2692 WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
2693 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
2694 agaw_to_width(domain->agaw),
2695 dmi_get_system_info(DMI_BIOS_VENDOR),
2696 dmi_get_system_info(DMI_BIOS_VERSION),
2697 dmi_get_system_info(DMI_PRODUCT_VERSION));
Joerg Roedeld66ce542015-09-23 19:00:10 +02002698 return -EIO;
David Woodhouse2ff729f2009-08-26 14:25:41 +01002699 }
David Woodhouse19943b02009-08-04 16:19:20 +01002700
Joerg Roedeld66ce542015-09-23 19:00:10 +02002701 return iommu_domain_identity_map(domain, start, end);
2702}
2703
2704static int iommu_prepare_identity_map(struct device *dev,
2705 unsigned long long start,
2706 unsigned long long end)
2707{
2708 struct dmar_domain *domain;
2709 int ret;
2710
2711 domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2712 if (!domain)
2713 return -ENOMEM;
2714
2715 ret = domain_prepare_identity_map(dev, domain, start, end);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002716 if (ret)
Joerg Roedeld66ce542015-09-23 19:00:10 +02002717 domain_exit(domain);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002718
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002719 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002720}
2721
2722static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
David Woodhouse0b9d9752014-03-09 15:48:15 -07002723 struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002724{
David Woodhouse0b9d9752014-03-09 15:48:15 -07002725 if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002726 return 0;
David Woodhouse0b9d9752014-03-09 15:48:15 -07002727 return iommu_prepare_identity_map(dev, rmrr->base_address,
2728 rmrr->end_address);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07002729}
2730
Suresh Siddhad3f13812011-08-23 17:05:25 -07002731#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002732static inline void iommu_prepare_isa(void)
2733{
2734 struct pci_dev *pdev;
2735 int ret;
2736
2737 pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
2738 if (!pdev)
2739 return;
2740
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002741 pr_info("Prepare 0-16MiB unity mapping for LPC\n");
David Woodhouse0b9d9752014-03-09 15:48:15 -07002742 ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002743
2744 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002745 pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002746
Yijing Wang9b27e822014-05-20 20:37:52 +08002747 pci_dev_put(pdev);
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002748}
2749#else
2750static inline void iommu_prepare_isa(void)
2751{
2752 return;
2753}
Suresh Siddhad3f13812011-08-23 17:05:25 -07002754#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07002755
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002756static int md_domain_init(struct dmar_domain *domain, int guest_width);
David Woodhousec7ab48d2009-06-26 19:10:36 +01002757
Matt Kraai071e1372009-08-23 22:30:22 -07002758static int __init si_domain_init(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002759{
David Woodhousec7ab48d2009-06-26 19:10:36 +01002760 int nid, ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002761
Jiang Liuab8dfe22014-07-11 14:19:27 +08002762 si_domain = alloc_domain(DOMAIN_FLAG_STATIC_IDENTITY);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002763 if (!si_domain)
2764 return -EFAULT;
2765
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002766 if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
2767 domain_exit(si_domain);
2768 return -EFAULT;
2769 }
2770
Joerg Roedel0dc79712015-07-21 15:40:06 +02002771 pr_debug("Identity mapping domain allocated\n");
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002772
David Woodhouse19943b02009-08-04 16:19:20 +01002773 if (hw)
2774 return 0;
2775
David Woodhousec7ab48d2009-06-26 19:10:36 +01002776 for_each_online_node(nid) {
Tejun Heod4bbf7e2011-11-28 09:46:22 -08002777 unsigned long start_pfn, end_pfn;
2778 int i;
2779
2780 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
2781 ret = iommu_domain_identity_map(si_domain,
2782 PFN_PHYS(start_pfn), PFN_PHYS(end_pfn));
2783 if (ret)
2784 return ret;
2785 }
David Woodhousec7ab48d2009-06-26 19:10:36 +01002786 }
2787
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002788 return 0;
2789}
2790
David Woodhouse9b226622014-03-09 14:03:28 -07002791static int identity_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002792{
2793 struct device_domain_info *info;
2794
2795 if (likely(!iommu_identity_mapping))
2796 return 0;
2797
David Woodhouse9b226622014-03-09 14:03:28 -07002798 info = dev->archdata.iommu;
Mike Traviscb452a42011-05-28 13:15:03 -05002799 if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
2800 return (info->domain == si_domain);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002801
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002802 return 0;
2803}
2804
Joerg Roedel28ccce02015-07-21 14:45:31 +02002805static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002806{
David Woodhouse0ac72662014-03-09 13:19:22 -07002807 struct dmar_domain *ndomain;
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002808 struct intel_iommu *iommu;
David Woodhouse156baca2014-03-09 14:00:57 -07002809 u8 bus, devfn;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002810
David Woodhouse5913c9b2014-03-09 16:27:31 -07002811 iommu = device_to_iommu(dev, &bus, &devfn);
David Woodhouse5a8f40e2014-03-09 13:31:18 -07002812 if (!iommu)
2813 return -ENODEV;
2814
Joerg Roedel5db31562015-07-22 12:40:43 +02002815 ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
David Woodhouse0ac72662014-03-09 13:19:22 -07002816 if (ndomain != domain)
2817 return -EBUSY;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002818
2819 return 0;
2820}
2821
David Woodhouse0b9d9752014-03-09 15:48:15 -07002822static bool device_has_rmrr(struct device *dev)
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002823{
2824 struct dmar_rmrr_unit *rmrr;
David Woodhouse832bd852014-03-07 15:08:36 +00002825 struct device *tmp;
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002826 int i;
2827
Jiang Liu0e242612014-02-19 14:07:34 +08002828 rcu_read_lock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002829 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08002830 /*
2831 * Return TRUE if this RMRR contains the device that
2832 * is passed in.
2833 */
2834 for_each_active_dev_scope(rmrr->devices,
2835 rmrr->devices_cnt, i, tmp)
David Woodhouse0b9d9752014-03-09 15:48:15 -07002836 if (tmp == dev) {
Jiang Liu0e242612014-02-19 14:07:34 +08002837 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002838 return true;
Jiang Liub683b232014-02-19 14:07:32 +08002839 }
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002840 }
Jiang Liu0e242612014-02-19 14:07:34 +08002841 rcu_read_unlock();
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002842 return false;
2843}
2844
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002845/*
2846 * There are a couple cases where we need to restrict the functionality of
2847 * devices associated with RMRRs. The first is when evaluating a device for
2848 * identity mapping because problems exist when devices are moved in and out
2849 * of domains and their respective RMRR information is lost. This means that
2850 * a device with associated RMRRs will never be in a "passthrough" domain.
2851 * The second is use of the device through the IOMMU API. This interface
2852 * expects to have full control of the IOVA space for the device. We cannot
2853 * satisfy both the requirement that RMRR access is maintained and have an
2854 * unencumbered IOVA space. We also have no ability to quiesce the device's
2855 * use of the RMRR space or even inform the IOMMU API user of the restriction.
2856 * We therefore prevent devices associated with an RMRR from participating in
2857 * the IOMMU API, which eliminates them from device assignment.
2858 *
2859 * In both cases we assume that PCI USB devices with RMRRs have them largely
2860 * for historical reasons and that the RMRR space is not actively used post
2861 * boot. This exclusion may change if vendors begin to abuse it.
David Woodhouse18436af2015-03-25 15:05:47 +00002862 *
2863 * The same exception is made for graphics devices, with the requirement that
2864 * any use of the RMRR regions will be torn down before assigning the device
2865 * to a guest.
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002866 */
2867static bool device_is_rmrr_locked(struct device *dev)
2868{
2869 if (!device_has_rmrr(dev))
2870 return false;
2871
2872 if (dev_is_pci(dev)) {
2873 struct pci_dev *pdev = to_pci_dev(dev);
2874
David Woodhouse18436af2015-03-25 15:05:47 +00002875 if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002876 return false;
2877 }
2878
2879 return true;
2880}
2881
David Woodhouse3bdb2592014-03-09 16:03:08 -07002882static int iommu_should_identity_map(struct device *dev, int startup)
David Woodhouse6941af22009-07-04 18:24:27 +01002883{
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002884
David Woodhouse3bdb2592014-03-09 16:03:08 -07002885 if (dev_is_pci(dev)) {
2886 struct pci_dev *pdev = to_pci_dev(dev);
Tom Mingarelliea2447f2012-11-20 19:43:17 +00002887
Alex Williamsonc875d2c2014-07-03 09:57:02 -06002888 if (device_is_rmrr_locked(dev))
David Woodhouse3bdb2592014-03-09 16:03:08 -07002889 return 0;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002890
David Woodhouse3bdb2592014-03-09 16:03:08 -07002891 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2892 return 1;
David Woodhousee0fc7e02009-09-30 09:12:17 -07002893
David Woodhouse3bdb2592014-03-09 16:03:08 -07002894 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2895 return 1;
2896
2897 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2898 return 0;
2899
2900 /*
2901 * We want to start off with all devices in the 1:1 domain, and
2902 * take them out later if we find they can't access all of memory.
2903 *
2904 * However, we can't do this for PCI devices behind bridges,
2905 * because all PCI devices behind the same bridge will end up
2906 * with the same source-id on their transactions.
2907 *
2908 * Practically speaking, we can't change things around for these
2909 * devices at run-time, because we can't be sure there'll be no
2910 * DMA transactions in flight for any of their siblings.
2911 *
2912 * So PCI devices (unless they're on the root bus) as well as
2913 * their parent PCI-PCI or PCIe-PCI bridges must be left _out_ of
2914 * the 1:1 domain, just in _case_ one of their siblings turns out
2915 * not to be able to map all of memory.
2916 */
2917 if (!pci_is_pcie(pdev)) {
2918 if (!pci_is_root_bus(pdev->bus))
2919 return 0;
2920 if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
2921 return 0;
2922 } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
2923 return 0;
2924 } else {
2925 if (device_has_rmrr(dev))
2926 return 0;
2927 }
David Woodhouse6941af22009-07-04 18:24:27 +01002928
David Woodhouse3dfc8132009-07-04 19:11:08 +01002929 /*
David Woodhouse3dfc8132009-07-04 19:11:08 +01002930 * At boot time, we don't yet know if devices will be 64-bit capable.
David Woodhouse3bdb2592014-03-09 16:03:08 -07002931 * Assume that they will — if they turn out not to be, then we can
David Woodhouse3dfc8132009-07-04 19:11:08 +01002932 * take them out of the 1:1 domain later.
2933 */
Chris Wright8fcc5372011-05-28 13:15:02 -05002934 if (!startup) {
2935 /*
2936 * If the device's dma_mask is less than the system's memory
2937 * size then this is not a candidate for identity mapping.
2938 */
David Woodhouse3bdb2592014-03-09 16:03:08 -07002939 u64 dma_mask = *dev->dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002940
David Woodhouse3bdb2592014-03-09 16:03:08 -07002941 if (dev->coherent_dma_mask &&
2942 dev->coherent_dma_mask < dma_mask)
2943 dma_mask = dev->coherent_dma_mask;
Chris Wright8fcc5372011-05-28 13:15:02 -05002944
David Woodhouse3bdb2592014-03-09 16:03:08 -07002945 return dma_mask >= dma_get_required_mask(dev);
Chris Wright8fcc5372011-05-28 13:15:02 -05002946 }
David Woodhouse6941af22009-07-04 18:24:27 +01002947
2948 return 1;
2949}
2950
David Woodhousecf04eee2014-03-21 16:49:04 +00002951static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw)
2952{
2953 int ret;
2954
2955 if (!iommu_should_identity_map(dev, 1))
2956 return 0;
2957
Joerg Roedel28ccce02015-07-21 14:45:31 +02002958 ret = domain_add_dev_info(si_domain, dev);
David Woodhousecf04eee2014-03-21 16:49:04 +00002959 if (!ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02002960 pr_info("%s identity mapping for device %s\n",
2961 hw ? "Hardware" : "Software", dev_name(dev));
David Woodhousecf04eee2014-03-21 16:49:04 +00002962 else if (ret == -ENODEV)
2963 /* device not associated with an iommu */
2964 ret = 0;
2965
2966 return ret;
2967}
2968
2969
Matt Kraai071e1372009-08-23 22:30:22 -07002970static int __init iommu_prepare_static_identity_mapping(int hw)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002971{
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002972 struct pci_dev *pdev = NULL;
David Woodhousecf04eee2014-03-21 16:49:04 +00002973 struct dmar_drhd_unit *drhd;
2974 struct intel_iommu *iommu;
2975 struct device *dev;
2976 int i;
2977 int ret = 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002978
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002979 for_each_pci_dev(pdev) {
David Woodhousecf04eee2014-03-21 16:49:04 +00002980 ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
2981 if (ret)
2982 return ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07002983 }
2984
David Woodhousecf04eee2014-03-21 16:49:04 +00002985 for_each_active_iommu(iommu, drhd)
2986 for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
2987 struct acpi_device_physical_node *pn;
2988 struct acpi_device *adev;
2989
2990 if (dev->bus != &acpi_bus_type)
2991 continue;
Joerg Roedel86080cc2015-06-12 12:27:16 +02002992
David Woodhousecf04eee2014-03-21 16:49:04 +00002993 adev= to_acpi_device(dev);
2994 mutex_lock(&adev->physical_node_lock);
2995 list_for_each_entry(pn, &adev->physical_node_list, node) {
2996 ret = dev_prepare_static_identity_mapping(pn->dev, hw);
2997 if (ret)
2998 break;
2999 }
3000 mutex_unlock(&adev->physical_node_lock);
3001 if (ret)
3002 return ret;
3003 }
3004
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003005 return 0;
3006}
3007
Jiang Liuffebeb42014-11-09 22:48:02 +08003008static void intel_iommu_init_qi(struct intel_iommu *iommu)
3009{
3010 /*
3011 * Start from the sane iommu hardware state.
3012 * If the queued invalidation is already initialized by us
3013 * (for example, while enabling interrupt-remapping) then
3014 * we got the things already rolling from a sane state.
3015 */
3016 if (!iommu->qi) {
3017 /*
3018 * Clear any previous faults.
3019 */
3020 dmar_fault(-1, iommu);
3021 /*
3022 * Disable queued invalidation if supported and already enabled
3023 * before OS handover.
3024 */
3025 dmar_disable_qi(iommu);
3026 }
3027
3028 if (dmar_enable_qi(iommu)) {
3029 /*
3030 * Queued Invalidate not enabled, use Register Based Invalidate
3031 */
3032 iommu->flush.flush_context = __iommu_flush_context;
3033 iommu->flush.flush_iotlb = __iommu_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003034 pr_info("%s: Using Register based invalidation\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08003035 iommu->name);
3036 } else {
3037 iommu->flush.flush_context = qi_flush_context;
3038 iommu->flush.flush_iotlb = qi_flush_iotlb;
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003039 pr_info("%s: Using Queued invalidation\n", iommu->name);
Jiang Liuffebeb42014-11-09 22:48:02 +08003040 }
3041}
3042
Joerg Roedel091d42e2015-06-12 11:56:10 +02003043static int copy_context_table(struct intel_iommu *iommu,
Dan Williamsdfddb9692015-10-09 18:16:46 -04003044 struct root_entry *old_re,
Joerg Roedel091d42e2015-06-12 11:56:10 +02003045 struct context_entry **tbl,
3046 int bus, bool ext)
3047{
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003048 int tbl_idx, pos = 0, idx, devfn, ret = 0, did;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003049 struct context_entry *new_ce = NULL, ce;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003050 struct context_entry *old_ce = NULL;
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003051 struct root_entry re;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003052 phys_addr_t old_ce_phys;
3053
3054 tbl_idx = ext ? bus * 2 : bus;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003055 memcpy(&re, old_re, sizeof(re));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003056
3057 for (devfn = 0; devfn < 256; devfn++) {
3058 /* First calculate the correct index */
3059 idx = (ext ? devfn * 2 : devfn) % 256;
3060
3061 if (idx == 0) {
3062 /* First save what we may have and clean up */
3063 if (new_ce) {
3064 tbl[tbl_idx] = new_ce;
3065 __iommu_flush_cache(iommu, new_ce,
3066 VTD_PAGE_SIZE);
3067 pos = 1;
3068 }
3069
3070 if (old_ce)
3071 iounmap(old_ce);
3072
3073 ret = 0;
3074 if (devfn < 0x80)
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003075 old_ce_phys = root_entry_lctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003076 else
Joerg Roedel543c8dc2015-08-13 11:56:59 +02003077 old_ce_phys = root_entry_uctp(&re);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003078
3079 if (!old_ce_phys) {
3080 if (ext && devfn == 0) {
3081 /* No LCTP, try UCTP */
3082 devfn = 0x7f;
3083 continue;
3084 } else {
3085 goto out;
3086 }
3087 }
3088
3089 ret = -ENOMEM;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003090 old_ce = memremap(old_ce_phys, PAGE_SIZE,
3091 MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003092 if (!old_ce)
3093 goto out;
3094
3095 new_ce = alloc_pgtable_page(iommu->node);
3096 if (!new_ce)
3097 goto out_unmap;
3098
3099 ret = 0;
3100 }
3101
3102 /* Now copy the context entry */
Dan Williamsdfddb9692015-10-09 18:16:46 -04003103 memcpy(&ce, old_ce + idx, sizeof(ce));
Joerg Roedel091d42e2015-06-12 11:56:10 +02003104
Joerg Roedelcf484d02015-06-12 12:21:46 +02003105 if (!__context_present(&ce))
Joerg Roedel091d42e2015-06-12 11:56:10 +02003106 continue;
3107
Joerg Roedeldbcd8612015-06-12 12:02:09 +02003108 did = context_domain_id(&ce);
3109 if (did >= 0 && did < cap_ndoms(iommu->cap))
3110 set_bit(did, iommu->domain_ids);
3111
Joerg Roedelcf484d02015-06-12 12:21:46 +02003112 /*
3113 * We need a marker for copied context entries. This
3114 * marker needs to work for the old format as well as
3115 * for extended context entries.
3116 *
3117 * Bit 67 of the context entry is used. In the old
3118 * format this bit is available to software, in the
3119 * extended format it is the PGE bit, but PGE is ignored
3120 * by HW if PASIDs are disabled (and thus still
3121 * available).
3122 *
3123 * So disable PASIDs first and then mark the entry
3124 * copied. This means that we don't copy PASID
3125 * translations from the old kernel, but this is fine as
3126 * faults there are not fatal.
3127 */
3128 context_clear_pasid_enable(&ce);
3129 context_set_copied(&ce);
3130
Joerg Roedel091d42e2015-06-12 11:56:10 +02003131 new_ce[idx] = ce;
3132 }
3133
3134 tbl[tbl_idx + pos] = new_ce;
3135
3136 __iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);
3137
3138out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003139 memunmap(old_ce);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003140
3141out:
3142 return ret;
3143}
3144
3145static int copy_translation_tables(struct intel_iommu *iommu)
3146{
3147 struct context_entry **ctxt_tbls;
Dan Williamsdfddb9692015-10-09 18:16:46 -04003148 struct root_entry *old_rt;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003149 phys_addr_t old_rt_phys;
3150 int ctxt_table_entries;
3151 unsigned long flags;
3152 u64 rtaddr_reg;
3153 int bus, ret;
Joerg Roedelc3361f22015-06-12 12:39:25 +02003154 bool new_ext, ext;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003155
3156 rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
3157 ext = !!(rtaddr_reg & DMA_RTADDR_RTT);
Joerg Roedelc3361f22015-06-12 12:39:25 +02003158 new_ext = !!ecap_ecs(iommu->ecap);
3159
3160 /*
3161 * The RTT bit can only be changed when translation is disabled,
3162 * but disabling translation means to open a window for data
3163 * corruption. So bail out and don't copy anything if we would
3164 * have to change the bit.
3165 */
3166 if (new_ext != ext)
3167 return -EINVAL;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003168
3169 old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
3170 if (!old_rt_phys)
3171 return -EINVAL;
3172
Dan Williamsdfddb9692015-10-09 18:16:46 -04003173 old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_WB);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003174 if (!old_rt)
3175 return -ENOMEM;
3176
3177 /* This is too big for the stack - allocate it from slab */
3178 ctxt_table_entries = ext ? 512 : 256;
3179 ret = -ENOMEM;
3180 ctxt_tbls = kzalloc(ctxt_table_entries * sizeof(void *), GFP_KERNEL);
3181 if (!ctxt_tbls)
3182 goto out_unmap;
3183
3184 for (bus = 0; bus < 256; bus++) {
3185 ret = copy_context_table(iommu, &old_rt[bus],
3186 ctxt_tbls, bus, ext);
3187 if (ret) {
3188 pr_err("%s: Failed to copy context table for bus %d\n",
3189 iommu->name, bus);
3190 continue;
3191 }
3192 }
3193
3194 spin_lock_irqsave(&iommu->lock, flags);
3195
3196 /* Context tables are copied, now write them to the root_entry table */
3197 for (bus = 0; bus < 256; bus++) {
3198 int idx = ext ? bus * 2 : bus;
3199 u64 val;
3200
3201 if (ctxt_tbls[idx]) {
3202 val = virt_to_phys(ctxt_tbls[idx]) | 1;
3203 iommu->root_entry[bus].lo = val;
3204 }
3205
3206 if (!ext || !ctxt_tbls[idx + 1])
3207 continue;
3208
3209 val = virt_to_phys(ctxt_tbls[idx + 1]) | 1;
3210 iommu->root_entry[bus].hi = val;
3211 }
3212
3213 spin_unlock_irqrestore(&iommu->lock, flags);
3214
3215 kfree(ctxt_tbls);
3216
3217 __iommu_flush_cache(iommu, iommu->root_entry, PAGE_SIZE);
3218
3219 ret = 0;
3220
3221out_unmap:
Dan Williamsdfddb9692015-10-09 18:16:46 -04003222 memunmap(old_rt);
Joerg Roedel091d42e2015-06-12 11:56:10 +02003223
3224 return ret;
3225}
3226
Joseph Cihulab7792602011-05-03 00:08:37 -07003227static int __init init_dmars(void)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003228{
3229 struct dmar_drhd_unit *drhd;
3230 struct dmar_rmrr_unit *rmrr;
Joerg Roedela87f4912015-06-12 12:32:54 +02003231 bool copied_tables = false;
David Woodhouse832bd852014-03-07 15:08:36 +00003232 struct device *dev;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003233 struct intel_iommu *iommu;
Joerg Roedel13cf0172017-08-11 11:40:10 +02003234 int i, ret;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003235
3236 /*
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003237 * for each drhd
3238 * allocate root
3239 * initialize and program root entry to not present
3240 * endfor
3241 */
3242 for_each_drhd_unit(drhd) {
mark gross5e0d2a62008-03-04 15:22:08 -08003243 /*
3244 * lock not needed as this is only incremented in the single
3245 * threaded kernel __init code path all other access are read
3246 * only
3247 */
Jiang Liu78d8e702014-11-09 22:47:57 +08003248 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED) {
Mike Travis1b198bb2012-03-05 15:05:16 -08003249 g_num_of_iommus++;
3250 continue;
3251 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003252 pr_err_once("Exceeded %d IOMMUs\n", DMAR_UNITS_SUPPORTED);
mark gross5e0d2a62008-03-04 15:22:08 -08003253 }
3254
Jiang Liuffebeb42014-11-09 22:48:02 +08003255 /* Preallocate enough resources for IOMMU hot-addition */
3256 if (g_num_of_iommus < DMAR_UNITS_SUPPORTED)
3257 g_num_of_iommus = DMAR_UNITS_SUPPORTED;
3258
Weidong Hand9630fe2008-12-08 11:06:32 +08003259 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
3260 GFP_KERNEL);
3261 if (!g_iommus) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003262 pr_err("Allocating global iommu array failed\n");
Weidong Hand9630fe2008-12-08 11:06:32 +08003263 ret = -ENOMEM;
3264 goto error;
3265 }
3266
Jiang Liu7c919772014-01-06 14:18:18 +08003267 for_each_active_iommu(iommu, drhd) {
Weidong Hand9630fe2008-12-08 11:06:32 +08003268 g_iommus[iommu->seq_id] = iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003269
Joerg Roedelb63d80d2015-06-12 09:14:34 +02003270 intel_iommu_init_qi(iommu);
3271
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003272 ret = iommu_init_domains(iommu);
3273 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003274 goto free_iommu;
Suresh Siddhae61d98d2008-07-10 11:16:35 -07003275
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003276 init_translation_status(iommu);
3277
Joerg Roedel091d42e2015-06-12 11:56:10 +02003278 if (translation_pre_enabled(iommu) && !is_kdump_kernel()) {
3279 iommu_disable_translation(iommu);
3280 clear_translation_pre_enabled(iommu);
3281 pr_warn("Translation was enabled for %s but we are not in kdump mode\n",
3282 iommu->name);
3283 }
Joerg Roedel4158c2e2015-06-12 10:14:02 +02003284
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003285 /*
3286 * TBD:
3287 * we could share the same root & context tables
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003288 * among all IOMMU's. Need to Split it later.
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003289 */
3290 ret = iommu_alloc_root_entry(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003291 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003292 goto free_iommu;
Joerg Roedel5f0a7f72015-06-12 09:18:53 +02003293
Joerg Roedel091d42e2015-06-12 11:56:10 +02003294 if (translation_pre_enabled(iommu)) {
3295 pr_info("Translation already enabled - trying to copy translation structures\n");
3296
3297 ret = copy_translation_tables(iommu);
3298 if (ret) {
3299 /*
3300 * We found the IOMMU with translation
3301 * enabled - but failed to copy over the
3302 * old root-entry table. Try to proceed
3303 * by disabling translation now and
3304 * allocating a clean root-entry table.
3305 * This might cause DMAR faults, but
3306 * probably the dump will still succeed.
3307 */
3308 pr_err("Failed to copy translation tables from previous kernel for %s\n",
3309 iommu->name);
3310 iommu_disable_translation(iommu);
3311 clear_translation_pre_enabled(iommu);
3312 } else {
3313 pr_info("Copied translation tables from previous kernel for %s\n",
3314 iommu->name);
Joerg Roedela87f4912015-06-12 12:32:54 +02003315 copied_tables = true;
Joerg Roedel091d42e2015-06-12 11:56:10 +02003316 }
3317 }
3318
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003319 if (!ecap_pass_through(iommu->ecap))
David Woodhouse19943b02009-08-04 16:19:20 +01003320 hw_pass_through = 0;
David Woodhouse8a94ade2015-03-24 14:54:56 +00003321#ifdef CONFIG_INTEL_IOMMU_SVM
3322 if (pasid_enabled(iommu))
3323 intel_svm_alloc_pasid_tables(iommu);
3324#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003325 }
3326
Joerg Roedela4c34ff2016-06-17 11:29:48 +02003327 /*
3328 * Now that qi is enabled on all iommus, set the root entry and flush
3329 * caches. This is required on some Intel X58 chipsets, otherwise the
3330 * flush_context function will loop forever and the boot hangs.
3331 */
3332 for_each_active_iommu(iommu, drhd) {
3333 iommu_flush_write_buffer(iommu);
3334 iommu_set_root_entry(iommu);
3335 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
3336 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
3337 }
3338
David Woodhouse19943b02009-08-04 16:19:20 +01003339 if (iommu_pass_through)
David Woodhousee0fc7e02009-09-30 09:12:17 -07003340 iommu_identity_mapping |= IDENTMAP_ALL;
3341
Suresh Siddhad3f13812011-08-23 17:05:25 -07003342#ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
David Woodhousee0fc7e02009-09-30 09:12:17 -07003343 iommu_identity_mapping |= IDENTMAP_GFX;
David Woodhouse19943b02009-08-04 16:19:20 +01003344#endif
David Woodhousee0fc7e02009-09-30 09:12:17 -07003345
Ashok Raj21e722c2017-01-30 09:39:53 -08003346 check_tylersburg_isoch();
3347
Joerg Roedel86080cc2015-06-12 12:27:16 +02003348 if (iommu_identity_mapping) {
3349 ret = si_domain_init(hw_pass_through);
3350 if (ret)
3351 goto free_iommu;
3352 }
3353
David Woodhousee0fc7e02009-09-30 09:12:17 -07003354
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003355 /*
Joerg Roedela87f4912015-06-12 12:32:54 +02003356 * If we copied translations from a previous kernel in the kdump
3357 * case, we can not assign the devices to domains now, as that
3358 * would eliminate the old mappings. So skip this part and defer
3359 * the assignment to device driver initialization time.
3360 */
3361 if (copied_tables)
3362 goto domains_done;
3363
3364 /*
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003365 * If pass through is not set or not enabled, setup context entries for
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003366 * identity mappings for rmrr, gfx, and isa and may fall back to static
3367 * identity mapping if iommu_identity_mapping is set.
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003368 */
David Woodhouse19943b02009-08-04 16:19:20 +01003369 if (iommu_identity_mapping) {
3370 ret = iommu_prepare_static_identity_mapping(hw_pass_through);
3371 if (ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003372 pr_crit("Failed to setup IOMMU pass-through\n");
Jiang Liu989d51f2014-02-19 14:07:21 +08003373 goto free_iommu;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003374 }
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07003375 }
David Woodhouse19943b02009-08-04 16:19:20 +01003376 /*
3377 * For each rmrr
3378 * for each dev attached to rmrr
3379 * do
3380 * locate drhd for dev, alloc domain for dev
3381 * allocate free domain
3382 * allocate page table entries for rmrr
3383 * if context not allocated for bus
3384 * allocate and init context
3385 * set present in root table for this bus
3386 * init context with domain, translation etc
3387 * endfor
3388 * endfor
3389 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003390 pr_info("Setting RMRR:\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003391 for_each_rmrr_units(rmrr) {
Jiang Liub683b232014-02-19 14:07:32 +08003392 /* some BIOS lists non-exist devices in DMAR table. */
3393 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
David Woodhouse832bd852014-03-07 15:08:36 +00003394 i, dev) {
David Woodhouse0b9d9752014-03-09 15:48:15 -07003395 ret = iommu_prepare_rmrr_dev(rmrr, dev);
David Woodhouse19943b02009-08-04 16:19:20 +01003396 if (ret)
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003397 pr_err("Mapping reserved region failed\n");
David Woodhouse19943b02009-08-04 16:19:20 +01003398 }
3399 }
3400
3401 iommu_prepare_isa();
Keshavamurthy, Anil S49a04292007-10-21 16:41:57 -07003402
Joerg Roedela87f4912015-06-12 12:32:54 +02003403domains_done:
3404
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003405 /*
3406 * for each drhd
3407 * enable fault log
3408 * global invalidate context cache
3409 * global invalidate iotlb
3410 * enable translation
3411 */
Jiang Liu7c919772014-01-06 14:18:18 +08003412 for_each_iommu(iommu, drhd) {
Joseph Cihula51a63e62011-03-21 11:04:24 -07003413 if (drhd->ignored) {
3414 /*
3415 * we always have to disable PMRs or DMA may fail on
3416 * this device
3417 */
3418 if (force_on)
Jiang Liu7c919772014-01-06 14:18:18 +08003419 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003420 continue;
Joseph Cihula51a63e62011-03-21 11:04:24 -07003421 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003422
3423 iommu_flush_write_buffer(iommu);
3424
David Woodhousea222a7f2015-10-07 23:35:18 +01003425#ifdef CONFIG_INTEL_IOMMU_SVM
3426 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
3427 ret = intel_svm_enable_prq(iommu);
3428 if (ret)
3429 goto free_iommu;
3430 }
3431#endif
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003432 ret = dmar_set_interrupt(iommu);
3433 if (ret)
Jiang Liu989d51f2014-02-19 14:07:21 +08003434 goto free_iommu;
Keshavamurthy, Anil S3460a6d2007-10-21 16:41:54 -07003435
Joerg Roedel8939ddf2015-06-12 14:40:01 +02003436 if (!translation_pre_enabled(iommu))
3437 iommu_enable_translation(iommu);
3438
David Woodhouseb94996c2009-09-19 15:28:12 -07003439 iommu_disable_protect_mem_regions(iommu);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003440 }
3441
3442 return 0;
Jiang Liu989d51f2014-02-19 14:07:21 +08003443
3444free_iommu:
Jiang Liuffebeb42014-11-09 22:48:02 +08003445 for_each_active_iommu(iommu, drhd) {
3446 disable_dmar_iommu(iommu);
Jiang Liua868e6b2014-01-06 14:18:20 +08003447 free_dmar_iommu(iommu);
Jiang Liuffebeb42014-11-09 22:48:02 +08003448 }
Joerg Roedel13cf0172017-08-11 11:40:10 +02003449
Weidong Hand9630fe2008-12-08 11:06:32 +08003450 kfree(g_iommus);
Joerg Roedel13cf0172017-08-11 11:40:10 +02003451
Jiang Liu989d51f2014-02-19 14:07:21 +08003452error:
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003453 return ret;
3454}
3455
David Woodhouse5a5e02a2009-07-04 09:35:44 +01003456/* This takes a number of _MM_ pages, not VTD pages */
Omer Peleg2aac6302016-04-20 11:33:57 +03003457static unsigned long intel_alloc_iova(struct device *dev,
David Woodhouse875764d2009-06-28 21:20:51 +01003458 struct dmar_domain *domain,
3459 unsigned long nrpages, uint64_t dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003460{
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003461 unsigned long iova_pfn = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003462
David Woodhouse875764d2009-06-28 21:20:51 +01003463 /* Restrict dma_mask to the width that the iommu can handle */
3464 dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
Robin Murphy8f6429c2015-07-16 19:40:12 +01003465 /* Ensure we reserve the whole size-aligned region */
3466 nrpages = __roundup_pow_of_two(nrpages);
David Woodhouse875764d2009-06-28 21:20:51 +01003467
3468 if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) {
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003469 /*
3470 * First try to allocate an io virtual address in
Yang Hongyang284901a2009-04-06 19:01:15 -07003471 * DMA_BIT_MASK(32) and if that fails then try allocating
Joe Perches36098012007-12-17 11:40:11 -08003472 * from higher range
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003473 */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003474 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003475 IOVA_PFN(DMA_BIT_MASK(32)), false);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003476 if (iova_pfn)
3477 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003478 }
Tomasz Nowicki538d5b32017-09-20 10:52:02 +02003479 iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
3480 IOVA_PFN(dma_mask), true);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003481 if (unlikely(!iova_pfn)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003482 pr_err("Allocating %ld-page iova for %s failed",
David Woodhouse207e3592014-03-09 16:12:32 -07003483 nrpages, dev_name(dev));
Omer Peleg2aac6302016-04-20 11:33:57 +03003484 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003485 }
3486
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003487 return iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003488}
3489
Peter Xub316d022017-05-22 18:28:51 +08003490static struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003491{
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003492 struct dmar_domain *domain, *tmp;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003493 struct dmar_rmrr_unit *rmrr;
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003494 struct device *i_dev;
3495 int i, ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003496
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003497 domain = find_domain(dev);
3498 if (domain)
3499 goto out;
3500
3501 domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
3502 if (!domain)
3503 goto out;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003504
Joerg Roedelb1ce5b72015-09-23 19:16:01 +02003505 /* We have a new domain - setup possible RMRRs for the device */
3506 rcu_read_lock();
3507 for_each_rmrr_units(rmrr) {
3508 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
3509 i, i_dev) {
3510 if (i_dev != dev)
3511 continue;
3512
3513 ret = domain_prepare_identity_map(dev, domain,
3514 rmrr->base_address,
3515 rmrr->end_address);
3516 if (ret)
3517 dev_err(dev, "Mapping reserved region failed\n");
3518 }
3519 }
3520 rcu_read_unlock();
3521
Joerg Roedel1c5ebba2016-08-25 13:52:51 +02003522 tmp = set_domain_for_dev(dev, domain);
3523 if (!tmp || domain != tmp) {
3524 domain_exit(domain);
3525 domain = tmp;
3526 }
3527
3528out:
3529
3530 if (!domain)
3531 pr_err("Allocating domain for %s failed\n", dev_name(dev));
3532
3533
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003534 return domain;
3535}
3536
David Woodhouseecb509e2014-03-09 16:29:55 -07003537/* Check if the dev needs to go through non-identity map and unmap process.*/
David Woodhouse73676832009-07-04 14:08:36 +01003538static int iommu_no_mapping(struct device *dev)
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003539{
3540 int found;
3541
David Woodhouse3d891942014-03-06 15:59:26 +00003542 if (iommu_dummy(dev))
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003543 return 1;
3544
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003545 if (!iommu_identity_mapping)
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003546 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003547
David Woodhouse9b226622014-03-09 14:03:28 -07003548 found = identity_mapping(dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003549 if (found) {
David Woodhouseecb509e2014-03-09 16:29:55 -07003550 if (iommu_should_identity_map(dev, 0))
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003551 return 1;
3552 else {
3553 /*
3554 * 32 bit DMA is removed from si_domain and fall back
3555 * to non-identity mapping.
3556 */
Joerg Roedele6de0f82015-07-22 16:30:36 +02003557 dmar_remove_one_dev_info(si_domain, dev);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003558 pr_info("32bit %s uses non-identity mapping\n",
3559 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003560 return 0;
3561 }
3562 } else {
3563 /*
3564 * In case of a detached 64 bit DMA device from vm, the device
3565 * is put into si_domain for identity mapping.
3566 */
David Woodhouseecb509e2014-03-09 16:29:55 -07003567 if (iommu_should_identity_map(dev, 0)) {
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003568 int ret;
Joerg Roedel28ccce02015-07-21 14:45:31 +02003569 ret = domain_add_dev_info(si_domain, dev);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003570 if (!ret) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003571 pr_info("64bit %s uses identity mapping\n",
3572 dev_name(dev));
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003573 return 1;
3574 }
3575 }
3576 }
3577
David Woodhouse1e4c64c2009-07-04 10:40:38 +01003578 return 0;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003579}
3580
David Woodhouse5040a912014-03-09 16:14:00 -07003581static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003582 size_t size, int dir, u64 dma_mask)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003583{
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003584 struct dmar_domain *domain;
Fenghua Yu5b6985c2008-10-16 18:02:32 -07003585 phys_addr_t start_paddr;
Omer Peleg2aac6302016-04-20 11:33:57 +03003586 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003587 int prot = 0;
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003588 int ret;
Weidong Han8c11e792008-12-08 15:29:22 +08003589 struct intel_iommu *iommu;
Fenghua Yu33041ec2009-08-04 15:10:59 -07003590 unsigned long paddr_pfn = paddr >> PAGE_SHIFT;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003591
3592 BUG_ON(dir == DMA_NONE);
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003593
David Woodhouse5040a912014-03-09 16:14:00 -07003594 if (iommu_no_mapping(dev))
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003595 return paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003596
David Woodhouse5040a912014-03-09 16:14:00 -07003597 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003598 if (!domain)
3599 return 0;
3600
Weidong Han8c11e792008-12-08 15:29:22 +08003601 iommu = domain_get_iommu(domain);
David Woodhouse88cb6a72009-06-28 15:03:06 +01003602 size = aligned_nrpages(paddr, size);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003603
Omer Peleg2aac6302016-04-20 11:33:57 +03003604 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size), dma_mask);
3605 if (!iova_pfn)
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003606 goto error;
3607
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003608 /*
3609 * Check if DMAR supports zero-length reads on write only
3610 * mappings..
3611 */
3612 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003613 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003614 prot |= DMA_PTE_READ;
3615 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3616 prot |= DMA_PTE_WRITE;
3617 /*
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003618 * paddr - (paddr + size) might be partial page, we should map the whole
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003619 * page. Note: if two part of one page are separately mapped, we
Ingo Molnar6865f0d2008-04-22 11:09:04 +02003620 * might have two guest_addr mapping to the same host paddr, but this
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003621 * is not a big problem
3622 */
Omer Peleg2aac6302016-04-20 11:33:57 +03003623 ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
Fenghua Yu33041ec2009-08-04 15:10:59 -07003624 mm_to_dma_pfn(paddr_pfn), size, prot);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003625 if (ret)
3626 goto error;
3627
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003628 /* it's a non-present to present mapping. Only flush if caching mode */
3629 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003630 iommu_flush_iotlb_psi(iommu, domain,
Omer Peleg2aac6302016-04-20 11:33:57 +03003631 mm_to_dma_pfn(iova_pfn),
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003632 size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003633 else
Weidong Han8c11e792008-12-08 15:29:22 +08003634 iommu_flush_write_buffer(iommu);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003635
Omer Peleg2aac6302016-04-20 11:33:57 +03003636 start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
David Woodhouse03d6a242009-06-28 15:33:46 +01003637 start_paddr += paddr & ~PAGE_MASK;
3638 return start_paddr;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003639
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003640error:
Omer Peleg2aac6302016-04-20 11:33:57 +03003641 if (iova_pfn)
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003642 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003643 pr_err("Device %s request: %zx@%llx dir %d --- failed\n",
David Woodhouse5040a912014-03-09 16:14:00 -07003644 dev_name(dev), size, (unsigned long long)paddr, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003645 return 0;
3646}
3647
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003648static dma_addr_t intel_map_page(struct device *dev, struct page *page,
3649 unsigned long offset, size_t size,
3650 enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003651 unsigned long attrs)
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003652{
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003653 return __intel_map_single(dev, page_to_phys(page) + offset, size,
David Woodhouse46333e32014-03-10 20:01:21 -07003654 dir, *dev->dma_mask);
FUJITA Tomonoribb9e6d62008-10-15 16:08:28 +09003655}
3656
Omer Peleg769530e2016-04-20 11:33:25 +03003657static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003658{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003659 struct dmar_domain *domain;
David Woodhoused794dc92009-06-28 00:27:49 +01003660 unsigned long start_pfn, last_pfn;
Omer Peleg769530e2016-04-20 11:33:25 +03003661 unsigned long nrpages;
Omer Peleg2aac6302016-04-20 11:33:57 +03003662 unsigned long iova_pfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003663 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00003664 struct page *freelist;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003665
David Woodhouse73676832009-07-04 14:08:36 +01003666 if (iommu_no_mapping(dev))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003667 return;
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07003668
David Woodhouse1525a292014-03-06 16:19:30 +00003669 domain = find_domain(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003670 BUG_ON(!domain);
3671
Weidong Han8c11e792008-12-08 15:29:22 +08003672 iommu = domain_get_iommu(domain);
3673
Omer Peleg2aac6302016-04-20 11:33:57 +03003674 iova_pfn = IOVA_PFN(dev_addr);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003675
Omer Peleg769530e2016-04-20 11:33:25 +03003676 nrpages = aligned_nrpages(dev_addr, size);
Omer Peleg2aac6302016-04-20 11:33:57 +03003677 start_pfn = mm_to_dma_pfn(iova_pfn);
Omer Peleg769530e2016-04-20 11:33:25 +03003678 last_pfn = start_pfn + nrpages - 1;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003679
David Woodhoused794dc92009-06-28 00:27:49 +01003680 pr_debug("Device %s unmapping: pfn %lx-%lx\n",
David Woodhouse207e3592014-03-09 16:12:32 -07003681 dev_name(dev), start_pfn, last_pfn);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003682
David Woodhouseea8ea462014-03-05 17:09:32 +00003683 freelist = domain_unmap(domain, start_pfn, last_pfn);
David Woodhoused794dc92009-06-28 00:27:49 +01003684
mark gross5e0d2a62008-03-04 15:22:08 -08003685 if (intel_iommu_strict) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003686 iommu_flush_iotlb_psi(iommu, domain, start_pfn,
Omer Peleg769530e2016-04-20 11:33:25 +03003687 nrpages, !freelist, 0);
mark gross5e0d2a62008-03-04 15:22:08 -08003688 /* free iova */
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003689 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
David Woodhouseea8ea462014-03-05 17:09:32 +00003690 dma_free_pagelist(freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003691 } else {
Joerg Roedel13cf0172017-08-11 11:40:10 +02003692 queue_iova(&domain->iovad, iova_pfn, nrpages,
3693 (unsigned long)freelist);
mark gross5e0d2a62008-03-04 15:22:08 -08003694 /*
3695 * queue up the release of the unmap to save the 1/6th of the
3696 * cpu used up by the iotlb flush operation...
3697 */
mark gross5e0d2a62008-03-04 15:22:08 -08003698 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003699}
3700
Jiang Liud41a4ad2014-07-11 14:19:34 +08003701static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
3702 size_t size, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003703 unsigned long attrs)
Jiang Liud41a4ad2014-07-11 14:19:34 +08003704{
Omer Peleg769530e2016-04-20 11:33:25 +03003705 intel_unmap(dev, dev_addr, size);
Jiang Liud41a4ad2014-07-11 14:19:34 +08003706}
3707
David Woodhouse5040a912014-03-09 16:14:00 -07003708static void *intel_alloc_coherent(struct device *dev, size_t size,
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003709 dma_addr_t *dma_handle, gfp_t flags,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003710 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003711{
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003712 void *vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003713
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003714 vaddr = dma_direct_alloc(dev, size, dma_handle, flags, attrs);
3715 if (iommu_no_mapping(dev) || !vaddr)
3716 return vaddr;
Alex Williamsone8bb9102009-11-04 15:59:34 -07003717
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003718 *dma_handle = __intel_map_single(dev, virt_to_phys(vaddr),
3719 PAGE_ALIGN(size), DMA_BIDIRECTIONAL,
3720 dev->coherent_dma_mask);
3721 if (!*dma_handle)
3722 goto out_free_pages;
3723 return vaddr;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003724
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003725out_free_pages:
3726 dma_direct_free(dev, size, vaddr, *dma_handle, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003727 return NULL;
3728}
3729
David Woodhouse5040a912014-03-09 16:14:00 -07003730static void intel_free_coherent(struct device *dev, size_t size, void *vaddr,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003731 dma_addr_t dma_handle, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003732{
Christoph Hellwigd657c5c2018-03-19 11:38:20 +01003733 if (!iommu_no_mapping(dev))
3734 intel_unmap(dev, dma_handle, PAGE_ALIGN(size));
3735 dma_direct_free(dev, size, vaddr, dma_handle, attrs);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003736}
3737
David Woodhouse5040a912014-03-09 16:14:00 -07003738static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
FUJITA Tomonorid7ab5c42009-01-28 21:53:18 +09003739 int nelems, enum dma_data_direction dir,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003740 unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003741{
Omer Peleg769530e2016-04-20 11:33:25 +03003742 dma_addr_t startaddr = sg_dma_address(sglist) & PAGE_MASK;
3743 unsigned long nrpages = 0;
3744 struct scatterlist *sg;
3745 int i;
3746
3747 for_each_sg(sglist, sg, nelems, i) {
3748 nrpages += aligned_nrpages(sg_dma_address(sg), sg_dma_len(sg));
3749 }
3750
3751 intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003752}
3753
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003754static int intel_nontranslate_map_sg(struct device *hddev,
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003755 struct scatterlist *sglist, int nelems, int dir)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003756{
3757 int i;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003758 struct scatterlist *sg;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003759
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003760 for_each_sg(sglist, sg, nelems, i) {
FUJITA Tomonori12d4d402007-10-23 09:32:25 +02003761 BUG_ON(!sg_page(sg));
Robin Murphy29a90b72017-09-28 15:14:01 +01003762 sg->dma_address = sg_phys(sg);
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003763 sg->dma_length = sg->length;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003764 }
3765 return nelems;
3766}
3767
David Woodhouse5040a912014-03-09 16:14:00 -07003768static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
Krzysztof Kozlowski00085f12016-08-03 13:46:00 -07003769 enum dma_data_direction dir, unsigned long attrs)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003770{
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003771 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003772 struct dmar_domain *domain;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003773 size_t size = 0;
3774 int prot = 0;
Omer Peleg2aac6302016-04-20 11:33:57 +03003775 unsigned long iova_pfn;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003776 int ret;
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003777 struct scatterlist *sg;
David Woodhouseb536d242009-06-28 14:49:31 +01003778 unsigned long start_vpfn;
Weidong Han8c11e792008-12-08 15:29:22 +08003779 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003780
3781 BUG_ON(dir == DMA_NONE);
David Woodhouse5040a912014-03-09 16:14:00 -07003782 if (iommu_no_mapping(dev))
3783 return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003784
David Woodhouse5040a912014-03-09 16:14:00 -07003785 domain = get_valid_domain_for_dev(dev);
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003786 if (!domain)
3787 return 0;
3788
Weidong Han8c11e792008-12-08 15:29:22 +08003789 iommu = domain_get_iommu(domain);
3790
David Woodhouseb536d242009-06-28 14:49:31 +01003791 for_each_sg(sglist, sg, nelems, i)
David Woodhouse88cb6a72009-06-28 15:03:06 +01003792 size += aligned_nrpages(sg->offset, sg->length);
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003793
Omer Peleg2aac6302016-04-20 11:33:57 +03003794 iova_pfn = intel_alloc_iova(dev, domain, dma_to_mm_pfn(size),
David Woodhouse5040a912014-03-09 16:14:00 -07003795 *dev->dma_mask);
Omer Peleg2aac6302016-04-20 11:33:57 +03003796 if (!iova_pfn) {
FUJITA Tomonoric03ab372007-10-21 16:42:00 -07003797 sglist->dma_length = 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003798 return 0;
3799 }
3800
3801 /*
3802 * Check if DMAR supports zero-length reads on write only
3803 * mappings..
3804 */
3805 if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
Weidong Han8c11e792008-12-08 15:29:22 +08003806 !cap_zlr(iommu->cap))
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003807 prot |= DMA_PTE_READ;
3808 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
3809 prot |= DMA_PTE_WRITE;
3810
Omer Peleg2aac6302016-04-20 11:33:57 +03003811 start_vpfn = mm_to_dma_pfn(iova_pfn);
David Woodhousee1605492009-06-29 11:17:38 +01003812
Fenghua Yuf5329592009-08-04 15:09:37 -07003813 ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot);
David Woodhousee1605492009-06-29 11:17:38 +01003814 if (unlikely(ret)) {
David Woodhousee1605492009-06-29 11:17:38 +01003815 dma_pte_free_pagetable(domain, start_vpfn,
David Dillowbc24c572017-06-28 19:42:23 -07003816 start_vpfn + size - 1,
3817 agaw_to_level(domain->agaw) + 1);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03003818 free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(size));
David Woodhousee1605492009-06-29 11:17:38 +01003819 return 0;
Keshavamurthy, Anil Sf76aec72007-10-21 16:41:58 -07003820 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003821
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003822 /* it's a non-present to present mapping. Only flush if caching mode */
3823 if (cap_caching_mode(iommu->cap))
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02003824 iommu_flush_iotlb_psi(iommu, domain, start_vpfn, size, 0, 1);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003825 else
Weidong Han8c11e792008-12-08 15:29:22 +08003826 iommu_flush_write_buffer(iommu);
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01003827
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003828 return nelems;
3829}
3830
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003831static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
3832{
3833 return !dma_addr;
3834}
3835
Arvind Yadav01e19322017-06-28 16:39:32 +05303836const struct dma_map_ops intel_dma_ops = {
Andrzej Pietrasiewiczbaa676f2012-03-27 14:28:18 +02003837 .alloc = intel_alloc_coherent,
3838 .free = intel_free_coherent,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003839 .map_sg = intel_map_sg,
3840 .unmap_sg = intel_unmap_sg,
FUJITA Tomonoriffbbef52009-01-05 23:47:26 +09003841 .map_page = intel_map_page,
3842 .unmap_page = intel_unmap_page,
FUJITA Tomonoridfb805e2009-01-28 21:53:17 +09003843 .mapping_error = intel_mapping_error,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003844#ifdef CONFIG_X86
Christoph Hellwigfec777c2018-03-19 11:38:15 +01003845 .dma_supported = dma_direct_supported,
Christoph Hellwig5860acc2017-05-22 11:38:27 +02003846#endif
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003847};
3848
3849static inline int iommu_domain_cache_init(void)
3850{
3851 int ret = 0;
3852
3853 iommu_domain_cache = kmem_cache_create("iommu_domain",
3854 sizeof(struct dmar_domain),
3855 0,
3856 SLAB_HWCACHE_ALIGN,
3857
3858 NULL);
3859 if (!iommu_domain_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003860 pr_err("Couldn't create iommu_domain cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003861 ret = -ENOMEM;
3862 }
3863
3864 return ret;
3865}
3866
3867static inline int iommu_devinfo_cache_init(void)
3868{
3869 int ret = 0;
3870
3871 iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
3872 sizeof(struct device_domain_info),
3873 0,
3874 SLAB_HWCACHE_ALIGN,
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003875 NULL);
3876 if (!iommu_devinfo_cache) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02003877 pr_err("Couldn't create devinfo cache\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003878 ret = -ENOMEM;
3879 }
3880
3881 return ret;
3882}
3883
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003884static int __init iommu_init_mempool(void)
3885{
3886 int ret;
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003887 ret = iova_cache_get();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003888 if (ret)
3889 return ret;
3890
3891 ret = iommu_domain_cache_init();
3892 if (ret)
3893 goto domain_error;
3894
3895 ret = iommu_devinfo_cache_init();
3896 if (!ret)
3897 return ret;
3898
3899 kmem_cache_destroy(iommu_domain_cache);
3900domain_error:
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003901 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003902
3903 return -ENOMEM;
3904}
3905
3906static void __init iommu_exit_mempool(void)
3907{
3908 kmem_cache_destroy(iommu_devinfo_cache);
3909 kmem_cache_destroy(iommu_domain_cache);
Sakari Ailusae1ff3d2015-07-13 14:31:28 +03003910 iova_cache_put();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003911}
3912
Dan Williams556ab452010-07-23 15:47:56 -07003913static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev)
3914{
3915 struct dmar_drhd_unit *drhd;
3916 u32 vtbar;
3917 int rc;
3918
3919 /* We know that this device on this chipset has its own IOMMU.
3920 * If we find it under a different IOMMU, then the BIOS is lying
3921 * to us. Hope that the IOMMU for this device is actually
3922 * disabled, and it needs no translation...
3923 */
3924 rc = pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(0, 0), 0xb0, &vtbar);
3925 if (rc) {
3926 /* "can't" happen */
3927 dev_info(&pdev->dev, "failed to run vt-d quirk\n");
3928 return;
3929 }
3930 vtbar &= 0xffff0000;
3931
3932 /* we know that the this iommu should be at offset 0xa000 from vtbar */
3933 drhd = dmar_find_matched_drhd_unit(pdev);
3934 if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000,
3935 TAINT_FIRMWARE_WORKAROUND,
3936 "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"))
3937 pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
3938}
3939DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu);
3940
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003941static void __init init_no_remapping_devices(void)
3942{
3943 struct dmar_drhd_unit *drhd;
David Woodhouse832bd852014-03-07 15:08:36 +00003944 struct device *dev;
Jiang Liub683b232014-02-19 14:07:32 +08003945 int i;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003946
3947 for_each_drhd_unit(drhd) {
3948 if (!drhd->include_all) {
Jiang Liub683b232014-02-19 14:07:32 +08003949 for_each_active_dev_scope(drhd->devices,
3950 drhd->devices_cnt, i, dev)
3951 break;
David Woodhouse832bd852014-03-07 15:08:36 +00003952 /* ignore DMAR unit if no devices exist */
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003953 if (i == drhd->devices_cnt)
3954 drhd->ignored = 1;
3955 }
3956 }
3957
Jiang Liu7c919772014-01-06 14:18:18 +08003958 for_each_active_drhd_unit(drhd) {
Jiang Liu7c919772014-01-06 14:18:18 +08003959 if (drhd->include_all)
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003960 continue;
3961
Jiang Liub683b232014-02-19 14:07:32 +08003962 for_each_active_dev_scope(drhd->devices,
3963 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003964 if (!dev_is_pci(dev) || !IS_GFX_DEVICE(to_pci_dev(dev)))
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003965 break;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003966 if (i < drhd->devices_cnt)
3967 continue;
3968
David Woodhousec0771df2011-10-14 20:59:46 +01003969 /* This IOMMU has *only* gfx devices. Either bypass it or
3970 set the gfx_mapped flag, as appropriate */
3971 if (dmar_map_gfx) {
3972 intel_iommu_gfx_mapped = 1;
3973 } else {
3974 drhd->ignored = 1;
Jiang Liub683b232014-02-19 14:07:32 +08003975 for_each_active_dev_scope(drhd->devices,
3976 drhd->devices_cnt, i, dev)
David Woodhouse832bd852014-03-07 15:08:36 +00003977 dev->archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07003978 }
3979 }
3980}
3981
Fenghua Yuf59c7b62009-03-27 14:22:42 -07003982#ifdef CONFIG_SUSPEND
3983static int init_iommu_hw(void)
3984{
3985 struct dmar_drhd_unit *drhd;
3986 struct intel_iommu *iommu = NULL;
3987
3988 for_each_active_iommu(iommu, drhd)
3989 if (iommu->qi)
3990 dmar_reenable_qi(iommu);
3991
Joseph Cihulab7792602011-05-03 00:08:37 -07003992 for_each_iommu(iommu, drhd) {
3993 if (drhd->ignored) {
3994 /*
3995 * we always have to disable PMRs or DMA may fail on
3996 * this device
3997 */
3998 if (force_on)
3999 iommu_disable_protect_mem_regions(iommu);
4000 continue;
4001 }
4002
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004003 iommu_flush_write_buffer(iommu);
4004
4005 iommu_set_root_entry(iommu);
4006
4007 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004008 DMA_CCMD_GLOBAL_INVL);
Jiang Liu2a41cce2014-07-11 14:19:33 +08004009 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4010 iommu_enable_translation(iommu);
David Woodhouseb94996c2009-09-19 15:28:12 -07004011 iommu_disable_protect_mem_regions(iommu);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004012 }
4013
4014 return 0;
4015}
4016
4017static void iommu_flush_all(void)
4018{
4019 struct dmar_drhd_unit *drhd;
4020 struct intel_iommu *iommu;
4021
4022 for_each_active_iommu(iommu, drhd) {
4023 iommu->flush.flush_context(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004024 DMA_CCMD_GLOBAL_INVL);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004025 iommu->flush.flush_iotlb(iommu, 0, 0, 0,
David Woodhouse1f0ef2a2009-05-10 19:58:49 +01004026 DMA_TLB_GLOBAL_FLUSH);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004027 }
4028}
4029
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004030static int iommu_suspend(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004031{
4032 struct dmar_drhd_unit *drhd;
4033 struct intel_iommu *iommu = NULL;
4034 unsigned long flag;
4035
4036 for_each_active_iommu(iommu, drhd) {
4037 iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
4038 GFP_ATOMIC);
4039 if (!iommu->iommu_state)
4040 goto nomem;
4041 }
4042
4043 iommu_flush_all();
4044
4045 for_each_active_iommu(iommu, drhd) {
4046 iommu_disable_translation(iommu);
4047
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004048 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004049
4050 iommu->iommu_state[SR_DMAR_FECTL_REG] =
4051 readl(iommu->reg + DMAR_FECTL_REG);
4052 iommu->iommu_state[SR_DMAR_FEDATA_REG] =
4053 readl(iommu->reg + DMAR_FEDATA_REG);
4054 iommu->iommu_state[SR_DMAR_FEADDR_REG] =
4055 readl(iommu->reg + DMAR_FEADDR_REG);
4056 iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
4057 readl(iommu->reg + DMAR_FEUADDR_REG);
4058
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004059 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004060 }
4061 return 0;
4062
4063nomem:
4064 for_each_active_iommu(iommu, drhd)
4065 kfree(iommu->iommu_state);
4066
4067 return -ENOMEM;
4068}
4069
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004070static void iommu_resume(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004071{
4072 struct dmar_drhd_unit *drhd;
4073 struct intel_iommu *iommu = NULL;
4074 unsigned long flag;
4075
4076 if (init_iommu_hw()) {
Joseph Cihulab7792602011-05-03 00:08:37 -07004077 if (force_on)
4078 panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
4079 else
4080 WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004081 return;
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004082 }
4083
4084 for_each_active_iommu(iommu, drhd) {
4085
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004086 raw_spin_lock_irqsave(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004087
4088 writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
4089 iommu->reg + DMAR_FECTL_REG);
4090 writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
4091 iommu->reg + DMAR_FEDATA_REG);
4092 writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
4093 iommu->reg + DMAR_FEADDR_REG);
4094 writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
4095 iommu->reg + DMAR_FEUADDR_REG);
4096
Thomas Gleixner1f5b3c32011-07-19 16:19:51 +02004097 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004098 }
4099
4100 for_each_active_iommu(iommu, drhd)
4101 kfree(iommu->iommu_state);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004102}
4103
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004104static struct syscore_ops iommu_syscore_ops = {
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004105 .resume = iommu_resume,
4106 .suspend = iommu_suspend,
4107};
4108
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004109static void __init init_iommu_pm_ops(void)
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004110{
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004111 register_syscore_ops(&iommu_syscore_ops);
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004112}
4113
4114#else
Rafael J. Wysocki99592ba2011-06-07 21:32:31 +02004115static inline void init_iommu_pm_ops(void) {}
Fenghua Yuf59c7b62009-03-27 14:22:42 -07004116#endif /* CONFIG_PM */
4117
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004118
Jiang Liuc2a0b532014-11-09 22:47:56 +08004119int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004120{
4121 struct acpi_dmar_reserved_memory *rmrr;
Eric Auger0659b8d2017-01-19 20:57:53 +00004122 int prot = DMA_PTE_READ|DMA_PTE_WRITE;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004123 struct dmar_rmrr_unit *rmrru;
Eric Auger0659b8d2017-01-19 20:57:53 +00004124 size_t length;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004125
4126 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
4127 if (!rmrru)
Eric Auger0659b8d2017-01-19 20:57:53 +00004128 goto out;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004129
4130 rmrru->hdr = header;
4131 rmrr = (struct acpi_dmar_reserved_memory *)header;
4132 rmrru->base_address = rmrr->base_address;
4133 rmrru->end_address = rmrr->end_address;
Eric Auger0659b8d2017-01-19 20:57:53 +00004134
4135 length = rmrr->end_address - rmrr->base_address + 1;
4136 rmrru->resv = iommu_alloc_resv_region(rmrr->base_address, length, prot,
4137 IOMMU_RESV_DIRECT);
4138 if (!rmrru->resv)
4139 goto free_rmrru;
4140
Jiang Liu2e455282014-02-19 14:07:36 +08004141 rmrru->devices = dmar_alloc_dev_scope((void *)(rmrr + 1),
4142 ((void *)rmrr) + rmrr->header.length,
4143 &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004144 if (rmrru->devices_cnt && rmrru->devices == NULL)
4145 goto free_all;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004146
Jiang Liu2e455282014-02-19 14:07:36 +08004147 list_add(&rmrru->list, &dmar_rmrr_units);
4148
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004149 return 0;
Eric Auger0659b8d2017-01-19 20:57:53 +00004150free_all:
4151 kfree(rmrru->resv);
4152free_rmrru:
4153 kfree(rmrru);
4154out:
4155 return -ENOMEM;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004156}
4157
Jiang Liu6b197242014-11-09 22:47:58 +08004158static struct dmar_atsr_unit *dmar_find_atsr(struct acpi_dmar_atsr *atsr)
4159{
4160 struct dmar_atsr_unit *atsru;
4161 struct acpi_dmar_atsr *tmp;
4162
4163 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4164 tmp = (struct acpi_dmar_atsr *)atsru->hdr;
4165 if (atsr->segment != tmp->segment)
4166 continue;
4167 if (atsr->header.length != tmp->header.length)
4168 continue;
4169 if (memcmp(atsr, tmp, atsr->header.length) == 0)
4170 return atsru;
4171 }
4172
4173 return NULL;
4174}
4175
4176int dmar_parse_one_atsr(struct acpi_dmar_header *hdr, void *arg)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004177{
4178 struct acpi_dmar_atsr *atsr;
4179 struct dmar_atsr_unit *atsru;
4180
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004181 if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled)
Jiang Liu6b197242014-11-09 22:47:58 +08004182 return 0;
4183
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004184 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
Jiang Liu6b197242014-11-09 22:47:58 +08004185 atsru = dmar_find_atsr(atsr);
4186 if (atsru)
4187 return 0;
4188
4189 atsru = kzalloc(sizeof(*atsru) + hdr->length, GFP_KERNEL);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004190 if (!atsru)
4191 return -ENOMEM;
4192
Jiang Liu6b197242014-11-09 22:47:58 +08004193 /*
4194 * If memory is allocated from slab by ACPI _DSM method, we need to
4195 * copy the memory content because the memory buffer will be freed
4196 * on return.
4197 */
4198 atsru->hdr = (void *)(atsru + 1);
4199 memcpy(atsru->hdr, hdr, hdr->length);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004200 atsru->include_all = atsr->flags & 0x1;
Jiang Liu2e455282014-02-19 14:07:36 +08004201 if (!atsru->include_all) {
4202 atsru->devices = dmar_alloc_dev_scope((void *)(atsr + 1),
4203 (void *)atsr + atsr->header.length,
4204 &atsru->devices_cnt);
4205 if (atsru->devices_cnt && atsru->devices == NULL) {
4206 kfree(atsru);
4207 return -ENOMEM;
4208 }
4209 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004210
Jiang Liu0e242612014-02-19 14:07:34 +08004211 list_add_rcu(&atsru->list, &dmar_atsr_units);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004212
4213 return 0;
4214}
4215
Jiang Liu9bdc5312014-01-06 14:18:27 +08004216static void intel_iommu_free_atsr(struct dmar_atsr_unit *atsru)
4217{
4218 dmar_free_dev_scope(&atsru->devices, &atsru->devices_cnt);
4219 kfree(atsru);
4220}
4221
Jiang Liu6b197242014-11-09 22:47:58 +08004222int dmar_release_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4223{
4224 struct acpi_dmar_atsr *atsr;
4225 struct dmar_atsr_unit *atsru;
4226
4227 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4228 atsru = dmar_find_atsr(atsr);
4229 if (atsru) {
4230 list_del_rcu(&atsru->list);
4231 synchronize_rcu();
4232 intel_iommu_free_atsr(atsru);
4233 }
4234
4235 return 0;
4236}
4237
4238int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg)
4239{
4240 int i;
4241 struct device *dev;
4242 struct acpi_dmar_atsr *atsr;
4243 struct dmar_atsr_unit *atsru;
4244
4245 atsr = container_of(hdr, struct acpi_dmar_atsr, header);
4246 atsru = dmar_find_atsr(atsr);
4247 if (!atsru)
4248 return 0;
4249
Linus Torvalds194dc872016-07-27 20:03:31 -07004250 if (!atsru->include_all && atsru->devices && atsru->devices_cnt) {
Jiang Liu6b197242014-11-09 22:47:58 +08004251 for_each_active_dev_scope(atsru->devices, atsru->devices_cnt,
4252 i, dev)
4253 return -EBUSY;
Linus Torvalds194dc872016-07-27 20:03:31 -07004254 }
Jiang Liu6b197242014-11-09 22:47:58 +08004255
4256 return 0;
4257}
4258
Jiang Liuffebeb42014-11-09 22:48:02 +08004259static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
4260{
4261 int sp, ret = 0;
4262 struct intel_iommu *iommu = dmaru->iommu;
4263
4264 if (g_iommus[iommu->seq_id])
4265 return 0;
4266
4267 if (hw_pass_through && !ecap_pass_through(iommu->ecap)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004268 pr_warn("%s: Doesn't support hardware pass through.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004269 iommu->name);
4270 return -ENXIO;
4271 }
4272 if (!ecap_sc_support(iommu->ecap) &&
4273 domain_update_iommu_snooping(iommu)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004274 pr_warn("%s: Doesn't support snooping.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004275 iommu->name);
4276 return -ENXIO;
4277 }
4278 sp = domain_update_iommu_superpage(iommu) - 1;
4279 if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004280 pr_warn("%s: Doesn't support large page.\n",
Jiang Liuffebeb42014-11-09 22:48:02 +08004281 iommu->name);
4282 return -ENXIO;
4283 }
4284
4285 /*
4286 * Disable translation if already enabled prior to OS handover.
4287 */
4288 if (iommu->gcmd & DMA_GCMD_TE)
4289 iommu_disable_translation(iommu);
4290
4291 g_iommus[iommu->seq_id] = iommu;
4292 ret = iommu_init_domains(iommu);
4293 if (ret == 0)
4294 ret = iommu_alloc_root_entry(iommu);
4295 if (ret)
4296 goto out;
4297
David Woodhouse8a94ade2015-03-24 14:54:56 +00004298#ifdef CONFIG_INTEL_IOMMU_SVM
4299 if (pasid_enabled(iommu))
4300 intel_svm_alloc_pasid_tables(iommu);
4301#endif
4302
Jiang Liuffebeb42014-11-09 22:48:02 +08004303 if (dmaru->ignored) {
4304 /*
4305 * we always have to disable PMRs or DMA may fail on this device
4306 */
4307 if (force_on)
4308 iommu_disable_protect_mem_regions(iommu);
4309 return 0;
4310 }
4311
4312 intel_iommu_init_qi(iommu);
4313 iommu_flush_write_buffer(iommu);
David Woodhousea222a7f2015-10-07 23:35:18 +01004314
4315#ifdef CONFIG_INTEL_IOMMU_SVM
4316 if (pasid_enabled(iommu) && ecap_prs(iommu->ecap)) {
4317 ret = intel_svm_enable_prq(iommu);
4318 if (ret)
4319 goto disable_iommu;
4320 }
4321#endif
Jiang Liuffebeb42014-11-09 22:48:02 +08004322 ret = dmar_set_interrupt(iommu);
4323 if (ret)
4324 goto disable_iommu;
4325
4326 iommu_set_root_entry(iommu);
4327 iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
4328 iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
4329 iommu_enable_translation(iommu);
4330
Jiang Liuffebeb42014-11-09 22:48:02 +08004331 iommu_disable_protect_mem_regions(iommu);
4332 return 0;
4333
4334disable_iommu:
4335 disable_dmar_iommu(iommu);
4336out:
4337 free_dmar_iommu(iommu);
4338 return ret;
4339}
4340
Jiang Liu6b197242014-11-09 22:47:58 +08004341int dmar_iommu_hotplug(struct dmar_drhd_unit *dmaru, bool insert)
4342{
Jiang Liuffebeb42014-11-09 22:48:02 +08004343 int ret = 0;
4344 struct intel_iommu *iommu = dmaru->iommu;
4345
4346 if (!intel_iommu_enabled)
4347 return 0;
4348 if (iommu == NULL)
4349 return -EINVAL;
4350
4351 if (insert) {
4352 ret = intel_iommu_add(dmaru);
4353 } else {
4354 disable_dmar_iommu(iommu);
4355 free_dmar_iommu(iommu);
4356 }
4357
4358 return ret;
Jiang Liu6b197242014-11-09 22:47:58 +08004359}
4360
Jiang Liu9bdc5312014-01-06 14:18:27 +08004361static void intel_iommu_free_dmars(void)
4362{
4363 struct dmar_rmrr_unit *rmrru, *rmrr_n;
4364 struct dmar_atsr_unit *atsru, *atsr_n;
4365
4366 list_for_each_entry_safe(rmrru, rmrr_n, &dmar_rmrr_units, list) {
4367 list_del(&rmrru->list);
4368 dmar_free_dev_scope(&rmrru->devices, &rmrru->devices_cnt);
Eric Auger0659b8d2017-01-19 20:57:53 +00004369 kfree(rmrru->resv);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004370 kfree(rmrru);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004371 }
4372
Jiang Liu9bdc5312014-01-06 14:18:27 +08004373 list_for_each_entry_safe(atsru, atsr_n, &dmar_atsr_units, list) {
4374 list_del(&atsru->list);
4375 intel_iommu_free_atsr(atsru);
4376 }
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004377}
4378
4379int dmar_find_matched_atsr_unit(struct pci_dev *dev)
4380{
Jiang Liub683b232014-02-19 14:07:32 +08004381 int i, ret = 1;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004382 struct pci_bus *bus;
David Woodhouse832bd852014-03-07 15:08:36 +00004383 struct pci_dev *bridge = NULL;
4384 struct device *tmp;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004385 struct acpi_dmar_atsr *atsr;
4386 struct dmar_atsr_unit *atsru;
4387
4388 dev = pci_physfn(dev);
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004389 for (bus = dev->bus; bus; bus = bus->parent) {
Jiang Liub5f82dd2014-02-19 14:07:31 +08004390 bridge = bus->self;
David Woodhoused14053b32015-10-15 09:28:06 +01004391 /* If it's an integrated device, allow ATS */
4392 if (!bridge)
4393 return 1;
4394 /* Connected via non-PCIe: no ATS */
4395 if (!pci_is_pcie(bridge) ||
Yijing Wang62f87c02012-07-24 17:20:03 +08004396 pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004397 return 0;
David Woodhoused14053b32015-10-15 09:28:06 +01004398 /* If we found the root port, look it up in the ATSR */
Jiang Liub5f82dd2014-02-19 14:07:31 +08004399 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT)
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004400 break;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004401 }
4402
Jiang Liu0e242612014-02-19 14:07:34 +08004403 rcu_read_lock();
Jiang Liub5f82dd2014-02-19 14:07:31 +08004404 list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) {
4405 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4406 if (atsr->segment != pci_domain_nr(dev->bus))
4407 continue;
4408
Jiang Liub683b232014-02-19 14:07:32 +08004409 for_each_dev_scope(atsru->devices, atsru->devices_cnt, i, tmp)
David Woodhouse832bd852014-03-07 15:08:36 +00004410 if (tmp == &bridge->dev)
Jiang Liub683b232014-02-19 14:07:32 +08004411 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004412
4413 if (atsru->include_all)
Jiang Liub683b232014-02-19 14:07:32 +08004414 goto out;
Jiang Liub5f82dd2014-02-19 14:07:31 +08004415 }
Jiang Liub683b232014-02-19 14:07:32 +08004416 ret = 0;
4417out:
Jiang Liu0e242612014-02-19 14:07:34 +08004418 rcu_read_unlock();
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004419
Jiang Liub683b232014-02-19 14:07:32 +08004420 return ret;
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004421}
4422
Jiang Liu59ce0512014-02-19 14:07:35 +08004423int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
4424{
4425 int ret = 0;
4426 struct dmar_rmrr_unit *rmrru;
4427 struct dmar_atsr_unit *atsru;
4428 struct acpi_dmar_atsr *atsr;
4429 struct acpi_dmar_reserved_memory *rmrr;
4430
Thomas Gleixnerb608fe32017-05-16 20:42:41 +02004431 if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING)
Jiang Liu59ce0512014-02-19 14:07:35 +08004432 return 0;
4433
4434 list_for_each_entry(rmrru, &dmar_rmrr_units, list) {
4435 rmrr = container_of(rmrru->hdr,
4436 struct acpi_dmar_reserved_memory, header);
4437 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4438 ret = dmar_insert_dev_scope(info, (void *)(rmrr + 1),
4439 ((void *)rmrr) + rmrr->header.length,
4440 rmrr->segment, rmrru->devices,
4441 rmrru->devices_cnt);
Jiang Liu27e24952014-06-20 15:08:06 +08004442 if(ret < 0)
Jiang Liu59ce0512014-02-19 14:07:35 +08004443 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004444 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu27e24952014-06-20 15:08:06 +08004445 dmar_remove_dev_scope(info, rmrr->segment,
4446 rmrru->devices, rmrru->devices_cnt);
Jiang Liu59ce0512014-02-19 14:07:35 +08004447 }
4448 }
4449
4450 list_for_each_entry(atsru, &dmar_atsr_units, list) {
4451 if (atsru->include_all)
4452 continue;
4453
4454 atsr = container_of(atsru->hdr, struct acpi_dmar_atsr, header);
4455 if (info->event == BUS_NOTIFY_ADD_DEVICE) {
4456 ret = dmar_insert_dev_scope(info, (void *)(atsr + 1),
4457 (void *)atsr + atsr->header.length,
4458 atsr->segment, atsru->devices,
4459 atsru->devices_cnt);
4460 if (ret > 0)
4461 break;
4462 else if(ret < 0)
4463 return ret;
Joerg Roedele6a8c9b2016-02-29 23:49:47 +01004464 } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
Jiang Liu59ce0512014-02-19 14:07:35 +08004465 if (dmar_remove_dev_scope(info, atsr->segment,
4466 atsru->devices, atsru->devices_cnt))
4467 break;
4468 }
4469 }
4470
4471 return 0;
4472}
4473
Fenghua Yu99dcade2009-11-11 07:23:06 -08004474/*
4475 * Here we only respond to action of unbound device from driver.
4476 *
4477 * Added device is not attached to its DMAR domain here yet. That will happen
4478 * when mapping the device to iova.
4479 */
4480static int device_notifier(struct notifier_block *nb,
4481 unsigned long action, void *data)
4482{
4483 struct device *dev = data;
Fenghua Yu99dcade2009-11-11 07:23:06 -08004484 struct dmar_domain *domain;
4485
David Woodhouse3d891942014-03-06 15:59:26 +00004486 if (iommu_dummy(dev))
David Woodhouse44cd6132009-12-02 10:18:30 +00004487 return 0;
4488
Joerg Roedel1196c2f2014-09-30 13:02:03 +02004489 if (action != BUS_NOTIFY_REMOVED_DEVICE)
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004490 return 0;
4491
David Woodhouse1525a292014-03-06 16:19:30 +00004492 domain = find_domain(dev);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004493 if (!domain)
4494 return 0;
4495
Joerg Roedele6de0f82015-07-22 16:30:36 +02004496 dmar_remove_one_dev_info(domain, dev);
Jiang Liuab8dfe22014-07-11 14:19:27 +08004497 if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
Jiang Liu7e7dfab2014-02-19 14:07:23 +08004498 domain_exit(domain);
Alex Williamsona97590e2011-03-04 14:52:16 -07004499
Fenghua Yu99dcade2009-11-11 07:23:06 -08004500 return 0;
4501}
4502
4503static struct notifier_block device_nb = {
4504 .notifier_call = device_notifier,
4505};
4506
Jiang Liu75f05562014-02-19 14:07:37 +08004507static int intel_iommu_memory_notifier(struct notifier_block *nb,
4508 unsigned long val, void *v)
4509{
4510 struct memory_notify *mhp = v;
4511 unsigned long long start, end;
4512 unsigned long start_vpfn, last_vpfn;
4513
4514 switch (val) {
4515 case MEM_GOING_ONLINE:
4516 start = mhp->start_pfn << PAGE_SHIFT;
4517 end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1;
4518 if (iommu_domain_identity_map(si_domain, start, end)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004519 pr_warn("Failed to build identity map for [%llx-%llx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004520 start, end);
4521 return NOTIFY_BAD;
4522 }
4523 break;
4524
4525 case MEM_OFFLINE:
4526 case MEM_CANCEL_ONLINE:
4527 start_vpfn = mm_to_dma_pfn(mhp->start_pfn);
4528 last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1);
4529 while (start_vpfn <= last_vpfn) {
4530 struct iova *iova;
4531 struct dmar_drhd_unit *drhd;
4532 struct intel_iommu *iommu;
David Woodhouseea8ea462014-03-05 17:09:32 +00004533 struct page *freelist;
Jiang Liu75f05562014-02-19 14:07:37 +08004534
4535 iova = find_iova(&si_domain->iovad, start_vpfn);
4536 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004537 pr_debug("Failed get IOVA for PFN %lx\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004538 start_vpfn);
4539 break;
4540 }
4541
4542 iova = split_and_remove_iova(&si_domain->iovad, iova,
4543 start_vpfn, last_vpfn);
4544 if (iova == NULL) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004545 pr_warn("Failed to split IOVA PFN [%lx-%lx]\n",
Jiang Liu75f05562014-02-19 14:07:37 +08004546 start_vpfn, last_vpfn);
4547 return NOTIFY_BAD;
4548 }
4549
David Woodhouseea8ea462014-03-05 17:09:32 +00004550 freelist = domain_unmap(si_domain, iova->pfn_lo,
4551 iova->pfn_hi);
4552
Jiang Liu75f05562014-02-19 14:07:37 +08004553 rcu_read_lock();
4554 for_each_active_iommu(iommu, drhd)
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02004555 iommu_flush_iotlb_psi(iommu, si_domain,
Jiang Liua156ef92014-07-11 14:19:36 +08004556 iova->pfn_lo, iova_size(iova),
David Woodhouseea8ea462014-03-05 17:09:32 +00004557 !freelist, 0);
Jiang Liu75f05562014-02-19 14:07:37 +08004558 rcu_read_unlock();
David Woodhouseea8ea462014-03-05 17:09:32 +00004559 dma_free_pagelist(freelist);
Jiang Liu75f05562014-02-19 14:07:37 +08004560
4561 start_vpfn = iova->pfn_hi + 1;
4562 free_iova_mem(iova);
4563 }
4564 break;
4565 }
4566
4567 return NOTIFY_OK;
4568}
4569
4570static struct notifier_block intel_iommu_memory_nb = {
4571 .notifier_call = intel_iommu_memory_notifier,
4572 .priority = 0
4573};
4574
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004575static void free_all_cpu_cached_iovas(unsigned int cpu)
4576{
4577 int i;
4578
4579 for (i = 0; i < g_num_of_iommus; i++) {
4580 struct intel_iommu *iommu = g_iommus[i];
4581 struct dmar_domain *domain;
Aaron Campbell0caa7612016-07-02 21:23:24 -03004582 int did;
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004583
4584 if (!iommu)
4585 continue;
4586
Jan Niehusmann3bd4f912016-06-06 14:20:11 +02004587 for (did = 0; did < cap_ndoms(iommu->cap); did++) {
Aaron Campbell0caa7612016-07-02 21:23:24 -03004588 domain = get_iommu_domain(iommu, (u16)did);
Omer Peleg22e2f9f2016-04-20 11:34:11 +03004589
4590 if (!domain)
4591 continue;
4592 free_cpu_cached_iovas(cpu, &domain->iovad);
4593 }
4594 }
4595}
4596
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004597static int intel_iommu_cpu_dead(unsigned int cpu)
Omer Pelegaa473242016-04-20 11:33:02 +03004598{
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004599 free_all_cpu_cached_iovas(cpu);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004600 return 0;
Omer Pelegaa473242016-04-20 11:33:02 +03004601}
4602
Joerg Roedel161b28a2017-03-28 17:04:52 +02004603static void intel_disable_iommus(void)
4604{
4605 struct intel_iommu *iommu = NULL;
4606 struct dmar_drhd_unit *drhd;
4607
4608 for_each_iommu(iommu, drhd)
4609 iommu_disable_translation(iommu);
4610}
4611
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004612static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev)
4613{
Joerg Roedel2926a2aa2017-08-14 17:19:26 +02004614 struct iommu_device *iommu_dev = dev_to_iommu_device(dev);
4615
4616 return container_of(iommu_dev, struct intel_iommu, iommu);
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004617}
4618
Alex Williamsona5459cf2014-06-12 16:12:31 -06004619static ssize_t intel_iommu_show_version(struct device *dev,
4620 struct device_attribute *attr,
4621 char *buf)
4622{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004623 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004624 u32 ver = readl(iommu->reg + DMAR_VER_REG);
4625 return sprintf(buf, "%d:%d\n",
4626 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver));
4627}
4628static DEVICE_ATTR(version, S_IRUGO, intel_iommu_show_version, NULL);
4629
4630static ssize_t intel_iommu_show_address(struct device *dev,
4631 struct device_attribute *attr,
4632 char *buf)
4633{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004634 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004635 return sprintf(buf, "%llx\n", iommu->reg_phys);
4636}
4637static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL);
4638
4639static ssize_t intel_iommu_show_cap(struct device *dev,
4640 struct device_attribute *attr,
4641 char *buf)
4642{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004643 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004644 return sprintf(buf, "%llx\n", iommu->cap);
4645}
4646static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL);
4647
4648static ssize_t intel_iommu_show_ecap(struct device *dev,
4649 struct device_attribute *attr,
4650 char *buf)
4651{
Joerg Roedela7fdb6e2017-02-28 13:57:18 +01004652 struct intel_iommu *iommu = dev_to_intel_iommu(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06004653 return sprintf(buf, "%llx\n", iommu->ecap);
4654}
4655static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL);
4656
Alex Williamson2238c082015-07-14 15:24:53 -06004657static ssize_t intel_iommu_show_ndoms(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 Williamson2238c082015-07-14 15:24:53 -06004662 return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap));
4663}
4664static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL);
4665
4666static ssize_t intel_iommu_show_ndoms_used(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 Williamson2238c082015-07-14 15:24:53 -06004671 return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids,
4672 cap_ndoms(iommu->cap)));
4673}
4674static DEVICE_ATTR(domains_used, S_IRUGO, intel_iommu_show_ndoms_used, NULL);
4675
Alex Williamsona5459cf2014-06-12 16:12:31 -06004676static struct attribute *intel_iommu_attrs[] = {
4677 &dev_attr_version.attr,
4678 &dev_attr_address.attr,
4679 &dev_attr_cap.attr,
4680 &dev_attr_ecap.attr,
Alex Williamson2238c082015-07-14 15:24:53 -06004681 &dev_attr_domains_supported.attr,
4682 &dev_attr_domains_used.attr,
Alex Williamsona5459cf2014-06-12 16:12:31 -06004683 NULL,
4684};
4685
4686static struct attribute_group intel_iommu_group = {
4687 .name = "intel-iommu",
4688 .attrs = intel_iommu_attrs,
4689};
4690
4691const struct attribute_group *intel_iommu_groups[] = {
4692 &intel_iommu_group,
4693 NULL,
4694};
4695
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004696int __init intel_iommu_init(void)
4697{
Jiang Liu9bdc5312014-01-06 14:18:27 +08004698 int ret = -ENODEV;
Takao Indoh3a93c842013-04-23 17:35:03 +09004699 struct dmar_drhd_unit *drhd;
Jiang Liu7c919772014-01-06 14:18:18 +08004700 struct intel_iommu *iommu;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004701
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004702 /* VT-d is required for a TXT/tboot launch, so enforce that */
4703 force_on = tboot_force_iommu();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004704
Jiang Liu3a5670e2014-02-19 14:07:33 +08004705 if (iommu_init_mempool()) {
4706 if (force_on)
4707 panic("tboot: Failed to initialize iommu memory\n");
4708 return -ENOMEM;
4709 }
4710
4711 down_write(&dmar_global_lock);
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004712 if (dmar_table_init()) {
4713 if (force_on)
4714 panic("tboot: Failed to initialize DMAR table\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004715 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004716 }
4717
Suresh Siddhac2c72862011-08-23 17:05:19 -07004718 if (dmar_dev_scope_init() < 0) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004719 if (force_on)
4720 panic("tboot: Failed to initialize DMAR device scope\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004721 goto out_free_dmar;
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004722 }
Suresh Siddha1886e8a2008-07-10 11:16:37 -07004723
Joerg Roedelec154bf2017-10-06 15:00:53 +02004724 up_write(&dmar_global_lock);
4725
4726 /*
4727 * The bus notifier takes the dmar_global_lock, so lockdep will
4728 * complain later when we register it under the lock.
4729 */
4730 dmar_register_bus_notifier();
4731
4732 down_write(&dmar_global_lock);
4733
Joerg Roedel161b28a2017-03-28 17:04:52 +02004734 if (no_iommu || dmar_disabled) {
4735 /*
Shaohua Libfd20f12017-04-26 09:18:35 -07004736 * We exit the function here to ensure IOMMU's remapping and
4737 * mempool aren't setup, which means that the IOMMU's PMRs
4738 * won't be disabled via the call to init_dmars(). So disable
4739 * it explicitly here. The PMRs were setup by tboot prior to
4740 * calling SENTER, but the kernel is expected to reset/tear
4741 * down the PMRs.
4742 */
4743 if (intel_iommu_tboot_noforce) {
4744 for_each_iommu(iommu, drhd)
4745 iommu_disable_protect_mem_regions(iommu);
4746 }
4747
4748 /*
Joerg Roedel161b28a2017-03-28 17:04:52 +02004749 * Make sure the IOMMUs are switched off, even when we
4750 * boot into a kexec kernel and the previous kernel left
4751 * them enabled
4752 */
4753 intel_disable_iommus();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004754 goto out_free_dmar;
Joerg Roedel161b28a2017-03-28 17:04:52 +02004755 }
Suresh Siddha2ae21012008-07-10 11:16:43 -07004756
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004757 if (list_empty(&dmar_rmrr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004758 pr_info("No RMRR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004759
4760 if (list_empty(&dmar_atsr_units))
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004761 pr_info("No ATSR found\n");
Suresh Siddha318fe7d2011-08-23 17:05:20 -07004762
Joseph Cihula51a63e62011-03-21 11:04:24 -07004763 if (dmar_init_reserved_ranges()) {
4764 if (force_on)
4765 panic("tboot: Failed to reserve iommu ranges\n");
Jiang Liu3a5670e2014-02-19 14:07:33 +08004766 goto out_free_reserved_range;
Joseph Cihula51a63e62011-03-21 11:04:24 -07004767 }
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004768
4769 init_no_remapping_devices();
4770
Joseph Cihulab7792602011-05-03 00:08:37 -07004771 ret = init_dmars();
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004772 if (ret) {
Joseph Cihulaa59b50e2009-06-30 19:31:10 -07004773 if (force_on)
4774 panic("tboot: Failed to initialize DMARs\n");
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004775 pr_err("Initialization failed\n");
Jiang Liu9bdc5312014-01-06 14:18:27 +08004776 goto out_free_reserved_range;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004777 }
Jiang Liu3a5670e2014-02-19 14:07:33 +08004778 up_write(&dmar_global_lock);
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004779 pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004780
Christoph Hellwig4fac8072017-12-24 13:57:08 +01004781#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
FUJITA Tomonori75f1cdf2009-11-10 19:46:20 +09004782 swiotlb = 0;
4783#endif
David Woodhouse19943b02009-08-04 16:19:20 +01004784 dma_ops = &intel_dma_ops;
Fenghua Yu4ed0d3e2009-04-24 17:30:20 -07004785
Rafael J. Wysocki134fac32011-03-23 22:16:14 +01004786 init_iommu_pm_ops();
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01004787
Joerg Roedel39ab9552017-02-01 16:56:46 +01004788 for_each_active_iommu(iommu, drhd) {
4789 iommu_device_sysfs_add(&iommu->iommu, NULL,
4790 intel_iommu_groups,
4791 "%s", iommu->name);
4792 iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops);
4793 iommu_device_register(&iommu->iommu);
4794 }
Alex Williamsona5459cf2014-06-12 16:12:31 -06004795
Joerg Roedel4236d97d2011-09-06 17:56:07 +02004796 bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
Fenghua Yu99dcade2009-11-11 07:23:06 -08004797 bus_register_notifier(&pci_bus_type, &device_nb);
Jiang Liu75f05562014-02-19 14:07:37 +08004798 if (si_domain && !hw_pass_through)
4799 register_memory_notifier(&intel_iommu_memory_nb);
Anna-Maria Gleixner21647612016-11-27 00:13:41 +01004800 cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
4801 intel_iommu_cpu_dead);
Eugeni Dodonov8bc1f852011-11-23 16:42:14 -02004802 intel_iommu_enabled = 1;
4803
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004804 return 0;
Jiang Liu9bdc5312014-01-06 14:18:27 +08004805
4806out_free_reserved_range:
4807 put_iova_domain(&reserved_iova_list);
Jiang Liu9bdc5312014-01-06 14:18:27 +08004808out_free_dmar:
4809 intel_iommu_free_dmars();
Jiang Liu3a5670e2014-02-19 14:07:33 +08004810 up_write(&dmar_global_lock);
4811 iommu_exit_mempool();
Jiang Liu9bdc5312014-01-06 14:18:27 +08004812 return ret;
Keshavamurthy, Anil Sba395922007-10-21 16:41:49 -07004813}
Keshavamurthy, Anil Se8204822007-10-21 16:41:55 -07004814
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004815static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
Alex Williamson579305f2014-07-03 09:51:43 -06004816{
4817 struct intel_iommu *iommu = opaque;
4818
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004819 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
Alex Williamson579305f2014-07-03 09:51:43 -06004820 return 0;
4821}
4822
4823/*
4824 * NB - intel-iommu lacks any sort of reference counting for the users of
4825 * dependent devices. If multiple endpoints have intersecting dependent
4826 * devices, unbinding the driver from any one of them will possibly leave
4827 * the others unable to operate.
4828 */
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004829static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
Han, Weidong3199aa62009-02-26 17:31:12 +08004830{
David Woodhouse0bcb3e22014-03-06 17:12:03 +00004831 if (!iommu || !dev || !dev_is_pci(dev))
Han, Weidong3199aa62009-02-26 17:31:12 +08004832 return;
4833
Joerg Roedel2452d9d2015-07-23 16:20:14 +02004834 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
Han, Weidong3199aa62009-02-26 17:31:12 +08004835}
4836
Joerg Roedel127c7612015-07-23 17:44:46 +02004837static void __dmar_remove_one_dev_info(struct device_domain_info *info)
Weidong Hanc7151a82008-12-08 22:51:37 +08004838{
Weidong Hanc7151a82008-12-08 22:51:37 +08004839 struct intel_iommu *iommu;
4840 unsigned long flags;
Weidong Hanc7151a82008-12-08 22:51:37 +08004841
Joerg Roedel55d94042015-07-22 16:50:40 +02004842 assert_spin_locked(&device_domain_lock);
4843
Joerg Roedelb608ac32015-07-21 18:19:08 +02004844 if (WARN_ON(!info))
Weidong Hanc7151a82008-12-08 22:51:37 +08004845 return;
4846
Joerg Roedel127c7612015-07-23 17:44:46 +02004847 iommu = info->iommu;
4848
4849 if (info->dev) {
4850 iommu_disable_dev_iotlb(info);
4851 domain_context_clear(iommu, info->dev);
4852 }
4853
Joerg Roedelb608ac32015-07-21 18:19:08 +02004854 unlink_domain_info(info);
Roland Dreier3e7abe22011-07-20 06:22:21 -07004855
Joerg Roedeld160aca2015-07-22 11:52:53 +02004856 spin_lock_irqsave(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004857 domain_detach_iommu(info->domain, iommu);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004858 spin_unlock_irqrestore(&iommu->lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004859
4860 free_devinfo_mem(info);
Weidong Hanc7151a82008-12-08 22:51:37 +08004861}
4862
Joerg Roedel55d94042015-07-22 16:50:40 +02004863static void dmar_remove_one_dev_info(struct dmar_domain *domain,
4864 struct device *dev)
4865{
Joerg Roedel127c7612015-07-23 17:44:46 +02004866 struct device_domain_info *info;
Joerg Roedel55d94042015-07-22 16:50:40 +02004867 unsigned long flags;
4868
Weidong Hanc7151a82008-12-08 22:51:37 +08004869 spin_lock_irqsave(&device_domain_lock, flags);
Joerg Roedel127c7612015-07-23 17:44:46 +02004870 info = dev->archdata.iommu;
4871 __dmar_remove_one_dev_info(info);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004872 spin_unlock_irqrestore(&device_domain_lock, flags);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004873}
4874
4875static int md_domain_init(struct dmar_domain *domain, int guest_width)
4876{
4877 int adjust_width;
4878
Zhen Leiaa3ac942017-09-21 16:52:45 +01004879 init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004880 domain_reserve_special_ranges(domain);
4881
4882 /* calculate AGAW */
4883 domain->gaw = guest_width;
4884 adjust_width = guestwidth_to_adjustwidth(guest_width);
4885 domain->agaw = width_to_agaw(adjust_width);
4886
Weidong Han5e98c4b2008-12-08 23:03:27 +08004887 domain->iommu_coherency = 0;
Sheng Yangc5b15252009-08-06 13:31:56 +08004888 domain->iommu_snooping = 0;
Youquan Song6dd9a7c2011-05-25 19:13:49 +01004889 domain->iommu_superpage = 0;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004890 domain->max_addr = 0;
Weidong Han5e98c4b2008-12-08 23:03:27 +08004891
4892 /* always allocate the top pgd */
Suresh Siddha4c923d42009-10-02 11:01:24 -07004893 domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
Weidong Han5e98c4b2008-12-08 23:03:27 +08004894 if (!domain->pgd)
4895 return -ENOMEM;
4896 domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
4897 return 0;
4898}
4899
Joerg Roedel00a77de2015-03-26 13:43:08 +01004900static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
Kay, Allen M38717942008-09-09 18:37:29 +03004901{
Joerg Roedel5d450802008-12-03 14:52:32 +01004902 struct dmar_domain *dmar_domain;
Joerg Roedel00a77de2015-03-26 13:43:08 +01004903 struct iommu_domain *domain;
4904
4905 if (type != IOMMU_DOMAIN_UNMANAGED)
4906 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004907
Jiang Liuab8dfe22014-07-11 14:19:27 +08004908 dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
Joerg Roedel5d450802008-12-03 14:52:32 +01004909 if (!dmar_domain) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004910 pr_err("Can't allocate dmar_domain\n");
Joerg Roedel00a77de2015-03-26 13:43:08 +01004911 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004912 }
Fenghua Yu2c2e2c32009-06-19 13:47:29 -07004913 if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004914 pr_err("Domain initialization failed\n");
Jiang Liu92d03cc2014-02-19 14:07:28 +08004915 domain_exit(dmar_domain);
Joerg Roedel00a77de2015-03-26 13:43:08 +01004916 return NULL;
Kay, Allen M38717942008-09-09 18:37:29 +03004917 }
Allen Kay8140a952011-10-14 12:32:17 -07004918 domain_update_iommu_cap(dmar_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004919
Joerg Roedel00a77de2015-03-26 13:43:08 +01004920 domain = &dmar_domain->domain;
Joerg Roedel8a0e7152012-01-26 19:40:54 +01004921 domain->geometry.aperture_start = 0;
4922 domain->geometry.aperture_end = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
4923 domain->geometry.force_aperture = true;
4924
Joerg Roedel00a77de2015-03-26 13:43:08 +01004925 return domain;
Kay, Allen M38717942008-09-09 18:37:29 +03004926}
Kay, Allen M38717942008-09-09 18:37:29 +03004927
Joerg Roedel00a77de2015-03-26 13:43:08 +01004928static void intel_iommu_domain_free(struct iommu_domain *domain)
Kay, Allen M38717942008-09-09 18:37:29 +03004929{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004930 domain_exit(to_dmar_domain(domain));
Kay, Allen M38717942008-09-09 18:37:29 +03004931}
Kay, Allen M38717942008-09-09 18:37:29 +03004932
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004933static int intel_iommu_attach_device(struct iommu_domain *domain,
4934 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004935{
Joerg Roedel00a77de2015-03-26 13:43:08 +01004936 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004937 struct intel_iommu *iommu;
4938 int addr_width;
David Woodhouse156baca2014-03-09 14:00:57 -07004939 u8 bus, devfn;
Kay, Allen M38717942008-09-09 18:37:29 +03004940
Alex Williamsonc875d2c2014-07-03 09:57:02 -06004941 if (device_is_rmrr_locked(dev)) {
4942 dev_warn(dev, "Device is ineligible for IOMMU domain attach due to platform RMRR requirement. Contact your platform vendor.\n");
4943 return -EPERM;
4944 }
4945
David Woodhouse7207d8f2014-03-09 16:31:06 -07004946 /* normally dev is not mapped */
4947 if (unlikely(domain_context_mapped(dev))) {
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004948 struct dmar_domain *old_domain;
4949
David Woodhouse1525a292014-03-06 16:19:30 +00004950 old_domain = find_domain(dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004951 if (old_domain) {
Joerg Roedeld160aca2015-07-22 11:52:53 +02004952 rcu_read_lock();
Joerg Roedelde7e8882015-07-22 11:58:07 +02004953 dmar_remove_one_dev_info(old_domain, dev);
Joerg Roedeld160aca2015-07-22 11:52:53 +02004954 rcu_read_unlock();
Joerg Roedel62c22162014-12-09 12:56:45 +01004955
4956 if (!domain_type_is_vm_or_si(old_domain) &&
4957 list_empty(&old_domain->devices))
4958 domain_exit(old_domain);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004959 }
4960 }
4961
David Woodhouse156baca2014-03-09 14:00:57 -07004962 iommu = device_to_iommu(dev, &bus, &devfn);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004963 if (!iommu)
4964 return -ENODEV;
4965
4966 /* check if this iommu agaw is sufficient for max mapped address */
4967 addr_width = agaw_to_width(iommu->agaw);
Tom Lyona99c47a2010-05-17 08:20:45 +01004968 if (addr_width > cap_mgaw(iommu->cap))
4969 addr_width = cap_mgaw(iommu->cap);
4970
4971 if (dmar_domain->max_addr > (1LL << addr_width)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02004972 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004973 "sufficient for the mapped address (%llx)\n",
Tom Lyona99c47a2010-05-17 08:20:45 +01004974 __func__, addr_width, dmar_domain->max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004975 return -EFAULT;
4976 }
Tom Lyona99c47a2010-05-17 08:20:45 +01004977 dmar_domain->gaw = addr_width;
4978
4979 /*
4980 * Knock out extra levels of page tables if necessary
4981 */
4982 while (iommu->agaw < dmar_domain->agaw) {
4983 struct dma_pte *pte;
4984
4985 pte = dmar_domain->pgd;
4986 if (dma_pte_present(pte)) {
Sheng Yang25cbff12010-06-12 19:21:42 +08004987 dmar_domain->pgd = (struct dma_pte *)
4988 phys_to_virt(dma_pte_addr(pte));
Jan Kiszka7a661012010-11-02 08:05:51 +01004989 free_pgtable_page(pte);
Tom Lyona99c47a2010-05-17 08:20:45 +01004990 }
4991 dmar_domain->agaw--;
4992 }
Weidong Hanfe40f1e2008-12-08 23:10:23 +08004993
Joerg Roedel28ccce02015-07-21 14:45:31 +02004994 return domain_add_dev_info(dmar_domain, dev);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004995}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08004996
Joerg Roedel4c5478c2008-12-03 14:58:24 +01004997static void intel_iommu_detach_device(struct iommu_domain *domain,
4998 struct device *dev)
Kay, Allen M38717942008-09-09 18:37:29 +03004999{
Joerg Roedele6de0f82015-07-22 16:30:36 +02005000 dmar_remove_one_dev_info(to_dmar_domain(domain), dev);
Kay, Allen M38717942008-09-09 18:37:29 +03005001}
Kay, Allen M38717942008-09-09 18:37:29 +03005002
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005003static int intel_iommu_map(struct iommu_domain *domain,
5004 unsigned long iova, phys_addr_t hpa,
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005005 size_t size, int iommu_prot)
Kay, Allen M38717942008-09-09 18:37:29 +03005006{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005007 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005008 u64 max_addr;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005009 int prot = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005010 int ret;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005011
Joerg Roedeldde57a22008-12-03 15:04:09 +01005012 if (iommu_prot & IOMMU_READ)
5013 prot |= DMA_PTE_READ;
5014 if (iommu_prot & IOMMU_WRITE)
5015 prot |= DMA_PTE_WRITE;
Sheng Yang9cf06692009-03-18 15:33:07 +08005016 if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
5017 prot |= DMA_PTE_SNP;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005018
David Woodhouse163cc522009-06-28 00:51:17 +01005019 max_addr = iova + size;
Joerg Roedeldde57a22008-12-03 15:04:09 +01005020 if (dmar_domain->max_addr < max_addr) {
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005021 u64 end;
5022
5023 /* check if minimum agaw is sufficient for mapped address */
Tom Lyon8954da12010-05-17 08:19:52 +01005024 end = __DOMAIN_MAX_ADDR(dmar_domain->gaw) + 1;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005025 if (end < max_addr) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005026 pr_err("%s: iommu width (%d) is not "
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005027 "sufficient for the mapped address (%llx)\n",
Tom Lyon8954da12010-05-17 08:19:52 +01005028 __func__, dmar_domain->gaw, max_addr);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005029 return -EFAULT;
5030 }
Joerg Roedeldde57a22008-12-03 15:04:09 +01005031 dmar_domain->max_addr = max_addr;
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005032 }
David Woodhousead051222009-06-28 14:22:28 +01005033 /* Round up size to next multiple of PAGE_SIZE, if it and
5034 the low bits of hpa would take us onto the next page */
David Woodhouse88cb6a72009-06-28 15:03:06 +01005035 size = aligned_nrpages(hpa, size);
David Woodhousead051222009-06-28 14:22:28 +01005036 ret = domain_pfn_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
5037 hpa >> VTD_PAGE_SHIFT, size, prot);
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005038 return ret;
Kay, Allen M38717942008-09-09 18:37:29 +03005039}
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005040
Ohad Ben-Cohen50090652011-11-10 11:32:25 +02005041static size_t intel_iommu_unmap(struct iommu_domain *domain,
David Woodhouseea8ea462014-03-05 17:09:32 +00005042 unsigned long iova, size_t size)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005043{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005044 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
David Woodhouseea8ea462014-03-05 17:09:32 +00005045 struct page *freelist = NULL;
5046 struct intel_iommu *iommu;
5047 unsigned long start_pfn, last_pfn;
5048 unsigned int npages;
Joerg Roedel42e8c182015-07-21 15:50:02 +02005049 int iommu_id, level = 0;
Sheng Yang4b99d352009-07-08 11:52:52 +01005050
David Woodhouse5cf0a762014-03-19 16:07:49 +00005051 /* Cope with horrid API which requires us to unmap more than the
5052 size argument if it happens to be a large-page mapping. */
Joerg Roedeldc02e462015-08-13 11:15:13 +02005053 BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level));
David Woodhouse5cf0a762014-03-19 16:07:49 +00005054
5055 if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
5056 size = VTD_PAGE_SIZE << level_to_offset_bits(level);
5057
David Woodhouseea8ea462014-03-05 17:09:32 +00005058 start_pfn = iova >> VTD_PAGE_SHIFT;
5059 last_pfn = (iova + size - 1) >> VTD_PAGE_SHIFT;
5060
5061 freelist = domain_unmap(dmar_domain, start_pfn, last_pfn);
5062
5063 npages = last_pfn - start_pfn + 1;
5064
Joerg Roedel29a27712015-07-21 17:17:12 +02005065 for_each_domain_iommu(iommu_id, dmar_domain) {
Joerg Roedela1ddcbe2015-07-21 15:20:32 +02005066 iommu = g_iommus[iommu_id];
David Woodhouseea8ea462014-03-05 17:09:32 +00005067
Joerg Roedel42e8c182015-07-21 15:50:02 +02005068 iommu_flush_iotlb_psi(g_iommus[iommu_id], dmar_domain,
5069 start_pfn, npages, !freelist, 0);
David Woodhouseea8ea462014-03-05 17:09:32 +00005070 }
5071
5072 dma_free_pagelist(freelist);
Weidong Hanfe40f1e2008-12-08 23:10:23 +08005073
David Woodhouse163cc522009-06-28 00:51:17 +01005074 if (dmar_domain->max_addr == iova + size)
5075 dmar_domain->max_addr = iova;
Joerg Roedelb146a1c9f2010-01-20 17:17:37 +01005076
David Woodhouse5cf0a762014-03-19 16:07:49 +00005077 return size;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005078}
Kay, Allen M38717942008-09-09 18:37:29 +03005079
Joerg Roedeld14d6572008-12-03 15:06:57 +01005080static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
Varun Sethibb5547a2013-03-29 01:23:58 +05305081 dma_addr_t iova)
Kay, Allen M38717942008-09-09 18:37:29 +03005082{
Joerg Roedel00a77de2015-03-26 13:43:08 +01005083 struct dmar_domain *dmar_domain = to_dmar_domain(domain);
Kay, Allen M38717942008-09-09 18:37:29 +03005084 struct dma_pte *pte;
David Woodhouse5cf0a762014-03-19 16:07:49 +00005085 int level = 0;
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005086 u64 phys = 0;
Kay, Allen M38717942008-09-09 18:37:29 +03005087
David Woodhouse5cf0a762014-03-19 16:07:49 +00005088 pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level);
Kay, Allen M38717942008-09-09 18:37:29 +03005089 if (pte)
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005090 phys = dma_pte_addr(pte);
Kay, Allen M38717942008-09-09 18:37:29 +03005091
Weidong Hanfaa3d6f2008-12-08 23:09:29 +08005092 return phys;
Kay, Allen M38717942008-09-09 18:37:29 +03005093}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005094
Joerg Roedel5d587b82014-09-05 10:50:45 +02005095static bool intel_iommu_capable(enum iommu_cap cap)
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005096{
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005097 if (cap == IOMMU_CAP_CACHE_COHERENCY)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005098 return domain_update_iommu_snooping(NULL) == 1;
Tom Lyon323f99c2010-07-02 16:56:14 -04005099 if (cap == IOMMU_CAP_INTR_REMAP)
Joerg Roedel5d587b82014-09-05 10:50:45 +02005100 return irq_remapping_enabled == 1;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005101
Joerg Roedel5d587b82014-09-05 10:50:45 +02005102 return false;
Sheng Yangdbb9fd82009-03-18 15:33:06 +08005103}
5104
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005105static int intel_iommu_add_device(struct device *dev)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005106{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005107 struct intel_iommu *iommu;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005108 struct iommu_group *group;
David Woodhouse156baca2014-03-09 14:00:57 -07005109 u8 bus, devfn;
Alex Williamson70ae6f02011-10-21 15:56:11 -04005110
Alex Williamsona5459cf2014-06-12 16:12:31 -06005111 iommu = device_to_iommu(dev, &bus, &devfn);
5112 if (!iommu)
Alex Williamson70ae6f02011-10-21 15:56:11 -04005113 return -ENODEV;
5114
Joerg Roedele3d10af2017-02-01 17:23:22 +01005115 iommu_device_link(&iommu->iommu, dev);
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005116
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005117 group = iommu_group_get_for_dev(dev);
Alex Williamson783f1572012-05-30 14:19:43 -06005118
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005119 if (IS_ERR(group))
5120 return PTR_ERR(group);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005121
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005122 iommu_group_put(group);
Alex Williamsone17f9ff2014-07-03 09:51:37 -06005123 return 0;
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005124}
5125
5126static void intel_iommu_remove_device(struct device *dev)
5127{
Alex Williamsona5459cf2014-06-12 16:12:31 -06005128 struct intel_iommu *iommu;
5129 u8 bus, devfn;
5130
5131 iommu = device_to_iommu(dev, &bus, &devfn);
5132 if (!iommu)
5133 return;
5134
Alex Williamsonabdfdde2012-05-30 14:19:19 -06005135 iommu_group_remove_device(dev);
Alex Williamsona5459cf2014-06-12 16:12:31 -06005136
Joerg Roedele3d10af2017-02-01 17:23:22 +01005137 iommu_device_unlink(&iommu->iommu, dev);
Alex Williamson70ae6f02011-10-21 15:56:11 -04005138}
5139
Eric Auger0659b8d2017-01-19 20:57:53 +00005140static void intel_iommu_get_resv_regions(struct device *device,
5141 struct list_head *head)
5142{
5143 struct iommu_resv_region *reg;
5144 struct dmar_rmrr_unit *rmrr;
5145 struct device *i_dev;
5146 int i;
5147
5148 rcu_read_lock();
5149 for_each_rmrr_units(rmrr) {
5150 for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
5151 i, i_dev) {
5152 if (i_dev != device)
5153 continue;
5154
5155 list_add_tail(&rmrr->resv->list, head);
5156 }
5157 }
5158 rcu_read_unlock();
5159
5160 reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
5161 IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
Robin Murphy9d3a4de2017-03-16 17:00:16 +00005162 0, IOMMU_RESV_MSI);
Eric Auger0659b8d2017-01-19 20:57:53 +00005163 if (!reg)
5164 return;
5165 list_add_tail(&reg->list, head);
5166}
5167
5168static void intel_iommu_put_resv_regions(struct device *dev,
5169 struct list_head *head)
5170{
5171 struct iommu_resv_region *entry, *next;
5172
5173 list_for_each_entry_safe(entry, next, head, list) {
5174 if (entry->type == IOMMU_RESV_RESERVED)
5175 kfree(entry);
5176 }
Kay, Allen M38717942008-09-09 18:37:29 +03005177}
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005178
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005179#ifdef CONFIG_INTEL_IOMMU_SVM
Jacob Pan65ca7f52016-12-06 10:14:23 -08005180#define MAX_NR_PASID_BITS (20)
5181static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
5182{
5183 /*
5184 * Convert ecap_pss to extend context entry pts encoding, also
5185 * respect the soft pasid_max value set by the iommu.
5186 * - number of PASID bits = ecap_pss + 1
5187 * - number of PASID table entries = 2^(pts + 5)
5188 * Therefore, pts = ecap_pss - 4
5189 * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
5190 */
5191 if (ecap_pss(iommu->ecap) < 5)
5192 return 0;
5193
5194 /* pasid_max is encoded as actual number of entries not the bits */
5195 return find_first_bit((unsigned long *)&iommu->pasid_max,
5196 MAX_NR_PASID_BITS) - 5;
5197}
5198
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005199int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
5200{
5201 struct device_domain_info *info;
5202 struct context_entry *context;
5203 struct dmar_domain *domain;
5204 unsigned long flags;
5205 u64 ctx_lo;
5206 int ret;
5207
5208 domain = get_valid_domain_for_dev(sdev->dev);
5209 if (!domain)
5210 return -EINVAL;
5211
5212 spin_lock_irqsave(&device_domain_lock, flags);
5213 spin_lock(&iommu->lock);
5214
5215 ret = -EINVAL;
5216 info = sdev->dev->archdata.iommu;
5217 if (!info || !info->pasid_supported)
5218 goto out;
5219
5220 context = iommu_context_addr(iommu, info->bus, info->devfn, 0);
5221 if (WARN_ON(!context))
5222 goto out;
5223
5224 ctx_lo = context[0].lo;
5225
5226 sdev->did = domain->iommu_did[iommu->seq_id];
5227 sdev->sid = PCI_DEVID(info->bus, info->devfn);
5228
5229 if (!(ctx_lo & CONTEXT_PASIDE)) {
Ashok Raj11b93eb2017-08-08 13:29:28 -07005230 if (iommu->pasid_state_table)
5231 context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
Jacob Pan65ca7f52016-12-06 10:14:23 -08005232 context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
5233 intel_iommu_get_pts(iommu);
5234
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005235 wmb();
5236 /* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
5237 * extended to permit requests-with-PASID if the PASIDE bit
5238 * is set. which makes sense. For CONTEXT_TT_PASS_THROUGH,
5239 * however, the PASIDE bit is ignored and requests-with-PASID
5240 * are unconditionally blocked. Which makes less sense.
5241 * So convert from CONTEXT_TT_PASS_THROUGH to one of the new
5242 * "guest mode" translation types depending on whether ATS
5243 * is available or not. Annoyingly, we can't use the new
5244 * modes *unless* PASIDE is set. */
5245 if ((ctx_lo & CONTEXT_TT_MASK) == (CONTEXT_TT_PASS_THROUGH << 2)) {
5246 ctx_lo &= ~CONTEXT_TT_MASK;
5247 if (info->ats_supported)
5248 ctx_lo |= CONTEXT_TT_PT_PASID_DEV_IOTLB << 2;
5249 else
5250 ctx_lo |= CONTEXT_TT_PT_PASID << 2;
5251 }
5252 ctx_lo |= CONTEXT_PASIDE;
David Woodhouse907fea32015-10-13 14:11:13 +01005253 if (iommu->pasid_state_table)
5254 ctx_lo |= CONTEXT_DINVE;
David Woodhousea222a7f2015-10-07 23:35:18 +01005255 if (info->pri_supported)
5256 ctx_lo |= CONTEXT_PRS;
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005257 context[0].lo = ctx_lo;
5258 wmb();
5259 iommu->flush.flush_context(iommu, sdev->did, sdev->sid,
5260 DMA_CCMD_MASK_NOBIT,
5261 DMA_CCMD_DEVICE_INVL);
5262 }
5263
5264 /* Enable PASID support in the device, if it wasn't already */
5265 if (!info->pasid_enabled)
5266 iommu_enable_dev_iotlb(info);
5267
5268 if (info->ats_enabled) {
5269 sdev->dev_iotlb = 1;
5270 sdev->qdep = info->ats_qdep;
5271 if (sdev->qdep >= QI_DEV_EIOTLB_MAX_INVS)
5272 sdev->qdep = 0;
5273 }
5274 ret = 0;
5275
5276 out:
5277 spin_unlock(&iommu->lock);
5278 spin_unlock_irqrestore(&device_domain_lock, flags);
5279
5280 return ret;
5281}
5282
5283struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
5284{
5285 struct intel_iommu *iommu;
5286 u8 bus, devfn;
5287
5288 if (iommu_dummy(dev)) {
5289 dev_warn(dev,
5290 "No IOMMU translation for device; cannot enable SVM\n");
5291 return NULL;
5292 }
5293
5294 iommu = device_to_iommu(dev, &bus, &devfn);
5295 if ((!iommu)) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005296 dev_err(dev, "No IOMMU for device; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005297 return NULL;
5298 }
5299
5300 if (!iommu->pasid_table) {
Sudeep Duttb9997e32015-10-18 20:54:37 -07005301 dev_err(dev, "PASID not enabled on IOMMU; cannot enable SVM\n");
David Woodhouse2f26e0a2015-09-09 11:40:47 +01005302 return NULL;
5303 }
5304
5305 return iommu;
5306}
5307#endif /* CONFIG_INTEL_IOMMU_SVM */
5308
Joerg Roedelb0119e82017-02-01 13:23:08 +01005309const struct iommu_ops intel_iommu_ops = {
Eric Auger0659b8d2017-01-19 20:57:53 +00005310 .capable = intel_iommu_capable,
5311 .domain_alloc = intel_iommu_domain_alloc,
5312 .domain_free = intel_iommu_domain_free,
5313 .attach_dev = intel_iommu_attach_device,
5314 .detach_dev = intel_iommu_detach_device,
5315 .map = intel_iommu_map,
5316 .unmap = intel_iommu_unmap,
5317 .map_sg = default_iommu_map_sg,
5318 .iova_to_phys = intel_iommu_iova_to_phys,
5319 .add_device = intel_iommu_add_device,
5320 .remove_device = intel_iommu_remove_device,
5321 .get_resv_regions = intel_iommu_get_resv_regions,
5322 .put_resv_regions = intel_iommu_put_resv_regions,
5323 .device_group = pci_device_group,
5324 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,
Joerg Roedela8bcbb0d2008-12-03 15:14:02 +01005325};
David Woodhouse9af88142009-02-13 23:18:03 +00005326
Daniel Vetter94526182013-01-20 23:50:13 +01005327static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
5328{
5329 /* G4x/GM45 integrated gfx dmar support is totally busted. */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005330 pr_info("Disabling IOMMU for graphics on this chipset\n");
Daniel Vetter94526182013-01-20 23:50:13 +01005331 dmar_map_gfx = 0;
5332}
5333
5334DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
5335DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
5336DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
5337DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
5338DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
5339DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
5340DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
5341
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005342static void quirk_iommu_rwbf(struct pci_dev *dev)
David Woodhouse9af88142009-02-13 23:18:03 +00005343{
5344 /*
5345 * Mobile 4 Series Chipset neglects to set RWBF capability,
Daniel Vetter210561f2013-01-21 19:48:59 +01005346 * but needs it. Same seems to hold for the desktop versions.
David Woodhouse9af88142009-02-13 23:18:03 +00005347 */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005348 pr_info("Forcing write-buffer flush capability\n");
David Woodhouse9af88142009-02-13 23:18:03 +00005349 rwbf_quirk = 1;
5350}
5351
5352DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
Daniel Vetter210561f2013-01-21 19:48:59 +01005353DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf);
5354DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf);
5355DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf);
5356DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf);
5357DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf);
5358DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf);
David Woodhousee0fc7e02009-09-30 09:12:17 -07005359
Adam Jacksoneecfd572010-08-25 21:17:34 +01005360#define GGC 0x52
5361#define GGC_MEMORY_SIZE_MASK (0xf << 8)
5362#define GGC_MEMORY_SIZE_NONE (0x0 << 8)
5363#define GGC_MEMORY_SIZE_1M (0x1 << 8)
5364#define GGC_MEMORY_SIZE_2M (0x3 << 8)
5365#define GGC_MEMORY_VT_ENABLED (0x8 << 8)
5366#define GGC_MEMORY_SIZE_2M_VT (0x9 << 8)
5367#define GGC_MEMORY_SIZE_3M_VT (0xa << 8)
5368#define GGC_MEMORY_SIZE_4M_VT (0xb << 8)
5369
Greg Kroah-Hartmand34d6512012-12-21 15:05:21 -08005370static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
David Woodhouse9eecabc2010-09-21 22:28:23 +01005371{
5372 unsigned short ggc;
5373
Adam Jacksoneecfd572010-08-25 21:17:34 +01005374 if (pci_read_config_word(dev, GGC, &ggc))
David Woodhouse9eecabc2010-09-21 22:28:23 +01005375 return;
5376
Adam Jacksoneecfd572010-08-25 21:17:34 +01005377 if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005378 pr_info("BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
David Woodhouse9eecabc2010-09-21 22:28:23 +01005379 dmar_map_gfx = 0;
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005380 } else if (dmar_map_gfx) {
5381 /* we have to ensure the gfx device is idle before we flush */
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005382 pr_info("Disabling batched IOTLB flush on Ironlake\n");
David Woodhouse6fbcfb32011-09-25 19:11:14 -07005383 intel_iommu_strict = 1;
5384 }
David Woodhouse9eecabc2010-09-21 22:28:23 +01005385}
5386DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
5387DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
5388DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0062, quirk_calpella_no_shadow_gtt);
5389DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x006a, quirk_calpella_no_shadow_gtt);
5390
David Woodhousee0fc7e02009-09-30 09:12:17 -07005391/* On Tylersburg chipsets, some BIOSes have been known to enable the
5392 ISOCH DMAR unit for the Azalia sound device, but not give it any
5393 TLB entries, which causes it to deadlock. Check for that. We do
5394 this in a function called from init_dmars(), instead of in a PCI
5395 quirk, because we don't want to print the obnoxious "BIOS broken"
5396 message if VT-d is actually disabled.
5397*/
5398static void __init check_tylersburg_isoch(void)
5399{
5400 struct pci_dev *pdev;
5401 uint32_t vtisochctrl;
5402
5403 /* If there's no Azalia in the system anyway, forget it. */
5404 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
5405 if (!pdev)
5406 return;
5407 pci_dev_put(pdev);
5408
5409 /* System Management Registers. Might be hidden, in which case
5410 we can't do the sanity check. But that's OK, because the
5411 known-broken BIOSes _don't_ actually hide it, so far. */
5412 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
5413 if (!pdev)
5414 return;
5415
5416 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
5417 pci_dev_put(pdev);
5418 return;
5419 }
5420
5421 pci_dev_put(pdev);
5422
5423 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
5424 if (vtisochctrl & 1)
5425 return;
5426
5427 /* Drop all bits other than the number of TLB entries */
5428 vtisochctrl &= 0x1c;
5429
5430 /* If we have the recommended number of TLB entries (16), fine. */
5431 if (vtisochctrl == 0x10)
5432 return;
5433
5434 /* Zero TLB entries? You get to ride the short bus to school. */
5435 if (!vtisochctrl) {
5436 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
5437 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
5438 dmi_get_system_info(DMI_BIOS_VENDOR),
5439 dmi_get_system_info(DMI_BIOS_VERSION),
5440 dmi_get_system_info(DMI_PRODUCT_VERSION));
5441 iommu_identity_mapping |= IDENTMAP_AZALIA;
5442 return;
5443 }
Joerg Roedel9f10e5b2015-06-12 09:57:06 +02005444
5445 pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
David Woodhousee0fc7e02009-09-30 09:12:17 -07005446 vtisochctrl);
5447}